mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-02 10:03:45 +00:00
new: Add wiggle to block time
This commit is contained in:
parent
4f850edec2
commit
c27b8b7801
7 changed files with 51 additions and 27 deletions
|
|
@ -111,6 +111,7 @@ func (w *wizard) makeGenesis() {
|
|||
Period: 1,
|
||||
ProducerDelay: 5,
|
||||
Sprint: 60,
|
||||
BackupMultiplier: 1,
|
||||
ValidatorContract: "0x0000000000000000000000000000000000001000",
|
||||
StateReceiverContract: "0x0000000000000000000000000000000000001001",
|
||||
}
|
||||
|
|
|
|||
|
|
@ -207,14 +207,18 @@ func CalcDifficulty(snap *Snapshot, signer common.Address, sprint uint64) *big.I
|
|||
return big.NewInt(0).SetUint64(snap.inturn(snap.Number+1, signer, sprint))
|
||||
}
|
||||
|
||||
// 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 {
|
||||
// CalcProducerDelay is the block delay algorithm based on block time, period, producerDelay and turn-ness of a signer
|
||||
func CalcProducerDelay(number uint64, succession int, c *params.BorConfig) 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
|
||||
delay := c.Period
|
||||
if number%c.Sprint == 0 {
|
||||
delay = c.ProducerDelay
|
||||
}
|
||||
return period
|
||||
if succession > 0 {
|
||||
delay += uint64(succession) * c.BackupMultiplier
|
||||
}
|
||||
return delay
|
||||
}
|
||||
|
||||
// BorRLP returns the rlp bytes which needs to be signed for the bor
|
||||
|
|
@ -334,17 +338,6 @@ 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
|
||||
|
|
@ -590,10 +583,22 @@ func (c *Bor) verifySeal(chain consensus.ChainReader, header *types.Header, pare
|
|||
return errUnauthorizedSigner
|
||||
}
|
||||
|
||||
if _, err = snap.GetSignerSuccessionNumber(signer); err != nil {
|
||||
succession, err := snap.GetSignerSuccessionNumber(signer)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
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, succession, c.config) {
|
||||
return &BlockTooSoonError{number, succession}
|
||||
}
|
||||
|
||||
// Ensure that the difficulty corresponds to the turn-ness of the signer
|
||||
if !c.fakeDiff {
|
||||
difficulty := snap.inturn(header.Number.Uint64(), signer, c.config.Sprint)
|
||||
|
|
@ -654,7 +659,11 @@ func (c *Bor) Prepare(chain consensus.ChainReader, header *types.Header) error {
|
|||
return consensus.ErrUnknownAncestor
|
||||
}
|
||||
|
||||
header.Time = parent.Time + CalcProducerDelay(number, c.config.Period, c.config.Sprint, c.config.ProducerDelay)
|
||||
succession, err := snap.GetSignerSuccessionNumber(c.signer)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
header.Time = parent.Time + CalcProducerDelay(number, succession, c.config)
|
||||
if header.Time < uint64(time.Now().Unix()) {
|
||||
header.Time = uint64(time.Now().Unix())
|
||||
}
|
||||
|
|
@ -765,8 +774,8 @@ func (c *Bor) Seal(chain consensus.ChainReader, block *types.Block, results chan
|
|||
|
||||
// Sweet, the protocol permits us to sign the block, wait for our time
|
||||
delay := time.Unix(int64(header.Time), 0).Sub(time.Now()) // nolint: gosimple
|
||||
wiggle := time.Duration(2*c.config.Period) * time.Second * time.Duration(successionNumber)
|
||||
delay += wiggle
|
||||
// wiggle was already accounted for in header.Time, this is just for logging
|
||||
wiggle := time.Duration(successionNumber) * time.Duration(c.config.BackupMultiplier) * time.Second
|
||||
|
||||
// Sign all the things!
|
||||
sighash, err := signFn(accounts.Account{Address: signer}, accounts.MimetypeBor, BorRLP(header))
|
||||
|
|
|
|||
|
|
@ -24,11 +24,7 @@ func TestCommitSpan(t *testing.T) {
|
|||
// Mock HeimdallClient.FetchWithRetry to return span data from span.json
|
||||
res, heimdallSpan := loadSpanFromFile(t)
|
||||
h := &mocks.IHeimdallClient{}
|
||||
// FetchWithRetry is invoked 3 times
|
||||
// 1. bor.FinalizeAndAssemble to prepare a new block when calling insertNewBlock
|
||||
// 2. bor.Finalize via(bc.insertChain => bc.processor.Process)
|
||||
// 3. bor.FinalizeAndAssemble via worker.commit
|
||||
h.On("FetchWithRetry", "bor", "span", "1").Return(res, nil).Times(3)
|
||||
h.On("FetchWithRetry", "bor", "span", "1").Return(res, nil)
|
||||
_bor.SetHeimdallClient(h)
|
||||
|
||||
db := init.ethereum.ChainDb()
|
||||
|
|
@ -45,7 +41,10 @@ func TestCommitSpan(t *testing.T) {
|
|||
block = insertNewBlock(t, _bor, chain, header, statedb, _key)
|
||||
}
|
||||
|
||||
assert.True(t, h.AssertNumberOfCalls(t, "FetchWithRetry", 3))
|
||||
// FetchWithRetry is invoked 2 times
|
||||
// 1. bor.FinalizeAndAssemble to prepare a new block when calling insertNewBlock
|
||||
// 2. bor.Finalize via(bc.insertChain => bc.processor.Process)
|
||||
assert.True(t, h.AssertNumberOfCalls(t, "FetchWithRetry", 2))
|
||||
validators, err := _bor.GetCurrentValidators(sprintSize, 256) // new span starts at 256
|
||||
if err != nil {
|
||||
t.Fatalf("%s", err)
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
"bor": {
|
||||
"period": 1,
|
||||
"producerDelay": 4,
|
||||
"backupMultiplier": 1,
|
||||
"sprint": 4,
|
||||
"validatorContract": "0x0000000000000000000000000000000000001000",
|
||||
"stateReceiverContract": "0x0000000000000000000000000000000000001001"
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@ func buildMinimalNextHeader(t *testing.T, block *types.Block, borConfig *params.
|
|||
header := block.Header()
|
||||
header.Number.Add(header.Number, big.NewInt(1))
|
||||
header.ParentHash = block.Hash()
|
||||
header.Time += bor.CalcProducerDelay(header.Number.Uint64(), borConfig.Period, borConfig.Sprint, borConfig.ProducerDelay)
|
||||
header.Time += bor.CalcProducerDelay(header.Number.Uint64(), 0, borConfig)
|
||||
header.Extra = make([]byte, 32+65) // vanity + extraSeal
|
||||
|
||||
currentValidators := []*bor.Validator{bor.NewValidator(addr, 10)}
|
||||
|
|
|
|||
|
|
@ -96,3 +96,16 @@ func (e *MismatchingValidatorsError) Error() string {
|
|||
e.ValidatorSetHeader,
|
||||
)
|
||||
}
|
||||
|
||||
type BlockTooSoonError struct {
|
||||
Number uint64
|
||||
Succession int
|
||||
}
|
||||
|
||||
func (e *BlockTooSoonError) Error() string {
|
||||
return fmt.Sprintf(
|
||||
"Block %d was created too soon. Signer turn-ness number is %d\n",
|
||||
e.Number,
|
||||
e.Succession,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -319,6 +319,7 @@ type BorConfig struct {
|
|||
Period uint64 `json:"period"` // Number of seconds between blocks to enforce
|
||||
ProducerDelay uint64 `json:"producerDelay"` // Number of seconds delay between two producer interval
|
||||
Sprint uint64 `json:"sprint"` // Epoch length to proposer
|
||||
BackupMultiplier uint64 `json:"backupMultiplier"` // Backup multiplier to determine the wiggle time
|
||||
ValidatorContract string `json:"validatorContract"` // Validator set contract
|
||||
StateReceiverContract string `json:"stateReceiverContract"` // State receiver contract
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue