From ce6b05c17babb1040b1dbeeabb75ec786c9bc3d7 Mon Sep 17 00:00:00 2001 From: shak58 <150069539+shak58@users.noreply.github.com> Date: Thu, 15 Aug 2024 08:33:17 +0100 Subject: [PATCH 1/6] chore(readme): fix repeated word in x/incentives README (#1102) --- x/incentives/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/incentives/README.md b/x/incentives/README.md index c7fcbaa7c..988522e72 100644 --- a/x/incentives/README.md +++ b/x/incentives/README.md @@ -10,7 +10,7 @@ Anyone can create gauge and add rewards to the gauge, there is no way to take it There are two kinds of `gauges`, perpetual and non-perpetual ones. -- Non perpetual ones get removed from active queue after the the distribution period finish but perpetual ones persist. +- Non perpetual ones get removed from active queue after the distribution period finish but perpetual ones persist. - For non perpetual ones, they distribute the tokens equally per epoch during the `gauge` is in the active period. - For perpetual ones, it distribute all the tokens at a single time. Those gauges needs to be filled externally. From f1df3d7f7dced4d4ee6505d2bf229d15c4181398 Mon Sep 17 00:00:00 2001 From: keruch <53012408+keruch@users.noreply.github.com> Date: Thu, 15 Aug 2024 20:21:04 +0200 Subject: [PATCH 2/6] fix(streamer): don't distribute abstained part of sponsored distribution (#1097) --- x/streamer/types/distr_info.go | 23 ++---- x/streamer/types/distr_info_test.go | 116 ++++++++++++++++++++++++++++ 2 files changed, 122 insertions(+), 17 deletions(-) create mode 100644 x/streamer/types/distr_info_test.go diff --git a/x/streamer/types/distr_info.go b/x/streamer/types/distr_info.go index f5954a57c..8429b062a 100644 --- a/x/streamer/types/distr_info.go +++ b/x/streamer/types/distr_info.go @@ -1,7 +1,6 @@ package types import ( - "cosmossdk.io/math" sdk "github.com/cosmos/cosmos-sdk/types" sponsorshiptypes "github.com/dymensionxyz/dymension/v3/x/sponsorship/types" @@ -36,29 +35,19 @@ func (r DistrRecord) ValidateBasic() error { return nil } -var hundred = math.NewInt(100) - -// DistrInfoFromDistribution converts sponsorship distribution to the DistrInfo type and performs a -// basic validation for DistrInfo.Records. Returning an empty DistrInfo (with zero DistrInfo.TotalWeight) -// is a valid scenario. +// DistrInfoFromDistribution converts sponsorship distribution to the DistrInfo type. +// Returning an empty DistrInfo (with zero DistrInfo.TotalWeight) is a valid scenario. func DistrInfoFromDistribution(d sponsorshiptypes.Distribution) *DistrInfo { - totalWeight := math.ZeroInt() records := make([]DistrRecord, 0, len(d.Gauges)) for _, g := range d.Gauges { - // d.VotingPower is always > 0 to the Distribution type contract - weight := g.Power.Mul(hundred).Quo(d.VotingPower) - - record := DistrRecord{ + records = append(records, DistrRecord{ GaugeId: g.GaugeId, - Weight: weight, - } - - totalWeight = totalWeight.Add(weight) - records = append(records, record) + Weight: g.Power, + }) } return &DistrInfo{ - TotalWeight: totalWeight, + TotalWeight: d.VotingPower, Records: records, } } diff --git a/x/streamer/types/distr_info_test.go b/x/streamer/types/distr_info_test.go new file mode 100644 index 000000000..3bb7405fa --- /dev/null +++ b/x/streamer/types/distr_info_test.go @@ -0,0 +1,116 @@ +package types_test + +import ( + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/stretchr/testify/assert" + + sponsorshiptypes "github.com/dymensionxyz/dymension/v3/x/sponsorship/types" + "github.com/dymensionxyz/dymension/v3/x/streamer/types" +) + +func TestDistrInfoFromDistribution(t *testing.T) { + testCases := []struct { + name string + distr sponsorshiptypes.Distribution + expDistr *types.DistrInfo + }{ + { + name: "Empty distribution", + distr: sponsorshiptypes.NewDistribution(), + expDistr: &types.DistrInfo{ + TotalWeight: sdk.NewInt(0), + Records: []types.DistrRecord{}, + }, + }, + { + name: "Distribution with single gauge", + distr: sponsorshiptypes.Distribution{ + VotingPower: sdk.NewInt(10), + Gauges: []sponsorshiptypes.Gauge{ + { + GaugeId: 1, + Power: sdk.NewInt(10), + }, + }, + }, + expDistr: &types.DistrInfo{ + TotalWeight: sdk.NewInt(10), + Records: []types.DistrRecord{ + { + GaugeId: 1, + Weight: sdk.NewInt(10), + }, + }, + }, + }, + { + name: "Distribution with multiple gauges", + distr: sponsorshiptypes.Distribution{ + VotingPower: sdk.NewInt(30), + Gauges: []sponsorshiptypes.Gauge{ + { + GaugeId: 1, + Power: sdk.NewInt(10), + }, + { + GaugeId: 2, + Power: sdk.NewInt(20), + }, + }, + }, + expDistr: &types.DistrInfo{ + TotalWeight: sdk.NewInt(30), + Records: []types.DistrRecord{ + { + GaugeId: 1, + Weight: sdk.NewInt(10), + }, + { + GaugeId: 2, + Weight: sdk.NewInt(20), + }, + }, + }, + }, + { + name: "Distribution with abstained gauge", + distr: sponsorshiptypes.Distribution{ + VotingPower: sdk.NewInt(100), + Gauges: []sponsorshiptypes.Gauge{ + // 30 is abstained + { + GaugeId: 1, + Power: sdk.NewInt(50), + }, + { + GaugeId: 2, + Power: sdk.NewInt(20), + }, + }, + }, + expDistr: &types.DistrInfo{ + TotalWeight: sdk.NewInt(100), + Records: []types.DistrRecord{ + // 30 is abstained + { + GaugeId: 1, + Weight: sdk.NewInt(50), + }, + { + GaugeId: 2, + Weight: sdk.NewInt(20), + }, + }, + }, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + distr := types.DistrInfoFromDistribution(tc.distr) + assert.Equal(t, tc.expDistr, distr) + }) + } +} From a151b858c4c1465cfe66576301d2953f7afb931d Mon Sep 17 00:00:00 2001 From: artpav <19916123+artemijspavlovs@users.noreply.github.com> Date: Sat, 17 Aug 2024 12:28:37 +0300 Subject: [PATCH 3/6] chore(setup script): exit local setup if dymd is not installed (#1103) --- scripts/setup_local.sh | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/scripts/setup_local.sh b/scripts/setup_local.sh index 1fc4b8b4a..b2709550e 100755 --- a/scripts/setup_local.sh +++ b/scripts/setup_local.sh @@ -1,14 +1,10 @@ #!/bin/sh if [ "$EXECUTABLE" = "" ]; then - DEFAULT_EXECUTABLE=$(which dymd) - - if [ "$DEFAULT_EXECUTABLE" = "" ]; then + echo 'please run `make install` and export the installed binary with' + echo '`export EXECUTABLE=$(which dymd)' echo "dymd not found in PATH. Exiting." exit 1 - fi - echo "EXECUTABLE is not set, using '${DEFAULT_EXECUTABLE}'" - EXECUTABLE=$DEFAULT_EXECUTABLE fi # Validate dymension binary exists From 5148d6b8cf0ed272b0fe79c353d2652fc252a676 Mon Sep 17 00:00:00 2001 From: zale144 Date: Sun, 18 Aug 2024 20:08:15 +0200 Subject: [PATCH 4/6] fix(sequencer): make create sequencer cli command metadata optional (#1111) --- x/sequencer/client/cli/tx.go | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/x/sequencer/client/cli/tx.go b/x/sequencer/client/cli/tx.go index c6aeddd79..4c48d7f71 100644 --- a/x/sequencer/client/cli/tx.go +++ b/x/sequencer/client/cli/tx.go @@ -34,17 +34,19 @@ func GetTxCmd() *cobra.Command { func CmdCreateSequencer() *cobra.Command { cmd := &cobra.Command{ - Use: "create-sequencer [pubkey] [rollapp-id] [metadata] [bond]", + Use: "create-sequencer [pubkey] [rollapp-id] [bond] [metadata]", Short: "Create a new sequencer for a rollapp", - Args: cobra.ExactArgs(4), + Args: cobra.MinimumNArgs(3), RunE: func(cmd *cobra.Command, args []string) (err error) { argPubkey := args[0] argRollappId := args[1] - bond := args[3] + bond := args[2] - metadata := new(types.SequencerMetadata) - if err = utils.ParseJsonFromFile(args[2], metadata); err != nil { - return + var metadata types.SequencerMetadata + if len(args) == 4 { + if err = utils.ParseJsonFromFile(args[3], &metadata); err != nil { + return + } } clientCtx, err := client.GetClientTxContext(cmd) @@ -67,7 +69,7 @@ func CmdCreateSequencer() *cobra.Command { clientCtx.GetFromAddress().String(), pk, argRollappId, - metadata, + &metadata, bondCoin, ) if err != nil { From a5dc63e35e10eb4880cf8386e785e1af4fcc371e Mon Sep 17 00:00:00 2001 From: artpav <19916123+artemijspavlovs@users.noreply.github.com> Date: Mon, 19 Aug 2024 14:33:13 +0300 Subject: [PATCH 5/6] chore: use SETTLEMENT_EXECUTABLE to remove overlaps (#1114) --- scripts/setup_local.sh | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/scripts/setup_local.sh b/scripts/setup_local.sh index b2709550e..55f7b2d05 100755 --- a/scripts/setup_local.sh +++ b/scripts/setup_local.sh @@ -1,19 +1,19 @@ #!/bin/sh -if [ "$EXECUTABLE" = "" ]; then +if [ "$SETTLEMENT_EXECUTABLE" = "" ]; then echo 'please run `make install` and export the installed binary with' - echo '`export EXECUTABLE=$(which dymd)' + echo '`export SETTLEMENT_EXECUTABLE=$(which dymd)' echo "dymd not found in PATH. Exiting." exit 1 fi # Validate dymension binary exists export PATH="$PATH":"$HOME"/go/bin -if ! command -v "$EXECUTABLE" > /dev/null; then +if ! command -v "$SETTLEMENT_EXECUTABLE" > /dev/null; then make install - if ! command -v "$EXECUTABLE"; then - echo "dymension binary $EXECUTABLE not found in $PATH" + if ! command -v "$SETTLEMENT_EXECUTABLE"; then + echo "dymension binary $SETTLEMENT_EXECUTABLE not found in $PATH" exit 1 fi fi @@ -65,7 +65,7 @@ if [ -f "$GENESIS_FILE" ]; then fi # Create and init dymension chain -"$EXECUTABLE" init "$MONIKER_NAME" --chain-id="$CHAIN_ID" +"$SETTLEMENT_EXECUTABLE" init "$MONIKER_NAME" --chain-id="$CHAIN_ID" # ---------------------------------------------------------------------------- # # Set configurations # @@ -104,19 +104,19 @@ fi echo "Initialize AMM accounts? (Y/n) " read -r answer if [ ! "$answer" != "${answer#[Nn]}" ] ;then - "$EXECUTABLE" keys add pools --keyring-backend test - "$EXECUTABLE" keys add user --keyring-backend test + "$SETTLEMENT_EXECUTABLE" keys add pools --keyring-backend test + "$SETTLEMENT_EXECUTABLE" keys add user --keyring-backend test # Add genesis accounts and provide coins to the accounts - "$EXECUTABLE" add-genesis-account "$(dymd keys show pools --keyring-backend test -a)" 1000000000000000000000000adym,10000000000uatom,500000000000uusd + "$SETTLEMENT_EXECUTABLE" add-genesis-account "$(dymd keys show pools --keyring-backend test -a)" 1000000000000000000000000adym,10000000000uatom,500000000000uusd # Give some uatom to the local-user as well - "$EXECUTABLE" add-genesis-account "$(dymd keys show user --keyring-backend test -a)" 1000000000000000000000000adym,10000000000uatom + "$SETTLEMENT_EXECUTABLE" add-genesis-account "$(dymd keys show user --keyring-backend test -a)" 1000000000000000000000000adym,10000000000uatom fi -echo "$MNEMONIC" | "$EXECUTABLE" keys add "$KEY_NAME" --recover --keyring-backend test -"$EXECUTABLE" add-genesis-account "$(dymd keys show "$KEY_NAME" -a --keyring-backend test)" "$TOKEN_AMOUNT" +echo "$MNEMONIC" | "$SETTLEMENT_EXECUTABLE" keys add "$KEY_NAME" --recover --keyring-backend test +"$SETTLEMENT_EXECUTABLE" add-genesis-account "$(dymd keys show "$KEY_NAME" -a --keyring-backend test)" "$TOKEN_AMOUNT" -"$EXECUTABLE" gentx "$KEY_NAME" "$STAKING_AMOUNT" --chain-id "$CHAIN_ID" --keyring-backend test -"$EXECUTABLE" collect-gentxs +"$SETTLEMENT_EXECUTABLE" gentx "$KEY_NAME" "$STAKING_AMOUNT" --chain-id "$CHAIN_ID" --keyring-backend test +"$SETTLEMENT_EXECUTABLE" collect-gentxs -"$EXECUTABLE" validate-genesis +"$SETTLEMENT_EXECUTABLE" validate-genesis From e50966c0c82d340a4d2c6b36ecc354b00a900e09 Mon Sep 17 00:00:00 2001 From: Michael Tsitrin <114929630+mtsitrin@users.noreply.github.com> Date: Mon, 19 Aug 2024 19:13:00 +0300 Subject: [PATCH 6/6] feat(sequencers): sequencer rotation support (#1006) Co-authored-by: Omri --- app/apptesting/test_suite.go | 33 +- app/keepers/keepers.go | 1 - app/upgrades/v4/upgrade.go | 12 +- app/upgrades/v4/upgrade_test.go | 53 +- go.mod | 3 - proto/dymensionxyz/dymension/rollapp/tx.proto | 2 + .../dymension/sequencer/genesis.proto | 16 +- .../sequencer/operating_status.proto | 15 +- .../dymension/sequencer/params.proto | 18 +- .../dymension/sequencer/query.proto | 102 +- .../dymension/sequencer/sequencer.proto | 26 +- .../dymensionxyz/dymension/sequencer/tx.proto | 9 +- scripts/src/genesis_config_commands.sh | 4 + testutil/keeper/sequencer.go | 3 +- utils/keys.go | 37 + x/delayedack/keeper/invariants_test.go | 5 +- ...block_height_to_finalization_queue_test.go | 15 +- x/rollapp/keeper/fraud_handler_test.go | 32 +- x/rollapp/keeper/invariants_test.go | 10 +- .../keeper/msg_server_update_rollapp_test.go | 17 +- x/rollapp/keeper/msg_server_update_state.go | 12 +- .../keeper/msg_server_update_state_test.go | 334 +---- x/rollapp/types/hooks.go | 14 +- x/rollapp/types/tx.pb.go | 143 +- x/sequencer/client/cli/query.go | 2 + .../client/cli/query_sequencers_by_rollapp.go | 56 +- x/sequencer/genesis.go | 24 +- x/sequencer/genesis_test.go | 133 +- x/sequencer/keeper/bond_reductions.go | 51 + .../grpc_query_sequencers_by_rollapp.go | 45 +- .../grpc_query_sequencers_by_rollapp_test.go | 23 +- x/sequencer/keeper/hook_listener.go | 48 +- x/sequencer/keeper/hooks_test.go | 10 +- x/sequencer/keeper/invariants.go | 35 +- x/sequencer/keeper/invariants_test.go | 30 +- x/sequencer/keeper/keeper.go | 5 +- .../keeper/msg_server_create_sequencer.go | 30 +- .../msg_server_create_sequencer_test.go | 71 +- .../keeper/msg_server_decrease_bond_test.go | 8 +- .../keeper/msg_server_increase_bond.go | 2 +- .../keeper/msg_server_increase_bond_test.go | 10 +- x/sequencer/keeper/msg_server_unbond.go | 65 +- x/sequencer/keeper/msg_server_unbond_test.go | 107 +- .../msg_server_update_sequencer_test.go | 28 +- x/sequencer/keeper/params.go | 6 + x/sequencer/keeper/rotation.go | 141 ++ x/sequencer/keeper/rotation_test.go | 193 +++ x/sequencer/keeper/sequencer.go | 200 ++- x/sequencer/keeper/sequencer_suite_test.go | 18 +- x/sequencer/keeper/sequencer_test.go | 30 - x/sequencer/keeper/slashing.go | 71 +- x/sequencer/keeper/slashing_fraud_test.go | 99 +- x/sequencer/keeper/slashing_test.go | 34 +- x/sequencer/keeper/unbond.go | 223 ++- x/sequencer/keeper/unbond_test.go | 27 +- x/sequencer/module.go | 11 +- x/sequencer/types/errors.go | 2 + x/sequencer/types/events.go | 41 +- x/sequencer/types/genesis.go | 28 +- x/sequencer/types/genesis.pb.go | 323 ++++- x/sequencer/types/keys.go | 63 +- x/sequencer/types/operating_status.pb.go | 6 +- x/sequencer/types/params.go | 23 +- x/sequencer/types/params.pb.go | 117 +- x/sequencer/types/query.pb.go | 1272 ++++++++++++++--- x/sequencer/types/query.pb.gw.go | 202 +++ x/sequencer/types/sequencer.go | 23 +- x/sequencer/types/sequencer.pb.go | 178 ++- x/sequencer/types/tx.pb.go | 281 +++- 69 files changed, 3705 insertions(+), 1606 deletions(-) create mode 100644 utils/keys.go create mode 100644 x/sequencer/keeper/rotation.go create mode 100644 x/sequencer/keeper/rotation_test.go diff --git a/app/apptesting/test_suite.go b/app/apptesting/test_suite.go index 2790a370a..229500386 100644 --- a/app/apptesting/test_suite.go +++ b/app/apptesting/test_suite.go @@ -30,19 +30,25 @@ type KeeperTestHelper struct { Ctx sdk.Context } -func (s *KeeperTestHelper) CreateDefaultRollappWithProposer() (string, string) { - return s.CreateRollappWithNameWithProposer(urand.RollappID()) +func (s *KeeperTestHelper) CreateDefaultRollappAndProposer() (string, string) { + rollappId := s.CreateDefaultRollapp() + proposer := s.CreateDefaultSequencer(s.Ctx, rollappId) + return rollappId, proposer } -func (s *KeeperTestHelper) CreateRollappWithNameWithProposer(name string) (string, string) { - pubkey := ed25519.GenPrivKey().PubKey() - addr := sdk.AccAddress(pubkey.Address()) +// creates a rollapp and return its rollappID +func (s *KeeperTestHelper) CreateDefaultRollapp() string { + rollappId := urand.RollappID() + s.CreateRollappByName(rollappId) + return rollappId +} +func (s *KeeperTestHelper) CreateRollappByName(name string) { alias := strings.NewReplacer("_", "", "-", "").Replace(name) // base it on rollappID to avoid alias conflicts msgCreateRollapp := rollapptypes.MsgCreateRollapp{ Creator: alice, RollappId: name, - InitialSequencer: addr.String(), + InitialSequencer: "*", Bech32Prefix: strings.ToLower(rand.Str(3)), GenesisChecksum: "1234567890abcdefg", Alias: alias, @@ -57,24 +63,19 @@ func (s *KeeperTestHelper) CreateRollappWithNameWithProposer(name string) (strin }, } - // aliceBal := sdk.NewCoins(s.App.RollappKeeper.GetParams(s.Ctx).RegistrationFee) TODO: enable after x/dymns hooks are wired - // FundAccount(s.App, s.Ctx, sdk.MustAccAddressFromBech32(alice), aliceBal) - msgServer := rollappkeeper.NewMsgServerImpl(*s.App.RollappKeeper) _, err := msgServer.CreateRollapp(s.Ctx, &msgCreateRollapp) s.Require().NoError(err) - - err = s.CreateSequencer(s.Ctx, name, pubkey) - s.Require().NoError(err) - return name, addr.String() } -func (s *KeeperTestHelper) CreateDefaultSequencer(ctx sdk.Context, rollappId string) (string, error) { +func (s *KeeperTestHelper) CreateDefaultSequencer(ctx sdk.Context, rollappId string) string { pubkey := ed25519.GenPrivKey().PubKey() - return sdk.AccAddress(pubkey.Address()).String(), s.CreateSequencer(ctx, rollappId, pubkey) + err := s.CreateSequencerByPubkey(ctx, rollappId, pubkey) + s.Require().NoError(err) + return sdk.AccAddress(pubkey.Address()).String() } -func (s *KeeperTestHelper) CreateSequencer(ctx sdk.Context, rollappId string, pubKey types.PubKey) error { +func (s *KeeperTestHelper) CreateSequencerByPubkey(ctx sdk.Context, rollappId string, pubKey types.PubKey) error { addr := sdk.AccAddress(pubKey.Address()) // fund account err := bankutil.FundAccount(s.App.BankKeeper, ctx, addr, sdk.NewCoins(bond)) diff --git a/app/keepers/keepers.go b/app/keepers/keepers.go index e6b67c1b7..cc1f35fb7 100644 --- a/app/keepers/keepers.go +++ b/app/keepers/keepers.go @@ -350,7 +350,6 @@ func (a *AppKeepers) InitKeepers( a.SequencerKeeper = *sequencermodulekeeper.NewKeeper( appCodec, a.keys[sequencermoduletypes.StoreKey], - a.keys[sequencermoduletypes.MemStoreKey], a.GetSubspace(sequencermoduletypes.ModuleName), a.BankKeeper, a.RollappKeeper, diff --git a/app/upgrades/v4/upgrade.go b/app/upgrades/v4/upgrade.go index f80548933..b95166b22 100644 --- a/app/upgrades/v4/upgrade.go +++ b/app/upgrades/v4/upgrade.go @@ -50,7 +50,7 @@ func CreateUpgradeHandler( } migrateSequencers(ctx, keepers.SequencerKeeper) - // TODO: create rollapp gauges for each existing rollapp + // TODO: create rollapp gauges for each existing rollapp (https://github.com/dymensionxyz/dymension/issues/1005) // Start running the module migrations logger.Debug("running module migrations ...") @@ -129,11 +129,14 @@ func migrateSequencers(ctx sdk.Context, sequencerkeeper sequencerkeeper.Keeper) for _, oldSequencer := range list { newSequencer := ConvertOldSequencerToNew(oldSequencer) sequencerkeeper.SetSequencer(ctx, newSequencer) + + if oldSequencer.Proposer { + sequencerkeeper.SetProposer(ctx, oldSequencer.RollappId, oldSequencer.Address) + } } } func ConvertOldRollappToNew(oldRollapp rollapptypes.Rollapp) rollapptypes.Rollapp { - bech32Prefix := oldRollapp.RollappId[:5] return rollapptypes.Rollapp{ RollappId: oldRollapp.RollappId, Owner: oldRollapp.Owner, @@ -142,7 +145,7 @@ func ConvertOldRollappToNew(oldRollapp rollapptypes.Rollapp) rollapptypes.Rollap Frozen: oldRollapp.Frozen, RegisteredDenoms: oldRollapp.RegisteredDenoms, // TODO: regarding missing data - https://github.com/dymensionxyz/dymension/issues/986 - Bech32Prefix: bech32Prefix, // placeholder data + Bech32Prefix: oldRollapp.RollappId[:5], // placeholder data GenesisChecksum: string(crypto.Sha256([]byte(oldRollapp.RollappId))), // placeholder data VmType: rollapptypes.Rollapp_EVM, // placeholder data Metadata: &rollapptypes.RollappMetadata{ @@ -153,6 +156,8 @@ func ConvertOldRollappToNew(oldRollapp rollapptypes.Rollapp) rollapptypes.Rollap Telegram: "", X: "", }, + InitialSequencer: "*", + Sealed: true, } } @@ -164,7 +169,6 @@ func ConvertOldSequencerToNew(old sequencertypes.Sequencer) sequencertypes.Seque DymintPubKey: old.DymintPubKey, RollappId: old.RollappId, Status: old.Status, - Proposer: old.Proposer, Tokens: old.Tokens, Metadata: sequencertypes.SequencerMetadata{ Moniker: old.Metadata.Moniker, diff --git a/app/upgrades/v4/upgrade_test.go b/app/upgrades/v4/upgrade_test.go index f69e6e0c7..d52a4c7eb 100644 --- a/app/upgrades/v4/upgrade_test.go +++ b/app/upgrades/v4/upgrade_test.go @@ -116,6 +116,8 @@ func (s *UpgradeTestSuite) TestUpgrade() { return } + // TODO: check for rollapp gauges creation + return }, expPass: true, @@ -184,8 +186,9 @@ func (s *UpgradeTestSuite) validateRollappsMigration(numRoll int) error { } func (s *UpgradeTestSuite) validateSequencersMigration(numSeq int) error { - expectSequencers := make([]sequencertypes.Sequencer, numSeq) - for i, sequencer := range s.seedSequencers(numSeq) { + testSeqs := s.seedSequencers(numSeq) + expectSequencers := make([]sequencertypes.Sequencer, len(testSeqs)) + for i, sequencer := range testSeqs { expectSequencers[i] = v4.ConvertOldSequencerToNew(sequencer) } sequencers := s.App.SequencerKeeper.GetAllSequencers(s.Ctx) @@ -211,6 +214,13 @@ func (s *UpgradeTestSuite) validateSequencersMigration(numSeq int) error { s.Require().JSONEq(string(seq), string(nSeq)) } + + // check proposer + for _, rollapp := range s.App.RollappKeeper.GetAllRollapps(s.Ctx) { + _, found := s.App.SequencerKeeper.GetProposer(s.Ctx, rollapp.RollappId) + s.Assert().True(found) + } + return nil } @@ -242,25 +252,30 @@ func (s *UpgradeTestSuite) seedAndStoreSequencers(numRollapps int) { } } -func (s *UpgradeTestSuite) seedSequencers(numSeq int) []sequencertypes.Sequencer { - sequencers := make([]sequencertypes.Sequencer, numSeq) - for i := 0; i < numSeq; i++ { +func (s *UpgradeTestSuite) seedSequencers(numRollapps int) []sequencertypes.Sequencer { + numSeqPerRollapp := numRollapps + sequencers := make([]sequencertypes.Sequencer, 0, numSeqPerRollapp*numRollapps) + for i := 0; i < numRollapps; i++ { rollappID := rollappIDFromIdx(i) - pk := ed25519.GenPrivKeyFromSecret([]byte(rollappID)).PubKey() - pkAny, _ := codectypes.NewAnyWithValue(pk) - sequencer := sequencertypes.Sequencer{ - Address: sdk.AccAddress(pk.Address()).String(), - DymintPubKey: pkAny, - RollappId: rollappID, - Metadata: sequencertypes.SequencerMetadata{ - Moniker: fmt.Sprintf("sequencer-%d", i), - Details: fmt.Sprintf("Additional details about the sequencer-%d", i), - }, - Status: sequencertypes.Bonded, - Proposer: true, - Tokens: sdk.NewCoins(sdk.NewInt64Coin("dym", 100)), + + for j := 0; j < numSeqPerRollapp; j++ { + uuid := fmt.Sprintf("sequencer-%d-%d", i, j) + pk := ed25519.GenPrivKeyFromSecret([]byte(uuid)).PubKey() + pkAny, _ := codectypes.NewAnyWithValue(pk) + sequencer := sequencertypes.Sequencer{ + Address: sdk.AccAddress(pk.Address()).String(), + DymintPubKey: pkAny, + RollappId: rollappID, + Metadata: sequencertypes.SequencerMetadata{ + Moniker: uuid, + Details: fmt.Sprintf("Additional details about the %s", uuid), + }, + Status: sequencertypes.Bonded, + Tokens: sdk.NewCoins(sdk.NewInt64Coin("dym", 100)), + Proposer: j == 0, // first sequencer is proposer + } + sequencers = append(sequencers, sequencer) } - sequencers[i] = sequencer } return sequencers } diff --git a/go.mod b/go.mod index 04f35588a..846b61f7f 100644 --- a/go.mod +++ b/go.mod @@ -246,8 +246,5 @@ replace ( // broken goleveldb github.com/syndtr/goleveldb => github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 - // use cometbft - github.com/tendermint/tendermint => github.com/cometbft/cometbft v0.34.29 - golang.org/x/exp => golang.org/x/exp v0.0.0-20230711153332-06a737ee72cb ) diff --git a/proto/dymensionxyz/dymension/rollapp/tx.proto b/proto/dymensionxyz/dymension/rollapp/tx.proto index 06c155aba..1971932ff 100644 --- a/proto/dymensionxyz/dymension/rollapp/tx.proto +++ b/proto/dymensionxyz/dymension/rollapp/tx.proto @@ -88,6 +88,8 @@ message MsgUpdateState { // BDs is a list of block description objects (one per block) // the list must be ordered by height, starting from startHeight to startHeight+numBlocks-1 BlockDescriptors BDs = 7 [(gogoproto.nullable) = false]; + // last is true if this is the last batch of the sequencer + bool last = 8; } message MsgUpdateStateResponse { diff --git a/proto/dymensionxyz/dymension/sequencer/genesis.proto b/proto/dymensionxyz/dymension/sequencer/genesis.proto index 7073d2d62..ddfba68a0 100644 --- a/proto/dymensionxyz/dymension/sequencer/genesis.proto +++ b/proto/dymensionxyz/dymension/sequencer/genesis.proto @@ -9,7 +9,17 @@ option go_package = "github.com/dymensionxyz/dymension/v3/x/sequencer/types"; // GenesisState defines the sequencer module's genesis state. message GenesisState { - Params params = 1 [(gogoproto.nullable) = false]; - repeated Sequencer sequencerList = 2 [(gogoproto.nullable) = false]; - repeated BondReduction bondReductions = 3 [(gogoproto.nullable) = false]; + Params params = 1 [ (gogoproto.nullable) = false ]; + // sequencerList is a list of all defined sequencers + repeated Sequencer sequencerList = 2 [ (gogoproto.nullable) = false ]; + // genesisProposers is a list of the defined genesis proposers + repeated GenesisProposer genesisProposers = 3 + [ (gogoproto.nullable) = false ]; + // bondReductions is a list of all bond reductions + repeated BondReduction bondReductions = 4 [(gogoproto.nullable) = false]; } + +message GenesisProposer { + string address = 1; + string rollappId = 2; +} \ No newline at end of file diff --git a/proto/dymensionxyz/dymension/sequencer/operating_status.proto b/proto/dymensionxyz/dymension/sequencer/operating_status.proto index b80772e60..0ce95c1e1 100644 --- a/proto/dymensionxyz/dymension/sequencer/operating_status.proto +++ b/proto/dymensionxyz/dymension/sequencer/operating_status.proto @@ -2,16 +2,19 @@ syntax = "proto3"; package dymensionxyz.dymension.sequencer; import "gogoproto/gogo.proto"; - option go_package = "github.com/dymensionxyz/dymension/v3/x/sequencer/types"; // OperatingStatus defines the operating status of a sequencer enum OperatingStatus { option (gogoproto.goproto_enum_prefix) = false; - // OPERATING_STATUS_UNBONDED defines a sequencer that is not active and won't be scheduled - OPERATING_STATUS_UNBONDED = 0 [(gogoproto.enumvalue_customname) = "Unbonded"]; + // OPERATING_STATUS_UNBONDED defines a sequencer that is not active and won't + // be scheduled + OPERATING_STATUS_UNBONDED = 0 + [ (gogoproto.enumvalue_customname) = "Unbonded" ]; // UNBONDING defines a sequencer that is currently unbonding. - OPERATING_STATUS_UNBONDING = 1 [(gogoproto.enumvalue_customname) = "Unbonding"]; - // OPERATING_STATUS_BONDED defines a sequencer that is bonded and can be scheduled - OPERATING_STATUS_BONDED= 2 [(gogoproto.enumvalue_customname) = "Bonded"]; + OPERATING_STATUS_UNBONDING = 1 + [ (gogoproto.enumvalue_customname) = "Unbonding" ]; + // OPERATING_STATUS_BONDED defines a sequencer that is bonded and can be + // scheduled + OPERATING_STATUS_BONDED = 2 [ (gogoproto.enumvalue_customname) = "Bonded" ]; } \ No newline at end of file diff --git a/proto/dymensionxyz/dymension/sequencer/params.proto b/proto/dymensionxyz/dymension/sequencer/params.proto index a2aede599..5c276d59b 100644 --- a/proto/dymensionxyz/dymension/sequencer/params.proto +++ b/proto/dymensionxyz/dymension/sequencer/params.proto @@ -5,24 +5,30 @@ import "gogoproto/gogo.proto"; import "cosmos/base/v1beta1/coin.proto"; import "google/protobuf/duration.proto"; - option go_package = "github.com/dymensionxyz/dymension/v3/x/sequencer/types"; // Params defines the parameters for the module. message Params { - option (gogoproto.equal) = true; + option (gogoproto.equal) = true; option (gogoproto.goproto_stringer) = false; cosmos.base.v1beta1.Coin min_bond = 1 [ - (gogoproto.nullable) = false, - (gogoproto.jsontag) = "min_bond,omitempty" + (gogoproto.nullable) = false, + (gogoproto.jsontag) = "min_bond,omitempty" ]; // unbonding_time is the time duration of unbonding. - google.protobuf.Duration unbonding_time = 2 [(gogoproto.nullable) = false, (gogoproto.stdduration) = true]; + google.protobuf.Duration unbonding_time = 2 + [ (gogoproto.nullable) = false, (gogoproto.stdduration) = true ]; + // notice_period is the time duration of notice period. + // notice period is the duration between the unbond request and the actual + // unbonding starting. the proposer is still bonded during this period. + google.protobuf.Duration notice_period = 3 + [ (gogoproto.nullable) = false, (gogoproto.stdduration) = true ]; + // LivenessSlashMultiplier multiplies with the tokens of the slashed sequencer to compute the burn amount. - string liveness_slash_multiplier = 3 [ + string liveness_slash_multiplier = 4 [ (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", (gogoproto.moretags) = "yaml:\"liveness_slash_multiplier\"", (gogoproto.nullable) = false diff --git a/proto/dymensionxyz/dymension/sequencer/query.proto b/proto/dymensionxyz/dymension/sequencer/query.proto index fac2d7110..7cb15d4bf 100644 --- a/proto/dymensionxyz/dymension/sequencer/query.proto +++ b/proto/dymensionxyz/dymension/sequencer/query.proto @@ -18,65 +18,99 @@ service Query { } // Queries a Sequencer by address. - rpc Sequencer(QueryGetSequencerRequest) returns (QueryGetSequencerResponse) { - option (google.api.http).get = "/dymensionxyz/dymension/sequencer/sequencer/{sequencerAddress}"; - } - - // Queries a list of Sequencer items. - rpc Sequencers(QuerySequencersRequest) returns (QuerySequencersResponse) { - option (google.api.http).get = "/dymensionxyz/dymension/sequencer/sequencer"; - } - - // Queries a SequencersByRollapp by rollappId. - rpc SequencersByRollapp(QueryGetSequencersByRollappRequest) returns (QueryGetSequencersByRollappResponse) { - option (google.api.http).get = "/dymensionxyz/dymension/sequencer/sequencers_by_rollapp/{rollappId}"; - } - - // Queries a SequencersByRollappByStatus - rpc SequencersByRollappByStatus(QueryGetSequencersByRollappByStatusRequest) returns (QueryGetSequencersByRollappByStatusResponse) { - option (google.api.http).get = "/dymensionxyz/dymension/sequencer/sequencers_by_rollapp/{rollappId}/{status}"; - } + rpc Sequencer(QueryGetSequencerRequest) returns (QueryGetSequencerResponse) { + option (google.api.http).get = + "/dymensionxyz/dymension/sequencer/sequencer/{sequencerAddress}"; + } + + // Queries a list of Sequencer items. + rpc Sequencers(QuerySequencersRequest) returns (QuerySequencersResponse) { + option (google.api.http).get = + "/dymensionxyz/dymension/sequencer/sequencer"; + } + + // Queries a SequencersByRollapp by rollappId. + rpc SequencersByRollapp(QueryGetSequencersByRollappRequest) + returns (QueryGetSequencersByRollappResponse) { + option (google.api.http).get = + "/dymensionxyz/dymension/sequencer/sequencers_by_rollapp/{rollappId}"; + } + + // Queries a SequencersByRollappByStatus + rpc SequencersByRollappByStatus(QueryGetSequencersByRollappByStatusRequest) + returns (QueryGetSequencersByRollappByStatusResponse) { + option (google.api.http).get = "/dymensionxyz/dymension/sequencer/" + "sequencers_by_rollapp/{rollappId}/{status}"; + } + + // Queries the current proposer by rollappId. + rpc GetProposerByRollapp(QueryGetProposerByRollappRequest) + returns (QueryGetProposerByRollappResponse) { + option (google.api.http).get = + "/dymensionxyz/dymension/sequencer/proposer/{rollappId}"; + } + + // Queries the next proposer by rollappId. + rpc GetNextProposerByRollapp(QueryGetNextProposerByRollappRequest) + returns (QueryGetNextProposerByRollappResponse) { + option (google.api.http).get = + "/dymensionxyz/dymension/sequencer/next_proposer/{rollappId}"; + } } - + // QueryParamsRequest is request type for the Query/Params RPC method. message QueryParamsRequest {} // QueryParamsResponse is response type for the Query/Params RPC method. message QueryParamsResponse { // params holds all the parameters of this module. - Params params = 1 [(gogoproto.nullable) = false]; + Params params = 1 [ (gogoproto.nullable) = false ]; } -message QueryGetSequencerRequest { - string sequencerAddress = 1; -} +message QueryGetSequencerRequest { string sequencerAddress = 1; } message QueryGetSequencerResponse { - Sequencer sequencer = 1 [(gogoproto.nullable) = false]; + Sequencer sequencer = 1 [ (gogoproto.nullable) = false ]; } message QuerySequencersRequest { - cosmos.base.query.v1beta1.PageRequest pagination = 1; + cosmos.base.query.v1beta1.PageRequest pagination = 1; } message QuerySequencersResponse { - repeated Sequencer sequencers = 1 [(gogoproto.nullable) = false]; - cosmos.base.query.v1beta1.PageResponse pagination = 2; + repeated Sequencer sequencers = 1 [ (gogoproto.nullable) = false ]; + cosmos.base.query.v1beta1.PageResponse pagination = 2; } -message QueryGetSequencersByRollappRequest { - string rollappId = 1; -} +message QueryGetSequencersByRollappRequest { string rollappId = 1; } message QueryGetSequencersByRollappResponse { - repeated Sequencer sequencers = 1 [(gogoproto.nullable) = false]; + repeated Sequencer sequencers = 1 [ (gogoproto.nullable) = false ]; } message QueryGetSequencersByRollappByStatusRequest { - string rollappId = 1; - OperatingStatus status = 2; + string rollappId = 1; + OperatingStatus status = 2; } message QueryGetSequencersByRollappByStatusResponse { - repeated Sequencer sequencers = 1 [(gogoproto.nullable) = false]; + repeated Sequencer sequencers = 1 [ (gogoproto.nullable) = false ]; +} + +// Request type for the GetProposerByRollapp RPC method. +message QueryGetProposerByRollappRequest { string rollappId = 1; } + +// Response type for the GetProposerByRollapp RPC method. +message QueryGetProposerByRollappResponse { string proposerAddr = 1; } + +// Request type for the GetNextProposerByRollapp RPC method. +message QueryGetNextProposerByRollappRequest { string rollappId = 1; } + +// Response type for the GetNextProposerByRollapp RPC method. +message QueryGetNextProposerByRollappResponse { + // nextProposerAddr is the address of the next proposer. + // can be empty if no sequencer is available to be the next proposer. + string nextProposerAddr = 1; + // rotationInProgress is true if the proposer rotation is in progress. + bool rotationInProgress = 2; } diff --git a/proto/dymensionxyz/dymension/sequencer/sequencer.proto b/proto/dymensionxyz/dymension/sequencer/sequencer.proto index c49fd5774..e880dc41b 100644 --- a/proto/dymensionxyz/dymension/sequencer/sequencer.proto +++ b/proto/dymensionxyz/dymension/sequencer/sequencer.proto @@ -26,17 +26,27 @@ message Sequencer { SequencerMetadata metadata = 4 [(gogoproto.nullable) = false]; // jailed defined whether the sequencer has been jailed from bonded status or not. bool jailed = 5; - // proposer defines whether the sequencer is a proposer or not. - bool proposer = 6; + + bool proposer = 6 [deprecated = true]; + // status is the sequencer status (bonded/unbonding/unbonded). OperatingStatus status = 7; // tokens define the delegated tokens (incl. self-delegation). - repeated cosmos.base.v1beta1.Coin tokens = 8 - [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; - // unbonding_height defines, if unbonding, the height at which this sequencer has begun unbonding. - int64 unbonding_height = 9; - // unbond_time defines, if unbonding, the min time for the sequencer to complete unbonding. - google.protobuf.Timestamp unbond_time = 10 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true]; + repeated cosmos.base.v1beta1.Coin tokens = 8 [ + (gogoproto.nullable) = false, + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins" + ]; + + // unbond_request_height stores the height at which this sequencer has + // requested to unbond. + int64 unbond_request_height = 9; + // unbond_time defines the time when the sequencer will complete unbonding. + google.protobuf.Timestamp unbond_time = 10 + [ (gogoproto.nullable) = false, (gogoproto.stdtime) = true ]; + + // notice_period_time defines the time when the sequencer will finish it's notice period if started + google.protobuf.Timestamp notice_period_time = 11 + [ (gogoproto.nullable) = false, (gogoproto.stdtime) = true ]; } // BondReduction defines an object which holds the information about the sequencer and its queued unbonding amount diff --git a/proto/dymensionxyz/dymension/sequencer/tx.proto b/proto/dymensionxyz/dymension/sequencer/tx.proto index fba0bead3..6eb8a9e62 100644 --- a/proto/dymensionxyz/dymension/sequencer/tx.proto +++ b/proto/dymensionxyz/dymension/sequencer/tx.proto @@ -66,7 +66,14 @@ message MsgUnbond { // MsgUnbondResponse defines the Msg/Unbond response type. message MsgUnbondResponse { - google.protobuf.Timestamp completion_time = 1 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true]; + // completion_time defines the time at which the unbonding will be completed. + // If unbonding the proposer, the completion time is the time at which the notice period will be completed. + oneof completion_time { + // unbonding_completion_time is the time at which the unbonding will be completed. + google.protobuf.Timestamp unbonding_completion_time = 1 [ (gogoproto.stdtime) = true]; + // notice_period_completion_time is the time at which the notice period will be completed. + google.protobuf.Timestamp notice_period_completion_time = 2 [ (gogoproto.stdtime) = true]; + } } // MsgIncreaseBond defines a SDK message for increasing the bond amount of a sequencer. diff --git a/scripts/src/genesis_config_commands.sh b/scripts/src/genesis_config_commands.sh index bcbb4b004..691594166 100644 --- a/scripts/src/genesis_config_commands.sh +++ b/scripts/src/genesis_config_commands.sh @@ -15,6 +15,10 @@ set_hub_params() { sed -i'' -e 's/mint_denom": ".*"/mint_denom": "adym"/' "$GENESIS_FILE" jq '.app_state.rollapp.params.dispute_period_in_blocks = "50"' "$GENESIS_FILE" > "$tmp" && mv "$tmp" "$GENESIS_FILE" + + + jq '.app_state.sequencer.params.unbonding_time = "60s"' "$GENESIS_FILE" > "$tmp" && mv "$tmp" "$GENESIS_FILE" + jq '.app_state.sequencer.params.notice_period = "60s"' "$GENESIS_FILE" > "$tmp" && mv "$tmp" "$GENESIS_FILE" #increase the tx size cost per byte from 10 to 100 jq '.app_state.auth.params.tx_size_cost_per_byte = "100"' "$GENESIS_FILE" > "$tmp" && mv "$tmp" "$GENESIS_FILE" diff --git a/testutil/keeper/sequencer.go b/testutil/keeper/sequencer.go index e1144829e..cd5386a0c 100644 --- a/testutil/keeper/sequencer.go +++ b/testutil/keeper/sequencer.go @@ -21,7 +21,7 @@ import ( func SequencerKeeper(t testing.TB) (*keeper.Keeper, sdk.Context) { storeKey := sdk.NewKVStoreKey(types.StoreKey) - memStoreKey := storetypes.NewMemoryStoreKey(types.MemStoreKey) + memStoreKey := storetypes.NewMemoryStoreKey(types.StoreKey + "_transient") db := cometbftdb.NewMemDB() stateStore := store.NewCommitMultiStore(db) @@ -41,7 +41,6 @@ func SequencerKeeper(t testing.TB) (*keeper.Keeper, sdk.Context) { k := keeper.NewKeeper( cdc, storeKey, - memStoreKey, paramsSubspace, nil, &rollappkeeper.Keeper{}, diff --git a/utils/keys.go b/utils/keys.go new file mode 100644 index 000000000..4289a5e0c --- /dev/null +++ b/utils/keys.go @@ -0,0 +1,37 @@ +package utils + +import ( + "time" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// TODO: move to sdk-utils (https://github.com/dymensionxyz/dymension/issues/1008) + +// EncodeTimeToKey combines a given byte slice (queueKey) with an encoded representation of a specified time (endTime). +// The resulting byte slice can be used for lexicographical sorting, as the encoded time is in big-endian order. +// +// The function ensures that different times will be sorted correctly when iterated using big-endian order, +// as the time encoding preserves the natural chronological order. +// +// Example: +// +// queueKey := []byte("exampleKey") +// endTime1 := time.Date(2023, time.October, 1, 12, 0, 0, 0, time.UTC) +// endTime2 := time.Date(2023, time.October, 2, 12, 0, 0, 0, time.UTC) +// encodedKey1 := EncodeTimeToKey(queueKey, endTime1) +// encodedKey2 := EncodeTimeToKey(queueKey, endTime2) +// fmt.Printf("%x\n", encodedKey1) // Output will be the hexadecimal representation of the combined byte slice for endTime1 +// fmt.Printf("%x\n", encodedKey2) // Output will be the hexadecimal representation of the combined byte slice for endTime2 +// fmt.Println(string(encodedKey1) < string(encodedKey2)) // This will print 'true' as endTime1 is before endTime2 +func EncodeTimeToKey(queueKey []byte, endTime time.Time) []byte { + timeBz := sdk.FormatTimeBytes(endTime) + prefixL := len(queueKey) + bz := make([]byte, prefixL+len(timeBz)) + + // copy the prefix + copy(bz[:prefixL], queueKey) + // copy the encoded time bytes + copy(bz[prefixL:], timeBz) + return bz +} diff --git a/x/delayedack/keeper/invariants_test.go b/x/delayedack/keeper/invariants_test.go index 1d8d18564..9c30669a7 100644 --- a/x/delayedack/keeper/invariants_test.go +++ b/x/delayedack/keeper/invariants_test.go @@ -31,7 +31,7 @@ func (suite *DelayedAckTestSuite) TestInvariants() { rollappBlocks := make(map[string]uint64) for i := 0; i < numOfRollapps; i++ { - rollapp, seqaddr := suite.CreateDefaultRollappWithProposer() + rollapp, seqaddr := suite.CreateDefaultRollappAndProposer() // skip one of the rollapps so it won't have any state updates if i == 0 { @@ -236,7 +236,8 @@ func (suite *DelayedAckTestSuite) TestRollappPacketsCasesInvariant() { // create rollapp suite.SetupTest() ctx := suite.Ctx - _, proposer := suite.CreateRollappWithNameWithProposer(rollapp) + suite.CreateRollappByName(rollapp) + proposer := suite.CreateDefaultSequencer(ctx, rollapp) // update state infos stateInfo := rollapptypes.StateInfo{ diff --git a/x/rollapp/keeper/block_height_to_finalization_queue_test.go b/x/rollapp/keeper/block_height_to_finalization_queue_test.go index 2b5969a92..87ee4d81e 100644 --- a/x/rollapp/keeper/block_height_to_finalization_queue_test.go +++ b/x/rollapp/keeper/block_height_to_finalization_queue_test.go @@ -28,7 +28,7 @@ func (suite *RollappTestSuite) TestGetAllFinalizationQueueUntilHeight() { ctx := &suite.Ctx k := suite.App.RollappKeeper - rollapp, proposer := suite.CreateDefaultRollappWithProposer() + rollapp, proposer := suite.CreateDefaultRollappAndProposer() // Create 2 state updates _, err := suite.PostStateUpdate(*ctx, rollapp, proposer, 1, uint64(10)) suite.Require().Nil(err) @@ -298,12 +298,13 @@ func (suite *RollappTestSuite) TestFinalizeRollapps() { for _, rf := range tt.fields.rollappStateUpdates { // Create a rollapp - rollapp, proposer := suite.CreateRollappWithNameWithProposer(rf.rollappId) + suite.CreateRollappByName(rf.rollappId) + proposer := suite.CreateDefaultSequencer(suite.Ctx, rf.rollappId) // Create state update for _, su := range rf.stateUpdates { suite.Ctx = suite.Ctx.WithBlockHeight(su.blockHeight) - _, err := suite.PostStateUpdate(*ctx, rollapp, proposer, su.startHeight, su.numOfBlocks) + _, err := suite.PostStateUpdate(*ctx, rf.rollappId, proposer, su.startHeight, su.numOfBlocks) suite.Require().Nil(err) } } @@ -361,7 +362,7 @@ func (suite *RollappTestSuite) TestFinalize() { k := suite.App.RollappKeeper // Create a rollapp - rollapp, proposer := suite.CreateDefaultRollappWithProposer() + rollapp, proposer := suite.CreateDefaultRollappAndProposer() // Create 2 state updates _, err := suite.PostStateUpdate(*ctx, rollapp, proposer, 1, uint64(10)) @@ -643,6 +644,7 @@ func (suite *RollappTestSuite) setMockErrRollappKeeperHooks(failIndexes []types. var _ types.RollappHooks = mockRollappHooks{} type mockRollappHooks struct { + types.StubRollappCreatedHooks failIndexes []types.StateInfoIndex } @@ -652,8 +654,3 @@ func (m mockRollappHooks) AfterStateFinalized(_ sdk.Context, _ string, stateInfo } return } -func (m mockRollappHooks) BeforeUpdateState(sdk.Context, string, string) error { return nil } -func (m mockRollappHooks) FraudSubmitted(sdk.Context, string, uint64, string) error { return nil } -func (m mockRollappHooks) RollappCreated(sdk.Context, string, string, sdk.AccAddress) error { - return nil -} diff --git a/x/rollapp/keeper/fraud_handler_test.go b/x/rollapp/keeper/fraud_handler_test.go index 602c4081e..c73d1fbd2 100644 --- a/x/rollapp/keeper/fraud_handler_test.go +++ b/x/rollapp/keeper/fraud_handler_test.go @@ -25,13 +25,12 @@ func (suite *RollappTestSuite) TestHandleFraud() { fraudHeight := uint64(300) // unrelated rollapp just to validate it's unaffected - rollapp2, proposer2 := suite.CreateDefaultRollappWithProposer() + rollapp2, proposer2 := suite.CreateDefaultRollappAndProposer() // create rollapp and sequencers before fraud evidence - rollapp, proposer := suite.CreateDefaultRollappWithProposer() + rollapp, proposer := suite.CreateDefaultRollappAndProposer() for i := uint64(0); i < numOfSequencers-1; i++ { - _, err = suite.CreateDefaultSequencer(*ctx, rollapp) - suite.Require().Nil(err) + _ = suite.CreateDefaultSequencer(*ctx, rollapp) } // send state updates @@ -64,7 +63,7 @@ func (suite *RollappTestSuite) TestHandleFraud_InvalidRollapp() { ctx := &suite.Ctx keeper := suite.App.RollappKeeper - rollapp, proposer := suite.CreateDefaultRollappWithProposer() + rollapp, proposer := suite.CreateDefaultRollappAndProposer() _, err := suite.PostStateUpdate(*ctx, rollapp, proposer, 1, uint64(10)) suite.Require().Nil(err) @@ -77,7 +76,7 @@ func (suite *RollappTestSuite) TestHandleFraud_WrongHeight() { ctx := &suite.Ctx keeper := suite.App.RollappKeeper - rollapp, proposer := suite.CreateDefaultRollappWithProposer() + rollapp, proposer := suite.CreateDefaultRollappAndProposer() _, err := suite.PostStateUpdate(*ctx, rollapp, proposer, 1, uint64(10)) suite.Require().Nil(err) @@ -90,7 +89,7 @@ func (suite *RollappTestSuite) TestHandleFraud_WrongSequencer() { ctx := &suite.Ctx keeper := suite.App.RollappKeeper - rollapp, proposer := suite.CreateDefaultRollappWithProposer() + rollapp, proposer := suite.CreateDefaultRollappAndProposer() _, err := suite.PostStateUpdate(*ctx, rollapp, proposer, 1, uint64(10)) suite.Require().Nil(err) @@ -103,7 +102,7 @@ func (suite *RollappTestSuite) TestHandleFraud_WrongChannelID() { ctx := &suite.Ctx keeper := suite.App.RollappKeeper - rollapp, proposer := suite.CreateDefaultRollappWithProposer() + rollapp, proposer := suite.CreateDefaultRollappAndProposer() _, err := suite.PostStateUpdate(*ctx, rollapp, proposer, 1, uint64(10)) suite.Require().Nil(err) @@ -119,10 +118,9 @@ func (suite *RollappTestSuite) TestHandleFraud_AlreadyReverted() { numOfSequencers := uint64(3) - 1 // already created one with rollapp numOfStates := uint64(10) - rollapp, proposer := suite.CreateDefaultRollappWithProposer() + rollapp, proposer := suite.CreateDefaultRollappAndProposer() for i := uint64(0); i < numOfSequencers-1; i++ { - _, err = suite.CreateDefaultSequencer(*ctx, rollapp) - suite.Require().Nil(err) + _ = suite.CreateDefaultSequencer(*ctx, rollapp) } // send state updates @@ -146,7 +144,7 @@ func (suite *RollappTestSuite) TestHandleFraud_AlreadyFinalized() { ctx := &suite.Ctx keeper := suite.App.RollappKeeper - rollapp, proposer := suite.CreateDefaultRollappWithProposer() + rollapp, proposer := suite.CreateDefaultRollappAndProposer() _, err := suite.PostStateUpdate(*ctx, rollapp, proposer, 1, uint64(10)) suite.Require().Nil(err) @@ -205,10 +203,12 @@ func (suite *RollappTestSuite) assertFraudHandled(rollappId string) { suite.Require().True(rollapp.Frozen) // check sequencers - sequencers := suite.App.SequencerKeeper.GetSequencersByRollapp(suite.Ctx, rollappId) - for _, sequencer := range sequencers { - suite.Require().Equal(types.Unbonded, sequencer.Status) - } + sequencers := suite.App.SequencerKeeper.GetSequencersByRollappByStatus(suite.Ctx, rollappId, types.Bonded) + suite.Require().Equal(0, len(sequencers)) + _, ok := suite.App.SequencerKeeper.GetProposer(suite.Ctx, rollappId) + suite.Require().False(ok) + seq := suite.App.SequencerKeeper.ExpectedNextProposer(suite.Ctx, rollappId) + suite.Require().Empty(seq.Address) // check states finalIdx, _ := suite.App.RollappKeeper.GetLatestFinalizedStateIndex(suite.Ctx, rollappId) diff --git a/x/rollapp/keeper/invariants_test.go b/x/rollapp/keeper/invariants_test.go index 25a43c1be..e0e6ff3d2 100644 --- a/x/rollapp/keeper/invariants_test.go +++ b/x/rollapp/keeper/invariants_test.go @@ -18,7 +18,7 @@ func (suite *RollappTestSuite) TestInvariants() { // create rollapps seqPerRollapp := make(map[string]string) for i := 0; i < numOfRollapps; i++ { - rollapp, seqaddr := suite.CreateDefaultRollappWithProposer() + rollapp, seqaddr := suite.CreateDefaultRollappAndProposer() // skip one of the rollapps so it won't have any state updates if i == 0 { @@ -27,10 +27,10 @@ func (suite *RollappTestSuite) TestInvariants() { seqPerRollapp[rollapp] = seqaddr } - rollapp, seqaddr := suite.CreateRollappWithNameWithProposer("dym_1100-1") + rollapp, seqaddr := suite.CreateDefaultRollappAndProposer() seqPerRollapp[rollapp] = seqaddr - rollapp, seqaddr = suite.CreateRollappWithNameWithProposer("dymd_1101-2") + rollapp, seqaddr = suite.CreateDefaultRollappAndProposer() seqPerRollapp[rollapp] = seqaddr // send state updates @@ -142,7 +142,9 @@ func (suite *RollappTestSuite) TestRollappFinalizedStateInvariant() { for _, tc := range cases { suite.Run(tc.name, func() { // create rollapp - suite.CreateRollappWithNameWithProposer(tc.rollappId) + suite.CreateRollappByName(tc.rollappId) + // create sequencer + suite.CreateDefaultSequencer(ctx, tc.rollappId) // update state infos if tc.stateInfo != nil { suite.App.RollappKeeper.SetStateInfo(ctx, *tc.stateInfo) diff --git a/x/rollapp/keeper/msg_server_update_rollapp_test.go b/x/rollapp/keeper/msg_server_update_rollapp_test.go index 11a0758e2..b439a1f87 100644 --- a/x/rollapp/keeper/msg_server_update_rollapp_test.go +++ b/x/rollapp/keeper/msg_server_update_rollapp_test.go @@ -177,7 +177,7 @@ func (suite *RollappTestSuite) TestCreateAndUpdateRollapp() { suite.Require().NoError(err) // 2. try to register sequencer (not initial) - should fail because rollapp is not sealed - _, err = suite.CreateDefaultSequencer(suite.Ctx, rollappId) + err = suite.CreateSequencerByPubkey(suite.Ctx, rollappId, ed25519.GenPrivKey().PubKey()) suite.Require().ErrorIs(err, sequencertypes.ErrNotInitialSequencer) // 3. update rollapp immutable fields, set InitialSequencer, Alias and GenesisChecksum @@ -194,11 +194,13 @@ func (suite *RollappTestSuite) TestCreateAndUpdateRollapp() { // 4. register sequencer (initial) - should be proposer; rollapp should be sealed // from this point on, the rollapp is sealed and immutable fields cannot be updated - err = suite.CreateSequencer(suite.Ctx, rollappId, initSeqPubKey) + err = suite.CreateSequencerByPubkey(suite.Ctx, rollappId, initSeqPubKey) suite.Require().NoError(err) initSeq, ok := suite.App.SequencerKeeper.GetSequencer(suite.Ctx, addrInit) suite.Require().True(ok) - suite.Require().True(initSeq.Proposer) + proposer, found := suite.App.SequencerKeeper.GetProposer(suite.Ctx, rollappId) + suite.Require().True(found) + suite.Require().Equal(initSeq, proposer) rollapp, ok := suite.App.RollappKeeper.GetRollapp(suite.Ctx, rollappId) suite.Require().True(ok) suite.Require().True(rollapp.Sealed) @@ -212,11 +214,10 @@ func (suite *RollappTestSuite) TestCreateAndUpdateRollapp() { suite.Require().ErrorIs(err, types.ErrImmutableFieldUpdateAfterSealed) // 6. register another sequencer - should not be proposer - newSeqAddr, err := suite.CreateDefaultSequencer(suite.Ctx, rollappId) - suite.Require().NoError(err) - newSequencer, ok := suite.App.SequencerKeeper.GetSequencer(suite.Ctx, newSeqAddr) - suite.Require().True(ok) - suite.Require().False(newSequencer.Proposer) + newSeqAddr := suite.CreateDefaultSequencer(suite.Ctx, rollappId) + proposer, found = suite.App.SequencerKeeper.GetProposer(suite.Ctx, rollappId) + suite.Require().True(found) + suite.Require().NotEqual(proposer, newSeqAddr) // 7. create state update suite.App.RollappKeeper.SetLatestStateInfoIndex(suite.Ctx, types.StateInfoIndex{ diff --git a/x/rollapp/keeper/msg_server_update_state.go b/x/rollapp/keeper/msg_server_update_state.go index 6e225d50a..7a10230bc 100644 --- a/x/rollapp/keeper/msg_server_update_state.go +++ b/x/rollapp/keeper/msg_server_update_state.go @@ -19,12 +19,10 @@ func (k msgServer) UpdateState(goCtx context.Context, msg *types.MsgUpdateState) } // call the before-update-state hook - // checks if: - // 1. creator is the sequencer - // 2. sequencer rollappId matches the rollappId - // 3. sequencer is bonded - // 4. sequencer is the proposer - err := k.hooks.BeforeUpdateState(ctx, msg.Creator, msg.RollappId) + // currently used by `x/sequencer` to: + // 1. validate the state update submitter + // 2. complete the rotation of the proposer if needed + err := k.hooks.BeforeUpdateState(ctx, msg.Creator, msg.RollappId, msg.Last) if err != nil { return nil, err } @@ -83,6 +81,8 @@ func (k msgServer) UpdateState(goCtx context.Context, msg *types.MsgUpdateState) FinalizationQueue: newFinalizationQueue, }) + // TODO: enforce `final_state_update_timeout` if sequencer rotation is in progress + // https://github.com/dymensionxyz/dymension/issues/1085 k.IndicateLiveness(ctx, &rollapp) ctx.EventManager().EmitEvent( diff --git a/x/rollapp/keeper/msg_server_update_state_test.go b/x/rollapp/keeper/msg_server_update_state_test.go index 9c80ec5ce..c2448b0db 100644 --- a/x/rollapp/keeper/msg_server_update_state_test.go +++ b/x/rollapp/keeper/msg_server_update_state_test.go @@ -12,98 +12,31 @@ import ( sequencertypes "github.com/dymensionxyz/dymension/v3/x/sequencer/types" ) -// TODO: refactor the tests to use test-cases -// TODO: wrap the create rollapp and sequencer into a helper function func (suite *RollappTestSuite) TestFirstUpdateState() { - goCtx := sdk.WrapSDKContext(suite.Ctx) - - // set rollapp - rollapp := types.Rollapp{ - RollappId: urand.RollappID(), - Owner: alice, - InitialSequencer: sample.AccAddress(), - GenesisChecksum: "checksum", - Bech32Prefix: "rol", - Metadata: &types.RollappMetadata{ - Website: "https://dymension.xyz", - Description: "Sample description", - LogoDataUri: "data:image/png;base64,c2lzZQ==", - TokenLogoDataUri: "data:image/png;base64,ZHVwZQ==", - Telegram: "https://t.me/rolly", - X: "https://x.dymension.xyz", - }, - } - suite.App.RollappKeeper.SetRollapp(suite.Ctx, rollapp) - - // set sequencer - sequencer := sequencertypes.Sequencer{ - Address: bob, - RollappId: rollapp.GetRollappId(), - Status: sequencertypes.Bonded, - Proposer: true, - } - suite.App.SequencerKeeper.SetSequencer(suite.Ctx, sequencer) + rollappId, proposer := suite.CreateDefaultRollappAndProposer() // check no index exists - _, found := suite.App.RollappKeeper.GetLatestStateInfoIndex(suite.Ctx, rollapp.GetRollappId()) - suite.Require().EqualValues(false, found) + _, found := suite.App.RollappKeeper.GetLatestStateInfoIndex(suite.Ctx, rollappId) + suite.Require().False(found) - // update state - updateState := types.MsgUpdateState{ - Creator: bob, - RollappId: rollapp.GetRollappId(), - StartHeight: 1, - NumBlocks: 3, - DAPath: "", - BDs: types.BlockDescriptors{BD: []types.BlockDescriptor{{Height: 1}, {Height: 1}, {Height: 2}}}, - } - - _, err := suite.msgServer.UpdateState(goCtx, &updateState) - suite.Require().Nil(err) + _, err := suite.PostStateUpdate(suite.Ctx, rollappId, proposer, 1, uint64(3)) + suite.Require().NoError(err) // check first index is 1 - expectedLatestStateInfoIndex, found := suite.App.RollappKeeper.GetLatestStateInfoIndex(suite.Ctx, rollapp.GetRollappId()) - suite.Require().EqualValues(true, found) - suite.Require().EqualValues(expectedLatestStateInfoIndex.Index, 1) + expectedLatestStateInfoIndex, found := suite.App.RollappKeeper.GetLatestStateInfoIndex(suite.Ctx, rollappId) + suite.Require().True(found) + suite.Require().Equal(expectedLatestStateInfoIndex.Index, uint64(1)) } func (suite *RollappTestSuite) TestUpdateState() { - goCtx := sdk.WrapSDKContext(suite.Ctx) - // parameters disputePeriodInBlocks := suite.App.RollappKeeper.DisputePeriodInBlocks(suite.Ctx) // set rollapp - rollapp := types.Rollapp{ - RollappId: urand.RollappID(), - Owner: alice, - InitialSequencer: sample.AccAddress(), - Bech32Prefix: "rol", - GenesisChecksum: "checksum", - } - suite.App.RollappKeeper.SetRollapp(suite.Ctx, rollapp) - - // set sequencer - sequencer := sequencertypes.Sequencer{ - Address: bob, - RollappId: rollapp.GetRollappId(), - Status: sequencertypes.Bonded, - Proposer: true, - } - suite.App.SequencerKeeper.SetSequencer(suite.Ctx, sequencer) + rollappId, proposer := suite.CreateDefaultRollappAndProposer() // create new update - updateState := types.MsgUpdateState{ - Creator: bob, - RollappId: rollapp.GetRollappId(), - StartHeight: 1, - NumBlocks: 3, - DAPath: "", - BDs: types.BlockDescriptors{BD: []types.BlockDescriptor{{Height: 1}, {Height: 2}, {Height: 3}}}, - } - - // update state - _, err := suite.msgServer.UpdateState(goCtx, &updateState) + _, err := suite.PostStateUpdate(suite.Ctx, rollappId, proposer, 1, uint64(3)) suite.Require().Nil(err) // test 10 update state @@ -119,15 +52,14 @@ func (suite *RollappTestSuite) TestUpdateState() { } suite.Ctx = suite.Ctx.WithBlockHeight(suite.Ctx.BlockHeader().Height + 1) - goCtx = sdk.WrapSDKContext(suite.Ctx) // calc new updateState - latestStateInfoIndex, found := suite.App.RollappKeeper.GetLatestStateInfoIndex(suite.Ctx, rollapp.GetRollappId()) + latestStateInfoIndex, found := suite.App.RollappKeeper.GetLatestStateInfoIndex(suite.Ctx, rollappId) suite.Require().EqualValues(true, found) // verify index suite.Require().EqualValues(i+1, latestStateInfoIndex.Index) // load last state info - expectedStateInfo, found := suite.App.RollappKeeper.GetStateInfo(suite.Ctx, rollapp.GetRollappId(), latestStateInfoIndex.GetIndex()) + expectedStateInfo, found := suite.App.RollappKeeper.GetStateInfo(suite.Ctx, rollappId, latestStateInfoIndex.GetIndex()) suite.Require().EqualValues(true, found) // verify finalization queue @@ -137,18 +69,8 @@ func (suite *RollappTestSuite) TestUpdateState() { FinalizationQueue: []types.StateInfoIndex{latestStateInfoIndex}, }, "finalization queue", "i", i) - // create new update - updateState := types.MsgUpdateState{ - Creator: bob, - RollappId: rollapp.GetRollappId(), - StartHeight: expectedStateInfo.StartHeight + expectedStateInfo.NumBlocks, - NumBlocks: 2, - DAPath: "", - BDs: types.BlockDescriptors{BD: []types.BlockDescriptor{{Height: expectedStateInfo.StartHeight}, {Height: expectedStateInfo.StartHeight + 1}}}, - } - // update state - _, err := suite.msgServer.UpdateState(goCtx, &updateState) + _, err := suite.PostStateUpdate(suite.Ctx, rollappId, proposer, expectedStateInfo.StartHeight+expectedStateInfo.NumBlocks, uint64(2)) suite.Require().Nil(err) // end block @@ -156,7 +78,7 @@ func (suite *RollappTestSuite) TestUpdateState() { if uint64(suite.Ctx.BlockHeight()) > disputePeriodInBlocks { for i := uint64(1); i <= latestStateInfoIndex.Index; i++ { - expectedStateInfo, _ := suite.App.RollappKeeper.GetStateInfo(suite.Ctx, rollapp.GetRollappId(), i) + expectedStateInfo, _ := suite.App.RollappKeeper.GetStateInfo(suite.Ctx, rollappId, i) if expectedStateInfo.CreationHeight < uint64(suite.Ctx.BlockHeight())-disputePeriodInBlocks { suite.Require().EqualValues(expectedStateInfo.Status, common.Status_FINALIZED) } @@ -165,97 +87,36 @@ func (suite *RollappTestSuite) TestUpdateState() { // check finalization status change pendingQueues := suite.App.RollappKeeper.GetAllFinalizationQueueUntilHeightInclusive(suite.Ctx, uint64(suite.Ctx.BlockHeader().Height)) - for _, finalizationQueue := range pendingQueues { - - // fmt.Printf("finalizationQueue: %s %d\n", finalizationQueue.String()) stateInfo, found := suite.App.RollappKeeper.GetStateInfo(suite.Ctx, finalizationQueue.FinalizationQueue[0].RollappId, finalizationQueue.FinalizationQueue[0].Index) suite.Require().True(found) suite.Require().EqualValues(stateInfo.Status, common.Status_PENDING) - } } } func (suite *RollappTestSuite) TestUpdateStateUnknownRollappId() { - goCtx := sdk.WrapSDKContext(suite.Ctx) - - // update state of unknown rollapp - updateState := types.MsgUpdateState{ - Creator: bob, - RollappId: urand.RollappID(), - StartHeight: 1, - NumBlocks: 3, - DAPath: "", - BDs: types.BlockDescriptors{BD: []types.BlockDescriptor{{Height: 1}, {Height: 2}, {Height: 3}}}, - } - - _, err := suite.msgServer.UpdateState(goCtx, &updateState) + _, err := suite.PostStateUpdate(suite.Ctx, "unknown_rollapp", alice, 1, uint64(3)) suite.EqualError(err, types.ErrUnknownRollappID.Error()) } -// FIXME: need to add sequncer to rollapp to test this scenario func (suite *RollappTestSuite) TestUpdateStateUnknownSequencer() { - goCtx := sdk.WrapSDKContext(suite.Ctx) - - // set rollapp - rollapp := types.Rollapp{ - RollappId: urand.RollappID(), - Owner: alice, - InitialSequencer: sample.AccAddress(), - Bech32Prefix: "rol", - GenesisChecksum: "checksum", - } - suite.App.RollappKeeper.SetRollapp(suite.Ctx, rollapp) + rollappId, _ := suite.CreateDefaultRollappAndProposer() // update state - updateState := types.MsgUpdateState{ - Creator: bob, - RollappId: rollapp.GetRollappId(), - StartHeight: 1, - NumBlocks: 3, - DAPath: "", - BDs: types.BlockDescriptors{BD: []types.BlockDescriptor{{Height: 1}, {Height: 2}, {Height: 3}}}, - } - - _, err := suite.msgServer.UpdateState(goCtx, &updateState) - suite.ErrorIs(err, sequencertypes.ErrUnknownSequencer) + _, err := suite.PostStateUpdate(suite.Ctx, rollappId, bob, 1, uint64(3)) + suite.ErrorIs(err, sequencertypes.ErrNotActiveSequencer) } func (suite *RollappTestSuite) TestUpdateStateSequencerRollappMismatch() { - goCtx := sdk.WrapSDKContext(suite.Ctx) - - // set rollapp - rollapp := types.Rollapp{ - RollappId: urand.RollappID(), - Owner: alice, - InitialSequencer: sample.AccAddress(), - Bech32Prefix: "rol", - GenesisChecksum: "checksum", - } - suite.App.RollappKeeper.SetRollapp(suite.Ctx, rollapp) + suite.SetupTest() - // set sequencer - sequencer := sequencertypes.Sequencer{ - Address: bob, - RollappId: urand.RollappID(), - Status: sequencertypes.Bonded, - Proposer: true, - } - suite.App.SequencerKeeper.SetSequencer(suite.Ctx, sequencer) - - // update state - updateState := types.MsgUpdateState{ - Creator: bob, - RollappId: rollapp.GetRollappId(), - StartHeight: 1, - NumBlocks: 3, - DAPath: "", - BDs: types.BlockDescriptors{BD: []types.BlockDescriptor{{Height: 1}, {Height: 2}, {Height: 3}}}, - } + rollappId, _ := suite.CreateDefaultRollappAndProposer() + _, seq_2 := suite.CreateDefaultRollappAndProposer() - _, err := suite.msgServer.UpdateState(goCtx, &updateState) - suite.ErrorIs(err, sequencertypes.ErrSequencerRollappMismatch) + // update state from proposer of rollapp2 + _, err := suite.PostStateUpdate(suite.Ctx, rollappId, seq_2, 1, uint64(3)) + suite.ErrorIs(err, sequencertypes.ErrNotActiveSequencer) } func (suite *RollappTestSuite) TestUpdateStateErrLogicUnpermissioned() { @@ -278,14 +139,14 @@ func (suite *RollappTestSuite) TestUpdateStateErrLogicUnpermissioned() { Address: rollapp.InitialSequencer, RollappId: rollappID, Status: sequencertypes.Bonded, - Proposer: true, } suite.App.SequencerKeeper.SetSequencer(suite.Ctx, sequencer) + suite.App.SequencerKeeper.SetProposer(suite.Ctx, rollappID, sequencer.Address) // update state updateState := types.MsgUpdateState{ Creator: bob, - RollappId: rollapp.GetRollappId(), + RollappId: rollappID, StartHeight: 1, NumBlocks: 3, DAPath: "", @@ -293,81 +154,29 @@ func (suite *RollappTestSuite) TestUpdateStateErrLogicUnpermissioned() { } _, err := suite.msgServer.UpdateState(goCtx, &updateState) - suite.ErrorIs(err, sequencertypes.ErrUnknownSequencer) + suite.ErrorIs(err, sequencertypes.ErrNotActiveSequencer) } -func (suite *RollappTestSuite) TestFirstUpdateStateGensisHeightGreaterThanZero() { - goCtx := sdk.WrapSDKContext(suite.Ctx) +func (suite *RollappTestSuite) TestFirstUpdateStateGenesisHeightGreaterThanZero() { + rollappId, proposer := suite.CreateDefaultRollappAndProposer() - // set rollapp - rollappID := urand.RollappID() - rollapp := types.Rollapp{ - RollappId: rollappID, - Owner: alice, - InitialSequencer: sample.AccAddress(), - Bech32Prefix: "rol", - GenesisChecksum: "checksum", - } - suite.App.RollappKeeper.SetRollapp(suite.Ctx, rollapp) - - // set sequencer - sequencer := sequencertypes.Sequencer{ - Address: bob, - RollappId: rollappID, - Status: sequencertypes.Bonded, - Proposer: true, - } - suite.App.SequencerKeeper.SetSequencer(suite.Ctx, sequencer) - - // update state - updateState := types.MsgUpdateState{ - Creator: bob, - RollappId: rollapp.GetRollappId(), - StartHeight: 2, - NumBlocks: 3, - DAPath: "", - BDs: types.BlockDescriptors{BD: []types.BlockDescriptor{{Height: 2}, {Height: 3}}}, - } - - _, err := suite.msgServer.UpdateState(goCtx, &updateState) + _, err := suite.PostStateUpdate(suite.Ctx, rollappId, proposer, 3, uint64(3)) suite.NoError(err) } func (suite *RollappTestSuite) TestUpdateStateErrWrongBlockHeight() { - _ = sdk.WrapSDKContext(suite.Ctx) - - // set rollapp - rollappID := urand.RollappID() - rollapp := types.Rollapp{ - RollappId: rollappID, - Owner: alice, - InitialSequencer: sample.AccAddress(), - Bech32Prefix: "rol", - GenesisChecksum: "checksum", - } - suite.App.RollappKeeper.SetRollapp(suite.Ctx, rollapp) - - // set sequencer - sequencer := sequencertypes.Sequencer{ - Address: bob, - RollappId: rollappID, - Status: sequencertypes.Bonded, - Proposer: true, - } - suite.App.SequencerKeeper.SetSequencer(suite.Ctx, sequencer) + rollappId, proposer := suite.CreateDefaultRollappAndProposer() // set initial latestStateInfoIndex & StateInfo latestStateInfoIndex := types.StateInfoIndex{ - RollappId: rollappID, + RollappId: rollappId, Index: 1, } stateInfo := types.StateInfo{ - StateInfoIndex: types.StateInfoIndex{RollappId: rollappID, Index: 1}, - Sequencer: sequencer.Address, + StateInfoIndex: types.StateInfoIndex{RollappId: rollappId, Index: 1}, + Sequencer: proposer, StartHeight: 1, NumBlocks: 3, - DAPath: "", - CreationHeight: 0, Status: common.Status_PENDING, BDs: types.BlockDescriptors{BD: []types.BlockDescriptor{{Height: 1}, {Height: 2}, {Height: 3}}}, } @@ -376,100 +185,49 @@ func (suite *RollappTestSuite) TestUpdateStateErrWrongBlockHeight() { // bump block height suite.Ctx = suite.Ctx.WithBlockHeight(suite.Ctx.BlockHeader().Height + 1) - goCtx := sdk.WrapSDKContext(suite.Ctx) // update state updateState := types.MsgUpdateState{ - Creator: bob, - RollappId: rollapp.GetRollappId(), + Creator: proposer, + RollappId: rollappId, StartHeight: 2, NumBlocks: 3, - DAPath: "", BDs: types.BlockDescriptors{BD: []types.BlockDescriptor{{Height: 2}, {Height: 3}, {Height: 4}}}, } - _, err := suite.msgServer.UpdateState(goCtx, &updateState) + _, err := suite.msgServer.UpdateState(suite.Ctx, &updateState) suite.ErrorIs(err, types.ErrWrongBlockHeight) } func (suite *RollappTestSuite) TestUpdateStateErrLogicMissingStateInfo() { - goCtx := sdk.WrapSDKContext(suite.Ctx) - - // set rollapp - rollappID := urand.RollappID() - rollapp := types.Rollapp{ - RollappId: rollappID, - Owner: alice, - InitialSequencer: sample.AccAddress(), - Bech32Prefix: "rol", - GenesisChecksum: "checksum", - } - suite.App.RollappKeeper.SetRollapp(suite.Ctx, rollapp) - - // set sequencer - sequencer := sequencertypes.Sequencer{ - Address: bob, - RollappId: rollappID, - Status: sequencertypes.Bonded, - Proposer: true, - } - suite.App.SequencerKeeper.SetSequencer(suite.Ctx, sequencer) + rollappId, proposer := suite.CreateDefaultRollappAndProposer() // set initial latestStateInfoIndex latestStateInfoIndex := types.StateInfoIndex{ - RollappId: rollappID, + RollappId: rollappId, Index: 1, } suite.App.RollappKeeper.SetLatestStateInfoIndex(suite.Ctx, latestStateInfoIndex) // update state updateState := types.MsgUpdateState{ - Creator: bob, - RollappId: rollapp.GetRollappId(), + Creator: proposer, + RollappId: rollappId, StartHeight: 1, NumBlocks: 3, - DAPath: "", BDs: types.BlockDescriptors{BD: []types.BlockDescriptor{{Height: 1}, {Height: 2}, {Height: 3}}}, } - _, err := suite.msgServer.UpdateState(goCtx, &updateState) + _, err := suite.msgServer.UpdateState(suite.Ctx, &updateState) suite.ErrorIs(err, types.ErrLogic) } -// TODO: should test all status other than Proposer func (suite *RollappTestSuite) TestUpdateStateErrNotActiveSequencer() { - goCtx := sdk.WrapSDKContext(suite.Ctx) - - // set rollapp - rollappID := urand.RollappID() - rollapp := types.Rollapp{ - RollappId: rollappID, - Owner: alice, - InitialSequencer: sample.AccAddress(), - Bech32Prefix: "rol", - GenesisChecksum: "checksum", - } - suite.App.RollappKeeper.SetRollapp(suite.Ctx, rollapp) - - // set sequencer - sequencer := sequencertypes.Sequencer{ - Address: bob, - RollappId: rollappID, - Status: sequencertypes.Bonded, - } - suite.App.SequencerKeeper.SetSequencer(suite.Ctx, sequencer) + rollappId, _ := suite.CreateDefaultRollappAndProposer() + addr2 := suite.CreateDefaultSequencer(suite.Ctx, rollappId) // non-proposer - // update state - updateState := types.MsgUpdateState{ - Creator: bob, - RollappId: rollapp.GetRollappId(), - StartHeight: 1, - NumBlocks: 3, - DAPath: "", - BDs: types.BlockDescriptors{BD: []types.BlockDescriptor{{Height: 1}, {Height: 2}, {Height: 3}}}, - } - - _, err := suite.msgServer.UpdateState(goCtx, &updateState) + // update state from bob + _, err := suite.PostStateUpdate(suite.Ctx, rollappId, addr2, 1, uint64(3)) suite.ErrorIs(err, sequencertypes.ErrNotActiveSequencer) } diff --git a/x/rollapp/types/hooks.go b/x/rollapp/types/hooks.go index fc4ec70cd..4a1671297 100644 --- a/x/rollapp/types/hooks.go +++ b/x/rollapp/types/hooks.go @@ -11,8 +11,8 @@ import ( // RollappHooks event hooks for rollapp object (noalias) type RollappHooks interface { - BeforeUpdateState(ctx sdk.Context, seqAddr string, rollappId string) error // Must be called when a rollapp's state changes - AfterStateFinalized(ctx sdk.Context, rollappID string, stateInfo *StateInfo) error // Must be called when a rollapp's state changes + BeforeUpdateState(ctx sdk.Context, seqAddr, rollappId string, lastStateUpdateBySequencer bool) error // Must be called when a rollapp's state changes + AfterStateFinalized(ctx sdk.Context, rollappID string, stateInfo *StateInfo) error // Must be called when a rollapp's state changes FraudSubmitted(ctx sdk.Context, rollappID string, height uint64, seqAddr string) error RollappCreated(ctx sdk.Context, rollappID, alias string, creator sdk.AccAddress) error } @@ -27,9 +27,9 @@ func NewMultiRollappHooks(hooks ...RollappHooks) MultiRollappHooks { return hooks } -func (h MultiRollappHooks) BeforeUpdateState(ctx sdk.Context, seqAddr string, rollappId string) error { +func (h MultiRollappHooks) BeforeUpdateState(ctx sdk.Context, seqAddr, rollappId string, lastStateUpdateBySequencer bool) error { for i := range h { - err := h[i].BeforeUpdateState(ctx, seqAddr, rollappId) + err := h[i].BeforeUpdateState(ctx, seqAddr, rollappId, lastStateUpdateBySequencer) if err != nil { return err } @@ -68,13 +68,15 @@ func (h MultiRollappHooks) RollappCreated(ctx sdk.Context, rollappID, alias stri return nil } +var _ RollappHooks = &StubRollappCreatedHooks{} + type StubRollappCreatedHooks struct{} func (StubRollappCreatedHooks) RollappCreated(sdk.Context, string, string, sdk.AccAddress) error { return nil } -func (StubRollappCreatedHooks) BeforeUpdateState(sdk.Context, string, string) error { return nil } -func (StubRollappCreatedHooks) FraudSubmitted(sdk.Context, string, uint64, string) error { return nil } +func (StubRollappCreatedHooks) BeforeUpdateState(sdk.Context, string, string, bool) error { return nil } +func (StubRollappCreatedHooks) FraudSubmitted(sdk.Context, string, uint64, string) error { return nil } func (StubRollappCreatedHooks) AfterStateFinalized(sdk.Context, string, *StateInfo) error { return nil } diff --git a/x/rollapp/types/tx.pb.go b/x/rollapp/types/tx.pb.go index 96937317c..1df238dbb 100644 --- a/x/rollapp/types/tx.pb.go +++ b/x/rollapp/types/tx.pb.go @@ -322,6 +322,8 @@ type MsgUpdateState struct { // BDs is a list of block description objects (one per block) // the list must be ordered by height, starting from startHeight to startHeight+numBlocks-1 BDs BlockDescriptors `protobuf:"bytes,7,opt,name=BDs,proto3" json:"BDs"` + // last is true if this is the last batch of the sequencer + Last bool `protobuf:"varint,8,opt,name=last,proto3" json:"last,omitempty"` } func (m *MsgUpdateState) Reset() { *m = MsgUpdateState{} } @@ -399,6 +401,13 @@ func (m *MsgUpdateState) GetBDs() BlockDescriptors { return BlockDescriptors{} } +func (m *MsgUpdateState) GetLast() bool { + if m != nil { + return m.Last + } + return false +} + type MsgUpdateStateResponse struct { } @@ -551,56 +560,57 @@ func init() { } var fileDescriptor_1a86300fb8647ecb = []byte{ - // 771 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x96, 0xcf, 0x6e, 0xd3, 0x4e, - 0x10, 0xc7, 0xe3, 0x26, 0x4d, 0x9a, 0x4d, 0xda, 0xa6, 0xab, 0xaa, 0x3f, 0x2b, 0xed, 0xcf, 0x44, - 0xa9, 0x10, 0xe5, 0x9f, 0x0d, 0x69, 0x41, 0xa8, 0x70, 0x21, 0xad, 0x44, 0x0b, 0x0a, 0x2d, 0x6e, - 0xe1, 0xc0, 0x25, 0x72, 0x9c, 0xad, 0x63, 0x35, 0xf6, 0x1a, 0xef, 0x26, 0x4d, 0xe0, 0xc6, 0x05, - 0x24, 0x2e, 0x3c, 0x00, 0x27, 0x1e, 0x00, 0xf1, 0x18, 0x3d, 0xf6, 0xc8, 0x09, 0xa1, 0xf6, 0xc0, - 0x5b, 0x20, 0xe4, 0xf5, 0xda, 0x49, 0x9b, 0xa4, 0x49, 0xcb, 0x69, 0x33, 0xb3, 0xdf, 0x99, 0x1d, - 0x7f, 0x66, 0xd6, 0x0e, 0xb8, 0x56, 0x6d, 0x5b, 0xc8, 0x26, 0x26, 0xb6, 0x5b, 0xed, 0xb7, 0x4a, - 0x68, 0x28, 0x2e, 0xae, 0xd7, 0x35, 0xc7, 0x51, 0x68, 0x4b, 0x76, 0x5c, 0x4c, 0x31, 0x94, 0xba, - 0x85, 0x72, 0x68, 0xc8, 0x5c, 0x98, 0xfd, 0x4f, 0xc7, 0xc4, 0xc2, 0x44, 0xb1, 0x88, 0xa1, 0x34, - 0xef, 0x7a, 0x8b, 0x1f, 0x98, 0xbd, 0x37, 0xe4, 0x84, 0x4a, 0x1d, 0xeb, 0xfb, 0xe5, 0x2a, 0x22, - 0xba, 0x6b, 0x3a, 0x14, 0xbb, 0x3c, 0xec, 0xd6, 0x90, 0x30, 0xbe, 0x72, 0xf5, 0xed, 0x21, 0x6a, - 0x0b, 0x51, 0xad, 0xaa, 0x51, 0x8d, 0xcb, 0x67, 0x0d, 0x6c, 0x60, 0xf6, 0x53, 0xf1, 0x7e, 0xf9, - 0xde, 0xfc, 0xc7, 0x28, 0xc8, 0x94, 0x88, 0xb1, 0xe6, 0x22, 0x8d, 0x22, 0xd5, 0x8f, 0x84, 0x22, - 0x48, 0xe8, 0x9e, 0x03, 0xbb, 0xa2, 0x90, 0x13, 0x96, 0x92, 0x6a, 0x60, 0xc2, 0xff, 0x01, 0xe0, - 0xe9, 0xcb, 0x66, 0x55, 0x1c, 0x63, 0x9b, 0x49, 0xee, 0xd9, 0xac, 0xc2, 0x9b, 0x60, 0xc6, 0xb4, - 0x4d, 0x6a, 0x6a, 0xf5, 0x32, 0x41, 0x6f, 0x1a, 0xc8, 0xd6, 0x91, 0x2b, 0xa6, 0x98, 0x2a, 0xc3, - 0x37, 0x76, 0x02, 0x3f, 0x5c, 0x04, 0x93, 0x15, 0xa4, 0xd7, 0x96, 0x0b, 0x65, 0xc7, 0x45, 0x7b, - 0x66, 0x4b, 0x4c, 0x33, 0x61, 0xda, 0x77, 0x6e, 0x33, 0x1f, 0x9c, 0x05, 0xe3, 0x5a, 0xdd, 0xd4, - 0x88, 0x38, 0xc9, 0x36, 0x7d, 0x03, 0x5e, 0x07, 0x19, 0x03, 0xd9, 0x88, 0x98, 0xa4, 0xac, 0xd7, - 0x90, 0xbe, 0x4f, 0x1a, 0x96, 0x38, 0xc5, 0x04, 0xd3, 0xdc, 0xbf, 0xc6, 0xdd, 0xf0, 0x19, 0x98, - 0x08, 0x40, 0x88, 0xd3, 0x39, 0x61, 0x29, 0x55, 0x50, 0xe4, 0xf3, 0xdb, 0x2a, 0x73, 0x0c, 0x25, - 0x1e, 0xa6, 0x86, 0x09, 0xe0, 0x13, 0x90, 0x68, 0x5a, 0x65, 0xda, 0x76, 0x90, 0x98, 0xc9, 0x09, - 0x4b, 0x53, 0x05, 0x79, 0xc4, 0x5c, 0xf2, 0xab, 0xd2, 0x6e, 0xdb, 0x41, 0x6a, 0xbc, 0x69, 0x79, - 0xeb, 0x6a, 0xfa, 0xfd, 0xef, 0xef, 0x37, 0x02, 0xaa, 0x4f, 0x63, 0x13, 0xd1, 0x4c, 0x2a, 0x9f, - 0x05, 0xe2, 0xd9, 0x4e, 0xa8, 0x88, 0x38, 0xd8, 0x26, 0x28, 0xff, 0x6d, 0x0c, 0xcc, 0x97, 0x88, - 0xf1, 0xd2, 0xa9, 0x76, 0x36, 0x37, 0xed, 0x3d, 0xec, 0x5a, 0x1a, 0x35, 0xb1, 0xed, 0x61, 0xc2, - 0x07, 0x36, 0x0a, 0xfa, 0xe5, 0x1b, 0x97, 0xea, 0x56, 0x74, 0x40, 0xb7, 0xfa, 0x21, 0x8f, 0xf5, - 0x47, 0xfe, 0xa2, 0x0b, 0xf9, 0xf8, 0xa5, 0x90, 0x17, 0x63, 0x87, 0x3f, 0xaf, 0x08, 0x5d, 0xe0, - 0x7b, 0x66, 0x25, 0xde, 0x3b, 0x2b, 0xab, 0xc0, 0x83, 0xea, 0x3f, 0x7a, 0xfe, 0x2a, 0x58, 0x3c, - 0x87, 0x57, 0xc8, 0xf5, 0x8f, 0x00, 0xa6, 0x42, 0xdd, 0x0e, 0xd5, 0x28, 0x3a, 0x67, 0xf8, 0x17, - 0x40, 0x07, 0x5e, 0x2f, 0xcd, 0x1c, 0x48, 0x11, 0xaa, 0xb9, 0x74, 0x03, 0x99, 0x46, 0x8d, 0x32, - 0x8e, 0x31, 0xb5, 0xdb, 0xe5, 0xc5, 0xdb, 0x0d, 0xab, 0xe8, 0xdd, 0x7d, 0xc2, 0xd8, 0xc5, 0xd4, - 0x8e, 0x03, 0xce, 0x81, 0xf8, 0xfa, 0xe3, 0x6d, 0x8d, 0xd6, 0x18, 0xb3, 0xa4, 0xca, 0x2d, 0xb8, - 0x01, 0xa2, 0xc5, 0x75, 0x22, 0x26, 0x18, 0xc8, 0x3b, 0xc3, 0x40, 0xb2, 0x64, 0xeb, 0xe1, 0x8b, - 0x85, 0x30, 0x92, 0x11, 0xd5, 0x4b, 0xd1, 0x33, 0x74, 0xf1, 0x4c, 0x22, 0x2f, 0x82, 0xb9, 0xd3, - 0xcf, 0x1f, 0xa2, 0xf9, 0x24, 0x80, 0xd9, 0x12, 0x31, 0x76, 0x5d, 0xcd, 0x26, 0x7b, 0xc8, 0xdd, - 0xf2, 0xb0, 0x92, 0x9a, 0xe9, 0x78, 0xbd, 0xd0, 0x1b, 0xae, 0x8b, 0x6c, 0x5a, 0xee, 0x9e, 0xb9, - 0x34, 0x77, 0x32, 0x21, 0x9c, 0x07, 0x49, 0x1b, 0x1d, 0x70, 0x81, 0xcf, 0x6a, 0xc2, 0x46, 0x07, - 0x5b, 0x7d, 0xe6, 0x32, 0x7a, 0x86, 0xe4, 0x2a, 0xf4, 0xea, 0x3c, 0x7d, 0x46, 0x5e, 0x02, 0x0b, - 0xfd, 0x8a, 0x09, 0xaa, 0x2d, 0x7c, 0x8d, 0x81, 0x68, 0x89, 0x18, 0xf0, 0x1d, 0x98, 0x3c, 0xfd, - 0x2e, 0x1b, 0x4a, 0xec, 0xec, 0x9d, 0xcb, 0x3e, 0xb8, 0x68, 0x44, 0x50, 0x04, 0xfc, 0x22, 0x00, - 0x71, 0xe0, 0x15, 0x7d, 0x38, 0x42, 0xda, 0x41, 0xc1, 0xd9, 0xb5, 0x7f, 0x08, 0x0e, 0xcb, 0x6b, - 0x80, 0x54, 0xf7, 0xa0, 0xcb, 0x23, 0xe7, 0x64, 0xfa, 0xec, 0xfd, 0x8b, 0xe9, 0xc3, 0x63, 0x3f, - 0x08, 0x60, 0xa6, 0x77, 0x8a, 0x56, 0x46, 0xc8, 0xd6, 0x13, 0x95, 0x7d, 0x74, 0x99, 0xa8, 0xa0, - 0x92, 0xe2, 0xf3, 0xc3, 0x63, 0x49, 0x38, 0x3a, 0x96, 0x84, 0x5f, 0xc7, 0x92, 0xf0, 0xf9, 0x44, - 0x8a, 0x1c, 0x9d, 0x48, 0x91, 0x1f, 0x27, 0x52, 0xe4, 0xf5, 0x8a, 0x61, 0xd2, 0x5a, 0xa3, 0x22, - 0xeb, 0xd8, 0x52, 0x06, 0x7c, 0x56, 0x9b, 0xcb, 0x4a, 0xab, 0xf3, 0x17, 0xa1, 0xed, 0x20, 0x52, - 0x89, 0xb3, 0x6f, 0xe8, 0xf2, 0xdf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x44, 0x7b, 0x51, 0xc2, 0x51, - 0x08, 0x00, 0x00, + // 785 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x96, 0xcd, 0x6e, 0xd3, 0x4a, + 0x14, 0xc7, 0xe3, 0x26, 0xcd, 0xc7, 0x24, 0x6d, 0xd3, 0x51, 0xd5, 0x6b, 0xa5, 0xbd, 0xbe, 0x51, + 0xaa, 0xab, 0x9b, 0xfb, 0x65, 0x43, 0x5a, 0x10, 0x2a, 0x6c, 0x48, 0x2b, 0xd1, 0x82, 0x42, 0x8b, + 0x5b, 0x58, 0xb0, 0x89, 0x1c, 0x67, 0xea, 0x58, 0x8d, 0x3d, 0xc6, 0x33, 0x49, 0x13, 0xd8, 0xb1, + 0x01, 0x89, 0x0d, 0x62, 0xcd, 0x8a, 0x07, 0x40, 0x3c, 0x46, 0x97, 0x5d, 0xb2, 0x42, 0xa8, 0x5d, + 0xf0, 0x1a, 0xc8, 0xe3, 0xb1, 0x93, 0x36, 0x49, 0x93, 0x96, 0x95, 0xe7, 0x9c, 0xf9, 0x9f, 0x33, + 0x27, 0xbf, 0x73, 0xc6, 0x0e, 0xf8, 0xab, 0xde, 0xb5, 0x90, 0x4d, 0x4c, 0x6c, 0x77, 0xba, 0x2f, + 0x95, 0xd0, 0x50, 0x5c, 0xdc, 0x6c, 0x6a, 0x8e, 0xa3, 0xd0, 0x8e, 0xec, 0xb8, 0x98, 0x62, 0x28, + 0xf5, 0x0b, 0xe5, 0xd0, 0x90, 0xb9, 0x30, 0xf7, 0x9b, 0x8e, 0x89, 0x85, 0x89, 0x62, 0x11, 0x43, + 0x69, 0xdf, 0xf4, 0x1e, 0x7e, 0x60, 0xee, 0xd6, 0x98, 0x13, 0x6a, 0x4d, 0xac, 0x1f, 0x56, 0xeb, + 0x88, 0xe8, 0xae, 0xe9, 0x50, 0xec, 0xf2, 0xb0, 0xff, 0xc6, 0x84, 0xf1, 0x27, 0x57, 0xff, 0x3f, + 0x46, 0x6d, 0x21, 0xaa, 0xd5, 0x35, 0xaa, 0x71, 0xf9, 0x82, 0x81, 0x0d, 0xcc, 0x96, 0x8a, 0xb7, + 0xf2, 0xbd, 0x85, 0xb7, 0x51, 0x90, 0xad, 0x10, 0x63, 0xc3, 0x45, 0x1a, 0x45, 0xaa, 0x1f, 0x09, + 0x45, 0x90, 0xd0, 0x3d, 0x07, 0x76, 0x45, 0x21, 0x2f, 0x14, 0x53, 0x6a, 0x60, 0xc2, 0xdf, 0x01, + 0xe0, 0xe9, 0xab, 0x66, 0x5d, 0x9c, 0x62, 0x9b, 0x29, 0xee, 0xd9, 0xae, 0xc3, 0x7f, 0xc1, 0xbc, + 0x69, 0x9b, 0xd4, 0xd4, 0x9a, 0x55, 0x82, 0x5e, 0xb4, 0x90, 0xad, 0x23, 0x57, 0x4c, 0x33, 0x55, + 0x96, 0x6f, 0xec, 0x05, 0x7e, 0xb8, 0x02, 0x66, 0x6a, 0x48, 0x6f, 0xac, 0x96, 0xaa, 0x8e, 0x8b, + 0x0e, 0xcc, 0x8e, 0x98, 0x61, 0xc2, 0x8c, 0xef, 0xdc, 0x65, 0x3e, 0xb8, 0x00, 0xa6, 0xb5, 0xa6, + 0xa9, 0x11, 0x71, 0x86, 0x6d, 0xfa, 0x06, 0xfc, 0x1b, 0x64, 0x0d, 0x64, 0x23, 0x62, 0x92, 0xaa, + 0xde, 0x40, 0xfa, 0x21, 0x69, 0x59, 0xe2, 0x2c, 0x13, 0xcc, 0x71, 0xff, 0x06, 0x77, 0xc3, 0x47, + 0x20, 0x19, 0x80, 0x10, 0xe7, 0xf2, 0x42, 0x31, 0x5d, 0x52, 0xe4, 0xcb, 0xdb, 0x2a, 0x73, 0x0c, + 0x15, 0x1e, 0xa6, 0x86, 0x09, 0xe0, 0x03, 0x90, 0x68, 0x5b, 0x55, 0xda, 0x75, 0x90, 0x98, 0xcd, + 0x0b, 0xc5, 0xd9, 0x92, 0x3c, 0x61, 0x2e, 0xf9, 0x59, 0x65, 0xbf, 0xeb, 0x20, 0x35, 0xde, 0xb6, + 0xbc, 0xe7, 0x7a, 0xe6, 0xf5, 0x8f, 0x2f, 0xff, 0x04, 0x54, 0x1f, 0xc6, 0x92, 0xd1, 0x6c, 0xba, + 0x90, 0x03, 0xe2, 0xc5, 0x4e, 0xa8, 0x88, 0x38, 0xd8, 0x26, 0xa8, 0xf0, 0x79, 0x0a, 0x2c, 0x55, + 0x88, 0xf1, 0xd4, 0xa9, 0xf7, 0x36, 0xb7, 0xed, 0x03, 0xec, 0x5a, 0x1a, 0x35, 0xb1, 0xed, 0x61, + 0xc2, 0x47, 0x36, 0x0a, 0xfa, 0xe5, 0x1b, 0xd7, 0xea, 0x56, 0x74, 0x44, 0xb7, 0x86, 0x21, 0x8f, + 0x0d, 0x47, 0xfe, 0xa4, 0x0f, 0xf9, 0xf4, 0xb5, 0x90, 0x97, 0x63, 0xc7, 0xdf, 0xfe, 0x10, 0xfa, + 0xc0, 0x0f, 0xcc, 0x4a, 0x7c, 0x70, 0x56, 0xd6, 0x81, 0x07, 0xd5, 0xff, 0xe9, 0x85, 0x3f, 0xc1, + 0xca, 0x25, 0xbc, 0x42, 0xae, 0x1f, 0xa6, 0xc0, 0x6c, 0xa8, 0xdb, 0xa3, 0x1a, 0x45, 0x97, 0x0c, + 0xff, 0x32, 0xe8, 0xc1, 0x1b, 0xa4, 0x99, 0x07, 0x69, 0x42, 0x35, 0x97, 0x6e, 0x21, 0xd3, 0x68, + 0x50, 0xc6, 0x31, 0xa6, 0xf6, 0xbb, 0xbc, 0x78, 0xbb, 0x65, 0x95, 0xbd, 0xbb, 0x4f, 0x18, 0xbb, + 0x98, 0xda, 0x73, 0xc0, 0x45, 0x10, 0xdf, 0xbc, 0xbf, 0xab, 0xd1, 0x06, 0x63, 0x96, 0x52, 0xb9, + 0x05, 0xb7, 0x40, 0xb4, 0xbc, 0x49, 0xc4, 0x04, 0x03, 0x79, 0x63, 0x1c, 0x48, 0x96, 0x6c, 0x33, + 0x7c, 0xb1, 0x10, 0x46, 0x32, 0xa2, 0x7a, 0x29, 0x20, 0x04, 0xb1, 0xa6, 0x46, 0xa8, 0x98, 0xcc, + 0x0b, 0xc5, 0xa4, 0xca, 0xd6, 0x03, 0x83, 0x18, 0xcf, 0x26, 0x0a, 0x22, 0x58, 0x3c, 0xcf, 0x24, + 0xc4, 0xf5, 0x4e, 0x00, 0x0b, 0x15, 0x62, 0xec, 0xbb, 0x9a, 0x4d, 0x0e, 0x90, 0xbb, 0xe3, 0xa1, + 0x26, 0x0d, 0xd3, 0xf1, 0xfa, 0xa3, 0xb7, 0x5c, 0x17, 0xd9, 0xb4, 0xda, 0x3f, 0x87, 0x19, 0xee, + 0x64, 0x42, 0xb8, 0x04, 0x52, 0x36, 0x3a, 0xe2, 0x02, 0x9f, 0x5f, 0xd2, 0x46, 0x47, 0x3b, 0x43, + 0x66, 0x35, 0x7a, 0x81, 0xee, 0x3a, 0xf4, 0xea, 0x3c, 0x7f, 0x46, 0x41, 0x02, 0xcb, 0xc3, 0x8a, + 0x09, 0xaa, 0x2d, 0x7d, 0x8a, 0x81, 0x68, 0x85, 0x18, 0xf0, 0x15, 0x98, 0x39, 0xff, 0x7e, 0x1b, + 0x4b, 0xf1, 0xe2, 0x3d, 0xcc, 0xdd, 0xb9, 0x6a, 0x44, 0x50, 0x04, 0xfc, 0x28, 0x00, 0x71, 0xe4, + 0xb5, 0xbd, 0x3b, 0x41, 0xda, 0x51, 0xc1, 0xb9, 0x8d, 0x5f, 0x08, 0x0e, 0xcb, 0x6b, 0x81, 0x74, + 0xff, 0xf0, 0xcb, 0x13, 0xe7, 0x64, 0xfa, 0xdc, 0xed, 0xab, 0xe9, 0xc3, 0x63, 0xdf, 0x08, 0x60, + 0x7e, 0x70, 0x8a, 0xd6, 0x26, 0xc8, 0x36, 0x10, 0x95, 0xbb, 0x77, 0x9d, 0xa8, 0xa0, 0x92, 0xf2, + 0xe3, 0xe3, 0x53, 0x49, 0x38, 0x39, 0x95, 0x84, 0xef, 0xa7, 0x92, 0xf0, 0xfe, 0x4c, 0x8a, 0x9c, + 0x9c, 0x49, 0x91, 0xaf, 0x67, 0x52, 0xe4, 0xf9, 0x9a, 0x61, 0xd2, 0x46, 0xab, 0x26, 0xeb, 0xd8, + 0x52, 0x46, 0x7c, 0x6a, 0xdb, 0xab, 0x4a, 0xa7, 0xf7, 0xb7, 0xa1, 0xeb, 0x20, 0x52, 0x8b, 0xb3, + 0xef, 0xea, 0xea, 0xcf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x9f, 0xfc, 0xa4, 0x02, 0x65, 0x08, 0x00, + 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -1011,6 +1021,16 @@ func (m *MsgUpdateState) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.Last { + i-- + if m.Last { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x40 + } { size, err := m.BDs.MarshalToSizedBuffer(dAtA[:i]) if err != nil { @@ -1273,6 +1293,9 @@ func (m *MsgUpdateState) Size() (n int) { } l = m.BDs.Size() n += 1 + l + sovTx(uint64(l)) + if m.Last { + n += 2 + } return n } @@ -2160,6 +2183,26 @@ func (m *MsgUpdateState) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 8: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Last", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Last = bool(v != 0) default: iNdEx = preIndex skippy, err := skipTx(dAtA[iNdEx:]) diff --git a/x/sequencer/client/cli/query.go b/x/sequencer/client/cli/query.go index e8583f215..ee4d9992e 100644 --- a/x/sequencer/client/cli/query.go +++ b/x/sequencer/client/cli/query.go @@ -24,6 +24,8 @@ func GetQueryCmd(queryRoute string) *cobra.Command { cmd.AddCommand(CmdListSequencer()) cmd.AddCommand(CmdShowSequencer()) cmd.AddCommand(CmdShowSequencersByRollapp()) + cmd.AddCommand(CmdGetProposerByRollapp()) + cmd.AddCommand(CmdGetNextProposerByRollapp()) return cmd } diff --git a/x/sequencer/client/cli/query_sequencers_by_rollapp.go b/x/sequencer/client/cli/query_sequencers_by_rollapp.go index 4fa180599..578f43c5d 100644 --- a/x/sequencer/client/cli/query_sequencers_by_rollapp.go +++ b/x/sequencer/client/cli/query_sequencers_by_rollapp.go @@ -13,7 +13,7 @@ import ( func CmdShowSequencersByRollapp() *cobra.Command { cmd := &cobra.Command{ Use: "show-sequencers-by-rollapp [rollapp-id]", - Short: "shows a sequencers_by_rollapp", + Short: "shows the sequencers of a specific rollapp", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) (err error) { clientCtx := client.GetClientContextFromCmd(cmd) @@ -39,3 +39,57 @@ func CmdShowSequencersByRollapp() *cobra.Command { return cmd } + +func CmdGetProposerByRollapp() *cobra.Command { + cmd := &cobra.Command{ + Use: "proposer [rollapp-id]", + Short: "Get the current proposer by rollapp ID", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx := client.GetClientContextFromCmd(cmd) + queryClient := types.NewQueryClient(clientCtx) + argRollappId := args[0] + + params := &types.QueryGetProposerByRollappRequest{ + RollappId: argRollappId, + } + + res, err := queryClient.GetProposerByRollapp(context.Background(), params) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + return cmd +} + +func CmdGetNextProposerByRollapp() *cobra.Command { + cmd := &cobra.Command{ + Use: "next-proposer [rollapp-id]", + Short: "Get the next proposer by rollapp ID", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx := client.GetClientContextFromCmd(cmd) + queryClient := types.NewQueryClient(clientCtx) + argRollappId := args[0] + + params := &types.QueryGetNextProposerByRollappRequest{ + RollappId: argRollappId, + } + + res, err := queryClient.GetNextProposerByRollapp(context.Background(), params) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + return cmd +} diff --git a/x/sequencer/genesis.go b/x/sequencer/genesis.go index f26d3cf00..cead5f647 100644 --- a/x/sequencer/genesis.go +++ b/x/sequencer/genesis.go @@ -8,11 +8,24 @@ import ( // InitGenesis initializes the sequencer module's state from a provided genesis func InitGenesis(ctx sdk.Context, k keeper.Keeper, genState types.GenesisState) { + k.SetParams(ctx, genState.Params) + // Set all the sequencer for _, elem := range genState.SequencerList { k.SetSequencer(ctx, elem) + + // Set the unbonding queue for the sequencer + if elem.Status == types.Unbonding { + k.AddSequencerToUnbondingQueue(ctx, &elem) + } else if elem.IsNoticePeriodInProgress() { + k.AddSequencerToNoticePeriodQueue(ctx, &elem) + } } - k.SetParams(ctx, genState.Params) + + for _, elem := range genState.GenesisProposers { + k.SetProposer(ctx, elem.RollappId, elem.Address) + } + for _, bondReduction := range genState.BondReductions { k.SetDecreasingBondQueue(ctx, bondReduction) } @@ -24,5 +37,14 @@ func ExportGenesis(ctx sdk.Context, k keeper.Keeper) *types.GenesisState { genesis.Params = k.GetParams(ctx) genesis.SequencerList = k.GetAllSequencers(ctx) genesis.BondReductions = k.GetAllBondReductions(ctx) + + proposers := k.GetAllProposers(ctx) + for _, proposer := range proposers { + genesis.GenesisProposers = append(genesis.GenesisProposers, types.GenesisProposer{ + RollappId: proposer.RollappId, + Address: proposer.Address, + }) + } + return &genesis } diff --git a/x/sequencer/genesis_test.go b/x/sequencer/genesis_test.go index 52456eb97..52a41ddf2 100644 --- a/x/sequencer/genesis_test.go +++ b/x/sequencer/genesis_test.go @@ -8,85 +8,110 @@ import ( "github.com/stretchr/testify/require" keepertest "github.com/dymensionxyz/dymension/v3/testutil/keeper" - "github.com/dymensionxyz/dymension/v3/testutil/nullify" "github.com/dymensionxyz/dymension/v3/x/sequencer" "github.com/dymensionxyz/dymension/v3/x/sequencer/types" ) func TestInitGenesis(t *testing.T) { + timeToTest := time.Now().Round(0).UTC() + genesisState := types.GenesisState{ Params: types.DefaultParams(), SequencerList: []types.Sequencer{ + // rollapp 1 + // bonded - no tokens + { + Address: "rollapp1_addr1", + RollappId: "rollapp1", + Status: types.Bonded, + Tokens: sdk.Coins(nil), + }, + // bonded - 100 dym + { + Address: "rollapp1_addr2", + RollappId: "rollapp1", + Status: types.Bonded, + Tokens: sdk.NewCoins(sdk.NewCoin("dym", sdk.NewInt(100))), + }, + // unbonding + { + Address: "rollapp1_addr3", + RollappId: "rollapp1", + Status: types.Unbonding, + Tokens: sdk.Coins(nil), + UnbondRequestHeight: 10, + UnbondTime: timeToTest, + }, + // unbonded + { + Address: "rollapp1_addr4", + RollappId: "rollapp1", + Status: types.Unbonded, + Tokens: sdk.Coins(nil), + }, + // rollapp 2 { - Address: "0", - Status: types.Bonded, - Proposer: true, + Address: "rollapp2_addr1", + RollappId: "rollapp2", + Status: types.Bonded, + Tokens: sdk.Coins(nil), }, + // unbonding { - Address: "1", - Status: types.Bonded, + Address: "rollapp2_addr2", + RollappId: "rollapp2", + Status: types.Unbonding, + Tokens: sdk.Coins(nil), + UnbondRequestHeight: 10, + UnbondTime: timeToTest, + }, + // rollapp 3 + // proposer with notice period + { + Address: "rollapp3_addr1", + RollappId: "rollapp3", + Status: types.Bonded, + Tokens: sdk.Coins(nil), + UnbondRequestHeight: 20, + NoticePeriodTime: timeToTest, }, }, BondReductions: []types.BondReduction{ { - SequencerAddress: "0", + SequencerAddress: "rollapp1_addr1", DecreaseBondAmount: sdk.NewCoin("dym", sdk.NewInt(100)), - DecreaseBondTime: time.Now().UTC(), + DecreaseBondTime: timeToTest, }, }, - // this line is used by starport scaffolding # genesis/test/state + GenesisProposers: []types.GenesisProposer{ + { + Address: "rollapp1_addr1", + RollappId: "rollapp1", + }, + { + Address: "rollapp3_addr1", + RollappId: "rollapp3", + }, + // rollapp2 has no proposer + }, } + // change the params for assertion + genesisState.Params.NoticePeriod = 100 + k, ctx := keepertest.SequencerKeeper(t) sequencer.InitGenesis(ctx, *k, genesisState) - got := sequencer.ExportGenesis(ctx, *k) - require.NotNil(t, got) - - nullify.Fill(&genesisState) - nullify.Fill(got) - require.ElementsMatch(t, genesisState.SequencerList, got.SequencerList) - require.ElementsMatch(t, genesisState.BondReductions, got.BondReductions) - // this line is used by starport scaffolding # genesis/test/assert -} - -func TestExportGenesis(t *testing.T) { - params := types.Params{ - MinBond: sdk.NewCoin("dym", sdk.NewInt(100)), - UnbondingTime: 100, - LivenessSlashMultiplier: sdk.ZeroDec(), - } - sequencerList := []types.Sequencer{ - { - Address: "0", - Status: types.Bonded, - Proposer: true, - }, - { - Address: "1", - Status: types.Bonded, - }, - } - bondReductions := []types.BondReduction{ - { - SequencerAddress: "0", - DecreaseBondAmount: sdk.NewCoin("dym", sdk.NewInt(100)), - DecreaseBondTime: time.Now().UTC(), - }, - } - k, ctx := keepertest.SequencerKeeper(t) - k.SetParams(ctx, params) - for _, sequencer := range sequencerList { - k.SetSequencer(ctx, sequencer) - } - for _, bondReduction := range bondReductions { - k.SetDecreasingBondQueue(ctx, bondReduction) - } + require.Len(t, k.GetMatureNoticePeriodSequencers(ctx, timeToTest), 1) + require.Len(t, k.GetMatureUnbondingSequencers(ctx, timeToTest), 2) + require.Len(t, k.GetAllProposers(ctx), 2) + require.Len(t, k.GetAllBondReductions(ctx), 1) got := sequencer.ExportGenesis(ctx, *k) require.NotNil(t, got) - require.Equal(t, params, got.Params) - require.ElementsMatch(t, sequencerList, got.SequencerList) - require.ElementsMatch(t, bondReductions, got.BondReductions) + require.Equal(t, genesisState.Params, got.Params) + require.ElementsMatch(t, genesisState.SequencerList, got.SequencerList) + require.ElementsMatch(t, genesisState.GenesisProposers, got.GenesisProposers) + require.ElementsMatch(t, genesisState.BondReductions, got.BondReductions) } diff --git a/x/sequencer/keeper/bond_reductions.go b/x/sequencer/keeper/bond_reductions.go index 5bde2f967..d50ae56a3 100644 --- a/x/sequencer/keeper/bond_reductions.go +++ b/x/sequencer/keeper/bond_reductions.go @@ -3,11 +3,62 @@ package keeper import ( "time" + errorsmod "cosmossdk.io/errors" "github.com/cosmos/cosmos-sdk/store/prefix" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/dymensionxyz/dymension/v3/x/sequencer/types" + "github.com/osmosis-labs/osmosis/v15/osmoutils" ) +func (k Keeper) HandleBondReduction(ctx sdk.Context, currTime time.Time) { + unbondings := k.GetMatureDecreasingBondSequencers(ctx, currTime) + for _, unbonding := range unbondings { + wrapFn := func(ctx sdk.Context) error { + return k.completeBondReduction(ctx, unbonding) + } + err := osmoutils.ApplyFuncIfNoError(ctx, wrapFn) + if err != nil { + k.Logger(ctx).Error("reducing sequencer bond", "error", err, "sequencer", unbonding.SequencerAddress) + continue + } + } +} + +func (k Keeper) completeBondReduction(ctx sdk.Context, reduction types.BondReduction) error { + seq, found := k.GetSequencer(ctx, reduction.SequencerAddress) + if !found { + return types.ErrUnknownSequencer + } + + if seq.Tokens.IsAllLT(sdk.NewCoins(reduction.DecreaseBondAmount)) { + return errorsmod.Wrapf( + types.ErrInsufficientBond, + "sequencer does not have enough bond to reduce insufficient bond: got %s, reducing by %s", + seq.Tokens.String(), + reduction.DecreaseBondAmount.String(), + ) + } + newBalance := seq.Tokens.Sub(reduction.DecreaseBondAmount) + // in case between unbonding queue and now, the minbond value is increased, + // handle it by only returning upto minBond amount and not all + minBond := k.GetParams(ctx).MinBond + if newBalance.IsAllLT(sdk.NewCoins(minBond)) { + diff := minBond.SubAmount(newBalance.AmountOf(minBond.Denom)) + reduction.DecreaseBondAmount = reduction.DecreaseBondAmount.Sub(diff) + } + seqAddr := sdk.MustAccAddressFromBech32(reduction.SequencerAddress) + err := k.bankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, seqAddr, sdk.NewCoins(reduction.DecreaseBondAmount)) + if err != nil { + return err + } + + seq.Tokens = seq.Tokens.Sub(reduction.DecreaseBondAmount) + k.SetSequencer(ctx, seq) + k.removeDecreasingBondQueue(ctx, reduction) + + return nil +} + // GetMatureDecreasingBondSequencers returns all decreasing bond items for the given time func (k Keeper) GetMatureDecreasingBondSequencers(ctx sdk.Context, endTime time.Time) (unbondings []types.BondReduction) { store := ctx.KVStore(k.storeKey) diff --git a/x/sequencer/keeper/grpc_query_sequencers_by_rollapp.go b/x/sequencer/keeper/grpc_query_sequencers_by_rollapp.go index cc61e7ef9..45efada78 100644 --- a/x/sequencer/keeper/grpc_query_sequencers_by_rollapp.go +++ b/x/sequencer/keeper/grpc_query_sequencers_by_rollapp.go @@ -2,22 +2,21 @@ package keeper import ( "context" + "errors" sdk "github.com/cosmos/cosmos-sdk/types" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" - "github.com/dymensionxyz/dymension/v3/x/sequencer/types" + "github.com/dymensionxyz/gerr-cosmos/gerrc" ) func (k Keeper) SequencersByRollapp(c context.Context, req *types.QueryGetSequencersByRollappRequest) (*types.QueryGetSequencersByRollappResponse, error) { if req == nil { - return nil, status.Error(codes.InvalidArgument, "invalid request") + return nil, gerrc.ErrInvalidArgument } ctx := sdk.UnwrapSDKContext(c) if _, ok := k.rollappKeeper.GetRollapp(ctx, req.RollappId); !ok { - return nil, types.ErrUnknownRollappID + return nil, errors.Join(gerrc.ErrNotFound, types.ErrUnknownRollappID) } sequencers := k.GetSequencersByRollapp(ctx, req.RollappId) @@ -28,12 +27,12 @@ func (k Keeper) SequencersByRollapp(c context.Context, req *types.QueryGetSequen func (k Keeper) SequencersByRollappByStatus(c context.Context, req *types.QueryGetSequencersByRollappByStatusRequest) (*types.QueryGetSequencersByRollappByStatusResponse, error) { if req == nil { - return nil, status.Error(codes.InvalidArgument, "invalid request") + return nil, gerrc.ErrInvalidArgument } ctx := sdk.UnwrapSDKContext(c) if _, ok := k.rollappKeeper.GetRollapp(ctx, req.RollappId); !ok { - return nil, types.ErrUnknownRollappID + return nil, errors.Join(gerrc.ErrNotFound, types.ErrUnknownRollappID) } sequencers := k.GetSequencersByRollappByStatus( @@ -46,3 +45,35 @@ func (k Keeper) SequencersByRollappByStatus(c context.Context, req *types.QueryG Sequencers: sequencers, }, nil } + +// GetProposerByRollapp implements types.QueryServer. +func (k Keeper) GetProposerByRollapp(c context.Context, req *types.QueryGetProposerByRollappRequest) (*types.QueryGetProposerByRollappResponse, error) { + if req == nil { + return nil, gerrc.ErrInvalidArgument + } + ctx := sdk.UnwrapSDKContext(c) + + seq, ok := k.GetProposer(ctx, req.RollappId) + if !ok { + return nil, types.ErrNoProposer + } + + return &types.QueryGetProposerByRollappResponse{ + ProposerAddr: seq.Address, + }, nil +} + +// GetNextProposerByRollapp implements types.QueryServer. +func (k Keeper) GetNextProposerByRollapp(c context.Context, req *types.QueryGetNextProposerByRollappRequest) (*types.QueryGetNextProposerByRollappResponse, error) { + if req == nil { + return nil, gerrc.ErrInvalidArgument + } + ctx := sdk.UnwrapSDKContext(c) + + // if rotation is not in progress, we return the expected next proposer in case for the next rotation + expectedNext := k.ExpectedNextProposer(ctx, req.RollappId) + return &types.QueryGetNextProposerByRollappResponse{ + NextProposerAddr: expectedNext.Address, + RotationInProgress: k.IsRotating(ctx, req.RollappId), + }, nil +} diff --git a/x/sequencer/keeper/grpc_query_sequencers_by_rollapp_test.go b/x/sequencer/keeper/grpc_query_sequencers_by_rollapp_test.go index e8f189f68..2296904cc 100644 --- a/x/sequencer/keeper/grpc_query_sequencers_by_rollapp_test.go +++ b/x/sequencer/keeper/grpc_query_sequencers_by_rollapp_test.go @@ -6,12 +6,11 @@ import ( "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" "github.com/stretchr/testify/require" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" "github.com/dymensionxyz/dymension/v3/testutil/nullify" "github.com/dymensionxyz/dymension/v3/x/sequencer/keeper" "github.com/dymensionxyz/dymension/v3/x/sequencer/types" + "github.com/dymensionxyz/gerr-cosmos/gerrc" ) func (suite *SequencerTestSuite) TestSequencersByRollappQuery3() { @@ -21,8 +20,8 @@ func (suite *SequencerTestSuite) TestSequencersByRollappQuery3() { pk22 := ed25519.GenPrivKey().PubKey() // create 2 sequencer - addr11 := suite.CreateDefaultSequencer(suite.Ctx, rollappId, pk11) - addr21 := suite.CreateDefaultSequencer(suite.Ctx, rollappId, pk12) + addr11 := suite.CreateSequencer(suite.Ctx, rollappId, pk11) + addr21 := suite.CreateSequencer(suite.Ctx, rollappId, pk12) seq1, found := suite.App.SequencerKeeper.GetSequencer(suite.Ctx, addr11) require.True(suite.T(), found) seq2, found := suite.App.SequencerKeeper.GetSequencer(suite.Ctx, addr21) @@ -31,8 +30,8 @@ func (suite *SequencerTestSuite) TestSequencersByRollappQuery3() { Sequencers: []types.Sequencer{seq1, seq2}, } - addr12 := suite.CreateDefaultSequencer(suite.Ctx, rollappId2, pk21) - addr22 := suite.CreateDefaultSequencer(suite.Ctx, rollappId2, pk22) + addr12 := suite.CreateSequencer(suite.Ctx, rollappId2, pk21) + addr22 := suite.CreateSequencer(suite.Ctx, rollappId2, pk22) seq3, found := suite.App.SequencerKeeper.GetSequencer(suite.Ctx, addr12) require.True(suite.T(), found) seq4, found := suite.App.SequencerKeeper.GetSequencer(suite.Ctx, addr22) @@ -70,7 +69,7 @@ func (suite *SequencerTestSuite) TestSequencersByRollappQuery3() { }, { desc: "InvalidRequest", - err: status.Error(codes.InvalidArgument, "invalid request"), + err: gerrc.ErrInvalidArgument, }, } { suite.T().Run(tc.desc, func(t *testing.T) { @@ -94,8 +93,8 @@ func (suite *SequencerTestSuite) TestSequencersByRollappByStatusQuery() { rollappId, pk11 := suite.CreateDefaultRollapp() pk12 := ed25519.GenPrivKey().PubKey() // create 2 sequencers on rollapp1 - addr11 := suite.CreateDefaultSequencer(suite.Ctx, rollappId, pk11) - addr21 := suite.CreateDefaultSequencer(suite.Ctx, rollappId, pk12) + addr11 := suite.CreateSequencer(suite.Ctx, rollappId, pk11) + addr21 := suite.CreateSequencer(suite.Ctx, rollappId, pk12) _, err := msgserver.Unbond(suite.Ctx, &types.MsgUnbond{ Creator: addr21, }) @@ -104,8 +103,8 @@ func (suite *SequencerTestSuite) TestSequencersByRollappByStatusQuery() { // create 2 sequencers on rollapp2 rollappId2, pk21 := suite.CreateDefaultRollapp() pk22 := ed25519.GenPrivKey().PubKey() - addr12 := suite.CreateDefaultSequencer(suite.Ctx, rollappId2, pk21) - addr22 := suite.CreateDefaultSequencer(suite.Ctx, rollappId2, pk22) + addr12 := suite.CreateSequencer(suite.Ctx, rollappId2, pk21) + addr22 := suite.CreateSequencer(suite.Ctx, rollappId2, pk22) for _, tc := range []struct { desc string @@ -154,7 +153,7 @@ func (suite *SequencerTestSuite) TestSequencersByRollappByStatusQuery() { }, { desc: "InvalidRequest", - err: status.Error(codes.InvalidArgument, "invalid request"), + err: gerrc.ErrInvalidArgument, }, } { suite.T().Run(tc.desc, func(t *testing.T) { diff --git a/x/sequencer/keeper/hook_listener.go b/x/sequencer/keeper/hook_listener.go index 1ba274440..3df807374 100644 --- a/x/sequencer/keeper/hook_listener.go +++ b/x/sequencer/keeper/hook_listener.go @@ -20,44 +20,46 @@ func (k Keeper) RollappHooks() rollapptypes.RollappHooks { return rollappHook{k: k} } -func (hook rollappHook) BeforeUpdateState(ctx sdk.Context, seqAddr string, rollappId string) error { - // check to see if the sequencer has been registered before - sequencer, found := hook.k.GetSequencer(ctx, seqAddr) - if !found { - return types.ErrUnknownSequencer +// BeforeUpdateState checks various conditions before updating the state. +// It verifies if the sequencer has been registered, if the rollappId matches the one of the sequencer, +// if there is a proposer for the given rollappId, and if the sequencer is the active one. +// If the lastStateUpdateBySequencer flag is true, it also checks if the rollappId is rotating and +// performs a rotation of the proposer. +// Returns an error if any of the checks fail, otherwise returns nil. +func (hook rollappHook) BeforeUpdateState(ctx sdk.Context, seqAddr, rollappId string, lastStateUpdateBySequencer bool) error { + proposer, ok := hook.k.GetProposer(ctx, rollappId) + if !ok { + return types.ErrNoProposer } - - // check to see if the rollappId matches the one of the sequencer - if sequencer.RollappId != rollappId { - return types.ErrSequencerRollappMismatch + if seqAddr != proposer.Address { + return types.ErrNotActiveSequencer } - // check to see if the sequencer is active and can make the update - if sequencer.Status != types.Bonded { - return types.ErrInvalidSequencerStatus + if lastStateUpdateBySequencer { + // last state update received by sequencer + // it's expected that the sequencer produced a last block which handovers the proposer role on the L2 + // any divergence from this is considered fraud + err := hook.k.CompleteRotation(ctx, rollappId) + if err != nil { + return err + } } - if !sequencer.Proposer { - return types.ErrNotActiveSequencer - } return nil } // FraudSubmitted implements the RollappHooks interface // It slashes the sequencer and unbonds all other bonded sequencers func (hook rollappHook) FraudSubmitted(ctx sdk.Context, rollappID string, height uint64, seqAddr string) error { - err := hook.k.SlashAndJailFraud(ctx, seqAddr) + err := hook.k.JailSequencerOnFraud(ctx, seqAddr) if err != nil { return err } - // unbond all other bonded sequencers - sequencers := hook.k.GetSequencersByRollappByStatus(ctx, rollappID, types.Bonded) - for _, sequencer := range sequencers { - err := hook.k.forceUnbondSequencer(ctx, sequencer.Address) - if err != nil { - return err - } + // unbond all other other rollapp sequencers + err = hook.k.InstantUnbondAllSequencers(ctx, rollappID) + if err != nil { + return err } return nil diff --git a/x/sequencer/keeper/hooks_test.go b/x/sequencer/keeper/hooks_test.go index 416376020..44c9c4158 100644 --- a/x/sequencer/keeper/hooks_test.go +++ b/x/sequencer/keeper/hooks_test.go @@ -25,9 +25,13 @@ func (suite *SequencerTestSuite) TestFraudSubmittedHook() { for i := 1; i < numOfSequencers; i++ { pki := ed25519.GenPrivKey().PubKey() - seqAddrs[i] = suite.CreateDefaultSequencer(suite.Ctx, rollappId, pki) + seqAddrs[i] = suite.CreateSequencer(suite.Ctx, rollappId, pki) } + proposer := seqAddrs[0] + p, found := keeper.GetProposer(suite.Ctx, rollappId) + suite.Require().True(found) + suite.Require().Equal(proposer, p.Address) // queue the third sequencer to reduce bond unbondMsg := types.MsgDecreaseBond{Creator: seqAddrs[0], DecreaseAmount: sdk.NewInt64Coin(bond.Denom, 10)} @@ -49,10 +53,12 @@ func (suite *SequencerTestSuite) TestFraudSubmittedHook() { for i := 1; i < numOfSequencers; i++ { sequencer, found := keeper.GetSequencer(suite.Ctx, seqAddrs[i]) suite.Require().True(found) - suite.Require().False(sequencer.Proposer) suite.Require().Equal(sequencer.Status, types.Unbonded) } + // check no proposer is set for the rollapp after fraud + _, ok := keeper.GetProposer(suite.Ctx, rollappId) + suite.Require().False(ok) // check if bond reduction queue is pruned bds = keeper.GetMatureDecreasingBondSequencers(suite.Ctx, resp.GetCompletionTime()) suite.Require().Len(bds, 0) diff --git a/x/sequencer/keeper/invariants.go b/x/sequencer/keeper/invariants.go index 728ecdc84..356f28e39 100644 --- a/x/sequencer/keeper/invariants.go +++ b/x/sequencer/keeper/invariants.go @@ -9,7 +9,7 @@ import ( // RegisterInvariants registers the sequencer module invariants func RegisterInvariants(ir sdk.InvariantRegistry, k Keeper) { ir.RegisterRoute(types.ModuleName, "sequencers-count", SequencersCountInvariant(k)) - ir.RegisterRoute(types.ModuleName, "sequencers-per-rollapp", SequencersPerRollappInvariant(k)) + ir.RegisterRoute(types.ModuleName, "sequencer-proposer-bonded", ProposerBondedInvariant(k)) } // AllInvariants runs all invariants of the x/sequencer module. @@ -19,10 +19,12 @@ func AllInvariants(k Keeper) sdk.Invariant { if stop { return res, stop } - res, stop = SequencersPerRollappInvariant(k)(ctx) + + res, stop = ProposerBondedInvariant(k)(ctx) if stop { return res, stop } + return "", false } } @@ -64,7 +66,8 @@ func SequencersCountInvariant(k Keeper) sdk.Invariant { } } -func SequencersPerRollappInvariant(k Keeper) sdk.Invariant { +// ProposerBondedInvariant checks if the proposer and next proposer are bonded as expected +func ProposerBondedInvariant(k Keeper) sdk.Invariant { return func(ctx sdk.Context) (string, bool) { var ( broken bool @@ -73,31 +76,21 @@ func SequencersPerRollappInvariant(k Keeper) sdk.Invariant { rollapps := k.rollappKeeper.GetAllRollapps(ctx) for _, rollapp := range rollapps { - bonded := k.GetSequencersByRollappByStatus(ctx, rollapp.RollappId, types.Bonded) - - if len(bonded) == 0 { - continue + active, ok := k.GetProposer(ctx, rollapp.RollappId) + if ok && active.Status != types.Bonded { + broken = true + msg += "active sequencer is not bonded " + rollapp.RollappId + "\n" } - proposerFound := false - for _, seq := range bonded { - if seq.Proposer { - if proposerFound { - broken = true - msg += "more than one proposer for rollapp " + rollapp.RollappId + "\n" - } - proposerFound = true - } - } - if !proposerFound { + next := k.ExpectedNextProposer(ctx, rollapp.RollappId) + if !next.IsEmpty() && next.Status != types.Bonded { broken = true - msg += "no proposer for rollapp " + rollapp.RollappId + "\n" + msg += "next sequencer is not bonded " + rollapp.RollappId + "\n" } - } return sdk.FormatInvariant( - types.ModuleName, "sequencers-per-rollapp", + types.ModuleName, "sequencer-bonded", msg, ), broken } diff --git a/x/sequencer/keeper/invariants_test.go b/x/sequencer/keeper/invariants_test.go index 5729df2e3..820b3dfce 100644 --- a/x/sequencer/keeper/invariants_test.go +++ b/x/sequencer/keeper/invariants_test.go @@ -17,33 +17,45 @@ func (suite *SequencerTestSuite) TestInvariants() { numOfRollapps := 5 numOfSequencers := 5 + var ( + rollappToTest string + timeToMature time.Time + ) + // create rollapps and sequencers for i := 0; i < numOfRollapps; i++ { rollapp, pk := suite.CreateDefaultRollapp() // create sequencers seqAddr := make([]string, numOfSequencers) - seqAddr[0] = suite.CreateDefaultSequencer(suite.Ctx, rollapp, pk) + seqAddr[0] = suite.CreateSequencer(suite.Ctx, rollapp, pk) for j := 1; j < numOfSequencers; j++ { pki := ed25519.GenPrivKey().PubKey() - seqAddr[j] = suite.CreateDefaultSequencer(suite.Ctx, rollapp, pki) + seqAddr[j] = suite.CreateSequencer(suite.Ctx, rollapp, pki) } // unbonding some sequencers - for j := uint64(0); j < uint64(numOfSequencers/2); j++ { + for j := uint64(0); j < uint64(numOfSequencers-1); j++ { suite.Ctx = suite.Ctx.WithBlockHeight(int64(initialheight + j)).WithBlockTime(initialTime.Add(time.Duration(j) * time.Second)) - _, err := suite.msgServer.Unbond(suite.Ctx, &types.MsgUnbond{Creator: seqAddr[j]}) + res, err := suite.msgServer.Unbond(suite.Ctx, &types.MsgUnbond{Creator: seqAddr[j]}) suite.Require().NoError(err) + if i == 1 && j == 1 { + rollappToTest = rollapp + timeToMature = *res.GetUnbondingCompletionTime() + } } } - // unbond some - unbondTime := initialTime.Add(suite.App.SequencerKeeper.UnbondingTime(suite.Ctx)) - suite.App.SequencerKeeper.UnbondAllMatureSequencers(suite.Ctx, unbondTime) + + rollappid := rollappToTest + seqUnbonding := suite.App.SequencerKeeper.GetSequencersByRollappByStatus(suite.Ctx, rollappid, types.Unbonding) + suite.Require().True(len(seqUnbonding) > 0) + + // unbond some unbonding sequencers + suite.App.SequencerKeeper.UnbondAllMatureSequencers(suite.Ctx, timeToMature) // Test the test: make sure all status have entries - rollappid := suite.App.RollappKeeper.GetAllRollapps(suite.Ctx)[0].RollappId seqBonded := suite.App.SequencerKeeper.GetSequencersByRollappByStatus(suite.Ctx, rollappid, types.Bonded) - seqUnbonding := suite.App.SequencerKeeper.GetSequencersByRollappByStatus(suite.Ctx, rollappid, types.Unbonding) + seqUnbonding = suite.App.SequencerKeeper.GetSequencersByRollappByStatus(suite.Ctx, rollappid, types.Unbonding) seqUnbonded := suite.App.SequencerKeeper.GetSequencersByRollappByStatus(suite.Ctx, rollappid, types.Unbonded) if len(seqBonded) == 0 || len(seqUnbonding) == 0 || len(seqUnbonded) == 0 { diff --git a/x/sequencer/keeper/keeper.go b/x/sequencer/keeper/keeper.go index 7a6b8de97..3ae9575e0 100644 --- a/x/sequencer/keeper/keeper.go +++ b/x/sequencer/keeper/keeper.go @@ -17,7 +17,6 @@ type ( Keeper struct { cdc codec.BinaryCodec storeKey storetypes.StoreKey - memKey storetypes.StoreKey paramstore paramtypes.Subspace bankKeeper types.BankKeeper rollappKeeper types.RollappKeeper @@ -26,8 +25,7 @@ type ( func NewKeeper( cdc codec.BinaryCodec, - storeKey, - memKey storetypes.StoreKey, + storeKey storetypes.StoreKey, ps paramtypes.Subspace, bankKeeper types.BankKeeper, rollappKeeper types.RollappKeeper, @@ -40,7 +38,6 @@ func NewKeeper( return &Keeper{ cdc: cdc, storeKey: storeKey, - memKey: memKey, paramstore: ps, bankKeeper: bankKeeper, rollappKeeper: rollappKeeper, diff --git a/x/sequencer/keeper/msg_server_create_sequencer.go b/x/sequencer/keeper/msg_server_create_sequencer.go index 14fb94baa..6c6cc03c1 100644 --- a/x/sequencer/keeper/msg_server_create_sequencer.go +++ b/x/sequencer/keeper/msg_server_create_sequencer.go @@ -45,16 +45,14 @@ func (k msgServer) CreateSequencer(goCtx context.Context, msg *types.MsgCreateSe // 1. the initial sequencer from getting selected as the first proposer, // 2. the rollapp from getting sealed // In case the InitialSequencer is set to the "*" wildcard, any sequencer can be the first to register. - isInitialOrAllAllowed := slices.Contains(strings.Split(rollapp.InitialSequencer, ","), msg.Creator) || rollapp.InitialSequencer == "*" - if !rollapp.Sealed { - if isInitialOrAllAllowed { - if err := k.rollappKeeper.SealRollapp(ctx, msg.RollappId); err != nil { - return nil, err - } - } else { + isInitialOrAllAllowed := slices.Contains(strings.Split(rollapp.InitialSequencer, ","), msg.Creator) || rollapp.InitialSequencer == "*" + if !isInitialOrAllAllowed { return nil, types.ErrNotInitialSequencer } + if err := k.rollappKeeper.SealRollapp(ctx, msg.RollappId); err != nil { + return nil, err + } } bond := sdk.Coins{} @@ -85,10 +83,24 @@ func (k msgServer) CreateSequencer(goCtx context.Context, msg *types.MsgCreateSe RollappId: msg.RollappId, Metadata: msg.Metadata, Status: types.Bonded, - Proposer: !rollapp.Sealed, Tokens: bond, } + // we currently only support setting next proposer (or empty one) before the rotation started. This is in order to + // avoid handling the case a potential next proposer bonds in the middle of a rotation. + // This will be handled in next iteration. + nextProposer, ok := k.GetNextProposer(ctx, msg.RollappId) + if ok && nextProposer.IsEmpty() { + k.Logger(ctx).Info("rotation in progress. sequencer registration disabled", "rollappId", sequencer.RollappId) + return nil, types.ErrRotationInProgress + } + + // if no proposer set for he rollapp, set this sequencer as the proposer + _, proposerExists := k.GetProposer(ctx, msg.RollappId) + if !proposerExists { + k.SetProposer(ctx, sequencer.RollappId, sequencer.Address) + } + k.SetSequencer(ctx, sequencer) ctx.EventManager().EmitEvent( @@ -97,7 +109,7 @@ func (k msgServer) CreateSequencer(goCtx context.Context, msg *types.MsgCreateSe sdk.NewAttribute(types.AttributeKeyRollappId, msg.RollappId), sdk.NewAttribute(types.AttributeKeySequencer, msg.Creator), sdk.NewAttribute(types.AttributeKeyBond, msg.Bond.String()), - sdk.NewAttribute(types.AttributeKeyProposer, strconv.FormatBool(sequencer.Proposer)), + sdk.NewAttribute(types.AttributeKeyProposer, strconv.FormatBool(!proposerExists)), ), ) diff --git a/x/sequencer/keeper/msg_server_create_sequencer_test.go b/x/sequencer/keeper/msg_server_create_sequencer_test.go index a4a40ee35..1f460bef1 100644 --- a/x/sequencer/keeper/msg_server_create_sequencer_test.go +++ b/x/sequencer/keeper/msg_server_create_sequencer_test.go @@ -57,10 +57,8 @@ func (suite *SequencerTestSuite) TestMinBond() { } for _, tc := range testCases { - suite.SetupTest() seqParams := types.DefaultParams() seqParams.MinBond = tc.requiredBond - seqParams.UnbondingTime = 100 suite.App.SequencerKeeper.SetParams(suite.Ctx, seqParams) rollappId, pk := suite.CreateDefaultRollapp() @@ -110,6 +108,7 @@ func (suite *SequencerTestSuite) TestCreateSequencer() { rollappId, sequencerAddress string } rollappSequencersExpect := make(map[rollappSequencersExpectKey]string) + rollappExpectedProposers := make(map[string]string) const numRollapps = 3 rollappIDs := make([]string, numRollapps) @@ -162,10 +161,7 @@ func (suite *SequencerTestSuite) TestCreateSequencer() { Tokens: sdk.NewCoins(bond), Metadata: sequencerMsg.GetMetadata(), } - if i == 0 { - sequencerExpect.Status = types.Bonded - sequencerExpect.Proposer = true - } + // create sequencer createResponse, err := suite.msgServer.CreateSequencer(goCtx, &sequencerMsg) suite.Require().Nil(err) @@ -181,12 +177,16 @@ func (suite *SequencerTestSuite) TestCreateSequencer() { // add the sequencer to the list of get all expected list sequencersExpect = append(sequencersExpect, &sequencerExpect) + if i == 0 { + rollappExpectedProposers[rollappId] = sequencerExpect.Address + } + sequencersRes, totalRes := getAll(suite) suite.Require().EqualValues(len(sequencersExpect), totalRes) // verify that query all contains all the sequencers that were created suite.verifyAll(sequencersExpect, sequencersRes) - // add the sequencer to the list of spesific rollapp + // add the sequencer to the list of specific rollapp rollappSequencersExpect[rollappSequencersExpectKey{rollappId, sequencerExpect.Address}] = sequencerExpect.Address } } @@ -204,6 +204,12 @@ func (suite *SequencerTestSuite) TestCreateSequencer() { sequencer.Address) } totalFound += len(queryAllResponse.Sequencers) + + // check that the first sequencer created is the active sequencer + proposer, err := suite.queryClient.GetProposerByRollapp(goCtx, + &types.QueryGetProposerByRollappRequest{RollappId: rollappId}) + suite.Require().Nil(err) + suite.Require().EqualValues(proposer.ProposerAddr, rollappExpectedProposers[rollappId]) } suite.Require().EqualValues(totalFound, len(rollappSequencersExpect)) } @@ -214,7 +220,6 @@ func (suite *SequencerTestSuite) TestCreateSequencerAlreadyExists() { rollappId, pk := suite.CreateDefaultRollapp() addr := sdk.AccAddress(pk.Address()) - err := bankutil.FundAccount(suite.App.BankKeeper, suite.Ctx, addr, sdk.NewCoins(bond)) suite.Require().NoError(err) @@ -234,6 +239,15 @@ func (suite *SequencerTestSuite) TestCreateSequencerAlreadyExists() { _, err = suite.msgServer.CreateSequencer(goCtx, &sequencerMsg) suite.EqualError(err, types.ErrSequencerExists.Error()) + + // unbond the sequencer + unbondMsg := types.MsgUnbond{Creator: addr.String()} + _, err = suite.msgServer.Unbond(goCtx, &unbondMsg) + suite.Require().NoError(err) + + // create the sequencer again, expect to fail anyway + _, err = suite.msgServer.CreateSequencer(goCtx, &sequencerMsg) + suite.EqualError(err, types.ErrSequencerExists.Error()) } func (suite *SequencerTestSuite) TestCreateSequencerInitialSequencerAsProposer() { @@ -317,16 +331,20 @@ func (suite *SequencerTestSuite) TestCreateSequencerInitialSequencerAsProposer() }, } _, err = suite.msgServer.CreateSequencer(goCtx, &sequencerMsg) - suite.Require().ErrorIs(err, tc.expErr) + suite.Require().ErrorIs(err, tc.expErr, tc.name) if tc.expErr != nil { return } // check that the sequencer is the proposer - initSequencer, ok := suite.App.SequencerKeeper.GetSequencer(suite.Ctx, addr.String()) + proposer, ok := suite.App.SequencerKeeper.GetProposer(suite.Ctx, rollappId) suite.Require().True(ok) - suite.Require().Equal(seq.expProposer, initSequencer.Proposer) + if seq.expProposer { + suite.Require().Equal(addr.String(), proposer.Address, tc.name) + } else { + suite.Require().NotEqual(addr.String(), proposer.Address, tc.name) + } } } } @@ -354,31 +372,6 @@ func (suite *SequencerTestSuite) TestCreateSequencerUnknownRollappId() { suite.EqualError(err, types.ErrUnknownRollappID.Error()) } -func (suite *SequencerTestSuite) TestUpdateStateSecondSeqErrNotActiveSequencer() { - suite.SetupTest() - - rollappId, pk1 := suite.CreateDefaultRollapp() - - // create first sequencer - addr1 := suite.CreateDefaultSequencer(suite.Ctx, rollappId, pk1) - - pk2 := ed25519.GenPrivKey().PubKey() - // create second sequencer - addr2 := suite.CreateDefaultSequencer(suite.Ctx, rollappId, pk2) - - // check scheduler operating status - scheduler, found := suite.App.SequencerKeeper.GetSequencer(suite.Ctx, addr1) - suite.Require().True(found) - suite.EqualValues(scheduler.Status, types.Bonded) - suite.True(scheduler.Proposer) - - // check scheduler operating status - scheduler, found = suite.App.SequencerKeeper.GetSequencer(suite.Ctx, addr2) - suite.Require().True(found) - suite.EqualValues(scheduler.Status, types.Bonded) - suite.False(scheduler.Proposer) -} - // --------------------------------------- // verifyAll receives a list of expected results and a map of sequencerAddress->sequencer // the function verifies that the map contains all the sequencers that are in the list and only them @@ -462,13 +455,15 @@ func compareSequencers(s1, s2 *types.Sequencer) bool { return false } - if s1.UnbondingHeight != s2.UnbondingHeight { + if s1.UnbondRequestHeight != s2.UnbondRequestHeight { return false } if !s1.UnbondTime.Equal(s2.UnbondTime) { return false } - + if !s1.NoticePeriodTime.Equal(s2.NoticePeriodTime) { + return false + } if !reflect.DeepEqual(s1.Metadata, s2.Metadata) { return false } diff --git a/x/sequencer/keeper/msg_server_decrease_bond_test.go b/x/sequencer/keeper/msg_server_decrease_bond_test.go index eb4d0a964..7c94f987b 100644 --- a/x/sequencer/keeper/msg_server_decrease_bond_test.go +++ b/x/sequencer/keeper/msg_server_decrease_bond_test.go @@ -14,16 +14,16 @@ func (suite *SequencerTestSuite) TestDecreaseBond() { defaultSequencerAddress := suite.CreateSequencerWithBond(suite.Ctx, rollappId, bond.AddAmount(sdk.NewInt(20)), pk) // setup an unbonded sequencer unbondedPk := ed25519.GenPrivKey().PubKey() - unbondedSequencerAddress := suite.CreateDefaultSequencer(suite.Ctx, rollappId, unbondedPk) + unbondedSequencerAddress := suite.CreateSequencer(suite.Ctx, rollappId, unbondedPk) unbondedSequencer, _ := suite.App.SequencerKeeper.GetSequencer(suite.Ctx, unbondedSequencerAddress) unbondedSequencer.Status = types.Unbonded - suite.App.SequencerKeeper.UpdateSequencer(suite.Ctx, unbondedSequencer, unbondedSequencer.Status) + suite.App.SequencerKeeper.UpdateSequencer(suite.Ctx, &unbondedSequencer, unbondedSequencer.Status) // setup a jailed sequencer jailedPk := ed25519.GenPrivKey().PubKey() - jailedSequencerAddress := suite.CreateDefaultSequencer(suite.Ctx, rollappId, jailedPk) + jailedSequencerAddress := suite.CreateSequencer(suite.Ctx, rollappId, jailedPk) jailedSequencer, _ := suite.App.SequencerKeeper.GetSequencer(suite.Ctx, jailedSequencerAddress) jailedSequencer.Jailed = true - suite.App.SequencerKeeper.UpdateSequencer(suite.Ctx, jailedSequencer, jailedSequencer.Status) + suite.App.SequencerKeeper.UpdateSequencer(suite.Ctx, &jailedSequencer, jailedSequencer.Status) testCase := []struct { name string diff --git a/x/sequencer/keeper/msg_server_increase_bond.go b/x/sequencer/keeper/msg_server_increase_bond.go index 149934d0b..91151c71c 100644 --- a/x/sequencer/keeper/msg_server_increase_bond.go +++ b/x/sequencer/keeper/msg_server_increase_bond.go @@ -25,7 +25,7 @@ func (k msgServer) IncreaseBond(goCtx context.Context, msg *types.MsgIncreaseBon // update the sequencers bond amount in state sequencer.Tokens = sequencer.Tokens.Add(msg.AddAmount) - k.UpdateSequencer(ctx, sequencer, sequencer.Status) + k.UpdateSequencer(ctx, &sequencer, sequencer.Status) // emit a typed event which includes the added amount and the active bond amount err = ctx.EventManager().EmitTypedEvent( diff --git a/x/sequencer/keeper/msg_server_increase_bond_test.go b/x/sequencer/keeper/msg_server_increase_bond_test.go index bbeca5e4a..82666843a 100644 --- a/x/sequencer/keeper/msg_server_increase_bond_test.go +++ b/x/sequencer/keeper/msg_server_increase_bond_test.go @@ -13,19 +13,19 @@ import ( func (suite *SequencerTestSuite) TestIncreaseBond() { rollappId, pk := suite.CreateDefaultRollapp() // setup a default sequencer - defaultSequencerAddress := suite.CreateDefaultSequencer(suite.Ctx, rollappId, pk) + defaultSequencerAddress := suite.CreateSequencer(suite.Ctx, rollappId, pk) // setup an unbonded sequencer pk1 := ed25519.GenPrivKey().PubKey() - unbondedSequencerAddress := suite.CreateDefaultSequencer(suite.Ctx, rollappId, pk1) + unbondedSequencerAddress := suite.CreateSequencer(suite.Ctx, rollappId, pk1) unbondedSequencer, _ := suite.App.SequencerKeeper.GetSequencer(suite.Ctx, unbondedSequencerAddress) unbondedSequencer.Status = types.Unbonded - suite.App.SequencerKeeper.UpdateSequencer(suite.Ctx, unbondedSequencer, unbondedSequencer.Status) + suite.App.SequencerKeeper.UpdateSequencer(suite.Ctx, &unbondedSequencer, unbondedSequencer.Status) // setup a jailed sequencer pk2 := ed25519.GenPrivKey().PubKey() - jailedSequencerAddress := suite.CreateDefaultSequencer(suite.Ctx, rollappId, pk2) + jailedSequencerAddress := suite.CreateSequencer(suite.Ctx, rollappId, pk2) jailedSequencer, _ := suite.App.SequencerKeeper.GetSequencer(suite.Ctx, jailedSequencerAddress) jailedSequencer.Jailed = true - suite.App.SequencerKeeper.UpdateSequencer(suite.Ctx, jailedSequencer, jailedSequencer.Status) + suite.App.SequencerKeeper.UpdateSequencer(suite.Ctx, &jailedSequencer, jailedSequencer.Status) // fund all the sequencers which have been setup bondAmount := sdk.NewInt64Coin(types.DefaultParams().MinBond.Denom, 100) err := bankutil.FundAccount(suite.App.BankKeeper, suite.Ctx, sdk.MustAccAddressFromBech32(defaultSequencerAddress), sdk.NewCoins(bondAmount)) diff --git a/x/sequencer/keeper/msg_server_unbond.go b/x/sequencer/keeper/msg_server_unbond.go index b6a2ed5ce..aa7e73eef 100644 --- a/x/sequencer/keeper/msg_server_unbond.go +++ b/x/sequencer/keeper/msg_server_unbond.go @@ -2,7 +2,6 @@ package keeper import ( "context" - "time" errorsmod "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" @@ -14,54 +13,42 @@ import ( func (k msgServer) Unbond(goCtx context.Context, msg *types.MsgUnbond) (*types.MsgUnbondResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) - completionTime, err := k.setSequencerToUnbonding(ctx, msg.Creator) - if err != nil { - return nil, err - } - - return &types.MsgUnbondResponse{ - CompletionTime: completionTime, - }, nil -} - -func (k Keeper) setSequencerToUnbonding(ctx sdk.Context, seqAddr string) (time.Time, error) { - seq, found := k.GetSequencer(ctx, seqAddr) + seq, found := k.GetSequencer(ctx, msg.Creator) if !found { - return time.Time{}, types.ErrUnknownSequencer + return nil, types.ErrUnknownSequencer } if !seq.IsBonded() { - return time.Time{}, errorsmod.Wrapf( + return nil, errorsmod.Wrapf( types.ErrInvalidSequencerStatus, "sequencer status is not bonded: got %s", seq.Status.String(), ) } - oldStatus := seq.Status - wasProposer := seq.Proposer - - // set the status to unbonding - completionTime := ctx.BlockHeader().Time.Add(k.UnbondingTime(ctx)) - seq.Status = types.Unbonding - seq.Proposer = false - seq.UnbondingHeight = ctx.BlockHeight() - seq.UnbondTime = completionTime - k.UpdateSequencer(ctx, seq, oldStatus) - k.setUnbondingSequencerQueue(ctx, seq) - - ctx.EventManager().EmitEvent( - sdk.NewEvent( - types.EventTypeUnbonding, - sdk.NewAttribute(types.AttributeKeySequencer, seqAddr), - sdk.NewAttribute(types.AttributeKeyBond, seq.Tokens.String()), - sdk.NewAttribute(types.AttributeKeyCompletionTime, completionTime.String()), - ), - ) - - if wasProposer { - k.RotateProposer(ctx, seq.RollappId) + if seq.UnbondRequestHeight != 0 { + return nil, errorsmod.Wrapf( + types.ErrInvalidSequencerStatus, + "sequencer has already requested to unbond", + ) + } + seq.UnbondRequestHeight = ctx.BlockHeight() + + // check if the sequencer is required for a notice period before unbonding + if k.isNoticePeriodRequired(ctx, seq) { + completionTime := k.startNoticePeriodForSequencer(ctx, &seq) + return &types.MsgUnbondResponse{ + CompletionTime: &types.MsgUnbondResponse_NoticePeriodCompletionTime{ + NoticePeriodCompletionTime: &completionTime, + }, + }, nil } - return completionTime, nil + // otherwise, start unbonding + completionTime := k.startUnbondingPeriodForSequencer(ctx, &seq) + return &types.MsgUnbondResponse{ + CompletionTime: &types.MsgUnbondResponse_UnbondingCompletionTime{ + UnbondingCompletionTime: &completionTime, + }, + }, nil } diff --git a/x/sequencer/keeper/msg_server_unbond_test.go b/x/sequencer/keeper/msg_server_unbond_test.go index 7105303b3..2ee11caf3 100644 --- a/x/sequencer/keeper/msg_server_unbond_test.go +++ b/x/sequencer/keeper/msg_server_unbond_test.go @@ -1,95 +1,80 @@ package keeper_test import ( - "sort" "time" "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" - "github.com/dymensionxyz/dymension/v3/x/sequencer/types" ) -func (suite *SequencerTestSuite) TestUnbondingStatusChange() { - rollappId, pk1 := suite.CreateDefaultRollapp() +func (suite *SequencerTestSuite) TestUnbondingNonProposer() { + rollappId, pk := suite.CreateDefaultRollapp() + proposerAddr := suite.CreateSequencer(suite.Ctx, rollappId, pk) - addr1 := suite.CreateDefaultSequencer(suite.Ctx, rollappId, pk1) - seqAddrs := make([]string, 2) - pk2, pk3 := ed25519.GenPrivKey().PubKey(), ed25519.GenPrivKey().PubKey() - seqAddrs[0] = suite.CreateDefaultSequencer(suite.Ctx, rollappId, pk2) - seqAddrs[1] = suite.CreateDefaultSequencer(suite.Ctx, rollappId, pk3) - // sort the non proposer sequencers by address - sort.Strings(seqAddrs) - addr2 := seqAddrs[0] - addr3 := seqAddrs[1] + bondedAddr := suite.CreateDefaultSequencer(suite.Ctx, rollappId) + suite.Require().NotEqual(proposerAddr, bondedAddr) - /* ----------------------------- unbond proposer ---------------------------- */ - sequencer, found := suite.App.SequencerKeeper.GetSequencer(suite.Ctx, addr1) - suite.Require().True(found) - suite.Equal(types.Bonded, sequencer.Status) - suite.True(sequencer.Proposer) + proposer, ok := suite.App.SequencerKeeper.GetProposer(suite.Ctx, rollappId) + suite.Require().True(ok) + suite.Equal(proposerAddr, proposer.Address) - sequencer2, found := suite.App.SequencerKeeper.GetSequencer(suite.Ctx, addr2) + /* ------------------------- unbond non proposer sequencer ------------------------ */ + bondedSeq, found := suite.App.SequencerKeeper.GetSequencer(suite.Ctx, bondedAddr) suite.Require().True(found) - suite.Equal(types.Bonded, sequencer2.Status) - suite.False(sequencer2.Proposer) + suite.Equal(types.Bonded, bondedSeq.Status) - unbondMsg := types.MsgUnbond{Creator: addr1} + unbondMsg := types.MsgUnbond{Creator: bondedAddr} _, err := suite.msgServer.Unbond(suite.Ctx, &unbondMsg) suite.Require().NoError(err) - // check proposer rotation - sequencer2, _ = suite.App.SequencerKeeper.GetSequencer(suite.Ctx, addr2) - suite.Equal(types.Bonded, sequencer2.Status) - suite.True(sequencer2.Proposer) - // check sequencer operating status - sequencer, _ = suite.App.SequencerKeeper.GetSequencer(suite.Ctx, addr1) - suite.Equal(types.Unbonding, sequencer.Status) - suite.False(sequencer.Proposer) - - suite.App.SequencerKeeper.UnbondAllMatureSequencers(suite.Ctx, sequencer.UnbondTime.Add(10*time.Second)) - - sequencer, _ = suite.App.SequencerKeeper.GetSequencer(suite.Ctx, addr1) - suite.Equal(types.Unbonded, sequencer.Status) - - /* ------------------------- unbond non proposer sequencer ------------------------ */ - sequencer3, found := suite.App.SequencerKeeper.GetSequencer(suite.Ctx, addr3) + bondedSeq, found = suite.App.SequencerKeeper.GetSequencer(suite.Ctx, bondedAddr) suite.Require().True(found) - suite.Equal(types.Bonded, sequencer3.Status) - suite.False(sequencer3.Proposer) + suite.Equal(types.Unbonding, bondedSeq.Status) - unbondMsg = types.MsgUnbond{Creator: addr3} - _, err = suite.msgServer.Unbond(suite.Ctx, &unbondMsg) - suite.Require().NoError(err) - - // check sequencer operating status - sequencer3, found = suite.App.SequencerKeeper.GetSequencer(suite.Ctx, addr3) + suite.App.SequencerKeeper.UnbondAllMatureSequencers(suite.Ctx, bondedSeq.UnbondTime.Add(10*time.Second)) + bondedSeq, found = suite.App.SequencerKeeper.GetSequencer(suite.Ctx, bondedAddr) suite.Require().True(found) - suite.Equal(types.Unbonding, sequencer3.Status) + suite.Equal(types.Unbonded, bondedSeq.Status) - suite.App.SequencerKeeper.UnbondAllMatureSequencers(suite.Ctx, sequencer3.UnbondTime.Add(10*time.Second)) + // check proposer not changed + proposer, ok = suite.App.SequencerKeeper.GetProposer(suite.Ctx, rollappId) + suite.Require().True(ok) + suite.Equal(proposerAddr, proposer.Address) - sequencer3, found = suite.App.SequencerKeeper.GetSequencer(suite.Ctx, addr3) - suite.Require().True(found) - suite.Equal(types.Unbonded, sequencer3.Status) + // try to unbond again. already unbonded, we expect error + _, err = suite.msgServer.Unbond(suite.Ctx, &unbondMsg) + suite.Require().Error(err) } -func (suite *SequencerTestSuite) TestUnbondingNotBondedSequencer() { - rollappId, pk1 := suite.CreateDefaultRollapp() - addr1 := suite.CreateDefaultSequencer(suite.Ctx, rollappId, pk1) +func (suite *SequencerTestSuite) TestUnbondingProposer() { + suite.Ctx = suite.Ctx.WithBlockHeight(10) - unbondMsg := types.MsgUnbond{Creator: addr1} + rollappId, proposerAddr := suite.CreateDefaultRollappAndProposer() + _ = suite.CreateSequencer(suite.Ctx, rollappId, ed25519.GenPrivKey().PubKey()) + + /* ----------------------------- unbond proposer ---------------------------- */ + unbondMsg := types.MsgUnbond{Creator: proposerAddr} _, err := suite.msgServer.Unbond(suite.Ctx, &unbondMsg) suite.Require().NoError(err) - // already unbonding, we expect error + // check proposer still bonded and notice period started + p, ok := suite.App.SequencerKeeper.GetProposer(suite.Ctx, rollappId) + suite.Require().True(ok) + suite.Equal(proposerAddr, p.Address) + suite.Equal(suite.Ctx.BlockHeight(), p.UnbondRequestHeight) + + // unbonding again, we expect error as sequencer is in notice period _, err = suite.msgServer.Unbond(suite.Ctx, &unbondMsg) suite.Require().Error(err) - sequencer, _ := suite.App.SequencerKeeper.GetSequencer(suite.Ctx, addr1) - suite.App.SequencerKeeper.UnbondAllMatureSequencers(suite.Ctx, sequencer.UnbondTime.Add(10*time.Second)) + // next proposer should not be set yet + _, ok = suite.App.SequencerKeeper.GetNextProposer(suite.Ctx, rollappId) + suite.Require().False(ok) - // already unbonded, we expect error - _, err = suite.msgServer.Unbond(suite.Ctx, &unbondMsg) - suite.Require().Error(err) + // check notice period queue + m := suite.App.SequencerKeeper.GetMatureNoticePeriodSequencers(suite.Ctx, p.NoticePeriodTime.Add(-1*time.Second)) + suite.Require().Len(m, 0) + m = suite.App.SequencerKeeper.GetMatureNoticePeriodSequencers(suite.Ctx, p.NoticePeriodTime.Add(1*time.Second)) + suite.Require().Len(m, 1) } diff --git a/x/sequencer/keeper/msg_server_update_sequencer_test.go b/x/sequencer/keeper/msg_server_update_sequencer_test.go index a3100cb8e..e7b3aa926 100644 --- a/x/sequencer/keeper/msg_server_update_sequencer_test.go +++ b/x/sequencer/keeper/msg_server_update_sequencer_test.go @@ -84,12 +84,10 @@ func (suite *SequencerTestSuite) TestUpdateSequencer() { }, GasPrice: uptr.To(sdk.NewInt(100)), }, - Jailed: false, - Proposer: false, - Status: 0, - Tokens: nil, - UnbondingHeight: 0, - UnbondTime: time.Time{}, + Jailed: false, + Status: 0, + Tokens: nil, + UnbondTime: time.Time{}, }, }, { name: "Update rollapp: fail - try to update a non-existing rollapp", @@ -142,16 +140,14 @@ func (suite *SequencerTestSuite) TestUpdateSequencer() { suite.App.RollappKeeper.SetRollapp(suite.Ctx, rollapp) sequencer := types.Sequencer{ - Address: addr.String(), - DymintPubKey: pkAny, - RollappId: "rollapp_1234-1", - Metadata: types.SequencerMetadata{}, - Jailed: false, - Proposer: false, - Status: 0, - Tokens: nil, - UnbondingHeight: 0, - UnbondTime: time.Time{}, + Address: addr.String(), + DymintPubKey: pkAny, + RollappId: "rollapp_1234-1", + Metadata: types.SequencerMetadata{}, + Jailed: false, + Status: 0, + Tokens: nil, + UnbondTime: time.Time{}, } if tc.malleate != nil { diff --git a/x/sequencer/keeper/params.go b/x/sequencer/keeper/params.go index a29704a03..8551c49bd 100644 --- a/x/sequencer/keeper/params.go +++ b/x/sequencer/keeper/params.go @@ -13,6 +13,7 @@ func (k Keeper) GetParams(ctx sdk.Context) types.Params { return types.NewParams( k.MinBond(ctx), k.UnbondingTime(ctx), + k.NoticePeriod(ctx), k.LivenessSlashMultiplier(ctx), ) } @@ -27,6 +28,11 @@ func (k Keeper) UnbondingTime(ctx sdk.Context) (res time.Duration) { return } +func (k Keeper) NoticePeriod(ctx sdk.Context) (res time.Duration) { + k.paramstore.Get(ctx, types.KeyNoticePeriod, &res) + return +} + func (k Keeper) LivenessSlashMultiplier(ctx sdk.Context) (res sdk.Dec) { k.paramstore.Get(ctx, types.KeyLivenessSlashMultiplier, &res) return diff --git a/x/sequencer/keeper/rotation.go b/x/sequencer/keeper/rotation.go new file mode 100644 index 000000000..440cff138 --- /dev/null +++ b/x/sequencer/keeper/rotation.go @@ -0,0 +1,141 @@ +package keeper + +import ( + "sort" + "time" + + "cosmossdk.io/errors" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/dymensionxyz/dymension/v3/x/sequencer/types" + "github.com/dymensionxyz/gerr-cosmos/gerrc" +) + +func (k Keeper) startNoticePeriodForSequencer(ctx sdk.Context, seq *types.Sequencer) time.Time { + completionTime := ctx.BlockTime().Add(k.NoticePeriod(ctx)) + seq.NoticePeriodTime = completionTime + + k.UpdateSequencer(ctx, seq) + k.AddSequencerToNoticePeriodQueue(ctx, seq) + + ctx.EventManager().EmitEvent( + sdk.NewEvent( + types.EventTypeNoticePeriodStarted, + sdk.NewAttribute(types.AttributeKeyRollappId, seq.RollappId), + sdk.NewAttribute(types.AttributeKeySequencer, seq.Address), + sdk.NewAttribute(types.AttributeKeyCompletionTime, completionTime.String()), + ), + ) + + return completionTime +} + +// MatureSequencersWithNoticePeriod start rotation flow for all sequencers that have finished their notice period +// The next proposer is set to the next bonded sequencer +// The hub will expect a "last state update" from the sequencer to start unbonding +// In the middle of rotation, the next proposer required a notice period as well. +func (k Keeper) MatureSequencersWithNoticePeriod(ctx sdk.Context, currTime time.Time) { + seqs := k.GetMatureNoticePeriodSequencers(ctx, currTime) + for _, seq := range seqs { + if k.isProposer(ctx, seq.RollappId, seq.Address) { + k.startRotation(ctx, seq.RollappId) + k.removeNoticePeriodSequencer(ctx, seq) + } + // next proposer cannot mature it's notice period until the current proposer has finished rotation + // minor effect as notice_period >>> rotation time + } +} + +// IsRotating returns true if the rollapp is currently in the process of rotation. +// A process of rotation is defined by the existence of a next proposer. The next proposer can also be a "dummy" sequencer (i.e empty) in case no sequencer came. This is still considered rotation +// as the sequencer is rotating to an empty one (i.e gracefully leaving the rollapp). +// The next proposer can only be set after the notice period is over. The rotation period is over after the proposer sends his last batch. +func (k Keeper) IsRotating(ctx sdk.Context, rollappId string) bool { + return k.isNextProposerSet(ctx, rollappId) +} + +// isNoticePeriodRequired returns true if the sequencer requires a notice period before unbonding +// Both the proposer and the next proposer require a notice period +func (k Keeper) isNoticePeriodRequired(ctx sdk.Context, seq types.Sequencer) bool { + return k.isProposer(ctx, seq.RollappId, seq.Address) || k.isNextProposer(ctx, seq.RollappId, seq.Address) +} + +// ExpectedNextProposer returns the next proposer for a rollapp +// it selects the next proposer from the bonded sequencers by bond amount +// if there are no bonded sequencers, it returns an empty sequencer +func (k Keeper) ExpectedNextProposer(ctx sdk.Context, rollappId string) types.Sequencer { + // if nextProposer is set, were in the middle of rotation. The expected next proposer cannot change + seq, ok := k.GetNextProposer(ctx, rollappId) + if ok { + return seq + } + + // take the next bonded sequencer to be the proposer. sorted by bond + seqs := k.GetSequencersByRollappByStatus(ctx, rollappId, types.Bonded) + sort.SliceStable(seqs, func(i, j int) bool { + return seqs[i].Tokens.IsAllGT(seqs[j].Tokens) + }) + + // return the first sequencer that is not the proposer + proposer, _ := k.GetProposer(ctx, rollappId) + for _, s := range seqs { + if s.Address != proposer.Address { + return s + } + } + + return types.Sequencer{} +} + +// startRotation sets the nextSequencer for the rollapp. +// This function will not clear the current proposer +// This function called when the sequencer has finished its notice period +func (k Keeper) startRotation(ctx sdk.Context, rollappId string) { + // next proposer can be empty if there are no bonded sequencers available + nextProposer := k.ExpectedNextProposer(ctx, rollappId) + k.setNextProposer(ctx, rollappId, nextProposer.Address) + + k.Logger(ctx).Info("rotation started", "rollappId", rollappId, "nextProposer", nextProposer.Address) + + ctx.EventManager().EmitEvent( + sdk.NewEvent( + types.EventTypeRotationStarted, + sdk.NewAttribute(types.AttributeKeyRollappId, rollappId), + sdk.NewAttribute(types.AttributeKeyNextProposer, nextProposer.Address), + ), + ) +} + +// CompleteRotation completes the sequencer rotation flow. +// It's called when a last state update is received from the active, rotating sequencer. +// it will start unbonding the current proposer, and sets the nextProposer as the proposer. +func (k Keeper) CompleteRotation(ctx sdk.Context, rollappId string) error { + proposer, ok := k.GetProposer(ctx, rollappId) + if !ok { + return errors.Wrapf(gerrc.ErrInternal, "proposer not set for rollapp %s", rollappId) + } + nextProposer, ok := k.GetNextProposer(ctx, rollappId) + if !ok { + return errors.Wrapf(gerrc.ErrInternal, "next proposer not set for rollapp %s", rollappId) + } + + // start unbonding the current proposer + k.startUnbondingPeriodForSequencer(ctx, &proposer) + + // change the proposer + k.removeNextProposer(ctx, rollappId) + k.SetProposer(ctx, rollappId, nextProposer.Address) + + if nextProposer.Address == NO_SEQUENCER_AVAILABLE { + k.Logger(ctx).Info("Rollapp left with no proposer.", "RollappID", rollappId) + } + + ctx.EventManager().EmitEvent( + sdk.NewEvent( + types.EventTypeProposerRotated, + sdk.NewAttribute(types.AttributeKeyRollappId, rollappId), + sdk.NewAttribute(types.AttributeKeySequencer, nextProposer.Address), + ), + ) + + return nil +} diff --git a/x/sequencer/keeper/rotation_test.go b/x/sequencer/keeper/rotation_test.go new file mode 100644 index 000000000..eafbec0a3 --- /dev/null +++ b/x/sequencer/keeper/rotation_test.go @@ -0,0 +1,193 @@ +package keeper_test + +import ( + "time" + + "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/dymensionxyz/dymension/v3/x/sequencer/types" +) + +func (suite *SequencerTestSuite) TestExpectedNextProposer() { + type testCase struct { + name string + numSeqAddrs int + expectEmptyNextProposer bool + } + + testCases := []testCase{ + {"No additional sequencers", 0, true}, + {"few", 4, false}, + } + + for _, tc := range testCases { + suite.Run(tc.name, func() { + suite.SetupTest() + + rollappId, pk := suite.CreateDefaultRollapp() + _ = suite.CreateSequencerWithBond(suite.Ctx, rollappId, bond, pk) // proposer, with highest bond + + seqAddrs := make([]string, tc.numSeqAddrs) + currBond := sdk.NewCoin(bond.Denom, bond.Amount.Quo(sdk.NewInt(10))) + for i := 0; i < len(seqAddrs); i++ { + currBond = currBond.AddAmount(bond.Amount) + pubkey := ed25519.GenPrivKey().PubKey() + seqAddrs[i] = suite.CreateSequencerWithBond(suite.Ctx, rollappId, currBond, pubkey) + } + next := suite.App.SequencerKeeper.ExpectedNextProposer(suite.Ctx, rollappId) + if tc.expectEmptyNextProposer { + suite.Require().Empty(next.Address) + return + } + + expectedNextProposer := seqAddrs[len(seqAddrs)-1] + suite.Equal(expectedNextProposer, next.Address) + }) + } +} + +// TestStartRotation tests the StartRotation function which is called when a sequencer has finished its notice period +func (suite *SequencerTestSuite) TestStartRotation() { + rollappId, pk := suite.CreateDefaultRollapp() + addr1 := suite.CreateSequencer(suite.Ctx, rollappId, pk) + + _ = suite.CreateDefaultSequencer(suite.Ctx, rollappId) + _ = suite.CreateDefaultSequencer(suite.Ctx, rollappId) + + /* ----------------------------- unbond proposer ---------------------------- */ + unbondMsg := types.MsgUnbond{Creator: addr1} + _, err := suite.msgServer.Unbond(suite.Ctx, &unbondMsg) + suite.Require().NoError(err) + + // check proposer still bonded and notice period started + p, ok := suite.App.SequencerKeeper.GetProposer(suite.Ctx, rollappId) + suite.Require().True(ok) + suite.Equal(addr1, p.Address) + suite.Equal(suite.Ctx.BlockHeight(), p.UnbondRequestHeight) + + m := suite.App.SequencerKeeper.GetMatureNoticePeriodSequencers(suite.Ctx, p.NoticePeriodTime.Add(-10*time.Second)) + suite.Require().Len(m, 0) + m = suite.App.SequencerKeeper.GetMatureNoticePeriodSequencers(suite.Ctx, p.NoticePeriodTime.Add(10*time.Second)) + suite.Require().Len(m, 1) + suite.App.SequencerKeeper.MatureSequencersWithNoticePeriod(suite.Ctx, p.NoticePeriodTime.Add(10*time.Second)) + + // validate nextProposer is set + n, ok := suite.App.SequencerKeeper.GetNextProposer(suite.Ctx, rollappId) + suite.Require().True(ok) + suite.Require().NotEmpty(n.Address) + + // validate proposer not changed + p, _ = suite.App.SequencerKeeper.GetProposer(suite.Ctx, rollappId) + suite.Equal(addr1, p.Address) +} + +func (suite *SequencerTestSuite) TestRotateProposer() { + rollappId, pk := suite.CreateDefaultRollapp() + addr1 := suite.CreateSequencer(suite.Ctx, rollappId, pk) + addr2 := suite.CreateSequencer(suite.Ctx, rollappId, ed25519.GenPrivKey().PubKey()) + + /* ----------------------------- unbond proposer ---------------------------- */ + unbondMsg := types.MsgUnbond{Creator: addr1} + res, err := suite.msgServer.Unbond(suite.Ctx, &unbondMsg) + suite.Require().NoError(err) + + // mature notice period + suite.App.SequencerKeeper.MatureSequencersWithNoticePeriod(suite.Ctx, res.GetNoticePeriodCompletionTime().Add(10*time.Second)) + _, ok := suite.App.SequencerKeeper.GetNextProposer(suite.Ctx, rollappId) + suite.Require().True(ok) + + // simulate lastBlock received + err = suite.App.SequencerKeeper.CompleteRotation(suite.Ctx, rollappId) + suite.Require().NoError(err) + + // assert addr2 is now proposer + p, ok := suite.App.SequencerKeeper.GetProposer(suite.Ctx, rollappId) + suite.Require().True(ok) + suite.Equal(addr2, p.Address) + // assert addr1 is unbonding + u, _ := suite.App.SequencerKeeper.GetSequencer(suite.Ctx, addr1) + suite.Equal(types.Unbonding, u.Status) + // assert nextProposer is nil + _, ok = suite.App.SequencerKeeper.GetNextProposer(suite.Ctx, rollappId) + suite.Require().False(ok) +} + +func (suite *SequencerTestSuite) TestRotateProposerNoNextProposer() { + rollappId, pk := suite.CreateDefaultRollapp() + addr1 := suite.CreateSequencer(suite.Ctx, rollappId, pk) + + /* ----------------------------- unbond proposer ---------------------------- */ + unbondMsg := types.MsgUnbond{Creator: addr1} + res, err := suite.msgServer.Unbond(suite.Ctx, &unbondMsg) + suite.Require().NoError(err) + + // mature notice period + suite.App.SequencerKeeper.MatureSequencersWithNoticePeriod(suite.Ctx, res.GetNoticePeriodCompletionTime().Add(10*time.Second)) + // simulate lastBlock received + err = suite.App.SequencerKeeper.CompleteRotation(suite.Ctx, rollappId) + suite.Require().NoError(err) + + _, ok := suite.App.SequencerKeeper.GetProposer(suite.Ctx, rollappId) + suite.Require().False(ok) + + _, ok = suite.App.SequencerKeeper.GetNextProposer(suite.Ctx, rollappId) + suite.Require().False(ok) +} + +// Both the proposer and nextProposer tries to unbond +func (suite *SequencerTestSuite) TestStartRotationTwice() { + suite.Ctx = suite.Ctx.WithBlockHeight(10) + + rollappId, pk := suite.CreateDefaultRollapp() + addr1 := suite.CreateSequencer(suite.Ctx, rollappId, pk) + addr2 := suite.CreateSequencer(suite.Ctx, rollappId, ed25519.GenPrivKey().PubKey()) + + // unbond proposer + unbondMsg := types.MsgUnbond{Creator: addr1} + _, err := suite.msgServer.Unbond(suite.Ctx, &unbondMsg) + suite.Require().NoError(err) + + p, ok := suite.App.SequencerKeeper.GetProposer(suite.Ctx, rollappId) + suite.Require().True(ok) + suite.Equal(addr1, p.Address) + suite.Equal(suite.Ctx.BlockHeight(), p.UnbondRequestHeight) + + suite.App.SequencerKeeper.MatureSequencersWithNoticePeriod(suite.Ctx, p.NoticePeriodTime.Add(10*time.Second)) + suite.Require().True(suite.App.SequencerKeeper.IsRotating(suite.Ctx, rollappId)) + + n, ok := suite.App.SequencerKeeper.GetNextProposer(suite.Ctx, rollappId) + suite.Require().True(ok) + suite.Equal(addr2, n.Address) + + // unbond nextProposer before rotation completes + suite.Ctx = suite.Ctx.WithBlockHeight(20) + unbondMsg = types.MsgUnbond{Creator: addr2} + _, err = suite.msgServer.Unbond(suite.Ctx, &unbondMsg) + suite.Require().NoError(err) + + // check nextProposer is still the nextProposer and notice period started + n, ok = suite.App.SequencerKeeper.GetNextProposer(suite.Ctx, rollappId) + suite.Require().True(ok) + suite.Equal(addr2, n.Address) + suite.Require().True(n.IsNoticePeriodInProgress()) + + // rotation completes before notice period ends for addr2 (the nextProposer) + err = suite.App.SequencerKeeper.CompleteRotation(suite.Ctx, rollappId) // simulate lastBlock received + suite.Require().NoError(err) + + // validate addr2 is now proposer and still with notice period + p, _ = suite.App.SequencerKeeper.GetProposer(suite.Ctx, rollappId) + suite.Equal(addr2, p.Address) + suite.Require().True(p.IsNoticePeriodInProgress()) + + // validate nextProposer is unset after rotation completes + n, ok = suite.App.SequencerKeeper.GetNextProposer(suite.Ctx, rollappId) + suite.Require().False(ok) + + // mature notice period for addr2 + suite.App.SequencerKeeper.MatureSequencersWithNoticePeriod(suite.Ctx, p.NoticePeriodTime.Add(10*time.Second)) + // validate nextProposer is set + n, ok = suite.App.SequencerKeeper.GetNextProposer(suite.Ctx, rollappId) + suite.Require().True(ok) + suite.Require().Empty(n.Address) +} diff --git a/x/sequencer/keeper/sequencer.go b/x/sequencer/keeper/sequencer.go index 74c81bb8b..e38f8465a 100644 --- a/x/sequencer/keeper/sequencer.go +++ b/x/sequencer/keeper/sequencer.go @@ -1,7 +1,6 @@ package keeper import ( - "sort" "time" "github.com/cosmos/cosmos-sdk/store/prefix" @@ -10,6 +9,9 @@ import ( "github.com/dymensionxyz/dymension/v3/x/sequencer/types" ) +// used to indicate that no sequencer is available for a proposer / next proposer role +const NO_SEQUENCER_AVAILABLE = "" + // SetSequencer set a specific sequencer in the store from its index func (k Keeper) SetSequencer(ctx sdk.Context, sequencer types.Sequencer) { store := ctx.KVStore(k.storeKey) @@ -20,61 +22,23 @@ func (k Keeper) SetSequencer(ctx sdk.Context, sequencer types.Sequencer) { seqByRollappKey := types.SequencerByRollappByStatusKey(sequencer.RollappId, sequencer.Address, sequencer.Status) store.Set(seqByRollappKey, b) - - // To support InitGenesis scenario - if sequencer.Status == types.Unbonding { - k.setUnbondingSequencerQueue(ctx, sequencer) - } } -func (k Keeper) UpdateSequencer(ctx sdk.Context, sequencer types.Sequencer, oldStatus types.OperatingStatus) { - store := ctx.KVStore(k.storeKey) - b := k.cdc.MustMarshal(&sequencer) - store.Set(types.SequencerKey(sequencer.Address), b) - - seqByRollappKey := types.SequencerByRollappByStatusKey(sequencer.RollappId, sequencer.Address, sequencer.Status) - store.Set(seqByRollappKey, b) +// UpdateSequencer updates the state of a sequencer in the keeper. +// Parameters: +// - sequencer: The sequencer object to be updated. +// - oldStatus: An optional parameter representing the old status of the sequencer. +// Needs to be provided if the status of the sequencer has changed (e.g from Bonded to Unbonding). +func (k Keeper) UpdateSequencer(ctx sdk.Context, sequencer *types.Sequencer, oldStatus ...types.OperatingStatus) { + k.SetSequencer(ctx, *sequencer) // status changed, need to remove old status key - if sequencer.Status != oldStatus { - oldKey := types.SequencerByRollappByStatusKey(sequencer.RollappId, sequencer.Address, oldStatus) - store.Delete(oldKey) + if len(oldStatus) > 0 && sequencer.Status != oldStatus[0] { + oldKey := types.SequencerByRollappByStatusKey(sequencer.RollappId, sequencer.Address, oldStatus[0]) + ctx.KVStore(k.storeKey).Delete(oldKey) } } -// RotateProposer sets the proposer for a rollapp to be the proposer with the greatest bond -// This function will not clear the current proposer (assumes no proposer is set) -func (k Keeper) RotateProposer(ctx sdk.Context, rollappId string) { - seqs := k.GetSequencersByRollappByStatus(ctx, rollappId, types.Bonded) - if len(seqs) == 0 { - k.Logger(ctx).Info("no bonded sequencer found for rollapp", "rollappId", rollappId) - ctx.EventManager().EmitEvent( - sdk.NewEvent( - types.EventTypeNoBondedSequencer, - sdk.NewAttribute(types.AttributeKeyRollappId, rollappId), - ), - ) - return - } - - // take the next bonded sequencer to be the proposer. sorted by bond - sort.SliceStable(seqs, func(i, j int) bool { - return seqs[i].Tokens.IsAllGT(seqs[j].Tokens) - }) - - seq := seqs[0] - seq.Proposer = true - k.UpdateSequencer(ctx, seq, types.Bonded) - - ctx.EventManager().EmitEvent( - sdk.NewEvent( - types.EventTypeProposerRotated, - sdk.NewAttribute(types.AttributeKeyRollappId, rollappId), - sdk.NewAttribute(types.AttributeKeySequencer, seq.Address), - ), - ) -} - // GetSequencer returns a sequencer from its index func (k Keeper) GetSequencer(ctx sdk.Context, sequencerAddress string) (val types.Sequencer, found bool) { store := ctx.KVStore(k.storeKey) @@ -89,6 +53,16 @@ func (k Keeper) GetSequencer(ctx sdk.Context, sequencerAddress string) (val type return val, true } +// MustGetSequencer returns a sequencer from its index +// It will panic if the sequencer is not found +func (k Keeper) MustGetSequencer(ctx sdk.Context, sequencerAddress string) types.Sequencer { + seq, found := k.GetSequencer(ctx, sequencerAddress) + if !found { + panic("sequencer not found") + } + return seq +} + // GetAllSequencers returns all sequencer func (k Keeper) GetAllSequencers(ctx sdk.Context) (list []types.Sequencer) { store := prefix.NewStore(ctx.KVStore(k.storeKey), types.SequencersKeyPrefix) @@ -158,9 +132,9 @@ func (k Keeper) GetMatureUnbondingSequencers(ctx sdk.Context, endTime time.Time) return } -func (k Keeper) setUnbondingSequencerQueue(ctx sdk.Context, sequencer types.Sequencer) { +func (k Keeper) AddSequencerToUnbondingQueue(ctx sdk.Context, sequencer *types.Sequencer) { store := ctx.KVStore(k.storeKey) - b := k.cdc.MustMarshal(&sequencer) + b := k.cdc.MustMarshal(sequencer) unbondingQueueKey := types.UnbondingSequencerKey(sequencer.Address, sequencer.UnbondTime) store.Set(unbondingQueueKey, b) @@ -172,3 +146,127 @@ func (k Keeper) removeUnbondingSequencer(ctx sdk.Context, sequencer types.Sequen unbondingQueueKey := types.UnbondingSequencerKey(sequencer.Address, sequencer.UnbondTime) store.Delete(unbondingQueueKey) } + +/* -------------------------------------------------------------------------- */ +/* notice period */ +/* -------------------------------------------------------------------------- */ + +// GetMatureNoticePeriodSequencers returns all sequencers that have finished their notice period +func (k Keeper) GetMatureNoticePeriodSequencers(ctx sdk.Context, endTime time.Time) (list []types.Sequencer) { + store := ctx.KVStore(k.storeKey) + iterator := store.Iterator(types.NoticePeriodQueueKey, sdk.PrefixEndBytes(types.NoticePeriodQueueByTimeKey(endTime))) + + defer iterator.Close() // nolint: errcheck + + for ; iterator.Valid(); iterator.Next() { + var val types.Sequencer + k.cdc.MustUnmarshal(iterator.Value(), &val) + list = append(list, val) + } + + return +} + +// AddSequencerToNoticePeriodQueue set sequencer in notice period queue +func (k Keeper) AddSequencerToNoticePeriodQueue(ctx sdk.Context, sequencer *types.Sequencer) { + store := ctx.KVStore(k.storeKey) + b := k.cdc.MustMarshal(sequencer) + + noticePeriodKey := types.NoticePeriodSequencerKey(sequencer.Address, sequencer.NoticePeriodTime) + store.Set(noticePeriodKey, b) +} + +// remove sequencer from notice period queue +func (k Keeper) removeNoticePeriodSequencer(ctx sdk.Context, sequencer types.Sequencer) { + store := ctx.KVStore(k.storeKey) + noticePeriodKey := types.NoticePeriodSequencerKey(sequencer.Address, sequencer.NoticePeriodTime) + store.Delete(noticePeriodKey) +} + +/* ------------------------- proposer/next proposer ------------------------- */ + +// GetAllProposers returns all proposers for all rollapps +func (k Keeper) GetAllProposers(ctx sdk.Context) (list []types.Sequencer) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.ProposerByRollappKey("")) + iterator := sdk.KVStorePrefixIterator(store, []byte{}) + defer iterator.Close() // nolint: errcheck + + for ; iterator.Valid(); iterator.Next() { + address := string(iterator.Value()) + seq := k.MustGetSequencer(ctx, address) + list = append(list, seq) + } + + return +} + +func (k Keeper) SetProposer(ctx sdk.Context, rollappId, sequencerAddr string) { + store := ctx.KVStore(k.storeKey) + addressBytes := []byte(sequencerAddr) + + activeKey := types.ProposerByRollappKey(rollappId) + store.Set(activeKey, addressBytes) +} + +// GetProposer returns the proposer for a rollapp +func (k Keeper) GetProposer(ctx sdk.Context, rollappId string) (val types.Sequencer, found bool) { + store := ctx.KVStore(k.storeKey) + b := store.Get(types.ProposerByRollappKey(rollappId)) + if len(b) == 0 || string(b) == NO_SEQUENCER_AVAILABLE { + return val, false + } + + return k.GetSequencer(ctx, string(b)) +} + +func (k Keeper) removeProposer(ctx sdk.Context, rollappId string) { + k.SetProposer(ctx, rollappId, NO_SEQUENCER_AVAILABLE) +} + +func (k Keeper) isProposer(ctx sdk.Context, rollappId, seqAddr string) bool { + proposer, ok := k.GetProposer(ctx, rollappId) + return ok && proposer.Address == seqAddr +} + +// SetNextProposer sets the next proposer for a rollapp +// called when the proposer has finished its notice period and rotation flow has started +func (k Keeper) setNextProposer(ctx sdk.Context, rollappId, seqAddr string) { + store := ctx.KVStore(k.storeKey) + addressBytes := []byte(seqAddr) + nextProposerKey := types.NextProposerByRollappKey(rollappId) + store.Set(nextProposerKey, addressBytes) +} + +// GetNextProposer returns the next proposer for a rollapp +// It will return found=false if the next proposer is not set +// It will return found=true if the next proposer is set, even if it's empty +func (k Keeper) GetNextProposer(ctx sdk.Context, rollappId string) (val types.Sequencer, found bool) { + store := ctx.KVStore(k.storeKey) + b := store.Get(types.NextProposerByRollappKey(rollappId)) + if b == nil { + return val, false + } + + address := string(b) + if address == NO_SEQUENCER_AVAILABLE { + return val, true + } + return k.GetSequencer(ctx, address) +} + +func (k Keeper) isNextProposerSet(ctx sdk.Context, rollappId string) bool { + store := ctx.KVStore(k.storeKey) + return store.Has(types.NextProposerByRollappKey(rollappId)) +} + +func (k Keeper) isNextProposer(ctx sdk.Context, rollappId, seqAddr string) bool { + nextProposer, ok := k.GetNextProposer(ctx, rollappId) + return ok && nextProposer.Address == seqAddr +} + +// removeNextProposer removes the next proposer for a rollapp +// called when the proposer has finished its rotation flow +func (k Keeper) removeNextProposer(ctx sdk.Context, rollappId string) { + store := ctx.KVStore(k.storeKey) + store.Delete(types.NextProposerByRollappKey(rollappId)) +} diff --git a/x/sequencer/keeper/sequencer_suite_test.go b/x/sequencer/keeper/sequencer_suite_test.go index f56cb3636..35abcb253 100644 --- a/x/sequencer/keeper/sequencer_suite_test.go +++ b/x/sequencer/keeper/sequencer_suite_test.go @@ -62,7 +62,7 @@ func (suite *SequencerTestSuite) CreateRollappWithInitialSequencer(initSeq strin return rollapp.GetRollappId() } -func (suite *SequencerTestSuite) CreateDefaultSequencer(ctx sdk.Context, rollappId string, pk cryptotypes.PubKey) string { +func (suite *SequencerTestSuite) CreateSequencer(ctx sdk.Context, rollappId string, pk cryptotypes.PubKey) string { return suite.CreateSequencerWithBond(ctx, rollappId, bond, pk) } @@ -81,10 +81,24 @@ func (suite *SequencerTestSuite) CreateSequencerWithBond(ctx sdk.Context, rollap Bond: bond, RollappId: rollappId, Metadata: types.SequencerMetadata{ - Rpcs: []string{"https://rpc.wpd.evm.rollapp.noisnemyd.xyz:443"}, + Rpcs: []string{"https://rpc.wpd.evm.rollapp.noisnemyd.xyz:443"}, + EvmRpcs: []string{"https://rpc.evm.rollapp.noisnemyd.xyz:443"}, }, } _, err = suite.msgServer.CreateSequencer(ctx, &sequencerMsg1) suite.Require().NoError(err) return addr.String() } + +func (suite *SequencerTestSuite) assertJailed(seqAddr string) { + seq, found := suite.App.SequencerKeeper.GetSequencer(suite.Ctx, seqAddr) + suite.Require().True(found) + suite.True(seq.Jailed) + suite.Equal(types.Unbonded, seq.Status) + suite.Equal(sdk.Coins(nil), seq.Tokens) + + sequencers := suite.App.SequencerKeeper.GetMatureUnbondingSequencers(suite.Ctx, suite.Ctx.BlockTime()) + for _, s := range sequencers { + suite.NotEqual(s.Address, seqAddr) + } +} diff --git a/x/sequencer/keeper/sequencer_test.go b/x/sequencer/keeper/sequencer_test.go index 996138490..6b0f80494 100644 --- a/x/sequencer/keeper/sequencer_test.go +++ b/x/sequencer/keeper/sequencer_test.go @@ -4,7 +4,6 @@ import ( "strconv" "testing" - "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/require" @@ -69,32 +68,3 @@ func TestSequencersByRollappGet(t *testing.T) { nullify.Fill(rst), ) } - -func (suite *SequencerTestSuite) TestRotatingSequencerByBond() { - rollappId, pk := suite.CreateDefaultRollapp() - - numOfSequencers := 5 - - // create sequencers - seqAddrs := make([]string, numOfSequencers) - seqAddrs[0] = suite.CreateDefaultSequencer(suite.Ctx, rollappId, pk) - for j := 1; j < len(seqAddrs)-1; j++ { - seqAddrs[j] = suite.CreateDefaultSequencer(suite.Ctx, rollappId, ed25519.GenPrivKey().PubKey()) - } - // last one with high bond is the expected new proposer - pkx := ed25519.GenPrivKey().PubKey() - seqAddrs[len(seqAddrs)-1] = suite.CreateSequencerWithBond(suite.Ctx, rollappId, sdk.NewCoin(bond.Denom, bond.Amount.MulRaw(2)), pkx) - expecetedProposer := seqAddrs[len(seqAddrs)-1] - - // check starting proposer and unbond - sequencer, found := suite.App.SequencerKeeper.GetSequencer(suite.Ctx, seqAddrs[0]) - suite.Require().True(found) - suite.Require().True(sequencer.Proposer) - - suite.App.SequencerKeeper.RotateProposer(suite.Ctx, rollappId) - - // check proposer rotation - newProposer, _ := suite.App.SequencerKeeper.GetSequencer(suite.Ctx, expecetedProposer) - suite.Equal(types.Bonded, newProposer.Status) - suite.True(newProposer.Proposer) -} diff --git a/x/sequencer/keeper/slashing.go b/x/sequencer/keeper/slashing.go index 4c499e125..3e2dc1206 100644 --- a/x/sequencer/keeper/slashing.go +++ b/x/sequencer/keeper/slashing.go @@ -4,32 +4,15 @@ import ( errorsmod "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/dymensionxyz/dymension/v3/x/sequencer/types" - "github.com/dymensionxyz/gerr-cosmos/gerrc" "github.com/dymensionxyz/sdk-utils/utils/ucoin" ) -// SlashAndJailFraud slashes the sequencer for misbehaviour other than liveness issues -// Can occur on both Bonded and Unbonding sequencers -func (k Keeper) SlashAndJailFraud(ctx sdk.Context, seqAddr string) error { +func (k Keeper) JailSequencerOnFraud(ctx sdk.Context, seqAddr string) error { seq, found := k.GetSequencer(ctx, seqAddr) if !found { return types.ErrUnknownSequencer } - if seq.Status == types.Unbonded { - return errorsmod.Wrap( - types.ErrInvalidSequencerStatus, - "can't slash unbonded sequencer", - ) - } - - tokens := seq.Tokens - - // slash 100% of tokens - if err := k.Slash(ctx, &seq, tokens); err != nil { - return errorsmod.Wrap(err, "slash") - } - if err := k.Jail(ctx, seq); err != nil { return errorsmod.Wrap(err, "jail") } @@ -59,17 +42,27 @@ func (k Keeper) JailLiveness(ctx sdk.Context, rollappID string) error { // LivenessLiableSequencer returns the sequencer who is responsible for ensuring liveness func (k Keeper) LivenessLiableSequencer(ctx sdk.Context, rollappID string) (types.Sequencer, error) { - // TODO: find the sequencer who is currently responsible for ensuring liveness - // https://github.com/dymensionxyz/dymension/issues/1018 - return types.Sequencer{}, errorsmod.Wrap(gerrc.ErrNotFound, "not implemented") + proposer, found := k.GetProposer(ctx, rollappID) + if !found { + return types.Sequencer{}, types.ErrNoProposer + } + return proposer, nil } func (k Keeper) Slash(ctx sdk.Context, seq *types.Sequencer, amt sdk.Coins) error { - seq.Tokens = seq.Tokens.Sub(amt...) - err := k.bankKeeper.BurnCoins(ctx, types.ModuleName, amt) + if seq.Status == types.Unbonded { + return errorsmod.Wrap( + types.ErrInvalidSequencerStatus, + "can't slash unbonded sequencer", + ) + } + + err := k.reduceSequencerBond(ctx, seq, amt, true) if err != nil { - return errorsmod.Wrap(err, "burn coins") + return errorsmod.Wrap(err, "remove sequencer bond") } + k.UpdateSequencer(ctx, seq) + ctx.EventManager().EmitEvent( sdk.NewEvent( types.EventTypeSlashed, @@ -80,38 +73,18 @@ func (k Keeper) Slash(ctx sdk.Context, seq *types.Sequencer, amt sdk.Coins) erro return nil } +// Jail sets the sequencer status to Jailed and unbonds the sequencer func (k Keeper) Jail(ctx sdk.Context, seq types.Sequencer) error { - oldStatus := seq.Status - wasProposer := seq.Proposer - // in case we are slashing an unbonding sequencer, we need to remove it from the unbonding queue - if oldStatus == types.Unbonding { - k.removeUnbondingSequencer(ctx, seq) - } else { - // in case the sequencer is currently reducing its bond, then we need to remove it from the decreasing bond queue - // all the tokens are burned, so we don't need to reduce the bond anymore - if bondReductions := k.getSequencerDecreasingBonds(ctx, seq.Address); len(bondReductions) > 0 { - for _, bondReduce := range bondReductions { - k.removeDecreasingBondQueue(ctx, bondReduce) - } - } - } - - // set the status to unbonded - seq.Status = types.Unbonded - seq.Jailed = true - seq.Proposer = false - seq.UnbondingHeight = ctx.BlockHeight() - seq.UnbondTime = ctx.BlockHeader().Time - k.UpdateSequencer(ctx, seq, oldStatus) - // rotate proposer if the slashed sequencer was the proposer - if wasProposer { - k.RotateProposer(ctx, seq.RollappId) + err := k.unbondSequencerAndJail(ctx, seq.Address) + if err != nil { + return errorsmod.Wrap(err, "unbond and jail") } ctx.EventManager().EmitEvent( sdk.NewEvent( types.EventTypeJailed, sdk.NewAttribute(types.AttributeKeySequencer, seq.Address), + sdk.NewAttribute(types.AttributeKeyBond, seq.Tokens.String()), ), ) diff --git a/x/sequencer/keeper/slashing_fraud_test.go b/x/sequencer/keeper/slashing_fraud_test.go index 374cbd53e..9cfd99dca 100644 --- a/x/sequencer/keeper/slashing_fraud_test.go +++ b/x/sequencer/keeper/slashing_fraud_test.go @@ -3,108 +3,97 @@ package keeper_test import ( "time" - "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/dymensionxyz/dymension/v3/x/sequencer/types" ) -func (suite *SequencerTestSuite) assertSlashed(seqAddr string) { - seq, found := suite.App.SequencerKeeper.GetSequencer(suite.Ctx, seqAddr) - suite.Require().True(found) - suite.True(seq.Jailed) - suite.Equal(types.Unbonded, seq.Status) - suite.Equal(sdk.Coins(nil), seq.Tokens) - - sequencers := suite.App.SequencerKeeper.GetMatureUnbondingSequencers(suite.Ctx, suite.Ctx.BlockTime()) - for _, s := range sequencers { - suite.NotEqual(s.Address, seqAddr) - } -} - -func (suite *SequencerTestSuite) TestSlashingUnknownSequencer() { +func (suite *SequencerTestSuite) TestJailUnknownSequencer() { suite.CreateDefaultRollapp() keeper := suite.App.SequencerKeeper - err := keeper.SlashAndJailFraud(suite.Ctx, "unknown_sequencer") + err := keeper.JailSequencerOnFraud(suite.Ctx, "unknown_sequencer") suite.ErrorIs(err, types.ErrUnknownSequencer) } -func (suite *SequencerTestSuite) TestSlashingUnbondedSequencer() { +func (suite *SequencerTestSuite) TestJailUnbondedSequencer() { keeper := suite.App.SequencerKeeper - - rollappId, pk := suite.CreateDefaultRollapp() - seqAddr := suite.CreateDefaultSequencer(suite.Ctx, rollappId, pk) - suite.Ctx = suite.Ctx.WithBlockHeight(20) suite.Ctx = suite.Ctx.WithBlockTime(time.Now()) + rollappId, _ := suite.CreateDefaultRollappAndProposer() + seqAddr := suite.CreateDefaultSequencer(suite.Ctx, rollappId) // bonded non proposer + + // unbond the non-proposer unbondMsg := types.MsgUnbond{Creator: seqAddr} res, err := suite.msgServer.Unbond(suite.Ctx, &unbondMsg) suite.Require().NoError(err) - - unbondTime := res.CompletionTime + unbondTime := res.GetUnbondingCompletionTime() keeper.UnbondAllMatureSequencers(suite.Ctx, unbondTime.Add(1*time.Second)) - seq, found := keeper.GetSequencer(suite.Ctx, seqAddr) suite.Require().True(found) - suite.Equal(seq.Address, seqAddr) suite.Equal(seq.Status, types.Unbonded) - err = keeper.SlashAndJailFraud(suite.Ctx, seqAddr) + + // jail the unbonded sequencer + err = keeper.JailSequencerOnFraud(suite.Ctx, seqAddr) suite.ErrorIs(err, types.ErrInvalidSequencerStatus) } -func (suite *SequencerTestSuite) TestSlashingUnbondingSequencer() { +func (suite *SequencerTestSuite) TestJailUnbondingSequencer() { keeper := suite.App.SequencerKeeper - - rollappId, pk := suite.CreateDefaultRollapp() - seqAddr := suite.CreateDefaultSequencer(suite.Ctx, rollappId, pk) - suite.Ctx = suite.Ctx.WithBlockHeight(20) suite.Ctx = suite.Ctx.WithBlockTime(time.Now()) + rollappId, _ := suite.CreateDefaultRollappAndProposer() + seqAddr := suite.CreateDefaultSequencer(suite.Ctx, rollappId) // bonded non proposer + + // unbond the non-proposer unbondMsg := types.MsgUnbond{Creator: seqAddr} _, err := suite.msgServer.Unbond(suite.Ctx, &unbondMsg) suite.Require().NoError(err) - seq, ok := keeper.GetSequencer(suite.Ctx, seqAddr) suite.Require().True(ok) suite.Equal(seq.Status, types.Unbonding) - err = keeper.SlashAndJailFraud(suite.Ctx, seqAddr) - suite.NoError(err) - suite.assertSlashed(seqAddr) + // jail the unbonding sequencer + err = keeper.JailSequencerOnFraud(suite.Ctx, seqAddr) + suite.NoError(err) + suite.assertJailed(seqAddr) } -func (suite *SequencerTestSuite) TestSlashingProposerSequencer() { +func (suite *SequencerTestSuite) TestJailProposerSequencer() { keeper := suite.App.SequencerKeeper + suite.Ctx = suite.Ctx.WithBlockHeight(20) + suite.Ctx = suite.Ctx.WithBlockTime(time.Now()) - rollappId, pk1 := suite.CreateDefaultRollapp() - pk2 := ed25519.GenPrivKey().PubKey() - seqAddr := suite.CreateDefaultSequencer(suite.Ctx, rollappId, pk1) - seqAddr2 := suite.CreateDefaultSequencer(suite.Ctx, rollappId, pk2) + rollappId, proposer := suite.CreateDefaultRollappAndProposer() + err := keeper.JailSequencerOnFraud(suite.Ctx, proposer) + suite.NoError(err) + suite.assertJailed(proposer) + + _, found := keeper.GetProposer(suite.Ctx, rollappId) + suite.Require().False(found) +} +func (suite *SequencerTestSuite) TestJailBondReducingSequencer() { + keeper := suite.App.SequencerKeeper suite.Ctx = suite.Ctx.WithBlockHeight(20) suite.Ctx = suite.Ctx.WithBlockTime(time.Now()) - seq, ok := keeper.GetSequencer(suite.Ctx, seqAddr) - suite.Require().True(ok) - suite.Equal(seq.Status, types.Bonded) - suite.True(seq.Proposer) + rollappId, pk := suite.CreateDefaultRollapp() + seqAddr := suite.CreateSequencerWithBond(suite.Ctx, rollappId, bond.AddAmount(sdk.NewInt(20)), pk) - seq2, ok := keeper.GetSequencer(suite.Ctx, seqAddr2) - suite.Require().True(ok) - suite.Equal(seq2.Status, types.Bonded) - suite.False(seq2.Proposer) + reduceBondMsg := types.MsgDecreaseBond{Creator: seqAddr, DecreaseAmount: sdk.NewInt64Coin(bond.Denom, 10)} + resp, err := suite.msgServer.DecreaseBond(suite.Ctx, &reduceBondMsg) + suite.Require().NoError(err) + bondReductions := keeper.GetMatureDecreasingBondSequencers(suite.Ctx, resp.GetCompletionTime()) + suite.Require().Len(bondReductions, 1) - err := keeper.SlashAndJailFraud(suite.Ctx, seqAddr) + err = keeper.JailSequencerOnFraud(suite.Ctx, seqAddr) suite.NoError(err) - suite.assertSlashed(seqAddr) - - seq2, ok = keeper.GetSequencer(suite.Ctx, seqAddr2) - suite.Require().True(ok) - suite.Equal(seq2.Status, types.Bonded) - suite.True(seq2.Proposer) + bondReductions = keeper.GetMatureDecreasingBondSequencers(suite.Ctx, resp.GetCompletionTime()) + suite.Require().Len(bondReductions, 0) + suite.assertJailed(seqAddr) } diff --git a/x/sequencer/keeper/slashing_test.go b/x/sequencer/keeper/slashing_test.go index 8edb5f4b2..4b9edbb47 100644 --- a/x/sequencer/keeper/slashing_test.go +++ b/x/sequencer/keeper/slashing_test.go @@ -1,19 +1,11 @@ package keeper_test -import ( - "time" - - sdk "github.com/cosmos/cosmos-sdk/types" - - "github.com/dymensionxyz/dymension/v3/x/sequencer/types" -) - func (s *SequencerTestSuite) TestSlashBasic() { s.Run("slash at zero does not error", func() { // There shouldn't be an error if the sequencer has no tokens k := s.App.SequencerKeeper rollappId, pk := s.CreateDefaultRollapp() - seqAddr := s.CreateDefaultSequencer(s.Ctx, rollappId, pk) + seqAddr := s.CreateSequencer(s.Ctx, rollappId, pk) seq, found := k.GetSequencer(s.Ctx, seqAddr) s.Require().True(found) err := k.Slash(s.Ctx, &seq, seq.Tokens) @@ -22,27 +14,3 @@ func (s *SequencerTestSuite) TestSlashBasic() { s.Require().NoError(err) }) } - -func (suite *SequencerTestSuite) TestSlashAndJailBondReducingSequencer() { - suite.SetupTest() - keeper := suite.App.SequencerKeeper - - rollappId, pk := suite.CreateDefaultRollapp() - seqAddr := suite.CreateSequencerWithBond(suite.Ctx, rollappId, bond.AddAmount(sdk.NewInt(20)), pk) - - suite.Ctx = suite.Ctx.WithBlockHeight(20) - suite.Ctx = suite.Ctx.WithBlockTime(time.Now()) - - reduceBondMsg := types.MsgDecreaseBond{Creator: seqAddr, DecreaseAmount: sdk.NewInt64Coin(bond.Denom, 10)} - resp, err := suite.msgServer.DecreaseBond(suite.Ctx, &reduceBondMsg) - suite.Require().NoError(err) - bondReductions := keeper.GetMatureDecreasingBondSequencers(suite.Ctx, resp.GetCompletionTime()) - suite.Require().Len(bondReductions, 1) - - err = keeper.SlashAndJailFraud(suite.Ctx, seqAddr) - suite.NoError(err) - - bondReductions = keeper.GetMatureDecreasingBondSequencers(suite.Ctx, resp.GetCompletionTime()) - suite.Require().Len(bondReductions, 0) - suite.assertSlashed(seqAddr) -} diff --git a/x/sequencer/keeper/unbond.go b/x/sequencer/keeper/unbond.go index be0fc280d..07a26a967 100644 --- a/x/sequencer/keeper/unbond.go +++ b/x/sequencer/keeper/unbond.go @@ -10,13 +10,36 @@ import ( "github.com/dymensionxyz/dymension/v3/x/sequencer/types" ) +// startUnbondingPeriodForSequencer sets the sequencer to unbonding status +// can be called after notice period or directly if notice period is not required +// caller is responsible for updating the proposer for the rollapp if needed +func (k Keeper) startUnbondingPeriodForSequencer(ctx sdk.Context, seq *types.Sequencer) time.Time { + completionTime := ctx.BlockTime().Add(k.UnbondingTime(ctx)) + seq.UnbondTime = completionTime + + seq.Status = types.Unbonding + k.UpdateSequencer(ctx, seq, types.Bonded) + k.AddSequencerToUnbondingQueue(ctx, seq) + + ctx.EventManager().EmitEvent( + sdk.NewEvent( + types.EventTypeUnbonding, + sdk.NewAttribute(types.AttributeKeySequencer, seq.Address), + sdk.NewAttribute(types.AttributeKeyBond, seq.Tokens.String()), + sdk.NewAttribute(types.AttributeKeyCompletionTime, completionTime.String()), + ), + ) + + return completionTime +} + // UnbondAllMatureSequencers unbonds all the mature unbonding sequencers that // have finished their unbonding period. func (k Keeper) UnbondAllMatureSequencers(ctx sdk.Context, currTime time.Time) { sequencers := k.GetMatureUnbondingSequencers(ctx, currTime) for _, seq := range sequencers { wrapFn := func(ctx sdk.Context) error { - return k.unbondUnbondingSequencer(ctx, seq.Address) + return k.unbondSequencer(ctx, seq.Address) } err := osmoutils.ApplyFuncIfNoError(ctx, wrapFn) if err != nil { @@ -26,158 +49,132 @@ func (k Keeper) UnbondAllMatureSequencers(ctx sdk.Context, currTime time.Time) { } } -func (k Keeper) HandleBondReduction(ctx sdk.Context, currTime time.Time) { - unbondings := k.GetMatureDecreasingBondSequencers(ctx, currTime) - for _, unbonding := range unbondings { - wrapFn := func(ctx sdk.Context) error { - return k.completeBondReduction(ctx, unbonding) - } - err := osmoutils.ApplyFuncIfNoError(ctx, wrapFn) +// InstantUnbondAllSequencers unbonds all sequencers for a rollapp +// This is called when there is a fraud +func (k Keeper) InstantUnbondAllSequencers(ctx sdk.Context, rollappID string) error { + // unbond all bonded/unbonding sequencers + bonded := k.GetSequencersByRollappByStatus(ctx, rollappID, types.Bonded) + unbonding := k.GetSequencersByRollappByStatus(ctx, rollappID, types.Unbonding) + for _, sequencer := range append(bonded, unbonding...) { + err := k.unbondSequencer(ctx, sequencer.Address) if err != nil { - k.Logger(ctx).Error("reducing sequencer bond", "error", err, "sequencer", unbonding.SequencerAddress) - continue + return err } } + + return nil } -func (k Keeper) forceUnbondSequencer(ctx sdk.Context, seqAddr string) error { - seq, found := k.GetSequencer(ctx, seqAddr) - if !found { - return types.ErrUnknownSequencer +// reduceSequencerBond reduces the bond of a sequencer +// if burn is true, the tokens are burned, otherwise they are refunded +// returns an error if the sequencer does not have enough bond +// method updates the sequencer object. doesn't update the store +func (k Keeper) reduceSequencerBond(ctx sdk.Context, seq *types.Sequencer, amt sdk.Coins, burn bool) error { + if amt.IsZero() { + return nil } - - if seq.Status == types.Unbonded { - return errorsmod.Wrapf( - types.ErrInvalidSequencerStatus, - "sequencer status is already unbonded", - ) - } - - oldStatus := seq.Status - - seqTokens := seq.Tokens - if !seqTokens.Empty() { - seqAcc, err := sdk.AccAddressFromBech32(seq.Address) + if burn { + err := k.bankKeeper.BurnCoins(ctx, types.ModuleName, amt) if err != nil { return err } - - err = k.bankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, seqAcc, seqTokens) + } else { + // refund + seqAcc := sdk.MustAccAddressFromBech32(seq.Address) + err := k.bankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, seqAcc, amt) if err != nil { return err } - } else { - k.Logger(ctx).Error("sequencer has no tokens to unbond", "sequencer", seq.Address) } - // set the status to unbonded and remove from the unbonding queue if needed - seq.Status = types.Unbonded - seq.Proposer = false - seq.Tokens = sdk.Coins{} - - k.UpdateSequencer(ctx, seq, oldStatus) - - if oldStatus == types.Unbonding { - k.removeUnbondingSequencer(ctx, seq) - } else { - // in case the sequencer is currently reducing its bond, then we need to remove it from the decreasing bond queue - // all the tokens are returned, so we don't need to reduce the bond anymore - if bondReductions := k.getSequencerDecreasingBonds(ctx, seq.Address); len(bondReductions) > 0 { - for _, bondReduce := range bondReductions { - k.removeDecreasingBondQueue(ctx, bondReduce) - } - } - } + seq.Tokens = seq.Tokens.Sub(amt...) + return nil +} - ctx.EventManager().EmitEvent( - sdk.NewEvent( - types.EventTypeUnbonded, - sdk.NewAttribute(types.AttributeKeySequencer, seqAddr), - sdk.NewAttribute(types.AttributeKeyBond, seqTokens.String()), - ), - ) +func (k Keeper) unbondSequencerAndJail(ctx sdk.Context, seqAddr string) error { + return k.unbond(ctx, seqAddr, true) +} - return nil +func (k Keeper) unbondSequencer(ctx sdk.Context, seqAddr string) error { + return k.unbond(ctx, seqAddr, false) } -// unbondUnbondingSequencer unbonds a sequencer that currently unbonding -func (k Keeper) unbondUnbondingSequencer(ctx sdk.Context, seqAddr string) error { +// unbond unbonds a sequencer +// if jail is true, the sequencer is jailed as well (cannot be bonded again) +// bonded tokens are refunded by default, unless jail is true +func (k Keeper) unbond(ctx sdk.Context, seqAddr string, jail bool) error { seq, found := k.GetSequencer(ctx, seqAddr) if !found { return types.ErrUnknownSequencer } - if seq.Status != types.Unbonding { + if seq.Status == types.Unbonded { return errorsmod.Wrapf( types.ErrInvalidSequencerStatus, - "sequencer status is not unbonding: got %s", - seq.Status.String(), + "sequencer status is already unbonded", ) } - seqTokens := seq.Tokens - if !seqTokens.Empty() { - seqAcc, err := sdk.AccAddressFromBech32(seq.Address) - if err != nil { - return err + // keep the old status for updating the sequencer + oldStatus := seq.Status + + // handle bond: tokens refunded by default, unless jail is true + err := k.reduceSequencerBond(ctx, &seq, seq.Tokens, jail) + if err != nil { + return errorsmod.Wrap(err, "remove sequencer bond") + } + + /* ------------------------------ store cleanup ----------------------------- */ + // remove from queue if unbonding + if oldStatus == types.Unbonding { + k.removeUnbondingSequencer(ctx, seq) + } else { + // remove from notice period queue if needed + if seq.IsNoticePeriodInProgress() { + k.removeNoticePeriodSequencer(ctx, seq) } - err = k.bankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, seqAcc, seqTokens) - if err != nil { - return err + // if we unbond the proposer, remove it + // the caller should rotate the proposer + if k.isProposer(ctx, seq.RollappId, seqAddr) { + k.removeProposer(ctx, seq.RollappId) + } + + // if we unbond the next proposer, we're in the middle of rotation + // the caller should clean the rotation state + if k.isNextProposer(ctx, seq.RollappId, seqAddr) { + k.removeNextProposer(ctx, seq.RollappId) + } + } + // in case the sequencer is currently reducing its bond, then we need to remove it from the decreasing bond queue + // all the tokens are returned, so we don't need to reduce the bond anymore + if bondReductions := k.getSequencerDecreasingBonds(ctx, seq.Address); len(bondReductions) > 0 { + for _, bondReduce := range bondReductions { + k.removeDecreasingBondQueue(ctx, bondReduce) } - } else { - k.Logger(ctx).Error("sequencer has no tokens to unbond", "sequencer", seq.Address) } - // set the status to unbonded and remove from the unbonding queue - seq.Status = types.Unbonded - seq.Tokens = sdk.Coins{} + if jail { + seq.Jailed = true + } + // set the unbonding height and time, if not already set. + // to avoid leaving unbonded sequencer in the store with no unbond height or time + if seq.UnbondRequestHeight == 0 { + seq.UnbondRequestHeight = ctx.BlockHeight() + } + if seq.UnbondTime.IsZero() { + seq.UnbondTime = ctx.BlockTime() + } - k.UpdateSequencer(ctx, seq, types.Unbonding) - k.removeUnbondingSequencer(ctx, seq) + // update the sequencer in store + seq.Status = types.Unbonded + k.UpdateSequencer(ctx, &seq, oldStatus) ctx.EventManager().EmitEvent( sdk.NewEvent( types.EventTypeUnbonded, sdk.NewAttribute(types.AttributeKeySequencer, seqAddr), - sdk.NewAttribute(types.AttributeKeyBond, seqTokens.String()), ), ) return nil } - -func (k Keeper) completeBondReduction(ctx sdk.Context, reduction types.BondReduction) error { - seq, found := k.GetSequencer(ctx, reduction.SequencerAddress) - if !found { - return types.ErrUnknownSequencer - } - - if seq.Tokens.IsAllLT(sdk.NewCoins(reduction.DecreaseBondAmount)) { - return errorsmod.Wrapf( - types.ErrInsufficientBond, - "sequencer does not have enough bond to reduce insufficient bond: got %s, reducing by %s", - seq.Tokens.String(), - reduction.DecreaseBondAmount.String(), - ) - } - newBalance := seq.Tokens.Sub(reduction.DecreaseBondAmount) - // in case between unbonding queue and now, the minbond value is increased, - // handle it by only returning upto minBond amount and not all - minBond := k.GetParams(ctx).MinBond - if newBalance.IsAllLT(sdk.NewCoins(minBond)) { - diff := minBond.SubAmount(newBalance.AmountOf(minBond.Denom)) - reduction.DecreaseBondAmount = reduction.DecreaseBondAmount.Sub(diff) - } - seqAddr := sdk.MustAccAddressFromBech32(reduction.SequencerAddress) - err := k.bankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, seqAddr, sdk.NewCoins(reduction.DecreaseBondAmount)) - if err != nil { - return err - } - - seq.Tokens = seq.Tokens.Sub(reduction.DecreaseBondAmount) - k.SetSequencer(ctx, seq) - k.removeDecreasingBondQueue(ctx, reduction) - - return nil -} diff --git a/x/sequencer/keeper/unbond_test.go b/x/sequencer/keeper/unbond_test.go index bf021bd00..28ec69c27 100644 --- a/x/sequencer/keeper/unbond_test.go +++ b/x/sequencer/keeper/unbond_test.go @@ -18,7 +18,7 @@ func (suite *SequencerTestSuite) TestUnbondingMultiple() { rollappId, pk1 := suite.CreateDefaultRollapp() rollappId2, pk2 := suite.CreateDefaultRollapp() - numOfSequencers := 5 + numOfSequencers := 4 numOfSequencers2 := 3 unbodingSeq := 2 @@ -26,15 +26,15 @@ func (suite *SequencerTestSuite) TestUnbondingMultiple() { seqAddr2 := make([]string, numOfSequencers2) // create 5 sequencers for rollapp1 - seqAddr1[0] = suite.CreateDefaultSequencer(suite.Ctx, rollappId, pk1) + seqAddr1[0] = suite.CreateSequencer(suite.Ctx, rollappId, pk1) for i := 1; i < numOfSequencers; i++ { - seqAddr1[i] = suite.CreateDefaultSequencer(suite.Ctx, rollappId, ed25519.GenPrivKey().PubKey()) + seqAddr1[i] = suite.CreateSequencer(suite.Ctx, rollappId, ed25519.GenPrivKey().PubKey()) } // create 3 sequencers for rollapp2 - seqAddr2[0] = suite.CreateDefaultSequencer(suite.Ctx, rollappId2, pk2) + seqAddr2[0] = suite.CreateSequencer(suite.Ctx, rollappId2, pk2) for i := 1; i < numOfSequencers2; i++ { - seqAddr2[i] = suite.CreateDefaultSequencer(suite.Ctx, rollappId2, ed25519.GenPrivKey().PubKey()) + seqAddr2[i] = suite.CreateSequencer(suite.Ctx, rollappId2, ed25519.GenPrivKey().PubKey()) } // start unbonding for 2 sequencers in each rollapp @@ -42,7 +42,7 @@ func (suite *SequencerTestSuite) TestUnbondingMultiple() { now := time.Now() unbondTime := now.Add(keeper.GetParams(suite.Ctx).UnbondingTime) suite.Ctx = suite.Ctx.WithBlockTime(now) - for i := 0; i < unbodingSeq; i++ { + for i := 1; i < unbodingSeq+1; i++ { unbondMsg := types.MsgUnbond{Creator: seqAddr1[i]} _, err := suite.msgServer.Unbond(suite.Ctx, &unbondMsg) suite.Require().NoError(err) @@ -69,20 +69,19 @@ func (suite *SequencerTestSuite) TestTokensRefundOnUnbond() { blockheight := 20 var err error - rollappId, pk1 := suite.CreateDefaultRollapp() - addr1 := suite.CreateDefaultSequencer(suite.Ctx, rollappId, pk1) + rollappId, pk := suite.CreateDefaultRollapp() + _ = suite.CreateSequencer(suite.Ctx, rollappId, pk) + + pk1 := ed25519.GenPrivKey().PubKey() + addr1 := suite.CreateSequencer(suite.Ctx, rollappId, pk1) sequencer1, _ := suite.App.SequencerKeeper.GetSequencer(suite.Ctx, addr1) suite.Require().True(sequencer1.Status == types.Bonded) - suite.Require().True(sequencer1.Proposer) - suite.Require().False(sequencer1.Tokens.IsZero()) pk2 := ed25519.GenPrivKey().PubKey() - addr2 := suite.CreateDefaultSequencer(suite.Ctx, rollappId, pk2) + addr2 := suite.CreateSequencer(suite.Ctx, rollappId, pk2) sequencer2, _ := suite.App.SequencerKeeper.GetSequencer(suite.Ctx, addr2) suite.Require().True(sequencer2.Status == types.Bonded) - suite.Require().False(sequencer2.Proposer) - suite.Require().False(sequencer2.Tokens.IsZero()) suite.Ctx = suite.Ctx.WithBlockHeight(int64(blockheight)) @@ -94,7 +93,7 @@ func (suite *SequencerTestSuite) TestTokensRefundOnUnbond() { suite.Require().NoError(err) sequencer1, _ = suite.App.SequencerKeeper.GetSequencer(suite.Ctx, addr1) suite.Require().True(sequencer1.Status == types.Unbonding) - suite.Require().Equal(sequencer1.UnbondingHeight, int64(blockheight)) + suite.Require().Equal(sequencer1.UnbondRequestHeight, int64(blockheight)) suite.Require().False(sequencer1.Tokens.IsZero()) // start the 2nd unbond later diff --git a/x/sequencer/module.go b/x/sequencer/module.go index 8e234913c..806c94939 100644 --- a/x/sequencer/module.go +++ b/x/sequencer/module.go @@ -161,7 +161,14 @@ func (am AppModule) BeginBlock(_ sdk.Context, _ abci.RequestBeginBlock) {} // EndBlock executes all ABCI EndBlock logic respective to the capability module. It // returns no validator updates. func (am AppModule) EndBlock(ctx sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate { - am.keeper.UnbondAllMatureSequencers(ctx, ctx.BlockHeader().Time) - am.keeper.HandleBondReduction(ctx, ctx.BlockHeader().Time) + // start unbonding period for sequencers after notice period + am.keeper.MatureSequencersWithNoticePeriod(ctx, ctx.BlockTime()) + + // Unbond all mature sequencers + am.keeper.UnbondAllMatureSequencers(ctx, ctx.BlockTime()) + + // Handle bond reduction + am.keeper.HandleBondReduction(ctx, ctx.BlockTime()) + return []abci.ValidatorUpdate{} } diff --git a/x/sequencer/types/errors.go b/x/sequencer/types/errors.go index 086607846..1710a6f4d 100644 --- a/x/sequencer/types/errors.go +++ b/x/sequencer/types/errors.go @@ -25,6 +25,8 @@ var ( ErrUnknownRequest = errorsmod.Register(ModuleName, 1017, "unknown request") ErrInvalidRequest = errorsmod.Register(ModuleName, 1018, "invalid request") ErrSequencerJailed = errorsmod.Register(ModuleName, 1019, "sequencer is jailed") + ErrRotationInProgress = errorsmod.Wrap(gerrc.ErrFailedPrecondition, "sequencer rotation in progress") + ErrNoProposer = errorsmod.Wrap(gerrc.ErrNotFound, "proposer") ErrNotInitialSequencer = errorsmod.Wrap(gerrc.ErrFailedPrecondition, "not the initial sequencer") ErrInvalidURL = errorsmod.Wrap(gerrc.ErrInvalidArgument, "invalid url") ErrInvalidMetadata = errorsmod.Wrap(gerrc.ErrInvalidArgument, "invalid metadata") diff --git a/x/sequencer/types/events.go b/x/sequencer/types/events.go index 8cecaebe6..f3258928f 100644 --- a/x/sequencer/types/events.go +++ b/x/sequencer/types/events.go @@ -3,22 +3,36 @@ package types // Incentive module event types. const ( // EventTypeCreateSequencer is emitted when a sequencer is created + // Attributes: + // - AttributeKeyRollappId + // - AttributeKeySequencer + // - AttributeKeyBond + // - AttributeKeyProposer EventTypeCreateSequencer = "create_sequencer" - AttributeKeyRollappId = "rollapp_id" - AttributeKeySequencer = "sequencer" - AttributeKeyBond = "bond" - AttributeKeyProposer = "proposer" - // EventTypeUnbonding is emitted when a sequencer is unbonding - EventTypeUnbonding = "unbonding" - AttributeKeyCompletionTime = "completion_time" - - // EventTypeNoBondedSequencer is emitted when no bonded sequencer is found for a rollapp - EventTypeNoBondedSequencer = "no_bonded_sequencer" + // EventTypeRotationStarted is emitted when a rotation is started (after notice period) + // Attributes: + // - AttributeKeyRollappId + // - AttributeKeyNextProposer + EventTypeRotationStarted = "proposer_rotation_started" // EventTypeProposerRotated is emitted when a proposer is rotated + // Attributes: + // - AttributeKeyRollappId + // - AttributeKeySequencer EventTypeProposerRotated = "proposer_rotated" + // EventTypeNoticePeriodStarted is emitted when a sequencer's notice period starts + // Attributes: + // - AttributeKeyRollappId + // - AttributeKeySequencer + // - AttributeNextProposer + // - AttributeKeyCompletionTime + EventTypeNoticePeriodStarted = "notice_period_started" + + // EventTypeUnbonding is emitted when a sequencer is unbonding + EventTypeUnbonding = "unbonding" + // EventTypeUnbonded is emitted when a sequencer is unbonded EventTypeUnbonded = "unbonded" @@ -28,4 +42,11 @@ const ( EventTypeJailed = "jailed" // EventTypeBondIncreased is emitted when a sequencer's bond is increased EventTypeBondIncreased = "bond_increased" + + AttributeKeyRollappId = "rollapp_id" + AttributeKeySequencer = "sequencer" + AttributeKeyBond = "bond" + AttributeKeyProposer = "proposer" + AttributeKeyNextProposer = "next_proposer" + AttributeKeyCompletionTime = "completion_time" ) diff --git a/x/sequencer/types/genesis.go b/x/sequencer/types/genesis.go index 47121dfaf..6b840e7db 100644 --- a/x/sequencer/types/genesis.go +++ b/x/sequencer/types/genesis.go @@ -5,8 +5,9 @@ import "fmt" // DefaultGenesis returns the default Capability genesis state func DefaultGenesis() *GenesisState { return &GenesisState{ - SequencerList: []Sequencer{}, - Params: DefaultParams(), + SequencerList: []Sequencer{}, + GenesisProposers: []GenesisProposer{}, + Params: DefaultParams(), } } @@ -18,16 +19,27 @@ func (gs GenesisState) Validate() error { for _, elem := range gs.SequencerList { - // FIXME: should run validation on the sequencer objects + // TODO: should run validation on the sequencer objects - index := string(SequencerKey(elem.Address)) - if _, ok := sequencerIndexMap[index]; ok { - return fmt.Errorf("duplicated index for sequencer") + seqKey := string(SequencerKey(elem.Address)) + if _, ok := sequencerIndexMap[seqKey]; ok { + return fmt.Errorf("duplicated address for sequencer") } - sequencerIndexMap[index] = struct{}{} + sequencerIndexMap[seqKey] = struct{}{} } - // FIXME: validate single PROPOSER per rollapp + // Check for duplicated index in proposer + proposerIndexMap := make(map[string]struct{}) + for _, elem := range gs.GenesisProposers { + rollappId := elem.RollappId + if _, ok := proposerIndexMap[rollappId]; ok { + return fmt.Errorf("duplicated proposer for %s", rollappId) + } + if _, ok := sequencerIndexMap[string(SequencerKey(elem.Address))]; !ok { + return fmt.Errorf("proposer %s does not have a sequencer", rollappId) + } + proposerIndexMap[rollappId] = struct{}{} + } return gs.Params.Validate() } diff --git a/x/sequencer/types/genesis.pb.go b/x/sequencer/types/genesis.pb.go index 45d40caa6..437ebb004 100644 --- a/x/sequencer/types/genesis.pb.go +++ b/x/sequencer/types/genesis.pb.go @@ -25,9 +25,13 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package // GenesisState defines the sequencer module's genesis state. type GenesisState struct { - Params Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params"` - SequencerList []Sequencer `protobuf:"bytes,2,rep,name=sequencerList,proto3" json:"sequencerList"` - BondReductions []BondReduction `protobuf:"bytes,3,rep,name=bondReductions,proto3" json:"bondReductions"` + Params Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params"` + // sequencerList is a list of all defined sequencers + SequencerList []Sequencer `protobuf:"bytes,2,rep,name=sequencerList,proto3" json:"sequencerList"` + // genesisProposers is a list of the defined genesis proposers + GenesisProposers []GenesisProposer `protobuf:"bytes,3,rep,name=genesisProposers,proto3" json:"genesisProposers"` + // bondReductions is a list of all bond reductions + BondReductions []BondReduction `protobuf:"bytes,4,rep,name=bondReductions,proto3" json:"bondReductions"` } func (m *GenesisState) Reset() { *m = GenesisState{} } @@ -77,6 +81,13 @@ func (m *GenesisState) GetSequencerList() []Sequencer { return nil } +func (m *GenesisState) GetGenesisProposers() []GenesisProposer { + if m != nil { + return m.GenesisProposers + } + return nil +} + func (m *GenesisState) GetBondReductions() []BondReduction { if m != nil { return m.BondReductions @@ -84,8 +95,61 @@ func (m *GenesisState) GetBondReductions() []BondReduction { return nil } +type GenesisProposer struct { + Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` + RollappId string `protobuf:"bytes,2,opt,name=rollappId,proto3" json:"rollappId,omitempty"` +} + +func (m *GenesisProposer) Reset() { *m = GenesisProposer{} } +func (m *GenesisProposer) String() string { return proto.CompactTextString(m) } +func (*GenesisProposer) ProtoMessage() {} +func (*GenesisProposer) Descriptor() ([]byte, []int) { + return fileDescriptor_3115db717b16c2af, []int{1} +} +func (m *GenesisProposer) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *GenesisProposer) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_GenesisProposer.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *GenesisProposer) XXX_Merge(src proto.Message) { + xxx_messageInfo_GenesisProposer.Merge(m, src) +} +func (m *GenesisProposer) XXX_Size() int { + return m.Size() +} +func (m *GenesisProposer) XXX_DiscardUnknown() { + xxx_messageInfo_GenesisProposer.DiscardUnknown(m) +} + +var xxx_messageInfo_GenesisProposer proto.InternalMessageInfo + +func (m *GenesisProposer) GetAddress() string { + if m != nil { + return m.Address + } + return "" +} + +func (m *GenesisProposer) GetRollappId() string { + if m != nil { + return m.RollappId + } + return "" +} + func init() { proto.RegisterType((*GenesisState)(nil), "dymensionxyz.dymension.sequencer.GenesisState") + proto.RegisterType((*GenesisProposer)(nil), "dymensionxyz.dymension.sequencer.GenesisProposer") } func init() { @@ -93,24 +157,29 @@ func init() { } var fileDescriptor_3115db717b16c2af = []byte{ - // 271 bytes of a gzipped FileDescriptorProto + // 343 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xd2, 0x4b, 0xa9, 0xcc, 0x4d, 0xcd, 0x2b, 0xce, 0xcc, 0xcf, 0xab, 0xa8, 0xac, 0xd2, 0x87, 0x73, 0xf4, 0x8b, 0x53, 0x0b, 0x4b, 0x53, 0xf3, 0x92, 0x53, 0x8b, 0xf4, 0xd3, 0x53, 0xf3, 0x52, 0x8b, 0x33, 0x8b, 0xf5, 0x0a, 0x8a, 0xf2, 0x4b, 0xf2, 0x85, 0x14, 0x90, 0xd5, 0x23, 0x34, 0xeb, 0xc1, 0xd5, 0x4b, 0x89, 0xa4, 0xe7, 0xa7, 0xe7, 0x83, 0x15, 0xeb, 0x83, 0x58, 0x10, 0x7d, 0x52, 0xba, 0x04, 0xed, 0x29, 0x48, 0x2c, - 0x4a, 0xcc, 0x85, 0x5a, 0x23, 0x65, 0x40, 0x50, 0x39, 0x9c, 0x05, 0xd1, 0xa1, 0xd4, 0xc7, 0xc4, - 0xc5, 0xe3, 0x0e, 0x71, 0x6a, 0x70, 0x49, 0x62, 0x49, 0xaa, 0x90, 0x1b, 0x17, 0x1b, 0xc4, 0x48, - 0x09, 0x46, 0x05, 0x46, 0x0d, 0x6e, 0x23, 0x0d, 0x3d, 0x42, 0x4e, 0xd7, 0x0b, 0x00, 0xab, 0x77, - 0x62, 0x39, 0x71, 0x4f, 0x9e, 0x21, 0x08, 0xaa, 0x5b, 0x28, 0x9c, 0x8b, 0x17, 0xae, 0xc2, 0x27, - 0xb3, 0xb8, 0x44, 0x82, 0x49, 0x81, 0x59, 0x83, 0xdb, 0x48, 0x9b, 0xb0, 0x71, 0xc1, 0x30, 0x16, - 0xd4, 0x44, 0x54, 0x73, 0x84, 0x62, 0xb9, 0xf8, 0x92, 0xf2, 0xf3, 0x52, 0x82, 0x52, 0x53, 0x4a, - 0x93, 0x4b, 0x32, 0xf3, 0xf3, 0x8a, 0x25, 0x98, 0xc1, 0x26, 0xeb, 0x13, 0x36, 0xd9, 0x09, 0x59, - 0x1f, 0xd4, 0x74, 0x34, 0xc3, 0x9c, 0x02, 0x4e, 0x3c, 0x92, 0x63, 0xbc, 0xf0, 0x48, 0x8e, 0xf1, - 0xc1, 0x23, 0x39, 0xc6, 0x09, 0x8f, 0xe5, 0x18, 0x2e, 0x3c, 0x96, 0x63, 0xb8, 0xf1, 0x58, 0x8e, - 0x21, 0xca, 0x2c, 0x3d, 0xb3, 0x24, 0xa3, 0x34, 0x49, 0x2f, 0x39, 0x3f, 0x57, 0x1f, 0x47, 0x38, - 0x97, 0x19, 0xeb, 0x57, 0x20, 0x05, 0x76, 0x49, 0x65, 0x41, 0x6a, 0x71, 0x12, 0x1b, 0x38, 0xa4, - 0x8d, 0x01, 0x01, 0x00, 0x00, 0xff, 0xff, 0x86, 0xf4, 0xb9, 0xaf, 0x34, 0x02, 0x00, 0x00, + 0x4a, 0xcc, 0x85, 0x5a, 0x23, 0x65, 0x40, 0x50, 0x39, 0x9c, 0x05, 0xd1, 0xa1, 0xf4, 0x99, 0x89, + 0x8b, 0xc7, 0x1d, 0xe2, 0xd4, 0xe0, 0x92, 0xc4, 0x92, 0x54, 0x21, 0x37, 0x2e, 0x36, 0x88, 0x91, + 0x12, 0x8c, 0x0a, 0x8c, 0x1a, 0xdc, 0x46, 0x1a, 0x7a, 0x84, 0x9c, 0xae, 0x17, 0x00, 0x56, 0xef, + 0xc4, 0x72, 0xe2, 0x9e, 0x3c, 0x43, 0x10, 0x54, 0xb7, 0x50, 0x38, 0x17, 0x2f, 0x5c, 0x85, 0x4f, + 0x66, 0x71, 0x89, 0x04, 0x93, 0x02, 0xb3, 0x06, 0xb7, 0x91, 0x36, 0x61, 0xe3, 0x82, 0x61, 0x2c, + 0xa8, 0x89, 0xa8, 0xe6, 0x08, 0x25, 0x73, 0x09, 0x40, 0xc3, 0x36, 0xa0, 0x28, 0xbf, 0x20, 0xbf, + 0x38, 0xb5, 0xa8, 0x58, 0x82, 0x19, 0x6c, 0xb6, 0x21, 0x61, 0xb3, 0xdd, 0x51, 0x75, 0x42, 0x6d, + 0xc0, 0x30, 0x50, 0x28, 0x96, 0x8b, 0x2f, 0x29, 0x3f, 0x2f, 0x25, 0x28, 0x35, 0xa5, 0x34, 0xb9, + 0x24, 0x33, 0x3f, 0xaf, 0x58, 0x82, 0x05, 0x6c, 0x85, 0x3e, 0x61, 0x2b, 0x9c, 0x90, 0xf5, 0x41, + 0x2d, 0x40, 0x33, 0x4c, 0xc9, 0x93, 0x8b, 0x1f, 0xcd, 0x25, 0x42, 0x12, 0x5c, 0xec, 0x89, 0x29, + 0x29, 0x45, 0xa9, 0xc5, 0x90, 0x80, 0xe7, 0x0c, 0x82, 0x71, 0x85, 0x64, 0xb8, 0x38, 0x8b, 0xf2, + 0x73, 0x72, 0x12, 0x0b, 0x0a, 0x3c, 0x53, 0x24, 0x98, 0xc0, 0x72, 0x08, 0x01, 0xa7, 0x80, 0x13, + 0x8f, 0xe4, 0x18, 0x2f, 0x3c, 0x92, 0x63, 0x7c, 0xf0, 0x48, 0x8e, 0x71, 0xc2, 0x63, 0x39, 0x86, + 0x0b, 0x8f, 0xe5, 0x18, 0x6e, 0x3c, 0x96, 0x63, 0x88, 0x32, 0x4b, 0xcf, 0x2c, 0xc9, 0x28, 0x4d, + 0xd2, 0x4b, 0xce, 0xcf, 0xd5, 0xc7, 0x91, 0x2e, 0xca, 0x8c, 0xf5, 0x2b, 0x90, 0x12, 0x47, 0x49, + 0x65, 0x41, 0x6a, 0x71, 0x12, 0x1b, 0x38, 0x65, 0x18, 0x03, 0x02, 0x00, 0x00, 0xff, 0xff, 0x0d, + 0xdb, 0x09, 0xa8, 0xe4, 0x02, 0x00, 0x00, } func (m *GenesisState) Marshal() (dAtA []byte, err error) { @@ -144,6 +213,20 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintGenesis(dAtA, i, uint64(size)) } i-- + dAtA[i] = 0x22 + } + } + if len(m.GenesisProposers) > 0 { + for iNdEx := len(m.GenesisProposers) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.GenesisProposers[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- dAtA[i] = 0x1a } } @@ -174,6 +257,43 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *GenesisProposer) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *GenesisProposer) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *GenesisProposer) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.RollappId) > 0 { + i -= len(m.RollappId) + copy(dAtA[i:], m.RollappId) + i = encodeVarintGenesis(dAtA, i, uint64(len(m.RollappId))) + i-- + dAtA[i] = 0x12 + } + if len(m.Address) > 0 { + i -= len(m.Address) + copy(dAtA[i:], m.Address) + i = encodeVarintGenesis(dAtA, i, uint64(len(m.Address))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func encodeVarintGenesis(dAtA []byte, offset int, v uint64) int { offset -= sovGenesis(v) base := offset @@ -199,6 +319,12 @@ func (m *GenesisState) Size() (n int) { n += 1 + l + sovGenesis(uint64(l)) } } + if len(m.GenesisProposers) > 0 { + for _, e := range m.GenesisProposers { + l = e.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + } if len(m.BondReductions) > 0 { for _, e := range m.BondReductions { l = e.Size() @@ -208,6 +334,23 @@ func (m *GenesisState) Size() (n int) { return n } +func (m *GenesisProposer) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Address) + if l > 0 { + n += 1 + l + sovGenesis(uint64(l)) + } + l = len(m.RollappId) + if l > 0 { + n += 1 + l + sovGenesis(uint64(l)) + } + return n +} + func sovGenesis(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -311,6 +454,40 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { } iNdEx = postIndex case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field GenesisProposers", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.GenesisProposers = append(m.GenesisProposers, GenesisProposer{}) + if err := m.GenesisProposers[len(m.GenesisProposers)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field BondReductions", wireType) } @@ -365,6 +542,120 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { } return nil } +func (m *GenesisProposer) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: GenesisProposer: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GenesisProposer: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Address", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Address = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field RollappId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.RollappId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenesis(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenesis + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipGenesis(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 diff --git a/x/sequencer/types/keys.go b/x/sequencer/types/keys.go index 2331c84f3..90fb3d571 100644 --- a/x/sequencer/types/keys.go +++ b/x/sequencer/types/keys.go @@ -5,7 +5,7 @@ import ( fmt "fmt" "time" - sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/dymensionxyz/dymension/v3/utils" ) var _ binary.ByteOrder @@ -22,9 +22,6 @@ const ( // QuerierRoute defines the module's query routing key QuerierRoute = ModuleName - - // MemStoreKey defines the in-memory store key - MemStoreKey = "mem_sequencer" ) var ( @@ -36,12 +33,23 @@ var ( // SequencersByRollappKeyPrefix is the prefix to retrieve all SequencersByRollapp SequencersByRollappKeyPrefix = []byte{0x01} // prefix/rollappId + + // ProposerKeyPrefix is the prefix to retrieve the proposer for a rollapp + // This key is set when the rotation handshake is completed + ProposerKeyPrefix = []byte{0x02} // prefix/rollappId + // NextProposerKeyPrefix is the prefix to retrieve the next proposer for a rollapp + // This key is set only when rotation handshake is started + // It will be cleared after the rotation is completed + NextProposerKeyPrefix = []byte{0x03} // prefix/rollappId + + // Prefixes for the different sequencer statuses BondedSequencersKeyPrefix = []byte{0xa1} UnbondedSequencersKeyPrefix = []byte{0xa2} UnbondingSequencersKeyPrefix = []byte{0xa3} UnbondingQueueKey = []byte{0x41} // prefix for the timestamps in unbonding queue - DecreasingBondQueueKey = []byte{0x42} // prefix for the timestamps in decreasing bond queue + NoticePeriodQueueKey = []byte{0x42} // prefix for the timestamps in notice period queue + DecreasingBondQueueKey = []byte{0x43} // prefix for the timestamps in decreasing bond queue ) /* --------------------- specific sequencer address keys -------------------- */ @@ -82,19 +90,14 @@ func SequencersByRollappByStatusKey(rollappId string, status OperatingStatus) [] return []byte(fmt.Sprintf("%s%s%s", SequencersByRollappKey(rollappId), KeySeparator, prefix)) } -/* -------------------------- unbonding queue keys -------------------------- */ -func UnbondingQueueByTimeKey(endTime time.Time) []byte { - timeBz := sdk.FormatTimeBytes(endTime) - prefixL := len(UnbondingQueueKey) - - bz := make([]byte, prefixL+len(timeBz)) +/* -------------------------- queues keys -------------------------- */ - // copy the prefix - copy(bz[:prefixL], UnbondingQueueKey) - // copy the encoded time bytes - copy(bz[prefixL:prefixL+len(timeBz)], timeBz) +func UnbondingQueueByTimeKey(endTime time.Time) []byte { + return utils.EncodeTimeToKey(UnbondingQueueKey, endTime) +} - return bz +func NoticePeriodQueueByTimeKey(endTime time.Time) []byte { + return utils.EncodeTimeToKey(NoticePeriodQueueKey, endTime) } func UnbondingSequencerKey(sequencerAddress string, endTime time.Time) []byte { @@ -104,19 +107,16 @@ func UnbondingSequencerKey(sequencerAddress string, endTime time.Time) []byte { return key } +func NoticePeriodSequencerKey(sequencerAddress string, endTime time.Time) []byte { + key := NoticePeriodQueueByTimeKey(endTime) + key = append(key, KeySeparator...) + key = append(key, []byte(sequencerAddress)...) + return key +} + /* -------------------------- decreasing bond queue keys -------------------------- */ func DecreasingBondQueueByTimeKey(endTime time.Time) []byte { - timeBz := sdk.FormatTimeBytes(endTime) - prefixL := len(DecreasingBondQueueKey) - - bz := make([]byte, prefixL+len(timeBz)) - - // copy the prefix - copy(bz[:prefixL], DecreasingBondQueueKey) - // copy the encoded time bytes - copy(bz[prefixL:prefixL+len(timeBz)], timeBz) - - return bz + return utils.EncodeTimeToKey(DecreasingBondQueueKey, endTime) } func GetDecreasingBondQueueKey(sequencerAddress string, endTime time.Time) []byte { @@ -125,3 +125,12 @@ func GetDecreasingBondQueueKey(sequencerAddress string, endTime time.Time) []byt key = append(key, []byte(sequencerAddress)...) return key } + +/* --------------------- active and next sequencer keys --------------------- */ +func ProposerByRollappKey(rollappId string) []byte { + return []byte(fmt.Sprintf("%s%s%s", ProposerKeyPrefix, KeySeparator, []byte(rollappId))) +} + +func NextProposerByRollappKey(rollappId string) []byte { + return []byte(fmt.Sprintf("%s%s%s", NextProposerKeyPrefix, KeySeparator, []byte(rollappId))) +} diff --git a/x/sequencer/types/operating_status.pb.go b/x/sequencer/types/operating_status.pb.go index 32ef95b49..85d61bd01 100644 --- a/x/sequencer/types/operating_status.pb.go +++ b/x/sequencer/types/operating_status.pb.go @@ -25,11 +25,13 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package type OperatingStatus int32 const ( - // OPERATING_STATUS_UNBONDED defines a sequencer that is not active and won't be scheduled + // OPERATING_STATUS_UNBONDED defines a sequencer that is not active and won't + // be scheduled Unbonded OperatingStatus = 0 // UNBONDING defines a sequencer that is currently unbonding. Unbonding OperatingStatus = 1 - // OPERATING_STATUS_BONDED defines a sequencer that is bonded and can be scheduled + // OPERATING_STATUS_BONDED defines a sequencer that is bonded and can be + // scheduled Bonded OperatingStatus = 2 ) diff --git a/x/sequencer/types/params.go b/x/sequencer/types/params.go index d77d72419..f1dcd0117 100644 --- a/x/sequencer/types/params.go +++ b/x/sequencer/types/params.go @@ -17,13 +17,18 @@ var ( DefaultMinBond uint64 = 1000000 // DefaultUnbondingTime is the time duration for unbonding DefaultUnbondingTime time.Duration = time.Hour * 24 * 7 * 2 // 2 weeks + // DefaultNoticePeriod is the time duration for notice period + DefaultNoticePeriod time.Duration = time.Hour * 24 * 7 // 1 week // DefaultLivenessSlashMultiplier gives the amount of tokens to slash if the sequencer is liable for a liveness failure DefaultLivenessSlashMultiplier sdk.Dec = sdk.MustNewDecFromStr("0.01907") // leaves 50% of original funds remaining after 48 slashes // KeyMinBond is store's key for MinBond Params KeyMinBond = []byte("MinBond") // KeyUnbondingTime is store's key for UnbondingTime Params - KeyUnbondingTime = []byte("UnbondingTime") + KeyUnbondingTime = []byte("UnbondingTime") + // KeyNoticePeriod is store's key for NoticePeriod Params + KeyNoticePeriod = []byte("NoticePeriod") + // KeyLivenessSlashMultiplier is store's key for LivenessSlashMultiplier Params KeyLivenessSlashMultiplier = []byte("LivenessSlashMultiplier") ) @@ -33,10 +38,11 @@ func ParamKeyTable() paramtypes.KeyTable { } // NewParams creates a new Params instance -func NewParams(minBond sdk.Coin, unbondingPeriod time.Duration, livenessSlashMul sdk.Dec) Params { +func NewParams(minBond sdk.Coin, unbondingPeriod, noticePeriod time.Duration, livenessSlashMul sdk.Dec) Params { return Params{ MinBond: minBond, UnbondingTime: unbondingPeriod, + NoticePeriod: noticePeriod, LivenessSlashMultiplier: livenessSlashMul, } } @@ -49,7 +55,7 @@ func DefaultParams() Params { } minBond := sdk.NewCoin(denom, sdk.NewIntFromUint64(DefaultMinBond)) return NewParams( - minBond, DefaultUnbondingTime, DefaultLivenessSlashMultiplier, + minBond, DefaultUnbondingTime, DefaultNoticePeriod, DefaultLivenessSlashMultiplier, ) } @@ -57,12 +63,13 @@ func DefaultParams() Params { func (p *Params) ParamSetPairs() paramtypes.ParamSetPairs { return paramtypes.ParamSetPairs{ paramtypes.NewParamSetPair(KeyMinBond, &p.MinBond, validateMinBond), - paramtypes.NewParamSetPair(KeyUnbondingTime, &p.UnbondingTime, validateUnbondingTime), + paramtypes.NewParamSetPair(KeyUnbondingTime, &p.UnbondingTime, validateTime), + paramtypes.NewParamSetPair(KeyNoticePeriod, &p.NoticePeriod, validateTime), paramtypes.NewParamSetPair(KeyLivenessSlashMultiplier, &p.LivenessSlashMultiplier, validateLivenessSlashMultiplier), } } -func validateUnbondingTime(i interface{}) error { +func validateTime(i interface{}) error { v, ok := i.(time.Duration) if !ok { return fmt.Errorf("invalid parameter type: %T", i) @@ -101,7 +108,11 @@ func (p Params) Validate() error { return err } - if err := validateUnbondingTime(p.UnbondingTime); err != nil { + if err := validateTime(p.UnbondingTime); err != nil { + return err + } + + if err := validateTime(p.NoticePeriod); err != nil { return err } diff --git a/x/sequencer/types/params.pb.go b/x/sequencer/types/params.pb.go index 7bbac279d..ddafe03f5 100644 --- a/x/sequencer/types/params.pb.go +++ b/x/sequencer/types/params.pb.go @@ -34,8 +34,12 @@ type Params struct { MinBond types.Coin `protobuf:"bytes,1,opt,name=min_bond,json=minBond,proto3" json:"min_bond,omitempty"` // unbonding_time is the time duration of unbonding. UnbondingTime time.Duration `protobuf:"bytes,2,opt,name=unbonding_time,json=unbondingTime,proto3,stdduration" json:"unbonding_time"` + // notice_period is the time duration of notice period. + // notice period is the duration between the unbond request and the actual + // unbonding starting. the proposer is still bonded during this period. + NoticePeriod time.Duration `protobuf:"bytes,3,opt,name=notice_period,json=noticePeriod,proto3,stdduration" json:"notice_period"` // LivenessSlashMultiplier multiplies with the tokens of the slashed sequencer to compute the burn amount. - LivenessSlashMultiplier github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,3,opt,name=liveness_slash_multiplier,json=livenessSlashMultiplier,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"liveness_slash_multiplier" yaml:"liveness_slash_multiplier"` + LivenessSlashMultiplier github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,4,opt,name=liveness_slash_multiplier,json=livenessSlashMultiplier,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"liveness_slash_multiplier" yaml:"liveness_slash_multiplier"` } func (m *Params) Reset() { *m = Params{} } @@ -84,6 +88,13 @@ func (m *Params) GetUnbondingTime() time.Duration { return 0 } +func (m *Params) GetNoticePeriod() time.Duration { + if m != nil { + return m.NoticePeriod + } + return 0 +} + func init() { proto.RegisterType((*Params)(nil), "dymensionxyz.dymension.sequencer.Params") } @@ -93,32 +104,34 @@ func init() { } var fileDescriptor_599b0eefba99ee26 = []byte{ - // 399 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x92, 0xbd, 0x8a, 0xdb, 0x40, - 0x14, 0x85, 0x35, 0x0e, 0x38, 0x8e, 0x42, 0x52, 0x88, 0x40, 0x6c, 0x17, 0x92, 0x70, 0x11, 0x5c, - 0xc4, 0x33, 0x38, 0x86, 0x14, 0x2e, 0x15, 0x57, 0x81, 0x80, 0x51, 0x52, 0xa5, 0x11, 0xfa, 0x99, - 0xc8, 0x43, 0x34, 0x33, 0x8a, 0x66, 0x64, 0xac, 0x3c, 0xc4, 0xb2, 0xa5, 0x4b, 0xbf, 0xca, 0x76, - 0x2e, 0x5d, 0x2e, 0x5b, 0x68, 0x17, 0xbb, 0x59, 0xb6, 0xdc, 0x27, 0x58, 0xf4, 0x8b, 0x1b, 0x57, - 0xd2, 0x9d, 0x73, 0xce, 0xc7, 0xe1, 0x72, 0xd5, 0x49, 0x90, 0x51, 0xcc, 0x04, 0xe1, 0x6c, 0x93, - 0xfd, 0x47, 0xed, 0x80, 0x04, 0xfe, 0x97, 0x62, 0xe6, 0xe3, 0x04, 0xc5, 0x6e, 0xe2, 0x52, 0x01, - 0xe3, 0x84, 0x4b, 0xae, 0x99, 0xe7, 0x76, 0xd8, 0x0e, 0xb0, 0xb5, 0x0f, 0x3f, 0x84, 0x3c, 0xe4, - 0xa5, 0x19, 0x15, 0x7f, 0x55, 0x6e, 0xa8, 0xfb, 0x5c, 0x50, 0x2e, 0x90, 0xe7, 0x0a, 0x8c, 0xd6, - 0x53, 0x0f, 0x4b, 0x77, 0x8a, 0x7c, 0x4e, 0x58, 0xa3, 0x87, 0x9c, 0x87, 0x11, 0x46, 0xe5, 0xe4, - 0xa5, 0x7f, 0x50, 0x90, 0x26, 0xae, 0x2c, 0xc8, 0xe5, 0xcb, 0xe8, 0xa6, 0xa3, 0x76, 0x97, 0x65, - 0x11, 0x6d, 0xa9, 0xf6, 0x28, 0x61, 0x8e, 0xc7, 0x59, 0xd0, 0x07, 0x26, 0x18, 0xbf, 0xfd, 0x32, - 0x80, 0x15, 0x1d, 0x16, 0x74, 0x58, 0xd3, 0xe1, 0x37, 0x4e, 0x98, 0x35, 0xdc, 0xe7, 0x86, 0xf2, - 0x94, 0x1b, 0x5a, 0x13, 0xf9, 0xcc, 0x29, 0x91, 0x98, 0xc6, 0x32, 0xb3, 0x5f, 0x53, 0xc2, 0x2c, - 0xce, 0x02, 0xed, 0xbb, 0xfa, 0x3e, 0x65, 0x85, 0x48, 0x58, 0xe8, 0x48, 0x42, 0x71, 0xbf, 0x53, - 0x73, 0xab, 0x56, 0xb0, 0x69, 0x05, 0x17, 0x75, 0x2b, 0xab, 0x57, 0x70, 0xb7, 0xf7, 0x06, 0xb0, - 0xdf, 0xb5, 0xd1, 0x5f, 0x84, 0x62, 0xed, 0x0a, 0xa8, 0x83, 0x88, 0xac, 0x31, 0xc3, 0x42, 0x38, - 0x22, 0x72, 0xc5, 0xca, 0xa1, 0x69, 0x24, 0x49, 0x1c, 0x11, 0x9c, 0xf4, 0x5f, 0x99, 0x60, 0xfc, - 0xc6, 0xb2, 0x8b, 0xf0, 0x5d, 0x6e, 0x7c, 0x0a, 0x89, 0x5c, 0xa5, 0x1e, 0xf4, 0x39, 0x45, 0xf5, - 0x7e, 0xaa, 0xcf, 0x44, 0x04, 0x7f, 0x91, 0xcc, 0x62, 0x2c, 0xe0, 0x02, 0xfb, 0xcf, 0xb9, 0x61, - 0x66, 0x2e, 0x8d, 0xe6, 0xa3, 0x8b, 0xe0, 0x91, 0xfd, 0xb1, 0xd1, 0x7e, 0x16, 0xd2, 0x8f, 0x56, - 0x99, 0xf7, 0xb6, 0x3b, 0x43, 0x79, 0xdc, 0x19, 0xc0, 0x5a, 0xee, 0x8f, 0x3a, 0x38, 0x1c, 0x75, - 0xf0, 0x70, 0xd4, 0xc1, 0xf5, 0x49, 0x57, 0x0e, 0x27, 0x5d, 0xb9, 0x3d, 0xe9, 0xca, 0xef, 0xaf, - 0x67, 0x45, 0x2e, 0xdc, 0xc3, 0x7a, 0x86, 0x36, 0x67, 0x47, 0x51, 0x96, 0xf3, 0xba, 0xe5, 0x62, - 0x66, 0x2f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x42, 0x9a, 0x2f, 0x98, 0x45, 0x02, 0x00, 0x00, + // 422 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x92, 0x3f, 0x8b, 0xd4, 0x40, + 0x18, 0xc6, 0x33, 0x9e, 0x9c, 0x6b, 0xf4, 0x2c, 0x82, 0xe0, 0xde, 0x16, 0x49, 0xd8, 0x42, 0xae, + 0xf0, 0x66, 0x38, 0x0f, 0x2c, 0xae, 0x8c, 0x57, 0x88, 0x20, 0x84, 0x68, 0x65, 0x13, 0xf2, 0xe7, + 0x35, 0x37, 0x98, 0x99, 0x37, 0x66, 0x26, 0xcb, 0xc5, 0xaf, 0x20, 0x88, 0xe5, 0x95, 0xf7, 0x71, + 0xae, 0xbc, 0x52, 0x2c, 0xa2, 0xec, 0x36, 0x62, 0xe9, 0x27, 0x90, 0xfc, 0x65, 0x9b, 0x05, 0xab, + 0xe4, 0x9d, 0xe7, 0x79, 0x7e, 0x3c, 0xbc, 0xbc, 0xe6, 0x71, 0x5a, 0x0b, 0x90, 0x8a, 0xa3, 0xbc, + 0xac, 0x3f, 0xb3, 0x69, 0x60, 0x0a, 0x3e, 0x55, 0x20, 0x13, 0x28, 0x59, 0x11, 0x95, 0x91, 0x50, + 0xb4, 0x28, 0x51, 0xa3, 0xe5, 0x6e, 0xdb, 0xe9, 0x34, 0xd0, 0xc9, 0xbe, 0x78, 0x9c, 0x61, 0x86, + 0x9d, 0x99, 0xb5, 0x7f, 0x7d, 0x6e, 0x61, 0x27, 0xa8, 0x04, 0x2a, 0x16, 0x47, 0x0a, 0xd8, 0xea, + 0x24, 0x06, 0x1d, 0x9d, 0xb0, 0x04, 0xb9, 0x1c, 0xf5, 0x0c, 0x31, 0xcb, 0x81, 0x75, 0x53, 0x5c, + 0x7d, 0x60, 0x69, 0x55, 0x46, 0xba, 0x25, 0x77, 0x2f, 0xcb, 0x2f, 0x7b, 0xe6, 0xbe, 0xdf, 0x15, + 0xb1, 0x7c, 0x73, 0x26, 0xb8, 0x0c, 0x63, 0x94, 0xe9, 0x9c, 0xb8, 0xe4, 0xe8, 0xc1, 0xf3, 0x43, + 0xda, 0xd3, 0x69, 0x4b, 0xa7, 0x03, 0x9d, 0xbe, 0x44, 0x2e, 0xbd, 0xc5, 0x4d, 0xe3, 0x18, 0x7f, + 0x1a, 0xc7, 0x1a, 0x23, 0xcf, 0x50, 0x70, 0x0d, 0xa2, 0xd0, 0x75, 0x70, 0x4f, 0x70, 0xe9, 0xa1, + 0x4c, 0xad, 0xd7, 0xe6, 0xa3, 0x4a, 0xb6, 0x22, 0x97, 0x59, 0xa8, 0xb9, 0x80, 0xf9, 0x9d, 0x81, + 0xdb, 0xb7, 0xa2, 0x63, 0x2b, 0x7a, 0x3e, 0xb4, 0xf2, 0x66, 0x2d, 0xf7, 0xea, 0xa7, 0x43, 0x82, + 0x83, 0x29, 0xfa, 0x8e, 0x0b, 0xb0, 0x5e, 0x99, 0x07, 0x12, 0x35, 0x4f, 0x20, 0x2c, 0xa0, 0xe4, + 0x98, 0xce, 0xf7, 0xfe, 0x1f, 0xf5, 0xb0, 0x4f, 0xfa, 0x5d, 0xd0, 0xfa, 0x4a, 0xcc, 0xc3, 0x9c, + 0xaf, 0x40, 0x82, 0x52, 0xa1, 0xca, 0x23, 0x75, 0x11, 0x8a, 0x2a, 0xd7, 0xbc, 0xc8, 0x39, 0x94, + 0xf3, 0xbb, 0x2e, 0x39, 0xba, 0xef, 0x05, 0x6d, 0xf6, 0x47, 0xe3, 0x3c, 0xcd, 0xb8, 0xbe, 0xa8, + 0x62, 0x9a, 0xa0, 0x60, 0xc3, 0xa6, 0xfb, 0xcf, 0xb1, 0x4a, 0x3f, 0x32, 0x5d, 0x17, 0xa0, 0xe8, + 0x39, 0x24, 0x7f, 0x1b, 0xc7, 0xad, 0x23, 0x91, 0x9f, 0x2d, 0x77, 0x82, 0x97, 0xc1, 0x93, 0x51, + 0x7b, 0xdb, 0x4a, 0x6f, 0x26, 0xe5, 0x6c, 0x76, 0x75, 0xed, 0x18, 0xbf, 0xaf, 0x1d, 0xe2, 0xf9, + 0x37, 0x6b, 0x9b, 0xdc, 0xae, 0x6d, 0xf2, 0x6b, 0x6d, 0x93, 0x6f, 0x1b, 0xdb, 0xb8, 0xdd, 0xd8, + 0xc6, 0xf7, 0x8d, 0x6d, 0xbc, 0x7f, 0xb1, 0x55, 0x64, 0xc7, 0x65, 0xad, 0x4e, 0xd9, 0xe5, 0xd6, + 0x79, 0x75, 0xe5, 0xe2, 0xfd, 0x6e, 0x2f, 0xa7, 0xff, 0x02, 0x00, 0x00, 0xff, 0xff, 0xa5, 0x40, + 0xbb, 0x89, 0x8f, 0x02, 0x00, 0x00, } func (this *Params) Equal(that interface{}) bool { @@ -146,6 +159,9 @@ func (this *Params) Equal(that interface{}) bool { if this.UnbondingTime != that1.UnbondingTime { return false } + if this.NoticePeriod != that1.NoticePeriod { + return false + } if !this.LivenessSlashMultiplier.Equal(that1.LivenessSlashMultiplier) { return false } @@ -180,14 +196,22 @@ func (m *Params) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintParams(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x1a - n1, err1 := github_com_cosmos_gogoproto_types.StdDurationMarshalTo(m.UnbondingTime, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdDuration(m.UnbondingTime):]) + dAtA[i] = 0x22 + n1, err1 := github_com_cosmos_gogoproto_types.StdDurationMarshalTo(m.NoticePeriod, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdDuration(m.NoticePeriod):]) if err1 != nil { return 0, err1 } i -= n1 i = encodeVarintParams(dAtA, i, uint64(n1)) i-- + dAtA[i] = 0x1a + n2, err2 := github_com_cosmos_gogoproto_types.StdDurationMarshalTo(m.UnbondingTime, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdDuration(m.UnbondingTime):]) + if err2 != nil { + return 0, err2 + } + i -= n2 + i = encodeVarintParams(dAtA, i, uint64(n2)) + i-- dAtA[i] = 0x12 { size, err := m.MinBond.MarshalToSizedBuffer(dAtA[:i]) @@ -223,6 +247,8 @@ func (m *Params) Size() (n int) { n += 1 + l + sovParams(uint64(l)) l = github_com_cosmos_gogoproto_types.SizeOfStdDuration(m.UnbondingTime) n += 1 + l + sovParams(uint64(l)) + l = github_com_cosmos_gogoproto_types.SizeOfStdDuration(m.NoticePeriod) + n += 1 + l + sovParams(uint64(l)) l = m.LivenessSlashMultiplier.Size() n += 1 + l + sovParams(uint64(l)) return n @@ -330,6 +356,39 @@ func (m *Params) Unmarshal(dAtA []byte) error { } iNdEx = postIndex case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field NoticePeriod", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowParams + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthParams + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthParams + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := github_com_cosmos_gogoproto_types.StdDurationUnmarshal(&m.NoticePeriod, dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field LivenessSlashMultiplier", wireType) } diff --git a/x/sequencer/types/query.pb.go b/x/sequencer/types/query.pb.go index 42c21522b..f40a83e85 100644 --- a/x/sequencer/types/query.pb.go +++ b/x/sequencer/types/query.pb.go @@ -489,6 +489,194 @@ func (m *QueryGetSequencersByRollappByStatusResponse) GetSequencers() []Sequence return nil } +// Request type for the GetProposerByRollapp RPC method. +type QueryGetProposerByRollappRequest struct { + RollappId string `protobuf:"bytes,1,opt,name=rollappId,proto3" json:"rollappId,omitempty"` +} + +func (m *QueryGetProposerByRollappRequest) Reset() { *m = QueryGetProposerByRollappRequest{} } +func (m *QueryGetProposerByRollappRequest) String() string { return proto.CompactTextString(m) } +func (*QueryGetProposerByRollappRequest) ProtoMessage() {} +func (*QueryGetProposerByRollappRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_c6af1252721903a2, []int{10} +} +func (m *QueryGetProposerByRollappRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryGetProposerByRollappRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryGetProposerByRollappRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryGetProposerByRollappRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryGetProposerByRollappRequest.Merge(m, src) +} +func (m *QueryGetProposerByRollappRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryGetProposerByRollappRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryGetProposerByRollappRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryGetProposerByRollappRequest proto.InternalMessageInfo + +func (m *QueryGetProposerByRollappRequest) GetRollappId() string { + if m != nil { + return m.RollappId + } + return "" +} + +// Response type for the GetProposerByRollapp RPC method. +type QueryGetProposerByRollappResponse struct { + ProposerAddr string `protobuf:"bytes,1,opt,name=proposerAddr,proto3" json:"proposerAddr,omitempty"` +} + +func (m *QueryGetProposerByRollappResponse) Reset() { *m = QueryGetProposerByRollappResponse{} } +func (m *QueryGetProposerByRollappResponse) String() string { return proto.CompactTextString(m) } +func (*QueryGetProposerByRollappResponse) ProtoMessage() {} +func (*QueryGetProposerByRollappResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_c6af1252721903a2, []int{11} +} +func (m *QueryGetProposerByRollappResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryGetProposerByRollappResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryGetProposerByRollappResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryGetProposerByRollappResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryGetProposerByRollappResponse.Merge(m, src) +} +func (m *QueryGetProposerByRollappResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryGetProposerByRollappResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryGetProposerByRollappResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryGetProposerByRollappResponse proto.InternalMessageInfo + +func (m *QueryGetProposerByRollappResponse) GetProposerAddr() string { + if m != nil { + return m.ProposerAddr + } + return "" +} + +// Request type for the GetNextProposerByRollapp RPC method. +type QueryGetNextProposerByRollappRequest struct { + RollappId string `protobuf:"bytes,1,opt,name=rollappId,proto3" json:"rollappId,omitempty"` +} + +func (m *QueryGetNextProposerByRollappRequest) Reset() { *m = QueryGetNextProposerByRollappRequest{} } +func (m *QueryGetNextProposerByRollappRequest) String() string { return proto.CompactTextString(m) } +func (*QueryGetNextProposerByRollappRequest) ProtoMessage() {} +func (*QueryGetNextProposerByRollappRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_c6af1252721903a2, []int{12} +} +func (m *QueryGetNextProposerByRollappRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryGetNextProposerByRollappRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryGetNextProposerByRollappRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryGetNextProposerByRollappRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryGetNextProposerByRollappRequest.Merge(m, src) +} +func (m *QueryGetNextProposerByRollappRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryGetNextProposerByRollappRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryGetNextProposerByRollappRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryGetNextProposerByRollappRequest proto.InternalMessageInfo + +func (m *QueryGetNextProposerByRollappRequest) GetRollappId() string { + if m != nil { + return m.RollappId + } + return "" +} + +// Response type for the GetNextProposerByRollapp RPC method. +type QueryGetNextProposerByRollappResponse struct { + NextProposerAddr string `protobuf:"bytes,1,opt,name=nextProposerAddr,proto3" json:"nextProposerAddr,omitempty"` + RotationInProgress bool `protobuf:"varint,2,opt,name=rotationInProgress,proto3" json:"rotationInProgress,omitempty"` +} + +func (m *QueryGetNextProposerByRollappResponse) Reset() { *m = QueryGetNextProposerByRollappResponse{} } +func (m *QueryGetNextProposerByRollappResponse) String() string { return proto.CompactTextString(m) } +func (*QueryGetNextProposerByRollappResponse) ProtoMessage() {} +func (*QueryGetNextProposerByRollappResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_c6af1252721903a2, []int{13} +} +func (m *QueryGetNextProposerByRollappResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryGetNextProposerByRollappResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryGetNextProposerByRollappResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryGetNextProposerByRollappResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryGetNextProposerByRollappResponse.Merge(m, src) +} +func (m *QueryGetNextProposerByRollappResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryGetNextProposerByRollappResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryGetNextProposerByRollappResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryGetNextProposerByRollappResponse proto.InternalMessageInfo + +func (m *QueryGetNextProposerByRollappResponse) GetNextProposerAddr() string { + if m != nil { + return m.NextProposerAddr + } + return "" +} + +func (m *QueryGetNextProposerByRollappResponse) GetRotationInProgress() bool { + if m != nil { + return m.RotationInProgress + } + return false +} + func init() { proto.RegisterType((*QueryParamsRequest)(nil), "dymensionxyz.dymension.sequencer.QueryParamsRequest") proto.RegisterType((*QueryParamsResponse)(nil), "dymensionxyz.dymension.sequencer.QueryParamsResponse") @@ -500,6 +688,10 @@ func init() { proto.RegisterType((*QueryGetSequencersByRollappResponse)(nil), "dymensionxyz.dymension.sequencer.QueryGetSequencersByRollappResponse") proto.RegisterType((*QueryGetSequencersByRollappByStatusRequest)(nil), "dymensionxyz.dymension.sequencer.QueryGetSequencersByRollappByStatusRequest") proto.RegisterType((*QueryGetSequencersByRollappByStatusResponse)(nil), "dymensionxyz.dymension.sequencer.QueryGetSequencersByRollappByStatusResponse") + proto.RegisterType((*QueryGetProposerByRollappRequest)(nil), "dymensionxyz.dymension.sequencer.QueryGetProposerByRollappRequest") + proto.RegisterType((*QueryGetProposerByRollappResponse)(nil), "dymensionxyz.dymension.sequencer.QueryGetProposerByRollappResponse") + proto.RegisterType((*QueryGetNextProposerByRollappRequest)(nil), "dymensionxyz.dymension.sequencer.QueryGetNextProposerByRollappRequest") + proto.RegisterType((*QueryGetNextProposerByRollappResponse)(nil), "dymensionxyz.dymension.sequencer.QueryGetNextProposerByRollappResponse") } func init() { @@ -507,51 +699,60 @@ func init() { } var fileDescriptor_c6af1252721903a2 = []byte{ - // 695 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x56, 0x4d, 0x4f, 0x13, 0x4f, - 0x18, 0xef, 0xf0, 0xff, 0xdb, 0xd8, 0xc7, 0xc4, 0x98, 0x81, 0x28, 0xae, 0xa4, 0x92, 0x35, 0x51, - 0x52, 0x64, 0x87, 0x17, 0xdf, 0x4d, 0x8c, 0x56, 0x29, 0x21, 0xa2, 0x40, 0xf1, 0x64, 0x62, 0x70, - 0x4a, 0x27, 0xeb, 0x26, 0xed, 0xce, 0xb2, 0xb3, 0x25, 0xac, 0x84, 0xc4, 0xf8, 0x09, 0x48, 0x8c, - 0x9f, 0xc1, 0x4f, 0xa0, 0x47, 0xcf, 0x1c, 0x3c, 0x90, 0x78, 0xf1, 0x64, 0x0c, 0x78, 0xf7, 0x2b, - 0x98, 0xce, 0x4c, 0xb7, 0x85, 0x45, 0x76, 0x29, 0x70, 0xeb, 0x0e, 0xcf, 0xf3, 0x7b, 0x9b, 0x79, - 0x9e, 0x00, 0xd7, 0xab, 0x61, 0x9d, 0xb9, 0xc2, 0xe1, 0xee, 0x6a, 0xf8, 0x96, 0x44, 0x1f, 0x44, - 0xb0, 0xe5, 0x06, 0x73, 0x97, 0x98, 0x4f, 0x96, 0x1b, 0xcc, 0x0f, 0x2d, 0xcf, 0xe7, 0x01, 0xc7, - 0x83, 0x9d, 0xd5, 0x56, 0xf4, 0x61, 0x45, 0xd5, 0x46, 0x9f, 0xcd, 0x6d, 0x2e, 0x8b, 0x49, 0xf3, - 0x97, 0xea, 0x33, 0x06, 0x6c, 0xce, 0xed, 0x1a, 0x23, 0xd4, 0x73, 0x08, 0x75, 0x5d, 0x1e, 0xd0, - 0xc0, 0xe1, 0xae, 0xd0, 0x7f, 0x2d, 0x2c, 0x71, 0x51, 0xe7, 0x82, 0x54, 0xa8, 0x60, 0x8a, 0x8e, - 0xac, 0x8c, 0x55, 0x58, 0x40, 0xc7, 0x88, 0x47, 0x6d, 0xc7, 0x95, 0xc5, 0xba, 0x76, 0x24, 0x51, - 0xaf, 0x47, 0x7d, 0x5a, 0x6f, 0x41, 0x8f, 0x26, 0x96, 0x47, 0xbf, 0x74, 0xc7, 0xed, 0xc4, 0x0e, - 0xee, 0x31, 0x9f, 0x06, 0x8e, 0x6b, 0x2f, 0x8a, 0x80, 0x06, 0x0d, 0x4d, 0x65, 0xf6, 0x01, 0x9e, - 0x6f, 0x6a, 0x9f, 0x93, 0xfc, 0xe5, 0x66, 0xb9, 0x08, 0xcc, 0x57, 0xd0, 0xbb, 0xeb, 0x54, 0x78, - 0xdc, 0x15, 0x0c, 0x97, 0x20, 0xab, 0x74, 0xf6, 0xa3, 0x41, 0x34, 0x74, 0x66, 0x7c, 0xc8, 0x4a, - 0x4a, 0xd6, 0x52, 0x08, 0xc5, 0xff, 0x37, 0x7f, 0x5e, 0xce, 0x94, 0x75, 0xb7, 0x59, 0x82, 0x7e, - 0x09, 0x3f, 0xc5, 0x82, 0x85, 0x56, 0xa5, 0xa6, 0xc6, 0x05, 0x38, 0x17, 0x75, 0x3f, 0xaa, 0x56, - 0x7d, 0x26, 0x14, 0x5b, 0xae, 0x1c, 0x3b, 0x37, 0x6b, 0x70, 0x71, 0x1f, 0x1c, 0x2d, 0x76, 0x16, - 0x72, 0x51, 0x83, 0xd6, 0x3b, 0x9c, 0xac, 0x37, 0xc2, 0xd1, 0x92, 0xdb, 0x18, 0xe6, 0x6b, 0x38, - 0x2f, 0xd9, 0xa2, 0x92, 0x56, 0x5c, 0xb8, 0x04, 0xd0, 0xbe, 0x72, 0xcd, 0x75, 0xd5, 0x52, 0xef, - 0xc3, 0x6a, 0xbe, 0x0f, 0x4b, 0x3d, 0x47, 0xfd, 0x3e, 0xac, 0x39, 0x6a, 0x33, 0xdd, 0x5b, 0xee, - 0xe8, 0x34, 0x3f, 0x23, 0xb8, 0x10, 0xa3, 0xd0, 0x76, 0xe6, 0x01, 0x22, 0x29, 0xcd, 0x44, 0xfe, - 0xeb, 0xce, 0x4f, 0x07, 0x08, 0x9e, 0xda, 0x25, 0xbb, 0x47, 0xca, 0xbe, 0x96, 0x28, 0x5b, 0xe9, - 0xd9, 0xa5, 0xbb, 0x08, 0x66, 0xec, 0x1e, 0x44, 0x31, 0x2c, 0xf3, 0x5a, 0x8d, 0x7a, 0x5e, 0x2b, - 0xa5, 0x01, 0xc8, 0xf9, 0xea, 0x64, 0xba, 0xaa, 0xaf, 0xb4, 0x7d, 0x60, 0xae, 0xc2, 0x95, 0x03, - 0x31, 0x4e, 0x2c, 0x06, 0xf3, 0x23, 0x82, 0xc2, 0x01, 0xd4, 0xc5, 0x70, 0x41, 0x0e, 0x4c, 0x2a, - 0x1b, 0x78, 0x1a, 0xb2, 0x6a, 0xbe, 0x64, 0x9e, 0x67, 0xc7, 0xc7, 0x92, 0xb5, 0xcd, 0xb6, 0x26, - 0x53, 0xf3, 0x68, 0x00, 0xf3, 0x1d, 0x82, 0xe1, 0x54, 0xba, 0x4e, 0x2c, 0x9a, 0xf1, 0xaf, 0xa7, - 0xe1, 0x94, 0x94, 0x80, 0x3f, 0x21, 0xc8, 0xaa, 0x59, 0xc6, 0x37, 0x92, 0x31, 0xe3, 0x2b, 0xc5, - 0xb8, 0x79, 0xc8, 0x2e, 0x65, 0xca, 0x1c, 0x7d, 0xff, 0xfd, 0xf7, 0x87, 0x9e, 0x02, 0x1e, 0x22, - 0x29, 0x57, 0x28, 0xfe, 0x86, 0x20, 0x17, 0x79, 0xc2, 0xf7, 0x52, 0xd2, 0xee, 0xb3, 0x8a, 0x8c, - 0xfb, 0x5d, 0xf5, 0x6a, 0xe1, 0x25, 0x29, 0xfc, 0x21, 0x7e, 0x40, 0xd2, 0x2f, 0x73, 0xb2, 0xb6, - 0x77, 0xc5, 0xad, 0xe3, 0x2f, 0x08, 0xa0, 0x7d, 0xfb, 0xf8, 0x4e, 0x4a, 0x4d, 0xb1, 0x25, 0x65, - 0xdc, 0xed, 0xa2, 0x53, 0x7b, 0x99, 0x90, 0x5e, 0x46, 0xf0, 0xf0, 0x21, 0xbc, 0xe0, 0x3f, 0x08, - 0x7a, 0xf7, 0x79, 0xb6, 0xf8, 0x49, 0x17, 0xa9, 0xc6, 0x96, 0x89, 0x31, 0x79, 0x44, 0x14, 0xed, - 0xec, 0xa9, 0x74, 0x36, 0x89, 0x1f, 0x1f, 0xc2, 0x99, 0x58, 0xac, 0x84, 0x8b, 0x7a, 0xe2, 0xc9, - 0x5a, 0x34, 0xfa, 0xeb, 0x78, 0xa3, 0x07, 0x2e, 0x1d, 0x30, 0xa8, 0x78, 0xe6, 0x48, 0x9a, 0xf7, - 0xec, 0x21, 0xe3, 0xd9, 0x31, 0xa1, 0xe9, 0x24, 0x5e, 0xc8, 0x24, 0x9e, 0xe3, 0x99, 0x63, 0x48, - 0x82, 0xac, 0xa9, 0x15, 0xb6, 0x5e, 0x9c, 0xdb, 0xdc, 0xce, 0xa3, 0xad, 0xed, 0x3c, 0xfa, 0xb5, - 0x9d, 0x47, 0x1b, 0x3b, 0xf9, 0xcc, 0xd6, 0x4e, 0x3e, 0xf3, 0x63, 0x27, 0x9f, 0x79, 0x79, 0xcb, - 0x76, 0x82, 0x37, 0x8d, 0x8a, 0xb5, 0xc4, 0xeb, 0xff, 0x62, 0x5c, 0x99, 0x20, 0xab, 0x1d, 0xb4, - 0x41, 0xe8, 0x31, 0x51, 0xc9, 0xca, 0xff, 0x5b, 0x26, 0xfe, 0x06, 0x00, 0x00, 0xff, 0xff, 0x31, - 0x06, 0xc4, 0x66, 0x03, 0x0a, 0x00, 0x00, + // 846 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x56, 0xdd, 0x4e, 0xdb, 0x48, + 0x14, 0x8e, 0xd9, 0xdd, 0x68, 0x73, 0x16, 0xad, 0xd0, 0x80, 0x76, 0x59, 0x2f, 0xca, 0xb2, 0xee, + 0x1f, 0x0a, 0xc5, 0xc3, 0x4f, 0x4b, 0x69, 0x51, 0x11, 0x0d, 0x90, 0x08, 0x95, 0x42, 0x08, 0xbd, + 0xaa, 0x54, 0xa5, 0x0e, 0x19, 0xb9, 0x91, 0x12, 0x8f, 0xf1, 0x38, 0x28, 0x29, 0x42, 0xaa, 0xda, + 0x17, 0x40, 0x42, 0x7d, 0x86, 0x3e, 0x41, 0xfb, 0x0c, 0x5c, 0xf4, 0x02, 0xa9, 0x37, 0xbd, 0x6a, + 0x2b, 0xe8, 0x7d, 0xfb, 0x08, 0x95, 0xc7, 0x13, 0x27, 0x21, 0x21, 0x76, 0x12, 0xb8, 0x8b, 0x67, + 0xce, 0xf9, 0xce, 0xf7, 0x9d, 0x99, 0xf9, 0x4e, 0xe0, 0x66, 0xae, 0x52, 0x24, 0x06, 0xcb, 0x53, + 0xa3, 0x5c, 0x79, 0x81, 0xbd, 0x0f, 0xcc, 0xc8, 0x4e, 0x89, 0x18, 0xdb, 0xc4, 0xc2, 0x3b, 0x25, + 0x62, 0x55, 0x54, 0xd3, 0xa2, 0x36, 0x45, 0xa3, 0xf5, 0xd1, 0xaa, 0xf7, 0xa1, 0x7a, 0xd1, 0xf2, + 0x90, 0x4e, 0x75, 0xca, 0x83, 0xb1, 0xf3, 0xcb, 0xcd, 0x93, 0x47, 0x74, 0x4a, 0xf5, 0x02, 0xc1, + 0x9a, 0x99, 0xc7, 0x9a, 0x61, 0x50, 0x5b, 0xb3, 0xf3, 0xd4, 0x60, 0x62, 0x37, 0xb6, 0x4d, 0x59, + 0x91, 0x32, 0x9c, 0xd5, 0x18, 0x71, 0xcb, 0xe1, 0xdd, 0xa9, 0x2c, 0xb1, 0xb5, 0x29, 0x6c, 0x6a, + 0x7a, 0xde, 0xe0, 0xc1, 0x22, 0x76, 0xc2, 0x97, 0xaf, 0xa9, 0x59, 0x5a, 0xb1, 0x0a, 0x3d, 0xe9, + 0x1b, 0xee, 0xfd, 0x12, 0x19, 0x77, 0x7c, 0x33, 0xa8, 0x49, 0x2c, 0xcd, 0xce, 0x1b, 0x7a, 0x86, + 0xd9, 0x9a, 0x5d, 0x12, 0xa5, 0x94, 0x21, 0x40, 0x9b, 0x0e, 0xf7, 0x14, 0xaf, 0x9f, 0x76, 0xc2, + 0x99, 0xad, 0x3c, 0x85, 0xc1, 0x86, 0x55, 0x66, 0x52, 0x83, 0x11, 0x94, 0x80, 0xb0, 0xcb, 0x73, + 0x58, 0x1a, 0x95, 0xc6, 0xfe, 0x98, 0x1e, 0x53, 0xfd, 0x3a, 0xab, 0xba, 0x08, 0xf1, 0x5f, 0x8f, + 0x3e, 0xff, 0x17, 0x4a, 0x8b, 0x6c, 0x25, 0x01, 0xc3, 0x1c, 0x3e, 0x49, 0xec, 0xad, 0x6a, 0xa4, + 0x28, 0x8d, 0x62, 0x30, 0xe0, 0x65, 0x3f, 0xc8, 0xe5, 0x2c, 0xc2, 0xdc, 0x6a, 0x91, 0x74, 0xd3, + 0xba, 0x52, 0x80, 0x7f, 0x5a, 0xe0, 0x08, 0xb2, 0x1b, 0x10, 0xf1, 0x12, 0x04, 0xdf, 0x71, 0x7f, + 0xbe, 0x1e, 0x8e, 0xa0, 0x5c, 0xc3, 0x50, 0x9e, 0xc1, 0x5f, 0xbc, 0x9a, 0x17, 0x52, 0x6d, 0x17, + 0x4a, 0x00, 0xd4, 0x8e, 0x5c, 0xd4, 0xba, 0xae, 0xba, 0xf7, 0x43, 0x75, 0xee, 0x87, 0xea, 0x5e, + 0x47, 0x71, 0x3f, 0xd4, 0x94, 0xa6, 0x13, 0x91, 0x9b, 0xae, 0xcb, 0x54, 0xde, 0x49, 0xf0, 0x77, + 0x53, 0x09, 0x21, 0x67, 0x13, 0xc0, 0xa3, 0xe2, 0x74, 0xe4, 0x97, 0xee, 0xf4, 0xd4, 0x81, 0xa0, + 0x64, 0x03, 0xed, 0x3e, 0x4e, 0xfb, 0x86, 0x2f, 0x6d, 0x97, 0x4f, 0x03, 0xef, 0x38, 0x28, 0x4d, + 0xe7, 0xc0, 0xe2, 0x95, 0x34, 0x2d, 0x14, 0x34, 0xd3, 0xac, 0x76, 0x69, 0x04, 0x22, 0x96, 0xbb, + 0xb2, 0x9a, 0x13, 0x47, 0x5a, 0x5b, 0x50, 0xca, 0x70, 0xa5, 0x2d, 0xc6, 0xa5, 0xb5, 0x41, 0x79, + 0x23, 0x41, 0xac, 0x4d, 0xe9, 0x78, 0x65, 0x8b, 0x3f, 0x98, 0x40, 0x32, 0xd0, 0x2a, 0x84, 0xdd, + 0xf7, 0xc5, 0xfb, 0xf9, 0xe7, 0xf4, 0x94, 0x3f, 0xb7, 0x8d, 0xea, 0xcb, 0x14, 0x75, 0x04, 0x80, + 0xf2, 0x52, 0x82, 0xf1, 0x40, 0xbc, 0x2e, 0xaf, 0x35, 0x8b, 0x30, 0x5a, 0x65, 0x90, 0xb2, 0xa8, + 0x49, 0x19, 0xb1, 0x3a, 0x3c, 0xd6, 0x24, 0xfc, 0xdf, 0x06, 0x41, 0x30, 0x57, 0xa0, 0xdf, 0x14, + 0x9b, 0xce, 0xd3, 0x16, 0x28, 0x0d, 0x6b, 0xca, 0x32, 0x5c, 0xad, 0x02, 0xad, 0x93, 0x72, 0xb7, + 0x74, 0x5e, 0x4b, 0x70, 0xcd, 0x07, 0x46, 0x70, 0x8a, 0xc1, 0x80, 0x51, 0x17, 0x50, 0xc7, 0xab, + 0x69, 0x1d, 0xa9, 0x80, 0x2c, 0x31, 0x1d, 0x56, 0x8d, 0x94, 0x45, 0x75, 0xee, 0x5a, 0xce, 0x05, + 0xf8, 0x3d, 0xdd, 0x62, 0x67, 0xfa, 0xb0, 0x1f, 0x7e, 0xe3, 0x2c, 0xd0, 0x5b, 0x09, 0xc2, 0xae, + 0x45, 0xa2, 0x5b, 0xfe, 0x47, 0xd5, 0xec, 0xd4, 0xf2, 0xed, 0x0e, 0xb3, 0x5c, 0x75, 0xca, 0xe4, + 0xab, 0x8f, 0xdf, 0x0e, 0xfb, 0x62, 0x68, 0x0c, 0x07, 0x9c, 0x4c, 0xe8, 0x83, 0x04, 0x11, 0xef, + 0xaa, 0xa0, 0x7b, 0x01, 0xcb, 0xb6, 0x70, 0x78, 0x79, 0xbe, 0xab, 0x5c, 0x41, 0x3c, 0xc1, 0x89, + 0x2f, 0xa2, 0x05, 0x1c, 0x7c, 0x46, 0xe2, 0xbd, 0xb3, 0x93, 0x63, 0x1f, 0xbd, 0x97, 0x00, 0x6a, + 0x8f, 0x0a, 0xcd, 0x05, 0xe4, 0xd4, 0xe4, 0xfd, 0xf2, 0xdd, 0x2e, 0x32, 0x85, 0x96, 0x19, 0xae, + 0x65, 0x02, 0x8d, 0x77, 0xa0, 0x05, 0x7d, 0x97, 0x60, 0xb0, 0x85, 0x1b, 0xa0, 0xe5, 0x2e, 0xba, + 0xda, 0xe4, 0xd1, 0xf2, 0x4a, 0x8f, 0x28, 0x42, 0xd9, 0x43, 0xae, 0x6c, 0x05, 0x2d, 0x75, 0xa0, + 0x8c, 0x65, 0xb2, 0x95, 0x8c, 0x78, 0xa9, 0x78, 0xcf, 0x7b, 0xb2, 0xfb, 0xe8, 0xa0, 0x0f, 0xfe, + 0x6d, 0xe3, 0x7f, 0x68, 0xad, 0x27, 0xce, 0x67, 0xec, 0x5d, 0x7e, 0x74, 0x41, 0x68, 0xa2, 0x13, + 0x8f, 0x79, 0x27, 0xd6, 0xd1, 0xda, 0x05, 0x74, 0x02, 0xef, 0xb9, 0x93, 0x61, 0x1f, 0x7d, 0x91, + 0x60, 0xa8, 0x95, 0xa3, 0xa2, 0x78, 0x70, 0xf6, 0xe7, 0x39, 0xa8, 0xbc, 0xd4, 0x13, 0x86, 0xd0, + 0xbd, 0xc0, 0x75, 0xcf, 0xa1, 0xd9, 0x00, 0x06, 0x23, 0x40, 0x1a, 0x0e, 0xfd, 0x87, 0x04, 0xc3, + 0xe7, 0x79, 0x34, 0x4a, 0x04, 0x67, 0xd8, 0x6e, 0x56, 0xc8, 0xc9, 0x9e, 0x71, 0x84, 0xda, 0x25, + 0xae, 0xf6, 0x3e, 0x9a, 0xf7, 0x57, 0xeb, 0x0c, 0x8f, 0x4c, 0x2b, 0xc9, 0xf1, 0xd4, 0xd1, 0x49, + 0x54, 0x3a, 0x3e, 0x89, 0x4a, 0x5f, 0x4f, 0xa2, 0xd2, 0xc1, 0x69, 0x34, 0x74, 0x7c, 0x1a, 0x0d, + 0x7d, 0x3a, 0x8d, 0x86, 0x9e, 0xcc, 0xea, 0x79, 0xfb, 0x79, 0x29, 0xab, 0x6e, 0xd3, 0xe2, 0x79, + 0x05, 0x76, 0x67, 0x70, 0xb9, 0xae, 0x8a, 0x5d, 0x31, 0x09, 0xcb, 0x86, 0xf9, 0x7f, 0xfc, 0x99, + 0x9f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x7a, 0x51, 0xb4, 0xed, 0x2f, 0x0d, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -576,6 +777,10 @@ type QueryClient interface { SequencersByRollapp(ctx context.Context, in *QueryGetSequencersByRollappRequest, opts ...grpc.CallOption) (*QueryGetSequencersByRollappResponse, error) // Queries a SequencersByRollappByStatus SequencersByRollappByStatus(ctx context.Context, in *QueryGetSequencersByRollappByStatusRequest, opts ...grpc.CallOption) (*QueryGetSequencersByRollappByStatusResponse, error) + // Queries the current proposer by rollappId. + GetProposerByRollapp(ctx context.Context, in *QueryGetProposerByRollappRequest, opts ...grpc.CallOption) (*QueryGetProposerByRollappResponse, error) + // Queries the next proposer by rollappId. + GetNextProposerByRollapp(ctx context.Context, in *QueryGetNextProposerByRollappRequest, opts ...grpc.CallOption) (*QueryGetNextProposerByRollappResponse, error) } type queryClient struct { @@ -631,6 +836,24 @@ func (c *queryClient) SequencersByRollappByStatus(ctx context.Context, in *Query return out, nil } +func (c *queryClient) GetProposerByRollapp(ctx context.Context, in *QueryGetProposerByRollappRequest, opts ...grpc.CallOption) (*QueryGetProposerByRollappResponse, error) { + out := new(QueryGetProposerByRollappResponse) + err := c.cc.Invoke(ctx, "/dymensionxyz.dymension.sequencer.Query/GetProposerByRollapp", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *queryClient) GetNextProposerByRollapp(ctx context.Context, in *QueryGetNextProposerByRollappRequest, opts ...grpc.CallOption) (*QueryGetNextProposerByRollappResponse, error) { + out := new(QueryGetNextProposerByRollappResponse) + err := c.cc.Invoke(ctx, "/dymensionxyz.dymension.sequencer.Query/GetNextProposerByRollapp", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // QueryServer is the server API for Query service. type QueryServer interface { // Parameters queries the parameters of the module. @@ -643,6 +866,10 @@ type QueryServer interface { SequencersByRollapp(context.Context, *QueryGetSequencersByRollappRequest) (*QueryGetSequencersByRollappResponse, error) // Queries a SequencersByRollappByStatus SequencersByRollappByStatus(context.Context, *QueryGetSequencersByRollappByStatusRequest) (*QueryGetSequencersByRollappByStatusResponse, error) + // Queries the current proposer by rollappId. + GetProposerByRollapp(context.Context, *QueryGetProposerByRollappRequest) (*QueryGetProposerByRollappResponse, error) + // Queries the next proposer by rollappId. + GetNextProposerByRollapp(context.Context, *QueryGetNextProposerByRollappRequest) (*QueryGetNextProposerByRollappResponse, error) } // UnimplementedQueryServer can be embedded to have forward compatible implementations. @@ -664,6 +891,12 @@ func (*UnimplementedQueryServer) SequencersByRollapp(ctx context.Context, req *Q func (*UnimplementedQueryServer) SequencersByRollappByStatus(ctx context.Context, req *QueryGetSequencersByRollappByStatusRequest) (*QueryGetSequencersByRollappByStatusResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method SequencersByRollappByStatus not implemented") } +func (*UnimplementedQueryServer) GetProposerByRollapp(ctx context.Context, req *QueryGetProposerByRollappRequest) (*QueryGetProposerByRollappResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetProposerByRollapp not implemented") +} +func (*UnimplementedQueryServer) GetNextProposerByRollapp(ctx context.Context, req *QueryGetNextProposerByRollappRequest) (*QueryGetNextProposerByRollappResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetNextProposerByRollapp not implemented") +} func RegisterQueryServer(s grpc1.Server, srv QueryServer) { s.RegisterService(&_Query_serviceDesc, srv) @@ -759,6 +992,42 @@ func _Query_SequencersByRollappByStatus_Handler(srv interface{}, ctx context.Con return interceptor(ctx, in, info, handler) } +func _Query_GetProposerByRollapp_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryGetProposerByRollappRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).GetProposerByRollapp(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/dymensionxyz.dymension.sequencer.Query/GetProposerByRollapp", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).GetProposerByRollapp(ctx, req.(*QueryGetProposerByRollappRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Query_GetNextProposerByRollapp_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryGetNextProposerByRollappRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).GetNextProposerByRollapp(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/dymensionxyz.dymension.sequencer.Query/GetNextProposerByRollapp", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).GetNextProposerByRollapp(ctx, req.(*QueryGetNextProposerByRollappRequest)) + } + return interceptor(ctx, in, info, handler) +} + var _Query_serviceDesc = grpc.ServiceDesc{ ServiceName: "dymensionxyz.dymension.sequencer.Query", HandlerType: (*QueryServer)(nil), @@ -783,6 +1052,14 @@ var _Query_serviceDesc = grpc.ServiceDesc{ MethodName: "SequencersByRollappByStatus", Handler: _Query_SequencersByRollappByStatus_Handler, }, + { + MethodName: "GetProposerByRollapp", + Handler: _Query_GetProposerByRollapp_Handler, + }, + { + MethodName: "GetNextProposerByRollapp", + Handler: _Query_GetNextProposerByRollapp_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "dymensionxyz/dymension/sequencer/query.proto", @@ -1130,81 +1407,211 @@ func (m *QueryGetSequencersByRollappByStatusResponse) MarshalToSizedBuffer(dAtA return len(dAtA) - i, nil } -func encodeVarintQuery(dAtA []byte, offset int, v uint64) int { - offset -= sovQuery(v) - base := offset - for v >= 1<<7 { - dAtA[offset] = uint8(v&0x7f | 0x80) - v >>= 7 - offset++ - } - dAtA[offset] = uint8(v) - return base -} -func (m *QueryParamsRequest) Size() (n int) { - if m == nil { - return 0 +func (m *QueryGetProposerByRollappRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err } - var l int - _ = l - return n + return dAtA[:n], nil } -func (m *QueryParamsResponse) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = m.Params.Size() - n += 1 + l + sovQuery(uint64(l)) - return n +func (m *QueryGetProposerByRollappRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *QueryGetSequencerRequest) Size() (n int) { - if m == nil { - return 0 - } +func (m *QueryGetProposerByRollappRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i var l int _ = l - l = len(m.SequencerAddress) - if l > 0 { - n += 1 + l + sovQuery(uint64(l)) + if len(m.RollappId) > 0 { + i -= len(m.RollappId) + copy(dAtA[i:], m.RollappId) + i = encodeVarintQuery(dAtA, i, uint64(len(m.RollappId))) + i-- + dAtA[i] = 0xa } - return n + return len(dAtA) - i, nil } -func (m *QueryGetSequencerResponse) Size() (n int) { - if m == nil { - return 0 +func (m *QueryGetProposerByRollappResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err } - var l int - _ = l - l = m.Sequencer.Size() - n += 1 + l + sovQuery(uint64(l)) - return n + return dAtA[:n], nil } -func (m *QuerySequencersRequest) Size() (n int) { - if m == nil { - return 0 - } +func (m *QueryGetProposerByRollappResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryGetProposerByRollappResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i var l int _ = l - if m.Pagination != nil { - l = m.Pagination.Size() - n += 1 + l + sovQuery(uint64(l)) + if len(m.ProposerAddr) > 0 { + i -= len(m.ProposerAddr) + copy(dAtA[i:], m.ProposerAddr) + i = encodeVarintQuery(dAtA, i, uint64(len(m.ProposerAddr))) + i-- + dAtA[i] = 0xa } - return n + return len(dAtA) - i, nil } -func (m *QuerySequencersResponse) Size() (n int) { - if m == nil { - return 0 +func (m *QueryGetNextProposerByRollappRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err } + return dAtA[:n], nil +} + +func (m *QueryGetNextProposerByRollappRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryGetNextProposerByRollappRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i var l int _ = l - if len(m.Sequencers) > 0 { + if len(m.RollappId) > 0 { + i -= len(m.RollappId) + copy(dAtA[i:], m.RollappId) + i = encodeVarintQuery(dAtA, i, uint64(len(m.RollappId))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QueryGetNextProposerByRollappResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryGetNextProposerByRollappResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryGetNextProposerByRollappResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.RotationInProgress { + i-- + if m.RotationInProgress { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x10 + } + if len(m.NextProposerAddr) > 0 { + i -= len(m.NextProposerAddr) + copy(dAtA[i:], m.NextProposerAddr) + i = encodeVarintQuery(dAtA, i, uint64(len(m.NextProposerAddr))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func encodeVarintQuery(dAtA []byte, offset int, v uint64) int { + offset -= sovQuery(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *QueryParamsRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *QueryParamsResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.Params.Size() + n += 1 + l + sovQuery(uint64(l)) + return n +} + +func (m *QueryGetSequencerRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.SequencerAddress) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryGetSequencerResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.Sequencer.Size() + n += 1 + l + sovQuery(uint64(l)) + return n +} + +func (m *QuerySequencersRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Pagination != nil { + l = m.Pagination.Size() + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QuerySequencersResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Sequencers) > 0 { for _, e := range m.Sequencers { l = e.Size() n += 1 + l + sovQuery(uint64(l)) @@ -1276,6 +1683,61 @@ func (m *QueryGetSequencersByRollappByStatusResponse) Size() (n int) { return n } +func (m *QueryGetProposerByRollappRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.RollappId) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryGetProposerByRollappResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.ProposerAddr) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryGetNextProposerByRollappRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.RollappId) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryGetNextProposerByRollappResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.NextProposerAddr) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + if m.RotationInProgress { + n += 2 + } + return n +} + func sovQuery(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -1292,25 +1754,359 @@ func (m *QueryParamsRequest) Unmarshal(dAtA []byte) error { if shift >= 64 { return ErrIntOverflowQuery } - if iNdEx >= l { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryParamsRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryParamsRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryParamsResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryParamsResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryParamsResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Params", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Params.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryGetSequencerRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryGetSequencerRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryGetSequencerRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SequencerAddress", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.SequencerAddress = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryGetSequencerResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryGetSequencerResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryGetSequencerResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Sequencer", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Sequencer.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QuerySequencersRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QuerySequencersRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QuerySequencersRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Pagination", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { return io.ErrUnexpectedEOF } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break + if m.Pagination == nil { + m.Pagination = &query.PageRequest{} } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: QueryParamsRequest: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: QueryParamsRequest: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { + if err := m.Pagination.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipQuery(dAtA[iNdEx:]) @@ -1332,7 +2128,7 @@ func (m *QueryParamsRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *QueryParamsResponse) Unmarshal(dAtA []byte) error { +func (m *QuerySequencersResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -1355,15 +2151,15 @@ func (m *QueryParamsResponse) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: QueryParamsResponse: wiretype end group for non-group") + return fmt.Errorf("proto: QuerySequencersResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: QueryParamsResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: QuerySequencersResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Params", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Sequencers", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -1390,7 +2186,44 @@ func (m *QueryParamsResponse) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.Params.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + m.Sequencers = append(m.Sequencers, Sequencer{}) + if err := m.Sequencers[len(m.Sequencers)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Pagination", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Pagination == nil { + m.Pagination = &query.PageResponse{} + } + if err := m.Pagination.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -1415,7 +2248,7 @@ func (m *QueryParamsResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *QueryGetSequencerRequest) Unmarshal(dAtA []byte) error { +func (m *QueryGetSequencersByRollappRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -1438,15 +2271,15 @@ func (m *QueryGetSequencerRequest) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: QueryGetSequencerRequest: wiretype end group for non-group") + return fmt.Errorf("proto: QueryGetSequencersByRollappRequest: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: QueryGetSequencerRequest: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: QueryGetSequencersByRollappRequest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field SequencerAddress", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field RollappId", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -1474,7 +2307,7 @@ func (m *QueryGetSequencerRequest) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.SequencerAddress = string(dAtA[iNdEx:postIndex]) + m.RollappId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex @@ -1497,7 +2330,7 @@ func (m *QueryGetSequencerRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *QueryGetSequencerResponse) Unmarshal(dAtA []byte) error { +func (m *QueryGetSequencersByRollappResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -1520,15 +2353,15 @@ func (m *QueryGetSequencerResponse) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: QueryGetSequencerResponse: wiretype end group for non-group") + return fmt.Errorf("proto: QueryGetSequencersByRollappResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: QueryGetSequencerResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: QueryGetSequencersByRollappResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Sequencer", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Sequencers", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -1555,7 +2388,8 @@ func (m *QueryGetSequencerResponse) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.Sequencer.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + m.Sequencers = append(m.Sequencers, Sequencer{}) + if err := m.Sequencers[len(m.Sequencers)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -1580,7 +2414,7 @@ func (m *QueryGetSequencerResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *QuerySequencersRequest) Unmarshal(dAtA []byte) error { +func (m *QueryGetSequencersByRollappByStatusRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -1603,17 +2437,17 @@ func (m *QuerySequencersRequest) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: QuerySequencersRequest: wiretype end group for non-group") + return fmt.Errorf("proto: QueryGetSequencersByRollappByStatusRequest: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: QuerySequencersRequest: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: QueryGetSequencersByRollappByStatusRequest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Pagination", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field RollappId", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowQuery @@ -1623,28 +2457,43 @@ func (m *QuerySequencersRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthQuery } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthQuery } if postIndex > l { return io.ErrUnexpectedEOF } - if m.Pagination == nil { - m.Pagination = &query.PageRequest{} + m.RollappId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) } - if err := m.Pagination.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err + m.Status = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Status |= OperatingStatus(b&0x7F) << shift + if b < 0x80 { + break + } } - iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipQuery(dAtA[iNdEx:]) @@ -1666,7 +2515,7 @@ func (m *QuerySequencersRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *QuerySequencersResponse) Unmarshal(dAtA []byte) error { +func (m *QueryGetSequencersByRollappByStatusResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -1689,10 +2538,10 @@ func (m *QuerySequencersResponse) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: QuerySequencersResponse: wiretype end group for non-group") + return fmt.Errorf("proto: QueryGetSequencersByRollappByStatusResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: QuerySequencersResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: QueryGetSequencersByRollappByStatusResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -1729,42 +2578,6 @@ func (m *QuerySequencersResponse) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Pagination", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowQuery - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthQuery - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthQuery - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Pagination == nil { - m.Pagination = &query.PageResponse{} - } - if err := m.Pagination.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipQuery(dAtA[iNdEx:]) @@ -1786,7 +2599,7 @@ func (m *QuerySequencersResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *QueryGetSequencersByRollappRequest) Unmarshal(dAtA []byte) error { +func (m *QueryGetProposerByRollappRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -1809,10 +2622,10 @@ func (m *QueryGetSequencersByRollappRequest) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: QueryGetSequencersByRollappRequest: wiretype end group for non-group") + return fmt.Errorf("proto: QueryGetProposerByRollappRequest: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: QueryGetSequencersByRollappRequest: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: QueryGetProposerByRollappRequest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -1868,7 +2681,7 @@ func (m *QueryGetSequencersByRollappRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *QueryGetSequencersByRollappResponse) Unmarshal(dAtA []byte) error { +func (m *QueryGetProposerByRollappResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -1891,17 +2704,17 @@ func (m *QueryGetSequencersByRollappResponse) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: QueryGetSequencersByRollappResponse: wiretype end group for non-group") + return fmt.Errorf("proto: QueryGetProposerByRollappResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: QueryGetSequencersByRollappResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: QueryGetProposerByRollappResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Sequencers", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ProposerAddr", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowQuery @@ -1911,25 +2724,23 @@ func (m *QueryGetSequencersByRollappResponse) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthQuery } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthQuery } if postIndex > l { return io.ErrUnexpectedEOF } - m.Sequencers = append(m.Sequencers, Sequencer{}) - if err := m.Sequencers[len(m.Sequencers)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.ProposerAddr = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex @@ -1952,7 +2763,7 @@ func (m *QueryGetSequencersByRollappResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *QueryGetSequencersByRollappByStatusRequest) Unmarshal(dAtA []byte) error { +func (m *QueryGetNextProposerByRollappRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -1975,10 +2786,10 @@ func (m *QueryGetSequencersByRollappByStatusRequest) Unmarshal(dAtA []byte) erro fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: QueryGetSequencersByRollappByStatusRequest: wiretype end group for non-group") + return fmt.Errorf("proto: QueryGetNextProposerByRollappRequest: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: QueryGetSequencersByRollappByStatusRequest: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: QueryGetNextProposerByRollappRequest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -2013,25 +2824,6 @@ func (m *QueryGetSequencersByRollappByStatusRequest) Unmarshal(dAtA []byte) erro } m.RollappId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 2: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) - } - m.Status = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowQuery - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.Status |= OperatingStatus(b&0x7F) << shift - if b < 0x80 { - break - } - } default: iNdEx = preIndex skippy, err := skipQuery(dAtA[iNdEx:]) @@ -2053,7 +2845,7 @@ func (m *QueryGetSequencersByRollappByStatusRequest) Unmarshal(dAtA []byte) erro } return nil } -func (m *QueryGetSequencersByRollappByStatusResponse) Unmarshal(dAtA []byte) error { +func (m *QueryGetNextProposerByRollappResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -2076,17 +2868,17 @@ func (m *QueryGetSequencersByRollappByStatusResponse) Unmarshal(dAtA []byte) err fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: QueryGetSequencersByRollappByStatusResponse: wiretype end group for non-group") + return fmt.Errorf("proto: QueryGetNextProposerByRollappResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: QueryGetSequencersByRollappByStatusResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: QueryGetNextProposerByRollappResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Sequencers", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field NextProposerAddr", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowQuery @@ -2096,26 +2888,44 @@ func (m *QueryGetSequencersByRollappByStatusResponse) Unmarshal(dAtA []byte) err } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthQuery } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthQuery } if postIndex > l { return io.ErrUnexpectedEOF } - m.Sequencers = append(m.Sequencers, Sequencer{}) - if err := m.Sequencers[len(m.Sequencers)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.NextProposerAddr = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field RotationInProgress", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.RotationInProgress = bool(v != 0) default: iNdEx = preIndex skippy, err := skipQuery(dAtA[iNdEx:]) diff --git a/x/sequencer/types/query.pb.gw.go b/x/sequencer/types/query.pb.gw.go index 5a825bb4f..ea7d257aa 100644 --- a/x/sequencer/types/query.pb.gw.go +++ b/x/sequencer/types/query.pb.gw.go @@ -277,6 +277,114 @@ func local_request_Query_SequencersByRollappByStatus_0(ctx context.Context, mars } +func request_Query_GetProposerByRollapp_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryGetProposerByRollappRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["rollappId"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "rollappId") + } + + protoReq.RollappId, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "rollappId", err) + } + + msg, err := client.GetProposerByRollapp(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_GetProposerByRollapp_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryGetProposerByRollappRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["rollappId"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "rollappId") + } + + protoReq.RollappId, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "rollappId", err) + } + + msg, err := server.GetProposerByRollapp(ctx, &protoReq) + return msg, metadata, err + +} + +func request_Query_GetNextProposerByRollapp_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryGetNextProposerByRollappRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["rollappId"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "rollappId") + } + + protoReq.RollappId, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "rollappId", err) + } + + msg, err := client.GetNextProposerByRollapp(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_GetNextProposerByRollapp_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryGetNextProposerByRollappRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["rollappId"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "rollappId") + } + + protoReq.RollappId, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "rollappId", err) + } + + msg, err := server.GetNextProposerByRollapp(ctx, &protoReq) + return msg, metadata, err + +} + // RegisterQueryHandlerServer registers the http handlers for service Query to "mux". // UnaryRPC :call QueryServer directly. // StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. @@ -398,6 +506,52 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv }) + mux.Handle("GET", pattern_Query_GetProposerByRollapp_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_GetProposerByRollapp_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_GetProposerByRollapp_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_GetNextProposerByRollapp_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_GetNextProposerByRollapp_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_GetNextProposerByRollapp_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } @@ -539,6 +693,46 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie }) + mux.Handle("GET", pattern_Query_GetProposerByRollapp_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_GetProposerByRollapp_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_GetProposerByRollapp_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_GetNextProposerByRollapp_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_GetNextProposerByRollapp_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_GetNextProposerByRollapp_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } @@ -552,6 +746,10 @@ var ( pattern_Query_SequencersByRollapp_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"dymensionxyz", "dymension", "sequencer", "sequencers_by_rollapp", "rollappId"}, "", runtime.AssumeColonVerbOpt(false))) pattern_Query_SequencersByRollappByStatus_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4, 1, 0, 4, 1, 5, 5}, []string{"dymensionxyz", "dymension", "sequencer", "sequencers_by_rollapp", "rollappId", "status"}, "", runtime.AssumeColonVerbOpt(false))) + + pattern_Query_GetProposerByRollapp_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"dymensionxyz", "dymension", "sequencer", "proposer", "rollappId"}, "", runtime.AssumeColonVerbOpt(false))) + + pattern_Query_GetNextProposerByRollapp_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"dymensionxyz", "dymension", "sequencer", "next_proposer", "rollappId"}, "", runtime.AssumeColonVerbOpt(false))) ) var ( @@ -564,4 +762,8 @@ var ( forward_Query_SequencersByRollapp_0 = runtime.ForwardResponseMessage forward_Query_SequencersByRollappByStatus_0 = runtime.ForwardResponseMessage + + forward_Query_GetProposerByRollapp_0 = runtime.ForwardResponseMessage + + forward_Query_GetNextProposerByRollapp_0 = runtime.ForwardResponseMessage ) diff --git a/x/sequencer/types/sequencer.go b/x/sequencer/types/sequencer.go index dfeae08c9..e150c32d2 100644 --- a/x/sequencer/types/sequencer.go +++ b/x/sequencer/types/sequencer.go @@ -8,12 +8,31 @@ import ( cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" ) +// ValidateBasic performs basic validation of the sequencer object +func (seq Sequencer) ValidateBasic() error { + if seq.Status == Unbonding && (seq.UnbondRequestHeight == 0 || seq.UnbondTime.IsZero()) { + return ErrInvalidSequencerStatus + } + + // validate notice period + if seq.IsNoticePeriodInProgress() && seq.NoticePeriodTime.IsZero() { + return ErrInvalidSequencerStatus + } + + return nil +} + +func (seq Sequencer) IsEmpty() bool { + return seq.Address == "" +} + func (seq Sequencer) IsBonded() bool { return seq.Status == Bonded } -func (seq Sequencer) IsProposer() bool { - return seq.Proposer +// IsNoticePeriodInProgress returns true if the sequencer is bonded and has an unbond request +func (seq Sequencer) IsNoticePeriodInProgress() bool { + return seq.Status == Bonded && seq.UnbondRequestHeight != 0 } // GetDymintPubKeyHash returns the hash of the sequencer diff --git a/x/sequencer/types/sequencer.pb.go b/x/sequencer/types/sequencer.pb.go index 751c344f2..b2f4cb8fb 100644 --- a/x/sequencer/types/sequencer.pb.go +++ b/x/sequencer/types/sequencer.pb.go @@ -44,17 +44,20 @@ type Sequencer struct { // metadata defines the extra information for the sequencer. Metadata SequencerMetadata `protobuf:"bytes,4,opt,name=metadata,proto3" json:"metadata"` // jailed defined whether the sequencer has been jailed from bonded status or not. - Jailed bool `protobuf:"varint,5,opt,name=jailed,proto3" json:"jailed,omitempty"` - // proposer defines whether the sequencer is a proposer or not. - Proposer bool `protobuf:"varint,6,opt,name=proposer,proto3" json:"proposer,omitempty"` + Jailed bool `protobuf:"varint,5,opt,name=jailed,proto3" json:"jailed,omitempty"` + Proposer bool `protobuf:"varint,6,opt,name=proposer,proto3" json:"proposer,omitempty"` // Deprecated: Do not use. // status is the sequencer status (bonded/unbonding/unbonded). Status OperatingStatus `protobuf:"varint,7,opt,name=status,proto3,enum=dymensionxyz.dymension.sequencer.OperatingStatus" json:"status,omitempty"` // tokens define the delegated tokens (incl. self-delegation). Tokens github_com_cosmos_cosmos_sdk_types.Coins `protobuf:"bytes,8,rep,name=tokens,proto3,castrepeated=github.com/cosmos/cosmos-sdk/types.Coins" json:"tokens"` - // unbonding_height defines, if unbonding, the height at which this sequencer has begun unbonding. - UnbondingHeight int64 `protobuf:"varint,9,opt,name=unbonding_height,json=unbondingHeight,proto3" json:"unbonding_height,omitempty"` - // unbond_time defines, if unbonding, the min time for the sequencer to complete unbonding. + // unbond_request_height stores the height at which this sequencer has + // requested to unbond. + UnbondRequestHeight int64 `protobuf:"varint,9,opt,name=unbond_request_height,json=unbondRequestHeight,proto3" json:"unbond_request_height,omitempty"` + // unbond_time defines, if unbonding, the min time for the sequencer to + // complete unbonding. UnbondTime time.Time `protobuf:"bytes,10,opt,name=unbond_time,json=unbondTime,proto3,stdtime" json:"unbond_time"` + // notice_period_time defines the time when the sequencer will finish it's notice period if started + NoticePeriodTime time.Time `protobuf:"bytes,11,opt,name=notice_period_time,json=noticePeriodTime,proto3,stdtime" json:"notice_period_time"` } func (m *Sequencer) Reset() { *m = Sequencer{} } @@ -125,6 +128,7 @@ func (m *Sequencer) GetJailed() bool { return false } +// Deprecated: Do not use. func (m *Sequencer) GetProposer() bool { if m != nil { return m.Proposer @@ -146,9 +150,9 @@ func (m *Sequencer) GetTokens() github_com_cosmos_cosmos_sdk_types.Coins { return nil } -func (m *Sequencer) GetUnbondingHeight() int64 { +func (m *Sequencer) GetUnbondRequestHeight() int64 { if m != nil { - return m.UnbondingHeight + return m.UnbondRequestHeight } return 0 } @@ -160,6 +164,13 @@ func (m *Sequencer) GetUnbondTime() time.Time { return time.Time{} } +func (m *Sequencer) GetNoticePeriodTime() time.Time { + if m != nil { + return m.NoticePeriodTime + } + return time.Time{} +} + // BondReduction defines an object which holds the information about the sequencer and its queued unbonding amount type BondReduction struct { // sequencer_address is the bech32-encoded address of the sequencer account which is the account that the message was sent from. @@ -234,46 +245,48 @@ func init() { } var fileDescriptor_997b8663a5fc0f58 = []byte{ - // 618 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x53, 0x4f, 0x6f, 0xd3, 0x3e, - 0x18, 0x6e, 0x7e, 0xdd, 0xaf, 0x6b, 0x3d, 0xfe, 0x0c, 0xab, 0x82, 0xac, 0x42, 0x69, 0xb4, 0x53, - 0x10, 0x9a, 0xbd, 0x6e, 0x12, 0x9c, 0x57, 0x84, 0xc4, 0x84, 0x10, 0x23, 0x83, 0x0b, 0x97, 0xca, - 0x89, 0x4d, 0x16, 0xd6, 0xd8, 0x21, 0x76, 0xa6, 0x85, 0x4f, 0xb1, 0xcf, 0xc1, 0x99, 0x8f, 0xc0, - 0x61, 0xe2, 0xb4, 0x23, 0x27, 0x86, 0xd6, 0x2f, 0x82, 0xe2, 0x38, 0x59, 0x0b, 0x82, 0x8a, 0x93, - 0xfd, 0xfe, 0x79, 0x5e, 0xbf, 0xef, 0xf3, 0x3e, 0x06, 0xdb, 0xb4, 0x48, 0x18, 0x97, 0xb1, 0xe0, - 0xa7, 0xc5, 0x47, 0xdc, 0x18, 0x58, 0xb2, 0x0f, 0x39, 0xe3, 0x21, 0xcb, 0xae, 0x6f, 0x28, 0xcd, - 0x84, 0x12, 0xd0, 0x9d, 0x47, 0xa0, 0xc6, 0x40, 0x4d, 0xde, 0x60, 0x23, 0x14, 0x32, 0x11, 0x72, - 0xa2, 0xf3, 0x71, 0x65, 0x54, 0xe0, 0xc1, 0x46, 0x24, 0x44, 0x34, 0x65, 0x58, 0x5b, 0x41, 0xfe, - 0x0e, 0x13, 0x5e, 0x98, 0x50, 0x3f, 0x12, 0x91, 0xa8, 0x20, 0xe5, 0xcd, 0x78, 0x87, 0xbf, 0x02, - 0x54, 0x9c, 0x30, 0xa9, 0x48, 0x92, 0x9a, 0x04, 0xa7, 0xaa, 0x8f, 0x03, 0x22, 0x19, 0x3e, 0x19, - 0x05, 0x4c, 0x91, 0x11, 0x0e, 0x45, 0xcc, 0x4d, 0xfc, 0x9e, 0x89, 0x27, 0x32, 0xc2, 0x27, 0xa3, - 0xf2, 0x30, 0x01, 0xbc, 0x74, 0xf2, 0x84, 0x29, 0x42, 0x89, 0x22, 0x06, 0xf0, 0x78, 0x29, 0x40, - 0xa4, 0x2c, 0x23, 0x2a, 0xe6, 0xd1, 0x44, 0x2a, 0xa2, 0x72, 0x33, 0xf4, 0xe6, 0x97, 0x15, 0xd0, - 0x3b, 0xac, 0x93, 0xa0, 0x0d, 0x56, 0x09, 0xa5, 0x19, 0x93, 0xd2, 0xb6, 0x5c, 0xcb, 0xeb, 0xf9, - 0xb5, 0x09, 0x7d, 0x70, 0x83, 0x16, 0x49, 0xcc, 0xd5, 0x41, 0x1e, 0x3c, 0x67, 0x85, 0xfd, 0x9f, - 0x6b, 0x79, 0x6b, 0x3b, 0x7d, 0x54, 0x51, 0x80, 0x6a, 0x0a, 0xd0, 0x1e, 0x2f, 0xc6, 0xf6, 0xd7, - 0xcf, 0x5b, 0x7d, 0x43, 0x6d, 0x98, 0x15, 0xa9, 0x12, 0xa8, 0x42, 0xf9, 0x0b, 0x35, 0xe0, 0x7d, - 0xd0, 0xcb, 0xc4, 0x74, 0x4a, 0xd2, 0x74, 0x9f, 0xda, 0x6d, 0xfd, 0xde, 0xb5, 0x03, 0xbe, 0x01, - 0xdd, 0x7a, 0x48, 0x7b, 0x45, 0xbf, 0xb6, 0x8b, 0x96, 0xad, 0x17, 0x35, 0xa3, 0xbc, 0x30, 0xd0, - 0xf1, 0xca, 0xf9, 0xf7, 0x61, 0xcb, 0x6f, 0x4a, 0xc1, 0xbb, 0xa0, 0xf3, 0x9e, 0xc4, 0x53, 0x46, - 0xed, 0xff, 0x5d, 0xcb, 0xeb, 0xfa, 0xc6, 0x82, 0x03, 0xd0, 0x4d, 0x33, 0x91, 0x0a, 0xc9, 0x32, - 0xbb, 0xa3, 0x23, 0x8d, 0x0d, 0xf7, 0x41, 0xa7, 0x22, 0xcd, 0x5e, 0x75, 0x2d, 0xef, 0xd6, 0xce, - 0x68, 0x79, 0x23, 0x2f, 0x6b, 0xba, 0x0f, 0x35, 0xd0, 0x37, 0x05, 0x60, 0x08, 0x3a, 0x4a, 0x1c, - 0x33, 0x2e, 0xed, 0xae, 0xdb, 0xf6, 0xd6, 0x76, 0x36, 0x90, 0x21, 0xaa, 0xd4, 0x08, 0x32, 0x1a, - 0x41, 0x4f, 0x44, 0xcc, 0xc7, 0xdb, 0x65, 0xe7, 0x9f, 0x2e, 0x87, 0x5e, 0x14, 0xab, 0xa3, 0x3c, - 0x40, 0xa1, 0x48, 0x8c, 0x60, 0xcd, 0xb1, 0x25, 0xe9, 0x31, 0x56, 0x45, 0xca, 0xa4, 0x06, 0x48, - 0xdf, 0x94, 0x86, 0x0f, 0xc0, 0x7a, 0xce, 0x03, 0xc1, 0x69, 0xb9, 0xee, 0x23, 0x16, 0x47, 0x47, - 0xca, 0xee, 0xb9, 0x96, 0xd7, 0xf6, 0x6f, 0x37, 0xfe, 0x67, 0xda, 0x0d, 0x9f, 0x82, 0xb5, 0xca, - 0x35, 0x29, 0xc5, 0x6b, 0x03, 0x4d, 0xf4, 0xe0, 0xb7, 0xb5, 0xbe, 0xae, 0x95, 0x3d, 0xee, 0x96, - 0x5d, 0x9d, 0x5d, 0x0e, 0x2d, 0x1f, 0x54, 0xc0, 0x32, 0xb4, 0x39, 0xb3, 0xc0, 0xcd, 0xb1, 0xe0, - 0xd4, 0x67, 0x34, 0x0f, 0x55, 0x2c, 0x38, 0x7c, 0x08, 0xee, 0x34, 0x6c, 0x4c, 0x16, 0x45, 0xb5, - 0xde, 0x04, 0xf6, 0x8c, 0xba, 0x5e, 0x81, 0x3e, 0x65, 0x61, 0xc6, 0x88, 0x64, 0x13, 0xdd, 0x0c, - 0x49, 0x44, 0xce, 0x95, 0x51, 0xd9, 0x5f, 0x38, 0xaa, 0xb6, 0x0b, 0x6b, 0x70, 0xd9, 0xc2, 0x9e, - 0x86, 0x42, 0x1f, 0xc0, 0xc5, 0x92, 0x7a, 0xbe, 0xf6, 0x3f, 0xcc, 0xb7, 0x3e, 0x5f, 0xb5, 0x4c, - 0x18, 0x1f, 0x9c, 0x5f, 0x39, 0xd6, 0xc5, 0x95, 0x63, 0xfd, 0xb8, 0x72, 0xac, 0xb3, 0x99, 0xd3, - 0xba, 0x98, 0x39, 0xad, 0x6f, 0x33, 0xa7, 0xf5, 0xf6, 0xd1, 0xdc, 0x8e, 0xfe, 0xf0, 0x15, 0x4f, - 0x76, 0xf1, 0xe9, 0xdc, 0x7f, 0xd4, 0x7b, 0x0b, 0x3a, 0xba, 0x83, 0xdd, 0x9f, 0x01, 0x00, 0x00, - 0xff, 0xff, 0x11, 0x29, 0x96, 0xa7, 0xeb, 0x04, 0x00, 0x00, + // 645 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x53, 0x41, 0x6f, 0xd3, 0x30, + 0x18, 0x6d, 0xd6, 0xad, 0x6b, 0x5d, 0x40, 0xc3, 0x14, 0xc8, 0x26, 0x94, 0x56, 0x3b, 0x45, 0x42, + 0x73, 0xd6, 0x4e, 0x82, 0xf3, 0x82, 0x90, 0x98, 0x10, 0x62, 0x64, 0x70, 0xe1, 0x12, 0x39, 0x89, + 0xc9, 0xc2, 0x1a, 0x3b, 0xc4, 0xce, 0xb4, 0xf0, 0x2b, 0xf6, 0x27, 0xb8, 0x70, 0xe6, 0x47, 0x4c, + 0x9c, 0x76, 0xe4, 0xc4, 0xd0, 0xfa, 0x47, 0x90, 0x1d, 0x27, 0xeb, 0x40, 0x50, 0xed, 0x94, 0x7c, + 0x7e, 0xdf, 0x7b, 0xf9, 0xbe, 0xe7, 0x17, 0xb0, 0x1d, 0x95, 0x29, 0xa1, 0x3c, 0x61, 0xf4, 0xa4, + 0xfc, 0xec, 0x34, 0x85, 0xc3, 0xc9, 0xa7, 0x82, 0xd0, 0x90, 0xe4, 0x57, 0x6f, 0x28, 0xcb, 0x99, + 0x60, 0x70, 0x34, 0xcf, 0x40, 0x4d, 0x81, 0x9a, 0xbe, 0x8d, 0xf5, 0x90, 0xf1, 0x94, 0x71, 0x5f, + 0xf5, 0x3b, 0x55, 0x51, 0x91, 0x37, 0xd6, 0x63, 0xc6, 0xe2, 0x29, 0x71, 0x54, 0x15, 0x14, 0x1f, + 0x1c, 0x4c, 0x4b, 0x0d, 0x0d, 0x62, 0x16, 0xb3, 0x8a, 0x22, 0xdf, 0xf4, 0xe9, 0xf0, 0x4f, 0x82, + 0x48, 0x52, 0xc2, 0x05, 0x4e, 0x33, 0xdd, 0x60, 0x55, 0xfa, 0x4e, 0x80, 0x39, 0x71, 0x8e, 0xc7, + 0x01, 0x11, 0x78, 0xec, 0x84, 0x2c, 0xa1, 0x1a, 0x7f, 0xa8, 0xf1, 0x94, 0xc7, 0xce, 0xf1, 0x58, + 0x3e, 0x34, 0xe0, 0x2c, 0xdc, 0x3c, 0x25, 0x02, 0x47, 0x58, 0x60, 0x4d, 0x78, 0xba, 0x90, 0xc0, + 0x32, 0x92, 0x63, 0x91, 0xd0, 0xd8, 0xe7, 0x02, 0x8b, 0x42, 0x2f, 0xbd, 0xf9, 0x65, 0x05, 0xf4, + 0x0e, 0xea, 0x26, 0x68, 0x82, 0x55, 0x1c, 0x45, 0x39, 0xe1, 0xdc, 0x34, 0x46, 0x86, 0xdd, 0xf3, + 0xea, 0x12, 0x7a, 0xe0, 0x56, 0x54, 0xa6, 0x09, 0x15, 0xfb, 0x45, 0xf0, 0x92, 0x94, 0xe6, 0xd2, + 0xc8, 0xb0, 0xfb, 0x93, 0x01, 0xaa, 0x2c, 0x40, 0xb5, 0x05, 0x68, 0x97, 0x96, 0xae, 0xf9, 0xfd, + 0xdb, 0xd6, 0x40, 0x5b, 0x1b, 0xe6, 0x65, 0x26, 0x18, 0xaa, 0x58, 0xde, 0x35, 0x0d, 0xf8, 0x08, + 0xf4, 0x72, 0x36, 0x9d, 0xe2, 0x2c, 0xdb, 0x8b, 0xcc, 0xb6, 0xfa, 0xde, 0xd5, 0x01, 0x7c, 0x07, + 0xba, 0xf5, 0x92, 0xe6, 0xb2, 0xfa, 0xda, 0x0e, 0x5a, 0x74, 0xbd, 0xa8, 0x59, 0xe5, 0x95, 0xa6, + 0xba, 0xcb, 0x67, 0x3f, 0x87, 0x2d, 0xaf, 0x91, 0x82, 0x0f, 0x40, 0xe7, 0x23, 0x4e, 0xa6, 0x24, + 0x32, 0x57, 0x46, 0x86, 0xdd, 0xf5, 0x74, 0x05, 0x2d, 0xd0, 0xcd, 0x72, 0x96, 0x31, 0x4e, 0x72, + 0xb3, 0x23, 0x11, 0x77, 0xc9, 0x34, 0xbc, 0xe6, 0x0c, 0xee, 0x81, 0x4e, 0x65, 0x9c, 0xb9, 0x3a, + 0x32, 0xec, 0x3b, 0x93, 0xf1, 0xe2, 0x61, 0x5e, 0xd7, 0x96, 0x1f, 0x28, 0xa2, 0xa7, 0x05, 0x60, + 0x08, 0x3a, 0x82, 0x1d, 0x11, 0xca, 0xcd, 0xee, 0xa8, 0x6d, 0xf7, 0x27, 0xeb, 0x48, 0x9b, 0x25, + 0x73, 0x82, 0x74, 0x4e, 0xd0, 0x33, 0x96, 0x50, 0x77, 0x5b, 0x4e, 0xff, 0xf5, 0x62, 0x68, 0xc7, + 0x89, 0x38, 0x2c, 0x02, 0x14, 0xb2, 0x54, 0x87, 0x56, 0x3f, 0xb6, 0x78, 0x74, 0xe4, 0x88, 0x32, + 0x23, 0x5c, 0x11, 0xb8, 0xa7, 0xa5, 0xe1, 0x04, 0xdc, 0x2f, 0x68, 0xc0, 0x68, 0xe4, 0xe7, 0x72, + 0x20, 0x2e, 0xfc, 0x43, 0x92, 0xc4, 0x87, 0xc2, 0xec, 0x8d, 0x0c, 0xbb, 0xed, 0xdd, 0xab, 0x40, + 0xaf, 0xc2, 0x5e, 0x28, 0x08, 0x3e, 0x07, 0x7d, 0xcd, 0x91, 0x49, 0x36, 0x81, 0x72, 0x7d, 0xe3, + 0xaf, 0x3b, 0x7e, 0x5b, 0xc7, 0xdc, 0xed, 0xca, 0xf1, 0x4e, 0x2f, 0x86, 0x86, 0x07, 0x2a, 0xa2, + 0x84, 0xa0, 0x07, 0x20, 0x65, 0x22, 0x09, 0x89, 0x9f, 0x91, 0x3c, 0x61, 0x5a, 0xad, 0x7f, 0x03, + 0xb5, 0xb5, 0x8a, 0xbf, 0xaf, 0xe8, 0xb2, 0x61, 0x73, 0x66, 0x80, 0xdb, 0xae, 0x1a, 0x38, 0x2a, + 0x42, 0x91, 0x30, 0x0a, 0x1f, 0x83, 0xbb, 0x8d, 0xd5, 0xfe, 0xf5, 0xd4, 0xae, 0x35, 0xc0, 0xae, + 0x8e, 0xef, 0x1b, 0x30, 0x88, 0x48, 0x98, 0x13, 0xcc, 0x89, 0xaf, 0x16, 0xc4, 0x29, 0x2b, 0xa8, + 0xd0, 0x31, 0xfe, 0xcf, 0x05, 0x54, 0xf1, 0x81, 0x35, 0x59, 0x8e, 0xb0, 0xab, 0xa8, 0x72, 0xcb, + 0xeb, 0x92, 0x6a, 0xcb, 0xf6, 0x4d, 0xb6, 0x9c, 0x57, 0x95, 0x0d, 0xee, 0xfe, 0xd9, 0xa5, 0x65, + 0x9c, 0x5f, 0x5a, 0xc6, 0xaf, 0x4b, 0xcb, 0x38, 0x9d, 0x59, 0xad, 0xf3, 0x99, 0xd5, 0xfa, 0x31, + 0xb3, 0x5a, 0xef, 0x9f, 0xcc, 0x05, 0xe0, 0x1f, 0xff, 0xfa, 0xf1, 0x8e, 0x73, 0x32, 0xf7, 0xc3, + 0xab, 0x50, 0x04, 0x1d, 0x35, 0xc1, 0xce, 0xef, 0x00, 0x00, 0x00, 0xff, 0xff, 0xeb, 0x84, 0x3a, + 0x6a, 0x4c, 0x05, 0x00, 0x00, } func (m *Sequencer) Marshal() (dAtA []byte, err error) { @@ -296,16 +309,24 @@ func (m *Sequencer) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l - n1, err1 := github_com_cosmos_gogoproto_types.StdTimeMarshalTo(m.UnbondTime, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdTime(m.UnbondTime):]) + n1, err1 := github_com_cosmos_gogoproto_types.StdTimeMarshalTo(m.NoticePeriodTime, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdTime(m.NoticePeriodTime):]) if err1 != nil { return 0, err1 } i -= n1 i = encodeVarintSequencer(dAtA, i, uint64(n1)) i-- + dAtA[i] = 0x5a + n2, err2 := github_com_cosmos_gogoproto_types.StdTimeMarshalTo(m.UnbondTime, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdTime(m.UnbondTime):]) + if err2 != nil { + return 0, err2 + } + i -= n2 + i = encodeVarintSequencer(dAtA, i, uint64(n2)) + i-- dAtA[i] = 0x52 - if m.UnbondingHeight != 0 { - i = encodeVarintSequencer(dAtA, i, uint64(m.UnbondingHeight)) + if m.UnbondRequestHeight != 0 { + i = encodeVarintSequencer(dAtA, i, uint64(m.UnbondRequestHeight)) i-- dAtA[i] = 0x48 } @@ -407,12 +428,12 @@ func (m *BondReduction) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l - n4, err4 := github_com_cosmos_gogoproto_types.StdTimeMarshalTo(m.DecreaseBondTime, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdTime(m.DecreaseBondTime):]) - if err4 != nil { - return 0, err4 + n5, err5 := github_com_cosmos_gogoproto_types.StdTimeMarshalTo(m.DecreaseBondTime, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdTime(m.DecreaseBondTime):]) + if err5 != nil { + return 0, err5 } - i -= n4 - i = encodeVarintSequencer(dAtA, i, uint64(n4)) + i -= n5 + i = encodeVarintSequencer(dAtA, i, uint64(n5)) i-- dAtA[i] = 0x1a { @@ -481,11 +502,13 @@ func (m *Sequencer) Size() (n int) { n += 1 + l + sovSequencer(uint64(l)) } } - if m.UnbondingHeight != 0 { - n += 1 + sovSequencer(uint64(m.UnbondingHeight)) + if m.UnbondRequestHeight != 0 { + n += 1 + sovSequencer(uint64(m.UnbondRequestHeight)) } l = github_com_cosmos_gogoproto_types.SizeOfStdTime(m.UnbondTime) n += 1 + l + sovSequencer(uint64(l)) + l = github_com_cosmos_gogoproto_types.SizeOfStdTime(m.NoticePeriodTime) + n += 1 + l + sovSequencer(uint64(l)) return n } @@ -769,9 +792,9 @@ func (m *Sequencer) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 9: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field UnbondingHeight", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field UnbondRequestHeight", wireType) } - m.UnbondingHeight = 0 + m.UnbondRequestHeight = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowSequencer @@ -781,7 +804,7 @@ func (m *Sequencer) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.UnbondingHeight |= int64(b&0x7F) << shift + m.UnbondRequestHeight |= int64(b&0x7F) << shift if b < 0x80 { break } @@ -819,6 +842,39 @@ func (m *Sequencer) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 11: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field NoticePeriodTime", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSequencer + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthSequencer + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthSequencer + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := github_com_cosmos_gogoproto_types.StdTimeUnmarshal(&m.NoticePeriodTime, dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipSequencer(dAtA[iNdEx:]) diff --git a/x/sequencer/types/tx.pb.go b/x/sequencer/types/tx.pb.go index b1b1806f8..0ba40bd5f 100644 --- a/x/sequencer/types/tx.pb.go +++ b/x/sequencer/types/tx.pb.go @@ -300,7 +300,13 @@ func (m *MsgUnbond) GetCreator() string { // MsgUnbondResponse defines the Msg/Unbond response type. type MsgUnbondResponse struct { - CompletionTime time.Time `protobuf:"bytes,1,opt,name=completion_time,json=completionTime,proto3,stdtime" json:"completion_time"` + // completion_time defines the time at which the unbonding will be completed. + // If unbonding the proposer, the completion time is the time at which the notice period will be completed. + // + // Types that are valid to be assigned to CompletionTime: + // *MsgUnbondResponse_UnbondingCompletionTime + // *MsgUnbondResponse_NoticePeriodCompletionTime + CompletionTime isMsgUnbondResponse_CompletionTime `protobuf_oneof:"completion_time"` } func (m *MsgUnbondResponse) Reset() { *m = MsgUnbondResponse{} } @@ -336,11 +342,49 @@ func (m *MsgUnbondResponse) XXX_DiscardUnknown() { var xxx_messageInfo_MsgUnbondResponse proto.InternalMessageInfo -func (m *MsgUnbondResponse) GetCompletionTime() time.Time { +type isMsgUnbondResponse_CompletionTime interface { + isMsgUnbondResponse_CompletionTime() + MarshalTo([]byte) (int, error) + Size() int +} + +type MsgUnbondResponse_UnbondingCompletionTime struct { + UnbondingCompletionTime *time.Time `protobuf:"bytes,1,opt,name=unbonding_completion_time,json=unbondingCompletionTime,proto3,oneof,stdtime" json:"unbonding_completion_time,omitempty"` +} +type MsgUnbondResponse_NoticePeriodCompletionTime struct { + NoticePeriodCompletionTime *time.Time `protobuf:"bytes,2,opt,name=notice_period_completion_time,json=noticePeriodCompletionTime,proto3,oneof,stdtime" json:"notice_period_completion_time,omitempty"` +} + +func (*MsgUnbondResponse_UnbondingCompletionTime) isMsgUnbondResponse_CompletionTime() {} +func (*MsgUnbondResponse_NoticePeriodCompletionTime) isMsgUnbondResponse_CompletionTime() {} + +func (m *MsgUnbondResponse) GetCompletionTime() isMsgUnbondResponse_CompletionTime { if m != nil { return m.CompletionTime } - return time.Time{} + return nil +} + +func (m *MsgUnbondResponse) GetUnbondingCompletionTime() *time.Time { + if x, ok := m.GetCompletionTime().(*MsgUnbondResponse_UnbondingCompletionTime); ok { + return x.UnbondingCompletionTime + } + return nil +} + +func (m *MsgUnbondResponse) GetNoticePeriodCompletionTime() *time.Time { + if x, ok := m.GetCompletionTime().(*MsgUnbondResponse_NoticePeriodCompletionTime); ok { + return x.NoticePeriodCompletionTime + } + return nil +} + +// XXX_OneofWrappers is for the internal use of the proto package. +func (*MsgUnbondResponse) XXX_OneofWrappers() []interface{} { + return []interface{}{ + (*MsgUnbondResponse_UnbondingCompletionTime)(nil), + (*MsgUnbondResponse_NoticePeriodCompletionTime)(nil), + } } // MsgIncreaseBond defines a SDK message for increasing the bond amount of a sequencer. @@ -553,53 +597,57 @@ func init() { } var fileDescriptor_02cdd6b9ffa005b4 = []byte{ - // 728 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x56, 0xcf, 0x6b, 0x13, 0x4b, - 0x1c, 0xcf, 0xf6, 0xd7, 0x6b, 0xa6, 0xa5, 0x79, 0x6f, 0x29, 0x74, 0xb3, 0xbc, 0x6e, 0x4a, 0xe0, - 0xf1, 0xaa, 0xe2, 0x2e, 0x49, 0x44, 0xb0, 0x88, 0xd2, 0x54, 0xd0, 0x22, 0x81, 0x9a, 0xda, 0x8b, - 0x97, 0x30, 0xbb, 0x33, 0xdd, 0xae, 0x64, 0x67, 0xd6, 0x9d, 0x49, 0xe9, 0x8a, 0x27, 0xc1, 0x7b, - 0xc1, 0xb3, 0xe2, 0xc9, 0xb3, 0x07, 0x6f, 0xe2, 0xbd, 0x78, 0x2a, 0x9e, 0x3c, 0xa9, 0xb4, 0x07, - 0xfd, 0x33, 0x64, 0x77, 0x67, 0xb7, 0x9b, 0xb4, 0x4d, 0xd2, 0x56, 0x4f, 0xed, 0xcc, 0x7c, 0x3f, - 0x3f, 0xbe, 0xdf, 0x99, 0x4f, 0x12, 0x70, 0x09, 0x05, 0x2e, 0x26, 0xcc, 0xa1, 0x64, 0x27, 0x78, - 0x6a, 0xa4, 0x0b, 0x83, 0xe1, 0x27, 0x1d, 0x4c, 0x2c, 0xec, 0x1b, 0x7c, 0x47, 0xf7, 0x7c, 0xca, - 0xa9, 0xbc, 0x90, 0x2d, 0xd5, 0xd3, 0x85, 0x9e, 0x96, 0xaa, 0x45, 0x9b, 0x52, 0xbb, 0x8d, 0x8d, - 0xa8, 0xde, 0xec, 0x6c, 0x1a, 0x90, 0x04, 0x31, 0x58, 0x2d, 0x5a, 0x94, 0xb9, 0x94, 0xb5, 0xa2, - 0x95, 0x11, 0x2f, 0xc4, 0xd1, 0xac, 0x4d, 0x6d, 0x1a, 0xef, 0x87, 0xff, 0x89, 0x5d, 0x2d, 0xae, - 0x31, 0x4c, 0xc8, 0xb0, 0xb1, 0x5d, 0x31, 0x31, 0x87, 0x15, 0xc3, 0xa2, 0x0e, 0x11, 0xe7, 0xa5, - 0x5e, 0x2d, 0xee, 0xb8, 0x98, 0x71, 0xe8, 0x7a, 0xa2, 0x60, 0x4e, 0x10, 0xb8, 0xcc, 0x36, 0xb6, - 0x2b, 0xe1, 0x1f, 0x71, 0x60, 0x0c, 0x6c, 0xd9, 0xc5, 0x1c, 0x22, 0xc8, 0x61, 0x0c, 0x28, 0x7f, - 0x18, 0x01, 0x72, 0x83, 0xd9, 0x2b, 0x3e, 0x86, 0x1c, 0xaf, 0x27, 0x55, 0xb2, 0x02, 0xfe, 0xb2, - 0xc2, 0x2d, 0xea, 0x2b, 0xd2, 0x82, 0xb4, 0x98, 0x6f, 0x26, 0x4b, 0xb9, 0x09, 0xa6, 0x51, 0xe0, - 0x3a, 0x84, 0xaf, 0x75, 0xcc, 0xfb, 0x38, 0x50, 0x46, 0x16, 0xa4, 0xc5, 0xa9, 0xea, 0xac, 0x1e, - 0x5b, 0xd6, 0x13, 0xcb, 0xfa, 0x32, 0x09, 0xea, 0xca, 0xa7, 0xf7, 0x57, 0x67, 0xc5, 0x3c, 0x2c, - 0x3f, 0xf0, 0x38, 0xd5, 0x63, 0x54, 0xb3, 0x8b, 0x43, 0x9e, 0x07, 0xc0, 0xa7, 0xed, 0x36, 0xf4, - 0xbc, 0x96, 0x83, 0x94, 0xd1, 0x48, 0x30, 0x2f, 0x76, 0x56, 0x91, 0xbc, 0x01, 0x26, 0x13, 0xd7, - 0xca, 0x58, 0x24, 0x57, 0xd3, 0x07, 0xdd, 0x97, 0x9e, 0xf6, 0xd2, 0x10, 0xd0, 0xfa, 0xd8, 0xde, - 0xd7, 0x52, 0xae, 0x99, 0x52, 0xc9, 0x35, 0x30, 0x66, 0x52, 0x82, 0x94, 0xf1, 0x88, 0xb2, 0xa8, - 0x0b, 0xa3, 0xe1, 0xa5, 0xe8, 0xe2, 0x52, 0xf4, 0x15, 0xea, 0x10, 0x01, 0x8c, 0x8a, 0x97, 0xa6, - 0x9f, 0xff, 0x78, 0x77, 0x39, 0x19, 0x46, 0xf9, 0x5f, 0xa0, 0x1e, 0x1f, 0x5e, 0x13, 0x33, 0x8f, - 0x12, 0x86, 0xcb, 0x1f, 0x25, 0x30, 0xdf, 0x60, 0xf6, 0x86, 0x87, 0xb2, 0xc7, 0xab, 0x64, 0x93, - 0xfa, 0x2e, 0xe4, 0x0e, 0x25, 0x7d, 0xc6, 0xdc, 0x3d, 0x92, 0x91, 0x7e, 0x23, 0x19, 0xfd, 0x6d, - 0x23, 0xe9, 0xe9, 0xee, 0x7f, 0xf0, 0x5f, 0x5f, 0xfb, 0x69, 0xa3, 0x0f, 0x40, 0x3e, 0x2c, 0x24, - 0xe1, 0x84, 0xe4, 0x6a, 0x4f, 0x4f, 0x75, 0xe5, 0xf3, 0xd1, 0x2b, 0x58, 0x46, 0xc8, 0xc7, 0x8c, - 0xad, 0x73, 0xdf, 0x21, 0x76, 0xda, 0xed, 0xd2, 0xdf, 0x3f, 0xdf, 0x94, 0x72, 0x5d, 0xda, 0x26, - 0xf8, 0x27, 0xa5, 0x4c, 0x74, 0xe4, 0x06, 0x28, 0x58, 0xd4, 0xf5, 0xda, 0x38, 0x54, 0x6f, 0x85, - 0xa1, 0x88, 0x24, 0xa6, 0xaa, 0xea, 0xb1, 0xe7, 0xf7, 0x30, 0x49, 0x4c, 0x7d, 0x32, 0xec, 0x71, - 0xf7, 0x5b, 0x49, 0x6a, 0xce, 0x1c, 0x81, 0xc3, 0xe3, 0xf2, 0x4b, 0x09, 0x14, 0x1a, 0xcc, 0x5e, - 0x25, 0xa1, 0x28, 0xc3, 0xf5, 0x73, 0xba, 0x97, 0x6f, 0x01, 0x00, 0x11, 0x6a, 0x41, 0x97, 0x76, - 0x08, 0x17, 0x81, 0x18, 0xf8, 0x9c, 0xf2, 0x10, 0xa1, 0xe5, 0x08, 0xd1, 0x33, 0xf5, 0x22, 0x98, - 0xeb, 0x31, 0x95, 0xce, 0xf9, 0x55, 0x6c, 0xf8, 0x0e, 0xbe, 0xa0, 0xe1, 0x7b, 0xa0, 0x80, 0x04, - 0xc7, 0x19, 0x5d, 0xcf, 0x24, 0xb8, 0x13, 0xad, 0x6f, 0x45, 0xd6, 0xb3, 0xf6, 0xfe, 0xd0, 0xd5, - 0x55, 0x5f, 0x8f, 0x83, 0xd1, 0x06, 0xb3, 0xe5, 0x17, 0x12, 0x28, 0xf4, 0x7e, 0x76, 0x5d, 0x1b, - 0x9c, 0x84, 0xe3, 0xa1, 0x55, 0x6f, 0x9e, 0x07, 0x95, 0xb6, 0xf7, 0x56, 0x02, 0x6a, 0x9f, 0x9c, - 0xdf, 0x1e, 0x8a, 0xfc, 0x74, 0x02, 0xf5, 0xee, 0x05, 0x09, 0x52, 0xa3, 0x8f, 0xc1, 0x84, 0xc8, - 0xe9, 0x95, 0xe1, 0x28, 0xa3, 0x62, 0xb5, 0x76, 0x86, 0xe2, 0x54, 0xeb, 0x19, 0x98, 0xee, 0xca, - 0x56, 0x65, 0x28, 0x92, 0x2c, 0x44, 0xbd, 0x71, 0x66, 0x48, 0x56, 0xbd, 0x2b, 0x28, 0xc3, 0xa9, - 0x67, 0x21, 0x43, 0xaa, 0x9f, 0xf4, 0xde, 0xeb, 0x6b, 0x7b, 0x07, 0x9a, 0xb4, 0x7f, 0xa0, 0x49, - 0xdf, 0x0f, 0x34, 0x69, 0xf7, 0x50, 0xcb, 0xed, 0x1f, 0x6a, 0xb9, 0x2f, 0x87, 0x5a, 0xee, 0xd1, - 0x75, 0xdb, 0xe1, 0x5b, 0x1d, 0x53, 0xb7, 0xa8, 0x7b, 0xda, 0xb7, 0xf5, 0x76, 0xcd, 0xd8, 0xc9, - 0xfe, 0x4a, 0x09, 0x3c, 0xcc, 0xcc, 0x89, 0x28, 0x20, 0xb5, 0x5f, 0x01, 0x00, 0x00, 0xff, 0xff, - 0x07, 0xd3, 0x20, 0xe4, 0xd6, 0x08, 0x00, 0x00, + // 787 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x56, 0xcf, 0x6b, 0x13, 0x4d, + 0x18, 0xce, 0xa6, 0x69, 0xbf, 0x66, 0x5a, 0x9a, 0xaf, 0x4b, 0xa1, 0x9b, 0xe5, 0x6b, 0x52, 0x02, + 0x1f, 0x5f, 0x3f, 0xc5, 0x5d, 0x92, 0x88, 0x60, 0x11, 0xa5, 0xa9, 0x60, 0x8b, 0x04, 0x6a, 0x6a, + 0x2f, 0x1e, 0x0c, 0x9b, 0x9d, 0xe9, 0x76, 0x25, 0x3b, 0xb3, 0xee, 0x4c, 0x4a, 0x57, 0x3c, 0x09, + 0xde, 0x0b, 0x9e, 0x15, 0x4f, 0x9e, 0x3d, 0x78, 0x13, 0xef, 0xc5, 0x53, 0xf1, 0xe4, 0x49, 0xa5, + 0x3d, 0xe8, 0xc5, 0xff, 0x41, 0x76, 0x77, 0x76, 0xcc, 0x8f, 0x36, 0xd9, 0xb6, 0x9e, 0x92, 0x99, + 0x79, 0xdf, 0xe7, 0x79, 0xde, 0x67, 0xde, 0x77, 0x58, 0xf0, 0x3f, 0xf4, 0x1d, 0x84, 0xa9, 0x4d, + 0xf0, 0x9e, 0xff, 0x44, 0x17, 0x0b, 0x9d, 0xa2, 0xc7, 0x1d, 0x84, 0x4d, 0xe4, 0xe9, 0x6c, 0x4f, + 0x73, 0x3d, 0xc2, 0x88, 0xbc, 0xd8, 0x1d, 0xaa, 0x89, 0x85, 0x26, 0x42, 0xd5, 0xbc, 0x45, 0x88, + 0xd5, 0x46, 0x7a, 0x18, 0xdf, 0xea, 0x6c, 0xeb, 0x06, 0xf6, 0xa3, 0x64, 0x35, 0x6f, 0x12, 0xea, + 0x10, 0xda, 0x0c, 0x57, 0x7a, 0xb4, 0xe0, 0x47, 0x73, 0x16, 0xb1, 0x48, 0xb4, 0x1f, 0xfc, 0xe3, + 0xbb, 0x85, 0x28, 0x46, 0x6f, 0x19, 0x14, 0xe9, 0xbb, 0xe5, 0x16, 0x62, 0x46, 0x59, 0x37, 0x89, + 0x8d, 0xf9, 0x79, 0xb1, 0x9f, 0x8b, 0xd9, 0x0e, 0xa2, 0xcc, 0x70, 0x5c, 0x1e, 0x30, 0xcf, 0x01, + 0x1c, 0x6a, 0xe9, 0xbb, 0xe5, 0xe0, 0x87, 0x1f, 0xe8, 0x23, 0x4b, 0x76, 0x10, 0x33, 0xa0, 0xc1, + 0x8c, 0x28, 0xa1, 0xf4, 0x3e, 0x0d, 0xe4, 0x3a, 0xb5, 0x56, 0x3d, 0x64, 0x30, 0xb4, 0x19, 0x47, + 0xc9, 0x0a, 0xf8, 0xcb, 0x0c, 0xb6, 0x88, 0xa7, 0x48, 0x8b, 0xd2, 0x52, 0xb6, 0x11, 0x2f, 0xe5, + 0x06, 0x98, 0x86, 0xbe, 0x63, 0x63, 0xb6, 0xd1, 0x69, 0xdd, 0x45, 0xbe, 0x92, 0x5e, 0x94, 0x96, + 0xa6, 0x2a, 0x73, 0x5a, 0x24, 0x59, 0x8b, 0x25, 0x6b, 0x2b, 0xd8, 0xaf, 0x29, 0x1f, 0xdf, 0x5d, + 0x99, 0xe3, 0x7e, 0x98, 0x9e, 0xef, 0x32, 0xa2, 0x45, 0x59, 0x8d, 0x1e, 0x0c, 0x79, 0x01, 0x00, + 0x8f, 0xb4, 0xdb, 0x86, 0xeb, 0x36, 0x6d, 0xa8, 0x8c, 0x85, 0x84, 0x59, 0xbe, 0xb3, 0x0e, 0xe5, + 0x2d, 0x30, 0x19, 0xab, 0x56, 0x32, 0x21, 0x5d, 0x55, 0x1b, 0x75, 0x5f, 0x9a, 0xa8, 0xa5, 0xce, + 0x53, 0x6b, 0x99, 0x83, 0x2f, 0xc5, 0x54, 0x43, 0x40, 0xc9, 0x55, 0x90, 0x69, 0x11, 0x0c, 0x95, + 0xf1, 0x10, 0x32, 0xaf, 0x71, 0xa1, 0xc1, 0xa5, 0x68, 0xfc, 0x52, 0xb4, 0x55, 0x62, 0x63, 0x9e, + 0x18, 0x06, 0x2f, 0x4f, 0x3f, 0xfb, 0xfe, 0xf6, 0x52, 0x6c, 0x46, 0xe9, 0x1f, 0xa0, 0x0e, 0x9a, + 0xd7, 0x40, 0xd4, 0x25, 0x98, 0xa2, 0xd2, 0x07, 0x09, 0x2c, 0xd4, 0xa9, 0xb5, 0xe5, 0xc2, 0xee, + 0xe3, 0x75, 0xbc, 0x4d, 0x3c, 0xc7, 0x60, 0x36, 0xc1, 0x43, 0x6c, 0xee, 0xb5, 0x24, 0x3d, 0xcc, + 0x92, 0xb1, 0x3f, 0x66, 0x49, 0x5f, 0x75, 0xff, 0x81, 0x7f, 0x87, 0xca, 0x17, 0x85, 0xde, 0x03, + 0xd9, 0x20, 0x10, 0x07, 0x0e, 0xc9, 0x95, 0xbe, 0x9a, 0x6a, 0xca, 0xa7, 0xdf, 0x5d, 0xb0, 0x02, + 0xa1, 0x87, 0x28, 0xdd, 0x64, 0x9e, 0x8d, 0x2d, 0x51, 0xed, 0xf2, 0xdf, 0x3f, 0x5e, 0x17, 0x53, + 0x3d, 0xdc, 0x3f, 0x25, 0x30, 0x2b, 0x30, 0x63, 0x22, 0xf9, 0x21, 0xc8, 0x77, 0xc2, 0x1d, 0x1b, + 0x5b, 0x4d, 0x93, 0x38, 0x6e, 0x1b, 0x05, 0x42, 0x9a, 0xc1, 0x7c, 0x84, 0x6c, 0x53, 0x15, 0x75, + 0xa0, 0x13, 0xef, 0xc7, 0xc3, 0x53, 0xcb, 0xec, 0x7f, 0x2d, 0x4a, 0x6b, 0xa9, 0xc6, 0xbc, 0x00, + 0x59, 0x15, 0x18, 0x41, 0x94, 0x8c, 0xc0, 0x02, 0x26, 0xcc, 0x36, 0x51, 0xd3, 0x45, 0x9e, 0x4d, + 0xe0, 0x00, 0x47, 0x3a, 0x31, 0x87, 0x1a, 0x01, 0x6d, 0x84, 0x38, 0xbd, 0x34, 0xb5, 0x59, 0x90, + 0xeb, 0x03, 0x2e, 0xbd, 0x90, 0x40, 0xae, 0x4e, 0xad, 0x75, 0x1c, 0x18, 0x40, 0x51, 0xed, 0x9c, + 0x4e, 0xca, 0x37, 0x01, 0x30, 0x20, 0x6c, 0x1a, 0x0e, 0xe9, 0x60, 0xc6, 0xe5, 0x8e, 0x6c, 0xed, + 0xac, 0x01, 0xe1, 0x4a, 0x98, 0xd1, 0xd7, 0x01, 0x79, 0x30, 0xdf, 0x27, 0x4a, 0xdc, 0xf9, 0xcb, + 0x48, 0xf0, 0x6d, 0x74, 0x41, 0xc1, 0x6b, 0x20, 0x07, 0x39, 0xc6, 0x19, 0x55, 0xcf, 0xc4, 0x79, + 0x27, 0x4a, 0xdf, 0x09, 0xa5, 0x77, 0xcb, 0x13, 0x5d, 0x54, 0x1f, 0xb0, 0x3f, 0x41, 0xef, 0x4c, + 0x06, 0x9c, 0xc1, 0xdd, 0x36, 0x66, 0xcc, 0x9e, 0xdb, 0xac, 0xbc, 0x1a, 0x07, 0x63, 0x75, 0x6a, + 0xc9, 0xcf, 0x25, 0x90, 0xeb, 0x7f, 0x47, 0xaf, 0x8e, 0x9e, 0xca, 0xc1, 0x07, 0x44, 0xbd, 0x71, + 0x9e, 0x2c, 0x51, 0xde, 0x1b, 0x09, 0xa8, 0x43, 0xde, 0x9c, 0x5b, 0x89, 0xc0, 0x4f, 0x07, 0x50, + 0xef, 0x5c, 0x10, 0x40, 0x08, 0x7d, 0x04, 0x26, 0xf8, 0x9b, 0x71, 0x39, 0x19, 0x64, 0x18, 0xac, + 0x56, 0xcf, 0x10, 0x2c, 0xb8, 0x9e, 0x82, 0xe9, 0x9e, 0xd9, 0x2a, 0x27, 0x02, 0xe9, 0x4e, 0x51, + 0xaf, 0x9f, 0x39, 0xa5, 0x9b, 0xbd, 0x67, 0x50, 0x92, 0xb1, 0x77, 0xa7, 0x24, 0x64, 0x3f, 0xa9, + 0xdf, 0x6b, 0x1b, 0x07, 0x47, 0x05, 0xe9, 0xf0, 0xa8, 0x20, 0x7d, 0x3b, 0x2a, 0x48, 0xfb, 0xc7, + 0x85, 0xd4, 0xe1, 0x71, 0x21, 0xf5, 0xf9, 0xb8, 0x90, 0x7a, 0x70, 0xcd, 0xb2, 0xd9, 0x4e, 0xa7, + 0xa5, 0x99, 0xc4, 0x39, 0xed, 0xcb, 0x61, 0xb7, 0xaa, 0xef, 0x75, 0x7f, 0x31, 0xf9, 0x2e, 0xa2, + 0xad, 0x89, 0x70, 0x40, 0xaa, 0xbf, 0x02, 0x00, 0x00, 0xff, 0xff, 0xdf, 0x36, 0x33, 0xa3, 0x62, + 0x09, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -1048,17 +1096,56 @@ func (m *MsgUnbondResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l - n5, err5 := github_com_cosmos_gogoproto_types.StdTimeMarshalTo(m.CompletionTime, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdTime(m.CompletionTime):]) - if err5 != nil { - return 0, err5 + if m.CompletionTime != nil { + { + size := m.CompletionTime.Size() + i -= size + if _, err := m.CompletionTime.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + } + } + return len(dAtA) - i, nil +} + +func (m *MsgUnbondResponse_UnbondingCompletionTime) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgUnbondResponse_UnbondingCompletionTime) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.UnbondingCompletionTime != nil { + n5, err5 := github_com_cosmos_gogoproto_types.StdTimeMarshalTo(*m.UnbondingCompletionTime, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdTime(*m.UnbondingCompletionTime):]) + if err5 != nil { + return 0, err5 + } + i -= n5 + i = encodeVarintTx(dAtA, i, uint64(n5)) + i-- + dAtA[i] = 0xa } - i -= n5 - i = encodeVarintTx(dAtA, i, uint64(n5)) - i-- - dAtA[i] = 0xa return len(dAtA) - i, nil } +func (m *MsgUnbondResponse_NoticePeriodCompletionTime) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} +func (m *MsgUnbondResponse_NoticePeriodCompletionTime) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.NoticePeriodCompletionTime != nil { + n6, err6 := github_com_cosmos_gogoproto_types.StdTimeMarshalTo(*m.NoticePeriodCompletionTime, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdTime(*m.NoticePeriodCompletionTime):]) + if err6 != nil { + return 0, err6 + } + i -= n6 + i = encodeVarintTx(dAtA, i, uint64(n6)) + i-- + dAtA[i] = 0x12 + } + return len(dAtA) - i, nil +} func (m *MsgIncreaseBond) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -1182,12 +1269,12 @@ func (m *MsgDecreaseBondResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) _ = i var l int _ = l - n8, err8 := github_com_cosmos_gogoproto_types.StdTimeMarshalTo(m.CompletionTime, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdTime(m.CompletionTime):]) - if err8 != nil { - return 0, err8 + n9, err9 := github_com_cosmos_gogoproto_types.StdTimeMarshalTo(m.CompletionTime, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdTime(m.CompletionTime):]) + if err9 != nil { + return 0, err9 } - i -= n8 - i = encodeVarintTx(dAtA, i, uint64(n8)) + i -= n9 + i = encodeVarintTx(dAtA, i, uint64(n9)) i-- dAtA[i] = 0xa return len(dAtA) - i, nil @@ -1285,11 +1372,36 @@ func (m *MsgUnbondResponse) Size() (n int) { } var l int _ = l - l = github_com_cosmos_gogoproto_types.SizeOfStdTime(m.CompletionTime) - n += 1 + l + sovTx(uint64(l)) + if m.CompletionTime != nil { + n += m.CompletionTime.Size() + } return n } +func (m *MsgUnbondResponse_UnbondingCompletionTime) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.UnbondingCompletionTime != nil { + l = github_com_cosmos_gogoproto_types.SizeOfStdTime(*m.UnbondingCompletionTime) + n += 1 + l + sovTx(uint64(l)) + } + return n +} +func (m *MsgUnbondResponse_NoticePeriodCompletionTime) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.NoticePeriodCompletionTime != nil { + l = github_com_cosmos_gogoproto_types.SizeOfStdTime(*m.NoticePeriodCompletionTime) + n += 1 + l + sovTx(uint64(l)) + } + return n +} func (m *MsgIncreaseBond) Size() (n int) { if m == nil { return 0 @@ -1922,7 +2034,7 @@ func (m *MsgUnbondResponse) Unmarshal(dAtA []byte) error { switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field CompletionTime", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field UnbondingCompletionTime", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -1949,9 +2061,46 @@ func (m *MsgUnbondResponse) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := github_com_cosmos_gogoproto_types.StdTimeUnmarshal(&m.CompletionTime, dAtA[iNdEx:postIndex]); err != nil { + v := new(time.Time) + if err := github_com_cosmos_gogoproto_types.StdTimeUnmarshal(v, dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.CompletionTime = &MsgUnbondResponse_UnbondingCompletionTime{v} + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field NoticePeriodCompletionTime", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := new(time.Time) + if err := github_com_cosmos_gogoproto_types.StdTimeUnmarshal(v, dAtA[iNdEx:postIndex]); err != nil { return err } + m.CompletionTime = &MsgUnbondResponse_NoticePeriodCompletionTime{v} iNdEx = postIndex default: iNdEx = preIndex