borheimdall: add tests for validator set and selected proposers validation (#9089)

Adds unit tests for:
- Bor Heimdall Stage - `checkHeaderExtraData`
- at end of each sprint verifies that the validators in the header extra
data matches the selected proposers from the heimdall span
   - 1 test for selected proposers length mismatch
   - 1 test for selected proposers bytes mismatch
- BorHeimdall Stage - `persistValidatorSets`
- verifies that each header is created by a validator in the validator
set
   - in such situation we set the unwind point
This commit is contained in:
milen 2023-12-28 14:00:09 +00:00 committed by GitHub
parent ab27531fa7
commit 67704871c0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 270 additions and 83 deletions

View File

@ -26,7 +26,6 @@ import (
libcommon "github.com/ledgerwatch/erigon-lib/common"
"github.com/ledgerwatch/erigon-lib/common/length"
"github.com/ledgerwatch/erigon-lib/kv"
"github.com/ledgerwatch/erigon/common"
"github.com/ledgerwatch/erigon/consensus"
"github.com/ledgerwatch/erigon/consensus/bor/finality"
@ -112,7 +111,7 @@ var (
// errInvalidSpanValidators is returned if a block contains an
// invalid list of validators (i.e. non divisible by 40 bytes).
ErrInvalidSpanValidators = errors.New("invalid validator list on sprint end block")
errInvalidSpanValidators = errors.New("invalid validator list on sprint end block")
// errInvalidMixDigest is returned if a block's mix digest is non-zero.
errInvalidMixDigest = errors.New("non-zero mix digest")
@ -543,7 +542,7 @@ func (c *Bor) verifyHeader(chain consensus.ChainHeaderReader, header *types.Head
}
if isSprintEnd && signersBytes%validatorHeaderBytesLength != 0 {
return ErrInvalidSpanValidators
return errInvalidSpanValidators
}
// Ensure that the mix digest is zero as we don't have fork protection currently

View File

@ -5,6 +5,7 @@ import (
"context"
"encoding/binary"
"encoding/json"
"errors"
"fmt"
"math/big"
"sort"
@ -45,6 +46,11 @@ const (
extraSeal = 65 // Fixed number of extra-data suffix bytes reserved for signer seal
)
var (
ErrHeaderValidatorsLengthMismatch = errors.New("header validators length mismatch")
ErrHeaderValidatorsBytesMismatch = errors.New("header validators bytes mismatch")
)
type BorHeimdallCfg struct {
db kv.RwDB
snapDb kv.RwDB // Database to store and retrieve snapshot checkpoints
@ -280,6 +286,14 @@ func BorHeimdallForward(
return fmt.Errorf("verification failed for header %d: %x", blockNum, header.Hash())
}
}
sprintLength := cfg.chainConfig.Bor.CalculateSprint(blockNum)
spanID := bor.SpanIDAt(blockNum)
if (spanID > 0) && ((blockNum+1)%sprintLength == 0) {
if err = checkHeaderExtraData(u, ctx, chain, blockNum, header, cfg.chainConfig.Bor); err != nil {
return err
}
}
}
if blockNum > 0 && blockNum%cfg.chainConfig.Bor.CalculateSprint(blockNum) == 0 {
@ -312,16 +326,6 @@ func BorHeimdallForward(
return fmt.Errorf("can't persist validator sets: %w", err)
}
}
if !mine {
sprintLength := cfg.chainConfig.Bor.CalculateSprint(blockNum)
spanID := bor.SpanIDAt(blockNum)
if (spanID > 0) && ((blockNum+1)%sprintLength == 0) {
if err = checkHeaderExtraData(u, ctx, chain, blockNum, header, cfg.chainConfig.Bor); err != nil {
return err
}
}
}
}
if cfg.loopBreakCheck != nil && cfg.loopBreakCheck(int(blockNum-lastBlockNum)) {
@ -372,12 +376,12 @@ func checkHeaderExtraData(
}
if len(producerSet) != len(headerVals) {
return bor.ErrInvalidSpanValidators
return ErrHeaderValidatorsLengthMismatch
}
for i, val := range producerSet {
if !bytes.Equal(val.HeaderBytes(), headerVals[i].HeaderBytes()) {
return bor.ErrInvalidSpanValidators
return ErrHeaderValidatorsBytesMismatch
}
}
return nil

View File

@ -1,26 +1,35 @@
package stagedsync_test
import (
"bytes"
"context"
"errors"
"math/big"
"testing"
"time"
"github.com/ledgerwatch/log/v3"
"github.com/stretchr/testify/require"
"github.com/ledgerwatch/erigon/consensus/bor"
"github.com/ledgerwatch/erigon/consensus/bor/valset"
"github.com/ledgerwatch/erigon/core"
"github.com/ledgerwatch/erigon/core/types"
"github.com/ledgerwatch/erigon/crypto"
"github.com/ledgerwatch/erigon/eth/stagedsync"
"github.com/ledgerwatch/erigon/eth/stagedsync/stagedsynctest"
"github.com/ledgerwatch/erigon/eth/stagedsync/stages"
"github.com/ledgerwatch/erigon/eth/stagedsync/test"
"github.com/ledgerwatch/erigon/turbo/testlog"
)
func TestBorHeimdallForwardPersistsSpans(t *testing.T) {
t.Parallel()
ctx := context.Background()
logger := testlog.Logger(t, log.LvlInfo)
numBlocks := 6640
testHarness := test.InitHarness(ctx, t, logger, test.HarnessCfg{
ChainConfig: test.BorDevnetChainConfigWithNoBlockSealDelays(),
testHarness := stagedsynctest.InitHarness(ctx, t, stagedsynctest.HarnessCfg{
ChainConfig: stagedsynctest.BorDevnetChainConfigWithNoBlockSealDelays(),
GenerateChainNumBlocks: numBlocks,
LogLvl: log.LvlInfo,
})
// pretend-update previous stage progress
testHarness.SaveStageProgress(ctx, t, stages.Headers, uint64(numBlocks))
@ -29,7 +38,7 @@ func TestBorHeimdallForwardPersistsSpans(t *testing.T) {
testHarness.RunStageForward(t, stages.BorHeimdall)
// asserts
spans, err := testHarness.ReadSpansFromDb(ctx)
spans, err := testHarness.ReadSpansFromDB(ctx)
require.NoError(t, err)
require.Len(t, spans, 3)
require.Equal(t, uint64(0), spans[0].ID)
@ -47,11 +56,11 @@ func TestBorHeimdallForwardPersistsStateSyncEvents(t *testing.T) {
t.Parallel()
ctx := context.Background()
logger := testlog.Logger(t, log.LvlInfo)
numBlocks := 96
testHarness := test.InitHarness(ctx, t, logger, test.HarnessCfg{
ChainConfig: test.BorDevnetChainConfigWithNoBlockSealDelays(),
testHarness := stagedsynctest.InitHarness(ctx, t, stagedsynctest.HarnessCfg{
ChainConfig: stagedsynctest.BorDevnetChainConfigWithNoBlockSealDelays(),
GenerateChainNumBlocks: numBlocks,
LogLvl: log.LvlInfo,
})
// pretend-update previous stage progress
testHarness.SaveStageProgress(ctx, t, stages.Headers, uint64(numBlocks))
@ -61,11 +70,11 @@ func TestBorHeimdallForwardPersistsStateSyncEvents(t *testing.T) {
// asserts
// 1 event per sprint expected
events, err := testHarness.ReadStateSyncEventsFromDb(ctx)
events, err := testHarness.ReadStateSyncEventsFromDB(ctx)
require.NoError(t, err)
require.Len(t, events, 6)
firstEventNumPerBlock, err := testHarness.ReadFirstStateSyncEventNumPerBlockFromDb(ctx)
firstEventNumPerBlock, err := testHarness.ReadFirstStateSyncEventNumPerBlockFromDB(ctx)
require.NoError(t, err)
require.Len(t, firstEventNumPerBlock, 6)
require.Equal(t, uint64(1), firstEventNumPerBlock[16])
@ -75,3 +84,99 @@ func TestBorHeimdallForwardPersistsStateSyncEvents(t *testing.T) {
require.Equal(t, uint64(5), firstEventNumPerBlock[80])
require.Equal(t, uint64(6), firstEventNumPerBlock[96])
}
func TestBorHeimdallForwardErrHeaderValidatorsLengthMismatch(t *testing.T) {
t.Parallel()
ctx := context.Background()
numBlocks := 271
validatorKey1, err := crypto.GenerateKey()
require.NoError(t, err)
validatorKey2, err := crypto.GenerateKey()
require.NoError(t, err)
testHarness := stagedsynctest.InitHarness(ctx, t, stagedsynctest.HarnessCfg{
ChainConfig: stagedsynctest.BorDevnetChainConfigWithNoBlockSealDelays(),
GenerateChainNumBlocks: numBlocks,
LogLvl: log.LvlInfo,
HeimdallProducersOverride: map[uint64][]valset.Validator{
1: {
*valset.NewValidator(crypto.PubkeyToAddress(validatorKey1.PublicKey), 1),
*valset.NewValidator(crypto.PubkeyToAddress(validatorKey2.PublicKey), 1),
},
},
})
// pretend-update previous stage progress
testHarness.SaveStageProgress(ctx, t, stages.Headers, uint64(numBlocks))
// run stage under test
testHarness.RunStageForwardWithErrorIs(t, stages.BorHeimdall, stagedsync.ErrHeaderValidatorsLengthMismatch)
}
func TestBorHeimdallForwardErrHeaderValidatorsBytesMismatch(t *testing.T) {
t.Parallel()
ctx := context.Background()
numBlocks := 271
validatorKey1, err := crypto.GenerateKey()
require.NoError(t, err)
testHarness := stagedsynctest.InitHarness(ctx, t, stagedsynctest.HarnessCfg{
ChainConfig: stagedsynctest.BorDevnetChainConfigWithNoBlockSealDelays(),
GenerateChainNumBlocks: numBlocks,
LogLvl: log.LvlInfo,
HeimdallProducersOverride: map[uint64][]valset.Validator{
1: {
*valset.NewValidator(crypto.PubkeyToAddress(validatorKey1.PublicKey), 1),
},
},
})
// pretend-update previous stage progress
testHarness.SaveStageProgress(ctx, t, stages.Headers, uint64(numBlocks))
// run stage under test
testHarness.RunStageForwardWithErrorIs(t, stages.BorHeimdall, stagedsync.ErrHeaderValidatorsBytesMismatch)
}
func TestBorHeimdallForwardDetectsUnauthorizedSignerError(t *testing.T) {
t.Parallel()
ctx := context.Background()
numBlocks := 312
chainConfig := stagedsynctest.BorDevnetChainConfigWithNoBlockSealDelays()
testHarness := stagedsynctest.InitHarness(ctx, t, stagedsynctest.HarnessCfg{
ChainConfig: chainConfig,
GenerateChainNumBlocks: numBlocks,
LogLvl: log.LvlInfo,
})
// prepare invalid header and insert it in the db
latestHeader, err := testHarness.ReadHeaderByNumber(ctx, uint64(numBlocks))
require.NoError(t, err)
gasLimit := uint64(15500)
invalidHeader := core.MakeEmptyHeader(latestHeader, chainConfig, uint64(time.Now().Unix()), &gasLimit)
invalidHeader.Number = new(big.Int).Add(latestHeader.Number, big.NewInt(1))
invalidHeader.Extra = bytes.Repeat([]byte{0x00}, types.ExtraVanityLength+types.ExtraSealLength)
validatorKey1, err := crypto.GenerateKey()
require.NoError(t, err)
sighash, err := crypto.Sign(crypto.Keccak256(bor.BorRLP(invalidHeader, chainConfig.Bor)), validatorKey1)
require.NoError(t, err)
copy(invalidHeader.Extra[len(invalidHeader.Extra)-types.ExtraSealLength:], sighash)
testHarness.SaveHeader(ctx, t, invalidHeader)
// pretend-update previous stage progress
testHarness.SaveStageProgress(ctx, t, stages.Headers, invalidHeader.Number.Uint64())
require.Equal(t, uint64(numBlocks+1), testHarness.GetStageProgress(ctx, t, stages.Headers))
require.Equal(t, uint64(0), testHarness.GetStageProgress(ctx, t, stages.BorHeimdall))
// run stage under test
testHarness.RunStageForward(t, stages.BorHeimdall)
// asserts
require.Equal(t, uint64(numBlocks+1), testHarness.GetStageProgress(ctx, t, stages.BorHeimdall))
require.Equal(t, invalidHeader.Number.Uint64()-1, testHarness.StateSyncUnwindPoint())
unwindReason := testHarness.StateSyncUnwindReason()
require.Equal(t, invalidHeader.Hash(), *unwindReason.Block)
var unauthorizedSignerErr *bor.UnauthorizedSignerError
ok := errors.As(unwindReason.Err, &unauthorizedSignerErr)
require.True(t, ok)
require.Equal(t, invalidHeader.Number.Uint64(), unauthorizedSignerErr.Number)
require.Equal(t, crypto.PubkeyToAddress(validatorKey1.PublicKey).Bytes(), unauthorizedSignerErr.Signer)
}

View File

@ -1,4 +1,4 @@
package test
package stagedsynctest
import (
"github.com/ledgerwatch/erigon-lib/chain"

View File

@ -1,10 +1,11 @@
package test
package stagedsynctest
import (
"context"
"crypto/ecdsa"
"encoding/binary"
"encoding/json"
"errors"
"fmt"
"math/big"
"testing"
@ -12,8 +13,6 @@ import (
"github.com/golang/mock/gomock"
"github.com/holiman/uint256"
"github.com/ledgerwatch/erigon/turbo/services"
"github.com/ledgerwatch/erigon/turbo/stages/mock"
"github.com/ledgerwatch/log/v3"
"github.com/stretchr/testify/require"
@ -37,19 +36,23 @@ import (
"github.com/ledgerwatch/erigon/eth/ethconfig"
"github.com/ledgerwatch/erigon/eth/stagedsync"
"github.com/ledgerwatch/erigon/eth/stagedsync/stages"
"github.com/ledgerwatch/erigon/turbo/services"
"github.com/ledgerwatch/erigon/turbo/stages/mock"
"github.com/ledgerwatch/erigon/turbo/testlog"
)
func InitHarness(ctx context.Context, t *testing.T, logger log.Logger, cfg HarnessCfg) Harness {
func InitHarness(ctx context.Context, t *testing.T, cfg HarnessCfg) Harness {
logger := testlog.Logger(t, cfg.LogLvl)
genesisInit := createGenesisInitData(t, cfg.ChainConfig)
m := mock.MockWithGenesis(t, genesisInit.genesis, genesisInit.genesisAllocPrivateKey, false)
chainDataDb := m.DB
chainDataDB := m.DB
blockReader := m.BlockReader
borConsensusDb := memdb.NewTestDB(t)
borConsensusDB := memdb.NewTestDB(t)
ctrl := gomock.NewController(t)
heimdallClient := heimdallmock.NewMockIHeimdallClient(ctrl)
bhCfg := stagedsync.StageBorHeimdallCfg(
chainDataDb,
borConsensusDb,
chainDataDB,
borConsensusDB,
stagedsync.NewProposingState(&ethconfig.Defaults.Miner),
*cfg.ChainConfig,
heimdallClient,
@ -83,20 +86,21 @@ func InitHarness(ctx context.Context, t *testing.T, logger log.Logger, cfg Harne
require.NoError(t, err)
validatorAddress := crypto.PubkeyToAddress(validatorKey.PublicKey)
h := Harness{
logger: logger,
chainDataDb: chainDataDb,
borConsensusDb: borConsensusDb,
chainConfig: cfg.ChainConfig,
blockReader: blockReader,
stateSyncStages: stateSyncStages,
stateSync: stateSync,
bhCfg: bhCfg,
heimdallClient: heimdallClient,
sealedHeaders: make(map[uint64]*types.Header),
borSpanner: bormock.NewMockSpanner(ctrl),
validatorAddress: validatorAddress,
validatorKey: validatorKey,
genesisInitData: genesisInit,
logger: logger,
chainDataDB: chainDataDB,
borConsensusDB: borConsensusDB,
chainConfig: cfg.ChainConfig,
blockReader: blockReader,
stateSyncStages: stateSyncStages,
stateSync: stateSync,
bhCfg: bhCfg,
heimdallClient: heimdallClient,
heimdallProducersOverride: cfg.GetOrCreateDefaultHeimdallProducersOverride(),
sealedHeaders: make(map[uint64]*types.Header),
borSpanner: bormock.NewMockSpanner(ctrl),
validatorAddress: validatorAddress,
validatorKey: validatorKey,
genesisInitData: genesisInit,
}
if cfg.ChainConfig.Bor != nil {
@ -118,14 +122,24 @@ type genesisInitData struct {
}
type HarnessCfg struct {
ChainConfig *chain.Config
GenerateChainNumBlocks int
ChainConfig *chain.Config
GenerateChainNumBlocks int
LogLvl log.Lvl
HeimdallProducersOverride map[uint64][]valset.Validator
}
func (hc *HarnessCfg) GetOrCreateDefaultHeimdallProducersOverride() map[uint64][]valset.Validator {
if hc.HeimdallProducersOverride == nil {
hc.HeimdallProducersOverride = map[uint64][]valset.Validator{}
}
return hc.HeimdallProducersOverride
}
type Harness struct {
logger log.Logger
chainDataDb kv.RwDB
borConsensusDb kv.RwDB
chainDataDB kv.RwDB
borConsensusDB kv.RwDB
chainConfig *chain.Config
blockReader services.BlockReader
stateSyncStages []*stagedsync.Stage
@ -133,8 +147,9 @@ type Harness struct {
bhCfg stagedsync.BorHeimdallCfg
heimdallClient *heimdallmock.MockIHeimdallClient
heimdallNextMockSpan *span.HeimdallSpan
heimdallLastEventId uint64
heimdallLastEventID uint64
heimdallLastEventHeaderNum uint64
heimdallProducersOverride map[uint64][]valset.Validator // spanID -> selected producers override
sealedHeaders map[uint64]*types.Header
borSpanner *bormock.MockSpanner
validatorAddress libcommon.Address
@ -142,33 +157,63 @@ type Harness struct {
genesisInitData *genesisInitData
}
func (h *Harness) SaveStageProgress(ctx context.Context, t *testing.T, stageId stages.SyncStage, progress uint64) {
rwTx, err := h.chainDataDb.BeginRw(ctx)
func (h *Harness) Logger() log.Logger {
return h.logger
}
func (h *Harness) SaveStageProgress(ctx context.Context, t *testing.T, stageID stages.SyncStage, progress uint64) {
rwTx, err := h.chainDataDB.BeginRw(ctx)
require.NoError(t, err)
defer rwTx.Rollback()
err = stages.SaveStageProgress(rwTx, stageId, progress)
err = stages.SaveStageProgress(rwTx, stageID, progress)
require.NoError(t, err)
err = rwTx.Commit()
require.NoError(t, err)
}
func (h *Harness) GetStageProgress(ctx context.Context, t *testing.T, stageID stages.SyncStage) uint64 {
roTx, err := h.chainDataDB.BeginRo(ctx)
require.NoError(t, err)
defer roTx.Rollback()
progress, err := stages.GetStageProgress(roTx, stageID)
require.NoError(t, err)
return progress
}
func (h *Harness) StateSyncUnwindPoint() uint64 {
return h.stateSync.UnwindPoint()
}
func (h *Harness) StateSyncUnwindReason() stagedsync.UnwindReason {
return h.stateSync.UnwindReason()
}
func (h *Harness) RunStageForward(t *testing.T, id stages.SyncStage) {
h.RunStageForwardWithErrorIs(t, id, nil)
}
func (h *Harness) RunStageForwardWithErrorIs(t *testing.T, id stages.SyncStage, wantErr error) {
err := h.RunStageForwardWithReturnError(t, id)
require.ErrorIs(t, err, wantErr)
}
func (h *Harness) RunStageForwardWithReturnError(t *testing.T, id stages.SyncStage) error {
err := h.stateSync.SetCurrentStage(id)
require.NoError(t, err)
stage, found := h.findStateSyncStageById(id)
stage, found := h.findStateSyncStageByID(id)
require.True(t, found)
stageState, err := h.stateSync.StageState(id, nil, h.chainDataDb)
stageState, err := h.stateSync.StageState(id, nil, h.chainDataDB)
require.NoError(t, err)
err = stage.Forward(true, false, stageState, h.stateSync, nil, h.logger)
require.NoError(t, err)
return stage.Forward(true, false, stageState, h.stateSync, nil, h.logger)
}
func (h *Harness) ReadSpansFromDb(ctx context.Context) (spans []*span.HeimdallSpan, err error) {
err = h.chainDataDb.View(ctx, func(tx kv.Tx) error {
func (h *Harness) ReadSpansFromDB(ctx context.Context) (spans []*span.HeimdallSpan, err error) {
err = h.chainDataDB.View(ctx, func(tx kv.Tx) error {
spanIter, err := tx.Range(kv.BorSpans, nil, nil)
if err != nil {
return err
@ -202,8 +247,8 @@ func (h *Harness) ReadSpansFromDb(ctx context.Context) (spans []*span.HeimdallSp
return spans, nil
}
func (h *Harness) ReadStateSyncEventsFromDb(ctx context.Context) (eventIds []uint64, err error) {
err = h.chainDataDb.View(ctx, func(tx kv.Tx) error {
func (h *Harness) ReadStateSyncEventsFromDB(ctx context.Context) (eventIDs []uint64, err error) {
err = h.chainDataDB.View(ctx, func(tx kv.Tx) error {
eventsIter, err := tx.Range(kv.BorEvents, nil, nil)
if err != nil {
return err
@ -215,7 +260,7 @@ func (h *Harness) ReadStateSyncEventsFromDb(ctx context.Context) (eventIds []uin
return err
}
eventIds = append(eventIds, binary.BigEndian.Uint64(keyBytes))
eventIDs = append(eventIDs, binary.BigEndian.Uint64(keyBytes))
}
return nil
@ -224,12 +269,12 @@ func (h *Harness) ReadStateSyncEventsFromDb(ctx context.Context) (eventIds []uin
return nil, err
}
return eventIds, nil
return eventIDs, nil
}
func (h *Harness) ReadFirstStateSyncEventNumPerBlockFromDb(ctx context.Context) (nums map[uint64]uint64, err error) {
func (h *Harness) ReadFirstStateSyncEventNumPerBlockFromDB(ctx context.Context) (nums map[uint64]uint64, err error) {
nums = map[uint64]uint64{}
err = h.chainDataDb.View(ctx, func(tx kv.Tx) error {
err = h.chainDataDB.View(ctx, func(tx kv.Tx) error {
eventNumsIter, err := tx.Range(kv.BorEventNums, nil, nil)
if err != nil {
return err
@ -255,6 +300,19 @@ func (h *Harness) ReadFirstStateSyncEventNumPerBlockFromDb(ctx context.Context)
return nums, nil
}
func (h *Harness) ReadHeaderByNumber(ctx context.Context, number uint64) (header *types.Header, err error) {
err = h.chainDataDB.View(ctx, func(tx kv.Tx) error {
header = rawdb.ReadHeaderByNumber(tx, number)
if header == nil {
return errors.New("header not found by harness")
}
return nil
})
return
}
func createGenesisInitData(t *testing.T, chainConfig *chain.Config) *genesisInitData {
t.Helper()
accountPrivateKey, err := crypto.GenerateKey()
@ -283,7 +341,7 @@ func createGenesisInitData(t *testing.T, chainConfig *chain.Config) *genesisInit
func (h *Harness) generateChain(ctx context.Context, t *testing.T, ctrl *gomock.Controller, cfg HarnessCfg) {
consensusEngine := h.consensusEngine(t, cfg)
var parentBlock *types.Block
err := h.chainDataDb.View(ctx, func(tx kv.Tx) (err error) {
err := h.chainDataDB.View(ctx, func(tx kv.Tx) (err error) {
parentBlock, err = h.blockReader.BlockByNumber(ctx, tx, 0)
return err
})
@ -295,7 +353,7 @@ func (h *Harness) generateChain(ctx context.Context, t *testing.T, ctrl *gomock.
h.chainConfig,
parentBlock,
consensusEngine,
h.chainDataDb,
h.chainDataDB,
cfg.GenerateChainNumBlocks,
func(i int, gen *core.BlockGen) {
// seal parent block first so that we can Prepare the current header
@ -310,13 +368,13 @@ func (h *Harness) generateChain(ctx context.Context, t *testing.T, ctrl *gomock.
}
h.logger.Info("Adding 1 mock tx to block", "blockNum", gen.GetHeader().Number)
chainId := uint256.Int{}
overflow := chainId.SetFromBig(h.chainConfig.ChainID)
chainID := uint256.Int{}
overflow := chainID.SetFromBig(h.chainConfig.ChainID)
require.False(t, overflow)
from := h.genesisInitData.fundedAddresses[0]
tx, err := types.SignTx(
types.NewEIP1559Transaction(
chainId,
chainID,
gen.TxNonce(from),
from, // send to itself
new(uint256.Int),
@ -366,7 +424,7 @@ func (h *Harness) consensusEngine(t *testing.T, cfg HarnessCfg) consensus.Engine
borConsensusEng := bor.New(
h.chainConfig,
h.borConsensusDb,
h.borConsensusDB,
nil,
h.borSpanner,
h.heimdallClient,
@ -385,8 +443,12 @@ func (h *Harness) consensusEngine(t *testing.T, cfg HarnessCfg) consensus.Engine
return nil
}
func (h *Harness) SaveHeader(ctx context.Context, t *testing.T, header *types.Header) {
h.saveHeaders(ctx, t, []*types.Header{header})
}
func (h *Harness) saveHeaders(ctx context.Context, t *testing.T, headers []*types.Header) {
rwTx, err := h.chainDataDb.BeginRw(ctx)
rwTx, err := h.chainDataDB.BeginRw(ctx)
require.NoError(t, err)
defer rwTx.Rollback()
@ -493,6 +555,10 @@ func (h *Harness) mockHeimdallClient() {
SelectedProducers: res.SelectedProducers,
}
if selectedProducers, ok := h.heimdallProducersOverride[res.ID]; ok {
res.SelectedProducers = selectedProducers
}
return res, nil
}).
AnyTimes()
@ -501,12 +567,12 @@ func (h *Harness) mockHeimdallClient() {
EXPECT().
StateSyncEvents(gomock.Any(), gomock.Any(), gomock.Any()).
DoAndReturn(func(_ context.Context, _ uint64, _ int64) ([]*clerk.EventRecordWithTime, error) {
h.heimdallLastEventId++
h.heimdallLastEventID++
h.heimdallLastEventHeaderNum += h.chainConfig.Bor.CalculateSprint(h.heimdallLastEventHeaderNum)
stateSyncDelay := h.chainConfig.Bor.CalculateStateSyncDelay(h.heimdallLastEventHeaderNum)
newEvent := clerk.EventRecordWithTime{
EventRecord: clerk.EventRecord{
ID: h.heimdallLastEventId,
ID: h.heimdallLastEventID,
ChainID: h.chainConfig.ChainID.String(),
},
Time: time.Unix(int64(h.sealedHeaders[h.heimdallLastEventHeaderNum].Time-stateSyncDelay-1), 0),
@ -518,7 +584,7 @@ func (h *Harness) mockHeimdallClient() {
AnyTimes()
}
func (h *Harness) findStateSyncStageById(id stages.SyncStage) (*stagedsync.Stage, bool) {
func (h *Harness) findStateSyncStageByID(id stages.SyncStage) (*stagedsync.Stage, bool) {
for _, s := range h.stateSyncStages {
if s.ID == id {
return s, true

View File

@ -5,11 +5,11 @@ import (
"fmt"
"time"
"github.com/ledgerwatch/log/v3"
libcommon "github.com/ledgerwatch/erigon-lib/common"
"github.com/ledgerwatch/erigon-lib/common/dbg"
"github.com/ledgerwatch/erigon-lib/kv"
"github.com/ledgerwatch/log/v3"
"github.com/ledgerwatch/erigon/eth/ethconfig"
"github.com/ledgerwatch/erigon/eth/stagedsync/stages"
)
@ -37,8 +37,21 @@ type Timing struct {
took time.Duration
}
func (s *Sync) Len() int { return len(s.stages) }
func (s *Sync) PrevUnwindPoint() *uint64 { return s.prevUnwindPoint }
func (s *Sync) Len() int {
return len(s.stages)
}
func (s *Sync) UnwindPoint() uint64 {
return *s.unwindPoint
}
func (s *Sync) UnwindReason() UnwindReason {
return s.unwindReason
}
func (s *Sync) PrevUnwindPoint() *uint64 {
return s.prevUnwindPoint
}
func (s *Sync) NewUnwindState(id stages.SyncStage, unwindPoint, currentProgress uint64) *UnwindState {
return &UnwindState{id, unwindPoint, currentProgress, UnwindReason{nil, nil}, s}