forked from cerc-io/plugeth
core: during split properly insert parent blocks
During a split parent and grand parent were included in the database but not in the canonical chain (numbered chain). Added a `merge` function which finds the common ancestor of the chains and reinserts the missing blocks.
This commit is contained in:
parent
4f3c169b4e
commit
333d4e0f27
@ -490,8 +490,8 @@ func (self *ChainManager) InsertChain(chain types.Blocks) error {
|
|||||||
block.Td = td
|
block.Td = td
|
||||||
|
|
||||||
self.mu.Lock()
|
self.mu.Lock()
|
||||||
cblock := self.currentBlock
|
|
||||||
{
|
{
|
||||||
|
cblock := self.currentBlock
|
||||||
// Write block to database. Eventually we'll have to improve on this and throw away blocks that are
|
// Write block to database. Eventually we'll have to improve on this and throw away blocks that are
|
||||||
// not in the canonical chain.
|
// not in the canonical chain.
|
||||||
self.write(block)
|
self.write(block)
|
||||||
@ -505,6 +505,8 @@ func (self *ChainManager) InsertChain(chain types.Blocks) error {
|
|||||||
if glog.V(logger.Info) {
|
if glog.V(logger.Info) {
|
||||||
glog.Infof("Split detected. New head #%v (%x) TD=%v, was #%v (%x) TD=%v\n", block.Header().Number, hash[:4], td, cblock.Header().Number, chash[:4], self.td)
|
glog.Infof("Split detected. New head #%v (%x) TD=%v, was #%v (%x) TD=%v\n", block.Header().Number, hash[:4], td, cblock.Header().Number, chash[:4], self.td)
|
||||||
}
|
}
|
||||||
|
// during split we merge two different chains and create the new canonical chain
|
||||||
|
self.merge(cblock, block)
|
||||||
|
|
||||||
queue[i] = ChainSplitEvent{block, logs}
|
queue[i] = ChainSplitEvent{block, logs}
|
||||||
queueEvent.splitCount++
|
queueEvent.splitCount++
|
||||||
@ -553,6 +555,35 @@ func (self *ChainManager) InsertChain(chain types.Blocks) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// merge takes two blocks, an old chain and a new chain and will reconstruct the blocks and inserts them
|
||||||
|
// to be part of the new canonical chain.
|
||||||
|
func (self *ChainManager) merge(oldBlock, newBlock *types.Block) {
|
||||||
|
glog.V(logger.Debug).Infof("Applying diff to %x & %x\n", oldBlock.Hash().Bytes()[:4], newBlock.Hash().Bytes()[:4])
|
||||||
|
|
||||||
|
var oldChain, newChain types.Blocks
|
||||||
|
// First find the split (common ancestor) so we can perform an adequate merge
|
||||||
|
for {
|
||||||
|
oldBlock, newBlock = self.GetBlock(oldBlock.ParentHash()), self.GetBlock(newBlock.ParentHash())
|
||||||
|
if oldBlock.Hash() == newBlock.Hash() {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
oldChain = append(oldChain, oldBlock)
|
||||||
|
newChain = append(newChain, newBlock)
|
||||||
|
}
|
||||||
|
|
||||||
|
// insert blocks
|
||||||
|
for _, block := range newChain {
|
||||||
|
self.insert(block)
|
||||||
|
}
|
||||||
|
|
||||||
|
if glog.V(logger.Detail) {
|
||||||
|
for i, oldBlock := range oldChain {
|
||||||
|
glog.Infof("- %.10v = %x\n", oldBlock.Number(), oldBlock.Hash())
|
||||||
|
glog.Infof("+ %.10v = %x\n", newChain[i].Number(), newChain[i].Hash())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (self *ChainManager) update() {
|
func (self *ChainManager) update() {
|
||||||
events := self.eventMux.Subscribe(queueEvent{})
|
events := self.eventMux.Subscribe(queueEvent{})
|
||||||
futureTimer := time.NewTicker(5 * time.Second)
|
futureTimer := time.NewTicker(5 * time.Second)
|
||||||
|
Loading…
Reference in New Issue
Block a user