diff --git a/app/ante/ante.go b/app/ante/ante.go index 5d22260d..201de1ac 100644 --- a/app/ante/ante.go +++ b/app/ante/ante.go @@ -1,14 +1,10 @@ package ante import ( - "fmt" "runtime/debug" log "github.com/xlab/suplog" - "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" - "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" - "github.com/cosmos/cosmos-sdk/crypto/types/multisig" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/types/tx/signing" @@ -20,9 +16,6 @@ import ( ) const ( - // TODO: Use this cost per byte through parameter or overriding NewConsumeGasForTxSizeDecorator - // which currently defaults at 10, if intended - // memoCostPerByte sdk.Gas = 3 secp256k1VerifyCost uint64 = 21000 ) @@ -30,8 +23,7 @@ const ( type AccountKeeper interface { authante.AccountKeeper NewAccountWithAddress(ctx sdk.Context, addr sdk.AccAddress) authtypes.AccountI - GetAccount(ctx sdk.Context, addr sdk.AccAddress) authtypes.AccountI - SetAccount(ctx sdk.Context, account authtypes.AccountI) + GetSequence(sdk.Context, sdk.AccAddress) (uint64, error) } // BankKeeper defines an expected keeper interface for the bank module's Keeper @@ -67,43 +59,20 @@ func NewAnteHandler( // handle as *evmtypes.MsgEthereumTx anteHandler = sdk.ChainAnteDecorators( - NewEthSetupContextDecorator(evmKeeper), // outermost AnteDecorator. EthSetUpContext must be called first - NewEthMempoolFeeDecorator(evmKeeper), - NewEthValidateBasicDecorator(), + authante.NewSetUpContextDecorator(), // outermost AnteDecorator. SetUpContext must be called first + authante.NewMempoolFeeDecorator(), + authante.NewValidateBasicDecorator(), authante.TxTimeoutHeightDecorator{}, NewEthSigVerificationDecorator(evmKeeper), - NewEthAccountSetupDecorator(ak), NewEthAccountVerificationDecorator(ak, bankKeeper, evmKeeper), NewEthNonceVerificationDecorator(ak), NewEthGasConsumeDecorator(ak, bankKeeper, evmKeeper), NewEthIncrementSenderSequenceDecorator(ak), // innermost AnteDecorator. ) - case "/ethermint.evm.v1alpha1.ExtensionOptionsWeb3Tx": - // handle as normal Cosmos SDK tx, except signature is checked for EIP712 representation - - switch tx.(type) { - case sdk.Tx: - anteHandler = sdk.ChainAnteDecorators( - authante.NewSetUpContextDecorator(), // outermost AnteDecorator. SetUpContext must be called first - authante.NewMempoolFeeDecorator(), - authante.NewValidateBasicDecorator(), - authante.TxTimeoutHeightDecorator{}, - authante.NewValidateMemoDecorator(ak), - authante.NewConsumeGasForTxSizeDecorator(ak), - authante.NewSetPubKeyDecorator(ak), // SetPubKeyDecorator must be called before all signature verification decorators - authante.NewValidateSigCountDecorator(ak), - authante.NewDeductFeeDecorator(ak, bankKeeper), - authante.NewSigGasConsumeDecorator(ak, DefaultSigVerificationGasConsumer), - authante.NewIncrementSequenceDecorator(ak), // innermost AnteDecorator - ) - default: - return ctx, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "invalid transaction type: %T", tx) - } - default: log.WithField("type_url", typeURL).Errorln("rejecting tx with unsupported extension option") - return ctx, sdkerrors.ErrUnknownExtensionOptions + return ctx, sdkerrors.Wrap(sdkerrors.ErrUnknownExtensionOptions, typeURL) } return anteHandler(ctx, tx, sim) @@ -122,6 +91,7 @@ func NewAnteHandler( authante.TxTimeoutHeightDecorator{}, authante.NewValidateMemoDecorator(ak), authante.NewConsumeGasForTxSizeDecorator(ak), + authante.NewRejectFeeGranterDecorator(), authante.NewSetPubKeyDecorator(ak), // SetPubKeyDecorator must be called before all signature verification decorators authante.NewValidateSigCountDecorator(ak), authante.NewDeductFeeDecorator(ak, bankKeeper), @@ -158,33 +128,12 @@ var _ authante.SignatureVerificationGasConsumer = DefaultSigVerificationGasConsu func DefaultSigVerificationGasConsumer( meter sdk.GasMeter, sig signing.SignatureV2, params authtypes.Params, ) error { - pubkey := sig.PubKey - switch pubkey := pubkey.(type) { - case *ed25519.PubKey: - meter.ConsumeGas(params.SigVerifyCostED25519, "ante verify: ed25519") - return nil - - case *secp256k1.PubKey: - meter.ConsumeGas(params.SigVerifyCostSecp256k1, "ante verify: secp256k1") - return nil - // support for ethereum ECDSA secp256k1 keys - case *ethsecp256k1.PubKey: + _, ok := sig.PubKey.(*ethsecp256k1.PubKey) + if ok { meter.ConsumeGas(secp256k1VerifyCost, "ante verify: eth_secp256k1") return nil - - case multisig.PubKey: - multisignature, ok := sig.Data.(*signing.MultiSignatureData) - if !ok { - return fmt.Errorf("expected %T, got, %T", &signing.MultiSignatureData{}, sig.Data) - } - err := authante.ConsumeMultisignatureVerificationGas(meter, multisignature, pubkey, params, sig.Sequence) - if err != nil { - return err - } - return nil - - default: - return sdkerrors.Wrapf(sdkerrors.ErrInvalidPubKey, "unrecognized public key type: %T", pubkey) } + + return authante.DefaultSigVerificationGasConsumer(meter, sig, params) } diff --git a/app/ante/ante_test.go b/app/ante/ante_test.go index 2c98318e..4c8838c2 100644 --- a/app/ante/ante_test.go +++ b/app/ante/ante_test.go @@ -2,310 +2,68 @@ package ante_test import ( "math/big" - "testing" - "time" - "github.com/stretchr/testify/require" - - ethcmn "github.com/ethereum/go-ethereum/common" - - tmproto "github.com/tendermint/tendermint/proto/tendermint/types" - - cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/ethereum/go-ethereum/params" - "github.com/cosmos/ethermint/app" - "github.com/cosmos/ethermint/app/ante" - "github.com/cosmos/ethermint/types" evmtypes "github.com/cosmos/ethermint/x/evm/types" ) -func requireValidTx( - t *testing.T, anteHandler sdk.AnteHandler, ctx sdk.Context, tx sdk.Tx, sim bool, -) { - _, err := anteHandler(ctx, tx, sim) - require.NoError(t, err) -} +func (suite AnteTestSuite) TestAnteHandler() { + addr, privKey := newTestAddrKey() + to, _ := newTestAddrKey() -func requireInvalidTx( - t *testing.T, anteHandler sdk.AnteHandler, ctx sdk.Context, - tx sdk.Tx, sim bool, -) { - _, err := anteHandler(ctx, tx, sim) - require.Error(t, err) -} + signedContractTx := evmtypes.NewMsgEthereumTxContract(suite.app.EvmKeeper.ChainID(), 1, big.NewInt(10), 100000, big.NewInt(1), nil, nil) + signedContractTx.From = addr.Hex() -func (suite *AnteTestSuite) TestValidEthTx() { - suite.ctx = suite.ctx.WithBlockHeight(1) + signedTx := evmtypes.NewMsgEthereumTx(suite.app.EvmKeeper.ChainID(), 2, &to, big.NewInt(10), 100000, big.NewInt(1), nil, nil) + signedTx.From = addr.Hex() - addr1, priv1 := newTestAddrKey() - addr2, _ := newTestAddrKey() + txContract := suite.CreateTestTx(signedContractTx, privKey, 1) - acc1 := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr1) - suite.app.AccountKeeper.SetAccount(suite.ctx, acc1) - err := suite.app.BankKeeper.SetBalances(suite.ctx, acc1.GetAddress(), newTestCoins()) - suite.Require().NoError(err) + suite.txBuilder = suite.clientCtx.TxConfig.NewTxBuilder() + tx := suite.CreateTestTx(signedTx, privKey, 1) - acc2 := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr2) - suite.app.AccountKeeper.SetAccount(suite.ctx, acc2) - err = suite.app.BankKeeper.SetBalances(suite.ctx, acc2.GetAddress(), newTestCoins()) - suite.Require().NoError(err) - - // require a valid Ethereum tx to pass - to := ethcmn.BytesToAddress(addr2.Bytes()) - amt := big.NewInt(32) - gas := big.NewInt(20) - ethMsg := evmtypes.NewMsgEthereumTx(suite.chainID, 0, &to, amt, 22000, gas, []byte("test"), nil) - - tx, err := suite.newTestEthTx(ethMsg, priv1) - suite.Require().NoError(err) - requireValidTx(suite.T(), suite.anteHandler, suite.ctx, tx, false) -} - -func (suite *AnteTestSuite) TestValidTx() { - suite.ctx = suite.ctx.WithBlockHeight(1) - - addr1, priv1 := newTestAddrKey() - addr2, priv2 := newTestAddrKey() - - acc1 := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr1) - suite.app.AccountKeeper.SetAccount(suite.ctx, acc1) - err := suite.app.BankKeeper.SetBalances(suite.ctx, acc1.GetAddress(), newTestCoins()) - suite.Require().NoError(err) - - acc2 := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr2) - suite.app.AccountKeeper.SetAccount(suite.ctx, acc2) - err = suite.app.BankKeeper.SetBalances(suite.ctx, acc2.GetAddress(), newTestCoins()) - suite.Require().NoError(err) - - // require a valid SDK tx to pass - fee := newTestStdFee() - msg1 := newTestMsg(addr1, addr2) - msgs := []sdk.Msg{msg1} - - privKeys := []cryptotypes.PrivKey{priv1, priv2} - accNums := []uint64{acc1.GetAccountNumber(), acc2.GetAccountNumber()} - accSeqs := []uint64{acc1.GetSequence(), acc2.GetSequence()} - - tx := newTestSDKTx(suite.ctx, msgs, privKeys, accNums, accSeqs, fee) - - requireValidTx(suite.T(), suite.anteHandler, suite.ctx, tx, false) -} - -func (suite *AnteTestSuite) TestSDKInvalidSigs() { - suite.ctx = suite.ctx.WithBlockHeight(1) - - addr1, priv1 := newTestAddrKey() - addr2, priv2 := newTestAddrKey() - addr3, priv3 := newTestAddrKey() - - acc1 := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr1) - suite.app.AccountKeeper.SetAccount(suite.ctx, acc1) - err := suite.app.BankKeeper.SetBalances(suite.ctx, acc1.GetAddress(), newTestCoins()) - suite.Require().NoError(err) - - acc2 := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr2) - suite.app.AccountKeeper.SetAccount(suite.ctx, acc2) - err = suite.app.BankKeeper.SetBalances(suite.ctx, acc2.GetAddress(), newTestCoins()) - suite.Require().NoError(err) - - fee := newTestStdFee() - msg1 := newTestMsg(addr1, addr2) - - // require validation failure with no signers - msgs := []sdk.Msg{msg1} - - privKeys := []cryptotypes.PrivKey{} - accNums := []uint64{acc1.GetAccountNumber(), acc2.GetAccountNumber()} - accSeqs := []uint64{acc1.GetSequence(), acc2.GetSequence()} - - tx := newTestSDKTx(suite.ctx, msgs, privKeys, accNums, accSeqs, fee) - requireInvalidTx(suite.T(), suite.anteHandler, suite.ctx, tx, false) - - // require validation failure with invalid number of signers - msgs = []sdk.Msg{msg1} - - privKeys = []cryptotypes.PrivKey{priv1} - accNums = []uint64{acc1.GetAccountNumber(), acc2.GetAccountNumber()} - accSeqs = []uint64{acc1.GetSequence(), acc2.GetSequence()} - - tx = newTestSDKTx(suite.ctx, msgs, privKeys, accNums, accSeqs, fee) - requireInvalidTx(suite.T(), suite.anteHandler, suite.ctx, tx, false) - - // require validation failure with an invalid signer - msg2 := newTestMsg(addr1, addr3) - msgs = []sdk.Msg{msg1, msg2} - - privKeys = []cryptotypes.PrivKey{priv1, priv2, priv3} - accNums = []uint64{acc1.GetAccountNumber(), acc2.GetAccountNumber(), 0} - accSeqs = []uint64{acc1.GetSequence(), acc2.GetSequence(), 0} - - tx = newTestSDKTx(suite.ctx, msgs, privKeys, accNums, accSeqs, fee) - requireInvalidTx(suite.T(), suite.anteHandler, suite.ctx, tx, false) -} - -func (suite *AnteTestSuite) TestSDKInvalidAcc() { - suite.ctx = suite.ctx.WithBlockHeight(1) - - addr1, priv1 := newTestAddrKey() - - acc1 := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr1) - suite.app.AccountKeeper.SetAccount(suite.ctx, acc1) - err := suite.app.BankKeeper.SetBalances(suite.ctx, acc1.GetAddress(), newTestCoins()) - suite.Require().NoError(err) - - fee := newTestStdFee() - msg1 := newTestMsg(addr1) - msgs := []sdk.Msg{msg1} - privKeys := []cryptotypes.PrivKey{priv1} - - // require validation failure with invalid account number - accNums := []uint64{1} - accSeqs := []uint64{acc1.GetSequence()} - - tx := newTestSDKTx(suite.ctx, msgs, privKeys, accNums, accSeqs, fee) - requireInvalidTx(suite.T(), suite.anteHandler, suite.ctx, tx, false) - - // require validation failure with invalid sequence (nonce) - accNums = []uint64{acc1.GetAccountNumber()} - accSeqs = []uint64{1} - - tx = newTestSDKTx(suite.ctx, msgs, privKeys, accNums, accSeqs, fee) - requireInvalidTx(suite.T(), suite.anteHandler, suite.ctx, tx, false) -} - -func (suite *AnteTestSuite) TestEthInvalidSig() { - suite.ctx = suite.ctx.WithBlockHeight(1) - - _, priv1 := newTestAddrKey() - addr2, _ := newTestAddrKey() - to := ethcmn.BytesToAddress(addr2.Bytes()) - amt := big.NewInt(32) - gas := big.NewInt(20) - ethMsg := evmtypes.NewMsgEthereumTx(suite.chainID, 0, &to, amt, 22000, gas, []byte("test"), nil) - - tx, err := suite.newTestEthTx(ethMsg, priv1) - suite.Require().NoError(err) - - ctx := suite.ctx.WithChainID("ethermint-4") - requireInvalidTx(suite.T(), suite.anteHandler, ctx, tx, false) -} - -func (suite *AnteTestSuite) TestEthInvalidNonce() { - - suite.ctx = suite.ctx.WithBlockHeight(1) - - addr1, priv1 := newTestAddrKey() - addr2, _ := newTestAddrKey() - - acc := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr1) - err := acc.SetSequence(10) - suite.Require().NoError(err) - suite.app.AccountKeeper.SetAccount(suite.ctx, acc) - err = suite.app.BankKeeper.SetBalances(suite.ctx, acc.GetAddress(), newTestCoins()) - suite.Require().NoError(err) - - // require a valid Ethereum tx to pass - to := ethcmn.BytesToAddress(addr2.Bytes()) - amt := big.NewInt(32) - gas := big.NewInt(20) - ethMsg := evmtypes.NewMsgEthereumTx(suite.chainID, 0, &to, amt, 22000, gas, []byte("test"), nil) - - tx, err := suite.newTestEthTx(ethMsg, priv1) - suite.Require().NoError(err) - requireInvalidTx(suite.T(), suite.anteHandler, suite.ctx, tx, false) -} - -func (suite *AnteTestSuite) TestEthInsufficientBalance() { - suite.ctx = suite.ctx.WithBlockHeight(1) - - addr1, priv1 := newTestAddrKey() - addr2, _ := newTestAddrKey() - - acc := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr1) + acc := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr.Bytes()) + suite.Require().NoError(acc.SetSequence(1)) suite.app.AccountKeeper.SetAccount(suite.ctx, acc) - // require a valid Ethereum tx to pass - to := ethcmn.BytesToAddress(addr2.Bytes()) - amt := big.NewInt(32) - gas := big.NewInt(20) - ethMsg := evmtypes.NewMsgEthereumTx(suite.chainID, 0, &to, amt, 22000, gas, []byte("test"), nil) - - tx, err := suite.newTestEthTx(ethMsg, priv1) + err := suite.app.BankKeeper.SetBalance(suite.ctx, addr.Bytes(), sdk.NewCoin(evmtypes.DefaultEVMDenom, sdk.NewInt(10000000000))) suite.Require().NoError(err) - requireInvalidTx(suite.T(), suite.anteHandler, suite.ctx, tx, false) -} - -func (suite *AnteTestSuite) TestEthInvalidIntrinsicGas() { - suite.ctx = suite.ctx.WithBlockHeight(1) - - addr1, priv1 := newTestAddrKey() - addr2, _ := newTestAddrKey() - - acc := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr1) - suite.app.AccountKeeper.SetAccount(suite.ctx, acc) - err := suite.app.BankKeeper.SetBalances(suite.ctx, acc.GetAddress(), newTestCoins()) - suite.Require().NoError(err) - - // require a valid Ethereum tx to pass - to := ethcmn.BytesToAddress(addr2.Bytes()) - amt := big.NewInt(32) - gas := big.NewInt(20) - gasLimit := uint64(1000) - ethMsg := evmtypes.NewMsgEthereumTx(suite.chainID, 0, &to, amt, gasLimit, gas, []byte("test"), nil) - - tx, err := suite.newTestEthTx(ethMsg, priv1) - suite.Require().NoError(err) - requireInvalidTx(suite.T(), suite.anteHandler, suite.ctx.WithIsCheckTx(true), tx, false) -} - -func (suite *AnteTestSuite) TestEthInvalidMempoolFees() { - // setup app with checkTx = true - suite.app = app.Setup(true) - suite.ctx = suite.app.BaseApp.NewContext(true, tmproto.Header{Height: 1, ChainID: "ethermint-3", Time: time.Now().UTC()}) - suite.app.EvmKeeper.SetParams(suite.ctx, evmtypes.DefaultParams()) - - suite.anteHandler = ante.NewAnteHandler(suite.app.AccountKeeper, suite.app.BankKeeper, suite.app.EvmKeeper, suite.encodingConfig.TxConfig.SignModeHandler()) - suite.ctx = suite.ctx.WithMinGasPrices(sdk.NewDecCoins(types.NewPhotonDecCoin(sdk.NewInt(500000)))) - addr1, priv1 := newTestAddrKey() - addr2, _ := newTestAddrKey() - - acc := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr1) - suite.app.AccountKeeper.SetAccount(suite.ctx, acc) - err := suite.app.BankKeeper.SetBalances(suite.ctx, acc.GetAddress(), newTestCoins()) - suite.Require().NoError(err) - - // require a valid Ethereum tx to pass - to := ethcmn.BytesToAddress(addr2.Bytes()) - amt := big.NewInt(32) - gas := big.NewInt(20) - ethMsg := evmtypes.NewMsgEthereumTx(suite.chainID, 0, &to, amt, 22000, gas, []byte("payload"), nil) - - tx, err := suite.newTestEthTx(ethMsg, priv1) - suite.Require().NoError(err) - requireInvalidTx(suite.T(), suite.anteHandler, suite.ctx, tx, false) -} - -func (suite *AnteTestSuite) TestEthInvalidChainID() { - suite.ctx = suite.ctx.WithBlockHeight(1) - - addr1, priv1 := newTestAddrKey() - addr2, _ := newTestAddrKey() - - acc := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr1) - suite.app.AccountKeeper.SetAccount(suite.ctx, acc) - err := suite.app.BankKeeper.SetBalances(suite.ctx, acc.GetAddress(), newTestCoins()) - suite.Require().NoError(err) - - // require a valid Ethereum tx to pass - to := ethcmn.BytesToAddress(addr2.Bytes()) - amt := big.NewInt(32) - gas := big.NewInt(20) - ethMsg := evmtypes.NewMsgEthereumTx(suite.chainID, 0, &to, amt, 22000, gas, []byte("test"), nil) - - tx, err := suite.newTestEthTx(ethMsg, priv1) - suite.Require().NoError(err) - - ctx := suite.ctx.WithChainID("bad-chain-id") - requireInvalidTx(suite.T(), suite.anteHandler, ctx, tx, false) + + testCases := []struct { + name string + tx sdk.Tx + checkTx bool + reCheckTx bool + expPass bool + }{ + {"success - DeliverTx (contract)", txContract, false, false, true}, + {"success - CheckTx (contract)", txContract, true, false, true}, + {"success - ReCheckTx (contract)", txContract, false, true, true}, + {"success - DeliverTx", tx, false, false, true}, + {"success - CheckTx", tx, true, false, true}, + {"success - ReCheckTx", tx, false, true, true}, + } + + for _, tc := range testCases { + suite.Run(tc.name, func() { + + suite.ctx = suite.ctx.WithIsCheckTx(tc.reCheckTx).WithIsReCheckTx(tc.reCheckTx) + + expConsumed := params.TxGasContractCreation + params.TxGas + _, err := suite.anteHandler(suite.ctx, tc.tx, false) + + // suite.Require().Equal(consumed, ctx.GasMeter().GasConsumed()) + + if tc.expPass { + suite.Require().NoError(err) + suite.Require().Equal(int(expConsumed), int(suite.ctx.GasMeter().GasConsumed())) + } else { + suite.Require().Error(err) + } + + }) + } + } diff --git a/app/ante/eth.go b/app/ante/eth.go index 01aa842c..2495c527 100644 --- a/app/ante/eth.go +++ b/app/ante/eth.go @@ -1,16 +1,12 @@ package ante import ( - "fmt" "math/big" - log "github.com/xlab/suplog" - sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" authante "github.com/cosmos/cosmos-sdk/x/auth/ante" - ethermint "github.com/cosmos/ethermint/types" evmtypes "github.com/cosmos/ethermint/x/evm/types" "github.com/ethereum/go-ethereum/common" @@ -20,158 +16,13 @@ import ( // EVMKeeper defines the expected keeper interface used on the Eth AnteHandler type EVMKeeper interface { + ChainID() *big.Int GetParams(ctx sdk.Context) evmtypes.Params GetChainConfig(ctx sdk.Context) (evmtypes.ChainConfig, bool) WithContext(ctx sdk.Context) ResetRefundTransient(ctx sdk.Context) } -// EthSetupContextDecorator sets the infinite GasMeter in the Context and wraps -// the next AnteHandler with a defer clause to recover from any downstream -// OutOfGas panics in the AnteHandler chain to return an error with information -// on gas provided and gas used. -// CONTRACT: Must be first decorator in the chain -// CONTRACT: Tx must implement GasTx interface -type EthSetupContextDecorator struct { - evmKeeper EVMKeeper -} - -// NewEthSetupContextDecorator creates a new EthSetupContextDecorator -func NewEthSetupContextDecorator(ek EVMKeeper) EthSetupContextDecorator { - return EthSetupContextDecorator{ - evmKeeper: ek, - } -} - -// AnteHandle sets the infinite gas meter to done to ignore costs in AnteHandler checks. -// This is undone at the EthGasConsumeDecorator, where the context is set with the -// ethereum tx GasLimit. -func (escd EthSetupContextDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (newCtx sdk.Context, err error) { - ctx = ctx.WithGasMeter(sdk.NewInfiniteGasMeter()) - - // reset the refund gas value for the current transaction - escd.evmKeeper.ResetRefundTransient(ctx) - - // all transactions must implement GasTx - gasTx, ok := tx.(authante.GasTx) - if !ok { - return ctx, sdkerrors.Wrap(sdkerrors.ErrTxDecode, "Tx must be GasTx") - } - - // Decorator will catch an OutOfGasPanic caused in the next antehandler - // AnteHandlers must have their own defer/recover in order for the BaseApp - // to know how much gas was used! This is because the GasMeter is created in - // the AnteHandler, but if it panics the context won't be set properly in - // runTx's recover call. - defer func() { - if r := recover(); r != nil { - switch rType := r.(type) { - case sdk.ErrorOutOfGas: - log := fmt.Sprintf( - "out of gas in location: %v; gasLimit: %d, gasUsed: %d", - rType.Descriptor, gasTx.GetGas(), ctx.GasMeter().GasConsumed(), - ) - err = sdkerrors.Wrap(sdkerrors.ErrOutOfGas, log) - default: - log.Errorln(r) - panic(r) - } - } - }() - - return next(ctx, tx, simulate) -} - -// EthMempoolFeeDecorator validates that sufficient fees have been provided that -// meet a minimum threshold defined by the proposer (for mempool purposes during CheckTx). -type EthMempoolFeeDecorator struct { - evmKeeper EVMKeeper -} - -// NewEthMempoolFeeDecorator creates a new EthMempoolFeeDecorator -func NewEthMempoolFeeDecorator(ek EVMKeeper) EthMempoolFeeDecorator { - return EthMempoolFeeDecorator{ - evmKeeper: ek, - } -} - -// AnteHandle verifies that enough fees have been provided by the -// Ethereum transaction that meet the minimum threshold set by the block -// proposer. -// -// NOTE: This should only be run during a CheckTx mode. -func (emfd EthMempoolFeeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (newCtx sdk.Context, err error) { - if !ctx.IsCheckTx() { - return next(ctx, tx, simulate) - } - - msgEthTx, ok := tx.(sdk.FeeTx) - if !ok { - return ctx, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "invalid transaction type, not implements sdk.FeeTx: %T", tx) - } - - evmDenom := emfd.evmKeeper.GetParams(ctx).EvmDenom - txFee := msgEthTx.GetFee().AmountOf(evmDenom).Int64() - if txFee < 0 { - return ctx, sdkerrors.Wrap( - sdkerrors.ErrInsufficientFee, - "negative fee not allowed", - ) - } - - // txFee = GP * GL - fee := sdk.NewInt64DecCoin(evmDenom, txFee) - - minGasPrices := ctx.MinGasPrices() - - // check that fee provided is greater than the minimum - // NOTE: we only check if injs are present in min gas prices. It is up to the - // sender if they want to send additional fees in other denominations. - var hasEnoughFees bool - if fee.Amount.GTE(minGasPrices.AmountOf(evmDenom)) { - hasEnoughFees = true - } - - // reject transaction if minimum gas price is positive and the transaction does not - // meet the minimum fee - if !ctx.MinGasPrices().IsZero() && !hasEnoughFees { - return ctx, sdkerrors.Wrap( - sdkerrors.ErrInsufficientFee, - fmt.Sprintf("insufficient fee, got: %q required: %q", fee, ctx.MinGasPrices()), - ) - } - - return next(ctx, tx, simulate) -} - -// EthValidateBasicDecorator will call tx.ValidateBasic and return any non-nil error. -// If ValidateBasic passes, decorator calls next AnteHandler in chain. Note, -// EthValidateBasicDecorator decorator will not get executed on ReCheckTx since it -// is not dependent on application state. -type EthValidateBasicDecorator struct{} - -func NewEthValidateBasicDecorator() EthValidateBasicDecorator { - return EthValidateBasicDecorator{} -} - -func (vbd EthValidateBasicDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (sdk.Context, error) { - // no need to validate basic on recheck tx, call next antehandler - if ctx.IsReCheckTx() { - return next(ctx, tx, simulate) - } - - msgEthTx, ok := getTxMsg(tx).(*evmtypes.MsgEthereumTx) - if !ok { - return ctx, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "invalid transaction type: %T", getTxMsg(tx)) - } - - if err := msgEthTx.ValidateBasic(); err != nil { - return ctx, err - } - - return next(ctx, tx, simulate) -} - // EthSigVerificationDecorator validates an ethereum signature type EthSigVerificationDecorator struct { evmKeeper EVMKeeper @@ -184,67 +35,43 @@ func NewEthSigVerificationDecorator(ek EVMKeeper) EthSigVerificationDecorator { } } -// AnteHandle validates the signature and returns sender address +// AnteHandle validates checks that the registered chain id is the same as the one on the message, and +// that the signer address matches the one defined on the message. func (esvd EthSigVerificationDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (newCtx sdk.Context, err error) { - if simulate { - // when simulating, no signatures required and the from address is explicitly set + // no need to verify signatures on recheck tx + if ctx.IsReCheckTx() { return next(ctx, tx, simulate) } - msgEthTx, ok := getTxMsg(tx).(*evmtypes.MsgEthereumTx) - if !ok { - return ctx, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "invalid transaction type: %T", getTxMsg(tx)) - } + // get and set account must be called with an infinite gas meter in order to prevent + // additional gas from being deducted. + infCtx := ctx.WithGasMeter(sdk.NewInfiniteGasMeter()) - // parse the chainID from a string to a base-10 integer - chainIDEpoch, err := ethermint.ParseChainID(ctx.ChainID()) - if err != nil { - return ctx, err - } + chainID := esvd.evmKeeper.ChainID() - config, found := esvd.evmKeeper.GetChainConfig(ctx) + config, found := esvd.evmKeeper.GetChainConfig(infCtx) if !found { return ctx, evmtypes.ErrChainConfigNotFound } - ethCfg := config.EthereumConfig(chainIDEpoch) - + ethCfg := config.EthereumConfig(chainID) blockNum := big.NewInt(ctx.BlockHeight()) signer := ethtypes.MakeSigner(ethCfg, blockNum) - chainID := signer.ChainID() - if chainIDEpoch.Cmp(chainID) != 0 { - return ctx, sdkerrors.Wrapf(sdkerrors.ErrInvalidChainID, - "EVM chain ID doesn't match the one derived from the signer (%s ≠ %s)", - chainIDEpoch.String(), chainID.String(), - ) + for _, msg := range tx.GetMsgs() { + msgEthTx, ok := msg.(*evmtypes.MsgEthereumTx) + if !ok { + return ctx, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "invalid transaction type %T, expected %T", tx, &evmtypes.MsgEthereumTx{}) + } + + if _, err := signer.Sender(msgEthTx.AsTransaction()); err != nil { + return ctx, sdkerrors.Wrap(sdkerrors.ErrorInvalidSigner, err.Error()) + } } - sender, err := signer.Sender(msgEthTx.AsTransaction()) - if err != nil { - return ctx, sdkerrors.Wrap(sdkerrors.ErrorInvalidSigner, err.Error()) - } - - // set the sender - msgEthTx.From = sender.String() - - // NOTE: when signature verification succeeds, a non-empty signer address can be - // retrieved from the transaction on the next AnteDecorators. - return next(ctx, tx, simulate) } -type noMessages struct{} - -func getTxMsg(tx sdk.Tx) interface{} { - msgs := tx.GetMsgs() - if len(msgs) == 0 { - return &noMessages{} - } - - return msgs[0] -} - // EthAccountVerificationDecorator validates an account balance checks type EthAccountVerificationDecorator struct { ak AccountKeeper @@ -267,40 +94,37 @@ func (avd EthAccountVerificationDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx return next(ctx, tx, simulate) } - msgEthTx, ok := getTxMsg(tx).(*evmtypes.MsgEthereumTx) - if !ok { - return ctx, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "invalid transaction type: %T", getTxMsg(tx)) - } + // get and set account must be called with an infinite gas meter in order to prevent + // additional gas from being deducted. + infCtx := ctx.WithGasMeter(sdk.NewInfiniteGasMeter()) - // sender address should be in the tx cache from the previous AnteHandle call - address := msgEthTx.GetFrom() - if address.Empty() { - log.Panicln("sender address cannot be empty") - } + evmDenom := avd.evmKeeper.GetParams(infCtx).EvmDenom - acc := avd.ak.GetAccount(ctx, address) - if acc == nil { - acc = avd.ak.NewAccountWithAddress(ctx, address) - avd.ak.SetAccount(ctx, acc) - } + for _, msg := range tx.GetMsgs() { + msgEthTx, ok := msg.(*evmtypes.MsgEthereumTx) + if !ok { + return ctx, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "invalid transaction type %T, expected %T", tx, &evmtypes.MsgEthereumTx{}) + } - // on InitChain make sure account number == 0 - if ctx.BlockHeight() == 0 && acc.GetAccountNumber() != 0 { - return ctx, sdkerrors.Wrapf( - sdkerrors.ErrInvalidSequence, - "invalid account number for height zero (got %d)", acc.GetAccountNumber(), - ) - } + // sender address should be in the tx cache from the previous AnteHandle call + from := msgEthTx.GetFrom() + if from.Empty() { + return ctx, sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "from address cannot be empty") + } - evmDenom := avd.evmKeeper.GetParams(ctx).EvmDenom + acc := avd.ak.GetAccount(infCtx, from) + if acc == nil { + _ = avd.ak.NewAccountWithAddress(infCtx, from) + } - // validate sender has enough funds to pay for gas cost - balance := avd.bankKeeper.GetBalance(ctx, address, evmDenom) - if balance.Amount.BigInt().Cmp(msgEthTx.Cost()) < 0 { - return ctx, sdkerrors.Wrapf( - sdkerrors.ErrInsufficientFunds, - "sender balance < tx gas cost (%s < %s%s)", balance.String(), msgEthTx.Cost().String(), evmDenom, - ) + // validate sender has enough funds to pay for gas cost + balance := avd.bankKeeper.GetBalance(infCtx, from, evmDenom) + if balance.Amount.BigInt().Cmp(msgEthTx.Cost()) < 0 { + return ctx, sdkerrors.Wrapf( + sdkerrors.ErrInsufficientFunds, + "sender balance < tx gas cost (%s < %s%s)", balance.String(), msgEthTx.Cost().String(), evmDenom, + ) + } } return next(ctx, tx, simulate) @@ -322,34 +146,36 @@ func NewEthNonceVerificationDecorator(ak AccountKeeper) EthNonceVerificationDeco // AnteHandle validates that the transaction nonce is valid (equivalent to the sender account’s // current nonce). func (nvd EthNonceVerificationDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (newCtx sdk.Context, err error) { - msgEthTx, ok := getTxMsg(tx).(*evmtypes.MsgEthereumTx) - if !ok { - return ctx, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "invalid transaction type: %T", getTxMsg(tx)) + // no need to check the nonce on ReCheckTx + if ctx.IsReCheckTx() { + return next(ctx, tx, simulate) } - // sender address should be in the tx cache from the previous AnteHandle call - address := msgEthTx.GetFrom() - if address.Empty() { - log.Panicln("sender address cannot be empty") - } + // get and set account must be called with an infinite gas meter in order to prevent + // additional gas from being deducted. + infCtx := ctx.WithGasMeter(sdk.NewInfiniteGasMeter()) - acc := nvd.ak.GetAccount(ctx, address) - if acc == nil { - return ctx, sdkerrors.Wrapf( - sdkerrors.ErrUnknownAddress, - "account %s (%s) is nil", common.BytesToAddress(address.Bytes()), address, - ) - } + for _, msg := range tx.GetMsgs() { + msgEthTx, ok := msg.(*evmtypes.MsgEthereumTx) + if !ok { + return ctx, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "invalid transaction type %T, expected %T", tx, &evmtypes.MsgEthereumTx{}) + } - seq := acc.GetSequence() - // if multiple transactions are submitted in succession with increasing nonces, - // all will be rejected except the first, since the first needs to be included in a block - // before the sequence increments - if msgEthTx.Data.Nonce != seq { - return ctx, sdkerrors.Wrapf( - sdkerrors.ErrInvalidSequence, - "invalid nonce; got %d, expected %d", msgEthTx.Data.Nonce, seq, - ) + // sender address should be in the tx cache from the previous AnteHandle call + seq, err := nvd.ak.GetSequence(infCtx, msgEthTx.GetFrom()) + if err != nil { + return ctx, err + } + + // if multiple transactions are submitted in succession with increasing nonces, + // all will be rejected except the first, since the first needs to be included in a block + // before the sequence increments + if msgEthTx.Data.Nonce != seq { + return ctx, sdkerrors.Wrapf( + sdkerrors.ErrInvalidSequence, + "invalid nonce; got %d, expected %d", msgEthTx.Data.Nonce, seq, + ) + } } return next(ctx, tx, simulate) @@ -380,69 +206,84 @@ func NewEthGasConsumeDecorator(ak AccountKeeper, bankKeeper BankKeeper, ek EVMKe // constant value of 21000 plus any cost inccured by additional bytes of data // supplied with the transaction. func (egcd EthGasConsumeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (newCtx sdk.Context, err error) { - msgEthTx, ok := getTxMsg(tx).(*evmtypes.MsgEthereumTx) - if !ok { - return ctx, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "invalid transaction type: %T", getTxMsg(tx)) + // get and set account must be called with an infinite gas meter in order to prevent + // additional gas from being deducted. + infCtx := ctx.WithGasMeter(sdk.NewInfiniteGasMeter()) + + if len(tx.GetMsgs()) != 1 { + return ctx, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "only 1 ethereum msg supported per tx, got %d", len(tx.GetMsgs())) } - // sender address should be in the tx cache from the previous AnteHandle call - address := msgEthTx.GetFrom() - if address.Empty() { - log.Panicln("sender address cannot be empty") + // reset the refund gas value for the current transaction + egcd.evmKeeper.ResetRefundTransient(infCtx) + + config, found := egcd.evmKeeper.GetChainConfig(infCtx) + if !found { + return ctx, evmtypes.ErrChainConfigNotFound } - // fetch sender account from signature - senderAcc, err := authante.GetSignerAcc(ctx, egcd.ak, address) - if err != nil { - return ctx, err - } + ethCfg := config.EthereumConfig(egcd.evmKeeper.ChainID()) - if senderAcc == nil { - return ctx, sdkerrors.Wrapf( - sdkerrors.ErrUnknownAddress, - "sender account %s (%s) is nil", common.BytesToAddress(address.Bytes()), address, - ) - } + blockHeight := big.NewInt(ctx.BlockHeight()) + homestead := ethCfg.IsHomestead(blockHeight) + istanbul := ethCfg.IsIstanbul(blockHeight) - gasLimit := msgEthTx.GetGas() + for _, msg := range tx.GetMsgs() { + msgEthTx, ok := msg.(*evmtypes.MsgEthereumTx) + if !ok { + return ctx, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "invalid transaction type %T, expected %T", tx, &evmtypes.MsgEthereumTx{}) + } - var accessList ethtypes.AccessList - if msgEthTx.Data.Accesses != nil { - accessList = *msgEthTx.Data.Accesses.ToEthAccessList() - } + isContractCreation := msgEthTx.To() == nil - gas, err := core.IntrinsicGas(msgEthTx.Data.Input, accessList, msgEthTx.To() == nil, true, false) - if err != nil { - return ctx, sdkerrors.Wrap(err, "failed to compute intrinsic gas cost") - } - - // intrinsic gas verification during CheckTx - if ctx.IsCheckTx() && gasLimit < gas { - return ctx, sdkerrors.Wrapf(sdkerrors.ErrOutOfGas, "intrinsic gas too low: %d < %d", gasLimit, gas) - } - - // Charge sender for gas up to limit - if gasLimit != 0 { - // Cost calculates the fees paid to validators based on gas limit and price - cost := new(big.Int).Mul(new(big.Int).SetBytes(msgEthTx.Data.GasPrice), new(big.Int).SetUint64(gasLimit)) - - evmDenom := egcd.evmKeeper.GetParams(ctx).EvmDenom - - feeAmt := sdk.NewCoins( - sdk.NewCoin(evmDenom, sdk.NewIntFromBigInt(cost)), - ) - - err = authante.DeductFees(egcd.bankKeeper, ctx, senderAcc, feeAmt) + // fetch sender account from signature + signerAcc, err := authante.GetSignerAcc(infCtx, egcd.ak, msgEthTx.GetFrom()) if err != nil { return ctx, err } + + gasLimit := msgEthTx.GetGas() + + var accessList ethtypes.AccessList + if msgEthTx.Data.Accesses != nil { + accessList = *msgEthTx.Data.Accesses.ToEthAccessList() + } + + intrinsicGas, err := core.IntrinsicGas(msgEthTx.Data.Input, accessList, isContractCreation, homestead, istanbul) + if err != nil { + return ctx, sdkerrors.Wrap(err, "failed to compute intrinsic gas cost") + } + + // intrinsic gas verification during CheckTx + if ctx.IsCheckTx() && gasLimit < intrinsicGas { + return ctx, sdkerrors.Wrapf(sdkerrors.ErrOutOfGas, "gas limit too low: %d (gas limit) < %d (intrinsic gas)", gasLimit, intrinsicGas) + } + + // Cost calculates the fees paid to validators based on gas limit and price + cost := msgEthTx.Fee() // fee = gas limit * gas price + + evmDenom := egcd.evmKeeper.GetParams(infCtx).EvmDenom + feeAmt := sdk.Coins{sdk.NewCoin(evmDenom, sdk.NewIntFromBigInt(cost))} + + // deduct the full gas cost from the user balance + if err := authante.DeductFees(egcd.bankKeeper, infCtx, signerAcc, feeAmt); err != nil { + return ctx, err + } + + // consume intrinsic gas for the current transaction. After runTx is executed on Baseapp, the + // application will consume gas from the block gas pool. + ctx.GasMeter().ConsumeGas(intrinsicGas, "intrinsic gas") } - // Set gas meter after ante handler to ignore gaskv costs - newCtx = authante.SetGasMeter(simulate, ctx, gasLimit) - egcd.evmKeeper.WithContext(newCtx) + // generate a copy of the gas pool (i.e block gas meter) to see if we've run out of gas for this block + // if current gas consumed is greater than the limit, this funcion panics and the error is recovered on the Baseapp + gasPool := sdk.NewGasMeter(ctx.BlockGasMeter().Limit()) + gasPool.ConsumeGas(ctx.GasMeter().GasConsumedToLimit(), "gas pool check") - return next(newCtx, tx, simulate) + // we know that we have enough gas on the pool to cover the intrinsic gas + // set up the updated context to the evm Keeper + egcd.evmKeeper.WithContext(ctx) + return next(ctx, tx, simulate) } // EthIncrementSenderSequenceDecorator increments the sequence of the signers. The @@ -465,67 +306,27 @@ func NewEthIncrementSenderSequenceDecorator(ak AccountKeeper) EthIncrementSender func (issd EthIncrementSenderSequenceDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (sdk.Context, error) { // get and set account must be called with an infinite gas meter in order to prevent // additional gas from being deducted. - gasMeter := ctx.GasMeter() - ctx = ctx.WithGasMeter(sdk.NewInfiniteGasMeter()) + infCtx := ctx.WithGasMeter(sdk.NewInfiniteGasMeter()) - msgEthTx, ok := getTxMsg(tx).(*evmtypes.MsgEthereumTx) - if !ok { - ctx = ctx.WithGasMeter(gasMeter) - return ctx, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "invalid transaction type: %T", getTxMsg(tx)) - } + for _, msg := range tx.GetMsgs() { + // increment sequence of all signers + for _, addr := range msg.GetSigners() { + acc := issd.ak.GetAccount(infCtx, addr) + if acc == nil { + return ctx, sdkerrors.Wrapf( + sdkerrors.ErrUnknownAddress, + "account %s (%s) is nil", common.BytesToAddress(addr.Bytes()), addr, + ) + } - // increment sequence of all signers - for _, addr := range msgEthTx.GetSigners() { - acc := issd.ak.GetAccount(ctx, addr) - if err := acc.SetSequence(acc.GetSequence() + 1); err != nil { - log.WithError(err).Panicln("failed to set acc sequence") + if err := acc.SetSequence(acc.GetSequence() + 1); err != nil { + return ctx, err + } + + issd.ak.SetAccount(infCtx, acc) } - issd.ak.SetAccount(ctx, acc) } // set the original gas meter - ctx = ctx.WithGasMeter(gasMeter) return next(ctx, tx, simulate) } - -// EthAccountSetupDecorator sets an account to state if it's not stored already. This only applies for MsgEthermint. -type EthAccountSetupDecorator struct { - ak AccountKeeper -} - -// NewEthAccountSetupDecorator creates a new EthAccountSetupDecorator instance -func NewEthAccountSetupDecorator(ak AccountKeeper) EthAccountSetupDecorator { - return EthAccountSetupDecorator{ - ak: ak, - } -} - -// AnteHandle sets an account for MsgEthereumTx (evm) if the sender is registered. -func (asd EthAccountSetupDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (sdk.Context, error) { - // get and set account must be called with an infinite gas meter in order to prevent - // additional gas from being deducted. - gasMeter := ctx.GasMeter() - ctx = ctx.WithGasMeter(sdk.NewInfiniteGasMeter()) - - msgEthTx, ok := getTxMsg(tx).(*evmtypes.MsgEthereumTx) - if !ok { - ctx = ctx.WithGasMeter(gasMeter) - return ctx, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "invalid transaction type: %T", getTxMsg(tx)) - } - - setupAccount(asd.ak, ctx, msgEthTx.GetFrom()) - - // set the original gas meter - ctx = ctx.WithGasMeter(gasMeter) - return next(ctx, tx, simulate) -} - -func setupAccount(ak AccountKeeper, ctx sdk.Context, addr sdk.AccAddress) { - acc := ak.GetAccount(ctx, addr) - if acc != nil { - return - } - - acc = ak.NewAccountWithAddress(ctx, addr) - ak.SetAccount(ctx, acc) -} diff --git a/app/ante/eth_test.go b/app/ante/eth_test.go new file mode 100644 index 00000000..d5d42862 --- /dev/null +++ b/app/ante/eth_test.go @@ -0,0 +1,371 @@ +package ante_test + +import ( + "math/big" + + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/cosmos/ethermint/app/ante" + "github.com/cosmos/ethermint/tests" + evmtypes "github.com/cosmos/ethermint/x/evm/types" + + ethtypes "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/params" +) + +func nextFn(ctx sdk.Context, _ sdk.Tx, _ bool) (sdk.Context, error) { + return ctx, nil +} + +func (suite AnteTestSuite) TestEthSigVerificationDecorator() { + dec := ante.NewEthSigVerificationDecorator(suite.app.EvmKeeper) + addr, privKey := newTestAddrKey() + + signedTx := evmtypes.NewMsgEthereumTxContract(suite.app.EvmKeeper.ChainID(), 1, big.NewInt(10), 1000, big.NewInt(1), nil, nil) + signedTx.From = addr.Hex() + err := signedTx.Sign(suite.app.EvmKeeper.ChainID(), tests.NewSigner(privKey)) + suite.Require().NoError(err) + + testCases := []struct { + name string + tx sdk.Tx + reCheckTx bool + expPass bool + }{ + {"ReCheckTx", nil, true, true}, + {"invalid transaction type", &invalidTx{}, false, false}, + { + "invalid sender", + evmtypes.NewMsgEthereumTx(suite.app.EvmKeeper.ChainID(), 1, &addr, big.NewInt(10), 1000, big.NewInt(1), nil, nil), + false, + false, + }, + {"successful signature verification", signedTx, false, true}, + } + + for _, tc := range testCases { + suite.Run(tc.name, func() { + consumed := suite.ctx.GasMeter().GasConsumed() + ctx, err := dec.AnteHandle(suite.ctx.WithIsReCheckTx(tc.reCheckTx), tc.tx, false, nextFn) + suite.Require().Equal(consumed, ctx.GasMeter().GasConsumed()) + + if tc.expPass { + suite.Require().NoError(err) + } else { + suite.Require().Error(err) + } + + }) + } +} + +func (suite AnteTestSuite) TestNewEthAccountVerificationDecorator() { + dec := ante.NewEthAccountVerificationDecorator( + suite.app.AccountKeeper, suite.app.BankKeeper, suite.app.EvmKeeper, + ) + + addr, _ := newTestAddrKey() + + tx := evmtypes.NewMsgEthereumTxContract(suite.app.EvmKeeper.ChainID(), 1, big.NewInt(10), 1000, big.NewInt(1), nil, nil) + tx.From = addr.Hex() + + testCases := []struct { + name string + tx sdk.Tx + malleate func() + checkTx bool + expPass bool + }{ + {"not CheckTx", nil, func() {}, false, true}, + {"invalid transaction type", &invalidTx{}, func() {}, true, false}, + { + "sender not set to msg", + evmtypes.NewMsgEthereumTxContract(suite.app.EvmKeeper.ChainID(), 1, big.NewInt(10), 1000, big.NewInt(1), nil, nil), + func() {}, + true, + false, + }, + { + "not enough balance to cover tx cost", + tx, + func() {}, + true, + false, + }, + { + "success new account", + tx, + func() { + err := suite.app.BankKeeper.SetBalance(suite.ctx, addr.Bytes(), sdk.NewCoin(evmtypes.DefaultEVMDenom, sdk.NewInt(1000000))) + suite.Require().NoError(err) + }, + true, + true, + }, + { + "success existing account", + tx, + func() { + acc := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr.Bytes()) + suite.app.AccountKeeper.SetAccount(suite.ctx, acc) + + err := suite.app.BankKeeper.SetBalance(suite.ctx, addr.Bytes(), sdk.NewCoin(evmtypes.DefaultEVMDenom, sdk.NewInt(1000000))) + suite.Require().NoError(err) + }, + true, + true, + }, + } + + for _, tc := range testCases { + suite.Run(tc.name, func() { + tc.malleate() + + consumed := suite.ctx.GasMeter().GasConsumed() + ctx, err := dec.AnteHandle(suite.ctx.WithIsCheckTx(tc.checkTx), tc.tx, false, nextFn) + suite.Require().Equal(consumed, ctx.GasMeter().GasConsumed()) + + if tc.expPass { + suite.Require().NoError(err) + } else { + suite.Require().Error(err) + } + + }) + } +} + +func (suite AnteTestSuite) TestEthNonceVerificationDecorator() { + dec := ante.NewEthNonceVerificationDecorator(suite.app.AccountKeeper) + + addr, _ := newTestAddrKey() + + tx := evmtypes.NewMsgEthereumTxContract(suite.app.EvmKeeper.ChainID(), 1, big.NewInt(10), 1000, big.NewInt(1), nil, nil) + tx.From = addr.Hex() + + testCases := []struct { + name string + tx sdk.Tx + malleate func() + reCheckTx bool + expPass bool + }{ + {"ReCheckTx", nil, func() {}, true, true}, + {"invalid transaction type", &invalidTx{}, func() {}, false, false}, + {"sender account not found", tx, func() {}, false, false}, + { + "sender nonce missmatch", + tx, + func() { + acc := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr.Bytes()) + suite.app.AccountKeeper.SetAccount(suite.ctx, acc) + }, + false, + false, + }, + { + "success", + tx, + func() { + acc := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr.Bytes()) + suite.Require().NoError(acc.SetSequence(1)) + suite.app.AccountKeeper.SetAccount(suite.ctx, acc) + }, + false, + true, + }, + } + + for _, tc := range testCases { + suite.Run(tc.name, func() { + + tc.malleate() + consumed := suite.ctx.GasMeter().GasConsumed() + ctx, err := dec.AnteHandle(suite.ctx.WithIsReCheckTx(tc.reCheckTx), tc.tx, false, nextFn) + suite.Require().Equal(consumed, ctx.GasMeter().GasConsumed()) + + if tc.expPass { + suite.Require().NoError(err) + } else { + suite.Require().Error(err) + } + + }) + } +} + +func (suite AnteTestSuite) TestEthGasConsumeDecorator() { + dec := ante.NewEthGasConsumeDecorator( + suite.app.AccountKeeper, suite.app.BankKeeper, suite.app.EvmKeeper, + ) + + addr, _ := newTestAddrKey() + + tx := evmtypes.NewMsgEthereumTxContract(suite.app.EvmKeeper.ChainID(), 1, big.NewInt(10), 1000, big.NewInt(1), nil, nil) + tx.From = addr.Hex() + + tx2 := evmtypes.NewMsgEthereumTxContract(suite.app.EvmKeeper.ChainID(), 1, big.NewInt(10), 1000000, big.NewInt(1), nil, ðtypes.AccessList{{Address: addr, StorageKeys: nil}}) + tx2.From = addr.Hex() + + testCases := []struct { + name string + tx sdk.Tx + malleate func() + expPass bool + expPanic bool + }{ + {"invalid transaction type", &invalidTx{}, func() {}, false, false}, + { + "sender not found", + evmtypes.NewMsgEthereumTxContract(suite.app.EvmKeeper.ChainID(), 1, big.NewInt(10), 1000, big.NewInt(1), nil, nil), + func() {}, + false, false, + }, + { + "gas limit too low", + tx, + func() { + acc := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr.Bytes()) + suite.app.AccountKeeper.SetAccount(suite.ctx, acc) + }, + false, false, + }, + { + "not enough balance for fees", + tx2, + func() { + acc := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr.Bytes()) + suite.app.AccountKeeper.SetAccount(suite.ctx, acc) + }, + false, false, + }, + { + "not enough tx gas", + tx2, + func() { + acc := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr.Bytes()) + suite.app.AccountKeeper.SetAccount(suite.ctx, acc) + + err := suite.app.BankKeeper.SetBalance(suite.ctx, addr.Bytes(), sdk.NewCoin(evmtypes.DefaultEVMDenom, sdk.NewInt(10000000000))) + suite.Require().NoError(err) + }, + false, true, + }, + { + "not enough block gas", + tx2, + func() { + acc := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr.Bytes()) + suite.app.AccountKeeper.SetAccount(suite.ctx, acc) + + err := suite.app.BankKeeper.SetBalance(suite.ctx, addr.Bytes(), sdk.NewCoin(evmtypes.DefaultEVMDenom, sdk.NewInt(10000000000))) + suite.Require().NoError(err) + + suite.ctx = suite.ctx.WithBlockGasMeter(sdk.NewGasMeter(1)) + }, + false, true, + }, + { + "success", + tx2, + func() { + acc := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr.Bytes()) + suite.app.AccountKeeper.SetAccount(suite.ctx, acc) + + err := suite.app.BankKeeper.SetBalance(suite.ctx, addr.Bytes(), sdk.NewCoin(evmtypes.DefaultEVMDenom, sdk.NewInt(10000000000))) + suite.Require().NoError(err) + + suite.ctx = suite.ctx.WithBlockGasMeter(sdk.NewGasMeter(10000000000000000000)) + }, + true, false, + }, + } + + for _, tc := range testCases { + suite.Run(tc.name, func() { + + tc.malleate() + + if tc.expPanic { + suite.Require().Panics(func() { + _, _ = dec.AnteHandle(suite.ctx.WithIsCheckTx(true).WithGasMeter(sdk.NewGasMeter(1)), tc.tx, false, nextFn) + }) + return + } + + consumed := suite.ctx.GasMeter().GasConsumed() + ctx, err := dec.AnteHandle(suite.ctx.WithIsCheckTx(true), tc.tx, false, nextFn) + if tc.expPass { + suite.Require().NoError(err) + suite.Require().Equal(int(params.TxGasContractCreation+params.TxAccessListAddressGas), int(ctx.GasMeter().GasConsumed()-consumed)) + } else { + suite.Require().Error(err) + } + + }) + } +} + +func (suite AnteTestSuite) TestEthIncrementSenderSequenceDecorator() { + dec := ante.NewEthIncrementSenderSequenceDecorator(suite.app.AccountKeeper) + addr, privKey := newTestAddrKey() + + signedTx := evmtypes.NewMsgEthereumTxContract(suite.app.EvmKeeper.ChainID(), 1, big.NewInt(10), 1000, big.NewInt(1), nil, nil) + signedTx.From = addr.Hex() + err := signedTx.Sign(suite.app.EvmKeeper.ChainID(), tests.NewSigner(privKey)) + suite.Require().NoError(err) + + testCases := []struct { + name string + tx sdk.Tx + malleate func() + expPass bool + expPanic bool + }{ + { + "no signers", + evmtypes.NewMsgEthereumTxContract(suite.app.EvmKeeper.ChainID(), 1, big.NewInt(10), 1000, big.NewInt(1), nil, nil), + func() {}, + false, true, + }, + { + "account not set to store", + signedTx, + func() {}, + false, false, + }, + { + "success", + signedTx, + func() { + acc := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr.Bytes()) + suite.app.AccountKeeper.SetAccount(suite.ctx, acc) + }, + true, false, + }, + } + + for _, tc := range testCases { + suite.Run(tc.name, func() { + + tc.malleate() + consumed := suite.ctx.GasMeter().GasConsumed() + + if tc.expPanic { + suite.Require().Panics(func() { + _, _ = dec.AnteHandle(suite.ctx, tc.tx, false, nextFn) + }) + return + } + + ctx, err := dec.AnteHandle(suite.ctx, tc.tx, false, nextFn) + suite.Require().Equal(consumed, ctx.GasMeter().GasConsumed()) + + if tc.expPass { + suite.Require().NoError(err) + } else { + suite.Require().Error(err) + } + }) + } +} diff --git a/app/ante/utils_test.go b/app/ante/utils_test.go index 25b203af..f7266adb 100644 --- a/app/ante/utils_test.go +++ b/app/ante/utils_test.go @@ -1,115 +1,138 @@ package ante_test import ( - "math/big" "testing" "time" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" + "github.com/stretchr/testify/suite" + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/tx" + codectypes "github.com/cosmos/cosmos-sdk/codec/types" cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" - "github.com/cosmos/cosmos-sdk/simapp/params" "github.com/cosmos/cosmos-sdk/testutil/testdata" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/auth/legacy/legacytx" + "github.com/cosmos/cosmos-sdk/types/tx/signing" + authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing" + authtx "github.com/cosmos/cosmos-sdk/x/auth/tx" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" "github.com/cosmos/ethermint/app" ante "github.com/cosmos/ethermint/app/ante" "github.com/cosmos/ethermint/crypto/ethsecp256k1" "github.com/cosmos/ethermint/tests" - ethermint "github.com/cosmos/ethermint/types" evmtypes "github.com/cosmos/ethermint/x/evm/types" - "github.com/ethereum/go-ethereum/common" - ethcrypto "github.com/ethereum/go-ethereum/crypto" - tmproto "github.com/tendermint/tendermint/proto/tendermint/types" ) type AnteTestSuite struct { suite.Suite - ctx sdk.Context - app *app.EthermintApp - encodingConfig params.EncodingConfig - anteHandler sdk.AnteHandler - chainID *big.Int + ctx sdk.Context + app *app.EthermintApp + clientCtx client.Context + txBuilder client.TxBuilder + anteHandler sdk.AnteHandler } func (suite *AnteTestSuite) SetupTest() { checkTx := false - suite.app = app.Setup(checkTx) + suite.ctx = suite.app.BaseApp.NewContext(checkTx, tmproto.Header{Height: 2, ChainID: "ethermint-1", Time: time.Now().UTC()}) + suite.ctx = suite.ctx.WithMinGasPrices(sdk.NewDecCoins(sdk.NewDecCoin(evmtypes.DefaultEVMDenom, sdk.OneInt()))) + suite.ctx = suite.ctx.WithBlockGasMeter(sdk.NewGasMeter(1000000000000000000)) + suite.app.EvmKeeper.WithChainID(suite.ctx) - suite.ctx = suite.app.BaseApp.NewContext(checkTx, tmproto.Header{Height: 2, ChainID: "ethermint-888", Time: time.Now().UTC()}) - suite.app.AccountKeeper.SetParams(suite.ctx, authtypes.DefaultParams()) - suite.app.EvmKeeper.SetParams(suite.ctx, evmtypes.DefaultParams()) + infCtx := suite.ctx.WithGasMeter(sdk.NewInfiniteGasMeter()) + suite.app.AccountKeeper.SetParams(infCtx, authtypes.DefaultParams()) + suite.app.EvmKeeper.SetParams(infCtx, evmtypes.DefaultParams()) - suite.encodingConfig = app.MakeEncodingConfig() + encodingConfig := app.MakeEncodingConfig() // We're using TestMsg amino encoding in some tests, so register it here. - suite.encodingConfig.Amino.RegisterConcrete(&testdata.TestMsg{}, "testdata.TestMsg", nil) + encodingConfig.Amino.RegisterConcrete(&testdata.TestMsg{}, "testdata.TestMsg", nil) - suite.anteHandler = ante.NewAnteHandler(suite.app.AccountKeeper, suite.app.BankKeeper, suite.app.EvmKeeper, suite.encodingConfig.TxConfig.SignModeHandler()) - suite.chainID = big.NewInt(888) + suite.clientCtx = client.Context{}.WithTxConfig(encodingConfig.TxConfig) + suite.txBuilder = suite.clientCtx.TxConfig.NewTxBuilder() + + suite.anteHandler = ante.NewAnteHandler(suite.app.AccountKeeper, suite.app.BankKeeper, suite.app.EvmKeeper, encodingConfig.TxConfig.SignModeHandler()) } func TestAnteTestSuite(t *testing.T) { suite.Run(t, new(AnteTestSuite)) } -func newTestMsg(addrs ...sdk.AccAddress) *testdata.TestMsg { - return testdata.NewTestMsg(addrs...) +// CreateTestTx is a helper function to create a tx given multiple inputs. +func (suite *AnteTestSuite) CreateTestTx( + msg *evmtypes.MsgEthereumTx, priv cryptotypes.PrivKey, accNum uint64, +) authsigning.Tx { + + option, err := codectypes.NewAnyWithValue(&evmtypes.ExtensionOptionsEthereumTx{}) + suite.Require().NoError(err) + + builder, ok := suite.txBuilder.(authtx.ExtensionOptionsTxBuilder) + suite.Require().True(ok) + + builder.SetExtensionOptions(option) + + err = msg.Sign(suite.app.EvmKeeper.ChainID(), tests.NewSigner(priv)) + suite.Require().NoError(err) + + err = builder.SetMsgs(msg) + fees := sdk.NewCoins(sdk.NewCoin(evmtypes.DefaultEVMDenom, sdk.NewIntFromBigInt(msg.Fee()))) + builder.SetFeeAmount(fees) + builder.SetGasLimit(msg.GetGas()) + + // First round: we gather all the signer infos. We use the "set empty + // signature" hack to do that. + sigV2 := signing.SignatureV2{ + PubKey: priv.PubKey(), + Data: &signing.SingleSignatureData{ + SignMode: suite.clientCtx.TxConfig.SignModeHandler().DefaultMode(), + Signature: nil, + }, + Sequence: msg.Data.Nonce, + } + + sigsV2 := []signing.SignatureV2{sigV2} + + err = suite.txBuilder.SetSignatures(sigsV2...) + suite.Require().NoError(err) + + // Second round: all signer infos are set, so each signer can sign. + + signerData := authsigning.SignerData{ + ChainID: suite.ctx.ChainID(), + AccountNumber: accNum, + Sequence: msg.Data.Nonce, + } + sigV2, err = tx.SignWithPrivKey( + suite.clientCtx.TxConfig.SignModeHandler().DefaultMode(), signerData, + suite.txBuilder, priv, suite.clientCtx.TxConfig, msg.Data.Nonce, + ) + suite.Require().NoError(err) + + sigsV2 = []signing.SignatureV2{sigV2} + + err = suite.txBuilder.SetSignatures(sigsV2...) + suite.Require().NoError(err) + + return suite.txBuilder.GetTx() } -func newTestCoins() sdk.Coins { - return sdk.NewCoins(ethermint.NewPhotonCoinInt64(500000000)) -} - -func newTestStdFee() legacytx.StdFee { - return legacytx.NewStdFee(220000, sdk.NewCoins(ethermint.NewPhotonCoinInt64(150))) -} - -// GenerateAddress generates an Ethereum address. -func newTestAddrKey() (sdk.AccAddress, cryptotypes.PrivKey) { +func newTestAddrKey() (common.Address, cryptotypes.PrivKey) { privkey, _ := ethsecp256k1.GenerateKey() - addr := ethcrypto.PubkeyToAddress(privkey.ToECDSA().PublicKey) + addr := crypto.PubkeyToAddress(privkey.ToECDSA().PublicKey) - return sdk.AccAddress(addr.Bytes()), privkey + return addr, privkey } -func newTestSDKTx( - ctx sdk.Context, msgs []sdk.Msg, privs []cryptotypes.PrivKey, - accNums []uint64, seqs []uint64, fee legacytx.StdFee, -) sdk.Tx { +var _ sdk.Tx = &invalidTx{} - sigs := make([]legacytx.StdSignature, len(privs)) - for i, priv := range privs { - signBytes := legacytx.StdSignBytes(ctx.ChainID(), accNums[i], seqs[i], 0, fee, msgs, "") +type invalidTx struct{} - sig, err := priv.Sign(signBytes) - if err != nil { - panic(err) - } - - sigs[i] = legacytx.StdSignature{ - PubKey: priv.PubKey(), - Signature: sig, - } - } - - return legacytx.NewStdTx(msgs, fee, sigs, "") -} - -func (suite *AnteTestSuite) newTestEthTx(msg *evmtypes.MsgEthereumTx, priv cryptotypes.PrivKey) (sdk.Tx, error) { - privkey := ðsecp256k1.PrivKey{Key: priv.Bytes()} - - signer := tests.NewSigner(privkey) - msg.From = common.BytesToAddress(privkey.PubKey().Address().Bytes()).String() - - if err := msg.Sign(suite.chainID, signer); err != nil { - return nil, err - } - - return msg, nil -} +func (invalidTx) GetMsgs() []sdk.Msg { return []sdk.Msg{nil} } +func (invalidTx) ValidateBasic() error { return nil } diff --git a/app/app_test.go b/app/app_test.go index a31d5c3e..a2806357 100644 --- a/app/app_test.go +++ b/app/app_test.go @@ -25,6 +25,7 @@ func TestEthermintAppExport(t *testing.T) { // Initialize the chain app.InitChain( abci.RequestInitChain{ + ChainId: "ethermint-1", Validators: []abci.ValidatorUpdate{}, AppStateBytes: stateBytes, }, diff --git a/app/test_helpers.go b/app/test_helpers.go index 23a5bf33..05f5bb64 100644 --- a/app/test_helpers.go +++ b/app/test_helpers.go @@ -47,6 +47,7 @@ func Setup(isCheckTx bool) *EthermintApp { // Initialize the chain app.InitChain( abci.RequestInitChain{ + ChainId: "ethermint-1", Validators: []abci.ValidatorUpdate{}, ConsensusParams: DefaultConsensusParams, AppStateBytes: stateBytes, diff --git a/docs/core/proto-docs.md b/docs/core/proto-docs.md index 49928ddd..2ac1422d 100644 --- a/docs/core/proto-docs.md +++ b/docs/core/proto-docs.md @@ -186,6 +186,7 @@ values, use an software upgrade procedure. | `petersburg_block` | [string](#string) | | Petersburg switch block (< 0 same as Constantinople) | | `istanbul_block` | [string](#string) | | Istanbul switch block (< 0 no fork, 0 = already on istanbul) | | `muir_glacier_block` | [string](#string) | | Eip-2384 (bomb delay) switch block (< 0 no fork, 0 = already activated) | +| `berlin_block` | [string](#string) | | Berlin switch block (< 0 = no fork, 0 = already on berlin) | | `yolo_v3_block` | [string](#string) | | YOLO v3: Gas repricings | | `ewasm_block` | [string](#string) | | EWASM switch block (< 0 no fork, 0 = already activated) | | `catalyst_block` | [string](#string) | | Catalyst switch block (< 0 = no fork, 0 = already on catalyst) | diff --git a/go.mod b/go.mod index 1cac3dbb..c1774ff4 100644 --- a/go.mod +++ b/go.mod @@ -46,9 +46,7 @@ require ( github.com/xlab/closer v0.0.0-20190328110542-03326addb7c2 github.com/xlab/suplog v1.3.0 golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a - golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4 // indirect - golang.org/x/text v0.3.5 // indirect - google.golang.org/genproto v0.0.0-20210207032614-bba0dbe2a9ea + google.golang.org/genproto v0.0.0-20210524171403-669157292da3 google.golang.org/grpc v1.38.0 gopkg.in/yaml.v2 v2.4.0 gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect diff --git a/go.sum b/go.sum index b41b99df..3c9fcd8d 100644 --- a/go.sum +++ b/go.sum @@ -945,6 +945,7 @@ golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHl golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= +golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= @@ -1063,6 +1064,7 @@ golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210316164454-77fc1eacc6aa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210420205809-ac73e9fd8988/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007 h1:gG67DSER+11cZvqIMb8S8bt0vZtiN6xWYARwirrOSfE= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1114,6 +1116,7 @@ golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapK golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200108203644-89082a384178/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200110213125-a7a6caa82ab2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1165,8 +1168,8 @@ google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20201111145450-ac7456db90a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201119123407-9b1e624d6bc4/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210114201628-6edceaf6022f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210207032614-bba0dbe2a9ea h1:N98SvVh7Hdle2lgUVFuIkf0B3u29CUakMUQa7Hwz8Wc= -google.golang.org/genproto v0.0.0-20210207032614-bba0dbe2a9ea/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210524171403-669157292da3 h1:xFyh6GBb+NO1L0xqb978I3sBPQpk6FrKO0jJGRvdj/0= +google.golang.org/genproto v0.0.0-20210524171403-669157292da3/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.19.1/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= @@ -1188,6 +1191,7 @@ google.golang.org/grpc v1.32.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.38.0 h1:/9BgsAsa5nWe26HqOlvlgJnqBuktYOLCgjCPqsa56W0= google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= diff --git a/proto/ethermint/evm/v1alpha1/evm.proto b/proto/ethermint/evm/v1alpha1/evm.proto index 70daeb47..0ad21806 100644 --- a/proto/ethermint/evm/v1alpha1/evm.proto +++ b/proto/ethermint/evm/v1alpha1/evm.proto @@ -102,21 +102,27 @@ message ChainConfig { (gogoproto.moretags) = "yaml:\"muir_glacier_block\"", (gogoproto.nullable) = false ]; +// Berlin switch block (< 0 = no fork, 0 = already on berlin) + string berlin_block = 13 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", + (gogoproto.moretags) = "yaml:\"berlin_block\"", + (gogoproto.nullable) = false + ]; // YOLO v3: Gas repricings - string yolo_v3_block = 13 [ + string yolo_v3_block = 14 [ (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", (gogoproto.moretags) = "yaml:\"yolo_v3_block\"", (gogoproto.nullable) = false ]; // EWASM switch block (< 0 no fork, 0 = already activated) - string ewasm_block = 14 [ + string ewasm_block = 15 [ (gogoproto.customname) = "EWASMBlock", (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", (gogoproto.moretags) = "yaml:\"ewasm_block\"", (gogoproto.nullable) = false ]; // Catalyst switch block (< 0 = no fork, 0 = already on catalyst) - string catalyst_block = 15 [ + string catalyst_block = 16 [ (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", (gogoproto.moretags) = "yaml:\"catalyst_block\"", (gogoproto.nullable) = false diff --git a/x/evm/genesis.go b/x/evm/genesis.go index 802b0e60..3cf021b2 100644 --- a/x/evm/genesis.go +++ b/x/evm/genesis.go @@ -16,11 +16,14 @@ import ( // InitGenesis initializes genesis state based on exported genesis func InitGenesis( ctx sdk.Context, - k keeper.Keeper, + k *keeper.Keeper, accountKeeper types.AccountKeeper, // nolint: interfacer bankKeeper types.BankKeeper, data types.GenesisState, ) []abci.ValidatorUpdate { + k.WithContext(ctx) + k.WithChainID(ctx) + k.CommitStateDB.WithContext(ctx) k.SetParams(ctx, data.Params) @@ -81,7 +84,8 @@ func InitGenesis( } // ExportGenesis exports genesis state of the EVM module -func ExportGenesis(ctx sdk.Context, k keeper.Keeper, ak types.AccountKeeper) *types.GenesisState { +func ExportGenesis(ctx sdk.Context, k *keeper.Keeper, ak types.AccountKeeper) *types.GenesisState { + k.WithContext(ctx) k.CommitStateDB.WithContext(ctx) // nolint: prealloc diff --git a/x/evm/genesis_test.go b/x/evm/genesis_test.go index bdc3b36f..9f42b2b4 100644 --- a/x/evm/genesis_test.go +++ b/x/evm/genesis_test.go @@ -10,15 +10,6 @@ import ( "github.com/cosmos/ethermint/x/evm/types" ) -func (suite *EvmTestSuite) TestExportImport() { - var genState *types.GenesisState - suite.Require().NotPanics(func() { - genState = evm.ExportGenesis(suite.ctx, *suite.app.EvmKeeper, suite.app.AccountKeeper) - }) - - _ = evm.InitGenesis(suite.ctx, *suite.app.EvmKeeper, suite.app.AccountKeeper, suite.app.BankKeeper, *genState) -} - func (suite *EvmTestSuite) TestInitGenesis() { privkey, err := ethsecp256k1.GenerateKey() suite.Require().NoError(err) @@ -100,13 +91,13 @@ func (suite *EvmTestSuite) TestInitGenesis() { if tc.expPanic { suite.Require().Panics( func() { - _ = evm.InitGenesis(suite.ctx, *suite.app.EvmKeeper, suite.app.AccountKeeper, suite.app.BankKeeper, *tc.genState) + _ = evm.InitGenesis(suite.ctx, suite.app.EvmKeeper, suite.app.AccountKeeper, suite.app.BankKeeper, *tc.genState) }, ) } else { suite.Require().NotPanics( func() { - _ = evm.InitGenesis(suite.ctx, *suite.app.EvmKeeper, suite.app.AccountKeeper, suite.app.BankKeeper, *tc.genState) + _ = evm.InitGenesis(suite.ctx, suite.app.EvmKeeper, suite.app.AccountKeeper, suite.app.BankKeeper, *tc.genState) }, ) } diff --git a/x/evm/handler_test.go b/x/evm/handler_test.go index 58db8af2..9e6f7ad1 100644 --- a/x/evm/handler_test.go +++ b/x/evm/handler_test.go @@ -46,11 +46,11 @@ func (suite *EvmTestSuite) SetupTest() { checkTx := false suite.app = app.Setup(checkTx) - suite.ctx = suite.app.BaseApp.NewContext(checkTx, tmproto.Header{Height: 1, ChainID: "ethermint-888", Time: time.Now().UTC()}) + suite.ctx = suite.app.BaseApp.NewContext(checkTx, tmproto.Header{Height: 1, ChainID: "ethermint-1", Time: time.Now().UTC()}) suite.app.EvmKeeper.CommitStateDB.WithContext(suite.ctx) suite.handler = evm.NewHandler(suite.app.EvmKeeper) suite.codec = suite.app.AppCodec() - suite.chainID = suite.chainID + suite.chainID = suite.app.EvmKeeper.ChainID() privKey, err := ethsecp256k1.GenerateKey() suite.Require().NoError(err) diff --git a/x/evm/keeper/keeper.go b/x/evm/keeper/keeper.go index 3ceee7b9..2fa7b9b5 100644 --- a/x/evm/keeper/keeper.go +++ b/x/evm/keeper/keeper.go @@ -12,6 +12,7 @@ import ( ethtypes "github.com/ethereum/go-ethereum/core/types" "github.com/tendermint/tendermint/libs/log" + ethermint "github.com/cosmos/ethermint/types" "github.com/cosmos/ethermint/x/evm/types" ) @@ -36,6 +37,8 @@ type Keeper struct { bankKeeper types.BankKeeper ctx sdk.Context + // chain ID number obtained from the context's chain id + eip155ChainID *big.Int // Ethermint concrete implementation on the EVM StateDB interface CommitStateDB *types.CommitStateDB @@ -80,6 +83,25 @@ func (k *Keeper) WithContext(ctx sdk.Context) { k.ctx = ctx } +// WithChainID sets the chain id to the local variable in the keeper +func (k *Keeper) WithChainID(ctx sdk.Context) { + chainID, err := ethermint.ParseChainID(ctx.ChainID()) + if err != nil { + panic(err) + } + + if k.eip155ChainID != nil && k.eip155ChainID.Cmp(chainID) != 0 { + panic("chain id already set") + } + + k.eip155ChainID = chainID +} + +// ChainID returns the EIP155 chain ID for the EVM context +func (k Keeper) ChainID() *big.Int { + return k.eip155ChainID +} + // ---------------------------------------------------------------------------- // Block Bloom // Required by Web3 API. diff --git a/x/evm/keeper/keeper_test.go b/x/evm/keeper/keeper_test.go index ee8ffb25..97dcba36 100644 --- a/x/evm/keeper/keeper_test.go +++ b/x/evm/keeper/keeper_test.go @@ -42,7 +42,7 @@ func (suite *KeeperTestSuite) SetupTest() { checkTx := false suite.app = app.Setup(checkTx) - suite.ctx = suite.app.BaseApp.NewContext(checkTx, tmproto.Header{Height: 1, ChainID: "ethermint-3", Time: time.Now().UTC()}) + suite.ctx = suite.app.BaseApp.NewContext(checkTx, tmproto.Header{Height: 1, ChainID: "ethermint-1", Time: time.Now().UTC()}) suite.app.EvmKeeper.CommitStateDB.WithContext(suite.ctx) suite.address = ethcmn.HexToAddress(addrHex) diff --git a/x/evm/module.go b/x/evm/module.go index 53b1a005..b15dac3f 100644 --- a/x/evm/module.go +++ b/x/evm/module.go @@ -151,13 +151,13 @@ func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONMarshaler, data j var genesisState types.GenesisState cdc.MustUnmarshalJSON(data, &genesisState) - InitGenesis(ctx, *am.keeper, am.ak, am.bk, genesisState) + InitGenesis(ctx, am.keeper, am.ak, am.bk, genesisState) return []abci.ValidatorUpdate{} } // ExportGenesis returns the exported genesis state as raw bytes for the evm // module. func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONMarshaler) json.RawMessage { - gs := ExportGenesis(ctx, *am.keeper, am.ak) + gs := ExportGenesis(ctx, am.keeper, am.ak) return cdc.MustMarshalJSON(gs) } diff --git a/x/evm/types/chain_config.go b/x/evm/types/chain_config.go index 2fa71a84..36dd8085 100644 --- a/x/evm/types/chain_config.go +++ b/x/evm/types/chain_config.go @@ -28,6 +28,7 @@ func (cc ChainConfig) EthereumConfig(chainID *big.Int) *params.ChainConfig { PetersburgBlock: getBlockValue(cc.PetersburgBlock), IstanbulBlock: getBlockValue(cc.IstanbulBlock), MuirGlacierBlock: getBlockValue(cc.MuirGlacierBlock), + BerlinBlock: getBlockValue(cc.BerlinBlock), //TODO(xlab): after upgrading ethereum to newer version, this should be set to YoloV2Block YoloV3Block: getBlockValue(cc.YoloV3Block), EWASMBlock: getBlockValue(cc.EWASMBlock), @@ -35,7 +36,7 @@ func (cc ChainConfig) EthereumConfig(chainID *big.Int) *params.ChainConfig { } } -// DefaultChainConfig returns default evm parameters. Th +// DefaultChainConfig returns default evm parameters. func DefaultChainConfig() ChainConfig { return ChainConfig{ HomesteadBlock: sdk.ZeroInt(), @@ -48,9 +49,10 @@ func DefaultChainConfig() ChainConfig { ByzantiumBlock: sdk.ZeroInt(), ConstantinopleBlock: sdk.ZeroInt(), PetersburgBlock: sdk.ZeroInt(), - IstanbulBlock: sdk.NewInt(-1), - MuirGlacierBlock: sdk.NewInt(-1), - YoloV3Block: sdk.NewInt(-1), + IstanbulBlock: sdk.ZeroInt(), + MuirGlacierBlock: sdk.ZeroInt(), + BerlinBlock: sdk.ZeroInt(), + YoloV3Block: sdk.ZeroInt(), EWASMBlock: sdk.NewInt(-1), CatalystBlock: sdk.NewInt(-1), } diff --git a/x/evm/types/evm.pb.go b/x/evm/types/evm.pb.go index b632dbc8..437af575 100644 --- a/x/evm/types/evm.pb.go +++ b/x/evm/types/evm.pb.go @@ -134,12 +134,14 @@ type ChainConfig struct { IstanbulBlock github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,11,opt,name=istanbul_block,json=istanbulBlock,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"istanbul_block" yaml:"istanbul_block"` // Eip-2384 (bomb delay) switch block (< 0 no fork, 0 = already activated) MuirGlacierBlock github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,12,opt,name=muir_glacier_block,json=muirGlacierBlock,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"muir_glacier_block" yaml:"muir_glacier_block"` + // Berlin switch block (< 0 = no fork, 0 = already on berlin) + BerlinBlock github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,13,opt,name=berlin_block,json=berlinBlock,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"berlin_block" yaml:"berlin_block"` // YOLO v3: Gas repricings - YoloV3Block github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,13,opt,name=yolo_v3_block,json=yoloV3Block,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"yolo_v3_block" yaml:"yolo_v3_block"` + YoloV3Block github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,14,opt,name=yolo_v3_block,json=yoloV3Block,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"yolo_v3_block" yaml:"yolo_v3_block"` // EWASM switch block (< 0 no fork, 0 = already activated) - EWASMBlock github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,14,opt,name=ewasm_block,json=ewasmBlock,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"ewasm_block" yaml:"ewasm_block"` + EWASMBlock github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,15,opt,name=ewasm_block,json=ewasmBlock,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"ewasm_block" yaml:"ewasm_block"` // Catalyst switch block (< 0 = no fork, 0 = already on catalyst) - CatalystBlock github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,15,opt,name=catalyst_block,json=catalystBlock,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"catalyst_block" yaml:"catalyst_block"` + CatalystBlock github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,16,opt,name=catalyst_block,json=catalystBlock,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"catalyst_block" yaml:"catalyst_block"` } func (m *ChainConfig) Reset() { *m = ChainConfig{} } @@ -668,102 +670,103 @@ func init() { func init() { proto.RegisterFile("ethermint/evm/v1alpha1/evm.proto", fileDescriptor_98f00fcca8b6b943) } var fileDescriptor_98f00fcca8b6b943 = []byte{ - // 1506 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x57, 0x4b, 0x6f, 0x1b, 0x47, - 0x12, 0x16, 0x1f, 0xa2, 0x86, 0xcd, 0x11, 0xc5, 0x6d, 0x6b, 0xb5, 0xb4, 0x8d, 0xe5, 0x70, 0x67, - 0x81, 0xb5, 0x16, 0xb0, 0x25, 0x4b, 0x86, 0xb0, 0x82, 0x81, 0x3d, 0x90, 0x96, 0x6c, 0x09, 0x96, - 0x77, 0x85, 0xb6, 0xd6, 0x5e, 0xe4, 0x42, 0x34, 0x67, 0xda, 0xc3, 0x89, 0x66, 0xa6, 0x99, 0xe9, - 0x26, 0x4d, 0x06, 0x08, 0x90, 0x63, 0x8e, 0xc9, 0x2d, 0xc7, 0x9c, 0xf3, 0x03, 0xf2, 0x1b, 0x8c, - 0x9c, 0x7c, 0x0c, 0x72, 0x98, 0x04, 0xf4, 0x4d, 0x47, 0x5e, 0x72, 0x09, 0x90, 0xa0, 0x1f, 0x43, - 0x91, 0x7a, 0x04, 0x20, 0x74, 0x62, 0x57, 0x75, 0xf5, 0xf7, 0x75, 0x55, 0x75, 0x55, 0x0d, 0x41, - 0x9d, 0xf0, 0x0e, 0x89, 0x43, 0x3f, 0xe2, 0x9b, 0xa4, 0x1f, 0x6e, 0xf6, 0xb7, 0x70, 0xd0, 0xed, - 0xe0, 0x2d, 0x21, 0x6c, 0x74, 0x63, 0xca, 0x29, 0x5c, 0x9b, 0x58, 0x6c, 0x08, 0x65, 0x6a, 0x71, - 0x67, 0xd5, 0xa3, 0x1e, 0x95, 0x26, 0x9b, 0x62, 0xa5, 0xac, 0xed, 0x5f, 0x33, 0xa0, 0x70, 0x8c, - 0x63, 0x1c, 0x32, 0xb8, 0x05, 0x8a, 0xa4, 0x1f, 0xb6, 0x5c, 0x12, 0xd1, 0xb0, 0x9a, 0xa9, 0x67, - 0xd6, 0x8b, 0xcd, 0xd5, 0x71, 0x62, 0x55, 0x86, 0x38, 0x0c, 0x1e, 0xdb, 0x93, 0x2d, 0x1b, 0x19, - 0xa4, 0x1f, 0xee, 0x89, 0x25, 0xfc, 0x37, 0x58, 0x26, 0x11, 0x6e, 0x07, 0xa4, 0xe5, 0xc4, 0x04, - 0x73, 0x52, 0xcd, 0xd6, 0x33, 0xeb, 0x46, 0xb3, 0x3a, 0x4e, 0xac, 0x55, 0x7d, 0x6c, 0x7a, 0xdb, - 0x46, 0xa6, 0x92, 0x9f, 0x48, 0x11, 0xfe, 0x0b, 0x94, 0xd2, 0x7d, 0x1c, 0x04, 0xd5, 0x9c, 0x3c, - 0xbc, 0x36, 0x4e, 0x2c, 0x38, 0x7b, 0x18, 0x07, 0x81, 0x8d, 0x80, 0x3e, 0x8a, 0x83, 0x00, 0x36, - 0x00, 0x20, 0x03, 0x1e, 0xe3, 0x16, 0xf1, 0xbb, 0xac, 0x9a, 0xaf, 0xe7, 0xd6, 0x73, 0x4d, 0x7b, - 0x94, 0x58, 0xc5, 0x7d, 0xa1, 0xdd, 0x3f, 0x3c, 0x66, 0xe3, 0xc4, 0xfa, 0x93, 0x06, 0x99, 0x18, - 0xda, 0xa8, 0x28, 0x85, 0x7d, 0xbf, 0xcb, 0x1e, 0xe7, 0xbf, 0xfe, 0xc6, 0x5a, 0xb0, 0xbf, 0x5b, - 0x06, 0xa5, 0x27, 0x1d, 0xec, 0x47, 0x4f, 0x68, 0xf4, 0xc6, 0xf7, 0xe0, 0x27, 0x60, 0xa5, 0x43, - 0x43, 0xc2, 0x38, 0xc1, 0x6e, 0xab, 0x1d, 0x50, 0xe7, 0x54, 0x47, 0xe2, 0xe0, 0x5d, 0x62, 0x2d, - 0xfc, 0x98, 0x58, 0xff, 0xf0, 0x7c, 0xde, 0xe9, 0xb5, 0x37, 0x1c, 0x1a, 0x6e, 0x3a, 0x94, 0x85, - 0x94, 0xe9, 0x9f, 0x07, 0xcc, 0x3d, 0xdd, 0xe4, 0xc3, 0x2e, 0x61, 0x1b, 0x87, 0x11, 0x1f, 0x27, - 0xd6, 0x9a, 0xa2, 0xbf, 0x00, 0x67, 0xa3, 0xf2, 0x44, 0xd3, 0x14, 0x0a, 0xf8, 0x19, 0x28, 0xbb, - 0x98, 0xb6, 0xde, 0xd0, 0xf8, 0x54, 0x33, 0x66, 0x25, 0xe3, 0xeb, 0xf9, 0x18, 0x47, 0x89, 0x65, - 0xee, 0x35, 0xfe, 0xfb, 0x94, 0xc6, 0xa7, 0x12, 0x77, 0x9c, 0x58, 0x7f, 0x56, 0x37, 0x98, 0x45, - 0xb7, 0x91, 0xe9, 0x62, 0x3a, 0x31, 0x83, 0xaf, 0x41, 0x65, 0x62, 0xc0, 0x7a, 0xdd, 0x2e, 0x8d, - 0xb9, 0x4e, 0xc4, 0x83, 0x51, 0x62, 0x95, 0x35, 0xe4, 0x4b, 0xb5, 0x33, 0x4e, 0xac, 0xbf, 0x5c, - 0x00, 0xd5, 0x67, 0x6c, 0x54, 0xd6, 0xb0, 0xda, 0x14, 0xbe, 0x05, 0x26, 0xf1, 0xbb, 0x5b, 0x3b, - 0x0f, 0xb5, 0x57, 0x79, 0xe9, 0xd5, 0xc9, 0xdc, 0x5e, 0x95, 0xf6, 0x0f, 0x8f, 0xb7, 0x76, 0x1e, - 0xa6, 0x4e, 0xdd, 0xd2, 0x59, 0x9d, 0x82, 0xb6, 0x51, 0x49, 0x89, 0xca, 0xa3, 0x43, 0xa0, 0xc5, - 0x56, 0x07, 0xb3, 0x4e, 0x75, 0x51, 0xf2, 0xae, 0x8f, 0x12, 0x0b, 0x28, 0xa4, 0x03, 0xcc, 0x3a, - 0xe7, 0xf9, 0x69, 0x0f, 0x3f, 0xc5, 0x11, 0xf7, 0x7b, 0x61, 0x8a, 0x05, 0xd4, 0x61, 0x61, 0x35, - 0xf1, 0x61, 0x47, 0xfb, 0x50, 0xb8, 0x91, 0x0f, 0x3b, 0x57, 0xf9, 0xb0, 0x33, 0xeb, 0x83, 0xb2, - 0x99, 0x10, 0xef, 0x6a, 0xe2, 0xa5, 0x1b, 0x11, 0xef, 0x5e, 0x45, 0xbc, 0x3b, 0x4b, 0xac, 0x6c, - 0x44, 0x01, 0x5c, 0x88, 0x48, 0xd5, 0xb8, 0x59, 0x01, 0x5c, 0x0a, 0x70, 0x79, 0xa2, 0x51, 0x94, - 0x9f, 0x67, 0xc0, 0xaa, 0x43, 0x23, 0xc6, 0x85, 0x32, 0xa2, 0xdd, 0x80, 0x68, 0xe2, 0xa2, 0x24, - 0x7e, 0x31, 0x37, 0xf1, 0x5d, 0x45, 0x7c, 0x15, 0xa6, 0x8d, 0x6e, 0xcd, 0xaa, 0xd5, 0x15, 0x38, - 0xa8, 0x74, 0x09, 0x27, 0x31, 0x6b, 0xf7, 0x62, 0x4f, 0xb3, 0x03, 0xc9, 0x7e, 0x38, 0x37, 0xbb, - 0x2e, 0x90, 0x8b, 0x78, 0x36, 0x5a, 0x39, 0x57, 0x29, 0xd6, 0x08, 0x94, 0x7d, 0x71, 0x95, 0x76, - 0x2f, 0xd0, 0x9c, 0x25, 0xc9, 0xf9, 0x6c, 0x6e, 0x4e, 0x5d, 0xe9, 0xb3, 0x68, 0x36, 0x5a, 0x4e, - 0x15, 0x8a, 0x6f, 0x08, 0x60, 0xd8, 0xf3, 0xe3, 0x96, 0x17, 0x60, 0xc7, 0x27, 0xb1, 0xe6, 0x34, - 0x25, 0xe7, 0xf3, 0xb9, 0x39, 0x6f, 0x2b, 0xce, 0xcb, 0x88, 0x36, 0xaa, 0x08, 0xe5, 0x33, 0xa5, - 0x53, 0xd4, 0x1f, 0x83, 0xe5, 0x21, 0x0d, 0x68, 0xab, 0xff, 0x48, 0xb3, 0x2e, 0x4b, 0xd6, 0xa7, - 0x73, 0xb3, 0xea, 0xb1, 0x32, 0x03, 0x66, 0xa3, 0x92, 0x90, 0x5f, 0x3d, 0x52, 0x5c, 0x0c, 0x94, - 0xc8, 0x5b, 0xcc, 0xd2, 0xe7, 0x5b, 0x96, 0x4c, 0x68, 0xee, 0xd2, 0x01, 0xfb, 0xaf, 0x1b, 0x2f, - 0x5f, 0xa4, 0x95, 0x93, 0x4e, 0xa4, 0x73, 0x60, 0xd1, 0x29, 0x84, 0x34, 0xc9, 0xa5, 0x83, 0x39, - 0x0e, 0x86, 0x8c, 0x6b, 0xde, 0x95, 0x9b, 0xe5, 0x72, 0x16, 0xcd, 0x46, 0xcb, 0xa9, 0x42, 0xf2, - 0xd9, 0x9b, 0x60, 0xf1, 0x25, 0x17, 0x33, 0xb4, 0x02, 0x72, 0xa7, 0x64, 0xa8, 0xa6, 0x14, 0x12, - 0x4b, 0xb8, 0x0a, 0x16, 0xfb, 0x38, 0xe8, 0xa9, 0x61, 0x5c, 0x44, 0x4a, 0xb0, 0x5f, 0x81, 0x95, - 0x93, 0x18, 0x47, 0x0c, 0x3b, 0xdc, 0xa7, 0xd1, 0x11, 0xf5, 0x18, 0x84, 0x20, 0x2f, 0x3b, 0xa4, - 0x3a, 0x2b, 0xd7, 0x70, 0x13, 0xe4, 0x03, 0xea, 0xb1, 0x6a, 0xb6, 0x9e, 0x5b, 0x2f, 0x6d, 0xdf, - 0xdd, 0xb8, 0xfa, 0x63, 0x62, 0xe3, 0x88, 0x7a, 0x48, 0x1a, 0xda, 0xdf, 0x67, 0x41, 0xee, 0x88, - 0x7a, 0xb0, 0x0a, 0x96, 0xb0, 0xeb, 0xc6, 0x84, 0x31, 0x8d, 0x97, 0x8a, 0x70, 0x0d, 0x14, 0x38, - 0xed, 0xfa, 0x8e, 0x02, 0x2d, 0x22, 0x2d, 0x09, 0x7a, 0x17, 0x73, 0x2c, 0xa7, 0x8d, 0x89, 0xe4, - 0x1a, 0x6e, 0x03, 0x53, 0xfa, 0xdb, 0x8a, 0x7a, 0x61, 0x9b, 0xc4, 0x72, 0x68, 0xe4, 0x9b, 0x2b, - 0x67, 0x89, 0x55, 0x92, 0xfa, 0xff, 0x48, 0x35, 0x9a, 0x16, 0xe0, 0x7d, 0xb0, 0xc4, 0x07, 0xd3, - 0xbd, 0xfe, 0xd6, 0x59, 0x62, 0xad, 0xf0, 0x73, 0x67, 0x45, 0x2b, 0x47, 0x05, 0x3e, 0x38, 0x50, - 0x0e, 0x1a, 0x7c, 0xd0, 0xf2, 0x23, 0x97, 0x0c, 0x64, 0x3b, 0xcf, 0x37, 0x57, 0xcf, 0x12, 0xab, - 0x32, 0x65, 0x7e, 0x28, 0xf6, 0xd0, 0x12, 0x1f, 0xc8, 0x05, 0xbc, 0x0f, 0x80, 0xba, 0x92, 0x64, - 0x50, 0x8d, 0x78, 0xf9, 0x2c, 0xb1, 0x8a, 0x52, 0x2b, 0xb1, 0xcf, 0x97, 0xd0, 0x06, 0x8b, 0x0a, - 0xdb, 0x90, 0xd8, 0xe6, 0x59, 0x62, 0x19, 0x01, 0xf5, 0x14, 0xa6, 0xda, 0x12, 0xa1, 0x8a, 0x49, - 0x48, 0xfb, 0xc4, 0x95, 0x2d, 0xce, 0x40, 0xa9, 0x68, 0xff, 0x96, 0x01, 0xc5, 0x93, 0x01, 0x22, - 0x0e, 0xf1, 0xbb, 0xfc, 0xca, 0xfc, 0x40, 0x90, 0x7f, 0x13, 0xd3, 0x50, 0xe7, 0x56, 0xae, 0xe1, - 0xf6, 0x54, 0x20, 0x4b, 0xdb, 0xb5, 0xeb, 0x72, 0x76, 0x32, 0xd8, 0xc3, 0x1c, 0xeb, 0x40, 0xef, - 0x82, 0x42, 0x4c, 0x58, 0x2f, 0xe0, 0x32, 0xc4, 0xa5, 0xed, 0xfa, 0xf5, 0xa7, 0x90, 0xb4, 0x43, - 0xda, 0x5e, 0x3c, 0x2f, 0xe5, 0xa1, 0x08, 0x76, 0x3e, 0xf5, 0xe9, 0x6f, 0x69, 0xe2, 0x3a, 0xc4, - 0xf7, 0x3a, 0x5c, 0x85, 0x56, 0xe7, 0xe9, 0x40, 0xaa, 0xe0, 0x5f, 0x2f, 0x07, 0x72, 0x2a, 0x72, - 0x8f, 0xf3, 0x5f, 0x88, 0x0f, 0xb2, 0xaf, 0xb2, 0xc0, 0x48, 0x29, 0xe1, 0x53, 0x50, 0x71, 0x68, - 0xc4, 0x63, 0xec, 0xf0, 0xd6, 0xcc, 0xe3, 0x6a, 0xde, 0x3d, 0x6f, 0xb4, 0x17, 0x2d, 0x6c, 0xb4, - 0x92, 0xaa, 0x1a, 0xfa, 0x05, 0xae, 0x82, 0xc5, 0x76, 0x40, 0x75, 0xd4, 0x4c, 0xa4, 0x04, 0xf8, - 0x7f, 0xf9, 0x6e, 0xe4, 0x6b, 0x57, 0x91, 0xbb, 0x77, 0x6d, 0x0c, 0x66, 0x0b, 0xa7, 0xb9, 0x26, - 0x8a, 0x7a, 0x9c, 0x58, 0x65, 0x75, 0x03, 0x8d, 0x62, 0x8b, 0x37, 0x26, 0x0b, 0xab, 0x02, 0x72, - 0x31, 0x51, 0x91, 0x35, 0x91, 0x58, 0xc2, 0x3b, 0xc0, 0x88, 0x49, 0x9f, 0xc4, 0x9c, 0xb8, 0x32, - 0x6e, 0x06, 0x9a, 0xc8, 0xf0, 0x36, 0x30, 0x3c, 0xcc, 0x5a, 0x3d, 0x46, 0x5c, 0x1d, 0xb6, 0x25, - 0x0f, 0xb3, 0xff, 0x31, 0xe2, 0xea, 0x98, 0xfc, 0x92, 0x05, 0x05, 0x95, 0x3c, 0xb8, 0x05, 0x0c, - 0x47, 0x7c, 0xae, 0xb6, 0x7c, 0x57, 0x46, 0xc2, 0x6c, 0xae, 0x8d, 0x12, 0x6b, 0x49, 0x7e, 0xc2, - 0x1e, 0xee, 0x9d, 0x25, 0xd6, 0x92, 0xa3, 0x96, 0x48, 0x2f, 0x5c, 0xe1, 0x7c, 0x44, 0x23, 0x47, - 0xb5, 0x83, 0x3c, 0x52, 0x02, 0xfc, 0x27, 0x28, 0x0a, 0xd2, 0x6e, 0xec, 0x3b, 0x44, 0x55, 0x60, - 0xd3, 0x1c, 0x25, 0x96, 0xf1, 0x0c, 0xb3, 0x63, 0xa1, 0x43, 0xe2, 0x4e, 0x72, 0x05, 0x6b, 0x20, - 0xe7, 0x61, 0xa6, 0x4b, 0x31, 0x35, 0x3a, 0xf2, 0x43, 0x9f, 0x23, 0xb1, 0x01, 0xcb, 0x20, 0xcb, - 0xa9, 0x2a, 0x3d, 0x94, 0xe5, 0x14, 0xd6, 0xd3, 0xfe, 0x53, 0x90, 0xb0, 0x60, 0x94, 0x58, 0x85, - 0x46, 0x48, 0x7b, 0x11, 0xd7, 0xbd, 0x48, 0x3d, 0xa1, 0x6e, 0x8f, 0xcb, 0x47, 0x60, 0x22, 0x25, - 0x40, 0x0c, 0x0c, 0xec, 0x38, 0x84, 0x31, 0xc2, 0xaa, 0x86, 0x6c, 0x3f, 0x7f, 0xbf, 0x2e, 0x21, - 0x0d, 0x69, 0x77, 0xd2, 0x13, 0x03, 0xbc, 0x2e, 0x92, 0x71, 0x96, 0x58, 0x40, 0x1d, 0x3e, 0xf2, - 0x19, 0xff, 0xf6, 0x27, 0x0b, 0x34, 0x26, 0x12, 0x9a, 0xc0, 0x42, 0x13, 0x64, 0xfa, 0xb2, 0xe6, - 0x4c, 0x94, 0xe9, 0x0b, 0x29, 0x96, 0x63, 0xde, 0x44, 0x99, 0x58, 0x48, 0x4c, 0x0e, 0x60, 0x13, - 0x65, 0x98, 0x8e, 0xfc, 0x3d, 0x50, 0x6c, 0x0e, 0x39, 0x91, 0x30, 0xf2, 0x15, 0x09, 0xa1, 0x9a, - 0xa9, 0xe7, 0xe4, 0x2b, 0x12, 0x82, 0x36, 0xc4, 0xa0, 0x34, 0x75, 0xa7, 0x3f, 0x68, 0x86, 0xdb, - 0xc0, 0x64, 0x9c, 0xc6, 0xd8, 0x23, 0xad, 0x53, 0x32, 0xd4, 0x2d, 0x51, 0x35, 0x38, 0xad, 0x7f, - 0x4e, 0x86, 0x0c, 0x4d, 0x0b, 0x8a, 0xa2, 0xd9, 0x78, 0x37, 0xaa, 0x65, 0xde, 0x8f, 0x6a, 0x99, - 0x9f, 0x47, 0xb5, 0xcc, 0x97, 0x1f, 0x6a, 0x0b, 0xef, 0x3f, 0xd4, 0x16, 0x7e, 0xf8, 0x50, 0x5b, - 0xf8, 0xe8, 0xde, 0xe5, 0xd9, 0x72, 0xfe, 0x2f, 0x71, 0x20, 0xff, 0x27, 0xca, 0x01, 0xd3, 0x2e, - 0xc8, 0xff, 0x7c, 0x8f, 0x7e, 0x0f, 0x00, 0x00, 0xff, 0xff, 0xf2, 0x3d, 0x7c, 0x52, 0x45, 0x0e, - 0x00, 0x00, + // 1527 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x57, 0xbd, 0x6f, 0x1b, 0x47, + 0x16, 0x17, 0x3f, 0x44, 0x2d, 0x87, 0x2b, 0x8a, 0x37, 0xd6, 0xe9, 0x68, 0x1b, 0xc7, 0xe5, 0xed, + 0x01, 0x67, 0x1d, 0x60, 0x4b, 0x96, 0x0c, 0xe1, 0x04, 0x03, 0x57, 0x90, 0x96, 0x6c, 0x09, 0x96, + 0xef, 0x84, 0xb1, 0xce, 0x3e, 0xa4, 0x21, 0x86, 0xbb, 0xe3, 0xe5, 0x46, 0xbb, 0x3b, 0xcc, 0xce, + 0x90, 0x26, 0x03, 0x04, 0x48, 0x99, 0x32, 0xe9, 0x52, 0xba, 0xce, 0x5f, 0x62, 0xa4, 0x72, 0x19, + 0xa4, 0xd8, 0x04, 0x74, 0xa7, 0x92, 0x4d, 0x9a, 0x00, 0x09, 0xe6, 0x63, 0x29, 0x52, 0x1f, 0x01, + 0x08, 0x55, 0x9c, 0xf7, 0xe6, 0xcd, 0xef, 0x37, 0xef, 0xcd, 0xfb, 0x58, 0x82, 0x3a, 0xe1, 0x1d, + 0x12, 0x87, 0x7e, 0xc4, 0x37, 0x49, 0x3f, 0xdc, 0xec, 0x6f, 0xe1, 0xa0, 0xdb, 0xc1, 0x5b, 0x42, + 0xd8, 0xe8, 0xc6, 0x94, 0x53, 0xb8, 0x36, 0xb1, 0xd8, 0x10, 0xca, 0xd4, 0xe2, 0xce, 0xaa, 0x47, + 0x3d, 0x2a, 0x4d, 0x36, 0xc5, 0x4a, 0x59, 0xdb, 0xbf, 0x66, 0x40, 0xe1, 0x18, 0xc7, 0x38, 0x64, + 0x70, 0x0b, 0x14, 0x49, 0x3f, 0x6c, 0xb9, 0x24, 0xa2, 0x61, 0x35, 0x53, 0xcf, 0xac, 0x17, 0x9b, + 0xab, 0xe3, 0xc4, 0xaa, 0x0c, 0x71, 0x18, 0x3c, 0xb6, 0x27, 0x5b, 0x36, 0x32, 0x48, 0x3f, 0xdc, + 0x13, 0x4b, 0xf8, 0x6f, 0xb0, 0x4c, 0x22, 0xdc, 0x0e, 0x48, 0xcb, 0x89, 0x09, 0xe6, 0xa4, 0x9a, + 0xad, 0x67, 0xd6, 0x8d, 0x66, 0x75, 0x9c, 0x58, 0xab, 0xfa, 0xd8, 0xf4, 0xb6, 0x8d, 0x4c, 0x25, + 0x3f, 0x91, 0x22, 0xfc, 0x17, 0x28, 0xa5, 0xfb, 0x38, 0x08, 0xaa, 0x39, 0x79, 0x78, 0x6d, 0x9c, + 0x58, 0x70, 0xf6, 0x30, 0x0e, 0x02, 0x1b, 0x01, 0x7d, 0x14, 0x07, 0x01, 0x6c, 0x00, 0x40, 0x06, + 0x3c, 0xc6, 0x2d, 0xe2, 0x77, 0x59, 0x35, 0x5f, 0xcf, 0xad, 0xe7, 0x9a, 0xf6, 0x28, 0xb1, 0x8a, + 0xfb, 0x42, 0xbb, 0x7f, 0x78, 0xcc, 0xc6, 0x89, 0xf5, 0x27, 0x0d, 0x32, 0x31, 0xb4, 0x51, 0x51, + 0x0a, 0xfb, 0x7e, 0x97, 0x3d, 0xce, 0x7f, 0xfb, 0xce, 0x5a, 0xb0, 0xdf, 0x95, 0x41, 0xe9, 0x49, + 0x07, 0xfb, 0xd1, 0x13, 0x1a, 0xbd, 0xf1, 0x3d, 0xf8, 0x19, 0x58, 0xe9, 0xd0, 0x90, 0x30, 0x4e, + 0xb0, 0xdb, 0x6a, 0x07, 0xd4, 0x39, 0xd5, 0x91, 0x38, 0x78, 0x9f, 0x58, 0x0b, 0x3f, 0x26, 0xd6, + 0x3f, 0x3c, 0x9f, 0x77, 0x7a, 0xed, 0x0d, 0x87, 0x86, 0x9b, 0x0e, 0x65, 0x21, 0x65, 0xfa, 0xe7, + 0x01, 0x73, 0x4f, 0x37, 0xf9, 0xb0, 0x4b, 0xd8, 0xc6, 0x61, 0xc4, 0xc7, 0x89, 0xb5, 0xa6, 0xe8, + 0x2f, 0xc0, 0xd9, 0xa8, 0x3c, 0xd1, 0x34, 0x85, 0x02, 0x7e, 0x01, 0xca, 0x2e, 0xa6, 0xad, 0x37, + 0x34, 0x3e, 0xd5, 0x8c, 0x59, 0xc9, 0xf8, 0x7a, 0x3e, 0xc6, 0x51, 0x62, 0x99, 0x7b, 0x8d, 0xff, + 0x3e, 0xa5, 0xf1, 0xa9, 0xc4, 0x1d, 0x27, 0xd6, 0x9f, 0xd5, 0x0d, 0x66, 0xd1, 0x6d, 0x64, 0xba, + 0x98, 0x4e, 0xcc, 0xe0, 0x6b, 0x50, 0x99, 0x18, 0xb0, 0x5e, 0xb7, 0x4b, 0x63, 0xae, 0x1f, 0xe2, + 0xc1, 0x28, 0xb1, 0xca, 0x1a, 0xf2, 0xa5, 0xda, 0x19, 0x27, 0xd6, 0x5f, 0x2e, 0x80, 0xea, 0x33, + 0x36, 0x2a, 0x6b, 0x58, 0x6d, 0x0a, 0xdf, 0x02, 0x93, 0xf8, 0xdd, 0xad, 0x9d, 0x87, 0xda, 0xab, + 0xbc, 0xf4, 0xea, 0x64, 0x6e, 0xaf, 0x4a, 0xfb, 0x87, 0xc7, 0x5b, 0x3b, 0x0f, 0x53, 0xa7, 0x6e, + 0xe9, 0x57, 0x9d, 0x82, 0xb6, 0x51, 0x49, 0x89, 0xca, 0xa3, 0x43, 0xa0, 0xc5, 0x56, 0x07, 0xb3, + 0x4e, 0x75, 0x51, 0xf2, 0xae, 0x8f, 0x12, 0x0b, 0x28, 0xa4, 0x03, 0xcc, 0x3a, 0xe7, 0xef, 0xd3, + 0x1e, 0x7e, 0x8e, 0x23, 0xee, 0xf7, 0xc2, 0x14, 0x0b, 0xa8, 0xc3, 0xc2, 0x6a, 0xe2, 0xc3, 0x8e, + 0xf6, 0xa1, 0x70, 0x23, 0x1f, 0x76, 0xae, 0xf2, 0x61, 0x67, 0xd6, 0x07, 0x65, 0x33, 0x21, 0xde, + 0xd5, 0xc4, 0x4b, 0x37, 0x22, 0xde, 0xbd, 0x8a, 0x78, 0x77, 0x96, 0x58, 0xd9, 0x88, 0x02, 0xb8, + 0x10, 0x91, 0xaa, 0x71, 0xb3, 0x02, 0xb8, 0x14, 0xe0, 0xf2, 0x44, 0xa3, 0x28, 0xbf, 0xcc, 0x80, + 0x55, 0x87, 0x46, 0x8c, 0x0b, 0x65, 0x44, 0xbb, 0x01, 0xd1, 0xc4, 0x45, 0x49, 0xfc, 0x62, 0x6e, + 0xe2, 0xbb, 0x8a, 0xf8, 0x2a, 0x4c, 0x1b, 0xdd, 0x9a, 0x55, 0xab, 0x2b, 0x70, 0x50, 0xe9, 0x12, + 0x4e, 0x62, 0xd6, 0xee, 0xc5, 0x9e, 0x66, 0x07, 0x92, 0xfd, 0x70, 0x6e, 0x76, 0x5d, 0x20, 0x17, + 0xf1, 0x6c, 0xb4, 0x72, 0xae, 0x52, 0xac, 0x11, 0x28, 0xfb, 0xe2, 0x2a, 0xed, 0x5e, 0xa0, 0x39, + 0x4b, 0x92, 0xf3, 0xd9, 0xdc, 0x9c, 0xba, 0xd2, 0x67, 0xd1, 0x6c, 0xb4, 0x9c, 0x2a, 0x14, 0xdf, + 0x10, 0xc0, 0xb0, 0xe7, 0xc7, 0x2d, 0x2f, 0xc0, 0x8e, 0x4f, 0x62, 0xcd, 0x69, 0x4a, 0xce, 0xe7, + 0x73, 0x73, 0xde, 0x56, 0x9c, 0x97, 0x11, 0x6d, 0x54, 0x11, 0xca, 0x67, 0x4a, 0xa7, 0xa8, 0x3b, + 0xc0, 0x6c, 0x93, 0x38, 0xf0, 0x23, 0x4d, 0xba, 0x2c, 0x49, 0xf7, 0xe7, 0x26, 0xd5, 0x09, 0x3c, + 0x8d, 0x65, 0xa3, 0x92, 0x12, 0x15, 0xd3, 0xa7, 0x60, 0x79, 0x48, 0x03, 0xda, 0xea, 0x3f, 0xd2, + 0x54, 0x65, 0x49, 0xf5, 0x74, 0x6e, 0x2a, 0x3d, 0xc0, 0x66, 0xc0, 0x6c, 0x54, 0x12, 0xf2, 0xab, + 0x47, 0x8a, 0x8b, 0x81, 0x12, 0x79, 0x8b, 0x59, 0x5a, 0x28, 0x2b, 0x92, 0x09, 0xcd, 0x5d, 0xa4, + 0x60, 0xff, 0x75, 0xe3, 0xe5, 0x8b, 0xb4, 0x46, 0xd3, 0xd9, 0x77, 0x0e, 0x2c, 0x7a, 0x92, 0x90, + 0x26, 0x59, 0xe3, 0x60, 0x8e, 0x83, 0x21, 0xe3, 0x9a, 0xb7, 0x72, 0xb3, 0xac, 0x99, 0x45, 0xb3, + 0xd1, 0x72, 0xaa, 0x90, 0x7c, 0xf6, 0x26, 0x58, 0x7c, 0xc9, 0xc5, 0xb4, 0xae, 0x80, 0xdc, 0x29, + 0x19, 0xaa, 0x79, 0x88, 0xc4, 0x12, 0xae, 0x82, 0xc5, 0x3e, 0x0e, 0x7a, 0x6a, 0xec, 0x17, 0x91, + 0x12, 0xec, 0x57, 0x60, 0xe5, 0x24, 0xc6, 0x11, 0xc3, 0x0e, 0xf7, 0x69, 0x74, 0x44, 0x3d, 0x06, + 0x21, 0xc8, 0xcb, 0x5e, 0xac, 0xce, 0xca, 0x35, 0xdc, 0x04, 0xf9, 0x80, 0x7a, 0xac, 0x9a, 0xad, + 0xe7, 0xd6, 0x4b, 0xdb, 0x77, 0x37, 0xae, 0xfe, 0x6c, 0xd9, 0x38, 0xa2, 0x1e, 0x92, 0x86, 0xf6, + 0xf7, 0x59, 0x90, 0x3b, 0xa2, 0x1e, 0xac, 0x82, 0x25, 0xec, 0xba, 0x31, 0x61, 0x4c, 0xe3, 0xa5, + 0x22, 0x5c, 0x03, 0x05, 0x4e, 0xbb, 0xbe, 0xa3, 0x40, 0x8b, 0x48, 0x4b, 0x82, 0xde, 0xc5, 0x1c, + 0xcb, 0xb9, 0x66, 0x22, 0xb9, 0x86, 0xdb, 0xc0, 0x94, 0xfe, 0xb6, 0xa2, 0x5e, 0xd8, 0x26, 0xb1, + 0x1c, 0x4f, 0xf9, 0xe6, 0xca, 0x59, 0x62, 0x95, 0xa4, 0xfe, 0x3f, 0x52, 0x8d, 0xa6, 0x05, 0x78, + 0x1f, 0x2c, 0xf1, 0xc1, 0xf4, 0x54, 0xb9, 0x75, 0x96, 0x58, 0x2b, 0xfc, 0xdc, 0x59, 0x31, 0x34, + 0x50, 0x81, 0x0f, 0x0e, 0x94, 0x83, 0x06, 0x1f, 0xb4, 0xfc, 0xc8, 0x25, 0x03, 0x39, 0x38, 0xf2, + 0xcd, 0xd5, 0xb3, 0xc4, 0xaa, 0x4c, 0x99, 0x1f, 0x8a, 0x3d, 0xb4, 0xc4, 0x07, 0x72, 0x01, 0xef, + 0x03, 0xa0, 0xae, 0x24, 0x19, 0x54, 0xcb, 0x5f, 0x3e, 0x4b, 0xac, 0xa2, 0xd4, 0x4a, 0xec, 0xf3, + 0x25, 0xb4, 0xc1, 0xa2, 0xc2, 0x36, 0x24, 0xb6, 0x79, 0x96, 0x58, 0x46, 0x40, 0x3d, 0x85, 0xa9, + 0xb6, 0x44, 0xa8, 0x62, 0x12, 0xd2, 0x3e, 0x71, 0x65, 0x33, 0x35, 0x50, 0x2a, 0xda, 0xbf, 0x65, + 0x40, 0xf1, 0x64, 0x80, 0x88, 0x43, 0xfc, 0x2e, 0xbf, 0xf2, 0x7d, 0x20, 0xc8, 0xbf, 0x89, 0x69, + 0xa8, 0xdf, 0x56, 0xae, 0xe1, 0xf6, 0x54, 0x20, 0x4b, 0xdb, 0xb5, 0xeb, 0xde, 0xec, 0x64, 0xb0, + 0x87, 0x39, 0xd6, 0x81, 0xde, 0x05, 0x85, 0x98, 0xb0, 0x5e, 0xc0, 0x65, 0x88, 0x4b, 0xdb, 0xf5, + 0xeb, 0x4f, 0x21, 0x69, 0x87, 0xb4, 0xbd, 0x48, 0x2f, 0xe5, 0xa1, 0x08, 0x76, 0x3e, 0xf5, 0xe9, + 0x6f, 0xe9, 0xc3, 0x75, 0x88, 0xef, 0x75, 0xb8, 0x0a, 0xad, 0x7e, 0xa7, 0x03, 0xa9, 0x82, 0x7f, + 0xbd, 0x1c, 0xc8, 0xa9, 0xc8, 0x3d, 0xce, 0x7f, 0x25, 0x3e, 0xfd, 0xbe, 0xc9, 0x02, 0x23, 0xa5, + 0x84, 0x4f, 0x41, 0xc5, 0xa1, 0x11, 0x8f, 0xb1, 0xc3, 0x5b, 0x33, 0xc9, 0xd5, 0xbc, 0x7b, 0xde, + 0xd2, 0x2f, 0x5a, 0xd8, 0x68, 0x25, 0x55, 0x35, 0x74, 0x06, 0xae, 0x82, 0xc5, 0x76, 0x40, 0x75, + 0xd4, 0x4c, 0xa4, 0x04, 0xf8, 0x7f, 0x99, 0x37, 0x32, 0xdb, 0x55, 0xe4, 0xee, 0x5d, 0x1b, 0x83, + 0xd9, 0xc2, 0x69, 0xae, 0x89, 0xa2, 0x1e, 0x27, 0x56, 0x59, 0xdd, 0x40, 0xa3, 0xd8, 0x22, 0xc7, + 0x64, 0x61, 0x55, 0x40, 0x2e, 0x26, 0x2a, 0xb2, 0x26, 0x12, 0x4b, 0x78, 0x07, 0x18, 0x31, 0xe9, + 0x93, 0x98, 0x13, 0x57, 0xc6, 0xcd, 0x40, 0x13, 0x19, 0xde, 0x06, 0x86, 0x87, 0x59, 0xab, 0xc7, + 0x88, 0xab, 0xc3, 0xb6, 0xe4, 0x61, 0xf6, 0x3f, 0x46, 0x5c, 0x1d, 0x93, 0x5f, 0xb2, 0xa0, 0xa0, + 0x1e, 0x0f, 0x6e, 0x01, 0xc3, 0x11, 0x1f, 0xc6, 0x2d, 0xdf, 0x95, 0x91, 0x30, 0x9b, 0x6b, 0xa3, + 0xc4, 0x5a, 0x92, 0x1f, 0xcb, 0x87, 0x7b, 0x67, 0x89, 0xb5, 0xe4, 0xa8, 0x25, 0xd2, 0x0b, 0x57, + 0x38, 0x1f, 0xd1, 0xc8, 0x51, 0xed, 0x20, 0x8f, 0x94, 0x00, 0xff, 0x09, 0x8a, 0x82, 0xb4, 0x1b, + 0xfb, 0x0e, 0x51, 0x15, 0xd8, 0x34, 0x47, 0x89, 0x65, 0x3c, 0xc3, 0xec, 0x58, 0xe8, 0x90, 0xb8, + 0x93, 0x5c, 0xc1, 0x1a, 0xc8, 0x79, 0x98, 0xe9, 0x52, 0x4c, 0x8d, 0x8e, 0xfc, 0xd0, 0xe7, 0x48, + 0x6c, 0xc0, 0x32, 0xc8, 0x72, 0xaa, 0x4a, 0x0f, 0x65, 0x39, 0x85, 0xf5, 0xb4, 0xff, 0x14, 0x24, + 0x2c, 0x18, 0x25, 0x56, 0xa1, 0x11, 0xd2, 0x5e, 0xc4, 0x75, 0x2f, 0x52, 0x29, 0xd4, 0xed, 0x71, + 0x99, 0x04, 0x26, 0x52, 0x02, 0xc4, 0xc0, 0xc0, 0x8e, 0x43, 0x18, 0x23, 0xac, 0x6a, 0xc8, 0xf6, + 0xf3, 0xf7, 0xeb, 0x1e, 0xa4, 0x21, 0xed, 0x4e, 0x7a, 0xe2, 0x53, 0xa1, 0x2e, 0x1e, 0xe3, 0x2c, + 0xb1, 0x80, 0x3a, 0x7c, 0xe4, 0x33, 0xfe, 0xdd, 0x4f, 0x16, 0x68, 0x4c, 0x24, 0x34, 0x81, 0x85, + 0x26, 0xc8, 0xf4, 0x65, 0xcd, 0x99, 0x28, 0xd3, 0x17, 0x52, 0x2c, 0x3f, 0x28, 0x4c, 0x94, 0x89, + 0x85, 0xc4, 0xe4, 0xa8, 0x37, 0x51, 0x86, 0xe9, 0xc8, 0xdf, 0x03, 0xc5, 0xe6, 0x90, 0x13, 0x09, + 0x23, 0xb3, 0x48, 0x08, 0xd5, 0x4c, 0x3d, 0x27, 0xb3, 0x48, 0x08, 0xda, 0x10, 0x83, 0xd2, 0xd4, + 0x9d, 0xfe, 0xa0, 0x19, 0x6e, 0x03, 0x93, 0x71, 0x1a, 0x63, 0x8f, 0xb4, 0x4e, 0xc9, 0x50, 0xb7, + 0x44, 0xd5, 0xe0, 0xb4, 0xfe, 0x39, 0x19, 0x32, 0x34, 0x2d, 0x28, 0x8a, 0x66, 0xe3, 0xfd, 0xa8, + 0x96, 0xf9, 0x30, 0xaa, 0x65, 0x7e, 0x1e, 0xd5, 0x32, 0x5f, 0x7f, 0xac, 0x2d, 0x7c, 0xf8, 0x58, + 0x5b, 0xf8, 0xe1, 0x63, 0x6d, 0xe1, 0x93, 0x7b, 0x97, 0x67, 0xcb, 0xf9, 0xff, 0xd1, 0x81, 0xfc, + 0x47, 0x2a, 0x07, 0x4c, 0xbb, 0x20, 0xff, 0x5d, 0x3e, 0xfa, 0x3d, 0x00, 0x00, 0xff, 0xff, 0x20, + 0x17, 0x75, 0x75, 0xaf, 0x0e, 0x00, 0x00, } func (m *Params) Marshal() (dAtA []byte, err error) { @@ -864,7 +867,9 @@ func (m *ChainConfig) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintEvm(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x7a + dAtA[i] = 0x1 + i-- + dAtA[i] = 0x82 { size := m.EWASMBlock.Size() i -= size @@ -874,7 +879,7 @@ func (m *ChainConfig) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintEvm(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x72 + dAtA[i] = 0x7a { size := m.YoloV3Block.Size() i -= size @@ -884,6 +889,16 @@ func (m *ChainConfig) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintEvm(dAtA, i, uint64(size)) } i-- + dAtA[i] = 0x72 + { + size := m.BerlinBlock.Size() + i -= size + if _, err := m.BerlinBlock.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintEvm(dAtA, i, uint64(size)) + } + i-- dAtA[i] = 0x6a { size := m.MuirGlacierBlock.Size() @@ -1562,12 +1577,14 @@ func (m *ChainConfig) Size() (n int) { n += 1 + l + sovEvm(uint64(l)) l = m.MuirGlacierBlock.Size() n += 1 + l + sovEvm(uint64(l)) + l = m.BerlinBlock.Size() + n += 1 + l + sovEvm(uint64(l)) l = m.YoloV3Block.Size() n += 1 + l + sovEvm(uint64(l)) l = m.EWASMBlock.Size() n += 1 + l + sovEvm(uint64(l)) l = m.CatalystBlock.Size() - n += 1 + l + sovEvm(uint64(l)) + n += 2 + l + sovEvm(uint64(l)) return n } @@ -2430,6 +2447,40 @@ func (m *ChainConfig) Unmarshal(dAtA []byte) error { } iNdEx = postIndex case 13: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field BerlinBlock", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvm + } + 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 ErrInvalidLengthEvm + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvm + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.BerlinBlock.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 14: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field YoloV3Block", wireType) } @@ -2463,7 +2514,7 @@ func (m *ChainConfig) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 14: + case 15: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field EWASMBlock", wireType) } @@ -2497,7 +2548,7 @@ func (m *ChainConfig) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 15: + case 16: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field CatalystBlock", wireType) } diff --git a/x/evm/types/msg.go b/x/evm/types/msg.go index 60275964..e9fee9c1 100644 --- a/x/evm/types/msg.go +++ b/x/evm/types/msg.go @@ -8,6 +8,7 @@ import ( "github.com/cosmos/cosmos-sdk/crypto/keyring" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/cosmos/cosmos-sdk/x/auth/ante" "github.com/cosmos/ethermint/types" ethcmn "github.com/ethereum/go-ethereum/common" @@ -18,8 +19,9 @@ import ( ) var ( - _ sdk.Msg = &MsgEthereumTx{} - _ sdk.Tx = &MsgEthereumTx{} + _ sdk.Msg = &MsgEthereumTx{} + _ sdk.Tx = &MsgEthereumTx{} + _ ante.GasTx = &MsgEthereumTx{} ) // message type and route constants @@ -141,10 +143,12 @@ func (msg *MsgEthereumTx) GetMsgs() []sdk.Msg { // GetSigners returns the expected signers for an Ethereum transaction message. // For such a message, there should exist only a single 'signer'. // -// NOTE: This method panics if 'VerifySig' hasn't been called first. +// NOTE: This method panics if 'Sign' hasn't been called first. func (msg MsgEthereumTx) GetSigners() []sdk.AccAddress { - if msg.From == "" { - panic("must use 'VerifySig' with a chain ID to get the signer") + v, r, s := msg.RawSignatureValues() + + if msg.From == "" || v == nil || r == nil || s == nil { + panic("must use 'Sign' with a chain ID to get the signer") } signer := sdk.AccAddress(ethcmn.HexToAddress(msg.From).Bytes()) @@ -218,6 +222,10 @@ func (msg *MsgEthereumTx) Sign(chainID *big.Int, signer keyring.Signer) error { return fmt.Errorf("sender address not defined for message") } + if chainID == nil { + return fmt.Errorf("chain id cannot be nil") + } + txHash := msg.RLPSignBytes(chainID) sig, _, err := signer.SignByAddress(from, txHash[:]) @@ -335,7 +343,7 @@ func (msg MsgEthereumTx) AsMessage() (core.Message, error) { // AsEthereumData returns an AccessListTx transaction data from the proto-formatted // TxData defined on the Cosmos EVM. -func (data TxData) AsEthereumData() ethtypes.TxData { +func (data *TxData) AsEthereumData() ethtypes.TxData { var to *ethcmn.Address if data.To != "" { toAddr := ethcmn.HexToAddress(data.To) diff --git a/x/evm/types/params.go b/x/evm/types/params.go index ffb0ea8b..17e49af3 100644 --- a/x/evm/types/params.go +++ b/x/evm/types/params.go @@ -13,6 +13,10 @@ import ( var _ paramtypes.ParamSet = &Params{} +const ( + DefaultEVMDenom = types.AttoPhoton +) + // Parameter keys var ( ParamStoreKeyEVMDenom = []byte("EVMDenom") @@ -39,7 +43,7 @@ func NewParams(evmDenom string, enableCreate, enableCall bool, extraEIPs ...int6 // DefaultParams returns default evm parameters func DefaultParams() Params { return Params{ - EvmDenom: types.AttoPhoton, + EvmDenom: DefaultEVMDenom, EnableCreate: true, EnableCall: true, ExtraEIPs: []int64(nil), // TODO: define default values from: [2929, 2200, 1884, 1344] diff --git a/x/evm/types/query.pb.gw.go b/x/evm/types/query.pb.gw.go index c9e0e0b5..fb2ce0e7 100644 --- a/x/evm/types/query.pb.gw.go +++ b/x/evm/types/query.pb.gw.go @@ -20,7 +20,6 @@ import ( "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/grpclog" - "google.golang.org/grpc/metadata" "google.golang.org/grpc/status" ) @@ -31,7 +30,6 @@ var _ status.Status var _ = runtime.String var _ = utilities.NewDoubleArray var _ = descriptor.ForMessage -var _ = metadata.Join func request_Query_Account_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { var protoReq QueryAccountRequest @@ -634,14 +632,12 @@ func local_request_Query_StaticCall_0(ctx context.Context, marshaler runtime.Mar // RegisterQueryHandlerServer registers the http handlers for service Query to "mux". // UnaryRPC :call QueryServer directly. // StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. -// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterQueryHandlerFromEndpoint instead. +// Note that using this registration option will cause many gRPC library features (such as grpc.SendHeader, etc) to stop working. Consider using RegisterQueryHandlerFromEndpoint instead. func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, server QueryServer) error { mux.Handle("GET", pattern_Query_Account_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() - var stream runtime.ServerTransportStream - ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) if err != nil { @@ -649,7 +645,6 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv return } resp, md, err := local_request_Query_Account_0(rctx, inboundMarshaler, server, req, pathParams) - md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) ctx = runtime.NewServerMetadataContext(ctx, md) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) @@ -663,8 +658,6 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv mux.Handle("GET", pattern_Query_CosmosAccount_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() - var stream runtime.ServerTransportStream - ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) if err != nil { @@ -672,7 +665,6 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv return } resp, md, err := local_request_Query_CosmosAccount_0(rctx, inboundMarshaler, server, req, pathParams) - md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) ctx = runtime.NewServerMetadataContext(ctx, md) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) @@ -686,8 +678,6 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv mux.Handle("GET", pattern_Query_Balance_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() - var stream runtime.ServerTransportStream - ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) if err != nil { @@ -695,7 +685,6 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv return } resp, md, err := local_request_Query_Balance_0(rctx, inboundMarshaler, server, req, pathParams) - md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) ctx = runtime.NewServerMetadataContext(ctx, md) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) @@ -709,8 +698,6 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv mux.Handle("GET", pattern_Query_Storage_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() - var stream runtime.ServerTransportStream - ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) if err != nil { @@ -718,7 +705,6 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv return } resp, md, err := local_request_Query_Storage_0(rctx, inboundMarshaler, server, req, pathParams) - md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) ctx = runtime.NewServerMetadataContext(ctx, md) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) @@ -732,8 +718,6 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv mux.Handle("GET", pattern_Query_Code_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() - var stream runtime.ServerTransportStream - ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) if err != nil { @@ -741,7 +725,6 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv return } resp, md, err := local_request_Query_Code_0(rctx, inboundMarshaler, server, req, pathParams) - md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) ctx = runtime.NewServerMetadataContext(ctx, md) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) @@ -755,8 +738,6 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv mux.Handle("GET", pattern_Query_TxLogs_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() - var stream runtime.ServerTransportStream - ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) if err != nil { @@ -764,7 +745,6 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv return } resp, md, err := local_request_Query_TxLogs_0(rctx, inboundMarshaler, server, req, pathParams) - md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) ctx = runtime.NewServerMetadataContext(ctx, md) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) @@ -778,8 +758,6 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv mux.Handle("GET", pattern_Query_TxReceipt_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() - var stream runtime.ServerTransportStream - ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) if err != nil { @@ -787,7 +765,6 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv return } resp, md, err := local_request_Query_TxReceipt_0(rctx, inboundMarshaler, server, req, pathParams) - md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) ctx = runtime.NewServerMetadataContext(ctx, md) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) @@ -801,8 +778,6 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv mux.Handle("GET", pattern_Query_TxReceiptsByBlockHeight_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() - var stream runtime.ServerTransportStream - ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) if err != nil { @@ -810,7 +785,6 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv return } resp, md, err := local_request_Query_TxReceiptsByBlockHeight_0(rctx, inboundMarshaler, server, req, pathParams) - md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) ctx = runtime.NewServerMetadataContext(ctx, md) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) @@ -824,8 +798,6 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv mux.Handle("GET", pattern_Query_TxReceiptsByBlockHash_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() - var stream runtime.ServerTransportStream - ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) if err != nil { @@ -833,7 +805,6 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv return } resp, md, err := local_request_Query_TxReceiptsByBlockHash_0(rctx, inboundMarshaler, server, req, pathParams) - md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) ctx = runtime.NewServerMetadataContext(ctx, md) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) @@ -847,8 +818,6 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv mux.Handle("GET", pattern_Query_BlockLogs_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() - var stream runtime.ServerTransportStream - ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) if err != nil { @@ -856,7 +825,6 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv return } resp, md, err := local_request_Query_BlockLogs_0(rctx, inboundMarshaler, server, req, pathParams) - md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) ctx = runtime.NewServerMetadataContext(ctx, md) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) @@ -870,8 +838,6 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv mux.Handle("GET", pattern_Query_BlockBloom_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() - var stream runtime.ServerTransportStream - ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) if err != nil { @@ -879,7 +845,6 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv return } resp, md, err := local_request_Query_BlockBloom_0(rctx, inboundMarshaler, server, req, pathParams) - md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) ctx = runtime.NewServerMetadataContext(ctx, md) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) @@ -893,8 +858,6 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv mux.Handle("GET", pattern_Query_Params_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() - var stream runtime.ServerTransportStream - ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) if err != nil { @@ -902,7 +865,6 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv return } resp, md, err := local_request_Query_Params_0(rctx, inboundMarshaler, server, req, pathParams) - md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) ctx = runtime.NewServerMetadataContext(ctx, md) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) @@ -916,8 +878,6 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv mux.Handle("GET", pattern_Query_StaticCall_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() - var stream runtime.ServerTransportStream - ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) if err != nil { @@ -925,7 +885,6 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv return } resp, md, err := local_request_Query_StaticCall_0(rctx, inboundMarshaler, server, req, pathParams) - md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) ctx = runtime.NewServerMetadataContext(ctx, md) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)