ante: AnteHandler
changes from state transition refactor (#56)
* ante: cherry-pick changes from state transition refactor * ante: test setup * ante: fixes * ante: test (wip) * ante: finish unit tests * ante: intrinsic gas test * ante: chaindecorators test (wip) * update tests * ante: cleanup tests * ante: add test consuption test
This commit is contained in:
parent
4de0835b49
commit
9a5654f70d
@ -1,14 +1,10 @@
|
|||||||
package ante
|
package ante
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"runtime/debug"
|
"runtime/debug"
|
||||||
|
|
||||||
log "github.com/xlab/suplog"
|
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"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||||
"github.com/cosmos/cosmos-sdk/types/tx/signing"
|
"github.com/cosmos/cosmos-sdk/types/tx/signing"
|
||||||
@ -20,9 +16,6 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
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
|
secp256k1VerifyCost uint64 = 21000
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -30,8 +23,7 @@ const (
|
|||||||
type AccountKeeper interface {
|
type AccountKeeper interface {
|
||||||
authante.AccountKeeper
|
authante.AccountKeeper
|
||||||
NewAccountWithAddress(ctx sdk.Context, addr sdk.AccAddress) authtypes.AccountI
|
NewAccountWithAddress(ctx sdk.Context, addr sdk.AccAddress) authtypes.AccountI
|
||||||
GetAccount(ctx sdk.Context, addr sdk.AccAddress) authtypes.AccountI
|
GetSequence(sdk.Context, sdk.AccAddress) (uint64, error)
|
||||||
SetAccount(ctx sdk.Context, account authtypes.AccountI)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// BankKeeper defines an expected keeper interface for the bank module's Keeper
|
// BankKeeper defines an expected keeper interface for the bank module's Keeper
|
||||||
@ -67,43 +59,20 @@ func NewAnteHandler(
|
|||||||
// handle as *evmtypes.MsgEthereumTx
|
// handle as *evmtypes.MsgEthereumTx
|
||||||
|
|
||||||
anteHandler = sdk.ChainAnteDecorators(
|
anteHandler = sdk.ChainAnteDecorators(
|
||||||
NewEthSetupContextDecorator(evmKeeper), // outermost AnteDecorator. EthSetUpContext must be called first
|
authante.NewSetUpContextDecorator(), // outermost AnteDecorator. SetUpContext must be called first
|
||||||
NewEthMempoolFeeDecorator(evmKeeper),
|
authante.NewMempoolFeeDecorator(),
|
||||||
NewEthValidateBasicDecorator(),
|
authante.NewValidateBasicDecorator(),
|
||||||
authante.TxTimeoutHeightDecorator{},
|
authante.TxTimeoutHeightDecorator{},
|
||||||
NewEthSigVerificationDecorator(evmKeeper),
|
NewEthSigVerificationDecorator(evmKeeper),
|
||||||
NewEthAccountSetupDecorator(ak),
|
|
||||||
NewEthAccountVerificationDecorator(ak, bankKeeper, evmKeeper),
|
NewEthAccountVerificationDecorator(ak, bankKeeper, evmKeeper),
|
||||||
NewEthNonceVerificationDecorator(ak),
|
NewEthNonceVerificationDecorator(ak),
|
||||||
NewEthGasConsumeDecorator(ak, bankKeeper, evmKeeper),
|
NewEthGasConsumeDecorator(ak, bankKeeper, evmKeeper),
|
||||||
NewEthIncrementSenderSequenceDecorator(ak), // innermost AnteDecorator.
|
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:
|
default:
|
||||||
log.WithField("type_url", typeURL).Errorln("rejecting tx with unsupported extension option")
|
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)
|
return anteHandler(ctx, tx, sim)
|
||||||
@ -122,6 +91,7 @@ func NewAnteHandler(
|
|||||||
authante.TxTimeoutHeightDecorator{},
|
authante.TxTimeoutHeightDecorator{},
|
||||||
authante.NewValidateMemoDecorator(ak),
|
authante.NewValidateMemoDecorator(ak),
|
||||||
authante.NewConsumeGasForTxSizeDecorator(ak),
|
authante.NewConsumeGasForTxSizeDecorator(ak),
|
||||||
|
authante.NewRejectFeeGranterDecorator(),
|
||||||
authante.NewSetPubKeyDecorator(ak), // SetPubKeyDecorator must be called before all signature verification decorators
|
authante.NewSetPubKeyDecorator(ak), // SetPubKeyDecorator must be called before all signature verification decorators
|
||||||
authante.NewValidateSigCountDecorator(ak),
|
authante.NewValidateSigCountDecorator(ak),
|
||||||
authante.NewDeductFeeDecorator(ak, bankKeeper),
|
authante.NewDeductFeeDecorator(ak, bankKeeper),
|
||||||
@ -158,33 +128,12 @@ var _ authante.SignatureVerificationGasConsumer = DefaultSigVerificationGasConsu
|
|||||||
func DefaultSigVerificationGasConsumer(
|
func DefaultSigVerificationGasConsumer(
|
||||||
meter sdk.GasMeter, sig signing.SignatureV2, params authtypes.Params,
|
meter sdk.GasMeter, sig signing.SignatureV2, params authtypes.Params,
|
||||||
) error {
|
) 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
|
// support for ethereum ECDSA secp256k1 keys
|
||||||
case *ethsecp256k1.PubKey:
|
_, ok := sig.PubKey.(*ethsecp256k1.PubKey)
|
||||||
|
if ok {
|
||||||
meter.ConsumeGas(secp256k1VerifyCost, "ante verify: eth_secp256k1")
|
meter.ConsumeGas(secp256k1VerifyCost, "ante verify: eth_secp256k1")
|
||||||
return nil
|
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)
|
||||||
}
|
}
|
||||||
|
@ -2,310 +2,68 @@ package ante_test
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"math/big"
|
"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"
|
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"
|
evmtypes "github.com/cosmos/ethermint/x/evm/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
func requireValidTx(
|
func (suite AnteTestSuite) TestAnteHandler() {
|
||||||
t *testing.T, anteHandler sdk.AnteHandler, ctx sdk.Context, tx sdk.Tx, sim bool,
|
addr, privKey := newTestAddrKey()
|
||||||
) {
|
to, _ := newTestAddrKey()
|
||||||
_, err := anteHandler(ctx, tx, sim)
|
|
||||||
require.NoError(t, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
func requireInvalidTx(
|
signedContractTx := evmtypes.NewMsgEthereumTxContract(suite.app.EvmKeeper.ChainID(), 1, big.NewInt(10), 100000, big.NewInt(1), nil, nil)
|
||||||
t *testing.T, anteHandler sdk.AnteHandler, ctx sdk.Context,
|
signedContractTx.From = addr.Hex()
|
||||||
tx sdk.Tx, sim bool,
|
|
||||||
) {
|
|
||||||
_, err := anteHandler(ctx, tx, sim)
|
|
||||||
require.Error(t, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (suite *AnteTestSuite) TestValidEthTx() {
|
signedTx := evmtypes.NewMsgEthereumTx(suite.app.EvmKeeper.ChainID(), 2, &to, big.NewInt(10), 100000, big.NewInt(1), nil, nil)
|
||||||
suite.ctx = suite.ctx.WithBlockHeight(1)
|
signedTx.From = addr.Hex()
|
||||||
|
|
||||||
addr1, priv1 := newTestAddrKey()
|
txContract := suite.CreateTestTx(signedContractTx, privKey, 1)
|
||||||
addr2, _ := newTestAddrKey()
|
|
||||||
|
|
||||||
acc1 := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr1)
|
suite.txBuilder = suite.clientCtx.TxConfig.NewTxBuilder()
|
||||||
suite.app.AccountKeeper.SetAccount(suite.ctx, acc1)
|
tx := suite.CreateTestTx(signedTx, privKey, 1)
|
||||||
err := suite.app.BankKeeper.SetBalances(suite.ctx, acc1.GetAddress(), newTestCoins())
|
|
||||||
suite.Require().NoError(err)
|
|
||||||
|
|
||||||
acc2 := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr2)
|
acc := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr.Bytes())
|
||||||
suite.app.AccountKeeper.SetAccount(suite.ctx, acc2)
|
suite.Require().NoError(acc.SetSequence(1))
|
||||||
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)
|
|
||||||
suite.app.AccountKeeper.SetAccount(suite.ctx, acc)
|
suite.app.AccountKeeper.SetAccount(suite.ctx, acc)
|
||||||
|
|
||||||
// require a valid Ethereum tx to pass
|
err := suite.app.BankKeeper.SetBalance(suite.ctx, addr.Bytes(), sdk.NewCoin(evmtypes.DefaultEVMDenom, sdk.NewInt(10000000000)))
|
||||||
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)
|
suite.Require().NoError(err)
|
||||||
requireInvalidTx(suite.T(), suite.anteHandler, suite.ctx, tx, false)
|
|
||||||
}
|
testCases := []struct {
|
||||||
|
name string
|
||||||
func (suite *AnteTestSuite) TestEthInvalidIntrinsicGas() {
|
tx sdk.Tx
|
||||||
suite.ctx = suite.ctx.WithBlockHeight(1)
|
checkTx bool
|
||||||
|
reCheckTx bool
|
||||||
addr1, priv1 := newTestAddrKey()
|
expPass bool
|
||||||
addr2, _ := newTestAddrKey()
|
}{
|
||||||
|
{"success - DeliverTx (contract)", txContract, false, false, true},
|
||||||
acc := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr1)
|
{"success - CheckTx (contract)", txContract, true, false, true},
|
||||||
suite.app.AccountKeeper.SetAccount(suite.ctx, acc)
|
{"success - ReCheckTx (contract)", txContract, false, true, true},
|
||||||
err := suite.app.BankKeeper.SetBalances(suite.ctx, acc.GetAddress(), newTestCoins())
|
{"success - DeliverTx", tx, false, false, true},
|
||||||
suite.Require().NoError(err)
|
{"success - CheckTx", tx, true, false, true},
|
||||||
|
{"success - ReCheckTx", tx, false, true, true},
|
||||||
// require a valid Ethereum tx to pass
|
}
|
||||||
to := ethcmn.BytesToAddress(addr2.Bytes())
|
|
||||||
amt := big.NewInt(32)
|
for _, tc := range testCases {
|
||||||
gas := big.NewInt(20)
|
suite.Run(tc.name, func() {
|
||||||
gasLimit := uint64(1000)
|
|
||||||
ethMsg := evmtypes.NewMsgEthereumTx(suite.chainID, 0, &to, amt, gasLimit, gas, []byte("test"), nil)
|
suite.ctx = suite.ctx.WithIsCheckTx(tc.reCheckTx).WithIsReCheckTx(tc.reCheckTx)
|
||||||
|
|
||||||
tx, err := suite.newTestEthTx(ethMsg, priv1)
|
expConsumed := params.TxGasContractCreation + params.TxGas
|
||||||
suite.Require().NoError(err)
|
_, err := suite.anteHandler(suite.ctx, tc.tx, false)
|
||||||
requireInvalidTx(suite.T(), suite.anteHandler, suite.ctx.WithIsCheckTx(true), tx, false)
|
|
||||||
}
|
// suite.Require().Equal(consumed, ctx.GasMeter().GasConsumed())
|
||||||
|
|
||||||
func (suite *AnteTestSuite) TestEthInvalidMempoolFees() {
|
if tc.expPass {
|
||||||
// setup app with checkTx = true
|
suite.Require().NoError(err)
|
||||||
suite.app = app.Setup(true)
|
suite.Require().Equal(int(expConsumed), int(suite.ctx.GasMeter().GasConsumed()))
|
||||||
suite.ctx = suite.app.BaseApp.NewContext(true, tmproto.Header{Height: 1, ChainID: "ethermint-3", Time: time.Now().UTC()})
|
} else {
|
||||||
suite.app.EvmKeeper.SetParams(suite.ctx, evmtypes.DefaultParams())
|
suite.Require().Error(err)
|
||||||
|
}
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
|
503
app/ante/eth.go
503
app/ante/eth.go
@ -1,16 +1,12 @@
|
|||||||
package ante
|
package ante
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"math/big"
|
"math/big"
|
||||||
|
|
||||||
log "github.com/xlab/suplog"
|
|
||||||
|
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||||
authante "github.com/cosmos/cosmos-sdk/x/auth/ante"
|
authante "github.com/cosmos/cosmos-sdk/x/auth/ante"
|
||||||
|
|
||||||
ethermint "github.com/cosmos/ethermint/types"
|
|
||||||
evmtypes "github.com/cosmos/ethermint/x/evm/types"
|
evmtypes "github.com/cosmos/ethermint/x/evm/types"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
@ -20,158 +16,13 @@ import (
|
|||||||
|
|
||||||
// EVMKeeper defines the expected keeper interface used on the Eth AnteHandler
|
// EVMKeeper defines the expected keeper interface used on the Eth AnteHandler
|
||||||
type EVMKeeper interface {
|
type EVMKeeper interface {
|
||||||
|
ChainID() *big.Int
|
||||||
GetParams(ctx sdk.Context) evmtypes.Params
|
GetParams(ctx sdk.Context) evmtypes.Params
|
||||||
GetChainConfig(ctx sdk.Context) (evmtypes.ChainConfig, bool)
|
GetChainConfig(ctx sdk.Context) (evmtypes.ChainConfig, bool)
|
||||||
WithContext(ctx sdk.Context)
|
WithContext(ctx sdk.Context)
|
||||||
ResetRefundTransient(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
|
// EthSigVerificationDecorator validates an ethereum signature
|
||||||
type EthSigVerificationDecorator struct {
|
type EthSigVerificationDecorator struct {
|
||||||
evmKeeper EVMKeeper
|
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) {
|
func (esvd EthSigVerificationDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (newCtx sdk.Context, err error) {
|
||||||
if simulate {
|
// no need to verify signatures on recheck tx
|
||||||
// when simulating, no signatures required and the from address is explicitly set
|
if ctx.IsReCheckTx() {
|
||||||
return next(ctx, tx, simulate)
|
return next(ctx, tx, simulate)
|
||||||
}
|
}
|
||||||
|
|
||||||
msgEthTx, ok := getTxMsg(tx).(*evmtypes.MsgEthereumTx)
|
// get and set account must be called with an infinite gas meter in order to prevent
|
||||||
if !ok {
|
// additional gas from being deducted.
|
||||||
return ctx, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "invalid transaction type: %T", getTxMsg(tx))
|
infCtx := ctx.WithGasMeter(sdk.NewInfiniteGasMeter())
|
||||||
}
|
|
||||||
|
|
||||||
// parse the chainID from a string to a base-10 integer
|
chainID := esvd.evmKeeper.ChainID()
|
||||||
chainIDEpoch, err := ethermint.ParseChainID(ctx.ChainID())
|
|
||||||
if err != nil {
|
|
||||||
return ctx, err
|
|
||||||
}
|
|
||||||
|
|
||||||
config, found := esvd.evmKeeper.GetChainConfig(ctx)
|
config, found := esvd.evmKeeper.GetChainConfig(infCtx)
|
||||||
if !found {
|
if !found {
|
||||||
return ctx, evmtypes.ErrChainConfigNotFound
|
return ctx, evmtypes.ErrChainConfigNotFound
|
||||||
}
|
}
|
||||||
|
|
||||||
ethCfg := config.EthereumConfig(chainIDEpoch)
|
ethCfg := config.EthereumConfig(chainID)
|
||||||
|
|
||||||
blockNum := big.NewInt(ctx.BlockHeight())
|
blockNum := big.NewInt(ctx.BlockHeight())
|
||||||
signer := ethtypes.MakeSigner(ethCfg, blockNum)
|
signer := ethtypes.MakeSigner(ethCfg, blockNum)
|
||||||
chainID := signer.ChainID()
|
|
||||||
|
|
||||||
if chainIDEpoch.Cmp(chainID) != 0 {
|
for _, msg := range tx.GetMsgs() {
|
||||||
return ctx, sdkerrors.Wrapf(sdkerrors.ErrInvalidChainID,
|
msgEthTx, ok := msg.(*evmtypes.MsgEthereumTx)
|
||||||
"EVM chain ID doesn't match the one derived from the signer (%s ≠ %s)",
|
if !ok {
|
||||||
chainIDEpoch.String(), chainID.String(),
|
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)
|
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
|
// EthAccountVerificationDecorator validates an account balance checks
|
||||||
type EthAccountVerificationDecorator struct {
|
type EthAccountVerificationDecorator struct {
|
||||||
ak AccountKeeper
|
ak AccountKeeper
|
||||||
@ -267,40 +94,37 @@ func (avd EthAccountVerificationDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx
|
|||||||
return next(ctx, tx, simulate)
|
return next(ctx, tx, simulate)
|
||||||
}
|
}
|
||||||
|
|
||||||
msgEthTx, ok := getTxMsg(tx).(*evmtypes.MsgEthereumTx)
|
// get and set account must be called with an infinite gas meter in order to prevent
|
||||||
if !ok {
|
// additional gas from being deducted.
|
||||||
return ctx, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "invalid transaction type: %T", getTxMsg(tx))
|
infCtx := ctx.WithGasMeter(sdk.NewInfiniteGasMeter())
|
||||||
}
|
|
||||||
|
|
||||||
// sender address should be in the tx cache from the previous AnteHandle call
|
evmDenom := avd.evmKeeper.GetParams(infCtx).EvmDenom
|
||||||
address := msgEthTx.GetFrom()
|
|
||||||
if address.Empty() {
|
|
||||||
log.Panicln("sender address cannot be empty")
|
|
||||||
}
|
|
||||||
|
|
||||||
acc := avd.ak.GetAccount(ctx, address)
|
for _, msg := range tx.GetMsgs() {
|
||||||
if acc == nil {
|
msgEthTx, ok := msg.(*evmtypes.MsgEthereumTx)
|
||||||
acc = avd.ak.NewAccountWithAddress(ctx, address)
|
if !ok {
|
||||||
avd.ak.SetAccount(ctx, acc)
|
return ctx, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "invalid transaction type %T, expected %T", tx, &evmtypes.MsgEthereumTx{})
|
||||||
}
|
}
|
||||||
|
|
||||||
// on InitChain make sure account number == 0
|
// sender address should be in the tx cache from the previous AnteHandle call
|
||||||
if ctx.BlockHeight() == 0 && acc.GetAccountNumber() != 0 {
|
from := msgEthTx.GetFrom()
|
||||||
return ctx, sdkerrors.Wrapf(
|
if from.Empty() {
|
||||||
sdkerrors.ErrInvalidSequence,
|
return ctx, sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "from address cannot be empty")
|
||||||
"invalid account number for height zero (got %d)", acc.GetAccountNumber(),
|
}
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
// validate sender has enough funds to pay for gas cost
|
||||||
balance := avd.bankKeeper.GetBalance(ctx, address, evmDenom)
|
balance := avd.bankKeeper.GetBalance(infCtx, from, evmDenom)
|
||||||
if balance.Amount.BigInt().Cmp(msgEthTx.Cost()) < 0 {
|
if balance.Amount.BigInt().Cmp(msgEthTx.Cost()) < 0 {
|
||||||
return ctx, sdkerrors.Wrapf(
|
return ctx, sdkerrors.Wrapf(
|
||||||
sdkerrors.ErrInsufficientFunds,
|
sdkerrors.ErrInsufficientFunds,
|
||||||
"sender balance < tx gas cost (%s < %s%s)", balance.String(), msgEthTx.Cost().String(), evmDenom,
|
"sender balance < tx gas cost (%s < %s%s)", balance.String(), msgEthTx.Cost().String(), evmDenom,
|
||||||
)
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return next(ctx, tx, simulate)
|
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
|
// AnteHandle validates that the transaction nonce is valid (equivalent to the sender account’s
|
||||||
// current nonce).
|
// current nonce).
|
||||||
func (nvd EthNonceVerificationDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (newCtx sdk.Context, err error) {
|
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)
|
// no need to check the nonce on ReCheckTx
|
||||||
if !ok {
|
if ctx.IsReCheckTx() {
|
||||||
return ctx, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "invalid transaction type: %T", getTxMsg(tx))
|
return next(ctx, tx, simulate)
|
||||||
}
|
}
|
||||||
|
|
||||||
// sender address should be in the tx cache from the previous AnteHandle call
|
// get and set account must be called with an infinite gas meter in order to prevent
|
||||||
address := msgEthTx.GetFrom()
|
// additional gas from being deducted.
|
||||||
if address.Empty() {
|
infCtx := ctx.WithGasMeter(sdk.NewInfiniteGasMeter())
|
||||||
log.Panicln("sender address cannot be empty")
|
|
||||||
}
|
|
||||||
|
|
||||||
acc := nvd.ak.GetAccount(ctx, address)
|
for _, msg := range tx.GetMsgs() {
|
||||||
if acc == nil {
|
msgEthTx, ok := msg.(*evmtypes.MsgEthereumTx)
|
||||||
return ctx, sdkerrors.Wrapf(
|
if !ok {
|
||||||
sdkerrors.ErrUnknownAddress,
|
return ctx, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "invalid transaction type %T, expected %T", tx, &evmtypes.MsgEthereumTx{})
|
||||||
"account %s (%s) is nil", common.BytesToAddress(address.Bytes()), address,
|
}
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
seq := acc.GetSequence()
|
// sender address should be in the tx cache from the previous AnteHandle call
|
||||||
// if multiple transactions are submitted in succession with increasing nonces,
|
seq, err := nvd.ak.GetSequence(infCtx, msgEthTx.GetFrom())
|
||||||
// all will be rejected except the first, since the first needs to be included in a block
|
if err != nil {
|
||||||
// before the sequence increments
|
return ctx, err
|
||||||
if msgEthTx.Data.Nonce != seq {
|
}
|
||||||
return ctx, sdkerrors.Wrapf(
|
|
||||||
sdkerrors.ErrInvalidSequence,
|
// if multiple transactions are submitted in succession with increasing nonces,
|
||||||
"invalid nonce; got %d, expected %d", msgEthTx.Data.Nonce, seq,
|
// 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)
|
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
|
// constant value of 21000 plus any cost inccured by additional bytes of data
|
||||||
// supplied with the transaction.
|
// supplied with the transaction.
|
||||||
func (egcd EthGasConsumeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (newCtx sdk.Context, err error) {
|
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)
|
// get and set account must be called with an infinite gas meter in order to prevent
|
||||||
if !ok {
|
// additional gas from being deducted.
|
||||||
return ctx, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "invalid transaction type: %T", getTxMsg(tx))
|
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
|
// reset the refund gas value for the current transaction
|
||||||
address := msgEthTx.GetFrom()
|
egcd.evmKeeper.ResetRefundTransient(infCtx)
|
||||||
if address.Empty() {
|
|
||||||
log.Panicln("sender address cannot be empty")
|
config, found := egcd.evmKeeper.GetChainConfig(infCtx)
|
||||||
|
if !found {
|
||||||
|
return ctx, evmtypes.ErrChainConfigNotFound
|
||||||
}
|
}
|
||||||
|
|
||||||
// fetch sender account from signature
|
ethCfg := config.EthereumConfig(egcd.evmKeeper.ChainID())
|
||||||
senderAcc, err := authante.GetSignerAcc(ctx, egcd.ak, address)
|
|
||||||
if err != nil {
|
|
||||||
return ctx, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if senderAcc == nil {
|
blockHeight := big.NewInt(ctx.BlockHeight())
|
||||||
return ctx, sdkerrors.Wrapf(
|
homestead := ethCfg.IsHomestead(blockHeight)
|
||||||
sdkerrors.ErrUnknownAddress,
|
istanbul := ethCfg.IsIstanbul(blockHeight)
|
||||||
"sender account %s (%s) is nil", common.BytesToAddress(address.Bytes()), address,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
isContractCreation := msgEthTx.To() == nil
|
||||||
if msgEthTx.Data.Accesses != nil {
|
|
||||||
accessList = *msgEthTx.Data.Accesses.ToEthAccessList()
|
|
||||||
}
|
|
||||||
|
|
||||||
gas, err := core.IntrinsicGas(msgEthTx.Data.Input, accessList, msgEthTx.To() == nil, true, false)
|
// fetch sender account from signature
|
||||||
if err != nil {
|
signerAcc, err := authante.GetSignerAcc(infCtx, egcd.ak, msgEthTx.GetFrom())
|
||||||
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)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ctx, err
|
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
|
// generate a copy of the gas pool (i.e block gas meter) to see if we've run out of gas for this block
|
||||||
newCtx = authante.SetGasMeter(simulate, ctx, gasLimit)
|
// if current gas consumed is greater than the limit, this funcion panics and the error is recovered on the Baseapp
|
||||||
egcd.evmKeeper.WithContext(newCtx)
|
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
|
// 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) {
|
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
|
// get and set account must be called with an infinite gas meter in order to prevent
|
||||||
// additional gas from being deducted.
|
// additional gas from being deducted.
|
||||||
gasMeter := ctx.GasMeter()
|
infCtx := ctx.WithGasMeter(sdk.NewInfiniteGasMeter())
|
||||||
ctx = ctx.WithGasMeter(sdk.NewInfiniteGasMeter())
|
|
||||||
|
|
||||||
msgEthTx, ok := getTxMsg(tx).(*evmtypes.MsgEthereumTx)
|
for _, msg := range tx.GetMsgs() {
|
||||||
if !ok {
|
// increment sequence of all signers
|
||||||
ctx = ctx.WithGasMeter(gasMeter)
|
for _, addr := range msg.GetSigners() {
|
||||||
return ctx, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "invalid transaction type: %T", getTxMsg(tx))
|
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
|
if err := acc.SetSequence(acc.GetSequence() + 1); err != nil {
|
||||||
for _, addr := range msgEthTx.GetSigners() {
|
return ctx, err
|
||||||
acc := issd.ak.GetAccount(ctx, addr)
|
}
|
||||||
if err := acc.SetSequence(acc.GetSequence() + 1); err != nil {
|
|
||||||
log.WithError(err).Panicln("failed to set acc sequence")
|
issd.ak.SetAccount(infCtx, acc)
|
||||||
}
|
}
|
||||||
issd.ak.SetAccount(ctx, acc)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// set the original gas meter
|
// set the original gas meter
|
||||||
ctx = ctx.WithGasMeter(gasMeter)
|
|
||||||
return next(ctx, tx, simulate)
|
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)
|
|
||||||
}
|
|
||||||
|
371
app/ante/eth_test.go
Normal file
371
app/ante/eth_test.go
Normal file
@ -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)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
@ -1,115 +1,138 @@
|
|||||||
package ante_test
|
package ante_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"math/big"
|
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
|
|
||||||
"github.com/stretchr/testify/suite"
|
"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"
|
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
|
||||||
"github.com/cosmos/cosmos-sdk/simapp/params"
|
|
||||||
"github.com/cosmos/cosmos-sdk/testutil/testdata"
|
"github.com/cosmos/cosmos-sdk/testutil/testdata"
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
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"
|
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
|
||||||
|
|
||||||
"github.com/cosmos/ethermint/app"
|
"github.com/cosmos/ethermint/app"
|
||||||
ante "github.com/cosmos/ethermint/app/ante"
|
ante "github.com/cosmos/ethermint/app/ante"
|
||||||
"github.com/cosmos/ethermint/crypto/ethsecp256k1"
|
"github.com/cosmos/ethermint/crypto/ethsecp256k1"
|
||||||
"github.com/cosmos/ethermint/tests"
|
"github.com/cosmos/ethermint/tests"
|
||||||
ethermint "github.com/cosmos/ethermint/types"
|
|
||||||
evmtypes "github.com/cosmos/ethermint/x/evm/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"
|
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
type AnteTestSuite struct {
|
type AnteTestSuite struct {
|
||||||
suite.Suite
|
suite.Suite
|
||||||
|
|
||||||
ctx sdk.Context
|
ctx sdk.Context
|
||||||
app *app.EthermintApp
|
app *app.EthermintApp
|
||||||
encodingConfig params.EncodingConfig
|
clientCtx client.Context
|
||||||
anteHandler sdk.AnteHandler
|
txBuilder client.TxBuilder
|
||||||
chainID *big.Int
|
anteHandler sdk.AnteHandler
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *AnteTestSuite) SetupTest() {
|
func (suite *AnteTestSuite) SetupTest() {
|
||||||
checkTx := false
|
checkTx := false
|
||||||
|
|
||||||
suite.app = app.Setup(checkTx)
|
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()})
|
infCtx := suite.ctx.WithGasMeter(sdk.NewInfiniteGasMeter())
|
||||||
suite.app.AccountKeeper.SetParams(suite.ctx, authtypes.DefaultParams())
|
suite.app.AccountKeeper.SetParams(infCtx, authtypes.DefaultParams())
|
||||||
suite.app.EvmKeeper.SetParams(suite.ctx, evmtypes.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.
|
// 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.clientCtx = client.Context{}.WithTxConfig(encodingConfig.TxConfig)
|
||||||
suite.chainID = big.NewInt(888)
|
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) {
|
func TestAnteTestSuite(t *testing.T) {
|
||||||
suite.Run(t, new(AnteTestSuite))
|
suite.Run(t, new(AnteTestSuite))
|
||||||
}
|
}
|
||||||
|
|
||||||
func newTestMsg(addrs ...sdk.AccAddress) *testdata.TestMsg {
|
// CreateTestTx is a helper function to create a tx given multiple inputs.
|
||||||
return testdata.NewTestMsg(addrs...)
|
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 {
|
func newTestAddrKey() (common.Address, cryptotypes.PrivKey) {
|
||||||
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) {
|
|
||||||
privkey, _ := ethsecp256k1.GenerateKey()
|
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(
|
var _ sdk.Tx = &invalidTx{}
|
||||||
ctx sdk.Context, msgs []sdk.Msg, privs []cryptotypes.PrivKey,
|
|
||||||
accNums []uint64, seqs []uint64, fee legacytx.StdFee,
|
|
||||||
) sdk.Tx {
|
|
||||||
|
|
||||||
sigs := make([]legacytx.StdSignature, len(privs))
|
type invalidTx struct{}
|
||||||
for i, priv := range privs {
|
|
||||||
signBytes := legacytx.StdSignBytes(ctx.ChainID(), accNums[i], seqs[i], 0, fee, msgs, "")
|
|
||||||
|
|
||||||
sig, err := priv.Sign(signBytes)
|
func (invalidTx) GetMsgs() []sdk.Msg { return []sdk.Msg{nil} }
|
||||||
if err != nil {
|
func (invalidTx) ValidateBasic() error { return 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
|
|
||||||
}
|
|
||||||
|
@ -25,6 +25,7 @@ func TestEthermintAppExport(t *testing.T) {
|
|||||||
// Initialize the chain
|
// Initialize the chain
|
||||||
app.InitChain(
|
app.InitChain(
|
||||||
abci.RequestInitChain{
|
abci.RequestInitChain{
|
||||||
|
ChainId: "ethermint-1",
|
||||||
Validators: []abci.ValidatorUpdate{},
|
Validators: []abci.ValidatorUpdate{},
|
||||||
AppStateBytes: stateBytes,
|
AppStateBytes: stateBytes,
|
||||||
},
|
},
|
||||||
|
@ -47,6 +47,7 @@ func Setup(isCheckTx bool) *EthermintApp {
|
|||||||
// Initialize the chain
|
// Initialize the chain
|
||||||
app.InitChain(
|
app.InitChain(
|
||||||
abci.RequestInitChain{
|
abci.RequestInitChain{
|
||||||
|
ChainId: "ethermint-1",
|
||||||
Validators: []abci.ValidatorUpdate{},
|
Validators: []abci.ValidatorUpdate{},
|
||||||
ConsensusParams: DefaultConsensusParams,
|
ConsensusParams: DefaultConsensusParams,
|
||||||
AppStateBytes: stateBytes,
|
AppStateBytes: stateBytes,
|
||||||
|
@ -186,6 +186,7 @@ values, use an software upgrade procedure.
|
|||||||
| `petersburg_block` | [string](#string) | | Petersburg switch block (< 0 same as Constantinople) |
|
| `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) |
|
| `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) |
|
| `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 |
|
| `yolo_v3_block` | [string](#string) | | YOLO v3: Gas repricings |
|
||||||
| `ewasm_block` | [string](#string) | | EWASM switch block (< 0 no fork, 0 = already activated) |
|
| `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) |
|
| `catalyst_block` | [string](#string) | | Catalyst switch block (< 0 = no fork, 0 = already on catalyst) |
|
||||||
|
4
go.mod
4
go.mod
@ -46,9 +46,7 @@ require (
|
|||||||
github.com/xlab/closer v0.0.0-20190328110542-03326addb7c2
|
github.com/xlab/closer v0.0.0-20190328110542-03326addb7c2
|
||||||
github.com/xlab/suplog v1.3.0
|
github.com/xlab/suplog v1.3.0
|
||||||
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a
|
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a
|
||||||
golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4 // indirect
|
google.golang.org/genproto v0.0.0-20210524171403-669157292da3
|
||||||
golang.org/x/text v0.3.5 // indirect
|
|
||||||
google.golang.org/genproto v0.0.0-20210207032614-bba0dbe2a9ea
|
|
||||||
google.golang.org/grpc v1.38.0
|
google.golang.org/grpc v1.38.0
|
||||||
gopkg.in/yaml.v2 v2.4.0
|
gopkg.in/yaml.v2 v2.4.0
|
||||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
|
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
|
||||||
|
8
go.sum
8
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-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-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-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-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/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=
|
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-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-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-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-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 h1:gG67DSER+11cZvqIMb8S8bt0vZtiN6xWYARwirrOSfE=
|
||||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
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-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-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-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.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/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
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-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-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-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-20210524171403-669157292da3 h1:xFyh6GBb+NO1L0xqb978I3sBPQpk6FrKO0jJGRvdj/0=
|
||||||
google.golang.org/genproto v0.0.0-20210207032614-bba0dbe2a9ea/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
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.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.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||||
google.golang.org/grpc v1.19.1/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.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
|
||||||
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
|
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.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.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
|
||||||
google.golang.org/grpc v1.38.0 h1:/9BgsAsa5nWe26HqOlvlgJnqBuktYOLCgjCPqsa56W0=
|
google.golang.org/grpc v1.38.0 h1:/9BgsAsa5nWe26HqOlvlgJnqBuktYOLCgjCPqsa56W0=
|
||||||
google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
|
google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
|
||||||
|
@ -102,21 +102,27 @@ message ChainConfig {
|
|||||||
(gogoproto.moretags) = "yaml:\"muir_glacier_block\"",
|
(gogoproto.moretags) = "yaml:\"muir_glacier_block\"",
|
||||||
(gogoproto.nullable) = false
|
(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
|
// YOLO v3: Gas repricings
|
||||||
string yolo_v3_block = 13 [
|
string yolo_v3_block = 14 [
|
||||||
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
|
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
|
||||||
(gogoproto.moretags) = "yaml:\"yolo_v3_block\"",
|
(gogoproto.moretags) = "yaml:\"yolo_v3_block\"",
|
||||||
(gogoproto.nullable) = false
|
(gogoproto.nullable) = false
|
||||||
];
|
];
|
||||||
// EWASM switch block (< 0 no fork, 0 = already activated)
|
// EWASM switch block (< 0 no fork, 0 = already activated)
|
||||||
string ewasm_block = 14 [
|
string ewasm_block = 15 [
|
||||||
(gogoproto.customname) = "EWASMBlock",
|
(gogoproto.customname) = "EWASMBlock",
|
||||||
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
|
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
|
||||||
(gogoproto.moretags) = "yaml:\"ewasm_block\"",
|
(gogoproto.moretags) = "yaml:\"ewasm_block\"",
|
||||||
(gogoproto.nullable) = false
|
(gogoproto.nullable) = false
|
||||||
];
|
];
|
||||||
// Catalyst switch block (< 0 = no fork, 0 = already on catalyst)
|
// 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.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
|
||||||
(gogoproto.moretags) = "yaml:\"catalyst_block\"",
|
(gogoproto.moretags) = "yaml:\"catalyst_block\"",
|
||||||
(gogoproto.nullable) = false
|
(gogoproto.nullable) = false
|
||||||
|
@ -16,11 +16,14 @@ import (
|
|||||||
// InitGenesis initializes genesis state based on exported genesis
|
// InitGenesis initializes genesis state based on exported genesis
|
||||||
func InitGenesis(
|
func InitGenesis(
|
||||||
ctx sdk.Context,
|
ctx sdk.Context,
|
||||||
k keeper.Keeper,
|
k *keeper.Keeper,
|
||||||
accountKeeper types.AccountKeeper, // nolint: interfacer
|
accountKeeper types.AccountKeeper, // nolint: interfacer
|
||||||
bankKeeper types.BankKeeper,
|
bankKeeper types.BankKeeper,
|
||||||
data types.GenesisState,
|
data types.GenesisState,
|
||||||
) []abci.ValidatorUpdate {
|
) []abci.ValidatorUpdate {
|
||||||
|
k.WithContext(ctx)
|
||||||
|
k.WithChainID(ctx)
|
||||||
|
|
||||||
k.CommitStateDB.WithContext(ctx)
|
k.CommitStateDB.WithContext(ctx)
|
||||||
|
|
||||||
k.SetParams(ctx, data.Params)
|
k.SetParams(ctx, data.Params)
|
||||||
@ -81,7 +84,8 @@ func InitGenesis(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ExportGenesis exports genesis state of the EVM module
|
// 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)
|
k.CommitStateDB.WithContext(ctx)
|
||||||
|
|
||||||
// nolint: prealloc
|
// nolint: prealloc
|
||||||
|
@ -10,15 +10,6 @@ import (
|
|||||||
"github.com/cosmos/ethermint/x/evm/types"
|
"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() {
|
func (suite *EvmTestSuite) TestInitGenesis() {
|
||||||
privkey, err := ethsecp256k1.GenerateKey()
|
privkey, err := ethsecp256k1.GenerateKey()
|
||||||
suite.Require().NoError(err)
|
suite.Require().NoError(err)
|
||||||
@ -100,13 +91,13 @@ func (suite *EvmTestSuite) TestInitGenesis() {
|
|||||||
if tc.expPanic {
|
if tc.expPanic {
|
||||||
suite.Require().Panics(
|
suite.Require().Panics(
|
||||||
func() {
|
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 {
|
} else {
|
||||||
suite.Require().NotPanics(
|
suite.Require().NotPanics(
|
||||||
func() {
|
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)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -46,11 +46,11 @@ func (suite *EvmTestSuite) SetupTest() {
|
|||||||
checkTx := false
|
checkTx := false
|
||||||
|
|
||||||
suite.app = app.Setup(checkTx)
|
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.app.EvmKeeper.CommitStateDB.WithContext(suite.ctx)
|
||||||
suite.handler = evm.NewHandler(suite.app.EvmKeeper)
|
suite.handler = evm.NewHandler(suite.app.EvmKeeper)
|
||||||
suite.codec = suite.app.AppCodec()
|
suite.codec = suite.app.AppCodec()
|
||||||
suite.chainID = suite.chainID
|
suite.chainID = suite.app.EvmKeeper.ChainID()
|
||||||
|
|
||||||
privKey, err := ethsecp256k1.GenerateKey()
|
privKey, err := ethsecp256k1.GenerateKey()
|
||||||
suite.Require().NoError(err)
|
suite.Require().NoError(err)
|
||||||
|
@ -12,6 +12,7 @@ import (
|
|||||||
ethtypes "github.com/ethereum/go-ethereum/core/types"
|
ethtypes "github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/tendermint/tendermint/libs/log"
|
"github.com/tendermint/tendermint/libs/log"
|
||||||
|
|
||||||
|
ethermint "github.com/cosmos/ethermint/types"
|
||||||
"github.com/cosmos/ethermint/x/evm/types"
|
"github.com/cosmos/ethermint/x/evm/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -36,6 +37,8 @@ type Keeper struct {
|
|||||||
bankKeeper types.BankKeeper
|
bankKeeper types.BankKeeper
|
||||||
|
|
||||||
ctx sdk.Context
|
ctx sdk.Context
|
||||||
|
// chain ID number obtained from the context's chain id
|
||||||
|
eip155ChainID *big.Int
|
||||||
|
|
||||||
// Ethermint concrete implementation on the EVM StateDB interface
|
// Ethermint concrete implementation on the EVM StateDB interface
|
||||||
CommitStateDB *types.CommitStateDB
|
CommitStateDB *types.CommitStateDB
|
||||||
@ -80,6 +83,25 @@ func (k *Keeper) WithContext(ctx sdk.Context) {
|
|||||||
k.ctx = ctx
|
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
|
// Block Bloom
|
||||||
// Required by Web3 API.
|
// Required by Web3 API.
|
||||||
|
@ -42,7 +42,7 @@ func (suite *KeeperTestSuite) SetupTest() {
|
|||||||
checkTx := false
|
checkTx := false
|
||||||
|
|
||||||
suite.app = app.Setup(checkTx)
|
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.app.EvmKeeper.CommitStateDB.WithContext(suite.ctx)
|
||||||
|
|
||||||
suite.address = ethcmn.HexToAddress(addrHex)
|
suite.address = ethcmn.HexToAddress(addrHex)
|
||||||
|
@ -151,13 +151,13 @@ func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONMarshaler, data j
|
|||||||
var genesisState types.GenesisState
|
var genesisState types.GenesisState
|
||||||
|
|
||||||
cdc.MustUnmarshalJSON(data, &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{}
|
return []abci.ValidatorUpdate{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ExportGenesis returns the exported genesis state as raw bytes for the evm
|
// ExportGenesis returns the exported genesis state as raw bytes for the evm
|
||||||
// module.
|
// module.
|
||||||
func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONMarshaler) json.RawMessage {
|
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)
|
return cdc.MustMarshalJSON(gs)
|
||||||
}
|
}
|
||||||
|
@ -28,6 +28,7 @@ func (cc ChainConfig) EthereumConfig(chainID *big.Int) *params.ChainConfig {
|
|||||||
PetersburgBlock: getBlockValue(cc.PetersburgBlock),
|
PetersburgBlock: getBlockValue(cc.PetersburgBlock),
|
||||||
IstanbulBlock: getBlockValue(cc.IstanbulBlock),
|
IstanbulBlock: getBlockValue(cc.IstanbulBlock),
|
||||||
MuirGlacierBlock: getBlockValue(cc.MuirGlacierBlock),
|
MuirGlacierBlock: getBlockValue(cc.MuirGlacierBlock),
|
||||||
|
BerlinBlock: getBlockValue(cc.BerlinBlock),
|
||||||
//TODO(xlab): after upgrading ethereum to newer version, this should be set to YoloV2Block
|
//TODO(xlab): after upgrading ethereum to newer version, this should be set to YoloV2Block
|
||||||
YoloV3Block: getBlockValue(cc.YoloV3Block),
|
YoloV3Block: getBlockValue(cc.YoloV3Block),
|
||||||
EWASMBlock: getBlockValue(cc.EWASMBlock),
|
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 {
|
func DefaultChainConfig() ChainConfig {
|
||||||
return ChainConfig{
|
return ChainConfig{
|
||||||
HomesteadBlock: sdk.ZeroInt(),
|
HomesteadBlock: sdk.ZeroInt(),
|
||||||
@ -48,9 +49,10 @@ func DefaultChainConfig() ChainConfig {
|
|||||||
ByzantiumBlock: sdk.ZeroInt(),
|
ByzantiumBlock: sdk.ZeroInt(),
|
||||||
ConstantinopleBlock: sdk.ZeroInt(),
|
ConstantinopleBlock: sdk.ZeroInt(),
|
||||||
PetersburgBlock: sdk.ZeroInt(),
|
PetersburgBlock: sdk.ZeroInt(),
|
||||||
IstanbulBlock: sdk.NewInt(-1),
|
IstanbulBlock: sdk.ZeroInt(),
|
||||||
MuirGlacierBlock: sdk.NewInt(-1),
|
MuirGlacierBlock: sdk.ZeroInt(),
|
||||||
YoloV3Block: sdk.NewInt(-1),
|
BerlinBlock: sdk.ZeroInt(),
|
||||||
|
YoloV3Block: sdk.ZeroInt(),
|
||||||
EWASMBlock: sdk.NewInt(-1),
|
EWASMBlock: sdk.NewInt(-1),
|
||||||
CatalystBlock: sdk.NewInt(-1),
|
CatalystBlock: sdk.NewInt(-1),
|
||||||
}
|
}
|
||||||
|
@ -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"`
|
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)
|
// 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"`
|
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
|
// 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)
|
// 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)
|
// 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{} }
|
func (m *ChainConfig) Reset() { *m = ChainConfig{} }
|
||||||
@ -668,102 +670,103 @@ func init() {
|
|||||||
func init() { proto.RegisterFile("ethermint/evm/v1alpha1/evm.proto", fileDescriptor_98f00fcca8b6b943) }
|
func init() { proto.RegisterFile("ethermint/evm/v1alpha1/evm.proto", fileDescriptor_98f00fcca8b6b943) }
|
||||||
|
|
||||||
var fileDescriptor_98f00fcca8b6b943 = []byte{
|
var fileDescriptor_98f00fcca8b6b943 = []byte{
|
||||||
// 1506 bytes of a gzipped FileDescriptorProto
|
// 1527 bytes of a gzipped FileDescriptorProto
|
||||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x57, 0x4b, 0x6f, 0x1b, 0x47,
|
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x57, 0xbd, 0x6f, 0x1b, 0x47,
|
||||||
0x12, 0x16, 0x1f, 0xa2, 0x86, 0xcd, 0x11, 0xc5, 0x6d, 0x6b, 0xb5, 0xb4, 0x8d, 0xe5, 0x70, 0x67,
|
0x16, 0x17, 0x3f, 0x44, 0x2d, 0x87, 0x2b, 0x8a, 0x37, 0xd6, 0xe9, 0x68, 0x1b, 0xc7, 0xe5, 0xed,
|
||||||
0x81, 0xb5, 0x16, 0xb0, 0x25, 0x4b, 0x86, 0xb0, 0x82, 0x81, 0x3d, 0x90, 0x96, 0x6c, 0x09, 0x96,
|
0x01, 0x67, 0x1d, 0x60, 0x4b, 0x96, 0x0c, 0xe1, 0x04, 0x03, 0x57, 0x90, 0x96, 0x6c, 0x09, 0x96,
|
||||||
0x77, 0x85, 0xb6, 0xd6, 0x5e, 0xe4, 0x42, 0x34, 0x67, 0xda, 0xc3, 0x89, 0x66, 0xa6, 0x99, 0xe9,
|
0xef, 0x84, 0xb1, 0xce, 0x3e, 0xa4, 0x21, 0x86, 0xbb, 0xe3, 0xe5, 0x46, 0xbb, 0x3b, 0xcc, 0xce,
|
||||||
0x26, 0x4d, 0x06, 0x08, 0x90, 0x63, 0x8e, 0xc9, 0x2d, 0xc7, 0x9c, 0xf3, 0x03, 0xf2, 0x1b, 0x8c,
|
0x90, 0x26, 0x03, 0x04, 0x48, 0x99, 0x32, 0xe9, 0x52, 0xba, 0xce, 0x5f, 0x62, 0xa4, 0x72, 0x19,
|
||||||
0x9c, 0x7c, 0x0c, 0x72, 0x98, 0x04, 0xf4, 0x4d, 0x47, 0x5e, 0x72, 0x09, 0x90, 0xa0, 0x1f, 0x43,
|
0xa4, 0xd8, 0x04, 0x74, 0xa7, 0x92, 0x4d, 0x9a, 0x00, 0x09, 0xe6, 0x63, 0x29, 0x52, 0x1f, 0x01,
|
||||||
0x91, 0x7a, 0x04, 0x20, 0x74, 0x62, 0x57, 0x75, 0xf5, 0xf7, 0x75, 0x55, 0x75, 0x55, 0x0d, 0x41,
|
0x08, 0x55, 0x9c, 0xf7, 0xe6, 0xcd, 0xef, 0x37, 0xef, 0xcd, 0xfb, 0x58, 0x82, 0x3a, 0xe1, 0x1d,
|
||||||
0x9d, 0xf0, 0x0e, 0x89, 0x43, 0x3f, 0xe2, 0x9b, 0xa4, 0x1f, 0x6e, 0xf6, 0xb7, 0x70, 0xd0, 0xed,
|
0x12, 0x87, 0x7e, 0xc4, 0x37, 0x49, 0x3f, 0xdc, 0xec, 0x6f, 0xe1, 0xa0, 0xdb, 0xc1, 0x5b, 0x42,
|
||||||
0xe0, 0x2d, 0x21, 0x6c, 0x74, 0x63, 0xca, 0x29, 0x5c, 0x9b, 0x58, 0x6c, 0x08, 0x65, 0x6a, 0x71,
|
0xd8, 0xe8, 0xc6, 0x94, 0x53, 0xb8, 0x36, 0xb1, 0xd8, 0x10, 0xca, 0xd4, 0xe2, 0xce, 0xaa, 0x47,
|
||||||
0x67, 0xd5, 0xa3, 0x1e, 0x95, 0x26, 0x9b, 0x62, 0xa5, 0xac, 0xed, 0x5f, 0x33, 0xa0, 0x70, 0x8c,
|
0x3d, 0x2a, 0x4d, 0x36, 0xc5, 0x4a, 0x59, 0xdb, 0xbf, 0x66, 0x40, 0xe1, 0x18, 0xc7, 0x38, 0x64,
|
||||||
0x63, 0x1c, 0x32, 0xb8, 0x05, 0x8a, 0xa4, 0x1f, 0xb6, 0x5c, 0x12, 0xd1, 0xb0, 0x9a, 0xa9, 0x67,
|
0x70, 0x0b, 0x14, 0x49, 0x3f, 0x6c, 0xb9, 0x24, 0xa2, 0x61, 0x35, 0x53, 0xcf, 0xac, 0x17, 0x9b,
|
||||||
0xd6, 0x8b, 0xcd, 0xd5, 0x71, 0x62, 0x55, 0x86, 0x38, 0x0c, 0x1e, 0xdb, 0x93, 0x2d, 0x1b, 0x19,
|
0xab, 0xe3, 0xc4, 0xaa, 0x0c, 0x71, 0x18, 0x3c, 0xb6, 0x27, 0x5b, 0x36, 0x32, 0x48, 0x3f, 0xdc,
|
||||||
0xa4, 0x1f, 0xee, 0x89, 0x25, 0xfc, 0x37, 0x58, 0x26, 0x11, 0x6e, 0x07, 0xa4, 0xe5, 0xc4, 0x04,
|
0x13, 0x4b, 0xf8, 0x6f, 0xb0, 0x4c, 0x22, 0xdc, 0x0e, 0x48, 0xcb, 0x89, 0x09, 0xe6, 0xa4, 0x9a,
|
||||||
0x73, 0x52, 0xcd, 0xd6, 0x33, 0xeb, 0x46, 0xb3, 0x3a, 0x4e, 0xac, 0x55, 0x7d, 0x6c, 0x7a, 0xdb,
|
0xad, 0x67, 0xd6, 0x8d, 0x66, 0x75, 0x9c, 0x58, 0xab, 0xfa, 0xd8, 0xf4, 0xb6, 0x8d, 0x4c, 0x25,
|
||||||
0x46, 0xa6, 0x92, 0x9f, 0x48, 0x11, 0xfe, 0x0b, 0x94, 0xd2, 0x7d, 0x1c, 0x04, 0xd5, 0x9c, 0x3c,
|
0x3f, 0x91, 0x22, 0xfc, 0x17, 0x28, 0xa5, 0xfb, 0x38, 0x08, 0xaa, 0x39, 0x79, 0x78, 0x6d, 0x9c,
|
||||||
0xbc, 0x36, 0x4e, 0x2c, 0x38, 0x7b, 0x18, 0x07, 0x81, 0x8d, 0x80, 0x3e, 0x8a, 0x83, 0x00, 0x36,
|
0x58, 0x70, 0xf6, 0x30, 0x0e, 0x02, 0x1b, 0x01, 0x7d, 0x14, 0x07, 0x01, 0x6c, 0x00, 0x40, 0x06,
|
||||||
0x00, 0x20, 0x03, 0x1e, 0xe3, 0x16, 0xf1, 0xbb, 0xac, 0x9a, 0xaf, 0xe7, 0xd6, 0x73, 0x4d, 0x7b,
|
0x3c, 0xc6, 0x2d, 0xe2, 0x77, 0x59, 0x35, 0x5f, 0xcf, 0xad, 0xe7, 0x9a, 0xf6, 0x28, 0xb1, 0x8a,
|
||||||
0x94, 0x58, 0xc5, 0x7d, 0xa1, 0xdd, 0x3f, 0x3c, 0x66, 0xe3, 0xc4, 0xfa, 0x93, 0x06, 0x99, 0x18,
|
0xfb, 0x42, 0xbb, 0x7f, 0x78, 0xcc, 0xc6, 0x89, 0xf5, 0x27, 0x0d, 0x32, 0x31, 0xb4, 0x51, 0x51,
|
||||||
0xda, 0xa8, 0x28, 0x85, 0x7d, 0xbf, 0xcb, 0x1e, 0xe7, 0xbf, 0xfe, 0xc6, 0x5a, 0xb0, 0xbf, 0x5b,
|
0x0a, 0xfb, 0x7e, 0x97, 0x3d, 0xce, 0x7f, 0xfb, 0xce, 0x5a, 0xb0, 0xdf, 0x95, 0x41, 0xe9, 0x49,
|
||||||
0x06, 0xa5, 0x27, 0x1d, 0xec, 0x47, 0x4f, 0x68, 0xf4, 0xc6, 0xf7, 0xe0, 0x27, 0x60, 0xa5, 0x43,
|
0x07, 0xfb, 0xd1, 0x13, 0x1a, 0xbd, 0xf1, 0x3d, 0xf8, 0x19, 0x58, 0xe9, 0xd0, 0x90, 0x30, 0x4e,
|
||||||
0x43, 0xc2, 0x38, 0xc1, 0x6e, 0xab, 0x1d, 0x50, 0xe7, 0x54, 0x47, 0xe2, 0xe0, 0x5d, 0x62, 0x2d,
|
0xb0, 0xdb, 0x6a, 0x07, 0xd4, 0x39, 0xd5, 0x91, 0x38, 0x78, 0x9f, 0x58, 0x0b, 0x3f, 0x26, 0xd6,
|
||||||
0xfc, 0x98, 0x58, 0xff, 0xf0, 0x7c, 0xde, 0xe9, 0xb5, 0x37, 0x1c, 0x1a, 0x6e, 0x3a, 0x94, 0x85,
|
0x3f, 0x3c, 0x9f, 0x77, 0x7a, 0xed, 0x0d, 0x87, 0x86, 0x9b, 0x0e, 0x65, 0x21, 0x65, 0xfa, 0xe7,
|
||||||
0x94, 0xe9, 0x9f, 0x07, 0xcc, 0x3d, 0xdd, 0xe4, 0xc3, 0x2e, 0x61, 0x1b, 0x87, 0x11, 0x1f, 0x27,
|
0x01, 0x73, 0x4f, 0x37, 0xf9, 0xb0, 0x4b, 0xd8, 0xc6, 0x61, 0xc4, 0xc7, 0x89, 0xb5, 0xa6, 0xe8,
|
||||||
0xd6, 0x9a, 0xa2, 0xbf, 0x00, 0x67, 0xa3, 0xf2, 0x44, 0xd3, 0x14, 0x0a, 0xf8, 0x19, 0x28, 0xbb,
|
0x2f, 0xc0, 0xd9, 0xa8, 0x3c, 0xd1, 0x34, 0x85, 0x02, 0x7e, 0x01, 0xca, 0x2e, 0xa6, 0xad, 0x37,
|
||||||
0x98, 0xb6, 0xde, 0xd0, 0xf8, 0x54, 0x33, 0x66, 0x25, 0xe3, 0xeb, 0xf9, 0x18, 0x47, 0x89, 0x65,
|
0x34, 0x3e, 0xd5, 0x8c, 0x59, 0xc9, 0xf8, 0x7a, 0x3e, 0xc6, 0x51, 0x62, 0x99, 0x7b, 0x8d, 0xff,
|
||||||
0xee, 0x35, 0xfe, 0xfb, 0x94, 0xc6, 0xa7, 0x12, 0x77, 0x9c, 0x58, 0x7f, 0x56, 0x37, 0x98, 0x45,
|
0x3e, 0xa5, 0xf1, 0xa9, 0xc4, 0x1d, 0x27, 0xd6, 0x9f, 0xd5, 0x0d, 0x66, 0xd1, 0x6d, 0x64, 0xba,
|
||||||
0xb7, 0x91, 0xe9, 0x62, 0x3a, 0x31, 0x83, 0xaf, 0x41, 0x65, 0x62, 0xc0, 0x7a, 0xdd, 0x2e, 0x8d,
|
0x98, 0x4e, 0xcc, 0xe0, 0x6b, 0x50, 0x99, 0x18, 0xb0, 0x5e, 0xb7, 0x4b, 0x63, 0xae, 0x1f, 0xe2,
|
||||||
0xb9, 0x4e, 0xc4, 0x83, 0x51, 0x62, 0x95, 0x35, 0xe4, 0x4b, 0xb5, 0x33, 0x4e, 0xac, 0xbf, 0x5c,
|
0xc1, 0x28, 0xb1, 0xca, 0x1a, 0xf2, 0xa5, 0xda, 0x19, 0x27, 0xd6, 0x5f, 0x2e, 0x80, 0xea, 0x33,
|
||||||
0x00, 0xd5, 0x67, 0x6c, 0x54, 0xd6, 0xb0, 0xda, 0x14, 0xbe, 0x05, 0x26, 0xf1, 0xbb, 0x5b, 0x3b,
|
0x36, 0x2a, 0x6b, 0x58, 0x6d, 0x0a, 0xdf, 0x02, 0x93, 0xf8, 0xdd, 0xad, 0x9d, 0x87, 0xda, 0xab,
|
||||||
0x0f, 0xb5, 0x57, 0x79, 0xe9, 0xd5, 0xc9, 0xdc, 0x5e, 0x95, 0xf6, 0x0f, 0x8f, 0xb7, 0x76, 0x1e,
|
0xbc, 0xf4, 0xea, 0x64, 0x6e, 0xaf, 0x4a, 0xfb, 0x87, 0xc7, 0x5b, 0x3b, 0x0f, 0x53, 0xa7, 0x6e,
|
||||||
0xa6, 0x4e, 0xdd, 0xd2, 0x59, 0x9d, 0x82, 0xb6, 0x51, 0x49, 0x89, 0xca, 0xa3, 0x43, 0xa0, 0xc5,
|
0xe9, 0x57, 0x9d, 0x82, 0xb6, 0x51, 0x49, 0x89, 0xca, 0xa3, 0x43, 0xa0, 0xc5, 0x56, 0x07, 0xb3,
|
||||||
0x56, 0x07, 0xb3, 0x4e, 0x75, 0x51, 0xf2, 0xae, 0x8f, 0x12, 0x0b, 0x28, 0xa4, 0x03, 0xcc, 0x3a,
|
0x4e, 0x75, 0x51, 0xf2, 0xae, 0x8f, 0x12, 0x0b, 0x28, 0xa4, 0x03, 0xcc, 0x3a, 0xe7, 0xef, 0xd3,
|
||||||
0xe7, 0xf9, 0x69, 0x0f, 0x3f, 0xc5, 0x11, 0xf7, 0x7b, 0x61, 0x8a, 0x05, 0xd4, 0x61, 0x61, 0x35,
|
0x1e, 0x7e, 0x8e, 0x23, 0xee, 0xf7, 0xc2, 0x14, 0x0b, 0xa8, 0xc3, 0xc2, 0x6a, 0xe2, 0xc3, 0x8e,
|
||||||
0xf1, 0x61, 0x47, 0xfb, 0x50, 0xb8, 0x91, 0x0f, 0x3b, 0x57, 0xf9, 0xb0, 0x33, 0xeb, 0x83, 0xb2,
|
0xf6, 0xa1, 0x70, 0x23, 0x1f, 0x76, 0xae, 0xf2, 0x61, 0x67, 0xd6, 0x07, 0x65, 0x33, 0x21, 0xde,
|
||||||
0x99, 0x10, 0xef, 0x6a, 0xe2, 0xa5, 0x1b, 0x11, 0xef, 0x5e, 0x45, 0xbc, 0x3b, 0x4b, 0xac, 0x6c,
|
0xd5, 0xc4, 0x4b, 0x37, 0x22, 0xde, 0xbd, 0x8a, 0x78, 0x77, 0x96, 0x58, 0xd9, 0x88, 0x02, 0xb8,
|
||||||
0x44, 0x01, 0x5c, 0x88, 0x48, 0xd5, 0xb8, 0x59, 0x01, 0x5c, 0x0a, 0x70, 0x79, 0xa2, 0x51, 0x94,
|
0x10, 0x91, 0xaa, 0x71, 0xb3, 0x02, 0xb8, 0x14, 0xe0, 0xf2, 0x44, 0xa3, 0x28, 0xbf, 0xcc, 0x80,
|
||||||
0x9f, 0x67, 0xc0, 0xaa, 0x43, 0x23, 0xc6, 0x85, 0x32, 0xa2, 0xdd, 0x80, 0x68, 0xe2, 0xa2, 0x24,
|
0x55, 0x87, 0x46, 0x8c, 0x0b, 0x65, 0x44, 0xbb, 0x01, 0xd1, 0xc4, 0x45, 0x49, 0xfc, 0x62, 0x6e,
|
||||||
0x7e, 0x31, 0x37, 0xf1, 0x5d, 0x45, 0x7c, 0x15, 0xa6, 0x8d, 0x6e, 0xcd, 0xaa, 0xd5, 0x15, 0x38,
|
0xe2, 0xbb, 0x8a, 0xf8, 0x2a, 0x4c, 0x1b, 0xdd, 0x9a, 0x55, 0xab, 0x2b, 0x70, 0x50, 0xe9, 0x12,
|
||||||
0xa8, 0x74, 0x09, 0x27, 0x31, 0x6b, 0xf7, 0x62, 0x4f, 0xb3, 0x03, 0xc9, 0x7e, 0x38, 0x37, 0xbb,
|
0x4e, 0x62, 0xd6, 0xee, 0xc5, 0x9e, 0x66, 0x07, 0x92, 0xfd, 0x70, 0x6e, 0x76, 0x5d, 0x20, 0x17,
|
||||||
0x2e, 0x90, 0x8b, 0x78, 0x36, 0x5a, 0x39, 0x57, 0x29, 0xd6, 0x08, 0x94, 0x7d, 0x71, 0x95, 0x76,
|
0xf1, 0x6c, 0xb4, 0x72, 0xae, 0x52, 0xac, 0x11, 0x28, 0xfb, 0xe2, 0x2a, 0xed, 0x5e, 0xa0, 0x39,
|
||||||
0x2f, 0xd0, 0x9c, 0x25, 0xc9, 0xf9, 0x6c, 0x6e, 0x4e, 0x5d, 0xe9, 0xb3, 0x68, 0x36, 0x5a, 0x4e,
|
0x4b, 0x92, 0xf3, 0xd9, 0xdc, 0x9c, 0xba, 0xd2, 0x67, 0xd1, 0x6c, 0xb4, 0x9c, 0x2a, 0x14, 0xdf,
|
||||||
0x15, 0x8a, 0x6f, 0x08, 0x60, 0xd8, 0xf3, 0xe3, 0x96, 0x17, 0x60, 0xc7, 0x27, 0xb1, 0xe6, 0x34,
|
0x10, 0xc0, 0xb0, 0xe7, 0xc7, 0x2d, 0x2f, 0xc0, 0x8e, 0x4f, 0x62, 0xcd, 0x69, 0x4a, 0xce, 0xe7,
|
||||||
0x25, 0xe7, 0xf3, 0xb9, 0x39, 0x6f, 0x2b, 0xce, 0xcb, 0x88, 0x36, 0xaa, 0x08, 0xe5, 0x33, 0xa5,
|
0x73, 0x73, 0xde, 0x56, 0x9c, 0x97, 0x11, 0x6d, 0x54, 0x11, 0xca, 0x67, 0x4a, 0xa7, 0xa8, 0x3b,
|
||||||
0x53, 0xd4, 0x1f, 0x83, 0xe5, 0x21, 0x0d, 0x68, 0xab, 0xff, 0x48, 0xb3, 0x2e, 0x4b, 0xd6, 0xa7,
|
0xc0, 0x6c, 0x93, 0x38, 0xf0, 0x23, 0x4d, 0xba, 0x2c, 0x49, 0xf7, 0xe7, 0x26, 0xd5, 0x09, 0x3c,
|
||||||
0x73, 0xb3, 0xea, 0xb1, 0x32, 0x03, 0x66, 0xa3, 0x92, 0x90, 0x5f, 0x3d, 0x52, 0x5c, 0x0c, 0x94,
|
0x8d, 0x65, 0xa3, 0x92, 0x12, 0x15, 0xd3, 0xa7, 0x60, 0x79, 0x48, 0x03, 0xda, 0xea, 0x3f, 0xd2,
|
||||||
0xc8, 0x5b, 0xcc, 0xd2, 0xe7, 0x5b, 0x96, 0x4c, 0x68, 0xee, 0xd2, 0x01, 0xfb, 0xaf, 0x1b, 0x2f,
|
0x54, 0x65, 0x49, 0xf5, 0x74, 0x6e, 0x2a, 0x3d, 0xc0, 0x66, 0xc0, 0x6c, 0x54, 0x12, 0xf2, 0xab,
|
||||||
0x5f, 0xa4, 0x95, 0x93, 0x4e, 0xa4, 0x73, 0x60, 0xd1, 0x29, 0x84, 0x34, 0xc9, 0xa5, 0x83, 0x39,
|
0x47, 0x8a, 0x8b, 0x81, 0x12, 0x79, 0x8b, 0x59, 0x5a, 0x28, 0x2b, 0x92, 0x09, 0xcd, 0x5d, 0xa4,
|
||||||
0x0e, 0x86, 0x8c, 0x6b, 0xde, 0x95, 0x9b, 0xe5, 0x72, 0x16, 0xcd, 0x46, 0xcb, 0xa9, 0x42, 0xf2,
|
0x60, 0xff, 0x75, 0xe3, 0xe5, 0x8b, 0xb4, 0x46, 0xd3, 0xd9, 0x77, 0x0e, 0x2c, 0x7a, 0x92, 0x90,
|
||||||
0xd9, 0x9b, 0x60, 0xf1, 0x25, 0x17, 0x33, 0xb4, 0x02, 0x72, 0xa7, 0x64, 0xa8, 0xa6, 0x14, 0x12,
|
0x26, 0x59, 0xe3, 0x60, 0x8e, 0x83, 0x21, 0xe3, 0x9a, 0xb7, 0x72, 0xb3, 0xac, 0x99, 0x45, 0xb3,
|
||||||
0x4b, 0xb8, 0x0a, 0x16, 0xfb, 0x38, 0xe8, 0xa9, 0x61, 0x5c, 0x44, 0x4a, 0xb0, 0x5f, 0x81, 0x95,
|
0xd1, 0x72, 0xaa, 0x90, 0x7c, 0xf6, 0x26, 0x58, 0x7c, 0xc9, 0xc5, 0xb4, 0xae, 0x80, 0xdc, 0x29,
|
||||||
0x93, 0x18, 0x47, 0x0c, 0x3b, 0xdc, 0xa7, 0xd1, 0x11, 0xf5, 0x18, 0x84, 0x20, 0x2f, 0x3b, 0xa4,
|
0x19, 0xaa, 0x79, 0x88, 0xc4, 0x12, 0xae, 0x82, 0xc5, 0x3e, 0x0e, 0x7a, 0x6a, 0xec, 0x17, 0x91,
|
||||||
0x3a, 0x2b, 0xd7, 0x70, 0x13, 0xe4, 0x03, 0xea, 0xb1, 0x6a, 0xb6, 0x9e, 0x5b, 0x2f, 0x6d, 0xdf,
|
0x12, 0xec, 0x57, 0x60, 0xe5, 0x24, 0xc6, 0x11, 0xc3, 0x0e, 0xf7, 0x69, 0x74, 0x44, 0x3d, 0x06,
|
||||||
0xdd, 0xb8, 0xfa, 0x63, 0x62, 0xe3, 0x88, 0x7a, 0x48, 0x1a, 0xda, 0xdf, 0x67, 0x41, 0xee, 0x88,
|
0x21, 0xc8, 0xcb, 0x5e, 0xac, 0xce, 0xca, 0x35, 0xdc, 0x04, 0xf9, 0x80, 0x7a, 0xac, 0x9a, 0xad,
|
||||||
0x7a, 0xb0, 0x0a, 0x96, 0xb0, 0xeb, 0xc6, 0x84, 0x31, 0x8d, 0x97, 0x8a, 0x70, 0x0d, 0x14, 0x38,
|
0xe7, 0xd6, 0x4b, 0xdb, 0x77, 0x37, 0xae, 0xfe, 0x6c, 0xd9, 0x38, 0xa2, 0x1e, 0x92, 0x86, 0xf6,
|
||||||
0xed, 0xfa, 0x8e, 0x02, 0x2d, 0x22, 0x2d, 0x09, 0x7a, 0x17, 0x73, 0x2c, 0xa7, 0x8d, 0x89, 0xe4,
|
0xf7, 0x59, 0x90, 0x3b, 0xa2, 0x1e, 0xac, 0x82, 0x25, 0xec, 0xba, 0x31, 0x61, 0x4c, 0xe3, 0xa5,
|
||||||
0x1a, 0x6e, 0x03, 0x53, 0xfa, 0xdb, 0x8a, 0x7a, 0x61, 0x9b, 0xc4, 0x72, 0x68, 0xe4, 0x9b, 0x2b,
|
0x22, 0x5c, 0x03, 0x05, 0x4e, 0xbb, 0xbe, 0xa3, 0x40, 0x8b, 0x48, 0x4b, 0x82, 0xde, 0xc5, 0x1c,
|
||||||
0x67, 0x89, 0x55, 0x92, 0xfa, 0xff, 0x48, 0x35, 0x9a, 0x16, 0xe0, 0x7d, 0xb0, 0xc4, 0x07, 0xd3,
|
0xcb, 0xb9, 0x66, 0x22, 0xb9, 0x86, 0xdb, 0xc0, 0x94, 0xfe, 0xb6, 0xa2, 0x5e, 0xd8, 0x26, 0xb1,
|
||||||
0xbd, 0xfe, 0xd6, 0x59, 0x62, 0xad, 0xf0, 0x73, 0x67, 0x45, 0x2b, 0x47, 0x05, 0x3e, 0x38, 0x50,
|
0x1c, 0x4f, 0xf9, 0xe6, 0xca, 0x59, 0x62, 0x95, 0xa4, 0xfe, 0x3f, 0x52, 0x8d, 0xa6, 0x05, 0x78,
|
||||||
0x0e, 0x1a, 0x7c, 0xd0, 0xf2, 0x23, 0x97, 0x0c, 0x64, 0x3b, 0xcf, 0x37, 0x57, 0xcf, 0x12, 0xab,
|
0x1f, 0x2c, 0xf1, 0xc1, 0xf4, 0x54, 0xb9, 0x75, 0x96, 0x58, 0x2b, 0xfc, 0xdc, 0x59, 0x31, 0x34,
|
||||||
0x32, 0x65, 0x7e, 0x28, 0xf6, 0xd0, 0x12, 0x1f, 0xc8, 0x05, 0xbc, 0x0f, 0x80, 0xba, 0x92, 0x64,
|
0x50, 0x81, 0x0f, 0x0e, 0x94, 0x83, 0x06, 0x1f, 0xb4, 0xfc, 0xc8, 0x25, 0x03, 0x39, 0x38, 0xf2,
|
||||||
0x50, 0x8d, 0x78, 0xf9, 0x2c, 0xb1, 0x8a, 0x52, 0x2b, 0xb1, 0xcf, 0x97, 0xd0, 0x06, 0x8b, 0x0a,
|
0xcd, 0xd5, 0xb3, 0xc4, 0xaa, 0x4c, 0x99, 0x1f, 0x8a, 0x3d, 0xb4, 0xc4, 0x07, 0x72, 0x01, 0xef,
|
||||||
0xdb, 0x90, 0xd8, 0xe6, 0x59, 0x62, 0x19, 0x01, 0xf5, 0x14, 0xa6, 0xda, 0x12, 0xa1, 0x8a, 0x49,
|
0x03, 0xa0, 0xae, 0x24, 0x19, 0x54, 0xcb, 0x5f, 0x3e, 0x4b, 0xac, 0xa2, 0xd4, 0x4a, 0xec, 0xf3,
|
||||||
0x48, 0xfb, 0xc4, 0x95, 0x2d, 0xce, 0x40, 0xa9, 0x68, 0xff, 0x96, 0x01, 0xc5, 0x93, 0x01, 0x22,
|
0x25, 0xb4, 0xc1, 0xa2, 0xc2, 0x36, 0x24, 0xb6, 0x79, 0x96, 0x58, 0x46, 0x40, 0x3d, 0x85, 0xa9,
|
||||||
0x0e, 0xf1, 0xbb, 0xfc, 0xca, 0xfc, 0x40, 0x90, 0x7f, 0x13, 0xd3, 0x50, 0xe7, 0x56, 0xae, 0xe1,
|
0xb6, 0x44, 0xa8, 0x62, 0x12, 0xd2, 0x3e, 0x71, 0x65, 0x33, 0x35, 0x50, 0x2a, 0xda, 0xbf, 0x65,
|
||||||
0xf6, 0x54, 0x20, 0x4b, 0xdb, 0xb5, 0xeb, 0x72, 0x76, 0x32, 0xd8, 0xc3, 0x1c, 0xeb, 0x40, 0xef,
|
0x40, 0xf1, 0x64, 0x80, 0x88, 0x43, 0xfc, 0x2e, 0xbf, 0xf2, 0x7d, 0x20, 0xc8, 0xbf, 0x89, 0x69,
|
||||||
0x82, 0x42, 0x4c, 0x58, 0x2f, 0xe0, 0x32, 0xc4, 0xa5, 0xed, 0xfa, 0xf5, 0xa7, 0x90, 0xb4, 0x43,
|
0xa8, 0xdf, 0x56, 0xae, 0xe1, 0xf6, 0x54, 0x20, 0x4b, 0xdb, 0xb5, 0xeb, 0xde, 0xec, 0x64, 0xb0,
|
||||||
0xda, 0x5e, 0x3c, 0x2f, 0xe5, 0xa1, 0x08, 0x76, 0x3e, 0xf5, 0xe9, 0x6f, 0x69, 0xe2, 0x3a, 0xc4,
|
0x87, 0x39, 0xd6, 0x81, 0xde, 0x05, 0x85, 0x98, 0xb0, 0x5e, 0xc0, 0x65, 0x88, 0x4b, 0xdb, 0xf5,
|
||||||
0xf7, 0x3a, 0x5c, 0x85, 0x56, 0xe7, 0xe9, 0x40, 0xaa, 0xe0, 0x5f, 0x2f, 0x07, 0x72, 0x2a, 0x72,
|
0xeb, 0x4f, 0x21, 0x69, 0x87, 0xb4, 0xbd, 0x48, 0x2f, 0xe5, 0xa1, 0x08, 0x76, 0x3e, 0xf5, 0xe9,
|
||||||
0x8f, 0xf3, 0x5f, 0x88, 0x0f, 0xb2, 0xaf, 0xb2, 0xc0, 0x48, 0x29, 0xe1, 0x53, 0x50, 0x71, 0x68,
|
0x6f, 0xe9, 0xc3, 0x75, 0x88, 0xef, 0x75, 0xb8, 0x0a, 0xad, 0x7e, 0xa7, 0x03, 0xa9, 0x82, 0x7f,
|
||||||
0xc4, 0x63, 0xec, 0xf0, 0xd6, 0xcc, 0xe3, 0x6a, 0xde, 0x3d, 0x6f, 0xb4, 0x17, 0x2d, 0x6c, 0xb4,
|
0xbd, 0x1c, 0xc8, 0xa9, 0xc8, 0x3d, 0xce, 0x7f, 0x25, 0x3e, 0xfd, 0xbe, 0xc9, 0x02, 0x23, 0xa5,
|
||||||
0x92, 0xaa, 0x1a, 0xfa, 0x05, 0xae, 0x82, 0xc5, 0x76, 0x40, 0x75, 0xd4, 0x4c, 0xa4, 0x04, 0xf8,
|
0x84, 0x4f, 0x41, 0xc5, 0xa1, 0x11, 0x8f, 0xb1, 0xc3, 0x5b, 0x33, 0xc9, 0xd5, 0xbc, 0x7b, 0xde,
|
||||||
0x7f, 0xf9, 0x6e, 0xe4, 0x6b, 0x57, 0x91, 0xbb, 0x77, 0x6d, 0x0c, 0x66, 0x0b, 0xa7, 0xb9, 0x26,
|
0xd2, 0x2f, 0x5a, 0xd8, 0x68, 0x25, 0x55, 0x35, 0x74, 0x06, 0xae, 0x82, 0xc5, 0x76, 0x40, 0x75,
|
||||||
0x8a, 0x7a, 0x9c, 0x58, 0x65, 0x75, 0x03, 0x8d, 0x62, 0x8b, 0x37, 0x26, 0x0b, 0xab, 0x02, 0x72,
|
0xd4, 0x4c, 0xa4, 0x04, 0xf8, 0x7f, 0x99, 0x37, 0x32, 0xdb, 0x55, 0xe4, 0xee, 0x5d, 0x1b, 0x83,
|
||||||
0x31, 0x51, 0x91, 0x35, 0x91, 0x58, 0xc2, 0x3b, 0xc0, 0x88, 0x49, 0x9f, 0xc4, 0x9c, 0xb8, 0x32,
|
0xd9, 0xc2, 0x69, 0xae, 0x89, 0xa2, 0x1e, 0x27, 0x56, 0x59, 0xdd, 0x40, 0xa3, 0xd8, 0x22, 0xc7,
|
||||||
0x6e, 0x06, 0x9a, 0xc8, 0xf0, 0x36, 0x30, 0x3c, 0xcc, 0x5a, 0x3d, 0x46, 0x5c, 0x1d, 0xb6, 0x25,
|
0x64, 0x61, 0x55, 0x40, 0x2e, 0x26, 0x2a, 0xb2, 0x26, 0x12, 0x4b, 0x78, 0x07, 0x18, 0x31, 0xe9,
|
||||||
0x0f, 0xb3, 0xff, 0x31, 0xe2, 0xea, 0x98, 0xfc, 0x92, 0x05, 0x05, 0x95, 0x3c, 0xb8, 0x05, 0x0c,
|
0x93, 0x98, 0x13, 0x57, 0xc6, 0xcd, 0x40, 0x13, 0x19, 0xde, 0x06, 0x86, 0x87, 0x59, 0xab, 0xc7,
|
||||||
0x47, 0x7c, 0xae, 0xb6, 0x7c, 0x57, 0x46, 0xc2, 0x6c, 0xae, 0x8d, 0x12, 0x6b, 0x49, 0x7e, 0xc2,
|
0x88, 0xab, 0xc3, 0xb6, 0xe4, 0x61, 0xf6, 0x3f, 0x46, 0x5c, 0x1d, 0x93, 0x5f, 0xb2, 0xa0, 0xa0,
|
||||||
0x1e, 0xee, 0x9d, 0x25, 0xd6, 0x92, 0xa3, 0x96, 0x48, 0x2f, 0x5c, 0xe1, 0x7c, 0x44, 0x23, 0x47,
|
0x1e, 0x0f, 0x6e, 0x01, 0xc3, 0x11, 0x1f, 0xc6, 0x2d, 0xdf, 0x95, 0x91, 0x30, 0x9b, 0x6b, 0xa3,
|
||||||
0xb5, 0x83, 0x3c, 0x52, 0x02, 0xfc, 0x27, 0x28, 0x0a, 0xd2, 0x6e, 0xec, 0x3b, 0x44, 0x55, 0x60,
|
0xc4, 0x5a, 0x92, 0x1f, 0xcb, 0x87, 0x7b, 0x67, 0x89, 0xb5, 0xe4, 0xa8, 0x25, 0xd2, 0x0b, 0x57,
|
||||||
0xd3, 0x1c, 0x25, 0x96, 0xf1, 0x0c, 0xb3, 0x63, 0xa1, 0x43, 0xe2, 0x4e, 0x72, 0x05, 0x6b, 0x20,
|
0x38, 0x1f, 0xd1, 0xc8, 0x51, 0xed, 0x20, 0x8f, 0x94, 0x00, 0xff, 0x09, 0x8a, 0x82, 0xb4, 0x1b,
|
||||||
0xe7, 0x61, 0xa6, 0x4b, 0x31, 0x35, 0x3a, 0xf2, 0x43, 0x9f, 0x23, 0xb1, 0x01, 0xcb, 0x20, 0xcb,
|
0xfb, 0x0e, 0x51, 0x15, 0xd8, 0x34, 0x47, 0x89, 0x65, 0x3c, 0xc3, 0xec, 0x58, 0xe8, 0x90, 0xb8,
|
||||||
0xa9, 0x2a, 0x3d, 0x94, 0xe5, 0x14, 0xd6, 0xd3, 0xfe, 0x53, 0x90, 0xb0, 0x60, 0x94, 0x58, 0x85,
|
0x93, 0x5c, 0xc1, 0x1a, 0xc8, 0x79, 0x98, 0xe9, 0x52, 0x4c, 0x8d, 0x8e, 0xfc, 0xd0, 0xe7, 0x48,
|
||||||
0x46, 0x48, 0x7b, 0x11, 0xd7, 0xbd, 0x48, 0x3d, 0xa1, 0x6e, 0x8f, 0xcb, 0x47, 0x60, 0x22, 0x25,
|
0x6c, 0xc0, 0x32, 0xc8, 0x72, 0xaa, 0x4a, 0x0f, 0x65, 0x39, 0x85, 0xf5, 0xb4, 0xff, 0x14, 0x24,
|
||||||
0x40, 0x0c, 0x0c, 0xec, 0x38, 0x84, 0x31, 0xc2, 0xaa, 0x86, 0x6c, 0x3f, 0x7f, 0xbf, 0x2e, 0x21,
|
0x2c, 0x18, 0x25, 0x56, 0xa1, 0x11, 0xd2, 0x5e, 0xc4, 0x75, 0x2f, 0x52, 0x29, 0xd4, 0xed, 0x71,
|
||||||
0x0d, 0x69, 0x77, 0xd2, 0x13, 0x03, 0xbc, 0x2e, 0x92, 0x71, 0x96, 0x58, 0x40, 0x1d, 0x3e, 0xf2,
|
0x99, 0x04, 0x26, 0x52, 0x02, 0xc4, 0xc0, 0xc0, 0x8e, 0x43, 0x18, 0x23, 0xac, 0x6a, 0xc8, 0xf6,
|
||||||
0x19, 0xff, 0xf6, 0x27, 0x0b, 0x34, 0x26, 0x12, 0x9a, 0xc0, 0x42, 0x13, 0x64, 0xfa, 0xb2, 0xe6,
|
0xf3, 0xf7, 0xeb, 0x1e, 0xa4, 0x21, 0xed, 0x4e, 0x7a, 0xe2, 0x53, 0xa1, 0x2e, 0x1e, 0xe3, 0x2c,
|
||||||
0x4c, 0x94, 0xe9, 0x0b, 0x29, 0x96, 0x63, 0xde, 0x44, 0x99, 0x58, 0x48, 0x4c, 0x0e, 0x60, 0x13,
|
0xb1, 0x80, 0x3a, 0x7c, 0xe4, 0x33, 0xfe, 0xdd, 0x4f, 0x16, 0x68, 0x4c, 0x24, 0x34, 0x81, 0x85,
|
||||||
0x65, 0x98, 0x8e, 0xfc, 0x3d, 0x50, 0x6c, 0x0e, 0x39, 0x91, 0x30, 0xf2, 0x15, 0x09, 0xa1, 0x9a,
|
0x26, 0xc8, 0xf4, 0x65, 0xcd, 0x99, 0x28, 0xd3, 0x17, 0x52, 0x2c, 0x3f, 0x28, 0x4c, 0x94, 0x89,
|
||||||
0xa9, 0xe7, 0xe4, 0x2b, 0x12, 0x82, 0x36, 0xc4, 0xa0, 0x34, 0x75, 0xa7, 0x3f, 0x68, 0x86, 0xdb,
|
0x85, 0xc4, 0xe4, 0xa8, 0x37, 0x51, 0x86, 0xe9, 0xc8, 0xdf, 0x03, 0xc5, 0xe6, 0x90, 0x13, 0x09,
|
||||||
0xc0, 0x64, 0x9c, 0xc6, 0xd8, 0x23, 0xad, 0x53, 0x32, 0xd4, 0x2d, 0x51, 0x35, 0x38, 0xad, 0x7f,
|
0x23, 0xb3, 0x48, 0x08, 0xd5, 0x4c, 0x3d, 0x27, 0xb3, 0x48, 0x08, 0xda, 0x10, 0x83, 0xd2, 0xd4,
|
||||||
0x4e, 0x86, 0x0c, 0x4d, 0x0b, 0x8a, 0xa2, 0xd9, 0x78, 0x37, 0xaa, 0x65, 0xde, 0x8f, 0x6a, 0x99,
|
0x9d, 0xfe, 0xa0, 0x19, 0x6e, 0x03, 0x93, 0x71, 0x1a, 0x63, 0x8f, 0xb4, 0x4e, 0xc9, 0x50, 0xb7,
|
||||||
0x9f, 0x47, 0xb5, 0xcc, 0x97, 0x1f, 0x6a, 0x0b, 0xef, 0x3f, 0xd4, 0x16, 0x7e, 0xf8, 0x50, 0x5b,
|
0x44, 0xd5, 0xe0, 0xb4, 0xfe, 0x39, 0x19, 0x32, 0x34, 0x2d, 0x28, 0x8a, 0x66, 0xe3, 0xfd, 0xa8,
|
||||||
0xf8, 0xe8, 0xde, 0xe5, 0xd9, 0x72, 0xfe, 0x2f, 0x71, 0x20, 0xff, 0x27, 0xca, 0x01, 0xd3, 0x2e,
|
0x96, 0xf9, 0x30, 0xaa, 0x65, 0x7e, 0x1e, 0xd5, 0x32, 0x5f, 0x7f, 0xac, 0x2d, 0x7c, 0xf8, 0x58,
|
||||||
0xc8, 0xff, 0x7c, 0x8f, 0x7e, 0x0f, 0x00, 0x00, 0xff, 0xff, 0xf2, 0x3d, 0x7c, 0x52, 0x45, 0x0e,
|
0x5b, 0xf8, 0xe1, 0x63, 0x6d, 0xe1, 0x93, 0x7b, 0x97, 0x67, 0xcb, 0xf9, 0xff, 0xd1, 0x81, 0xfc,
|
||||||
0x00, 0x00,
|
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) {
|
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 = encodeVarintEvm(dAtA, i, uint64(size))
|
||||||
}
|
}
|
||||||
i--
|
i--
|
||||||
dAtA[i] = 0x7a
|
dAtA[i] = 0x1
|
||||||
|
i--
|
||||||
|
dAtA[i] = 0x82
|
||||||
{
|
{
|
||||||
size := m.EWASMBlock.Size()
|
size := m.EWASMBlock.Size()
|
||||||
i -= size
|
i -= size
|
||||||
@ -874,7 +879,7 @@ func (m *ChainConfig) MarshalToSizedBuffer(dAtA []byte) (int, error) {
|
|||||||
i = encodeVarintEvm(dAtA, i, uint64(size))
|
i = encodeVarintEvm(dAtA, i, uint64(size))
|
||||||
}
|
}
|
||||||
i--
|
i--
|
||||||
dAtA[i] = 0x72
|
dAtA[i] = 0x7a
|
||||||
{
|
{
|
||||||
size := m.YoloV3Block.Size()
|
size := m.YoloV3Block.Size()
|
||||||
i -= size
|
i -= size
|
||||||
@ -884,6 +889,16 @@ func (m *ChainConfig) MarshalToSizedBuffer(dAtA []byte) (int, error) {
|
|||||||
i = encodeVarintEvm(dAtA, i, uint64(size))
|
i = encodeVarintEvm(dAtA, i, uint64(size))
|
||||||
}
|
}
|
||||||
i--
|
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
|
dAtA[i] = 0x6a
|
||||||
{
|
{
|
||||||
size := m.MuirGlacierBlock.Size()
|
size := m.MuirGlacierBlock.Size()
|
||||||
@ -1562,12 +1577,14 @@ func (m *ChainConfig) Size() (n int) {
|
|||||||
n += 1 + l + sovEvm(uint64(l))
|
n += 1 + l + sovEvm(uint64(l))
|
||||||
l = m.MuirGlacierBlock.Size()
|
l = m.MuirGlacierBlock.Size()
|
||||||
n += 1 + l + sovEvm(uint64(l))
|
n += 1 + l + sovEvm(uint64(l))
|
||||||
|
l = m.BerlinBlock.Size()
|
||||||
|
n += 1 + l + sovEvm(uint64(l))
|
||||||
l = m.YoloV3Block.Size()
|
l = m.YoloV3Block.Size()
|
||||||
n += 1 + l + sovEvm(uint64(l))
|
n += 1 + l + sovEvm(uint64(l))
|
||||||
l = m.EWASMBlock.Size()
|
l = m.EWASMBlock.Size()
|
||||||
n += 1 + l + sovEvm(uint64(l))
|
n += 1 + l + sovEvm(uint64(l))
|
||||||
l = m.CatalystBlock.Size()
|
l = m.CatalystBlock.Size()
|
||||||
n += 1 + l + sovEvm(uint64(l))
|
n += 2 + l + sovEvm(uint64(l))
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2430,6 +2447,40 @@ func (m *ChainConfig) Unmarshal(dAtA []byte) error {
|
|||||||
}
|
}
|
||||||
iNdEx = postIndex
|
iNdEx = postIndex
|
||||||
case 13:
|
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 {
|
if wireType != 2 {
|
||||||
return fmt.Errorf("proto: wrong wireType = %d for field YoloV3Block", wireType)
|
return fmt.Errorf("proto: wrong wireType = %d for field YoloV3Block", wireType)
|
||||||
}
|
}
|
||||||
@ -2463,7 +2514,7 @@ func (m *ChainConfig) Unmarshal(dAtA []byte) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
iNdEx = postIndex
|
iNdEx = postIndex
|
||||||
case 14:
|
case 15:
|
||||||
if wireType != 2 {
|
if wireType != 2 {
|
||||||
return fmt.Errorf("proto: wrong wireType = %d for field EWASMBlock", wireType)
|
return fmt.Errorf("proto: wrong wireType = %d for field EWASMBlock", wireType)
|
||||||
}
|
}
|
||||||
@ -2497,7 +2548,7 @@ func (m *ChainConfig) Unmarshal(dAtA []byte) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
iNdEx = postIndex
|
iNdEx = postIndex
|
||||||
case 15:
|
case 16:
|
||||||
if wireType != 2 {
|
if wireType != 2 {
|
||||||
return fmt.Errorf("proto: wrong wireType = %d for field CatalystBlock", wireType)
|
return fmt.Errorf("proto: wrong wireType = %d for field CatalystBlock", wireType)
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ import (
|
|||||||
"github.com/cosmos/cosmos-sdk/crypto/keyring"
|
"github.com/cosmos/cosmos-sdk/crypto/keyring"
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||||
|
"github.com/cosmos/cosmos-sdk/x/auth/ante"
|
||||||
"github.com/cosmos/ethermint/types"
|
"github.com/cosmos/ethermint/types"
|
||||||
|
|
||||||
ethcmn "github.com/ethereum/go-ethereum/common"
|
ethcmn "github.com/ethereum/go-ethereum/common"
|
||||||
@ -18,8 +19,9 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
_ sdk.Msg = &MsgEthereumTx{}
|
_ sdk.Msg = &MsgEthereumTx{}
|
||||||
_ sdk.Tx = &MsgEthereumTx{}
|
_ sdk.Tx = &MsgEthereumTx{}
|
||||||
|
_ ante.GasTx = &MsgEthereumTx{}
|
||||||
)
|
)
|
||||||
|
|
||||||
// message type and route constants
|
// 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.
|
// GetSigners returns the expected signers for an Ethereum transaction message.
|
||||||
// For such a message, there should exist only a single 'signer'.
|
// 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 {
|
func (msg MsgEthereumTx) GetSigners() []sdk.AccAddress {
|
||||||
if msg.From == "" {
|
v, r, s := msg.RawSignatureValues()
|
||||||
panic("must use 'VerifySig' with a chain ID to get the signer")
|
|
||||||
|
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())
|
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")
|
return fmt.Errorf("sender address not defined for message")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if chainID == nil {
|
||||||
|
return fmt.Errorf("chain id cannot be nil")
|
||||||
|
}
|
||||||
|
|
||||||
txHash := msg.RLPSignBytes(chainID)
|
txHash := msg.RLPSignBytes(chainID)
|
||||||
|
|
||||||
sig, _, err := signer.SignByAddress(from, txHash[:])
|
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
|
// AsEthereumData returns an AccessListTx transaction data from the proto-formatted
|
||||||
// TxData defined on the Cosmos EVM.
|
// TxData defined on the Cosmos EVM.
|
||||||
func (data TxData) AsEthereumData() ethtypes.TxData {
|
func (data *TxData) AsEthereumData() ethtypes.TxData {
|
||||||
var to *ethcmn.Address
|
var to *ethcmn.Address
|
||||||
if data.To != "" {
|
if data.To != "" {
|
||||||
toAddr := ethcmn.HexToAddress(data.To)
|
toAddr := ethcmn.HexToAddress(data.To)
|
||||||
|
@ -13,6 +13,10 @@ import (
|
|||||||
|
|
||||||
var _ paramtypes.ParamSet = &Params{}
|
var _ paramtypes.ParamSet = &Params{}
|
||||||
|
|
||||||
|
const (
|
||||||
|
DefaultEVMDenom = types.AttoPhoton
|
||||||
|
)
|
||||||
|
|
||||||
// Parameter keys
|
// Parameter keys
|
||||||
var (
|
var (
|
||||||
ParamStoreKeyEVMDenom = []byte("EVMDenom")
|
ParamStoreKeyEVMDenom = []byte("EVMDenom")
|
||||||
@ -39,7 +43,7 @@ func NewParams(evmDenom string, enableCreate, enableCall bool, extraEIPs ...int6
|
|||||||
// DefaultParams returns default evm parameters
|
// DefaultParams returns default evm parameters
|
||||||
func DefaultParams() Params {
|
func DefaultParams() Params {
|
||||||
return Params{
|
return Params{
|
||||||
EvmDenom: types.AttoPhoton,
|
EvmDenom: DefaultEVMDenom,
|
||||||
EnableCreate: true,
|
EnableCreate: true,
|
||||||
EnableCall: true,
|
EnableCall: true,
|
||||||
ExtraEIPs: []int64(nil), // TODO: define default values from: [2929, 2200, 1884, 1344]
|
ExtraEIPs: []int64(nil), // TODO: define default values from: [2929, 2200, 1884, 1344]
|
||||||
|
@ -20,7 +20,6 @@ import (
|
|||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
"google.golang.org/grpc/codes"
|
"google.golang.org/grpc/codes"
|
||||||
"google.golang.org/grpc/grpclog"
|
"google.golang.org/grpc/grpclog"
|
||||||
"google.golang.org/grpc/metadata"
|
|
||||||
"google.golang.org/grpc/status"
|
"google.golang.org/grpc/status"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -31,7 +30,6 @@ var _ status.Status
|
|||||||
var _ = runtime.String
|
var _ = runtime.String
|
||||||
var _ = utilities.NewDoubleArray
|
var _ = utilities.NewDoubleArray
|
||||||
var _ = descriptor.ForMessage
|
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) {
|
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
|
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".
|
// RegisterQueryHandlerServer registers the http handlers for service Query to "mux".
|
||||||
// UnaryRPC :call QueryServer directly.
|
// UnaryRPC :call QueryServer directly.
|
||||||
// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906.
|
// 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 {
|
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) {
|
mux.Handle("GET", pattern_Query_Account_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||||
ctx, cancel := context.WithCancel(req.Context())
|
ctx, cancel := context.WithCancel(req.Context())
|
||||||
defer cancel()
|
defer cancel()
|
||||||
var stream runtime.ServerTransportStream
|
|
||||||
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
|
|
||||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||||
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
|
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -649,7 +645,6 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
resp, md, err := local_request_Query_Account_0(rctx, inboundMarshaler, server, req, pathParams)
|
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)
|
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
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) {
|
mux.Handle("GET", pattern_Query_CosmosAccount_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||||
ctx, cancel := context.WithCancel(req.Context())
|
ctx, cancel := context.WithCancel(req.Context())
|
||||||
defer cancel()
|
defer cancel()
|
||||||
var stream runtime.ServerTransportStream
|
|
||||||
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
|
|
||||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||||
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
|
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -672,7 +665,6 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
resp, md, err := local_request_Query_CosmosAccount_0(rctx, inboundMarshaler, server, req, pathParams)
|
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)
|
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
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) {
|
mux.Handle("GET", pattern_Query_Balance_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||||
ctx, cancel := context.WithCancel(req.Context())
|
ctx, cancel := context.WithCancel(req.Context())
|
||||||
defer cancel()
|
defer cancel()
|
||||||
var stream runtime.ServerTransportStream
|
|
||||||
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
|
|
||||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||||
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
|
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -695,7 +685,6 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
resp, md, err := local_request_Query_Balance_0(rctx, inboundMarshaler, server, req, pathParams)
|
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)
|
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
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) {
|
mux.Handle("GET", pattern_Query_Storage_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||||
ctx, cancel := context.WithCancel(req.Context())
|
ctx, cancel := context.WithCancel(req.Context())
|
||||||
defer cancel()
|
defer cancel()
|
||||||
var stream runtime.ServerTransportStream
|
|
||||||
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
|
|
||||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||||
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
|
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -718,7 +705,6 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
resp, md, err := local_request_Query_Storage_0(rctx, inboundMarshaler, server, req, pathParams)
|
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)
|
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
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) {
|
mux.Handle("GET", pattern_Query_Code_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||||
ctx, cancel := context.WithCancel(req.Context())
|
ctx, cancel := context.WithCancel(req.Context())
|
||||||
defer cancel()
|
defer cancel()
|
||||||
var stream runtime.ServerTransportStream
|
|
||||||
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
|
|
||||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||||
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
|
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -741,7 +725,6 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
resp, md, err := local_request_Query_Code_0(rctx, inboundMarshaler, server, req, pathParams)
|
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)
|
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
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) {
|
mux.Handle("GET", pattern_Query_TxLogs_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||||
ctx, cancel := context.WithCancel(req.Context())
|
ctx, cancel := context.WithCancel(req.Context())
|
||||||
defer cancel()
|
defer cancel()
|
||||||
var stream runtime.ServerTransportStream
|
|
||||||
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
|
|
||||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||||
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
|
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -764,7 +745,6 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
resp, md, err := local_request_Query_TxLogs_0(rctx, inboundMarshaler, server, req, pathParams)
|
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)
|
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
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) {
|
mux.Handle("GET", pattern_Query_TxReceipt_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||||
ctx, cancel := context.WithCancel(req.Context())
|
ctx, cancel := context.WithCancel(req.Context())
|
||||||
defer cancel()
|
defer cancel()
|
||||||
var stream runtime.ServerTransportStream
|
|
||||||
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
|
|
||||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||||
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
|
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -787,7 +765,6 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
resp, md, err := local_request_Query_TxReceipt_0(rctx, inboundMarshaler, server, req, pathParams)
|
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)
|
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
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) {
|
mux.Handle("GET", pattern_Query_TxReceiptsByBlockHeight_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||||
ctx, cancel := context.WithCancel(req.Context())
|
ctx, cancel := context.WithCancel(req.Context())
|
||||||
defer cancel()
|
defer cancel()
|
||||||
var stream runtime.ServerTransportStream
|
|
||||||
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
|
|
||||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||||
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
|
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -810,7 +785,6 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
resp, md, err := local_request_Query_TxReceiptsByBlockHeight_0(rctx, inboundMarshaler, server, req, pathParams)
|
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)
|
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
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) {
|
mux.Handle("GET", pattern_Query_TxReceiptsByBlockHash_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||||
ctx, cancel := context.WithCancel(req.Context())
|
ctx, cancel := context.WithCancel(req.Context())
|
||||||
defer cancel()
|
defer cancel()
|
||||||
var stream runtime.ServerTransportStream
|
|
||||||
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
|
|
||||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||||
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
|
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -833,7 +805,6 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
resp, md, err := local_request_Query_TxReceiptsByBlockHash_0(rctx, inboundMarshaler, server, req, pathParams)
|
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)
|
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
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) {
|
mux.Handle("GET", pattern_Query_BlockLogs_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||||
ctx, cancel := context.WithCancel(req.Context())
|
ctx, cancel := context.WithCancel(req.Context())
|
||||||
defer cancel()
|
defer cancel()
|
||||||
var stream runtime.ServerTransportStream
|
|
||||||
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
|
|
||||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||||
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
|
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -856,7 +825,6 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
resp, md, err := local_request_Query_BlockLogs_0(rctx, inboundMarshaler, server, req, pathParams)
|
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)
|
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
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) {
|
mux.Handle("GET", pattern_Query_BlockBloom_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||||
ctx, cancel := context.WithCancel(req.Context())
|
ctx, cancel := context.WithCancel(req.Context())
|
||||||
defer cancel()
|
defer cancel()
|
||||||
var stream runtime.ServerTransportStream
|
|
||||||
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
|
|
||||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||||
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
|
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -879,7 +845,6 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
resp, md, err := local_request_Query_BlockBloom_0(rctx, inboundMarshaler, server, req, pathParams)
|
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)
|
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
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) {
|
mux.Handle("GET", pattern_Query_Params_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||||
ctx, cancel := context.WithCancel(req.Context())
|
ctx, cancel := context.WithCancel(req.Context())
|
||||||
defer cancel()
|
defer cancel()
|
||||||
var stream runtime.ServerTransportStream
|
|
||||||
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
|
|
||||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||||
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
|
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -902,7 +865,6 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
resp, md, err := local_request_Query_Params_0(rctx, inboundMarshaler, server, req, pathParams)
|
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)
|
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
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) {
|
mux.Handle("GET", pattern_Query_StaticCall_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||||
ctx, cancel := context.WithCancel(req.Context())
|
ctx, cancel := context.WithCancel(req.Context())
|
||||||
defer cancel()
|
defer cancel()
|
||||||
var stream runtime.ServerTransportStream
|
|
||||||
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
|
|
||||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||||
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
|
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -925,7 +885,6 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
resp, md, err := local_request_Query_StaticCall_0(rctx, inboundMarshaler, server, req, pathParams)
|
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)
|
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||||
|
Loading…
Reference in New Issue
Block a user