@@ -74,8 +74,9 @@ type ChainManager struct {
74
74
eventMux * event.TypeMux
75
75
genesisBlock * types.Block
76
76
// Last known total difficulty
77
- mu sync.RWMutex
78
- tsmu sync.RWMutex
77
+ mu sync.RWMutex
78
+ tsmu sync.RWMutex
79
+
79
80
td * big.Int
80
81
currentBlock * types.Block
81
82
lastBlockHash common.Hash
@@ -92,15 +93,14 @@ type ChainManager struct {
92
93
93
94
func NewChainManager (blockDb , stateDb common.Database , mux * event.TypeMux ) * ChainManager {
94
95
bc := & ChainManager {
95
- blockDb : blockDb ,
96
- stateDb : stateDb ,
97
- genesisBlock : GenesisBlock (stateDb ),
98
- eventMux : mux ,
99
- quit : make (chan struct {}),
100
- cache : NewBlockCache (blockCacheLimit ),
101
- currentGasLimit : new (big.Int ),
96
+ blockDb : blockDb ,
97
+ stateDb : stateDb ,
98
+ genesisBlock : GenesisBlock (stateDb ),
99
+ eventMux : mux ,
100
+ quit : make (chan struct {}),
101
+ cache : NewBlockCache (blockCacheLimit ),
102
102
}
103
- bc .setLastBlock ()
103
+ bc .setLastState ()
104
104
105
105
// Check the current state of the block hashes and make sure that we do not have any of the bad blocks in our chain
106
106
for _ , hash := range badHashes {
@@ -145,7 +145,7 @@ func (bc *ChainManager) SetHead(head *types.Block) {
145
145
bc .transState = statedb .Copy ()
146
146
bc .setTotalDifficulty (head .Td )
147
147
bc .insert (head )
148
- bc .setLastBlock ()
148
+ bc .setLastState ()
149
149
}
150
150
151
151
func (self * ChainManager ) Td () * big.Int {
@@ -212,7 +212,7 @@ func (self *ChainManager) setTransState(statedb *state.StateDB) {
212
212
self .transState = statedb
213
213
}
214
214
215
- func (bc * ChainManager ) setLastBlock () {
215
+ func (bc * ChainManager ) setLastState () {
216
216
data , _ := bc .blockDb .Get ([]byte ("LastBlock" ))
217
217
if len (data ) != 0 {
218
218
block := bc .GetBlock (common .BytesToHash (data ))
@@ -224,6 +224,7 @@ func (bc *ChainManager) setLastBlock() {
224
224
} else {
225
225
bc .Reset ()
226
226
}
227
+ bc .currentGasLimit = CalcGasLimit (bc .currentBlock )
227
228
228
229
if glog .V (logger .Info ) {
229
230
glog .Infof ("Last block (#%v) %x TD=%v\n " , bc .currentBlock .Number (), bc .currentBlock .Hash (), bc .td )
@@ -319,6 +320,7 @@ func (bc *ChainManager) ResetWithGenesisBlock(gb *types.Block) {
319
320
bc .insert (bc .genesisBlock )
320
321
bc .currentBlock = bc .genesisBlock
321
322
bc .makeCache ()
323
+ bc .td = gb .Difficulty ()
322
324
}
323
325
324
326
// Export writes the active chain to the given writer.
@@ -346,8 +348,6 @@ func (self *ChainManager) Export(w io.Writer) error {
346
348
func (bc * ChainManager ) insert (block * types.Block ) {
347
349
key := append (blockNumPre , block .Number ().Bytes ()... )
348
350
bc .blockDb .Put (key , block .Hash ().Bytes ())
349
- // Push block to cache
350
- bc .cache .Push (block )
351
351
352
352
bc .blockDb .Put ([]byte ("LastBlock" ), block .Hash ().Bytes ())
353
353
bc .currentBlock = block
@@ -358,6 +358,8 @@ func (bc *ChainManager) write(block *types.Block) {
358
358
enc , _ := rlp .EncodeToBytes ((* types .StorageBlock )(block ))
359
359
key := append (blockHashPre , block .Hash ().Bytes ()... )
360
360
bc .blockDb .Put (key , enc )
361
+ // Push block to cache
362
+ bc .cache .Push (block )
361
363
}
362
364
363
365
// Accessors
@@ -552,16 +554,17 @@ func (self *ChainManager) InsertChain(chain types.Blocks) error {
552
554
// Compare the TD of the last known block in the canonical chain to make sure it's greater.
553
555
// At this point it's possible that a different chain (fork) becomes the new canonical chain.
554
556
if block .Td .Cmp (self .td ) > 0 {
555
- //if block.Header().Number.Cmp(new(big.Int).Add(cblock.Header().Number, common.Big1)) < 0 {
556
- if block .Number (). Cmp ( cblock . Number ()) <= 0 {
557
+ // Check for chain forks. If H(block.num - 1) != block.parent, we're on a fork and need to do some merging
558
+ if previous := self . getBlockByNumber ( block .NumberU64 () - 1 ); previous . Hash () != block . ParentHash () {
557
559
chash := cblock .Hash ()
558
560
hash := block .Hash ()
559
561
560
562
if glog .V (logger .Info ) {
561
563
glog .Infof ("Split detected. New head #%v (%x) TD=%v, was #%v (%x) TD=%v\n " , block .Header ().Number , hash [:4 ], block .Td , cblock .Header ().Number , chash [:4 ], self .td )
562
564
}
565
+
563
566
// during split we merge two different chains and create the new canonical chain
564
- self .merge (self . getBlockByNumber ( block . NumberU64 ()) , block )
567
+ self .merge (previous , block )
565
568
566
569
queue [i ] = ChainSplitEvent {block , logs }
567
570
queueEvent .splitCount ++
@@ -587,16 +590,19 @@ func (self *ChainManager) InsertChain(chain types.Blocks) error {
587
590
glog .Infof ("inserted block #%d (%d TXs %d UNCs) (%x...)\n " , block .Number (), len (block .Transactions ()), len (block .Uncles ()), block .Hash ().Bytes ()[0 :4 ])
588
591
}
589
592
} else {
593
+ if glog .V (logger .Detail ) {
594
+ glog .Infof ("inserted forked block #%d (%d TXs %d UNCs) (%x...)\n " , block .Number (), len (block .Transactions ()), len (block .Uncles ()), block .Hash ().Bytes ()[0 :4 ])
595
+ }
596
+
590
597
queue [i ] = ChainSideEvent {block , logs }
591
598
queueEvent .sideCount ++
592
599
}
600
+ self .futureBlocks .Delete (block .Hash ())
593
601
}
594
602
self .mu .Unlock ()
595
603
596
604
stats .processed ++
597
605
598
- self .futureBlocks .Delete (block .Hash ())
599
-
600
606
}
601
607
602
608
if (stats .queued > 0 || stats .processed > 0 ) && bool (glog .V (logger .Info )) {
@@ -610,33 +616,38 @@ func (self *ChainManager) InsertChain(chain types.Blocks) error {
610
616
return nil
611
617
}
612
618
613
- // merge takes two blocks, an old chain and a new chain and will reconstruct the blocks and inserts them
619
+ // diff takes two blocks, an old chain and a new chain and will reconstruct the blocks and inserts them
614
620
// to be part of the new canonical chain.
615
- func (self * ChainManager ) merge (oldBlock , newBlock * types.Block ) {
621
+ func (self * ChainManager ) diff (oldBlock , newBlock * types.Block ) types. Blocks {
616
622
glog .V (logger .Debug ).Infof ("Applying diff to %x & %x\n " , oldBlock .Hash ().Bytes ()[:4 ], newBlock .Hash ().Bytes ()[:4 ])
617
623
618
- var oldChain , newChain types.Blocks
619
- // First find the split (common ancestor) so we can perform an adequate merge
624
+ var newChain types.Blocks
625
+ // first find common number
626
+ for newBlock = newBlock ; newBlock .NumberU64 () != oldBlock .NumberU64 (); newBlock = self .GetBlock (newBlock .ParentHash ()) {
627
+ newChain = append (newChain , newBlock )
628
+ }
629
+
630
+ glog .V (logger .Debug ).Infoln ("Found common number" , newBlock .Number ())
620
631
for {
621
- oldBlock , newBlock = self .GetBlock (oldBlock .ParentHash ()), self .GetBlock (newBlock .ParentHash ())
622
632
if oldBlock .Hash () == newBlock .Hash () {
623
633
break
624
634
}
625
- oldChain = append (oldChain , oldBlock )
626
635
newChain = append (newChain , newBlock )
636
+
637
+ oldBlock , newBlock = self .GetBlock (oldBlock .ParentHash ()), self .GetBlock (newBlock .ParentHash ())
627
638
}
628
639
640
+ return newChain
641
+ }
642
+
643
+ // merge merges two different chain to the new canonical chain
644
+ func (self * ChainManager ) merge (oldBlock , newBlock * types.Block ) {
645
+ newChain := self .diff (oldBlock , newBlock )
646
+
629
647
// insert blocks
630
648
for _ , block := range newChain {
631
649
self .insert (block )
632
650
}
633
-
634
- if glog .V (logger .Detail ) {
635
- for i , oldBlock := range oldChain {
636
- glog .Infof ("- %.10v = %x\n " , oldBlock .Number (), oldBlock .Hash ())
637
- glog .Infof ("+ %.10v = %x\n " , newChain [i ].Number (), newChain [i ].Hash ())
638
- }
639
- }
640
651
}
641
652
642
653
func (self * ChainManager ) update () {
0 commit comments