@@ -88,6 +88,8 @@ type ProtocolManager struct {
8888 txsSub event.Subscription
8989 minedBlockSub * event.TypeMuxSubscription
9090
91+ whitelist map [uint64 ]common.Hash
92+
9193 // channels for fetcher, syncer, txsyncLoop
9294 newPeerCh chan * peer
9395 txsyncCh chan * txsync
@@ -101,7 +103,7 @@ type ProtocolManager struct {
101103
102104// NewProtocolManager returns a new Ethereum sub protocol manager. The Ethereum sub protocol manages peers capable
103105// with the Ethereum network.
104- func NewProtocolManager (config * params.ChainConfig , mode downloader.SyncMode , networkID uint64 , mux * event.TypeMux , txpool txPool , engine consensus.Engine , blockchain * core.BlockChain , chaindb ethdb.Database ) (* ProtocolManager , error ) {
106+ func NewProtocolManager (config * params.ChainConfig , mode downloader.SyncMode , networkID uint64 , mux * event.TypeMux , txpool txPool , engine consensus.Engine , blockchain * core.BlockChain , chaindb ethdb.Database , whitelist map [ uint64 ]common. Hash ) (* ProtocolManager , error ) {
105107 // Create the protocol manager with the base fields
106108 manager := & ProtocolManager {
107109 networkID : networkID ,
@@ -110,6 +112,7 @@ func NewProtocolManager(config *params.ChainConfig, mode downloader.SyncMode, ne
110112 blockchain : blockchain ,
111113 chainconfig : config ,
112114 peers : newPeerSet (),
115+ whitelist : whitelist ,
113116 newPeerCh : make (chan * peer ),
114117 noMorePeers : make (chan struct {}),
115118 txsyncCh : make (chan * txsync ),
@@ -307,7 +310,13 @@ func (pm *ProtocolManager) handle(p *peer) error {
307310 }
308311 }()
309312 }
310- // main loop. handle incoming messages.
313+ // If we have any explicit whitelist block hashes, request them
314+ for number := range pm .whitelist {
315+ if err := p .RequestHeadersByNumber (number , 1 , 0 , false ); err != nil {
316+ return err
317+ }
318+ }
319+ // Handle incoming messages until the connection is torn down
311320 for {
312321 if err := pm .handleMsg (p ); err != nil {
313322 p .Log ().Debug ("Ethereum message handling failed" , "err" , err )
@@ -466,6 +475,14 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
466475 p .Log ().Debug ("Verified to be on the same side of the DAO fork" )
467476 return nil
468477 }
478+ // Otherwise if it's a whitelisted block, validate against the set
479+ if want , ok := pm .whitelist [headers [0 ].Number .Uint64 ()]; ok {
480+ if hash := headers [0 ].Hash (); want != hash {
481+ p .Log ().Info ("Whitelist mismatch, dropping peer" , "number" , headers [0 ].Number .Uint64 (), "hash" , hash , "want" , want )
482+ return errors .New ("whitelist block mismatch" )
483+ }
484+ p .Log ().Debug ("Whitelist block verified" , "number" , headers [0 ].Number .Uint64 (), "hash" , want )
485+ }
469486 // Irrelevant of the fork checks, send the header to the fetcher just in case
470487 headers = pm .fetcher .FilterHeaders (p .id , headers , time .Now ())
471488 }
0 commit comments