Skip to content

Commit

Permalink
core: fix several bugs (bnb-chain#36)
Browse files Browse the repository at this point in the history
  • Loading branch information
NashBC authored Jan 11, 2023
1 parent ee08803 commit 6634a11
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 32 deletions.
9 changes: 7 additions & 2 deletions consensus/parlia/parlia.go
Original file line number Diff line number Diff line change
Expand Up @@ -378,7 +378,7 @@ func getVoteAttestationFromHeader(header *types.Header, chainConfig *params.Chai
return nil, nil
}
start := extraVanity + validatorNumberSizeAfterBoneh + num*validatorBytesLengthAfterBoneh
end := len(header.Extra) - extraVanity
end := len(header.Extra) - extraSeal
attestationBytes = header.Extra[start:end]
}

Expand Down Expand Up @@ -1187,6 +1187,10 @@ func (p *Parlia) VerifyVote(chain consensus.ChainHeaderReader, vote *types.VoteE
log.Warn("BlockHeader at current voteBlockNumber is nil", "targetNumber", targetNumber, "targetHash", targetHash)
return fmt.Errorf("BlockHeader at current voteBlockNumber is nil")
}
if header.Number.Uint64() != targetNumber {
log.Warn("unexpected target number", "expect", header.Number.Uint64(), "real", targetNumber)
return fmt.Errorf("target number mismatch")
}

justifiedHeader := p.GetJustifiedHeader(chain, header)
if justifiedHeader == nil {
Expand Down Expand Up @@ -1298,8 +1302,9 @@ func (p *Parlia) Seal(chain consensus.ChainHeaderReader, block *types.Block, res

err := p.assembleVoteAttestation(chain, header)
if err != nil {
/* If the vote attestation can't be assembled successfully, the blockchain won't get
fast finalized, but it can be tolerated, so just report this error here. */
log.Error("Assemble vote attestation failed when sealing", "err", err)
return
}

// Sign all the things!
Expand Down
36 changes: 20 additions & 16 deletions core/blockchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -606,25 +606,32 @@ func (bc *BlockChain) getFinalizedNumber(header *types.Header) uint64 {
return 0
}

// isFinalizedBlockHigher returns true when the new block's finalized block is higher than current block.
func (bc *BlockChain) isFinalizedBlockHigher(header *types.Header, curHeader *types.Header) bool {
// reorgNeededWithFastFinality returns true when the finalized block is higher, otherwise backoff to compare the td.
func (bc *BlockChain) reorgNeededWithFastFinality(current *types.Header, header *types.Header) (bool, error) {
p, ok := bc.engine.(consensus.PoSA)
if !ok {
return false
return bc.forker.ReorgNeeded(current, header)
}

ancestor := rawdb.FindCommonAncestor(bc.db, header, curHeader)
ancestor := rawdb.FindCommonAncestor(bc.db, current, header)
if ancestor == nil {
return false
return bc.forker.ReorgNeeded(current, header)
}

finalized := p.GetFinalizedHeader(bc, header, header.Number.Uint64()-ancestor.Number.Uint64())
curFinalized := p.GetFinalizedHeader(bc, curHeader, curHeader.Number.Uint64()-ancestor.Number.Uint64())
curFinalized := p.GetFinalizedHeader(bc, current, current.Number.Uint64()-ancestor.Number.Uint64())
if finalized == nil || curFinalized == nil {
return false
return bc.forker.ReorgNeeded(current, header)
} else if finalized.Number.Uint64() > ancestor.Number.Uint64() && curFinalized.Number.Uint64() > ancestor.Number.Uint64() {
log.Crit("find two conflict finalized headers", "header1", finalized, "header2", curFinalized)
return false, nil
} else if finalized.Number.Uint64() == curFinalized.Number.Uint64() {
return bc.forker.ReorgNeeded(current, header)
} else if finalized.Number.Uint64() > curFinalized.Number.Uint64() {
return true, nil
} else {
return false, nil
}

return finalized.Number.Uint64() > curFinalized.Number.Uint64()
}

// loadLastState loads the last known chain state from the database. This method
Expand Down Expand Up @@ -1247,7 +1254,7 @@ func (bc *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain [

// Rewind may have occurred, skip in that case.
if bc.CurrentHeader().Number.Cmp(head.Number()) >= 0 {
reorg, err := bc.forker.ReorgNeeded(bc.CurrentFastBlock().Header(), head.Header())
reorg, err := bc.reorgNeededWithFastFinality(bc.CurrentFastBlock().Header(), head.Header())
if err != nil {
log.Warn("Reorg failed", "err", err)
return false
Expand Down Expand Up @@ -1644,13 +1651,10 @@ func (bc *BlockChain) writeBlockAndSetHead(block *types.Block, receipts []*types
return NonStatTy, err
}
currentBlock := bc.CurrentBlock()
reorg, err := bc.forker.ReorgNeeded(currentBlock.Header(), block.Header())
reorg, err := bc.reorgNeededWithFastFinality(currentBlock.Header(), block.Header())
if err != nil {
return NonStatTy, err
}
if bc.isFinalizedBlockHigher(block.Header(), currentBlock.Header()) {
reorg = true
}
if reorg {
// Reorganise the chain if the parent is not the head block
if block.ParentHash() != currentBlock.Hash() {
Expand Down Expand Up @@ -1806,7 +1810,7 @@ func (bc *BlockChain) insertChain(chain types.Blocks, verifySeals, setHead bool)
current = bc.CurrentBlock()
)
for block != nil && bc.skipBlock(err, it) {
reorg, err = bc.forker.ReorgNeeded(current.Header(), block.Header())
reorg, err = bc.reorgNeededWithFastFinality(current.Header(), block.Header())
if err != nil {
return it.index, err
}
Expand Down Expand Up @@ -2186,7 +2190,7 @@ func (bc *BlockChain) insertSideChain(block *types.Block, it *insertIterator) (i
//
// If the externTd was larger than our local TD, we now need to reimport the previous
// blocks to regenerate the required state
reorg, err := bc.forker.ReorgNeeded(current.Header(), lastBlock.Header())
reorg, err := bc.reorgNeededWithFastFinality(current.Header(), lastBlock.Header())
if err != nil {
return it.index, err
}
Expand Down
29 changes: 18 additions & 11 deletions core/headerchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,25 +138,32 @@ func (hc *HeaderChain) getFinalizedNumber(header *types.Header) uint64 {
return 0
}

// isFinalizedBlockHigher returns true when the new block's finalized block is higher than current block.
func (hc *HeaderChain) isFinalizedBlockHigher(header *types.Header, curHeader *types.Header) bool {
// reorgNeededWithFastFinality returns true when the finalized block is higher, otherwise backoff to compare the td.
func (hc *HeaderChain) reorgNeededWithFastFinality(forker *ForkChoice, current *types.Header, header *types.Header) (bool, error) {
p, ok := hc.engine.(consensus.PoSA)
if !ok {
return false
return forker.ReorgNeeded(current, header)
}

ancestor := rawdb.FindCommonAncestor(hc.chainDb, header, curHeader)
ancestor := rawdb.FindCommonAncestor(hc.chainDb, current, header)
if ancestor == nil {
return false
return forker.ReorgNeeded(current, header)
}

finalized := p.GetFinalizedHeader(hc, header, header.Number.Uint64()-ancestor.Number.Uint64())
curFinalized := p.GetFinalizedHeader(hc, curHeader, curHeader.Number.Uint64()-ancestor.Number.Uint64())
curFinalized := p.GetFinalizedHeader(hc, current, current.Number.Uint64()-ancestor.Number.Uint64())
if finalized == nil || curFinalized == nil {
return false
return forker.ReorgNeeded(current, header)
} else if finalized.Number.Uint64() > ancestor.Number.Uint64() && curFinalized.Number.Uint64() > ancestor.Number.Uint64() {
log.Crit("find two conflict finalized headers", "header1", finalized, "header2", curFinalized)
return false, nil
} else if finalized.Number.Uint64() == curFinalized.Number.Uint64() {
return forker.ReorgNeeded(current, header)
} else if finalized.Number.Uint64() > curFinalized.Number.Uint64() {
return true, nil
} else {
return false, nil
}

return finalized.Number.Uint64() > curFinalized.Number.Uint64()
}

// GetBlockNumber retrieves the block number belonging to the given hash
Expand Down Expand Up @@ -332,9 +339,9 @@ func (hc *HeaderChain) writeHeadersAndSetHead(headers []*types.Header, forker *F
}
)
// Ask the fork choicer if the reorg is necessary
if reorg, err := forker.ReorgNeeded(hc.CurrentHeader(), lastHeader); err != nil {
if reorg, err := hc.reorgNeededWithFastFinality(forker, hc.CurrentHeader(), lastHeader); err != nil {
return nil, err
} else if !reorg && !hc.isFinalizedBlockHigher(lastHeader, hc.CurrentHeader()) {
} else if !reorg {
if inserted != 0 {
result.status = SideStatTy
}
Expand Down
2 changes: 1 addition & 1 deletion eth/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) {
log.Info("Create votePool successfully")

if _, err := vote.NewVoteManager(eth.EventMux(), chainConfig, eth.blockchain, votePool, voteJournalPath, blsPasswordPath, blsWalletPath, posa); err != nil {
log.Error("Failed to Initialize voteManager: %v.", err)
log.Error("Failed to Initialize voteManager", "err", err)
return nil, err
}
log.Info("Create voteManager successfully")
Expand Down
4 changes: 2 additions & 2 deletions params/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -765,12 +765,12 @@ func (c *ChainConfig) CheckConfigForkOrder() error {
{name: "mirrorSyncBlock", block: c.MirrorSyncBlock},
{name: "brunoBlock", block: c.BrunoBlock},
{name: "eulerBlock", block: c.EulerBlock},
{name: "bonehBlock", block: c.BonehBlock},
{name: "lynnBlock", block: c.LynnBlock},
{name: "berlinBlock", block: c.BerlinBlock},
{name: "londonBlock", block: c.LondonBlock},
{name: "arrowGlacierBlock", block: c.ArrowGlacierBlock, optional: true},
{name: "mergeStartBlock", block: c.MergeForkBlock, optional: true},
{name: "bonehBlock", block: c.BonehBlock},
{name: "lynnBlock", block: c.LynnBlock},
} {
if lastFork.name != "" {
// Next one must be higher number
Expand Down

0 comments on commit 6634a11

Please sign in to comment.