mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-27 23:26:44 +00:00
fix: Check block delay in verifyHeaders / remove empty chainId check (MAT-1080, MAT-1089) (#49)
* fix: Check block delay in verifyHeaders * Pull block time check out of if condition * fix: Always check chainId equality in heimdall response
This commit is contained in:
parent
710fb49226
commit
d8c07f302a
4 changed files with 27 additions and 12 deletions
|
|
@ -205,13 +205,13 @@ func CalcDifficulty(snap *Snapshot, signer common.Address, epoch uint64) *big.In
|
|||
return big.NewInt(0).SetUint64(snap.inturn(snap.Number+1, signer, epoch))
|
||||
}
|
||||
|
||||
// CalcProducerDelay is the producer delay algorithm based on block time.
|
||||
func CalcProducerDelay(snap *Snapshot, signer common.Address, period uint64, epoch uint64, producerDelay uint64) uint64 {
|
||||
// if block is epoch start block, proposer will be inturn signer
|
||||
if (snap.Number+1)%epoch == 0 {
|
||||
// CalcProducerDelay is the block delay algorithm based on block time and period / producerDelay values in genesis
|
||||
func CalcProducerDelay(number uint64, period uint64, sprint uint64, producerDelay uint64) uint64 {
|
||||
// When the block is the first block of the sprint, it is expected to be delayed by `producerDelay`.
|
||||
// That is to allow time for block propagation in the last sprint
|
||||
if number%sprint == 0 {
|
||||
return producerDelay
|
||||
}
|
||||
|
||||
return period
|
||||
}
|
||||
|
||||
|
|
@ -331,6 +331,17 @@ func (c *Bor) verifyHeader(chain consensus.ChainReader, header *types.Header, pa
|
|||
}
|
||||
number := header.Number.Uint64()
|
||||
|
||||
var parent *types.Header
|
||||
if len(parents) > 0 { // if parents is nil, len(parents) is zero
|
||||
parent = parents[len(parents)-1]
|
||||
} else if number > 0 {
|
||||
parent = chain.GetHeader(header.ParentHash, number-1)
|
||||
}
|
||||
|
||||
if parent != nil && header.Time < parent.Time+CalcProducerDelay(number, c.config.Period, c.config.Sprint, c.config.ProducerDelay) {
|
||||
return consensus.ErrBlockTooSoon
|
||||
}
|
||||
|
||||
// Don't waste time checking blocks from the future
|
||||
if header.Time > uint64(time.Now().Unix()) {
|
||||
return consensus.ErrFutureBlock
|
||||
|
|
@ -654,7 +665,7 @@ func (c *Bor) Prepare(chain consensus.ChainReader, header *types.Header) error {
|
|||
return consensus.ErrUnknownAncestor
|
||||
}
|
||||
|
||||
header.Time = parent.Time + CalcProducerDelay(snap, c.signer, c.config.Period, c.config.Sprint, c.config.ProducerDelay)
|
||||
header.Time = parent.Time + CalcProducerDelay(number, c.config.Period, c.config.Sprint, c.config.ProducerDelay)
|
||||
if header.Time < uint64(time.Now().Unix()) {
|
||||
header.Time = uint64(time.Now().Unix())
|
||||
}
|
||||
|
|
@ -1190,7 +1201,7 @@ func (c *Bor) CommitStates(
|
|||
}
|
||||
|
||||
// check if chain id matches with event record
|
||||
if eventRecord.ChainID != "" && eventRecord.ChainID != c.chainConfig.ChainID.String() {
|
||||
if eventRecord.ChainID != c.chainConfig.ChainID.String() {
|
||||
return fmt.Errorf(
|
||||
"Chain id proposed state in span, %s, and bor chain id, %s, doesn't match",
|
||||
eventRecord.ChainID,
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ func TestCommitSpan(t *testing.T) {
|
|||
db := init.ethereum.ChainDb()
|
||||
block := init.genesis.ToBlock(db)
|
||||
// Build 1st block's header
|
||||
header := buildMinimalNextHeader(t, block, init.genesis.Config.Bor.Period)
|
||||
header := buildMinimalNextHeader(t, block, init.genesis.Config.Bor)
|
||||
|
||||
statedb, err := chain.State()
|
||||
if err != nil {
|
||||
|
|
@ -89,7 +89,7 @@ func TestIsValidatorAction(t *testing.T) {
|
|||
db := init.ethereum.ChainDb()
|
||||
block := init.genesis.ToBlock(db)
|
||||
|
||||
header := buildMinimalNextHeader(t, block, init.genesis.Config.Bor.Period)
|
||||
header := buildMinimalNextHeader(t, block, init.genesis.Config.Bor)
|
||||
statedb, err := chain.State()
|
||||
if err != nil {
|
||||
t.Fatalf("%s", err)
|
||||
|
|
@ -101,7 +101,7 @@ func TestIsValidatorAction(t *testing.T) {
|
|||
|
||||
var headers []*types.Header
|
||||
for i := int64(2); i <= 255; i++ {
|
||||
header := buildMinimalNextHeader(t, block, init.genesis.Config.Bor.Period)
|
||||
header := buildMinimalNextHeader(t, block, init.genesis.Config.Bor)
|
||||
headers = append(headers, header)
|
||||
block = types.NewBlockWithHeader(header)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ import (
|
|||
"github.com/maticnetwork/bor/eth"
|
||||
"github.com/maticnetwork/bor/ethdb"
|
||||
"github.com/maticnetwork/bor/node"
|
||||
"github.com/maticnetwork/bor/params"
|
||||
)
|
||||
|
||||
var (
|
||||
|
|
@ -99,11 +100,11 @@ func insertNewBlock(t *testing.T, _bor *bor.Bor, chain *core.BlockChain, header
|
|||
}
|
||||
}
|
||||
|
||||
func buildMinimalNextHeader(t *testing.T, block *types.Block, period uint64) *types.Header {
|
||||
func buildMinimalNextHeader(t *testing.T, block *types.Block, borConfig *params.BorConfig) *types.Header {
|
||||
header := block.Header()
|
||||
header.Number.Add(header.Number, big.NewInt(1))
|
||||
header.ParentHash = block.Hash()
|
||||
header.Time += (period + 1)
|
||||
header.Time += bor.CalcProducerDelay(header.Number.Uint64(), borConfig.Period, borConfig.Sprint, borConfig.ProducerDelay)
|
||||
header.Extra = make([]byte, 97) // vanity (32) + extraSeal (65)
|
||||
_key, _ := hex.DecodeString(privKey)
|
||||
sig, err := secp256k1.Sign(crypto.Keccak256(bor.BorRLP(header)), _key)
|
||||
|
|
|
|||
|
|
@ -31,6 +31,9 @@ var (
|
|||
// to the current node.
|
||||
ErrFutureBlock = errors.New("block in the future")
|
||||
|
||||
// ErrBlockTooSoon is returned when the period / producerDelay values in the genesis were not respected
|
||||
ErrBlockTooSoon = errors.New("block was produced sooner than expected")
|
||||
|
||||
// ErrInvalidNumber is returned if a block's number doesn't equal it's parent's
|
||||
// plus one.
|
||||
ErrInvalidNumber = errors.New("invalid block number")
|
||||
|
|
|
|||
Loading…
Reference in a new issue