rpc: Add admin_addTrustedPeer and admin_removeTrustedPeer.
These RPC calls are analogous to Parity's parity_addReservedPeer and parity_removeReservedPeer. They are useful for adjusting the trusted peer set during runtime, without requiring restarting the server.
This commit is contained in:
parent
d926bf2c7e
commit
2a75fe3308
@ -123,6 +123,16 @@ web3._extend({
|
||||
call: 'admin_removePeer',
|
||||
params: 1
|
||||
}),
|
||||
new web3._extend.Method({
|
||||
name: 'addTrustedPeer',
|
||||
call: 'admin_addTrustedPeer',
|
||||
params: 1
|
||||
}),
|
||||
new web3._extend.Method({
|
||||
name: 'removeTrustedPeer',
|
||||
call: 'admin_removeTrustedPeer',
|
||||
params: 1
|
||||
}),
|
||||
new web3._extend.Method({
|
||||
name: 'exportChain',
|
||||
call: 'admin_exportChain',
|
||||
|
33
node/api.go
33
node/api.go
@ -59,7 +59,7 @@ func (api *PrivateAdminAPI) AddPeer(url string) (bool, error) {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// RemovePeer disconnects from a a remote node if the connection exists
|
||||
// RemovePeer disconnects from a remote node if the connection exists
|
||||
func (api *PrivateAdminAPI) RemovePeer(url string) (bool, error) {
|
||||
// Make sure the server is running, fail otherwise
|
||||
server := api.node.Server()
|
||||
@ -75,6 +75,37 @@ func (api *PrivateAdminAPI) RemovePeer(url string) (bool, error) {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// AddTrustedPeer allows a remote node to always connect, even if slots are full
|
||||
func (api *PrivateAdminAPI) AddTrustedPeer(url string) (bool, error) {
|
||||
// Make sure the server is running, fail otherwise
|
||||
server := api.node.Server()
|
||||
if server == nil {
|
||||
return false, ErrNodeStopped
|
||||
}
|
||||
node, err := discover.ParseNode(url)
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("invalid enode: %v", err)
|
||||
}
|
||||
server.AddTrustedPeer(node)
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// RemoveTrustedPeer removes a remote node from the trusted peer set, but it
|
||||
// does not disconnect it automatically.
|
||||
func (api *PrivateAdminAPI) RemoveTrustedPeer(url string) (bool, error) {
|
||||
// Make sure the server is running, fail otherwise
|
||||
server := api.node.Server()
|
||||
if server == nil {
|
||||
return false, ErrNodeStopped
|
||||
}
|
||||
node, err := discover.ParseNode(url)
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("invalid enode: %v", err)
|
||||
}
|
||||
server.RemoveTrustedPeer(node)
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// PeerEvents creates an RPC subscription which receives peer events from the
|
||||
// node's p2p.Server
|
||||
func (api *PrivateAdminAPI) PeerEvents(ctx context.Context) (*rpc.Subscription, error) {
|
||||
|
@ -169,6 +169,8 @@ type Server struct {
|
||||
quit chan struct{}
|
||||
addstatic chan *discover.Node
|
||||
removestatic chan *discover.Node
|
||||
addtrusted chan *discover.Node
|
||||
removetrusted chan *discover.Node
|
||||
posthandshake chan *conn
|
||||
addpeer chan *conn
|
||||
delpeer chan peerDrop
|
||||
@ -300,6 +302,23 @@ func (srv *Server) RemovePeer(node *discover.Node) {
|
||||
}
|
||||
}
|
||||
|
||||
// AddTrustedPeer adds the given node to a reserved whitelist which allows the
|
||||
// node to always connect, even if the slot are full.
|
||||
func (srv *Server) AddTrustedPeer(node *discover.Node) {
|
||||
select {
|
||||
case srv.addtrusted <- node:
|
||||
case <-srv.quit:
|
||||
}
|
||||
}
|
||||
|
||||
// RemoveTrustedPeer removes the given node from the trusted peer set.
|
||||
func (srv *Server) RemoveTrustedPeer(node *discover.Node) {
|
||||
select {
|
||||
case srv.removetrusted <- node:
|
||||
case <-srv.quit:
|
||||
}
|
||||
}
|
||||
|
||||
// SubscribePeers subscribes the given channel to peer events
|
||||
func (srv *Server) SubscribeEvents(ch chan *PeerEvent) event.Subscription {
|
||||
return srv.peerFeed.Subscribe(ch)
|
||||
@ -410,6 +429,8 @@ func (srv *Server) Start() (err error) {
|
||||
srv.posthandshake = make(chan *conn)
|
||||
srv.addstatic = make(chan *discover.Node)
|
||||
srv.removestatic = make(chan *discover.Node)
|
||||
srv.addtrusted = make(chan *discover.Node)
|
||||
srv.removetrusted = make(chan *discover.Node)
|
||||
srv.peerOp = make(chan peerOpFunc)
|
||||
srv.peerOpDone = make(chan struct{})
|
||||
|
||||
@ -546,8 +567,7 @@ func (srv *Server) run(dialstate dialer) {
|
||||
queuedTasks []task // tasks that can't run yet
|
||||
)
|
||||
// Put trusted nodes into a map to speed up checks.
|
||||
// Trusted peers are loaded on startup and cannot be
|
||||
// modified while the server is running.
|
||||
// Trusted peers are loaded on startup or added via AddTrustedPeer RPC.
|
||||
for _, n := range srv.TrustedNodes {
|
||||
trusted[n.ID] = true
|
||||
}
|
||||
@ -599,12 +619,32 @@ running:
|
||||
case n := <-srv.removestatic:
|
||||
// This channel is used by RemovePeer to send a
|
||||
// disconnect request to a peer and begin the
|
||||
// stop keeping the node connected
|
||||
// stop keeping the node connected.
|
||||
srv.log.Trace("Removing static node", "node", n)
|
||||
dialstate.removeStatic(n)
|
||||
if p, ok := peers[n.ID]; ok {
|
||||
p.Disconnect(DiscRequested)
|
||||
}
|
||||
case n := <-srv.addtrusted:
|
||||
// This channel is used by AddTrustedPeer to add an enode
|
||||
// to the trusted node set.
|
||||
srv.log.Trace("Adding trusted node", "node", n)
|
||||
trusted[n.ID] = true
|
||||
// Mark any already-connected peer as trusted
|
||||
if p, ok := peers[n.ID]; ok {
|
||||
p.rw.flags |= trustedConn
|
||||
}
|
||||
case n := <-srv.removetrusted:
|
||||
// This channel is used by RemoveTrustedPeer to remove an enode
|
||||
// from the trusted node set.
|
||||
srv.log.Trace("Removing trusted node", "node", n)
|
||||
if _, ok := trusted[n.ID]; ok {
|
||||
delete(trusted, n.ID)
|
||||
}
|
||||
// Unmark any already-connected peer as trusted
|
||||
if p, ok := peers[n.ID]; ok {
|
||||
p.rw.flags &= ^trustedConn
|
||||
}
|
||||
case op := <-srv.peerOp:
|
||||
// This channel is used by Peers and PeerCount.
|
||||
op(peers)
|
||||
|
Loading…
Reference in New Issue
Block a user