diff --git a/cmd/devnet/services/polygon/checkpoint.go b/cmd/devnet/services/polygon/checkpoint.go index 5386ab019..903919ecb 100644 --- a/cmd/devnet/services/polygon/checkpoint.go +++ b/cmd/devnet/services/polygon/checkpoint.go @@ -10,8 +10,6 @@ import ( "strings" "time" - "github.com/ledgerwatch/erigon/polygon/heimdall/checkpoint" - "github.com/ledgerwatch/erigon-lib/chain/networkname" libcommon "github.com/ledgerwatch/erigon-lib/common" "github.com/ledgerwatch/erigon-lib/common/hexutility" @@ -23,6 +21,7 @@ import ( "github.com/ledgerwatch/erigon/cmd/devnet/requests" "github.com/ledgerwatch/erigon/core/types" "github.com/ledgerwatch/erigon/crypto" + "github.com/ledgerwatch/erigon/polygon/heimdall" ) type CheckpointBlock struct { @@ -177,7 +176,7 @@ func (h *Heimdall) handleChildHeader(ctx context.Context, header *types.Header) return err } - h.pendingCheckpoint = &checkpoint.Checkpoint{ + h.pendingCheckpoint = &heimdall.Checkpoint{ Timestamp: timeStamp, StartBlock: big.NewInt(int64(expectedCheckpointState.newStart)), EndBlock: big.NewInt(int64(expectedCheckpointState.newEnd)), diff --git a/cmd/devnet/services/polygon/heimdall.go b/cmd/devnet/services/polygon/heimdall.go index 1288f67c6..80253bf27 100644 --- a/cmd/devnet/services/polygon/heimdall.go +++ b/cmd/devnet/services/polygon/heimdall.go @@ -16,11 +16,6 @@ import ( "github.com/go-chi/chi/v5" "github.com/ledgerwatch/log/v3" - "github.com/ledgerwatch/erigon/polygon/heimdall" - "github.com/ledgerwatch/erigon/polygon/heimdall/checkpoint" - "github.com/ledgerwatch/erigon/polygon/heimdall/milestone" - "github.com/ledgerwatch/erigon/polygon/heimdall/span" - ethereum "github.com/ledgerwatch/erigon" "github.com/ledgerwatch/erigon-lib/chain" libcommon "github.com/ledgerwatch/erigon-lib/common" @@ -31,6 +26,7 @@ import ( "github.com/ledgerwatch/erigon/cmd/devnet/devnet" "github.com/ledgerwatch/erigon/polygon/bor/borcfg" "github.com/ledgerwatch/erigon/polygon/bor/valset" + "github.com/ledgerwatch/erigon/polygon/heimdall" ) type BridgeEvent string @@ -79,11 +75,11 @@ type Heimdall struct { borConfig *borcfg.BorConfig listenAddr string validatorSet *valset.ValidatorSet - pendingCheckpoint *checkpoint.Checkpoint + pendingCheckpoint *heimdall.Checkpoint latestCheckpoint *CheckpointAck ackWaiter *sync.Cond - currentSpan *span.HeimdallSpan - spans map[uint64]*span.HeimdallSpan + currentSpan *heimdall.HeimdallSpan + spans map[uint64]*heimdall.HeimdallSpan logger log.Logger cancelFunc context.CancelFunc syncSenderAddress libcommon.Address @@ -109,7 +105,7 @@ func NewHeimdall( borConfig: chainConfig.Bor.(*borcfg.BorConfig), listenAddr: serverURL[7:], checkpointConfig: *checkpointConfig, - spans: map[uint64]*span.HeimdallSpan{}, + spans: map[uint64]*heimdall.HeimdallSpan{}, pendingSyncRecords: map[syncRecordKey]*EventRecordWithBlock{}, logger: logger} @@ -146,7 +142,7 @@ func NewHeimdall( return heimdall } -func (h *Heimdall) Span(ctx context.Context, spanID uint64) (*span.HeimdallSpan, error) { +func (h *Heimdall) Span(ctx context.Context, spanID uint64) (*heimdall.HeimdallSpan, error) { h.Lock() defer h.Unlock() @@ -155,7 +151,7 @@ func (h *Heimdall) Span(ctx context.Context, spanID uint64) (*span.HeimdallSpan, return span, nil } - var nextSpan = span.Span{ + var nextSpan = heimdall.Span{ ID: spanID, } @@ -179,7 +175,7 @@ func (h *Heimdall) Span(ctx context.Context, spanID uint64) (*span.HeimdallSpan, selectedProducers[i] = *v } - h.currentSpan = &span.HeimdallSpan{ + h.currentSpan = &heimdall.HeimdallSpan{ Span: nextSpan, ValidatorSet: *h.validatorSet, SelectedProducers: selectedProducers, @@ -205,7 +201,7 @@ func (h *Heimdall) getSpanOverrideHeight() uint64 { //MumbaiChain: 10205000 } -func (h *Heimdall) FetchCheckpoint(ctx context.Context, number int64) (*checkpoint.Checkpoint, error) { +func (h *Heimdall) FetchCheckpoint(ctx context.Context, number int64) (*heimdall.Checkpoint, error) { return nil, fmt.Errorf("TODO") } @@ -213,7 +209,7 @@ func (h *Heimdall) FetchCheckpointCount(ctx context.Context) (int64, error) { return 0, fmt.Errorf("TODO") } -func (h *Heimdall) FetchMilestone(ctx context.Context, number int64) (*milestone.Milestone, error) { +func (h *Heimdall) FetchMilestone(ctx context.Context, number int64) (*heimdall.Milestone, error) { return nil, fmt.Errorf("TODO") } @@ -392,7 +388,7 @@ func (h *Heimdall) Start(ctx context.Context) error { return startHTTPServer(ctx, server, "devnet Heimdall service", h.logger) } -func makeHeimdallRouter(ctx context.Context, client heimdall.IHeimdallClient) *chi.Mux { +func makeHeimdallRouter(ctx context.Context, client heimdall.HeimdallClient) *chi.Mux { router := chi.NewRouter() writeResponse := func(w http.ResponseWriter, result any, err error) { @@ -492,7 +488,7 @@ func makeHeimdallRouter(ctx context.Context, client heimdall.IHeimdallClient) *c router.Get("/milestone/count", func(w http.ResponseWriter, r *http.Request) { result, err := client.FetchMilestoneCount(ctx) - writeResponse(w, milestone.MilestoneCount{Count: result}, err) + writeResponse(w, heimdall.MilestoneCount{Count: result}, err) }) router.Get("/milestone/noAck/{id}", func(w http.ResponseWriter, r *http.Request) { diff --git a/cmd/devnet/services/polygon/heimdall_test.go b/cmd/devnet/services/polygon/heimdall_test.go index a9b34d3bd..0cb3e58ab 100644 --- a/cmd/devnet/services/polygon/heimdall_test.go +++ b/cmd/devnet/services/polygon/heimdall_test.go @@ -10,10 +10,7 @@ import ( "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" - "github.com/ledgerwatch/erigon/polygon/bor/clerk" - "github.com/ledgerwatch/erigon/polygon/heimdall/checkpoint" - heimdallmock "github.com/ledgerwatch/erigon/polygon/heimdall/mock" - heimdallspan "github.com/ledgerwatch/erigon/polygon/heimdall/span" + "github.com/ledgerwatch/erigon/polygon/heimdall" ) func TestHeimdallServer(t *testing.T) { @@ -21,18 +18,18 @@ func TestHeimdallServer(t *testing.T) { ctx := context.Background() ctrl := gomock.NewController(t) - client := heimdallmock.NewMockIHeimdallClient(ctrl) + client := heimdall.NewMockHeimdallClient(ctrl) - events := []*clerk.EventRecordWithTime{ + events := []*heimdall.EventRecordWithTime{ { - EventRecord: clerk.EventRecord{ + EventRecord: heimdall.EventRecord{ ID: 1, ChainID: "80001", }, Time: time.Now(), }, { - EventRecord: clerk.EventRecord{ + EventRecord: heimdall.EventRecord{ ID: 2, ChainID: "80001", }, @@ -41,8 +38,8 @@ func TestHeimdallServer(t *testing.T) { } client.EXPECT().StateSyncEvents(gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes().Return(events, nil) - span := &heimdallspan.HeimdallSpan{ - Span: heimdallspan.Span{ + span := &heimdall.HeimdallSpan{ + Span: heimdall.Span{ ID: 1, StartBlock: 1000, EndBlock: 2000, @@ -51,7 +48,7 @@ func TestHeimdallServer(t *testing.T) { } client.EXPECT().Span(gomock.Any(), gomock.Any()).AnyTimes().Return(span, nil) - checkpoint1 := &checkpoint.Checkpoint{ + checkpoint1 := &heimdall.Checkpoint{ StartBlock: big.NewInt(1000), EndBlock: big.NewInt(1999), BorChainID: "80001", diff --git a/cmd/devnet/services/polygon/proofgenerator_test.go b/cmd/devnet/services/polygon/proofgenerator_test.go index 4fc3829d8..79565cd9f 100644 --- a/cmd/devnet/services/polygon/proofgenerator_test.go +++ b/cmd/devnet/services/polygon/proofgenerator_test.go @@ -14,8 +14,6 @@ import ( "github.com/ledgerwatch/log/v3" "github.com/pion/randutil" - "github.com/ledgerwatch/erigon/polygon/heimdall/span" - "github.com/ledgerwatch/erigon-lib/chain" "github.com/ledgerwatch/erigon-lib/common" libcommon "github.com/ledgerwatch/erigon-lib/common" @@ -34,8 +32,8 @@ import ( "github.com/ledgerwatch/erigon/crypto" "github.com/ledgerwatch/erigon/params" "github.com/ledgerwatch/erigon/polygon/bor" - "github.com/ledgerwatch/erigon/polygon/bor/contract" "github.com/ledgerwatch/erigon/polygon/bor/valset" + "github.com/ledgerwatch/erigon/polygon/heimdall" "github.com/ledgerwatch/erigon/rlp" "github.com/ledgerwatch/erigon/rpc" "github.com/ledgerwatch/erigon/turbo/jsonrpc" @@ -77,9 +75,9 @@ func newRequestGenerator(sentry *mock.MockSentry, chain *core.ChainPack) (*reque sentry: sentry, bor: bor.NewRo(params.BorDevnetChainConfig, db, reader, &spanner{ - span.NewChainSpanner(contract.ValidatorSet(), params.BorDevnetChainConfig, false, log.Root()), + bor.NewChainSpanner(bor.GenesisContractValidatorSetABI(), params.BorDevnetChainConfig, false, log.Root()), libcommon.Address{}, - span.Span{}}, + heimdall.Span{}}, genesisContract{}, log.Root()), txBlockMap: map[libcommon.Hash]*types.Block{}, }, nil @@ -276,16 +274,16 @@ func (g genesisContract) LastStateId(syscall consensus.SystemCall) (*big.Int, er } type spanner struct { - *span.ChainSpanner + *bor.ChainSpanner validatorAddress libcommon.Address - currentSpan span.Span + currentSpan heimdall.Span } -func (c spanner) GetCurrentSpan(_ consensus.SystemCall) (*span.Span, error) { +func (c spanner) GetCurrentSpan(_ consensus.SystemCall) (*heimdall.Span, error) { return &c.currentSpan, nil } -func (c *spanner) CommitSpan(heimdallSpan span.HeimdallSpan, syscall consensus.SystemCall) error { +func (c *spanner) CommitSpan(heimdallSpan heimdall.HeimdallSpan, syscall consensus.SystemCall) error { c.currentSpan = heimdallSpan.Span return nil } diff --git a/cmd/devnet/services/polygon/statesync.go b/cmd/devnet/services/polygon/statesync.go index cf4bbd186..6c79c92c1 100644 --- a/cmd/devnet/services/polygon/statesync.go +++ b/cmd/devnet/services/polygon/statesync.go @@ -9,7 +9,7 @@ import ( "github.com/ledgerwatch/erigon/accounts/abi/bind" "github.com/ledgerwatch/erigon/cmd/devnet/contracts" - "github.com/ledgerwatch/erigon/polygon/bor/clerk" + "github.com/ledgerwatch/erigon/polygon/heimdall" ) // Maximum allowed event record data size @@ -19,7 +19,7 @@ const LegacyMaxStateSyncSize = 100000 const MaxStateSyncSize = 30000 type EventRecordWithBlock struct { - clerk.EventRecordWithTime + heimdall.EventRecordWithTime BlockNumber uint64 } @@ -42,7 +42,7 @@ func (h *Heimdall) startStateSyncSubscription() { } } -func (h *Heimdall) StateSyncEvents(ctx context.Context, fromID uint64, to int64) ([]*clerk.EventRecordWithTime, error) { +func (h *Heimdall) StateSyncEvents(ctx context.Context, fromID uint64, to int64) ([]*heimdall.EventRecordWithTime, error) { h.Lock() defer h.Unlock() @@ -79,7 +79,7 @@ func (h *Heimdall) StateSyncEvents(ctx context.Context, fromID uint64, to int64) return events[i].ID < events[j].ID }) - eventsWithTime := make([]*clerk.EventRecordWithTime, len(events)) + eventsWithTime := make([]*heimdall.EventRecordWithTime, len(events)) for i, event := range events { eventsWithTime[i] = &event.EventRecordWithTime } @@ -139,8 +139,8 @@ func (h *Heimdall) handleStateSynced(event *contracts.TestStateSenderStateSynced } h.pendingSyncRecords[syncRecordKey{event.Raw.TxHash, uint64(event.Raw.Index)}] = &EventRecordWithBlock{ - EventRecordWithTime: clerk.EventRecordWithTime{ - EventRecord: clerk.EventRecord{ + EventRecordWithTime: heimdall.EventRecordWithTime{ + EventRecord: heimdall.EventRecord{ ID: event.Id.Uint64(), Contract: event.ContractAddress, Data: event.Data, diff --git a/cmd/integration/commands/stages.go b/cmd/integration/commands/stages.go index ab9851c2d..18959df62 100644 --- a/cmd/integration/commands/stages.go +++ b/cmd/integration/commands/stages.go @@ -1669,7 +1669,7 @@ func overrideStorageMode(db kv.RwDB, logger log.Logger) error { }) } -func initConsensusEngine(ctx context.Context, cc *chain2.Config, dir string, db kv.RwDB, blockReader services.FullBlockReader, logger log.Logger) (engine consensus.Engine, heimdallClient heimdall.IHeimdallClient) { +func initConsensusEngine(ctx context.Context, cc *chain2.Config, dir string, db kv.RwDB, blockReader services.FullBlockReader, logger log.Logger) (engine consensus.Engine, heimdallClient heimdall.HeimdallClient) { config := ethconfig.Defaults var consensusConfig interface{} diff --git a/cmd/rpcdaemon/cli/config.go b/cmd/rpcdaemon/cli/config.go index b9c2e3429..9dbdc7c51 100644 --- a/cmd/rpcdaemon/cli/config.go +++ b/cmd/rpcdaemon/cli/config.go @@ -60,8 +60,6 @@ import ( "github.com/ledgerwatch/erigon/node/nodecfg" "github.com/ledgerwatch/erigon/polygon/bor" "github.com/ledgerwatch/erigon/polygon/bor/borcfg" - "github.com/ledgerwatch/erigon/polygon/bor/contract" - "github.com/ledgerwatch/erigon/polygon/heimdall/span" "github.com/ledgerwatch/erigon/rpc" "github.com/ledgerwatch/erigon/rpc/rpccfg" "github.com/ledgerwatch/erigon/turbo/debug" @@ -507,8 +505,8 @@ func RemoteServices(ctx context.Context, cfg *httpcfg.HttpCfg, logger log.Logger borConfig := cc.Bor.(*borcfg.BorConfig) engine = bor.NewRo(cc, borKv, blockReader, - span.NewChainSpanner(contract.ValidatorSet(), cc, true, logger), - contract.NewGenesisContractsClient(cc, borConfig.ValidatorContract, borConfig.StateReceiverContract, logger), logger) + bor.NewChainSpanner(bor.GenesisContractValidatorSetABI(), cc, true, logger), + bor.NewGenesisContractsClient(cc, borConfig.ValidatorContract, borConfig.StateReceiverContract, logger), logger) default: engine = ethash.NewFaker() @@ -931,8 +929,8 @@ func (e *remoteConsensusEngine) init(db kv.RoDB, blockReader services.FullBlockR borConfig := cc.Bor.(*borcfg.BorConfig) e.engine = bor.NewRo(cc, borKv, blockReader, - span.NewChainSpanner(contract.ValidatorSet(), cc, true, logger), - contract.NewGenesisContractsClient(cc, borConfig.ValidatorContract, borConfig.StateReceiverContract, logger), logger) + bor.NewChainSpanner(bor.GenesisContractValidatorSetABI(), cc, true, logger), + bor.NewGenesisContractsClient(cc, borConfig.ValidatorContract, borConfig.StateReceiverContract, logger), logger) } else { e.engine = ethash.NewFaker() } diff --git a/eth/backend.go b/eth/backend.go index 12fd08639..9d24aabaf 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -511,7 +511,7 @@ func New(ctx context.Context, stack *node.Node, config *ethconfig.Config, logger } else { consensusConfig = &config.Ethash } - var heimdallClient heimdall.IHeimdallClient + var heimdallClient heimdall.HeimdallClient if chainConfig.Bor != nil { if !config.WithoutHeimdall { heimdallClient = heimdall.NewHeimdallClient(config.HeimdallURL, logger) diff --git a/eth/ethconsensusconfig/config.go b/eth/ethconsensusconfig/config.go index 5eb4399f3..8050c5161 100644 --- a/eth/ethconsensusconfig/config.go +++ b/eth/ethconsensusconfig/config.go @@ -10,9 +10,6 @@ import ( "github.com/ledgerwatch/erigon-lib/chain" "github.com/ledgerwatch/erigon/polygon/bor/borcfg" - "github.com/ledgerwatch/erigon/polygon/heimdall" - "github.com/ledgerwatch/erigon/polygon/heimdall/span" - "github.com/ledgerwatch/erigon-lib/kv" "github.com/ledgerwatch/erigon/consensus" "github.com/ledgerwatch/erigon/consensus/aura" @@ -24,12 +21,12 @@ import ( "github.com/ledgerwatch/erigon/node/nodecfg" "github.com/ledgerwatch/erigon/params" "github.com/ledgerwatch/erigon/polygon/bor" - "github.com/ledgerwatch/erigon/polygon/bor/contract" + "github.com/ledgerwatch/erigon/polygon/heimdall" "github.com/ledgerwatch/erigon/turbo/services" ) func CreateConsensusEngine(ctx context.Context, nodeConfig *nodecfg.Config, chainConfig *chain.Config, config interface{}, notify []string, noVerify bool, - heimdallClient heimdall.IHeimdallClient, withoutHeimdall bool, blockReader services.FullBlockReader, readonly bool, + heimdallClient heimdall.HeimdallClient, withoutHeimdall bool, blockReader services.FullBlockReader, readonly bool, logger log.Logger, ) consensus.Engine { var eng consensus.Engine @@ -102,9 +99,9 @@ func CreateConsensusEngine(ctx context.Context, nodeConfig *nodecfg.Config, chai // In order to pass the ethereum transaction tests, we need to set the burn contract which is in the bor config // Then, bor != nil will also be enabled for ethash and clique. Only enable Bor for real if there is a validator contract present. if chainConfig.Bor != nil && consensusCfg.ValidatorContract != "" { - genesisContractsClient := contract.NewGenesisContractsClient(chainConfig, consensusCfg.ValidatorContract, consensusCfg.StateReceiverContract, logger) + genesisContractsClient := bor.NewGenesisContractsClient(chainConfig, consensusCfg.ValidatorContract, consensusCfg.StateReceiverContract, logger) - spanner := span.NewChainSpanner(contract.ValidatorSet(), chainConfig, withoutHeimdall, logger) + spanner := bor.NewChainSpanner(bor.GenesisContractValidatorSetABI(), chainConfig, withoutHeimdall, logger) var err error var db kv.RwDB diff --git a/eth/stagedsync/bor_heimdall_shared.go b/eth/stagedsync/bor_heimdall_shared.go index 323d443ea..cbb213f77 100644 --- a/eth/stagedsync/bor_heimdall_shared.go +++ b/eth/stagedsync/bor_heimdall_shared.go @@ -15,8 +15,8 @@ import ( "github.com/ledgerwatch/erigon-lib/kv" "github.com/ledgerwatch/erigon/core/types" + "github.com/ledgerwatch/erigon/polygon/bor" "github.com/ledgerwatch/erigon/polygon/heimdall" - "github.com/ledgerwatch/erigon/polygon/heimdall/span" "github.com/ledgerwatch/erigon/rlp" "github.com/ledgerwatch/erigon/turbo/services" ) @@ -92,7 +92,7 @@ func FetchSpanZeroForMiningIfNeeded( ctx context.Context, db kv.RwDB, blockReader services.FullBlockReader, - heimdallClient heimdall.IHeimdallClient, + heimdallClient heimdall.HeimdallClient, logger log.Logger, ) error { return db.Update(ctx, func(tx kv.RwTx) error { @@ -120,8 +120,8 @@ func fetchRequiredHeimdallSpansIfNeeded( logPrefix string, logger log.Logger, ) (uint64, error) { - requiredSpanID := span.IDAt(toBlockNum) - if span.BlockInLastSprintOfSpan(toBlockNum, cfg.borConfig) { + requiredSpanID := bor.SpanIDAt(toBlockNum) + if bor.IsBlockInLastSprintOfSpan(toBlockNum, cfg.borConfig) { requiredSpanID++ } @@ -153,7 +153,7 @@ func fetchAndWriteHeimdallSpan( ctx context.Context, spanID uint64, tx kv.RwTx, - heimdallClient heimdall.IHeimdallClient, + heimdallClient heimdall.HeimdallClient, logPrefix string, logger log.Logger, ) (uint64, error) { diff --git a/eth/stagedsync/stage_bor_heimdall.go b/eth/stagedsync/stage_bor_heimdall.go index c7edacb36..88199f747 100644 --- a/eth/stagedsync/stage_bor_heimdall.go +++ b/eth/stagedsync/stage_bor_heimdall.go @@ -25,12 +25,10 @@ import ( "github.com/ledgerwatch/erigon/eth/stagedsync/stages" "github.com/ledgerwatch/erigon/polygon/bor" "github.com/ledgerwatch/erigon/polygon/bor/borcfg" - "github.com/ledgerwatch/erigon/polygon/bor/contract" - "github.com/ledgerwatch/erigon/polygon/bor/finality/generics" + "github.com/ledgerwatch/erigon/polygon/bor/finality" "github.com/ledgerwatch/erigon/polygon/bor/finality/whitelist" "github.com/ledgerwatch/erigon/polygon/bor/valset" "github.com/ledgerwatch/erigon/polygon/heimdall" - "github.com/ledgerwatch/erigon/polygon/heimdall/span" "github.com/ledgerwatch/erigon/turbo/services" "github.com/ledgerwatch/erigon/turbo/stages/headerdownload" ) @@ -49,7 +47,7 @@ type BorHeimdallCfg struct { miningState MiningState chainConfig chain.Config borConfig *borcfg.BorConfig - heimdallClient heimdall.IHeimdallClient + heimdallClient heimdall.HeimdallClient blockReader services.FullBlockReader hd *headerdownload.HeaderDownload penalize func(context.Context, []headerdownload.PenaltyItem) @@ -64,7 +62,7 @@ func StageBorHeimdallCfg( snapDb kv.RwDB, miningState MiningState, chainConfig chain.Config, - heimdallClient heimdall.IHeimdallClient, + heimdallClient heimdall.HeimdallClient, blockReader services.FullBlockReader, hd *headerdownload.HeaderDownload, penalize func(context.Context, []headerdownload.PenaltyItem), @@ -87,7 +85,7 @@ func StageBorHeimdallCfg( blockReader: blockReader, hd: hd, penalize: penalize, - stateReceiverABI: contract.StateReceiver(), + stateReceiverABI: bor.GenesisContractStateReceiverABI(), loopBreakCheck: loopBreakCheck, recents: recents, signatures: signatures, @@ -126,7 +124,7 @@ func BorHeimdallForward( } whitelistService := whitelist.GetWhitelistingService() - if unwindPointPtr := generics.BorMilestoneRewind.Load(); unwindPointPtr != nil && *unwindPointPtr != 0 { + if unwindPointPtr := finality.BorMilestoneRewind.Load(); unwindPointPtr != nil && *unwindPointPtr != 0 { unwindPoint := *unwindPointPtr if whitelistService != nil && unwindPoint < headNumber { header, err := cfg.blockReader.HeaderByNumber(ctx, tx, headNumber) @@ -147,7 +145,7 @@ func BorHeimdallForward( dataflow.HeaderDownloadStates.AddChange(headNumber, dataflow.HeaderInvalidated) s.state.UnwindTo(unwindPoint, ForkReset(hash)) var reset uint64 = 0 - generics.BorMilestoneRewind.Store(&reset) + finality.BorMilestoneRewind.Store(&reset) return fmt.Errorf("verification failed for header %d: %x", headNumber, header.Hash()) } } @@ -428,7 +426,7 @@ func initValidatorSets( tx kv.RwTx, blockReader services.FullBlockReader, config *borcfg.BorConfig, - heimdallClient heimdall.IHeimdallClient, + heimdallClient heimdall.HeimdallClient, chain consensus.ChainHeaderReader, blockNum uint64, recents *lru.ARCCache[libcommon.Hash, *bor.Snapshot], @@ -471,7 +469,7 @@ func initValidatorSets( return nil, fmt.Errorf("zero span not found") } - var zeroSpan span.HeimdallSpan + var zeroSpan heimdall.HeimdallSpan if err = json.Unmarshal(zeroSpanBytes, &zeroSpan); err != nil { return nil, err } @@ -540,9 +538,9 @@ func checkBorHeaderExtraDataIfRequired(chr consensus.ChainHeaderReader, header * } func checkBorHeaderExtraData(chr consensus.ChainHeaderReader, header *types.Header, cfg *borcfg.BorConfig) error { - spanID := span.IDAt(header.Number.Uint64() + 1) + spanID := bor.SpanIDAt(header.Number.Uint64() + 1) spanBytes := chr.BorSpan(spanID) - var sp span.HeimdallSpan + var sp heimdall.HeimdallSpan if err := json.Unmarshal(spanBytes, &sp); err != nil { return err } @@ -629,7 +627,7 @@ func BorHeimdallUnwind(u *UnwindState, ctx context.Context, s *StageState, tx kv return err } defer spanCursor.Close() - lastSpanToKeep := span.IDAt(u.UnwindPoint) + lastSpanToKeep := bor.SpanIDAt(u.UnwindPoint) var spanIdBytes [8]byte binary.BigEndian.PutUint64(spanIdBytes[:], lastSpanToKeep+1) for k, _, err = spanCursor.Seek(spanIdBytes[:]); err == nil && k != nil; k, _, err = spanCursor.Next() { diff --git a/eth/stagedsync/stagedsynctest/harness.go b/eth/stagedsync/stagedsynctest/harness.go index a2b616999..ea203b65f 100644 --- a/eth/stagedsync/stagedsynctest/harness.go +++ b/eth/stagedsync/stagedsynctest/harness.go @@ -12,15 +12,13 @@ import ( "time" "github.com/ledgerwatch/erigon/polygon/bor/borcfg" + "github.com/ledgerwatch/erigon/polygon/heimdall" "github.com/golang/mock/gomock" "github.com/holiman/uint256" "github.com/ledgerwatch/log/v3" "github.com/stretchr/testify/require" - heimdallmock "github.com/ledgerwatch/erigon/polygon/heimdall/mock" - "github.com/ledgerwatch/erigon/polygon/heimdall/span" - "github.com/ledgerwatch/erigon-lib/chain" libcommon "github.com/ledgerwatch/erigon-lib/common" "github.com/ledgerwatch/erigon-lib/kv" @@ -36,9 +34,6 @@ import ( "github.com/ledgerwatch/erigon/eth/stagedsync" "github.com/ledgerwatch/erigon/eth/stagedsync/stages" "github.com/ledgerwatch/erigon/polygon/bor" - "github.com/ledgerwatch/erigon/polygon/bor/clerk" - "github.com/ledgerwatch/erigon/polygon/bor/contract" - bormock "github.com/ledgerwatch/erigon/polygon/bor/mock" "github.com/ledgerwatch/erigon/polygon/bor/valset" "github.com/ledgerwatch/erigon/turbo/services" "github.com/ledgerwatch/erigon/turbo/stages/mock" @@ -53,7 +48,7 @@ func InitHarness(ctx context.Context, t *testing.T, cfg HarnessCfg) Harness { blockReader := m.BlockReader borConsensusDB := memdb.NewTestDB(t) ctrl := gomock.NewController(t) - heimdallClient := heimdallmock.NewMockIHeimdallClient(ctrl) + heimdallClient := heimdall.NewMockHeimdallClient(ctrl) bhCfg := stagedsync.StageBorHeimdallCfg( chainDataDB, borConsensusDB, @@ -102,7 +97,7 @@ func InitHarness(ctx context.Context, t *testing.T, cfg HarnessCfg) Harness { heimdallClient: heimdallClient, heimdallProducersOverride: cfg.GetOrCreateDefaultHeimdallProducersOverride(), sealedHeaders: make(map[uint64]*types.Header), - borSpanner: bormock.NewMockSpanner(ctrl), + borSpanner: bor.NewMockSpanner(ctrl), validatorAddress: validatorAddress, validatorKey: validatorKey, genesisInitData: genesisInit, @@ -151,13 +146,13 @@ type Harness struct { stateSyncStages []*stagedsync.Stage stateSync *stagedsync.Sync bhCfg stagedsync.BorHeimdallCfg - heimdallClient *heimdallmock.MockIHeimdallClient - heimdallNextMockSpan *span.HeimdallSpan + heimdallClient *heimdall.MockHeimdallClient + heimdallNextMockSpan *heimdall.HeimdallSpan heimdallLastEventID uint64 heimdallLastEventHeaderNum uint64 heimdallProducersOverride map[uint64][]valset.Validator // spanID -> selected producers override sealedHeaders map[uint64]*types.Header - borSpanner *bormock.MockSpanner + borSpanner *bor.MockSpanner validatorAddress libcommon.Address validatorKey *ecdsa.PrivateKey genesisInitData *genesisInitData @@ -222,7 +217,7 @@ func (h *Harness) RunStageForwardWithReturnError(t *testing.T, id stages.SyncSta return stage.Forward(true, false, stageState, h.stateSync, wrap.TxContainer{}, h.logger) } -func (h *Harness) ReadSpansFromDB(ctx context.Context) (spans []*span.HeimdallSpan, err error) { +func (h *Harness) ReadSpansFromDB(ctx context.Context) (spans []*heimdall.HeimdallSpan, err error) { err = h.chainDataDB.View(ctx, func(tx kv.Tx) error { spanIter, err := tx.Range(kv.BorSpans, nil, nil) if err != nil { @@ -236,7 +231,7 @@ func (h *Harness) ReadSpansFromDB(ctx context.Context) (spans []*span.HeimdallSp } spanKey := binary.BigEndian.Uint64(keyBytes) - var heimdallSpan span.HeimdallSpan + var heimdallSpan heimdall.HeimdallSpan if err = json.Unmarshal(spanBytes, &heimdallSpan); err != nil { return err } @@ -425,7 +420,7 @@ func (h *Harness) seal(t *testing.T, chr consensus.ChainHeaderReader, eng consen func (h *Harness) consensusEngine(t *testing.T, cfg HarnessCfg) consensus.Engine { if h.chainConfig.Bor != nil { - genesisContracts := contract.NewGenesisContractsClient( + genesisContracts := bor.NewGenesisContractsClient( h.chainConfig, h.borConfig.ValidatorContract, h.borConfig.StateReceiverContract, @@ -517,8 +512,8 @@ func (h *Harness) setHeimdallNextMockSpan() { selectedProducers[i] = *validators[i] } - h.heimdallNextMockSpan = &span.HeimdallSpan{ - Span: span.Span{ + h.heimdallNextMockSpan = &heimdall.HeimdallSpan{ + Span: heimdall.Span{ ID: 0, StartBlock: 0, EndBlock: 255, @@ -553,10 +548,10 @@ func (h *Harness) mockHeimdallClient() { h.heimdallClient. EXPECT(). Span(gomock.Any(), gomock.Any()). - DoAndReturn(func(ctx context.Context, spanID uint64) (*span.HeimdallSpan, error) { + DoAndReturn(func(ctx context.Context, spanID uint64) (*heimdall.HeimdallSpan, error) { res := h.heimdallNextMockSpan - h.heimdallNextMockSpan = &span.HeimdallSpan{ - Span: span.Span{ + h.heimdallNextMockSpan = &heimdall.HeimdallSpan{ + Span: heimdall.Span{ ID: res.ID + 1, StartBlock: res.EndBlock + 1, EndBlock: res.EndBlock + 6400, @@ -576,12 +571,12 @@ func (h *Harness) mockHeimdallClient() { h.heimdallClient. EXPECT(). StateSyncEvents(gomock.Any(), gomock.Any(), gomock.Any()). - DoAndReturn(func(_ context.Context, _ uint64, _ int64) ([]*clerk.EventRecordWithTime, error) { + DoAndReturn(func(_ context.Context, _ uint64, _ int64) ([]*heimdall.EventRecordWithTime, error) { h.heimdallLastEventID++ h.heimdallLastEventHeaderNum += h.borConfig.CalculateSprintLength(h.heimdallLastEventHeaderNum) stateSyncDelay := h.borConfig.CalculateStateSyncDelay(h.heimdallLastEventHeaderNum) - newEvent := clerk.EventRecordWithTime{ - EventRecord: clerk.EventRecord{ + newEvent := heimdall.EventRecordWithTime{ + EventRecord: heimdall.EventRecord{ ID: h.heimdallLastEventID, ChainID: h.chainConfig.ChainID.String(), }, @@ -589,7 +584,7 @@ func (h *Harness) mockHeimdallClient() { } // 1 per sprint - return []*clerk.EventRecordWithTime{&newEvent}, nil + return []*heimdall.EventRecordWithTime{&newEvent}, nil }). AnyTimes() } diff --git a/polygon/bor/abi/interface.go b/polygon/bor/abi/interface.go deleted file mode 100644 index bb05bf0b2..000000000 --- a/polygon/bor/abi/interface.go +++ /dev/null @@ -1,6 +0,0 @@ -package abi - -type ABI interface { - Pack(name string, args ...interface{}) ([]byte, error) - UnpackIntoInterface(v interface{}, name string, data []byte) error -} diff --git a/polygon/bor/bor.go b/polygon/bor/bor.go index 90fb15965..d37f98880 100644 --- a/polygon/bor/bor.go +++ b/polygon/bor/bor.go @@ -22,9 +22,6 @@ import ( "golang.org/x/crypto/sha3" "golang.org/x/sync/errgroup" - "github.com/ledgerwatch/erigon/polygon/heimdall" - "github.com/ledgerwatch/erigon/polygon/heimdall/span" - "github.com/ledgerwatch/erigon-lib/chain" libcommon "github.com/ledgerwatch/erigon-lib/common" "github.com/ledgerwatch/erigon-lib/common/length" @@ -46,6 +43,7 @@ import ( "github.com/ledgerwatch/erigon/polygon/bor/finality/whitelist" "github.com/ledgerwatch/erigon/polygon/bor/statefull" "github.com/ledgerwatch/erigon/polygon/bor/valset" + "github.com/ledgerwatch/erigon/polygon/heimdall" "github.com/ledgerwatch/erigon/rlp" "github.com/ledgerwatch/erigon/rpc" "github.com/ledgerwatch/erigon/turbo/services" @@ -297,8 +295,8 @@ type Bor struct { execCtx context.Context // context of caller execution stage spanner Spanner - GenesisContractsClient GenesisContract - HeimdallClient heimdall.IHeimdallClient + GenesisContractsClient GenesisContracts + HeimdallClient heimdall.HeimdallClient // scope event.SubscriptionScope // The fields below are for testing only @@ -323,8 +321,8 @@ func New( db kv.RwDB, blockReader services.FullBlockReader, spanner Spanner, - heimdallClient heimdall.IHeimdallClient, - genesisContracts GenesisContract, + heimdallClient heimdall.HeimdallClient, + genesisContracts GenesisContracts, logger log.Logger, ) *Bor { // get bor config @@ -394,7 +392,7 @@ func (w rwWrapper) BeginRwNosync(ctx context.Context) (kv.RwTx, error) { // This is used by the rpcdaemon and tests which need read only access to the provided data services func NewRo(chainConfig *chain.Config, db kv.RoDB, blockReader services.FullBlockReader, spanner Spanner, - genesisContracts GenesisContract, logger log.Logger) *Bor { + genesisContracts GenesisContracts, logger log.Logger) *Bor { // get bor config borConfig := chainConfig.Bor.(*borcfg.BorConfig) @@ -890,7 +888,7 @@ func (c *Bor) Prepare(chain consensus.ChainHeaderReader, header *types.Header, s // where it fetches producers internally. As we fetch data from span // in Erigon, use directly the `GetCurrentProducers` function. if isSprintStart(number+1, c.config.CalculateSprintLength(number)) { - spanID := span.IDAt(number + 1) + spanID := SpanIDAt(number + 1) newValidators, err := c.spanner.GetCurrentProducers(spanID, c.authorizedSigner.Load().signer, chain) if err != nil { return errUnknownValidators @@ -1338,7 +1336,7 @@ func (c *Bor) fetchAndCommitSpan( chain statefull.ChainContext, syscall consensus.SystemCall, ) error { - var heimdallSpan span.HeimdallSpan + var heimdallSpan heimdall.HeimdallSpan if c.HeimdallClient == nil { // fixme: move to a new mock or fake and remove c.HeimdallClient completely @@ -1457,7 +1455,7 @@ func (c *Bor) CommitStates( return nil } -func (c *Bor) SetHeimdallClient(h heimdall.IHeimdallClient) { +func (c *Bor) SetHeimdallClient(h heimdall.HeimdallClient) { c.HeimdallClient = h } @@ -1471,7 +1469,7 @@ func (c *Bor) getNextHeimdallSpanForTest( header *types.Header, chain statefull.ChainContext, syscall consensus.SystemCall, -) (*span.HeimdallSpan, error) { +) (*heimdall.HeimdallSpan, error) { headerNumber := header.Number.Uint64() spanBor, err := c.spanner.GetCurrentSpan(syscall) @@ -1500,7 +1498,7 @@ func (c *Bor) getNextHeimdallSpanForTest( selectedProducers[i] = *v } - heimdallSpan := &span.HeimdallSpan{ + heimdallSpan := &heimdall.HeimdallSpan{ Span: *spanBor, ValidatorSet: *snap.ValidatorSet, SelectedProducers: selectedProducers, diff --git a/polygon/bor/bor_test.go b/polygon/bor/bor_test.go index 0c9f3c6d3..ee3586d73 100644 --- a/polygon/bor/bor_test.go +++ b/polygon/bor/bor_test.go @@ -8,13 +8,10 @@ import ( "testing" "github.com/ledgerwatch/erigon/polygon/bor/borcfg" + "github.com/ledgerwatch/erigon/polygon/heimdall" "github.com/ledgerwatch/log/v3" - "github.com/ledgerwatch/erigon/polygon/heimdall/checkpoint" - "github.com/ledgerwatch/erigon/polygon/heimdall/milestone" - "github.com/ledgerwatch/erigon/polygon/heimdall/span" - "github.com/ledgerwatch/erigon-lib/chain" "github.com/ledgerwatch/erigon-lib/common" libcommon "github.com/ledgerwatch/erigon-lib/common" @@ -28,19 +25,17 @@ import ( "github.com/ledgerwatch/erigon/ethdb/prune" "github.com/ledgerwatch/erigon/params" "github.com/ledgerwatch/erigon/polygon/bor" - "github.com/ledgerwatch/erigon/polygon/bor/clerk" - "github.com/ledgerwatch/erigon/polygon/bor/contract" "github.com/ledgerwatch/erigon/polygon/bor/valset" "github.com/ledgerwatch/erigon/rlp" "github.com/ledgerwatch/erigon/turbo/stages/mock" ) type test_heimdall struct { - currentSpan *span.HeimdallSpan + currentSpan *heimdall.HeimdallSpan chainConfig *chain.Config borConfig *borcfg.BorConfig validatorSet *valset.ValidatorSet - spans map[uint64]*span.HeimdallSpan + spans map[uint64]*heimdall.HeimdallSpan } func newTestHeimdall(chainConfig *chain.Config) *test_heimdall { @@ -49,7 +44,7 @@ func newTestHeimdall(chainConfig *chain.Config) *test_heimdall { chainConfig: chainConfig, borConfig: chainConfig.Bor.(*borcfg.BorConfig), validatorSet: nil, - spans: map[uint64]*span.HeimdallSpan{}, + spans: map[uint64]*heimdall.HeimdallSpan{}, } } @@ -57,18 +52,18 @@ func (h *test_heimdall) BorConfig() *borcfg.BorConfig { return h.borConfig } -func (h test_heimdall) StateSyncEvents(ctx context.Context, fromID uint64, to int64) ([]*clerk.EventRecordWithTime, error) { +func (h test_heimdall) StateSyncEvents(ctx context.Context, fromID uint64, to int64) ([]*heimdall.EventRecordWithTime, error) { return nil, nil } -func (h *test_heimdall) Span(ctx context.Context, spanID uint64) (*span.HeimdallSpan, error) { +func (h *test_heimdall) Span(ctx context.Context, spanID uint64) (*heimdall.HeimdallSpan, error) { if span, ok := h.spans[spanID]; ok { h.currentSpan = span return span, nil } - var nextSpan = span.Span{ + var nextSpan = heimdall.Span{ ID: spanID, } @@ -92,7 +87,7 @@ func (h *test_heimdall) Span(ctx context.Context, spanID uint64) (*span.Heimdall selectedProducers[i] = *v } - h.currentSpan = &span.HeimdallSpan{ + h.currentSpan = &heimdall.HeimdallSpan{ Span: nextSpan, ValidatorSet: *h.validatorSet, SelectedProducers: selectedProducers, @@ -112,7 +107,7 @@ func (h test_heimdall) currentSprintLength() int { return int(h.borConfig.CalculateSprintLength(256)) } -func (h test_heimdall) FetchCheckpoint(ctx context.Context, number int64) (*checkpoint.Checkpoint, error) { +func (h test_heimdall) FetchCheckpoint(ctx context.Context, number int64) (*heimdall.Checkpoint, error) { return nil, fmt.Errorf("TODO") } @@ -120,7 +115,7 @@ func (h test_heimdall) FetchCheckpointCount(ctx context.Context) (int64, error) return 0, fmt.Errorf("TODO") } -func (h test_heimdall) FetchMilestone(ctx context.Context, number int64) (*milestone.Milestone, error) { +func (h test_heimdall) FetchMilestone(ctx context.Context, number int64) (*heimdall.Milestone, error) { return nil, fmt.Errorf("TODO") } @@ -196,16 +191,16 @@ func (r headerReader) BorSpan(spanId uint64) []byte { } type spanner struct { - *span.ChainSpanner + *bor.ChainSpanner validatorAddress common.Address - currentSpan span.Span + currentSpan heimdall.Span } -func (c spanner) GetCurrentSpan(_ consensus.SystemCall) (*span.Span, error) { +func (c spanner) GetCurrentSpan(_ consensus.SystemCall) (*heimdall.Span, error) { return &c.currentSpan, nil } -func (c *spanner) CommitSpan(heimdallSpan span.HeimdallSpan, syscall consensus.SystemCall) error { +func (c *spanner) CommitSpan(heimdallSpan heimdall.HeimdallSpan, syscall consensus.SystemCall) error { c.currentSpan = heimdallSpan.Span return nil } @@ -278,6 +273,8 @@ func (v validator) verifyBlocks(blocks []*types.Block) error { return nil } +type heimdallSpan = heimdall.Span + func newValidator(t *testing.T, heimdall *test_heimdall, blocks map[uint64]*types.Block) validator { logger := log.Root() @@ -287,7 +284,11 @@ func newValidator(t *testing.T, heimdall *test_heimdall, blocks map[uint64]*type heimdall.chainConfig, memdb.New(""), nil, /* blockReader */ - &spanner{span.NewChainSpanner(contract.ValidatorSet(), heimdall.chainConfig, false, logger), validatorAddress, span.Span{}}, + &spanner{ + ChainSpanner: bor.NewChainSpanner(bor.GenesisContractValidatorSetABI(), heimdall.chainConfig, false, logger), + validatorAddress: validatorAddress, + currentSpan: heimdallSpan{}, + }, heimdall, test_genesisContract{}, logger, diff --git a/polygon/bor/contract/client.go b/polygon/bor/contract/client.go deleted file mode 100644 index 09f2ba5a3..000000000 --- a/polygon/bor/contract/client.go +++ /dev/null @@ -1,82 +0,0 @@ -package contract - -import ( - "math/big" - "strings" - - "github.com/ledgerwatch/erigon-lib/chain" - libcommon "github.com/ledgerwatch/erigon-lib/common" - "github.com/ledgerwatch/erigon/accounts/abi" - "github.com/ledgerwatch/erigon/consensus" - "github.com/ledgerwatch/erigon/rlp" - "github.com/ledgerwatch/log/v3" -) - -var ( - vABI, _ = abi.JSON(strings.NewReader(ValidatorsetABI)) - sABI, _ = abi.JSON(strings.NewReader(StateReceiverABI)) -) - -func ValidatorSet() abi.ABI { - return vABI -} - -func StateReceiver() abi.ABI { - return sABI -} - -type GenesisContractsClient struct { - validatorSetABI abi.ABI - stateReceiverABI abi.ABI - ValidatorContract libcommon.Address - StateReceiverContract libcommon.Address - chainConfig *chain.Config - logger log.Logger -} - -const ( - ValidatorsetABI = `[{"constant":true,"inputs":[],"name":"SPRINT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"SYSTEM_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"CHAIN","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"FIRST_END_BLOCK","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"producers","outputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"power","type":"uint256"},{"internalType":"address","name":"signer","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"ROUND_TYPE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"BOR_ID","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"spanNumbers","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"VOTE_TYPE","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"validators","outputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"power","type":"uint256"},{"internalType":"address","name":"signer","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"spans","outputs":[{"internalType":"uint256","name":"number","type":"uint256"},{"internalType":"uint256","name":"startBlock","type":"uint256"},{"internalType":"uint256","name":"endBlock","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"startBlock","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"endBlock","type":"uint256"}],"name":"NewSpan","type":"event"},{"constant":true,"inputs":[],"name":"currentSprint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"span","type":"uint256"}],"name":"getSpan","outputs":[{"internalType":"uint256","name":"number","type":"uint256"},{"internalType":"uint256","name":"startBlock","type":"uint256"},{"internalType":"uint256","name":"endBlock","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getCurrentSpan","outputs":[{"internalType":"uint256","name":"number","type":"uint256"},{"internalType":"uint256","name":"startBlock","type":"uint256"},{"internalType":"uint256","name":"endBlock","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getNextSpan","outputs":[{"internalType":"uint256","name":"number","type":"uint256"},{"internalType":"uint256","name":"startBlock","type":"uint256"},{"internalType":"uint256","name":"endBlock","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"number","type":"uint256"}],"name":"getSpanByBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"currentSpanNumber","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"span","type":"uint256"}],"name":"getValidatorsTotalStakeBySpan","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"span","type":"uint256"}],"name":"getProducersTotalStakeBySpan","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"span","type":"uint256"},{"internalType":"address","name":"signer","type":"address"}],"name":"getValidatorBySigner","outputs":[{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"power","type":"uint256"},{"internalType":"address","name":"signer","type":"address"}],"internalType":"struct BorValidatorSet.Validator","name":"result","type":"tuple"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"span","type":"uint256"},{"internalType":"address","name":"signer","type":"address"}],"name":"isValidator","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"span","type":"uint256"},{"internalType":"address","name":"signer","type":"address"}],"name":"isProducer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"signer","type":"address"}],"name":"isCurrentValidator","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"signer","type":"address"}],"name":"isCurrentProducer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"number","type":"uint256"}],"name":"getBorValidators","outputs":[{"internalType":"address[]","name":"","type":"address[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getInitialValidators","outputs":[{"internalType":"address[]","name":"","type":"address[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getValidators","outputs":[{"internalType":"address[]","name":"","type":"address[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"newSpan","type":"uint256"},{"internalType":"uint256","name":"startBlock","type":"uint256"},{"internalType":"uint256","name":"endBlock","type":"uint256"},{"internalType":"bytes","name":"validatorBytes","type":"bytes"},{"internalType":"bytes","name":"producerBytes","type":"bytes"}],"name":"commitSpan","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"span","type":"uint256"},{"internalType":"bytes32","name":"dataHash","type":"bytes32"},{"internalType":"bytes","name":"sigs","type":"bytes"}],"name":"getStakePowerBySigs","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"rootHash","type":"bytes32"},{"internalType":"bytes32","name":"leaf","type":"bytes32"},{"internalType":"bytes","name":"proof","type":"bytes"}],"name":"checkMembership","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"d","type":"bytes32"}],"name":"leafNode","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"left","type":"bytes32"},{"internalType":"bytes32","name":"right","type":"bytes32"}],"name":"innerNode","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"pure","type":"function"}]` - StateReceiverABI = `[{"constant":true,"inputs":[],"name":"SYSTEM_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"lastStateId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"syncTime","type":"uint256"},{"internalType":"bytes","name":"recordBytes","type":"bytes"}],"name":"commitState","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"}]` -) - -func NewGenesisContractsClient( - chainConfig *chain.Config, - validatorContract, - stateReceiverContract string, - logger log.Logger, -) *GenesisContractsClient { - return &GenesisContractsClient{ - validatorSetABI: ValidatorSet(), - stateReceiverABI: StateReceiver(), - ValidatorContract: libcommon.HexToAddress(validatorContract), - StateReceiverContract: libcommon.HexToAddress(stateReceiverContract), - chainConfig: chainConfig, - logger: logger, - } -} - -func (gc *GenesisContractsClient) CommitState(event rlp.RawValue, syscall consensus.SystemCall) error { - _, err := syscall(gc.StateReceiverContract, event) - return err -} - -func (gc *GenesisContractsClient) LastStateId(syscall consensus.SystemCall) (*big.Int, error) { - const method = "lastStateId" - - data, err := gc.stateReceiverABI.Pack(method) - if err != nil { - gc.logger.Error("[bor] Unable to pack tx for LastStateId", "err", err) - return nil, err - } - - result, err := syscall(gc.StateReceiverContract, data) - if err != nil { - return nil, err - } - - var ret = new(*big.Int) - if err := gc.stateReceiverABI.UnpackIntoInterface(ret, method, result); err != nil { - return nil, err - } - return *ret, nil -} diff --git a/polygon/bor/errors.go b/polygon/bor/errors.go index 1ee6fd9bd..7d57658ff 100644 --- a/polygon/bor/errors.go +++ b/polygon/bor/errors.go @@ -2,9 +2,6 @@ package bor import ( "fmt" - "time" - - "github.com/ledgerwatch/erigon/polygon/bor/clerk" ) type MaxCheckpointLengthExceededError struct { @@ -69,20 +66,3 @@ func (e *WrongDifficultyError) Error() string { e.Signer, ) } - -type InvalidStateReceivedError struct { - Number uint64 - LastStateID uint64 - To *time.Time - Event *clerk.EventRecordWithTime -} - -func (e *InvalidStateReceivedError) Error() string { - return fmt.Sprintf( - "Received invalid event %v at block %d. Requested events until %s. Last state id was %d", - e.Event, - e.Number, - e.To.Format(time.RFC3339), - e.LastStateID, - ) -} diff --git a/polygon/bor/finality/bor_verifier.go b/polygon/bor/finality/bor_verifier.go index 1cbb566e0..9a6da3203 100644 --- a/polygon/bor/finality/bor_verifier.go +++ b/polygon/bor/finality/bor_verifier.go @@ -10,7 +10,6 @@ import ( "github.com/ledgerwatch/erigon-lib/metrics" "github.com/ledgerwatch/erigon/core/rawdb" - "github.com/ledgerwatch/erigon/polygon/bor/finality/generics" "github.com/ledgerwatch/erigon/polygon/bor/finality/whitelist" ) @@ -161,5 +160,5 @@ func rewindBack(head uint64, rewindTo uint64) { // Chain cannot be rewinded from this routine // hence we are using a shared variable - generics.BorMilestoneRewind.Store(&rewindTo) + BorMilestoneRewind.Store(&rewindTo) } diff --git a/polygon/bor/finality/generics/generics.go b/polygon/bor/finality/generics/generics.go index d54b26fbb..7185ee893 100644 --- a/polygon/bor/finality/generics/generics.go +++ b/polygon/bor/finality/generics/generics.go @@ -1,8 +1,6 @@ package generics import ( - "sync/atomic" - libcommon "github.com/ledgerwatch/erigon-lib/common" "github.com/ledgerwatch/erigon/core/types" ) @@ -11,11 +9,6 @@ func Empty[T any]() (t T) { return } -// BorMilestoneRewind is used as a flag/variable -// Flag: if equals 0, no rewind according to bor whitelisting service -// Variable: if not equals 0, rewind chain back to BorMilestoneRewind -var BorMilestoneRewind atomic.Pointer[uint64] - type Response struct { Headers []*types.Header Hashes []libcommon.Hash diff --git a/polygon/bor/finality/milestone_rewind.go b/polygon/bor/finality/milestone_rewind.go new file mode 100644 index 000000000..772d91d98 --- /dev/null +++ b/polygon/bor/finality/milestone_rewind.go @@ -0,0 +1,12 @@ +package finality + +import "sync/atomic" + +// BorMilestoneRewind is used as a flag/variable +// Flag: if equals 0, no rewind according to bor whitelisting service +// Variable: if not equals 0, rewind chain back to BorMilestoneRewind +var BorMilestoneRewind atomic.Pointer[uint64] + +func IsMilestoneRewindPending() bool { + return BorMilestoneRewind.Load() != nil && *BorMilestoneRewind.Load() != 0 +} diff --git a/polygon/bor/finality/whitelist.go b/polygon/bor/finality/whitelist.go index 60a2731eb..97584eb6f 100644 --- a/polygon/bor/finality/whitelist.go +++ b/polygon/bor/finality/whitelist.go @@ -17,7 +17,7 @@ import ( ) type config struct { - heimdall heimdall.IHeimdallClient + heimdall heimdall.HeimdallClient borDB kv.RwDB chainDB kv.RwDB blockReader services.BlockReader @@ -30,7 +30,7 @@ type BorAPI interface { GetRootHash(start uint64, end uint64) (string, error) } -func Whitelist(heimdall heimdall.IHeimdallClient, borDB kv.RwDB, chainDB kv.RwDB, blockReader services.BlockReader, logger log.Logger, borAPI BorAPI, closeCh chan struct{}) { +func Whitelist(heimdall heimdall.HeimdallClient, borDB kv.RwDB, chainDB kv.RwDB, blockReader services.BlockReader, logger log.Logger, borAPI BorAPI, closeCh chan struct{}) { if !flags.Milestone { return } @@ -96,7 +96,7 @@ func startNoAckMilestoneByIDService(config *config) { RetryHeimdallHandler(handleNoAckMilestoneByID, config, tickerDuration, noAckMilestoneTimeout, fnName) } -type heimdallHandler func(ctx context.Context, heimdallClient heimdall.IHeimdallClient, config *config) error +type heimdallHandler func(ctx context.Context, heimdallClient heimdall.HeimdallClient, config *config) error func RetryHeimdallHandler(fn heimdallHandler, config *config, tickerDuration time.Duration, timeout time.Duration, fnName string) { retryHeimdallHandler(fn, config, tickerDuration, timeout, fnName) @@ -159,7 +159,7 @@ func retryHeimdallHandler(fn heimdallHandler, config *config, tickerDuration tim } // handleWhitelistCheckpoint handles the checkpoint whitelist mechanism. -func handleWhitelistCheckpoint(ctx context.Context, heimdallClient heimdall.IHeimdallClient, config *config) error { +func handleWhitelistCheckpoint(ctx context.Context, heimdallClient heimdall.HeimdallClient, config *config) error { service := whitelist.GetWhitelistingService() // Create a new bor verifier, which will be used to verify checkpoints and milestones @@ -179,7 +179,7 @@ func handleWhitelistCheckpoint(ctx context.Context, heimdallClient heimdall.IHei } // handleMilestone handles the milestone mechanism. -func handleMilestone(ctx context.Context, heimdallClient heimdall.IHeimdallClient, config *config) error { +func handleMilestone(ctx context.Context, heimdallClient heimdall.HeimdallClient, config *config) error { service := whitelist.GetWhitelistingService() // Create a new bor verifier, which will be used to verify checkpoints and milestones @@ -207,7 +207,7 @@ func handleMilestone(ctx context.Context, heimdallClient heimdall.IHeimdallClien return nil } -func handleNoAckMilestone(ctx context.Context, heimdallClient heimdall.IHeimdallClient, config *config) error { +func handleNoAckMilestone(ctx context.Context, heimdallClient heimdall.HeimdallClient, config *config) error { service := whitelist.GetWhitelistingService() milestoneID, err := fetchNoAckMilestone(ctx, heimdallClient, config.logger) @@ -224,7 +224,7 @@ func handleNoAckMilestone(ctx context.Context, heimdallClient heimdall.IHeimdall return nil } -func handleNoAckMilestoneByID(ctx context.Context, heimdallClient heimdall.IHeimdallClient, config *config) error { +func handleNoAckMilestoneByID(ctx context.Context, heimdallClient heimdall.HeimdallClient, config *config) error { service := whitelist.GetWhitelistingService() milestoneIDs := service.GetMilestoneIDsList() diff --git a/polygon/bor/finality/whitelist_helpers.go b/polygon/bor/finality/whitelist_helpers.go index b5d28cad0..f680c0d0f 100644 --- a/polygon/bor/finality/whitelist_helpers.go +++ b/polygon/bor/finality/whitelist_helpers.go @@ -26,7 +26,7 @@ var ( // fetchWhitelistCheckpoint fetches the latest checkpoint from it's local heimdall // and verifies the data against bor data. -func fetchWhitelistCheckpoint(ctx context.Context, heimdallClient heimdall.IHeimdallClient, verifier *borVerifier, config *config) (uint64, common.Hash, error) { +func fetchWhitelistCheckpoint(ctx context.Context, heimdallClient heimdall.HeimdallClient, verifier *borVerifier, config *config) (uint64, common.Hash, error) { var ( blockNum uint64 blockHash common.Hash @@ -66,7 +66,7 @@ func fetchWhitelistCheckpoint(ctx context.Context, heimdallClient heimdall.IHeim // fetchWhitelistMilestone fetches the latest milestone from it's local heimdall // and verifies the data against bor data. -func fetchWhitelistMilestone(ctx context.Context, heimdallClient heimdall.IHeimdallClient, verifier *borVerifier, config *config) (uint64, common.Hash, error) { +func fetchWhitelistMilestone(ctx context.Context, heimdallClient heimdall.HeimdallClient, verifier *borVerifier, config *config) (uint64, common.Hash, error) { var ( num uint64 hash common.Hash @@ -101,7 +101,7 @@ func fetchWhitelistMilestone(ctx context.Context, heimdallClient heimdall.IHeimd return num, hash, nil } -func fetchNoAckMilestone(ctx context.Context, heimdallClient heimdall.IHeimdallClient, logger log.Logger) (string, error) { +func fetchNoAckMilestone(ctx context.Context, heimdallClient heimdall.HeimdallClient, logger log.Logger) (string, error) { var ( milestoneID string ) @@ -120,7 +120,7 @@ func fetchNoAckMilestone(ctx context.Context, heimdallClient heimdall.IHeimdallC return milestoneID, nil } -func fetchNoAckMilestoneByID(ctx context.Context, heimdallClient heimdall.IHeimdallClient, milestoneID string, logger log.Logger) error { +func fetchNoAckMilestoneByID(ctx context.Context, heimdallClient heimdall.HeimdallClient, milestoneID string, logger log.Logger) error { err := heimdallClient.FetchNoAckMilestone(ctx, milestoneID) if errors.Is(err, heimdall.ErrServiceUnavailable) { logger.Debug("[bor.heimdall] Failed to fetch no-ack milestone by ID", "milestoneID", milestoneID, "err", err) diff --git a/polygon/bor/genesis_contract.go b/polygon/bor/genesis_contract.go deleted file mode 100644 index 7a232733b..000000000 --- a/polygon/bor/genesis_contract.go +++ /dev/null @@ -1,14 +0,0 @@ -package bor - -import ( - "math/big" - - "github.com/ledgerwatch/erigon/consensus" - "github.com/ledgerwatch/erigon/rlp" -) - -//go:generate mockgen -destination=./mock/genesis_contract_mock.go -package=mock . GenesisContract -type GenesisContract interface { - CommitState(event rlp.RawValue, syscall consensus.SystemCall) error - LastStateId(syscall consensus.SystemCall) (*big.Int, error) -} diff --git a/polygon/bor/genesis_contracts.go b/polygon/bor/genesis_contracts.go new file mode 100644 index 000000000..59af92c77 --- /dev/null +++ b/polygon/bor/genesis_contracts.go @@ -0,0 +1,87 @@ +package bor + +import ( + "math/big" + "strings" + + "github.com/ledgerwatch/log/v3" + + "github.com/ledgerwatch/erigon-lib/chain" + libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon/accounts/abi" + "github.com/ledgerwatch/erigon/consensus" + "github.com/ledgerwatch/erigon/rlp" +) + +const ( + validatorSetABIJSON = `[{"constant":true,"inputs":[],"name":"SPRINT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"SYSTEM_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"CHAIN","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"FIRST_END_BLOCK","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"producers","outputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"power","type":"uint256"},{"internalType":"address","name":"signer","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"ROUND_TYPE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"BOR_ID","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"spanNumbers","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"VOTE_TYPE","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"validators","outputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"power","type":"uint256"},{"internalType":"address","name":"signer","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"spans","outputs":[{"internalType":"uint256","name":"number","type":"uint256"},{"internalType":"uint256","name":"startBlock","type":"uint256"},{"internalType":"uint256","name":"endBlock","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"startBlock","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"endBlock","type":"uint256"}],"name":"NewSpan","type":"event"},{"constant":true,"inputs":[],"name":"currentSprint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"span","type":"uint256"}],"name":"getSpan","outputs":[{"internalType":"uint256","name":"number","type":"uint256"},{"internalType":"uint256","name":"startBlock","type":"uint256"},{"internalType":"uint256","name":"endBlock","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getCurrentSpan","outputs":[{"internalType":"uint256","name":"number","type":"uint256"},{"internalType":"uint256","name":"startBlock","type":"uint256"},{"internalType":"uint256","name":"endBlock","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getNextSpan","outputs":[{"internalType":"uint256","name":"number","type":"uint256"},{"internalType":"uint256","name":"startBlock","type":"uint256"},{"internalType":"uint256","name":"endBlock","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"number","type":"uint256"}],"name":"getSpanByBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"currentSpanNumber","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"span","type":"uint256"}],"name":"getValidatorsTotalStakeBySpan","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"span","type":"uint256"}],"name":"getProducersTotalStakeBySpan","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"span","type":"uint256"},{"internalType":"address","name":"signer","type":"address"}],"name":"getValidatorBySigner","outputs":[{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"power","type":"uint256"},{"internalType":"address","name":"signer","type":"address"}],"internalType":"struct BorValidatorSet.Validator","name":"result","type":"tuple"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"span","type":"uint256"},{"internalType":"address","name":"signer","type":"address"}],"name":"isValidator","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"span","type":"uint256"},{"internalType":"address","name":"signer","type":"address"}],"name":"isProducer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"signer","type":"address"}],"name":"isCurrentValidator","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"signer","type":"address"}],"name":"isCurrentProducer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"number","type":"uint256"}],"name":"getBorValidators","outputs":[{"internalType":"address[]","name":"","type":"address[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getInitialValidators","outputs":[{"internalType":"address[]","name":"","type":"address[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getValidators","outputs":[{"internalType":"address[]","name":"","type":"address[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"newSpan","type":"uint256"},{"internalType":"uint256","name":"startBlock","type":"uint256"},{"internalType":"uint256","name":"endBlock","type":"uint256"},{"internalType":"bytes","name":"validatorBytes","type":"bytes"},{"internalType":"bytes","name":"producerBytes","type":"bytes"}],"name":"commitSpan","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"span","type":"uint256"},{"internalType":"bytes32","name":"dataHash","type":"bytes32"},{"internalType":"bytes","name":"sigs","type":"bytes"}],"name":"getStakePowerBySigs","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"rootHash","type":"bytes32"},{"internalType":"bytes32","name":"leaf","type":"bytes32"},{"internalType":"bytes","name":"proof","type":"bytes"}],"name":"checkMembership","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"d","type":"bytes32"}],"name":"leafNode","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"left","type":"bytes32"},{"internalType":"bytes32","name":"right","type":"bytes32"}],"name":"innerNode","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"pure","type":"function"}]` + stateReceiverABIJSON = `[{"constant":true,"inputs":[],"name":"SYSTEM_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"lastStateId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"syncTime","type":"uint256"},{"internalType":"bytes","name":"recordBytes","type":"bytes"}],"name":"commitState","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"}]` +) + +var ( + validatorSetABI, _ = abi.JSON(strings.NewReader(validatorSetABIJSON)) + stateReceiverABI, _ = abi.JSON(strings.NewReader(stateReceiverABIJSON)) +) + +func GenesisContractValidatorSetABI() abi.ABI { + return validatorSetABI +} +func GenesisContractStateReceiverABI() abi.ABI { + return stateReceiverABI +} + +type GenesisContracts interface { + CommitState(event rlp.RawValue, syscall consensus.SystemCall) error + LastStateId(syscall consensus.SystemCall) (*big.Int, error) +} + +type GenesisContractsClient struct { + validatorSetABI abi.ABI + stateReceiverABI abi.ABI + ValidatorContract libcommon.Address + StateReceiverContract libcommon.Address + chainConfig *chain.Config + logger log.Logger +} + +func NewGenesisContractsClient( + chainConfig *chain.Config, + validatorContract, + stateReceiverContract string, + logger log.Logger, +) *GenesisContractsClient { + return &GenesisContractsClient{ + validatorSetABI: GenesisContractValidatorSetABI(), + stateReceiverABI: GenesisContractStateReceiverABI(), + ValidatorContract: libcommon.HexToAddress(validatorContract), + StateReceiverContract: libcommon.HexToAddress(stateReceiverContract), + chainConfig: chainConfig, + logger: logger, + } +} + +func (gc *GenesisContractsClient) CommitState(event rlp.RawValue, syscall consensus.SystemCall) error { + _, err := syscall(gc.StateReceiverContract, event) + return err +} + +func (gc *GenesisContractsClient) LastStateId(syscall consensus.SystemCall) (*big.Int, error) { + const method = "lastStateId" + + data, err := gc.stateReceiverABI.Pack(method) + if err != nil { + gc.logger.Error("[bor] Unable to pack tx for LastStateId", "err", err) + return nil, err + } + + result, err := syscall(gc.StateReceiverContract, data) + if err != nil { + return nil, err + } + + var ret = new(*big.Int) + if err := gc.stateReceiverABI.UnpackIntoInterface(ret, method, result); err != nil { + return nil, err + } + return *ret, nil +} diff --git a/polygon/bor/mock/genesis_contract_mock.go b/polygon/bor/mock/genesis_contract_mock.go deleted file mode 100644 index 475ae6ece..000000000 --- a/polygon/bor/mock/genesis_contract_mock.go +++ /dev/null @@ -1,66 +0,0 @@ -// Code generated by MockGen. DO NOT EDIT. -// Source: github.com/ledgerwatch/erigon/polygon/bor (interfaces: GenesisContract) - -// Package mock is a generated GoMock package. -package mock - -import ( - big "math/big" - reflect "reflect" - - gomock "github.com/golang/mock/gomock" - consensus "github.com/ledgerwatch/erigon/consensus" - rlp "github.com/ledgerwatch/erigon/rlp" -) - -// MockGenesisContract is a mock of GenesisContract interface. -type MockGenesisContract struct { - ctrl *gomock.Controller - recorder *MockGenesisContractMockRecorder -} - -// MockGenesisContractMockRecorder is the mock recorder for MockGenesisContract. -type MockGenesisContractMockRecorder struct { - mock *MockGenesisContract -} - -// NewMockGenesisContract creates a new mock instance. -func NewMockGenesisContract(ctrl *gomock.Controller) *MockGenesisContract { - mock := &MockGenesisContract{ctrl: ctrl} - mock.recorder = &MockGenesisContractMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockGenesisContract) EXPECT() *MockGenesisContractMockRecorder { - return m.recorder -} - -// CommitState mocks base method. -func (m *MockGenesisContract) CommitState(arg0 rlp.RawValue, arg1 consensus.SystemCall) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "CommitState", arg0, arg1) - ret0, _ := ret[0].(error) - return ret0 -} - -// CommitState indicates an expected call of CommitState. -func (mr *MockGenesisContractMockRecorder) CommitState(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CommitState", reflect.TypeOf((*MockGenesisContract)(nil).CommitState), arg0, arg1) -} - -// LastStateId mocks base method. -func (m *MockGenesisContract) LastStateId(arg0 consensus.SystemCall) (*big.Int, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "LastStateId", arg0) - ret0, _ := ret[0].(*big.Int) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// LastStateId indicates an expected call of LastStateId. -func (mr *MockGenesisContractMockRecorder) LastStateId(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LastStateId", reflect.TypeOf((*MockGenesisContract)(nil).LastStateId), arg0) -} diff --git a/polygon/heimdall/span/span_id.go b/polygon/bor/span_id.go similarity index 50% rename from polygon/heimdall/span/span_id.go rename to polygon/bor/span_id.go index 0485aa6fb..1c9348b6e 100644 --- a/polygon/heimdall/span/span_id.go +++ b/polygon/bor/span_id.go @@ -1,4 +1,4 @@ -package span +package bor import ( "github.com/ledgerwatch/erigon/polygon/bor/borcfg" @@ -9,26 +9,26 @@ const ( zerothSpanEnd = 255 // End block of 0th span ) -// IDAt returns the corresponding span id for the given block number. -func IDAt(blockNum uint64) uint64 { +// SpanIDAt returns the corresponding span id for the given block number. +func SpanIDAt(blockNum uint64) uint64 { if blockNum > zerothSpanEnd { return 1 + (blockNum-zerothSpanEnd-1)/spanLength } return 0 } -// EndBlockNum returns the number of the last block in the given span. -func EndBlockNum(spanID uint64) uint64 { +// SpanEndBlockNum returns the number of the last block in the given span. +func SpanEndBlockNum(spanID uint64) uint64 { if spanID > 0 { return spanID*spanLength + zerothSpanEnd } return zerothSpanEnd } -// BlockInLastSprintOfSpan returns true if a block num is within the last sprint of a span and false otherwise. -func BlockInLastSprintOfSpan(blockNum uint64, config *borcfg.BorConfig) bool { - spanNum := IDAt(blockNum) - endBlockNum := EndBlockNum(spanNum) +// IsBlockInLastSprintOfSpan returns true if a block num is within the last sprint of a span and false otherwise. +func IsBlockInLastSprintOfSpan(blockNum uint64, config *borcfg.BorConfig) bool { + spanNum := SpanIDAt(blockNum) + endBlockNum := SpanEndBlockNum(spanNum) sprintLen := config.CalculateSprintLength(blockNum) startBlockNum := endBlockNum - sprintLen + 1 return startBlockNum <= blockNum && blockNum <= endBlockNum diff --git a/polygon/bor/span_id_test.go b/polygon/bor/span_id_test.go new file mode 100644 index 000000000..328148657 --- /dev/null +++ b/polygon/bor/span_id_test.go @@ -0,0 +1,44 @@ +package bor + +import ( + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/ledgerwatch/erigon/polygon/bor/borcfg" +) + +func TestSpanIDAt(t *testing.T) { + assert.Equal(t, uint64(0), SpanIDAt(0)) + assert.Equal(t, uint64(0), SpanIDAt(1)) + assert.Equal(t, uint64(0), SpanIDAt(2)) + assert.Equal(t, uint64(0), SpanIDAt(zerothSpanEnd)) + assert.Equal(t, uint64(1), SpanIDAt(zerothSpanEnd+1)) + assert.Equal(t, uint64(1), SpanIDAt(zerothSpanEnd+2)) + assert.Equal(t, uint64(1), SpanIDAt(6655)) + assert.Equal(t, uint64(2), SpanIDAt(6656)) + assert.Equal(t, uint64(2), SpanIDAt(6657)) + assert.Equal(t, uint64(2), SpanIDAt(13055)) + assert.Equal(t, uint64(3), SpanIDAt(13056)) + assert.Equal(t, uint64(6839), SpanIDAt(43763456)) +} + +func TestSpanEndBlockNum(t *testing.T) { + assert.Equal(t, uint64(zerothSpanEnd), SpanEndBlockNum(0)) + assert.Equal(t, uint64(6655), SpanEndBlockNum(1)) + assert.Equal(t, uint64(13055), SpanEndBlockNum(2)) + assert.Equal(t, uint64(43769855), SpanEndBlockNum(6839)) +} + +func TestBlockInLastSprintOfSpan(t *testing.T) { + config := &borcfg.BorConfig{ + Sprint: map[string]uint64{ + "0": 16, + }, + } + assert.True(t, IsBlockInLastSprintOfSpan(6640, config)) + assert.True(t, IsBlockInLastSprintOfSpan(6645, config)) + assert.True(t, IsBlockInLastSprintOfSpan(6655, config)) + assert.False(t, IsBlockInLastSprintOfSpan(6639, config)) + assert.False(t, IsBlockInLastSprintOfSpan(6656, config)) +} diff --git a/polygon/bor/spanner.go b/polygon/bor/spanner.go index ab7710dd5..728bc20f2 100644 --- a/polygon/bor/spanner.go +++ b/polygon/bor/spanner.go @@ -1,17 +1,173 @@ package bor import ( - "github.com/ledgerwatch/erigon/polygon/heimdall/span" + "encoding/hex" + "encoding/json" + "math/big" + "github.com/ledgerwatch/log/v3" + + "github.com/ledgerwatch/erigon-lib/chain" libcommon "github.com/ledgerwatch/erigon-lib/common" "github.com/ledgerwatch/erigon/consensus" + "github.com/ledgerwatch/erigon/polygon/bor/borcfg" "github.com/ledgerwatch/erigon/polygon/bor/valset" + "github.com/ledgerwatch/erigon/polygon/heimdall" + "github.com/ledgerwatch/erigon/rlp" ) -//go:generate mockgen -destination=./mock/spanner_mock.go -package=mock . Spanner +//go:generate mockgen -destination=./spanner_mock.go -package=bor . Spanner type Spanner interface { - GetCurrentSpan(syscall consensus.SystemCall) (*span.Span, error) + GetCurrentSpan(syscall consensus.SystemCall) (*heimdall.Span, error) GetCurrentValidators(spanId uint64, signer libcommon.Address, chain consensus.ChainHeaderReader) ([]*valset.Validator, error) GetCurrentProducers(spanId uint64, signer libcommon.Address, chain consensus.ChainHeaderReader) ([]*valset.Validator, error) - CommitSpan(heimdallSpan span.HeimdallSpan, syscall consensus.SystemCall) error + CommitSpan(heimdallSpan heimdall.HeimdallSpan, syscall consensus.SystemCall) error +} + +type ABI interface { + Pack(name string, args ...interface{}) ([]byte, error) + UnpackIntoInterface(v interface{}, name string, data []byte) error +} + +type ChainSpanner struct { + validatorSet ABI + chainConfig *chain.Config + borConfig *borcfg.BorConfig + logger log.Logger + withoutHeimdall bool +} + +func NewChainSpanner(validatorSet ABI, chainConfig *chain.Config, withoutHeimdall bool, logger log.Logger) *ChainSpanner { + borConfig := chainConfig.Bor.(*borcfg.BorConfig) + return &ChainSpanner{ + validatorSet: validatorSet, + chainConfig: chainConfig, + borConfig: borConfig, + logger: logger, + withoutHeimdall: withoutHeimdall, + } +} + +// GetCurrentSpan get current span from contract +func (c *ChainSpanner) GetCurrentSpan(syscall consensus.SystemCall) (*heimdall.Span, error) { + + // method + const method = "getCurrentSpan" + + data, err := c.validatorSet.Pack(method) + if err != nil { + c.logger.Error("[bor] Unable to pack tx for getCurrentSpan", "error", err) + return nil, err + } + + result, err := syscall(libcommon.HexToAddress(c.borConfig.ValidatorContract), data) + if err != nil { + return nil, err + } + + // span result + ret := new(struct { + Number *big.Int + StartBlock *big.Int + EndBlock *big.Int + }) + + if err := c.validatorSet.UnpackIntoInterface(ret, method, result); err != nil { + return nil, err + } + + // create new span + span := heimdall.Span{ + ID: ret.Number.Uint64(), + StartBlock: ret.StartBlock.Uint64(), + EndBlock: ret.EndBlock.Uint64(), + } + + return &span, nil +} + +func (c *ChainSpanner) GetCurrentValidators(spanId uint64, signer libcommon.Address, chain consensus.ChainHeaderReader) ([]*valset.Validator, error) { + // Use hardcoded bor devnet valset if chain-name = bor-devnet + if NetworkNameVals[c.chainConfig.ChainName] != nil && c.withoutHeimdall { + return NetworkNameVals[c.chainConfig.ChainName], nil + } + + spanBytes := chain.BorSpan(spanId) + var span heimdall.HeimdallSpan + if err := json.Unmarshal(spanBytes, &span); err != nil { + return nil, err + } + + return span.ValidatorSet.Validators, nil +} + +func (c *ChainSpanner) GetCurrentProducers(spanId uint64, signer libcommon.Address, chain consensus.ChainHeaderReader) ([]*valset.Validator, error) { + // Use hardcoded bor devnet valset if chain-name = bor-devnet + if NetworkNameVals[c.chainConfig.ChainName] != nil && c.withoutHeimdall { + return NetworkNameVals[c.chainConfig.ChainName], nil + } + + spanBytes := chain.BorSpan(spanId) + var span heimdall.HeimdallSpan + if err := json.Unmarshal(spanBytes, &span); err != nil { + return nil, err + } + + producers := make([]*valset.Validator, len(span.SelectedProducers)) + for i := range span.SelectedProducers { + producers[i] = &span.SelectedProducers[i] + } + + return producers, nil +} + +func (c *ChainSpanner) CommitSpan(heimdallSpan heimdall.HeimdallSpan, syscall consensus.SystemCall) error { + + // method + const method = "commitSpan" + + // get validators bytes + validators := make([]valset.MinimalVal, 0, len(heimdallSpan.ValidatorSet.Validators)) + for _, val := range heimdallSpan.ValidatorSet.Validators { + validators = append(validators, val.MinimalVal()) + } + validatorBytes, err := rlp.EncodeToBytes(validators) + if err != nil { + return err + } + + // get producers bytes + producers := make([]valset.MinimalVal, 0, len(heimdallSpan.SelectedProducers)) + for _, val := range heimdallSpan.SelectedProducers { + producers = append(producers, val.MinimalVal()) + } + producerBytes, err := rlp.EncodeToBytes(producers) + if err != nil { + return err + } + + c.logger.Debug("[bor] ✅ Committing new span", + "id", heimdallSpan.ID, + "startBlock", heimdallSpan.StartBlock, + "endBlock", heimdallSpan.EndBlock, + "validatorBytes", hex.EncodeToString(validatorBytes), + "producerBytes", hex.EncodeToString(producerBytes), + ) + + // get packed data + data, err := c.validatorSet.Pack(method, + big.NewInt(0).SetUint64(heimdallSpan.ID), + big.NewInt(0).SetUint64(heimdallSpan.StartBlock), + big.NewInt(0).SetUint64(heimdallSpan.EndBlock), + validatorBytes, + producerBytes, + ) + if err != nil { + c.logger.Error("[bor] Unable to pack tx for commitSpan", "error", err) + return err + } + + _, err = syscall(libcommon.HexToAddress(c.borConfig.ValidatorContract), data) + + return err } diff --git a/polygon/bor/mock/spanner_mock.go b/polygon/bor/spanner_mock.go similarity index 92% rename from polygon/bor/mock/spanner_mock.go rename to polygon/bor/spanner_mock.go index 07c9b881b..45d65a517 100644 --- a/polygon/bor/mock/spanner_mock.go +++ b/polygon/bor/spanner_mock.go @@ -1,8 +1,8 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ledgerwatch/erigon/polygon/bor (interfaces: Spanner) -// Package mock is a generated GoMock package. -package mock +// Package bor is a generated GoMock package. +package bor import ( reflect "reflect" @@ -10,8 +10,8 @@ import ( gomock "github.com/golang/mock/gomock" common "github.com/ledgerwatch/erigon-lib/common" consensus "github.com/ledgerwatch/erigon/consensus" - span "github.com/ledgerwatch/erigon/polygon/heimdall/span" valset "github.com/ledgerwatch/erigon/polygon/bor/valset" + heimdall "github.com/ledgerwatch/erigon/polygon/heimdall" ) // MockSpanner is a mock of Spanner interface. @@ -38,7 +38,7 @@ func (m *MockSpanner) EXPECT() *MockSpannerMockRecorder { } // CommitSpan mocks base method. -func (m *MockSpanner) CommitSpan(arg0 span.HeimdallSpan, arg1 consensus.SystemCall) error { +func (m *MockSpanner) CommitSpan(arg0 heimdall.HeimdallSpan, arg1 consensus.SystemCall) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "CommitSpan", arg0, arg1) ret0, _ := ret[0].(error) @@ -67,10 +67,10 @@ func (mr *MockSpannerMockRecorder) GetCurrentProducers(arg0, arg1, arg2 interfac } // GetCurrentSpan mocks base method. -func (m *MockSpanner) GetCurrentSpan(arg0 consensus.SystemCall) (*span.Span, error) { +func (m *MockSpanner) GetCurrentSpan(arg0 consensus.SystemCall) (*heimdall.Span, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetCurrentSpan", arg0) - ret0, _ := ret[0].(*span.Span) + ret0, _ := ret[0].(*heimdall.Span) ret1, _ := ret[1].(error) return ret0, ret1 } diff --git a/polygon/heimdall/span/testValidators.go b/polygon/bor/spanner_test_validators.go similarity index 98% rename from polygon/heimdall/span/testValidators.go rename to polygon/bor/spanner_test_validators.go index 1dfaa722e..7cc3d5d3e 100644 --- a/polygon/heimdall/span/testValidators.go +++ b/polygon/bor/spanner_test_validators.go @@ -1,4 +1,4 @@ -package span +package bor import ( "github.com/ledgerwatch/erigon-lib/chain/networkname" diff --git a/polygon/heimdall/checkpoint/checkpoint.go b/polygon/heimdall/checkpoint.go similarity index 98% rename from polygon/heimdall/checkpoint/checkpoint.go rename to polygon/heimdall/checkpoint.go index ebced7bee..267bb7d8b 100644 --- a/polygon/heimdall/checkpoint/checkpoint.go +++ b/polygon/heimdall/checkpoint.go @@ -1,4 +1,4 @@ -package checkpoint +package heimdall import ( "fmt" diff --git a/polygon/heimdall/client.go b/polygon/heimdall/client.go index 6b2f83c6f..263390580 100644 --- a/polygon/heimdall/client.go +++ b/polygon/heimdall/client.go @@ -15,12 +15,7 @@ import ( "github.com/ledgerwatch/log/v3" - "github.com/ledgerwatch/erigon/polygon/heimdall/checkpoint" - "github.com/ledgerwatch/erigon/polygon/heimdall/milestone" - "github.com/ledgerwatch/erigon/polygon/heimdall/span" - "github.com/ledgerwatch/erigon-lib/metrics" - "github.com/ledgerwatch/erigon/polygon/bor/clerk" ) var ( @@ -40,14 +35,25 @@ const ( maxRetries = 5 ) -type StateSyncEventsResponse struct { - Height string `json:"height"` - Result []*clerk.EventRecordWithTime `json:"result"` -} +//go:generate mockgen -destination=./client_mock.go -package=heimdall . HeimdallClient +type HeimdallClient interface { + StateSyncEvents(ctx context.Context, fromID uint64, to int64) ([]*EventRecordWithTime, error) + Span(ctx context.Context, spanID uint64) (*HeimdallSpan, error) + FetchCheckpoint(ctx context.Context, number int64) (*Checkpoint, error) + FetchCheckpointCount(ctx context.Context) (int64, error) + FetchMilestone(ctx context.Context, number int64) (*Milestone, error) + FetchMilestoneCount(ctx context.Context) (int64, error) -type SpanResponse struct { - Height string `json:"height"` - Result span.HeimdallSpan `json:"result"` + // FetchNoAckMilestone fetches a bool value whether milestone corresponding to the given id failed in the Heimdall + FetchNoAckMilestone(ctx context.Context, milestoneID string) error + + // FetchLastNoAckMilestone fetches the latest failed milestone id + FetchLastNoAckMilestone(ctx context.Context) (string, error) + + // FetchMilestoneID fetches a bool value whether milestone corresponding to the given id is in process in Heimdall + FetchMilestoneID(ctx context.Context, milestoneID string) error + + Close() } type Client struct { @@ -65,7 +71,7 @@ type Request struct { start time.Time } -//go:generate mockgen -destination=./mock/http_client_mock.go -package=mock . HttpClient +//go:generate mockgen -destination=./http_client_mock.go -package=heimdall . HttpClient type HttpClient interface { Do(req *http.Request) (*http.Response, error) CloseIdleConnections() @@ -107,8 +113,8 @@ const ( fetchSpanFormat = "bor/span/%d" ) -func (c *Client) StateSyncEvents(ctx context.Context, fromID uint64, to int64) ([]*clerk.EventRecordWithTime, error) { - eventRecords := make([]*clerk.EventRecordWithTime, 0) +func (c *Client) StateSyncEvents(ctx context.Context, fromID uint64, to int64) ([]*EventRecordWithTime, error) { + eventRecords := make([]*EventRecordWithTime, 0) for { url, err := stateSyncURL(c.urlString, fromID, to) @@ -154,7 +160,7 @@ func (c *Client) StateSyncEvents(ctx context.Context, fromID uint64, to int64) ( return eventRecords, nil } -func (c *Client) Span(ctx context.Context, spanID uint64) (*span.HeimdallSpan, error) { +func (c *Client) Span(ctx context.Context, spanID uint64) (*HeimdallSpan, error) { url, err := spanURL(c.urlString, spanID) if err != nil { return nil, err @@ -171,7 +177,7 @@ func (c *Client) Span(ctx context.Context, spanID uint64) (*span.HeimdallSpan, e } // FetchCheckpoint fetches the checkpoint from heimdall -func (c *Client) FetchCheckpoint(ctx context.Context, number int64) (*checkpoint.Checkpoint, error) { +func (c *Client) FetchCheckpoint(ctx context.Context, number int64) (*Checkpoint, error) { url, err := checkpointURL(c.urlString, number) if err != nil { return nil, err @@ -179,7 +185,7 @@ func (c *Client) FetchCheckpoint(ctx context.Context, number int64) (*checkpoint ctx = withRequestType(ctx, checkpointRequest) - response, err := FetchWithRetry[checkpoint.CheckpointResponse](ctx, c, url) + response, err := FetchWithRetry[CheckpointResponse](ctx, c, url) if err != nil { return nil, err } @@ -193,7 +199,7 @@ func isInvalidMilestoneIndexError(err error) bool { } // FetchMilestone fetches a milestone from heimdall -func (c *Client) FetchMilestone(ctx context.Context, number int64) (*milestone.Milestone, error) { +func (c *Client) FetchMilestone(ctx context.Context, number int64) (*Milestone, error) { url, err := milestoneURL(c.urlString, number) if err != nil { return nil, err @@ -205,7 +211,7 @@ func (c *Client) FetchMilestone(ctx context.Context, number int64) (*milestone.M return !isInvalidMilestoneIndexError(err) } - response, err := FetchWithRetryEx[milestone.MilestoneResponse](ctx, c, url, isRecoverableError) + response, err := FetchWithRetryEx[MilestoneResponse](ctx, c, url, isRecoverableError) if err != nil { if isInvalidMilestoneIndexError(err) { return nil, fmt.Errorf("%w: number %d", ErrNotInMilestoneList, number) @@ -225,7 +231,7 @@ func (c *Client) FetchCheckpointCount(ctx context.Context) (int64, error) { ctx = withRequestType(ctx, checkpointCountRequest) - response, err := FetchWithRetry[checkpoint.CheckpointCountResponse](ctx, c, url) + response, err := FetchWithRetry[CheckpointCountResponse](ctx, c, url) if err != nil { return 0, err } @@ -242,7 +248,7 @@ func (c *Client) FetchMilestoneCount(ctx context.Context) (int64, error) { ctx = withRequestType(ctx, milestoneCountRequest) - response, err := FetchWithRetry[milestone.MilestoneCountResponse](ctx, c, url) + response, err := FetchWithRetry[MilestoneCountResponse](ctx, c, url) if err != nil { return 0, err } @@ -259,7 +265,7 @@ func (c *Client) FetchLastNoAckMilestone(ctx context.Context) (string, error) { ctx = withRequestType(ctx, milestoneLastNoAckRequest) - response, err := FetchWithRetry[milestone.MilestoneLastNoAckResponse](ctx, c, url) + response, err := FetchWithRetry[MilestoneLastNoAckResponse](ctx, c, url) if err != nil { return "", err } @@ -276,7 +282,7 @@ func (c *Client) FetchNoAckMilestone(ctx context.Context, milestoneID string) er ctx = withRequestType(ctx, milestoneNoAckRequest) - response, err := FetchWithRetry[milestone.MilestoneNoAckResponse](ctx, c, url) + response, err := FetchWithRetry[MilestoneNoAckResponse](ctx, c, url) if err != nil { return err } @@ -298,7 +304,7 @@ func (c *Client) FetchMilestoneID(ctx context.Context, milestoneID string) error ctx = withRequestType(ctx, milestoneIDRequest) - response, err := FetchWithRetry[milestone.MilestoneIDResponse](ctx, c, url) + response, err := FetchWithRetry[MilestoneIDResponse](ctx, c, url) if err != nil { return err diff --git a/polygon/heimdall/client_mock.go b/polygon/heimdall/client_mock.go new file mode 100644 index 000000000..352ae1b5f --- /dev/null +++ b/polygon/heimdall/client_mock.go @@ -0,0 +1,180 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/ledgerwatch/erigon/polygon/heimdall (interfaces: HeimdallClient) + +// Package heimdall is a generated GoMock package. +package heimdall + +import ( + context "context" + reflect "reflect" + + gomock "github.com/golang/mock/gomock" +) + +// MockHeimdallClient is a mock of HeimdallClient interface. +type MockHeimdallClient struct { + ctrl *gomock.Controller + recorder *MockHeimdallClientMockRecorder +} + +// MockHeimdallClientMockRecorder is the mock recorder for MockHeimdallClient. +type MockHeimdallClientMockRecorder struct { + mock *MockHeimdallClient +} + +// NewMockHeimdallClient creates a new mock instance. +func NewMockHeimdallClient(ctrl *gomock.Controller) *MockHeimdallClient { + mock := &MockHeimdallClient{ctrl: ctrl} + mock.recorder = &MockHeimdallClientMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockHeimdallClient) EXPECT() *MockHeimdallClientMockRecorder { + return m.recorder +} + +// Close mocks base method. +func (m *MockHeimdallClient) Close() { + m.ctrl.T.Helper() + m.ctrl.Call(m, "Close") +} + +// Close indicates an expected call of Close. +func (mr *MockHeimdallClientMockRecorder) Close() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockHeimdallClient)(nil).Close)) +} + +// FetchCheckpoint mocks base method. +func (m *MockHeimdallClient) FetchCheckpoint(arg0 context.Context, arg1 int64) (*Checkpoint, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "FetchCheckpoint", arg0, arg1) + ret0, _ := ret[0].(*Checkpoint) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// FetchCheckpoint indicates an expected call of FetchCheckpoint. +func (mr *MockHeimdallClientMockRecorder) FetchCheckpoint(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FetchCheckpoint", reflect.TypeOf((*MockHeimdallClient)(nil).FetchCheckpoint), arg0, arg1) +} + +// FetchCheckpointCount mocks base method. +func (m *MockHeimdallClient) FetchCheckpointCount(arg0 context.Context) (int64, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "FetchCheckpointCount", arg0) + ret0, _ := ret[0].(int64) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// FetchCheckpointCount indicates an expected call of FetchCheckpointCount. +func (mr *MockHeimdallClientMockRecorder) FetchCheckpointCount(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FetchCheckpointCount", reflect.TypeOf((*MockHeimdallClient)(nil).FetchCheckpointCount), arg0) +} + +// FetchLastNoAckMilestone mocks base method. +func (m *MockHeimdallClient) FetchLastNoAckMilestone(arg0 context.Context) (string, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "FetchLastNoAckMilestone", arg0) + ret0, _ := ret[0].(string) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// FetchLastNoAckMilestone indicates an expected call of FetchLastNoAckMilestone. +func (mr *MockHeimdallClientMockRecorder) FetchLastNoAckMilestone(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FetchLastNoAckMilestone", reflect.TypeOf((*MockHeimdallClient)(nil).FetchLastNoAckMilestone), arg0) +} + +// FetchMilestone mocks base method. +func (m *MockHeimdallClient) FetchMilestone(arg0 context.Context, arg1 int64) (*Milestone, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "FetchMilestone", arg0, arg1) + ret0, _ := ret[0].(*Milestone) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// FetchMilestone indicates an expected call of FetchMilestone. +func (mr *MockHeimdallClientMockRecorder) FetchMilestone(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FetchMilestone", reflect.TypeOf((*MockHeimdallClient)(nil).FetchMilestone), arg0, arg1) +} + +// FetchMilestoneCount mocks base method. +func (m *MockHeimdallClient) FetchMilestoneCount(arg0 context.Context) (int64, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "FetchMilestoneCount", arg0) + ret0, _ := ret[0].(int64) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// FetchMilestoneCount indicates an expected call of FetchMilestoneCount. +func (mr *MockHeimdallClientMockRecorder) FetchMilestoneCount(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FetchMilestoneCount", reflect.TypeOf((*MockHeimdallClient)(nil).FetchMilestoneCount), arg0) +} + +// FetchMilestoneID mocks base method. +func (m *MockHeimdallClient) FetchMilestoneID(arg0 context.Context, arg1 string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "FetchMilestoneID", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// FetchMilestoneID indicates an expected call of FetchMilestoneID. +func (mr *MockHeimdallClientMockRecorder) FetchMilestoneID(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FetchMilestoneID", reflect.TypeOf((*MockHeimdallClient)(nil).FetchMilestoneID), arg0, arg1) +} + +// FetchNoAckMilestone mocks base method. +func (m *MockHeimdallClient) FetchNoAckMilestone(arg0 context.Context, arg1 string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "FetchNoAckMilestone", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// FetchNoAckMilestone indicates an expected call of FetchNoAckMilestone. +func (mr *MockHeimdallClientMockRecorder) FetchNoAckMilestone(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FetchNoAckMilestone", reflect.TypeOf((*MockHeimdallClient)(nil).FetchNoAckMilestone), arg0, arg1) +} + +// Span mocks base method. +func (m *MockHeimdallClient) Span(arg0 context.Context, arg1 uint64) (*HeimdallSpan, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Span", arg0, arg1) + ret0, _ := ret[0].(*HeimdallSpan) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Span indicates an expected call of Span. +func (mr *MockHeimdallClientMockRecorder) Span(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Span", reflect.TypeOf((*MockHeimdallClient)(nil).Span), arg0, arg1) +} + +// StateSyncEvents mocks base method. +func (m *MockHeimdallClient) StateSyncEvents(arg0 context.Context, arg1 uint64, arg2 int64) ([]*EventRecordWithTime, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateSyncEvents", arg0, arg1, arg2) + ret0, _ := ret[0].([]*EventRecordWithTime) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateSyncEvents indicates an expected call of StateSyncEvents. +func (mr *MockHeimdallClientMockRecorder) StateSyncEvents(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateSyncEvents", reflect.TypeOf((*MockHeimdallClient)(nil).StateSyncEvents), arg0, arg1, arg2) +} diff --git a/polygon/heimdall/client_test.go b/polygon/heimdall/client_test.go index b8804bba6..19638dab8 100644 --- a/polygon/heimdall/client_test.go +++ b/polygon/heimdall/client_test.go @@ -11,8 +11,6 @@ import ( "github.com/ledgerwatch/log/v3" "github.com/stretchr/testify/require" - "github.com/ledgerwatch/erigon/polygon/heimdall/mock" - "github.com/ledgerwatch/erigon/turbo/testlog" ) @@ -29,7 +27,7 @@ func (ebrc emptyBodyReadCloser) Close() error { func TestHeimdallClientFetchesTerminateUponTooManyErrors(t *testing.T) { ctx := context.Background() ctrl := gomock.NewController(t) - httpClient := mock.NewMockHttpClient(ctrl) + httpClient := NewMockHttpClient(ctrl) httpClient.EXPECT(). Do(gomock.Any()). Return(&http.Response{ @@ -48,7 +46,7 @@ func TestHeimdallClientFetchesTerminateUponTooManyErrors(t *testing.T) { func TestHeimdallClientStateSyncEventsReturnsErrNoResponseWhenHttp200WithEmptyBody(t *testing.T) { ctx := context.Background() ctrl := gomock.NewController(t) - httpClient := mock.NewMockHttpClient(ctrl) + httpClient := NewMockHttpClient(ctrl) httpClient.EXPECT(). Do(gomock.Any()). Return(&http.Response{ diff --git a/polygon/bor/clerk/clerk.go b/polygon/heimdall/event_record.go similarity index 89% rename from polygon/bor/clerk/clerk.go rename to polygon/heimdall/event_record.go index 39b9aefb8..09d9be406 100644 --- a/polygon/bor/clerk/clerk.go +++ b/polygon/heimdall/event_record.go @@ -1,4 +1,4 @@ -package clerk +package heimdall import ( "fmt" @@ -47,3 +47,8 @@ func (e *EventRecordWithTime) BuildEventRecord() *EventRecord { ChainID: e.ChainID, } } + +type StateSyncEventsResponse struct { + Height string `json:"height"` + Result []*EventRecordWithTime `json:"result"` +} diff --git a/polygon/heimdall/heimdall.go b/polygon/heimdall/heimdall.go deleted file mode 100644 index e72cf25ec..000000000 --- a/polygon/heimdall/heimdall.go +++ /dev/null @@ -1,30 +0,0 @@ -package heimdall - -import ( - "context" - - "github.com/ledgerwatch/erigon/polygon/heimdall/checkpoint" - "github.com/ledgerwatch/erigon/polygon/heimdall/milestone" - "github.com/ledgerwatch/erigon/polygon/heimdall/span" - - "github.com/ledgerwatch/erigon/polygon/bor/clerk" - "github.com/ledgerwatch/erigon/polygon/bor/finality/generics" -) - -func MilestoneRewindPending() bool { - return generics.BorMilestoneRewind.Load() != nil && *generics.BorMilestoneRewind.Load() != 0 -} - -//go:generate mockgen -destination=./mock/heimdall_client_mock.go -package=mock . IHeimdallClient -type IHeimdallClient interface { - StateSyncEvents(ctx context.Context, fromID uint64, to int64) ([]*clerk.EventRecordWithTime, error) - Span(ctx context.Context, spanID uint64) (*span.HeimdallSpan, error) - FetchCheckpoint(ctx context.Context, number int64) (*checkpoint.Checkpoint, error) - FetchCheckpointCount(ctx context.Context) (int64, error) - FetchMilestone(ctx context.Context, number int64) (*milestone.Milestone, error) - FetchMilestoneCount(ctx context.Context) (int64, error) - FetchNoAckMilestone(ctx context.Context, milestoneID string) error //Fetch the bool value whether milestone corresponding to the given id failed in the Heimdall - FetchLastNoAckMilestone(ctx context.Context) (string, error) //Fetch latest failed milestone id - FetchMilestoneID(ctx context.Context, milestoneID string) error //Fetch the bool value whether milestone corresponding to the given id is in process in Heimdall - Close() -} diff --git a/polygon/heimdall/mock/http_client_mock.go b/polygon/heimdall/http_client_mock.go similarity index 96% rename from polygon/heimdall/mock/http_client_mock.go rename to polygon/heimdall/http_client_mock.go index b41cfa8f1..bf1564bb5 100644 --- a/polygon/heimdall/mock/http_client_mock.go +++ b/polygon/heimdall/http_client_mock.go @@ -1,8 +1,8 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ledgerwatch/erigon/polygon/heimdall (interfaces: HttpClient) -// Package mock is a generated GoMock package. -package mock +// Package heimdall is a generated GoMock package. +package heimdall import ( http "net/http" diff --git a/polygon/heimdall/milestone/milestone.go b/polygon/heimdall/milestone.go similarity index 98% rename from polygon/heimdall/milestone/milestone.go rename to polygon/heimdall/milestone.go index a849f4461..44cfa2e9c 100644 --- a/polygon/heimdall/milestone/milestone.go +++ b/polygon/heimdall/milestone.go @@ -1,4 +1,4 @@ -package milestone +package heimdall import ( "math/big" diff --git a/polygon/heimdall/mock/heimdall_client_mock.go b/polygon/heimdall/mock/heimdall_client_mock.go deleted file mode 100644 index de1762716..000000000 --- a/polygon/heimdall/mock/heimdall_client_mock.go +++ /dev/null @@ -1,184 +0,0 @@ -// Code generated by MockGen. DO NOT EDIT. -// Source: github.com/ledgerwatch/erigon/polygon/heimdall (interfaces: IHeimdallClient) - -// Package mock is a generated GoMock package. -package mock - -import ( - context "context" - reflect "reflect" - - gomock "github.com/golang/mock/gomock" - clerk "github.com/ledgerwatch/erigon/polygon/bor/clerk" - checkpoint "github.com/ledgerwatch/erigon/polygon/heimdall/checkpoint" - milestone "github.com/ledgerwatch/erigon/polygon/heimdall/milestone" - span "github.com/ledgerwatch/erigon/polygon/heimdall/span" -) - -// MockIHeimdallClient is a mock of IHeimdallClient interface. -type MockIHeimdallClient struct { - ctrl *gomock.Controller - recorder *MockIHeimdallClientMockRecorder -} - -// MockIHeimdallClientMockRecorder is the mock recorder for MockIHeimdallClient. -type MockIHeimdallClientMockRecorder struct { - mock *MockIHeimdallClient -} - -// NewMockIHeimdallClient creates a new mock instance. -func NewMockIHeimdallClient(ctrl *gomock.Controller) *MockIHeimdallClient { - mock := &MockIHeimdallClient{ctrl: ctrl} - mock.recorder = &MockIHeimdallClientMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockIHeimdallClient) EXPECT() *MockIHeimdallClientMockRecorder { - return m.recorder -} - -// Close mocks base method. -func (m *MockIHeimdallClient) Close() { - m.ctrl.T.Helper() - m.ctrl.Call(m, "Close") -} - -// Close indicates an expected call of Close. -func (mr *MockIHeimdallClientMockRecorder) Close() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockIHeimdallClient)(nil).Close)) -} - -// FetchCheckpoint mocks base method. -func (m *MockIHeimdallClient) FetchCheckpoint(arg0 context.Context, arg1 int64) (*checkpoint.Checkpoint, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "FetchCheckpoint", arg0, arg1) - ret0, _ := ret[0].(*checkpoint.Checkpoint) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// FetchCheckpoint indicates an expected call of FetchCheckpoint. -func (mr *MockIHeimdallClientMockRecorder) FetchCheckpoint(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FetchCheckpoint", reflect.TypeOf((*MockIHeimdallClient)(nil).FetchCheckpoint), arg0, arg1) -} - -// FetchCheckpointCount mocks base method. -func (m *MockIHeimdallClient) FetchCheckpointCount(arg0 context.Context) (int64, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "FetchCheckpointCount", arg0) - ret0, _ := ret[0].(int64) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// FetchCheckpointCount indicates an expected call of FetchCheckpointCount. -func (mr *MockIHeimdallClientMockRecorder) FetchCheckpointCount(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FetchCheckpointCount", reflect.TypeOf((*MockIHeimdallClient)(nil).FetchCheckpointCount), arg0) -} - -// FetchLastNoAckMilestone mocks base method. -func (m *MockIHeimdallClient) FetchLastNoAckMilestone(arg0 context.Context) (string, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "FetchLastNoAckMilestone", arg0) - ret0, _ := ret[0].(string) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// FetchLastNoAckMilestone indicates an expected call of FetchLastNoAckMilestone. -func (mr *MockIHeimdallClientMockRecorder) FetchLastNoAckMilestone(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FetchLastNoAckMilestone", reflect.TypeOf((*MockIHeimdallClient)(nil).FetchLastNoAckMilestone), arg0) -} - -// FetchMilestone mocks base method. -func (m *MockIHeimdallClient) FetchMilestone(arg0 context.Context, arg1 int64) (*milestone.Milestone, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "FetchMilestone", arg0, arg1) - ret0, _ := ret[0].(*milestone.Milestone) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// FetchMilestone indicates an expected call of FetchMilestone. -func (mr *MockIHeimdallClientMockRecorder) FetchMilestone(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FetchMilestone", reflect.TypeOf((*MockIHeimdallClient)(nil).FetchMilestone), arg0, arg1) -} - -// FetchMilestoneCount mocks base method. -func (m *MockIHeimdallClient) FetchMilestoneCount(arg0 context.Context) (int64, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "FetchMilestoneCount", arg0) - ret0, _ := ret[0].(int64) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// FetchMilestoneCount indicates an expected call of FetchMilestoneCount. -func (mr *MockIHeimdallClientMockRecorder) FetchMilestoneCount(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FetchMilestoneCount", reflect.TypeOf((*MockIHeimdallClient)(nil).FetchMilestoneCount), arg0) -} - -// FetchMilestoneID mocks base method. -func (m *MockIHeimdallClient) FetchMilestoneID(arg0 context.Context, arg1 string) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "FetchMilestoneID", arg0, arg1) - ret0, _ := ret[0].(error) - return ret0 -} - -// FetchMilestoneID indicates an expected call of FetchMilestoneID. -func (mr *MockIHeimdallClientMockRecorder) FetchMilestoneID(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FetchMilestoneID", reflect.TypeOf((*MockIHeimdallClient)(nil).FetchMilestoneID), arg0, arg1) -} - -// FetchNoAckMilestone mocks base method. -func (m *MockIHeimdallClient) FetchNoAckMilestone(arg0 context.Context, arg1 string) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "FetchNoAckMilestone", arg0, arg1) - ret0, _ := ret[0].(error) - return ret0 -} - -// FetchNoAckMilestone indicates an expected call of FetchNoAckMilestone. -func (mr *MockIHeimdallClientMockRecorder) FetchNoAckMilestone(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FetchNoAckMilestone", reflect.TypeOf((*MockIHeimdallClient)(nil).FetchNoAckMilestone), arg0, arg1) -} - -// Span mocks base method. -func (m *MockIHeimdallClient) Span(arg0 context.Context, arg1 uint64) (*span.HeimdallSpan, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Span", arg0, arg1) - ret0, _ := ret[0].(*span.HeimdallSpan) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// Span indicates an expected call of Span. -func (mr *MockIHeimdallClientMockRecorder) Span(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Span", reflect.TypeOf((*MockIHeimdallClient)(nil).Span), arg0, arg1) -} - -// StateSyncEvents mocks base method. -func (m *MockIHeimdallClient) StateSyncEvents(arg0 context.Context, arg1 uint64, arg2 int64) ([]*clerk.EventRecordWithTime, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "StateSyncEvents", arg0, arg1, arg2) - ret0, _ := ret[0].([]*clerk.EventRecordWithTime) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// StateSyncEvents indicates an expected call of StateSyncEvents. -func (mr *MockIHeimdallClientMockRecorder) StateSyncEvents(arg0, arg1, arg2 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateSyncEvents", reflect.TypeOf((*MockIHeimdallClient)(nil).StateSyncEvents), arg0, arg1, arg2) -} diff --git a/polygon/heimdall/span/span.go b/polygon/heimdall/span.go similarity index 88% rename from polygon/heimdall/span/span.go rename to polygon/heimdall/span.go index 7ab715b53..862f0573f 100644 --- a/polygon/heimdall/span/span.go +++ b/polygon/heimdall/span.go @@ -1,7 +1,8 @@ -package span +package heimdall import ( "github.com/google/btree" + "github.com/ledgerwatch/erigon/polygon/bor/valset" ) @@ -28,3 +29,8 @@ func (hs *HeimdallSpan) Less(other btree.Item) bool { } return hs.EndBlock < otherHs.EndBlock } + +type SpanResponse struct { + Height string `json:"height"` + Result HeimdallSpan `json:"result"` +} diff --git a/polygon/heimdall/span/span_id_test.go b/polygon/heimdall/span/span_id_test.go deleted file mode 100644 index 34c2b669f..000000000 --- a/polygon/heimdall/span/span_id_test.go +++ /dev/null @@ -1,44 +0,0 @@ -package span - -import ( - "testing" - - "github.com/stretchr/testify/assert" - - "github.com/ledgerwatch/erigon/polygon/bor/borcfg" -) - -func TestSpanIDAt(t *testing.T) { - assert.Equal(t, uint64(0), IDAt(0)) - assert.Equal(t, uint64(0), IDAt(1)) - assert.Equal(t, uint64(0), IDAt(2)) - assert.Equal(t, uint64(0), IDAt(zerothSpanEnd)) - assert.Equal(t, uint64(1), IDAt(zerothSpanEnd+1)) - assert.Equal(t, uint64(1), IDAt(zerothSpanEnd+2)) - assert.Equal(t, uint64(1), IDAt(6655)) - assert.Equal(t, uint64(2), IDAt(6656)) - assert.Equal(t, uint64(2), IDAt(6657)) - assert.Equal(t, uint64(2), IDAt(13055)) - assert.Equal(t, uint64(3), IDAt(13056)) - assert.Equal(t, uint64(6839), IDAt(43763456)) -} - -func TestSpanEndBlockNum(t *testing.T) { - assert.Equal(t, uint64(zerothSpanEnd), EndBlockNum(0)) - assert.Equal(t, uint64(6655), EndBlockNum(1)) - assert.Equal(t, uint64(13055), EndBlockNum(2)) - assert.Equal(t, uint64(43769855), EndBlockNum(6839)) -} - -func TestBlockInLastSprintOfSpan(t *testing.T) { - config := &borcfg.BorConfig{ - Sprint: map[string]uint64{ - "0": 16, - }, - } - assert.True(t, BlockInLastSprintOfSpan(6640, config)) - assert.True(t, BlockInLastSprintOfSpan(6645, config)) - assert.True(t, BlockInLastSprintOfSpan(6655, config)) - assert.False(t, BlockInLastSprintOfSpan(6639, config)) - assert.False(t, BlockInLastSprintOfSpan(6656, config)) -} diff --git a/polygon/heimdall/span/spanner.go b/polygon/heimdall/span/spanner.go deleted file mode 100644 index 315617f9e..000000000 --- a/polygon/heimdall/span/spanner.go +++ /dev/null @@ -1,160 +0,0 @@ -package span - -import ( - "encoding/hex" - "encoding/json" - "math/big" - - "github.com/ledgerwatch/log/v3" - - "github.com/ledgerwatch/erigon-lib/chain" - libcommon "github.com/ledgerwatch/erigon-lib/common" - "github.com/ledgerwatch/erigon/consensus" - "github.com/ledgerwatch/erigon/polygon/bor/abi" - "github.com/ledgerwatch/erigon/polygon/bor/borcfg" - "github.com/ledgerwatch/erigon/polygon/bor/valset" - "github.com/ledgerwatch/erigon/rlp" -) - -type ChainSpanner struct { - validatorSet abi.ABI - chainConfig *chain.Config - borConfig *borcfg.BorConfig - logger log.Logger - withoutHeimdall bool -} - -func NewChainSpanner(validatorSet abi.ABI, chainConfig *chain.Config, withoutHeimdall bool, logger log.Logger) *ChainSpanner { - borConfig := chainConfig.Bor.(*borcfg.BorConfig) - return &ChainSpanner{ - validatorSet: validatorSet, - chainConfig: chainConfig, - borConfig: borConfig, - logger: logger, - withoutHeimdall: withoutHeimdall, - } -} - -// GetCurrentSpan get current span from contract -func (c *ChainSpanner) GetCurrentSpan(syscall consensus.SystemCall) (*Span, error) { - - // method - const method = "getCurrentSpan" - - data, err := c.validatorSet.Pack(method) - if err != nil { - c.logger.Error("[bor] Unable to pack tx for getCurrentSpan", "error", err) - return nil, err - } - - result, err := syscall(libcommon.HexToAddress(c.borConfig.ValidatorContract), data) - if err != nil { - return nil, err - } - - // span result - ret := new(struct { - Number *big.Int - StartBlock *big.Int - EndBlock *big.Int - }) - - if err := c.validatorSet.UnpackIntoInterface(ret, method, result); err != nil { - return nil, err - } - - // create new span - span := Span{ - ID: ret.Number.Uint64(), - StartBlock: ret.StartBlock.Uint64(), - EndBlock: ret.EndBlock.Uint64(), - } - - return &span, nil -} - -func (c *ChainSpanner) GetCurrentValidators(spanId uint64, signer libcommon.Address, chain consensus.ChainHeaderReader) ([]*valset.Validator, error) { - // Use hardcoded bor devnet valset if chain-name = bor-devnet - if NetworkNameVals[c.chainConfig.ChainName] != nil && c.withoutHeimdall { - return NetworkNameVals[c.chainConfig.ChainName], nil - } - - spanBytes := chain.BorSpan(spanId) - var span HeimdallSpan - if err := json.Unmarshal(spanBytes, &span); err != nil { - return nil, err - } - - return span.ValidatorSet.Validators, nil -} - -func (c *ChainSpanner) GetCurrentProducers(spanId uint64, signer libcommon.Address, chain consensus.ChainHeaderReader) ([]*valset.Validator, error) { - // Use hardcoded bor devnet valset if chain-name = bor-devnet - if NetworkNameVals[c.chainConfig.ChainName] != nil && c.withoutHeimdall { - return NetworkNameVals[c.chainConfig.ChainName], nil - } - - spanBytes := chain.BorSpan(spanId) - var span HeimdallSpan - if err := json.Unmarshal(spanBytes, &span); err != nil { - return nil, err - } - - producers := make([]*valset.Validator, len(span.SelectedProducers)) - for i := range span.SelectedProducers { - producers[i] = &span.SelectedProducers[i] - } - - return producers, nil -} - -func (c *ChainSpanner) CommitSpan(heimdallSpan HeimdallSpan, syscall consensus.SystemCall) error { - - // method - const method = "commitSpan" - - // get validators bytes - validators := make([]valset.MinimalVal, 0, len(heimdallSpan.ValidatorSet.Validators)) - for _, val := range heimdallSpan.ValidatorSet.Validators { - validators = append(validators, val.MinimalVal()) - } - validatorBytes, err := rlp.EncodeToBytes(validators) - if err != nil { - return err - } - - // get producers bytes - producers := make([]valset.MinimalVal, 0, len(heimdallSpan.SelectedProducers)) - for _, val := range heimdallSpan.SelectedProducers { - producers = append(producers, val.MinimalVal()) - } - producerBytes, err := rlp.EncodeToBytes(producers) - if err != nil { - return err - } - - c.logger.Debug("[bor] ✅ Committing new span", - "id", heimdallSpan.ID, - "startBlock", heimdallSpan.StartBlock, - "endBlock", heimdallSpan.EndBlock, - "validatorBytes", hex.EncodeToString(validatorBytes), - "producerBytes", hex.EncodeToString(producerBytes), - ) - - // get packed data - data, err := c.validatorSet.Pack(method, - big.NewInt(0).SetUint64(heimdallSpan.ID), - big.NewInt(0).SetUint64(heimdallSpan.StartBlock), - big.NewInt(0).SetUint64(heimdallSpan.EndBlock), - validatorBytes, - producerBytes, - ) - if err != nil { - c.logger.Error("[bor] Unable to pack tx for commitSpan", "error", err) - return err - } - - _, err = syscall(libcommon.HexToAddress(c.borConfig.ValidatorContract), data) - - return err -} diff --git a/polygon/sync/canonical_chain_builder_test.go b/polygon/sync/canonical_chain_builder_test.go index 0fb061732..fec41c509 100644 --- a/polygon/sync/canonical_chain_builder_test.go +++ b/polygon/sync/canonical_chain_builder_test.go @@ -9,9 +9,8 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - heimdallspan "github.com/ledgerwatch/erigon/polygon/heimdall/span" - "github.com/ledgerwatch/erigon/core/types" + heimdallspan "github.com/ledgerwatch/erigon/polygon/heimdall" ) type testDifficultyCalculator struct { diff --git a/polygon/sync/header_downloader_test.go b/polygon/sync/header_downloader_test.go index 7a24a6ab5..5c430bf4f 100644 --- a/polygon/sync/header_downloader_test.go +++ b/polygon/sync/header_downloader_test.go @@ -14,8 +14,7 @@ import ( "github.com/ledgerwatch/erigon-lib/common" "github.com/ledgerwatch/erigon/core/types" - "github.com/ledgerwatch/erigon/polygon/heimdall/checkpoint" - "github.com/ledgerwatch/erigon/polygon/heimdall/milestone" + "github.com/ledgerwatch/erigon/polygon/heimdall" "github.com/ledgerwatch/erigon/turbo/testlog" ) @@ -80,11 +79,11 @@ func (hdt headerDownloaderTest) fakePeers(count int, blockNums ...*big.Int) Peer return peers } -func (hdt headerDownloaderTest) fakeCheckpoints(count int) []*checkpoint.Checkpoint { - checkpoints := make([]*checkpoint.Checkpoint, count) +func (hdt headerDownloaderTest) fakeCheckpoints(count int) []*heimdall.Checkpoint { + checkpoints := make([]*heimdall.Checkpoint, count) for i := range checkpoints { num := i + 1 - checkpoints[i] = &checkpoint.Checkpoint{ + checkpoints[i] = &heimdall.Checkpoint{ StartBlock: big.NewInt(int64(num)), EndBlock: big.NewInt(int64(num)), RootHash: common.BytesToHash([]byte(fmt.Sprintf("0x%d", num))), @@ -94,11 +93,11 @@ func (hdt headerDownloaderTest) fakeCheckpoints(count int) []*checkpoint.Checkpo return checkpoints } -func (hdt headerDownloaderTest) fakeMilestones(count int) []*milestone.Milestone { - milestones := make([]*milestone.Milestone, count) +func (hdt headerDownloaderTest) fakeMilestones(count int) []*heimdall.Milestone { + milestones := make([]*heimdall.Milestone, count) for i := range milestones { num := i + 1 - milestones[i] = &milestone.Milestone{ + milestones[i] = &heimdall.Milestone{ StartBlock: big.NewInt(int64(num)), EndBlock: big.NewInt(int64(num)), Hash: common.BytesToHash([]byte(fmt.Sprintf("0x%d", num))), diff --git a/polygon/sync/heimdall.go b/polygon/sync/heimdall.go index b77d58c8e..0491b9c23 100644 --- a/polygon/sync/heimdall.go +++ b/polygon/sync/heimdall.go @@ -8,34 +8,31 @@ import ( "github.com/ledgerwatch/log/v3" - "github.com/ledgerwatch/erigon/polygon/heimdall" - "github.com/ledgerwatch/erigon/polygon/heimdall/checkpoint" - "github.com/ledgerwatch/erigon/polygon/heimdall/milestone" - "github.com/ledgerwatch/erigon/polygon/heimdall/span" - "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon/polygon/bor" + "github.com/ledgerwatch/erigon/polygon/heimdall" ) // Heimdall is a wrapper of Heimdall HTTP API // //go:generate mockgen -destination=./heimdall_mock.go -package=sync . Heimdall type Heimdall interface { - FetchCheckpoints(ctx context.Context, start uint64) ([]*checkpoint.Checkpoint, error) - FetchMilestones(ctx context.Context, start uint64) ([]*milestone.Milestone, error) - FetchSpan(ctx context.Context, start uint64) (*span.HeimdallSpan, error) - OnMilestoneEvent(ctx context.Context, callback func(*milestone.Milestone)) error + FetchCheckpoints(ctx context.Context, start uint64) ([]*heimdall.Checkpoint, error) + FetchMilestones(ctx context.Context, start uint64) ([]*heimdall.Milestone, error) + FetchSpan(ctx context.Context, start uint64) (*heimdall.HeimdallSpan, error) + OnMilestoneEvent(ctx context.Context, callback func(*heimdall.Milestone)) error } // ErrIncompleteMilestoneRange happens when FetchMilestones is called with an old start block because old milestones are evicted var ErrIncompleteMilestoneRange = errors.New("milestone range doesn't contain the start block") type HeimdallImpl struct { - client heimdall.IHeimdallClient + client heimdall.HeimdallClient pollDelay time.Duration logger log.Logger } -func NewHeimdall(client heimdall.IHeimdallClient, logger log.Logger) Heimdall { +func NewHeimdall(client heimdall.HeimdallClient, logger log.Logger) Heimdall { impl := HeimdallImpl{ client: client, pollDelay: time.Second, @@ -55,21 +52,21 @@ func cmpNumToRange(n uint64, min *big.Int, max *big.Int) int { return 0 } -func cmpBlockNumToCheckpointRange(n uint64, c *checkpoint.Checkpoint) int { +func cmpBlockNumToCheckpointRange(n uint64, c *heimdall.Checkpoint) int { return cmpNumToRange(n, c.StartBlock, c.EndBlock) } -func cmpBlockNumToMilestoneRange(n uint64, m *milestone.Milestone) int { +func cmpBlockNumToMilestoneRange(n uint64, m *heimdall.Milestone) int { return cmpNumToRange(n, m.StartBlock, m.EndBlock) } -func (impl *HeimdallImpl) FetchCheckpoints(ctx context.Context, start uint64) ([]*checkpoint.Checkpoint, error) { +func (impl *HeimdallImpl) FetchCheckpoints(ctx context.Context, start uint64) ([]*heimdall.Checkpoint, error) { count, err := impl.client.FetchCheckpointCount(ctx) if err != nil { return nil, err } - var checkpoints []*checkpoint.Checkpoint + var checkpoints []*heimdall.Checkpoint for i := count; i >= 1; i-- { c, err := impl.client.FetchCheckpoint(ctx, i) @@ -95,13 +92,13 @@ func (impl *HeimdallImpl) FetchCheckpoints(ctx context.Context, start uint64) ([ return checkpoints, nil } -func (impl *HeimdallImpl) FetchMilestones(ctx context.Context, start uint64) ([]*milestone.Milestone, error) { +func (impl *HeimdallImpl) FetchMilestones(ctx context.Context, start uint64) ([]*heimdall.Milestone, error) { count, err := impl.client.FetchMilestoneCount(ctx) if err != nil { return nil, err } - var milestones []*milestone.Milestone + var milestones []*heimdall.Milestone for i := count; i >= 1; i-- { m, err := impl.client.FetchMilestone(ctx, i) @@ -131,11 +128,11 @@ func (impl *HeimdallImpl) FetchMilestones(ctx context.Context, start uint64) ([] return milestones, nil } -func (impl *HeimdallImpl) FetchSpan(ctx context.Context, start uint64) (*span.HeimdallSpan, error) { - return impl.client.Span(ctx, span.IDAt(start)) +func (impl *HeimdallImpl) FetchSpan(ctx context.Context, start uint64) (*heimdall.HeimdallSpan, error) { + return impl.client.Span(ctx, bor.SpanIDAt(start)) } -func (impl *HeimdallImpl) OnMilestoneEvent(ctx context.Context, callback func(*milestone.Milestone)) error { +func (impl *HeimdallImpl) OnMilestoneEvent(ctx context.Context, callback func(*heimdall.Milestone)) error { currentCount, err := impl.client.FetchMilestoneCount(ctx) if err != nil { return err diff --git a/polygon/sync/heimdall_mock.go b/polygon/sync/heimdall_mock.go index 8604e623e..ca7d1e1fb 100644 --- a/polygon/sync/heimdall_mock.go +++ b/polygon/sync/heimdall_mock.go @@ -9,9 +9,8 @@ import ( reflect "reflect" gomock "github.com/golang/mock/gomock" - checkpoint "github.com/ledgerwatch/erigon/polygon/heimdall/checkpoint" - milestone "github.com/ledgerwatch/erigon/polygon/heimdall/milestone" - span "github.com/ledgerwatch/erigon/polygon/heimdall/span" + + checkpoint "github.com/ledgerwatch/erigon/polygon/heimdall" ) // MockHeimdall is a mock of Heimdall interface. @@ -53,10 +52,10 @@ func (mr *MockHeimdallMockRecorder) FetchCheckpoints(arg0, arg1 interface{}) *go } // FetchMilestones mocks base method. -func (m *MockHeimdall) FetchMilestones(arg0 context.Context, arg1 uint64) ([]*milestone.Milestone, error) { +func (m *MockHeimdall) FetchMilestones(arg0 context.Context, arg1 uint64) ([]*checkpoint.Milestone, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "FetchMilestones", arg0, arg1) - ret0, _ := ret[0].([]*milestone.Milestone) + ret0, _ := ret[0].([]*checkpoint.Milestone) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -68,10 +67,10 @@ func (mr *MockHeimdallMockRecorder) FetchMilestones(arg0, arg1 interface{}) *gom } // FetchSpan mocks base method. -func (m *MockHeimdall) FetchSpan(arg0 context.Context, arg1 uint64) (*span.HeimdallSpan, error) { +func (m *MockHeimdall) FetchSpan(arg0 context.Context, arg1 uint64) (*checkpoint.HeimdallSpan, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "FetchSpan", arg0, arg1) - ret0, _ := ret[0].(*span.HeimdallSpan) + ret0, _ := ret[0].(*checkpoint.HeimdallSpan) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -83,7 +82,7 @@ func (mr *MockHeimdallMockRecorder) FetchSpan(arg0, arg1 interface{}) *gomock.Ca } // OnMilestoneEvent mocks base method. -func (m *MockHeimdall) OnMilestoneEvent(arg0 context.Context, arg1 func(*milestone.Milestone)) error { +func (m *MockHeimdall) OnMilestoneEvent(arg0 context.Context, arg1 func(*checkpoint.Milestone)) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "OnMilestoneEvent", arg0, arg1) ret0, _ := ret[0].(error) diff --git a/polygon/sync/heimdall_test.go b/polygon/sync/heimdall_test.go index 2d809749d..2c4f11c07 100644 --- a/polygon/sync/heimdall_test.go +++ b/polygon/sync/heimdall_test.go @@ -12,13 +12,10 @@ import ( "github.com/stretchr/testify/require" heimdallclient "github.com/ledgerwatch/erigon/polygon/heimdall" - "github.com/ledgerwatch/erigon/polygon/heimdall/checkpoint" - "github.com/ledgerwatch/erigon/polygon/heimdall/milestone" - heimdallmock "github.com/ledgerwatch/erigon/polygon/heimdall/mock" ) -func makeCheckpoint(start uint64, len uint) *checkpoint.Checkpoint { - c := checkpoint.Checkpoint{ +func makeCheckpoint(start uint64, len uint) *heimdallclient.Checkpoint { + c := heimdallclient.Checkpoint{ StartBlock: new(big.Int).SetUint64(start), EndBlock: new(big.Int).SetUint64(start + uint64(len) - 1), Timestamp: uint64(time.Now().Unix()), @@ -26,8 +23,8 @@ func makeCheckpoint(start uint64, len uint) *checkpoint.Checkpoint { return &c } -func makeMilestone(start uint64, len uint) *milestone.Milestone { - m := milestone.Milestone{ +func makeMilestone(start uint64, len uint) *heimdallclient.Milestone { + m := heimdallclient.Milestone{ StartBlock: new(big.Int).SetUint64(start), EndBlock: new(big.Int).SetUint64(start + uint64(len) - 1), Timestamp: uint64(time.Now().Unix()), @@ -37,7 +34,7 @@ func makeMilestone(start uint64, len uint) *milestone.Milestone { type heimdallTest struct { ctx context.Context - client *heimdallmock.MockIHeimdallClient + client *heimdallclient.MockHeimdallClient heimdall Heimdall logger log.Logger } @@ -49,7 +46,7 @@ func newHeimdallTest(t *testing.T) heimdallTest { ctrl := gomock.NewController(t) t.Cleanup(ctrl.Finish) - client := heimdallmock.NewMockIHeimdallClient(ctrl) + client := heimdallclient.NewMockHeimdallClient(ctrl) heimdall := NewHeimdall(client, logger) return heimdallTest{ @@ -60,8 +57,8 @@ func newHeimdallTest(t *testing.T) heimdallTest { } } -func (test heimdallTest) setupCheckpoints(count int) []*checkpoint.Checkpoint { - var expectedCheckpoints []*checkpoint.Checkpoint +func (test heimdallTest) setupCheckpoints(count int) []*heimdallclient.Checkpoint { + var expectedCheckpoints []*heimdallclient.Checkpoint for i := 0; i < count; i++ { c := makeCheckpoint(uint64(i*256), 256) expectedCheckpoints = append(expectedCheckpoints, c) @@ -69,15 +66,15 @@ func (test heimdallTest) setupCheckpoints(count int) []*checkpoint.Checkpoint { client := test.client client.EXPECT().FetchCheckpointCount(gomock.Any()).Return(int64(len(expectedCheckpoints)), nil) - client.EXPECT().FetchCheckpoint(gomock.Any(), gomock.Any()).DoAndReturn(func(ctx context.Context, number int64) (*checkpoint.Checkpoint, error) { + client.EXPECT().FetchCheckpoint(gomock.Any(), gomock.Any()).DoAndReturn(func(ctx context.Context, number int64) (*heimdallclient.Checkpoint, error) { return expectedCheckpoints[number-1], nil }).AnyTimes() return expectedCheckpoints } -func (test heimdallTest) setupMilestones(count int) []*milestone.Milestone { - var expectedMilestones []*milestone.Milestone +func (test heimdallTest) setupMilestones(count int) []*heimdallclient.Milestone { + var expectedMilestones []*heimdallclient.Milestone for i := 0; i < count; i++ { m := makeMilestone(uint64(i*16), 16) expectedMilestones = append(expectedMilestones, m) @@ -85,7 +82,7 @@ func (test heimdallTest) setupMilestones(count int) []*milestone.Milestone { client := test.client client.EXPECT().FetchMilestoneCount(gomock.Any()).Return(int64(len(expectedMilestones)), nil) - client.EXPECT().FetchMilestone(gomock.Any(), gomock.Any()).DoAndReturn(func(ctx context.Context, number int64) (*milestone.Milestone, error) { + client.EXPECT().FetchMilestone(gomock.Any(), gomock.Any()).DoAndReturn(func(ctx context.Context, number int64) (*heimdallclient.Milestone, error) { return expectedMilestones[number-1], nil }).AnyTimes() @@ -191,7 +188,7 @@ func TestFetchMilestonesMiddleStart(t *testing.T) { func TestFetchMilestonesStartingBeforeEvictionPoint(t *testing.T) { test := newHeimdallTest(t) - var expectedMilestones []*milestone.Milestone + var expectedMilestones []*heimdallclient.Milestone for i := 0; i < 20; i++ { m := makeMilestone(uint64(i*16), 16) expectedMilestones = append(expectedMilestones, m) @@ -200,7 +197,7 @@ func TestFetchMilestonesStartingBeforeEvictionPoint(t *testing.T) { client := test.client client.EXPECT().FetchMilestoneCount(gomock.Any()).Return(int64(len(expectedMilestones)), nil) - client.EXPECT().FetchMilestone(gomock.Any(), gomock.Any()).DoAndReturn(func(ctx context.Context, number int64) (*milestone.Milestone, error) { + client.EXPECT().FetchMilestone(gomock.Any(), gomock.Any()).DoAndReturn(func(ctx context.Context, number int64) (*heimdallclient.Milestone, error) { if int(number) <= len(expectedMilestones)-keptMilestones { return nil, heimdallclient.ErrNotInMilestoneList } @@ -239,8 +236,8 @@ func TestOnMilestoneEvent(t *testing.T) { expectedMilestone := makeMilestone(0, 12) client.EXPECT().FetchMilestone(gomock.Any(), gomock.Any()).Return(expectedMilestone, nil) - eventChan := make(chan *milestone.Milestone) - err := test.heimdall.OnMilestoneEvent(test.ctx, func(m *milestone.Milestone) { + eventChan := make(chan *heimdallclient.Milestone) + err := test.heimdall.OnMilestoneEvent(test.ctx, func(m *heimdallclient.Milestone) { eventChan <- m }) require.Nil(t, err) diff --git a/polygon/sync/spans_cache.go b/polygon/sync/spans_cache.go index 5c03a4229..6d3598495 100644 --- a/polygon/sync/spans_cache.go +++ b/polygon/sync/spans_cache.go @@ -1,6 +1,8 @@ package sync -import heimdallspan "github.com/ledgerwatch/erigon/polygon/heimdall/span" +import ( + heimdallspan "github.com/ledgerwatch/erigon/polygon/heimdall" +) type SpansCache struct { spans map[uint64]*heimdallspan.HeimdallSpan diff --git a/polygon/sync/state_point.go b/polygon/sync/state_point.go index cad44407d..c8f9c3997 100644 --- a/polygon/sync/state_point.go +++ b/polygon/sync/state_point.go @@ -3,13 +3,11 @@ package sync import ( "math/big" - "github.com/ledgerwatch/erigon/polygon/heimdall/checkpoint" - "github.com/ledgerwatch/erigon/polygon/heimdall/milestone" - "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon/polygon/heimdall" ) -func statePointFromCheckpoint(checkpoint *checkpoint.Checkpoint) *statePoint { +func statePointFromCheckpoint(checkpoint *heimdall.Checkpoint) *statePoint { return &statePoint{ proposer: checkpoint.Proposer, startBlock: new(big.Int).Set(checkpoint.StartBlock), @@ -21,7 +19,7 @@ func statePointFromCheckpoint(checkpoint *checkpoint.Checkpoint) *statePoint { } } -func statePointFromMilestone(milestone *milestone.Milestone) *statePoint { +func statePointFromMilestone(milestone *heimdall.Milestone) *statePoint { return &statePoint{ proposer: milestone.Proposer, startBlock: new(big.Int).Set(milestone.StartBlock), diff --git a/polygon/sync/state_points.go b/polygon/sync/state_points.go index e88c3160c..650dc80f9 100644 --- a/polygon/sync/state_points.go +++ b/polygon/sync/state_points.go @@ -1,11 +1,10 @@ package sync import ( - "github.com/ledgerwatch/erigon/polygon/heimdall/checkpoint" - "github.com/ledgerwatch/erigon/polygon/heimdall/milestone" + "github.com/ledgerwatch/erigon/polygon/heimdall" ) -func statePointsFromCheckpoints(checkpoints []*checkpoint.Checkpoint) statePoints { +func statePointsFromCheckpoints(checkpoints []*heimdall.Checkpoint) statePoints { statePoints := make(statePoints, len(checkpoints)) for i, checkpoint := range checkpoints { statePoints[i] = statePointFromCheckpoint(checkpoint) @@ -14,7 +13,7 @@ func statePointsFromCheckpoints(checkpoints []*checkpoint.Checkpoint) statePoint return statePoints } -func statePointsFromMilestones(milestones []*milestone.Milestone) statePoints { +func statePointsFromMilestones(milestones []*heimdall.Milestone) statePoints { statePoints := make(statePoints, len(milestones)) for i, milestone := range milestones { statePoints[i] = statePointFromMilestone(milestone) diff --git a/turbo/snapshotsync/freezeblocks/block_reader.go b/turbo/snapshotsync/freezeblocks/block_reader.go index e80b5d359..fc6834937 100644 --- a/turbo/snapshotsync/freezeblocks/block_reader.go +++ b/turbo/snapshotsync/freezeblocks/block_reader.go @@ -10,8 +10,6 @@ import ( "github.com/ledgerwatch/log/v3" - "github.com/ledgerwatch/erigon/polygon/heimdall/span" - "github.com/ledgerwatch/erigon-lib/common" "github.com/ledgerwatch/erigon-lib/common/dbg" "github.com/ledgerwatch/erigon-lib/common/length" @@ -22,6 +20,7 @@ import ( "github.com/ledgerwatch/erigon/core/rawdb" "github.com/ledgerwatch/erigon/core/types" "github.com/ledgerwatch/erigon/eth/ethconfig" + "github.com/ledgerwatch/erigon/polygon/bor" "github.com/ledgerwatch/erigon/rlp" "github.com/ledgerwatch/erigon/turbo/services" ) @@ -1174,7 +1173,7 @@ func (r *BlockReader) LastFrozenSpanID() uint64 { return 0 } - lastSpanID := span.IDAt(lastSegment.to) + lastSpanID := bor.SpanIDAt(lastSegment.to) if lastSpanID > 0 { lastSpanID-- } @@ -1184,7 +1183,7 @@ func (r *BlockReader) LastFrozenSpanID() uint64 { func (r *BlockReader) Span(ctx context.Context, tx kv.Getter, spanId uint64) ([]byte, error) { var endBlock uint64 if spanId > 0 { - endBlock = span.EndBlockNum(spanId) + endBlock = bor.SpanEndBlockNum(spanId) } var buf [8]byte binary.BigEndian.PutUint64(buf[:], spanId) @@ -1207,11 +1206,11 @@ func (r *BlockReader) Span(ctx context.Context, tx kv.Getter, spanId uint64) ([] if sn.idx == nil { continue } - spanFrom := span.IDAt(sn.from) + spanFrom := bor.SpanIDAt(sn.from) if spanId < spanFrom { continue } - spanTo := span.IDAt(sn.to) + spanTo := bor.SpanIDAt(sn.to) if spanId >= spanTo { continue } diff --git a/turbo/snapshotsync/freezeblocks/block_snapshots.go b/turbo/snapshotsync/freezeblocks/block_snapshots.go index 473af9652..866a21553 100644 --- a/turbo/snapshotsync/freezeblocks/block_snapshots.go +++ b/turbo/snapshotsync/freezeblocks/block_snapshots.go @@ -21,8 +21,6 @@ import ( "golang.org/x/exp/slices" "golang.org/x/sync/errgroup" - "github.com/ledgerwatch/erigon/polygon/heimdall/span" - "github.com/ledgerwatch/erigon-lib/chain" "github.com/ledgerwatch/erigon-lib/chain/snapcfg" common2 "github.com/ledgerwatch/erigon-lib/common" @@ -48,6 +46,7 @@ import ( "github.com/ledgerwatch/erigon/eth/ethconfig/estimate" "github.com/ledgerwatch/erigon/eth/stagedsync/stages" "github.com/ledgerwatch/erigon/params" + "github.com/ledgerwatch/erigon/polygon/bor" "github.com/ledgerwatch/erigon/rlp" "github.com/ledgerwatch/erigon/turbo/services" "github.com/ledgerwatch/erigon/turbo/silkworm" @@ -1476,7 +1475,7 @@ func (br *BlockRetire) PruneAncientBlocks(tx kv.RwTx, limit int) error { canDeleteTo := CanDeleteTo(currentProgress, br.blockReader.FrozenBorBlocks()) br.logger.Info("[snapshots] Prune Bor Blocks", "to", canDeleteTo, "limit", limit) - if err := br.blockWriter.PruneBorBlocks(context.Background(), tx, canDeleteTo, limit, span.IDAt); err != nil { + if err := br.blockWriter.PruneBorBlocks(context.Background(), tx, canDeleteTo, limit, bor.SpanIDAt); err != nil { return err } } diff --git a/turbo/snapshotsync/freezeblocks/bor_snapshots.go b/turbo/snapshotsync/freezeblocks/bor_snapshots.go index 39a683bbf..af486ef93 100644 --- a/turbo/snapshotsync/freezeblocks/bor_snapshots.go +++ b/turbo/snapshotsync/freezeblocks/bor_snapshots.go @@ -17,8 +17,6 @@ import ( "github.com/ledgerwatch/log/v3" "golang.org/x/exp/slices" - "github.com/ledgerwatch/erigon/polygon/heimdall/span" - "github.com/ledgerwatch/erigon-lib/chain" "github.com/ledgerwatch/erigon-lib/chain/snapcfg" common2 "github.com/ledgerwatch/erigon-lib/common" @@ -35,6 +33,7 @@ import ( "github.com/ledgerwatch/erigon/core/rawdb" "github.com/ledgerwatch/erigon/core/types" "github.com/ledgerwatch/erigon/eth/ethconfig" + "github.com/ledgerwatch/erigon/polygon/bor" "github.com/ledgerwatch/erigon/turbo/services" ) @@ -377,8 +376,8 @@ func DumpBorEvents(ctx context.Context, db kv.RoDB, blockFrom, blockTo uint64, w func DumpBorSpans(ctx context.Context, db kv.RoDB, blockFrom, blockTo uint64, workers int, lvl log.Lvl, logger log.Logger, collect func([]byte) error) error { logEvery := time.NewTicker(20 * time.Second) defer logEvery.Stop() - spanFrom := span.IDAt(blockFrom) - spanTo := span.IDAt(blockTo) + spanFrom := bor.SpanIDAt(blockFrom) + spanTo := bor.SpanIDAt(blockTo) from := hexutility.EncodeTs(spanFrom) if err := kv.BigChunks(db, kv.BorSpans, from, func(tx kv.Tx, spanIdBytes, spanBytes []byte) (bool, error) { spanId := binary.BigEndian.Uint64(spanIdBytes) @@ -509,7 +508,7 @@ func BorSpansIdx(ctx context.Context, segmentFilePath string, version uint8, blo g := d.MakeGetter() var idxFilePath = filepath.Join(snapDir, snaptype.IdxFileName(version, blockFrom, blockTo, snaptype.BorSpans.String())) - baseSpanId := span.IDAt(blockFrom) + baseSpanId := bor.SpanIDAt(blockFrom) rs, err := recsplit.NewRecSplit(recsplit.RecSplitArgs{ KeyCount: d.Count(), diff --git a/turbo/stages/stageloop.go b/turbo/stages/stageloop.go index 95db1e1e8..35aab454b 100644 --- a/turbo/stages/stageloop.go +++ b/turbo/stages/stageloop.go @@ -20,6 +20,7 @@ import ( "github.com/ledgerwatch/erigon-lib/kv/membatchwithdb" "github.com/ledgerwatch/erigon-lib/state" "github.com/ledgerwatch/erigon-lib/wrap" + "github.com/ledgerwatch/erigon/polygon/bor/finality" "github.com/ledgerwatch/erigon/polygon/heimdall" @@ -471,7 +472,7 @@ func NewDefaultStages(ctx context.Context, agg *state.AggregatorV3, silkworm *silkworm.Silkworm, forkValidator *engine_helpers.ForkValidator, - heimdallClient heimdall.IHeimdallClient, + heimdallClient heimdall.HeimdallClient, recents *lru.ARCCache[libcommon.Hash, *bor.Snapshot], signatures *lru.ARCCache[libcommon.Hash, libcommon.Address], logger log.Logger, @@ -487,7 +488,7 @@ func NewDefaultStages(ctx context.Context, if heimdallClient != nil && flags.Milestone { loopBreakCheck = func(int) bool { - return heimdall.MilestoneRewindPending() + return finality.IsMilestoneRewindPending() } }