forked from cerc-io/laconicd-deprecated
all, deps: bump go-ethereum version (#5)
* evm, rpc: access lists, JSON-RPC and transaction updates (wip) * ante, evm, rpc: update signature verification * evm: msg server and tests updates * evm: tests (wip) * evm: fix cdc and params * evm: cleanup state transition * fix nil cases * lint
This commit is contained in:
+3
-3
@@ -63,7 +63,7 @@ func NewAnteHandler(
|
||||
opts := txWithExtensions.GetExtensionOptions()
|
||||
if len(opts) > 0 {
|
||||
switch typeURL := opts[0].GetTypeUrl(); typeURL {
|
||||
case "/injective.evm.v1beta1.ExtensionOptionsEthereumTx":
|
||||
case "/ethermint.evm.v1beta1.ExtensionOptionsEthereumTx":
|
||||
// handle as *evmtypes.MsgEthereumTx
|
||||
|
||||
anteHandler = sdk.ChainAnteDecorators(
|
||||
@@ -71,7 +71,7 @@ func NewAnteHandler(
|
||||
NewEthMempoolFeeDecorator(evmKeeper),
|
||||
NewEthValidateBasicDecorator(),
|
||||
authante.TxTimeoutHeightDecorator{},
|
||||
NewEthSigVerificationDecorator(),
|
||||
NewEthSigVerificationDecorator(evmKeeper),
|
||||
NewEthAccountSetupDecorator(ak),
|
||||
NewEthAccountVerificationDecorator(ak, bankKeeper, evmKeeper),
|
||||
NewEthNonceVerificationDecorator(ak),
|
||||
@@ -79,7 +79,7 @@ func NewAnteHandler(
|
||||
NewEthIncrementSenderSequenceDecorator(ak), // innermost AnteDecorator.
|
||||
)
|
||||
|
||||
case "/injective.evm.v1beta1.ExtensionOptionsWeb3Tx":
|
||||
case "/ethermint.evm.v1beta1.ExtensionOptionsWeb3Tx":
|
||||
// handle as normal Cosmos SDK tx, except signature is checked for EIP712 representation
|
||||
|
||||
switch tx.(type) {
|
||||
|
||||
+14
-14
@@ -55,9 +55,9 @@ func (suite *AnteTestSuite) TestValidEthTx() {
|
||||
to := ethcmn.BytesToAddress(addr2.Bytes())
|
||||
amt := big.NewInt(32)
|
||||
gas := big.NewInt(20)
|
||||
ethMsg := evmtypes.NewMsgEthereumTx(0, &to, amt, 22000, gas, []byte("test"))
|
||||
ethMsg := evmtypes.NewMsgEthereumTx(suite.chainID, 0, &to, amt, 22000, gas, []byte("test"), nil)
|
||||
|
||||
tx, err := newTestEthTx(suite.ctx, ethMsg, priv1)
|
||||
tx, err := suite.newTestEthTx(ethMsg, priv1)
|
||||
suite.Require().NoError(err)
|
||||
requireValidTx(suite.T(), suite.anteHandler, suite.ctx, tx, false)
|
||||
}
|
||||
@@ -182,9 +182,9 @@ func (suite *AnteTestSuite) TestEthInvalidSig() {
|
||||
to := ethcmn.BytesToAddress(addr2.Bytes())
|
||||
amt := big.NewInt(32)
|
||||
gas := big.NewInt(20)
|
||||
ethMsg := evmtypes.NewMsgEthereumTx(0, &to, amt, 22000, gas, []byte("test"))
|
||||
ethMsg := evmtypes.NewMsgEthereumTx(suite.chainID, 0, &to, amt, 22000, gas, []byte("test"), nil)
|
||||
|
||||
tx, err := newTestEthTx(suite.ctx, ethMsg, priv1)
|
||||
tx, err := suite.newTestEthTx(ethMsg, priv1)
|
||||
suite.Require().NoError(err)
|
||||
|
||||
ctx := suite.ctx.WithChainID("ethermint-4")
|
||||
@@ -209,9 +209,9 @@ func (suite *AnteTestSuite) TestEthInvalidNonce() {
|
||||
to := ethcmn.BytesToAddress(addr2.Bytes())
|
||||
amt := big.NewInt(32)
|
||||
gas := big.NewInt(20)
|
||||
ethMsg := evmtypes.NewMsgEthereumTx(0, &to, amt, 22000, gas, []byte("test"))
|
||||
ethMsg := evmtypes.NewMsgEthereumTx(suite.chainID, 0, &to, amt, 22000, gas, []byte("test"), nil)
|
||||
|
||||
tx, err := newTestEthTx(suite.ctx, ethMsg, priv1)
|
||||
tx, err := suite.newTestEthTx(ethMsg, priv1)
|
||||
suite.Require().NoError(err)
|
||||
requireInvalidTx(suite.T(), suite.anteHandler, suite.ctx, tx, false)
|
||||
}
|
||||
@@ -229,9 +229,9 @@ func (suite *AnteTestSuite) TestEthInsufficientBalance() {
|
||||
to := ethcmn.BytesToAddress(addr2.Bytes())
|
||||
amt := big.NewInt(32)
|
||||
gas := big.NewInt(20)
|
||||
ethMsg := evmtypes.NewMsgEthereumTx(0, &to, amt, 22000, gas, []byte("test"))
|
||||
ethMsg := evmtypes.NewMsgEthereumTx(suite.chainID, 0, &to, amt, 22000, gas, []byte("test"), nil)
|
||||
|
||||
tx, err := newTestEthTx(suite.ctx, ethMsg, priv1)
|
||||
tx, err := suite.newTestEthTx(ethMsg, priv1)
|
||||
suite.Require().NoError(err)
|
||||
requireInvalidTx(suite.T(), suite.anteHandler, suite.ctx, tx, false)
|
||||
}
|
||||
@@ -252,9 +252,9 @@ func (suite *AnteTestSuite) TestEthInvalidIntrinsicGas() {
|
||||
amt := big.NewInt(32)
|
||||
gas := big.NewInt(20)
|
||||
gasLimit := uint64(1000)
|
||||
ethMsg := evmtypes.NewMsgEthereumTx(0, &to, amt, gasLimit, gas, []byte("test"))
|
||||
ethMsg := evmtypes.NewMsgEthereumTx(suite.chainID, 0, &to, amt, gasLimit, gas, []byte("test"), nil)
|
||||
|
||||
tx, err := newTestEthTx(suite.ctx, ethMsg, priv1)
|
||||
tx, err := suite.newTestEthTx(ethMsg, priv1)
|
||||
suite.Require().NoError(err)
|
||||
requireInvalidTx(suite.T(), suite.anteHandler, suite.ctx.WithIsCheckTx(true), tx, false)
|
||||
}
|
||||
@@ -279,9 +279,9 @@ func (suite *AnteTestSuite) TestEthInvalidMempoolFees() {
|
||||
to := ethcmn.BytesToAddress(addr2.Bytes())
|
||||
amt := big.NewInt(32)
|
||||
gas := big.NewInt(20)
|
||||
ethMsg := evmtypes.NewMsgEthereumTx(0, &to, amt, 22000, gas, []byte("payload"))
|
||||
ethMsg := evmtypes.NewMsgEthereumTx(suite.chainID, 0, &to, amt, 22000, gas, []byte("payload"), nil)
|
||||
|
||||
tx, err := newTestEthTx(suite.ctx, ethMsg, priv1)
|
||||
tx, err := suite.newTestEthTx(ethMsg, priv1)
|
||||
suite.Require().NoError(err)
|
||||
requireInvalidTx(suite.T(), suite.anteHandler, suite.ctx, tx, false)
|
||||
}
|
||||
@@ -301,9 +301,9 @@ func (suite *AnteTestSuite) TestEthInvalidChainID() {
|
||||
to := ethcmn.BytesToAddress(addr2.Bytes())
|
||||
amt := big.NewInt(32)
|
||||
gas := big.NewInt(20)
|
||||
ethMsg := evmtypes.NewMsgEthereumTx(0, &to, amt, 22000, gas, []byte("test"))
|
||||
ethMsg := evmtypes.NewMsgEthereumTx(suite.chainID, 0, &to, amt, 22000, gas, []byte("test"), nil)
|
||||
|
||||
tx, err := newTestEthTx(suite.ctx, ethMsg, priv1)
|
||||
tx, err := suite.newTestEthTx(ethMsg, priv1)
|
||||
suite.Require().NoError(err)
|
||||
|
||||
ctx := suite.ctx.WithChainID("bad-chain-id")
|
||||
|
||||
+42
-21
@@ -6,7 +6,6 @@ import (
|
||||
|
||||
log "github.com/xlab/suplog"
|
||||
|
||||
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||
authante "github.com/cosmos/cosmos-sdk/x/auth/ante"
|
||||
@@ -15,12 +14,14 @@ import (
|
||||
evmtypes "github.com/cosmos/ethermint/x/evm/types"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
ethcore "github.com/ethereum/go-ethereum/core"
|
||||
"github.com/ethereum/go-ethereum/core"
|
||||
ethtypes "github.com/ethereum/go-ethereum/core/types"
|
||||
)
|
||||
|
||||
// EVMKeeper defines the expected keeper interface used on the Eth AnteHandler
|
||||
type EVMKeeper interface {
|
||||
GetParams(ctx sdk.Context) evmtypes.Params
|
||||
GetChainConfig(ctx sdk.Context) (evmtypes.ChainConfig, bool)
|
||||
}
|
||||
|
||||
// EthSetupContextDecorator sets the infinite GasMeter in the Context and wraps
|
||||
@@ -164,12 +165,14 @@ func (vbd EthValidateBasicDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simu
|
||||
|
||||
// EthSigVerificationDecorator validates an ethereum signature
|
||||
type EthSigVerificationDecorator struct {
|
||||
interfaceRegistry codectypes.InterfaceRegistry
|
||||
evmKeeper EVMKeeper
|
||||
}
|
||||
|
||||
// NewEthSigVerificationDecorator creates a new EthSigVerificationDecorator
|
||||
func NewEthSigVerificationDecorator() EthSigVerificationDecorator {
|
||||
return EthSigVerificationDecorator{}
|
||||
func NewEthSigVerificationDecorator(ek EVMKeeper) EthSigVerificationDecorator {
|
||||
return EthSigVerificationDecorator{
|
||||
evmKeeper: ek,
|
||||
}
|
||||
}
|
||||
|
||||
// AnteHandle validates the signature and returns sender address
|
||||
@@ -187,23 +190,35 @@ func (esvd EthSigVerificationDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, s
|
||||
// parse the chainID from a string to a base-10 integer
|
||||
chainIDEpoch, err := ethermint.ParseChainID(ctx.ChainID())
|
||||
if err != nil {
|
||||
fmt.Println("chain id parsing failed")
|
||||
|
||||
return ctx, err
|
||||
}
|
||||
|
||||
// validate sender/signature
|
||||
_, eip155Err := msgEthTx.VerifySig(chainIDEpoch)
|
||||
if eip155Err != nil {
|
||||
_, homesteadErr := msgEthTx.VerifySigHomestead()
|
||||
if homesteadErr != nil {
|
||||
errMsg := fmt.Sprintf("signature verification failed for both EIP155 and Homestead signers: (%s, %s)",
|
||||
eip155Err.Error(), homesteadErr.Error())
|
||||
err := sdkerrors.Wrap(sdkerrors.ErrUnauthorized, errMsg)
|
||||
return ctx, err
|
||||
}
|
||||
config, found := esvd.evmKeeper.GetChainConfig(ctx)
|
||||
if !found {
|
||||
return ctx, evmtypes.ErrChainConfigNotFound
|
||||
}
|
||||
|
||||
ethCfg := config.EthereumConfig(chainIDEpoch)
|
||||
|
||||
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(),
|
||||
)
|
||||
}
|
||||
|
||||
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.
|
||||
|
||||
@@ -321,10 +336,10 @@ func (nvd EthNonceVerificationDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx,
|
||||
// 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.AccountNonce != seq {
|
||||
if msgEthTx.Data.Nonce != seq {
|
||||
return ctx, sdkerrors.Wrapf(
|
||||
sdkerrors.ErrInvalidSequence,
|
||||
"invalid nonce; got %d, expected %d", msgEthTx.Data.AccountNonce, seq,
|
||||
"invalid nonce; got %d, expected %d", msgEthTx.Data.Nonce, seq,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -381,7 +396,13 @@ func (egcd EthGasConsumeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simula
|
||||
}
|
||||
|
||||
gasLimit := msgEthTx.GetGas()
|
||||
gas, err := ethcore.IntrinsicGas(msgEthTx.Data.Payload, msgEthTx.To() == nil, true, false)
|
||||
|
||||
var accessList ethtypes.AccessList
|
||||
if msgEthTx.Data.Accesses != nil {
|
||||
accessList = *msgEthTx.Data.Accesses.ToEthAccessList()
|
||||
}
|
||||
|
||||
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")
|
||||
}
|
||||
@@ -394,7 +415,7 @@ func (egcd EthGasConsumeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simula
|
||||
// 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.Price), new(big.Int).SetUint64(gasLimit))
|
||||
cost := new(big.Int).Mul(new(big.Int).SetBytes(msgEthTx.Data.GasPrice), new(big.Int).SetUint64(gasLimit))
|
||||
|
||||
evmDenom := egcd.evmKeeper.GetParams(ctx).EvmDenom
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package ante_test
|
||||
|
||||
import (
|
||||
"math/big"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@@ -31,6 +32,7 @@ type AnteTestSuite struct {
|
||||
app *app.EthermintApp
|
||||
encodingConfig params.EncodingConfig
|
||||
anteHandler sdk.AnteHandler
|
||||
chainID *big.Int
|
||||
}
|
||||
|
||||
func (suite *AnteTestSuite) SetupTest() {
|
||||
@@ -38,7 +40,7 @@ func (suite *AnteTestSuite) SetupTest() {
|
||||
|
||||
suite.app = app.Setup(checkTx)
|
||||
|
||||
suite.ctx = suite.app.BaseApp.NewContext(checkTx, tmproto.Header{Height: 2, ChainID: "injective-3", Time: time.Now().UTC()})
|
||||
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())
|
||||
|
||||
@@ -47,6 +49,7 @@ func (suite *AnteTestSuite) SetupTest() {
|
||||
suite.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)
|
||||
}
|
||||
|
||||
func TestAnteTestSuite(t *testing.T) {
|
||||
@@ -96,15 +99,10 @@ func newTestSDKTx(
|
||||
return legacytx.NewStdTx(msgs, fee, sigs, "")
|
||||
}
|
||||
|
||||
func newTestEthTx(ctx sdk.Context, msg *evmtypes.MsgEthereumTx, priv cryptotypes.PrivKey) (sdk.Tx, error) {
|
||||
chainIDEpoch, err := ethermint.ParseChainID(ctx.ChainID())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
func (suite *AnteTestSuite) newTestEthTx(msg *evmtypes.MsgEthereumTx, priv cryptotypes.PrivKey) (sdk.Tx, error) {
|
||||
privkey := ðsecp256k1.PrivKey{Key: priv.Bytes()}
|
||||
|
||||
if err := msg.Sign(chainIDEpoch, privkey.ToECDSA()); err != nil {
|
||||
if err := msg.Sign(suite.chainID, privkey.ToECDSA()); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user