From 3d6114336c535ab22e7c9f7eb0088e72f5430d81 Mon Sep 17 00:00:00 2001 From: avalkov Date: Wed, 11 Dec 2024 12:48:47 +0200 Subject: [PATCH 1/8] V1.1.0 new span msg (#1213) * New propose span msg * helper: temporarily set antevortaHeight for testing * bor: fix nil author clause * bor: fix TestProposeSpanOne and TestGetNextSpanSeed * bor: avoid nil ptr deref * Add support for new msg propose span in cli and rest * Enable all hardforks at zero height * helper: temporarily add non-zero hf heights for testing * bor: fix handler * When proposing span query height from the node * Enable all forks on zero height * Add temporary commands to test malicious cases * Add temporary commands to test malicious cases * Let the bridge propose only the first two spans * Dont enable antevorta from zero height * Restrict new msg pre-hardfork * set non-zero height for antevorta * Add debug logging * Lower enable fork height * Clean up * Cleanup * Fix lint * Fix comments * fix: nil logger --------- Co-authored-by: Raneet Debnath Co-authored-by: marcello33 --- bor/client/cli/query.go | 56 ++++++++++---- bor/client/cli/tx.go | 40 +++++++--- bor/client/rest/tx.go | 45 +++++++---- bor/handler.go | 63 +++++++++++---- bor/keeper.go | 22 ++++-- bor/keeper_test.go | 11 ++- bor/querier.go | 6 +- bor/side_handler.go | 128 ++++++++++++++++++++++++------- bor/types/codec.go | 1 + bor/types/msg.go | 82 ++++++++++++++++++++ bor/types/querier.go | 13 ++++ bridge/setu/processor/span.go | 66 +++++++++++----- cmd/heimdalld/service/service.go | 1 - helper/config.go | 11 +++ 14 files changed, 427 insertions(+), 118 deletions(-) diff --git a/bor/client/cli/query.go b/bor/client/cli/query.go index c9433df91..62f9565e5 100644 --- a/bor/client/cli/query.go +++ b/bor/client/cli/query.go @@ -13,8 +13,6 @@ import ( "github.com/spf13/cobra" "github.com/spf13/viper" - "github.com/ethereum/go-ethereum/common" - "github.com/maticnetwork/heimdall/bor/types" hmClient "github.com/maticnetwork/heimdall/client" "github.com/maticnetwork/heimdall/helper" @@ -271,7 +269,7 @@ func GetNextSpanSeed(cdc *codec.Codec) *cobra.Command { return cmd } -// PostSendProposeSpanTx send propose span transaction +// GetPreparedProposeSpan generates a propose span transaction func GetPreparedProposeSpan(cdc *codec.Codec) *cobra.Command { cmd := &cobra.Command{ Use: "propose-span", @@ -313,6 +311,11 @@ func GetPreparedProposeSpan(cdc *codec.Codec) *cobra.Command { return err } + nodeStatus, err := helper.GetNodeStatus(cliCtx) + if err != nil { + return err + } + // // Query data // @@ -345,23 +348,42 @@ func GetPreparedProposeSpan(cdc *codec.Codec) *cobra.Command { return errors.New("next span seed not found") } - var seed common.Hash - if err := jsoniter.Unmarshal(res, &seed); err != nil { + var seedResponse types.QuerySpanSeedResponse + if err := jsoniter.Unmarshal(res, &seedResponse); err != nil { return err } - msg := types.NewMsgProposeSpan( - spanID, - proposer, - startBlock, - startBlock+spanDuration-1, - borChainID, - seed, - ) - - result, err := jsoniter.Marshal(&msg) - if err != nil { - return err + var result []byte + + if nodeStatus.SyncInfo.LatestBlockHeight < helper.GetAntevortaHeight() { + msg := types.NewMsgProposeSpan( + spanID, + proposer, + startBlock, + startBlock+spanDuration-1, + borChainID, + seedResponse.Seed, + ) + + result, err = jsoniter.Marshal(&msg) + if err != nil { + return err + } + } else { + msg := types.NewMsgProposeSpanV2( + spanID, + proposer, + startBlock, + startBlock+spanDuration-1, + borChainID, + seedResponse.Seed, + seedResponse.SeedAuthor, + ) + + result, err = jsoniter.Marshal(&msg) + if err != nil { + return err + } } fmt.Println(string(result)) diff --git a/bor/client/cli/tx.go b/bor/client/cli/tx.go index 46aba4c7b..0efdc9f65 100644 --- a/bor/client/cli/tx.go +++ b/bor/client/cli/tx.go @@ -13,8 +13,6 @@ import ( "github.com/spf13/cobra" "github.com/spf13/viper" - "github.com/ethereum/go-ethereum/common" - "github.com/maticnetwork/heimdall/bor/types" hmClient "github.com/maticnetwork/heimdall/client" "github.com/maticnetwork/heimdall/helper" @@ -84,6 +82,11 @@ func PostSendProposeSpanTx(cdc *codec.Codec) *cobra.Command { return err } + nodeStatus, err := helper.GetNodeStatus(cliCtx) + if err != nil { + return err + } + // // Query data // @@ -116,19 +119,32 @@ func PostSendProposeSpanTx(cdc *codec.Codec) *cobra.Command { return errors.New("next span seed not found") } - var seed common.Hash - if err := jsoniter.ConfigFastest.Unmarshal(res, &seed); err != nil { + var seedResponse types.QuerySpanSeedResponse + if err := jsoniter.ConfigFastest.Unmarshal(res, &seedResponse); err != nil { return err } - msg := types.NewMsgProposeSpan( - spanID, - proposer, - startBlock, - startBlock+spanDuration-1, - borChainID, - seed, - ) + var msg sdk.Msg + if nodeStatus.SyncInfo.LatestBlockHeight < helper.GetAntevortaHeight() { + msg = types.NewMsgProposeSpan( + spanID, + proposer, + startBlock, + startBlock+spanDuration-1, + borChainID, + seedResponse.Seed, + ) + } else { + msg = types.NewMsgProposeSpanV2( + spanID, + proposer, + startBlock, + startBlock+spanDuration-1, + borChainID, + seedResponse.Seed, + seedResponse.SeedAuthor, + ) + } return helper.BroadcastMsgsWithCLI(cliCtx, []sdk.Msg{msg}) }, diff --git a/bor/client/rest/tx.go b/bor/client/rest/tx.go index 842aaae3a..66a46739a 100644 --- a/bor/client/rest/tx.go +++ b/bor/client/rest/tx.go @@ -11,10 +11,9 @@ import ( "github.com/gorilla/mux" jsoniter "github.com/json-iterator/go" - "github.com/ethereum/go-ethereum/common" - "github.com/maticnetwork/heimdall/bor/types" restClient "github.com/maticnetwork/heimdall/client/rest" + "github.com/maticnetwork/heimdall/helper" hmTypes "github.com/maticnetwork/heimdall/types" "github.com/maticnetwork/heimdall/types/rest" ) @@ -163,20 +162,40 @@ func postProposeSpanHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { return } - var seed common.Hash - if err = jsoniter.ConfigFastest.Unmarshal(res, &seed); err != nil { + var seedResponse types.QuerySpanSeedResponse + if err = jsoniter.ConfigFastest.Unmarshal(res, &seedResponse); err != nil { return } - // draft a propose span message - msg := types.NewMsgProposeSpan( - req.ID, - hmTypes.HexToHeimdallAddress(req.BaseReq.From), - req.StartBlock, - req.StartBlock+spanDuration-1, - req.BorChainID, - seed, - ) + nodeStatus, err := helper.GetNodeStatus(cliCtx) + if err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + var msg sdk.Msg + if nodeStatus.SyncInfo.LatestBlockHeight < helper.GetAntevortaHeight() { + // draft a propose span message + msg = types.NewMsgProposeSpan( + req.ID, + hmTypes.HexToHeimdallAddress(req.BaseReq.From), + req.StartBlock, + req.StartBlock+spanDuration-1, + req.BorChainID, + seedResponse.Seed, + ) + } else { + // draft a propose span v2 message + msg = types.NewMsgProposeSpanV2( + req.ID, + hmTypes.HexToHeimdallAddress(req.BaseReq.From), + req.StartBlock, + req.StartBlock+spanDuration-1, + req.BorChainID, + seedResponse.Seed, + seedResponse.SeedAuthor, + ) + } // send response restClient.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) diff --git a/bor/handler.go b/bor/handler.go index 5dac5a773..43c9d8f98 100644 --- a/bor/handler.go +++ b/bor/handler.go @@ -1,12 +1,14 @@ package bor import ( + "errors" "strconv" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/maticnetwork/heimdall/bor/types" "github.com/maticnetwork/heimdall/common" + "github.com/maticnetwork/heimdall/helper" ) // NewHandler returns a handler for "bor" type messages. @@ -15,7 +17,8 @@ func NewHandler(k Keeper) sdk.Handler { ctx = ctx.WithEventManager(sdk.NewEventManager()) switch msg := msg.(type) { - case types.MsgProposeSpan: + case types.MsgProposeSpan, + types.MsgProposeSpanV2: return HandleMsgProposeSpan(ctx, msg, k) default: return sdk.ErrTxDecode("Invalid message in bor module").Result() @@ -24,12 +27,38 @@ func NewHandler(k Keeper) sdk.Handler { } // HandleMsgProposeSpan handles proposeSpan msg -func HandleMsgProposeSpan(ctx sdk.Context, msg types.MsgProposeSpan, k Keeper) sdk.Result { +func HandleMsgProposeSpan(ctx sdk.Context, msg sdk.Msg, k Keeper) sdk.Result { + var proposeMsg types.MsgProposeSpanV2 + switch msg := msg.(type) { + case types.MsgProposeSpan: + if ctx.BlockHeight() >= helper.GetAntevortaHeight() { + err := errors.New("msg span is not allowed after Antevorta hardfork height") + k.Logger(ctx).Error(err.Error()) + return sdk.ErrTxDecode(err.Error()).Result() + } + proposeMsg = types.MsgProposeSpanV2{ + ID: msg.ID, + Proposer: msg.Proposer, + StartBlock: msg.StartBlock, + EndBlock: msg.EndBlock, + ChainID: msg.ChainID, + Seed: msg.Seed, + } + case types.MsgProposeSpanV2: + if ctx.BlockHeight() < helper.GetAntevortaHeight() { + err := errors.New("msg span v2 is not allowed before Antevorta hardfork height") + k.Logger(ctx).Error(err.Error()) + return sdk.ErrTxDecode(err.Error()).Result() + } + proposeMsg = msg + } + k.Logger(ctx).Debug("✅ Validating proposed span msg", - "spanId", msg.ID, - "startBlock", msg.StartBlock, - "endBlock", msg.EndBlock, - "seed", msg.Seed.String(), + "proposer", proposeMsg.Proposer.String(), + "spanId", proposeMsg.ID, + "startBlock", proposeMsg.StartBlock, + "endBlock", proposeMsg.EndBlock, + "seed", proposeMsg.Seed.String(), ) // chainManager params @@ -37,8 +66,8 @@ func HandleMsgProposeSpan(ctx sdk.Context, msg types.MsgProposeSpan, k Keeper) s chainParams := params.ChainParams // check chain id - if chainParams.BorChainID != msg.ChainID { - k.Logger(ctx).Error("Invalid Bor chain id", "msgChainID", msg.ChainID) + if chainParams.BorChainID != proposeMsg.ChainID { + k.Logger(ctx).Error("Invalid Bor chain id", "msgChainID", proposeMsg.ChainID) return common.ErrInvalidBorChainID(k.Codespace()).Result() } @@ -50,14 +79,14 @@ func HandleMsgProposeSpan(ctx sdk.Context, msg types.MsgProposeSpan, k Keeper) s } // Validate span continuity - if lastSpan.ID+1 != msg.ID || msg.StartBlock != lastSpan.EndBlock+1 || msg.EndBlock < msg.StartBlock { + if lastSpan.ID+1 != proposeMsg.ID || proposeMsg.StartBlock != lastSpan.EndBlock+1 || proposeMsg.EndBlock < proposeMsg.StartBlock { k.Logger(ctx).Error("Blocks not in continuity", "lastSpanId", lastSpan.ID, - "spanId", msg.ID, + "spanId", proposeMsg.ID, "lastSpanStartBlock", lastSpan.StartBlock, "lastSpanEndBlock", lastSpan.EndBlock, - "spanStartBlock", msg.StartBlock, - "spanEndBlock", msg.EndBlock, + "spanStartBlock", proposeMsg.StartBlock, + "spanEndBlock", proposeMsg.EndBlock, ) return common.ErrSpanNotInContinuity(k.Codespace()).Result() @@ -65,9 +94,9 @@ func HandleMsgProposeSpan(ctx sdk.Context, msg types.MsgProposeSpan, k Keeper) s // Validate Span duration spanDuration := k.GetParams(ctx).SpanDuration - if spanDuration != (msg.EndBlock - msg.StartBlock + 1) { + if spanDuration != (proposeMsg.EndBlock - proposeMsg.StartBlock + 1) { k.Logger(ctx).Error("Span duration of proposed span is wrong", - "proposedSpanDuration", msg.EndBlock-msg.StartBlock+1, + "proposedSpanDuration", proposeMsg.EndBlock-proposeMsg.StartBlock+1, "paramsSpanDuration", spanDuration, ) @@ -79,9 +108,9 @@ func HandleMsgProposeSpan(ctx sdk.Context, msg types.MsgProposeSpan, k Keeper) s sdk.NewEvent( types.EventTypeProposeSpan, sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), - sdk.NewAttribute(types.AttributeKeySpanID, strconv.FormatUint(msg.ID, 10)), - sdk.NewAttribute(types.AttributeKeySpanStartBlock, strconv.FormatUint(msg.StartBlock, 10)), - sdk.NewAttribute(types.AttributeKeySpanEndBlock, strconv.FormatUint(msg.EndBlock, 10)), + sdk.NewAttribute(types.AttributeKeySpanID, strconv.FormatUint(proposeMsg.ID, 10)), + sdk.NewAttribute(types.AttributeKeySpanStartBlock, strconv.FormatUint(proposeMsg.StartBlock, 10)), + sdk.NewAttribute(types.AttributeKeySpanEndBlock, strconv.FormatUint(proposeMsg.EndBlock, 10)), ), }) diff --git a/bor/keeper.go b/bor/keeper.go index d4872c321..2fb0205d8 100644 --- a/bor/keeper.go +++ b/bor/keeper.go @@ -349,11 +349,13 @@ func (k *Keeper) GetLastEthBlock(ctx sdk.Context) *big.Int { return lastEthBlock } -func (k *Keeper) GetNextSpanSeed(ctx sdk.Context, id uint64) (common.Hash, error) { +func (k *Keeper) GetNextSpanSeed(ctx sdk.Context, id uint64) (common.Hash, common.Address, error) { var ( blockHeader *ethTypes.Header + borBlock uint64 seedSpan *hmTypes.Span err error + author *common.Address ) if ctx.BlockHeader().Height < helper.GetJorvikHeight() { @@ -367,8 +369,9 @@ func (k *Keeper) GetNextSpanSeed(ctx sdk.Context, id uint64) (common.Hash, 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 + return common.Hash{}, common.Address{}, err } + author = &common.Address{} } else { var seedSpanID uint64 if id < 2 { @@ -379,24 +382,29 @@ func (k *Keeper) GetNextSpanSeed(ctx sdk.Context, id uint64) (common.Hash, error 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 + return common.Hash{}, common.Address{}, err } - borBlock, author, err := k.getBorBlockForSpanSeed(ctx, seedSpan, id) + borBlock, author, err = k.getBorBlockForSpanSeed(ctx, seedSpan, id) if err != nil { - return common.Hash{}, err + return common.Hash{}, common.Address{}, 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 + return common.Hash{}, common.Address{}, err + } + + if author == nil { + k.Logger(ctx).Error("seed author is nil") + return blockHeader.Hash(), common.Address{}, fmt.Errorf("seed author is nil") } k.Logger(ctx).Debug("fetched block for seed", "block", borBlock, "author", author, "span id", id) } - return blockHeader.Hash(), nil + return blockHeader.Hash(), *author, nil } // StoreSeedProducer stores producer of the block used for seed for the given span id diff --git a/bor/keeper_test.go b/bor/keeper_test.go index 68e3cbe4c..b839cd41b 100644 --- a/bor/keeper_test.go +++ b/bor/keeper_test.go @@ -108,30 +108,35 @@ func (s *BorKeeperTestSuite) TestGetNextSpanSeed() { lastSpanId uint64 lastSeedProducer *common.Address expSeed common.Hash + expAuthor *common.Address }{ { name: "Last seed producer is different than end block author", lastSeedProducer: &val2Addr, lastSpanId: 0, expSeed: blockHash1, + expAuthor: &val2Addr, }, { name: "Last seed producer is same as end block author", lastSeedProducer: &val1Addr, lastSpanId: 1, expSeed: blockHash2, + expAuthor: &val1Addr, }, { name: "Next seed producer should be different from previous recent seed producers", lastSeedProducer: &val2Addr, lastSpanId: 2, expSeed: blockHash3, + expAuthor: &val3Addr, }, { 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, + expAuthor: &val2Addr, }, } @@ -149,9 +154,10 @@ func (s *BorKeeperTestSuite) TestGetNextSpanSeed() { for _, tc := range testcases { s.T().Run(tc.name, func(t *testing.T) { - seed, err := borKeeper.GetNextSpanSeed(ctx, tc.lastSpanId+2) + seed, author, err := borKeeper.GetNextSpanSeed(ctx, tc.lastSpanId+2) require.NoError(err) require.Equal(tc.expSeed.Bytes(), seed.Bytes()) + require.Equal(tc.expAuthor.Bytes(), author.Bytes()) }) } } @@ -178,9 +184,10 @@ func (s *BorKeeperTestSuite) TestProposeSpanOne() { blockHash1 := blockHeader1.Hash() contractCaller.On("GetMaticChainBlock", big.NewInt(seedBlock1)).Return(&blockHeader1, nil) - seed, err := app.BorKeeper.GetNextSpanSeed(ctx, 1) + seed, author, err := app.BorKeeper.GetNextSpanSeed(ctx, 1) s.Require().NoError(err) s.Require().Equal(blockHash1.Bytes(), seed.Bytes()) + s.Require().Equal(val1Addr.Bytes(), author.Bytes()) } func (s *BorKeeperTestSuite) TestGetSeedProducer() { diff --git a/bor/querier.go b/bor/querier.go index 1726a72e2..4fe237f36 100644 --- a/bor/querier.go +++ b/bor/querier.go @@ -171,7 +171,7 @@ func handleQueryNextProducers(ctx sdk.Context, req abci.RequestQuery, keeper Kee logger := ctx.Logger() logger.Debug("querying next producers", "spanId", spanId) - nextSpanSeed, err := keeper.GetNextSpanSeed(ctx, 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()))) } @@ -214,14 +214,14 @@ func handlerQueryNextSpanSeed(ctx sdk.Context, req abci.RequestQuery, keeper Kee return nil, sdk.ErrInternal(fmt.Sprintf("failed to parse params: %s", err)) } - nextSpanSeed, err := keeper.GetNextSpanSeed(ctx, params.RecordID) + nextSpanSeed, author, err := keeper.GetNextSpanSeed(ctx, params.RecordID) if err != nil { return nil, sdk.ErrInternal(sdk.AppendMsgToErr("Error fetching next span seed", err.Error())) } // json record - bz, err := jsoniter.ConfigFastest.Marshal(nextSpanSeed) + bz, err := jsoniter.ConfigFastest.Marshal(types.NewQuerySpanSeedResponse(nextSpanSeed, author)) if err != nil { return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err.Error())) } diff --git a/bor/side_handler.go b/bor/side_handler.go index 93c471097..16990dc96 100644 --- a/bor/side_handler.go +++ b/bor/side_handler.go @@ -6,6 +6,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" + ethCommon "github.com/ethereum/go-ethereum/common" "github.com/maticnetwork/heimdall/bor/types" "github.com/maticnetwork/heimdall/common" hmCommon "github.com/maticnetwork/heimdall/common" @@ -21,7 +22,8 @@ func NewSideTxHandler(k Keeper, contractCaller helper.IContractCaller) hmTypes.S return func(ctx sdk.Context, msg sdk.Msg) abci.ResponseDeliverSideTx { ctx = ctx.WithEventManager(sdk.NewEventManager()) switch msg := msg.(type) { - case types.MsgProposeSpan: + case types.MsgProposeSpan, + types.MsgProposeSpanV2: return SideHandleMsgSpan(ctx, k, msg, contractCaller) default: return abci.ResponseDeliverSideTx{ @@ -36,7 +38,8 @@ func NewPostTxHandler(k Keeper, contractCaller helper.IContractCaller) hmTypes.P return func(ctx sdk.Context, msg sdk.Msg, sideTxResult abci.SideTxResultType) sdk.Result { ctx = ctx.WithEventManager(sdk.NewEventManager()) switch msg := msg.(type) { - case types.MsgProposeSpan: + case types.MsgProposeSpan, + types.MsgProposeSpanV2: return PostHandleMsgEventSpan(ctx, k, msg, sideTxResult) default: errMsg := "Unrecognized Span Msg type: %s" + msg.Type() @@ -46,29 +49,71 @@ func NewPostTxHandler(k Keeper, contractCaller helper.IContractCaller) hmTypes.P } // SideHandleMsgSpan validates external calls required for processing proposed span -func SideHandleMsgSpan(ctx sdk.Context, k Keeper, msg types.MsgProposeSpan, contractCaller helper.IContractCaller) (result abci.ResponseDeliverSideTx) { +func SideHandleMsgSpan(ctx sdk.Context, k Keeper, msg sdk.Msg, contractCaller helper.IContractCaller) (result abci.ResponseDeliverSideTx) { + var proposeMsg types.MsgProposeSpanV2 + switch msg := msg.(type) { + case types.MsgProposeSpan: + if ctx.BlockHeight() >= helper.GetAntevortaHeight() { + k.Logger(ctx).Error("Msg span is not allowed after Antevorta hardfork height") + return hmCommon.ErrorSideTx(k.Codespace(), common.CodeInvalidMsg) + } + proposeMsg = types.MsgProposeSpanV2{ + ID: msg.ID, + Proposer: msg.Proposer, + StartBlock: msg.StartBlock, + EndBlock: msg.EndBlock, + ChainID: msg.ChainID, + Seed: msg.Seed, + } + case types.MsgProposeSpanV2: + if ctx.BlockHeight() < helper.GetAntevortaHeight() { + k.Logger(ctx).Error("Msg span v2 is not allowed before Antevorta hardfork height") + return hmCommon.ErrorSideTx(k.Codespace(), common.CodeInvalidMsg) + } + proposeMsg = msg + } + k.Logger(ctx).Debug("✅ Validating External call for span msg", - "msgSeed", msg.Seed.String(), + "msgSeed", proposeMsg.Seed.String(), ) // calculate next span seed locally - nextSpanSeed, err := k.GetNextSpanSeed(ctx, msg.ID) + seed, seedAuthor, err := k.GetNextSpanSeed(ctx, proposeMsg.ID) if err != nil { k.Logger(ctx).Error("Error fetching next span seed from mainchain") return hmCommon.ErrorSideTx(k.Codespace(), common.CodeInvalidMsg) } // check if span seed matches or not. - if !bytes.Equal(msg.Seed.Bytes(), nextSpanSeed.Bytes()) { + if !bytes.Equal(proposeMsg.Seed.Bytes(), seed.Bytes()) { k.Logger(ctx).Error( "Span Seed does not match", - "msgSeed", msg.Seed.String(), - "mainchainSeed", nextSpanSeed.String(), + "proposer", proposeMsg.Proposer.String(), + "chainID", proposeMsg.ChainID, + "msgSeed", proposeMsg.Seed.String(), + "mainchainSeed", seed.String(), ) return hmCommon.ErrorSideTx(k.Codespace(), common.CodeInvalidMsg) } + if ctx.BlockHeight() >= helper.GetAntevortaHeight() { + // check if span seed author matches or not. + if !bytes.Equal(proposeMsg.SeedAuthor.Bytes(), seedAuthor.Bytes()) { + k.Logger(ctx).Error( + "Span Seed Author does not match", + "proposer", proposeMsg.Proposer.String(), + "chainID", proposeMsg.ChainID, + "msgSeed", proposeMsg.Seed.String(), + "msgSeedAuthor", proposeMsg.SeedAuthor.String(), + "mainchainSeedAuthor", seedAuthor.String(), + "mainchainSeed", seed.String(), + ) + + return hmCommon.ErrorSideTx(k.Codespace(), common.CodeInvalidMsg) + } + } + // fetch current child block childBlock, err := contractCaller.GetMaticChainBlock(nil) if err != nil { @@ -88,8 +133,8 @@ func SideHandleMsgSpan(ctx sdk.Context, k Keeper, msg types.MsgProposeSpan, cont k.Logger(ctx).Error( "Span proposed is not in-turn", "currentChildBlock", currentBlock, - "msgStartblock", msg.StartBlock, - "msgEndBlock", msg.EndBlock, + "msgStartblock", proposeMsg.StartBlock, + "msgEndBlock", proposeMsg.EndBlock, ) return hmCommon.ErrorSideTx(k.Codespace(), common.CodeInvalidMsg) @@ -103,7 +148,7 @@ 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 { +func PostHandleMsgEventSpan(ctx sdk.Context, k Keeper, msg sdk.Msg, sideTxResult abci.SideTxResultType) sdk.Result { logger := k.Logger(ctx) // Skip handler if span is not approved @@ -112,20 +157,43 @@ func PostHandleMsgEventSpan(ctx sdk.Context, k Keeper, msg types.MsgProposeSpan, return common.ErrSideTxValidation(k.Codespace()).Result() } + // check if msg is of type MsgProposeSpanV2 + var proposeMsg types.MsgProposeSpanV2 + switch msg := msg.(type) { + case types.MsgProposeSpan: + proposeMsg = types.MsgProposeSpanV2{ + ID: msg.ID, + Proposer: msg.Proposer, + StartBlock: msg.StartBlock, + EndBlock: msg.EndBlock, + ChainID: msg.ChainID, + Seed: msg.Seed, + } + case types.MsgProposeSpanV2: + proposeMsg = msg + } + // check for replay - if k.HasSpan(ctx, msg.ID) { + if k.HasSpan(ctx, proposeMsg.ID) { logger.Debug("Skipping new span as it's already processed") return hmCommon.ErrOldTx(k.Codespace()).Result() } - logger.Debug("Persisting span state", "sideTxResult", sideTxResult) + logger.Debug("Persisting span state", + "sideTxResult", sideTxResult, + "proposer", proposeMsg.Proposer.String(), + "spanId", proposeMsg.ID, + "startBlock", proposeMsg.StartBlock, + "endBlock", proposeMsg.EndBlock, + "seed", proposeMsg.Seed.String(), + ) if ctx.BlockHeader().Height >= helper.GetJorvikHeight() { var seedSpanID uint64 - if msg.ID < 2 { - seedSpanID = msg.ID - 1 + if proposeMsg.ID < 2 { + seedSpanID = proposeMsg.ID - 1 } else { - seedSpanID = msg.ID - 2 + seedSpanID = proposeMsg.ID - 2 } lastSpan, err := k.GetSpan(ctx, seedSpanID) @@ -134,21 +202,27 @@ func PostHandleMsgEventSpan(ctx sdk.Context, k Keeper, msg types.MsgProposeSpan, 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() + var producer *ethCommon.Address + + if ctx.BlockHeight() < helper.GetAntevortaHeight() { + // store the seed producer + _, producer, err = k.getBorBlockForSpanSeed(ctx, lastSpan, proposeMsg.ID) + if err != nil { + logger.Error("Unable to get seed producer", "Error", err) + return common.ErrUnableToGetSeed(k.Codespace()).Result() + } + } else { + producer = &proposeMsg.SeedAuthor } - if err = k.StoreSeedProducer(ctx, msg.ID, producer); err != nil { + if err = k.StoreSeedProducer(ctx, proposeMsg.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) + err := k.FreezeSet(ctx, proposeMsg.ID, proposeMsg.StartBlock, proposeMsg.EndBlock, proposeMsg.ChainID, proposeMsg.Seed) if err != nil { k.Logger(ctx).Error("Unable to freeze validator set for span", "Error", err) return common.ErrUnableToFreezeValSet(k.Codespace()).Result() @@ -166,9 +240,9 @@ func PostHandleMsgEventSpan(ctx sdk.Context, k Keeper, msg types.MsgProposeSpan, sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), // module name sdk.NewAttribute(hmTypes.AttributeKeyTxHash, hmTypes.BytesToHeimdallHash(hash).Hex()), // tx hash sdk.NewAttribute(hmTypes.AttributeKeySideTxResult, sideTxResult.String()), // result - sdk.NewAttribute(types.AttributeKeySpanID, strconv.FormatUint(msg.ID, 10)), - sdk.NewAttribute(types.AttributeKeySpanStartBlock, strconv.FormatUint(msg.StartBlock, 10)), - sdk.NewAttribute(types.AttributeKeySpanEndBlock, strconv.FormatUint(msg.EndBlock, 10)), + sdk.NewAttribute(types.AttributeKeySpanID, strconv.FormatUint(proposeMsg.ID, 10)), + sdk.NewAttribute(types.AttributeKeySpanStartBlock, strconv.FormatUint(proposeMsg.StartBlock, 10)), + sdk.NewAttribute(types.AttributeKeySpanEndBlock, strconv.FormatUint(proposeMsg.EndBlock, 10)), ), }) diff --git a/bor/types/codec.go b/bor/types/codec.go index cc4fbb3ee..75b5371d6 100644 --- a/bor/types/codec.go +++ b/bor/types/codec.go @@ -6,6 +6,7 @@ import ( func RegisterCodec(cdc *codec.Codec) { cdc.RegisterConcrete(MsgProposeSpan{}, "bor/MsgProposeSpan", nil) + cdc.RegisterConcrete(MsgProposeSpanV2{}, "bor/MsgProposeSpanV2", nil) } // ModuleCdc generic sealed codec to be used throughout module diff --git a/bor/types/msg.go b/bor/types/msg.go index eac888925..119924140 100644 --- a/bor/types/msg.go +++ b/bor/types/msg.go @@ -80,3 +80,85 @@ func (msg MsgProposeSpan) ValidateBasic() sdk.Error { func (msg MsgProposeSpan) GetSideSignBytes() []byte { return nil } + +// +// Propose Span v2 Msg +// + +var _ sdk.Msg = &MsgProposeSpanV2{} + +// MsgProposeSpanV2 creates msg propose span +type MsgProposeSpanV2 struct { + ID uint64 `json:"span_id"` + Proposer hmTypes.HeimdallAddress `json:"proposer"` + StartBlock uint64 `json:"start_block"` + EndBlock uint64 `json:"end_block"` + ChainID string `json:"bor_chain_id"` + Seed common.Hash `json:"seed"` + SeedAuthor common.Address `json:"seed_author"` +} + +// NewMsgProposeSpan creates new propose span message +func NewMsgProposeSpanV2( + id uint64, + proposer hmTypes.HeimdallAddress, + startBlock uint64, + endBlock uint64, + chainID string, + seed common.Hash, + seedAuthor common.Address, +) MsgProposeSpanV2 { + return MsgProposeSpanV2{ + ID: id, + Proposer: proposer, + StartBlock: startBlock, + EndBlock: endBlock, + ChainID: chainID, + Seed: seed, + SeedAuthor: seedAuthor, + } +} + +// Type returns message type +func (msg MsgProposeSpanV2) Type() string { + return "propose-span-v2" +} + +// Route returns route for message +func (msg MsgProposeSpanV2) Route() string { + return RouterKey +} + +// GetSigners returns address of the signer +func (msg MsgProposeSpanV2) GetSigners() []sdk.AccAddress { + return []sdk.AccAddress{hmTypes.HeimdallAddressToAccAddress(msg.Proposer)} +} + +// GetSignBytes returns sign bytes for proposeSpan message type +func (msg MsgProposeSpanV2) GetSignBytes() []byte { + b, err := ModuleCdc.MarshalJSON(msg) + if err != nil { + panic(err) + } + + return sdk.MustSortJSON(b) +} + +// ValidateBasic validates the message and returns error +func (msg MsgProposeSpanV2) ValidateBasic() sdk.Error { + if msg.Proposer.Empty() { + return sdk.ErrInvalidAddress(msg.Proposer.String()) + } + if msg.Seed.Cmp(common.Hash{}) == 0 { + return sdk.ErrUnknownRequest("Seed cannot be empty") + } + if msg.SeedAuthor.Cmp(common.Address{}) == 0 { + return sdk.ErrUnknownRequest("SeedAuthor cannot be empty") + } + return nil +} + +// GetSideSignBytes returns side sign bytes +func (msg MsgProposeSpanV2) GetSideSignBytes() []byte { + return nil +} diff --git a/bor/types/querier.go b/bor/types/querier.go index df981d5fa..d6b075257 100644 --- a/bor/types/querier.go +++ b/bor/types/querier.go @@ -1,5 +1,7 @@ package types +import "github.com/ethereum/go-ethereum/common" + // query endpoints supported by the auth Querier const ( QueryParams = "params" @@ -25,3 +27,14 @@ type QuerySpanParams struct { func NewQuerySpanParams(recordID uint64) QuerySpanParams { return QuerySpanParams{RecordID: recordID} } + +// QuerySpanSeedResponse defines the response to a span seed query +type QuerySpanSeedResponse struct { + Seed common.Hash `json:"seed"` + SeedAuthor common.Address `json:"seed_author"` +} + +// NewQuerySpanSeedResponse creates a new instance of QuerySpanSeedResponse. +func NewQuerySpanSeedResponse(seed common.Hash, seedAuthor common.Address) QuerySpanSeedResponse { + return QuerySpanSeedResponse{Seed: seed, SeedAuthor: seedAuthor} +} diff --git a/bridge/setu/processor/span.go b/bridge/setu/processor/span.go index e869e4f95..5a717862d 100644 --- a/bridge/setu/processor/span.go +++ b/bridge/setu/processor/span.go @@ -108,29 +108,55 @@ 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(nextSpanMsg.ID) + seed, seedAuthor, err := sp.fetchNextSpanSeed(nextSpanMsg.ID) if err != nil { sp.Logger.Info("Error while fetching next span seed from HeimdallServer", "err", err) return } - // broadcast to heimdall - msg := borTypes.MsgProposeSpan{ - ID: nextSpanMsg.ID, - Proposer: types.BytesToHeimdallAddress(helper.GetAddress()), - StartBlock: nextSpanMsg.StartBlock, - EndBlock: nextSpanMsg.EndBlock, - ChainID: nextSpanMsg.ChainID, - Seed: seed, - } - - // return broadcast to heimdall - txRes, err := sp.txBroadcaster.BroadcastToHeimdall(msg, nil) + nodeStatus, err := helper.GetNodeStatus(sp.cliCtx) if err != nil { - sp.Logger.Error("Error while broadcasting span to heimdall", "spanId", nextSpanMsg.ID, "startBlock", nextSpanMsg.StartBlock, "endBlock", nextSpanMsg.EndBlock, "error", err) + sp.Logger.Error("Error while fetching heimdall node status", "error", err) return } + var txRes sdk.TxResponse + + if nodeStatus.SyncInfo.LatestBlockHeight < helper.GetAntevortaHeight() { + // broadcast to heimdall + msg := borTypes.MsgProposeSpan{ + ID: nextSpanMsg.ID, + Proposer: types.BytesToHeimdallAddress(helper.GetAddress()), + StartBlock: nextSpanMsg.StartBlock, + EndBlock: nextSpanMsg.EndBlock, + ChainID: nextSpanMsg.ChainID, + Seed: seed, + } + + // return broadcast to heimdall + txRes, err = sp.txBroadcaster.BroadcastToHeimdall(msg, nil) + if err != nil { + sp.Logger.Error("Error while broadcasting span to heimdall", "spanId", nextSpanMsg.ID, "startBlock", nextSpanMsg.StartBlock, "endBlock", nextSpanMsg.EndBlock, "error", err) + return + } + } else { + msg := borTypes.MsgProposeSpanV2{ + ID: nextSpanMsg.ID, + Proposer: types.BytesToHeimdallAddress(helper.GetAddress()), + StartBlock: nextSpanMsg.StartBlock, + EndBlock: nextSpanMsg.EndBlock, + ChainID: nextSpanMsg.ChainID, + Seed: seed, + SeedAuthor: seedAuthor, + } + + txRes, err = sp.txBroadcaster.BroadcastToHeimdall(msg, nil) + if err != nil { + sp.Logger.Error("Error while broadcasting span to heimdall", "spanId", nextSpanMsg.ID, "startBlock", nextSpanMsg.StartBlock, "endBlock", nextSpanMsg.EndBlock, "error", err) + return + } + } + if txRes.Code != uint32(sdk.CodeOK) { sp.Logger.Error("span tx failed on heimdall", "txHash", txRes.TxHash, "code", txRes.Code) return @@ -219,23 +245,25 @@ func (sp *SpanProcessor) fetchNextSpanDetails(id uint64, start uint64) (*types.S } // fetchNextSpanSeed - fetches seed for next span -func (sp *SpanProcessor) fetchNextSpanSeed(id uint64) (nextSpanSeed common.Hash, err error) { +func (sp *SpanProcessor) fetchNextSpanSeed(id uint64) (common.Hash, common.Address, error) { sp.Logger.Info("Sending Rest call to Get Seed for next span") 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 + return common.Hash{}, common.Address{}, err } sp.Logger.Info("Next span seed fetched") - if err = jsoniter.ConfigFastest.Unmarshal(response.Result, &nextSpanSeed); err != nil { + var nextSpanSeedResponse borTypes.QuerySpanSeedResponse + + if err = jsoniter.ConfigFastest.Unmarshal(response.Result, &nextSpanSeedResponse); err != nil { sp.Logger.Error("Error unmarshalling nextSpanSeed received from Heimdall Server", "error", err) - return nextSpanSeed, err + return common.Hash{}, common.Address{}, err } - return nextSpanSeed, nil + return nextSpanSeedResponse.Seed, nextSpanSeedResponse.SeedAuthor, nil } // Stop stops all necessary go routines diff --git a/cmd/heimdalld/service/service.go b/cmd/heimdalld/service/service.go index be1932dbc..fe639f0bd 100644 --- a/cmd/heimdalld/service/service.go +++ b/cmd/heimdalld/service/service.go @@ -262,7 +262,6 @@ which accepts a path for the resulting pprof file. logger, err := SetupCtxLogger(logWriter, ctx.Config.LogLevel) if err != nil { - logger.Error("Unable to setup logger", "err", err) return err } diff --git a/helper/config.go b/helper/config.go index 93b33c00f..8aa56f7b4 100644 --- a/helper/config.go +++ b/helper/config.go @@ -243,6 +243,8 @@ var newHexToStringAlgoHeight int64 = 0 var jorvikHeight int64 = 0 +var antevortaHeight int64 = 0 + type ChainManagerAddressMigration struct { MaticTokenAddress hmTypes.HeimdallAddress RootChainAddress hmTypes.HeimdallAddress @@ -413,24 +415,28 @@ func InitHeimdallConfigWith(homeDir string, heimdallConfigFileFromFLag string) { newHexToStringAlgoHeight = 9266260 aalborgHeight = 15950759 jorvikHeight = -1 + antevortaHeight = -1 case MumbaiChain: newSelectionAlgoHeight = 282500 spanOverrideHeight = 10205000 newHexToStringAlgoHeight = 12048023 aalborgHeight = 18035772 jorvikHeight = -1 + antevortaHeight = -1 case AmoyChain: newSelectionAlgoHeight = 0 spanOverrideHeight = 0 newHexToStringAlgoHeight = 0 aalborgHeight = 0 jorvikHeight = 5768528 + antevortaHeight = 0 default: newSelectionAlgoHeight = 0 spanOverrideHeight = 0 newHexToStringAlgoHeight = 0 aalborgHeight = 0 jorvikHeight = 0 + antevortaHeight = 0 } } @@ -588,6 +594,11 @@ func GetJorvikHeight() int64 { return jorvikHeight } +// GetAntevortaHeight returns antevortaHeight +func GetAntevortaHeight() int64 { + return antevortaHeight +} + func GetChainManagerAddressMigration(blockNum int64) (ChainManagerAddressMigration, bool) { chainMigration := chainManagerAddressMigrations[conf.Chain] if chainMigration == nil { From fe8bb211f62d1f77296d04f90354efacb1652a35 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 12 Dec 2024 00:16:55 +0000 Subject: [PATCH 2/8] build(deps): bump golang.org/x/crypto from 0.24.0 to 0.31.0 Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.24.0 to 0.31.0. - [Commits](https://github.com/golang/crypto/compare/v0.24.0...v0.31.0) --- updated-dependencies: - dependency-name: golang.org/x/crypto dependency-type: indirect ... Signed-off-by: dependabot[bot] --- go.mod | 8 ++++---- go.sum | 12 ++++++++---- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/go.mod b/go.mod index 8bb28b171..032182437 100644 --- a/go.mod +++ b/go.mod @@ -28,7 +28,7 @@ require ( github.com/tendermint/go-amino v0.16.0 github.com/tendermint/tendermint v0.34.24 github.com/tendermint/tm-db v0.6.7 - golang.org/x/sync v0.7.0 + golang.org/x/sync v0.10.0 google.golang.org/grpc v1.64.1 google.golang.org/protobuf v1.34.1 ) @@ -158,11 +158,11 @@ require ( go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0 go.opentelemetry.io/otel/sdk v1.27.0 go.opentelemetry.io/otel/trace v1.27.0 - golang.org/x/crypto v0.24.0 // indirect + golang.org/x/crypto v0.31.0 // indirect golang.org/x/net v0.26.0 // indirect golang.org/x/oauth2 v0.20.0 // indirect - golang.org/x/sys v0.21.0 // indirect - golang.org/x/text v0.16.0 // indirect + golang.org/x/sys v0.28.0 // indirect + golang.org/x/text v0.21.0 // indirect google.golang.org/api v0.169.0 // indirect google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect gopkg.in/yaml.v3 v3.0.1 diff --git a/go.sum b/go.sum index 8c5059c03..b28f04c40 100644 --- a/go.sum +++ b/go.sum @@ -2913,8 +2913,9 @@ golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1m golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= -golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI= golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM= +golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= +golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -3162,8 +3163,9 @@ golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= +golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -3306,8 +3308,9 @@ golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/telemetry v0.0.0-20240208230135-b75ee8823808/go.mod h1:KG1lNk5ZFNssSZLrpVb4sMXKMpGwGXOxSG3rnu2gZQQ= golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE= golang.org/x/telemetry v0.0.0-20240521205824-bda55230c457/go.mod h1:pRgIJT+bRLFKnoM1ldnzKoxTIn14Yxz928LQRYYgIN0= @@ -3356,8 +3359,9 @@ golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= From 17d8d2672f98bda1425f02285b25eb31a995c74c Mon Sep 17 00:00:00 2001 From: Daniel Jones Date: Thu, 12 Dec 2024 15:22:24 -0600 Subject: [PATCH 3/8] Fixes for profiles, removing some unecessary postinst file, update to prerm, and postrm.profile --- .github/workflows/amoy_deb_profiles.yml | 6 +++--- .github/workflows/mainnet_deb_profiles.yml | 6 +++--- packaging/deb/heimdalld/DEBIAN/prerm | 2 +- packaging/templates/package_scripts/postinst.validator | 4 ---- packaging/templates/package_scripts/postrm.profile | 2 -- 5 files changed, 7 insertions(+), 13 deletions(-) delete mode 100755 packaging/templates/package_scripts/postinst.validator diff --git a/.github/workflows/amoy_deb_profiles.yml b/.github/workflows/amoy_deb_profiles.yml index da17ad285..1882f145e 100644 --- a/.github/workflows/amoy_deb_profiles.yml +++ b/.github/workflows/amoy_deb_profiles.yml @@ -122,19 +122,19 @@ jobs: run: cp -rp packaging/templates/package_scripts/preinst.${{ env.NETWORK }} packaging/deb/heimdall-${{ env.NETWORK }}-${{ env.NODE }}-config_${{ env.GIT_TAG }}-${{ env.ARCH }}/DEBIAN/preinst env: ARCH: all - NODE: sentry + NODE: validator NETWORK: amoy - name: Copying config for ${{ env.NODE }} on ${{ env.NETWORK }} on ${{ env.ARCH }} run: cp -rp packaging/templates/config/${{ env.NETWORK }}/heimdall-config.toml packaging/deb/heimdall-${{ env.NETWORK }}-${{ env.NODE }}-config_${{ env.GIT_TAG }}-${{ env.ARCH }}/var/lib/heimdall/config/heimdall-config.toml env: ARCH: all - NODE: sentry + NODE: validator NETWORK: amoy - name: Copying config for ${{ env.NODE }} on ${{ env.NETWORK }} on ${{ env.ARCH }} run: cp -rp packaging/templates/config/${{ env.NETWORK }}/config.toml packaging/deb/heimdall-${{ env.NETWORK }}-${{ env.NODE }}-config_${{ env.GIT_TAG }}-${{ env.ARCH }}/var/lib/heimdall/config/config.toml env: ARCH: all - NODE: sentry + NODE: validator NETWORK: amoy - name: Copying systemd file for ${{ env.NODE }} on ${{ env.NETWORK }} on ${{ env.ARCH }} run: cp -rp packaging/templates/systemd/heimdalld-amoy-validator.service packaging/deb/heimdall-${{ env.NETWORK }}-${{ env.NODE }}-config_${{ env.GIT_TAG }}-${{ env.ARCH }}/lib/systemd/system/heimdalld.service diff --git a/.github/workflows/mainnet_deb_profiles.yml b/.github/workflows/mainnet_deb_profiles.yml index 836bb291d..71f4ab824 100644 --- a/.github/workflows/mainnet_deb_profiles.yml +++ b/.github/workflows/mainnet_deb_profiles.yml @@ -128,19 +128,19 @@ jobs: run: cp -rp packaging/templates/package_scripts/preinst.${{ env.NETWORK }} packaging/deb/heimdall-${{ env.NETWORK }}-${{ env.NODE }}-config_${{ env.GIT_TAG }}-${{ env.ARCH }}/DEBIAN/preinst env: ARCH: all - NODE: sentry + NODE: validator NETWORK: mainnet - name: Copying config for ${{ env.NODE }} on ${{ env.NETWORK }} on ${{ env.ARCH }} run: cp -rp packaging/templates/config/${{ env.NETWORK }}/heimdall-config.toml packaging/deb/heimdall-${{ env.NETWORK }}-${{ env.NODE }}-config_${{ env.GIT_TAG }}-${{ env.ARCH }}/var/lib/heimdall/config/heimdall-config.toml env: ARCH: all - NODE: sentry + NODE: validator NETWORK: mainnet - name: Copying config for ${{ env.NODE }} on ${{ env.NETWORK }} on ${{ env.ARCH }} run: cp -rp packaging/templates/config/${{ env.NETWORK }}/config.toml packaging/deb/heimdall-${{ env.NETWORK }}-${{ env.NODE }}-config_${{ env.GIT_TAG }}-${{ env.ARCH }}/var/lib/heimdall/config/config.toml env: ARCH: all - NODE: sentry + NODE: validator NETWORK: mainnet - name: Copying the postrm for ${{ env.NODE }} on ${{ env.NETWORK }} on ${{ env.ARCH }} run: cp -rp packaging/templates/package_scripts/postrm.profile packaging/deb/heimdall-${{ env.NETWORK }}-${{ env.NODE }}-config_${{ env.GIT_TAG }}-${{ env.ARCH }}/DEBIAN/postrm diff --git a/packaging/deb/heimdalld/DEBIAN/prerm b/packaging/deb/heimdalld/DEBIAN/prerm index 37d3ffd90..0946b7eb0 100755 --- a/packaging/deb/heimdalld/DEBIAN/prerm +++ b/packaging/deb/heimdalld/DEBIAN/prerm @@ -4,4 +4,4 @@ ################## # Stops existing for upgrade ################# -sudo systemctl stop heimdalld.service +#sudo systemctl stop heimdalld.service diff --git a/packaging/templates/package_scripts/postinst.validator b/packaging/templates/package_scripts/postinst.validator deleted file mode 100755 index 2515e30fe..000000000 --- a/packaging/templates/package_scripts/postinst.validator +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/bash -# This is a postinstallation script so the service can be configured and started when requested -# -sudo systemctl daemon-reload diff --git a/packaging/templates/package_scripts/postrm.profile b/packaging/templates/package_scripts/postrm.profile index 2dc7e21cc..ca4dca45f 100755 --- a/packaging/templates/package_scripts/postrm.profile +++ b/packaging/templates/package_scripts/postrm.profile @@ -3,6 +3,4 @@ ################### # Remove heimdall profile installation ################### -sudo rm /var/lib/heimdall/config/heimdall-config.toml -sudo rm /var/lib/heimdall/config/config.toml sudo systemctl daemon-reload \ No newline at end of file From 58bd98e40e3cb2fb9fcab5221641c51576bb8ce5 Mon Sep 17 00:00:00 2001 From: Raneet Debnath <35629432+Raneet10@users.noreply.github.com> Date: Thu, 16 Jan 2025 17:37:42 +0530 Subject: [PATCH 4/8] Merge v1.1.0-new-span-msg (#1226) * New propose span msg * helper: temporarily set antevortaHeight for testing * bor: fix nil author clause * bor: fix TestProposeSpanOne and TestGetNextSpanSeed * bor: avoid nil ptr deref * Add support for new msg propose span in cli and rest * Enable all hardforks at zero height * helper: temporarily add non-zero hf heights for testing * bor: fix handler * When proposing span query height from the node * Enable all forks on zero height * Add temporary commands to test malicious cases * Add temporary commands to test malicious cases * Let the bridge propose only the first two spans * Dont enable antevorta from zero height * Restrict new msg pre-hardfork * set non-zero height for antevorta * Add debug logging * Lower enable fork height * Clean up * Cleanup * Fix lint * Fix comments * fix: nil logger * Unify how we check for Jorvik height * Allow new and old span propose messages only at correct heights in PostHandle * Propose span only if proposedSpanID-2 is finished * Propose span only if proposedSpanID-2 is finished * rm: useless tests (#1223) Co-authored-by: marcello33 * bor,bridge,helper: rename antevorta to danelaw fork * bor,bridge: rebase and renaming to danelaw * Fix rollback command (#1217) * cmd: fix rollback * cmd: init rootmultistore from given db * cmd: disable rollback * align go deps * cmd: renable rollback * Rename Antevorta to Danelaw in error logs * helper: set danelaw height for amoy * Fixes for profiles, removing some unecessary postinst file, update to prerm, and postrm.profile --------- Co-authored-by: Angel Valkov Co-authored-by: marcello33 Co-authored-by: Daniel Jones --- Makefile | 2 +- bor/client/cli/query.go | 2 +- bor/client/cli/tx.go | 2 +- bor/client/rest/tx.go | 2 +- bor/handler.go | 8 +- bor/keeper.go | 4 +- bor/side_handler.go | 22 +- bridge/setu/processor/span.go | 21 +- cmd/heimdalld/service/rollback.go | 22 +- go.mod | 6 +- go.sum | 8 +- gov/genesis_test.go | 130 ------- gov/keeper_test.go | 356 ------------------ gov/querier_test.go | 302 --------------- gov/tally_test.go | 604 ------------------------------ gov/types/keys_test.go | 16 +- gov/types/msgs_test.go | 121 ------ helper/config.go | 16 +- 18 files changed, 86 insertions(+), 1558 deletions(-) delete mode 100644 gov/genesis_test.go delete mode 100644 gov/keeper_test.go delete mode 100644 gov/querier_test.go delete mode 100644 gov/tally_test.go delete mode 100644 gov/types/msgs_test.go diff --git a/Makefile b/Makefile index 150069c0e..db8d50c51 100644 --- a/Makefile +++ b/Makefile @@ -22,7 +22,7 @@ clean: tests: # go test -v ./... - go test -v ./app/ ./auth/ ./clerk/ ./sidechannel/ ./bank/ ./chainmanager/ ./topup/ ./checkpoint/ ./staking/ -cover -coverprofile=cover.out -parallel 1 + go test -v ./app/ ./auth/ ./clerk/ ./sidechannel/ ./bank/ ./chainmanager/ ./topup/ ./checkpoint/ ./staking/ ./gov/ -cover -coverprofile=cover.out -parallel 1 # make build build: clean diff --git a/bor/client/cli/query.go b/bor/client/cli/query.go index 62f9565e5..e1e148f50 100644 --- a/bor/client/cli/query.go +++ b/bor/client/cli/query.go @@ -355,7 +355,7 @@ func GetPreparedProposeSpan(cdc *codec.Codec) *cobra.Command { var result []byte - if nodeStatus.SyncInfo.LatestBlockHeight < helper.GetAntevortaHeight() { + if nodeStatus.SyncInfo.LatestBlockHeight < helper.GetDanelawHeight() { msg := types.NewMsgProposeSpan( spanID, proposer, diff --git a/bor/client/cli/tx.go b/bor/client/cli/tx.go index 0efdc9f65..f0c06581b 100644 --- a/bor/client/cli/tx.go +++ b/bor/client/cli/tx.go @@ -125,7 +125,7 @@ func PostSendProposeSpanTx(cdc *codec.Codec) *cobra.Command { } var msg sdk.Msg - if nodeStatus.SyncInfo.LatestBlockHeight < helper.GetAntevortaHeight() { + if nodeStatus.SyncInfo.LatestBlockHeight < helper.GetDanelawHeight() { msg = types.NewMsgProposeSpan( spanID, proposer, diff --git a/bor/client/rest/tx.go b/bor/client/rest/tx.go index 66a46739a..0f2e04c37 100644 --- a/bor/client/rest/tx.go +++ b/bor/client/rest/tx.go @@ -174,7 +174,7 @@ func postProposeSpanHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { } var msg sdk.Msg - if nodeStatus.SyncInfo.LatestBlockHeight < helper.GetAntevortaHeight() { + if nodeStatus.SyncInfo.LatestBlockHeight < helper.GetDanelawHeight() { // draft a propose span message msg = types.NewMsgProposeSpan( req.ID, diff --git a/bor/handler.go b/bor/handler.go index 43c9d8f98..f128929a8 100644 --- a/bor/handler.go +++ b/bor/handler.go @@ -31,8 +31,8 @@ func HandleMsgProposeSpan(ctx sdk.Context, msg sdk.Msg, k Keeper) sdk.Result { var proposeMsg types.MsgProposeSpanV2 switch msg := msg.(type) { case types.MsgProposeSpan: - if ctx.BlockHeight() >= helper.GetAntevortaHeight() { - err := errors.New("msg span is not allowed after Antevorta hardfork height") + if ctx.BlockHeight() >= helper.GetDanelawHeight() { + err := errors.New("msg span is not allowed after Danelaw hardfork height") k.Logger(ctx).Error(err.Error()) return sdk.ErrTxDecode(err.Error()).Result() } @@ -45,8 +45,8 @@ func HandleMsgProposeSpan(ctx sdk.Context, msg sdk.Msg, k Keeper) sdk.Result { Seed: msg.Seed, } case types.MsgProposeSpanV2: - if ctx.BlockHeight() < helper.GetAntevortaHeight() { - err := errors.New("msg span v2 is not allowed before Antevorta hardfork height") + if ctx.BlockHeight() < helper.GetDanelawHeight() { + err := errors.New("msg span v2 is not allowed before Danelaw hardfork height") k.Logger(ctx).Error(err.Error()) return sdk.ErrTxDecode(err.Error()).Result() } diff --git a/bor/keeper.go b/bor/keeper.go index 2fb0205d8..5ebf7e046 100644 --- a/bor/keeper.go +++ b/bor/keeper.go @@ -265,7 +265,7 @@ func (k *Keeper) FreezeSet(ctx sdk.Context, id uint64, startBlock uint64, endBlo // SelectNextProducers selects producers for next span func (k *Keeper) SelectNextProducers(ctx sdk.Context, seed common.Hash, prevVals []hmTypes.Validator) (vals []hmTypes.Validator, err error) { - if ctx.BlockHeader().Height < helper.GetJorvikHeight() { + if ctx.BlockHeight() < helper.GetJorvikHeight() { prevVals = nil } @@ -358,7 +358,7 @@ func (k *Keeper) GetNextSpanSeed(ctx sdk.Context, id uint64) (common.Hash, commo author *common.Address ) - if ctx.BlockHeader().Height < helper.GetJorvikHeight() { + if ctx.BlockHeight() < helper.GetJorvikHeight() { lastEthBlock := k.GetLastEthBlock(ctx) // increment last processed header block number newEthBlock := lastEthBlock.Add(lastEthBlock, big.NewInt(1)) diff --git a/bor/side_handler.go b/bor/side_handler.go index 16990dc96..d82e8415f 100644 --- a/bor/side_handler.go +++ b/bor/side_handler.go @@ -53,8 +53,8 @@ func SideHandleMsgSpan(ctx sdk.Context, k Keeper, msg sdk.Msg, contractCaller he var proposeMsg types.MsgProposeSpanV2 switch msg := msg.(type) { case types.MsgProposeSpan: - if ctx.BlockHeight() >= helper.GetAntevortaHeight() { - k.Logger(ctx).Error("Msg span is not allowed after Antevorta hardfork height") + if ctx.BlockHeight() >= helper.GetDanelawHeight() { + k.Logger(ctx).Error("Msg span is not allowed after Danelaw hardfork height") return hmCommon.ErrorSideTx(k.Codespace(), common.CodeInvalidMsg) } proposeMsg = types.MsgProposeSpanV2{ @@ -66,8 +66,8 @@ func SideHandleMsgSpan(ctx sdk.Context, k Keeper, msg sdk.Msg, contractCaller he Seed: msg.Seed, } case types.MsgProposeSpanV2: - if ctx.BlockHeight() < helper.GetAntevortaHeight() { - k.Logger(ctx).Error("Msg span v2 is not allowed before Antevorta hardfork height") + if ctx.BlockHeight() < helper.GetDanelawHeight() { + k.Logger(ctx).Error("Msg span v2 is not allowed before Danelaw hardfork height") return hmCommon.ErrorSideTx(k.Codespace(), common.CodeInvalidMsg) } proposeMsg = msg @@ -97,7 +97,7 @@ func SideHandleMsgSpan(ctx sdk.Context, k Keeper, msg sdk.Msg, contractCaller he return hmCommon.ErrorSideTx(k.Codespace(), common.CodeInvalidMsg) } - if ctx.BlockHeight() >= helper.GetAntevortaHeight() { + if ctx.BlockHeight() >= helper.GetDanelawHeight() { // check if span seed author matches or not. if !bytes.Equal(proposeMsg.SeedAuthor.Bytes(), seedAuthor.Bytes()) { k.Logger(ctx).Error( @@ -161,6 +161,10 @@ func PostHandleMsgEventSpan(ctx sdk.Context, k Keeper, msg sdk.Msg, sideTxResult var proposeMsg types.MsgProposeSpanV2 switch msg := msg.(type) { case types.MsgProposeSpan: + if ctx.BlockHeight() >= helper.GetDanelawHeight() { + k.Logger(ctx).Error("Msg span is not allowed after Danelaw hardfork height") + return common.ErrSideTxValidation(k.Codespace()).Result() + } proposeMsg = types.MsgProposeSpanV2{ ID: msg.ID, Proposer: msg.Proposer, @@ -170,6 +174,10 @@ func PostHandleMsgEventSpan(ctx sdk.Context, k Keeper, msg sdk.Msg, sideTxResult Seed: msg.Seed, } case types.MsgProposeSpanV2: + if ctx.BlockHeight() < helper.GetDanelawHeight() { + k.Logger(ctx).Error("Msg span v2 is not allowed before Danelaw hardfork height") + return common.ErrSideTxValidation(k.Codespace()).Result() + } proposeMsg = msg } @@ -188,7 +196,7 @@ func PostHandleMsgEventSpan(ctx sdk.Context, k Keeper, msg sdk.Msg, sideTxResult "seed", proposeMsg.Seed.String(), ) - if ctx.BlockHeader().Height >= helper.GetJorvikHeight() { + if ctx.BlockHeight() >= helper.GetJorvikHeight() { var seedSpanID uint64 if proposeMsg.ID < 2 { seedSpanID = proposeMsg.ID - 1 @@ -204,7 +212,7 @@ func PostHandleMsgEventSpan(ctx sdk.Context, k Keeper, msg sdk.Msg, sideTxResult var producer *ethCommon.Address - if ctx.BlockHeight() < helper.GetAntevortaHeight() { + if ctx.BlockHeight() < helper.GetDanelawHeight() { // store the seed producer _, producer, err = k.getBorBlockForSpanSeed(ctx, lastSpan, proposeMsg.ID) if err != nil { diff --git a/bridge/setu/processor/span.go b/bridge/setu/processor/span.go index 5a717862d..304ac87a2 100644 --- a/bridge/setu/processor/span.go +++ b/bridge/setu/processor/span.go @@ -81,6 +81,25 @@ func (sp *SpanProcessor) checkAndPropose() { return } + nodeStatus, err := helper.GetNodeStatus(sp.cliCtx) + if err != nil { + sp.Logger.Error("Error while fetching heimdall node status", "error", err) + return + } + + if nodeStatus.SyncInfo.LatestBlockHeight >= helper.GetDanelawHeight() { + latestBlock, err := sp.contractConnector.GetMaticChainBlock(nil) + if err != nil { + sp.Logger.Error("Error fetching current child block", "error", err) + return + } + + if latestBlock.Number.Uint64() < lastSpan.StartBlock { + sp.Logger.Debug("Current bor block is less than last span start block, skipping proposing span", "currentBlock", latestBlock.Number.Uint64(), "lastSpanStartBlock", lastSpan.StartBlock) + return + } + } + sp.Logger.Debug("Found last span", "lastSpan", lastSpan.ID, "startBlock", lastSpan.StartBlock, "endBlock", lastSpan.EndBlock) nextSpanMsg, err := sp.fetchNextSpanDetails(lastSpan.ID+1, lastSpan.EndBlock+1) @@ -122,7 +141,7 @@ func (sp *SpanProcessor) propose(lastSpan *types.Span, nextSpanMsg *types.Span) var txRes sdk.TxResponse - if nodeStatus.SyncInfo.LatestBlockHeight < helper.GetAntevortaHeight() { + if nodeStatus.SyncInfo.LatestBlockHeight < helper.GetDanelawHeight() { // broadcast to heimdall msg := borTypes.MsgProposeSpan{ ID: nextSpanMsg.ID, diff --git a/cmd/heimdalld/service/rollback.go b/cmd/heimdalld/service/rollback.go index c63bb7027..0f97279ed 100644 --- a/cmd/heimdalld/service/rollback.go +++ b/cmd/heimdalld/service/rollback.go @@ -7,6 +7,7 @@ import ( "github.com/cosmos/cosmos-sdk/server" "github.com/cosmos/cosmos-sdk/store/rootmulti" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/maticnetwork/heimdall/app" "github.com/maticnetwork/heimdall/helper" stakingcli "github.com/maticnetwork/heimdall/staking/client/cli" "github.com/spf13/cobra" @@ -15,6 +16,8 @@ import ( "github.com/tendermint/tendermint/libs/cli" ) +const flagForce = "force" + func rollbackCmd(ctx *server.Context) *cobra.Command { cmd := &cobra.Command{ Use: "rollback", @@ -27,8 +30,8 @@ The application also roll back to height n - 1. No blocks are removed, so upon restarting Tendermint the transactions in block n will be re-executed against the application. `, - Args: cobra.NoArgs, - RunE: func(_ *cobra.Command, _ []string) error { + RunE: func(_ *cobra.Command, args []string) error { + forceRollback := viper.GetBool(flagForce) config := ctx.Config config.SetRoot(viper.GetString(cli.HomeFlag)) @@ -37,19 +40,28 @@ application. return err } - height, hash, err := commands.RollbackState(config) + height, hash, err := commands.RollbackState(config, forceRollback) if err != nil { return fmt.Errorf("failed to rollback tendermint state: %w", err) } // rollback the multistore - cms := rootmulti.NewStore(db) - cms.RollbackToVersion(height) + hApp := app.NewHeimdallApp(logger, db) + cms := hApp.BaseApp.GetCommitMultiStore() + rs, ok := cms.(*rootmulti.Store) + if !ok { + panic("store not of type rootmultistore") + } + + if err := rs.RollbackToVersion(height); err != nil { + return err + } fmt.Printf("Rolled back state to height %d and hash %X", height, hash) return nil }, } + cmd.Flags().Bool(flagForce, false, "force rollback") cmd.Flags().String(cli.HomeFlag, helper.DefaultNodeHome, "Node's home directory") cmd.Flags().String(helper.FlagClientHome, helper.DefaultCLIHome, "Client's home directory") cmd.Flags().String(client.FlagChainID, "", "Genesis file chain-id, if left blank will be randomly created") diff --git a/go.mod b/go.mod index 99ca5af78..cf3915f15 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/maticnetwork/heimdall -go 1.22 +go 1.22.5 require ( github.com/RichardKnop/machinery v1.10.6 @@ -169,11 +169,11 @@ require ( gopkg.in/yaml.v3 v3.0.1 ) -replace github.com/tendermint/tendermint => github.com/maticnetwork/tendermint v0.33.2 +replace github.com/tendermint/tendermint => github.com/maticnetwork/tendermint v0.33.3 replace github.com/tendermint/tm-db => github.com/tendermint/tm-db v0.2.0 -replace github.com/cosmos/cosmos-sdk => github.com/maticnetwork/cosmos-sdk v0.38.4 +replace github.com/cosmos/cosmos-sdk => github.com/maticnetwork/cosmos-sdk v0.38.5-polygon replace github.com/ethereum/go-ethereum => github.com/maticnetwork/bor v1.4.1 diff --git a/go.sum b/go.sum index 17c18efa3..955728eca 100644 --- a/go.sum +++ b/go.sum @@ -2219,16 +2219,16 @@ github.com/mailgun/raymond/v2 v2.0.48/go.mod h1:lsgvL50kgt1ylcFJYZiULi5fjPBkkhNf github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/maticnetwork/bor v1.4.1 h1:IS6/ap7TgUYIEzM5uwq776NxOkx4rziyit32UZUPDyU= github.com/maticnetwork/bor v1.4.1/go.mod h1:DSIYFopCa1PqDOI6f3cTunTbSCL2VpBhGwAsTFiYMbo= -github.com/maticnetwork/cosmos-sdk v0.38.4 h1:PAfkMXzHDHJoAf4bXQL4UWgwbu/U3yYuXoXxPhXdpBw= -github.com/maticnetwork/cosmos-sdk v0.38.4/go.mod h1:NbuVdUoqlRF6RrFJp27hpbqSoRB8cJJfUxCzUJWtaLA= +github.com/maticnetwork/cosmos-sdk v0.38.5-polygon h1:2KpGeMOYjhBlVlsa08LtTAhAu02haTA/1CuCCCYkEdA= +github.com/maticnetwork/cosmos-sdk v0.38.5-polygon/go.mod h1:pQ7A1CnHMIQko4QTD6EVj+Qp3EniTsR5C6utLPStDHI= github.com/maticnetwork/crand v1.0.2 h1:Af0tAivC8zrxXDpGWNWVT/0s1fOz8w0eRbahZgURS8I= github.com/maticnetwork/crand v1.0.2/go.mod h1:/NRNL3bj2eYdqpWmoIP5puxndTpi0XRxpj5ZKxfHjyg= github.com/maticnetwork/heimdall v1.0.7/go.mod h1:+ANI5+VV28ahwfdl7oMzrcNwaTEs1Fn6z39BqBGcvaA= github.com/maticnetwork/polyproto v0.0.3-0.20230216113155-340ea926ca53/go.mod h1:e1mU2EXSwEpn5jM7GfNwu3AupsV6WAGoPFFfswXOF0o= github.com/maticnetwork/polyproto v0.0.4 h1:qQ/qwcO6UNGS4mJlzlLJn1AUMfJK9Rqmf1v+KJgnPsk= github.com/maticnetwork/polyproto v0.0.4/go.mod h1:e1mU2EXSwEpn5jM7GfNwu3AupsV6WAGoPFFfswXOF0o= -github.com/maticnetwork/tendermint v0.33.2 h1:R9M7jgAmON8K/LbzMvtWPDhtPkNcqzkUUHp1ict/h3s= -github.com/maticnetwork/tendermint v0.33.2/go.mod h1:D2fcnxGk6bje+LoPwImuKSSYLiK7/G06IynGNDSEcJk= +github.com/maticnetwork/tendermint v0.33.3 h1:s1/Ubxh7Axv2bClr+aFMWNn5qzbRKEHEw/uEVxLTc0I= +github.com/maticnetwork/tendermint v0.33.3/go.mod h1:D2fcnxGk6bje+LoPwImuKSSYLiK7/G06IynGNDSEcJk= github.com/matryer/try v0.0.0-20161228173917-9ac251b645a2/go.mod h1:0KeJpeMD6o+O4hW7qJOT7vyQPKrWmj26uf5wMc/IiIs= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= diff --git a/gov/genesis_test.go b/gov/genesis_test.go deleted file mode 100644 index 62fa3a9e4..000000000 --- a/gov/genesis_test.go +++ /dev/null @@ -1,130 +0,0 @@ -package gov - -import ( - "testing" - - "github.com/stretchr/testify/require" - abci "github.com/tendermint/tendermint/abci/types" -) - -func TestEqualProposalID(t *testing.T) { - state1 := GenesisState{} - state2 := GenesisState{} - require.Equal(t, state1, state2) - - // Proposals - state1.StartingProposalID = 1 - require.NotEqual(t, state1, state2) - require.False(t, state1.Equal(state2)) - - state2.StartingProposalID = 1 - require.Equal(t, state1, state2) - require.True(t, state1.Equal(state2)) -} - -func TestEqualProposals(t *testing.T) { - // Generate mock app and keepers - input := getMockApp(t, 2, GenesisState{}, nil) - SortAddresses(input.addrs) - - header := abci.Header{Height: input.mApp.LastBlockHeight() + 1} - input.mApp.BeginBlock(abci.RequestBeginBlock{Header: header}) - - ctx := input.mApp.BaseApp.NewContext(false, abci.Header{}) - - // Submit two proposals - proposal := testProposal() - proposal1, err := input.keeper.SubmitProposal(ctx, proposal) - require.NoError(t, err) - proposal2, err := input.keeper.SubmitProposal(ctx, proposal) - require.NoError(t, err) - - // They are similar but their IDs should be different - require.NotEqual(t, proposal1, proposal2) - require.False(t, ProposalEqual(proposal1, proposal2)) - - // Now create two genesis blocks - state1 := GenesisState{Proposals: []Proposal{proposal1}} - state2 := GenesisState{Proposals: []Proposal{proposal2}} - require.NotEqual(t, state1, state2) - require.False(t, state1.Equal(state2)) - - // Now make proposals identical by setting both IDs to 55 - proposal1.ProposalID = 55 - proposal2.ProposalID = 55 - require.Equal(t, proposal1, proposal1) - require.True(t, ProposalEqual(proposal1, proposal2)) - - // Reassign proposals into state - state1.Proposals[0] = proposal1 - state2.Proposals[0] = proposal2 - - // State should be identical now.. - require.Equal(t, state1, state2) - require.True(t, state1.Equal(state2)) -} - -func TestImportExportQueues(t *testing.T) { - // Generate mock app and keepers - input := getMockApp(t, 2, GenesisState{}, nil) - SortAddresses(input.addrs) - - header := abci.Header{Height: input.mApp.LastBlockHeight() + 1} - input.mApp.BeginBlock(abci.RequestBeginBlock{Header: header}) - - ctx := input.mApp.BaseApp.NewContext(false, abci.Header{}) - - // Create two proposals, put the second into the voting period - proposal := testProposal() - proposal1, err := input.keeper.SubmitProposal(ctx, proposal) - require.NoError(t, err) - proposalID1 := proposal1.ProposalID - - proposal2, err := input.keeper.SubmitProposal(ctx, proposal) - require.NoError(t, err) - proposalID2 := proposal2.ProposalID - - err, votingStarted := input.keeper.AddDeposit(ctx, proposalID2, input.addrs[0], input.keeper.GetDepositParams(ctx).MinDeposit) - require.NoError(t, err) - require.True(t, votingStarted) - - proposal1, ok := input.keeper.GetProposal(ctx, proposalID1) - require.True(t, ok) - proposal2, ok = input.keeper.GetProposal(ctx, proposalID2) - require.True(t, ok) - require.True(t, proposal1.Status == StatusDepositPeriod) - require.True(t, proposal2.Status == StatusVotingPeriod) - - genAccs := input.mApp.AccountKeeper.GetAllAccounts(ctx) - - // Export the state and import it into a new Mock App - genState := ExportGenesis(ctx, input.keeper) - input2 := getMockApp(t, 2, genState, genAccs) - - header = abci.Header{Height: input.mApp.LastBlockHeight() + 1} - input2.mApp.BeginBlock(abci.RequestBeginBlock{Header: header}) - - ctx2 := input2.mApp.BaseApp.NewContext(false, abci.Header{}) - - // Jump the time forward past the DepositPeriod and VotingPeriod - ctx2 = ctx2.WithBlockTime(ctx2.BlockHeader().Time.Add(input2.keeper.GetDepositParams(ctx2).MaxDepositPeriod).Add(input2.keeper.GetVotingParams(ctx2).VotingPeriod)) - - // Make sure that they are still in the DepositPeriod and VotingPeriod respectively - proposal1, ok = input2.keeper.GetProposal(ctx2, proposalID1) - require.True(t, ok) - proposal2, ok = input2.keeper.GetProposal(ctx2, proposalID2) - require.True(t, ok) - require.True(t, proposal1.Status == StatusDepositPeriod) - require.True(t, proposal2.Status == StatusVotingPeriod) - - require.Equal(t, input2.keeper.GetDepositParams(ctx2).MinDeposit, input2.keeper.GetGovernanceAccount(ctx2).GetCoins()) - - // Run the endblocker. Check to make sure that proposal1 is removed from state, and proposal2 is finished VotingPeriod. - EndBlocker(ctx2, input2.keeper) - - proposal1, ok = input2.keeper.GetProposal(ctx2, proposalID1) - require.False(t, ok) - proposal2, ok = input2.keeper.GetProposal(ctx2, proposalID2) - require.True(t, ok) - require.True(t, proposal2.Status == StatusRejected) -} diff --git a/gov/keeper_test.go b/gov/keeper_test.go deleted file mode 100644 index 8689bf55d..000000000 --- a/gov/keeper_test.go +++ /dev/null @@ -1,356 +0,0 @@ -package gov - -import ( - "strings" - "testing" - "time" - - "github.com/stretchr/testify/require" - - abci "github.com/tendermint/tendermint/abci/types" - - "github.com/cosmos/cosmos-sdk/codec" - sdk "github.com/cosmos/cosmos-sdk/types" -) - -func TestGetSetProposal(t *testing.T) { - input := getMockApp(t, 0, GenesisState{}, nil) - - header := abci.Header{Height: input.mApp.LastBlockHeight() + 1} - input.mApp.BeginBlock(abci.RequestBeginBlock{Header: header}) - - ctx := input.mApp.BaseApp.NewContext(false, abci.Header{}) - - tp := testProposal() - proposal, err := input.keeper.SubmitProposal(ctx, tp) - require.NoError(t, err) - proposalID := proposal.ProposalID - input.keeper.SetProposal(ctx, proposal) - - gotProposal, ok := input.keeper.GetProposal(ctx, proposalID) - require.True(t, ok) - require.True(t, ProposalEqual(proposal, gotProposal)) -} - -func TestIncrementProposalNumber(t *testing.T) { - input := getMockApp(t, 0, GenesisState{}, nil) - - header := abci.Header{Height: input.mApp.LastBlockHeight() + 1} - input.mApp.BeginBlock(abci.RequestBeginBlock{Header: header}) - - ctx := input.mApp.BaseApp.NewContext(false, abci.Header{}) - - tp := testProposal() - input.keeper.SubmitProposal(ctx, tp) - input.keeper.SubmitProposal(ctx, tp) - input.keeper.SubmitProposal(ctx, tp) - input.keeper.SubmitProposal(ctx, tp) - input.keeper.SubmitProposal(ctx, tp) - proposal6, err := input.keeper.SubmitProposal(ctx, tp) - require.NoError(t, err) - - require.Equal(t, uint64(6), proposal6.ProposalID) -} - -func TestActivateVotingPeriod(t *testing.T) { - input := getMockApp(t, 0, GenesisState{}, nil) - - header := abci.Header{Height: input.mApp.LastBlockHeight() + 1} - input.mApp.BeginBlock(abci.RequestBeginBlock{Header: header}) - - ctx := input.mApp.BaseApp.NewContext(false, abci.Header{}) - - tp := testProposal() - proposal, err := input.keeper.SubmitProposal(ctx, tp) - require.NoError(t, err) - - require.True(t, proposal.VotingStartTime.Equal(time.Time{})) - - input.keeper.activateVotingPeriod(ctx, proposal) - - require.True(t, proposal.VotingStartTime.Equal(ctx.BlockHeader().Time)) - - proposal, ok := input.keeper.GetProposal(ctx, proposal.ProposalID) - require.True(t, ok) - - activeIterator := input.keeper.ActiveProposalQueueIterator(ctx, proposal.VotingEndTime) - require.True(t, activeIterator.Valid()) - var proposalID uint64 - input.keeper.cdc.UnmarshalBinaryLengthPrefixed(activeIterator.Value(), &proposalID) - require.Equal(t, proposalID, proposal.ProposalID) - activeIterator.Close() -} - -func TestDeposits(t *testing.T) { - input := getMockApp(t, 2, GenesisState{}, nil) - - SortAddresses(input.addrs) - - header := abci.Header{Height: input.mApp.LastBlockHeight() + 1} - input.mApp.BeginBlock(abci.RequestBeginBlock{Header: header}) - - ctx := input.mApp.BaseApp.NewContext(false, abci.Header{}) - - tp := testProposal() - proposal, err := input.keeper.SubmitProposal(ctx, tp) - require.NoError(t, err) - proposalID := proposal.ProposalID - - fourStake := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.TokensFromConsensusPower(4))) - fiveStake := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.TokensFromConsensusPower(5))) - - addr0Initial := input.mApp.AccountKeeper.GetAccount(ctx, input.addrs[0]).GetCoins() - addr1Initial := input.mApp.AccountKeeper.GetAccount(ctx, input.addrs[1]).GetCoins() - - expTokens := sdk.TokensFromConsensusPower(42) - require.Equal(t, sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, expTokens)), addr0Initial) - require.True(t, proposal.TotalDeposit.IsEqual(sdk.NewCoins())) - - // Check no deposits at beginning - deposit, found := input.keeper.GetDeposit(ctx, proposalID, input.addrs[1]) - require.False(t, found) - proposal, ok := input.keeper.GetProposal(ctx, proposalID) - require.True(t, ok) - require.True(t, proposal.VotingStartTime.Equal(time.Time{})) - - // Check first deposit - err, votingStarted := input.keeper.AddDeposit(ctx, proposalID, input.addrs[0], fourStake) - require.Nil(t, err) - require.False(t, votingStarted) - deposit, found = input.keeper.GetDeposit(ctx, proposalID, input.addrs[0]) - require.True(t, found) - require.Equal(t, fourStake, deposit.Amount) - require.Equal(t, input.addrs[0], deposit.Depositor) - proposal, ok = input.keeper.GetProposal(ctx, proposalID) - require.True(t, ok) - require.Equal(t, fourStake, proposal.TotalDeposit) - require.Equal(t, addr0Initial.Sub(fourStake), input.mApp.AccountKeeper.GetAccount(ctx, input.addrs[0]).GetCoins()) - - // Check a second deposit from same address - err, votingStarted = input.keeper.AddDeposit(ctx, proposalID, input.addrs[0], fiveStake) - require.Nil(t, err) - require.False(t, votingStarted) - deposit, found = input.keeper.GetDeposit(ctx, proposalID, input.addrs[0]) - require.True(t, found) - require.Equal(t, fourStake.Add(fiveStake), deposit.Amount) - require.Equal(t, input.addrs[0], deposit.Depositor) - proposal, ok = input.keeper.GetProposal(ctx, proposalID) - require.True(t, ok) - require.Equal(t, fourStake.Add(fiveStake), proposal.TotalDeposit) - require.Equal(t, addr0Initial.Sub(fourStake).Sub(fiveStake), input.mApp.AccountKeeper.GetAccount(ctx, input.addrs[0]).GetCoins()) - - // Check third deposit from a new address - err, votingStarted = input.keeper.AddDeposit(ctx, proposalID, input.addrs[1], fourStake) - require.Nil(t, err) - require.True(t, votingStarted) - deposit, found = input.keeper.GetDeposit(ctx, proposalID, input.addrs[1]) - require.True(t, found) - require.Equal(t, input.addrs[1], deposit.Depositor) - require.Equal(t, fourStake, deposit.Amount) - proposal, ok = input.keeper.GetProposal(ctx, proposalID) - require.True(t, ok) - require.Equal(t, fourStake.Add(fiveStake).Add(fourStake), proposal.TotalDeposit) - require.Equal(t, addr1Initial.Sub(fourStake), input.mApp.AccountKeeper.GetAccount(ctx, input.addrs[1]).GetCoins()) - - // Check that proposal moved to voting period - proposal, ok = input.keeper.GetProposal(ctx, proposalID) - require.True(t, ok) - require.True(t, proposal.VotingStartTime.Equal(ctx.BlockHeader().Time)) - - // Test deposit iterator - depositsIterator := input.keeper.GetDepositsIterator(ctx, proposalID) - require.True(t, depositsIterator.Valid()) - input.keeper.cdc.MustUnmarshalBinaryLengthPrefixed(depositsIterator.Value(), &deposit) - require.Equal(t, input.addrs[0], deposit.Depositor) - require.Equal(t, fourStake.Add(fiveStake), deposit.Amount) - depositsIterator.Next() - input.keeper.cdc.MustUnmarshalBinaryLengthPrefixed(depositsIterator.Value(), &deposit) - require.Equal(t, input.addrs[1], deposit.Depositor) - require.Equal(t, fourStake, deposit.Amount) - depositsIterator.Next() - require.False(t, depositsIterator.Valid()) - depositsIterator.Close() - - // Test Refund Deposits - deposit, found = input.keeper.GetDeposit(ctx, proposalID, input.addrs[1]) - require.True(t, found) - require.Equal(t, fourStake, deposit.Amount) - input.keeper.RefundDeposits(ctx, proposalID) - deposit, found = input.keeper.GetDeposit(ctx, proposalID, input.addrs[1]) - require.False(t, found) - require.Equal(t, addr0Initial, input.mApp.AccountKeeper.GetAccount(ctx, input.addrs[0]).GetCoins()) - require.Equal(t, addr1Initial, input.mApp.AccountKeeper.GetAccount(ctx, input.addrs[1]).GetCoins()) - -} - -func TestVotes(t *testing.T) { - input := getMockApp(t, 2, GenesisState{}, nil) - SortAddresses(input.addrs) - - header := abci.Header{Height: input.mApp.LastBlockHeight() + 1} - input.mApp.BeginBlock(abci.RequestBeginBlock{Header: header}) - - ctx := input.mApp.BaseApp.NewContext(false, abci.Header{}) - - tp := testProposal() - proposal, err := input.keeper.SubmitProposal(ctx, tp) - require.NoError(t, err) - proposalID := proposal.ProposalID - - proposal.Status = StatusVotingPeriod - input.keeper.SetProposal(ctx, proposal) - - // Test first vote - input.keeper.AddVote(ctx, proposalID, input.addrs[0], OptionAbstain) - vote, found := input.keeper.GetVote(ctx, proposalID, input.addrs[0]) - require.True(t, found) - require.Equal(t, input.addrs[0], vote.Voter) - require.Equal(t, proposalID, vote.ProposalID) - require.Equal(t, OptionAbstain, vote.Option) - - // Test change of vote - input.keeper.AddVote(ctx, proposalID, input.addrs[0], OptionYes) - vote, found = input.keeper.GetVote(ctx, proposalID, input.addrs[0]) - require.True(t, found) - require.Equal(t, input.addrs[0], vote.Voter) - require.Equal(t, proposalID, vote.ProposalID) - require.Equal(t, OptionYes, vote.Option) - - // Test second vote - input.keeper.AddVote(ctx, proposalID, input.addrs[1], OptionNoWithVeto) - vote, found = input.keeper.GetVote(ctx, proposalID, input.addrs[1]) - require.True(t, found) - require.Equal(t, input.addrs[1], vote.Voter) - require.Equal(t, proposalID, vote.ProposalID) - require.Equal(t, OptionNoWithVeto, vote.Option) - - // Test vote iterator - votesIterator := input.keeper.GetVotesIterator(ctx, proposalID) - require.True(t, votesIterator.Valid()) - input.keeper.cdc.MustUnmarshalBinaryLengthPrefixed(votesIterator.Value(), &vote) - require.True(t, votesIterator.Valid()) - require.Equal(t, input.addrs[0], vote.Voter) - require.Equal(t, proposalID, vote.ProposalID) - require.Equal(t, OptionYes, vote.Option) - votesIterator.Next() - require.True(t, votesIterator.Valid()) - input.keeper.cdc.MustUnmarshalBinaryLengthPrefixed(votesIterator.Value(), &vote) - require.True(t, votesIterator.Valid()) - require.Equal(t, input.addrs[1], vote.Voter) - require.Equal(t, proposalID, vote.ProposalID) - require.Equal(t, OptionNoWithVeto, vote.Option) - votesIterator.Next() - require.False(t, votesIterator.Valid()) - votesIterator.Close() -} - -func TestProposalQueues(t *testing.T) { - input := getMockApp(t, 0, GenesisState{}, nil) - - header := abci.Header{Height: input.mApp.LastBlockHeight() + 1} - input.mApp.BeginBlock(abci.RequestBeginBlock{Header: header}) - - ctx := input.mApp.BaseApp.NewContext(false, abci.Header{}) - input.mApp.InitChainer(ctx, abci.RequestInitChain{}) - - // create test proposals - tp := testProposal() - proposal, err := input.keeper.SubmitProposal(ctx, tp) - require.NoError(t, err) - - inactiveIterator := input.keeper.InactiveProposalQueueIterator(ctx, proposal.DepositEndTime) - require.True(t, inactiveIterator.Valid()) - var proposalID uint64 - input.keeper.cdc.UnmarshalBinaryLengthPrefixed(inactiveIterator.Value(), &proposalID) - require.Equal(t, proposalID, proposal.ProposalID) - inactiveIterator.Close() - - input.keeper.activateVotingPeriod(ctx, proposal) - - proposal, ok := input.keeper.GetProposal(ctx, proposal.ProposalID) - require.True(t, ok) - - activeIterator := input.keeper.ActiveProposalQueueIterator(ctx, proposal.VotingEndTime) - require.True(t, activeIterator.Valid()) - input.keeper.cdc.UnmarshalBinaryLengthPrefixed(activeIterator.Value(), &proposalID) - require.Equal(t, proposalID, proposal.ProposalID) - activeIterator.Close() -} - -type validProposal struct{} - -func (validProposal) GetTitle() string { return "title" } -func (validProposal) GetDescription() string { return "description" } -func (validProposal) ProposalRoute() string { return RouterKey } -func (validProposal) ProposalType() string { return ProposalTypeText } -func (validProposal) String() string { return "" } -func (validProposal) ValidateBasic() sdk.Error { return nil } - -type invalidProposalTitle1 struct{ validProposal } - -func (invalidProposalTitle1) GetTitle() string { return "" } - -type invalidProposalTitle2 struct{ validProposal } - -func (invalidProposalTitle2) GetTitle() string { return strings.Repeat("1234567890", 100) } - -type invalidProposalDesc1 struct{ validProposal } - -func (invalidProposalDesc1) GetDescription() string { return "" } - -type invalidProposalDesc2 struct{ validProposal } - -func (invalidProposalDesc2) GetDescription() string { return strings.Repeat("1234567890", 1000) } - -type invalidProposalRoute struct{ validProposal } - -func (invalidProposalRoute) ProposalRoute() string { return "nonexistingroute" } - -type invalidProposalValidation struct{ validProposal } - -func (invalidProposalValidation) ValidateBasic() sdk.Error { - return sdk.NewError(sdk.CodespaceUndefined, sdk.CodeInternal, "") -} - -func registerTestCodec(cdc *codec.Codec) { - cdc.RegisterConcrete(validProposal{}, "test/validproposal", nil) - cdc.RegisterConcrete(invalidProposalTitle1{}, "test/invalidproposalt1", nil) - cdc.RegisterConcrete(invalidProposalTitle2{}, "test/invalidproposalt2", nil) - cdc.RegisterConcrete(invalidProposalDesc1{}, "test/invalidproposald1", nil) - cdc.RegisterConcrete(invalidProposalDesc2{}, "test/invalidproposald2", nil) - cdc.RegisterConcrete(invalidProposalRoute{}, "test/invalidproposalr", nil) - cdc.RegisterConcrete(invalidProposalValidation{}, "test/invalidproposalv", nil) -} - -func TestSubmitProposal(t *testing.T) { - input := getMockApp(t, 0, GenesisState{}, nil) - - registerTestCodec(input.keeper.cdc) - - header := abci.Header{Height: input.mApp.LastBlockHeight() + 1} - input.mApp.BeginBlock(abci.RequestBeginBlock{Header: header}) - - ctx := input.mApp.BaseApp.NewContext(false, abci.Header{}) - input.mApp.InitChainer(ctx, abci.RequestInitChain{}) - - testCases := []struct { - content Content - expectedErr sdk.Error - }{ - {validProposal{}, nil}, - // Keeper does not check the validity of title and description, no error - {invalidProposalTitle1{}, nil}, - {invalidProposalTitle2{}, nil}, - {invalidProposalDesc1{}, nil}, - {invalidProposalDesc2{}, nil}, - // error only when invalid route - {invalidProposalRoute{}, ErrNoProposalHandlerExists(DefaultCodespace, invalidProposalRoute{})}, - // Keeper does not call ValidateBasic, msg.ValidateBasic does - {invalidProposalValidation{}, nil}, - } - - for _, tc := range testCases { - _, err := input.keeper.SubmitProposal(ctx, tc.content) - require.Equal(t, tc.expectedErr, err, "unexpected type of error: %s", err) - } -} diff --git a/gov/querier_test.go b/gov/querier_test.go deleted file mode 100644 index 33772e781..000000000 --- a/gov/querier_test.go +++ /dev/null @@ -1,302 +0,0 @@ -package gov - -import ( - "strings" - "testing" - - "github.com/stretchr/testify/require" - abci "github.com/tendermint/tendermint/abci/types" - - "github.com/cosmos/cosmos-sdk/codec" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/maticnetwork/heimdall/gov/types" -) - -const custom = "custom" - -func getQueriedParams(t *testing.T, ctx sdk.Context, cdc *codec.Codec, querier sdk.Querier) (DepositParams, VotingParams, TallyParams) { - query := abci.RequestQuery{ - Path: strings.Join([]string{custom, QuerierRoute, QueryParams, ParamDeposit}, "/"), - Data: []byte{}, - } - - bz, err := querier(ctx, []string{QueryParams, ParamDeposit}, query) - require.Nil(t, err) - require.NotNil(t, bz) - - var depositParams DepositParams - err2 := cdc.UnmarshalJSON(bz, &depositParams) - require.Nil(t, err2) - - query = abci.RequestQuery{ - Path: strings.Join([]string{custom, QuerierRoute, QueryParams, ParamVoting}, "/"), - Data: []byte{}, - } - - bz, err = querier(ctx, []string{QueryParams, ParamVoting}, query) - require.Nil(t, err) - require.NotNil(t, bz) - - var votingParams VotingParams - err2 = cdc.UnmarshalJSON(bz, &votingParams) - require.Nil(t, err2) - - query = abci.RequestQuery{ - Path: strings.Join([]string{custom, QuerierRoute, QueryParams, ParamTallying}, "/"), - Data: []byte{}, - } - - bz, err = querier(ctx, []string{QueryParams, ParamTallying}, query) - require.Nil(t, err) - require.NotNil(t, bz) - - var tallyParams TallyParams - err2 = cdc.UnmarshalJSON(bz, &tallyParams) - require.Nil(t, err2) - - return depositParams, votingParams, tallyParams -} - -func getQueriedProposal(t *testing.T, ctx sdk.Context, cdc *codec.Codec, querier sdk.Querier, proposalID uint64) Proposal { - query := abci.RequestQuery{ - Path: strings.Join([]string{custom, QuerierRoute, QueryProposal}, "/"), - Data: cdc.MustMarshalJSON(NewQueryProposalParams(proposalID)), - } - - bz, err := querier(ctx, []string{QueryProposal}, query) - require.Nil(t, err) - require.NotNil(t, bz) - - var proposal Proposal - err2 := cdc.UnmarshalJSON(bz, proposal) - require.Nil(t, err2) - return proposal -} - -func getQueriedProposals(t *testing.T, ctx sdk.Context, cdc *codec.Codec, querier sdk.Querier, depositor, voter sdk.AccAddress, status ProposalStatus, limit uint64) []Proposal { - query := abci.RequestQuery{ - Path: strings.Join([]string{custom, QuerierRoute, QueryProposals}, "/"), - Data: cdc.MustMarshalJSON(NewQueryProposalsParams(status, limit, voter, depositor)), - } - - bz, err := querier(ctx, []string{QueryProposals}, query) - require.Nil(t, err) - require.NotNil(t, bz) - - var proposals Proposals - err2 := cdc.UnmarshalJSON(bz, &proposals) - require.Nil(t, err2) - return proposals -} - -func getQueriedDeposit(t *testing.T, ctx sdk.Context, cdc *codec.Codec, querier sdk.Querier, proposalID uint64, depositor sdk.AccAddress) Deposit { - query := abci.RequestQuery{ - Path: strings.Join([]string{custom, QuerierRoute, QueryDeposit}, "/"), - Data: cdc.MustMarshalJSON(NewQueryDepositParams(proposalID, depositor)), - } - - bz, err := querier(ctx, []string{QueryDeposit}, query) - require.Nil(t, err) - require.NotNil(t, bz) - - var deposit Deposit - err2 := cdc.UnmarshalJSON(bz, &deposit) - require.Nil(t, err2) - return deposit -} - -func getQueriedDeposits(t *testing.T, ctx sdk.Context, cdc *codec.Codec, querier sdk.Querier, proposalID uint64) []Deposit { - query := abci.RequestQuery{ - Path: strings.Join([]string{custom, QuerierRoute, QueryDeposits}, "/"), - Data: cdc.MustMarshalJSON(NewQueryProposalParams(proposalID)), - } - - bz, err := querier(ctx, []string{QueryDeposits}, query) - require.Nil(t, err) - require.NotNil(t, bz) - - var deposits []Deposit - err2 := cdc.UnmarshalJSON(bz, &deposits) - require.Nil(t, err2) - return deposits -} - -func getQueriedVote(t *testing.T, ctx sdk.Context, cdc *codec.Codec, querier sdk.Querier, proposalID uint64, voter sdk.AccAddress) Vote { - query := abci.RequestQuery{ - Path: strings.Join([]string{custom, QuerierRoute, QueryVote}, "/"), - Data: cdc.MustMarshalJSON(NewQueryVoteParams(proposalID, voter)), - } - - bz, err := querier(ctx, []string{QueryVote}, query) - require.Nil(t, err) - require.NotNil(t, bz) - - var vote Vote - err2 := cdc.UnmarshalJSON(bz, &vote) - require.Nil(t, err2) - return vote -} - -func getQueriedVotes(t *testing.T, ctx sdk.Context, cdc *codec.Codec, querier sdk.Querier, proposalID uint64) []Vote { - query := abci.RequestQuery{ - Path: strings.Join([]string{custom, QuerierRoute, QueryVote}, "/"), - Data: cdc.MustMarshalJSON(NewQueryProposalParams(proposalID)), - } - - bz, err := querier(ctx, []string{QueryVotes}, query) - require.Nil(t, err) - require.NotNil(t, bz) - - var votes []Vote - err2 := cdc.UnmarshalJSON(bz, &votes) - require.Nil(t, err2) - return votes -} - -func getQueriedTally(t *testing.T, ctx sdk.Context, cdc *codec.Codec, querier sdk.Querier, proposalID uint64) TallyResult { - query := abci.RequestQuery{ - Path: strings.Join([]string{custom, QuerierRoute, QueryTally}, "/"), - Data: cdc.MustMarshalJSON(NewQueryProposalParams(proposalID)), - } - - bz, err := querier(ctx, []string{QueryTally}, query) - require.Nil(t, err) - require.NotNil(t, bz) - - var tally TallyResult - err2 := cdc.UnmarshalJSON(bz, &tally) - require.Nil(t, err2) - return tally -} - -func TestQueryParams(t *testing.T) { - cdc := codec.New() - input := getMockApp(t, 1000, GenesisState{}, nil) - querier := NewQuerier(input.keeper) - - header := abci.Header{Height: input.mApp.LastBlockHeight() + 1} - input.mApp.BeginBlock(abci.RequestBeginBlock{Header: header}) - - ctx := input.mApp.NewContext(false, abci.Header{}) - - getQueriedParams(t, ctx, cdc, querier) -} - -func TestQueries(t *testing.T) { - cdc := codec.New() - input := getMockApp(t, 1000, GenesisState{}, nil) - querier := NewQuerier(input.keeper) - handler := NewHandler(input.keeper) - - types.RegisterCodec(cdc) - - header := abci.Header{Height: input.mApp.LastBlockHeight() + 1} - input.mApp.BeginBlock(abci.RequestBeginBlock{Header: header}) - - ctx := input.mApp.NewContext(false, abci.Header{}) - - depositParams, _, _ := getQueriedParams(t, ctx, cdc, querier) - - // input.addrs[0] proposes (and deposits) proposals #1 and #2 - res := handler(ctx, NewMsgSubmitProposal(testProposal(), sdk.Coins{sdk.NewInt64Coin(sdk.DefaultBondDenom, 1)}, input.addrs[0])) - var proposalID1 uint64 - require.True(t, res.IsOK()) - cdc.MustUnmarshalBinaryLengthPrefixed(res.Data, &proposalID1) - - res = handler(ctx, NewMsgSubmitProposal(testProposal(), sdk.Coins{sdk.NewInt64Coin(sdk.DefaultBondDenom, 10000000)}, input.addrs[0])) - var proposalID2 uint64 - require.True(t, res.IsOK()) - cdc.MustUnmarshalBinaryLengthPrefixed(res.Data, &proposalID2) - - // input.addrs[1] proposes (and deposits) proposals #3 - res = handler(ctx, NewMsgSubmitProposal(testProposal(), sdk.Coins{sdk.NewInt64Coin(sdk.DefaultBondDenom, 1)}, input.addrs[1])) - var proposalID3 uint64 - require.True(t, res.IsOK()) - cdc.MustUnmarshalBinaryLengthPrefixed(res.Data, &proposalID3) - - // input.addrs[1] deposits on proposals #2 & #3 - res = handler(ctx, NewMsgDeposit(input.addrs[1], proposalID2, depositParams.MinDeposit)) - res = handler(ctx, NewMsgDeposit(input.addrs[1], proposalID3, depositParams.MinDeposit)) - - // check deposits on proposal1 match individual deposits - deposits := getQueriedDeposits(t, ctx, cdc, querier, proposalID1) - require.Len(t, deposits, 1) - deposit := getQueriedDeposit(t, ctx, cdc, querier, proposalID1, input.addrs[0]) - require.Equal(t, deposit, deposits[0]) - - // check deposits on proposal2 match individual deposits - deposits = getQueriedDeposits(t, ctx, cdc, querier, proposalID2) - require.Len(t, deposits, 2) - deposit = getQueriedDeposit(t, ctx, cdc, querier, proposalID2, input.addrs[0]) - require.True(t, deposit.Equals(deposits[0])) - deposit = getQueriedDeposit(t, ctx, cdc, querier, proposalID2, input.addrs[1]) - require.True(t, deposit.Equals(deposits[1])) - - // check deposits on proposal3 match individual deposits - deposits = getQueriedDeposits(t, ctx, cdc, querier, proposalID3) - require.Len(t, deposits, 1) - deposit = getQueriedDeposit(t, ctx, cdc, querier, proposalID3, input.addrs[1]) - require.Equal(t, deposit, deposits[0]) - - // Only proposal #1 should be in Deposit Period - proposals := getQueriedProposals(t, ctx, cdc, querier, nil, nil, StatusDepositPeriod, 0) - require.Len(t, proposals, 1) - require.Equal(t, proposalID1, proposals[0].ProposalID) - - // Only proposals #2 and #3 should be in Voting Period - proposals = getQueriedProposals(t, ctx, cdc, querier, nil, nil, StatusVotingPeriod, 0) - require.Len(t, proposals, 2) - require.Equal(t, proposalID2, proposals[0].ProposalID) - require.Equal(t, proposalID3, proposals[1].ProposalID) - - // Addrs[0] votes on proposals #2 & #3 - require.True(t, handler(ctx, NewMsgVote(input.addrs[0], proposalID2, OptionYes)).IsOK()) - require.True(t, handler(ctx, NewMsgVote(input.addrs[0], proposalID3, OptionYes)).IsOK()) - - // Addrs[1] votes on proposal #3 - handler(ctx, NewMsgVote(input.addrs[1], proposalID3, OptionYes)) - - // Test query voted by input.addrs[0] - proposals = getQueriedProposals(t, ctx, cdc, querier, nil, input.addrs[0], StatusNil, 0) - require.Equal(t, proposalID2, (proposals[0]).ProposalID) - require.Equal(t, proposalID3, (proposals[1]).ProposalID) - - // Test query votes on Proposal 2 - votes := getQueriedVotes(t, ctx, cdc, querier, proposalID2) - require.Len(t, votes, 1) - require.Equal(t, input.addrs[0], votes[0].Voter) - - vote := getQueriedVote(t, ctx, cdc, querier, proposalID2, input.addrs[0]) - require.Equal(t, vote, votes[0]) - - // Test query votes on Proposal 3 - votes = getQueriedVotes(t, ctx, cdc, querier, proposalID3) - require.Len(t, votes, 2) - require.True(t, input.addrs[0].String() == votes[0].Voter.String()) - require.True(t, input.addrs[1].String() == votes[1].Voter.String()) - - // Test proposals queries with filters - - // Test query all proposals - proposals = getQueriedProposals(t, ctx, cdc, querier, nil, nil, StatusNil, 0) - require.Equal(t, proposalID1, (proposals[0]).ProposalID) - require.Equal(t, proposalID2, (proposals[1]).ProposalID) - require.Equal(t, proposalID3, (proposals[2]).ProposalID) - - // Test query voted by input.addrs[1] - proposals = getQueriedProposals(t, ctx, cdc, querier, nil, input.addrs[1], StatusNil, 0) - require.Equal(t, proposalID3, (proposals[0]).ProposalID) - - // Test query deposited by input.addrs[0] - proposals = getQueriedProposals(t, ctx, cdc, querier, input.addrs[0], nil, StatusNil, 0) - require.Equal(t, proposalID1, (proposals[0]).ProposalID) - - // Test query deposited by addr2 - proposals = getQueriedProposals(t, ctx, cdc, querier, input.addrs[1], nil, StatusNil, 0) - require.Equal(t, proposalID2, (proposals[0]).ProposalID) - require.Equal(t, proposalID3, (proposals[1]).ProposalID) - - // Test query voted AND deposited by addr1 - proposals = getQueriedProposals(t, ctx, cdc, querier, input.addrs[0], input.addrs[0], StatusNil, 0) - require.Equal(t, proposalID2, (proposals[0]).ProposalID) -} diff --git a/gov/tally_test.go b/gov/tally_test.go deleted file mode 100644 index 929f353ba..000000000 --- a/gov/tally_test.go +++ /dev/null @@ -1,604 +0,0 @@ -package gov - -import ( - "testing" - - "github.com/stretchr/testify/require" - - abci "github.com/tendermint/tendermint/abci/types" - "github.com/tendermint/tendermint/crypto/ed25519" - - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/staking" -) - -func TestTallyNoOneVotes(t *testing.T) { - input := getMockApp(t, 10, GenesisState{}, nil) - - header := abci.Header{Height: input.mApp.LastBlockHeight() + 1} - input.mApp.BeginBlock(abci.RequestBeginBlock{Header: header}) - - ctx := input.mApp.BaseApp.NewContext(false, abci.Header{}) - stakingHandler := staking.NewHandler(input.sk) - - valAddrs := make([]sdk.ValAddress, len(input.addrs[:2])) - for i, addr := range input.addrs[:2] { - valAddrs[i] = sdk.ValAddress(addr) - } - - createValidators(t, stakingHandler, ctx, valAddrs, []int64{5, 5}) - staking.EndBlocker(ctx, input.sk) - - tp := testProposal() - proposal, err := input.keeper.SubmitProposal(ctx, tp) - require.NoError(t, err) - proposalID := proposal.ProposalID - proposal.Status = StatusVotingPeriod - input.keeper.SetProposal(ctx, proposal) - - proposal, ok := input.keeper.GetProposal(ctx, proposalID) - require.True(t, ok) - passes, burnDeposits, tallyResults := tally(ctx, input.keeper, proposal) - - require.False(t, passes) - require.True(t, burnDeposits) - require.True(t, tallyResults.Equals(EmptyTallyResult())) -} - -func TestTallyNoQuorum(t *testing.T) { - input := getMockApp(t, 10, GenesisState{}, nil) - - header := abci.Header{Height: input.mApp.LastBlockHeight() + 1} - input.mApp.BeginBlock(abci.RequestBeginBlock{Header: header}) - - ctx := input.mApp.BaseApp.NewContext(false, abci.Header{}) - stakingHandler := staking.NewHandler(input.sk) - - valAddrs := make([]sdk.ValAddress, len(input.addrs[:2])) - for i, addr := range input.addrs[:2] { - valAddrs[i] = sdk.ValAddress(addr) - } - - createValidators(t, stakingHandler, ctx, valAddrs, []int64{2, 5}) - staking.EndBlocker(ctx, input.sk) - - tp := testProposal() - proposal, err := input.keeper.SubmitProposal(ctx, tp) - require.NoError(t, err) - proposalID := proposal.ProposalID - proposal.Status = StatusVotingPeriod - input.keeper.SetProposal(ctx, proposal) - - err = input.keeper.AddVote(ctx, proposalID, input.addrs[0], OptionYes) - require.Nil(t, err) - - proposal, ok := input.keeper.GetProposal(ctx, proposalID) - require.True(t, ok) - passes, burnDeposits, _ := tally(ctx, input.keeper, proposal) - require.False(t, passes) - require.True(t, burnDeposits) -} - -func TestTallyOnlyValidatorsAllYes(t *testing.T) { - input := getMockApp(t, 10, GenesisState{}, nil) - - header := abci.Header{Height: input.mApp.LastBlockHeight() + 1} - input.mApp.BeginBlock(abci.RequestBeginBlock{Header: header}) - - ctx := input.mApp.BaseApp.NewContext(false, abci.Header{}) - stakingHandler := staking.NewHandler(input.sk) - - valAddrs := make([]sdk.ValAddress, len(input.addrs[:2])) - for i, addr := range input.addrs[:2] { - valAddrs[i] = sdk.ValAddress(addr) - } - - createValidators(t, stakingHandler, ctx, valAddrs, []int64{5, 5}) - staking.EndBlocker(ctx, input.sk) - - tp := testProposal() - proposal, err := input.keeper.SubmitProposal(ctx, tp) - require.NoError(t, err) - proposalID := proposal.ProposalID - proposal.Status = StatusVotingPeriod - input.keeper.SetProposal(ctx, proposal) - - err = input.keeper.AddVote(ctx, proposalID, input.addrs[0], OptionYes) - require.Nil(t, err) - err = input.keeper.AddVote(ctx, proposalID, input.addrs[1], OptionYes) - require.Nil(t, err) - - proposal, ok := input.keeper.GetProposal(ctx, proposalID) - require.True(t, ok) - passes, burnDeposits, tallyResults := tally(ctx, input.keeper, proposal) - - require.True(t, passes) - require.False(t, burnDeposits) - require.False(t, tallyResults.Equals(EmptyTallyResult())) -} - -func TestTallyOnlyValidators51No(t *testing.T) { - input := getMockApp(t, 10, GenesisState{}, nil) - - header := abci.Header{Height: input.mApp.LastBlockHeight() + 1} - input.mApp.BeginBlock(abci.RequestBeginBlock{Header: header}) - - ctx := input.mApp.BaseApp.NewContext(false, abci.Header{}) - stakingHandler := staking.NewHandler(input.sk) - - valAddrs := make([]sdk.ValAddress, len(input.addrs[:2])) - for i, addr := range input.addrs[:2] { - valAddrs[i] = sdk.ValAddress(addr) - } - - createValidators(t, stakingHandler, ctx, valAddrs, []int64{5, 6}) - staking.EndBlocker(ctx, input.sk) - - tp := testProposal() - proposal, err := input.keeper.SubmitProposal(ctx, tp) - require.NoError(t, err) - proposalID := proposal.ProposalID - proposal.Status = StatusVotingPeriod - input.keeper.SetProposal(ctx, proposal) - - err = input.keeper.AddVote(ctx, proposalID, input.addrs[0], OptionYes) - require.Nil(t, err) - err = input.keeper.AddVote(ctx, proposalID, input.addrs[1], OptionNo) - require.Nil(t, err) - - proposal, ok := input.keeper.GetProposal(ctx, proposalID) - require.True(t, ok) - passes, burnDeposits, _ := tally(ctx, input.keeper, proposal) - - require.False(t, passes) - require.False(t, burnDeposits) -} - -func TestTallyOnlyValidators51Yes(t *testing.T) { - input := getMockApp(t, 10, GenesisState{}, nil) - - header := abci.Header{Height: input.mApp.LastBlockHeight() + 1} - input.mApp.BeginBlock(abci.RequestBeginBlock{Header: header}) - - ctx := input.mApp.BaseApp.NewContext(false, abci.Header{}) - stakingHandler := staking.NewHandler(input.sk) - - valAddrs := make([]sdk.ValAddress, len(input.addrs[:3])) - for i, addr := range input.addrs[:3] { - valAddrs[i] = sdk.ValAddress(addr) - } - - createValidators(t, stakingHandler, ctx, valAddrs, []int64{6, 6, 7}) - staking.EndBlocker(ctx, input.sk) - - tp := testProposal() - proposal, err := input.keeper.SubmitProposal(ctx, tp) - require.NoError(t, err) - proposalID := proposal.ProposalID - proposal.Status = StatusVotingPeriod - input.keeper.SetProposal(ctx, proposal) - - err = input.keeper.AddVote(ctx, proposalID, input.addrs[0], OptionYes) - require.Nil(t, err) - err = input.keeper.AddVote(ctx, proposalID, input.addrs[1], OptionYes) - require.Nil(t, err) - err = input.keeper.AddVote(ctx, proposalID, input.addrs[2], OptionNo) - require.Nil(t, err) - - proposal, ok := input.keeper.GetProposal(ctx, proposalID) - require.True(t, ok) - passes, burnDeposits, tallyResults := tally(ctx, input.keeper, proposal) - - require.True(t, passes) - require.False(t, burnDeposits) - require.False(t, tallyResults.Equals(EmptyTallyResult())) -} - -func TestTallyOnlyValidatorsVetoed(t *testing.T) { - input := getMockApp(t, 10, GenesisState{}, nil) - - header := abci.Header{Height: input.mApp.LastBlockHeight() + 1} - input.mApp.BeginBlock(abci.RequestBeginBlock{Header: header}) - - ctx := input.mApp.BaseApp.NewContext(false, abci.Header{}) - stakingHandler := staking.NewHandler(input.sk) - - valAddrs := make([]sdk.ValAddress, len(input.addrs[:3])) - for i, addr := range input.addrs[:3] { - valAddrs[i] = sdk.ValAddress(addr) - } - - createValidators(t, stakingHandler, ctx, valAddrs, []int64{6, 6, 7}) - staking.EndBlocker(ctx, input.sk) - - tp := testProposal() - proposal, err := input.keeper.SubmitProposal(ctx, tp) - require.NoError(t, err) - proposalID := proposal.ProposalID - proposal.Status = StatusVotingPeriod - input.keeper.SetProposal(ctx, proposal) - - err = input.keeper.AddVote(ctx, proposalID, input.addrs[0], OptionYes) - require.Nil(t, err) - err = input.keeper.AddVote(ctx, proposalID, input.addrs[1], OptionYes) - require.Nil(t, err) - err = input.keeper.AddVote(ctx, proposalID, input.addrs[2], OptionNoWithVeto) - require.Nil(t, err) - - proposal, ok := input.keeper.GetProposal(ctx, proposalID) - require.True(t, ok) - passes, burnDeposits, tallyResults := tally(ctx, input.keeper, proposal) - - require.False(t, passes) - require.True(t, burnDeposits) - require.False(t, tallyResults.Equals(EmptyTallyResult())) - -} - -func TestTallyOnlyValidatorsAbstainPasses(t *testing.T) { - input := getMockApp(t, 10, GenesisState{}, nil) - - header := abci.Header{Height: input.mApp.LastBlockHeight() + 1} - input.mApp.BeginBlock(abci.RequestBeginBlock{Header: header}) - - ctx := input.mApp.BaseApp.NewContext(false, abci.Header{}) - stakingHandler := staking.NewHandler(input.sk) - - valAddrs := make([]sdk.ValAddress, len(input.addrs[:3])) - for i, addr := range input.addrs[:3] { - valAddrs[i] = sdk.ValAddress(addr) - } - - createValidators(t, stakingHandler, ctx, valAddrs, []int64{6, 6, 7}) - staking.EndBlocker(ctx, input.sk) - - tp := testProposal() - proposal, err := input.keeper.SubmitProposal(ctx, tp) - require.NoError(t, err) - proposalID := proposal.ProposalID - proposal.Status = StatusVotingPeriod - input.keeper.SetProposal(ctx, proposal) - - err = input.keeper.AddVote(ctx, proposalID, input.addrs[0], OptionAbstain) - require.Nil(t, err) - err = input.keeper.AddVote(ctx, proposalID, input.addrs[1], OptionNo) - require.Nil(t, err) - err = input.keeper.AddVote(ctx, proposalID, input.addrs[2], OptionYes) - require.Nil(t, err) - - proposal, ok := input.keeper.GetProposal(ctx, proposalID) - require.True(t, ok) - passes, burnDeposits, tallyResults := tally(ctx, input.keeper, proposal) - - require.True(t, passes) - require.False(t, burnDeposits) - require.False(t, tallyResults.Equals(EmptyTallyResult())) -} - -func TestTallyOnlyValidatorsAbstainFails(t *testing.T) { - input := getMockApp(t, 10, GenesisState{}, nil) - - header := abci.Header{Height: input.mApp.LastBlockHeight() + 1} - input.mApp.BeginBlock(abci.RequestBeginBlock{Header: header}) - - ctx := input.mApp.BaseApp.NewContext(false, abci.Header{}) - stakingHandler := staking.NewHandler(input.sk) - - valAddrs := make([]sdk.ValAddress, len(input.addrs[:3])) - for i, addr := range input.addrs[:3] { - valAddrs[i] = sdk.ValAddress(addr) - } - - createValidators(t, stakingHandler, ctx, valAddrs, []int64{6, 6, 7}) - staking.EndBlocker(ctx, input.sk) - - tp := testProposal() - proposal, err := input.keeper.SubmitProposal(ctx, tp) - require.NoError(t, err) - proposalID := proposal.ProposalID - proposal.Status = StatusVotingPeriod - input.keeper.SetProposal(ctx, proposal) - - err = input.keeper.AddVote(ctx, proposalID, input.addrs[0], OptionAbstain) - require.Nil(t, err) - err = input.keeper.AddVote(ctx, proposalID, input.addrs[1], OptionYes) - require.Nil(t, err) - err = input.keeper.AddVote(ctx, proposalID, input.addrs[2], OptionNo) - require.Nil(t, err) - - proposal, ok := input.keeper.GetProposal(ctx, proposalID) - require.True(t, ok) - passes, burnDeposits, tallyResults := tally(ctx, input.keeper, proposal) - - require.False(t, passes) - require.False(t, burnDeposits) - require.False(t, tallyResults.Equals(EmptyTallyResult())) -} - -func TestTallyOnlyValidatorsNonVoter(t *testing.T) { - input := getMockApp(t, 10, GenesisState{}, nil) - - header := abci.Header{Height: input.mApp.LastBlockHeight() + 1} - input.mApp.BeginBlock(abci.RequestBeginBlock{Header: header}) - - ctx := input.mApp.BaseApp.NewContext(false, abci.Header{}) - stakingHandler := staking.NewHandler(input.sk) - - valAddrs := make([]sdk.ValAddress, len(input.addrs[:3])) - for i, addr := range input.addrs[:3] { - valAddrs[i] = sdk.ValAddress(addr) - } - - createValidators(t, stakingHandler, ctx, valAddrs, []int64{6, 6, 7}) - staking.EndBlocker(ctx, input.sk) - - tp := testProposal() - proposal, err := input.keeper.SubmitProposal(ctx, tp) - require.NoError(t, err) - proposalID := proposal.ProposalID - proposal.Status = StatusVotingPeriod - input.keeper.SetProposal(ctx, proposal) - - err = input.keeper.AddVote(ctx, proposalID, input.addrs[1], OptionYes) - require.Nil(t, err) - err = input.keeper.AddVote(ctx, proposalID, input.addrs[2], OptionNo) - require.Nil(t, err) - - proposal, ok := input.keeper.GetProposal(ctx, proposalID) - require.True(t, ok) - passes, burnDeposits, tallyResults := tally(ctx, input.keeper, proposal) - - require.False(t, passes) - require.False(t, burnDeposits) - require.False(t, tallyResults.Equals(EmptyTallyResult())) -} - -func TestTallyDelegatorOverride(t *testing.T) { - input := getMockApp(t, 10, GenesisState{}, nil) - - header := abci.Header{Height: input.mApp.LastBlockHeight() + 1} - input.mApp.BeginBlock(abci.RequestBeginBlock{Header: header}) - - ctx := input.mApp.BaseApp.NewContext(false, abci.Header{}) - stakingHandler := staking.NewHandler(input.sk) - - valAddrs := make([]sdk.ValAddress, len(input.addrs[:3])) - for i, addr := range input.addrs[:3] { - valAddrs[i] = sdk.ValAddress(addr) - } - - createValidators(t, stakingHandler, ctx, valAddrs, []int64{5, 6, 7}) - staking.EndBlocker(ctx, input.sk) - - delTokens := sdk.TokensFromConsensusPower(30) - delegator1Msg := staking.NewMsgDelegate(input.addrs[3], sdk.ValAddress(input.addrs[2]), sdk.NewCoin(sdk.DefaultBondDenom, delTokens)) - stakingHandler(ctx, delegator1Msg) - - tp := testProposal() - proposal, err := input.keeper.SubmitProposal(ctx, tp) - require.NoError(t, err) - proposalID := proposal.ProposalID - proposal.Status = StatusVotingPeriod - input.keeper.SetProposal(ctx, proposal) - - err = input.keeper.AddVote(ctx, proposalID, input.addrs[0], OptionYes) - require.Nil(t, err) - err = input.keeper.AddVote(ctx, proposalID, input.addrs[1], OptionYes) - require.Nil(t, err) - err = input.keeper.AddVote(ctx, proposalID, input.addrs[2], OptionYes) - require.Nil(t, err) - err = input.keeper.AddVote(ctx, proposalID, input.addrs[3], OptionNo) - require.Nil(t, err) - - proposal, ok := input.keeper.GetProposal(ctx, proposalID) - require.True(t, ok) - passes, burnDeposits, tallyResults := tally(ctx, input.keeper, proposal) - - require.False(t, passes) - require.False(t, burnDeposits) - require.False(t, tallyResults.Equals(EmptyTallyResult())) -} - -func TestTallyDelegatorInherit(t *testing.T) { - input := getMockApp(t, 10, GenesisState{}, nil) - - header := abci.Header{Height: input.mApp.LastBlockHeight() + 1} - input.mApp.BeginBlock(abci.RequestBeginBlock{Header: header}) - - ctx := input.mApp.BaseApp.NewContext(false, abci.Header{}) - stakingHandler := staking.NewHandler(input.sk) - - valAddrs := make([]sdk.ValAddress, len(input.addrs[:3])) - for i, addr := range input.addrs[:3] { - valAddrs[i] = sdk.ValAddress(addr) - } - - createValidators(t, stakingHandler, ctx, valAddrs, []int64{5, 6, 7}) - staking.EndBlocker(ctx, input.sk) - - delTokens := sdk.TokensFromConsensusPower(30) - delegator1Msg := staking.NewMsgDelegate(input.addrs[3], sdk.ValAddress(input.addrs[2]), sdk.NewCoin(sdk.DefaultBondDenom, delTokens)) - stakingHandler(ctx, delegator1Msg) - - tp := testProposal() - proposal, err := input.keeper.SubmitProposal(ctx, tp) - require.NoError(t, err) - proposalID := proposal.ProposalID - proposal.Status = StatusVotingPeriod - input.keeper.SetProposal(ctx, proposal) - - err = input.keeper.AddVote(ctx, proposalID, input.addrs[0], OptionNo) - require.Nil(t, err) - err = input.keeper.AddVote(ctx, proposalID, input.addrs[1], OptionNo) - require.Nil(t, err) - err = input.keeper.AddVote(ctx, proposalID, input.addrs[2], OptionYes) - require.Nil(t, err) - - proposal, ok := input.keeper.GetProposal(ctx, proposalID) - require.True(t, ok) - passes, burnDeposits, tallyResults := tally(ctx, input.keeper, proposal) - - require.True(t, passes) - require.False(t, burnDeposits) - require.False(t, tallyResults.Equals(EmptyTallyResult())) -} - -func TestTallyDelegatorMultipleOverride(t *testing.T) { - input := getMockApp(t, 10, GenesisState{}, nil) - - header := abci.Header{Height: input.mApp.LastBlockHeight() + 1} - input.mApp.BeginBlock(abci.RequestBeginBlock{Header: header}) - - ctx := input.mApp.BaseApp.NewContext(false, abci.Header{}) - stakingHandler := staking.NewHandler(input.sk) - - valAddrs := make([]sdk.ValAddress, len(input.addrs[:3])) - for i, addr := range input.addrs[:3] { - valAddrs[i] = sdk.ValAddress(addr) - } - - createValidators(t, stakingHandler, ctx, valAddrs, []int64{5, 6, 7}) - staking.EndBlocker(ctx, input.sk) - - delTokens := sdk.TokensFromConsensusPower(10) - delegator1Msg := staking.NewMsgDelegate(input.addrs[3], sdk.ValAddress(input.addrs[2]), sdk.NewCoin(sdk.DefaultBondDenom, delTokens)) - stakingHandler(ctx, delegator1Msg) - delegator1Msg2 := staking.NewMsgDelegate(input.addrs[3], sdk.ValAddress(input.addrs[1]), sdk.NewCoin(sdk.DefaultBondDenom, delTokens)) - stakingHandler(ctx, delegator1Msg2) - - tp := testProposal() - proposal, err := input.keeper.SubmitProposal(ctx, tp) - require.NoError(t, err) - proposalID := proposal.ProposalID - proposal.Status = StatusVotingPeriod - input.keeper.SetProposal(ctx, proposal) - - err = input.keeper.AddVote(ctx, proposalID, input.addrs[0], OptionYes) - require.Nil(t, err) - err = input.keeper.AddVote(ctx, proposalID, input.addrs[1], OptionYes) - require.Nil(t, err) - err = input.keeper.AddVote(ctx, proposalID, input.addrs[2], OptionYes) - require.Nil(t, err) - err = input.keeper.AddVote(ctx, proposalID, input.addrs[3], OptionNo) - require.Nil(t, err) - - proposal, ok := input.keeper.GetProposal(ctx, proposalID) - require.True(t, ok) - passes, burnDeposits, tallyResults := tally(ctx, input.keeper, proposal) - - require.False(t, passes) - require.False(t, burnDeposits) - require.False(t, tallyResults.Equals(EmptyTallyResult())) -} - -func TestTallyDelegatorMultipleInherit(t *testing.T) { - input := getMockApp(t, 10, GenesisState{}, nil) - - header := abci.Header{Height: input.mApp.LastBlockHeight() + 1} - input.mApp.BeginBlock(abci.RequestBeginBlock{Header: header}) - - ctx := input.mApp.BaseApp.NewContext(false, abci.Header{}) - stakingHandler := staking.NewHandler(input.sk) - - valTokens1 := sdk.TokensFromConsensusPower(25) - val1CreateMsg := staking.NewMsgCreateValidator( - sdk.ValAddress(input.addrs[0]), ed25519.GenPrivKey().PubKey(), sdk.NewCoin(sdk.DefaultBondDenom, valTokens1), testDescription, testCommissionRates, sdk.OneInt(), - ) - stakingHandler(ctx, val1CreateMsg) - - valTokens2 := sdk.TokensFromConsensusPower(6) - val2CreateMsg := staking.NewMsgCreateValidator( - sdk.ValAddress(input.addrs[1]), ed25519.GenPrivKey().PubKey(), sdk.NewCoin(sdk.DefaultBondDenom, valTokens2), testDescription, testCommissionRates, sdk.OneInt(), - ) - stakingHandler(ctx, val2CreateMsg) - - valTokens3 := sdk.TokensFromConsensusPower(7) - val3CreateMsg := staking.NewMsgCreateValidator( - sdk.ValAddress(input.addrs[2]), ed25519.GenPrivKey().PubKey(), sdk.NewCoin(sdk.DefaultBondDenom, valTokens3), testDescription, testCommissionRates, sdk.OneInt(), - ) - stakingHandler(ctx, val3CreateMsg) - - delTokens := sdk.TokensFromConsensusPower(10) - delegator1Msg := staking.NewMsgDelegate(input.addrs[3], sdk.ValAddress(input.addrs[2]), sdk.NewCoin(sdk.DefaultBondDenom, delTokens)) - stakingHandler(ctx, delegator1Msg) - - delegator1Msg2 := staking.NewMsgDelegate(input.addrs[3], sdk.ValAddress(input.addrs[1]), sdk.NewCoin(sdk.DefaultBondDenom, delTokens)) - stakingHandler(ctx, delegator1Msg2) - - staking.EndBlocker(ctx, input.sk) - - tp := testProposal() - proposal, err := input.keeper.SubmitProposal(ctx, tp) - require.NoError(t, err) - proposalID := proposal.ProposalID - proposal.Status = StatusVotingPeriod - input.keeper.SetProposal(ctx, proposal) - - err = input.keeper.AddVote(ctx, proposalID, input.addrs[0], OptionYes) - require.Nil(t, err) - err = input.keeper.AddVote(ctx, proposalID, input.addrs[1], OptionNo) - require.Nil(t, err) - err = input.keeper.AddVote(ctx, proposalID, input.addrs[2], OptionNo) - require.Nil(t, err) - - proposal, ok := input.keeper.GetProposal(ctx, proposalID) - require.True(t, ok) - passes, burnDeposits, tallyResults := tally(ctx, input.keeper, proposal) - - require.False(t, passes) - require.False(t, burnDeposits) - require.False(t, tallyResults.Equals(EmptyTallyResult())) -} - -func TestTallyJailedValidator(t *testing.T) { - input := getMockApp(t, 10, GenesisState{}, nil) - - header := abci.Header{Height: input.mApp.LastBlockHeight() + 1} - input.mApp.BeginBlock(abci.RequestBeginBlock{Header: header}) - - ctx := input.mApp.BaseApp.NewContext(false, abci.Header{}) - stakingHandler := staking.NewHandler(input.sk) - - valAddrs := make([]sdk.ValAddress, len(input.addrs[:3])) - for i, addr := range input.addrs[:3] { - valAddrs[i] = sdk.ValAddress(addr) - } - - createValidators(t, stakingHandler, ctx, valAddrs, []int64{25, 6, 7}) - staking.EndBlocker(ctx, input.sk) - - delTokens := sdk.TokensFromConsensusPower(10) - delegator1Msg := staking.NewMsgDelegate(input.addrs[3], sdk.ValAddress(input.addrs[2]), sdk.NewCoin(sdk.DefaultBondDenom, delTokens)) - stakingHandler(ctx, delegator1Msg) - - delegator1Msg2 := staking.NewMsgDelegate(input.addrs[3], sdk.ValAddress(input.addrs[1]), sdk.NewCoin(sdk.DefaultBondDenom, delTokens)) - stakingHandler(ctx, delegator1Msg2) - - val2, found := input.sk.GetValidator(ctx, sdk.ValAddress(input.addrs[1])) - require.True(t, found) - input.sk.Jail(ctx, sdk.ConsAddress(val2.ConsPubKey.Address())) - - staking.EndBlocker(ctx, input.sk) - - tp := testProposal() - proposal, err := input.keeper.SubmitProposal(ctx, tp) - require.NoError(t, err) - proposalID := proposal.ProposalID - proposal.Status = StatusVotingPeriod - input.keeper.SetProposal(ctx, proposal) - - err = input.keeper.AddVote(ctx, proposalID, input.addrs[0], OptionYes) - require.Nil(t, err) - err = input.keeper.AddVote(ctx, proposalID, input.addrs[1], OptionNo) - require.Nil(t, err) - err = input.keeper.AddVote(ctx, proposalID, input.addrs[2], OptionNo) - require.Nil(t, err) - - proposal, ok := input.keeper.GetProposal(ctx, proposalID) - require.True(t, ok) - passes, burnDeposits, tallyResults := tally(ctx, input.keeper, proposal) - - require.True(t, passes) - require.False(t, burnDeposits) - require.False(t, tallyResults.Equals(EmptyTallyResult())) -} diff --git a/gov/types/keys_test.go b/gov/types/keys_test.go index fd343f5de..871484bee 100644 --- a/gov/types/keys_test.go +++ b/gov/types/keys_test.go @@ -5,9 +5,9 @@ import ( "time" "github.com/stretchr/testify/require" + "github.com/tendermint/tendermint/crypto/secp256k1" hmTypes "github.com/maticnetwork/heimdall/types" - "github.com/tendermint/tendermint/crypto/secp256k1" ) var addr = hmTypes.BytesToHeimdallAddress(secp256k1.GenPrivKey().PubKey().Address()) @@ -38,34 +38,36 @@ func TestProposalKeys(t *testing.T) { func TestDepositKeys(t *testing.T) { + id := 1 + key := DepositsKey(2) proposalID := SplitProposalKey(key) require.Equal(t, int(proposalID), 2) - key = DepositKey(2, addr) + key = DepositKey(2, hmTypes.ValidatorID(id)) proposalID, depositorAddr := SplitKeyDeposit(key) require.Equal(t, int(proposalID), 2) require.Equal(t, addr, depositorAddr) // invalid key - addr2 := hmTypes.SampleHeimdallAddress("test1") - key = DepositKey(5, addr2) + key = DepositKey(5, hmTypes.ValidatorID(id)) require.Panics(t, func() { SplitKeyDeposit(key) }) } func TestVoteKeys(t *testing.T) { + id := 1 + key := VotesKey(2) proposalID := SplitProposalKey(key) require.Equal(t, int(proposalID), 2) - key = VoteKey(2, addr) + key = VoteKey(2, hmTypes.ValidatorID(id)) proposalID, voterAddr := SplitKeyDeposit(key) require.Equal(t, int(proposalID), 2) require.Equal(t, addr, voterAddr) // invalid key - addr2 := hmTypes.SampleHeimdallAddress("test1") - key = VoteKey(5, addr2) + key = VoteKey(5, hmTypes.ValidatorID(id)) require.Panics(t, func() { SplitKeyVote(key) }) } diff --git a/gov/types/msgs_test.go b/gov/types/msgs_test.go deleted file mode 100644 index bb2fc79db..000000000 --- a/gov/types/msgs_test.go +++ /dev/null @@ -1,121 +0,0 @@ -package types - -import ( - "strings" - "testing" - - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/stretchr/testify/require" - - authTypes "github.com/maticnetwork/heimdall/auth/types" - hmTypes "github.com/maticnetwork/heimdall/types" -) - -var ( - coinsPos = sdk.NewCoins(hmTypes.NewInt64Coin(authTypes.FeeToken, 1000)) - coinsZero = sdk.NewCoins() - coinsPosNotMatic = sdk.NewCoins(hmTypes.NewInt64Coin("foo", 10000)) - coinsMulti = sdk.NewCoins(hmTypes.NewInt64Coin(authTypes.FeeToken, 1000), hmTypes.NewInt64Coin("foo", 10000)) - addrs = []hmTypes.HeimdallAddress{ - hmTypes.SampleHeimdallAddress("test1"), - hmTypes.SampleHeimdallAddress("test2"), - } -) - -func init() { - coinsMulti.Sort() -} - -// test ValidateBasic for MsgCreateValidator -func TestMsgSubmitProposal(t *testing.T) { - tests := []struct { - title, description string - proposalType string - proposerAddr hmTypes.HeimdallAddress - initialDeposit sdk.Coins - expectPass bool - }{ - {"Test Proposal", "the purpose of this proposal is to test", ProposalTypeText, addrs[0], coinsPos, true}, - {"", "the purpose of this proposal is to test", ProposalTypeText, addrs[0], coinsPos, false}, - {"Test Proposal", "", ProposalTypeText, addrs[0], coinsPos, false}, - {"Test Proposal", "the purpose of this proposal is to test", ProposalTypeSoftwareUpgrade, addrs[0], coinsPos, false}, - {"Test Proposal", "the purpose of this proposal is to test", ProposalTypeText, hmTypes.HeimdallAddress{}, coinsPos, false}, - {"Test Proposal", "the purpose of this proposal is to test", ProposalTypeText, addrs[0], coinsZero, true}, - {"Test Proposal", "the purpose of this proposal is to test", ProposalTypeText, addrs[0], coinsMulti, true}, - {strings.Repeat("#", MaxTitleLength*2), "the purpose of this proposal is to test", ProposalTypeText, addrs[0], coinsMulti, false}, - {"Test Proposal", strings.Repeat("#", MaxDescriptionLength*2), ProposalTypeText, addrs[0], coinsMulti, false}, - } - - for i, tc := range tests { - msg := NewMsgSubmitProposal( - ContentFromProposalType(tc.title, tc.description, tc.proposalType), - tc.initialDeposit, - tc.proposerAddr, - ) - - if tc.expectPass { - require.NoError(t, msg.ValidateBasic(), "test: %v", i) - } else { - require.Error(t, msg.ValidateBasic(), "test: %v", i) - } - } -} - -func TestMsgDepositGetSignBytes(t *testing.T) { - addr := hmTypes.SampleHeimdallAddress("addr1") - msg := NewMsgDeposit(addr, 0, coinsPos) - res := msg.GetSignBytes() - - expected := `{"type":"heimdall/MsgDeposit","value":{"amount":[{"amount":"1000","denom":"matic"}],"depositor":"0x0000000000000000000000000000006164647231","proposal_id":"0"}}` - require.Equal(t, expected, string(res)) -} - -// test ValidateBasic for MsgDeposit -func TestMsgDeposit(t *testing.T) { - tests := []struct { - proposalID uint64 - depositorAddr hmTypes.HeimdallAddress - depositAmount sdk.Coins - expectPass bool - }{ - {0, addrs[0], coinsPos, true}, - {1, hmTypes.HeimdallAddress{}, coinsPos, false}, - {1, addrs[0], coinsZero, true}, - {1, addrs[0], coinsMulti, true}, - } - - for i, tc := range tests { - msg := NewMsgDeposit(tc.depositorAddr, tc.proposalID, tc.depositAmount) - if tc.expectPass { - require.NoError(t, msg.ValidateBasic(), "test: %v", i) - } else { - require.Error(t, msg.ValidateBasic(), "test: %v", i) - } - } -} - -// test ValidateBasic for MsgDeposit -func TestMsgVote(t *testing.T) { - tests := []struct { - proposalID uint64 - voterAddr hmTypes.HeimdallAddress - option VoteOption - expectPass bool - }{ - {0, addrs[0], OptionYes, true}, - {0, hmTypes.HeimdallAddress{}, OptionYes, false}, - {0, addrs[0], OptionNo, true}, - {0, addrs[0], OptionNoWithVeto, true}, - {0, addrs[0], OptionAbstain, true}, - {0, addrs[0], VoteOption(0x13), false}, - } - - for i, tc := range tests { - msg := NewMsgVote(tc.voterAddr, tc.proposalID, tc.option) - if tc.expectPass { - require.Nil(t, msg.ValidateBasic(), "test: %v", i) - } else { - require.NotNil(t, msg.ValidateBasic(), "test: %v", i) - } - } -} diff --git a/helper/config.go b/helper/config.go index 8aa56f7b4..7c7bed293 100644 --- a/helper/config.go +++ b/helper/config.go @@ -243,7 +243,7 @@ var newHexToStringAlgoHeight int64 = 0 var jorvikHeight int64 = 0 -var antevortaHeight int64 = 0 +var danelawHeight int64 = 0 type ChainManagerAddressMigration struct { MaticTokenAddress hmTypes.HeimdallAddress @@ -415,28 +415,28 @@ func InitHeimdallConfigWith(homeDir string, heimdallConfigFileFromFLag string) { newHexToStringAlgoHeight = 9266260 aalborgHeight = 15950759 jorvikHeight = -1 - antevortaHeight = -1 + danelawHeight = -1 case MumbaiChain: newSelectionAlgoHeight = 282500 spanOverrideHeight = 10205000 newHexToStringAlgoHeight = 12048023 aalborgHeight = 18035772 jorvikHeight = -1 - antevortaHeight = -1 + danelawHeight = -1 case AmoyChain: newSelectionAlgoHeight = 0 spanOverrideHeight = 0 newHexToStringAlgoHeight = 0 aalborgHeight = 0 jorvikHeight = 5768528 - antevortaHeight = 0 + danelawHeight = 6490424 default: newSelectionAlgoHeight = 0 spanOverrideHeight = 0 newHexToStringAlgoHeight = 0 aalborgHeight = 0 jorvikHeight = 0 - antevortaHeight = 0 + danelawHeight = 0 } } @@ -594,9 +594,9 @@ func GetJorvikHeight() int64 { return jorvikHeight } -// GetAntevortaHeight returns antevortaHeight -func GetAntevortaHeight() int64 { - return antevortaHeight +// GetDanelawHeight returns danelawHeight +func GetDanelawHeight() int64 { + return danelawHeight } func GetChainManagerAddressMigration(blockNum int64) (ChainManagerAddressMigration, bool) { From 3cde3f4c313b93a17cdde8f39c5c3d6c786f3d89 Mon Sep 17 00:00:00 2001 From: Angel Valkov Date: Wed, 22 Jan 2025 12:10:21 +0200 Subject: [PATCH 5/8] Tx decoder restrict new msgs before HF --- app/app.go | 8 ++++++-- auth/types/stdtx.go | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/app/app.go b/app/app.go index 675f1633e..72a3df4fe 100644 --- a/app/app.go +++ b/app/app.go @@ -192,8 +192,12 @@ func NewHeimdallApp(logger log.Logger, db dbm.DB, baseAppOptions ...func(*bam.Ba config := sdk.GetConfig() config.Seal() + var app *HeimdallApp + // base app - bApp := bam.NewBaseApp(AppName, logger, db, authTypes.DefaultTxDecoder(cdc), baseAppOptions...) + bApp := bam.NewBaseApp(AppName, logger, db, authTypes.DefaultMainTxDecoder(cdc, func() int64 { + return app.LastBlockHeight() + }, helper.GetDanelawHeight, helper.GetJorvikHeight), baseAppOptions...) bApp.SetCommitMultiStoreTracer(nil) bApp.SetAppVersion(version.Version) @@ -217,7 +221,7 @@ func NewHeimdallApp(logger log.Logger, db dbm.DB, baseAppOptions ...func(*bam.Ba tkeys := sdk.NewTransientStoreKeys(paramsTypes.TStoreKey) // create heimdall app - var app = &HeimdallApp{ + app = &HeimdallApp{ cdc: cdc, BaseApp: bApp, keys: keys, diff --git a/auth/types/stdtx.go b/auth/types/stdtx.go index c725810da..04124916c 100644 --- a/auth/types/stdtx.go +++ b/auth/types/stdtx.go @@ -203,6 +203,41 @@ func (fee StdFee) GasPrices() sdk.DecCoins { // Decoders // +// DefaultMainTxDecoder logic for standard transaction decoding +func DefaultMainTxDecoder(cdc *codec.Codec, lastBlockHeight func() int64, getDanelawHeight func() int64, getJorvikHeight func() int64) sdk.TxDecoder { + return func(txBytes []byte) (sdk.Tx, sdk.Error) { + var tx = StdTx{} + + if len(txBytes) == 0 { + return nil, sdk.ErrTxDecode("txBytes are empty") + } + + currentHeight := lastBlockHeight() + 1 + if currentHeight < getDanelawHeight() && getDanelawHeight() == getJorvikHeight() { + var hftx = StdTx{} + if err := cdc.UnmarshalBinaryLengthPrefixed(txBytes, &hftx); err != nil { + return nil, sdk.ErrTxDecode("error decoding transaction").TraceSDK(err.Error()) + } + + msgs := hftx.GetMsgs() + for _, msg := range msgs { + if msg.Route() == "bor" && msg.Type() == "MsgProposeSpanV2" { + return nil, sdk.ErrTxDecode("error decoding transaction") + } + } + } + + // StdTx.Msg is an interface. The concrete types + // are registered by MakeTxCodec + err := cdc.UnmarshalBinaryLengthPrefixed(txBytes, &tx) + if err != nil { + return nil, sdk.ErrTxDecode("error decoding transaction").TraceSDK(err.Error()) + } + + return tx, nil + } +} + // DefaultTxDecoder logic for standard transaction decoding func DefaultTxDecoder(cdc *codec.Codec) sdk.TxDecoder { return func(txBytes []byte) (sdk.Tx, sdk.Error) { From be2fc357b2ffa1c0467ab0dff538c5a9e9f608a5 Mon Sep 17 00:00:00 2001 From: Angel Valkov Date: Wed, 22 Jan 2025 12:27:37 +0200 Subject: [PATCH 6/8] Fixed type check in tx decoder --- auth/types/stdtx.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/auth/types/stdtx.go b/auth/types/stdtx.go index 04124916c..d0c2a234c 100644 --- a/auth/types/stdtx.go +++ b/auth/types/stdtx.go @@ -221,7 +221,7 @@ func DefaultMainTxDecoder(cdc *codec.Codec, lastBlockHeight func() int64, getDan msgs := hftx.GetMsgs() for _, msg := range msgs { - if msg.Route() == "bor" && msg.Type() == "MsgProposeSpanV2" { + if msg.Route() == "bor" && msg.Type() == "propose-span-v2" { return nil, sdk.ErrTxDecode("error decoding transaction") } } From 32e8586aef3603bc1732d3504cf7660b3c38b1fe Mon Sep 17 00:00:00 2001 From: Raneet Debnath Date: Wed, 29 Jan 2025 16:53:26 +0530 Subject: [PATCH 7/8] set jorvik and danelaw HF height for mainnet --- helper/config.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/helper/config.go b/helper/config.go index 7c7bed293..a5537bc55 100644 --- a/helper/config.go +++ b/helper/config.go @@ -414,8 +414,8 @@ func InitHeimdallConfigWith(homeDir string, heimdallConfigFileFromFLag string) { spanOverrideHeight = 8664000 newHexToStringAlgoHeight = 9266260 aalborgHeight = 15950759 - jorvikHeight = -1 - danelawHeight = -1 + jorvikHeight = 22393043 + danelawHeight = 22393043 case MumbaiChain: newSelectionAlgoHeight = 282500 spanOverrideHeight = 10205000 From 0f83271141334935fde8bb7f3c616fabb3363956 Mon Sep 17 00:00:00 2001 From: luchenhan Date: Fri, 7 Feb 2025 17:52:52 +0800 Subject: [PATCH 8/8] chore: fix wrong function name in go docs Signed-off-by: luchenhan --- checkpoint/keeper_milestone.go | 2 +- clerk/types/errors.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/checkpoint/keeper_milestone.go b/checkpoint/keeper_milestone.go index 03cc7ef36..5b38152db 100644 --- a/checkpoint/keeper_milestone.go +++ b/checkpoint/keeper_milestone.go @@ -116,7 +116,7 @@ func (k *Keeper) SetMilestoneCount(ctx sdk.Context, number uint64) { store.Set(CountKey, value) } -// GetCount returns milestone count +// GetMilestoneCount returns milestone count func (k *Keeper) GetMilestoneCount(ctx sdk.Context) uint64 { store := ctx.KVStore(k.storeKey) // check if count is there diff --git a/clerk/types/errors.go b/clerk/types/errors.go index 3279a25d4..c2ae62e49 100644 --- a/clerk/types/errors.go +++ b/clerk/types/errors.go @@ -27,7 +27,7 @@ func ErrEventRecordInvalid(codespace sdk.CodespaceType) sdk.Error { return sdk.NewError(codespace, CodeEventRecordInvalid, "Event record is invalid") } -// ErrEventUpdates represent event update error +// ErrEventUpdate represent event update error func ErrEventUpdate(codespace sdk.CodespaceType) sdk.Error { return sdk.NewError(codespace, CodeEventRecordUpdate, "Event record update error") }