This commit is contained in:
Andrey Petrov 2018-03-12 21:02:05 +00:00 committed by GitHub
commit ed50bebaaa
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 48 additions and 4 deletions

View file

@ -123,6 +123,11 @@ web3._extend({
call: 'admin_removePeer', call: 'admin_removePeer',
params: 1 params: 1
}), }),
new web3._extend.Method({
name: 'trustPeer',
call: 'admin_trustPeer',
params: 1
}),
new web3._extend.Method({ new web3._extend.Method({
name: 'exportChain', name: 'exportChain',
call: 'admin_exportChain', call: 'admin_exportChain',

View file

@ -59,7 +59,7 @@ func (api *PrivateAdminAPI) AddPeer(url string) (bool, error) {
return true, nil 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) { func (api *PrivateAdminAPI) RemovePeer(url string) (bool, error) {
// Make sure the server is running, fail otherwise // Make sure the server is running, fail otherwise
server := api.node.Server() server := api.node.Server()
@ -75,6 +75,21 @@ func (api *PrivateAdminAPI) RemovePeer(url string) (bool, error) {
return true, nil return true, nil
} }
// TrustPeer allows a remote node to always connect, even if slots are full
func (api *PrivateAdminAPI) TrustPeer(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.TrustPeer(node)
return true, nil
}
// PeerEvents creates an RPC subscription which receives peer events from the // PeerEvents creates an RPC subscription which receives peer events from the
// node's p2p.Server // node's p2p.Server
func (api *PrivateAdminAPI) PeerEvents(ctx context.Context) (*rpc.Subscription, error) { func (api *PrivateAdminAPI) PeerEvents(ctx context.Context) (*rpc.Subscription, error) {

View file

@ -169,6 +169,7 @@ type Server struct {
quit chan struct{} quit chan struct{}
addstatic chan *discover.Node addstatic chan *discover.Node
removestatic chan *discover.Node removestatic chan *discover.Node
addtrusted chan *discover.Node
posthandshake chan *conn posthandshake chan *conn
addpeer chan *conn addpeer chan *conn
delpeer chan peerDrop delpeer chan peerDrop
@ -300,6 +301,15 @@ func (srv *Server) RemovePeer(node *discover.Node) {
} }
} }
// TrustPeer adds the given node to a reserved whitelist which allows the
// node to always connect, even if the slot are full.
func (srv *Server) TrustPeer(node *discover.Node) {
select {
case srv.addtrusted <- node:
case <-srv.quit:
}
}
// SubscribePeers subscribes the given channel to peer events // SubscribePeers subscribes the given channel to peer events
func (srv *Server) SubscribeEvents(ch chan *PeerEvent) event.Subscription { func (srv *Server) SubscribeEvents(ch chan *PeerEvent) event.Subscription {
return srv.peerFeed.Subscribe(ch) return srv.peerFeed.Subscribe(ch)
@ -410,6 +420,7 @@ func (srv *Server) Start() (err error) {
srv.posthandshake = make(chan *conn) srv.posthandshake = make(chan *conn)
srv.addstatic = make(chan *discover.Node) srv.addstatic = make(chan *discover.Node)
srv.removestatic = make(chan *discover.Node) srv.removestatic = make(chan *discover.Node)
srv.addtrusted = make(chan *discover.Node)
srv.peerOp = make(chan peerOpFunc) srv.peerOp = make(chan peerOpFunc)
srv.peerOpDone = make(chan struct{}) srv.peerOpDone = make(chan struct{})
@ -546,8 +557,7 @@ func (srv *Server) run(dialstate dialer) {
queuedTasks []task // tasks that can't run yet queuedTasks []task // tasks that can't run yet
) )
// Put trusted nodes into a map to speed up checks. // Put trusted nodes into a map to speed up checks.
// Trusted peers are loaded on startup and cannot be // Trusted peers are loaded on startup or added via TrustPeer RPC.
// modified while the server is running.
for _, n := range srv.TrustedNodes { for _, n := range srv.TrustedNodes {
trusted[n.ID] = true trusted[n.ID] = true
} }
@ -599,12 +609,26 @@ running:
case n := <-srv.removestatic: case n := <-srv.removestatic:
// This channel is used by RemovePeer to send a // This channel is used by RemovePeer to send a
// disconnect request to a peer and begin the // disconnect request to a peer and begin the
// stop keeping the node connected // stop keeping the node connected. It will also
// remove nodes from the trusted set, if present.
srv.log.Debug("Removing static node", "node", n) srv.log.Debug("Removing static node", "node", n)
dialstate.removeStatic(n) dialstate.removeStatic(n)
if p, ok := peers[n.ID]; ok { if p, ok := peers[n.ID]; ok {
p.Disconnect(DiscRequested) p.Disconnect(DiscRequested)
} }
if _, ok := trusted[n.ID]; ok {
srv.log.Debug("Removing trusted node", "node", n)
delete(trusted, n.ID)
}
case n := <-srv.addtrusted:
// This channel is used by TrustPeer to add an enode
// to the trusted node set.
srv.log.Debug("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 op := <-srv.peerOp: case op := <-srv.peerOp:
// This channel is used by Peers and PeerCount. // This channel is used by Peers and PeerCount.
op(peers) op(peers)