From 6e0cfe9c271155c160b4680082edc03066d6345f Mon Sep 17 00:00:00 2001 From: Jeremy Wei Date: Thu, 26 Sep 2024 16:18:10 -0400 Subject: [PATCH] EIP-1559 - Dynamic Base Fee (#1843) * initial impl * remove libjs changes * fix some broken tests * fix some more tests * fix some more tests * fix test * fix test * fix test * fix test * fix test * change BaseFee Set and Get to use sdk.Dec instead of float * fix test * fix test * reset base fee after fee_test * don't burn base fee * fix * fix * fix * fix * fix * try to fix blocktests * fix block test and hopefully dont break other tests * skip some failing block tests * skip some failing block tests * fix test * applyEVMMessageNoBaseFee for CallEVM * cleanup prints * comment out failing wasmd precompile test * fix * adjust block base fee on next height * fix * fix wasm integration precompile test * fix loadtest client * update params.proto * update params.pb.go * new params for upward and downward adjustment * incorporate new params * fix * fix * fix failing unit tests * add migration handlers * bump consensus version * add upgrade version for testing purposes (revert later) * add upgrade version for testing purposes (revert later) * Revert "add upgrade version for testing purposes (revert later)" This reverts commit 30a474d0997122bb418bec8a1db435f576677b62. * Revert "add upgrade version for testing purposes (revert later)" This reverts commit b3bfc7680a2fa7bb05f694bebb9df0c09db7274b. * some fixes, check if all tests still pass * address comments * address more comments * bump geth version * fix previous commit - regenerate params proto * fix tests * bump geth after merge and max up/down 0% * fix TestAdjustBaseFeePerGas * revert burn base fee changes on geth --- aclmapping/evm/mappings_test.go | 1 + app/app.go | 9 +- app/eth_replay.go | 1 + evmrpc/block.go | 6 +- evmrpc/block_test.go | 4 +- evmrpc/info.go | 14 +- evmrpc/info_test.go | 18 +- evmrpc/setup_test.go | 2 +- evmrpc/simulate.go | 2 +- evmrpc/simulate_test.go | 4 +- evmrpc/tx_test.go | 2 +- go.mod | 4 +- go.sum | 8 +- loadtest/evm.go | 9 +- occ_tests/messages/test_msgs.go | 4 +- precompiles/pointer/pointer_test.go | 2 +- proto/evm/params.proto | 56 +++++- run_blocktests.sh | 5 + x/evm/ante/fee.go | 6 +- x/evm/genesis_test.go | 2 + x/evm/keeper/evm.go | 1 + x/evm/keeper/evm_test.go | 4 + x/evm/keeper/fee.go | 63 +++++++ x/evm/keeper/fee_test.go | 81 +++++++++ x/evm/keeper/keeper.go | 6 +- x/evm/keeper/msg_server.go | 2 + x/evm/keeper/msg_server_test.go | 14 +- x/evm/keeper/params.go | 8 + x/evm/keeper/params_test.go | 4 +- x/evm/keeper/replay.go | 9 + x/evm/migrations/migrate_eip_1559_params.go | 15 ++ .../migrate_eip_1559_params_test.go | 29 +++ x/evm/module.go | 9 +- x/evm/module_test.go | 4 +- x/evm/types/keys.go | 1 + x/evm/types/params.go | 39 +++- x/evm/types/params.pb.go | 166 ++++++++++++++---- x/evm/types/params_test.go | 31 +++- 38 files changed, 551 insertions(+), 94 deletions(-) create mode 100644 x/evm/keeper/fee.go create mode 100644 x/evm/keeper/fee_test.go create mode 100644 x/evm/migrations/migrate_eip_1559_params.go create mode 100644 x/evm/migrations/migrate_eip_1559_params_test.go diff --git a/aclmapping/evm/mappings_test.go b/aclmapping/evm/mappings_test.go index fb56460aa..397431206 100644 --- a/aclmapping/evm/mappings_test.go +++ b/aclmapping/evm/mappings_test.go @@ -126,6 +126,7 @@ func (suite *KeeperTestSuite) TestMsgEVMTransaction() { ctx, err := suite.preprocessor.AnteHandle(handlerCtx, tx.GetTx(), false, func(ctx sdk.Context, _ sdk.Tx, _ bool) (sdk.Context, error) { return ctx, nil }) suite.Require().Nil(err) cms.ResetEvents() + suite.App.EvmKeeper.SetDynamicBaseFeePerGas(ctx, sdk.ZeroDec()) _, err = suite.msgServer.EVMTransaction(sdk.WrapSDKContext(ctx), tc.msg) suite.Require().Nil(err) diff --git a/app/app.go b/app/app.go index 580aef2d4..a159cfd56 100644 --- a/app/app.go +++ b/app/app.go @@ -1599,8 +1599,15 @@ func (app *App) ProcessBlock(ctx sdk.Context, txs [][]byte, req BlockProcessRequ lazyWriteEvents := app.BankKeeper.WriteDeferredBalances(ctx) events = append(events, lazyWriteEvents...) + // Sum up total used per block + blockTotalGasUsed := int64(0) + for _, txResult := range txResults { + blockTotalGasUsed += txResult.GasUsed + } + endBlockResp := app.EndBlock(ctx, abci.RequestEndBlock{ - Height: req.GetHeight(), + Height: req.GetHeight(), + BlockGasUsed: blockTotalGasUsed, }) events = append(events, endBlockResp.Events...) diff --git a/app/eth_replay.go b/app/eth_replay.go index d63a3f1dd..780267b9d 100644 --- a/app/eth_replay.go +++ b/app/eth_replay.go @@ -141,6 +141,7 @@ func BlockTest(a *App, bt *ethtests.BlockTest) { } params := a.EvmKeeper.GetParams(a.GetContextForDeliverTx([]byte{})) params.MinimumFeePerGas = sdk.NewDecFromInt(sdk.NewInt(0)) + // params.BaseFeePerGas = sdk.NewDecFromInt(sdk.NewInt(0)) a.EvmKeeper.SetParams(a.GetContextForDeliverTx([]byte{}), params) } diff --git a/evmrpc/block.go b/evmrpc/block.go index 789275fb5..51e15fda7 100644 --- a/evmrpc/block.go +++ b/evmrpc/block.go @@ -79,7 +79,7 @@ func (a *BlockAPI) getBlockByHash(ctx context.Context, blockHash common.Hash, fu return nil, err } blockBloom := a.keeper.GetBlockBloom(a.ctxProvider(block.Block.Height)) - return EncodeTmBlock(a.ctxProvider(LatestCtxHeight), block, blockRes, blockBloom, a.keeper, a.txConfig.TxDecoder(), fullTx, a.includeSyntheticTxs) + return EncodeTmBlock(a.ctxProvider(block.Block.Height), block, blockRes, blockBloom, a.keeper, a.txConfig.TxDecoder(), fullTx, a.includeSyntheticTxs) } func (a *BlockAPI) GetBlockByNumber(ctx context.Context, number rpc.BlockNumber, fullTx bool) (result map[string]interface{}, returnErr error) { @@ -127,7 +127,7 @@ func (a *BlockAPI) getBlockByNumber(ctx context.Context, number rpc.BlockNumber, return nil, err } blockBloom := a.keeper.GetBlockBloom(a.ctxProvider(block.Block.Height)) - return EncodeTmBlock(a.ctxProvider(LatestCtxHeight), block, blockRes, blockBloom, a.keeper, a.txConfig.TxDecoder(), fullTx, a.includeSyntheticTxs) + return EncodeTmBlock(a.ctxProvider(block.Block.Height), block, blockRes, blockBloom, a.keeper, a.txConfig.TxDecoder(), fullTx, a.includeSyntheticTxs) } func (a *BlockAPI) GetBlockReceipts(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (result []map[string]interface{}, returnErr error) { @@ -215,7 +215,7 @@ func EncodeTmBlock( txHash := common.HexToHash(block.Block.DataHash.String()) resultHash := common.HexToHash(block.Block.LastResultsHash.String()) miner := common.HexToAddress(block.Block.ProposerAddress.String()) - baseFeePerGas := k.GetBaseFeePerGas(ctx).TruncateInt().BigInt() + baseFeePerGas := k.GetDynamicBaseFeePerGas(ctx).TruncateInt().BigInt() var blockGasUsed int64 chainConfig := types.DefaultChainConfig().EthereumConfig(k.ChainID(ctx)) transactions := []interface{}{} diff --git a/evmrpc/block_test.go b/evmrpc/block_test.go index 1a4c76d0f..d4f5d6505 100644 --- a/evmrpc/block_test.go +++ b/evmrpc/block_test.go @@ -167,7 +167,7 @@ func verifyBlockResult(t *testing.T, resObj map[string]interface{}) { require.Equal(t, "0x0000000000000000000000000000000000000000000000000000000000000001", tx["blockHash"]) require.Equal(t, "0x5b4eba929f3811980f5ae0c5d04fa200f837df4e", tx["from"]) require.Equal(t, "0x3e8", tx["gas"]) - require.Equal(t, "0x0", tx["gasPrice"]) + require.Equal(t, "0xa", tx["gasPrice"]) require.Equal(t, "0xa", tx["maxFeePerGas"]) require.Equal(t, "0x0", tx["maxPriorityFeePerGas"]) require.Equal(t, "0xf02362077ac075a397344172496b28e913ce5294879d811bb0269b3be20a872e", tx["hash"]) @@ -185,7 +185,7 @@ func verifyBlockResult(t *testing.T, resObj map[string]interface{}) { require.Equal(t, "0x0", tx["yParity"]) require.Equal(t, "0x0000000000000000000000000000000000000000000000000000000000000002", resObj["transactionsRoot"]) require.Equal(t, []interface{}{}, resObj["uncles"]) - require.Equal(t, "0x0", resObj["baseFeePerGas"]) + require.Equal(t, "0x174876e800", resObj["baseFeePerGas"]) require.Equal(t, "0x0", resObj["totalDifficulty"]) } diff --git a/evmrpc/info.go b/evmrpc/info.go index d79526103..5b7badb8f 100644 --- a/evmrpc/info.go +++ b/evmrpc/info.go @@ -80,12 +80,15 @@ func (i *InfoAPI) GasPrice(ctx context.Context) (result *hexutil.Big, returnErr } if len(feeHist.Reward) == 0 || len(feeHist.Reward[0]) == 0 { // if there is no EVM tx in the most recent block, return the minimum fee param - return (*hexutil.Big)(i.keeper.GetMinimumFeePerGas(i.ctxProvider(LatestCtxHeight)).TruncateInt().BigInt()), nil + baseFee := i.keeper.GetMinimumFeePerGas(i.ctxProvider(LatestCtxHeight)).TruncateInt().BigInt() + return (*hexutil.Big)(baseFee), nil } - return (*hexutil.Big)(new(big.Int).Add( + baseFee := i.keeper.GetDynamicBaseFeePerGas(i.ctxProvider(LatestCtxHeight)).TruncateInt().BigInt() + sum := new(big.Int).Add( feeHist.Reward[0][0].ToInt(), - i.keeper.GetBaseFeePerGas(i.ctxProvider(LatestCtxHeight)).TruncateInt().BigInt(), - )), nil + baseFee, + ) + return (*hexutil.Big)(sum), nil } // lastBlock is inclusive @@ -195,7 +198,8 @@ func (i *InfoAPI) safeGetBaseFee(targetHeight int64) (res *big.Int) { res = nil } }() - res = i.keeper.GetBaseFeePerGas(i.ctxProvider(targetHeight)).BigInt() + baseFee := i.keeper.GetDynamicBaseFeePerGas(i.ctxProvider(targetHeight)) + res = baseFee.TruncateInt().BigInt() return } diff --git a/evmrpc/info_test.go b/evmrpc/info_test.go index b56f9e2c6..e92769717 100644 --- a/evmrpc/info_test.go +++ b/evmrpc/info_test.go @@ -58,11 +58,10 @@ func TestCoinbase(t *testing.T) { } func TestGasPrice(t *testing.T) { - Ctx = Ctx.WithBlockHeight(1) resObj := sendRequestGood(t, "gasPrice") Ctx = Ctx.WithBlockHeight(8) result := resObj["result"].(string) - require.Equal(t, "0xa", result) + require.Equal(t, "0x174876e800", result) } func TestFeeHistory(t *testing.T) { @@ -81,12 +80,12 @@ func TestFeeHistory(t *testing.T) { Ctx = Ctx.WithBlockHeight(1) // Simulate context with a specific block height testCases := []feeHistoryTestCase{ - {name: "Valid request by number", blockCount: 1, lastBlock: "0x8", rewardPercentiles: []interface{}{0.5}, expectedOldest: "0x1", expectedReward: "0xa", expectedBaseFee: "0x0", expectedGasUsed: 0.5}, - {name: "Valid request by latest", blockCount: 1, lastBlock: "latest", rewardPercentiles: []interface{}{0.5}, expectedOldest: "0x1", expectedReward: "0xa", expectedBaseFee: "0x0", expectedGasUsed: 0.5}, - {name: "Valid request by earliest", blockCount: 1, lastBlock: "earliest", rewardPercentiles: []interface{}{0.5}, expectedOldest: "0x1", expectedReward: "0xa", expectedBaseFee: "0x0", expectedGasUsed: 0.5}, - {name: "Request on the same block", blockCount: 1, lastBlock: "0x1", rewardPercentiles: []interface{}{0.5}, expectedOldest: "0x1", expectedReward: "0xa", expectedBaseFee: "0x0", expectedGasUsed: 0.5}, - {name: "Request on future block", blockCount: 1, lastBlock: "0x9", rewardPercentiles: []interface{}{0.5}, expectedOldest: "0x1", expectedReward: "0xa", expectedBaseFee: "0x0", expectedGasUsed: 0.5}, - {name: "Block count truncates", blockCount: 1025, lastBlock: "latest", rewardPercentiles: []interface{}{25}, expectedOldest: "0x1", expectedReward: "0xa", expectedBaseFee: "0x0", expectedGasUsed: 0.5}, + {name: "Valid request by number", blockCount: 1, lastBlock: "0x8", rewardPercentiles: []interface{}{0.5}, expectedOldest: "0x1", expectedReward: "0x0", expectedBaseFee: "0x174876e800", expectedGasUsed: 0.5}, + {name: "Valid request by latest", blockCount: 1, lastBlock: "latest", rewardPercentiles: []interface{}{0.5}, expectedOldest: "0x1", expectedReward: "0x0", expectedBaseFee: "0x174876e800", expectedGasUsed: 0.5}, + {name: "Valid request by earliest", blockCount: 1, lastBlock: "earliest", rewardPercentiles: []interface{}{0.5}, expectedOldest: "0x1", expectedReward: "0x0", expectedBaseFee: "0x174876e800", expectedGasUsed: 0.5}, + {name: "Request on the same block", blockCount: 1, lastBlock: "0x1", rewardPercentiles: []interface{}{0.5}, expectedOldest: "0x1", expectedReward: "0x0", expectedBaseFee: "0x174876e800", expectedGasUsed: 0.5}, + {name: "Request on future block", blockCount: 1, lastBlock: "0x9", rewardPercentiles: []interface{}{0.5}, expectedOldest: "0x1", expectedReward: "0x0", expectedBaseFee: "0x174876e800", expectedGasUsed: 0.5}, + {name: "Block count truncates", blockCount: 1025, lastBlock: "latest", rewardPercentiles: []interface{}{25}, expectedOldest: "0x1", expectedReward: "0x0", expectedBaseFee: "0x174876e800", expectedGasUsed: 0.5}, {name: "Too many percentiles", blockCount: 10, lastBlock: "latest", rewardPercentiles: make([]interface{}, 101), expectedError: errors.New("rewardPercentiles length must be less than or equal to 100")}, {name: "Invalid percentiles order", blockCount: 10, lastBlock: "latest", rewardPercentiles: []interface{}{99, 1}, expectedError: errors.New("invalid reward percentiles: must be ascending and between 0 and 100")}, } @@ -103,6 +102,7 @@ func TestFeeHistory(t *testing.T) { require.False(t, errorExists) resObj = resObj["result"].(map[string]interface{}) + require.Equal(t, tc.expectedOldest, resObj["oldestBlock"].(string)) rewards, ok := resObj["reward"].([]interface{}) @@ -164,5 +164,5 @@ func TestMaxPriorityFeePerGas(t *testing.T) { Ctx = Ctx.WithBlockHeight(1) // Mimic request sending and handle the response resObj := sendRequestGood(t, "maxPriorityFeePerGas") - assert.Equal(t, "0xa", resObj["result"]) + assert.Equal(t, "0x0", resObj["result"]) } diff --git a/evmrpc/setup_test.go b/evmrpc/setup_test.go index 3449bb640..d252f3167 100644 --- a/evmrpc/setup_test.go +++ b/evmrpc/setup_test.go @@ -575,7 +575,7 @@ func generateTxData() { TxHashHex: tx1.Hash().Hex(), GasUsed: 55, Status: 0, - EffectiveGasPrice: 10, + EffectiveGasPrice: 100000000000, Logs: []*types.Log{{ Address: "0x1111111111111111111111111111111111111111", Topics: []string{"0x1111111111111111111111111111111111111111111111111111111111111111", "0x1111111111111111111111111111111111111111111111111111111111111112"}, diff --git a/evmrpc/simulate.go b/evmrpc/simulate.go index e78c500f3..55cafd639 100644 --- a/evmrpc/simulate.go +++ b/evmrpc/simulate.go @@ -424,7 +424,7 @@ func (b *Backend) getHeader(blockNumber *big.Int) *ethtypes.Header { header := ðtypes.Header{ Difficulty: common.Big0, Number: blockNumber, - BaseFee: b.keeper.GetBaseFeePerGas(b.ctxProvider(LatestCtxHeight)).BigInt(), + BaseFee: b.keeper.GetDynamicBaseFeePerGas(b.ctxProvider(LatestCtxHeight)).TruncateInt().BigInt(), GasLimit: b.config.GasCap, Time: uint64(time.Now().Unix()), ExcessBlobGas: &zeroExcessBlobGas, diff --git a/evmrpc/simulate_test.go b/evmrpc/simulate_test.go index 5375722f6..777b5d1f3 100644 --- a/evmrpc/simulate_test.go +++ b/evmrpc/simulate_test.go @@ -89,7 +89,7 @@ func TestCreateAccessList(t *testing.T) { "chainId": fmt.Sprintf("%#x", EVMKeeper.ChainID(Ctx)), "input": fmt.Sprintf("%#x", input), } - amts := sdk.NewCoins(sdk.NewCoin(EVMKeeper.GetBaseDenom(Ctx), sdk.NewInt(20))) + amts := sdk.NewCoins(sdk.NewCoin(EVMKeeper.GetBaseDenom(Ctx), sdk.NewInt(2000000))) EVMKeeper.BankKeeper().MintCoins(Ctx, types.ModuleName, amts) EVMKeeper.BankKeeper().SendCoinsFromModuleToAccount(Ctx, types.ModuleName, sdk.AccAddress(from[:]), amts) resObj := sendRequestGood(t, "createAccessList", txArgs, "latest") @@ -148,10 +148,8 @@ func TestEthCallHighAmount(t *testing.T) { from.Hex(): {"balance": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"}, } resObj := sendRequestGood(t, "call", txArgs, "latest", overrides) - fmt.Println("resObj = ", resObj) errMap := resObj["error"].(map[string]interface{}) result := errMap["message"] - fmt.Println("res = ", result) require.Equal(t, result, "error: balance override overflow") Ctx = Ctx.WithBlockHeight(8) diff --git a/evmrpc/tx_test.go b/evmrpc/tx_test.go index b6695d05d..b41c07f2c 100644 --- a/evmrpc/tx_test.go +++ b/evmrpc/tx_test.go @@ -44,7 +44,7 @@ func testGetTxReceipt(t *testing.T, namespace string) { require.Equal(t, "0x0000000000000000000000000000000000000000000000000000000000000001", resObj["blockHash"].(string)) require.Equal(t, "0x8", resObj["blockNumber"].(string)) require.Equal(t, "0x7b", resObj["cumulativeGasUsed"].(string)) - require.Equal(t, "0xa", resObj["effectiveGasPrice"].(string)) + require.Equal(t, "0x174876e800", resObj["effectiveGasPrice"].(string)) require.Equal(t, "0x1234567890123456789012345678901234567890", resObj["from"].(string)) require.Equal(t, "0x37", resObj["gasUsed"].(string)) logs := resObj["logs"].([]interface{}) diff --git a/go.mod b/go.mod index 2704c761a..fc71d4f6f 100644 --- a/go.mod +++ b/go.mod @@ -349,12 +349,12 @@ replace ( github.com/cosmos/cosmos-sdk => github.com/sei-protocol/sei-cosmos v0.3.37-0.20240923023912-aa7a702d42cc github.com/cosmos/iavl => github.com/sei-protocol/sei-iavl v0.2.0 github.com/cosmos/ibc-go/v3 => github.com/sei-protocol/sei-ibc-go/v3 v3.3.2 - github.com/ethereum/go-ethereum => github.com/sei-protocol/go-ethereum v1.13.5-sei-9.0.20240923122925-0050f0abba7b + github.com/ethereum/go-ethereum => github.com/sei-protocol/go-ethereum v1.13.5-sei-9.0.20240925211216-af807e581c3a github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 github.com/sei-protocol/sei-db => github.com/sei-protocol/sei-db v0.0.44 // Latest goleveldb is broken, we have to stick to this version github.com/syndtr/goleveldb => github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 - github.com/tendermint/tendermint => github.com/sei-protocol/sei-tendermint v0.3.8 + github.com/tendermint/tendermint => github.com/sei-protocol/sei-tendermint v0.3.9-0.20240926181940-e9348a908b27 github.com/tendermint/tm-db => github.com/sei-protocol/tm-db v0.0.4 google.golang.org/grpc => google.golang.org/grpc v1.33.2 ) diff --git a/go.sum b/go.sum index d6154754f..0f4715c55 100644 --- a/go.sum +++ b/go.sum @@ -1343,8 +1343,8 @@ github.com/seccomp/libseccomp-golang v0.9.2-0.20220502022130-f33da4d89646/go.mod github.com/securego/gosec/v2 v2.11.0 h1:+PDkpzR41OI2jrw1q6AdXZCbsNGNGT7pQjal0H0cArI= github.com/securego/gosec/v2 v2.11.0/go.mod h1:SX8bptShuG8reGC0XS09+a4H2BoWSJi+fscA+Pulbpo= github.com/segmentio/fasthash v1.0.3/go.mod h1:waKX8l2N8yckOgmSsXJi7x1ZfdKZ4x7KRMzBtS3oedY= -github.com/sei-protocol/go-ethereum v1.13.5-sei-9.0.20240923122925-0050f0abba7b h1:cxonMwt+Ry3ovjncQCBI6XqT/RWiU0N8dBNi6WJtY04= -github.com/sei-protocol/go-ethereum v1.13.5-sei-9.0.20240923122925-0050f0abba7b/go.mod h1:kcRZmuzRn1lVejiFNTz4l4W7imnpq1bDAnuKS/RyhbQ= +github.com/sei-protocol/go-ethereum v1.13.5-sei-9.0.20240925211216-af807e581c3a h1:eicGeFgoEmKaSEPXMUMbTvYFk385iw2+u5/Wmqiz/JY= +github.com/sei-protocol/go-ethereum v1.13.5-sei-9.0.20240925211216-af807e581c3a/go.mod h1:kcRZmuzRn1lVejiFNTz4l4W7imnpq1bDAnuKS/RyhbQ= github.com/sei-protocol/goutils v0.0.2 h1:Bfa7Sv+4CVLNM20QcpvGb81B8C5HkQC/kW1CQpIbXDA= github.com/sei-protocol/goutils v0.0.2/go.mod h1:iYE2DuJfEnM+APPehr2gOUXfuLuPsVxorcDO+Tzq9q8= github.com/sei-protocol/sei-cosmos v0.3.37-0.20240923023912-aa7a702d42cc h1:srWLbsoS0NYBIl8OjZOFuPmIeqf+fJTkfsK39MmG3+k= @@ -1355,8 +1355,8 @@ github.com/sei-protocol/sei-iavl v0.2.0 h1:OisPjXiDT+oe+aeckzDEFgkZCYuUjHgs/PP8D github.com/sei-protocol/sei-iavl v0.2.0/go.mod h1:qRf8QYUPfrAO7K6VDB2B2l/N7K5L76OorioGBcJBIbw= github.com/sei-protocol/sei-ibc-go/v3 v3.3.2 h1:BaMZ6gjwqe3R/5dLmcJ1TkSZ3omcWy2TjaAZAeOJH44= github.com/sei-protocol/sei-ibc-go/v3 v3.3.2/go.mod h1:VwB/vWu4ysT5DN2aF78d17LYmx3omSAdq6gpKvM7XRA= -github.com/sei-protocol/sei-tendermint v0.3.8 h1:9o+A3tL6q1ki++dLng/J8MHHiT6y3l7D4Ir2UIQSkAQ= -github.com/sei-protocol/sei-tendermint v0.3.8/go.mod h1:4LSlJdhl3nf3OmohliwRNUFLOB1XWlrmSodrIP7fLh4= +github.com/sei-protocol/sei-tendermint v0.3.9-0.20240926181940-e9348a908b27 h1:IREoTJ2mrjmGGHVtuVLzzPjh7U7sqjqJLHAIN1BSIW4= +github.com/sei-protocol/sei-tendermint v0.3.9-0.20240926181940-e9348a908b27/go.mod h1:4LSlJdhl3nf3OmohliwRNUFLOB1XWlrmSodrIP7fLh4= github.com/sei-protocol/sei-tm-db v0.0.5 h1:3WONKdSXEqdZZeLuWYfK5hP37TJpfaUa13vAyAlvaQY= github.com/sei-protocol/sei-tm-db v0.0.5/go.mod h1:Cpa6rGyczgthq7/0pI31jys2Fw0Nfrc+/jKdP1prVqY= github.com/sei-protocol/sei-wasmd v0.2.4 h1:W++xiJ1P57BhBW8TGk8vfPRJlWXr1vp2kQCvSc8Qpaw= diff --git a/loadtest/evm.go b/loadtest/evm.go index 05c9fdeb4..ecf22cf16 100644 --- a/loadtest/evm.go +++ b/loadtest/evm.go @@ -25,8 +25,8 @@ import ( ) var ( - DefaultPriorityFee = big.NewInt(1000000000) // 1gwei - DefaultMaxFee = big.NewInt(1000000000) // 1gwei + DefaultPriorityFee = big.NewInt(1000000000) // 1gwei + DefaultMaxFee = big.NewInt(1000000000000) // 1000gwei ) type EvmTxClient struct { @@ -112,7 +112,7 @@ func (txClient *EvmTxClient) GenerateSendFundsTx() *ethtypes.Transaction { if !txClient.useEip1559 { tx = ethtypes.NewTx(ðtypes.LegacyTx{ Nonce: txClient.nextNonce(), - GasPrice: txClient.gasPrice, + GasPrice: DefaultMaxFee, Gas: uint64(21000), To: &txClient.accountAddress, Value: randomValue(), @@ -186,7 +186,7 @@ func (txClient *EvmTxClient) getTransactOpts() *bind.TransactOpts { panic(fmt.Sprintf("Failed to create transactor: %v \n", err)) } if !txClient.useEip1559 { - auth.GasPrice = txClient.gasPrice + auth.GasPrice = DefaultMaxFee } else { auth.GasFeeCap = DefaultMaxFee auth.GasTipCap = DefaultPriorityFee @@ -221,7 +221,6 @@ func (txClient *EvmTxClient) SendEvmTx(signedTx *ethtypes.Transaction, onSuccess if err != nil { fmt.Printf("Failed to send evm transaction: %v \n", err) } else { - // We choose not to GetTxReceipt because we assume the EVM RPC would be running with broadcast mode = block onSuccess() } } diff --git a/occ_tests/messages/test_msgs.go b/occ_tests/messages/test_msgs.go index 6ea0d5c65..d7df19532 100644 --- a/occ_tests/messages/test_msgs.go +++ b/occ_tests/messages/test_msgs.go @@ -82,8 +82,8 @@ func EVMTransferConflicting(tCtx *utils.TestContext, count int) []*utils.TestMes // each message will have a brand new address func evmTransfer(testAcct utils.TestAcct, to common.Address, scenario string) *utils.TestMessage { signedTx, err := ethtypes.SignTx(ethtypes.NewTx(ðtypes.DynamicFeeTx{ - GasFeeCap: new(big.Int).SetUint64(1000000000000), - GasTipCap: new(big.Int).SetUint64(1000000000000), + GasFeeCap: new(big.Int).SetUint64(100000000000), + GasTipCap: new(big.Int).SetUint64(100000000000), Gas: 21000, ChainID: big.NewInt(config.DefaultChainID), To: &to, diff --git a/precompiles/pointer/pointer_test.go b/precompiles/pointer/pointer_test.go index d3fe14b00..18266466a 100644 --- a/precompiles/pointer/pointer_test.go +++ b/precompiles/pointer/pointer_test.go @@ -57,7 +57,7 @@ func TestAddNative(t *testing.T) { evm = vm.NewEVM(*blockCtx, vm.TxContext{}, statedb, cfg, vm.Config{}) ret, g, err := p.RunAndCalculateGas(evm, caller, caller, append(p.GetExecutor().(*pointer.PrecompileExecutor).AddNativePointerID, args...), suppliedGas, nil, nil, false, false) require.Nil(t, err) - require.Equal(t, uint64(8888494), g) + require.Equal(t, uint64(8883738), g) outputs, err := m.Outputs.Unpack(ret) require.Nil(t, err) addr := outputs[0].(common.Address) diff --git a/proto/evm/params.proto b/proto/evm/params.proto index d945c7c9c..6d2868ade 100644 --- a/proto/evm/params.proto +++ b/proto/evm/params.proto @@ -2,7 +2,6 @@ syntax = "proto3"; package seiprotocol.seichain.evm; import "gogoproto/gogo.proto"; -import "evm/config.proto"; option go_package = "github.com/sei-protocol/sei-chain/x/evm/types"; @@ -49,4 +48,59 @@ string minimum_fee_per_gas = 4 [ ]; uint64 deliver_tx_hook_wasm_gas_limit = 9; + + string max_dynamic_base_fee_upward_adjustment = 10 [ + (gogoproto.moretags) = "yaml:\"max_dynamic_base_fee_upward_adjustment\"", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false, + (gogoproto.jsontag) = "max_dynamic_base_fee_upward_adjustment" + ]; + string max_dynamic_base_fee_downward_adjustment = 11 [ + (gogoproto.moretags) = "yaml:\"max_dynamic_base_fee_downward_adjustment\"", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false, + (gogoproto.jsontag) = "max_dynamic_base_fee_downward_adjustment" + ]; +} + +message ParamsPreV580 { + option (gogoproto.goproto_stringer) = false; + + // string base_denom = 1 [ + // (gogoproto.moretags) = "yaml:\"base_denom\"", + // (gogoproto.jsontag) = "base_denom" + // ]; + string priority_normalizer = 2 [ + (gogoproto.moretags) = "yaml:\"priority_normalizer\"", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false, + (gogoproto.jsontag) = "priority_normalizer" + ]; + string base_fee_per_gas = 3 [ + (gogoproto.moretags) = "yaml:\"base_fee_per_gas\"", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false, + (gogoproto.jsontag) = "base_fee_per_gas" +]; +string minimum_fee_per_gas = 4 [ + (gogoproto.moretags) = "yaml:\"minimum_fee_per_gas\"", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false, + (gogoproto.jsontag) = "minimum_fee_per_gas" +]; + // ChainConfig chain_config = 5 [(gogoproto.moretags) = "yaml:\"chain_config\"", (gogoproto.nullable) = false]; +// string chain_id = 6 [ +// (gogoproto.moretags) = "yaml:\"chain_id\"", +// (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", +// (gogoproto.nullable) = false, +// (gogoproto.jsontag) = "chain_id" +// ]; +// repeated string whitelisted_codehashes_bank_send = 7 [ +// (gogoproto.moretags) = "yaml:\"whitelisted_codehashes_bank_send\"", +// (gogoproto.jsontag) = "whitelisted_codehashes_bank_send" +// ]; +repeated bytes whitelisted_cw_code_hashes_for_delegate_call = 8 [ + (gogoproto.moretags) = "yaml:\"whitelisted_cw_code_hashes_for_delegate_call\"", + (gogoproto.jsontag) = "whitelisted_cw_code_hashes_for_delegate_call" +]; } \ No newline at end of file diff --git a/run_blocktests.sh b/run_blocktests.sh index e3c259a94..0620f9bbf 100755 --- a/run_blocktests.sh +++ b/run_blocktests.sh @@ -34,6 +34,11 @@ declare -a test_name_skip_list=( "BLOCKHASH_Bounds" # failing "logRevert" # uses an invalid opcode (0xBA) "blockWithAllTransactionTypes" # recently started failing + "tipInsideBlock" # failing after turning on eip-1559 and not burning base fee + "multimpleBalanceInstruction" # failing after turning on eip-1559 and not burning base fee + "tips" # failing after turning on eip-1559 and not burning base fee + "burnVerify" # failing after turning on eip-1559 and not burning base fee + "emptyPostTransfer" # failing after turning on eip-1559 and not burning base fee "multimpleBalanceInstruction" # failing from 150% max gas refund change "burnVerify" # failing from 150% max gas refund change "refundReset" # failing from 150% max gas refund change diff --git a/x/evm/ante/fee.go b/x/evm/ante/fee.go index 262a88fe8..7e963d6d6 100644 --- a/x/evm/ante/fee.go +++ b/x/evm/ante/fee.go @@ -99,12 +99,12 @@ func (fc EVMFeeCheckDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate b return next(ctx, tx, simulate) } -// fee per gas to be burnt +// minimum fee per gas required for a tx to be processed func (fc EVMFeeCheckDecorator) getBaseFee(ctx sdk.Context) *big.Int { - return fc.evmKeeper.GetBaseFeePerGas(ctx).TruncateInt().BigInt() + return fc.evmKeeper.GetDynamicBaseFeePerGas(ctx).TruncateInt().BigInt() } -// lowest allowed fee per gas +// lowest allowed fee per gas, base fee will not be lower than this func (fc EVMFeeCheckDecorator) getMinimumFee(ctx sdk.Context) *big.Int { return fc.evmKeeper.GetMinimumFeePerGas(ctx).TruncateInt().BigInt() } diff --git a/x/evm/genesis_test.go b/x/evm/genesis_test.go index f43dc2d60..df2453b35 100644 --- a/x/evm/genesis_test.go +++ b/x/evm/genesis_test.go @@ -33,6 +33,8 @@ func TestExportImportGenesis(t *testing.T) { assert.Equal(t, types.DefaultParams().BaseFeePerGas, param.BaseFeePerGas) assert.Equal(t, types.DefaultParams().MinimumFeePerGas, param.MinimumFeePerGas) assert.Equal(t, types.DefaultParams().WhitelistedCwCodeHashesForDelegateCall, param.WhitelistedCwCodeHashesForDelegateCall) + assert.Equal(t, types.DefaultParams().MaxDynamicBaseFeeUpwardAdjustment, param.MaxDynamicBaseFeeUpwardAdjustment) + assert.Equal(t, types.DefaultParams().MaxDynamicBaseFeeDownwardAdjustment, param.MaxDynamicBaseFeeDownwardAdjustment) evm.InitGenesis(origctx, keeper, *genesis) require.Equal(t, evmAddr, keeper.GetEVMAddressOrDefault(origctx, seiAddr)) require.Equal(t, keeper.GetCode(ctx, codeAddr), keeper.GetCode(origctx, codeAddr)) diff --git a/x/evm/keeper/evm.go b/x/evm/keeper/evm.go index 1ec7f039d..a11c696df 100644 --- a/x/evm/keeper/evm.go +++ b/x/evm/keeper/evm.go @@ -103,6 +103,7 @@ func (k *Keeper) CallEVM(ctx sdk.Context, from common.Address, to *common.Addres SkipAccountChecks: false, From: from, } + fmt.Println("JEREMYDEBUG: calling apply evm message from CallEVM") res, err := k.applyEVMMessage(ctx, evmMsg, stateDB, gp) if err != nil { return nil, err diff --git a/x/evm/keeper/evm_test.go b/x/evm/keeper/evm_test.go index afd667b6e..3d4a0162b 100644 --- a/x/evm/keeper/evm_test.go +++ b/x/evm/keeper/evm_test.go @@ -39,11 +39,15 @@ func TestInternalCallCreateContract(t *testing.T) { _, err = k.HandleInternalEVMCall(ctx, req) require.Equal(t, "sei does not support EVM->CW->EVM call pattern", err.Error()) ctx = ctx.WithIsEVM(false) + oldBaseFee := k.GetDynamicBaseFeePerGas(ctx) + k.SetDynamicBaseFeePerGas(ctx, sdk.ZeroDec()) _, err = k.HandleInternalEVMCall(ctx, req) require.Nil(t, err) receipt, err := k.GetTransientReceipt(ctx, [32]byte{1, 2, 3}) require.Nil(t, err) require.NotNil(t, receipt) + // reset base fee + k.SetDynamicBaseFeePerGas(ctx, oldBaseFee) } func TestInternalCall(t *testing.T) { diff --git a/x/evm/keeper/fee.go b/x/evm/keeper/fee.go new file mode 100644 index 000000000..6019a2f59 --- /dev/null +++ b/x/evm/keeper/fee.go @@ -0,0 +1,63 @@ +package keeper + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/sei-protocol/sei-chain/x/evm/types" +) + +// modified eip-1559 adjustment +func (k *Keeper) AdjustDynamicBaseFeePerGas(ctx sdk.Context, blockGasUsed uint64) { + if ctx.ConsensusParams() == nil || ctx.ConsensusParams().Block == nil { + return + } + currentBaseFee := k.GetDynamicBaseFeePerGas(ctx) + minimumFeePerGas := k.GetParams(ctx).MinimumFeePerGas + blockGasLimit := sdk.NewDec(ctx.ConsensusParams().Block.MaxGas) + blockGasUsedDec := sdk.NewDec(int64(blockGasUsed)) + + blockFullness := blockGasUsedDec.Quo(blockGasLimit) + + half := sdk.NewDec(1).Quo(sdk.NewDec(2)) // 0.5 + var newBaseFee sdk.Dec + if blockFullness.GT(half) { + // upward adjustment + adjustmentFactor := k.GetMaxDynamicBaseFeeUpwardAdjustment(ctx).Mul(blockFullness.Sub(half)).Quo(half) + newBaseFee = currentBaseFee.Mul(sdk.NewDec(1).Add(adjustmentFactor)) + } else { + // downward adjustment + adjustmentFactor := k.GetMaxDynamicBaseFeeDownwardAdjustment(ctx).Mul(half.Sub(blockFullness)).Quo(half) + newBaseFee = currentBaseFee.Mul(sdk.NewDec(1).Sub(adjustmentFactor)) + } + + // Ensure the new base fee is not lower than the minimum fee + if newBaseFee.LT(minimumFeePerGas) { + newBaseFee = minimumFeePerGas + } + + // Set the new base fee for the next height + k.SetDynamicBaseFeePerGas(ctx.WithBlockHeight(ctx.BlockHeight()+1), newBaseFee) +} + +// dont have height be a prefix, just store the current base fee directly +func (k *Keeper) GetDynamicBaseFeePerGas(ctx sdk.Context) sdk.Dec { + store := ctx.KVStore(k.storeKey) + bz := store.Get(types.BaseFeePerGasPrefix) + if bz == nil { + return k.GetMinimumFeePerGas(ctx) + } + d := sdk.Dec{} + err := d.UnmarshalJSON(bz) + if err != nil { + panic(err) + } + return d +} + +func (k *Keeper) SetDynamicBaseFeePerGas(ctx sdk.Context, baseFeePerGas sdk.Dec) { + store := ctx.KVStore(k.storeKey) + bz, err := baseFeePerGas.MarshalJSON() + if err != nil { + panic(err) + } + store.Set(types.BaseFeePerGasPrefix, bz) +} diff --git a/x/evm/keeper/fee_test.go b/x/evm/keeper/fee_test.go new file mode 100644 index 000000000..7495ea208 --- /dev/null +++ b/x/evm/keeper/fee_test.go @@ -0,0 +1,81 @@ +package keeper_test + +import ( + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + testkeeper "github.com/sei-protocol/sei-chain/testutil/keeper" + "github.com/stretchr/testify/require" + tmproto "github.com/tendermint/tendermint/proto/tendermint/types" +) + +func TestBaseFeePerGas(t *testing.T) { + k := &testkeeper.EVMTestApp.EvmKeeper + ctx := testkeeper.EVMTestApp.GetContextForDeliverTx([]byte{}) + require.Equal(t, k.GetMinimumFeePerGas(ctx), k.GetDynamicBaseFeePerGas(ctx)) + originalbf := k.GetDynamicBaseFeePerGas(ctx) + k.SetDynamicBaseFeePerGas(ctx, sdk.OneDec()) + require.Equal(t, sdk.NewDecFromInt(sdk.NewInt(1)), k.GetDynamicBaseFeePerGas(ctx)) + k.SetDynamicBaseFeePerGas(ctx, originalbf) +} + +func TestAdjustBaseFeePerGas(t *testing.T) { + k, ctx := testkeeper.MockEVMKeeper() + testCases := []struct { + name string + currentBaseFee float64 + minimumFee float64 + blockGasUsed uint64 + blockGasLimit uint64 + expectedBaseFee uint64 + }{ + { + name: "Block gas usage exactly half of limit, no fee change", + currentBaseFee: 100, + minimumFee: 10, + blockGasUsed: 500000, + blockGasLimit: 1000000, + expectedBaseFee: 100, + }, + { + name: "Block gas usage 75%, base fee stays the same", + currentBaseFee: 10000, + minimumFee: 10, + blockGasUsed: 750000, + blockGasLimit: 1000000, + expectedBaseFee: 10000, + }, + { + name: "Block gas usage 25%, base fee stays the same", + currentBaseFee: 10000, + minimumFee: 10, + blockGasUsed: 250000, + blockGasLimit: 1000000, + expectedBaseFee: 10000, + }, + { + name: "Block gas usage low, new base fee below minimum, set to minimum", + currentBaseFee: 100, + minimumFee: 100, + blockGasUsed: 0, + blockGasLimit: 1000000, + expectedBaseFee: 100, // Should not go below the minimum fee + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + ctx = ctx.WithConsensusParams(&tmproto.ConsensusParams{ + Block: &tmproto.BlockParams{MaxGas: int64(tc.blockGasLimit)}, + }) + k.SetDynamicBaseFeePerGas(ctx, sdk.NewDecFromInt(sdk.NewInt(int64(tc.currentBaseFee)))) + p := k.GetParams(ctx) + p.MinimumFeePerGas = sdk.NewDec(int64(tc.minimumFee)) + k.SetParams(ctx, p) + k.AdjustDynamicBaseFeePerGas(ctx, tc.blockGasUsed) + expected := sdk.NewDecFromInt(sdk.NewInt(int64(tc.expectedBaseFee))) + height := ctx.BlockHeight() + require.Equal(t, expected, k.GetDynamicBaseFeePerGas(ctx.WithBlockHeight(height+1)), "base fee did not match expected value") + }) + } +} diff --git a/x/evm/keeper/keeper.go b/x/evm/keeper/keeper.go index 889f1c167..9b754398e 100644 --- a/x/evm/keeper/keeper.go +++ b/x/evm/keeper/keeper.go @@ -209,9 +209,9 @@ func (k *Keeper) GetVMBlockContext(ctx sdk.Context, gp core.GasPool) (*vm.BlockC GasLimit: gp.Gas(), BlockNumber: big.NewInt(ctx.BlockHeight()), Time: uint64(ctx.BlockHeader().Time.Unix()), - Difficulty: utils.Big0, // only needed for PoW - BaseFee: k.GetBaseFeePerGas(ctx).TruncateInt().BigInt(), // feemarket not enabled - BlobBaseFee: utils.Big1, // Cancun not enabled + Difficulty: utils.Big0, // only needed for PoW + BaseFee: k.GetDynamicBaseFeePerGas(ctx).TruncateInt().BigInt(), + BlobBaseFee: utils.Big1, // Cancun not enabled Random: &rh, }, nil } diff --git a/x/evm/keeper/msg_server.go b/x/evm/keeper/msg_server.go index 76e9d329a..f26dfd6a2 100644 --- a/x/evm/keeper/msg_server.go +++ b/x/evm/keeper/msg_server.go @@ -160,6 +160,7 @@ func (server msgServer) EVMTransaction(goCtx context.Context, msg *types.MsgEVMT originalGasMeter.ConsumeGas(adjustedGasUsed.TruncateInt().Uint64(), "evm transaction") }() + fmt.Println("JEREMYDEBUG: calling apply evm message from EVMTransaction") res, applyErr := server.applyEVMMessage(ctx, emsg, stateDB, gp) serverRes = &types.MsgEVMTransactionResponse{ Hash: tx.Hash().Hex(), @@ -229,6 +230,7 @@ func (k *Keeper) GetEVMMessage(ctx sdk.Context, tx *ethtypes.Transaction, sender } func (k Keeper) applyEVMMessage(ctx sdk.Context, msg *core.Message, stateDB *state.DBImpl, gp core.GasPool) (*core.ExecutionResult, error) { + // fmt.Printf("JEREMYDEBUG: In applyEVMMessage, msg = %+v\n", msg) blockCtx, err := k.GetVMBlockContext(ctx, gp) if err != nil { return nil, err diff --git a/x/evm/keeper/msg_server_test.go b/x/evm/keeper/msg_server_test.go index deb333287..d4bc82971 100644 --- a/x/evm/keeper/msg_server_test.go +++ b/x/evm/keeper/msg_server_test.go @@ -4,6 +4,7 @@ import ( "bytes" "crypto/sha256" "encoding/hex" + "fmt" "math/big" "os" "testing" @@ -338,14 +339,17 @@ func TestEVMPrecompiles(t *testing.T) { return ctx, nil }) require.Nil(t, err) + coinbaseBalanceBefore := k.BankKeeper().GetBalance(ctx, state.GetCoinbaseAddress(ctx.TxIndex()), "usei").Amount.Uint64() res, err := msgServer.EVMTransaction(sdk.WrapSDKContext(ctx), req) require.Nil(t, err) require.LessOrEqual(t, res.GasUsed, uint64(500000)) require.Empty(t, res.VmError) require.NotEmpty(t, res.ReturnData) require.NotEmpty(t, res.Hash) - require.Equal(t, uint64(1000000)-res.GasUsed, k.BankKeeper().GetBalance(ctx, sdk.AccAddress(evmAddr[:]), "usei").Amount.Uint64()) - require.Equal(t, res.GasUsed, k.BankKeeper().GetBalance(ctx, state.GetCoinbaseAddress(ctx.TxIndex()), k.GetBaseDenom(ctx)).Amount.Uint64()) + require.Equal(t, uint64(1000000)-res.GasUsed, k.BankKeeper().GetBalance(ctx, sdk.AccAddress(evmAddr[:]), k.GetBaseDenom(ctx)).Amount.Uint64()) + coinbaseBalanceAfter := k.BankKeeper().GetBalance(ctx, state.GetCoinbaseAddress(ctx.TxIndex()), k.GetBaseDenom(ctx)).Amount.Uint64() + diff := coinbaseBalanceAfter - coinbaseBalanceBefore + require.Equal(t, res.GasUsed, diff) require.NoError(t, k.FlushTransientReceipts(ctx)) receipt, err := k.GetReceipt(ctx, common.HexToHash(res.Hash)) require.Nil(t, err) @@ -462,7 +466,11 @@ func TestEVMBlockEnv(t *testing.T) { require.NotEmpty(t, res.ReturnData) require.NotEmpty(t, res.Hash) require.Equal(t, uint64(1000000)-res.GasUsed, k.BankKeeper().GetBalance(ctx, sdk.AccAddress(evmAddr[:]), "usei").Amount.Uint64()) - require.Equal(t, res.GasUsed, k.BankKeeper().GetBalance(ctx, state.GetCoinbaseAddress(ctx.TxIndex()), k.GetBaseDenom(ctx)).Amount.Uint64()) + fmt.Println("all balances sender = ", k.BankKeeper().GetAllBalances(ctx, sdk.AccAddress(evmAddr[:]))) + fmt.Println("all balances coinbase = ", k.BankKeeper().GetAllBalances(ctx, state.GetCoinbaseAddress(ctx.TxIndex()))) + fmt.Println("wei = ", k.BankKeeper().GetBalance(ctx, state.GetCoinbaseAddress(ctx.TxIndex()), "wei").Amount.Uint64()) + require.Equal(t, res.GasUsed, k.BankKeeper().GetBalance(ctx, state.GetCoinbaseAddress(ctx.TxIndex()), "usei").Amount.Uint64()) + require.NoError(t, k.FlushTransientReceipts(ctx)) receipt, err := k.GetReceipt(ctx, common.HexToHash(res.Hash)) require.Nil(t, err) diff --git a/x/evm/keeper/params.go b/x/evm/keeper/params.go index fc0b6dc57..1ce43a7c5 100644 --- a/x/evm/keeper/params.go +++ b/x/evm/keeper/params.go @@ -37,6 +37,14 @@ func (k *Keeper) GetBaseFeePerGas(ctx sdk.Context) sdk.Dec { return k.GetParams(ctx).BaseFeePerGas } +func (k *Keeper) GetMaxDynamicBaseFeeUpwardAdjustment(ctx sdk.Context) sdk.Dec { + return k.GetParams(ctx).MaxDynamicBaseFeeUpwardAdjustment +} + +func (k *Keeper) GetMaxDynamicBaseFeeDownwardAdjustment(ctx sdk.Context) sdk.Dec { + return k.GetParams(ctx).MaxDynamicBaseFeeDownwardAdjustment +} + func (k *Keeper) GetMinimumFeePerGas(ctx sdk.Context) sdk.Dec { return k.GetParams(ctx).MinimumFeePerGas } diff --git a/x/evm/keeper/params_test.go b/x/evm/keeper/params_test.go index 2f157ad68..f47323152 100644 --- a/x/evm/keeper/params_test.go +++ b/x/evm/keeper/params_test.go @@ -15,10 +15,12 @@ func TestParams(t *testing.T) { ctx := testkeeper.EVMTestApp.GetContextForDeliverTx([]byte{}).WithBlockTime(time.Now()) require.Equal(t, "usei", k.GetBaseDenom(ctx)) require.Equal(t, types.DefaultPriorityNormalizer, k.GetPriorityNormalizer(ctx)) + require.Equal(t, types.DefaultMinFeePerGas, k.GetDynamicBaseFeePerGas(ctx)) require.Equal(t, types.DefaultBaseFeePerGas, k.GetBaseFeePerGas(ctx)) require.Equal(t, types.DefaultMinFeePerGas, k.GetMinimumFeePerGas(ctx)) require.Equal(t, types.DefaultDeliverTxHookWasmGasLimit, k.GetDeliverTxHookWasmGasLimit(ctx)) - + require.Equal(t, types.DefaultMaxDynamicBaseFeeUpwardAdjustment, k.GetMaxDynamicBaseFeeUpwardAdjustment(ctx)) + require.Equal(t, types.DefaultMaxDynamicBaseFeeDownwardAdjustment, k.GetMaxDynamicBaseFeeDownwardAdjustment(ctx)) require.Nil(t, k.GetParams(ctx).Validate()) } diff --git a/x/evm/keeper/replay.go b/x/evm/keeper/replay.go index 0ef8246df..0af33741e 100644 --- a/x/evm/keeper/replay.go +++ b/x/evm/keeper/replay.go @@ -83,6 +83,15 @@ func (k *Keeper) VerifyAccount(ctx sdk.Context, addr common.Address, accountData } } +func contains(slice []common.Address, element common.Address) bool { + for _, v := range slice { + if v == element { + return true + } + } + return false +} + func (k *Keeper) VerifyState(ctx sdk.Context, addr common.Address) { store := k.PrefixStore(ctx, types.StateKey(addr)) iter := store.Iterator(nil, nil) diff --git a/x/evm/migrations/migrate_eip_1559_params.go b/x/evm/migrations/migrate_eip_1559_params.go new file mode 100644 index 000000000..e6dba7b16 --- /dev/null +++ b/x/evm/migrations/migrate_eip_1559_params.go @@ -0,0 +1,15 @@ +package migrations + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/sei-protocol/sei-chain/x/evm/keeper" + "github.com/sei-protocol/sei-chain/x/evm/types" +) + +func MigrateEip1559Params(ctx sdk.Context, k *keeper.Keeper) error { + keeperParams := k.GetParamsIfExists(ctx) + keeperParams.MaxDynamicBaseFeeUpwardAdjustment = types.DefaultParams().MaxDynamicBaseFeeUpwardAdjustment + keeperParams.MaxDynamicBaseFeeDownwardAdjustment = types.DefaultParams().MaxDynamicBaseFeeDownwardAdjustment + k.SetParams(ctx, keeperParams) + return nil +} diff --git a/x/evm/migrations/migrate_eip_1559_params_test.go b/x/evm/migrations/migrate_eip_1559_params_test.go new file mode 100644 index 000000000..256cccc62 --- /dev/null +++ b/x/evm/migrations/migrate_eip_1559_params_test.go @@ -0,0 +1,29 @@ +package migrations_test + +import ( + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + testkeeper "github.com/sei-protocol/sei-chain/testutil/keeper" + "github.com/sei-protocol/sei-chain/x/evm/migrations" + "github.com/sei-protocol/sei-chain/x/evm/types" + "github.com/stretchr/testify/require" + tmtypes "github.com/tendermint/tendermint/proto/tendermint/types" +) + +func TestMigrateEip1559Params(t *testing.T) { + k := testkeeper.EVMTestApp.EvmKeeper + ctx := testkeeper.EVMTestApp.NewContext(false, tmtypes.Header{}) + + keeperParams := k.GetParams(ctx) + keeperParams.BaseFeePerGas = sdk.NewDec(123) + + // Perform the migration + err := migrations.MigrateEip1559Params(ctx, &k) + require.NoError(t, err) + + // Ensure that the new EIP-1559 parameters were migrated and the old ones were not changed + require.Equal(t, keeperParams.BaseFeePerGas, sdk.NewDec(123)) + require.Equal(t, keeperParams.MaxDynamicBaseFeeUpwardAdjustment, types.DefaultParams().MaxDynamicBaseFeeUpwardAdjustment) + require.Equal(t, keeperParams.MaxDynamicBaseFeeDownwardAdjustment, types.DefaultParams().MaxDynamicBaseFeeDownwardAdjustment) +} diff --git a/x/evm/module.go b/x/evm/module.go index 16d44ecb5..42c7c498c 100644 --- a/x/evm/module.go +++ b/x/evm/module.go @@ -216,6 +216,10 @@ func (am AppModule) RegisterServices(cfg module.Configurator) { _ = cfg.RegisterMigration(types.ModuleName, 12, func(ctx sdk.Context) error { return migrations.MigrateBlockBloom(ctx, am.keeper) }) + + _ = cfg.RegisterMigration(types.ModuleName, 13, func(ctx sdk.Context) error { + return migrations.MigrateEip1559Params(ctx, am.keeper) + }) } // RegisterInvariants registers the capability module's invariants. @@ -253,7 +257,7 @@ func (am AppModule) ExportGenesisStream(ctx sdk.Context, cdc codec.JSONCodec) <- } // ConsensusVersion implements ConsensusVersion. -func (AppModule) ConsensusVersion() uint64 { return 13 } +func (AppModule) ConsensusVersion() uint64 { return 14 } // BeginBlock executes all ABCI BeginBlock logic respective to the capability module. func (am AppModule) BeginBlock(ctx sdk.Context, _ abci.RequestBeginBlock) { @@ -280,7 +284,8 @@ func (am AppModule) BeginBlock(ctx sdk.Context, _ abci.RequestBeginBlock) { // EndBlock executes all ABCI EndBlock logic respective to the evm module. It // returns no validator updates. -func (am AppModule) EndBlock(ctx sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate { +func (am AppModule) EndBlock(ctx sdk.Context, req abci.RequestEndBlock) []abci.ValidatorUpdate { + am.keeper.AdjustDynamicBaseFeePerGas(ctx, uint64(req.BlockGasUsed)) var coinbase sdk.AccAddress if am.keeper.EthBlockTestConfig.Enabled { blocks := am.keeper.BlockTest.Json.Blocks diff --git a/x/evm/module_test.go b/x/evm/module_test.go index 624810dea..dbab3540d 100644 --- a/x/evm/module_test.go +++ b/x/evm/module_test.go @@ -53,13 +53,13 @@ func TestModuleExportGenesis(t *testing.T) { module := evm.NewAppModule(nil, k) jsonMsg := module.ExportGenesis(ctx, types.ModuleCdc) jsonStr := string(jsonMsg) - assert.Equal(t, "{\"params\":{\"priority_normalizer\":\"1.000000000000000000\",\"base_fee_per_gas\":\"0.000000000000000000\",\"minimum_fee_per_gas\":\"100000000000.000000000000000000\",\"whitelisted_cw_code_hashes_for_delegate_call\":[],\"deliver_tx_hook_wasm_gas_limit\":\"300000\"},\"address_associations\":[{\"sei_address\":\"sei17xpfvakm2amg962yls6f84z3kell8c5la4jkdu\",\"eth_address\":\"0x27F7B8B8B5A4e71E8E9aA671f4e4031E3773303F\"}],\"codes\":[],\"states\":[],\"nonces\":[],\"serialized\":[{\"prefix\":\"Fg==\",\"key\":\"AwAC\",\"value\":\"AAAAAAAAAAM=\"},{\"prefix\":\"Fg==\",\"key\":\"BAAG\",\"value\":\"AAAAAAAAAAQ=\"}]}", jsonStr) + assert.Equal(t, "{\"params\":{\"priority_normalizer\":\"1.000000000000000000\",\"base_fee_per_gas\":\"0.000000000000000000\",\"minimum_fee_per_gas\":\"100000000000.000000000000000000\",\"whitelisted_cw_code_hashes_for_delegate_call\":[],\"deliver_tx_hook_wasm_gas_limit\":\"300000\",\"max_dynamic_base_fee_upward_adjustment\":\"0.000000000000000000\",\"max_dynamic_base_fee_downward_adjustment\":\"0.000000000000000000\"},\"address_associations\":[{\"sei_address\":\"sei17xpfvakm2amg962yls6f84z3kell8c5la4jkdu\",\"eth_address\":\"0x27F7B8B8B5A4e71E8E9aA671f4e4031E3773303F\"}],\"codes\":[],\"states\":[],\"nonces\":[],\"serialized\":[{\"prefix\":\"Fg==\",\"key\":\"AwAC\",\"value\":\"AAAAAAAAAAM=\"},{\"prefix\":\"Fg==\",\"key\":\"BAAG\",\"value\":\"AAAAAAAAAAQ=\"}]}", jsonStr) } func TestConsensusVersion(t *testing.T) { k, _ := testkeeper.MockEVMKeeper() module := evm.NewAppModule(nil, k) - assert.Equal(t, uint64(13), module.ConsensusVersion()) + assert.Equal(t, uint64(14), module.ConsensusVersion()) } func TestABCI(t *testing.T) { diff --git a/x/evm/types/keys.go b/x/evm/types/keys.go index d6e269b3f..47402aa70 100644 --- a/x/evm/types/keys.go +++ b/x/evm/types/keys.go @@ -56,6 +56,7 @@ var ( DeferredInfoPrefix = []byte{0x19} // transient LegacyBlockBloomCutoffHeightKey = []byte{0x1a} + BaseFeePerGasPrefix = []byte{0x1b} ) var ( diff --git a/x/evm/types/params.go b/x/evm/types/params.go index 45663986b..fda1a8c63 100644 --- a/x/evm/types/params.go +++ b/x/evm/types/params.go @@ -10,11 +10,13 @@ import ( ) var ( - KeyPriorityNormalizer = []byte("KeyPriorityNormalizer") - KeyBaseFeePerGas = []byte("KeyBaseFeePerGas") - KeyMinFeePerGas = []byte("KeyMinFeePerGas") - KeyDeliverTxHookWasmGasLimit = []byte("KeyDeliverTxHookWasmGasLimit") + KeyPriorityNormalizer = []byte("KeyPriorityNormalizer") + KeyMinFeePerGas = []byte("KeyMinFeePerGas") + KeyDeliverTxHookWasmGasLimit = []byte("KeyDeliverTxHookWasmGasLimit") + KeyMaxDynamicBaseFeeUpwardAdjustment = []byte("KeyMaxDynamicBaseFeeUpwardAdjustment") + KeyMaxDynamicBaseFeeDownwardAdjustment = []byte("KeyMaxDynamicBaseFeeDownwardAdjustment") // deprecated + KeyBaseFeePerGas = []byte("KeyBaseFeePerGas") KeyWhitelistedCwCodeHashesForDelegateCall = []byte("KeyWhitelistedCwCodeHashesForDelegateCall") ) @@ -23,12 +25,15 @@ var DefaultPriorityNormalizer = sdk.NewDec(1) // DefaultBaseFeePerGas determines how much usei per gas spent is // burnt rather than go to validators (similar to base fee on // Ethereum). -var DefaultBaseFeePerGas = sdk.NewDec(0) +var DefaultBaseFeePerGas = sdk.NewDec(0) // used for static base fee, deprecated in favor of dynamic base fee var DefaultMinFeePerGas = sdk.NewDec(100000000000) var DefaultDeliverTxHookWasmGasLimit = uint64(300000) var DefaultWhitelistedCwCodeHashesForDelegateCall = generateDefaultWhitelistedCwCodeHashesForDelegateCall() +var DefaultMaxDynamicBaseFeeUpwardAdjustment = sdk.NewDec(0) +var DefaultMaxDynamicBaseFeeDownwardAdjustment = sdk.NewDec(0) + var _ paramtypes.ParamSet = (*Params)(nil) func ParamKeyTable() paramtypes.KeyTable { @@ -39,6 +44,8 @@ func DefaultParams() Params { return Params{ PriorityNormalizer: DefaultPriorityNormalizer, BaseFeePerGas: DefaultBaseFeePerGas, + MaxDynamicBaseFeeUpwardAdjustment: DefaultMaxDynamicBaseFeeUpwardAdjustment, + MaxDynamicBaseFeeDownwardAdjustment: DefaultMaxDynamicBaseFeeDownwardAdjustment, MinimumFeePerGas: DefaultMinFeePerGas, DeliverTxHookWasmGasLimit: DefaultDeliverTxHookWasmGasLimit, WhitelistedCwCodeHashesForDelegateCall: DefaultWhitelistedCwCodeHashesForDelegateCall, @@ -49,6 +56,8 @@ func (p *Params) ParamSetPairs() paramtypes.ParamSetPairs { return paramtypes.ParamSetPairs{ paramtypes.NewParamSetPair(KeyPriorityNormalizer, &p.PriorityNormalizer, validatePriorityNormalizer), paramtypes.NewParamSetPair(KeyBaseFeePerGas, &p.BaseFeePerGas, validateBaseFeePerGas), + paramtypes.NewParamSetPair(KeyMaxDynamicBaseFeeUpwardAdjustment, &p.MaxDynamicBaseFeeUpwardAdjustment, validateBaseFeeAdjustment), + paramtypes.NewParamSetPair(KeyMaxDynamicBaseFeeDownwardAdjustment, &p.MaxDynamicBaseFeeDownwardAdjustment, validateBaseFeeAdjustment), paramtypes.NewParamSetPair(KeyMinFeePerGas, &p.MinimumFeePerGas, validateMinFeePerGas), paramtypes.NewParamSetPair(KeyWhitelistedCwCodeHashesForDelegateCall, &p.WhitelistedCwCodeHashesForDelegateCall, validateWhitelistedCwHashesForDelegateCall), paramtypes.NewParamSetPair(KeyDeliverTxHookWasmGasLimit, &p.DeliverTxHookWasmGasLimit, validateDeliverTxHookWasmGasLimit), @@ -71,9 +80,29 @@ func (p Params) Validate() error { if p.MinimumFeePerGas.LT(p.BaseFeePerGas) { return errors.New("minimum fee cannot be lower than base fee") } + if err := validateBaseFeeAdjustment(p.MaxDynamicBaseFeeUpwardAdjustment); err != nil { + return fmt.Errorf("invalid max dynamic base fee upward adjustment: %s, err: %s", p.MaxDynamicBaseFeeUpwardAdjustment, err) + } + if err := validateBaseFeeAdjustment(p.MaxDynamicBaseFeeDownwardAdjustment); err != nil { + return fmt.Errorf("invalid max dynamic base fee downward adjustment: %s, err: %s", p.MaxDynamicBaseFeeDownwardAdjustment, err) + } return validateWhitelistedCwHashesForDelegateCall(p.WhitelistedCwCodeHashesForDelegateCall) } +func validateBaseFeeAdjustment(i interface{}) error { + adjustment, ok := i.(sdk.Dec) + if !ok { + return fmt.Errorf("invalid parameter type: %T", i) + } + if adjustment.IsNegative() { + return fmt.Errorf("negative base fee adjustment: %s", adjustment) + } + if adjustment.GT(sdk.OneDec()) { + return fmt.Errorf("base fee adjustment must be less than or equal to 1: %s", adjustment) + } + return nil +} + func (p Params) String() string { out, _ := yaml.Marshal(p) return string(out) diff --git a/x/evm/types/params.pb.go b/x/evm/types/params.pb.go index 44d20f736..959b5b54f 100644 --- a/x/evm/types/params.pb.go +++ b/x/evm/types/params.pb.go @@ -44,8 +44,10 @@ type Params struct { // (gogoproto.moretags) = "yaml:\"whitelisted_codehashes_bank_send\"", // (gogoproto.jsontag) = "whitelisted_codehashes_bank_send" // ]; - WhitelistedCwCodeHashesForDelegateCall [][]byte `protobuf:"bytes,8,rep,name=whitelisted_cw_code_hashes_for_delegate_call,json=whitelistedCwCodeHashesForDelegateCall,proto3" json:"whitelisted_cw_code_hashes_for_delegate_call" yaml:"whitelisted_cw_code_hashes_for_delegate_call"` - DeliverTxHookWasmGasLimit uint64 `protobuf:"varint,9,opt,name=deliver_tx_hook_wasm_gas_limit,json=deliverTxHookWasmGasLimit,proto3" json:"deliver_tx_hook_wasm_gas_limit,omitempty"` + WhitelistedCwCodeHashesForDelegateCall [][]byte `protobuf:"bytes,8,rep,name=whitelisted_cw_code_hashes_for_delegate_call,json=whitelistedCwCodeHashesForDelegateCall,proto3" json:"whitelisted_cw_code_hashes_for_delegate_call" yaml:"whitelisted_cw_code_hashes_for_delegate_call"` + DeliverTxHookWasmGasLimit uint64 `protobuf:"varint,9,opt,name=deliver_tx_hook_wasm_gas_limit,json=deliverTxHookWasmGasLimit,proto3" json:"deliver_tx_hook_wasm_gas_limit,omitempty"` + MaxDynamicBaseFeeUpwardAdjustment github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,10,opt,name=max_dynamic_base_fee_upward_adjustment,json=maxDynamicBaseFeeUpwardAdjustment,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"max_dynamic_base_fee_upward_adjustment" yaml:"max_dynamic_base_fee_upward_adjustment"` + MaxDynamicBaseFeeDownwardAdjustment github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,11,opt,name=max_dynamic_base_fee_downward_adjustment,json=maxDynamicBaseFeeDownwardAdjustment,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"max_dynamic_base_fee_downward_adjustment" yaml:"max_dynamic_base_fee_downward_adjustment"` } func (m *Params) Reset() { *m = Params{} } @@ -101,37 +103,43 @@ func init() { func init() { proto.RegisterFile("evm/params.proto", fileDescriptor_9272f3679901ea94) } var fileDescriptor_9272f3679901ea94 = []byte{ - // 473 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x53, 0xcf, 0x8b, 0xd3, 0x40, - 0x14, 0x4e, 0xdc, 0xba, 0xb8, 0x41, 0xa1, 0x64, 0x05, 0x63, 0x0f, 0x49, 0xc9, 0x61, 0xe9, 0xc1, - 0x26, 0x87, 0xbd, 0xed, 0xcd, 0x76, 0xd9, 0xee, 0x41, 0x64, 0x09, 0x82, 0x20, 0xc8, 0x30, 0x4d, - 0x5e, 0x93, 0xa1, 0x33, 0x7d, 0x61, 0x26, 0xdb, 0x1f, 0xfe, 0x01, 0x9e, 0x45, 0x3c, 0x78, 0xf4, - 0x9f, 0x11, 0xf6, 0x24, 0x7b, 0x14, 0x0f, 0x41, 0xda, 0xdb, 0x1e, 0xfb, 0x17, 0x48, 0xa6, 0x5d, - 0xb7, 0x6a, 0x2f, 0xf5, 0x94, 0x97, 0xef, 0xfb, 0xde, 0xc7, 0x37, 0xef, 0xf1, 0xac, 0x3a, 0x8c, - 0x45, 0x98, 0x53, 0x49, 0x85, 0x0a, 0x72, 0x89, 0x05, 0xda, 0x8e, 0x02, 0xa6, 0xab, 0x18, 0x79, - 0xa0, 0x80, 0xc5, 0x19, 0x65, 0xa3, 0x00, 0xc6, 0xa2, 0xf1, 0x38, 0xc5, 0x14, 0x35, 0x15, 0x56, - 0xd5, 0x4a, 0xdf, 0xd0, 0x0e, 0x31, 0x8e, 0x06, 0x2c, 0x5d, 0x21, 0xfe, 0xb7, 0xfb, 0xd6, 0xfe, - 0x85, 0xb6, 0xb4, 0x3f, 0x99, 0xd6, 0x61, 0x2e, 0x19, 0x4a, 0x56, 0xcc, 0xc8, 0x08, 0xa5, 0xa0, - 0x9c, 0xbd, 0x03, 0xe9, 0xdc, 0x6b, 0x9a, 0xad, 0x83, 0x4e, 0x7c, 0x55, 0x7a, 0xc6, 0x8f, 0xd2, - 0x3b, 0x4a, 0x59, 0x91, 0x5d, 0xf6, 0x83, 0x18, 0x2b, 0x27, 0x25, 0x50, 0xad, 0x3f, 0x6d, 0x95, - 0x0c, 0xc3, 0x62, 0x96, 0x83, 0x0a, 0x4e, 0x21, 0xbe, 0x29, 0xbd, 0x6d, 0x66, 0xcb, 0xd2, 0x6b, - 0xcc, 0xa8, 0xe0, 0x27, 0xfe, 0x16, 0xd2, 0x8f, 0xec, 0x5b, 0xf4, 0xe5, 0x6f, 0xd0, 0x7e, 0x6f, - 0x5a, 0xf5, 0x3e, 0x55, 0x40, 0x06, 0x00, 0x24, 0x07, 0x49, 0x52, 0xaa, 0x9c, 0x3d, 0x9d, 0xe9, - 0xed, 0xce, 0x99, 0xfe, 0x71, 0x5a, 0x96, 0xde, 0x93, 0x55, 0xa0, 0xbf, 0x19, 0x3f, 0x7a, 0x54, - 0x41, 0x67, 0x00, 0x17, 0x20, 0x7b, 0x54, 0xd9, 0x1f, 0x4d, 0xeb, 0x50, 0xb0, 0x11, 0x13, 0x97, - 0xe2, 0x8f, 0x2c, 0xb5, 0xff, 0x9d, 0xcf, 0x16, 0xb3, 0xbb, 0xf9, 0x6c, 0x21, 0xfd, 0xa8, 0xbe, - 0x46, 0xef, 0x42, 0x7d, 0x35, 0xad, 0x67, 0x93, 0x8c, 0x15, 0xc0, 0x99, 0x2a, 0x20, 0x21, 0xf1, - 0x84, 0xc4, 0x98, 0x00, 0xc9, 0xa8, 0xca, 0x40, 0x91, 0x01, 0x4a, 0x92, 0x00, 0x87, 0x94, 0x16, - 0x40, 0x62, 0xca, 0xb9, 0xf3, 0xa0, 0xb9, 0xd7, 0x7a, 0xd8, 0x49, 0x6f, 0x4a, 0x6f, 0xa7, 0xbe, - 0x65, 0xe9, 0x1d, 0xaf, 0x82, 0xed, 0xd2, 0xe5, 0x47, 0x47, 0x1b, 0xf2, 0xee, 0xa4, 0x8b, 0x09, - 0x9c, 0x6b, 0xed, 0x19, 0xca, 0xd3, 0xb5, 0xb2, 0x4b, 0x39, 0xb7, 0x9f, 0x5b, 0x6e, 0x02, 0x9c, - 0x8d, 0x41, 0x92, 0x62, 0x4a, 0x32, 0xc4, 0x21, 0x99, 0x50, 0x25, 0xaa, 0x67, 0x13, 0xce, 0x04, - 0x2b, 0x9c, 0x83, 0xa6, 0xd9, 0xaa, 0x45, 0x4f, 0xd7, 0xaa, 0x57, 0xd3, 0x73, 0xc4, 0xe1, 0x6b, - 0xaa, 0x44, 0x8f, 0xaa, 0x17, 0x95, 0xe0, 0xa4, 0xf6, 0xf9, 0x8b, 0x67, 0x74, 0x7a, 0x57, 0x73, - 0xd7, 0xbc, 0x9e, 0xbb, 0xe6, 0xcf, 0xb9, 0x6b, 0x7e, 0x58, 0xb8, 0xc6, 0xf5, 0xc2, 0x35, 0xbe, - 0x2f, 0x5c, 0xe3, 0x4d, 0x7b, 0x63, 0x33, 0x0a, 0x58, 0xfb, 0xf6, 0x70, 0xf4, 0x8f, 0xbe, 0x9c, - 0x70, 0x1a, 0x56, 0x07, 0xa2, 0x97, 0xd4, 0xdf, 0xd7, 0xfc, 0xf1, 0xaf, 0x00, 0x00, 0x00, 0xff, - 0xff, 0x12, 0x58, 0xeb, 0xa3, 0x76, 0x03, 0x00, 0x00, + // 572 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x94, 0xc1, 0x6b, 0x13, 0x4f, + 0x14, 0xc7, 0x33, 0xbf, 0x96, 0xf2, 0xeb, 0xaa, 0x50, 0xb6, 0x82, 0x6b, 0x0f, 0xbb, 0x75, 0x85, + 0x92, 0x83, 0xc9, 0x1e, 0x7a, 0xeb, 0xad, 0x49, 0x68, 0x7a, 0x10, 0x29, 0x8b, 0x22, 0x08, 0x32, + 0x4c, 0x76, 0x5f, 0x77, 0xc7, 0xec, 0xec, 0x2c, 0x33, 0x9b, 0x6c, 0xe2, 0x1f, 0x20, 0x78, 0x10, + 0x44, 0x44, 0x3c, 0xfa, 0xcf, 0x08, 0x3d, 0xf6, 0x28, 0x82, 0x8b, 0x24, 0x78, 0xe9, 0x31, 0x7f, + 0x81, 0x64, 0xb2, 0x4d, 0x6a, 0xbb, 0x48, 0xe2, 0x29, 0x93, 0xf7, 0x3e, 0xef, 0xcd, 0xf7, 0x3b, + 0x6f, 0x79, 0xda, 0x16, 0xf4, 0x99, 0x93, 0x10, 0x41, 0x98, 0xac, 0x27, 0x82, 0xa7, 0x5c, 0x37, + 0x24, 0x50, 0x75, 0xf2, 0x78, 0x54, 0x97, 0x40, 0xbd, 0x90, 0xd0, 0xb8, 0x0e, 0x7d, 0xb6, 0x73, + 0x37, 0xe0, 0x01, 0x57, 0x29, 0x67, 0x7a, 0x9a, 0xf1, 0xf6, 0xa7, 0x4d, 0x6d, 0xe3, 0x44, 0x35, + 0xd0, 0x3f, 0x22, 0x6d, 0x3b, 0x11, 0x94, 0x0b, 0x9a, 0x0e, 0x71, 0xcc, 0x05, 0x23, 0x11, 0x7d, + 0x0d, 0xc2, 0xf8, 0x6f, 0x17, 0x55, 0x37, 0x1b, 0xde, 0x59, 0x6e, 0x55, 0xbe, 0xe7, 0xd6, 0x5e, + 0x40, 0xd3, 0xb0, 0xd7, 0xa9, 0x7b, 0x9c, 0x39, 0x1e, 0x97, 0x8c, 0xcb, 0xe2, 0xa7, 0x26, 0xfd, + 0xae, 0x93, 0x0e, 0x13, 0x90, 0xf5, 0x16, 0x78, 0x17, 0xb9, 0x55, 0xd6, 0x6c, 0x92, 0x5b, 0x3b, + 0x43, 0xc2, 0xa2, 0x03, 0xbb, 0x24, 0x69, 0xbb, 0xfa, 0x65, 0xf4, 0xc9, 0x3c, 0xa8, 0xbf, 0x41, + 0xda, 0x56, 0x87, 0x48, 0xc0, 0xa7, 0x00, 0x38, 0x01, 0x81, 0x03, 0x22, 0x8d, 0x35, 0xa5, 0xe9, + 0xe5, 0xca, 0x9a, 0x6e, 0x74, 0x9a, 0xe4, 0xd6, 0xbd, 0x99, 0xa0, 0xeb, 0x19, 0xdb, 0xbd, 0x33, + 0x0d, 0x1d, 0x01, 0x9c, 0x80, 0x68, 0x13, 0xa9, 0x7f, 0x40, 0xda, 0x36, 0xa3, 0x31, 0x65, 0x3d, + 0xf6, 0x87, 0x96, 0xf5, 0x7f, 0x7d, 0x9f, 0x92, 0x66, 0x8b, 0xf7, 0x29, 0x49, 0xda, 0xee, 0x56, + 0x11, 0x5d, 0x88, 0xfa, 0x8a, 0xb4, 0x47, 0x59, 0x48, 0x53, 0x88, 0xa8, 0x4c, 0xc1, 0xc7, 0x5e, + 0x86, 0x3d, 0xee, 0x03, 0x0e, 0x89, 0x0c, 0x41, 0xe2, 0x53, 0x2e, 0xb0, 0x0f, 0x11, 0x04, 0x24, + 0x05, 0xec, 0x91, 0x28, 0x32, 0xfe, 0xdf, 0x5d, 0xab, 0xde, 0x6e, 0x04, 0x17, 0xb9, 0xb5, 0x52, + 0xdd, 0x24, 0xb7, 0xf6, 0x67, 0xc2, 0x56, 0xa9, 0xb2, 0xdd, 0xbd, 0x2b, 0x78, 0x33, 0x6b, 0x72, + 0x1f, 0x8e, 0x15, 0x7b, 0xc4, 0x45, 0xab, 0x20, 0x9b, 0x24, 0x8a, 0xf4, 0x43, 0xcd, 0xf4, 0x21, + 0xa2, 0x7d, 0x10, 0x38, 0x1d, 0xe0, 0x90, 0xf3, 0x2e, 0xce, 0x88, 0x64, 0x53, 0xdb, 0x38, 0xa2, + 0x8c, 0xa6, 0xc6, 0xe6, 0x2e, 0xaa, 0xae, 0xbb, 0xf7, 0x0b, 0xea, 0xe9, 0xe0, 0x98, 0xf3, 0xee, + 0x73, 0x22, 0x59, 0x9b, 0xc8, 0xc7, 0x53, 0x40, 0xff, 0x81, 0xb4, 0x3d, 0x46, 0x06, 0xd8, 0x1f, + 0xc6, 0x84, 0x51, 0x0f, 0xcf, 0x07, 0xda, 0x4b, 0x32, 0x22, 0x7c, 0x4c, 0xfc, 0x57, 0x3d, 0x99, + 0x32, 0x88, 0x53, 0x43, 0x53, 0x23, 0x7b, 0x8b, 0x56, 0x9e, 0xd9, 0x92, 0x17, 0x4c, 0x72, 0xab, + 0x56, 0x8c, 0x71, 0x29, 0xde, 0x76, 0x1f, 0x30, 0x32, 0x68, 0xcd, 0xb8, 0xc6, 0xec, 0xab, 0x7b, + 0xa6, 0xa0, 0xc3, 0x39, 0xa3, 0xff, 0x42, 0x5a, 0xb5, 0xb4, 0x9d, 0xcf, 0xb3, 0xf8, 0xba, 0xc3, + 0x5b, 0xca, 0xe1, 0xbb, 0xd5, 0x1d, 0x2e, 0x7d, 0xc5, 0x24, 0xb7, 0x9c, 0xbf, 0x78, 0x2c, 0xa9, + 0xb0, 0xdd, 0x87, 0x37, 0x5c, 0xb6, 0x0a, 0x6c, 0xe1, 0xf3, 0x60, 0xfd, 0xf3, 0x17, 0xab, 0xd2, + 0x68, 0x9f, 0x8d, 0x4c, 0x74, 0x3e, 0x32, 0xd1, 0xcf, 0x91, 0x89, 0xde, 0x8f, 0xcd, 0xca, 0xf9, + 0xd8, 0xac, 0x7c, 0x1b, 0x9b, 0x95, 0x17, 0xb5, 0x2b, 0x5e, 0x24, 0xd0, 0xda, 0xe5, 0xba, 0x53, + 0x7f, 0xd4, 0xbe, 0x73, 0x06, 0xce, 0x74, 0x31, 0x2a, 0x5b, 0x9d, 0x0d, 0x95, 0xdf, 0xff, 0x1d, + 0x00, 0x00, 0xff, 0xff, 0x5f, 0xd6, 0xbc, 0x8c, 0x2c, 0x05, 0x00, 0x00, } func (m *Params) Marshal() (dAtA []byte, err error) { @@ -154,6 +162,26 @@ func (m *Params) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + { + size := m.MaxDynamicBaseFeeDownwardAdjustment.Size() + i -= size + if _, err := m.MaxDynamicBaseFeeDownwardAdjustment.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintParams(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x5a + { + size := m.MaxDynamicBaseFeeUpwardAdjustment.Size() + i -= size + if _, err := m.MaxDynamicBaseFeeUpwardAdjustment.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintParams(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x52 if m.DeliverTxHookWasmGasLimit != 0 { i = encodeVarintParams(dAtA, i, uint64(m.DeliverTxHookWasmGasLimit)) i-- @@ -233,6 +261,10 @@ func (m *Params) Size() (n int) { if m.DeliverTxHookWasmGasLimit != 0 { n += 1 + sovParams(uint64(m.DeliverTxHookWasmGasLimit)) } + l = m.MaxDynamicBaseFeeUpwardAdjustment.Size() + n += 1 + l + sovParams(uint64(l)) + l = m.MaxDynamicBaseFeeDownwardAdjustment.Size() + n += 1 + l + sovParams(uint64(l)) return n } @@ -424,6 +456,74 @@ func (m *Params) Unmarshal(dAtA []byte) error { break } } + case 10: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field MaxDynamicBaseFeeUpwardAdjustment", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowParams + } + 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 ErrInvalidLengthParams + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthParams + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.MaxDynamicBaseFeeUpwardAdjustment.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 11: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field MaxDynamicBaseFeeDownwardAdjustment", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowParams + } + 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 ErrInvalidLengthParams + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthParams + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.MaxDynamicBaseFeeDownwardAdjustment.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipParams(dAtA[iNdEx:]) diff --git a/x/evm/types/params_test.go b/x/evm/types/params_test.go index 40b7dc911..cfc9f4774 100644 --- a/x/evm/types/params_test.go +++ b/x/evm/types/params_test.go @@ -16,8 +16,9 @@ func TestDefaultParams(t *testing.T) { MinimumFeePerGas: types.DefaultMinFeePerGas, DeliverTxHookWasmGasLimit: types.DefaultDeliverTxHookWasmGasLimit, WhitelistedCwCodeHashesForDelegateCall: types.DefaultWhitelistedCwCodeHashesForDelegateCall, + MaxDynamicBaseFeeUpwardAdjustment: types.DefaultMaxDynamicBaseFeeUpwardAdjustment, + MaxDynamicBaseFeeDownwardAdjustment: types.DefaultMaxDynamicBaseFeeDownwardAdjustment, }, types.DefaultParams()) - require.Nil(t, types.DefaultParams().Validate()) } @@ -48,6 +49,34 @@ func TestBaseFeeMinimumFee(t *testing.T) { require.Contains(t, err.Error(), "minimum fee cannot be lower than base fee") } +func TestValidateParamsInvalidMaxDynamicBaseFeeUpwardAdjustment(t *testing.T) { + params := types.DefaultParams() + params.MaxDynamicBaseFeeUpwardAdjustment = sdk.NewDec(-1) // Set to invalid negative value + + err := params.Validate() + require.Error(t, err) + require.Contains(t, err.Error(), "negative base fee adjustment") + + params.MaxDynamicBaseFeeUpwardAdjustment = sdk.NewDec(2) + err = params.Validate() + require.Error(t, err) + require.Contains(t, err.Error(), "base fee adjustment must be less than or equal to 1") +} + +func TestValidateParamsInvalidMaxDynamicBaseFeeDownwardAdjustment(t *testing.T) { + params := types.DefaultParams() + params.MaxDynamicBaseFeeDownwardAdjustment = sdk.NewDec(-1) // Set to invalid negative value + + err := params.Validate() + require.Error(t, err) + require.Contains(t, err.Error(), "negative base fee adjustment") + + params.MaxDynamicBaseFeeDownwardAdjustment = sdk.NewDec(2) + err = params.Validate() + require.Error(t, err) + require.Contains(t, err.Error(), "base fee adjustment must be less than or equal to 1") +} + func TestValidateParamsInvalidDeliverTxHookWasmGasLimit(t *testing.T) { params := types.DefaultParams() params.DeliverTxHookWasmGasLimit = 0 // Set to invalid value (0)