@@ -88,6 +88,8 @@ type ProtocolManager struct {
88
88
txsSub event.Subscription
89
89
minedBlockSub * event.TypeMuxSubscription
90
90
91
+ whitelist map [uint64 ]common.Hash
92
+
91
93
// channels for fetcher, syncer, txsyncLoop
92
94
newPeerCh chan * peer
93
95
txsyncCh chan * txsync
@@ -101,7 +103,7 @@ type ProtocolManager struct {
101
103
102
104
// NewProtocolManager returns a new Ethereum sub protocol manager. The Ethereum sub protocol manages peers capable
103
105
// 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 ) {
105
107
// Create the protocol manager with the base fields
106
108
manager := & ProtocolManager {
107
109
networkID : networkID ,
@@ -110,6 +112,7 @@ func NewProtocolManager(config *params.ChainConfig, mode downloader.SyncMode, ne
110
112
blockchain : blockchain ,
111
113
chainconfig : config ,
112
114
peers : newPeerSet (),
115
+ whitelist : whitelist ,
113
116
newPeerCh : make (chan * peer ),
114
117
noMorePeers : make (chan struct {}),
115
118
txsyncCh : make (chan * txsync ),
@@ -307,7 +310,13 @@ func (pm *ProtocolManager) handle(p *peer) error {
307
310
}
308
311
}()
309
312
}
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
311
320
for {
312
321
if err := pm .handleMsg (p ); err != nil {
313
322
p .Log ().Debug ("Ethereum message handling failed" , "err" , err )
@@ -466,6 +475,14 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
466
475
p .Log ().Debug ("Verified to be on the same side of the DAO fork" )
467
476
return nil
468
477
}
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
+ }
469
486
// Irrelevant of the fork checks, send the header to the fetcher just in case
470
487
headers = pm .fetcher .FilterHeaders (p .id , headers , time .Now ())
471
488
}
0 commit comments