WIP: upgrade cosmos-sdk from 0.45 to SMT 0.46

This commit is contained in:
Sai Kumar 2022-04-11 13:39:39 +05:30
parent 4ddc8afd18
commit a0e2858d4f
56 changed files with 1124 additions and 3255 deletions

View File

@ -1,103 +0,0 @@
package ante
import (
"fmt"
"runtime/debug"
tmlog "github.com/tendermint/tendermint/libs/log"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
"github.com/cosmos/cosmos-sdk/types/tx/signing"
authante "github.com/cosmos/cosmos-sdk/x/auth/ante"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
"github.com/tharsis/ethermint/crypto/ethsecp256k1"
)
const (
secp256k1VerifyCost uint64 = 21000
)
// NewAnteHandler returns an ante handler responsible for attempting to route an
// Ethereum or SDK transaction to an internal ante handler for performing
// transaction-level processing (e.g. fee payment, signature verification) before
// being passed onto it's respective handler.
func NewAnteHandler(options HandlerOptions) sdk.AnteHandler {
return func(
ctx sdk.Context, tx sdk.Tx, sim bool,
) (newCtx sdk.Context, err error) {
var anteHandler sdk.AnteHandler
defer Recover(ctx.Logger(), &err)
txWithExtensions, ok := tx.(authante.HasExtensionOptionsTx)
if ok {
opts := txWithExtensions.GetExtensionOptions()
if len(opts) > 0 {
switch typeURL := opts[0].GetTypeUrl(); typeURL {
case "/ethermint.evm.v1.ExtensionOptionsEthereumTx":
// handle as *evmtypes.MsgEthereumTx
anteHandler = newEthAnteHandler(options)
case "/ethermint.types.v1.ExtensionOptionsWeb3Tx":
// handle as normal Cosmos SDK tx, except signature is checked for EIP712 representation
anteHandler = newCosmosAnteHandlerEip712(options)
default:
return ctx, sdkerrors.Wrapf(
sdkerrors.ErrUnknownExtensionOptions,
"rejecting tx with unsupported extension option: %s", typeURL,
)
}
return anteHandler(ctx, tx, sim)
}
}
// handle as totally normal Cosmos SDK tx
switch tx.(type) {
case sdk.Tx:
anteHandler = newCosmosAnteHandler(options)
default:
return ctx, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "invalid transaction type: %T", tx)
}
return anteHandler(ctx, tx, sim)
}
}
func Recover(logger tmlog.Logger, err *error) {
if r := recover(); r != nil {
*err = sdkerrors.Wrapf(sdkerrors.ErrPanic, "%v", r)
if e, ok := r.(error); ok {
logger.Error(
"ante handler panicked",
"error", e,
"stack trace", string(debug.Stack()),
)
} else {
logger.Error(
"ante handler panicked",
"recover", fmt.Sprintf("%v", r),
)
}
}
}
var _ authante.SignatureVerificationGasConsumer = DefaultSigVerificationGasConsumer
// DefaultSigVerificationGasConsumer is the default implementation of SignatureVerificationGasConsumer. It consumes gas
// for signature verification based upon the public key type. The cost is fetched from the given params and is matched
// by the concrete type.
func DefaultSigVerificationGasConsumer(
meter sdk.GasMeter, sig signing.SignatureV2, params authtypes.Params,
) error {
// support for ethereum ECDSA secp256k1 keys
_, ok := sig.PubKey.(*ethsecp256k1.PubKey)
if ok {
meter.ConsumeGas(secp256k1VerifyCost, "ante verify: eth_secp256k1")
return nil
}
return authante.DefaultSigVerificationGasConsumer(meter, sig, params)
}

View File

@ -1,687 +0,0 @@
package ante_test
import (
"github.com/cosmos/cosmos-sdk/types/tx/signing"
"math/big"
"strings"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/ethereum/go-ethereum/core/types"
ethparams "github.com/ethereum/go-ethereum/params"
"github.com/tharsis/ethermint/tests"
evmtypes "github.com/tharsis/ethermint/x/evm/types"
)
func (suite AnteTestSuite) TestAnteHandler() {
suite.enableFeemarket = false
suite.SetupTest() // reset
addr, privKey := tests.NewAddrKey()
to := tests.GenerateAddress()
acc := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr.Bytes())
suite.Require().NoError(acc.SetSequence(1))
suite.app.AccountKeeper.SetAccount(suite.ctx, acc)
suite.app.EvmKeeper.SetBalance(suite.ctx, addr, big.NewInt(10000000000))
suite.app.FeeMarketKeeper.SetBaseFee(suite.ctx, big.NewInt(100))
testCases := []struct {
name string
txFn func() sdk.Tx
checkTx bool
reCheckTx bool
expPass bool
}{
{
"success - DeliverTx (contract)",
func() sdk.Tx {
signedContractTx := evmtypes.NewTxContract(
suite.app.EvmKeeper.ChainID(),
1,
big.NewInt(10),
100000,
big.NewInt(150),
big.NewInt(200),
nil,
nil,
nil,
)
signedContractTx.From = addr.Hex()
tx := suite.CreateTestTx(signedContractTx, privKey, 1, false)
return tx
},
false, false, true,
},
{
"success - CheckTx (contract)",
func() sdk.Tx {
signedContractTx := evmtypes.NewTxContract(
suite.app.EvmKeeper.ChainID(),
2,
big.NewInt(10),
100000,
big.NewInt(150),
big.NewInt(200),
nil,
nil,
nil,
)
signedContractTx.From = addr.Hex()
tx := suite.CreateTestTx(signedContractTx, privKey, 1, false)
return tx
},
true, false, true,
},
{
"success - ReCheckTx (contract)",
func() sdk.Tx {
signedContractTx := evmtypes.NewTxContract(
suite.app.EvmKeeper.ChainID(),
3,
big.NewInt(10),
100000,
big.NewInt(150),
big.NewInt(200),
nil,
nil,
nil,
)
signedContractTx.From = addr.Hex()
tx := suite.CreateTestTx(signedContractTx, privKey, 1, false)
return tx
},
false, true, true,
},
{
"success - DeliverTx",
func() sdk.Tx {
signedTx := evmtypes.NewTx(
suite.app.EvmKeeper.ChainID(),
4,
&to,
big.NewInt(10),
100000,
big.NewInt(150),
big.NewInt(200),
nil,
nil,
nil,
)
signedTx.From = addr.Hex()
tx := suite.CreateTestTx(signedTx, privKey, 1, false)
return tx
},
false, false, true,
},
{
"success - CheckTx",
func() sdk.Tx {
signedTx := evmtypes.NewTx(
suite.app.EvmKeeper.ChainID(),
5,
&to,
big.NewInt(10),
100000,
big.NewInt(150),
big.NewInt(200),
nil,
nil,
nil,
)
signedTx.From = addr.Hex()
tx := suite.CreateTestTx(signedTx, privKey, 1, false)
return tx
},
true, false, true,
},
{
"success - ReCheckTx",
func() sdk.Tx {
signedTx := evmtypes.NewTx(
suite.app.EvmKeeper.ChainID(),
6,
&to,
big.NewInt(10),
100000,
big.NewInt(150),
big.NewInt(200),
nil,
nil,
nil,
)
signedTx.From = addr.Hex()
tx := suite.CreateTestTx(signedTx, privKey, 1, false)
return tx
}, false, true, true,
},
{
"success - CheckTx (cosmos tx not signed)",
func() sdk.Tx {
signedTx := evmtypes.NewTx(
suite.app.EvmKeeper.ChainID(),
7,
&to,
big.NewInt(10),
100000,
big.NewInt(150),
big.NewInt(200),
nil,
nil,
nil,
)
signedTx.From = addr.Hex()
tx := suite.CreateTestTx(signedTx, privKey, 1, false)
return tx
}, false, true, true,
},
{
"fail - CheckTx (cosmos tx is not valid)",
func() sdk.Tx {
signedTx := evmtypes.NewTx(suite.app.EvmKeeper.ChainID(), 8, &to, big.NewInt(10), 100000, big.NewInt(1), nil, nil, nil, nil)
signedTx.From = addr.Hex()
txBuilder := suite.CreateTestTxBuilder(signedTx, privKey, 1, false)
// bigger than MaxGasWanted
txBuilder.SetGasLimit(uint64(1 << 63))
return txBuilder.GetTx()
}, true, false, false,
},
{
"fail - CheckTx (memo too long)",
func() sdk.Tx {
signedTx := evmtypes.NewTx(suite.app.EvmKeeper.ChainID(), 5, &to, big.NewInt(10), 100000, big.NewInt(1), nil, nil, nil, nil)
signedTx.From = addr.Hex()
txBuilder := suite.CreateTestTxBuilder(signedTx, privKey, 1, false)
txBuilder.SetMemo(strings.Repeat("*", 257))
return txBuilder.GetTx()
}, true, false, false,
},
{
"fail - CheckTx (ExtensionOptionsEthereumTx not set)",
func() sdk.Tx {
signedTx := evmtypes.NewTx(suite.app.EvmKeeper.ChainID(), 5, &to, big.NewInt(10), 100000, big.NewInt(1), nil, nil, nil, nil)
signedTx.From = addr.Hex()
txBuilder := suite.CreateTestTxBuilder(signedTx, privKey, 1, false, true)
return txBuilder.GetTx()
}, true, false, false,
},
// Based on EVMBackend.SendTransaction, for cosmos tx, forcing null for some fields except ExtensionOptions, Fee, MsgEthereumTx
// should be part of consensus
{
"fail - DeliverTx (cosmos tx signed)",
func() sdk.Tx {
nonce, err := suite.app.AccountKeeper.GetSequence(suite.ctx, acc.GetAddress())
suite.Require().NoError(err)
signedTx := evmtypes.NewTx(suite.app.EvmKeeper.ChainID(), nonce, &to, big.NewInt(10), 100000, big.NewInt(1), nil, nil, nil, nil)
signedTx.From = addr.Hex()
tx := suite.CreateTestTx(signedTx, privKey, 1, true)
return tx
}, false, false, false,
},
{
"fail - DeliverTx (cosmos tx with memo)",
func() sdk.Tx {
nonce, err := suite.app.AccountKeeper.GetSequence(suite.ctx, acc.GetAddress())
suite.Require().NoError(err)
signedTx := evmtypes.NewTx(suite.app.EvmKeeper.ChainID(), nonce, &to, big.NewInt(10), 100000, big.NewInt(1), nil, nil, nil, nil)
signedTx.From = addr.Hex()
txBuilder := suite.CreateTestTxBuilder(signedTx, privKey, 1, false)
txBuilder.SetMemo("memo for cosmos tx not allowed")
return txBuilder.GetTx()
}, false, false, false,
},
{
"fail - DeliverTx (cosmos tx with timeoutheight)",
func() sdk.Tx {
nonce, err := suite.app.AccountKeeper.GetSequence(suite.ctx, acc.GetAddress())
suite.Require().NoError(err)
signedTx := evmtypes.NewTx(suite.app.EvmKeeper.ChainID(), nonce, &to, big.NewInt(10), 100000, big.NewInt(1), nil, nil, nil, nil)
signedTx.From = addr.Hex()
txBuilder := suite.CreateTestTxBuilder(signedTx, privKey, 1, false)
txBuilder.SetTimeoutHeight(10)
return txBuilder.GetTx()
}, false, false, false,
},
{
"fail - DeliverTx (invalid fee amount)",
func() sdk.Tx {
nonce, err := suite.app.AccountKeeper.GetSequence(suite.ctx, acc.GetAddress())
suite.Require().NoError(err)
signedTx := evmtypes.NewTx(suite.app.EvmKeeper.ChainID(), nonce, &to, big.NewInt(10), 100000, big.NewInt(1), nil, nil, nil, nil)
signedTx.From = addr.Hex()
txBuilder := suite.CreateTestTxBuilder(signedTx, privKey, 1, false)
txData, err := evmtypes.UnpackTxData(signedTx.Data)
suite.Require().NoError(err)
expFee := txData.Fee()
invalidFee := new(big.Int).Add(expFee, big.NewInt(1))
invalidFeeAmount := sdk.Coins{sdk.NewCoin(evmtypes.DefaultEVMDenom, sdk.NewIntFromBigInt(invalidFee))}
txBuilder.SetFeeAmount(invalidFeeAmount)
return txBuilder.GetTx()
}, false, false, false,
},
{
"fail - DeliverTx (invalid fee gaslimit)",
func() sdk.Tx {
nonce, err := suite.app.AccountKeeper.GetSequence(suite.ctx, acc.GetAddress())
suite.Require().NoError(err)
signedTx := evmtypes.NewTx(suite.app.EvmKeeper.ChainID(), nonce, &to, big.NewInt(10), 100000, big.NewInt(1), nil, nil, nil, nil)
signedTx.From = addr.Hex()
txBuilder := suite.CreateTestTxBuilder(signedTx, privKey, 1, false)
expGasLimit := signedTx.GetGas()
invalidGasLimit := expGasLimit + 1
txBuilder.SetGasLimit(invalidGasLimit)
return txBuilder.GetTx()
}, false, false, false,
},
{
"success - DeliverTx EIP712 signed Cosmos Tx with MsgSend",
func() sdk.Tx {
from := acc.GetAddress()
amount := sdk.NewCoins(sdk.NewCoin(evmtypes.DefaultEVMDenom, sdk.NewInt(20)))
gas := uint64(200000)
txBuilder := suite.CreateTestEIP712TxBuilderMsgSend(from, privKey, "ethermint_9000-1", gas, amount)
return txBuilder.GetTx()
}, false, false, true,
},
{
"success - DeliverTx EIP712 signed Cosmos Tx with DelegateMsg",
func() sdk.Tx {
from := acc.GetAddress()
coinAmount := sdk.NewCoin(evmtypes.DefaultEVMDenom, sdk.NewInt(20))
amount := sdk.NewCoins(coinAmount)
gas := uint64(200000)
txBuilder := suite.CreateTestEIP712TxBuilderMsgDelegate(from, privKey, "ethermint_9000-1", gas, amount)
return txBuilder.GetTx()
}, false, false, true,
},
{
"fails - DeliverTx EIP712 signed Cosmos Tx with wrong Chain ID",
func() sdk.Tx {
from := acc.GetAddress()
amount := sdk.NewCoins(sdk.NewCoin(evmtypes.DefaultEVMDenom, sdk.NewInt(20)))
gas := uint64(200000)
txBuilder := suite.CreateTestEIP712TxBuilderMsgSend(from, privKey, "ethermint_9002-1", gas, amount)
return txBuilder.GetTx()
}, false, false, false,
},
{
"fails - DeliverTx EIP712 signed Cosmos Tx with different gas fees",
func() sdk.Tx {
from := acc.GetAddress()
amount := sdk.NewCoins(sdk.NewCoin(evmtypes.DefaultEVMDenom, sdk.NewInt(20)))
gas := uint64(200000)
txBuilder := suite.CreateTestEIP712TxBuilderMsgSend(from, privKey, "ethermint_9001-1", gas, amount)
txBuilder.SetGasLimit(uint64(300000))
txBuilder.SetFeeAmount(sdk.NewCoins(sdk.NewCoin(evmtypes.DefaultEVMDenom, sdk.NewInt(30))))
return txBuilder.GetTx()
}, false, false, false,
},
{
"fails - DeliverTx EIP712 signed Cosmos Tx with empty signature",
func() sdk.Tx {
from := acc.GetAddress()
amount := sdk.NewCoins(sdk.NewCoin(evmtypes.DefaultEVMDenom, sdk.NewInt(20)))
gas := uint64(200000)
txBuilder := suite.CreateTestEIP712TxBuilderMsgSend(from, privKey, "ethermint_9001-1", gas, amount)
sigsV2 := signing.SignatureV2{}
txBuilder.SetSignatures(sigsV2)
return txBuilder.GetTx()
}, false, false, false,
},
{
"fails - DeliverTx EIP712 signed Cosmos Tx with invalid sequence",
func() sdk.Tx {
from := acc.GetAddress()
amount := sdk.NewCoins(sdk.NewCoin(evmtypes.DefaultEVMDenom, sdk.NewInt(20)))
gas := uint64(200000)
txBuilder := suite.CreateTestEIP712TxBuilderMsgSend(from, privKey, "ethermint_9001-1", gas, amount)
nonce, err := suite.app.AccountKeeper.GetSequence(suite.ctx, acc.GetAddress())
suite.Require().NoError(err)
sigsV2 := signing.SignatureV2{
PubKey: privKey.PubKey(),
Data: &signing.SingleSignatureData{
SignMode: signing.SignMode_SIGN_MODE_LEGACY_AMINO_JSON,
},
Sequence: nonce - 1,
}
txBuilder.SetSignatures(sigsV2)
return txBuilder.GetTx()
}, false, false, false,
},
{
"fails - DeliverTx EIP712 signed Cosmos Tx with invalid signMode",
func() sdk.Tx {
from := acc.GetAddress()
amount := sdk.NewCoins(sdk.NewCoin(evmtypes.DefaultEVMDenom, sdk.NewInt(20)))
gas := uint64(200000)
txBuilder := suite.CreateTestEIP712TxBuilderMsgSend(from, privKey, "ethermint_9001-1", gas, amount)
nonce, err := suite.app.AccountKeeper.GetSequence(suite.ctx, acc.GetAddress())
suite.Require().NoError(err)
sigsV2 := signing.SignatureV2{
PubKey: privKey.PubKey(),
Data: &signing.SingleSignatureData{
SignMode: signing.SignMode_SIGN_MODE_UNSPECIFIED,
},
Sequence: nonce,
}
txBuilder.SetSignatures(sigsV2)
return txBuilder.GetTx()
}, false, false, false,
},
}
for _, tc := range testCases {
suite.Run(tc.name, func() {
suite.ctx = suite.ctx.WithIsCheckTx(tc.checkTx).WithIsReCheckTx(tc.reCheckTx)
// expConsumed := params.TxGasContractCreation + params.TxGas
_, err := suite.anteHandler(suite.ctx, tc.txFn(), false)
// suite.Require().Equal(consumed, ctx.GasMeter().GasConsumed())
if tc.expPass {
suite.Require().NoError(err)
// suite.Require().Equal(int(expConsumed), int(suite.ctx.GasMeter().GasConsumed()))
} else {
suite.Require().Error(err)
}
})
}
}
func (suite AnteTestSuite) TestAnteHandlerWithDynamicTxFee() {
addr, privKey := tests.NewAddrKey()
to := tests.GenerateAddress()
testCases := []struct {
name string
txFn func() sdk.Tx
enableLondonHF bool
checkTx bool
reCheckTx bool
expPass bool
}{
{
"success - DeliverTx (contract)",
func() sdk.Tx {
signedContractTx :=
evmtypes.NewTxContract(
suite.app.EvmKeeper.ChainID(),
1,
big.NewInt(10),
100000,
nil,
big.NewInt(ethparams.InitialBaseFee+1),
big.NewInt(1),
nil,
&types.AccessList{},
)
signedContractTx.From = addr.Hex()
tx := suite.CreateTestTx(signedContractTx, privKey, 1, false)
return tx
},
true,
false, false, true,
},
{
"success - CheckTx (contract)",
func() sdk.Tx {
signedContractTx :=
evmtypes.NewTxContract(
suite.app.EvmKeeper.ChainID(),
1,
big.NewInt(10),
100000,
nil,
big.NewInt(ethparams.InitialBaseFee+1),
big.NewInt(1),
nil,
&types.AccessList{},
)
signedContractTx.From = addr.Hex()
tx := suite.CreateTestTx(signedContractTx, privKey, 1, false)
return tx
},
true,
true, false, true,
},
{
"success - ReCheckTx (contract)",
func() sdk.Tx {
signedContractTx :=
evmtypes.NewTxContract(
suite.app.EvmKeeper.ChainID(),
1,
big.NewInt(10),
100000,
nil,
big.NewInt(ethparams.InitialBaseFee+1),
big.NewInt(1),
nil,
&types.AccessList{},
)
signedContractTx.From = addr.Hex()
tx := suite.CreateTestTx(signedContractTx, privKey, 1, false)
return tx
},
true,
false, true, true,
},
{
"success - DeliverTx",
func() sdk.Tx {
signedTx :=
evmtypes.NewTx(
suite.app.EvmKeeper.ChainID(),
1,
&to,
big.NewInt(10),
100000,
nil,
big.NewInt(ethparams.InitialBaseFee+1),
big.NewInt(1),
nil,
&types.AccessList{},
)
signedTx.From = addr.Hex()
tx := suite.CreateTestTx(signedTx, privKey, 1, false)
return tx
},
true,
false, false, true,
},
{
"success - CheckTx",
func() sdk.Tx {
signedTx :=
evmtypes.NewTx(
suite.app.EvmKeeper.ChainID(),
1,
&to,
big.NewInt(10),
100000,
nil,
big.NewInt(ethparams.InitialBaseFee+1),
big.NewInt(1),
nil,
&types.AccessList{},
)
signedTx.From = addr.Hex()
tx := suite.CreateTestTx(signedTx, privKey, 1, false)
return tx
},
true,
true, false, true,
},
{
"success - ReCheckTx",
func() sdk.Tx {
signedTx :=
evmtypes.NewTx(
suite.app.EvmKeeper.ChainID(),
1,
&to,
big.NewInt(10),
100000,
nil,
big.NewInt(ethparams.InitialBaseFee+1),
big.NewInt(1),
nil,
&types.AccessList{},
)
signedTx.From = addr.Hex()
tx := suite.CreateTestTx(signedTx, privKey, 1, false)
return tx
},
true,
false, true, true,
},
{
"success - CheckTx (cosmos tx not signed)",
func() sdk.Tx {
signedTx :=
evmtypes.NewTx(
suite.app.EvmKeeper.ChainID(),
1,
&to,
big.NewInt(10),
100000,
nil,
big.NewInt(ethparams.InitialBaseFee+1),
big.NewInt(1),
nil,
&types.AccessList{},
)
signedTx.From = addr.Hex()
tx := suite.CreateTestTx(signedTx, privKey, 1, false)
return tx
},
true,
false, true, true,
},
{
"fail - CheckTx (cosmos tx is not valid)",
func() sdk.Tx {
signedTx :=
evmtypes.NewTx(
suite.app.EvmKeeper.ChainID(),
1,
&to,
big.NewInt(10),
100000,
nil,
big.NewInt(ethparams.InitialBaseFee+1),
big.NewInt(1),
nil,
&types.AccessList{},
)
signedTx.From = addr.Hex()
txBuilder := suite.CreateTestTxBuilder(signedTx, privKey, 1, false)
// bigger than MaxGasWanted
txBuilder.SetGasLimit(uint64(1 << 63))
return txBuilder.GetTx()
},
true,
true, false, false,
},
{
"fail - CheckTx (memo too long)",
func() sdk.Tx {
signedTx :=
evmtypes.NewTx(
suite.app.EvmKeeper.ChainID(),
1,
&to,
big.NewInt(10),
100000,
nil,
big.NewInt(ethparams.InitialBaseFee+1),
big.NewInt(1),
nil,
&types.AccessList{},
)
signedTx.From = addr.Hex()
txBuilder := suite.CreateTestTxBuilder(signedTx, privKey, 1, false)
txBuilder.SetMemo(strings.Repeat("*", 257))
return txBuilder.GetTx()
},
true,
true, false, false,
},
{
"fail - DynamicFeeTx without london hark fork",
func() sdk.Tx {
signedContractTx :=
evmtypes.NewTxContract(
suite.app.EvmKeeper.ChainID(),
1,
big.NewInt(10),
100000,
nil,
big.NewInt(ethparams.InitialBaseFee+1),
big.NewInt(1),
nil,
&types.AccessList{},
)
signedContractTx.From = addr.Hex()
tx := suite.CreateTestTx(signedContractTx, privKey, 1, false)
return tx
},
false,
false, false, false,
},
}
for _, tc := range testCases {
suite.Run(tc.name, func() {
suite.enableFeemarket = true
suite.enableLondonHF = tc.enableLondonHF
suite.SetupTest() // reset
acc := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr.Bytes())
suite.Require().NoError(acc.SetSequence(1))
suite.app.AccountKeeper.SetAccount(suite.ctx, acc)
suite.ctx = suite.ctx.WithIsCheckTx(tc.checkTx).WithIsReCheckTx(tc.reCheckTx)
suite.app.EvmKeeper.SetBalance(suite.ctx, addr, big.NewInt((ethparams.InitialBaseFee+10)*100000))
_, err := suite.anteHandler(suite.ctx, tc.txFn(), false)
if tc.expPass {
suite.Require().NoError(err)
} else {
suite.Require().Error(err)
}
})
}
suite.enableFeemarket = false
suite.enableLondonHF = true
}

View File

@ -1,11 +0,0 @@
/*Package ante defines the SDK auth module's AnteHandler as well as an internal
AnteHandler for an Ethereum transaction (i.e MsgEthereumTx).
During CheckTx, the transaction is passed through a series of
pre-message execution validation checks such as signature and account
verification in addition to minimum fees being checked. Otherwise, during
DeliverTx, the transaction is simply passed to the EVM which will also
perform the same series of checks. The distinction is made in CheckTx to
prevent spam and DoS attacks.
*/
package ante

View File

@ -1,272 +0,0 @@
package ante
import (
"fmt"
"github.com/cosmos/cosmos-sdk/codec"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
"github.com/cosmos/cosmos-sdk/types/tx/signing"
authante "github.com/cosmos/cosmos-sdk/x/auth/ante"
"github.com/cosmos/cosmos-sdk/x/auth/legacy/legacytx"
authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing"
ethcrypto "github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/crypto/secp256k1"
"github.com/tharsis/ethermint/crypto/ethsecp256k1"
"github.com/tharsis/ethermint/ethereum/eip712"
ethermint "github.com/tharsis/ethermint/types"
evmtypes "github.com/tharsis/ethermint/x/evm/types"
)
var ethermintCodec codec.ProtoCodecMarshaler
func init() {
registry := codectypes.NewInterfaceRegistry()
ethermint.RegisterInterfaces(registry)
ethermintCodec = codec.NewProtoCodec(registry)
}
// Eip712SigVerificationDecorator Verify all signatures for a tx and return an error if any are invalid. Note,
// the Eip712SigVerificationDecorator decorator will not get executed on ReCheck.
//
// CONTRACT: Pubkeys are set in context for all signers before this decorator runs
// CONTRACT: Tx must implement SigVerifiableTx interface
type Eip712SigVerificationDecorator struct {
ak evmtypes.AccountKeeper
signModeHandler authsigning.SignModeHandler
}
// NewEip712SigVerificationDecorator creates a new Eip712SigVerificationDecorator
func NewEip712SigVerificationDecorator(ak evmtypes.AccountKeeper, signModeHandler authsigning.SignModeHandler) Eip712SigVerificationDecorator {
return Eip712SigVerificationDecorator{
ak: ak,
signModeHandler: signModeHandler,
}
}
// AnteHandle handles validation of EIP712 signed cosmos txs.
// it is not run on RecheckTx
func (svd Eip712SigVerificationDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (newCtx sdk.Context, err error) {
// no need to verify signatures on recheck tx
if ctx.IsReCheckTx() {
return next(ctx, tx, simulate)
}
sigTx, ok := tx.(authsigning.SigVerifiableTx)
if !ok {
return ctx, sdkerrors.Wrapf(sdkerrors.ErrInvalidType, "tx %T doesn't implement authsigning.SigVerifiableTx", tx)
}
authSignTx, ok := tx.(authsigning.Tx)
if !ok {
return ctx, sdkerrors.Wrapf(sdkerrors.ErrInvalidType, "tx %T doesn't implement the authsigning.Tx interface", tx)
}
// stdSigs contains the sequence number, account number, and signatures.
// When simulating, this would just be a 0-length slice.
sigs, err := sigTx.GetSignaturesV2()
if err != nil {
return ctx, err
}
signerAddrs := sigTx.GetSigners()
// EIP712 allows just one signature
if len(sigs) != 1 {
return ctx, sdkerrors.Wrapf(sdkerrors.ErrUnauthorized, "invalid number of signers (%d); EIP712 signatures allows just one signature", len(sigs))
}
// check that signer length and signature length are the same
if len(sigs) != len(signerAddrs) {
return ctx, sdkerrors.Wrapf(sdkerrors.ErrUnauthorized, "invalid number of signer; expected: %d, got %d", len(signerAddrs), len(sigs))
}
// EIP712 has just one signature, avoid looping here and only read index 0
i := 0
sig := sigs[i]
acc, err := authante.GetSignerAcc(ctx, svd.ak, signerAddrs[i])
if err != nil {
return ctx, err
}
// retrieve pubkey
pubKey := acc.GetPubKey()
if !simulate && pubKey == nil {
return ctx, sdkerrors.Wrap(sdkerrors.ErrInvalidPubKey, "pubkey on account is not set")
}
// Check account sequence number.
if sig.Sequence != acc.GetSequence() {
return ctx, sdkerrors.Wrapf(
sdkerrors.ErrWrongSequence,
"account sequence mismatch, expected %d, got %d", acc.GetSequence(), sig.Sequence,
)
}
// retrieve signer data
genesis := ctx.BlockHeight() == 0
chainID := ctx.ChainID()
var accNum uint64
if !genesis {
accNum = acc.GetAccountNumber()
}
signerData := authsigning.SignerData{
ChainID: chainID,
AccountNumber: accNum,
Sequence: acc.GetSequence(),
}
if simulate {
return next(ctx, tx, simulate)
}
if err := VerifySignature(pubKey, signerData, sig.Data, svd.signModeHandler, authSignTx); err != nil {
errMsg := fmt.Errorf("signature verification failed; please verify account number (%d) and chain-id (%s): %w", accNum, chainID, err)
return ctx, sdkerrors.Wrap(sdkerrors.ErrUnauthorized, errMsg.Error())
}
return next(ctx, tx, simulate)
}
// VerifySignature verifies a transaction signature contained in SignatureData abstracting over different signing modes
// and single vs multi-signatures.
func VerifySignature(
pubKey cryptotypes.PubKey,
signerData authsigning.SignerData,
sigData signing.SignatureData,
_ authsigning.SignModeHandler,
tx authsigning.Tx,
) error {
switch data := sigData.(type) {
case *signing.SingleSignatureData:
if data.SignMode != signing.SignMode_SIGN_MODE_LEGACY_AMINO_JSON {
return sdkerrors.Wrapf(sdkerrors.ErrNotSupported, "unexpected SignatureData %T: wrong SignMode", sigData)
}
// Note: this prevents the user from sending thrash data in the signature field
if len(data.Signature) != 0 {
return sdkerrors.Wrap(sdkerrors.ErrTooManySignatures, "invalid signature value; EIP712 must have the cosmos transaction signature empty")
}
// @contract: this code is reached only when Msg has Web3Tx extension (so this custom Ante handler flow),
// and the signature is SIGN_MODE_LEGACY_AMINO_JSON which is supported for EIP712 for now
msgs := tx.GetMsgs()
if len(msgs) == 0 {
return sdkerrors.Wrap(sdkerrors.ErrNoSignatures, "tx doesn't contain any msgs to verify signature")
}
txBytes := legacytx.StdSignBytes(
signerData.ChainID,
signerData.AccountNumber,
signerData.Sequence,
tx.GetTimeoutHeight(),
legacytx.StdFee{
Amount: tx.GetFee(),
Gas: tx.GetGas(),
},
msgs, tx.GetMemo(),
)
signerChainID, err := ethermint.ParseChainID(signerData.ChainID)
if err != nil {
return sdkerrors.Wrapf(err, "failed to parse chainID: %s", signerData.ChainID)
}
txWithExtensions, ok := tx.(authante.HasExtensionOptionsTx)
if !ok {
return sdkerrors.Wrap(sdkerrors.ErrUnknownExtensionOptions, "tx doesnt contain any extensions")
}
opts := txWithExtensions.GetExtensionOptions()
if len(opts) != 1 {
return sdkerrors.Wrap(sdkerrors.ErrUnknownExtensionOptions, "tx doesnt contain expected amount of extension options")
}
var optIface ethermint.ExtensionOptionsWeb3TxI
if err := ethermintCodec.UnpackAny(opts[0], &optIface); err != nil {
return sdkerrors.Wrap(err, "failed to proto-unpack ExtensionOptionsWeb3Tx")
}
extOpt, ok := optIface.(*ethermint.ExtensionOptionsWeb3Tx)
if !ok {
return sdkerrors.Wrap(sdkerrors.ErrInvalidChainID, "unknown extension option")
}
if extOpt.TypedDataChainID != signerChainID.Uint64() {
return sdkerrors.Wrap(sdkerrors.ErrInvalidChainID, "invalid chainID")
}
if len(extOpt.FeePayer) == 0 {
return sdkerrors.Wrap(sdkerrors.ErrUnknownExtensionOptions, "no feePayer on ExtensionOptionsWeb3Tx")
}
feePayer, err := sdk.AccAddressFromBech32(extOpt.FeePayer)
if err != nil {
return sdkerrors.Wrap(err, "failed to parse feePayer from ExtensionOptionsWeb3Tx")
}
feeDelegation := &eip712.FeeDelegationOptions{
FeePayer: feePayer,
}
typedData, err := eip712.WrapTxToTypedData(ethermintCodec, extOpt.TypedDataChainID, msgs[0], txBytes, feeDelegation)
if err != nil {
return sdkerrors.Wrap(err, "failed to pack tx data in EIP712 object")
}
sigHash, err := eip712.ComputeTypedDataHash(typedData)
if err != nil {
return err
}
feePayerSig := extOpt.FeePayerSig
if len(feePayerSig) != ethcrypto.SignatureLength {
return sdkerrors.Wrap(sdkerrors.ErrorInvalidSigner, "signature length doesn't match typical [R||S||V] signature 65 bytes")
}
// Remove the recovery offset if needed (ie. Metamask eip712 signature)
if feePayerSig[ethcrypto.RecoveryIDOffset] == 27 || feePayerSig[ethcrypto.RecoveryIDOffset] == 28 {
feePayerSig[ethcrypto.RecoveryIDOffset] -= 27
}
feePayerPubkey, err := secp256k1.RecoverPubkey(sigHash, feePayerSig)
if err != nil {
return sdkerrors.Wrap(err, "failed to recover delegated fee payer from sig")
}
ecPubKey, err := ethcrypto.UnmarshalPubkey(feePayerPubkey)
if err != nil {
return sdkerrors.Wrap(err, "failed to unmarshal recovered fee payer pubkey")
}
pk := &ethsecp256k1.PubKey{
Key: ethcrypto.CompressPubkey(ecPubKey),
}
if !pubKey.Equals(pk) {
return sdkerrors.Wrapf(sdkerrors.ErrInvalidPubKey, "feePayer pubkey %s is different from transaction pubkey %s", pubKey, pk)
}
recoveredFeePayerAcc := sdk.AccAddress(pk.Address().Bytes())
if !recoveredFeePayerAcc.Equals(feePayer) {
return sdkerrors.Wrapf(sdkerrors.ErrorInvalidSigner, "failed to verify delegated fee payer %s signature", recoveredFeePayerAcc)
}
// VerifySignature of ethsecp256k1 accepts 64 byte signature [R||S]
// WARNING! Under NO CIRCUMSTANCES try to use pubKey.VerifySignature there
if !secp256k1.VerifySignature(pubKey.Bytes(), sigHash, feePayerSig[:len(feePayerSig)-1]) {
return sdkerrors.Wrap(sdkerrors.ErrorInvalidSigner, "unable to verify signer signature of EIP712 typed data")
}
return nil
default:
return sdkerrors.Wrapf(sdkerrors.ErrTooManySignatures, "unexpected SignatureData %T", sigData)
}
}

View File

@ -1,534 +0,0 @@
package ante
import (
"errors"
"math/big"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
authante "github.com/cosmos/cosmos-sdk/x/auth/ante"
ethermint "github.com/tharsis/ethermint/types"
evmkeeper "github.com/tharsis/ethermint/x/evm/keeper"
"github.com/tharsis/ethermint/x/evm/statedb"
evmtypes "github.com/tharsis/ethermint/x/evm/types"
"github.com/ethereum/go-ethereum/common"
ethtypes "github.com/ethereum/go-ethereum/core/types"
)
// EthSigVerificationDecorator validates an ethereum signatures
type EthSigVerificationDecorator struct {
evmKeeper EVMKeeper
}
// NewEthSigVerificationDecorator creates a new EthSigVerificationDecorator
func NewEthSigVerificationDecorator(ek EVMKeeper) EthSigVerificationDecorator {
return EthSigVerificationDecorator{
evmKeeper: ek,
}
}
// 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.
// It's not skipped for RecheckTx, because it set `From` address which is critical from other ante handler to work.
// Failure in RecheckTx will prevent tx to be included into block, especially when CheckTx succeed, in which case user
// won't see the error message.
func (esvd EthSigVerificationDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (newCtx sdk.Context, err error) {
chainID := esvd.evmKeeper.ChainID()
params := esvd.evmKeeper.GetParams(ctx)
ethCfg := params.ChainConfig.EthereumConfig(chainID)
blockNum := big.NewInt(ctx.BlockHeight())
signer := ethtypes.MakeSigner(ethCfg, blockNum)
for _, msg := range tx.GetMsgs() {
msgEthTx, ok := msg.(*evmtypes.MsgEthereumTx)
if !ok {
return ctx, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "invalid message type %T, expected %T", msg, (*evmtypes.MsgEthereumTx)(nil))
}
sender, err := signer.Sender(msgEthTx.AsTransaction())
if err != nil {
return ctx, sdkerrors.Wrapf(
sdkerrors.ErrorInvalidSigner,
"couldn't retrieve sender address ('%s') from the ethereum transaction: %s",
msgEthTx.From,
err.Error(),
)
}
// set up the sender to the transaction field if not already
msgEthTx.From = sender.Hex()
}
return next(ctx, tx, simulate)
}
// EthAccountVerificationDecorator validates an account balance checks
type EthAccountVerificationDecorator struct {
ak evmtypes.AccountKeeper
bankKeeper evmtypes.BankKeeper
evmKeeper EVMKeeper
}
// NewEthAccountVerificationDecorator creates a new EthAccountVerificationDecorator
func NewEthAccountVerificationDecorator(ak evmtypes.AccountKeeper, bankKeeper evmtypes.BankKeeper, ek EVMKeeper) EthAccountVerificationDecorator {
return EthAccountVerificationDecorator{
ak: ak,
bankKeeper: bankKeeper,
evmKeeper: ek,
}
}
// AnteHandle validates checks that the sender balance is greater than the total transaction cost.
// The account will be set to store if it doesn't exis, i.e cannot be found on store.
// This AnteHandler decorator will fail if:
// - any of the msgs is not a MsgEthereumTx
// - from address is empty
// - account balance is lower than the transaction cost
func (avd EthAccountVerificationDecorator) 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)
}
for i, msg := range tx.GetMsgs() {
msgEthTx, ok := msg.(*evmtypes.MsgEthereumTx)
if !ok {
return ctx, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "invalid message type %T, expected %T", msg, (*evmtypes.MsgEthereumTx)(nil))
}
txData, err := evmtypes.UnpackTxData(msgEthTx.Data)
if err != nil {
return ctx, sdkerrors.Wrapf(err, "failed to unpack tx data any for tx %d", i)
}
// sender address should be in the tx cache from the previous AnteHandle call
from := msgEthTx.GetFrom()
if from.Empty() {
return ctx, sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "from address cannot be empty")
}
// check whether the sender address is EOA
fromAddr := common.BytesToAddress(from)
acct := avd.evmKeeper.GetAccount(ctx, fromAddr)
if acct == nil {
acc := avd.ak.NewAccountWithAddress(ctx, from)
avd.ak.SetAccount(ctx, acc)
acct = statedb.NewEmptyAccount()
} else if acct.IsContract() {
return ctx, sdkerrors.Wrapf(sdkerrors.ErrInvalidType,
"the sender is not EOA: address %s, codeHash <%s>", fromAddr, acct.CodeHash)
}
if err := evmkeeper.CheckSenderBalance(sdk.NewIntFromBigInt(acct.Balance), txData); err != nil {
return ctx, sdkerrors.Wrap(err, "failed to check sender balance")
}
}
return next(ctx, tx, simulate)
}
// EthGasConsumeDecorator validates enough intrinsic gas for the transaction and
// gas consumption.
type EthGasConsumeDecorator struct {
evmKeeper EVMKeeper
maxGasWanted uint64
}
// NewEthGasConsumeDecorator creates a new EthGasConsumeDecorator
func NewEthGasConsumeDecorator(
evmKeeper EVMKeeper,
maxGasWanted uint64,
) EthGasConsumeDecorator {
return EthGasConsumeDecorator{
evmKeeper,
maxGasWanted,
}
}
// AnteHandle validates that the Ethereum tx message has enough to cover intrinsic gas
// (during CheckTx only) and that the sender has enough balance to pay for the gas cost.
//
// Intrinsic gas for a transaction is the amount of gas that the transaction uses before the
// transaction is executed. The gas is a constant value plus any cost inccured by additional bytes
// of data supplied with the transaction.
//
// This AnteHandler decorator will fail if:
// - the message is not a MsgEthereumTx
// - sender account cannot be found
// - transaction's gas limit is lower than the intrinsic gas
// - user doesn't have enough balance to deduct the transaction fees (gas_limit * gas_price)
// - transaction or block gas meter runs out of gas
// - sets the gas meter limit
func (egcd EthGasConsumeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (newCtx sdk.Context, err error) {
params := egcd.evmKeeper.GetParams(ctx)
ethCfg := params.ChainConfig.EthereumConfig(egcd.evmKeeper.ChainID())
blockHeight := big.NewInt(ctx.BlockHeight())
homestead := ethCfg.IsHomestead(blockHeight)
istanbul := ethCfg.IsIstanbul(blockHeight)
london := ethCfg.IsLondon(blockHeight)
evmDenom := params.EvmDenom
gasWanted := uint64(0)
var events sdk.Events
for _, msg := range tx.GetMsgs() {
msgEthTx, ok := msg.(*evmtypes.MsgEthereumTx)
if !ok {
return ctx, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "invalid message type %T, expected %T", msg, (*evmtypes.MsgEthereumTx)(nil))
}
txData, err := evmtypes.UnpackTxData(msgEthTx.Data)
if err != nil {
return ctx, sdkerrors.Wrap(err, "failed to unpack tx data")
}
if ctx.IsCheckTx() {
// We can't trust the tx gas limit, because we'll refund the unused gas.
if txData.GetGas() > egcd.maxGasWanted {
gasWanted += egcd.maxGasWanted
} else {
gasWanted += txData.GetGas()
}
} else {
gasWanted += txData.GetGas()
}
fees, err := egcd.evmKeeper.DeductTxCostsFromUserBalance(
ctx,
*msgEthTx,
txData,
evmDenom,
homestead,
istanbul,
london,
)
if err != nil {
return ctx, sdkerrors.Wrapf(err, "failed to deduct transaction costs from user balance")
}
events = append(events, sdk.NewEvent(sdk.EventTypeTx, sdk.NewAttribute(sdk.AttributeKeyFee, fees.String())))
}
// TODO: change to typed events
ctx.EventManager().EmitEvents(events)
// TODO: deprecate after https://github.com/cosmos/cosmos-sdk/issues/9514 is fixed on SDK
blockGasLimit := ethermint.BlockGasLimit(ctx)
// NOTE: safety check
if blockGasLimit > 0 {
// generate a copy of the gas pool (i.e block gas meter) to see if we've run out of gas for this block
// if current gas consumed is greater than the limit, this funcion panics and the error is recovered on the Baseapp
gasPool := sdk.NewGasMeter(blockGasLimit)
gasPool.ConsumeGas(ctx.GasMeter().GasConsumedToLimit(), "gas pool check")
}
// Set ctx.GasMeter with a limit of GasWanted (gasLimit)
gasConsumed := ctx.GasMeter().GasConsumed()
ctx = ctx.WithGasMeter(ethermint.NewInfiniteGasMeterWithLimit(gasWanted))
ctx.GasMeter().ConsumeGas(gasConsumed, "copy gas consumed")
// we know that we have enough gas on the pool to cover the intrinsic gas
return next(ctx, tx, simulate)
}
// CanTransferDecorator checks if the sender is allowed to transfer funds according to the EVM block
// context rules.
type CanTransferDecorator struct {
evmKeeper EVMKeeper
}
// NewCanTransferDecorator creates a new CanTransferDecorator instance.
func NewCanTransferDecorator(evmKeeper EVMKeeper) CanTransferDecorator {
return CanTransferDecorator{
evmKeeper: evmKeeper,
}
}
// AnteHandle creates an EVM from the message and calls the BlockContext CanTransfer function to
// see if the address can execute the transaction.
func (ctd CanTransferDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (sdk.Context, error) {
params := ctd.evmKeeper.GetParams(ctx)
ethCfg := params.ChainConfig.EthereumConfig(ctd.evmKeeper.ChainID())
signer := ethtypes.MakeSigner(ethCfg, big.NewInt(ctx.BlockHeight()))
for _, msg := range tx.GetMsgs() {
msgEthTx, ok := msg.(*evmtypes.MsgEthereumTx)
if !ok {
return ctx, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "invalid message type %T, expected %T", msg, (*evmtypes.MsgEthereumTx)(nil))
}
baseFee := ctd.evmKeeper.BaseFee(ctx, ethCfg)
coreMsg, err := msgEthTx.AsMessage(signer, baseFee)
if err != nil {
return ctx, sdkerrors.Wrapf(
err,
"failed to create an ethereum core.Message from signer %T", signer,
)
}
// NOTE: pass in an empty coinbase address and nil tracer as we don't need them for the check below
cfg := &evmtypes.EVMConfig{
ChainConfig: ethCfg,
Params: params,
CoinBase: common.Address{},
BaseFee: baseFee,
}
stateDB := statedb.New(ctx, ctd.evmKeeper, statedb.NewEmptyTxConfig(common.BytesToHash(ctx.HeaderHash().Bytes())))
evm := ctd.evmKeeper.NewEVM(ctx, coreMsg, cfg, evmtypes.NewNoOpTracer(), stateDB)
// check that caller has enough balance to cover asset transfer for **topmost** call
// NOTE: here the gas consumed is from the context with the infinite gas meter
if coreMsg.Value().Sign() > 0 && !evm.Context.CanTransfer(stateDB, coreMsg.From(), coreMsg.Value()) {
return ctx, sdkerrors.Wrapf(
sdkerrors.ErrInsufficientFunds,
"failed to transfer %s from address %s using the EVM block context transfer function",
coreMsg.Value(),
coreMsg.From(),
)
}
if evmtypes.IsLondon(ethCfg, ctx.BlockHeight()) {
if baseFee == nil {
return ctx, sdkerrors.Wrap(
evmtypes.ErrInvalidBaseFee,
"base fee is supported but evm block context value is nil",
)
}
if coreMsg.GasFeeCap().Cmp(baseFee) < 0 {
return ctx, sdkerrors.Wrapf(
sdkerrors.ErrInsufficientFee,
"max fee per gas less than block base fee (%s < %s)",
coreMsg.GasFeeCap(), baseFee,
)
}
}
}
return next(ctx, tx, simulate)
}
// EthIncrementSenderSequenceDecorator increments the sequence of the signers.
type EthIncrementSenderSequenceDecorator struct {
ak evmtypes.AccountKeeper
}
// NewEthIncrementSenderSequenceDecorator creates a new EthIncrementSenderSequenceDecorator.
func NewEthIncrementSenderSequenceDecorator(ak evmtypes.AccountKeeper) EthIncrementSenderSequenceDecorator {
return EthIncrementSenderSequenceDecorator{
ak: ak,
}
}
// AnteHandle handles incrementing the sequence of the signer (i.e sender). If the transaction is a
// contract creation, the nonce will be incremented during the transaction execution and not within
// this AnteHandler decorator.
func (issd EthIncrementSenderSequenceDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (sdk.Context, error) {
for _, msg := range tx.GetMsgs() {
msgEthTx, ok := msg.(*evmtypes.MsgEthereumTx)
if !ok {
return ctx, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "invalid message type %T, expected %T", msg, (*evmtypes.MsgEthereumTx)(nil))
}
txData, err := evmtypes.UnpackTxData(msgEthTx.Data)
if err != nil {
return ctx, sdkerrors.Wrap(err, "failed to unpack tx data")
}
// increase sequence of sender
acc := issd.ak.GetAccount(ctx, msgEthTx.GetFrom())
if acc == nil {
return ctx, sdkerrors.Wrapf(
sdkerrors.ErrUnknownAddress,
"account %s is nil", common.BytesToAddress(msgEthTx.GetFrom().Bytes()),
)
}
nonce := acc.GetSequence()
// we merged the nonce verification to nonce increment, so when tx includes multiple messages
// with same sender, they'll be accepted.
if txData.GetNonce() != nonce {
return ctx, sdkerrors.Wrapf(
sdkerrors.ErrInvalidSequence,
"invalid nonce; got %d, expected %d", txData.GetNonce(), nonce,
)
}
if err := acc.SetSequence(nonce + 1); err != nil {
return ctx, sdkerrors.Wrapf(err, "failed to set sequence to %d", acc.GetSequence()+1)
}
issd.ak.SetAccount(ctx, acc)
}
return next(ctx, tx, simulate)
}
// EthValidateBasicDecorator is adapted from ValidateBasicDecorator from cosmos-sdk, it ignores ErrNoSignatures
type EthValidateBasicDecorator struct {
evmKeeper EVMKeeper
}
// NewEthValidateBasicDecorator creates a new EthValidateBasicDecorator
func NewEthValidateBasicDecorator(ek EVMKeeper) EthValidateBasicDecorator {
return EthValidateBasicDecorator{
evmKeeper: ek,
}
}
// AnteHandle handles basic validation of tx
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)
}
err := tx.ValidateBasic()
// ErrNoSignatures is fine with eth tx
if err != nil && !errors.Is(err, sdkerrors.ErrNoSignatures) {
return ctx, sdkerrors.Wrap(err, "tx basic validation failed")
}
// For eth type cosmos tx, some fields should be veified as zero values,
// since we will only verify the signature against the hash of the MsgEthereumTx.Data
if wrapperTx, ok := tx.(protoTxProvider); ok {
protoTx := wrapperTx.GetProtoTx()
body := protoTx.Body
if body.Memo != "" || body.TimeoutHeight != uint64(0) || len(body.NonCriticalExtensionOptions) > 0 {
return ctx, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest,
"for eth tx body Memo TimeoutHeight NonCriticalExtensionOptions should be empty")
}
if len(body.ExtensionOptions) != 1 {
return ctx, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "for eth tx length of ExtensionOptions should be 1")
}
txFee := sdk.Coins{}
txGasLimit := uint64(0)
for _, msg := range protoTx.GetMsgs() {
msgEthTx, ok := msg.(*evmtypes.MsgEthereumTx)
if !ok {
return ctx, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "invalid message type %T, expected %T", msg, (*evmtypes.MsgEthereumTx)(nil))
}
txGasLimit += msgEthTx.GetGas()
txData, err := evmtypes.UnpackTxData(msgEthTx.Data)
if err != nil {
return ctx, sdkerrors.Wrap(err, "failed to unpack MsgEthereumTx Data")
}
params := vbd.evmKeeper.GetParams(ctx)
chainID := vbd.evmKeeper.ChainID()
ethCfg := params.ChainConfig.EthereumConfig(chainID)
baseFee := vbd.evmKeeper.BaseFee(ctx, ethCfg)
if baseFee == nil && txData.TxType() == ethtypes.DynamicFeeTxType {
return ctx, sdkerrors.Wrap(ethtypes.ErrTxTypeNotSupported, "dynamic fee tx not supported")
}
txFee = txFee.Add(sdk.NewCoin(params.EvmDenom, sdk.NewIntFromBigInt(txData.Fee())))
}
authInfo := protoTx.AuthInfo
if len(authInfo.SignerInfos) > 0 {
return ctx, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "for eth tx AuthInfo SignerInfos should be empty")
}
if authInfo.Fee.Payer != "" || authInfo.Fee.Granter != "" {
return ctx, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "for eth tx AuthInfo Fee payer and granter should be empty")
}
if !authInfo.Fee.Amount.IsEqual(txFee) {
return ctx, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid AuthInfo Fee Amount (%s != %s)", authInfo.Fee.Amount, txFee)
}
if authInfo.Fee.GasLimit != txGasLimit {
return ctx, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid AuthInfo Fee GasLimit (%d != %d)", authInfo.Fee.GasLimit, txGasLimit)
}
sigs := protoTx.Signatures
if len(sigs) > 0 {
return ctx, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "for eth tx Signatures should be empty")
}
}
return next(ctx, tx, simulate)
}
// EthSetupContextDecorator is adapted from SetUpContextDecorator from cosmos-sdk, it ignores gas consumption
// by setting the gas meter to infinite
type EthSetupContextDecorator struct {
evmKeeper EVMKeeper
}
func NewEthSetUpContextDecorator(evmKeeper EVMKeeper) EthSetupContextDecorator {
return EthSetupContextDecorator{
evmKeeper: evmKeeper,
}
}
func (esc EthSetupContextDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (newCtx sdk.Context, err error) {
// all transactions must implement GasTx
_, ok := tx.(authante.GasTx)
if !ok {
return newCtx, sdkerrors.Wrap(sdkerrors.ErrTxDecode, "Tx must be GasTx")
}
newCtx = ctx.WithGasMeter(sdk.NewInfiniteGasMeter())
// Reset transient gas used to prepare the execution of current cosmos tx.
// Transient gas-used is necessary to sum the gas-used of cosmos tx, when it contains multiple eth msgs.
esc.evmKeeper.ResetTransientGasUsed(ctx)
return next(newCtx, tx, simulate)
}
// EthMempoolFeeDecorator will check if the transaction's effective fee is at least as large
// as the local validator's minimum gasFee (defined in validator config).
// If fee is too low, decorator returns error and tx is rejected from mempool.
// Note this only applies when ctx.CheckTx = true
// If fee is high enough or not CheckTx, then call next AnteHandler
// CONTRACT: Tx must implement FeeTx to use MempoolFeeDecorator
type EthMempoolFeeDecorator struct {
evmKeeper EVMKeeper
}
func NewEthMempoolFeeDecorator(ek EVMKeeper) EthMempoolFeeDecorator {
return EthMempoolFeeDecorator{
evmKeeper: ek,
}
}
// AnteHandle ensures that the provided fees meet a minimum threshold for the validator,
// if this is a CheckTx. This is only for local mempool purposes, and thus
// is only ran on check tx.
// It only do the check if london hardfork not enabled or feemarket not enabled, because in that case feemarket will take over the task.
func (mfd EthMempoolFeeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (newCtx sdk.Context, err error) {
if ctx.IsCheckTx() && !simulate {
params := mfd.evmKeeper.GetParams(ctx)
ethCfg := params.ChainConfig.EthereumConfig(mfd.evmKeeper.ChainID())
baseFee := mfd.evmKeeper.BaseFee(ctx, ethCfg)
if baseFee == nil {
for _, msg := range tx.GetMsgs() {
ethMsg, ok := msg.(*evmtypes.MsgEthereumTx)
if !ok {
return ctx, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "invalid message type %T, expected %T", msg, (*evmtypes.MsgEthereumTx)(nil))
}
evmDenom := params.EvmDenom
feeAmt := ethMsg.GetFee()
glDec := sdk.NewDec(int64(ethMsg.GetGas()))
requiredFee := ctx.MinGasPrices().AmountOf(evmDenom).Mul(glDec)
if sdk.NewDecFromBigInt(feeAmt).LT(requiredFee) {
return ctx, sdkerrors.Wrapf(sdkerrors.ErrInsufficientFee, "insufficient fees; got: %s required: %s", feeAmt, requiredFee)
}
}
}
}
return next(ctx, tx, simulate)
}

View File

@ -1,509 +0,0 @@
package ante_test
import (
"math/big"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/tharsis/ethermint/app/ante"
"github.com/tharsis/ethermint/server/config"
"github.com/tharsis/ethermint/tests"
"github.com/tharsis/ethermint/x/evm/statedb"
evmtypes "github.com/tharsis/ethermint/x/evm/types"
ethtypes "github.com/ethereum/go-ethereum/core/types"
)
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 := tests.NewAddrKey()
signedTx := evmtypes.NewTxContract(suite.app.EvmKeeper.ChainID(), 1, big.NewInt(10), 1000, big.NewInt(1), nil, nil, nil, nil)
signedTx.From = addr.Hex()
err := signedTx.Sign(suite.ethSigner, tests.NewSigner(privKey))
suite.Require().NoError(err)
testCases := []struct {
name string
tx sdk.Tx
reCheckTx bool
expPass bool
}{
{"ReCheckTx", &invalidTx{}, true, false},
{"invalid transaction type", &invalidTx{}, false, false},
{
"invalid sender",
evmtypes.NewTx(suite.app.EvmKeeper.ChainID(), 1, &addr, big.NewInt(10), 1000, big.NewInt(1), nil, nil, nil, nil),
false,
false,
},
{"successful signature verification", signedTx, false, true},
}
for _, tc := range testCases {
suite.Run(tc.name, func() {
_, err := dec.AnteHandle(suite.ctx.WithIsReCheckTx(tc.reCheckTx), tc.tx, false, nextFn)
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 := tests.GenerateAddress()
tx := evmtypes.NewTxContract(suite.app.EvmKeeper.ChainID(), 1, big.NewInt(10), 1000, big.NewInt(1), nil, nil, nil, nil)
tx.From = addr.Hex()
var vmdb *statedb.StateDB
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.NewTxContract(suite.app.EvmKeeper.ChainID(), 1, big.NewInt(10), 1000, big.NewInt(1), nil, nil, nil, nil),
func() {},
true,
false,
},
{
"sender not EOA",
tx,
func() {
// set not as an EOA
vmdb.SetCode(addr, []byte("1"))
},
true,
false,
},
{
"not enough balance to cover tx cost",
tx,
func() {
// reset back to EOA
vmdb.SetCode(addr, nil)
},
true,
false,
},
{
"success new account",
tx,
func() {
vmdb.AddBalance(addr, big.NewInt(1000000))
},
true,
true,
},
{
"success existing account",
tx,
func() {
acc := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr.Bytes())
suite.app.AccountKeeper.SetAccount(suite.ctx, acc)
vmdb.AddBalance(addr, big.NewInt(1000000))
},
true,
true,
},
}
for _, tc := range testCases {
suite.Run(tc.name, func() {
vmdb = suite.StateDB()
tc.malleate()
suite.Require().NoError(vmdb.Commit())
_, err := dec.AnteHandle(suite.ctx.WithIsCheckTx(tc.checkTx), tc.tx, false, nextFn)
if tc.expPass {
suite.Require().NoError(err)
} else {
suite.Require().Error(err)
}
})
}
}
func (suite AnteTestSuite) TestEthNonceVerificationDecorator() {
suite.SetupTest()
dec := ante.NewEthIncrementSenderSequenceDecorator(suite.app.AccountKeeper)
addr := tests.GenerateAddress()
tx := evmtypes.NewTxContract(suite.app.EvmKeeper.ChainID(), 1, big.NewInt(10), 1000, big.NewInt(1), nil, nil, nil, nil)
tx.From = addr.Hex()
testCases := []struct {
name string
tx sdk.Tx
malleate func()
reCheckTx bool
expPass bool
}{
{"ReCheckTx", &invalidTx{}, func() {}, true, false},
{"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()
_, err := dec.AnteHandle(suite.ctx.WithIsReCheckTx(tc.reCheckTx), tc.tx, false, nextFn)
if tc.expPass {
suite.Require().NoError(err)
} else {
suite.Require().Error(err)
}
})
}
}
func (suite AnteTestSuite) TestEthGasConsumeDecorator() {
dec := ante.NewEthGasConsumeDecorator(suite.app.EvmKeeper, config.DefaultMaxTxGasWanted)
addr := tests.GenerateAddress()
txGasLimit := uint64(1000)
tx := evmtypes.NewTxContract(suite.app.EvmKeeper.ChainID(), 1, big.NewInt(10), txGasLimit, big.NewInt(1), nil, nil, nil, nil)
tx.From = addr.Hex()
tx2GasLimit := uint64(1000000)
tx2 := evmtypes.NewTxContract(suite.app.EvmKeeper.ChainID(), 1, big.NewInt(10), tx2GasLimit, big.NewInt(1), nil, nil, nil, &ethtypes.AccessList{{Address: addr, StorageKeys: nil}})
tx2.From = addr.Hex()
var vmdb *statedb.StateDB
testCases := []struct {
name string
tx sdk.Tx
gasLimit uint64
malleate func()
expPass bool
expPanic bool
}{
{"invalid transaction type", &invalidTx{}, 0, func() {}, false, false},
{
"sender not found",
evmtypes.NewTxContract(suite.app.EvmKeeper.ChainID(), 1, big.NewInt(10), 1000, big.NewInt(1), nil, nil, nil, nil),
0,
func() {},
false, false,
},
{
"gas limit too low",
tx,
0,
func() {},
false, false,
},
{
"not enough balance for fees",
tx2,
0,
func() {},
false, false,
},
{
"not enough tx gas",
tx2,
0,
func() {
vmdb.AddBalance(addr, big.NewInt(1000000))
},
false, true,
},
{
"not enough block gas",
tx2,
0,
func() {
vmdb.AddBalance(addr, big.NewInt(1000000))
suite.ctx = suite.ctx.WithBlockGasMeter(sdk.NewGasMeter(1))
},
false, true,
},
{
"success",
tx2,
config.DefaultMaxTxGasWanted, // it's capped
func() {
vmdb.AddBalance(addr, big.NewInt(1000000))
suite.ctx = suite.ctx.WithBlockGasMeter(sdk.NewGasMeter(10000000000000000000))
},
true, false,
},
}
for _, tc := range testCases {
suite.Run(tc.name, func() {
vmdb = suite.StateDB()
tc.malleate()
suite.Require().NoError(vmdb.Commit())
if tc.expPanic {
suite.Require().Panics(func() {
_, _ = dec.AnteHandle(suite.ctx.WithIsCheckTx(true).WithGasMeter(sdk.NewGasMeter(1)), tc.tx, false, nextFn)
})
return
}
ctx, err := dec.AnteHandle(suite.ctx.WithIsCheckTx(true).WithGasMeter(sdk.NewInfiniteGasMeter()), tc.tx, false, nextFn)
if tc.expPass {
suite.Require().NoError(err)
} else {
suite.Require().Error(err)
}
suite.Require().Equal(tc.gasLimit, ctx.GasMeter().Limit())
})
}
}
func (suite AnteTestSuite) TestCanTransferDecorator() {
dec := ante.NewCanTransferDecorator(suite.app.EvmKeeper)
addr, privKey := tests.NewAddrKey()
suite.app.FeeMarketKeeper.SetBaseFee(suite.ctx, big.NewInt(100))
tx := evmtypes.NewTxContract(
suite.app.EvmKeeper.ChainID(),
1,
big.NewInt(10),
1000,
big.NewInt(150),
big.NewInt(200),
nil,
nil,
&ethtypes.AccessList{},
)
tx2 := evmtypes.NewTxContract(
suite.app.EvmKeeper.ChainID(),
1,
big.NewInt(10),
1000,
big.NewInt(150),
big.NewInt(200),
nil,
nil,
&ethtypes.AccessList{},
)
tx.From = addr.Hex()
err := tx.Sign(suite.ethSigner, tests.NewSigner(privKey))
suite.Require().NoError(err)
var vmdb *statedb.StateDB
testCases := []struct {
name string
tx sdk.Tx
malleate func()
expPass bool
}{
{"invalid transaction type", &invalidTx{}, func() {}, false},
{"AsMessage failed", tx2, func() {}, false},
{
"evm CanTransfer failed",
tx,
func() {
acc := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr.Bytes())
suite.app.AccountKeeper.SetAccount(suite.ctx, acc)
},
false,
},
{
"success",
tx,
func() {
acc := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr.Bytes())
suite.app.AccountKeeper.SetAccount(suite.ctx, acc)
vmdb.AddBalance(addr, big.NewInt(1000000))
},
true,
},
}
for _, tc := range testCases {
suite.Run(tc.name, func() {
vmdb = suite.StateDB()
tc.malleate()
suite.Require().NoError(vmdb.Commit())
_, err := dec.AnteHandle(suite.ctx.WithIsCheckTx(true), tc.tx, false, nextFn)
if tc.expPass {
suite.Require().NoError(err)
} else {
suite.Require().Error(err)
}
})
}
}
func (suite AnteTestSuite) TestEthIncrementSenderSequenceDecorator() {
dec := ante.NewEthIncrementSenderSequenceDecorator(suite.app.AccountKeeper)
addr, privKey := tests.NewAddrKey()
contract := evmtypes.NewTxContract(suite.app.EvmKeeper.ChainID(), 0, big.NewInt(10), 1000, big.NewInt(1), nil, nil, nil, nil)
contract.From = addr.Hex()
err := contract.Sign(suite.ethSigner, tests.NewSigner(privKey))
suite.Require().NoError(err)
to := tests.GenerateAddress()
tx := evmtypes.NewTx(suite.app.EvmKeeper.ChainID(), 0, &to, big.NewInt(10), 1000, big.NewInt(1), nil, nil, nil, nil)
tx.From = addr.Hex()
err = tx.Sign(suite.ethSigner, tests.NewSigner(privKey))
suite.Require().NoError(err)
tx2 := evmtypes.NewTx(suite.app.EvmKeeper.ChainID(), 1, &to, big.NewInt(10), 1000, big.NewInt(1), nil, nil, nil, nil)
tx2.From = addr.Hex()
err = tx2.Sign(suite.ethSigner, tests.NewSigner(privKey))
suite.Require().NoError(err)
testCases := []struct {
name string
tx sdk.Tx
malleate func()
expPass bool
expPanic bool
}{
{
"invalid transaction type",
&invalidTx{},
func() {},
false, false,
},
{
"no signers",
evmtypes.NewTx(suite.app.EvmKeeper.ChainID(), 1, &to, big.NewInt(10), 1000, big.NewInt(1), nil, nil, nil, nil),
func() {},
false, false,
},
{
"account not set to store",
tx,
func() {},
false, false,
},
{
"success - create contract",
contract,
func() {
acc := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr.Bytes())
suite.app.AccountKeeper.SetAccount(suite.ctx, acc)
},
true, false,
},
{
"success - call",
tx2,
func() {},
true, false,
},
}
for _, tc := range testCases {
suite.Run(tc.name, func() {
tc.malleate()
if tc.expPanic {
suite.Require().Panics(func() {
_, _ = dec.AnteHandle(suite.ctx, tc.tx, false, nextFn)
})
return
}
_, err := dec.AnteHandle(suite.ctx, tc.tx, false, nextFn)
if tc.expPass {
suite.Require().NoError(err)
msg := tc.tx.(*evmtypes.MsgEthereumTx)
txData, err := evmtypes.UnpackTxData(msg.Data)
suite.Require().NoError(err)
nonce := suite.app.EvmKeeper.GetNonce(suite.ctx, addr)
suite.Require().Equal(txData.GetNonce()+1, nonce)
} else {
suite.Require().Error(err)
}
})
}
}
func (suite AnteTestSuite) TestEthSetupContextDecorator() {
dec := ante.NewEthSetUpContextDecorator(suite.app.EvmKeeper)
tx := evmtypes.NewTxContract(suite.app.EvmKeeper.ChainID(), 1, big.NewInt(10), 1000, big.NewInt(1), nil, nil, nil, nil)
testCases := []struct {
name string
tx sdk.Tx
expPass bool
}{
{"invalid transaction type - does not implement GasTx", &invalidTx{}, false},
{
"success - transaction implement GasTx",
tx,
true,
},
}
for _, tc := range testCases {
suite.Run(tc.name, func() {
_, err := dec.AnteHandle(suite.ctx, tc.tx, false, nextFn)
if tc.expPass {
suite.Require().NoError(err)
} else {
suite.Require().Error(err)
}
})
}
}

View File

@ -1,105 +0,0 @@
package ante
import (
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
"github.com/cosmos/cosmos-sdk/types/tx/signing"
"github.com/cosmos/cosmos-sdk/x/auth/ante"
authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
ibcante "github.com/cosmos/ibc-go/v3/modules/core/ante"
ibckeeper "github.com/cosmos/ibc-go/v3/modules/core/keeper"
evmtypes "github.com/tharsis/ethermint/x/evm/types"
)
// HandlerOptions extend the SDK's AnteHandler options by requiring the IBC
// channel keeper, EVM Keeper and Fee Market Keeper.
type HandlerOptions struct {
AccountKeeper evmtypes.AccountKeeper
BankKeeper evmtypes.BankKeeper
IBCKeeper *ibckeeper.Keeper
FeeMarketKeeper evmtypes.FeeMarketKeeper
EvmKeeper EVMKeeper
FeegrantKeeper ante.FeegrantKeeper
SignModeHandler authsigning.SignModeHandler
SigGasConsumer func(meter sdk.GasMeter, sig signing.SignatureV2, params authtypes.Params) error
MaxTxGasWanted uint64
}
func (options HandlerOptions) Validate() error {
if options.AccountKeeper == nil {
return sdkerrors.Wrap(sdkerrors.ErrLogic, "account keeper is required for AnteHandler")
}
if options.BankKeeper == nil {
return sdkerrors.Wrap(sdkerrors.ErrLogic, "bank keeper is required for AnteHandler")
}
if options.SignModeHandler == nil {
return sdkerrors.Wrap(sdkerrors.ErrLogic, "sign mode handler is required for ante builder")
}
if options.FeeMarketKeeper == nil {
return sdkerrors.Wrap(sdkerrors.ErrLogic, "fee market keeper is required for AnteHandler")
}
if options.EvmKeeper == nil {
return sdkerrors.Wrap(sdkerrors.ErrLogic, "evm keeper is required for AnteHandler")
}
return nil
}
func newEthAnteHandler(options HandlerOptions) sdk.AnteHandler {
return sdk.ChainAnteDecorators(
NewEthSetUpContextDecorator(options.EvmKeeper), // outermost AnteDecorator. SetUpContext must be called first
NewEthMempoolFeeDecorator(options.EvmKeeper), // Check eth effective gas price against minimal-gas-prices
NewEthValidateBasicDecorator(options.EvmKeeper),
NewEthSigVerificationDecorator(options.EvmKeeper),
NewEthAccountVerificationDecorator(options.AccountKeeper, options.BankKeeper, options.EvmKeeper),
NewEthGasConsumeDecorator(options.EvmKeeper, options.MaxTxGasWanted),
NewCanTransferDecorator(options.EvmKeeper),
NewEthIncrementSenderSequenceDecorator(options.AccountKeeper), // innermost AnteDecorator.
)
}
func newCosmosAnteHandler(options HandlerOptions) sdk.AnteHandler {
return sdk.ChainAnteDecorators(
RejectMessagesDecorator{}, // reject MsgEthereumTxs
ante.NewSetUpContextDecorator(),
ante.NewRejectExtensionOptionsDecorator(),
ante.NewMempoolFeeDecorator(),
ante.NewValidateBasicDecorator(),
ante.NewTxTimeoutHeightDecorator(),
ante.NewValidateMemoDecorator(options.AccountKeeper),
ante.NewConsumeGasForTxSizeDecorator(options.AccountKeeper),
ante.NewDeductFeeDecorator(options.AccountKeeper, options.BankKeeper, options.FeegrantKeeper),
// SetPubKeyDecorator must be called before all signature verification decorators
ante.NewSetPubKeyDecorator(options.AccountKeeper),
ante.NewValidateSigCountDecorator(options.AccountKeeper),
ante.NewSigGasConsumeDecorator(options.AccountKeeper, options.SigGasConsumer),
ante.NewSigVerificationDecorator(options.AccountKeeper, options.SignModeHandler),
ante.NewIncrementSequenceDecorator(options.AccountKeeper),
ibcante.NewAnteDecorator(options.IBCKeeper),
)
}
func newCosmosAnteHandlerEip712(options HandlerOptions) sdk.AnteHandler {
return sdk.ChainAnteDecorators(
RejectMessagesDecorator{}, // reject MsgEthereumTxs
ante.NewSetUpContextDecorator(),
// NOTE: extensions option decorator removed
// ante.NewRejectExtensionOptionsDecorator(),
ante.NewMempoolFeeDecorator(),
ante.NewValidateBasicDecorator(),
ante.NewTxTimeoutHeightDecorator(),
ante.NewValidateMemoDecorator(options.AccountKeeper),
ante.NewConsumeGasForTxSizeDecorator(options.AccountKeeper),
ante.NewDeductFeeDecorator(options.AccountKeeper, options.BankKeeper, options.FeegrantKeeper),
// SetPubKeyDecorator must be called before all signature verification decorators
ante.NewSetPubKeyDecorator(options.AccountKeeper),
ante.NewValidateSigCountDecorator(options.AccountKeeper),
ante.NewSigGasConsumeDecorator(options.AccountKeeper, options.SigGasConsumer),
// Note: signature verification uses EIP instead of the cosmos signature validator
NewEip712SigVerificationDecorator(options.AccountKeeper, options.SignModeHandler),
ante.NewIncrementSequenceDecorator(options.AccountKeeper),
ibcante.NewAnteDecorator(options.IBCKeeper),
)
}

View File

@ -1,33 +0,0 @@
package ante
import (
"math/big"
sdk "github.com/cosmos/cosmos-sdk/types"
tx "github.com/cosmos/cosmos-sdk/types/tx"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/params"
"github.com/tharsis/ethermint/x/evm/statedb"
evmtypes "github.com/tharsis/ethermint/x/evm/types"
)
// EVMKeeper defines the expected keeper interface used on the Eth AnteHandler
type EVMKeeper interface {
statedb.Keeper
ChainID() *big.Int
GetParams(ctx sdk.Context) evmtypes.Params
NewEVM(ctx sdk.Context, msg core.Message, cfg *evmtypes.EVMConfig, tracer vm.EVMLogger, stateDB vm.StateDB) *vm.EVM
DeductTxCostsFromUserBalance(
ctx sdk.Context, msgEthTx evmtypes.MsgEthereumTx, txData evmtypes.TxData, denom string, homestead, istanbul, london bool,
) (sdk.Coins, error)
BaseFee(ctx sdk.Context, ethCfg *params.ChainConfig) *big.Int
GetBalance(ctx sdk.Context, addr common.Address) *big.Int
ResetTransientGasUsed(ctx sdk.Context)
}
type protoTxProvider interface {
GetProtoTx() *tx.Tx
}

View File

@ -1,25 +0,0 @@
package ante
import (
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
evmtypes "github.com/tharsis/ethermint/x/evm/types"
)
// RejectMessagesDecorator prevents invalid msg types from being executed
type RejectMessagesDecorator struct{}
// AnteHandle rejects messages that requires ethereum-specific authentication.
// For example `MsgEthereumTx` requires fee to be deducted in the antehandler in
// order to perform the refund.
func (rmd RejectMessagesDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (newCtx sdk.Context, err error) {
for _, msg := range tx.GetMsgs() {
if _, ok := msg.(*evmtypes.MsgEthereumTx); ok {
return ctx, sdkerrors.Wrapf(
sdkerrors.ErrInvalidType,
"MsgEthereumTx needs to be contained within a tx with 'ExtensionOptionsEthereumTx' option",
)
}
}
return next(ctx, tx, simulate)
}

View File

@ -1,46 +0,0 @@
package ante_test
import (
"math/big"
"github.com/tharsis/ethermint/tests"
"github.com/tharsis/ethermint/x/evm/statedb"
evmtypes "github.com/tharsis/ethermint/x/evm/types"
)
func (suite AnteTestSuite) TestSignatures() {
suite.enableFeemarket = false
suite.SetupTest() // reset
addr, privKey := tests.NewAddrKey()
to := tests.GenerateAddress()
acc := statedb.NewEmptyAccount()
acc.Nonce = 1
acc.Balance = big.NewInt(10000000000)
suite.app.EvmKeeper.SetAccount(suite.ctx, addr, *acc)
msgEthereumTx := evmtypes.NewTx(suite.app.EvmKeeper.ChainID(), 1, &to, big.NewInt(10), 100000, big.NewInt(1), nil, nil, nil, nil)
msgEthereumTx.From = addr.Hex()
// CreateTestTx will sign the msgEthereumTx but not sign the cosmos tx since we have signCosmosTx as false
tx := suite.CreateTestTx(msgEthereumTx, privKey, 1, false)
sigs, err := tx.GetSignaturesV2()
suite.Require().NoError(err)
// signatures of cosmos tx should be empty
suite.Require().Equal(len(sigs), 0)
txData, err := evmtypes.UnpackTxData(msgEthereumTx.Data)
suite.Require().NoError(err)
msgV, msgR, msgS := txData.GetRawSignatureValues()
ethTx := msgEthereumTx.AsTransaction()
ethV, ethR, ethS := ethTx.RawSignatureValues()
// The signatures of MsgehtereumTx should be the same with the corresponding eth tx
suite.Require().Equal(msgV, ethV)
suite.Require().Equal(msgR, ethR)
suite.Require().Equal(msgS, ethS)
}

View File

@ -1,289 +0,0 @@
package ante_test
import (
"math"
"testing"
"time"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/x/auth/legacy/legacytx"
types2 "github.com/cosmos/cosmos-sdk/x/bank/types"
types3 "github.com/cosmos/cosmos-sdk/x/staking/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/tharsis/ethermint/ethereum/eip712"
"github.com/tharsis/ethermint/types"
"github.com/ethereum/go-ethereum/common"
ethtypes "github.com/ethereum/go-ethereum/core/types"
"github.com/stretchr/testify/suite"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/tx"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
"github.com/cosmos/cosmos-sdk/simapp"
"github.com/cosmos/cosmos-sdk/testutil/testdata"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/tx/signing"
authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing"
authtx "github.com/cosmos/cosmos-sdk/x/auth/tx"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
"github.com/tharsis/ethermint/app"
ante "github.com/tharsis/ethermint/app/ante"
"github.com/tharsis/ethermint/encoding"
"github.com/tharsis/ethermint/tests"
"github.com/tharsis/ethermint/x/evm/statedb"
evmtypes "github.com/tharsis/ethermint/x/evm/types"
feemarkettypes "github.com/tharsis/ethermint/x/feemarket/types"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
)
type AnteTestSuite struct {
suite.Suite
ctx sdk.Context
app *app.EthermintApp
clientCtx client.Context
anteHandler sdk.AnteHandler
ethSigner ethtypes.Signer
enableFeemarket bool
enableLondonHF bool
}
func (suite *AnteTestSuite) StateDB() *statedb.StateDB {
return statedb.New(suite.ctx, suite.app.EvmKeeper, statedb.NewEmptyTxConfig(common.BytesToHash(suite.ctx.HeaderHash().Bytes())))
}
func (suite *AnteTestSuite) SetupTest() {
checkTx := false
suite.app = app.Setup(checkTx, func(app *app.EthermintApp, genesis simapp.GenesisState) simapp.GenesisState {
if suite.enableFeemarket {
// setup feemarketGenesis params
feemarketGenesis := feemarkettypes.DefaultGenesisState()
feemarketGenesis.Params.EnableHeight = 1
feemarketGenesis.Params.NoBaseFee = false
// Verify feeMarket genesis
err := feemarketGenesis.Validate()
suite.Require().NoError(err)
genesis[feemarkettypes.ModuleName] = app.AppCodec().MustMarshalJSON(feemarketGenesis)
}
if !suite.enableLondonHF {
evmGenesis := evmtypes.DefaultGenesisState()
maxInt := sdk.NewInt(math.MaxInt64)
evmGenesis.Params.ChainConfig.LondonBlock = &maxInt
evmGenesis.Params.ChainConfig.ArrowGlacierBlock = &maxInt
evmGenesis.Params.ChainConfig.MergeForkBlock = &maxInt
genesis[evmtypes.ModuleName] = app.AppCodec().MustMarshalJSON(evmGenesis)
}
return genesis
})
suite.ctx = suite.app.BaseApp.NewContext(checkTx, tmproto.Header{Height: 2, ChainID: "ethermint_9000-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)
infCtx := suite.ctx.WithGasMeter(sdk.NewInfiniteGasMeter())
suite.app.AccountKeeper.SetParams(infCtx, authtypes.DefaultParams())
encodingConfig := encoding.MakeConfig(app.ModuleBasics)
// We're using TestMsg amino encoding in some tests, so register it here.
encodingConfig.Amino.RegisterConcrete(&testdata.TestMsg{}, "testdata.TestMsg", nil)
suite.clientCtx = client.Context{}.WithTxConfig(encodingConfig.TxConfig)
options := ante.HandlerOptions{
AccountKeeper: suite.app.AccountKeeper,
BankKeeper: suite.app.BankKeeper,
EvmKeeper: suite.app.EvmKeeper,
FeegrantKeeper: suite.app.FeeGrantKeeper,
IBCKeeper: suite.app.IBCKeeper,
FeeMarketKeeper: suite.app.FeeMarketKeeper,
SignModeHandler: encodingConfig.TxConfig.SignModeHandler(),
SigGasConsumer: ante.DefaultSigVerificationGasConsumer,
}
suite.Require().NoError(options.Validate())
suite.anteHandler = ante.NewAnteHandler(options)
suite.ethSigner = ethtypes.LatestSignerForChainID(suite.app.EvmKeeper.ChainID())
}
func TestAnteTestSuite(t *testing.T) {
suite.Run(t, &AnteTestSuite{
enableLondonHF: true,
})
}
// CreateTestTx is a helper function to create a tx given multiple inputs.
func (suite *AnteTestSuite) CreateTestTx(
msg *evmtypes.MsgEthereumTx, priv cryptotypes.PrivKey, accNum uint64, signCosmosTx bool,
unsetExtensionOptions ...bool,
) authsigning.Tx {
return suite.CreateTestTxBuilder(msg, priv, accNum, signCosmosTx).GetTx()
}
// CreateTestTxBuilder is a helper function to create a tx builder given multiple inputs.
func (suite *AnteTestSuite) CreateTestTxBuilder(
msg *evmtypes.MsgEthereumTx, priv cryptotypes.PrivKey, accNum uint64, signCosmosTx bool,
unsetExtensionOptions ...bool,
) client.TxBuilder {
var option *codectypes.Any
var err error
if len(unsetExtensionOptions) == 0 {
option, err = codectypes.NewAnyWithValue(&evmtypes.ExtensionOptionsEthereumTx{})
suite.Require().NoError(err)
}
txBuilder := suite.clientCtx.TxConfig.NewTxBuilder()
builder, ok := txBuilder.(authtx.ExtensionOptionsTxBuilder)
suite.Require().True(ok)
if len(unsetExtensionOptions) == 0 {
builder.SetExtensionOptions(option)
}
err = msg.Sign(suite.ethSigner, tests.NewSigner(priv))
suite.Require().NoError(err)
err = builder.SetMsgs(msg)
suite.Require().NoError(err)
txData, err := evmtypes.UnpackTxData(msg.Data)
suite.Require().NoError(err)
fees := sdk.NewCoins(sdk.NewCoin(evmtypes.DefaultEVMDenom, sdk.NewIntFromBigInt(txData.Fee())))
builder.SetFeeAmount(fees)
builder.SetGasLimit(msg.GetGas())
if signCosmosTx {
// 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: txData.GetNonce(),
}
sigsV2 := []signing.SignatureV2{sigV2}
err = 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: txData.GetNonce(),
}
sigV2, err = tx.SignWithPrivKey(
suite.clientCtx.TxConfig.SignModeHandler().DefaultMode(), signerData,
txBuilder, priv, suite.clientCtx.TxConfig, txData.GetNonce(),
)
suite.Require().NoError(err)
sigsV2 = []signing.SignatureV2{sigV2}
err = txBuilder.SetSignatures(sigsV2...)
suite.Require().NoError(err)
}
return txBuilder
}
func (suite *AnteTestSuite) CreateTestEIP712TxBuilderMsgSend(from sdk.AccAddress, priv cryptotypes.PrivKey, chainId string, gas uint64, gasAmount sdk.Coins) client.TxBuilder {
// Build MsgSend
recipient := sdk.AccAddress(common.Address{}.Bytes())
msgSend := types2.NewMsgSend(from, recipient, sdk.NewCoins(sdk.NewCoin(evmtypes.DefaultEVMDenom, sdk.NewInt(1))))
return suite.CreateTestEIP712CosmosTxBuilder(from, priv, chainId, gas, gasAmount, msgSend)
}
func (suite *AnteTestSuite) CreateTestEIP712TxBuilderMsgDelegate(from sdk.AccAddress, priv cryptotypes.PrivKey, chainId string, gas uint64, gasAmount sdk.Coins) client.TxBuilder {
// Build MsgSend
valEthAddr := tests.GenerateAddress()
valAddr := sdk.ValAddress(valEthAddr.Bytes())
msgSend := types3.NewMsgDelegate(from, valAddr, sdk.NewCoin(evmtypes.DefaultEVMDenom, sdk.NewInt(20)))
return suite.CreateTestEIP712CosmosTxBuilder(from, priv, chainId, gas, gasAmount, msgSend)
}
func (suite *AnteTestSuite) CreateTestEIP712CosmosTxBuilder(
from sdk.AccAddress, priv cryptotypes.PrivKey, chainId string, gas uint64, gasAmount sdk.Coins, msg sdk.Msg,
) client.TxBuilder {
var err error
nonce, err := suite.app.AccountKeeper.GetSequence(suite.ctx, from)
suite.Require().NoError(err)
pc, err := types.ParseChainID(chainId)
suite.Require().NoError(err)
ethChainId := pc.Uint64()
// GenerateTypedData TypedData
var ethermintCodec codec.ProtoCodecMarshaler
fee := legacytx.NewStdFee(gas, gasAmount)
accNumber := suite.app.AccountKeeper.GetAccount(suite.ctx, from).GetAccountNumber()
data := legacytx.StdSignBytes(chainId, accNumber, nonce, 0, fee, []sdk.Msg{msg}, "")
typedData, err := eip712.WrapTxToTypedData(ethermintCodec, ethChainId, msg, data, &eip712.FeeDelegationOptions{
FeePayer: from,
})
suite.Require().NoError(err)
sigHash, err := eip712.ComputeTypedDataHash(typedData)
suite.Require().NoError(err)
// Sign typedData
keyringSigner := tests.NewSigner(priv)
signature, pubKey, err := keyringSigner.SignByAddress(from, sigHash)
suite.Require().NoError(err)
signature[crypto.RecoveryIDOffset] += 27 // Transform V from 0/1 to 27/28 according to the yellow paper
// Add ExtensionOptionsWeb3Tx extension
var option *codectypes.Any
option, err = codectypes.NewAnyWithValue(&types.ExtensionOptionsWeb3Tx{
FeePayer: from.String(),
TypedDataChainID: ethChainId,
FeePayerSig: signature,
})
suite.Require().NoError(err)
suite.clientCtx.TxConfig.SignModeHandler()
txBuilder := suite.clientCtx.TxConfig.NewTxBuilder()
builder, ok := txBuilder.(authtx.ExtensionOptionsTxBuilder)
suite.Require().True(ok)
builder.SetExtensionOptions(option)
builder.SetFeeAmount(gasAmount)
builder.SetGasLimit(gas)
sigsV2 := signing.SignatureV2{
PubKey: pubKey,
Data: &signing.SingleSignatureData{
SignMode: signing.SignMode_SIGN_MODE_LEGACY_AMINO_JSON,
},
Sequence: nonce,
}
err = builder.SetSignatures(sigsV2)
suite.Require().NoError(err)
err = builder.SetMsgs(msg)
suite.Require().NoError(err)
return builder
}
var _ sdk.Tx = &invalidTx{}
type invalidTx struct{}
func (invalidTx) GetMsgs() []sdk.Msg { return []sdk.Msg{nil} }
func (invalidTx) ValidateBasic() error { return nil }

View File

@ -11,17 +11,12 @@ import (
"github.com/rakyll/statik/fs" "github.com/rakyll/statik/fs"
"github.com/spf13/cast" "github.com/spf13/cast"
abci "github.com/tendermint/tendermint/abci/types"
"github.com/tendermint/tendermint/libs/log"
tmos "github.com/tendermint/tendermint/libs/os"
dbm "github.com/tendermint/tm-db"
"github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/baseapp"
"github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/grpc/tmservice" "github.com/cosmos/cosmos-sdk/client/grpc/tmservice"
"github.com/cosmos/cosmos-sdk/client/rpc"
"github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/codec/types" "github.com/cosmos/cosmos-sdk/codec/types"
"github.com/cosmos/cosmos-sdk/db"
"github.com/cosmos/cosmos-sdk/server/api" "github.com/cosmos/cosmos-sdk/server/api"
"github.com/cosmos/cosmos-sdk/server/config" "github.com/cosmos/cosmos-sdk/server/config"
servertypes "github.com/cosmos/cosmos-sdk/server/types" servertypes "github.com/cosmos/cosmos-sdk/server/types"
@ -32,6 +27,7 @@ import (
"github.com/cosmos/cosmos-sdk/version" "github.com/cosmos/cosmos-sdk/version"
"github.com/cosmos/cosmos-sdk/x/auth" "github.com/cosmos/cosmos-sdk/x/auth"
authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper" authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
authmiddleware "github.com/cosmos/cosmos-sdk/x/auth/middleware"
authsims "github.com/cosmos/cosmos-sdk/x/auth/simulation" authsims "github.com/cosmos/cosmos-sdk/x/auth/simulation"
authtx "github.com/cosmos/cosmos-sdk/x/auth/tx" 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"
@ -62,8 +58,10 @@ import (
"github.com/cosmos/cosmos-sdk/x/genutil" "github.com/cosmos/cosmos-sdk/x/genutil"
genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types"
"github.com/cosmos/cosmos-sdk/x/gov" "github.com/cosmos/cosmos-sdk/x/gov"
govclient "github.com/cosmos/cosmos-sdk/x/gov/client"
govkeeper "github.com/cosmos/cosmos-sdk/x/gov/keeper" govkeeper "github.com/cosmos/cosmos-sdk/x/gov/keeper"
govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
govv1beta1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1"
"github.com/cosmos/cosmos-sdk/x/mint" "github.com/cosmos/cosmos-sdk/x/mint"
mintkeeper "github.com/cosmos/cosmos-sdk/x/mint/keeper" mintkeeper "github.com/cosmos/cosmos-sdk/x/mint/keeper"
minttypes "github.com/cosmos/cosmos-sdk/x/mint/types" minttypes "github.com/cosmos/cosmos-sdk/x/mint/types"
@ -82,25 +80,31 @@ import (
upgradeclient "github.com/cosmos/cosmos-sdk/x/upgrade/client" upgradeclient "github.com/cosmos/cosmos-sdk/x/upgrade/client"
upgradekeeper "github.com/cosmos/cosmos-sdk/x/upgrade/keeper" upgradekeeper "github.com/cosmos/cosmos-sdk/x/upgrade/keeper"
upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"
abci "github.com/tendermint/tendermint/abci/types"
"github.com/tendermint/tendermint/libs/log"
"github.com/cosmos/ibc-go/v3/modules/apps/transfer" // "github.com/cosmos/ibc-go/v3/modules/apps/transfer"
ibctransferkeeper "github.com/cosmos/ibc-go/v3/modules/apps/transfer/keeper"
ibctransfertypes "github.com/cosmos/ibc-go/v3/modules/apps/transfer/types" // "github.com/cosmos/ibc-go/v3/modules/apps/transfer"
ibc "github.com/cosmos/ibc-go/v3/modules/core" // ibctransferkeeper "github.com/cosmos/ibc-go/v3/modules/apps/transfer/keeper"
ibcclient "github.com/cosmos/ibc-go/v3/modules/core/02-client" // ibctransfertypes "github.com/cosmos/ibc-go/v3/modules/apps/transfer/types"
ibcclientclient "github.com/cosmos/ibc-go/v3/modules/core/02-client/client" // ibc "github.com/cosmos/ibc-go/v3/modules/core"
porttypes "github.com/cosmos/ibc-go/v3/modules/core/05-port/types" // ibcclient "github.com/cosmos/ibc-go/v3/modules/core/02-client"
ibchost "github.com/cosmos/ibc-go/v3/modules/core/24-host" // ibcclientclient "github.com/cosmos/ibc-go/v3/modules/core/02-client/client"
ibckeeper "github.com/cosmos/ibc-go/v3/modules/core/keeper" // porttypes "github.com/cosmos/ibc-go/v3/modules/core/05-port/types"
// ibchost "github.com/cosmos/ibc-go/v3/modules/core/24-host"
// ibckeeper "github.com/cosmos/ibc-go/v3/modules/core/keeper"
// unnamed import of statik for swagger UI support // unnamed import of statik for swagger UI support
_ "github.com/tharsis/ethermint/client/docs/statik" _ "github.com/tharsis/ethermint/client/docs/statik"
"github.com/tharsis/ethermint/app/ante" // "github.com/tharsis/ethermint/app/ante"
srvflags "github.com/tharsis/ethermint/server/flags" srvflags "github.com/tharsis/ethermint/server/flags"
ethermint "github.com/tharsis/ethermint/types" ethermint "github.com/tharsis/ethermint/types"
"github.com/tharsis/ethermint/x/evm" "github.com/tharsis/ethermint/x/evm"
evmrest "github.com/tharsis/ethermint/x/evm/client/rest"
// evmrest "github.com/tharsis/ethermint/x/evm/client/rest"
storetypes "github.com/cosmos/cosmos-sdk/store/types"
evmkeeper "github.com/tharsis/ethermint/x/evm/keeper" evmkeeper "github.com/tharsis/ethermint/x/evm/keeper"
evmtypes "github.com/tharsis/ethermint/x/evm/types" evmtypes "github.com/tharsis/ethermint/x/evm/types"
"github.com/tharsis/ethermint/x/feemarket" "github.com/tharsis/ethermint/x/feemarket"
@ -139,18 +143,18 @@ var (
mint.AppModuleBasic{}, mint.AppModuleBasic{},
distr.AppModuleBasic{}, distr.AppModuleBasic{},
gov.NewAppModuleBasic( gov.NewAppModuleBasic(
paramsclient.ProposalHandler, distrclient.ProposalHandler, upgradeclient.ProposalHandler, upgradeclient.CancelProposalHandler, []govclient.ProposalHandler{paramsclient.ProposalHandler, distrclient.ProposalHandler, upgradeclient.LegacyProposalHandler, upgradeclient.LegacyCancelProposalHandler},
ibcclientclient.UpdateClientProposalHandler, ibcclientclient.UpgradeProposalHandler, // ibcclientclient.UpdateClientProposalHandler, ibcclientclient.UpgradeProposalHandler,
), ),
params.AppModuleBasic{}, params.AppModuleBasic{},
crisis.AppModuleBasic{}, crisis.AppModuleBasic{},
slashing.AppModuleBasic{}, slashing.AppModuleBasic{},
ibc.AppModuleBasic{}, // ibc.AppModuleBasic{},
authzmodule.AppModuleBasic{}, authzmodule.AppModuleBasic{},
feegrantmodule.AppModuleBasic{}, feegrantmodule.AppModuleBasic{},
upgrade.AppModuleBasic{}, upgrade.AppModuleBasic{},
evidence.AppModuleBasic{}, evidence.AppModuleBasic{},
transfer.AppModuleBasic{}, // transfer.AppModuleBasic{},
vesting.AppModuleBasic{}, vesting.AppModuleBasic{},
// Ethermint modules // Ethermint modules
evm.AppModuleBasic{}, evm.AppModuleBasic{},
@ -165,8 +169,8 @@ var (
stakingtypes.BondedPoolName: {authtypes.Burner, authtypes.Staking}, stakingtypes.BondedPoolName: {authtypes.Burner, authtypes.Staking},
stakingtypes.NotBondedPoolName: {authtypes.Burner, authtypes.Staking}, stakingtypes.NotBondedPoolName: {authtypes.Burner, authtypes.Staking},
govtypes.ModuleName: {authtypes.Burner}, govtypes.ModuleName: {authtypes.Burner},
ibctransfertypes.ModuleName: {authtypes.Minter, authtypes.Burner}, // ibctransfertypes.ModuleName: {authtypes.Minter, authtypes.Burner},
evmtypes.ModuleName: {authtypes.Minter, authtypes.Burner}, // used for secure addition and subtraction of balance using module account evmtypes.ModuleName: {authtypes.Minter, authtypes.Burner}, // used for secure addition and subtraction of balance using module account
} }
// module accounts that are allowed to receive tokens // module accounts that are allowed to receive tokens
@ -189,13 +193,14 @@ type EthermintApp struct {
cdc *codec.LegacyAmino cdc *codec.LegacyAmino
appCodec codec.Codec appCodec codec.Codec
interfaceRegistry types.InterfaceRegistry interfaceRegistry types.InterfaceRegistry
msgSvcRouter *authmiddleware.MsgServiceRouter
invCheckPeriod uint legacyRouter sdk.Router
invCheckPeriod uint
// keys to access the substores // keys to access the substores
keys map[string]*sdk.KVStoreKey keys map[string]*storetypes.KVStoreKey
tkeys map[string]*sdk.TransientStoreKey tkeys map[string]*storetypes.TransientStoreKey
memKeys map[string]*sdk.MemoryStoreKey memKeys map[string]*storetypes.MemoryStoreKey
// keepers // keepers
AccountKeeper authkeeper.AccountKeeper AccountKeeper authkeeper.AccountKeeper
@ -211,9 +216,9 @@ type EthermintApp struct {
ParamsKeeper paramskeeper.Keeper ParamsKeeper paramskeeper.Keeper
FeeGrantKeeper feegrantkeeper.Keeper FeeGrantKeeper feegrantkeeper.Keeper
AuthzKeeper authzkeeper.Keeper AuthzKeeper authzkeeper.Keeper
IBCKeeper *ibckeeper.Keeper // IBC Keeper must be a pointer in the app, so we can SetRouter on it correctly // IBCKeeper *ibckeeper.Keeper // IBC Keeper must be a pointer in the app, so we can SetRouter on it correctly
EvidenceKeeper evidencekeeper.Keeper EvidenceKeeper evidencekeeper.Keeper
TransferKeeper ibctransferkeeper.Keeper // TransferKeeper ibctransferkeeper.Keeper
// make scoped keepers public for test purposes // make scoped keepers public for test purposes
ScopedIBCKeeper capabilitykeeper.ScopedKeeper ScopedIBCKeeper capabilitykeeper.ScopedKeeper
@ -236,7 +241,7 @@ type EthermintApp struct {
// NewEthermintApp returns a reference to a new initialized Ethermint application. // NewEthermintApp returns a reference to a new initialized Ethermint application.
func NewEthermintApp( func NewEthermintApp(
logger log.Logger, logger log.Logger,
db dbm.DB, db db.DBConnection,
traceStore io.Writer, traceStore io.Writer,
loadLatest bool, loadLatest bool,
skipUpgradeHeights map[int64]bool, skipUpgradeHeights map[int64]bool,
@ -244,9 +249,9 @@ func NewEthermintApp(
invCheckPeriod uint, invCheckPeriod uint,
encodingConfig simappparams.EncodingConfig, encodingConfig simappparams.EncodingConfig,
appOpts servertypes.AppOptions, appOpts servertypes.AppOptions,
baseAppOptions ...func(*baseapp.BaseApp), baseAppOptions ...baseapp.AppOption,
) *EthermintApp { ) *EthermintApp {
appCodec := encodingConfig.Marshaler appCodec := encodingConfig.Codec
cdc := encodingConfig.Amino cdc := encodingConfig.Amino
interfaceRegistry := encodingConfig.InterfaceRegistry interfaceRegistry := encodingConfig.InterfaceRegistry
@ -255,7 +260,6 @@ func NewEthermintApp(
appName, appName,
logger, logger,
db, db,
encodingConfig.TxConfig.TxDecoder(),
baseAppOptions..., baseAppOptions...,
) )
bApp.SetCommitMultiStoreTracer(traceStore) bApp.SetCommitMultiStoreTracer(traceStore)
@ -270,7 +274,7 @@ func NewEthermintApp(
evidencetypes.StoreKey, capabilitytypes.StoreKey, evidencetypes.StoreKey, capabilitytypes.StoreKey,
feegrant.StoreKey, authzkeeper.StoreKey, feegrant.StoreKey, authzkeeper.StoreKey,
// ibc keys // ibc keys
ibchost.StoreKey, ibctransfertypes.StoreKey, // ibchost.StoreKey, ibctransfertypes.StoreKey,
// ethermint keys // ethermint keys
evmtypes.StoreKey, feemarkettypes.StoreKey, evmtypes.StoreKey, feemarkettypes.StoreKey,
) )
@ -285,6 +289,8 @@ func NewEthermintApp(
appCodec: appCodec, appCodec: appCodec,
interfaceRegistry: interfaceRegistry, interfaceRegistry: interfaceRegistry,
invCheckPeriod: invCheckPeriod, invCheckPeriod: invCheckPeriod,
legacyRouter: authmiddleware.NewLegacyRouter(),
msgSvcRouter: authmiddleware.NewMsgServiceRouter(interfaceRegistry),
keys: keys, keys: keys,
tkeys: tkeys, tkeys: tkeys,
memKeys: memKeys, memKeys: memKeys,
@ -293,13 +299,13 @@ func NewEthermintApp(
// init params keeper and subspaces // init params keeper and subspaces
app.ParamsKeeper = initParamsKeeper(appCodec, cdc, keys[paramstypes.StoreKey], tkeys[paramstypes.TStoreKey]) app.ParamsKeeper = initParamsKeeper(appCodec, cdc, keys[paramstypes.StoreKey], tkeys[paramstypes.TStoreKey])
// set the BaseApp's parameter store // set the BaseApp's parameter store
bApp.SetParamStore(app.ParamsKeeper.Subspace(baseapp.Paramspace).WithKeyTable(paramskeeper.ConsensusParamsKeyTable())) bApp.SetParamStore(app.ParamsKeeper.Subspace(baseapp.Paramspace).WithKeyTable(paramstypes.ConsensusParamsKeyTable()))
// add capability keeper and ScopeToModule for ibc module // add capability keeper and ScopeToModule for ibc module
app.CapabilityKeeper = capabilitykeeper.NewKeeper(appCodec, keys[capabilitytypes.StoreKey], memKeys[capabilitytypes.MemStoreKey]) app.CapabilityKeeper = capabilitykeeper.NewKeeper(appCodec, keys[capabilitytypes.StoreKey], memKeys[capabilitytypes.MemStoreKey])
scopedIBCKeeper := app.CapabilityKeeper.ScopeToModule(ibchost.ModuleName) // scopedIBCKeeper := app.CapabilityKeeper.ScopeToModule(ibchost.ModuleName)
scopedTransferKeeper := app.CapabilityKeeper.ScopeToModule(ibctransfertypes.ModuleName) // scopedTransferKeeper := app.CapabilityKeeper.ScopeToModule(ibctransfertypes.ModuleName)
// Applications that wish to enforce statically created ScopedKeepers should call `Seal` after creating // Applications that wish to enforce statically created ScopedKeepers should call `Seal` after creating
// their scoped modules in `NewApp` with `ScopeToModule` // their scoped modules in `NewApp` with `ScopeToModule`
@ -307,7 +313,7 @@ func NewEthermintApp(
// use custom Ethermint account for contracts // use custom Ethermint account for contracts
app.AccountKeeper = authkeeper.NewAccountKeeper( app.AccountKeeper = authkeeper.NewAccountKeeper(
appCodec, keys[authtypes.StoreKey], app.GetSubspace(authtypes.ModuleName), ethermint.ProtoAccount, maccPerms, appCodec, keys[authtypes.StoreKey], app.GetSubspace(authtypes.ModuleName), ethermint.ProtoAccount, maccPerms, sdk.Bech32MainPrefix,
) )
app.BankKeeper = bankkeeper.NewBaseKeeper( app.BankKeeper = bankkeeper.NewBaseKeeper(
appCodec, keys[banktypes.StoreKey], app.AccountKeeper, app.GetSubspace(banktypes.ModuleName), app.BlockedAddrs(), appCodec, keys[banktypes.StoreKey], app.AccountKeeper, app.GetSubspace(banktypes.ModuleName), app.BlockedAddrs(),
@ -321,7 +327,7 @@ func NewEthermintApp(
) )
app.DistrKeeper = distrkeeper.NewKeeper( app.DistrKeeper = distrkeeper.NewKeeper(
appCodec, keys[distrtypes.StoreKey], app.GetSubspace(distrtypes.ModuleName), app.AccountKeeper, app.BankKeeper, appCodec, keys[distrtypes.StoreKey], app.GetSubspace(distrtypes.ModuleName), app.AccountKeeper, app.BankKeeper,
&stakingKeeper, authtypes.FeeCollectorName, app.ModuleAccountAddrs(), &stakingKeeper, authtypes.FeeCollectorName,
) )
app.SlashingKeeper = slashingkeeper.NewKeeper( app.SlashingKeeper = slashingkeeper.NewKeeper(
appCodec, keys[slashingtypes.StoreKey], &stakingKeeper, app.GetSubspace(slashingtypes.ModuleName), appCodec, keys[slashingtypes.StoreKey], &stakingKeeper, app.GetSubspace(slashingtypes.ModuleName),
@ -330,7 +336,7 @@ func NewEthermintApp(
app.GetSubspace(crisistypes.ModuleName), invCheckPeriod, app.BankKeeper, authtypes.FeeCollectorName, app.GetSubspace(crisistypes.ModuleName), invCheckPeriod, app.BankKeeper, authtypes.FeeCollectorName,
) )
app.FeeGrantKeeper = feegrantkeeper.NewKeeper(appCodec, keys[feegrant.StoreKey], app.AccountKeeper) app.FeeGrantKeeper = feegrantkeeper.NewKeeper(appCodec, keys[feegrant.StoreKey], app.AccountKeeper)
app.UpgradeKeeper = upgradekeeper.NewKeeper(skipUpgradeHeights, keys[upgradetypes.StoreKey], appCodec, homePath, app.BaseApp) app.UpgradeKeeper = upgradekeeper.NewKeeper(skipUpgradeHeights, keys[upgradetypes.StoreKey], appCodec, homePath, app.BaseApp, authtypes.NewModuleAddress(govtypes.ModuleName).String())
// register the staking hooks // register the staking hooks
// NOTE: stakingKeeper above is passed by reference, so that it will contain these hooks // NOTE: stakingKeeper above is passed by reference, so that it will contain these hooks
@ -338,7 +344,7 @@ func NewEthermintApp(
stakingtypes.NewMultiStakingHooks(app.DistrKeeper.Hooks(), app.SlashingKeeper.Hooks()), stakingtypes.NewMultiStakingHooks(app.DistrKeeper.Hooks(), app.SlashingKeeper.Hooks()),
) )
app.AuthzKeeper = authzkeeper.NewKeeper(keys[authzkeeper.StoreKey], appCodec, app.BaseApp.MsgServiceRouter()) app.AuthzKeeper = authzkeeper.NewKeeper(keys[authzkeeper.StoreKey], appCodec, app.msgSvcRouter, app.AccountKeeper)
tracer := cast.ToString(appOpts.Get(srvflags.EVMTracer)) tracer := cast.ToString(appOpts.Get(srvflags.EVMTracer))
@ -353,22 +359,27 @@ func NewEthermintApp(
tracer, tracer,
) )
// Create IBC Keeper // // Create IBC Keeper
app.IBCKeeper = ibckeeper.NewKeeper( // app.IBCKeeper = ibckeeper.NewKeeper(
appCodec, keys[ibchost.StoreKey], app.GetSubspace(ibchost.ModuleName), app.StakingKeeper, app.UpgradeKeeper, scopedIBCKeeper, // appCodec, keys[ibchost.StoreKey], app.GetSubspace(ibchost.ModuleName), app.StakingKeeper, app.UpgradeKeeper, scopedIBCKeeper,
) // )
// register the proposal types // register the proposal types
govRouter := govtypes.NewRouter() govRouter := govv1beta1.NewRouter()
govRouter.AddRoute(govtypes.RouterKey, govtypes.ProposalHandler). govRouter.AddRoute(govtypes.RouterKey, govv1beta1.ProposalHandler).
AddRoute(paramproposal.RouterKey, params.NewParamChangeProposalHandler(app.ParamsKeeper)). AddRoute(paramproposal.RouterKey, params.NewParamChangeProposalHandler(app.ParamsKeeper)).
AddRoute(distrtypes.RouterKey, distr.NewCommunityPoolSpendProposalHandler(app.DistrKeeper)). AddRoute(distrtypes.RouterKey, distr.NewCommunityPoolSpendProposalHandler(app.DistrKeeper)).
AddRoute(upgradetypes.RouterKey, upgrade.NewSoftwareUpgradeProposalHandler(app.UpgradeKeeper)). AddRoute(upgradetypes.RouterKey, upgrade.NewSoftwareUpgradeProposalHandler(app.UpgradeKeeper))
AddRoute(ibchost.RouterKey, ibcclient.NewClientProposalHandler(app.IBCKeeper.ClientKeeper))
govConfig := govtypes.DefaultConfig()
/*
Example of setting gov params:
govConfig.MaxMetadataLen = 10000
*/
govKeeper := govkeeper.NewKeeper( govKeeper := govkeeper.NewKeeper(
appCodec, keys[govtypes.StoreKey], app.GetSubspace(govtypes.ModuleName), app.AccountKeeper, app.BankKeeper, appCodec, keys[govtypes.StoreKey], app.GetSubspace(govtypes.ModuleName), app.AccountKeeper, app.BankKeeper,
&stakingKeeper, govRouter, &stakingKeeper, govRouter, app.msgSvcRouter, govConfig,
) )
app.GovKeeper = *govKeeper.SetHooks( app.GovKeeper = *govKeeper.SetHooks(
@ -377,19 +388,19 @@ func NewEthermintApp(
), ),
) )
// Create Transfer Keepers // // Create Transfer Keepers
app.TransferKeeper = ibctransferkeeper.NewKeeper( // app.TransferKeeper = ibctransferkeeper.NewKeeper(
appCodec, keys[ibctransfertypes.StoreKey], app.GetSubspace(ibctransfertypes.ModuleName), // appCodec, keys[ibctransfertypes.StoreKey], app.GetSubspace(ibctransfertypes.ModuleName),
app.IBCKeeper.ChannelKeeper, app.IBCKeeper.ChannelKeeper, &app.IBCKeeper.PortKeeper, // app.IBCKeeper.ChannelKeeper, app.IBCKeeper.ChannelKeeper, &app.IBCKeeper.PortKeeper,
app.AccountKeeper, app.BankKeeper, scopedTransferKeeper, // app.AccountKeeper, app.BankKeeper, scopedTransferKeeper,
) // )
transferModule := transfer.NewAppModule(app.TransferKeeper) // transferModule := transfer.NewAppModule(app.TransferKeeper)
transferIBCModule := transfer.NewIBCModule(app.TransferKeeper) // transferIBCModule := transfer.NewIBCModule(app.TransferKeeper)
// Create static IBC router, add transfer route, then set and seal it // Create static IBC router, add transfer route, then set and seal it
ibcRouter := porttypes.NewRouter() // ibcRouter := porttypes.NewRouter()
ibcRouter.AddRoute(ibctransfertypes.ModuleName, transferIBCModule) // ibcRouter.AddRoute(ibctransfertypes.ModuleName, transferIBCModule)
app.IBCKeeper.SetRouter(ibcRouter) // app.IBCKeeper.SetRouter(ibcRouter)
// create evidence keeper with router // create evidence keeper with router
evidenceKeeper := evidencekeeper.NewKeeper( evidenceKeeper := evidencekeeper.NewKeeper(
@ -418,7 +429,7 @@ func NewEthermintApp(
capability.NewAppModule(appCodec, *app.CapabilityKeeper), capability.NewAppModule(appCodec, *app.CapabilityKeeper),
crisis.NewAppModule(&app.CrisisKeeper, skipGenesisInvariants), crisis.NewAppModule(&app.CrisisKeeper, skipGenesisInvariants),
gov.NewAppModule(appCodec, app.GovKeeper, app.AccountKeeper, app.BankKeeper), gov.NewAppModule(appCodec, app.GovKeeper, app.AccountKeeper, app.BankKeeper),
mint.NewAppModule(appCodec, app.MintKeeper, app.AccountKeeper), mint.NewAppModule(appCodec, app.MintKeeper, app.AccountKeeper, nil),
slashing.NewAppModule(appCodec, app.SlashingKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper), slashing.NewAppModule(appCodec, app.SlashingKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper),
distr.NewAppModule(appCodec, app.DistrKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper), distr.NewAppModule(appCodec, app.DistrKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper),
staking.NewAppModule(appCodec, app.StakingKeeper, app.AccountKeeper, app.BankKeeper), staking.NewAppModule(appCodec, app.StakingKeeper, app.AccountKeeper, app.BankKeeper),
@ -429,8 +440,7 @@ func NewEthermintApp(
authzmodule.NewAppModule(appCodec, app.AuthzKeeper, app.AccountKeeper, app.BankKeeper, app.interfaceRegistry), authzmodule.NewAppModule(appCodec, app.AuthzKeeper, app.AccountKeeper, app.BankKeeper, app.interfaceRegistry),
// ibc modules // ibc modules
ibc.NewAppModule(app.IBCKeeper), // ibc.NewAppModule(app.IBCKeeper),
transferModule,
// Ethermint app modules // Ethermint app modules
evm.NewAppModule(app.EvmKeeper, app.AccountKeeper), evm.NewAppModule(app.EvmKeeper, app.AccountKeeper),
feemarket.NewAppModule(app.FeeMarketKeeper), feemarket.NewAppModule(app.FeeMarketKeeper),
@ -452,9 +462,7 @@ func NewEthermintApp(
slashingtypes.ModuleName, slashingtypes.ModuleName,
evidencetypes.ModuleName, evidencetypes.ModuleName,
stakingtypes.ModuleName, stakingtypes.ModuleName,
ibchost.ModuleName,
// no-op modules // no-op modules
ibctransfertypes.ModuleName,
authtypes.ModuleName, authtypes.ModuleName,
banktypes.ModuleName, banktypes.ModuleName,
govtypes.ModuleName, govtypes.ModuleName,
@ -474,8 +482,6 @@ func NewEthermintApp(
evmtypes.ModuleName, evmtypes.ModuleName,
feemarkettypes.ModuleName, feemarkettypes.ModuleName,
// no-op modules // no-op modules
ibchost.ModuleName,
ibctransfertypes.ModuleName,
capabilitytypes.ModuleName, capabilitytypes.ModuleName,
authtypes.ModuleName, authtypes.ModuleName,
banktypes.ModuleName, banktypes.ModuleName,
@ -506,10 +512,8 @@ func NewEthermintApp(
slashingtypes.ModuleName, slashingtypes.ModuleName,
govtypes.ModuleName, govtypes.ModuleName,
minttypes.ModuleName, minttypes.ModuleName,
ibchost.ModuleName,
genutiltypes.ModuleName, genutiltypes.ModuleName,
evidencetypes.ModuleName, evidencetypes.ModuleName,
ibctransfertypes.ModuleName,
authz.ModuleName, authz.ModuleName,
feegrant.ModuleName, feegrant.ModuleName,
paramstypes.ModuleName, paramstypes.ModuleName,
@ -524,8 +528,8 @@ func NewEthermintApp(
) )
app.mm.RegisterInvariants(&app.CrisisKeeper) app.mm.RegisterInvariants(&app.CrisisKeeper)
app.mm.RegisterRoutes(app.Router(), app.QueryRouter(), encodingConfig.Amino) app.mm.RegisterRoutes(app.legacyRouter, app.QueryRouter(), encodingConfig.Amino)
app.configurator = module.NewConfigurator(app.appCodec, app.MsgServiceRouter(), app.GRPCQueryRouter()) app.configurator = module.NewConfigurator(app.appCodec, app.msgSvcRouter, app.GRPCQueryRouter())
app.mm.RegisterServices(app.configurator) app.mm.RegisterServices(app.configurator)
// add test gRPC service for testing gRPC queries in isolation // add test gRPC service for testing gRPC queries in isolation
@ -540,7 +544,7 @@ func NewEthermintApp(
bank.NewAppModule(appCodec, app.BankKeeper, app.AccountKeeper), bank.NewAppModule(appCodec, app.BankKeeper, app.AccountKeeper),
capability.NewAppModule(appCodec, *app.CapabilityKeeper), capability.NewAppModule(appCodec, *app.CapabilityKeeper),
gov.NewAppModule(appCodec, app.GovKeeper, app.AccountKeeper, app.BankKeeper), gov.NewAppModule(appCodec, app.GovKeeper, app.AccountKeeper, app.BankKeeper),
mint.NewAppModule(appCodec, app.MintKeeper, app.AccountKeeper), mint.NewAppModule(appCodec, app.MintKeeper, app.AccountKeeper, nil),
staking.NewAppModule(appCodec, app.StakingKeeper, app.AccountKeeper, app.BankKeeper), staking.NewAppModule(appCodec, app.StakingKeeper, app.AccountKeeper, app.BankKeeper),
distr.NewAppModule(appCodec, app.DistrKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper), distr.NewAppModule(appCodec, app.DistrKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper),
slashing.NewAppModule(appCodec, app.SlashingKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper), slashing.NewAppModule(appCodec, app.SlashingKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper),
@ -548,53 +552,41 @@ func NewEthermintApp(
evidence.NewAppModule(app.EvidenceKeeper), evidence.NewAppModule(app.EvidenceKeeper),
feegrantmodule.NewAppModule(appCodec, app.AccountKeeper, app.BankKeeper, app.FeeGrantKeeper, app.interfaceRegistry), feegrantmodule.NewAppModule(appCodec, app.AccountKeeper, app.BankKeeper, app.FeeGrantKeeper, app.interfaceRegistry),
authzmodule.NewAppModule(appCodec, app.AuthzKeeper, app.AccountKeeper, app.BankKeeper, app.interfaceRegistry), authzmodule.NewAppModule(appCodec, app.AuthzKeeper, app.AccountKeeper, app.BankKeeper, app.interfaceRegistry),
ibc.NewAppModule(app.IBCKeeper), // ibc.NewAppModule(app.IBCKeeper),
transferModule,
evm.NewAppModule(app.EvmKeeper, app.AccountKeeper), evm.NewAppModule(app.EvmKeeper, app.AccountKeeper),
feemarket.NewAppModule(app.FeeMarketKeeper), feemarket.NewAppModule(app.FeeMarketKeeper),
) )
app.sm.RegisterStoreDecoders() app.sm.RegisterStoreDecoders()
// initialize stores
app.MountKVStores(keys)
app.MountTransientStores(tkeys)
app.MountMemoryStores(memKeys)
// initialize BaseApp // initialize BaseApp
app.SetInitChainer(app.InitChainer) app.SetInitChainer(app.InitChainer)
app.SetBeginBlocker(app.BeginBlocker) app.SetBeginBlocker(app.BeginBlocker)
// use Ethermint's custom AnteHandler // use Ethermint's custom AnteHandler
maxGasWanted := cast.ToUint64(appOpts.Get(srvflags.EVMMaxTxGasWanted)) // maxGasWanted := cast.ToUint64(appOpts.Get(srvflags.EVMMaxTxGasWanted))
options := ante.HandlerOptions{ // options := ante.HandlerOptions{
AccountKeeper: app.AccountKeeper, // AccountKeeper: app.AccountKeeper,
BankKeeper: app.BankKeeper, // BankKeeper: app.BankKeeper,
EvmKeeper: app.EvmKeeper, // EvmKeeper: app.EvmKeeper,
FeegrantKeeper: app.FeeGrantKeeper, // FeegrantKeeper: app.FeeGrantKeeper,
IBCKeeper: app.IBCKeeper, // IBCKeeper: app.IBCKeeper,
FeeMarketKeeper: app.FeeMarketKeeper, // FeeMarketKeeper: app.FeeMarketKeeper,
SignModeHandler: encodingConfig.TxConfig.SignModeHandler(), // SignModeHandler: encodingConfig.TxConfig.SignModeHandler(),
SigGasConsumer: ante.DefaultSigVerificationGasConsumer, // SigGasConsumer: ante.DefaultSigVerificationGasConsumer,
MaxTxGasWanted: maxGasWanted, // MaxTxGasWanted: maxGasWanted,
} // }
if err := options.Validate(); err != nil { // if err := options.Validate(); err != nil {
panic(err) // panic(err)
} // }
app.SetAnteHandler(ante.NewAnteHandler(options)) // app.SetAnteHandler(ante.NewAnteHandler(options))
app.SetEndBlocker(app.EndBlocker) app.SetEndBlocker(app.EndBlocker)
if loadLatest { // app.ScopedIBCKeeper = scopedIBCKeeper
if err := app.LoadLatestVersion(); err != nil { // app.ScopedTransferKeeper = scopedTransferKeeper
tmos.Exit(err.Error())
}
}
app.ScopedIBCKeeper = scopedIBCKeeper
app.ScopedTransferKeeper = scopedTransferKeeper
return app return app
} }
@ -624,7 +616,8 @@ func (app *EthermintApp) InitChainer(ctx sdk.Context, req abci.RequestInitChain)
// LoadHeight loads state at a particular height // LoadHeight loads state at a particular height
func (app *EthermintApp) LoadHeight(height int64) error { func (app *EthermintApp) LoadHeight(height int64) error {
return app.LoadVersion(height) // return app.LoadVersion(height)
return nil
} }
// ModuleAccountAddrs returns all the app's module account addresses. // ModuleAccountAddrs returns all the app's module account addresses.
@ -672,21 +665,21 @@ func (app *EthermintApp) InterfaceRegistry() types.InterfaceRegistry {
// GetKey returns the KVStoreKey for the provided store key. // GetKey returns the KVStoreKey for the provided store key.
// //
// NOTE: This is solely to be used for testing purposes. // NOTE: This is solely to be used for testing purposes.
func (app *EthermintApp) GetKey(storeKey string) *sdk.KVStoreKey { func (app *EthermintApp) GetKey(storeKey string) *storetypes.KVStoreKey {
return app.keys[storeKey] return app.keys[storeKey]
} }
// GetTKey returns the TransientStoreKey for the provided store key. // GetTKey returns the TransientStoreKey for the provided store key.
// //
// NOTE: This is solely to be used for testing purposes. // NOTE: This is solely to be used for testing purposes.
func (app *EthermintApp) GetTKey(storeKey string) *sdk.TransientStoreKey { func (app *EthermintApp) GetTKey(storeKey string) *storetypes.TransientStoreKey {
return app.tkeys[storeKey] return app.tkeys[storeKey]
} }
// GetMemKey returns the MemStoreKey for the provided mem key. // GetMemKey returns the MemStoreKey for the provided mem key.
// //
// NOTE: This is solely used for testing purposes. // NOTE: This is solely used for testing purposes.
func (app *EthermintApp) GetMemKey(storeKey string) *sdk.MemoryStoreKey { func (app *EthermintApp) GetMemKey(storeKey string) *storetypes.MemoryStoreKey {
return app.memKeys[storeKey] return app.memKeys[storeKey]
} }
@ -707,9 +700,9 @@ func (app *EthermintApp) SimulationManager() *module.SimulationManager {
// API server. // API server.
func (app *EthermintApp) RegisterAPIRoutes(apiSvr *api.Server, apiConfig config.APIConfig) { func (app *EthermintApp) RegisterAPIRoutes(apiSvr *api.Server, apiConfig config.APIConfig) {
clientCtx := apiSvr.ClientCtx clientCtx := apiSvr.ClientCtx
rpc.RegisterRoutes(clientCtx, apiSvr.Router) // rpc.RegisterRoutes(clientCtx, apiSvr.Router)
evmrest.RegisterTxRoutes(clientCtx, apiSvr.Router) // evmrest.RegisterTxRoutes(clientCtx, apiSvr.Router)
// Register new tx routes from grpc-gateway. // Register new tx routes from grpc-gateway.
authtx.RegisterGRPCGatewayRoutes(clientCtx, apiSvr.GRPCGatewayRouter) authtx.RegisterGRPCGatewayRoutes(clientCtx, apiSvr.GRPCGatewayRouter)
@ -757,7 +750,7 @@ func GetMaccPerms() map[string][]string {
// initParamsKeeper init params keeper and its subspaces // initParamsKeeper init params keeper and its subspaces
func initParamsKeeper( func initParamsKeeper(
appCodec codec.BinaryCodec, legacyAmino *codec.LegacyAmino, key, tkey sdk.StoreKey, appCodec codec.BinaryCodec, legacyAmino *codec.LegacyAmino, key, tkey storetypes.StoreKey,
) paramskeeper.Keeper { ) paramskeeper.Keeper {
paramsKeeper := paramskeeper.NewKeeper(appCodec, legacyAmino, key, tkey) paramsKeeper := paramskeeper.NewKeeper(appCodec, legacyAmino, key, tkey)
@ -768,10 +761,10 @@ func initParamsKeeper(
paramsKeeper.Subspace(minttypes.ModuleName) paramsKeeper.Subspace(minttypes.ModuleName)
paramsKeeper.Subspace(distrtypes.ModuleName) paramsKeeper.Subspace(distrtypes.ModuleName)
paramsKeeper.Subspace(slashingtypes.ModuleName) paramsKeeper.Subspace(slashingtypes.ModuleName)
paramsKeeper.Subspace(govtypes.ModuleName).WithKeyTable(govtypes.ParamKeyTable()) paramsKeeper.Subspace(govtypes.ModuleName)
paramsKeeper.Subspace(crisistypes.ModuleName) paramsKeeper.Subspace(crisistypes.ModuleName)
paramsKeeper.Subspace(ibctransfertypes.ModuleName) // paramsKeeper.Subspace(ibctransfertypes.ModuleName)
paramsKeeper.Subspace(ibchost.ModuleName) // paramsKeeper.Subspace(ibchost.ModuleName)
// ethermint subspaces // ethermint subspaces
paramsKeeper.Subspace(evmtypes.ModuleName) paramsKeeper.Subspace(evmtypes.ModuleName)
paramsKeeper.Subspace(feemarkettypes.ModuleName) paramsKeeper.Subspace(feemarkettypes.ModuleName)

View File

@ -19,7 +19,7 @@ import (
// NewDefaultGenesisState generates the default state for the application. // NewDefaultGenesisState generates the default state for the application.
func NewDefaultGenesisState() simapp.GenesisState { func NewDefaultGenesisState() simapp.GenesisState {
encCfg := encoding.MakeConfig(ModuleBasics) encCfg := encoding.MakeConfig(ModuleBasics)
return ModuleBasics.DefaultGenesis(encCfg.Marshaler) return ModuleBasics.DefaultGenesis(encCfg.Codec)
} }
// ExportAppStateAndValidators exports the state of the application for a genesis // ExportAppStateAndValidators exports the state of the application for a genesis

View File

@ -27,7 +27,8 @@ import (
"github.com/cosmos/cosmos-sdk/x/simulation" "github.com/cosmos/cosmos-sdk/x/simulation"
slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types" slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
ibctransfertypes "github.com/cosmos/ibc-go/v3/modules/apps/transfer/types"
// ibctransfertypes "github.com/cosmos/ibc-go/v3/modules/apps/transfer/types"
ibchost "github.com/cosmos/ibc-go/v3/modules/core/24-host" ibchost "github.com/cosmos/ibc-go/v3/modules/core/24-host"
abci "github.com/tendermint/tendermint/abci/types" abci "github.com/tendermint/tendermint/abci/types"
"github.com/tendermint/tendermint/libs/log" "github.com/tendermint/tendermint/libs/log"
@ -188,7 +189,7 @@ func TestAppImportExport(t *testing.T) {
{app.keys[evidencetypes.StoreKey], newApp.keys[evidencetypes.StoreKey], [][]byte{}}, {app.keys[evidencetypes.StoreKey], newApp.keys[evidencetypes.StoreKey], [][]byte{}},
{app.keys[capabilitytypes.StoreKey], newApp.keys[capabilitytypes.StoreKey], [][]byte{}}, {app.keys[capabilitytypes.StoreKey], newApp.keys[capabilitytypes.StoreKey], [][]byte{}},
{app.keys[ibchost.StoreKey], newApp.keys[ibchost.StoreKey], [][]byte{}}, {app.keys[ibchost.StoreKey], newApp.keys[ibchost.StoreKey], [][]byte{}},
{app.keys[ibctransfertypes.StoreKey], newApp.keys[ibctransfertypes.StoreKey], [][]byte{}}, // {app.keys[ibctransfertypes.StoreKey], newApp.keys[ibctransfertypes.StoreKey], [][]byte{}},
} }
for _, skp := range storeKeysPrefixes { for _, skp := range storeKeysPrefixes {

View File

@ -7,17 +7,17 @@ import (
"github.com/cosmos/cosmos-sdk/simapp" "github.com/cosmos/cosmos-sdk/simapp"
"github.com/tharsis/ethermint/encoding" "github.com/tharsis/ethermint/encoding"
"github.com/cosmos/cosmos-sdk/db/memdb"
abci "github.com/tendermint/tendermint/abci/types" abci "github.com/tendermint/tendermint/abci/types"
"github.com/tendermint/tendermint/libs/log" "github.com/tendermint/tendermint/libs/log"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types" tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
tmtypes "github.com/tendermint/tendermint/types" tmtypes "github.com/tendermint/tendermint/types"
dbm "github.com/tendermint/tm-db"
) )
// DefaultConsensusParams defines the default Tendermint consensus params used in // DefaultConsensusParams defines the default Tendermint consensus params used in
// EthermintApp testing. // EthermintApp testing.
var DefaultConsensusParams = &abci.ConsensusParams{ var DefaultConsensusParams = &tmproto.ConsensusParams{
Block: &abci.BlockParams{ Block: &tmproto.BlockParams{
MaxBytes: 200000, MaxBytes: 200000,
MaxGas: -1, // no limit MaxGas: -1, // no limit
}, },
@ -35,8 +35,7 @@ var DefaultConsensusParams = &abci.ConsensusParams{
// Setup initializes a new EthermintApp. A Nop logger is set in EthermintApp. // Setup initializes a new EthermintApp. A Nop logger is set in EthermintApp.
func Setup(isCheckTx bool, patchGenesis func(*EthermintApp, simapp.GenesisState) simapp.GenesisState) *EthermintApp { func Setup(isCheckTx bool, patchGenesis func(*EthermintApp, simapp.GenesisState) simapp.GenesisState) *EthermintApp {
db := dbm.NewMemDB() app := NewEthermintApp(log.NewNopLogger(), memdb.NewDB(), nil, true, map[int64]bool{}, DefaultNodeHome, 5, encoding.MakeConfig(ModuleBasics), simapp.EmptyAppOptions{})
app := NewEthermintApp(log.NewNopLogger(), db, nil, true, map[int64]bool{}, DefaultNodeHome, 5, encoding.MakeConfig(ModuleBasics), simapp.EmptyAppOptions{})
if !isCheckTx { if !isCheckTx {
// init chain must be called to stop deliverState from being nil // init chain must be called to stop deliverState from being nil
genesisState := NewDefaultGenesisState() genesisState := NewDefaultGenesisState()

View File

@ -5,6 +5,7 @@ import (
"fmt" "fmt"
"strings" "strings"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/client/input" "github.com/cosmos/cosmos-sdk/client/input"
"github.com/cosmos/cosmos-sdk/crypto" "github.com/cosmos/cosmos-sdk/crypto"
@ -30,12 +31,13 @@ func UnsafeExportEthKeyCommand() *cobra.Command {
keyringBackend, _ := cmd.Flags().GetString(flags.FlagKeyringBackend) keyringBackend, _ := cmd.Flags().GetString(flags.FlagKeyringBackend)
rootDir, _ := cmd.Flags().GetString(flags.FlagHome) rootDir, _ := cmd.Flags().GetString(flags.FlagHome)
clientCtx := client.GetClientContextFromCmd(cmd)
kr, err := keyring.New( kr, err := keyring.New(
sdk.KeyringServiceName(), sdk.KeyringServiceName(),
keyringBackend, keyringBackend,
rootDir, rootDir,
inBuf, inBuf,
clientCtx.Codec,
hd.EthSecp256k1Option(), hd.EthSecp256k1Option(),
) )
if err != nil { if err != nil {

View File

@ -5,6 +5,7 @@ import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/client/input" "github.com/cosmos/cosmos-sdk/client/input"
"github.com/cosmos/cosmos-sdk/crypto" "github.com/cosmos/cosmos-sdk/crypto"
@ -31,12 +32,14 @@ func runImportCmd(cmd *cobra.Command, args []string) error {
inBuf := bufio.NewReader(cmd.InOrStdin()) inBuf := bufio.NewReader(cmd.InOrStdin())
keyringBackend, _ := cmd.Flags().GetString(flags.FlagKeyringBackend) keyringBackend, _ := cmd.Flags().GetString(flags.FlagKeyringBackend)
rootDir, _ := cmd.Flags().GetString(flags.FlagHome) rootDir, _ := cmd.Flags().GetString(flags.FlagHome)
clientCtx := client.GetClientContextFromCmd(cmd)
kb, err := keyring.New( kb, err := keyring.New(
sdk.KeyringServiceName(), sdk.KeyringServiceName(),
keyringBackend, keyringBackend,
rootDir, rootDir,
inBuf, inBuf,
clientCtx.Codec,
hd.EthSecp256k1Option(), hd.EthSecp256k1Option(),
) )
if err != nil { if err != nil {

View File

@ -92,7 +92,7 @@ func runAddCmd(cmd *cobra.Command, args []string) error {
dryRun, _ := cmd.Flags().GetBool(flags.FlagDryRun) dryRun, _ := cmd.Flags().GetBool(flags.FlagDryRun)
if dryRun { if dryRun {
kr, err = keyring.New(sdk.KeyringServiceName(), keyring.BackendMemory, clientCtx.KeyringDir, buf, hd.EthSecp256k1Option()) kr, err = keyring.New(sdk.KeyringServiceName(), keyring.BackendMemory, clientCtx.KeyringDir, buf, clientCtx.Codec, hd.EthSecp256k1Option())
clientCtx = clientCtx.WithKeyring(kr) clientCtx = clientCtx.WithKeyring(kr)
} }

View File

@ -122,7 +122,7 @@ func RunAddCmd(ctx client.Context, cmd *cobra.Command, args []string, inBuf *buf
if dryRun, _ := cmd.Flags().GetBool(flags.FlagDryRun); dryRun { if dryRun, _ := cmd.Flags().GetBool(flags.FlagDryRun); dryRun {
// use in memory keybase // use in memory keybase
kb = keyring.NewInMemory(etherminthd.EthSecp256k1Option()) kb = keyring.NewInMemory(ctx.Codec, etherminthd.EthSecp256k1Option())
} else { } else {
_, err = kb.Key(name) _, err = kb.Key(name)
if err == nil { if err == nil {
@ -156,7 +156,7 @@ func RunAddCmd(ctx client.Context, cmd *cobra.Command, args []string, inBuf *buf
return err return err
} }
pks[i] = k.GetPubKey() pks[i], err = k.GetPubKey()
} }
if noSort, _ := cmd.Flags().GetBool(flagNoSort); !noSort { if noSort, _ := cmd.Flags().GetBool(flagNoSort); !noSort {
@ -183,7 +183,7 @@ func RunAddCmd(ctx client.Context, cmd *cobra.Command, args []string, inBuf *buf
return err return err
} }
info, err := kb.SavePubKey(name, pk, algo.Name()) info, err := kb.SaveOfflineKey(name, pk)
if err != nil { if err != nil {
return err return err
} }
@ -289,7 +289,7 @@ func RunAddCmd(ctx client.Context, cmd *cobra.Command, args []string, inBuf *buf
return printCreate(cmd, info, showMnemonic, mnemonic, outputFormat) return printCreate(cmd, info, showMnemonic, mnemonic, outputFormat)
} }
func printCreate(cmd *cobra.Command, info keyring.Info, showMnemonic bool, mnemonic, outputFormat string) error { func printCreate(cmd *cobra.Command, info *keyring.Record, showMnemonic bool, mnemonic, outputFormat string) error {
switch outputFormat { switch outputFormat {
case OutputFormatText: case OutputFormatText:
cmd.PrintErrln() cmd.PrintErrln()

View File

@ -3,7 +3,6 @@ package keys
import ( import (
"fmt" "fmt"
"io" "io"
"path/filepath"
yaml "gopkg.in/yaml.v2" yaml "gopkg.in/yaml.v2"
@ -20,19 +19,19 @@ const (
defaultKeyDBName = "keys" defaultKeyDBName = "keys"
) )
type bechKeyOutFn func(keyInfo cryptokeyring.Info) (cryptokeyring.KeyOutput, error) type bechKeyOutFn func(keyInfo *cryptokeyring.Record) (cryptokeyring.KeyOutput, error)
// NewLegacyKeyBaseFromDir initializes a legacy keybase at the rootDir directory. Keybase // // NewLegacyKeyBaseFromDir initializes a legacy keybase at the rootDir directory. Keybase
// options can be applied when generating this new Keybase. // // options can be applied when generating this new Keybase.
func NewLegacyKeyBaseFromDir(rootDir string, opts ...cryptokeyring.KeybaseOption) (cryptokeyring.LegacyKeybase, error) { // func NewLegacyKeyBaseFromDir(rootDir string, opts ...cryptokeyring.KeybaseOption) (cryptokeyring.LegacyKeybase, error) {
return getLegacyKeyBaseFromDir(rootDir, opts...) // return getLegacyKeyBaseFromDir(rootDir, opts...)
} // }
func getLegacyKeyBaseFromDir(rootDir string, opts ...cryptokeyring.KeybaseOption) (cryptokeyring.LegacyKeybase, error) { // func getLegacyKeyBaseFromDir(rootDir string, opts ...cryptokeyring.KeybaseOption) (cryptokeyring.LegacyKeybase, error) {
return cryptokeyring.NewLegacy(defaultKeyDBName, filepath.Join(rootDir, "keys"), opts...) // return cryptokeyring.NewLegacy(defaultKeyDBName, filepath.Join(rootDir, "keys"), opts...)
} // }
func printKeyInfo(w io.Writer, keyInfo cryptokeyring.Info, bechKeyOut bechKeyOutFn, output string) { func printKeyInfo(w io.Writer, keyInfo *cryptokeyring.Record, bechKeyOut bechKeyOutFn, output string) {
ko, err := bechKeyOut(keyInfo) ko, err := bechKeyOut(keyInfo)
if err != nil { if err != nil {
panic(err) panic(err)

View File

@ -6,17 +6,18 @@ import (
"bufio" "bufio"
"encoding/json" "encoding/json"
"fmt" "fmt"
"math/rand"
"net" "net"
"os" "os"
"path/filepath" "path/filepath"
"time"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
tmcfg "github.com/tendermint/tendermint/config"
"github.com/spf13/cobra" "github.com/spf13/cobra"
tmconfig "github.com/tendermint/tendermint/config" tmconfig "github.com/tendermint/tendermint/config"
tmrand "github.com/tendermint/tendermint/libs/rand"
"github.com/tendermint/tendermint/types" "github.com/tendermint/tendermint/types"
tmtime "github.com/tendermint/tendermint/types/time"
"github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/client/flags"
@ -34,6 +35,8 @@ import (
"github.com/cosmos/cosmos-sdk/x/genutil" "github.com/cosmos/cosmos-sdk/x/genutil"
genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types"
govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
v1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1"
mintypes "github.com/cosmos/cosmos-sdk/x/mint/types" mintypes "github.com/cosmos/cosmos-sdk/x/mint/types"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
@ -209,7 +212,7 @@ func initTestnetFiles(
args initArgs, args initArgs,
) error { ) error {
if args.chainID == "" { if args.chainID == "" {
args.chainID = fmt.Sprintf("ethermint_%d-1", tmrand.Int63n(9999999999999)+1) args.chainID = fmt.Sprintf("ethermint_%d-1", rand.Int63n(9999999999999)+1)
} }
nodeIDs := make([]string, args.numValidators) nodeIDs := make([]string, args.numValidators)
@ -261,7 +264,7 @@ func initTestnetFiles(
memo := fmt.Sprintf("%s@%s:26656", nodeIDs[i], ip) memo := fmt.Sprintf("%s@%s:26656", nodeIDs[i], ip)
genFiles = append(genFiles, nodeConfig.GenesisFile()) genFiles = append(genFiles, nodeConfig.GenesisFile())
kb, err := keyring.New(sdk.KeyringServiceName(), args.keyringBackend, nodeDir, inBuf, hd.EthSecp256k1Option()) kb, err := keyring.New(sdk.KeyringServiceName(), args.keyringBackend, nodeDir, inBuf, clientCtx.Codec, hd.EthSecp256k1Option())
if err != nil { if err != nil {
return err return err
} }
@ -343,7 +346,8 @@ func initTestnetFiles(
customAppTemplate, customAppConfig := config.AppConfig(ethermint.AttoPhoton) customAppTemplate, customAppConfig := config.AppConfig(ethermint.AttoPhoton)
srvconfig.SetConfigTemplate(customAppTemplate) srvconfig.SetConfigTemplate(customAppTemplate)
if err := sdkserver.InterceptConfigsPreRunHandler(cmd, customAppTemplate, customAppConfig); err != nil { customTmConfig := tmcfg.DefaultConfig()
if err := sdkserver.InterceptConfigsPreRunHandler(cmd, customAppTemplate, customAppConfig, customTmConfig); err != nil {
return err return err
} }
@ -402,7 +406,7 @@ func initGenFiles(
stakingGenState.Params.BondDenom = coinDenom stakingGenState.Params.BondDenom = coinDenom
appGenState[stakingtypes.ModuleName] = clientCtx.Codec.MustMarshalJSON(&stakingGenState) appGenState[stakingtypes.ModuleName] = clientCtx.Codec.MustMarshalJSON(&stakingGenState)
var govGenState govtypes.GenesisState var govGenState v1.GenesisState
clientCtx.Codec.MustUnmarshalJSON(appGenState[govtypes.ModuleName], &govGenState) clientCtx.Codec.MustUnmarshalJSON(appGenState[govtypes.ModuleName], &govGenState)
govGenState.DepositParams.MinDeposit[0].Denom = coinDenom govGenState.DepositParams.MinDeposit[0].Denom = coinDenom
@ -452,7 +456,8 @@ func collectGenFiles(
outputDir, nodeDirPrefix, nodeDaemonHome string, genBalIterator banktypes.GenesisBalancesIterator, outputDir, nodeDirPrefix, nodeDaemonHome string, genBalIterator banktypes.GenesisBalancesIterator,
) error { ) error {
var appState json.RawMessage var appState json.RawMessage
genTime := tmtime.Now() // genTime := tmtime.Now()
genTime := time.Now()
for i := 0; i < numValidators; i++ { for i := 0; i < numValidators; i++ {
nodeDirName := fmt.Sprintf("%s%d", nodeDirPrefix, i) nodeDirName := fmt.Sprintf("%s%d", nodeDirPrefix, i)

View File

@ -8,7 +8,7 @@ import (
const ( const (
// Bech32Prefix defines the Bech32 prefix used for EthAccounts // Bech32Prefix defines the Bech32 prefix used for EthAccounts
Bech32Prefix = "ethm" Bech32Prefix = ethermint.Bech32MainPrefix
// Bech32PrefixAccAddr defines the Bech32 prefix of an account's address // Bech32PrefixAccAddr defines the Bech32 prefix of an account's address
Bech32PrefixAccAddr = Bech32Prefix Bech32PrefixAccAddr = Bech32Prefix

View File

@ -63,6 +63,7 @@ contain valid denominations. Accounts may optionally be supplied with vesting pa
keyringBackend, keyringBackend,
clientCtx.HomeDir, clientCtx.HomeDir,
inBuf, inBuf,
clientCtx.Codec,
hd.EthSecp256k1Option(), hd.EthSecp256k1Option(),
) )
if err != nil { if err != nil {
@ -77,7 +78,10 @@ contain valid denominations. Accounts may optionally be supplied with vesting pa
return fmt.Errorf("failed to get address from Keyring: %w", err) return fmt.Errorf("failed to get address from Keyring: %w", err)
} }
addr = info.GetAddress() addr, err = info.GetAddress()
if err != nil {
return fmt.Errorf("failed to get address from Keyring: %w", err)
}
} }
coins, err := sdk.ParseCoinsNormalized(args[1]) coins, err := sdk.ParseCoinsNormalized(args[1])

View File

@ -17,7 +17,7 @@ func main() {
rootCmd, _ := NewRootCmd() rootCmd, _ := NewRootCmd()
if err := svrcmd.Execute(rootCmd, app.DefaultNodeHome); err != nil { if err := svrcmd.Execute(rootCmd, "", app.DefaultNodeHome); err != nil {
switch e := err.(type) { switch e := err.(type) {
case server.ErrorCode: case server.ErrorCode:
os.Exit(e.Code) os.Exit(e.Code)

View File

@ -6,18 +6,13 @@ import (
"os" "os"
"path/filepath" "path/filepath"
"github.com/spf13/cast"
"github.com/spf13/cobra"
tmcli "github.com/tendermint/tendermint/libs/cli"
tmlog "github.com/tendermint/tendermint/libs/log"
dbm "github.com/tendermint/tm-db"
"github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/baseapp"
"github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/config" "github.com/cosmos/cosmos-sdk/client/config"
"github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/client/rpc" "github.com/cosmos/cosmos-sdk/client/rpc"
dbm "github.com/cosmos/cosmos-sdk/db"
"github.com/cosmos/cosmos-sdk/db/badgerdb"
sdkserver "github.com/cosmos/cosmos-sdk/server" sdkserver "github.com/cosmos/cosmos-sdk/server"
servertypes "github.com/cosmos/cosmos-sdk/server/types" servertypes "github.com/cosmos/cosmos-sdk/server/types"
"github.com/cosmos/cosmos-sdk/simapp/params" "github.com/cosmos/cosmos-sdk/simapp/params"
@ -29,6 +24,11 @@ import (
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
"github.com/cosmos/cosmos-sdk/x/crisis" "github.com/cosmos/cosmos-sdk/x/crisis"
genutilcli "github.com/cosmos/cosmos-sdk/x/genutil/client/cli" genutilcli "github.com/cosmos/cosmos-sdk/x/genutil/client/cli"
"github.com/spf13/cast"
"github.com/spf13/cobra"
tmcfg "github.com/tendermint/tendermint/config"
tmcli "github.com/tendermint/tendermint/libs/cli"
tmlog "github.com/tendermint/tendermint/libs/log"
"github.com/tharsis/ethermint/app" "github.com/tharsis/ethermint/app"
ethermintclient "github.com/tharsis/ethermint/client" ethermintclient "github.com/tharsis/ethermint/client"
@ -48,7 +48,7 @@ const EnvPrefix = "ETHERMINT"
func NewRootCmd() (*cobra.Command, params.EncodingConfig) { func NewRootCmd() (*cobra.Command, params.EncodingConfig) {
encodingConfig := encoding.MakeConfig(app.ModuleBasics) encodingConfig := encoding.MakeConfig(app.ModuleBasics)
initClientCtx := client.Context{}. initClientCtx := client.Context{}.
WithCodec(encodingConfig.Marshaler). WithCodec(encodingConfig.Codec).
WithInterfaceRegistry(encodingConfig.InterfaceRegistry). WithInterfaceRegistry(encodingConfig.InterfaceRegistry).
WithTxConfig(encodingConfig.TxConfig). WithTxConfig(encodingConfig.TxConfig).
WithLegacyAmino(encodingConfig.Amino). WithLegacyAmino(encodingConfig.Amino).
@ -83,8 +83,9 @@ func NewRootCmd() (*cobra.Command, params.EncodingConfig) {
// FIXME: replace AttoPhoton with bond denom // FIXME: replace AttoPhoton with bond denom
customAppTemplate, customAppConfig := servercfg.AppConfig(ethermint.AttoPhoton) customAppTemplate, customAppConfig := servercfg.AppConfig(ethermint.AttoPhoton)
customTMConfig := initTendermintConfig()
return sdkserver.InterceptConfigsPreRunHandler(cmd, customAppTemplate, customAppConfig) return sdkserver.InterceptConfigsPreRunHandler(cmd, customAppTemplate, customAppConfig, customTMConfig)
}, },
} }
@ -126,8 +127,7 @@ func NewRootCmd() (*cobra.Command, params.EncodingConfig) {
} }
// add rosetta // add rosetta
rootCmd.AddCommand(sdkserver.RosettaCommand(encodingConfig.InterfaceRegistry, encodingConfig.Marshaler)) rootCmd.AddCommand(sdkserver.RosettaCommand(encodingConfig.InterfaceRegistry, encodingConfig.Codec))
return rootCmd, encodingConfig return rootCmd, encodingConfig
} }
@ -135,6 +135,18 @@ func addModuleInitFlags(startCmd *cobra.Command) {
crisis.AddModuleInitFlags(startCmd) crisis.AddModuleInitFlags(startCmd)
} }
// initTendermintConfig helps to override default Tendermint Config values.
// return tmcfg.DefaultConfig if no custom configuration is required for the application.
func initTendermintConfig() *tmcfg.Config {
cfg := tmcfg.DefaultConfig()
// these values put a higher strain on node memory
// cfg.P2P.MaxNumInboundPeers = 100
// cfg.P2P.MaxNumOutboundPeers = 40
return cfg
}
func queryCommand() *cobra.Command { func queryCommand() *cobra.Command {
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "query", Use: "query",
@ -190,7 +202,7 @@ type appCreator struct {
} }
// newApp is an appCreator // newApp is an appCreator
func (a appCreator) newApp(logger tmlog.Logger, db dbm.DB, traceStore io.Writer, appOpts servertypes.AppOptions) servertypes.Application { func (a appCreator) newApp(logger tmlog.Logger, db dbm.DBConnection, traceStore io.Writer, appOpts servertypes.AppOptions) servertypes.Application {
var cache sdk.MultiStorePersistentCache var cache sdk.MultiStorePersistentCache
if cast.ToBool(appOpts.Get(sdkserver.FlagInterBlockCache)) { if cast.ToBool(appOpts.Get(sdkserver.FlagInterBlockCache)) {
@ -208,7 +220,7 @@ func (a appCreator) newApp(logger tmlog.Logger, db dbm.DB, traceStore io.Writer,
} }
snapshotDir := filepath.Join(cast.ToString(appOpts.Get(flags.FlagHome)), "data", "snapshots") snapshotDir := filepath.Join(cast.ToString(appOpts.Get(flags.FlagHome)), "data", "snapshots")
snapshotDB, err := sdk.NewLevelDB("metadata", snapshotDir) snapshotDB, err := badgerdb.NewDB(filepath.Join(snapshotDir, "metadata"))
if err != nil { if err != nil {
panic(err) panic(err)
} }
@ -242,7 +254,7 @@ func (a appCreator) newApp(logger tmlog.Logger, db dbm.DB, traceStore io.Writer,
// appExport creates a new simapp (optionally at a given height) // appExport creates a new simapp (optionally at a given height)
// and exports state. // and exports state.
func (a appCreator) appExport( func (a appCreator) appExport(
logger tmlog.Logger, db dbm.DB, traceStore io.Writer, height int64, forZeroHeight bool, jailAllowedAddrs []string, logger tmlog.Logger, db dbm.DBConnection, traceStore io.Writer, height int64, forZeroHeight bool, jailAllowedAddrs []string,
appOpts servertypes.AppOptions, appOpts servertypes.AppOptions,
) (servertypes.ExportedApp, error) { ) (servertypes.ExportedApp, error) {
var ethermintApp *app.EthermintApp var ethermintApp *app.EthermintApp

View File

@ -1,7 +1,7 @@
package encoding package encoding
import ( import (
amino "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/codec/types" "github.com/cosmos/cosmos-sdk/codec/types"
"github.com/cosmos/cosmos-sdk/simapp/params" "github.com/cosmos/cosmos-sdk/simapp/params"
"github.com/cosmos/cosmos-sdk/types/module" "github.com/cosmos/cosmos-sdk/types/module"
@ -12,14 +12,14 @@ import (
// MakeConfig creates an EncodingConfig for testing // MakeConfig creates an EncodingConfig for testing
func MakeConfig(mb module.BasicManager) params.EncodingConfig { func MakeConfig(mb module.BasicManager) params.EncodingConfig {
cdc := amino.NewLegacyAmino() cdc := codec.NewLegacyAmino()
interfaceRegistry := types.NewInterfaceRegistry() interfaceRegistry := types.NewInterfaceRegistry()
marshaler := amino.NewProtoCodec(interfaceRegistry) codec := codec.NewProtoCodec(interfaceRegistry)
encodingConfig := params.EncodingConfig{ encodingConfig := params.EncodingConfig{
InterfaceRegistry: interfaceRegistry, InterfaceRegistry: interfaceRegistry,
Marshaler: marshaler, Codec: codec,
TxConfig: tx.NewTxConfig(marshaler, tx.DefaultSignModes), TxConfig: tx.NewTxConfig(codec, tx.DefaultSignModes),
Amino: cdc, Amino: cdc,
} }

109
go.mod
View File

@ -5,9 +5,10 @@ go 1.17
require ( require (
github.com/btcsuite/btcd v0.22.0-beta github.com/btcsuite/btcd v0.22.0-beta
github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce
github.com/cosmos/cosmos-sdk v0.45.1 github.com/cosmos/cosmos-sdk v0.46.0-alpha3.0.20220325134903-a69764f9f01b
github.com/cosmos/cosmos-sdk/db v1.0.0-beta.1
github.com/cosmos/go-bip39 v1.0.0 github.com/cosmos/go-bip39 v1.0.0
github.com/cosmos/ibc-go/v3 v3.0.0 github.com/cosmos/ibc-go/v3 v3.0.0-alpha1.0.20220331200732-34f03df4aa59
github.com/davecgh/go-spew v1.1.1 github.com/davecgh/go-spew v1.1.1
github.com/ethereum/go-ethereum v1.10.16 github.com/ethereum/go-ethereum v1.10.16
github.com/gogo/protobuf v1.3.3 github.com/gogo/protobuf v1.3.3
@ -23,46 +24,54 @@ require (
github.com/rakyll/statik v0.1.7 github.com/rakyll/statik v0.1.7
github.com/regen-network/cosmos-proto v0.3.1 github.com/regen-network/cosmos-proto v0.3.1
github.com/rs/cors v1.8.2 github.com/rs/cors v1.8.2
github.com/rs/zerolog v1.26.1
github.com/spf13/cast v1.4.1 github.com/spf13/cast v1.4.1
github.com/spf13/cobra v1.4.0 github.com/spf13/cobra v1.4.0
github.com/spf13/viper v1.10.1 github.com/spf13/viper v1.10.1
github.com/status-im/keycard-go v0.0.0-20200402102358-957c09536969 github.com/status-im/keycard-go v0.0.0-20200402102358-957c09536969
github.com/stretchr/testify v1.7.1 github.com/stretchr/testify v1.7.1
github.com/tendermint/tendermint v0.34.14 github.com/tendermint/tendermint v0.35.2
github.com/tendermint/tm-db v0.6.7 github.com/tendermint/tm-db v0.6.7
github.com/tyler-smith/go-bip39 v1.1.0 github.com/tyler-smith/go-bip39 v1.1.0
google.golang.org/genproto v0.0.0-20220211171837-173942840c17 google.golang.org/genproto v0.0.0-20220222213610-43724f9ea8cf
google.golang.org/grpc v1.44.0 google.golang.org/grpc v1.45.0
google.golang.org/protobuf v1.28.0 google.golang.org/protobuf v1.28.0
gopkg.in/yaml.v2 v2.4.0 gopkg.in/yaml.v2 v2.4.0
) )
require ( require (
filippo.io/edwards25519 v1.0.0-beta.2 // indirect cloud.google.com/go v0.99.0 // indirect
cloud.google.com/go/storage v1.14.0 // indirect
filippo.io/edwards25519 v1.0.0-rc.1 // indirect
github.com/99designs/keyring v1.1.6 // indirect github.com/99designs/keyring v1.1.6 // indirect
github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d // indirect
github.com/DataDog/zstd v1.4.5 // indirect
github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 // indirect github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 // indirect
github.com/VictoriaMetrics/fastcache v1.6.0 // indirect github.com/VictoriaMetrics/fastcache v1.6.0 // indirect
github.com/Workiva/go-datastructures v1.0.52 // indirect github.com/Workiva/go-datastructures v1.0.53 // indirect
github.com/armon/go-metrics v0.3.10 // indirect github.com/armon/go-metrics v0.3.10 // indirect
github.com/aws/aws-sdk-go v1.40.45 // indirect
github.com/beorn7/perks v1.0.1 // indirect github.com/beorn7/perks v1.0.1 // indirect
github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect
github.com/bgentry/speakeasy v0.1.0 // indirect github.com/bgentry/speakeasy v0.1.0 // indirect
github.com/cenkalti/backoff/v4 v4.1.1 // indirect github.com/cenkalti/backoff/v4 v4.1.1 // indirect
github.com/cespare/xxhash v1.1.0 // indirect github.com/cespare/xxhash v1.1.0 // indirect
github.com/cespare/xxhash/v2 v2.1.2 // indirect github.com/cespare/xxhash/v2 v2.1.2 // indirect
github.com/coinbase/rosetta-sdk-go v0.7.0 // indirect github.com/cockroachdb/apd/v2 v2.0.2 // indirect
github.com/coinbase/rosetta-sdk-go v0.7.7 // indirect
github.com/confio/ics23/go v0.7.0 // indirect github.com/confio/ics23/go v0.7.0 // indirect
github.com/cosmos/btcutil v1.0.4 // indirect github.com/cosmos/btcutil v1.0.4 // indirect
github.com/cosmos/cosmos-proto v1.0.0-alpha7 // indirect
github.com/cosmos/cosmos-sdk/api v0.1.0 // indirect
github.com/cosmos/cosmos-sdk/errors v1.0.0-beta.3 // indirect
github.com/cosmos/gorocksdb v1.2.0 // indirect github.com/cosmos/gorocksdb v1.2.0 // indirect
github.com/cosmos/iavl v0.17.3 // indirect github.com/cosmos/iavl v0.18.0 // indirect
github.com/cosmos/ledger-cosmos-go v0.11.1 // indirect github.com/cosmos/ledger-cosmos-go v0.11.1 // indirect
github.com/cosmos/ledger-go v0.9.2 // indirect github.com/cosmos/ledger-go v0.9.2 // indirect
github.com/danieljoos/wincred v1.0.2 // indirect github.com/danieljoos/wincred v1.0.2 // indirect
github.com/deckarep/golang-set v1.8.0 // indirect github.com/deckarep/golang-set v1.8.0 // indirect
github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f // indirect github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f // indirect
github.com/dgraph-io/badger/v2 v2.2007.2 // indirect github.com/dgraph-io/badger/v2 v2.2007.4 // indirect
github.com/dgraph-io/ristretto v0.0.3 // indirect github.com/dgraph-io/badger/v3 v3.2103.2 // indirect
github.com/dgraph-io/ristretto v0.1.0 // indirect
github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 // indirect github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 // indirect
github.com/dustin/go-humanize v1.0.0 // indirect github.com/dustin/go-humanize v1.0.0 // indirect
github.com/dvsekhvalnov/jose2go v0.0.0-20200901110807-248326c1351b // indirect github.com/dvsekhvalnov/jose2go v0.0.0-20200901110807-248326c1351b // indirect
@ -70,60 +79,69 @@ require (
github.com/felixge/httpsnoop v1.0.1 // indirect github.com/felixge/httpsnoop v1.0.1 // indirect
github.com/fsnotify/fsnotify v1.5.1 // indirect github.com/fsnotify/fsnotify v1.5.1 // indirect
github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff // indirect github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff // indirect
github.com/go-kit/kit v0.10.0 // indirect github.com/go-kit/kit v0.12.0 // indirect
github.com/go-logfmt/logfmt v0.5.0 // indirect github.com/go-ole/go-ole v1.2.6 // indirect
github.com/go-ole/go-ole v1.2.1 // indirect
github.com/go-playground/validator/v10 v10.4.1 // indirect github.com/go-playground/validator/v10 v10.4.1 // indirect
github.com/go-stack/stack v1.8.0 // indirect github.com/go-stack/stack v1.8.0 // indirect
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 // indirect github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 // indirect
github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect
github.com/gogo/gateway v1.1.0 // indirect github.com/gogo/gateway v1.1.0 // indirect
github.com/golang/glog v1.0.0 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/snappy v0.0.4 // indirect github.com/golang/snappy v0.0.4 // indirect
github.com/google/btree v1.0.0 // indirect github.com/google/btree v1.0.1 // indirect
github.com/google/flatbuffers v2.0.0+incompatible // indirect
github.com/google/orderedcode v0.0.1 // indirect github.com/google/orderedcode v0.0.1 // indirect
github.com/google/uuid v1.1.5 // indirect github.com/google/uuid v1.3.0 // indirect
github.com/googleapis/gax-go/v2 v2.1.1 // indirect
github.com/gorilla/handlers v1.5.1 // indirect github.com/gorilla/handlers v1.5.1 // indirect
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 // indirect
github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect
github.com/gtank/merlin v0.1.1 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/gtank/ristretto255 v0.1.2 // indirect github.com/hashicorp/go-getter v1.5.11 // indirect
github.com/hashicorp/go-immutable-radix v1.3.1 // indirect github.com/hashicorp/go-immutable-radix v1.3.1 // indirect
github.com/hashicorp/go-safetemp v1.0.0 // indirect
github.com/hashicorp/go-version v1.2.1 // indirect
github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d // indirect github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d // indirect
github.com/hashicorp/hcl v1.0.0 // indirect github.com/hashicorp/hcl v1.0.0 // indirect
github.com/hdevalence/ed25519consensus v0.0.0-20210204194344-59a8610d2b87 // indirect github.com/hdevalence/ed25519consensus v0.0.0-20220222234857-c00d1f31bab3 // indirect
github.com/holiman/bloomfilter/v2 v2.0.3 // indirect github.com/holiman/bloomfilter/v2 v2.0.3 // indirect
github.com/huin/goupnp v1.0.2 // indirect github.com/huin/goupnp v1.0.2 // indirect
github.com/inconshreveable/mousetrap v1.0.0 // indirect github.com/inconshreveable/mousetrap v1.0.0 // indirect
github.com/jackpal/go-nat-pmp v1.0.2 // indirect github.com/jackpal/go-nat-pmp v1.0.2 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/jmhodges/levigo v1.0.0 // indirect github.com/jmhodges/levigo v1.0.0 // indirect
github.com/keybase/go-keychain v0.0.0-20190712205309-48d3d31d256d // indirect github.com/keybase/go-keychain v0.0.0-20190712205309-48d3d31d256d // indirect
github.com/klauspost/compress v1.11.7 // indirect github.com/klauspost/compress v1.13.6 // indirect
github.com/lib/pq v1.10.2 // indirect github.com/lazyledger/smt v0.2.1-0.20210709230900-03ea40719554 // indirect
github.com/lib/pq v1.10.4 // indirect
github.com/libp2p/go-buffer-pool v0.0.2 // indirect github.com/libp2p/go-buffer-pool v0.0.2 // indirect
github.com/magiconair/properties v1.8.5 // indirect github.com/magiconair/properties v1.8.6 // indirect
github.com/mattn/go-isatty v0.0.14 // indirect github.com/mattn/go-isatty v0.0.14 // indirect
github.com/mattn/go-runewidth v0.0.9 // indirect github.com/mattn/go-runewidth v0.0.9 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
github.com/mimoo/StrobeGo v0.0.0-20181016162300-f8f6d4d2b643 // indirect github.com/minio/highwayhash v1.0.2 // indirect
github.com/minio/highwayhash v1.0.1 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/mitchellh/go-testing-interface v1.0.0 // indirect
github.com/mitchellh/mapstructure v1.4.3 // indirect github.com/mitchellh/mapstructure v1.4.3 // indirect
github.com/mtibben/percent v0.2.1 // indirect github.com/mtibben/percent v0.2.1 // indirect
github.com/nxadm/tail v1.4.8 // indirect github.com/nxadm/tail v1.4.8 // indirect
github.com/oasisprotocol/curve25519-voi v0.0.0-20210609091139-0a56a4bca00b // indirect
github.com/olekukonko/tablewriter v0.0.5 // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect
github.com/pelletier/go-toml v1.9.4 // indirect github.com/pelletier/go-toml v1.9.4 // indirect
github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 // indirect github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/prometheus/client_golang v1.11.0 // indirect github.com/prometheus/client_golang v1.12.1 // indirect
github.com/prometheus/client_model v0.2.0 // indirect github.com/prometheus/client_model v0.2.0 // indirect
github.com/prometheus/common v0.29.0 // indirect github.com/prometheus/common v0.33.0 // indirect
github.com/prometheus/procfs v0.6.0 // indirect github.com/prometheus/procfs v0.7.3 // indirect
github.com/prometheus/tsdb v0.7.1 // indirect github.com/prometheus/tsdb v0.7.1 // indirect
github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0 // indirect github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0 // indirect
github.com/rjeczalik/notify v0.9.1 // indirect github.com/rjeczalik/notify v0.9.1 // indirect
github.com/rs/zerolog v1.23.0 // indirect
github.com/sasha-s/go-deadlock v0.2.1-0.20190427202633-1595213edefa // indirect github.com/sasha-s/go-deadlock v0.2.1-0.20190427202633-1595213edefa // indirect
github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible // indirect github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible // indirect
github.com/spf13/afero v1.6.0 // indirect github.com/spf13/afero v1.8.0 // indirect
github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect github.com/spf13/pflag v1.0.5 // indirect
github.com/subosito/gotenv v1.2.0 // indirect github.com/subosito/gotenv v1.2.0 // indirect
@ -131,27 +149,38 @@ require (
github.com/tendermint/btcd v0.1.1 // indirect github.com/tendermint/btcd v0.1.1 // indirect
github.com/tendermint/crypto v0.0.0-20191022145703-50d29ede1e15 // indirect github.com/tendermint/crypto v0.0.0-20191022145703-50d29ede1e15 // indirect
github.com/tendermint/go-amino v0.16.0 // indirect github.com/tendermint/go-amino v0.16.0 // indirect
github.com/tklauser/go-sysconf v0.3.5 // indirect github.com/tklauser/go-sysconf v0.3.9 // indirect
github.com/tklauser/numcpus v0.2.2 // indirect github.com/tklauser/numcpus v0.3.0 // indirect
github.com/zondax/hid v0.9.0 // indirect github.com/ulikunitz/xz v0.5.8 // indirect
github.com/zondax/hid v0.9.1-0.20220302062450-5552068d2266 // indirect
go.etcd.io/bbolt v1.3.6 // indirect go.etcd.io/bbolt v1.3.6 // indirect
go.opencensus.io v0.23.0 // indirect
golang.org/x/crypto v0.0.0-20220213190939-1e6e3497d506 // indirect golang.org/x/crypto v0.0.0-20220213190939-1e6e3497d506 // indirect
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 // indirect golang.org/x/net v0.0.0-20220225172249-27dd8689420f // indirect
golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b // indirect
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
golang.org/x/sys v0.0.0-20211210111614-af8b64212486 // indirect golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 // indirect
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 // indirect golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect
golang.org/x/text v0.3.7 // indirect golang.org/x/text v0.3.7 // indirect
golang.org/x/tools v0.1.5 // indirect golang.org/x/tools v0.1.9 // indirect
gopkg.in/ini.v1 v1.66.2 // indirect golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
google.golang.org/api v0.63.0 // indirect
google.golang.org/appengine v1.6.7 // indirect
gopkg.in/ini.v1 v1.66.3 // indirect
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200619000410-60c24ae608a6 // indirect gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200619000410-60c24ae608a6 // indirect
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
nhooyr.io/websocket v1.8.6 // indirect nhooyr.io/websocket v1.8.6 // indirect
sigs.k8s.io/yaml v1.3.0 // indirect
) )
replace ( replace (
github.com/99designs/keyring => github.com/cosmos/keyring v1.1.7-0.20210622111912-ef00f8ac3d76 github.com/99designs/keyring => github.com/cosmos/keyring v1.1.7-0.20210622111912-ef00f8ac3d76
// replace cosmos
github.com/cosmos/cosmos-sdk => github.com/vulcanize/cosmos-sdk v0.46.0-smt-0.0.3-alpha
github.com/cosmos/cosmos-sdk/db => /home/vitwit/Projects/vulcanize/cosmos-sdk/db
github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1
google.golang.org/grpc => google.golang.org/grpc v1.33.2 google.golang.org/grpc => google.golang.org/grpc v1.44.0
) )

717
go.sum

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,6 @@
package backend package backend
import ( import (
"bytes"
"context" "context"
"encoding/json" "encoding/json"
"fmt" "fmt"
@ -15,7 +14,8 @@ import (
"github.com/ethereum/go-ethereum/accounts/keystore" "github.com/ethereum/go-ethereum/accounts/keystore"
"github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/rpc" "github.com/ethereum/go-ethereum/rpc"
tmrpctypes "github.com/tendermint/tendermint/rpc/core/types"
tmrpctypes "github.com/tendermint/tendermint/rpc/coretypes"
"google.golang.org/grpc" "google.golang.org/grpc"
"google.golang.org/grpc/metadata" "google.golang.org/grpc/metadata"
@ -334,8 +334,8 @@ func (e *EVMBackend) BlockBloom(height *int64) (ethtypes.Bloom, error) {
} }
for _, attr := range event.Attributes { for _, attr := range event.Attributes {
if bytes.Equal(attr.Key, bAttributeKeyEthereumBloom) { if attr.Key == string(bAttributeKeyEthereumBloom) {
return ethtypes.BytesToBloom(attr.Value), nil return ethtypes.BytesToBloom([]byte(attr.Value)), nil
} }
} }
} }

View File

@ -7,7 +7,7 @@ import (
"github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/rpc" "github.com/ethereum/go-ethereum/rpc"
tmrpctypes "github.com/tendermint/tendermint/rpc/core/types" tmrpctypes "github.com/tendermint/tendermint/rpc/coretypes"
rpctypes "github.com/tharsis/ethermint/rpc/ethereum/types" rpctypes "github.com/tharsis/ethermint/rpc/ethereum/types"
evmtypes "github.com/tharsis/ethermint/x/evm/types" evmtypes "github.com/tharsis/ethermint/x/evm/types"
) )

View File

@ -238,12 +238,12 @@ func TxLogsFromEvents(events []abci.Event, msgIndex int) ([]*ethtypes.Log, error
func ParseTxLogsFromEvent(event abci.Event) ([]*ethtypes.Log, error) { func ParseTxLogsFromEvent(event abci.Event) ([]*ethtypes.Log, error) {
logs := make([]*evmtypes.Log, 0, len(event.Attributes)) logs := make([]*evmtypes.Log, 0, len(event.Attributes))
for _, attr := range event.Attributes { for _, attr := range event.Attributes {
if !bytes.Equal(attr.Key, []byte(evmtypes.AttributeKeyTxLog)) { if !bytes.Equal([]byte(attr.Key), []byte(evmtypes.AttributeKeyTxLog)) {
continue continue
} }
var log evmtypes.Log var log evmtypes.Log
if err := json.Unmarshal(attr.Value, &log); err != nil { if err := json.Unmarshal([]byte(attr.Value), &log); err != nil {
return nil, err return nil, err
} }

View File

@ -14,7 +14,7 @@ import (
"time" "time"
"github.com/davecgh/go-spew/spew" "github.com/davecgh/go-spew/spew"
tmrpctypes "github.com/tendermint/tendermint/rpc/core/types" tmrpctypes "github.com/tendermint/tendermint/rpc/coretypes"
evmtypes "github.com/tharsis/ethermint/x/evm/types" evmtypes "github.com/tharsis/ethermint/x/evm/types"

View File

@ -20,7 +20,7 @@ import (
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/spf13/viper" "github.com/spf13/viper"
"github.com/tendermint/tendermint/libs/log" "github.com/tendermint/tendermint/libs/log"
tmrpctypes "github.com/tendermint/tendermint/rpc/core/types" tmrpctypes "github.com/tendermint/tendermint/rpc/coretypes"
"github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/client/flags"
@ -74,6 +74,7 @@ func NewPublicAPI(
viper.GetString(flags.FlagKeyringBackend), viper.GetString(flags.FlagKeyringBackend),
clientCtx.KeyringDir, clientCtx.KeyringDir,
clientCtx.Input, clientCtx.Input,
clientCtx.Codec,
hd.EthSecp256k1Option(), hd.EthSecp256k1Option(),
) )
if err != nil { if err != nil {
@ -242,7 +243,11 @@ func (e *PublicAPI) Accounts() ([]common.Address, error) {
} }
for _, info := range infos { for _, info := range infos {
addressBytes := info.GetPubKey().Address().Bytes() pubKey, err := info.GetPubKey()
if err != nil {
return addresses, err
}
addressBytes := pubKey.Address().Bytes()
addresses = append(addresses, common.BytesToAddress(addressBytes)) addresses = append(addresses, common.BytesToAddress(addressBytes))
} }

View File

@ -11,7 +11,7 @@ import (
"github.com/tendermint/tendermint/libs/log" "github.com/tendermint/tendermint/libs/log"
coretypes "github.com/tendermint/tendermint/rpc/core/types" coretypes "github.com/tendermint/tendermint/rpc/coretypes"
rpcclient "github.com/tendermint/tendermint/rpc/jsonrpc/client" rpcclient "github.com/tendermint/tendermint/rpc/jsonrpc/client"
tmtypes "github.com/tendermint/tendermint/types" tmtypes "github.com/tendermint/tendermint/types"
@ -371,7 +371,13 @@ func (api *PublicFilterAPI) Logs(ctx context.Context, crit filters.FilterCriteri
} }
// filter only events from EVM module txs // filter only events from EVM module txs
_, isMsgEthereumTx := ev.Events[evmtypes.TypeMsgEthereumTx] var isMsgEthereumTx bool
for _, event := range ev.Events {
if event.Type == evmtypes.TypeMsgEthereumTx {
isMsgEthereumTx = true
}
}
if !isMsgEthereumTx { if !isMsgEthereumTx {
// ignore transaction as it's not from the evm module // ignore transaction as it's not from the evm module

View File

@ -10,8 +10,7 @@ import (
tmjson "github.com/tendermint/tendermint/libs/json" tmjson "github.com/tendermint/tendermint/libs/json"
"github.com/tendermint/tendermint/libs/log" "github.com/tendermint/tendermint/libs/log"
tmquery "github.com/tendermint/tendermint/libs/pubsub/query" coretypes "github.com/tendermint/tendermint/rpc/coretypes"
coretypes "github.com/tendermint/tendermint/rpc/core/types"
rpcclient "github.com/tendermint/tendermint/rpc/jsonrpc/client" rpcclient "github.com/tendermint/tendermint/rpc/jsonrpc/client"
tmtypes "github.com/tendermint/tendermint/types" tmtypes "github.com/tendermint/tendermint/types"
@ -27,9 +26,9 @@ import (
) )
var ( var (
txEvents = tmtypes.QueryForEvent(tmtypes.EventTx).String() txEvents = tmtypes.QueryForEvent(tmtypes.EventTxValue).String()
evmEvents = tmquery.MustParse(fmt.Sprintf("%s='%s' AND %s.%s='%s'", tmtypes.EventTypeKey, tmtypes.EventTx, sdk.EventTypeMessage, sdk.AttributeKeyModule, evmtypes.ModuleName)).String() evmEvents = fmt.Sprintf("%s='%s' AND %s.%s='%s'", tmtypes.EventTypeKey, tmtypes.EventTx, sdk.EventTypeMessage, sdk.AttributeKeyModule, evmtypes.ModuleName)
headerEvents = tmtypes.QueryForEvent(tmtypes.EventNewBlockHeader).String() headerEvents = tmtypes.QueryForEvent(tmtypes.EventNewBlockHeaderValue).String()
) )
// EventSystem creates subscriptions, processes events and broadcasts them to the // EventSystem creates subscriptions, processes events and broadcasts them to the

View File

@ -7,7 +7,7 @@ import (
ethtypes "github.com/ethereum/go-ethereum/core/types" ethtypes "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/eth/filters" "github.com/ethereum/go-ethereum/eth/filters"
"github.com/ethereum/go-ethereum/rpc" "github.com/ethereum/go-ethereum/rpc"
coretypes "github.com/tendermint/tendermint/rpc/core/types" coretypes "github.com/tendermint/tendermint/rpc/coretypes"
) )
// Subscription defines a wrapper for the private subscription // Subscription defines a wrapper for the private subscription

View File

@ -124,7 +124,7 @@ func (api *API) SetEtherbase(etherbase common.Address) bool {
return false return false
} }
if err := tx.Sign(txFactory, keyInfo.GetName(), builder, false); err != nil { if err := tx.Sign(txFactory, keyInfo.Name, builder, false); err != nil {
api.logger.Debug("failed to sign tx", "error", err.Error()) api.logger.Debug("failed to sign tx", "error", err.Error())
return false return false
} }

View File

@ -102,7 +102,11 @@ func (api *PrivateAccountAPI) ListAccounts() ([]common.Address, error) {
} }
for _, info := range list { for _, info := range list {
addrs = append(addrs, common.BytesToAddress(info.GetPubKey().Address())) pubKey, err := info.GetPubKey()
if err != nil {
return nil, err
}
addrs = append(addrs, common.BytesToAddress(pubKey.Address()))
} }
return addrs, nil return addrs, nil
@ -131,7 +135,8 @@ func (api *PrivateAccountAPI) NewAccount(password string) (common.Address, error
return common.Address{}, err return common.Address{}, err
} }
addr := common.BytesToAddress(info.GetPubKey().Address().Bytes()) pubKeyAddr, err := info.GetAddress()
addr := common.BytesToAddress(pubKeyAddr.Bytes())
api.logger.Info("Your new key was generated", "address", addr.String()) api.logger.Info("Your new key was generated", "address", addr.String())
api.logger.Info("Please backup your key file!", "path", os.Getenv("HOME")+"/.ethermint/"+name) // TODO: pass the correct binary api.logger.Info("Please backup your key file!", "path", os.Getenv("HOME")+"/.ethermint/"+name) // TODO: pass the correct binary
api.logger.Info("Please remember your password!") api.logger.Info("Please remember your password!")

View File

@ -6,7 +6,7 @@ import (
"github.com/pkg/errors" "github.com/pkg/errors"
coretypes "github.com/tendermint/tendermint/rpc/core/types" coretypes "github.com/tendermint/tendermint/rpc/coretypes"
) )
type UnsubscribeFunc func() type UnsubscribeFunc func()

View File

@ -8,7 +8,7 @@ import (
"time" "time"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
coretypes "github.com/tendermint/tendermint/rpc/core/types" coretypes "github.com/tendermint/tendermint/rpc/coretypes"
) )
func TestAddTopic(t *testing.T) { func TestAddTopic(t *testing.T) {

View File

@ -242,7 +242,7 @@ func BaseFeeFromEvents(events []abci.Event) *big.Int {
} }
for _, attr := range event.Attributes { for _, attr := range event.Attributes {
if bytes.Equal(attr.Key, []byte(feemarkettypes.AttributeKeyBaseFee)) { if attr.Key == feemarkettypes.AttributeKeyBaseFee {
result, success := new(big.Int).SetString(string(attr.Value), 10) result, success := new(big.Int).SetString(string(attr.Value), 10)
if success { if success {
return result return result
@ -250,6 +250,14 @@ func BaseFeeFromEvents(events []abci.Event) *big.Int {
return nil return nil
} }
// if bytes.Equal(attr.Key, []byte(feemarkettypes.AttributeKeyBaseFee)) {
// result, success := new(big.Int).SetString(string(attr.Value), 10)
// if success {
// return result
// }
// return nil
// }
} }
} }
return nil return nil
@ -310,10 +318,10 @@ func FindTxAttributesByIndex(events []abci.Event, txIndex uint64) int {
// FindAttribute find event attribute with specified key, if not found returns nil. // FindAttribute find event attribute with specified key, if not found returns nil.
func FindAttribute(attrs []abci.EventAttribute, key []byte) []byte { func FindAttribute(attrs []abci.EventAttribute, key []byte) []byte {
for _, attr := range attrs { for _, attr := range attrs {
if !bytes.Equal(attr.Key, key) { if !bytes.Equal([]byte(attr.Key), key) {
continue continue
} }
return attr.Value return []byte(attr.Value)
} }
return nil return nil
} }

View File

@ -16,36 +16,43 @@ import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
tmservice "github.com/tendermint/tendermint/libs/service"
"google.golang.org/grpc" "google.golang.org/grpc"
abciserver "github.com/tendermint/tendermint/abci/server"
tcmd "github.com/tendermint/tendermint/cmd/tendermint/commands"
tmos "github.com/tendermint/tendermint/libs/os"
"github.com/tendermint/tendermint/node"
"github.com/tendermint/tendermint/p2p"
pvm "github.com/tendermint/tendermint/privval"
"github.com/tendermint/tendermint/proxy"
"github.com/tendermint/tendermint/rpc/client/local"
dbm "github.com/tendermint/tm-db"
"github.com/cosmos/cosmos-sdk/server/rosetta"
crgserver "github.com/cosmos/cosmos-sdk/server/rosetta/lib/server"
"github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/client/flags"
dbm "github.com/cosmos/cosmos-sdk/db"
"github.com/cosmos/cosmos-sdk/server" "github.com/cosmos/cosmos-sdk/server"
"github.com/cosmos/cosmos-sdk/server/api" "github.com/cosmos/cosmos-sdk/server/api"
serverconfig "github.com/cosmos/cosmos-sdk/server/config" serverconfig "github.com/cosmos/cosmos-sdk/server/config"
servergrpc "github.com/cosmos/cosmos-sdk/server/grpc" servergrpc "github.com/cosmos/cosmos-sdk/server/grpc"
"github.com/cosmos/cosmos-sdk/server/rosetta"
crgserver "github.com/cosmos/cosmos-sdk/server/rosetta/lib/server"
"github.com/cosmos/cosmos-sdk/server/types" "github.com/cosmos/cosmos-sdk/server/types"
storetypes "github.com/cosmos/cosmos-sdk/store/types" storetypes "github.com/cosmos/cosmos-sdk/store/types"
sdk "github.com/cosmos/cosmos-sdk/types" abciclient "github.com/tendermint/tendermint/abci/client"
abciserver "github.com/tendermint/tendermint/abci/server"
tcmd "github.com/tendermint/tendermint/cmd/tendermint/commands"
tmos "github.com/tendermint/tendermint/libs/os"
"github.com/tendermint/tendermint/node"
"github.com/tendermint/tendermint/rpc/client/local"
tmtypes "github.com/tendermint/tendermint/types"
ethdebug "github.com/tharsis/ethermint/rpc/ethereum/namespaces/debug" ethdebug "github.com/tharsis/ethermint/rpc/ethereum/namespaces/debug"
"github.com/tharsis/ethermint/server/config" "github.com/tharsis/ethermint/server/config"
srvflags "github.com/tharsis/ethermint/server/flags" srvflags "github.com/tharsis/ethermint/server/flags"
) )
const (
// gRPC-related flags
flagGRPCOnly = "grpc-only"
flagGRPCEnable = "grpc.enable"
flagGRPCAddress = "grpc.address"
flagGRPCWebEnable = "grpc-web.enable"
flagGRPCWebAddress = "grpc-web.address"
)
// StartCmd runs the service passed in, either stand-alone or in-process with // StartCmd runs the service passed in, either stand-alone or in-process with
// Tendermint. // Tendermint.
func StartCmd(appCreator types.AppCreator, defaultNodeHome string) *cobra.Command { func StartCmd(appCreator types.AppCreator, defaultNodeHome string) *cobra.Command {
@ -139,7 +146,7 @@ which accepts a path for the resulting pprof file.
cmd.Flags().Bool(server.FlagTrace, false, "Provide full stack traces for errors in ABCI Log") cmd.Flags().Bool(server.FlagTrace, false, "Provide full stack traces for errors in ABCI Log")
cmd.Flags().String(server.FlagPruning, storetypes.PruningOptionDefault, "Pruning strategy (default|nothing|everything|custom)") cmd.Flags().String(server.FlagPruning, storetypes.PruningOptionDefault, "Pruning strategy (default|nothing|everything|custom)")
cmd.Flags().Uint64(server.FlagPruningKeepRecent, 0, "Number of recent heights to keep on disk (ignored if pruning is not 'custom')") cmd.Flags().Uint64(server.FlagPruningKeepRecent, 0, "Number of recent heights to keep on disk (ignored if pruning is not 'custom')")
cmd.Flags().Uint64(server.FlagPruningKeepEvery, 0, "Offset heights to keep on disk after 'keep-every' (ignored if pruning is not 'custom')") // cmd.Flags().Uint64(server.FlagPruningKeepEvery, 0, "Offset heights to keep on disk after 'keep-every' (ignored if pruning is not 'custom')")
cmd.Flags().Uint64(server.FlagPruningInterval, 0, "Height interval at which pruned heights are removed from disk (ignored if pruning is not 'custom')") cmd.Flags().Uint64(server.FlagPruningInterval, 0, "Height interval at which pruned heights are removed from disk (ignored if pruning is not 'custom')")
cmd.Flags().Uint(server.FlagInvCheckPeriod, 0, "Assert registered invariants every N blocks") cmd.Flags().Uint(server.FlagInvCheckPeriod, 0, "Assert registered invariants every N blocks")
cmd.Flags().Uint64(server.FlagMinRetainBlocks, 0, "Minimum block height offset during ABCI commit to prune Tendermint blocks") cmd.Flags().Uint64(server.FlagMinRetainBlocks, 0, "Minimum block height offset during ABCI commit to prune Tendermint blocks")
@ -184,10 +191,11 @@ func startStandAlone(ctx *server.Context, appCreator types.AppCreator) error {
transport := ctx.Viper.GetString(srvflags.Transport) transport := ctx.Viper.GetString(srvflags.Transport)
home := ctx.Viper.GetString(flags.FlagHome) home := ctx.Viper.GetString(flags.FlagHome)
db, err := openDB(home) db, err := openDB(home, server.GetAppDBBackend((ctx.Viper)))
if err != nil { if err != nil {
return err return err
} }
defer func() { defer func() {
if err := db.Close(); err != nil { if err := db.Close(); err != nil {
ctx.Logger.With("error", err).Error("error closing db") ctx.Logger.With("error", err).Error("error closing db")
@ -259,9 +267,8 @@ func startInProcess(ctx *server.Context, clientCtx client.Context, appCreator ty
} }
traceWriterFile := ctx.Viper.GetString(srvflags.TraceStore) traceWriterFile := ctx.Viper.GetString(srvflags.TraceStore)
db, err := openDB(home) db, err := openDB(home, server.GetAppDBBackend(ctx.Viper))
if err != nil { if err != nil {
logger.Error("failed to open DB", "error", err.Error())
return err return err
} }
defer func() { defer func() {
@ -292,38 +299,46 @@ func startInProcess(ctx *server.Context, clientCtx client.Context, appCreator ty
app := appCreator(ctx.Logger, db, traceWriter, ctx.Viper) app := appCreator(ctx.Logger, db, traceWriter, ctx.Viper)
nodeKey, err := p2p.LoadOrGenNodeKey(cfg.NodeKeyFile()) genDoc, err := tmtypes.GenesisDocFromFile(cfg.GenesisFile())
if err != nil { if err != nil {
logger.Error("failed load or gen node key", "error", err.Error())
return err return err
} }
genDocProvider := node.DefaultGenesisDocProviderFunc(cfg) var (
tmNode, err := node.NewNode( tmNode tmservice.Service
cfg, gRPCOnly = ctx.Viper.GetBool(flagGRPCOnly)
pvm.LoadOrGenFilePV(cfg.PrivValidatorKeyFile(), cfg.PrivValidatorStateFile()),
nodeKey,
proxy.NewLocalClientCreator(app),
genDocProvider,
node.DefaultDBProvider,
node.DefaultMetricsProvider(cfg.Instrumentation),
ctx.Logger.With("server", "node"),
) )
if err != nil { if gRPCOnly {
logger.Error("failed init node", "error", err.Error()) ctx.Logger.Info("starting node in gRPC only mode; Tendermint is disabled")
return err config.GRPC.Enable = true
} } else {
ctx.Logger.Info("starting node with ABCI Tendermint in-process")
if err := tmNode.Start(); err != nil { tmNode, err = node.New(cfg, ctx.Logger, abciclient.NewLocalCreator(app), genDoc)
logger.Error("failed start tendermint server", "error", err.Error()) if err != nil {
return err return err
}
if err := tmNode.Start(); err != nil {
return err
}
} }
// Add the tx service to the gRPC router. We only need to register this // Add the tx service to the gRPC router. We only need to register this
// service if API or gRPC or JSONRPC is enabled, and avoid doing so in the general // service if API or gRPC or JSONRPC is enabled, and avoid doing so in the general
// case, because it spawns a new local tendermint RPC client. // case, because it spawns a new local tendermint RPC client.
if config.API.Enable || config.GRPC.Enable || config.JSONRPC.Enable { if config.API.Enable || config.GRPC.Enable || config.JSONRPC.Enable {
clientCtx = clientCtx.WithClient(local.New(tmNode)) node, ok := tmNode.(local.NodeService)
if !ok {
return fmt.Errorf("unable to set node type; please try re-installing the binary")
}
localNode, err := local.New(node)
if err != nil {
return err
}
clientCtx = clientCtx.WithClient(localNode)
app.RegisterTxService(clientCtx) app.RegisterTxService(clientCtx)
app.RegisterTendermintService(clientCtx) app.RegisterTendermintService(clientCtx)
@ -331,7 +346,7 @@ func startInProcess(ctx *server.Context, clientCtx client.Context, appCreator ty
var apiSrv *api.Server var apiSrv *api.Server
if config.API.Enable { if config.API.Enable {
genDoc, err := genDocProvider() genDoc, err := tmtypes.GenesisDocFromFile(cfg.GenesisFile())
if err != nil { if err != nil {
return err return err
} }
@ -417,7 +432,7 @@ func startInProcess(ctx *server.Context, clientCtx client.Context, appCreator ty
) )
if config.JSONRPC.Enable { if config.JSONRPC.Enable {
genDoc, err := genDocProvider() genDoc, err := tmtypes.GenesisDocFromFile(cfg.GenesisFile())
if err != nil { if err != nil {
return err return err
} }
@ -476,9 +491,9 @@ func startInProcess(ctx *server.Context, clientCtx client.Context, appCreator ty
return server.WaitForQuitSignals() return server.WaitForQuitSignals()
} }
func openDB(rootDir string) (dbm.DB, error) { func openDB(rootDir string, backendType dbm.BackendType) (dbm.DBConnection, error) {
dataDir := filepath.Join(rootDir, "data") dataDir := filepath.Join(rootDir, "data")
return sdk.NewLevelDB("application", dataDir) return dbm.NewDB("application", backendType, dataDir)
} }
func openTraceWriter(traceWriterFile string) (w io.Writer, err error) { func openTraceWriter(traceWriterFile string) (w io.Writer, err error) {

View File

@ -2,7 +2,6 @@ package server
import ( import (
"net/http" "net/http"
"time"
"github.com/gorilla/mux" "github.com/gorilla/mux"
"github.com/improbable-eng/grpc-web/go/grpcweb" "github.com/improbable-eng/grpc-web/go/grpcweb"
@ -43,31 +42,31 @@ func AddCommands(rootCmd *cobra.Command, defaultNodeHome string, appCreator type
} }
func ConnectTmWS(tmRPCAddr, tmEndpoint string, logger tmlog.Logger) *rpcclient.WSClient { func ConnectTmWS(tmRPCAddr, tmEndpoint string, logger tmlog.Logger) *rpcclient.WSClient {
tmWsClient, err := rpcclient.NewWS(tmRPCAddr, tmEndpoint, // tmWsClient, err := rpcclient.NewWS(tmRPCAddr, tmEndpoint,
rpcclient.MaxReconnectAttempts(256), // rpcclient.MaxReconnectAttempts(256),
rpcclient.ReadWait(120*time.Second), // rpcclient.ReadWait(120*time.Second),
rpcclient.WriteWait(120*time.Second), // rpcclient.WriteWait(120*time.Second),
rpcclient.PingPeriod(50*time.Second), // rpcclient.PingPeriod(50*time.Second),
rpcclient.OnReconnect(func() { // rpcclient.OnReconnect(func() {
logger.Debug("EVM RPC reconnects to Tendermint WS", "address", tmRPCAddr+tmEndpoint) // logger.Debug("EVM RPC reconnects to Tendermint WS", "address", tmRPCAddr+tmEndpoint)
}), // }),
) // )
if err != nil { // if err != nil {
logger.Error( // logger.Error(
"Tendermint WS client could not be created", // "Tendermint WS client could not be created",
"address", tmRPCAddr+tmEndpoint, // "address", tmRPCAddr+tmEndpoint,
"error", err, // "error", err,
) // )
} else if err := tmWsClient.OnStart(); err != nil { // } else if err := tmWsClient.OnStart(); err != nil {
logger.Error( // logger.Error(
"Tendermint WS client could not start", // "Tendermint WS client could not start",
"address", tmRPCAddr+tmEndpoint, // "address", tmRPCAddr+tmEndpoint,
"error", err, // "error", err,
) // )
} // }
return tmWsClient return nil
} }
func MountGRPCWebServices( func MountGRPCWebServices(

View File

@ -6,6 +6,7 @@ import (
"encoding/json" "encoding/json"
"errors" "errors"
"fmt" "fmt"
"math/rand"
"net/http" "net/http"
"net/url" "net/url"
"os" "os"
@ -17,14 +18,10 @@ import (
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/ethclient" "github.com/ethereum/go-ethereum/ethclient"
"github.com/rs/zerolog"
"github.com/spf13/cobra" "github.com/spf13/cobra"
tmcfg "github.com/tendermint/tendermint/config" "github.com/tendermint/tendermint/libs/service"
tmflags "github.com/tendermint/tendermint/libs/cli/flags"
"github.com/tendermint/tendermint/libs/log"
tmrand "github.com/tendermint/tendermint/libs/rand"
"github.com/tendermint/tendermint/node"
tmclient "github.com/tendermint/tendermint/rpc/client" tmclient "github.com/tendermint/tendermint/rpc/client"
dbm "github.com/tendermint/tm-db"
"google.golang.org/grpc" "google.golang.org/grpc"
"github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/baseapp"
@ -34,6 +31,7 @@ import (
codectypes "github.com/cosmos/cosmos-sdk/codec/types" codectypes "github.com/cosmos/cosmos-sdk/codec/types"
"github.com/cosmos/cosmos-sdk/crypto/keyring" "github.com/cosmos/cosmos-sdk/crypto/keyring"
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
"github.com/cosmos/cosmos-sdk/db/memdb"
"github.com/cosmos/cosmos-sdk/server" "github.com/cosmos/cosmos-sdk/server"
"github.com/cosmos/cosmos-sdk/server/api" "github.com/cosmos/cosmos-sdk/server/api"
srvconfig "github.com/cosmos/cosmos-sdk/server/config" srvconfig "github.com/cosmos/cosmos-sdk/server/config"
@ -67,8 +65,8 @@ type AppConstructor = func(val Validator) servertypes.Application
// NewAppConstructor returns a new simapp AppConstructor // NewAppConstructor returns a new simapp AppConstructor
func NewAppConstructor(encodingCfg params.EncodingConfig) AppConstructor { func NewAppConstructor(encodingCfg params.EncodingConfig) AppConstructor {
return func(val Validator) servertypes.Application { return func(val Validator) servertypes.Application {
return app.NewEthermintApp( return simapp.NewSimApp(
val.Ctx.Logger, dbm.NewMemDB(), nil, true, make(map[int64]bool), val.Ctx.Config.RootDir, 0, val.Ctx.Logger, memdb.NewDB(), nil, true, make(map[int64]bool), val.Ctx.Config.RootDir, 0,
encodingCfg, encodingCfg,
simapp.EmptyAppOptions{}, simapp.EmptyAppOptions{},
baseapp.SetPruning(storetypes.NewPruningOptionsFromString(val.AppConfig.Pruning)), baseapp.SetPruning(storetypes.NewPruningOptionsFromString(val.AppConfig.Pruning)),
@ -113,15 +111,15 @@ func DefaultConfig() Config {
encCfg := encoding.MakeConfig(app.ModuleBasics) encCfg := encoding.MakeConfig(app.ModuleBasics)
return Config{ return Config{
Codec: encCfg.Marshaler, Codec: encCfg.Codec,
TxConfig: encCfg.TxConfig, TxConfig: encCfg.TxConfig,
LegacyAmino: encCfg.Amino, LegacyAmino: encCfg.Amino,
InterfaceRegistry: encCfg.InterfaceRegistry, InterfaceRegistry: encCfg.InterfaceRegistry,
AccountRetriever: authtypes.AccountRetriever{}, AccountRetriever: authtypes.AccountRetriever{},
AppConstructor: NewAppConstructor(encCfg), AppConstructor: NewAppConstructor(encCfg),
GenesisState: app.ModuleBasics.DefaultGenesis(encCfg.Marshaler), GenesisState: simapp.ModuleBasics.DefaultGenesis(encCfg.Codec),
TimeoutCommit: 2 * time.Second, TimeoutCommit: 2 * time.Second,
ChainID: fmt.Sprintf("ethermint_%d-1", tmrand.Int63n(9999999999999)+1), ChainID: fmt.Sprintf("ethermint_%d-1", rand.Int63n(9999999999999)+1),
NumValidators: 4, NumValidators: 4,
BondDenom: ethermint.AttoPhoton, BondDenom: ethermint.AttoPhoton,
MinGasPrices: fmt.Sprintf("0.000006%s", ethermint.AttoPhoton), MinGasPrices: fmt.Sprintf("0.000006%s", ethermint.AttoPhoton),
@ -174,7 +172,7 @@ type (
RPCClient tmclient.Client RPCClient tmclient.Client
JSONRPCClient *ethclient.Client JSONRPCClient *ethclient.Client
tmNode *node.Node tmNode service.Service
api *api.Server api *api.Server
grpc *grpc.Server grpc *grpc.Server
grpcWeb *http.Server grpcWeb *http.Server
@ -322,12 +320,13 @@ func New(l Logger, baseDir string, cfg Config) (*Network, error) {
appCfg.JSONRPC.API = config.GetAPINamespaces() appCfg.JSONRPC.API = config.GetAPINamespaces()
} }
logger := log.NewNopLogger() logger := server.ZeroLogWrapper{Logger: zerolog.Nop()}
if cfg.EnableTMLogging { if cfg.EnableTMLogging {
logger = log.NewTMLogger(log.NewSyncWriter(os.Stdout)) logWriter := zerolog.ConsoleWriter{Out: os.Stderr}
logger, _ = tmflags.ParseLogLevel("info", logger, tmcfg.DefaultLogLevel) logger = server.ZeroLogWrapper{Logger: zerolog.New(logWriter).Level(zerolog.InfoLevel).With().Timestamp().Logger()}
} }
ctx.Logger = logger
ctx.Logger = logger ctx.Logger = logger
nodeDirName := fmt.Sprintf("node%d", i) nodeDirName := fmt.Sprintf("node%d", i)
@ -370,7 +369,7 @@ func New(l Logger, baseDir string, cfg Config) (*Network, error) {
nodeIDs[i] = nodeID nodeIDs[i] = nodeID
valPubKeys[i] = pubKey valPubKeys[i] = pubKey
kb, err := keyring.New(sdk.KeyringServiceName(), keyring.BackendTest, clientDir, buf, cfg.KeyringOptions...) kb, err := keyring.New(sdk.KeyringServiceName(), keyring.BackendTest, clientDir, buf, cfg.Codec, cfg.KeyringOptions...)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -629,20 +628,20 @@ func (n *Network) Cleanup() {
} }
} }
if v.jsonrpc != nil { // if v.jsonrpc != nil {
shutdownCtx, cancelFn := context.WithTimeout(context.Background(), 10*time.Second) // shutdownCtx, cancelFn := context.WithTimeout(context.Background(), 10*time.Second)
defer cancelFn() // defer cancelFn()
if err := v.jsonrpc.Shutdown(shutdownCtx); err != nil { // if err := v.jsonrpc.Shutdown(shutdownCtx); err != nil {
v.tmNode.Logger.Error("HTTP server shutdown produced a warning", "error", err.Error()) // v.tmNode.Logger.Error("HTTP server shutdown produced a warning", "error", err.Error())
} else { // } else {
v.tmNode.Logger.Info("HTTP server shut down, waiting 5 sec") // v.tmNode.Logger.Info("HTTP server shut down, waiting 5 sec")
select { // select {
case <-time.Tick(5 * time.Second): // case <-time.Tick(5 * time.Second):
case <-v.jsonrpcDone: // case <-v.jsonrpcDone:
} // }
} // }
} // }
} }
if n.Config.CleanupDir { if n.Config.CleanupDir {

View File

@ -3,18 +3,16 @@ package network
import ( import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"io/ioutil"
"path/filepath" "path/filepath"
"time" "time"
"github.com/ethereum/go-ethereum/ethclient" "github.com/ethereum/go-ethereum/ethclient"
abciclient "github.com/tendermint/tendermint/abci/client"
tmos "github.com/tendermint/tendermint/libs/os" tmos "github.com/tendermint/tendermint/libs/os"
"github.com/tendermint/tendermint/node" "github.com/tendermint/tendermint/node"
"github.com/tendermint/tendermint/p2p"
pvm "github.com/tendermint/tendermint/privval"
"github.com/tendermint/tendermint/proxy"
"github.com/tendermint/tendermint/rpc/client/local" "github.com/tendermint/tendermint/rpc/client/local"
"github.com/tendermint/tendermint/types" "github.com/tendermint/tendermint/types"
tmtime "github.com/tendermint/tendermint/types/time"
"github.com/cosmos/cosmos-sdk/server/api" "github.com/cosmos/cosmos-sdk/server/api"
servergrpc "github.com/cosmos/cosmos-sdk/server/grpc" servergrpc "github.com/cosmos/cosmos-sdk/server/grpc"
@ -25,6 +23,7 @@ import (
"github.com/cosmos/cosmos-sdk/x/genutil" "github.com/cosmos/cosmos-sdk/x/genutil"
genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types"
govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
v1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1"
mintypes "github.com/cosmos/cosmos-sdk/x/mint/types" mintypes "github.com/cosmos/cosmos-sdk/x/mint/types"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
@ -41,36 +40,35 @@ func startInProcess(cfg Config, val *Validator) error {
return err return err
} }
nodeKey, err := p2p.LoadOrGenNodeKey(tmCfg.NodeKeyFile()) app := cfg.AppConstructor(*val)
genDoc, err := types.GenesisDocFromFile(tmCfg.GenesisFile())
if err != nil { if err != nil {
return err return err
} }
app := cfg.AppConstructor(*val) val.tmNode, err = node.New(
genDocProvider := node.DefaultGenesisDocProviderFunc(tmCfg)
tmNode, err := node.NewNode(
tmCfg, tmCfg,
pvm.LoadOrGenFilePV(tmCfg.PrivValidatorKeyFile(), tmCfg.PrivValidatorStateFile()),
nodeKey,
proxy.NewLocalClientCreator(app),
genDocProvider,
node.DefaultDBProvider,
node.DefaultMetricsProvider(tmCfg.Instrumentation),
logger.With("module", val.Moniker), logger.With("module", val.Moniker),
abciclient.NewLocalCreator(app),
genDoc,
) )
if err != nil { if err != nil {
return err return err
} }
if err := tmNode.Start(); err != nil { if err := val.tmNode.Start(); err != nil {
return err return err
} }
val.tmNode = tmNode
if val.RPCAddress != "" { if val.RPCAddress != "" {
val.RPCClient = local.New(tmNode) node, ok := val.tmNode.(local.NodeService)
if !ok {
panic("can't cast service.Service to NodeService")
}
val.RPCClient, err = local.New(node)
if err != nil {
panic("cant create a local node")
}
} }
// We'll need a RPC client if the validator exposes a gRPC or REST endpoint. // We'll need a RPC client if the validator exposes a gRPC or REST endpoint.
@ -147,7 +145,8 @@ func startInProcess(cfg Config, val *Validator) error {
} }
func collectGenFiles(cfg Config, vals []*Validator, outputDir string) error { func collectGenFiles(cfg Config, vals []*Validator, outputDir string) error {
genTime := tmtime.Now() // genTime := tmtime.Now()
genTime := time.Now()
for i := 0; i < cfg.NumValidators; i++ { for i := 0; i < cfg.NumValidators; i++ {
tmCfg := vals[i].Ctx.Config tmCfg := vals[i].Ctx.Config
@ -205,7 +204,7 @@ func initGenFiles(cfg Config, genAccounts []authtypes.GenesisAccount, genBalance
stakingGenState.Params.BondDenom = cfg.BondDenom stakingGenState.Params.BondDenom = cfg.BondDenom
cfg.GenesisState[stakingtypes.ModuleName] = cfg.Codec.MustMarshalJSON(&stakingGenState) cfg.GenesisState[stakingtypes.ModuleName] = cfg.Codec.MustMarshalJSON(&stakingGenState)
var govGenState govtypes.GenesisState var govGenState v1.GenesisState
cfg.Codec.MustUnmarshalJSON(cfg.GenesisState[govtypes.ModuleName], &govGenState) cfg.Codec.MustUnmarshalJSON(cfg.GenesisState[govtypes.ModuleName], &govGenState)
govGenState.DepositParams.MinDeposit[0].Denom = cfg.BondDenom govGenState.DepositParams.MinDeposit[0].Denom = cfg.BondDenom
@ -251,12 +250,18 @@ func initGenFiles(cfg Config, genAccounts []authtypes.GenesisAccount, genBalance
} }
func WriteFile(name string, dir string, contents []byte) error { func WriteFile(name string, dir string, contents []byte) error {
file := filepath.Join(dir, name) writePath := filepath.Join(dir)
file := filepath.Join(writePath, name)
err := tmos.EnsureDir(dir, 0o755) err := tmos.EnsureDir(writePath, 0755)
if err != nil { if err != nil {
return err return err
} }
return tmos.WriteFile(file, contents, 0o644) err = ioutil.WriteFile(file, contents, 0644) // nolint: gosec
if err != nil {
return err
}
return nil
} }

6
types/address.go Normal file
View File

@ -0,0 +1,6 @@
package types
const (
// Bech32MainPrefix defines the main SDK Bech32 prefix of an account's address
Bech32MainPrefix = "ethm"
)

View File

@ -26,7 +26,7 @@ type infiniteGasMeterWithLimit struct {
} }
// NewInfiniteGasMeterWithLimit returns a reference to a new infiniteGasMeter. // NewInfiniteGasMeterWithLimit returns a reference to a new infiniteGasMeter.
func NewInfiniteGasMeterWithLimit(limit sdk.Gas) sdk.GasMeter { func NewInfiniteGasMeterWithLimit(limit sdk.Gas) *infiniteGasMeterWithLimit {
return &infiniteGasMeterWithLimit{ return &infiniteGasMeterWithLimit{
consumed: 0, consumed: 0,
limit: limit, limit: limit,

View File

@ -1,116 +1,98 @@
package rest package rest
import ( // clientrest "github.com/cosmos/cosmos-sdk/client/rest"
"context" // "github.com/cosmos/cosmos-sdk/types/rest"
"encoding/hex" // authrest "github.com/cosmos/cosmos-sdk/x/auth/client/rest"
"encoding/json"
"errors"
"math/big"
"net/http"
"strings"
"github.com/gorilla/mux" // // RegisterTxRoutes - Central function to define routes that get registered by the main application
// func RegisterTxRoutes(clientCtx client.Context, rtr *mux.Router) {
"github.com/cosmos/cosmos-sdk/client" // r := testutil.GetRequestWithHeaders(rtr)
clientrest "github.com/cosmos/cosmos-sdk/client/rest" // r.HandleFunc("/txs/{hash}", QueryTxRequestHandlerFn(clientCtx)).Methods("GET")
"github.com/cosmos/cosmos-sdk/types/rest" // r.HandleFunc("/txs", testutil.QueryTxsRequestHandlerFn(clientCtx)).Methods("GET")
authrest "github.com/cosmos/cosmos-sdk/x/auth/client/rest" // r.HandleFunc("/txs/decode", testutil.DecodeTxRequestHandlerFn(clientCtx)).Methods("POST")
// }
rpctypes "github.com/tharsis/ethermint/rpc/ethereum/types"
feemarkettypes "github.com/tharsis/ethermint/x/feemarket/types"
"github.com/ethereum/go-ethereum/common"
)
// RegisterTxRoutes - Central function to define routes that get registered by the main application
func RegisterTxRoutes(clientCtx client.Context, rtr *mux.Router) {
r := clientrest.WithHTTPDeprecationHeaders(rtr)
r.HandleFunc("/txs/{hash}", QueryTxRequestHandlerFn(clientCtx)).Methods("GET")
r.HandleFunc("/txs", authrest.QueryTxsRequestHandlerFn(clientCtx)).Methods("GET")
r.HandleFunc("/txs/decode", authrest.DecodeTxRequestHandlerFn(clientCtx)).Methods("POST")
}
// QueryTxRequestHandlerFn implements a REST handler that queries a transaction // QueryTxRequestHandlerFn implements a REST handler that queries a transaction
// by hash in a committed block. // by hash in a committed block.
func QueryTxRequestHandlerFn(clientCtx client.Context) http.HandlerFunc { // func QueryTxRequestHandlerFn(clientCtx client.Context) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) { // return func(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r) // vars := mux.Vars(r)
hashHexStr := vars["hash"] // hashHexStr := vars["hash"]
clientCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, clientCtx, r) // clientCtx, ok := testutil.ParseQueryHeightOrReturnBadRequest(w, clientCtx, r)
if !ok { // if !ok {
return // return
} // }
ethHashPrefix := "0x" // ethHashPrefix := "0x"
if !strings.HasPrefix(hashHexStr, ethHashPrefix) { // // if !strings.HasPrefix(hashHexStr, ethHashPrefix) {
authrest.QueryTxRequestHandlerFn(clientCtx) // // authrest.QueryTxRequestHandlerFn(clientCtx)
return // // return
} // // }
// eth Tx // // eth Tx
ethHashPrefixLength := len(ethHashPrefix) // ethHashPrefixLength := len(ethHashPrefix)
output, err := getEthTransactionByHash(clientCtx, hashHexStr[ethHashPrefixLength:]) // output, err := getEthTransactionByHash(clientCtx, hashHexStr[ethHashPrefixLength:])
if err != nil { // if err != nil {
rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) // rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
return // return
} // }
rest.PostProcessResponseBare(w, clientCtx, output) // rest.PostProcessResponseBare(w, clientCtx, output)
} // }
} // }
// GetTransactionByHash returns the transaction identified by hash. // // GetTransactionByHash returns the transaction identified by hash.
func getEthTransactionByHash(clientCtx client.Context, hashHex string) ([]byte, error) { // func getEthTransactionByHash(clientCtx client.Context, hashHex string) ([]byte, error) {
hash, err := hex.DecodeString(hashHex) // hash, err := hex.DecodeString(hashHex)
if err != nil { // if err != nil {
return nil, err // return nil, err
} // }
node, err := clientCtx.GetNode() // node, err := clientCtx.GetNode()
if err != nil { // if err != nil {
return nil, err // return nil, err
} // }
tx, err := node.Tx(context.Background(), hash, false) // tx, err := node.Tx(context.Background(), hash, false)
if err != nil { // if err != nil {
return nil, err // return nil, err
} // }
// Can either cache or just leave this out if not necessary // // Can either cache or just leave this out if not necessary
block, err := node.Block(context.Background(), &tx.Height) // block, err := node.Block(context.Background(), &tx.Height)
if err != nil { // if err != nil {
return nil, err // return nil, err
} // }
client := feemarkettypes.NewQueryClient(clientCtx) // client := feemarkettypes.NewQueryClient(clientCtx)
res, err := client.BaseFee(context.Background(), &feemarkettypes.QueryBaseFeeRequest{}) // res, err := client.BaseFee(context.Background(), &feemarkettypes.QueryBaseFeeRequest{})
if err != nil { // if err != nil {
return nil, err // return nil, err
} // }
var baseFee *big.Int // var baseFee *big.Int
if res.BaseFee != nil { // if res.BaseFee != nil {
baseFee = res.BaseFee.BigInt() // baseFee = res.BaseFee.BigInt()
} // }
blockHash := common.BytesToHash(block.Block.Header.Hash()) // blockHash := common.BytesToHash(block.Block.Header.Hash())
ethTxs, err := rpctypes.RawTxToEthTx(clientCtx, tx.Tx) // ethTxs, err := rpctypes.RawTxToEthTx(clientCtx, tx.Tx)
if err != nil { // if err != nil {
return nil, err // return nil, err
} // }
height := uint64(tx.Height) // height := uint64(tx.Height)
for _, ethTx := range ethTxs { // for _, ethTx := range ethTxs {
if common.HexToHash(ethTx.Hash) == common.BytesToHash(hash) { // if common.HexToHash(ethTx.Hash) == common.BytesToHash(hash) {
rpcTx, err := rpctypes.NewRPCTransaction(ethTx.AsTransaction(), blockHash, height, uint64(tx.Index), baseFee) // rpcTx, err := rpctypes.NewRPCTransaction(ethTx.AsTransaction(), blockHash, height, uint64(tx.Index), baseFee)
if err != nil { // if err != nil {
return nil, err // return nil, err
} // }
return json.Marshal(rpcTx) // return json.Marshal(rpcTx)
} // }
} // }
return nil, errors.New("eth tx not found") // return nil, errors.New("eth tx not found")
} // }

View File

@ -7,7 +7,8 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
sdk "github.com/cosmos/cosmos-sdk/types" sdk "github.com/cosmos/cosmos-sdk/types"
authante "github.com/cosmos/cosmos-sdk/x/auth/ante" // authante "github.com/cosmos/cosmos-sdk/x/auth/ante"
// authante "github.com/cosmos/cosmos-sdk/x/auth/ante"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
ethtypes "github.com/ethereum/go-ethereum/core/types" ethtypes "github.com/ethereum/go-ethereum/core/types"
@ -63,12 +64,12 @@ func DoBenchmark(b *testing.B, txBuilder TxBuilder) {
ctx, _ := suite.ctx.CacheContext() ctx, _ := suite.ctx.CacheContext()
// deduct fee first // deduct fee first
txData, err := types.UnpackTxData(msg.Data) // txData, err := types.UnpackTxData(msg.Data)
require.NoError(b, err) // require.NoError(b, err)
fees := sdk.Coins{sdk.NewCoin(suite.EvmDenom(), sdk.NewIntFromBigInt(txData.Fee()))} // fees := sdk.Coins{sdk.NewCoin(suite.EvmDenom(), sdk.NewIntFromBigInt(txData.Fee()))}
err = authante.DeductFees(suite.app.BankKeeper, suite.ctx, suite.app.AccountKeeper.GetAccount(ctx, msg.GetFrom()), fees) // err = authante.DeductFees(suite.app.BankKeeper, suite.ctx, suite.app.AccountKeeper.GetAccount(ctx, msg.GetFrom()), fees)
require.NoError(b, err) // require.NoError(b, err)
rsp, err := suite.app.EvmKeeper.EthereumTx(sdk.WrapSDKContext(ctx), msg) rsp, err := suite.app.EvmKeeper.EthereumTx(sdk.WrapSDKContext(ctx), msg)
require.NoError(b, err) require.NoError(b, err)

View File

@ -5,6 +5,7 @@ import (
"github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/store/prefix" "github.com/cosmos/cosmos-sdk/store/prefix"
storetypes "github.com/cosmos/cosmos-sdk/store/types"
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"
paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"
@ -29,10 +30,10 @@ type Keeper struct {
// - storing account's Code // - storing account's Code
// - storing transaction Logs // - storing transaction Logs
// - storing Bloom filters by block height. Needed for the Web3 API. // - storing Bloom filters by block height. Needed for the Web3 API.
storeKey sdk.StoreKey storeKey storetypes.StoreKey
// key to access the transient store, which is reset on every block during Commit // key to access the transient store, which is reset on every block during Commit
transientKey sdk.StoreKey transientKey storetypes.StoreKey
// module specific parameter space that can be configured through governance // module specific parameter space that can be configured through governance
paramSpace paramtypes.Subspace paramSpace paramtypes.Subspace
@ -58,7 +59,7 @@ type Keeper struct {
// NewKeeper generates new evm module keeper // NewKeeper generates new evm module keeper
func NewKeeper( func NewKeeper(
cdc codec.BinaryCodec, cdc codec.BinaryCodec,
storeKey, transientKey sdk.StoreKey, paramSpace paramtypes.Subspace, storeKey, transientKey storetypes.StoreKey, paramSpace paramtypes.Subspace,
ak types.AccountKeeper, bankKeeper types.BankKeeper, sk types.StakingKeeper, ak types.AccountKeeper, bankKeeper types.BankKeeper, sk types.StakingKeeper,
fmk types.FeeMarketKeeper, fmk types.FeeMarketKeeper,
tracer string, tracer string,

View File

@ -183,7 +183,7 @@ func (suite *KeeperTestSuite) DoSetupTest(t require.TestingT) {
encodingConfig := encoding.MakeConfig(app.ModuleBasics) encodingConfig := encoding.MakeConfig(app.ModuleBasics)
suite.clientCtx = client.Context{}.WithTxConfig(encodingConfig.TxConfig) suite.clientCtx = client.Context{}.WithTxConfig(encodingConfig.TxConfig)
suite.ethSigner = ethtypes.LatestSignerForChainID(suite.app.EvmKeeper.ChainID()) suite.ethSigner = ethtypes.LatestSignerForChainID(suite.app.EvmKeeper.ChainID())
suite.appCodec = encodingConfig.Marshaler suite.appCodec = encodingConfig.Codec
} }
func (suite *KeeperTestSuite) SetupTest() { func (suite *KeeperTestSuite) SetupTest() {

View File

@ -5,7 +5,8 @@ import (
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"
evmtypes "github.com/tharsis/ethermint/x/evm/types" evmtypes "github.com/tharsis/ethermint/x/evm/types"
@ -24,10 +25,10 @@ func (k Keeper) DeductTxCostsFromUserBalance(
isContractCreation := txData.GetTo() == nil isContractCreation := txData.GetTo() == nil
// fetch sender account from signature // fetch sender account from signature
signerAcc, err := authante.GetSignerAcc(ctx, k.accountKeeper, msgEthTx.GetFrom()) // signerAcc, err := authante.GetSignerAcc(ctx, k.accountKeeper, msgEthTx.GetFrom())
if err != nil { // if err != nil {
return nil, sdkerrors.Wrapf(err, "account not found for sender %s", msgEthTx.From) // return nil, sdkerrors.Wrapf(err, "account not found for sender %s", msgEthTx.From)
} // }
gasLimit := txData.GetGas() gasLimit := txData.GetGas()
@ -73,14 +74,14 @@ func (k Keeper) DeductTxCostsFromUserBalance(
fees := sdk.Coins{sdk.NewCoin(denom, sdk.NewIntFromBigInt(feeAmt))} fees := sdk.Coins{sdk.NewCoin(denom, sdk.NewIntFromBigInt(feeAmt))}
// deduct the full gas cost from the user balance // // deduct the full gas cost from the user balance
if err := authante.DeductFees(k.bankKeeper, ctx, signerAcc, fees); err != nil { // if err := authante.DeductFees(k.bankKeeper, ctx, signerAcc, fees); err != nil {
return nil, sdkerrors.Wrapf( // return nil, sdkerrors.Wrapf(
err, // err,
"failed to deduct full gas cost %s from the user %s balance", // "failed to deduct full gas cost %s from the user %s balance",
fees, msgEthTx.From, // fees, msgEthTx.From,
) // )
} // }
return fees, nil return fees, nil
} }

View File

@ -10,7 +10,8 @@ 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/cosmos-sdk/x/auth/ante"
"github.com/cosmos/cosmos-sdk/x/auth/signing" "github.com/cosmos/cosmos-sdk/x/auth/signing"
authtx "github.com/cosmos/cosmos-sdk/x/auth/tx" authtx "github.com/cosmos/cosmos-sdk/x/auth/tx"
@ -22,9 +23,9 @@ import (
) )
var ( var (
_ sdk.Msg = &MsgEthereumTx{} _ sdk.Msg = &MsgEthereumTx{}
_ sdk.Tx = &MsgEthereumTx{} _ sdk.Tx = &MsgEthereumTx{}
_ ante.GasTx = &MsgEthereumTx{} // _ ante.GasTx = &MsgEthereumTx{}
_ codectypes.UnpackInterfacesMessage = MsgEthereumTx{} _ codectypes.UnpackInterfacesMessage = MsgEthereumTx{}
) )

View File

@ -6,6 +6,7 @@ import (
paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"
"github.com/tendermint/tendermint/libs/log" "github.com/tendermint/tendermint/libs/log"
storetypes "github.com/cosmos/cosmos-sdk/store/types"
"github.com/tharsis/ethermint/x/feemarket/types" "github.com/tharsis/ethermint/x/feemarket/types"
) )
@ -14,14 +15,14 @@ type Keeper struct {
// Protobuf codec // Protobuf codec
cdc codec.BinaryCodec cdc codec.BinaryCodec
// Store key required for the Fee Market Prefix KVStore. // Store key required for the Fee Market Prefix KVStore.
storeKey sdk.StoreKey storeKey storetypes.StoreKey
// module specific parameter space that can be configured through governance // module specific parameter space that can be configured through governance
paramSpace paramtypes.Subspace paramSpace paramtypes.Subspace
} }
// NewKeeper generates new fee market module keeper // NewKeeper generates new fee market module keeper
func NewKeeper( func NewKeeper(
cdc codec.BinaryCodec, storeKey sdk.StoreKey, paramSpace paramtypes.Subspace, cdc codec.BinaryCodec, storeKey storetypes.StoreKey, paramSpace paramtypes.Subspace,
) Keeper { ) Keeper {
// set KeyTable if it has not already been set // set KeyTable if it has not already been set
if !paramSpace.HasKeyTable() { if !paramSpace.HasKeyTable() {

View File

@ -113,7 +113,7 @@ func (suite *KeeperTestSuite) DoSetupTest(t require.TestingT) {
encodingConfig := encoding.MakeConfig(app.ModuleBasics) encodingConfig := encoding.MakeConfig(app.ModuleBasics)
suite.clientCtx = client.Context{}.WithTxConfig(encodingConfig.TxConfig) suite.clientCtx = client.Context{}.WithTxConfig(encodingConfig.TxConfig)
suite.ethSigner = ethtypes.LatestSignerForChainID(suite.app.EvmKeeper.ChainID()) suite.ethSigner = ethtypes.LatestSignerForChainID(suite.app.EvmKeeper.ChainID())
suite.appCodec = encodingConfig.Marshaler suite.appCodec = encodingConfig.Codec
} }
func (suite *KeeperTestSuite) SetupTest() { func (suite *KeeperTestSuite) SetupTest() {

View File

@ -5,6 +5,7 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types" sdk "github.com/cosmos/cosmos-sdk/types"
storetypes "github.com/cosmos/cosmos-sdk/store/types"
paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"
v09types "github.com/tharsis/ethermint/x/feemarket/migrations/v09/types" v09types "github.com/tharsis/ethermint/x/feemarket/migrations/v09/types"
"github.com/tharsis/ethermint/x/feemarket/types" "github.com/tharsis/ethermint/x/feemarket/types"
@ -15,7 +16,7 @@ var KeyPrefixBaseFeeV1 = []byte{2}
// MigrateStore migrates the BaseFee value from the store to the params for // MigrateStore migrates the BaseFee value from the store to the params for
// In-Place Store migration logic. // In-Place Store migration logic.
func MigrateStore(ctx sdk.Context, paramstore *paramtypes.Subspace, storeKey sdk.StoreKey) error { func MigrateStore(ctx sdk.Context, paramstore *paramtypes.Subspace, storeKey storetypes.StoreKey) error {
baseFee := types.DefaultParams().BaseFee baseFee := types.DefaultParams().BaseFee
store := ctx.KVStore(storeKey) store := ctx.KVStore(storeKey)