-
Notifications
You must be signed in to change notification settings - Fork 8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: in-protocol minimum gas price #107
Merged
Merged
Changes from 6 commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
1b2422e
new ante module
SebastianElvis 93aa77a
fee checker and tests
SebastianElvis 4c746ac
changelog and gas price
SebastianElvis 81ab31d
fix fee grant e2e
SebastianElvis 2acf2b6
fix fp commission
SebastianElvis 716de24
Merge branch 'main' into feat/in-protocol-min-gas-price
SebastianElvis 8733934
Merge branch 'main' into feat/in-protocol-min-gas-price
SebastianElvis 1cdb4da
Merge branch 'main' into feat/in-protocol-min-gas-price
SebastianElvis 084a934
fix default min gas price
SebastianElvis File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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) | ||
} | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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) | ||
}) | ||
} | ||
} |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NOTE: this is the place where min gas price is enforced