Skip to content

Commit

Permalink
[R4R] the miner module should propose block on a proper fork (bnb-cha…
Browse files Browse the repository at this point in the history
…in#355)

* change Canon chain condition

* resolve comment
  • Loading branch information
unclezoro authored Aug 10, 2021
1 parent 3bd4e29 commit 955c78b
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 1 deletion.
1 change: 1 addition & 0 deletions consensus/consensus.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,4 +140,5 @@ type PoSA interface {
IsSystemTransaction(tx *types.Transaction, header *types.Header) (bool, error)
IsSystemContract(to *common.Address) bool
EnoughDistance(chain ChainReader, header *types.Header) bool
IsLocalBlock(header *types.Header) bool
}
28 changes: 28 additions & 0 deletions consensus/parlia/parlia.go
Original file line number Diff line number Diff line change
Expand Up @@ -882,6 +882,34 @@ func (p *Parlia) EnoughDistance(chain consensus.ChainReader, header *types.Heade
return snap.enoughDistance(p.val, header)
}

func (p *Parlia) IsLocalBlock(header *types.Header) bool {
return p.val == header.Coinbase
}

func (p *Parlia) SignRecently(chain consensus.ChainReader, parent *types.Header) (bool, error) {
snap, err := p.snapshot(chain, parent.Number.Uint64(), parent.ParentHash, nil)
if err != nil {
return true, err
}

// Bail out if we're unauthorized to sign a block
if _, authorized := snap.Validators[p.val]; !authorized {
return true, errUnauthorizedValidator
}

// If we're amongst the recent signers, wait for the next block
number := parent.Number.Uint64() + 1
for seen, recent := range snap.Recents {
if recent == p.val {
// Signer is among recents, only wait if the current block doesn't shift it out
if limit := uint64(len(snap.Validators)/2 + 1); number < limit || seen > number-limit {
return true, nil
}
}
}
return false, nil
}

// CalcDifficulty is the difficulty adjustment algorithm. It returns the difficulty
// that a new block should have based on the previous blocks in the chain and the
// current signer.
Expand Down
4 changes: 3 additions & 1 deletion core/blockchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -1581,7 +1581,9 @@ func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types.
if !reorg && externTd.Cmp(localTd) == 0 {
// Split same-difficulty blocks by number, then preferentially select
// the block generated by the local miner as the canonical block.
if block.NumberU64() < currentBlock.NumberU64() {
if block.NumberU64() < currentBlock.NumberU64() || block.Time() < currentBlock.Time() {
reorg = true
} else if p, ok := bc.engine.(consensus.PoSA); ok && p.IsLocalBlock(currentBlock.Header()) {
reorg = true
} else if block.NumberU64() == currentBlock.NumberU64() {
var currentPreserve, blockPreserve bool
Expand Down
11 changes: 11 additions & 0 deletions miner/worker.go
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,17 @@ func (w *worker) newWorkLoop(recommit time.Duration) {
}
clearPending(head.Block.NumberU64())
timestamp = time.Now().Unix()
if p, ok := w.engine.(*parlia.Parlia); ok {
signedRecent, err := p.SignRecently(w.chain, head.Block.Header())
if err != nil {
log.Info("Not allowed to propose block", "err", err)
continue
}
if signedRecent {
log.Info("Signed recently, must wait")
continue
}
}
commit(true, commitInterruptNewHead)

case <-timer.C:
Expand Down

0 comments on commit 955c78b

Please sign in to comment.