From f6c02619fbbd06b692c552b3174460c3e8a0cba5 Mon Sep 17 00:00:00 2001 From: Raneet Debnath <35629432+Raneet10@users.noreply.github.com> Date: Wed, 27 Nov 2024 11:30:20 +0530 Subject: [PATCH] Change parameters for bor producer selection algorithm (#1208) * bor,helper: update seed and voting powers for producer selection * bor: minor fixes * bor: fix GetNextSpanSeed for span-id<2 * helper: (temp) set HF height for testing * bor: (temp) change default params * bor: add logs + fix query for next span * bor: modify last sprint producer case * bor: (temp) add logs for debugging * bor,helper: modify approach to get seed * bor: some cleanup * bor: use pointer receivers + add some debug logs * bor,common: fix storage of seed producer * app,bor,helper: add UTs * Reduce validators collusion chance * Additional tests * If no unique author found, return first one that is different from last author * Change settings for testing * Prevent taking seed in two consecutive spans from same author when there are other authors * Enable at zero height for testing * Add more logging * When proposing span 1, take block 1 * Test for proposing span 1 * Fix tests * Refactor * Update params * bor,helper: address TODOs * bor: add comments for getBorBlockForSpanSeed * helper: (temp) set HF height for testing * bor,helper: set HF name and height for amoy and minor error logging changes in querier * bor: fix lint --------- Co-authored-by: Angel Valkov --- app/app.go | 2 +- bor/client/cli/query.go | 35 ++- bor/client/cli/tx.go | 7 +- bor/client/rest/query.go | 40 ++- bor/client/rest/tx.go | 7 +- bor/export_test.go | 3 + bor/keeper.go | 274 ++++++++++++++++-- bor/keeper_test.go | 252 +++++++++++++++++ bor/querier.go | 44 ++- bor/side_handler.go | 37 ++- bor/types/params.go | 2 +- bridge/setu/processor/span.go | 7 +- bridge/setu/util/common.go | 2 +- common/error.go | 29 +- helper/call.go | 38 +++ helper/config.go | 11 + helper/mocks/IContractCaller.go | 481 ++++++++++++++++++++++++++------ 17 files changed, 1128 insertions(+), 143 deletions(-) create mode 100644 bor/export_test.go create mode 100644 bor/keeper_test.go diff --git a/app/app.go b/app/app.go index ab35e28b0..675f1633e 100644 --- a/app/app.go +++ b/app/app.go @@ -357,7 +357,7 @@ func NewHeimdallApp(logger log.Logger, db dbm.DB, baseAppOptions ...func(*bam.Ba common.DefaultCodespace, app.ChainKeeper, app.StakingKeeper, - app.caller, + &app.caller, ) app.ClerkKeeper = clerk.NewKeeper( diff --git a/bor/client/cli/query.go b/bor/client/cli/query.go index 3042fada6..c9433df91 100644 --- a/bor/client/cli/query.go +++ b/bor/client/cli/query.go @@ -223,14 +223,28 @@ func GetSpanList(cdc *codec.Codec) *cobra.Command { // GetNextSpanSeed implements the next span seed. func GetNextSpanSeed(cdc *codec.Codec) *cobra.Command { - return &cobra.Command{ + cmd := &cobra.Command{ Use: "next-span-seed", - Args: cobra.NoArgs, Short: "show the next span seed", RunE: func(cmd *cobra.Command, args []string) error { cliCtx := context.NewCLIContext().WithCodec(cdc) - res, _, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/%s", types.QuerierRoute, types.QueryNextSpanSeed), nil) + spanIDStr := viper.GetString(FlagSpanId) + if spanIDStr == "" { + return fmt.Errorf("span id cannot be empty") + } + + spanID, err := strconv.ParseUint(spanIDStr, 10, 64) + if err != nil { + return err + } + + seedQueryParams, err := cliCtx.Codec.MarshalJSON(types.NewQuerySpanParams(spanID)) + if err != nil { + return err + } + + res, _, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/%s", types.QuerierRoute, types.QueryNextSpanSeed), seedQueryParams) if err != nil { fmt.Println("Error while fetching the span seed") @@ -247,6 +261,14 @@ func GetNextSpanSeed(cdc *codec.Codec) *cobra.Command { }, } + + cmd.Flags().String(FlagSpanId, "", "--span-id=") + + if err := cmd.MarkFlagRequired(FlagSpanId); err != nil { + cliLogger.Error("GetNextSpanSeed | MarkFlagRequired | FlagSpanId", "Error", err) + } + + return cmd } // PostSendProposeSpanTx send propose span transaction @@ -309,7 +331,12 @@ func GetPreparedProposeSpan(cdc *codec.Codec) *cobra.Command { return err } - res, _, err = cliCtx.QueryWithData(fmt.Sprintf("custom/%s/%s", types.QuerierRoute, types.QueryNextSpanSeed), nil) + seedQueryParams, err := cliCtx.Codec.MarshalJSON(types.NewQuerySpanParams(spanID)) + if err != nil { + return err + } + + res, _, err = cliCtx.QueryWithData(fmt.Sprintf("custom/%s/%s", types.QuerierRoute, types.QueryNextSpanSeed), seedQueryParams) if err != nil { return err } diff --git a/bor/client/cli/tx.go b/bor/client/cli/tx.go index 4d9d5c48a..46aba4c7b 100644 --- a/bor/client/cli/tx.go +++ b/bor/client/cli/tx.go @@ -102,7 +102,12 @@ func PostSendProposeSpanTx(cdc *codec.Codec) *cobra.Command { return err } - res, _, err = cliCtx.QueryWithData(fmt.Sprintf("custom/%s/%s", types.QuerierRoute, types.QueryNextSpanSeed), nil) + seedQueryParams, err := cliCtx.Codec.MarshalJSON(types.NewQuerySpanParams(spanID)) + if err != nil { + return err + } + + res, _, err = cliCtx.QueryWithData(fmt.Sprintf("custom/%s/%s", types.QuerierRoute, types.QueryNextSpanSeed), seedQueryParams) if err != nil { return err } diff --git a/bor/client/rest/query.go b/bor/client/rest/query.go index 060266e1f..590775169 100644 --- a/bor/client/rest/query.go +++ b/bor/client/rest/query.go @@ -135,11 +135,21 @@ func registerQueryRoutes(cliCtx context.CLIContext, r *mux.Router) { r.HandleFunc("/bor/span/{id}", spanHandlerFn(cliCtx)).Methods("GET") r.HandleFunc("/bor/latest-span", latestSpanHandlerFn(cliCtx)).Methods("GET") r.HandleFunc("/bor/prepare-next-span", prepareNextSpanHandlerFn(cliCtx)).Methods("GET") - r.HandleFunc("/bor/next-span-seed", fetchNextSpanSeedHandlerFn(cliCtx)).Methods("GET") + r.HandleFunc("/bor/next-span-seed/{id}", fetchNextSpanSeedHandlerFn(cliCtx)).Methods("GET") r.HandleFunc("/bor/params", paramsHandlerFn(cliCtx)).Methods("GET") } -// swagger:route GET /bor/next-span-seed bor borNextSpanSeed +//swagger:parameters borCurrentSpanById +type borCurrentSpanById struct { + + //Id number of the span + //required:true + //type:integer + //in:path + Id int `json:"id"` +} + +// swagger:route GET /bor/next-span-seed/{id} bor borCurrentSpanById // It returns the seed for the next span // responses: // 200: borNextSpanSeedResponse @@ -153,7 +163,19 @@ func fetchNextSpanSeedHandlerFn( return } - res, _, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/%s", types.QuerierRoute, types.QueryNextSpanSeed), nil) + vars := mux.Vars(r) + + spanID, ok := rest.ParseUint64OrReturnBadRequest(w, vars["id"]) + if !ok { + return + } + + seedQueryParams, err := cliCtx.Codec.MarshalJSON(types.NewQuerySpanParams(spanID)) + if err != nil { + return + } + + res, _, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/%s", types.QuerierRoute, types.QueryNextSpanSeed), seedQueryParams) if err != nil { RestLogger.Error("Error while fetching next span seed ", "Error", err.Error()) rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) @@ -165,7 +187,7 @@ func fetchNextSpanSeedHandlerFn( // error if span seed found if !hmRest.ReturnNotFoundIfNoContent(w, res, "NextSpanSeed not found") { - RestLogger.Error("NextSpanSeed not found ", "Error", err.Error()) + RestLogger.Error("NextSpanSeed not found ", "Error", err) return } @@ -458,8 +480,16 @@ func prepareNextSpanHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { // Fetching SelectedProducers // - nextProducerBytes, _, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/%s", types.QuerierRoute, types.QueryNextProducers), nil) + query, err := cliCtx.Codec.MarshalJSON(types.NewQuerySpanParams(spanID)) + if err != nil { + fmt.Println("error while marshalling: ", err) + hmRest.WriteErrorResponse(w, http.StatusNoContent, errors.New("unable to marshal JSON").Error()) + return + } + + nextProducerBytes, _, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/%s", types.QuerierRoute, types.QueryNextProducers), query) if err != nil { + fmt.Println("error while querying next producers: ", err) hmRest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) return } diff --git a/bor/client/rest/tx.go b/bor/client/rest/tx.go index 71db0e119..842aaae3a 100644 --- a/bor/client/rest/tx.go +++ b/bor/client/rest/tx.go @@ -149,8 +149,13 @@ func postProposeSpanHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { return } + seedQueryParams, err := cliCtx.Codec.MarshalJSON(types.NewQuerySpanParams(req.ID)) + if err != nil { + return + } + // fetch seed - res, _, err = cliCtx.QueryWithData(fmt.Sprintf("custom/%s/%s", types.QuerierRoute, types.QueryNextSpanSeed), nil) + res, _, err = cliCtx.QueryWithData(fmt.Sprintf("custom/%s/%s", types.QuerierRoute, types.QueryNextSpanSeed), seedQueryParams) if err != nil { RestLogger.Error("Error while fetching next span seed ", "Error", err.Error()) rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) diff --git a/bor/export_test.go b/bor/export_test.go new file mode 100644 index 000000000..10cc66b3d --- /dev/null +++ b/bor/export_test.go @@ -0,0 +1,3 @@ +package bor + +var RollbackVotingPowers = rollbackVotingPowers diff --git a/bor/keeper.go b/bor/keeper.go index ab3d41824..d4872c321 100644 --- a/bor/keeper.go +++ b/bor/keeper.go @@ -2,6 +2,7 @@ package bor import ( "errors" + "fmt" "math/big" "strconv" @@ -10,6 +11,7 @@ import ( "github.com/tendermint/tendermint/libs/log" "github.com/ethereum/go-ethereum/common" + ethTypes "github.com/ethereum/go-ethereum/core/types" "github.com/maticnetwork/heimdall/bor/types" "github.com/maticnetwork/heimdall/chainmanager" @@ -20,11 +22,14 @@ import ( ) const maxSpanListLimit = 150 // a span is ~6 KB => we can fit 150 spans in 1 MB response +const blockAuthorsCollisionCheck = 10 +const blockProducerMaxSpanLookback = 50 var ( LastSpanIDKey = []byte{0x35} // Key to store last span start block SpanPrefixKey = []byte{0x36} // prefix key to store span LastProcessedEthBlock = []byte{0x38} // key to store last processed eth block for seed + SeedLastProducerKey = []byte{0x39} // key to store last producer of the span ) // Keeper stores all related data @@ -38,7 +43,7 @@ type Keeper struct { // param space paramSpace subspace.Subspace // contract caller - contractCaller helper.ContractCaller + contractCaller helper.IContractCaller // chain manager keeper chainKeeper chainmanager.Keeper } @@ -51,7 +56,7 @@ func NewKeeper( codespace sdk.CodespaceType, chainKeeper chainmanager.Keeper, stakingKeeper staking.Keeper, - caller helper.ContractCaller, + caller *helper.ContractCaller, ) Keeper { return Keeper{ cdc: cdc, @@ -79,6 +84,16 @@ func GetSpanKey(id uint64) []byte { return append(SpanPrefixKey, []byte(strconv.FormatUint(id, 10))...) } +func GetLastSeedProducer(id uint64) []byte { + idBytes := sdk.Uint64ToBigEndian(id) + return append(SeedLastProducerKey, idBytes...) +} + +// SetContractCaller sets contract caller +func (k *Keeper) SetContractCaller(contractCaller helper.IContractCaller) { + k.contractCaller = contractCaller +} + // AddNewSpan adds new span for bor to store func (k *Keeper) AddNewSpan(ctx sdk.Context, span hmTypes.Span) error { store := ctx.KVStore(k.storeKey) @@ -194,14 +209,44 @@ func (k *Keeper) GetLastSpan(ctx sdk.Context) (*hmTypes.Span, error) { // FreezeSet freezes validator set for next span func (k *Keeper) FreezeSet(ctx sdk.Context, id uint64, startBlock uint64, endBlock uint64, borChainID string, seed common.Hash) error { - // select next producers - newProducers, err := k.SelectNextProducers(ctx, seed) - if err != nil { - return err - } + var ( + newProducers []hmTypes.Validator + err error + ) + + if ctx.BlockHeight() < helper.GetJorvikHeight() { + newProducers, err = k.SelectNextProducers(ctx, seed, nil) + if err != nil { + return err + } + + // increment last eth block + k.IncrementLastEthBlock(ctx) + } else { + var lastSpan *hmTypes.Span + var lastSpanId uint64 + if id < 2 { + lastSpanId = id - 1 + } else { + lastSpanId = id - 2 + } - // increment last eth block - k.IncrementLastEthBlock(ctx) + lastSpan, err = k.GetSpan(ctx, lastSpanId) + if err != nil { + return err + } + + prevVals := make([]hmTypes.Validator, 0, len(lastSpan.ValidatorSet.Validators)) + for _, val := range lastSpan.ValidatorSet.Validators { + prevVals = append(prevVals, *val) + } + + // select next producers + newProducers, err = k.SelectNextProducers(ctx, seed, prevVals) + if err != nil { + return err + } + } // generate new span newSpan := hmTypes.NewSpan( @@ -213,11 +258,17 @@ func (k *Keeper) FreezeSet(ctx sdk.Context, id uint64, startBlock uint64, endBlo borChainID, ) + k.Logger(ctx).Info("Freezing new span", "id", id, "span", newSpan) + return k.AddNewSpan(ctx, newSpan) } // SelectNextProducers selects producers for next span -func (k *Keeper) SelectNextProducers(ctx sdk.Context, seed common.Hash) (vals []hmTypes.Validator, err error) { +func (k *Keeper) SelectNextProducers(ctx sdk.Context, seed common.Hash, prevVals []hmTypes.Validator) (vals []hmTypes.Validator, err error) { + if ctx.BlockHeader().Height < helper.GetJorvikHeight() { + prevVals = nil + } + // spanEligibleVals are current validators who are not getting deactivated in between next span spanEligibleVals := k.sk.GetSpanEligibleValidators(ctx) producerCount := k.GetParams(ctx).ProducerCount @@ -227,8 +278,13 @@ func (k *Keeper) SelectNextProducers(ctx sdk.Context, seed common.Hash) (vals [] return spanEligibleVals, nil } - // TODO remove old selection algorigthm - // select next producers using seed as blockheader hash + if len(prevVals) > 0 { + // rollback voting powers for the selection algorithm + spanEligibleVals = rollbackVotingPowers(ctx, spanEligibleVals, prevVals) + } + + // TODO remove old selection algorithm + // select next producers using seed as block header hash fn := SelectNextProducers if ctx.BlockHeight() < helper.GetNewSelectionAlgoHeight() { fn = XXXSelectNextProducers @@ -293,23 +349,84 @@ func (k *Keeper) GetLastEthBlock(ctx sdk.Context) *big.Int { return lastEthBlock } -func (k Keeper) GetNextSpanSeed(ctx sdk.Context) (common.Hash, error) { - lastEthBlock := k.GetLastEthBlock(ctx) +func (k *Keeper) GetNextSpanSeed(ctx sdk.Context, id uint64) (common.Hash, error) { + var ( + blockHeader *ethTypes.Header + seedSpan *hmTypes.Span + err error + ) - // increment last processed header block number - newEthBlock := lastEthBlock.Add(lastEthBlock, big.NewInt(1)) - k.Logger(ctx).Debug("newEthBlock to generate seed", "newEthBlock", newEthBlock) + if ctx.BlockHeader().Height < helper.GetJorvikHeight() { + lastEthBlock := k.GetLastEthBlock(ctx) + // increment last processed header block number + newEthBlock := lastEthBlock.Add(lastEthBlock, big.NewInt(1)) + k.Logger(ctx).Debug("newEthBlock to generate seed", "newEthBlock", newEthBlock) - // fetch block header from mainchain - blockHeader, err := k.contractCaller.GetMainChainBlock(newEthBlock) - if err != nil { - k.Logger(ctx).Error("Error fetching block header from mainchain while calculating next span seed", "error", err) - return common.Hash{}, err + // fetch block header from mainchain + var err error + blockHeader, err = k.contractCaller.GetMainChainBlock(newEthBlock) + if err != nil { + k.Logger(ctx).Error("Error fetching block header from mainchain while calculating next span seed", "error", err) + return common.Hash{}, err + } + } else { + var seedSpanID uint64 + if id < 2 { + seedSpanID = id - 1 + } else { + seedSpanID = id - 2 + } + seedSpan, err = k.GetSpan(ctx, seedSpanID) + if err != nil { + k.Logger(ctx).Error("Error fetching span while calculating next span seed", "error", err) + return common.Hash{}, err + } + + borBlock, author, err := k.getBorBlockForSpanSeed(ctx, seedSpan, id) + if err != nil { + return common.Hash{}, err + } + + blockHeader, err = k.contractCaller.GetMaticChainBlock(big.NewInt(int64(borBlock))) + if err != nil { + k.Logger(ctx).Error("Error fetching block header from bor chain while calculating next span seed", "error", err, "block", borBlock) + return common.Hash{}, err + } + + k.Logger(ctx).Debug("fetched block for seed", "block", borBlock, "author", author, "span id", id) } return blockHeader.Hash(), nil } +// StoreSeedProducer stores producer of the block used for seed for the given span id +func (k *Keeper) StoreSeedProducer(ctx sdk.Context, id uint64, producer *common.Address) error { + store := ctx.KVStore(k.storeKey) + lastSeedKey := GetLastSeedProducer(id) + + if store.Has(lastSeedKey) { + return errors.New("seed producer already stored") + } + + store.Set(lastSeedKey, producer.Bytes()) + return nil +} + +// GetSeedProducer gets producer of the block used for seed for the given span id +func (k *Keeper) GetSeedProducer(ctx sdk.Context, id uint64) (*common.Address, error) { + store := ctx.KVStore(k.storeKey) + lastSeedKey := GetLastSeedProducer(id) + + authorBytes := store.Get(lastSeedKey) + if authorBytes == nil { + return nil, nil //nolint: nilnil + } + + author := common.BytesToAddress(authorBytes) + + return &author, nil +} + // ----------------------------------------------------------------------------- // Params @@ -349,3 +466,116 @@ func (k *Keeper) IterateSpansAndApplyFn(ctx sdk.Context, f func(span hmTypes.Spa } } } + +// getBorBlockForSpanSeed returns the bor block number and its producer whose hash is used as seed for the next span +func (k *Keeper) getBorBlockForSpanSeed(ctx sdk.Context, seedSpan *hmTypes.Span, proposedSpanID uint64) (uint64, *common.Address, error) { + var ( + borBlock uint64 + author *common.Address + err error + ) + + logger := k.Logger(ctx) + + logger.Debug("getting bor block for span seed", "span id", seedSpan.ID, "proposed span id", proposedSpanID) + + if proposedSpanID == 1 { + borBlock = 1 + author, err = k.contractCaller.GetBorChainBlockAuthor(big.NewInt(int64(borBlock))) + if err != nil { + logger.Error("Error fetching first block for span seed", "error", err, "block", borBlock) + return 0, nil, err + } + + logger.Debug("returning first block author", "author", author, "block", borBlock) + + return borBlock, author, nil + } + + uniqueAuthors := make(map[string]struct{}) + spanID := proposedSpanID - 1 + + lastAuthor, err := k.GetSeedProducer(ctx, spanID) + if err != nil { + logger.Error("Error fetching last seed producer", "error", err, "span id", spanID) + return 0, nil, err + } + + // get seed block authors from last "blockProducerMaxSpanLookback" spans + for i := 0; len(uniqueAuthors) < blockAuthorsCollisionCheck && i < blockProducerMaxSpanLookback; i++ { + if spanID == 0 { + break + } + + author, err := k.GetSeedProducer(ctx, spanID) + if err != nil { + logger.Error("Error fetching span seed producer", "error", err, "span id", spanID) + return 0, nil, err + } + + if author == nil { + logger.Info("GetSeedProducer returned empty value", "span id", spanID) + break + } + + uniqueAuthors[author.Hex()] = struct{}{} + spanID-- + } + + logger.Debug("last authors", "authors", fmt.Sprintf("%+v", uniqueAuthors), "span id", seedSpan.ID) + + firstDiffFromLast := uint64(0) + + // try to find a seed block with an author not in the last "blockAuthorsCollisionCheck" spans + borParams := k.GetParams(ctx) + for borBlock = seedSpan.EndBlock; borBlock >= seedSpan.StartBlock; borBlock -= borParams.SprintDuration { + author, err = k.contractCaller.GetBorChainBlockAuthor(big.NewInt(int64(borBlock))) + if err != nil { + logger.Error("Error fetching block author from bor chain while calculating next span seed", "error", err, "block", borBlock) + return 0, nil, err + } + + if _, exists := uniqueAuthors[author.Hex()]; !exists || len(seedSpan.ValidatorSet.Validators) == 1 { + logger.Debug("got author", "author", author, "block", borBlock) + return borBlock, author, nil + } + + if firstDiffFromLast == 0 && lastAuthor != nil && author.Hex() != lastAuthor.Hex() { + firstDiffFromLast = borBlock + } + } + + // if no unique author found, return the first different block author + borBlock = firstDiffFromLast + if borBlock == 0 { + borBlock = seedSpan.EndBlock + } + + author, err = k.contractCaller.GetBorChainBlockAuthor(big.NewInt(int64(borBlock))) + if err != nil { + logger.Error("Error fetching end block author from bor chain while calculating next span seed", "error", err, "block", borBlock) + return 0, nil, err + } + + logger.Debug("returning first different block author", "author", author, "block", borBlock) + + return borBlock, author, nil +} + +// rollbackVotingPowers rolls back voting powers of validators from a previous snapshot of validators +func rollbackVotingPowers(ctx sdk.Context, valsNew, valsOld []hmTypes.Validator) []hmTypes.Validator { + idToVP := make(map[uint64]int64) + for _, val := range valsOld { + idToVP[val.ID.Uint64()] = val.VotingPower + } + + for i := range valsNew { + if _, ok := idToVP[valsNew[i].ID.Uint64()]; ok { + valsNew[i].VotingPower = idToVP[valsNew[i].ID.Uint64()] + } else { + valsNew[i].VotingPower = 0 + } + } + + return valsNew +} diff --git a/bor/keeper_test.go b/bor/keeper_test.go new file mode 100644 index 000000000..68e3cbe4c --- /dev/null +++ b/bor/keeper_test.go @@ -0,0 +1,252 @@ +package bor_test + +import ( + "math/big" + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/ethereum/go-ethereum/common" + ethTypes "github.com/ethereum/go-ethereum/core/types" + "github.com/maticnetwork/heimdall/app" + "github.com/maticnetwork/heimdall/bor" + "github.com/maticnetwork/heimdall/helper/mocks" + hmTypes "github.com/maticnetwork/heimdall/types" + "github.com/stretchr/testify/suite" + abci "github.com/tendermint/tendermint/abci/types" +) + +type BorKeeperTestSuite struct { + suite.Suite + + app *app.HeimdallApp + contractCaller *mocks.IContractCaller + ctx sdk.Context +} + +func createTestApp(isCheckTx bool) (*app.HeimdallApp, sdk.Context) { + app := app.Setup(isCheckTx) + ctx := app.BaseApp.NewContext(isCheckTx, abci.Header{}) + + return app, ctx +} + +func (suite *BorKeeperTestSuite) SetupTest() { + suite.app, suite.ctx = createTestApp(false) + suite.contractCaller = &mocks.IContractCaller{} + suite.app.BorKeeper.SetContractCaller(suite.contractCaller) +} + +func TestKeeperTestSuite(t *testing.T) { + t.Parallel() + suite.Run(t, new(BorKeeperTestSuite)) +} + +func (s *BorKeeperTestSuite) TestGetNextSpanSeed() { + require, ctx, borKeeper := s.Require(), s.ctx, s.app.BorKeeper + valSet := s.setupValSet() + vals := make([]hmTypes.Validator, 0, len(valSet.Validators)) + for _, val := range valSet.Validators { + vals = append(vals, *val) + } + + spans := []hmTypes.Span{ + hmTypes.NewSpan(0, 0, 256, *valSet, vals, "test-chain"), + hmTypes.NewSpan(1, 257, 6656, *valSet, vals, "test-chain"), + hmTypes.NewSpan(2, 6657, 16656, *valSet, vals, "test-chain"), + hmTypes.NewSpan(3, 16657, 26656, *valSet, vals, "test-chain"), + } + + for _, span := range spans { + err := borKeeper.AddNewSpan(ctx, span) + require.NoError(err) + } + + val1Addr := vals[0].PubKey.Address() + val2Addr := vals[1].PubKey.Address() + val3Addr := vals[2].PubKey.Address() + + borParams := borKeeper.GetParams(ctx) + + seedBlock1 := spans[0].EndBlock + s.contractCaller.On("GetBorChainBlockAuthor", big.NewInt(int64(seedBlock1))).Return(&val2Addr, nil) + + seedBlock2 := spans[1].EndBlock - borParams.SprintDuration + s.contractCaller.On("GetBorChainBlockAuthor", big.NewInt(int64(spans[1].EndBlock))).Return(&val2Addr, nil) + s.contractCaller.On("GetBorChainBlockAuthor", big.NewInt(int64(seedBlock2))).Return(&val1Addr, nil) + for block := spans[1].EndBlock - (2 * borParams.SprintDuration); block >= spans[1].StartBlock; block -= borParams.SprintDuration { + s.contractCaller.On("GetBorChainBlockAuthor", big.NewInt(int64(block))).Return(&val1Addr, nil) + } + + seedBlock3 := spans[2].EndBlock - (2 * borParams.SprintDuration) + s.contractCaller.On("GetBorChainBlockAuthor", big.NewInt(int64(spans[2].EndBlock))).Return(&val1Addr, nil) + s.contractCaller.On("GetBorChainBlockAuthor", big.NewInt(int64(spans[2].EndBlock-borParams.SprintDuration))).Return(&val2Addr, nil) + s.contractCaller.On("GetBorChainBlockAuthor", big.NewInt(int64(seedBlock3))).Return(&val3Addr, nil) + + seedBlock4 := spans[3].EndBlock - borParams.SprintDuration + s.contractCaller.On("GetBorChainBlockAuthor", big.NewInt(int64(spans[3].EndBlock))).Return(&val1Addr, nil) + + for block := spans[3].EndBlock; block >= spans[3].StartBlock; block -= borParams.SprintDuration { + s.contractCaller.On("GetBorChainBlockAuthor", big.NewInt(int64(block))).Return(&val2Addr, nil) + } + + blockHeader1 := ethTypes.Header{Number: big.NewInt(int64(seedBlock1))} + blockHash1 := blockHeader1.Hash() + blockHeader2 := ethTypes.Header{Number: big.NewInt(int64(seedBlock2))} + blockHash2 := blockHeader2.Hash() + blockHeader3 := ethTypes.Header{Number: big.NewInt(int64(seedBlock3))} + blockHash3 := blockHeader3.Hash() + blockHeader4 := ethTypes.Header{Number: big.NewInt(int64(seedBlock4))} + blockHash4 := blockHeader4.Hash() + + s.contractCaller.On("GetMaticChainBlock", big.NewInt(int64(seedBlock1))).Return(&blockHeader1, nil) + s.contractCaller.On("GetMaticChainBlock", big.NewInt(int64(seedBlock2))).Return(&blockHeader2, nil) + s.contractCaller.On("GetMaticChainBlock", big.NewInt(int64(seedBlock3))).Return(&blockHeader3, nil) + s.contractCaller.On("GetMaticChainBlock", big.NewInt(int64(seedBlock4))).Return(&blockHeader4, nil) + + testcases := []struct { + name string + lastSpanId uint64 + lastSeedProducer *common.Address + expSeed common.Hash + }{ + { + name: "Last seed producer is different than end block author", + lastSeedProducer: &val2Addr, + lastSpanId: 0, + expSeed: blockHash1, + }, + { + name: "Last seed producer is same as end block author", + lastSeedProducer: &val1Addr, + lastSpanId: 1, + expSeed: blockHash2, + }, + { + name: "Next seed producer should be different from previous recent seed producers", + lastSeedProducer: &val2Addr, + lastSpanId: 2, + expSeed: blockHash3, + }, + { + name: "If no unique seed producer is found, first block with different author from previous seed producer is selected", + lastSeedProducer: &val1Addr, + lastSpanId: 3, + expSeed: blockHash4, + }, + } + + lastSpanID := uint64(0) + + for _, tc := range testcases { + err := borKeeper.StoreSeedProducer(ctx, tc.lastSpanId, tc.lastSeedProducer) + require.NoError(err) + + lastSpanID = tc.lastSpanId + } + + err := borKeeper.StoreSeedProducer(ctx, lastSpanID+1, &val1Addr) + require.NoError(err) + + for _, tc := range testcases { + s.T().Run(tc.name, func(t *testing.T) { + seed, err := borKeeper.GetNextSpanSeed(ctx, tc.lastSpanId+2) + require.NoError(err) + require.Equal(tc.expSeed.Bytes(), seed.Bytes()) + }) + } +} + +func (s *BorKeeperTestSuite) TestProposeSpanOne() { + app, ctx := createTestApp(false) + contractCaller := &mocks.IContractCaller{} + app.BorKeeper.SetContractCaller(contractCaller) + + valSet := setupValSet() + vals := make([]hmTypes.Validator, 0, len(valSet.Validators)) + for _, val := range valSet.Validators { + vals = append(vals, *val) + } + err := app.BorKeeper.AddNewSpan(ctx, hmTypes.NewSpan(0, 0, 256, *valSet, vals, "test-chain")) + s.Require().NoError(err) + + val1Addr := vals[0].PubKey.Address() + + seedBlock1 := int64(1) + contractCaller.On("GetBorChainBlockAuthor", big.NewInt(seedBlock1)).Return(&val1Addr, nil) + + blockHeader1 := ethTypes.Header{Number: big.NewInt(seedBlock1)} + blockHash1 := blockHeader1.Hash() + contractCaller.On("GetMaticChainBlock", big.NewInt(seedBlock1)).Return(&blockHeader1, nil) + + seed, err := app.BorKeeper.GetNextSpanSeed(ctx, 1) + s.Require().NoError(err) + s.Require().Equal(blockHash1.Bytes(), seed.Bytes()) +} + +func (s *BorKeeperTestSuite) TestGetSeedProducer() { + borKeeper := s.app.BorKeeper + producer := common.HexToAddress("0xc0ffee254729296a45a3885639AC7E10F9d54979") + err := borKeeper.StoreSeedProducer(s.ctx, 1, &producer) + s.Require().NoError(err) + + author, err := borKeeper.GetSeedProducer(s.ctx, 1) + s.Require().NoError(err) + s.Require().Equal(producer.Bytes(), author.Bytes()) + +} + +func (s *BorKeeperTestSuite) TestRollbackVotingPowers() { + testcases := []struct { + name string + valsOld []hmTypes.Validator + valsNew []hmTypes.Validator + expRes []hmTypes.Validator + }{ + { + name: "Revert to old voting powers", + valsOld: []hmTypes.Validator{{ID: 1, VotingPower: 100}, {ID: 2, VotingPower: 200}, {ID: 3, VotingPower: 300}}, + valsNew: []hmTypes.Validator{{ID: 1, VotingPower: 200}, {ID: 2, VotingPower: 400}, {ID: 3, VotingPower: 200}}, + expRes: []hmTypes.Validator{{ID: 1, VotingPower: 100}, {ID: 2, VotingPower: 200}, {ID: 3, VotingPower: 300}}, + }, + { + name: "Validator joined", + valsOld: []hmTypes.Validator{{ID: 1, VotingPower: 100}, {ID: 2, VotingPower: 200}}, + valsNew: []hmTypes.Validator{{ID: 1, VotingPower: 100}, {ID: 2, VotingPower: 200}, {ID: 3, VotingPower: 300}}, + expRes: []hmTypes.Validator{{ID: 1, VotingPower: 100}, {ID: 2, VotingPower: 200}, {ID: 3, VotingPower: 0}}, + }, + { + name: "Validator left", + valsOld: []hmTypes.Validator{{ID: 1, VotingPower: 100}, {ID: 2, VotingPower: 200}, {ID: 3, VotingPower: 300}}, + valsNew: []hmTypes.Validator{{ID: 1, VotingPower: 100}, {ID: 2, VotingPower: 200}}, + expRes: []hmTypes.Validator{{ID: 1, VotingPower: 100}, {ID: 2, VotingPower: 200}}, + }, + } + + for _, tc := range testcases { + s.T().Run(tc.name, func(t *testing.T) { + res := bor.RollbackVotingPowers(s.ctx, tc.valsNew, tc.valsOld) + s.Require().Equal(tc.expRes, res) + }) + } +} + +func (suite *BorKeeperTestSuite) setupValSet() *hmTypes.ValidatorSet { + suite.T().Helper() + return setupValSet() +} + +func setupValSet() *hmTypes.ValidatorSet { + + pubKey1 := hmTypes.NewPubKey([]byte("pubkey1")) + pubKey2 := hmTypes.NewPubKey([]byte("pubkey2")) + pubKey3 := hmTypes.NewPubKey([]byte("pubkey3")) + + val1 := hmTypes.NewValidator(1, 100, 0, 1, 100, hmTypes.NewPubKey(pubKey1[:]), hmTypes.HeimdallAddress(pubKey1.Address())) + val2 := hmTypes.NewValidator(2, 100, 0, 1, 100, hmTypes.NewPubKey(pubKey2[:]), hmTypes.HeimdallAddress(pubKey2.Address())) + val3 := hmTypes.NewValidator(3, 100, 0, 1, 100, hmTypes.NewPubKey(pubKey3[:]), hmTypes.HeimdallAddress(pubKey3.Address())) + + vals := []*hmTypes.Validator{val1, val2, val3} + valSet := hmTypes.NewValidatorSet(vals) + + return valSet +} diff --git a/bor/querier.go b/bor/querier.go index 47a1772c6..1726a72e2 100644 --- a/bor/querier.go +++ b/bor/querier.go @@ -160,13 +160,41 @@ func handleQueryLatestSpan(ctx sdk.Context, _ abci.RequestQuery, keeper Keeper) return bz, nil } -func handleQueryNextProducers(ctx sdk.Context, _ abci.RequestQuery, keeper Keeper) ([]byte, sdk.Error) { - nextSpanSeed, err := keeper.GetNextSpanSeed(ctx) +func handleQueryNextProducers(ctx sdk.Context, req abci.RequestQuery, keeper Keeper) ([]byte, sdk.Error) { + var params types.QuerySpanParams + + if err := keeper.cdc.UnmarshalJSON(req.Data, ¶ms); err != nil { + return nil, sdk.ErrInternal(fmt.Sprintf("failed to parse params: %s", err)) + } + + spanId := params.RecordID + logger := ctx.Logger() + logger.Debug("querying next producers", "spanId", spanId) + + nextSpanSeed, err := keeper.GetNextSpanSeed(ctx, spanId) if err != nil { return nil, sdk.ErrInternal((sdk.AppendMsgToErr("cannot fetch next span seed from keeper", err.Error()))) } - nextProducers, err := keeper.SelectNextProducers(ctx, nextSpanSeed) + logger.Debug("next span seed", "seed", nextSpanSeed) + + if params.RecordID < 2 { + spanId = params.RecordID - 1 + } else { + spanId = params.RecordID - 2 + } + + prevSpan, err := keeper.GetSpan(ctx, spanId) + if err != nil { + return nil, sdk.ErrInternal((sdk.AppendMsgToErr("cannot fetch last span from keeper", err.Error()))) + } + + prevVals := make([]hmTypes.Validator, 0, len(prevSpan.ValidatorSet.Validators)) + for _, val := range prevSpan.ValidatorSet.Validators { + prevVals = append(prevVals, *val) + } + + nextProducers, err := keeper.SelectNextProducers(ctx, nextSpanSeed, prevVals) if err != nil { return nil, sdk.ErrInternal((sdk.AppendMsgToErr("cannot fetch next producers from keeper", err.Error()))) } @@ -179,8 +207,14 @@ func handleQueryNextProducers(ctx sdk.Context, _ abci.RequestQuery, keeper Keepe return bz, nil } -func handlerQueryNextSpanSeed(ctx sdk.Context, _ abci.RequestQuery, keeper Keeper) ([]byte, sdk.Error) { - nextSpanSeed, err := keeper.GetNextSpanSeed(ctx) +func handlerQueryNextSpanSeed(ctx sdk.Context, req abci.RequestQuery, keeper Keeper) ([]byte, sdk.Error) { + var params types.QuerySpanParams + + if err := keeper.cdc.UnmarshalJSON(req.Data, ¶ms); err != nil { + return nil, sdk.ErrInternal(fmt.Sprintf("failed to parse params: %s", err)) + } + + nextSpanSeed, err := keeper.GetNextSpanSeed(ctx, params.RecordID) if err != nil { return nil, sdk.ErrInternal(sdk.AppendMsgToErr("Error fetching next span seed", err.Error())) diff --git a/bor/side_handler.go b/bor/side_handler.go index b3543e936..93c471097 100644 --- a/bor/side_handler.go +++ b/bor/side_handler.go @@ -52,7 +52,7 @@ func SideHandleMsgSpan(ctx sdk.Context, k Keeper, msg types.MsgProposeSpan, cont ) // calculate next span seed locally - nextSpanSeed, err := k.GetNextSpanSeed(ctx) + nextSpanSeed, err := k.GetNextSpanSeed(ctx, msg.ID) if err != nil { k.Logger(ctx).Error("Error fetching next span seed from mainchain") return hmCommon.ErrorSideTx(k.Codespace(), common.CodeInvalidMsg) @@ -104,20 +104,49 @@ func SideHandleMsgSpan(ctx sdk.Context, k Keeper, msg types.MsgProposeSpan, cont // PostHandleMsgEventSpan handles state persisting span msg func PostHandleMsgEventSpan(ctx sdk.Context, k Keeper, msg types.MsgProposeSpan, sideTxResult abci.SideTxResultType) sdk.Result { + logger := k.Logger(ctx) + // Skip handler if span is not approved if sideTxResult != abci.SideTxResultType_Yes { - k.Logger(ctx).Debug("Skipping new span since side-tx didn't get yes votes") + logger.Debug("Skipping new span since side-tx didn't get yes votes") return common.ErrSideTxValidation(k.Codespace()).Result() } // check for replay if k.HasSpan(ctx, msg.ID) { - k.Logger(ctx).Debug("Skipping new span as it's already processed") + logger.Debug("Skipping new span as it's already processed") return hmCommon.ErrOldTx(k.Codespace()).Result() } - k.Logger(ctx).Debug("Persisting span state", "sideTxResult", sideTxResult) + logger.Debug("Persisting span state", "sideTxResult", sideTxResult) + + if ctx.BlockHeader().Height >= helper.GetJorvikHeight() { + var seedSpanID uint64 + if msg.ID < 2 { + seedSpanID = msg.ID - 1 + } else { + seedSpanID = msg.ID - 2 + } + + lastSpan, err := k.GetSpan(ctx, seedSpanID) + if err != nil { + logger.Error("Unable to get last span", "Error", err) + return common.ErrUnableToGetSpan(k.Codespace()).Result() + } + + // store the seed producer + _, producer, err := k.getBorBlockForSpanSeed(ctx, lastSpan, msg.ID) + if err != nil { + logger.Error("Unable to get seed producer", "Error", err) + return common.ErrUnableToGetSeed(k.Codespace()).Result() + } + if err = k.StoreSeedProducer(ctx, msg.ID, producer); err != nil { + logger.Error("Unable to store seed producer", "Error", err) + return common.ErrUnableToStoreSeedProducer(k.Codespace()).Result() + } + + } // freeze for new span err := k.FreezeSet(ctx, msg.ID, msg.StartBlock, msg.EndBlock, msg.ChainID, msg.Seed) if err != nil { diff --git a/bor/types/params.go b/bor/types/params.go index b1e0dcda6..66fb36e48 100644 --- a/bor/types/params.go +++ b/bor/types/params.go @@ -15,7 +15,7 @@ const ( // Default parameter values const ( - DefaultSprintDuration uint64 = 64 + DefaultSprintDuration uint64 = 16 DefaultSpanDuration uint64 = 100 * DefaultSprintDuration DefaultFirstSpanDuration uint64 = 256 DefaultProducerCount uint64 = 4 diff --git a/bridge/setu/processor/span.go b/bridge/setu/processor/span.go index 87da73b95..e869e4f95 100644 --- a/bridge/setu/processor/span.go +++ b/bridge/setu/processor/span.go @@ -3,6 +3,7 @@ package processor import ( "bytes" "context" + "fmt" "net/http" "strconv" "time" @@ -107,7 +108,7 @@ func (sp *SpanProcessor) propose(lastSpan *types.Span, nextSpanMsg *types.Span) // log new span sp.Logger.Info("✅ Proposing new span", "spanId", nextSpanMsg.ID, "startBlock", nextSpanMsg.StartBlock, "endBlock", nextSpanMsg.EndBlock) - seed, err := sp.fetchNextSpanSeed() + seed, err := sp.fetchNextSpanSeed(nextSpanMsg.ID) if err != nil { sp.Logger.Info("Error while fetching next span seed from HeimdallServer", "err", err) return @@ -218,10 +219,10 @@ func (sp *SpanProcessor) fetchNextSpanDetails(id uint64, start uint64) (*types.S } // fetchNextSpanSeed - fetches seed for next span -func (sp *SpanProcessor) fetchNextSpanSeed() (nextSpanSeed common.Hash, err error) { +func (sp *SpanProcessor) fetchNextSpanSeed(id uint64) (nextSpanSeed common.Hash, err error) { sp.Logger.Info("Sending Rest call to Get Seed for next span") - response, err := helper.FetchFromAPI(sp.cliCtx, helper.GetHeimdallServerEndpoint(util.NextSpanSeedURL)) + response, err := helper.FetchFromAPI(sp.cliCtx, helper.GetHeimdallServerEndpoint(fmt.Sprintf(util.NextSpanSeedURL, strconv.FormatUint(id, 10)))) if err != nil { sp.Logger.Error("Error Fetching nextspanseed from HeimdallServer ", "error", err) return nextSpanSeed, err diff --git a/bridge/setu/util/common.go b/bridge/setu/util/common.go index 12a4ae108..6195ee9d0 100644 --- a/bridge/setu/util/common.go +++ b/bridge/setu/util/common.go @@ -51,7 +51,7 @@ const ( CurrentProposerURL = "/staking/current-proposer" LatestSpanURL = "/bor/latest-span" NextSpanInfoURL = "/bor/prepare-next-span" - NextSpanSeedURL = "/bor/next-span-seed" + NextSpanSeedURL = "/bor/next-span-seed/%v" DividendAccountRootURL = "/topup/dividend-account-root" ValidatorURL = "/staking/validator/%v" CurrentValidatorSetURL = "staking/validator-set" diff --git a/common/error.go b/common/error.go index fedf3abcd..88dfb3fc8 100644 --- a/common/error.go +++ b/common/error.go @@ -50,13 +50,16 @@ const ( CodeNoSignerChangeError CodeType = 2513 CodeNonce CodeType = 2514 - CodeSpanNotContinuous CodeType = 3501 - CodeUnableToFreezeSet CodeType = 3502 - CodeSpanNotFound CodeType = 3503 - CodeValSetMisMatch CodeType = 3504 - CodeProducerMisMatch CodeType = 3505 - CodeInvalidBorChainID CodeType = 3506 - CodeInvalidSpanDuration CodeType = 3507 + CodeSpanNotContinuous CodeType = 3501 + CodeUnableToFreezeSet CodeType = 3502 + CodeSpanNotFound CodeType = 3503 + CodeValSetMisMatch CodeType = 3504 + CodeProducerMisMatch CodeType = 3505 + CodeInvalidBorChainID CodeType = 3506 + CodeInvalidSpanDuration CodeType = 3507 + CodeUnableToGetSpan CodeType = 3508 + CodeUnableToGetSeed CodeType = 3509 + CodeUnableToStoreSeedProducer CodeType = 3510 CodeFetchCheckpointSigners CodeType = 4501 CodeErrComputeGenesisAccountRoot CodeType = 4503 @@ -286,6 +289,18 @@ func ErrProducerMisMatch(codespace sdk.CodespaceType) sdk.Error { return newError(codespace, CodeProducerMisMatch, "Producer set mismatch") } +func ErrUnableToGetSpan(codespace sdk.CodespaceType) sdk.Error { + return newError(codespace, CodeUnableToGetSpan, "Span not found") +} + +func ErrUnableToGetSeed(codespace sdk.CodespaceType) sdk.Error { + return newError(codespace, CodeUnableToGetSeed, "Seed not found") +} + +func ErrUnableToStoreSeedProducer(codespace sdk.CodespaceType) sdk.Error { + return newError(codespace, CodeUnableToStoreSeedProducer, "Unable to store seed producer") +} + // // Side-tx errors // diff --git a/helper/call.go b/helper/call.go index bac756edb..905ca3502 100644 --- a/helper/call.go +++ b/helper/call.go @@ -9,8 +9,10 @@ import ( "strings" "time" + "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" ethTypes "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/ethclient" "github.com/ethereum/go-ethereum/rpc" @@ -58,6 +60,7 @@ type IContractCaller interface { GetCheckpointSign(txHash common.Hash) ([]byte, []byte, []byte, error) GetMainChainBlock(*big.Int) (*ethTypes.Header, error) GetMaticChainBlock(*big.Int) (*ethTypes.Header, error) + GetBorChainBlockAuthor(*big.Int) (*common.Address, error) IsTxConfirmed(common.Hash, uint64) bool GetConfirmedTxReceipt(common.Hash, uint64) (*ethTypes.Receipt, error) GetBlockNumberFromTxHash(common.Hash) (*big.Int, error) @@ -483,6 +486,41 @@ func (c *ContractCaller) GetMaticChainBlock(blockNum *big.Int) (header *ethTypes return latestBlock, nil } +// GetBorChainBlockAuthor returns the producer of the bor block +func (c *ContractCaller) GetBorChainBlockAuthor(blockNum *big.Int) (*common.Address, error) { + ctx, cancel := context.WithTimeout(context.Background(), c.MaticChainTimeout) + defer cancel() + + var author *common.Address + err := c.MaticChainClient.Client().CallContext(ctx, &author, "bor_getAuthor", toBlockNumArg(blockNum)) + if err != nil { + Logger.Error("Unable to connect to bor chain", "error", err) + return nil, err + } + + if author == nil { + return nil, ethereum.NotFound + } + + return author, nil +} + +// copied from bor/ethclient package +func toBlockNumArg(number *big.Int) string { + if number == nil { + return "latest" + } + if number.Sign() >= 0 { + return hexutil.EncodeBig(number) + } + // It's negative. + if number.IsInt64() { + return rpc.BlockNumber(number.Int64()).String() + } + // It's negative and large, which is invalid. + return fmt.Sprintf("", number) +} + // GetBlockNumberFromTxHash gets block number of transaction func (c *ContractCaller) GetBlockNumberFromTxHash(tx common.Hash) (*big.Int, error) { var rpcTx rpcTransaction diff --git a/helper/config.go b/helper/config.go index 7e1a0e624..93b33c00f 100644 --- a/helper/config.go +++ b/helper/config.go @@ -241,6 +241,8 @@ var aalborgHeight int64 = 0 var newHexToStringAlgoHeight int64 = 0 +var jorvikHeight int64 = 0 + type ChainManagerAddressMigration struct { MaticTokenAddress hmTypes.HeimdallAddress RootChainAddress hmTypes.HeimdallAddress @@ -410,21 +412,25 @@ func InitHeimdallConfigWith(homeDir string, heimdallConfigFileFromFLag string) { spanOverrideHeight = 8664000 newHexToStringAlgoHeight = 9266260 aalborgHeight = 15950759 + jorvikHeight = -1 case MumbaiChain: newSelectionAlgoHeight = 282500 spanOverrideHeight = 10205000 newHexToStringAlgoHeight = 12048023 aalborgHeight = 18035772 + jorvikHeight = -1 case AmoyChain: newSelectionAlgoHeight = 0 spanOverrideHeight = 0 newHexToStringAlgoHeight = 0 aalborgHeight = 0 + jorvikHeight = 5768528 default: newSelectionAlgoHeight = 0 spanOverrideHeight = 0 newHexToStringAlgoHeight = 0 aalborgHeight = 0 + jorvikHeight = 0 } } @@ -577,6 +583,11 @@ func GetNewHexToStringAlgoHeight() int64 { return newHexToStringAlgoHeight } +// GetJorvikHeight returns jorvikHeight +func GetJorvikHeight() int64 { + return jorvikHeight +} + func GetChainManagerAddressMigration(blockNum int64) (ChainManagerAddressMigration, bool) { chainMigration := chainManagerAddressMigrations[conf.Chain] if chainMigration == nil { diff --git a/helper/mocks/IContractCaller.go b/helper/mocks/IContractCaller.go index 9da738e8e..9e4ab87c5 100644 --- a/helper/mocks/IContractCaller.go +++ b/helper/mocks/IContractCaller.go @@ -1,4 +1,4 @@ -// Code generated by mockery v0.0.0-dev. DO NOT EDIT. +// Code generated by mockery v2.45.0. DO NOT EDIT. package mocks @@ -38,6 +38,10 @@ type IContractCaller struct { func (_m *IContractCaller) ApproveTokens(_a0 *big.Int, _a1 common.Address, _a2 common.Address, _a3 *erc20.Erc20) error { ret := _m.Called(_a0, _a1, _a2, _a3) + if len(ret) == 0 { + panic("no return value specified for ApproveTokens") + } + var r0 error if rf, ok := ret.Get(0).(func(*big.Int, common.Address, common.Address, *erc20.Erc20) error); ok { r0 = rf(_a0, _a1, _a2, _a3) @@ -52,6 +56,10 @@ func (_m *IContractCaller) ApproveTokens(_a0 *big.Int, _a1 common.Address, _a2 c func (_m *IContractCaller) CheckIfBlocksExist(end uint64) bool { ret := _m.Called(end) + if len(ret) == 0 { + panic("no return value specified for CheckIfBlocksExist") + } + var r0 bool if rf, ok := ret.Get(0).(func(uint64) bool); ok { r0 = rf(end) @@ -66,7 +74,15 @@ func (_m *IContractCaller) CheckIfBlocksExist(end uint64) bool { func (_m *IContractCaller) CurrentAccountStateRoot(stakingInfoInstance *stakinginfo.Stakinginfo) ([32]byte, error) { ret := _m.Called(stakingInfoInstance) + if len(ret) == 0 { + panic("no return value specified for CurrentAccountStateRoot") + } + var r0 [32]byte + var r1 error + if rf, ok := ret.Get(0).(func(*stakinginfo.Stakinginfo) ([32]byte, error)); ok { + return rf(stakingInfoInstance) + } if rf, ok := ret.Get(0).(func(*stakinginfo.Stakinginfo) [32]byte); ok { r0 = rf(stakingInfoInstance) } else { @@ -75,7 +91,6 @@ func (_m *IContractCaller) CurrentAccountStateRoot(stakingInfoInstance *stakingi } } - var r1 error if rf, ok := ret.Get(1).(func(*stakinginfo.Stakinginfo) error); ok { r1 = rf(stakingInfoInstance) } else { @@ -89,14 +104,21 @@ func (_m *IContractCaller) CurrentAccountStateRoot(stakingInfoInstance *stakingi func (_m *IContractCaller) CurrentHeaderBlock(rootChainInstance *rootchain.Rootchain, childBlockInterval uint64) (uint64, error) { ret := _m.Called(rootChainInstance, childBlockInterval) + if len(ret) == 0 { + panic("no return value specified for CurrentHeaderBlock") + } + var r0 uint64 + var r1 error + if rf, ok := ret.Get(0).(func(*rootchain.Rootchain, uint64) (uint64, error)); ok { + return rf(rootChainInstance, childBlockInterval) + } if rf, ok := ret.Get(0).(func(*rootchain.Rootchain, uint64) uint64); ok { r0 = rf(rootChainInstance, childBlockInterval) } else { r0 = ret.Get(0).(uint64) } - var r1 error if rf, ok := ret.Get(1).(func(*rootchain.Rootchain, uint64) error); ok { r1 = rf(rootChainInstance, childBlockInterval) } else { @@ -106,13 +128,17 @@ func (_m *IContractCaller) CurrentHeaderBlock(rootChainInstance *rootchain.Rootc return r0, r1 } -// CurrentSpanNumber provides a mock function with given fields: _a0 -func (_m *IContractCaller) CurrentSpanNumber(_a0 *validatorset.Validatorset) *big.Int { - ret := _m.Called(_a0) +// CurrentSpanNumber provides a mock function with given fields: validatorSet +func (_m *IContractCaller) CurrentSpanNumber(validatorSet *validatorset.Validatorset) *big.Int { + ret := _m.Called(validatorSet) + + if len(ret) == 0 { + panic("no return value specified for CurrentSpanNumber") + } var r0 *big.Int if rf, ok := ret.Get(0).(func(*validatorset.Validatorset) *big.Int); ok { - r0 = rf(_a0) + r0 = rf(validatorSet) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*big.Int) @@ -126,6 +152,10 @@ func (_m *IContractCaller) CurrentSpanNumber(_a0 *validatorset.Validatorset) *bi func (_m *IContractCaller) CurrentStateCounter(stateSenderInstance *statesender.Statesender) *big.Int { ret := _m.Called(stateSenderInstance) + if len(ret) == 0 { + panic("no return value specified for CurrentStateCounter") + } + var r0 *big.Int if rf, ok := ret.Get(0).(func(*statesender.Statesender) *big.Int); ok { r0 = rf(stateSenderInstance) @@ -142,7 +172,15 @@ func (_m *IContractCaller) CurrentStateCounter(stateSenderInstance *statesender. func (_m *IContractCaller) DecodeNewHeaderBlockEvent(_a0 common.Address, _a1 *types.Receipt, _a2 uint64) (*rootchain.RootchainNewHeaderBlock, error) { ret := _m.Called(_a0, _a1, _a2) + if len(ret) == 0 { + panic("no return value specified for DecodeNewHeaderBlockEvent") + } + var r0 *rootchain.RootchainNewHeaderBlock + var r1 error + if rf, ok := ret.Get(0).(func(common.Address, *types.Receipt, uint64) (*rootchain.RootchainNewHeaderBlock, error)); ok { + return rf(_a0, _a1, _a2) + } if rf, ok := ret.Get(0).(func(common.Address, *types.Receipt, uint64) *rootchain.RootchainNewHeaderBlock); ok { r0 = rf(_a0, _a1, _a2) } else { @@ -151,7 +189,6 @@ func (_m *IContractCaller) DecodeNewHeaderBlockEvent(_a0 common.Address, _a1 *ty } } - var r1 error if rf, ok := ret.Get(1).(func(common.Address, *types.Receipt, uint64) error); ok { r1 = rf(_a0, _a1, _a2) } else { @@ -165,7 +202,15 @@ func (_m *IContractCaller) DecodeNewHeaderBlockEvent(_a0 common.Address, _a1 *ty func (_m *IContractCaller) DecodeSignerUpdateEvent(_a0 common.Address, _a1 *types.Receipt, _a2 uint64) (*stakinginfo.StakinginfoSignerChange, error) { ret := _m.Called(_a0, _a1, _a2) + if len(ret) == 0 { + panic("no return value specified for DecodeSignerUpdateEvent") + } + var r0 *stakinginfo.StakinginfoSignerChange + var r1 error + if rf, ok := ret.Get(0).(func(common.Address, *types.Receipt, uint64) (*stakinginfo.StakinginfoSignerChange, error)); ok { + return rf(_a0, _a1, _a2) + } if rf, ok := ret.Get(0).(func(common.Address, *types.Receipt, uint64) *stakinginfo.StakinginfoSignerChange); ok { r0 = rf(_a0, _a1, _a2) } else { @@ -174,7 +219,6 @@ func (_m *IContractCaller) DecodeSignerUpdateEvent(_a0 common.Address, _a1 *type } } - var r1 error if rf, ok := ret.Get(1).(func(common.Address, *types.Receipt, uint64) error); ok { r1 = rf(_a0, _a1, _a2) } else { @@ -188,7 +232,15 @@ func (_m *IContractCaller) DecodeSignerUpdateEvent(_a0 common.Address, _a1 *type func (_m *IContractCaller) DecodeSlashedEvent(_a0 common.Address, _a1 *types.Receipt, _a2 uint64) (*stakinginfo.StakinginfoSlashed, error) { ret := _m.Called(_a0, _a1, _a2) + if len(ret) == 0 { + panic("no return value specified for DecodeSlashedEvent") + } + var r0 *stakinginfo.StakinginfoSlashed + var r1 error + if rf, ok := ret.Get(0).(func(common.Address, *types.Receipt, uint64) (*stakinginfo.StakinginfoSlashed, error)); ok { + return rf(_a0, _a1, _a2) + } if rf, ok := ret.Get(0).(func(common.Address, *types.Receipt, uint64) *stakinginfo.StakinginfoSlashed); ok { r0 = rf(_a0, _a1, _a2) } else { @@ -197,7 +249,6 @@ func (_m *IContractCaller) DecodeSlashedEvent(_a0 common.Address, _a1 *types.Rec } } - var r1 error if rf, ok := ret.Get(1).(func(common.Address, *types.Receipt, uint64) error); ok { r1 = rf(_a0, _a1, _a2) } else { @@ -211,7 +262,15 @@ func (_m *IContractCaller) DecodeSlashedEvent(_a0 common.Address, _a1 *types.Rec func (_m *IContractCaller) DecodeStateSyncedEvent(_a0 common.Address, _a1 *types.Receipt, _a2 uint64) (*statesender.StatesenderStateSynced, error) { ret := _m.Called(_a0, _a1, _a2) + if len(ret) == 0 { + panic("no return value specified for DecodeStateSyncedEvent") + } + var r0 *statesender.StatesenderStateSynced + var r1 error + if rf, ok := ret.Get(0).(func(common.Address, *types.Receipt, uint64) (*statesender.StatesenderStateSynced, error)); ok { + return rf(_a0, _a1, _a2) + } if rf, ok := ret.Get(0).(func(common.Address, *types.Receipt, uint64) *statesender.StatesenderStateSynced); ok { r0 = rf(_a0, _a1, _a2) } else { @@ -220,7 +279,6 @@ func (_m *IContractCaller) DecodeStateSyncedEvent(_a0 common.Address, _a1 *types } } - var r1 error if rf, ok := ret.Get(1).(func(common.Address, *types.Receipt, uint64) error); ok { r1 = rf(_a0, _a1, _a2) } else { @@ -234,7 +292,15 @@ func (_m *IContractCaller) DecodeStateSyncedEvent(_a0 common.Address, _a1 *types func (_m *IContractCaller) DecodeUnJailedEvent(_a0 common.Address, _a1 *types.Receipt, _a2 uint64) (*stakinginfo.StakinginfoUnJailed, error) { ret := _m.Called(_a0, _a1, _a2) + if len(ret) == 0 { + panic("no return value specified for DecodeUnJailedEvent") + } + var r0 *stakinginfo.StakinginfoUnJailed + var r1 error + if rf, ok := ret.Get(0).(func(common.Address, *types.Receipt, uint64) (*stakinginfo.StakinginfoUnJailed, error)); ok { + return rf(_a0, _a1, _a2) + } if rf, ok := ret.Get(0).(func(common.Address, *types.Receipt, uint64) *stakinginfo.StakinginfoUnJailed); ok { r0 = rf(_a0, _a1, _a2) } else { @@ -243,7 +309,6 @@ func (_m *IContractCaller) DecodeUnJailedEvent(_a0 common.Address, _a1 *types.Re } } - var r1 error if rf, ok := ret.Get(1).(func(common.Address, *types.Receipt, uint64) error); ok { r1 = rf(_a0, _a1, _a2) } else { @@ -257,7 +322,15 @@ func (_m *IContractCaller) DecodeUnJailedEvent(_a0 common.Address, _a1 *types.Re func (_m *IContractCaller) DecodeValidatorExitEvent(_a0 common.Address, _a1 *types.Receipt, _a2 uint64) (*stakinginfo.StakinginfoUnstakeInit, error) { ret := _m.Called(_a0, _a1, _a2) + if len(ret) == 0 { + panic("no return value specified for DecodeValidatorExitEvent") + } + var r0 *stakinginfo.StakinginfoUnstakeInit + var r1 error + if rf, ok := ret.Get(0).(func(common.Address, *types.Receipt, uint64) (*stakinginfo.StakinginfoUnstakeInit, error)); ok { + return rf(_a0, _a1, _a2) + } if rf, ok := ret.Get(0).(func(common.Address, *types.Receipt, uint64) *stakinginfo.StakinginfoUnstakeInit); ok { r0 = rf(_a0, _a1, _a2) } else { @@ -266,7 +339,6 @@ func (_m *IContractCaller) DecodeValidatorExitEvent(_a0 common.Address, _a1 *typ } } - var r1 error if rf, ok := ret.Get(1).(func(common.Address, *types.Receipt, uint64) error); ok { r1 = rf(_a0, _a1, _a2) } else { @@ -280,7 +352,15 @@ func (_m *IContractCaller) DecodeValidatorExitEvent(_a0 common.Address, _a1 *typ func (_m *IContractCaller) DecodeValidatorJoinEvent(_a0 common.Address, _a1 *types.Receipt, _a2 uint64) (*stakinginfo.StakinginfoStaked, error) { ret := _m.Called(_a0, _a1, _a2) + if len(ret) == 0 { + panic("no return value specified for DecodeValidatorJoinEvent") + } + var r0 *stakinginfo.StakinginfoStaked + var r1 error + if rf, ok := ret.Get(0).(func(common.Address, *types.Receipt, uint64) (*stakinginfo.StakinginfoStaked, error)); ok { + return rf(_a0, _a1, _a2) + } if rf, ok := ret.Get(0).(func(common.Address, *types.Receipt, uint64) *stakinginfo.StakinginfoStaked); ok { r0 = rf(_a0, _a1, _a2) } else { @@ -289,7 +369,6 @@ func (_m *IContractCaller) DecodeValidatorJoinEvent(_a0 common.Address, _a1 *typ } } - var r1 error if rf, ok := ret.Get(1).(func(common.Address, *types.Receipt, uint64) error); ok { r1 = rf(_a0, _a1, _a2) } else { @@ -303,7 +382,15 @@ func (_m *IContractCaller) DecodeValidatorJoinEvent(_a0 common.Address, _a1 *typ func (_m *IContractCaller) DecodeValidatorStakeUpdateEvent(_a0 common.Address, _a1 *types.Receipt, _a2 uint64) (*stakinginfo.StakinginfoStakeUpdate, error) { ret := _m.Called(_a0, _a1, _a2) + if len(ret) == 0 { + panic("no return value specified for DecodeValidatorStakeUpdateEvent") + } + var r0 *stakinginfo.StakinginfoStakeUpdate + var r1 error + if rf, ok := ret.Get(0).(func(common.Address, *types.Receipt, uint64) (*stakinginfo.StakinginfoStakeUpdate, error)); ok { + return rf(_a0, _a1, _a2) + } if rf, ok := ret.Get(0).(func(common.Address, *types.Receipt, uint64) *stakinginfo.StakinginfoStakeUpdate); ok { r0 = rf(_a0, _a1, _a2) } else { @@ -312,7 +399,6 @@ func (_m *IContractCaller) DecodeValidatorStakeUpdateEvent(_a0 common.Address, _ } } - var r1 error if rf, ok := ret.Get(1).(func(common.Address, *types.Receipt, uint64) error); ok { r1 = rf(_a0, _a1, _a2) } else { @@ -326,7 +412,15 @@ func (_m *IContractCaller) DecodeValidatorStakeUpdateEvent(_a0 common.Address, _ func (_m *IContractCaller) DecodeValidatorTopupFeesEvent(_a0 common.Address, _a1 *types.Receipt, _a2 uint64) (*stakinginfo.StakinginfoTopUpFee, error) { ret := _m.Called(_a0, _a1, _a2) + if len(ret) == 0 { + panic("no return value specified for DecodeValidatorTopupFeesEvent") + } + var r0 *stakinginfo.StakinginfoTopUpFee + var r1 error + if rf, ok := ret.Get(0).(func(common.Address, *types.Receipt, uint64) (*stakinginfo.StakinginfoTopUpFee, error)); ok { + return rf(_a0, _a1, _a2) + } if rf, ok := ret.Get(0).(func(common.Address, *types.Receipt, uint64) *stakinginfo.StakinginfoTopUpFee); ok { r0 = rf(_a0, _a1, _a2) } else { @@ -335,7 +429,6 @@ func (_m *IContractCaller) DecodeValidatorTopupFeesEvent(_a0 common.Address, _a1 } } - var r1 error if rf, ok := ret.Get(1).(func(common.Address, *types.Receipt, uint64) error); ok { r1 = rf(_a0, _a1, _a2) } else { @@ -349,7 +442,15 @@ func (_m *IContractCaller) DecodeValidatorTopupFeesEvent(_a0 common.Address, _a1 func (_m *IContractCaller) GetBalance(address common.Address) (*big.Int, error) { ret := _m.Called(address) + if len(ret) == 0 { + panic("no return value specified for GetBalance") + } + var r0 *big.Int + var r1 error + if rf, ok := ret.Get(0).(func(common.Address) (*big.Int, error)); ok { + return rf(address) + } if rf, ok := ret.Get(0).(func(common.Address) *big.Int); ok { r0 = rf(address) } else { @@ -358,7 +459,6 @@ func (_m *IContractCaller) GetBalance(address common.Address) (*big.Int, error) } } - var r1 error if rf, ok := ret.Get(1).(func(common.Address) error); ok { r1 = rf(address) } else { @@ -372,7 +472,15 @@ func (_m *IContractCaller) GetBalance(address common.Address) (*big.Int, error) func (_m *IContractCaller) GetBlockNumberFromTxHash(_a0 common.Hash) (*big.Int, error) { ret := _m.Called(_a0) + if len(ret) == 0 { + panic("no return value specified for GetBlockNumberFromTxHash") + } + var r0 *big.Int + var r1 error + if rf, ok := ret.Get(0).(func(common.Hash) (*big.Int, error)); ok { + return rf(_a0) + } if rf, ok := ret.Get(0).(func(common.Hash) *big.Int); ok { r0 = rf(_a0) } else { @@ -381,7 +489,6 @@ func (_m *IContractCaller) GetBlockNumberFromTxHash(_a0 common.Hash) (*big.Int, } } - var r1 error if rf, ok := ret.Get(1).(func(common.Hash) error); ok { r1 = rf(_a0) } else { @@ -391,11 +498,51 @@ func (_m *IContractCaller) GetBlockNumberFromTxHash(_a0 common.Hash) (*big.Int, return r0, r1 } +// GetBorChainBlockAuthor provides a mock function with given fields: _a0 +func (_m *IContractCaller) GetBorChainBlockAuthor(_a0 *big.Int) (*common.Address, error) { + ret := _m.Called(_a0) + + if len(ret) == 0 { + panic("no return value specified for GetBorChainBlockAuthor") + } + + var r0 *common.Address + var r1 error + if rf, ok := ret.Get(0).(func(*big.Int) (*common.Address, error)); ok { + return rf(_a0) + } + if rf, ok := ret.Get(0).(func(*big.Int) *common.Address); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*common.Address) + } + } + + if rf, ok := ret.Get(1).(func(*big.Int) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + // GetCheckpointSign provides a mock function with given fields: txHash func (_m *IContractCaller) GetCheckpointSign(txHash common.Hash) ([]byte, []byte, []byte, error) { ret := _m.Called(txHash) + if len(ret) == 0 { + panic("no return value specified for GetCheckpointSign") + } + var r0 []byte + var r1 []byte + var r2 []byte + var r3 error + if rf, ok := ret.Get(0).(func(common.Hash) ([]byte, []byte, []byte, error)); ok { + return rf(txHash) + } if rf, ok := ret.Get(0).(func(common.Hash) []byte); ok { r0 = rf(txHash) } else { @@ -404,7 +551,6 @@ func (_m *IContractCaller) GetCheckpointSign(txHash common.Hash) ([]byte, []byte } } - var r1 []byte if rf, ok := ret.Get(1).(func(common.Hash) []byte); ok { r1 = rf(txHash) } else { @@ -413,7 +559,6 @@ func (_m *IContractCaller) GetCheckpointSign(txHash common.Hash) ([]byte, []byte } } - var r2 []byte if rf, ok := ret.Get(2).(func(common.Hash) []byte); ok { r2 = rf(txHash) } else { @@ -422,7 +567,6 @@ func (_m *IContractCaller) GetCheckpointSign(txHash common.Hash) ([]byte, []byte } } - var r3 error if rf, ok := ret.Get(3).(func(common.Hash) error); ok { r3 = rf(txHash) } else { @@ -436,7 +580,15 @@ func (_m *IContractCaller) GetCheckpointSign(txHash common.Hash) ([]byte, []byte func (_m *IContractCaller) GetConfirmedTxReceipt(_a0 common.Hash, _a1 uint64) (*types.Receipt, error) { ret := _m.Called(_a0, _a1) + if len(ret) == 0 { + panic("no return value specified for GetConfirmedTxReceipt") + } + var r0 *types.Receipt + var r1 error + if rf, ok := ret.Get(0).(func(common.Hash, uint64) (*types.Receipt, error)); ok { + return rf(_a0, _a1) + } if rf, ok := ret.Get(0).(func(common.Hash, uint64) *types.Receipt); ok { r0 = rf(_a0, _a1) } else { @@ -445,7 +597,6 @@ func (_m *IContractCaller) GetConfirmedTxReceipt(_a0 common.Hash, _a1 uint64) (* } } - var r1 error if rf, ok := ret.Get(1).(func(common.Hash, uint64) error); ok { r1 = rf(_a0, _a1) } else { @@ -459,7 +610,19 @@ func (_m *IContractCaller) GetConfirmedTxReceipt(_a0 common.Hash, _a1 uint64) (* func (_m *IContractCaller) GetHeaderInfo(headerID uint64, rootChainInstance *rootchain.Rootchain, childBlockInterval uint64) (common.Hash, uint64, uint64, uint64, heimdalltypes.HeimdallAddress, error) { ret := _m.Called(headerID, rootChainInstance, childBlockInterval) + if len(ret) == 0 { + panic("no return value specified for GetHeaderInfo") + } + var r0 common.Hash + var r1 uint64 + var r2 uint64 + var r3 uint64 + var r4 heimdalltypes.HeimdallAddress + var r5 error + if rf, ok := ret.Get(0).(func(uint64, *rootchain.Rootchain, uint64) (common.Hash, uint64, uint64, uint64, heimdalltypes.HeimdallAddress, error)); ok { + return rf(headerID, rootChainInstance, childBlockInterval) + } if rf, ok := ret.Get(0).(func(uint64, *rootchain.Rootchain, uint64) common.Hash); ok { r0 = rf(headerID, rootChainInstance, childBlockInterval) } else { @@ -468,28 +631,24 @@ func (_m *IContractCaller) GetHeaderInfo(headerID uint64, rootChainInstance *roo } } - var r1 uint64 if rf, ok := ret.Get(1).(func(uint64, *rootchain.Rootchain, uint64) uint64); ok { r1 = rf(headerID, rootChainInstance, childBlockInterval) } else { r1 = ret.Get(1).(uint64) } - var r2 uint64 if rf, ok := ret.Get(2).(func(uint64, *rootchain.Rootchain, uint64) uint64); ok { r2 = rf(headerID, rootChainInstance, childBlockInterval) } else { r2 = ret.Get(2).(uint64) } - var r3 uint64 if rf, ok := ret.Get(3).(func(uint64, *rootchain.Rootchain, uint64) uint64); ok { r3 = rf(headerID, rootChainInstance, childBlockInterval) } else { r3 = ret.Get(3).(uint64) } - var r4 heimdalltypes.HeimdallAddress if rf, ok := ret.Get(4).(func(uint64, *rootchain.Rootchain, uint64) heimdalltypes.HeimdallAddress); ok { r4 = rf(headerID, rootChainInstance, childBlockInterval) } else { @@ -498,7 +657,6 @@ func (_m *IContractCaller) GetHeaderInfo(headerID uint64, rootChainInstance *roo } } - var r5 error if rf, ok := ret.Get(5).(func(uint64, *rootchain.Rootchain, uint64) error); ok { r5 = rf(headerID, rootChainInstance, childBlockInterval) } else { @@ -512,14 +670,21 @@ func (_m *IContractCaller) GetHeaderInfo(headerID uint64, rootChainInstance *roo func (_m *IContractCaller) GetLastChildBlock(rootChainInstance *rootchain.Rootchain) (uint64, error) { ret := _m.Called(rootChainInstance) + if len(ret) == 0 { + panic("no return value specified for GetLastChildBlock") + } + var r0 uint64 + var r1 error + if rf, ok := ret.Get(0).(func(*rootchain.Rootchain) (uint64, error)); ok { + return rf(rootChainInstance) + } if rf, ok := ret.Get(0).(func(*rootchain.Rootchain) uint64); ok { r0 = rf(rootChainInstance) } else { r0 = ret.Get(0).(uint64) } - var r1 error if rf, ok := ret.Get(1).(func(*rootchain.Rootchain) error); ok { r1 = rf(rootChainInstance) } else { @@ -533,7 +698,15 @@ func (_m *IContractCaller) GetLastChildBlock(rootChainInstance *rootchain.Rootch func (_m *IContractCaller) GetMainChainBlock(_a0 *big.Int) (*types.Header, error) { ret := _m.Called(_a0) + if len(ret) == 0 { + panic("no return value specified for GetMainChainBlock") + } + var r0 *types.Header + var r1 error + if rf, ok := ret.Get(0).(func(*big.Int) (*types.Header, error)); ok { + return rf(_a0) + } if rf, ok := ret.Get(0).(func(*big.Int) *types.Header); ok { r0 = rf(_a0) } else { @@ -542,7 +715,6 @@ func (_m *IContractCaller) GetMainChainBlock(_a0 *big.Int) (*types.Header, error } } - var r1 error if rf, ok := ret.Get(1).(func(*big.Int) error); ok { r1 = rf(_a0) } else { @@ -556,7 +728,15 @@ func (_m *IContractCaller) GetMainChainBlock(_a0 *big.Int) (*types.Header, error func (_m *IContractCaller) GetMainTxReceipt(_a0 common.Hash) (*types.Receipt, error) { ret := _m.Called(_a0) + if len(ret) == 0 { + panic("no return value specified for GetMainTxReceipt") + } + var r0 *types.Receipt + var r1 error + if rf, ok := ret.Get(0).(func(common.Hash) (*types.Receipt, error)); ok { + return rf(_a0) + } if rf, ok := ret.Get(0).(func(common.Hash) *types.Receipt); ok { r0 = rf(_a0) } else { @@ -565,7 +745,6 @@ func (_m *IContractCaller) GetMainTxReceipt(_a0 common.Hash) (*types.Receipt, er } } - var r1 error if rf, ok := ret.Get(1).(func(common.Hash) error); ok { r1 = rf(_a0) } else { @@ -579,7 +758,15 @@ func (_m *IContractCaller) GetMainTxReceipt(_a0 common.Hash) (*types.Receipt, er func (_m *IContractCaller) GetMaticChainBlock(_a0 *big.Int) (*types.Header, error) { ret := _m.Called(_a0) + if len(ret) == 0 { + panic("no return value specified for GetMaticChainBlock") + } + var r0 *types.Header + var r1 error + if rf, ok := ret.Get(0).(func(*big.Int) (*types.Header, error)); ok { + return rf(_a0) + } if rf, ok := ret.Get(0).(func(*big.Int) *types.Header); ok { r0 = rf(_a0) } else { @@ -588,7 +775,6 @@ func (_m *IContractCaller) GetMaticChainBlock(_a0 *big.Int) (*types.Header, erro } } - var r1 error if rf, ok := ret.Get(1).(func(*big.Int) error); ok { r1 = rf(_a0) } else { @@ -602,7 +788,15 @@ func (_m *IContractCaller) GetMaticChainBlock(_a0 *big.Int) (*types.Header, erro func (_m *IContractCaller) GetMaticTokenInstance(maticTokenAddress common.Address) (*erc20.Erc20, error) { ret := _m.Called(maticTokenAddress) + if len(ret) == 0 { + panic("no return value specified for GetMaticTokenInstance") + } + var r0 *erc20.Erc20 + var r1 error + if rf, ok := ret.Get(0).(func(common.Address) (*erc20.Erc20, error)); ok { + return rf(maticTokenAddress) + } if rf, ok := ret.Get(0).(func(common.Address) *erc20.Erc20); ok { r0 = rf(maticTokenAddress) } else { @@ -611,7 +805,6 @@ func (_m *IContractCaller) GetMaticTokenInstance(maticTokenAddress common.Addres } } - var r1 error if rf, ok := ret.Get(1).(func(common.Address) error); ok { r1 = rf(maticTokenAddress) } else { @@ -625,7 +818,15 @@ func (_m *IContractCaller) GetMaticTokenInstance(maticTokenAddress common.Addres func (_m *IContractCaller) GetMaticTxReceipt(_a0 common.Hash) (*types.Receipt, error) { ret := _m.Called(_a0) + if len(ret) == 0 { + panic("no return value specified for GetMaticTxReceipt") + } + var r0 *types.Receipt + var r1 error + if rf, ok := ret.Get(0).(func(common.Hash) (*types.Receipt, error)); ok { + return rf(_a0) + } if rf, ok := ret.Get(0).(func(common.Hash) *types.Receipt); ok { r0 = rf(_a0) } else { @@ -634,7 +835,6 @@ func (_m *IContractCaller) GetMaticTxReceipt(_a0 common.Hash) (*types.Receipt, e } } - var r1 error if rf, ok := ret.Get(1).(func(common.Hash) error); ok { r1 = rf(_a0) } else { @@ -644,22 +844,29 @@ func (_m *IContractCaller) GetMaticTxReceipt(_a0 common.Hash) (*types.Receipt, e return r0, r1 } -// GetRootChainInstance provides a mock function with given fields: rootchainAddress -func (_m *IContractCaller) GetRootChainInstance(rootchainAddress common.Address) (*rootchain.Rootchain, error) { - ret := _m.Called(rootchainAddress) +// GetRootChainInstance provides a mock function with given fields: rootChainAddress +func (_m *IContractCaller) GetRootChainInstance(rootChainAddress common.Address) (*rootchain.Rootchain, error) { + ret := _m.Called(rootChainAddress) + + if len(ret) == 0 { + panic("no return value specified for GetRootChainInstance") + } var r0 *rootchain.Rootchain + var r1 error + if rf, ok := ret.Get(0).(func(common.Address) (*rootchain.Rootchain, error)); ok { + return rf(rootChainAddress) + } if rf, ok := ret.Get(0).(func(common.Address) *rootchain.Rootchain); ok { - r0 = rf(rootchainAddress) + r0 = rf(rootChainAddress) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*rootchain.Rootchain) } } - var r1 error if rf, ok := ret.Get(1).(func(common.Address) error); ok { - r1 = rf(rootchainAddress) + r1 = rf(rootChainAddress) } else { r1 = ret.Error(1) } @@ -671,7 +878,15 @@ func (_m *IContractCaller) GetRootChainInstance(rootchainAddress common.Address) func (_m *IContractCaller) GetRootHash(start uint64, end uint64, checkpointLength uint64) ([]byte, error) { ret := _m.Called(start, end, checkpointLength) + if len(ret) == 0 { + panic("no return value specified for GetRootHash") + } + var r0 []byte + var r1 error + if rf, ok := ret.Get(0).(func(uint64, uint64, uint64) ([]byte, error)); ok { + return rf(start, end, checkpointLength) + } if rf, ok := ret.Get(0).(func(uint64, uint64, uint64) []byte); ok { r0 = rf(start, end, checkpointLength) } else { @@ -680,7 +895,6 @@ func (_m *IContractCaller) GetRootHash(start uint64, end uint64, checkpointLengt } } - var r1 error if rf, ok := ret.Get(1).(func(uint64, uint64, uint64) error); ok { r1 = rf(start, end, checkpointLength) } else { @@ -690,34 +904,19 @@ func (_m *IContractCaller) GetRootHash(start uint64, end uint64, checkpointLengt return r0, r1 } -// GetVoteOnsHash provides a mock function with given fields: start, end, milestoneLength,Hash, milestoneID -func (_m *IContractCaller) GetVoteOnHash(start uint64, end uint64, milestoneLength uint64, rootHash string, milestoneID string) (bool, error) { - ret := _m.Called(start, end, milestoneLength,rootHash,milestoneID) - - var r0 bool - if rf, ok := ret.Get(0).(func(uint64, uint64, uint64,string,string) bool); ok { - r0 = rf(start, end, milestoneLength,rootHash,milestoneID) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(bool) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(uint64, uint64, uint64,string,string) error); ok { - r1 = rf(start, end, milestoneLength,rootHash,milestoneID) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - // GetSlashManagerInstance provides a mock function with given fields: slashManagerAddress func (_m *IContractCaller) GetSlashManagerInstance(slashManagerAddress common.Address) (*slashmanager.Slashmanager, error) { ret := _m.Called(slashManagerAddress) + if len(ret) == 0 { + panic("no return value specified for GetSlashManagerInstance") + } + var r0 *slashmanager.Slashmanager + var r1 error + if rf, ok := ret.Get(0).(func(common.Address) (*slashmanager.Slashmanager, error)); ok { + return rf(slashManagerAddress) + } if rf, ok := ret.Get(0).(func(common.Address) *slashmanager.Slashmanager); ok { r0 = rf(slashManagerAddress) } else { @@ -726,7 +925,6 @@ func (_m *IContractCaller) GetSlashManagerInstance(slashManagerAddress common.Ad } } - var r1 error if rf, ok := ret.Get(1).(func(common.Address) error); ok { r1 = rf(slashManagerAddress) } else { @@ -736,40 +934,47 @@ func (_m *IContractCaller) GetSlashManagerInstance(slashManagerAddress common.Ad return r0, r1 } -// GetSpanDetails provides a mock function with given fields: id, _a1 -func (_m *IContractCaller) GetSpanDetails(id *big.Int, _a1 *validatorset.Validatorset) (*big.Int, *big.Int, *big.Int, error) { - ret := _m.Called(id, _a1) +// GetSpanDetails provides a mock function with given fields: id, validatorSet +func (_m *IContractCaller) GetSpanDetails(id *big.Int, validatorSet *validatorset.Validatorset) (*big.Int, *big.Int, *big.Int, error) { + ret := _m.Called(id, validatorSet) + + if len(ret) == 0 { + panic("no return value specified for GetSpanDetails") + } var r0 *big.Int + var r1 *big.Int + var r2 *big.Int + var r3 error + if rf, ok := ret.Get(0).(func(*big.Int, *validatorset.Validatorset) (*big.Int, *big.Int, *big.Int, error)); ok { + return rf(id, validatorSet) + } if rf, ok := ret.Get(0).(func(*big.Int, *validatorset.Validatorset) *big.Int); ok { - r0 = rf(id, _a1) + r0 = rf(id, validatorSet) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*big.Int) } } - var r1 *big.Int if rf, ok := ret.Get(1).(func(*big.Int, *validatorset.Validatorset) *big.Int); ok { - r1 = rf(id, _a1) + r1 = rf(id, validatorSet) } else { if ret.Get(1) != nil { r1 = ret.Get(1).(*big.Int) } } - var r2 *big.Int if rf, ok := ret.Get(2).(func(*big.Int, *validatorset.Validatorset) *big.Int); ok { - r2 = rf(id, _a1) + r2 = rf(id, validatorSet) } else { if ret.Get(2) != nil { r2 = ret.Get(2).(*big.Int) } } - var r3 error if rf, ok := ret.Get(3).(func(*big.Int, *validatorset.Validatorset) error); ok { - r3 = rf(id, _a1) + r3 = rf(id, validatorSet) } else { r3 = ret.Error(3) } @@ -781,7 +986,15 @@ func (_m *IContractCaller) GetSpanDetails(id *big.Int, _a1 *validatorset.Validat func (_m *IContractCaller) GetStakeManagerInstance(stakingManagerAddress common.Address) (*stakemanager.Stakemanager, error) { ret := _m.Called(stakingManagerAddress) + if len(ret) == 0 { + panic("no return value specified for GetStakeManagerInstance") + } + var r0 *stakemanager.Stakemanager + var r1 error + if rf, ok := ret.Get(0).(func(common.Address) (*stakemanager.Stakemanager, error)); ok { + return rf(stakingManagerAddress) + } if rf, ok := ret.Get(0).(func(common.Address) *stakemanager.Stakemanager); ok { r0 = rf(stakingManagerAddress) } else { @@ -790,7 +1003,6 @@ func (_m *IContractCaller) GetStakeManagerInstance(stakingManagerAddress common. } } - var r1 error if rf, ok := ret.Get(1).(func(common.Address) error); ok { r1 = rf(stakingManagerAddress) } else { @@ -804,7 +1016,15 @@ func (_m *IContractCaller) GetStakeManagerInstance(stakingManagerAddress common. func (_m *IContractCaller) GetStakingInfoInstance(stakingInfoAddress common.Address) (*stakinginfo.Stakinginfo, error) { ret := _m.Called(stakingInfoAddress) + if len(ret) == 0 { + panic("no return value specified for GetStakingInfoInstance") + } + var r0 *stakinginfo.Stakinginfo + var r1 error + if rf, ok := ret.Get(0).(func(common.Address) (*stakinginfo.Stakinginfo, error)); ok { + return rf(stakingInfoAddress) + } if rf, ok := ret.Get(0).(func(common.Address) *stakinginfo.Stakinginfo); ok { r0 = rf(stakingInfoAddress) } else { @@ -813,7 +1033,6 @@ func (_m *IContractCaller) GetStakingInfoInstance(stakingInfoAddress common.Addr } } - var r1 error if rf, ok := ret.Get(1).(func(common.Address) error); ok { r1 = rf(stakingInfoAddress) } else { @@ -827,7 +1046,15 @@ func (_m *IContractCaller) GetStakingInfoInstance(stakingInfoAddress common.Addr func (_m *IContractCaller) GetStateReceiverInstance(stateReceiverAddress common.Address) (*statereceiver.Statereceiver, error) { ret := _m.Called(stateReceiverAddress) + if len(ret) == 0 { + panic("no return value specified for GetStateReceiverInstance") + } + var r0 *statereceiver.Statereceiver + var r1 error + if rf, ok := ret.Get(0).(func(common.Address) (*statereceiver.Statereceiver, error)); ok { + return rf(stateReceiverAddress) + } if rf, ok := ret.Get(0).(func(common.Address) *statereceiver.Statereceiver); ok { r0 = rf(stateReceiverAddress) } else { @@ -836,7 +1063,6 @@ func (_m *IContractCaller) GetStateReceiverInstance(stateReceiverAddress common. } } - var r1 error if rf, ok := ret.Get(1).(func(common.Address) error); ok { r1 = rf(stateReceiverAddress) } else { @@ -850,7 +1076,15 @@ func (_m *IContractCaller) GetStateReceiverInstance(stateReceiverAddress common. func (_m *IContractCaller) GetStateSenderInstance(stateSenderAddress common.Address) (*statesender.Statesender, error) { ret := _m.Called(stateSenderAddress) + if len(ret) == 0 { + panic("no return value specified for GetStateSenderInstance") + } + var r0 *statesender.Statesender + var r1 error + if rf, ok := ret.Get(0).(func(common.Address) (*statesender.Statesender, error)); ok { + return rf(stateSenderAddress) + } if rf, ok := ret.Get(0).(func(common.Address) *statesender.Statesender); ok { r0 = rf(stateSenderAddress) } else { @@ -859,7 +1093,6 @@ func (_m *IContractCaller) GetStateSenderInstance(stateSenderAddress common.Addr } } - var r1 error if rf, ok := ret.Get(1).(func(common.Address) error); ok { r1 = rf(stateSenderAddress) } else { @@ -873,14 +1106,21 @@ func (_m *IContractCaller) GetStateSenderInstance(stateSenderAddress common.Addr func (_m *IContractCaller) GetValidatorInfo(valID heimdalltypes.ValidatorID, stakingInfoInstance *stakinginfo.Stakinginfo) (heimdalltypes.Validator, error) { ret := _m.Called(valID, stakingInfoInstance) + if len(ret) == 0 { + panic("no return value specified for GetValidatorInfo") + } + var r0 heimdalltypes.Validator + var r1 error + if rf, ok := ret.Get(0).(func(heimdalltypes.ValidatorID, *stakinginfo.Stakinginfo) (heimdalltypes.Validator, error)); ok { + return rf(valID, stakingInfoInstance) + } if rf, ok := ret.Get(0).(func(heimdalltypes.ValidatorID, *stakinginfo.Stakinginfo) heimdalltypes.Validator); ok { r0 = rf(valID, stakingInfoInstance) } else { r0 = ret.Get(0).(heimdalltypes.Validator) } - var r1 error if rf, ok := ret.Get(1).(func(heimdalltypes.ValidatorID, *stakinginfo.Stakinginfo) error); ok { r1 = rf(valID, stakingInfoInstance) } else { @@ -894,7 +1134,15 @@ func (_m *IContractCaller) GetValidatorInfo(valID heimdalltypes.ValidatorID, sta func (_m *IContractCaller) GetValidatorSetInstance(validatorSetAddress common.Address) (*validatorset.Validatorset, error) { ret := _m.Called(validatorSetAddress) + if len(ret) == 0 { + panic("no return value specified for GetValidatorSetInstance") + } + var r0 *validatorset.Validatorset + var r1 error + if rf, ok := ret.Get(0).(func(common.Address) (*validatorset.Validatorset, error)); ok { + return rf(validatorSetAddress) + } if rf, ok := ret.Get(0).(func(common.Address) *validatorset.Validatorset); ok { r0 = rf(validatorSetAddress) } else { @@ -903,7 +1151,6 @@ func (_m *IContractCaller) GetValidatorSetInstance(validatorSetAddress common.Ad } } - var r1 error if rf, ok := ret.Get(1).(func(common.Address) error); ok { r1 = rf(validatorSetAddress) } else { @@ -913,10 +1160,42 @@ func (_m *IContractCaller) GetValidatorSetInstance(validatorSetAddress common.Ad return r0, r1 } +// GetVoteOnHash provides a mock function with given fields: start, end, milestoneLength, hash, milestoneID +func (_m *IContractCaller) GetVoteOnHash(start uint64, end uint64, milestoneLength uint64, hash string, milestoneID string) (bool, error) { + ret := _m.Called(start, end, milestoneLength, hash, milestoneID) + + if len(ret) == 0 { + panic("no return value specified for GetVoteOnHash") + } + + var r0 bool + var r1 error + if rf, ok := ret.Get(0).(func(uint64, uint64, uint64, string, string) (bool, error)); ok { + return rf(start, end, milestoneLength, hash, milestoneID) + } + if rf, ok := ret.Get(0).(func(uint64, uint64, uint64, string, string) bool); ok { + r0 = rf(start, end, milestoneLength, hash, milestoneID) + } else { + r0 = ret.Get(0).(bool) + } + + if rf, ok := ret.Get(1).(func(uint64, uint64, uint64, string, string) error); ok { + r1 = rf(start, end, milestoneLength, hash, milestoneID) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + // IsTxConfirmed provides a mock function with given fields: _a0, _a1 func (_m *IContractCaller) IsTxConfirmed(_a0 common.Hash, _a1 uint64) bool { ret := _m.Called(_a0, _a1) + if len(ret) == 0 { + panic("no return value specified for IsTxConfirmed") + } + var r0 bool if rf, ok := ret.Get(0).(func(common.Hash, uint64) bool); ok { r0 = rf(_a0, _a1) @@ -927,13 +1206,17 @@ func (_m *IContractCaller) IsTxConfirmed(_a0 common.Hash, _a1 uint64) bool { return r0 } -// SendCheckpoint provides a mock function with given fields: sigedData, sigs, rootchainAddress, rootChainInstance -func (_m *IContractCaller) SendCheckpoint(sigedData []byte, sigs [][3]*big.Int, rootchainAddress common.Address, rootChainInstance *rootchain.Rootchain) error { - ret := _m.Called(sigedData, sigs, rootchainAddress, rootChainInstance) +// SendCheckpoint provides a mock function with given fields: signedData, sigs, rootChainAddress, rootChainInstance +func (_m *IContractCaller) SendCheckpoint(signedData []byte, sigs [][3]*big.Int, rootChainAddress common.Address, rootChainInstance *rootchain.Rootchain) error { + ret := _m.Called(signedData, sigs, rootChainAddress, rootChainInstance) + + if len(ret) == 0 { + panic("no return value specified for SendCheckpoint") + } var r0 error if rf, ok := ret.Get(0).(func([]byte, [][3]*big.Int, common.Address, *rootchain.Rootchain) error); ok { - r0 = rf(sigedData, sigs, rootchainAddress, rootChainInstance) + r0 = rf(signedData, sigs, rootChainAddress, rootChainInstance) } else { r0 = ret.Error(0) } @@ -941,13 +1224,17 @@ func (_m *IContractCaller) SendCheckpoint(sigedData []byte, sigs [][3]*big.Int, return r0 } -// SendTick provides a mock function with given fields: sigedData, sigs, slashManagerAddress, slashManagerInstance -func (_m *IContractCaller) SendTick(sigedData []byte, sigs []byte, slashManagerAddress common.Address, slashManagerInstance *slashmanager.Slashmanager) error { - ret := _m.Called(sigedData, sigs, slashManagerAddress, slashManagerInstance) +// SendTick provides a mock function with given fields: signedData, sigs, slashManagerAddress, slashManagerInstance +func (_m *IContractCaller) SendTick(signedData []byte, sigs []byte, slashManagerAddress common.Address, slashManagerInstance *slashmanager.Slashmanager) error { + ret := _m.Called(signedData, sigs, slashManagerAddress, slashManagerInstance) + + if len(ret) == 0 { + panic("no return value specified for SendTick") + } var r0 error if rf, ok := ret.Get(0).(func([]byte, []byte, common.Address, *slashmanager.Slashmanager) error); ok { - r0 = rf(sigedData, sigs, slashManagerAddress, slashManagerInstance) + r0 = rf(signedData, sigs, slashManagerAddress, slashManagerInstance) } else { r0 = ret.Error(0) } @@ -959,6 +1246,10 @@ func (_m *IContractCaller) SendTick(sigedData []byte, sigs []byte, slashManagerA func (_m *IContractCaller) StakeFor(_a0 common.Address, _a1 *big.Int, _a2 *big.Int, _a3 bool, _a4 common.Address, _a5 *stakemanager.Stakemanager) error { ret := _m.Called(_a0, _a1, _a2, _a3, _a4, _a5) + if len(ret) == 0 { + panic("no return value specified for StakeFor") + } + var r0 error if rf, ok := ret.Get(0).(func(common.Address, *big.Int, *big.Int, bool, common.Address, *stakemanager.Stakemanager) error); ok { r0 = rf(_a0, _a1, _a2, _a3, _a4, _a5) @@ -968,3 +1259,17 @@ func (_m *IContractCaller) StakeFor(_a0 common.Address, _a1 *big.Int, _a2 *big.I return r0 } + +// NewIContractCaller creates a new instance of IContractCaller. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewIContractCaller(t interface { + mock.TestingT + Cleanup(func()) +}) *IContractCaller { + mock := &IContractCaller{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +}