From ae2e53e5a15e9e1018e4b9fbfba29982344889bf Mon Sep 17 00:00:00 2001 From: Runchao Han Date: Tue, 1 Oct 2024 08:33:23 +0800 Subject: [PATCH] feat: in-protocol minimum gas price (#107) Resolves https://github.com/babylonlabs-io/pm/issues/49 This PR introduces the in-protocol minimum gas price mechanism, in which the consensus (more specifically the AnteHandler) enforces every tx has to set a gas price at least 0.002 ubbn. The PR also provides relevant tests. The impl closely follows https://github.com/celestiaorg/celestia-app/pull/2985. In addition, this PR creates a new package `app/ante` to abstract out the construction of the AnteHandler for Babylon, following the practice at Celestia. - RFC: https://github.com/babylonlabs-io/pm/pull/56 - ADR: https://github.com/babylonlabs-io/pm/pull/61 --- CHANGELOG.md | 4 + app/ante.go | 24 ----- app/ante/ante.go | 91 ++++++++++++++++ .../ante_btc_validation_decorator.go | 6 +- app/ante/fee_checker.go | 66 ++++++++++++ app/ante/fee_checker_test.go | 100 ++++++++++++++++++ app/ante/get_tx_priority_test.go | 60 +++++++++++ app/app.go | 50 +++------ app/params/config.go | 12 +++ cmd/babylond/cmd/custom_babylon_config.go | 20 +--- test/e2e/btc_staking_e2e_test.go | 15 +-- test/e2e/configurer/chain/commands.go | 4 +- .../configurer/chain/commands_btcstaking.go | 8 +- test/e2e/containers/containers.go | 2 +- test/e2e/initialization/config.go | 2 +- test/e2e/initialization/node.go | 3 +- .../keeper/drop_validator_msg_decorator.go | 4 +- .../drop_validator_msg_decorator_test.go | 2 +- 18 files changed, 380 insertions(+), 93 deletions(-) delete mode 100644 app/ante.go create mode 100644 app/ante/ante.go rename app/{ => ante}/ante_btc_validation_decorator.go (96%) create mode 100644 app/ante/fee_checker.go create mode 100644 app/ante/fee_checker_test.go create mode 100644 app/ante/get_tx_priority_test.go diff --git a/CHANGELOG.md b/CHANGELOG.md index 8db847578..e95dc2d06 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -39,11 +39,15 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) ### State Machine Breaking +* [#107](https://github.com/babylonlabs-io/babylon/pull/107) Implement ADR-027 and +enable in-protocol minimum gas price * [#103](https://github.com/babylonlabs-io/babylon/pull/103) Add token distribution to upgrade handler and rename `signet-launch` to `v1` * [#55](https://github.com/babylonlabs-io/babylon/pull/55) Remove `x/zoneconcierge` module +### Bug fixes + ### Misc Improvements * [#106](https://github.com/babylonlabs-io/babylon/pull/106) Add CLI command for diff --git a/app/ante.go b/app/ante.go deleted file mode 100644 index 1cd6b9dee..000000000 --- a/app/ante.go +++ /dev/null @@ -1,24 +0,0 @@ -package app - -import ( - sdk "github.com/cosmos/cosmos-sdk/types" -) - -// WrappedAnteHandler is the wrapped AnteHandler that implements the `AnteDecorator` interface, which has a single function `AnteHandle`. -// It allows us to chain an existing AnteHandler with other decorators by using `sdk.ChainAnteDecorators`. -type WrappedAnteHandler struct { - ah sdk.AnteHandler -} - -// NewWrappedAnteHandler creates a new WrappedAnteHandler for a given AnteHandler. -func NewWrappedAnteHandler(ah sdk.AnteHandler) WrappedAnteHandler { - return WrappedAnteHandler{ah} -} - -func (wah WrappedAnteHandler) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (newCtx sdk.Context, err error) { - newCtx, err = wah.ah(ctx, tx, simulate) - if err != nil { - return newCtx, err - } - return next(newCtx, tx, simulate) -} diff --git a/app/ante/ante.go b/app/ante/ante.go new file mode 100644 index 000000000..cd7b83a86 --- /dev/null +++ b/app/ante/ante.go @@ -0,0 +1,91 @@ +package ante + +import ( + "cosmossdk.io/core/store" + circuitkeeper "cosmossdk.io/x/circuit/keeper" + txsigning "cosmossdk.io/x/tx/signing" + wasmapp "github.com/CosmWasm/wasmd/app" + wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" + wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" + bbn "github.com/babylonlabs-io/babylon/types" + btcckeeper "github.com/babylonlabs-io/babylon/x/btccheckpoint/keeper" + epochingkeeper "github.com/babylonlabs-io/babylon/x/epoching/keeper" + sdk "github.com/cosmos/cosmos-sdk/types" + authante "github.com/cosmos/cosmos-sdk/x/auth/ante" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + ibckeeper "github.com/cosmos/ibc-go/v8/modules/core/keeper" +) + +// NewAnteHandler creates a new AnteHandler for the Babylon chain. +func NewAnteHandler( + accountKeeper authante.AccountKeeper, + bankKeeper authtypes.BankKeeper, + feegrantKeeper authante.FeegrantKeeper, + signModeHandler *txsigning.HandlerMap, + ibcKeeper *ibckeeper.Keeper, + wasmConfig *wasmtypes.WasmConfig, + wasmKeeper *wasmkeeper.Keeper, + circuitKeeper *circuitkeeper.Keeper, + epochingKeeper *epochingkeeper.Keeper, + btcConfig *bbn.BtcConfig, + btccKeeper *btcckeeper.Keeper, + txCounterStoreService store.KVStoreService, +) sdk.AnteHandler { + // initialize AnteHandler, which includes + // - authAnteHandler + // - custom wasm ante handler NewLimitSimulationGasDecorator and NewCountTXDecorator + // - Extra decorators introduced in Babylon, such as DropValidatorMsgDecorator that delays validator-related messages + // + // We are using constructor from wasmapp as it introduces custom wasm ante handle decorators + // early in chain of ante handlers. + authAnteHandler, err := wasmapp.NewAnteHandler( + wasmapp.HandlerOptions{ + HandlerOptions: authante.HandlerOptions{ + AccountKeeper: accountKeeper, + BankKeeper: bankKeeper, + SignModeHandler: signModeHandler, + FeegrantKeeper: feegrantKeeper, + SigGasConsumer: authante.DefaultSigVerificationGasConsumer, + // CheckTxFeeWithGlobalMinGasPrices will enforce the global minimum + // gas price for all transactions. + TxFeeChecker: CheckTxFeeWithGlobalMinGasPrices, + }, + IBCKeeper: ibcKeeper, + WasmConfig: wasmConfig, + TXCounterStoreService: txCounterStoreService, + WasmKeeper: wasmKeeper, + CircuitKeeper: circuitKeeper, + }, + ) + + if err != nil { + panic(err) + } + + anteHandler := sdk.ChainAnteDecorators( + NewWrappedAnteHandler(authAnteHandler), + epochingkeeper.NewDropValidatorMsgDecorator(epochingKeeper), + NewBtcValidationDecorator(btcConfig, btccKeeper), + ) + + return anteHandler +} + +// WrappedAnteHandler is the wrapped AnteHandler that implements the `AnteDecorator` interface, which has a single function `AnteHandle`. +// It allows us to chain an existing AnteHandler with other decorators by using `sdk.ChainAnteDecorators`. +type WrappedAnteHandler struct { + ah sdk.AnteHandler +} + +// NewWrappedAnteHandler creates a new WrappedAnteHandler for a given AnteHandler. +func NewWrappedAnteHandler(ah sdk.AnteHandler) WrappedAnteHandler { + return WrappedAnteHandler{ah} +} + +func (wah WrappedAnteHandler) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (newCtx sdk.Context, err error) { + newCtx, err = wah.ah(ctx, tx, simulate) + if err != nil { + return newCtx, err + } + return next(newCtx, tx, simulate) +} diff --git a/app/ante_btc_validation_decorator.go b/app/ante/ante_btc_validation_decorator.go similarity index 96% rename from app/ante_btc_validation_decorator.go rename to app/ante/ante_btc_validation_decorator.go index 8e5febfb8..ffe7d21cc 100644 --- a/app/ante_btc_validation_decorator.go +++ b/app/ante/ante_btc_validation_decorator.go @@ -1,4 +1,4 @@ -package app +package ante import ( bbn "github.com/babylonlabs-io/babylon/types" @@ -9,12 +9,12 @@ import ( ) type BtcValidationDecorator struct { - BtcCfg bbn.BtcConfig + BtcCfg *bbn.BtcConfig btccheckpointKeeper *btccheckpointkeeper.Keeper } func NewBtcValidationDecorator( - cfg bbn.BtcConfig, + cfg *bbn.BtcConfig, k *btccheckpointkeeper.Keeper, ) BtcValidationDecorator { return BtcValidationDecorator{ diff --git a/app/ante/fee_checker.go b/app/ante/fee_checker.go new file mode 100644 index 000000000..48118af23 --- /dev/null +++ b/app/ante/fee_checker.go @@ -0,0 +1,66 @@ +package ante + +import ( + "fmt" + + errors "cosmossdk.io/errors" + sdkmath "cosmossdk.io/math" + appparams "github.com/babylonlabs-io/babylon/app/params" + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerror "github.com/cosmos/cosmos-sdk/types/errors" +) + +const ( + // priorityScalingFactor is a scaling factor to convert the gas price to a priority. + priorityScalingFactor = 1_000_000 +) + +// CheckTxFeeWithGlobalMinGasPrices implements the default fee logic, where the minimum price per +// unit of gas is fixed and set globally, and the tx priority is computed from the gas price. +// adapted from https://github.com/celestiaorg/celestia-app/pull/2985 +func CheckTxFeeWithGlobalMinGasPrices(ctx sdk.Context, tx sdk.Tx) (sdk.Coins, int64, error) { + feeTx, ok := tx.(sdk.FeeTx) + if !ok { + return nil, 0, errors.Wrap(sdkerror.ErrTxDecode, "Tx must be a FeeTx") + } + + denom := appparams.DefaultBondDenom + + fee := feeTx.GetFee().AmountOf(denom) + gas := feeTx.GetGas() + + // convert the global minimum gas price to a big.Int + globalMinGasPrice, err := sdkmath.LegacyNewDecFromStr(fmt.Sprintf("%f", appparams.GlobalMinGasPrice)) + if err != nil { + return nil, 0, errors.Wrap(err, "invalid GlobalMinGasPrice") + } + + gasInt := sdkmath.NewIntFromUint64(gas) + minFee := globalMinGasPrice.MulInt(gasInt).RoundInt() + + if !fee.GTE(minFee) { + return nil, 0, errors.Wrapf(sdkerror.ErrInsufficientFee, "insufficient fees; got: %s required: %s", fee, minFee) + } + + priority := getTxPriority(feeTx.GetFee(), int64(gas)) + return feeTx.GetFee(), priority, nil +} + +// getTxPriority returns a naive tx priority based on the amount of the smallest denomination of the gas price +// provided in a transaction. +// NOTE: This implementation should not be used for txs with multiple coins. +func getTxPriority(fee sdk.Coins, gas int64) int64 { + var priority int64 + for _, c := range fee { + p := c.Amount.Mul(sdkmath.NewInt(priorityScalingFactor)).QuoRaw(gas) + if !p.IsInt64() { + continue + } + // take the lowest priority as the tx priority + if priority == 0 || p.Int64() < priority { + priority = p.Int64() + } + } + + return priority +} diff --git a/app/ante/fee_checker_test.go b/app/ante/fee_checker_test.go new file mode 100644 index 000000000..35d025160 --- /dev/null +++ b/app/ante/fee_checker_test.go @@ -0,0 +1,100 @@ +package ante_test + +import ( + "math" + "testing" + + bbnapp "github.com/babylonlabs-io/babylon/app" + "github.com/babylonlabs-io/babylon/app/ante" + appparams "github.com/babylonlabs-io/babylon/app/params" + "github.com/babylonlabs-io/babylon/testutil/datagen" + sdk "github.com/cosmos/cosmos-sdk/types" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + "github.com/stretchr/testify/require" +) + +// TestCheckTxFeeWithGlobalMinGasPrices tests the CheckTxFeeWithGlobalMinGasPrices +// function +// adapted from https://github.com/celestiaorg/celestia-app/pull/2985 +func TestCheckTxFeeWithGlobalMinGasPrices(t *testing.T) { + encCfg := bbnapp.GetEncodingConfig() + + builder := encCfg.TxConfig.NewTxBuilder() + err := builder.SetMsgs( + banktypes.NewMsgSend( + datagen.GenRandomAccount().GetAddress(), + datagen.GenRandomAccount().GetAddress(), + sdk.NewCoins(sdk.NewInt64Coin(appparams.DefaultBondDenom, 10)), + ), + ) + require.NoError(t, err) + + feeAmount := int64(1000) + ctx := sdk.Context{} + + testCases := []struct { + name string + fee sdk.Coins + gasLimit uint64 + appVersion uint64 + expErr bool + }{ + { + name: "bad tx; fee below required minimum", + fee: sdk.NewCoins(sdk.NewInt64Coin(appparams.DefaultBondDenom, feeAmount-1)), + gasLimit: uint64(float64(feeAmount) / appparams.GlobalMinGasPrice), + appVersion: uint64(2), + expErr: true, + }, + { + name: "good tx; fee equal to required minimum", + fee: sdk.NewCoins(sdk.NewInt64Coin(appparams.DefaultBondDenom, feeAmount)), + gasLimit: uint64(float64(feeAmount) / appparams.GlobalMinGasPrice), + appVersion: uint64(2), + expErr: false, + }, + { + name: "good tx; fee above required minimum", + fee: sdk.NewCoins(sdk.NewInt64Coin(appparams.DefaultBondDenom, feeAmount+1)), + gasLimit: uint64(float64(feeAmount) / appparams.GlobalMinGasPrice), + appVersion: uint64(2), + expErr: false, + }, + { + name: "good tx; gas limit and fee are maximum values", + fee: sdk.NewCoins(sdk.NewInt64Coin(appparams.DefaultBondDenom, math.MaxInt64)), + gasLimit: math.MaxUint64, + appVersion: uint64(2), + expErr: false, + }, + { + name: "bad tx; gas limit and fee are 0", + fee: sdk.NewCoins(sdk.NewInt64Coin(appparams.DefaultBondDenom, 0)), + gasLimit: 0, + appVersion: uint64(2), + expErr: false, + }, + { + name: "good tx; minFee = 0.8, rounds up to 1", + fee: sdk.NewCoins(sdk.NewInt64Coin(appparams.DefaultBondDenom, feeAmount)), + gasLimit: 400, + appVersion: uint64(2), + expErr: false, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + builder.SetGasLimit(tc.gasLimit) + builder.SetFeeAmount(tc.fee) + tx := builder.GetTx() + + _, _, err := ante.CheckTxFeeWithGlobalMinGasPrices(ctx, tx) + if tc.expErr { + require.Error(t, err) + } else { + require.NoError(t, err) + } + }) + } +} diff --git a/app/ante/get_tx_priority_test.go b/app/ante/get_tx_priority_test.go new file mode 100644 index 000000000..d4859dd14 --- /dev/null +++ b/app/ante/get_tx_priority_test.go @@ -0,0 +1,60 @@ +package ante + +import ( + "testing" + + appparams "github.com/babylonlabs-io/babylon/app/params" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/stretchr/testify/assert" +) + +// TestGetTxPriority tests the getTxPriority function +// adapted from https://github.com/celestiaorg/celestia-app/pull/2985 +func TestGetTxPriority(t *testing.T) { + denom := appparams.DefaultBondDenom + + cases := []struct { + name string + fee sdk.Coins + gas int64 + expectedPri int64 + }{ + { + name: "1 bbn fee large gas", + fee: sdk.NewCoins(sdk.NewInt64Coin(denom, 1_000_000)), + gas: 1000000, + expectedPri: 1000000, + }, + { + name: "1 ubbn fee small gas", + fee: sdk.NewCoins(sdk.NewInt64Coin(denom, 1)), + gas: 1, + expectedPri: 1000000, + }, + { + name: "2 ubbn fee small gas", + fee: sdk.NewCoins(sdk.NewInt64Coin(denom, 2)), + gas: 1, + expectedPri: 2000000, + }, + { + name: "1_000_000 bbn fee normal gas tx", + fee: sdk.NewCoins(sdk.NewInt64Coin(denom, 1_000_000_000_000)), + gas: 75000, + expectedPri: 13333333333333, + }, + { + name: "0.001 ubbn gas price", + fee: sdk.NewCoins(sdk.NewInt64Coin(denom, 1_000)), + gas: 1_000_000, + expectedPri: 1000, + }, + } + + for _, tc := range cases { + t.Run(tc.name, func(t *testing.T) { + pri := getTxPriority(tc.fee, tc.gas) + assert.Equal(t, tc.expectedPri, pri) + }) + } +} diff --git a/app/app.go b/app/app.go index f0f740fae..601f0edac 100644 --- a/app/app.go +++ b/app/app.go @@ -20,7 +20,6 @@ import ( feegrantmodule "cosmossdk.io/x/feegrant/module" "cosmossdk.io/x/upgrade" upgradetypes "cosmossdk.io/x/upgrade/types" - wasmapp "github.com/CosmWasm/wasmd/app" "github.com/CosmWasm/wasmd/x/wasm" wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" @@ -47,7 +46,6 @@ import ( "github.com/cosmos/cosmos-sdk/types/msgservice" "github.com/cosmos/cosmos-sdk/version" "github.com/cosmos/cosmos-sdk/x/auth" - "github.com/cosmos/cosmos-sdk/x/auth/ante" authcodec "github.com/cosmos/cosmos-sdk/x/auth/codec" authsims "github.com/cosmos/cosmos-sdk/x/auth/simulation" authtx "github.com/cosmos/cosmos-sdk/x/auth/tx" @@ -93,6 +91,7 @@ import ( ibctm "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint" "github.com/spf13/cast" + "github.com/babylonlabs-io/babylon/app/ante" "github.com/babylonlabs-io/babylon/app/upgrades" bbn "github.com/babylonlabs-io/babylon/types" @@ -108,7 +107,6 @@ import ( "github.com/babylonlabs-io/babylon/x/checkpointing" checkpointingtypes "github.com/babylonlabs-io/babylon/x/checkpointing/types" "github.com/babylonlabs-io/babylon/x/epoching" - epochingkeeper "github.com/babylonlabs-io/babylon/x/epoching/keeper" epochingtypes "github.com/babylonlabs-io/babylon/x/epoching/types" "github.com/babylonlabs-io/babylon/x/finality" finalitytypes "github.com/babylonlabs-io/babylon/x/finality/types" @@ -471,38 +469,20 @@ func NewBabylonApp( app.MountTransientStores(app.GetTransientStoreKeys()) app.MountMemoryStores(app.GetMemoryStoreKeys()) - // initialize AnteHandler, which includes - // - authAnteHandler - // - custom wasm ante handler NewLimitSimulationGasDecorator and NewCountTXDecorator - // - Extra decorators introduced in Babylon, such as DropValidatorMsgDecorator that delays validator-related messages - // - // We are using constructor from wasmapp as it introduces custom wasm ante handle decorators - // early in chain of ante handlers. - authAnteHandler, err := wasmapp.NewAnteHandler( - wasmapp.HandlerOptions{ - HandlerOptions: ante.HandlerOptions{ - AccountKeeper: app.AccountKeeper, - BankKeeper: app.BankKeeper, - SignModeHandler: txConfig.SignModeHandler(), - FeegrantKeeper: app.FeeGrantKeeper, - SigGasConsumer: ante.DefaultSigVerificationGasConsumer, - }, - IBCKeeper: app.IBCKeeper, - WasmConfig: &wasmConfig, - TXCounterStoreService: runtime.NewKVStoreService(app.AppKeepers.GetKey(wasmtypes.StoreKey)), - WasmKeeper: &app.WasmKeeper, - CircuitKeeper: &app.CircuitKeeper, - }, - ) - - if err != nil { - panic(err) - } - - anteHandler := sdk.ChainAnteDecorators( - NewWrappedAnteHandler(authAnteHandler), - epochingkeeper.NewDropValidatorMsgDecorator(app.EpochingKeeper), - NewBtcValidationDecorator(btcConfig, &app.BtcCheckpointKeeper), + // initialize AnteHandler for the app + anteHandler := ante.NewAnteHandler( + &app.AccountKeeper, + app.BankKeeper, + &app.FeeGrantKeeper, + txConfig.SignModeHandler(), + app.IBCKeeper, + &wasmConfig, + &app.WasmKeeper, + &app.CircuitKeeper, + &app.EpochingKeeper, + &btcConfig, + &app.BtcCheckpointKeeper, + runtime.NewKVStoreService(app.AppKeepers.GetKey(wasmtypes.StoreKey)), ) // set proposal extension diff --git a/app/params/config.go b/app/params/config.go index 3d4322677..222752e95 100644 --- a/app/params/config.go +++ b/app/params/config.go @@ -20,6 +20,18 @@ const ( Bech32PrefixAccAddr = "bbn" ) +// taken from https://github.com/celestiaorg/celestia-app/pull/2985 +const ( + // DefaultMinGasPrice is the default min gas price that gets set in the app.toml file. + // The min gas price acts as a filter. Transactions below that limit will not pass + // a nodes `CheckTx` and thus not be proposed by that node. + DefaultMinGasPrice = 0.002 + + // GlobalMinGasPrice is used in the AnteHandler to ensure + // that all transactions have a gas price greater than or equal to this value. + GlobalMinGasPrice = DefaultMinGasPrice +) + var ( // Bech32PrefixAccPub defines the Bech32 prefix of an account's public key. Bech32PrefixAccPub = Bech32PrefixAccAddr + "pub" diff --git a/cmd/babylond/cmd/custom_babylon_config.go b/cmd/babylond/cmd/custom_babylon_config.go index 6b4e6c9f9..6e4c4dfc2 100644 --- a/cmd/babylond/cmd/custom_babylon_config.go +++ b/cmd/babylond/cmd/custom_babylon_config.go @@ -1,11 +1,11 @@ package cmd import ( + "fmt" + wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" - sdkmath "cosmossdk.io/math" serverconfig "github.com/cosmos/cosmos-sdk/server/config" - sdk "github.com/cosmos/cosmos-sdk/types" appparams "github.com/babylonlabs-io/babylon/app/params" bbn "github.com/babylonlabs-io/babylon/types" @@ -31,19 +31,9 @@ type BabylonAppConfig struct { func DefaultBabylonAppConfig() *BabylonAppConfig { baseConfig := *serverconfig.DefaultConfig() - // The SDK's default minimum gas price is set to "" (empty value) inside - // app.toml. If left empty by validators, the node will halt on startup. - // However, the chain developer can set a default app.toml value for their - // validators here. - // - // In summary: - // - if you leave srvCfg.MinGasPrices = "", all validators MUST tweak their - // own app.toml config, - // - if you set srvCfg.MinGasPrices non-empty, validators CAN tweak their - // own app.toml to override, or use this default value. - // - // In app, we set the min gas prices to 0. - baseConfig.MinGasPrices = sdk.NewCoin(appparams.BaseCoinUnit, sdkmath.NewInt(1)).String() + // The SDK's default minimum gas price is set to "0.002ubbn" (empty value) inside + // app.toml, in order to avoid spamming attacks due to transactions with 0 gas price. + baseConfig.MinGasPrices = fmt.Sprintf("%f%s", appparams.GlobalMinGasPrice, appparams.BaseCoinUnit) return &BabylonAppConfig{ Config: baseConfig, Wasm: wasmtypes.DefaultWasmConfig(), diff --git a/test/e2e/btc_staking_e2e_test.go b/test/e2e/btc_staking_e2e_test.go index d73a7757d..eaf5b725d 100644 --- a/test/e2e/btc_staking_e2e_test.go +++ b/test/e2e/btc_staking_e2e_test.go @@ -15,6 +15,7 @@ import ( sdkmath "cosmossdk.io/math" feegrantcli "cosmossdk.io/x/feegrant/client/cli" + appparams "github.com/babylonlabs-io/babylon/app/params" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/babylonlabs-io/babylon/app/params" @@ -553,7 +554,6 @@ func (s *BTCStakingTestSuite) Test7BTCDelegationFeeGrant() { granteeStakerAddr := sdk.MustAccAddressFromBech32(nonValidatorNode.KeysAdd(wGratee)) feePayerBalanceBeforeBTCDel := sdk.NewCoin(params.DefaultBondDenom, sdkmath.NewInt(100000)) - fees := sdk.NewCoin(params.DefaultBondDenom, sdkmath.NewInt(50000)) // fund the granter nonValidatorNode.BankSendFromNode(feePayerAddr.String(), feePayerBalanceBeforeBTCDel.String()) @@ -604,7 +604,6 @@ func (s *BTCStakingTestSuite) Test7BTCDelegationFeeGrant() { wGratee, false, fmt.Sprintf("--fee-granter=%s", feePayerAddr.String()), - fmt.Sprintf("--fees=%s", fees.String()), ) // wait for a block so that above txs take effect @@ -621,10 +620,10 @@ func (s *BTCStakingTestSuite) Test7BTCDelegationFeeGrant() { s.NoError(err) s.True(stakerBalances.IsZero()) - // the fee payer should have the (feePayerBalanceBeforeBTCDel - fee) == currentBalance + // the fee payer should have the feePayerBalanceBeforeBTCDel > currentBalance feePayerBalances, err := nonValidatorNode.QueryBalances(feePayerAddr.String()) s.NoError(err) - s.Equal(feePayerBalanceBeforeBTCDel.Sub(fees).String(), feePayerBalances.String()) + s.True(feePayerBalanceBeforeBTCDel.Amount.GT(feePayerBalances.AmountOf(appparams.BaseCoinUnit))) } // Test8BTCDelegationFeeGrantTyped is an end-to-end test to create a BTC delegation @@ -738,7 +737,6 @@ func (s *BTCStakingTestSuite) Test8BTCDelegationFeeGrantTyped() { wGratee, false, fmt.Sprintf("--fee-granter=%s", feePayerAddr.String()), - fmt.Sprintf("--fees=%s", fees.String()), ) // wait for a block so that above txs take effect @@ -755,10 +753,10 @@ func (s *BTCStakingTestSuite) Test8BTCDelegationFeeGrantTyped() { s.NoError(err) s.Equal(stakerBalance.String(), stakerBalances.String()) - // the fee payer should have the (feePayerBalanceBeforeBTCDel - fee) == currentBalance + // the fee payer should have the feePayerBalanceBeforeBTCDel > currentBalance feePayerBalances, err := node.QueryBalances(feePayerAddr.String()) s.NoError(err) - s.Equal(feePayerBalanceBeforeBTCDel.Sub(fees).String(), feePayerBalances.String()) + s.True(feePayerBalanceBeforeBTCDel.Amount.GT(feePayerBalances.AmountOf(appparams.BaseCoinUnit))) } // ParseRespsBTCDelToBTCDel parses an BTC delegation response to BTC Delegation @@ -867,6 +865,9 @@ func (s *BTCStakingTestSuite) CreateNodeFP(node *chain.NodeConfig) (newFP *bstyp newFP, err = datagen.GenRandomFinalityProviderWithBTCBabylonSKs(r, fpBTCSK, nodeAddr) s.NoError(err) + // use a higher commission to ensure the reward is more than tx fee of a finality sig + commission := sdkmath.LegacyNewDecWithPrec(20, 2) + newFP.Commission = &commission node.CreateFinalityProvider(newFP.Addr, newFP.BtcPk, newFP.Pop, newFP.Description.Moniker, newFP.Description.Identity, newFP.Description.Website, newFP.Description.SecurityContact, newFP.Description.Details, newFP.Commission) // wait for a block so that above txs take effect diff --git a/test/e2e/configurer/chain/commands.go b/test/e2e/configurer/chain/commands.go index feca59645..73c6e1889 100644 --- a/test/e2e/configurer/chain/commands.go +++ b/test/e2e/configurer/chain/commands.go @@ -258,7 +258,7 @@ func (n *NodeConfig) FinalizeSealedEpochs(startEpoch uint64, lastEpoch uint64) { func (n *NodeConfig) StoreWasmCode(wasmFile, from string) { n.LogActionF("storing wasm code from file %s", wasmFile) - cmd := []string{"babylond", "tx", "wasm", "store", wasmFile, fmt.Sprintf("--from=%s", from), "--gas=auto", "--gas-prices=1ubbn", "--gas-adjustment=1.3"} + cmd := []string{"babylond", "tx", "wasm", "store", wasmFile, fmt.Sprintf("--from=%s", from), "--gas=auto", "--gas-adjustment=1.3"} n.LogActionF(strings.Join(cmd, " ")) _, _, err := n.containerManager.ExecTxCmd(n.t, n.chainId, n.Name, cmd) require.NoError(n.t, err) @@ -267,7 +267,7 @@ func (n *NodeConfig) StoreWasmCode(wasmFile, from string) { func (n *NodeConfig) InstantiateWasmContract(codeId, initMsg, from string) { n.LogActionF("instantiating wasm contract %s with %s", codeId, initMsg) - cmd := []string{"babylond", "tx", "wasm", "instantiate", codeId, initMsg, fmt.Sprintf("--from=%s", from), "--no-admin", "--label=contract", "--gas=auto", "--gas-prices=1ubbn", "--gas-adjustment=1.3"} + cmd := []string{"babylond", "tx", "wasm", "instantiate", codeId, initMsg, fmt.Sprintf("--from=%s", from), "--no-admin", "--label=contract", "--gas=auto", "--gas-adjustment=1.3"} n.LogActionF(strings.Join(cmd, " ")) _, _, err := n.containerManager.ExecTxCmd(n.t, n.chainId, n.Name, cmd) require.NoError(n.t, err) diff --git a/test/e2e/configurer/chain/commands_btcstaking.go b/test/e2e/configurer/chain/commands_btcstaking.go index f7586d812..a6469982a 100644 --- a/test/e2e/configurer/chain/commands_btcstaking.go +++ b/test/e2e/configurer/chain/commands_btcstaking.go @@ -98,9 +98,15 @@ func (n *NodeConfig) CreateBTCDelegation( n.FlagChainID(), "--log_format=json", } + // gas price + cmd = append(cmd, "--gas-prices=0.002ubbn") + if generateOnly { cmd = append(cmd, "--generate-only") } else { + // gas + cmd = append(cmd, "--gas=auto", "--gas-adjustment=1.3") + // broadcast stuff cmd = append(cmd, "-b=sync", "--yes") } @@ -137,7 +143,7 @@ func (n *NodeConfig) AddCovenantSigs(covPK *bbn.BIP340PubKey, stakingTxHash stri // used key cmd = append(cmd, "--from=val") // gas - cmd = append(cmd, "--gas=auto", "--gas-prices=1ubbn", "--gas-adjustment=1.3") + cmd = append(cmd, "--gas=auto", "--gas-adjustment=1.3") _, _, err := n.containerManager.ExecTxCmd(n.t, n.chainId, n.Name, cmd) require.NoError(n.t, err) diff --git a/test/e2e/containers/containers.go b/test/e2e/containers/containers.go index cd09f1aec..62929b300 100644 --- a/test/e2e/containers/containers.go +++ b/test/e2e/containers/containers.go @@ -69,7 +69,7 @@ func (m *Manager) ExecTxCmd(t *testing.T, chainId string, nodeName string, comma // namely adding flags `--chain-id={chain-id} -b=block --yes --keyring-backend=test "--log_format=json"`, // and searching for `successStr` func (m *Manager) ExecTxCmdWithSuccessString(t *testing.T, chainId string, containerName string, command []string, successStr string) (bytes.Buffer, bytes.Buffer, error) { - allTxArgs := []string{fmt.Sprintf("--chain-id=%s", chainId), "-b=sync", "--yes", "--keyring-backend=test", "--log_format=json", "--home=/home/babylon/babylondata"} + allTxArgs := []string{fmt.Sprintf("--chain-id=%s", chainId), "--gas-prices=0.002ubbn", "-b=sync", "--yes", "--keyring-backend=test", "--log_format=json", "--home=/home/babylon/babylondata"} txCommand := append(command, allTxArgs...) return m.ExecCmd(t, containerName, txCommand, successStr) } diff --git a/test/e2e/initialization/config.go b/test/e2e/initialization/config.go index e01be3ee4..31b876ac2 100644 --- a/test/e2e/initialization/config.go +++ b/test/e2e/initialization/config.go @@ -50,7 +50,7 @@ type NodeConfig struct { const ( // common BabylonDenom = "ubbn" - MinGasPrice = "0.000" + MinGasPrice = "0.002" ValidatorWalletName = "val" BabylonOpReturnTag = "01020304" diff --git a/test/e2e/initialization/node.go b/test/e2e/initialization/node.go index b43ba62b0..dea6df497 100644 --- a/test/e2e/initialization/node.go +++ b/test/e2e/initialization/node.go @@ -32,6 +32,7 @@ import ( "github.com/spf13/viper" babylonApp "github.com/babylonlabs-io/babylon/app" + appparams "github.com/babylonlabs-io/babylon/app/params" "github.com/babylonlabs-io/babylon/cmd/babylond/cmd" "github.com/babylonlabs-io/babylon/crypto/bls12381" "github.com/babylonlabs-io/babylon/privval" @@ -396,7 +397,7 @@ func (n *internalNode) signMsg(msgs ...sdk.Msg) (*sdktx.Tx, error) { } txBuilder.SetMemo(fmt.Sprintf("%s@%s:26656", n.nodeKey.ID(), n.moniker)) - txBuilder.SetFeeAmount(sdk.NewCoins()) + txBuilder.SetFeeAmount(sdk.NewCoins(sdk.NewCoin(appparams.DefaultBondDenom, math.NewInt(20000)))) txBuilder.SetGasLimit(uint64(200000 * len(msgs))) addr, err := n.keyInfo.GetAddress() diff --git a/x/epoching/keeper/drop_validator_msg_decorator.go b/x/epoching/keeper/drop_validator_msg_decorator.go index c6261b1e3..7ab644b7f 100644 --- a/x/epoching/keeper/drop_validator_msg_decorator.go +++ b/x/epoching/keeper/drop_validator_msg_decorator.go @@ -8,11 +8,11 @@ import ( // DropValidatorMsgDecorator defines an AnteHandler decorator that rejects all messages that might change the validator set. type DropValidatorMsgDecorator struct { - ek Keeper + ek *Keeper } // NewDropValidatorMsgDecorator creates a new DropValidatorMsgDecorator -func NewDropValidatorMsgDecorator(ek Keeper) *DropValidatorMsgDecorator { +func NewDropValidatorMsgDecorator(ek *Keeper) *DropValidatorMsgDecorator { return &DropValidatorMsgDecorator{ ek: ek, } diff --git a/x/epoching/keeper/drop_validator_msg_decorator_test.go b/x/epoching/keeper/drop_validator_msg_decorator_test.go index a6411e373..0880f9462 100644 --- a/x/epoching/keeper/drop_validator_msg_decorator_test.go +++ b/x/epoching/keeper/drop_validator_msg_decorator_test.go @@ -24,7 +24,7 @@ func TestDropValidatorMsgDecorator(t *testing.T) { {&stakingtypes.MsgEditValidator{}, false}, } - decorator := NewDropValidatorMsgDecorator(Keeper{}) + decorator := NewDropValidatorMsgDecorator(&Keeper{}) for _, tc := range testCases { res := decorator.IsValidatorRelatedMsg(tc.msg)