WIP: upgrade cosmos-sdk from 0.45 to SMT 0.46
This commit is contained in:
parent
4ddc8afd18
commit
a0e2858d4f
103
app/ante/ante.go
103
app/ante/ante.go
@ -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)
|
||||
}
|
@ -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
|
||||
}
|
@ -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
|
@ -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 := ðsecp256k1.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)
|
||||
}
|
||||
}
|
534
app/ante/eth.go
534
app/ante/eth.go
@ -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)
|
||||
}
|
@ -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, ðtypes.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,
|
||||
ðtypes.AccessList{},
|
||||
)
|
||||
tx2 := evmtypes.NewTxContract(
|
||||
suite.app.EvmKeeper.ChainID(),
|
||||
1,
|
||||
big.NewInt(10),
|
||||
1000,
|
||||
big.NewInt(150),
|
||||
big.NewInt(200),
|
||||
nil,
|
||||
nil,
|
||||
ðtypes.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)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
@ -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),
|
||||
)
|
||||
}
|
@ -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
|
||||
}
|
@ -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)
|
||||
}
|
@ -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)
|
||||
}
|
@ -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 }
|
225
app/app.go
225
app/app.go
@ -11,17 +11,12 @@ import (
|
||||
"github.com/rakyll/statik/fs"
|
||||
"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/client"
|
||||
"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/types"
|
||||
"github.com/cosmos/cosmos-sdk/db"
|
||||
"github.com/cosmos/cosmos-sdk/server/api"
|
||||
"github.com/cosmos/cosmos-sdk/server/config"
|
||||
servertypes "github.com/cosmos/cosmos-sdk/server/types"
|
||||
@ -32,6 +27,7 @@ import (
|
||||
"github.com/cosmos/cosmos-sdk/version"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth"
|
||||
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"
|
||||
authtx "github.com/cosmos/cosmos-sdk/x/auth/tx"
|
||||
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
|
||||
@ -62,8 +58,10 @@ import (
|
||||
"github.com/cosmos/cosmos-sdk/x/genutil"
|
||||
genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types"
|
||||
"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"
|
||||
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"
|
||||
mintkeeper "github.com/cosmos/cosmos-sdk/x/mint/keeper"
|
||||
minttypes "github.com/cosmos/cosmos-sdk/x/mint/types"
|
||||
@ -82,25 +80,31 @@ import (
|
||||
upgradeclient "github.com/cosmos/cosmos-sdk/x/upgrade/client"
|
||||
upgradekeeper "github.com/cosmos/cosmos-sdk/x/upgrade/keeper"
|
||||
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"
|
||||
ibctransferkeeper "github.com/cosmos/ibc-go/v3/modules/apps/transfer/keeper"
|
||||
ibctransfertypes "github.com/cosmos/ibc-go/v3/modules/apps/transfer/types"
|
||||
ibc "github.com/cosmos/ibc-go/v3/modules/core"
|
||||
ibcclient "github.com/cosmos/ibc-go/v3/modules/core/02-client"
|
||||
ibcclientclient "github.com/cosmos/ibc-go/v3/modules/core/02-client/client"
|
||||
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"
|
||||
// "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"
|
||||
// ibc "github.com/cosmos/ibc-go/v3/modules/core"
|
||||
// ibcclient "github.com/cosmos/ibc-go/v3/modules/core/02-client"
|
||||
// ibcclientclient "github.com/cosmos/ibc-go/v3/modules/core/02-client/client"
|
||||
// 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
|
||||
_ "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"
|
||||
ethermint "github.com/tharsis/ethermint/types"
|
||||
"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"
|
||||
evmtypes "github.com/tharsis/ethermint/x/evm/types"
|
||||
"github.com/tharsis/ethermint/x/feemarket"
|
||||
@ -139,18 +143,18 @@ var (
|
||||
mint.AppModuleBasic{},
|
||||
distr.AppModuleBasic{},
|
||||
gov.NewAppModuleBasic(
|
||||
paramsclient.ProposalHandler, distrclient.ProposalHandler, upgradeclient.ProposalHandler, upgradeclient.CancelProposalHandler,
|
||||
ibcclientclient.UpdateClientProposalHandler, ibcclientclient.UpgradeProposalHandler,
|
||||
[]govclient.ProposalHandler{paramsclient.ProposalHandler, distrclient.ProposalHandler, upgradeclient.LegacyProposalHandler, upgradeclient.LegacyCancelProposalHandler},
|
||||
// ibcclientclient.UpdateClientProposalHandler, ibcclientclient.UpgradeProposalHandler,
|
||||
),
|
||||
params.AppModuleBasic{},
|
||||
crisis.AppModuleBasic{},
|
||||
slashing.AppModuleBasic{},
|
||||
ibc.AppModuleBasic{},
|
||||
// ibc.AppModuleBasic{},
|
||||
authzmodule.AppModuleBasic{},
|
||||
feegrantmodule.AppModuleBasic{},
|
||||
upgrade.AppModuleBasic{},
|
||||
evidence.AppModuleBasic{},
|
||||
transfer.AppModuleBasic{},
|
||||
// transfer.AppModuleBasic{},
|
||||
vesting.AppModuleBasic{},
|
||||
// Ethermint modules
|
||||
evm.AppModuleBasic{},
|
||||
@ -165,8 +169,8 @@ var (
|
||||
stakingtypes.BondedPoolName: {authtypes.Burner, authtypes.Staking},
|
||||
stakingtypes.NotBondedPoolName: {authtypes.Burner, authtypes.Staking},
|
||||
govtypes.ModuleName: {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
|
||||
// ibctransfertypes.ModuleName: {authtypes.Minter, authtypes.Burner},
|
||||
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
|
||||
@ -189,13 +193,14 @@ type EthermintApp struct {
|
||||
cdc *codec.LegacyAmino
|
||||
appCodec codec.Codec
|
||||
interfaceRegistry types.InterfaceRegistry
|
||||
|
||||
invCheckPeriod uint
|
||||
msgSvcRouter *authmiddleware.MsgServiceRouter
|
||||
legacyRouter sdk.Router
|
||||
invCheckPeriod uint
|
||||
|
||||
// keys to access the substores
|
||||
keys map[string]*sdk.KVStoreKey
|
||||
tkeys map[string]*sdk.TransientStoreKey
|
||||
memKeys map[string]*sdk.MemoryStoreKey
|
||||
keys map[string]*storetypes.KVStoreKey
|
||||
tkeys map[string]*storetypes.TransientStoreKey
|
||||
memKeys map[string]*storetypes.MemoryStoreKey
|
||||
|
||||
// keepers
|
||||
AccountKeeper authkeeper.AccountKeeper
|
||||
@ -211,9 +216,9 @@ type EthermintApp struct {
|
||||
ParamsKeeper paramskeeper.Keeper
|
||||
FeeGrantKeeper feegrantkeeper.Keeper
|
||||
AuthzKeeper authzkeeper.Keeper
|
||||
IBCKeeper *ibckeeper.Keeper // IBC Keeper must be a pointer in the app, so we can SetRouter on it correctly
|
||||
EvidenceKeeper evidencekeeper.Keeper
|
||||
TransferKeeper ibctransferkeeper.Keeper
|
||||
// IBCKeeper *ibckeeper.Keeper // IBC Keeper must be a pointer in the app, so we can SetRouter on it correctly
|
||||
EvidenceKeeper evidencekeeper.Keeper
|
||||
// TransferKeeper ibctransferkeeper.Keeper
|
||||
|
||||
// make scoped keepers public for test purposes
|
||||
ScopedIBCKeeper capabilitykeeper.ScopedKeeper
|
||||
@ -236,7 +241,7 @@ type EthermintApp struct {
|
||||
// NewEthermintApp returns a reference to a new initialized Ethermint application.
|
||||
func NewEthermintApp(
|
||||
logger log.Logger,
|
||||
db dbm.DB,
|
||||
db db.DBConnection,
|
||||
traceStore io.Writer,
|
||||
loadLatest bool,
|
||||
skipUpgradeHeights map[int64]bool,
|
||||
@ -244,9 +249,9 @@ func NewEthermintApp(
|
||||
invCheckPeriod uint,
|
||||
encodingConfig simappparams.EncodingConfig,
|
||||
appOpts servertypes.AppOptions,
|
||||
baseAppOptions ...func(*baseapp.BaseApp),
|
||||
baseAppOptions ...baseapp.AppOption,
|
||||
) *EthermintApp {
|
||||
appCodec := encodingConfig.Marshaler
|
||||
appCodec := encodingConfig.Codec
|
||||
cdc := encodingConfig.Amino
|
||||
interfaceRegistry := encodingConfig.InterfaceRegistry
|
||||
|
||||
@ -255,7 +260,6 @@ func NewEthermintApp(
|
||||
appName,
|
||||
logger,
|
||||
db,
|
||||
encodingConfig.TxConfig.TxDecoder(),
|
||||
baseAppOptions...,
|
||||
)
|
||||
bApp.SetCommitMultiStoreTracer(traceStore)
|
||||
@ -270,7 +274,7 @@ func NewEthermintApp(
|
||||
evidencetypes.StoreKey, capabilitytypes.StoreKey,
|
||||
feegrant.StoreKey, authzkeeper.StoreKey,
|
||||
// ibc keys
|
||||
ibchost.StoreKey, ibctransfertypes.StoreKey,
|
||||
// ibchost.StoreKey, ibctransfertypes.StoreKey,
|
||||
// ethermint keys
|
||||
evmtypes.StoreKey, feemarkettypes.StoreKey,
|
||||
)
|
||||
@ -285,6 +289,8 @@ func NewEthermintApp(
|
||||
appCodec: appCodec,
|
||||
interfaceRegistry: interfaceRegistry,
|
||||
invCheckPeriod: invCheckPeriod,
|
||||
legacyRouter: authmiddleware.NewLegacyRouter(),
|
||||
msgSvcRouter: authmiddleware.NewMsgServiceRouter(interfaceRegistry),
|
||||
keys: keys,
|
||||
tkeys: tkeys,
|
||||
memKeys: memKeys,
|
||||
@ -293,13 +299,13 @@ func NewEthermintApp(
|
||||
// init params keeper and subspaces
|
||||
app.ParamsKeeper = initParamsKeeper(appCodec, cdc, keys[paramstypes.StoreKey], tkeys[paramstypes.TStoreKey])
|
||||
// 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
|
||||
app.CapabilityKeeper = capabilitykeeper.NewKeeper(appCodec, keys[capabilitytypes.StoreKey], memKeys[capabilitytypes.MemStoreKey])
|
||||
|
||||
scopedIBCKeeper := app.CapabilityKeeper.ScopeToModule(ibchost.ModuleName)
|
||||
scopedTransferKeeper := app.CapabilityKeeper.ScopeToModule(ibctransfertypes.ModuleName)
|
||||
// scopedIBCKeeper := app.CapabilityKeeper.ScopeToModule(ibchost.ModuleName)
|
||||
// scopedTransferKeeper := app.CapabilityKeeper.ScopeToModule(ibctransfertypes.ModuleName)
|
||||
|
||||
// Applications that wish to enforce statically created ScopedKeepers should call `Seal` after creating
|
||||
// their scoped modules in `NewApp` with `ScopeToModule`
|
||||
@ -307,7 +313,7 @@ func NewEthermintApp(
|
||||
|
||||
// use custom Ethermint account for contracts
|
||||
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(
|
||||
appCodec, keys[banktypes.StoreKey], app.AccountKeeper, app.GetSubspace(banktypes.ModuleName), app.BlockedAddrs(),
|
||||
@ -321,7 +327,7 @@ func NewEthermintApp(
|
||||
)
|
||||
app.DistrKeeper = distrkeeper.NewKeeper(
|
||||
appCodec, keys[distrtypes.StoreKey], app.GetSubspace(distrtypes.ModuleName), app.AccountKeeper, app.BankKeeper,
|
||||
&stakingKeeper, authtypes.FeeCollectorName, app.ModuleAccountAddrs(),
|
||||
&stakingKeeper, authtypes.FeeCollectorName,
|
||||
)
|
||||
app.SlashingKeeper = slashingkeeper.NewKeeper(
|
||||
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.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
|
||||
// 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()),
|
||||
)
|
||||
|
||||
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))
|
||||
|
||||
@ -353,22 +359,27 @@ func NewEthermintApp(
|
||||
tracer,
|
||||
)
|
||||
|
||||
// Create IBC Keeper
|
||||
app.IBCKeeper = ibckeeper.NewKeeper(
|
||||
appCodec, keys[ibchost.StoreKey], app.GetSubspace(ibchost.ModuleName), app.StakingKeeper, app.UpgradeKeeper, scopedIBCKeeper,
|
||||
)
|
||||
// // Create IBC Keeper
|
||||
// app.IBCKeeper = ibckeeper.NewKeeper(
|
||||
// appCodec, keys[ibchost.StoreKey], app.GetSubspace(ibchost.ModuleName), app.StakingKeeper, app.UpgradeKeeper, scopedIBCKeeper,
|
||||
// )
|
||||
|
||||
// register the proposal types
|
||||
govRouter := govtypes.NewRouter()
|
||||
govRouter.AddRoute(govtypes.RouterKey, govtypes.ProposalHandler).
|
||||
govRouter := govv1beta1.NewRouter()
|
||||
govRouter.AddRoute(govtypes.RouterKey, govv1beta1.ProposalHandler).
|
||||
AddRoute(paramproposal.RouterKey, params.NewParamChangeProposalHandler(app.ParamsKeeper)).
|
||||
AddRoute(distrtypes.RouterKey, distr.NewCommunityPoolSpendProposalHandler(app.DistrKeeper)).
|
||||
AddRoute(upgradetypes.RouterKey, upgrade.NewSoftwareUpgradeProposalHandler(app.UpgradeKeeper)).
|
||||
AddRoute(ibchost.RouterKey, ibcclient.NewClientProposalHandler(app.IBCKeeper.ClientKeeper))
|
||||
AddRoute(upgradetypes.RouterKey, upgrade.NewSoftwareUpgradeProposalHandler(app.UpgradeKeeper))
|
||||
|
||||
govConfig := govtypes.DefaultConfig()
|
||||
/*
|
||||
Example of setting gov params:
|
||||
govConfig.MaxMetadataLen = 10000
|
||||
*/
|
||||
|
||||
govKeeper := govkeeper.NewKeeper(
|
||||
appCodec, keys[govtypes.StoreKey], app.GetSubspace(govtypes.ModuleName), app.AccountKeeper, app.BankKeeper,
|
||||
&stakingKeeper, govRouter,
|
||||
&stakingKeeper, govRouter, app.msgSvcRouter, govConfig,
|
||||
)
|
||||
|
||||
app.GovKeeper = *govKeeper.SetHooks(
|
||||
@ -377,19 +388,19 @@ func NewEthermintApp(
|
||||
),
|
||||
)
|
||||
|
||||
// Create Transfer Keepers
|
||||
app.TransferKeeper = ibctransferkeeper.NewKeeper(
|
||||
appCodec, keys[ibctransfertypes.StoreKey], app.GetSubspace(ibctransfertypes.ModuleName),
|
||||
app.IBCKeeper.ChannelKeeper, app.IBCKeeper.ChannelKeeper, &app.IBCKeeper.PortKeeper,
|
||||
app.AccountKeeper, app.BankKeeper, scopedTransferKeeper,
|
||||
)
|
||||
transferModule := transfer.NewAppModule(app.TransferKeeper)
|
||||
transferIBCModule := transfer.NewIBCModule(app.TransferKeeper)
|
||||
// // Create Transfer Keepers
|
||||
// app.TransferKeeper = ibctransferkeeper.NewKeeper(
|
||||
// appCodec, keys[ibctransfertypes.StoreKey], app.GetSubspace(ibctransfertypes.ModuleName),
|
||||
// app.IBCKeeper.ChannelKeeper, app.IBCKeeper.ChannelKeeper, &app.IBCKeeper.PortKeeper,
|
||||
// app.AccountKeeper, app.BankKeeper, scopedTransferKeeper,
|
||||
// )
|
||||
// transferModule := transfer.NewAppModule(app.TransferKeeper)
|
||||
// transferIBCModule := transfer.NewIBCModule(app.TransferKeeper)
|
||||
|
||||
// Create static IBC router, add transfer route, then set and seal it
|
||||
ibcRouter := porttypes.NewRouter()
|
||||
ibcRouter.AddRoute(ibctransfertypes.ModuleName, transferIBCModule)
|
||||
app.IBCKeeper.SetRouter(ibcRouter)
|
||||
// ibcRouter := porttypes.NewRouter()
|
||||
// ibcRouter.AddRoute(ibctransfertypes.ModuleName, transferIBCModule)
|
||||
// app.IBCKeeper.SetRouter(ibcRouter)
|
||||
|
||||
// create evidence keeper with router
|
||||
evidenceKeeper := evidencekeeper.NewKeeper(
|
||||
@ -418,7 +429,7 @@ func NewEthermintApp(
|
||||
capability.NewAppModule(appCodec, *app.CapabilityKeeper),
|
||||
crisis.NewAppModule(&app.CrisisKeeper, skipGenesisInvariants),
|
||||
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),
|
||||
distr.NewAppModule(appCodec, app.DistrKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper),
|
||||
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),
|
||||
|
||||
// ibc modules
|
||||
ibc.NewAppModule(app.IBCKeeper),
|
||||
transferModule,
|
||||
// ibc.NewAppModule(app.IBCKeeper),
|
||||
// Ethermint app modules
|
||||
evm.NewAppModule(app.EvmKeeper, app.AccountKeeper),
|
||||
feemarket.NewAppModule(app.FeeMarketKeeper),
|
||||
@ -452,9 +462,7 @@ func NewEthermintApp(
|
||||
slashingtypes.ModuleName,
|
||||
evidencetypes.ModuleName,
|
||||
stakingtypes.ModuleName,
|
||||
ibchost.ModuleName,
|
||||
// no-op modules
|
||||
ibctransfertypes.ModuleName,
|
||||
authtypes.ModuleName,
|
||||
banktypes.ModuleName,
|
||||
govtypes.ModuleName,
|
||||
@ -474,8 +482,6 @@ func NewEthermintApp(
|
||||
evmtypes.ModuleName,
|
||||
feemarkettypes.ModuleName,
|
||||
// no-op modules
|
||||
ibchost.ModuleName,
|
||||
ibctransfertypes.ModuleName,
|
||||
capabilitytypes.ModuleName,
|
||||
authtypes.ModuleName,
|
||||
banktypes.ModuleName,
|
||||
@ -506,10 +512,8 @@ func NewEthermintApp(
|
||||
slashingtypes.ModuleName,
|
||||
govtypes.ModuleName,
|
||||
minttypes.ModuleName,
|
||||
ibchost.ModuleName,
|
||||
genutiltypes.ModuleName,
|
||||
evidencetypes.ModuleName,
|
||||
ibctransfertypes.ModuleName,
|
||||
authz.ModuleName,
|
||||
feegrant.ModuleName,
|
||||
paramstypes.ModuleName,
|
||||
@ -524,8 +528,8 @@ func NewEthermintApp(
|
||||
)
|
||||
|
||||
app.mm.RegisterInvariants(&app.CrisisKeeper)
|
||||
app.mm.RegisterRoutes(app.Router(), app.QueryRouter(), encodingConfig.Amino)
|
||||
app.configurator = module.NewConfigurator(app.appCodec, app.MsgServiceRouter(), app.GRPCQueryRouter())
|
||||
app.mm.RegisterRoutes(app.legacyRouter, app.QueryRouter(), encodingConfig.Amino)
|
||||
app.configurator = module.NewConfigurator(app.appCodec, app.msgSvcRouter, app.GRPCQueryRouter())
|
||||
app.mm.RegisterServices(app.configurator)
|
||||
|
||||
// add test gRPC service for testing gRPC queries in isolation
|
||||
@ -540,7 +544,7 @@ func NewEthermintApp(
|
||||
bank.NewAppModule(appCodec, app.BankKeeper, app.AccountKeeper),
|
||||
capability.NewAppModule(appCodec, *app.CapabilityKeeper),
|
||||
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),
|
||||
distr.NewAppModule(appCodec, app.DistrKeeper, 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),
|
||||
feegrantmodule.NewAppModule(appCodec, app.AccountKeeper, app.BankKeeper, app.FeeGrantKeeper, app.interfaceRegistry),
|
||||
authzmodule.NewAppModule(appCodec, app.AuthzKeeper, app.AccountKeeper, app.BankKeeper, app.interfaceRegistry),
|
||||
ibc.NewAppModule(app.IBCKeeper),
|
||||
transferModule,
|
||||
// ibc.NewAppModule(app.IBCKeeper),
|
||||
evm.NewAppModule(app.EvmKeeper, app.AccountKeeper),
|
||||
feemarket.NewAppModule(app.FeeMarketKeeper),
|
||||
)
|
||||
|
||||
app.sm.RegisterStoreDecoders()
|
||||
|
||||
// initialize stores
|
||||
app.MountKVStores(keys)
|
||||
app.MountTransientStores(tkeys)
|
||||
app.MountMemoryStores(memKeys)
|
||||
|
||||
// initialize BaseApp
|
||||
app.SetInitChainer(app.InitChainer)
|
||||
app.SetBeginBlocker(app.BeginBlocker)
|
||||
|
||||
// use Ethermint's custom AnteHandler
|
||||
|
||||
maxGasWanted := cast.ToUint64(appOpts.Get(srvflags.EVMMaxTxGasWanted))
|
||||
options := ante.HandlerOptions{
|
||||
AccountKeeper: app.AccountKeeper,
|
||||
BankKeeper: app.BankKeeper,
|
||||
EvmKeeper: app.EvmKeeper,
|
||||
FeegrantKeeper: app.FeeGrantKeeper,
|
||||
IBCKeeper: app.IBCKeeper,
|
||||
FeeMarketKeeper: app.FeeMarketKeeper,
|
||||
SignModeHandler: encodingConfig.TxConfig.SignModeHandler(),
|
||||
SigGasConsumer: ante.DefaultSigVerificationGasConsumer,
|
||||
MaxTxGasWanted: maxGasWanted,
|
||||
}
|
||||
// maxGasWanted := cast.ToUint64(appOpts.Get(srvflags.EVMMaxTxGasWanted))
|
||||
// options := ante.HandlerOptions{
|
||||
// AccountKeeper: app.AccountKeeper,
|
||||
// BankKeeper: app.BankKeeper,
|
||||
// EvmKeeper: app.EvmKeeper,
|
||||
// FeegrantKeeper: app.FeeGrantKeeper,
|
||||
// IBCKeeper: app.IBCKeeper,
|
||||
// FeeMarketKeeper: app.FeeMarketKeeper,
|
||||
// SignModeHandler: encodingConfig.TxConfig.SignModeHandler(),
|
||||
// SigGasConsumer: ante.DefaultSigVerificationGasConsumer,
|
||||
// MaxTxGasWanted: maxGasWanted,
|
||||
// }
|
||||
|
||||
if err := options.Validate(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
// if err := options.Validate(); err != nil {
|
||||
// panic(err)
|
||||
// }
|
||||
|
||||
app.SetAnteHandler(ante.NewAnteHandler(options))
|
||||
// app.SetAnteHandler(ante.NewAnteHandler(options))
|
||||
app.SetEndBlocker(app.EndBlocker)
|
||||
|
||||
if loadLatest {
|
||||
if err := app.LoadLatestVersion(); err != nil {
|
||||
tmos.Exit(err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
app.ScopedIBCKeeper = scopedIBCKeeper
|
||||
app.ScopedTransferKeeper = scopedTransferKeeper
|
||||
// app.ScopedIBCKeeper = scopedIBCKeeper
|
||||
// app.ScopedTransferKeeper = scopedTransferKeeper
|
||||
|
||||
return app
|
||||
}
|
||||
@ -624,7 +616,8 @@ func (app *EthermintApp) InitChainer(ctx sdk.Context, req abci.RequestInitChain)
|
||||
|
||||
// LoadHeight loads state at a particular height
|
||||
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.
|
||||
@ -672,21 +665,21 @@ func (app *EthermintApp) InterfaceRegistry() types.InterfaceRegistry {
|
||||
// GetKey returns the KVStoreKey for the provided store key.
|
||||
//
|
||||
// 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]
|
||||
}
|
||||
|
||||
// GetTKey returns the TransientStoreKey for the provided store key.
|
||||
//
|
||||
// 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]
|
||||
}
|
||||
|
||||
// GetMemKey returns the MemStoreKey for the provided mem key.
|
||||
//
|
||||
// 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]
|
||||
}
|
||||
|
||||
@ -707,9 +700,9 @@ func (app *EthermintApp) SimulationManager() *module.SimulationManager {
|
||||
// API server.
|
||||
func (app *EthermintApp) RegisterAPIRoutes(apiSvr *api.Server, apiConfig config.APIConfig) {
|
||||
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.
|
||||
authtx.RegisterGRPCGatewayRoutes(clientCtx, apiSvr.GRPCGatewayRouter)
|
||||
@ -757,7 +750,7 @@ func GetMaccPerms() map[string][]string {
|
||||
|
||||
// initParamsKeeper init params keeper and its subspaces
|
||||
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 := paramskeeper.NewKeeper(appCodec, legacyAmino, key, tkey)
|
||||
|
||||
@ -768,10 +761,10 @@ func initParamsKeeper(
|
||||
paramsKeeper.Subspace(minttypes.ModuleName)
|
||||
paramsKeeper.Subspace(distrtypes.ModuleName)
|
||||
paramsKeeper.Subspace(slashingtypes.ModuleName)
|
||||
paramsKeeper.Subspace(govtypes.ModuleName).WithKeyTable(govtypes.ParamKeyTable())
|
||||
paramsKeeper.Subspace(govtypes.ModuleName)
|
||||
paramsKeeper.Subspace(crisistypes.ModuleName)
|
||||
paramsKeeper.Subspace(ibctransfertypes.ModuleName)
|
||||
paramsKeeper.Subspace(ibchost.ModuleName)
|
||||
// paramsKeeper.Subspace(ibctransfertypes.ModuleName)
|
||||
// paramsKeeper.Subspace(ibchost.ModuleName)
|
||||
// ethermint subspaces
|
||||
paramsKeeper.Subspace(evmtypes.ModuleName)
|
||||
paramsKeeper.Subspace(feemarkettypes.ModuleName)
|
||||
|
@ -19,7 +19,7 @@ import (
|
||||
// NewDefaultGenesisState generates the default state for the application.
|
||||
func NewDefaultGenesisState() simapp.GenesisState {
|
||||
encCfg := encoding.MakeConfig(ModuleBasics)
|
||||
return ModuleBasics.DefaultGenesis(encCfg.Marshaler)
|
||||
return ModuleBasics.DefaultGenesis(encCfg.Codec)
|
||||
}
|
||||
|
||||
// ExportAppStateAndValidators exports the state of the application for a genesis
|
||||
|
@ -27,7 +27,8 @@ import (
|
||||
"github.com/cosmos/cosmos-sdk/x/simulation"
|
||||
slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/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"
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
"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[capabilitytypes.StoreKey], newApp.keys[capabilitytypes.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 {
|
||||
|
@ -7,17 +7,17 @@ import (
|
||||
"github.com/cosmos/cosmos-sdk/simapp"
|
||||
"github.com/tharsis/ethermint/encoding"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/db/memdb"
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
"github.com/tendermint/tendermint/libs/log"
|
||||
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
|
||||
tmtypes "github.com/tendermint/tendermint/types"
|
||||
dbm "github.com/tendermint/tm-db"
|
||||
)
|
||||
|
||||
// DefaultConsensusParams defines the default Tendermint consensus params used in
|
||||
// EthermintApp testing.
|
||||
var DefaultConsensusParams = &abci.ConsensusParams{
|
||||
Block: &abci.BlockParams{
|
||||
var DefaultConsensusParams = &tmproto.ConsensusParams{
|
||||
Block: &tmproto.BlockParams{
|
||||
MaxBytes: 200000,
|
||||
MaxGas: -1, // no limit
|
||||
},
|
||||
@ -35,8 +35,7 @@ var DefaultConsensusParams = &abci.ConsensusParams{
|
||||
|
||||
// Setup initializes a new EthermintApp. A Nop logger is set in EthermintApp.
|
||||
func Setup(isCheckTx bool, patchGenesis func(*EthermintApp, simapp.GenesisState) simapp.GenesisState) *EthermintApp {
|
||||
db := dbm.NewMemDB()
|
||||
app := NewEthermintApp(log.NewNopLogger(), db, nil, true, map[int64]bool{}, DefaultNodeHome, 5, encoding.MakeConfig(ModuleBasics), simapp.EmptyAppOptions{})
|
||||
app := NewEthermintApp(log.NewNopLogger(), memdb.NewDB(), nil, true, map[int64]bool{}, DefaultNodeHome, 5, encoding.MakeConfig(ModuleBasics), simapp.EmptyAppOptions{})
|
||||
if !isCheckTx {
|
||||
// init chain must be called to stop deliverState from being nil
|
||||
genesisState := NewDefaultGenesisState()
|
||||
|
@ -5,6 +5,7 @@ import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/client/flags"
|
||||
"github.com/cosmos/cosmos-sdk/client/input"
|
||||
"github.com/cosmos/cosmos-sdk/crypto"
|
||||
@ -30,12 +31,13 @@ func UnsafeExportEthKeyCommand() *cobra.Command {
|
||||
|
||||
keyringBackend, _ := cmd.Flags().GetString(flags.FlagKeyringBackend)
|
||||
rootDir, _ := cmd.Flags().GetString(flags.FlagHome)
|
||||
|
||||
clientCtx := client.GetClientContextFromCmd(cmd)
|
||||
kr, err := keyring.New(
|
||||
sdk.KeyringServiceName(),
|
||||
keyringBackend,
|
||||
rootDir,
|
||||
inBuf,
|
||||
clientCtx.Codec,
|
||||
hd.EthSecp256k1Option(),
|
||||
)
|
||||
if err != nil {
|
||||
|
@ -5,6 +5,7 @@ import (
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/client/flags"
|
||||
"github.com/cosmos/cosmos-sdk/client/input"
|
||||
"github.com/cosmos/cosmos-sdk/crypto"
|
||||
@ -31,12 +32,14 @@ func runImportCmd(cmd *cobra.Command, args []string) error {
|
||||
inBuf := bufio.NewReader(cmd.InOrStdin())
|
||||
keyringBackend, _ := cmd.Flags().GetString(flags.FlagKeyringBackend)
|
||||
rootDir, _ := cmd.Flags().GetString(flags.FlagHome)
|
||||
clientCtx := client.GetClientContextFromCmd(cmd)
|
||||
|
||||
kb, err := keyring.New(
|
||||
sdk.KeyringServiceName(),
|
||||
keyringBackend,
|
||||
rootDir,
|
||||
inBuf,
|
||||
clientCtx.Codec,
|
||||
hd.EthSecp256k1Option(),
|
||||
)
|
||||
if err != nil {
|
||||
|
@ -92,7 +92,7 @@ func runAddCmd(cmd *cobra.Command, args []string) error {
|
||||
|
||||
dryRun, _ := cmd.Flags().GetBool(flags.FlagDryRun)
|
||||
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)
|
||||
}
|
||||
|
||||
|
@ -122,7 +122,7 @@ func RunAddCmd(ctx client.Context, cmd *cobra.Command, args []string, inBuf *buf
|
||||
|
||||
if dryRun, _ := cmd.Flags().GetBool(flags.FlagDryRun); dryRun {
|
||||
// use in memory keybase
|
||||
kb = keyring.NewInMemory(etherminthd.EthSecp256k1Option())
|
||||
kb = keyring.NewInMemory(ctx.Codec, etherminthd.EthSecp256k1Option())
|
||||
} else {
|
||||
_, err = kb.Key(name)
|
||||
if err == nil {
|
||||
@ -156,7 +156,7 @@ func RunAddCmd(ctx client.Context, cmd *cobra.Command, args []string, inBuf *buf
|
||||
return err
|
||||
}
|
||||
|
||||
pks[i] = k.GetPubKey()
|
||||
pks[i], err = k.GetPubKey()
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
info, err := kb.SavePubKey(name, pk, algo.Name())
|
||||
info, err := kb.SaveOfflineKey(name, pk)
|
||||
if err != nil {
|
||||
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)
|
||||
}
|
||||
|
||||
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 {
|
||||
case OutputFormatText:
|
||||
cmd.PrintErrln()
|
||||
|
@ -3,7 +3,6 @@ package keys
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"path/filepath"
|
||||
|
||||
yaml "gopkg.in/yaml.v2"
|
||||
|
||||
@ -20,19 +19,19 @@ const (
|
||||
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
|
||||
// options can be applied when generating this new Keybase.
|
||||
func NewLegacyKeyBaseFromDir(rootDir string, opts ...cryptokeyring.KeybaseOption) (cryptokeyring.LegacyKeybase, error) {
|
||||
return getLegacyKeyBaseFromDir(rootDir, opts...)
|
||||
}
|
||||
// // NewLegacyKeyBaseFromDir initializes a legacy keybase at the rootDir directory. Keybase
|
||||
// // options can be applied when generating this new Keybase.
|
||||
// func NewLegacyKeyBaseFromDir(rootDir string, opts ...cryptokeyring.KeybaseOption) (cryptokeyring.LegacyKeybase, error) {
|
||||
// return getLegacyKeyBaseFromDir(rootDir, opts...)
|
||||
// }
|
||||
|
||||
func getLegacyKeyBaseFromDir(rootDir string, opts ...cryptokeyring.KeybaseOption) (cryptokeyring.LegacyKeybase, error) {
|
||||
return cryptokeyring.NewLegacy(defaultKeyDBName, filepath.Join(rootDir, "keys"), opts...)
|
||||
}
|
||||
// func getLegacyKeyBaseFromDir(rootDir string, opts ...cryptokeyring.KeybaseOption) (cryptokeyring.LegacyKeybase, error) {
|
||||
// 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)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
|
@ -6,17 +6,18 @@ import (
|
||||
"bufio"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"net"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
tmcfg "github.com/tendermint/tendermint/config"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
tmconfig "github.com/tendermint/tendermint/config"
|
||||
tmrand "github.com/tendermint/tendermint/libs/rand"
|
||||
"github.com/tendermint/tendermint/types"
|
||||
tmtime "github.com/tendermint/tendermint/types/time"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/client/flags"
|
||||
@ -34,6 +35,8 @@ import (
|
||||
"github.com/cosmos/cosmos-sdk/x/genutil"
|
||||
genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/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"
|
||||
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
|
||||
|
||||
@ -209,7 +212,7 @@ func initTestnetFiles(
|
||||
args initArgs,
|
||||
) error {
|
||||
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)
|
||||
@ -261,7 +264,7 @@ func initTestnetFiles(
|
||||
memo := fmt.Sprintf("%s@%s:26656", nodeIDs[i], ip)
|
||||
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 {
|
||||
return err
|
||||
}
|
||||
@ -343,7 +346,8 @@ func initTestnetFiles(
|
||||
|
||||
customAppTemplate, customAppConfig := config.AppConfig(ethermint.AttoPhoton)
|
||||
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
|
||||
}
|
||||
|
||||
@ -402,7 +406,7 @@ func initGenFiles(
|
||||
stakingGenState.Params.BondDenom = coinDenom
|
||||
appGenState[stakingtypes.ModuleName] = clientCtx.Codec.MustMarshalJSON(&stakingGenState)
|
||||
|
||||
var govGenState govtypes.GenesisState
|
||||
var govGenState v1.GenesisState
|
||||
clientCtx.Codec.MustUnmarshalJSON(appGenState[govtypes.ModuleName], &govGenState)
|
||||
|
||||
govGenState.DepositParams.MinDeposit[0].Denom = coinDenom
|
||||
@ -452,7 +456,8 @@ func collectGenFiles(
|
||||
outputDir, nodeDirPrefix, nodeDaemonHome string, genBalIterator banktypes.GenesisBalancesIterator,
|
||||
) error {
|
||||
var appState json.RawMessage
|
||||
genTime := tmtime.Now()
|
||||
// genTime := tmtime.Now()
|
||||
genTime := time.Now()
|
||||
|
||||
for i := 0; i < numValidators; i++ {
|
||||
nodeDirName := fmt.Sprintf("%s%d", nodeDirPrefix, i)
|
||||
|
@ -8,7 +8,7 @@ import (
|
||||
|
||||
const (
|
||||
// Bech32Prefix defines the Bech32 prefix used for EthAccounts
|
||||
Bech32Prefix = "ethm"
|
||||
Bech32Prefix = ethermint.Bech32MainPrefix
|
||||
|
||||
// Bech32PrefixAccAddr defines the Bech32 prefix of an account's address
|
||||
Bech32PrefixAccAddr = Bech32Prefix
|
||||
|
@ -63,6 +63,7 @@ contain valid denominations. Accounts may optionally be supplied with vesting pa
|
||||
keyringBackend,
|
||||
clientCtx.HomeDir,
|
||||
inBuf,
|
||||
clientCtx.Codec,
|
||||
hd.EthSecp256k1Option(),
|
||||
)
|
||||
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)
|
||||
}
|
||||
|
||||
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])
|
||||
|
@ -17,7 +17,7 @@ func main() {
|
||||
|
||||
rootCmd, _ := NewRootCmd()
|
||||
|
||||
if err := svrcmd.Execute(rootCmd, app.DefaultNodeHome); err != nil {
|
||||
if err := svrcmd.Execute(rootCmd, "", app.DefaultNodeHome); err != nil {
|
||||
switch e := err.(type) {
|
||||
case server.ErrorCode:
|
||||
os.Exit(e.Code)
|
||||
|
@ -6,18 +6,13 @@ import (
|
||||
"os"
|
||||
"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/client"
|
||||
"github.com/cosmos/cosmos-sdk/client/config"
|
||||
"github.com/cosmos/cosmos-sdk/client/flags"
|
||||
"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"
|
||||
servertypes "github.com/cosmos/cosmos-sdk/server/types"
|
||||
"github.com/cosmos/cosmos-sdk/simapp/params"
|
||||
@ -29,6 +24,11 @@ import (
|
||||
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/crisis"
|
||||
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"
|
||||
ethermintclient "github.com/tharsis/ethermint/client"
|
||||
@ -48,7 +48,7 @@ const EnvPrefix = "ETHERMINT"
|
||||
func NewRootCmd() (*cobra.Command, params.EncodingConfig) {
|
||||
encodingConfig := encoding.MakeConfig(app.ModuleBasics)
|
||||
initClientCtx := client.Context{}.
|
||||
WithCodec(encodingConfig.Marshaler).
|
||||
WithCodec(encodingConfig.Codec).
|
||||
WithInterfaceRegistry(encodingConfig.InterfaceRegistry).
|
||||
WithTxConfig(encodingConfig.TxConfig).
|
||||
WithLegacyAmino(encodingConfig.Amino).
|
||||
@ -83,8 +83,9 @@ func NewRootCmd() (*cobra.Command, params.EncodingConfig) {
|
||||
|
||||
// FIXME: replace AttoPhoton with bond denom
|
||||
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
|
||||
rootCmd.AddCommand(sdkserver.RosettaCommand(encodingConfig.InterfaceRegistry, encodingConfig.Marshaler))
|
||||
|
||||
rootCmd.AddCommand(sdkserver.RosettaCommand(encodingConfig.InterfaceRegistry, encodingConfig.Codec))
|
||||
return rootCmd, encodingConfig
|
||||
}
|
||||
|
||||
@ -135,6 +135,18 @@ func addModuleInitFlags(startCmd *cobra.Command) {
|
||||
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 {
|
||||
cmd := &cobra.Command{
|
||||
Use: "query",
|
||||
@ -190,7 +202,7 @@ type appCreator struct {
|
||||
}
|
||||
|
||||
// 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
|
||||
|
||||
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")
|
||||
snapshotDB, err := sdk.NewLevelDB("metadata", snapshotDir)
|
||||
snapshotDB, err := badgerdb.NewDB(filepath.Join(snapshotDir, "metadata"))
|
||||
if err != nil {
|
||||
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)
|
||||
// and exports state.
|
||||
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,
|
||||
) (servertypes.ExportedApp, error) {
|
||||
var ethermintApp *app.EthermintApp
|
||||
|
@ -1,7 +1,7 @@
|
||||
package encoding
|
||||
|
||||
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/simapp/params"
|
||||
"github.com/cosmos/cosmos-sdk/types/module"
|
||||
@ -12,14 +12,14 @@ import (
|
||||
|
||||
// MakeConfig creates an EncodingConfig for testing
|
||||
func MakeConfig(mb module.BasicManager) params.EncodingConfig {
|
||||
cdc := amino.NewLegacyAmino()
|
||||
cdc := codec.NewLegacyAmino()
|
||||
interfaceRegistry := types.NewInterfaceRegistry()
|
||||
marshaler := amino.NewProtoCodec(interfaceRegistry)
|
||||
codec := codec.NewProtoCodec(interfaceRegistry)
|
||||
|
||||
encodingConfig := params.EncodingConfig{
|
||||
InterfaceRegistry: interfaceRegistry,
|
||||
Marshaler: marshaler,
|
||||
TxConfig: tx.NewTxConfig(marshaler, tx.DefaultSignModes),
|
||||
Codec: codec,
|
||||
TxConfig: tx.NewTxConfig(codec, tx.DefaultSignModes),
|
||||
Amino: cdc,
|
||||
}
|
||||
|
||||
|
109
go.mod
109
go.mod
@ -5,9 +5,10 @@ go 1.17
|
||||
require (
|
||||
github.com/btcsuite/btcd v0.22.0-beta
|
||||
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/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/ethereum/go-ethereum v1.10.16
|
||||
github.com/gogo/protobuf v1.3.3
|
||||
@ -23,46 +24,54 @@ require (
|
||||
github.com/rakyll/statik v0.1.7
|
||||
github.com/regen-network/cosmos-proto v0.3.1
|
||||
github.com/rs/cors v1.8.2
|
||||
github.com/rs/zerolog v1.26.1
|
||||
github.com/spf13/cast v1.4.1
|
||||
github.com/spf13/cobra v1.4.0
|
||||
github.com/spf13/viper v1.10.1
|
||||
github.com/status-im/keycard-go v0.0.0-20200402102358-957c09536969
|
||||
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/tyler-smith/go-bip39 v1.1.0
|
||||
google.golang.org/genproto v0.0.0-20220211171837-173942840c17
|
||||
google.golang.org/grpc v1.44.0
|
||||
google.golang.org/genproto v0.0.0-20220222213610-43724f9ea8cf
|
||||
google.golang.org/grpc v1.45.0
|
||||
google.golang.org/protobuf v1.28.0
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
)
|
||||
|
||||
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/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/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/aws/aws-sdk-go v1.40.45 // 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/cenkalti/backoff/v4 v4.1.1 // indirect
|
||||
github.com/cespare/xxhash v1.1.0 // 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/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/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-go v0.9.2 // indirect
|
||||
github.com/danieljoos/wincred v1.0.2 // indirect
|
||||
github.com/deckarep/golang-set v1.8.0 // 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/ristretto v0.0.3 // indirect
|
||||
github.com/dgraph-io/badger/v2 v2.2007.4 // 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/dustin/go-humanize v1.0.0 // 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/fsnotify/fsnotify v1.5.1 // indirect
|
||||
github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff // indirect
|
||||
github.com/go-kit/kit v0.10.0 // indirect
|
||||
github.com/go-logfmt/logfmt v0.5.0 // indirect
|
||||
github.com/go-ole/go-ole v1.2.1 // indirect
|
||||
github.com/go-kit/kit v0.12.0 // indirect
|
||||
github.com/go-ole/go-ole v1.2.6 // indirect
|
||||
github.com/go-playground/validator/v10 v10.4.1 // indirect
|
||||
github.com/go-stack/stack v1.8.0 // 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/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/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/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/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/gtank/merlin v0.1.1 // indirect
|
||||
github.com/gtank/ristretto255 v0.1.2 // indirect
|
||||
github.com/hashicorp/go-cleanhttp v0.5.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-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/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/huin/goupnp v1.0.2 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.0.0 // 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/keybase/go-keychain v0.0.0-20190712205309-48d3d31d256d // indirect
|
||||
github.com/klauspost/compress v1.11.7 // indirect
|
||||
github.com/lib/pq v1.10.2 // indirect
|
||||
github.com/klauspost/compress v1.13.6 // 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/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-runewidth v0.0.9 // 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.1 // indirect
|
||||
github.com/minio/highwayhash v1.0.2 // 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/mtibben/percent v0.2.1 // 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/pelletier/go-toml v1.9.4 // indirect
|
||||
github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 // 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/common v0.29.0 // indirect
|
||||
github.com/prometheus/procfs v0.6.0 // indirect
|
||||
github.com/prometheus/common v0.33.0 // indirect
|
||||
github.com/prometheus/procfs v0.7.3 // indirect
|
||||
github.com/prometheus/tsdb v0.7.1 // indirect
|
||||
github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0 // 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/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/pflag v1.0.5 // 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/crypto v0.0.0-20191022145703-50d29ede1e15 // indirect
|
||||
github.com/tendermint/go-amino v0.16.0 // indirect
|
||||
github.com/tklauser/go-sysconf v0.3.5 // indirect
|
||||
github.com/tklauser/numcpus v0.2.2 // indirect
|
||||
github.com/zondax/hid v0.9.0 // indirect
|
||||
github.com/tklauser/go-sysconf v0.3.9 // indirect
|
||||
github.com/tklauser/numcpus v0.3.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.opencensus.io v0.23.0 // 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/sys v0.0.0-20211210111614-af8b64212486 // indirect
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 // indirect
|
||||
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 // indirect
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect
|
||||
golang.org/x/text v0.3.7 // indirect
|
||||
golang.org/x/tools v0.1.5 // indirect
|
||||
gopkg.in/ini.v1 v1.66.2 // indirect
|
||||
golang.org/x/tools v0.1.9 // 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/olebedev/go-duktape.v3 v3.0.0-20200619000410-60c24ae608a6 // indirect
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
|
||||
nhooyr.io/websocket v1.8.6 // indirect
|
||||
sigs.k8s.io/yaml v1.3.0 // indirect
|
||||
)
|
||||
|
||||
replace (
|
||||
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
|
||||
google.golang.org/grpc => google.golang.org/grpc v1.33.2
|
||||
google.golang.org/grpc => google.golang.org/grpc v1.44.0
|
||||
)
|
||||
|
@ -1,7 +1,6 @@
|
||||
package backend
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
@ -15,7 +14,8 @@ import (
|
||||
"github.com/ethereum/go-ethereum/accounts/keystore"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
"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/metadata"
|
||||
@ -334,8 +334,8 @@ func (e *EVMBackend) BlockBloom(height *int64) (ethtypes.Bloom, error) {
|
||||
}
|
||||
|
||||
for _, attr := range event.Attributes {
|
||||
if bytes.Equal(attr.Key, bAttributeKeyEthereumBloom) {
|
||||
return ethtypes.BytesToBloom(attr.Value), nil
|
||||
if attr.Key == string(bAttributeKeyEthereumBloom) {
|
||||
return ethtypes.BytesToBloom([]byte(attr.Value)), nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ import (
|
||||
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"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"
|
||||
evmtypes "github.com/tharsis/ethermint/x/evm/types"
|
||||
)
|
||||
|
@ -238,12 +238,12 @@ func TxLogsFromEvents(events []abci.Event, msgIndex int) ([]*ethtypes.Log, error
|
||||
func ParseTxLogsFromEvent(event abci.Event) ([]*ethtypes.Log, error) {
|
||||
logs := make([]*evmtypes.Log, 0, len(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
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
|
@ -14,7 +14,7 @@ import (
|
||||
"time"
|
||||
|
||||
"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"
|
||||
|
||||
|
@ -20,7 +20,7 @@ import (
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/viper"
|
||||
"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/flags"
|
||||
@ -74,6 +74,7 @@ func NewPublicAPI(
|
||||
viper.GetString(flags.FlagKeyringBackend),
|
||||
clientCtx.KeyringDir,
|
||||
clientCtx.Input,
|
||||
clientCtx.Codec,
|
||||
hd.EthSecp256k1Option(),
|
||||
)
|
||||
if err != nil {
|
||||
@ -242,7 +243,11 @@ func (e *PublicAPI) Accounts() ([]common.Address, error) {
|
||||
}
|
||||
|
||||
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))
|
||||
}
|
||||
|
||||
|
@ -11,7 +11,7 @@ import (
|
||||
|
||||
"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"
|
||||
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
|
||||
_, isMsgEthereumTx := ev.Events[evmtypes.TypeMsgEthereumTx]
|
||||
var isMsgEthereumTx bool
|
||||
|
||||
for _, event := range ev.Events {
|
||||
if event.Type == evmtypes.TypeMsgEthereumTx {
|
||||
isMsgEthereumTx = true
|
||||
}
|
||||
}
|
||||
|
||||
if !isMsgEthereumTx {
|
||||
// ignore transaction as it's not from the evm module
|
||||
|
@ -10,8 +10,7 @@ import (
|
||||
|
||||
tmjson "github.com/tendermint/tendermint/libs/json"
|
||||
"github.com/tendermint/tendermint/libs/log"
|
||||
tmquery "github.com/tendermint/tendermint/libs/pubsub/query"
|
||||
coretypes "github.com/tendermint/tendermint/rpc/core/types"
|
||||
coretypes "github.com/tendermint/tendermint/rpc/coretypes"
|
||||
rpcclient "github.com/tendermint/tendermint/rpc/jsonrpc/client"
|
||||
tmtypes "github.com/tendermint/tendermint/types"
|
||||
|
||||
@ -27,9 +26,9 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
txEvents = tmtypes.QueryForEvent(tmtypes.EventTx).String()
|
||||
evmEvents = tmquery.MustParse(fmt.Sprintf("%s='%s' AND %s.%s='%s'", tmtypes.EventTypeKey, tmtypes.EventTx, sdk.EventTypeMessage, sdk.AttributeKeyModule, evmtypes.ModuleName)).String()
|
||||
headerEvents = tmtypes.QueryForEvent(tmtypes.EventNewBlockHeader).String()
|
||||
txEvents = tmtypes.QueryForEvent(tmtypes.EventTxValue).String()
|
||||
evmEvents = fmt.Sprintf("%s='%s' AND %s.%s='%s'", tmtypes.EventTypeKey, tmtypes.EventTx, sdk.EventTypeMessage, sdk.AttributeKeyModule, evmtypes.ModuleName)
|
||||
headerEvents = tmtypes.QueryForEvent(tmtypes.EventNewBlockHeaderValue).String()
|
||||
)
|
||||
|
||||
// EventSystem creates subscriptions, processes events and broadcasts them to the
|
||||
|
@ -7,7 +7,7 @@ import (
|
||||
ethtypes "github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/eth/filters"
|
||||
"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
|
||||
|
@ -124,7 +124,7 @@ func (api *API) SetEtherbase(etherbase common.Address) bool {
|
||||
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())
|
||||
return false
|
||||
}
|
||||
|
@ -102,7 +102,11 @@ func (api *PrivateAccountAPI) ListAccounts() ([]common.Address, error) {
|
||||
}
|
||||
|
||||
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
|
||||
@ -131,7 +135,8 @@ func (api *PrivateAccountAPI) NewAccount(password string) (common.Address, error
|
||||
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("Please backup your key file!", "path", os.Getenv("HOME")+"/.ethermint/"+name) // TODO: pass the correct binary
|
||||
api.logger.Info("Please remember your password!")
|
||||
|
@ -6,7 +6,7 @@ import (
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
coretypes "github.com/tendermint/tendermint/rpc/core/types"
|
||||
coretypes "github.com/tendermint/tendermint/rpc/coretypes"
|
||||
)
|
||||
|
||||
type UnsubscribeFunc func()
|
||||
|
@ -8,7 +8,7 @@ import (
|
||||
"time"
|
||||
|
||||
"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) {
|
||||
|
@ -242,7 +242,7 @@ func BaseFeeFromEvents(events []abci.Event) *big.Int {
|
||||
}
|
||||
|
||||
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)
|
||||
if success {
|
||||
return result
|
||||
@ -250,6 +250,14 @@ func BaseFeeFromEvents(events []abci.Event) *big.Int {
|
||||
|
||||
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
|
||||
@ -310,10 +318,10 @@ func FindTxAttributesByIndex(events []abci.Event, txIndex uint64) int {
|
||||
// FindAttribute find event attribute with specified key, if not found returns nil.
|
||||
func FindAttribute(attrs []abci.EventAttribute, key []byte) []byte {
|
||||
for _, attr := range attrs {
|
||||
if !bytes.Equal(attr.Key, key) {
|
||||
if !bytes.Equal([]byte(attr.Key), key) {
|
||||
continue
|
||||
}
|
||||
return attr.Value
|
||||
return []byte(attr.Value)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -16,36 +16,43 @@ import (
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
tmservice "github.com/tendermint/tendermint/libs/service"
|
||||
"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/flags"
|
||||
dbm "github.com/cosmos/cosmos-sdk/db"
|
||||
"github.com/cosmos/cosmos-sdk/server"
|
||||
"github.com/cosmos/cosmos-sdk/server/api"
|
||||
serverconfig "github.com/cosmos/cosmos-sdk/server/config"
|
||||
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"
|
||||
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"
|
||||
"github.com/tharsis/ethermint/server/config"
|
||||
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
|
||||
// Tendermint.
|
||||
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().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.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().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")
|
||||
@ -184,10 +191,11 @@ func startStandAlone(ctx *server.Context, appCreator types.AppCreator) error {
|
||||
transport := ctx.Viper.GetString(srvflags.Transport)
|
||||
home := ctx.Viper.GetString(flags.FlagHome)
|
||||
|
||||
db, err := openDB(home)
|
||||
db, err := openDB(home, server.GetAppDBBackend((ctx.Viper)))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer func() {
|
||||
if err := db.Close(); err != nil {
|
||||
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)
|
||||
db, err := openDB(home)
|
||||
db, err := openDB(home, server.GetAppDBBackend(ctx.Viper))
|
||||
if err != nil {
|
||||
logger.Error("failed to open DB", "error", err.Error())
|
||||
return err
|
||||
}
|
||||
defer func() {
|
||||
@ -292,38 +299,46 @@ func startInProcess(ctx *server.Context, clientCtx client.Context, appCreator ty
|
||||
|
||||
app := appCreator(ctx.Logger, db, traceWriter, ctx.Viper)
|
||||
|
||||
nodeKey, err := p2p.LoadOrGenNodeKey(cfg.NodeKeyFile())
|
||||
genDoc, err := tmtypes.GenesisDocFromFile(cfg.GenesisFile())
|
||||
if err != nil {
|
||||
logger.Error("failed load or gen node key", "error", err.Error())
|
||||
return err
|
||||
}
|
||||
|
||||
genDocProvider := node.DefaultGenesisDocProviderFunc(cfg)
|
||||
tmNode, err := node.NewNode(
|
||||
cfg,
|
||||
pvm.LoadOrGenFilePV(cfg.PrivValidatorKeyFile(), cfg.PrivValidatorStateFile()),
|
||||
nodeKey,
|
||||
proxy.NewLocalClientCreator(app),
|
||||
genDocProvider,
|
||||
node.DefaultDBProvider,
|
||||
node.DefaultMetricsProvider(cfg.Instrumentation),
|
||||
ctx.Logger.With("server", "node"),
|
||||
var (
|
||||
tmNode tmservice.Service
|
||||
gRPCOnly = ctx.Viper.GetBool(flagGRPCOnly)
|
||||
)
|
||||
if err != nil {
|
||||
logger.Error("failed init node", "error", err.Error())
|
||||
return err
|
||||
}
|
||||
if gRPCOnly {
|
||||
ctx.Logger.Info("starting node in gRPC only mode; Tendermint is disabled")
|
||||
config.GRPC.Enable = true
|
||||
} else {
|
||||
ctx.Logger.Info("starting node with ABCI Tendermint in-process")
|
||||
|
||||
if err := tmNode.Start(); err != nil {
|
||||
logger.Error("failed start tendermint server", "error", err.Error())
|
||||
return err
|
||||
tmNode, err = node.New(cfg, ctx.Logger, abciclient.NewLocalCreator(app), genDoc)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := tmNode.Start(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// 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
|
||||
// case, because it spawns a new local tendermint RPC client.
|
||||
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.RegisterTendermintService(clientCtx)
|
||||
@ -331,7 +346,7 @@ func startInProcess(ctx *server.Context, clientCtx client.Context, appCreator ty
|
||||
|
||||
var apiSrv *api.Server
|
||||
if config.API.Enable {
|
||||
genDoc, err := genDocProvider()
|
||||
genDoc, err := tmtypes.GenesisDocFromFile(cfg.GenesisFile())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -417,7 +432,7 @@ func startInProcess(ctx *server.Context, clientCtx client.Context, appCreator ty
|
||||
)
|
||||
|
||||
if config.JSONRPC.Enable {
|
||||
genDoc, err := genDocProvider()
|
||||
genDoc, err := tmtypes.GenesisDocFromFile(cfg.GenesisFile())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -476,9 +491,9 @@ func startInProcess(ctx *server.Context, clientCtx client.Context, appCreator ty
|
||||
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")
|
||||
return sdk.NewLevelDB("application", dataDir)
|
||||
return dbm.NewDB("application", backendType, dataDir)
|
||||
}
|
||||
|
||||
func openTraceWriter(traceWriterFile string) (w io.Writer, err error) {
|
||||
|
@ -2,7 +2,6 @@ package server
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"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 {
|
||||
tmWsClient, err := rpcclient.NewWS(tmRPCAddr, tmEndpoint,
|
||||
rpcclient.MaxReconnectAttempts(256),
|
||||
rpcclient.ReadWait(120*time.Second),
|
||||
rpcclient.WriteWait(120*time.Second),
|
||||
rpcclient.PingPeriod(50*time.Second),
|
||||
rpcclient.OnReconnect(func() {
|
||||
logger.Debug("EVM RPC reconnects to Tendermint WS", "address", tmRPCAddr+tmEndpoint)
|
||||
}),
|
||||
)
|
||||
// tmWsClient, err := rpcclient.NewWS(tmRPCAddr, tmEndpoint,
|
||||
// rpcclient.MaxReconnectAttempts(256),
|
||||
// rpcclient.ReadWait(120*time.Second),
|
||||
// rpcclient.WriteWait(120*time.Second),
|
||||
// rpcclient.PingPeriod(50*time.Second),
|
||||
// rpcclient.OnReconnect(func() {
|
||||
// logger.Debug("EVM RPC reconnects to Tendermint WS", "address", tmRPCAddr+tmEndpoint)
|
||||
// }),
|
||||
// )
|
||||
|
||||
if err != nil {
|
||||
logger.Error(
|
||||
"Tendermint WS client could not be created",
|
||||
"address", tmRPCAddr+tmEndpoint,
|
||||
"error", err,
|
||||
)
|
||||
} else if err := tmWsClient.OnStart(); err != nil {
|
||||
logger.Error(
|
||||
"Tendermint WS client could not start",
|
||||
"address", tmRPCAddr+tmEndpoint,
|
||||
"error", err,
|
||||
)
|
||||
}
|
||||
// if err != nil {
|
||||
// logger.Error(
|
||||
// "Tendermint WS client could not be created",
|
||||
// "address", tmRPCAddr+tmEndpoint,
|
||||
// "error", err,
|
||||
// )
|
||||
// } else if err := tmWsClient.OnStart(); err != nil {
|
||||
// logger.Error(
|
||||
// "Tendermint WS client could not start",
|
||||
// "address", tmRPCAddr+tmEndpoint,
|
||||
// "error", err,
|
||||
// )
|
||||
// }
|
||||
|
||||
return tmWsClient
|
||||
return nil
|
||||
}
|
||||
|
||||
func MountGRPCWebServices(
|
||||
|
@ -6,6 +6,7 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
@ -17,14 +18,10 @@ import (
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/ethclient"
|
||||
"github.com/rs/zerolog"
|
||||
"github.com/spf13/cobra"
|
||||
tmcfg "github.com/tendermint/tendermint/config"
|
||||
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"
|
||||
"github.com/tendermint/tendermint/libs/service"
|
||||
tmclient "github.com/tendermint/tendermint/rpc/client"
|
||||
dbm "github.com/tendermint/tm-db"
|
||||
"google.golang.org/grpc"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/baseapp"
|
||||
@ -34,6 +31,7 @@ import (
|
||||
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/keyring"
|
||||
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/api"
|
||||
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
|
||||
func NewAppConstructor(encodingCfg params.EncodingConfig) AppConstructor {
|
||||
return func(val Validator) servertypes.Application {
|
||||
return app.NewEthermintApp(
|
||||
val.Ctx.Logger, dbm.NewMemDB(), nil, true, make(map[int64]bool), val.Ctx.Config.RootDir, 0,
|
||||
return simapp.NewSimApp(
|
||||
val.Ctx.Logger, memdb.NewDB(), nil, true, make(map[int64]bool), val.Ctx.Config.RootDir, 0,
|
||||
encodingCfg,
|
||||
simapp.EmptyAppOptions{},
|
||||
baseapp.SetPruning(storetypes.NewPruningOptionsFromString(val.AppConfig.Pruning)),
|
||||
@ -113,15 +111,15 @@ func DefaultConfig() Config {
|
||||
encCfg := encoding.MakeConfig(app.ModuleBasics)
|
||||
|
||||
return Config{
|
||||
Codec: encCfg.Marshaler,
|
||||
Codec: encCfg.Codec,
|
||||
TxConfig: encCfg.TxConfig,
|
||||
LegacyAmino: encCfg.Amino,
|
||||
InterfaceRegistry: encCfg.InterfaceRegistry,
|
||||
AccountRetriever: authtypes.AccountRetriever{},
|
||||
AppConstructor: NewAppConstructor(encCfg),
|
||||
GenesisState: app.ModuleBasics.DefaultGenesis(encCfg.Marshaler),
|
||||
GenesisState: simapp.ModuleBasics.DefaultGenesis(encCfg.Codec),
|
||||
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,
|
||||
BondDenom: ethermint.AttoPhoton,
|
||||
MinGasPrices: fmt.Sprintf("0.000006%s", ethermint.AttoPhoton),
|
||||
@ -174,7 +172,7 @@ type (
|
||||
RPCClient tmclient.Client
|
||||
JSONRPCClient *ethclient.Client
|
||||
|
||||
tmNode *node.Node
|
||||
tmNode service.Service
|
||||
api *api.Server
|
||||
grpc *grpc.Server
|
||||
grpcWeb *http.Server
|
||||
@ -322,12 +320,13 @@ func New(l Logger, baseDir string, cfg Config) (*Network, error) {
|
||||
appCfg.JSONRPC.API = config.GetAPINamespaces()
|
||||
}
|
||||
|
||||
logger := log.NewNopLogger()
|
||||
logger := server.ZeroLogWrapper{Logger: zerolog.Nop()}
|
||||
if cfg.EnableTMLogging {
|
||||
logger = log.NewTMLogger(log.NewSyncWriter(os.Stdout))
|
||||
logger, _ = tmflags.ParseLogLevel("info", logger, tmcfg.DefaultLogLevel)
|
||||
logWriter := zerolog.ConsoleWriter{Out: os.Stderr}
|
||||
logger = server.ZeroLogWrapper{Logger: zerolog.New(logWriter).Level(zerolog.InfoLevel).With().Timestamp().Logger()}
|
||||
}
|
||||
|
||||
ctx.Logger = logger
|
||||
ctx.Logger = logger
|
||||
|
||||
nodeDirName := fmt.Sprintf("node%d", i)
|
||||
@ -370,7 +369,7 @@ func New(l Logger, baseDir string, cfg Config) (*Network, error) {
|
||||
nodeIDs[i] = nodeID
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
@ -629,20 +628,20 @@ func (n *Network) Cleanup() {
|
||||
}
|
||||
}
|
||||
|
||||
if v.jsonrpc != nil {
|
||||
shutdownCtx, cancelFn := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
defer cancelFn()
|
||||
// if v.jsonrpc != nil {
|
||||
// shutdownCtx, cancelFn := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
// defer cancelFn()
|
||||
|
||||
if err := v.jsonrpc.Shutdown(shutdownCtx); err != nil {
|
||||
v.tmNode.Logger.Error("HTTP server shutdown produced a warning", "error", err.Error())
|
||||
} else {
|
||||
v.tmNode.Logger.Info("HTTP server shut down, waiting 5 sec")
|
||||
select {
|
||||
case <-time.Tick(5 * time.Second):
|
||||
case <-v.jsonrpcDone:
|
||||
}
|
||||
}
|
||||
}
|
||||
// if err := v.jsonrpc.Shutdown(shutdownCtx); err != nil {
|
||||
// v.tmNode.Logger.Error("HTTP server shutdown produced a warning", "error", err.Error())
|
||||
// } else {
|
||||
// v.tmNode.Logger.Info("HTTP server shut down, waiting 5 sec")
|
||||
// select {
|
||||
// case <-time.Tick(5 * time.Second):
|
||||
// case <-v.jsonrpcDone:
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
if n.Config.CleanupDir {
|
||||
|
@ -3,18 +3,16 @@ package network
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/ethclient"
|
||||
abciclient "github.com/tendermint/tendermint/abci/client"
|
||||
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"
|
||||
"github.com/tendermint/tendermint/types"
|
||||
tmtime "github.com/tendermint/tendermint/types/time"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/server/api"
|
||||
servergrpc "github.com/cosmos/cosmos-sdk/server/grpc"
|
||||
@ -25,6 +23,7 @@ import (
|
||||
"github.com/cosmos/cosmos-sdk/x/genutil"
|
||||
genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/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"
|
||||
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
|
||||
|
||||
@ -41,36 +40,35 @@ func startInProcess(cfg Config, val *Validator) error {
|
||||
return err
|
||||
}
|
||||
|
||||
nodeKey, err := p2p.LoadOrGenNodeKey(tmCfg.NodeKeyFile())
|
||||
app := cfg.AppConstructor(*val)
|
||||
genDoc, err := types.GenesisDocFromFile(tmCfg.GenesisFile())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
app := cfg.AppConstructor(*val)
|
||||
|
||||
genDocProvider := node.DefaultGenesisDocProviderFunc(tmCfg)
|
||||
tmNode, err := node.NewNode(
|
||||
val.tmNode, err = node.New(
|
||||
tmCfg,
|
||||
pvm.LoadOrGenFilePV(tmCfg.PrivValidatorKeyFile(), tmCfg.PrivValidatorStateFile()),
|
||||
nodeKey,
|
||||
proxy.NewLocalClientCreator(app),
|
||||
genDocProvider,
|
||||
node.DefaultDBProvider,
|
||||
node.DefaultMetricsProvider(tmCfg.Instrumentation),
|
||||
logger.With("module", val.Moniker),
|
||||
abciclient.NewLocalCreator(app),
|
||||
genDoc,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := tmNode.Start(); err != nil {
|
||||
if err := val.tmNode.Start(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
val.tmNode = tmNode
|
||||
|
||||
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.
|
||||
@ -147,7 +145,8 @@ func startInProcess(cfg Config, val *Validator) 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++ {
|
||||
tmCfg := vals[i].Ctx.Config
|
||||
@ -205,7 +204,7 @@ func initGenFiles(cfg Config, genAccounts []authtypes.GenesisAccount, genBalance
|
||||
stakingGenState.Params.BondDenom = cfg.BondDenom
|
||||
cfg.GenesisState[stakingtypes.ModuleName] = cfg.Codec.MustMarshalJSON(&stakingGenState)
|
||||
|
||||
var govGenState govtypes.GenesisState
|
||||
var govGenState v1.GenesisState
|
||||
cfg.Codec.MustUnmarshalJSON(cfg.GenesisState[govtypes.ModuleName], &govGenState)
|
||||
|
||||
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 {
|
||||
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 {
|
||||
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
6
types/address.go
Normal file
@ -0,0 +1,6 @@
|
||||
package types
|
||||
|
||||
const (
|
||||
// Bech32MainPrefix defines the main SDK Bech32 prefix of an account's address
|
||||
Bech32MainPrefix = "ethm"
|
||||
)
|
@ -26,7 +26,7 @@ type infiniteGasMeterWithLimit struct {
|
||||
}
|
||||
|
||||
// NewInfiniteGasMeterWithLimit returns a reference to a new infiniteGasMeter.
|
||||
func NewInfiniteGasMeterWithLimit(limit sdk.Gas) sdk.GasMeter {
|
||||
func NewInfiniteGasMeterWithLimit(limit sdk.Gas) *infiniteGasMeterWithLimit {
|
||||
return &infiniteGasMeterWithLimit{
|
||||
consumed: 0,
|
||||
limit: limit,
|
||||
|
@ -1,116 +1,98 @@
|
||||
package rest
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"math/big"
|
||||
"net/http"
|
||||
"strings"
|
||||
// clientrest "github.com/cosmos/cosmos-sdk/client/rest"
|
||||
// "github.com/cosmos/cosmos-sdk/types/rest"
|
||||
// authrest "github.com/cosmos/cosmos-sdk/x/auth/client/rest"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
clientrest "github.com/cosmos/cosmos-sdk/client/rest"
|
||||
"github.com/cosmos/cosmos-sdk/types/rest"
|
||||
authrest "github.com/cosmos/cosmos-sdk/x/auth/client/rest"
|
||||
|
||||
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")
|
||||
}
|
||||
// // RegisterTxRoutes - Central function to define routes that get registered by the main application
|
||||
// func RegisterTxRoutes(clientCtx client.Context, rtr *mux.Router) {
|
||||
// r := testutil.GetRequestWithHeaders(rtr)
|
||||
// r.HandleFunc("/txs/{hash}", QueryTxRequestHandlerFn(clientCtx)).Methods("GET")
|
||||
// r.HandleFunc("/txs", testutil.QueryTxsRequestHandlerFn(clientCtx)).Methods("GET")
|
||||
// r.HandleFunc("/txs/decode", testutil.DecodeTxRequestHandlerFn(clientCtx)).Methods("POST")
|
||||
// }
|
||||
|
||||
// QueryTxRequestHandlerFn implements a REST handler that queries a transaction
|
||||
// by hash in a committed block.
|
||||
func QueryTxRequestHandlerFn(clientCtx client.Context) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
hashHexStr := vars["hash"]
|
||||
// func QueryTxRequestHandlerFn(clientCtx client.Context) http.HandlerFunc {
|
||||
// return func(w http.ResponseWriter, r *http.Request) {
|
||||
// vars := mux.Vars(r)
|
||||
// hashHexStr := vars["hash"]
|
||||
|
||||
clientCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, clientCtx, r)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
// clientCtx, ok := testutil.ParseQueryHeightOrReturnBadRequest(w, clientCtx, r)
|
||||
// if !ok {
|
||||
// return
|
||||
// }
|
||||
|
||||
ethHashPrefix := "0x"
|
||||
if !strings.HasPrefix(hashHexStr, ethHashPrefix) {
|
||||
authrest.QueryTxRequestHandlerFn(clientCtx)
|
||||
return
|
||||
}
|
||||
// ethHashPrefix := "0x"
|
||||
// // if !strings.HasPrefix(hashHexStr, ethHashPrefix) {
|
||||
// // authrest.QueryTxRequestHandlerFn(clientCtx)
|
||||
// // return
|
||||
// // }
|
||||
|
||||
// eth Tx
|
||||
ethHashPrefixLength := len(ethHashPrefix)
|
||||
output, err := getEthTransactionByHash(clientCtx, hashHexStr[ethHashPrefixLength:])
|
||||
if err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
// // eth Tx
|
||||
// ethHashPrefixLength := len(ethHashPrefix)
|
||||
// output, err := getEthTransactionByHash(clientCtx, hashHexStr[ethHashPrefixLength:])
|
||||
// if err != nil {
|
||||
// rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
|
||||
// return
|
||||
// }
|
||||
|
||||
rest.PostProcessResponseBare(w, clientCtx, output)
|
||||
}
|
||||
}
|
||||
// rest.PostProcessResponseBare(w, clientCtx, output)
|
||||
// }
|
||||
// }
|
||||
|
||||
// GetTransactionByHash returns the transaction identified by hash.
|
||||
func getEthTransactionByHash(clientCtx client.Context, hashHex string) ([]byte, error) {
|
||||
hash, err := hex.DecodeString(hashHex)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
node, err := clientCtx.GetNode()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// // GetTransactionByHash returns the transaction identified by hash.
|
||||
// func getEthTransactionByHash(clientCtx client.Context, hashHex string) ([]byte, error) {
|
||||
// hash, err := hex.DecodeString(hashHex)
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
// node, err := clientCtx.GetNode()
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
|
||||
tx, err := node.Tx(context.Background(), hash, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// tx, err := node.Tx(context.Background(), hash, false)
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
|
||||
// Can either cache or just leave this out if not necessary
|
||||
block, err := node.Block(context.Background(), &tx.Height)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// // Can either cache or just leave this out if not necessary
|
||||
// block, err := node.Block(context.Background(), &tx.Height)
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
|
||||
client := feemarkettypes.NewQueryClient(clientCtx)
|
||||
res, err := client.BaseFee(context.Background(), &feemarkettypes.QueryBaseFeeRequest{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// client := feemarkettypes.NewQueryClient(clientCtx)
|
||||
// res, err := client.BaseFee(context.Background(), &feemarkettypes.QueryBaseFeeRequest{})
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
|
||||
var baseFee *big.Int
|
||||
if res.BaseFee != nil {
|
||||
baseFee = res.BaseFee.BigInt()
|
||||
}
|
||||
// var baseFee *big.Int
|
||||
// if res.BaseFee != nil {
|
||||
// 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)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// ethTxs, err := rpctypes.RawTxToEthTx(clientCtx, tx.Tx)
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
|
||||
height := uint64(tx.Height)
|
||||
// height := uint64(tx.Height)
|
||||
|
||||
for _, ethTx := range ethTxs {
|
||||
if common.HexToHash(ethTx.Hash) == common.BytesToHash(hash) {
|
||||
rpcTx, err := rpctypes.NewRPCTransaction(ethTx.AsTransaction(), blockHash, height, uint64(tx.Index), baseFee)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return json.Marshal(rpcTx)
|
||||
}
|
||||
}
|
||||
// for _, ethTx := range ethTxs {
|
||||
// if common.HexToHash(ethTx.Hash) == common.BytesToHash(hash) {
|
||||
// rpcTx, err := rpctypes.NewRPCTransaction(ethTx.AsTransaction(), blockHash, height, uint64(tx.Index), baseFee)
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
// return json.Marshal(rpcTx)
|
||||
// }
|
||||
// }
|
||||
|
||||
return nil, errors.New("eth tx not found")
|
||||
}
|
||||
// return nil, errors.New("eth tx not found")
|
||||
// }
|
||||
|
@ -7,7 +7,8 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
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"
|
||||
|
||||
ethtypes "github.com/ethereum/go-ethereum/core/types"
|
||||
@ -63,12 +64,12 @@ func DoBenchmark(b *testing.B, txBuilder TxBuilder) {
|
||||
ctx, _ := suite.ctx.CacheContext()
|
||||
|
||||
// deduct fee first
|
||||
txData, err := types.UnpackTxData(msg.Data)
|
||||
require.NoError(b, err)
|
||||
// txData, err := types.UnpackTxData(msg.Data)
|
||||
// require.NoError(b, err)
|
||||
|
||||
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)
|
||||
require.NoError(b, err)
|
||||
// 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)
|
||||
// require.NoError(b, err)
|
||||
|
||||
rsp, err := suite.app.EvmKeeper.EthereumTx(sdk.WrapSDKContext(ctx), msg)
|
||||
require.NoError(b, err)
|
||||
|
@ -5,6 +5,7 @@ import (
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
"github.com/cosmos/cosmos-sdk/store/prefix"
|
||||
storetypes "github.com/cosmos/cosmos-sdk/store/types"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||
paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"
|
||||
@ -29,10 +30,10 @@ type Keeper struct {
|
||||
// - storing account's Code
|
||||
// - storing transaction Logs
|
||||
// - 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
|
||||
transientKey sdk.StoreKey
|
||||
transientKey storetypes.StoreKey
|
||||
|
||||
// module specific parameter space that can be configured through governance
|
||||
paramSpace paramtypes.Subspace
|
||||
@ -58,7 +59,7 @@ type Keeper struct {
|
||||
// NewKeeper generates new evm module keeper
|
||||
func NewKeeper(
|
||||
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,
|
||||
fmk types.FeeMarketKeeper,
|
||||
tracer string,
|
||||
|
@ -183,7 +183,7 @@ func (suite *KeeperTestSuite) DoSetupTest(t require.TestingT) {
|
||||
encodingConfig := encoding.MakeConfig(app.ModuleBasics)
|
||||
suite.clientCtx = client.Context{}.WithTxConfig(encodingConfig.TxConfig)
|
||||
suite.ethSigner = ethtypes.LatestSignerForChainID(suite.app.EvmKeeper.ChainID())
|
||||
suite.appCodec = encodingConfig.Marshaler
|
||||
suite.appCodec = encodingConfig.Codec
|
||||
}
|
||||
|
||||
func (suite *KeeperTestSuite) SetupTest() {
|
||||
|
@ -5,7 +5,8 @@ import (
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
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"
|
||||
|
||||
@ -24,10 +25,10 @@ func (k Keeper) DeductTxCostsFromUserBalance(
|
||||
isContractCreation := txData.GetTo() == nil
|
||||
|
||||
// fetch sender account from signature
|
||||
signerAcc, err := authante.GetSignerAcc(ctx, k.accountKeeper, msgEthTx.GetFrom())
|
||||
if err != nil {
|
||||
return nil, sdkerrors.Wrapf(err, "account not found for sender %s", msgEthTx.From)
|
||||
}
|
||||
// signerAcc, err := authante.GetSignerAcc(ctx, k.accountKeeper, msgEthTx.GetFrom())
|
||||
// if err != nil {
|
||||
// return nil, sdkerrors.Wrapf(err, "account not found for sender %s", msgEthTx.From)
|
||||
// }
|
||||
|
||||
gasLimit := txData.GetGas()
|
||||
|
||||
@ -73,14 +74,14 @@ func (k Keeper) DeductTxCostsFromUserBalance(
|
||||
|
||||
fees := sdk.Coins{sdk.NewCoin(denom, sdk.NewIntFromBigInt(feeAmt))}
|
||||
|
||||
// deduct the full gas cost from the user balance
|
||||
if err := authante.DeductFees(k.bankKeeper, ctx, signerAcc, fees); err != nil {
|
||||
return nil, sdkerrors.Wrapf(
|
||||
err,
|
||||
"failed to deduct full gas cost %s from the user %s balance",
|
||||
fees, msgEthTx.From,
|
||||
)
|
||||
}
|
||||
// // deduct the full gas cost from the user balance
|
||||
// if err := authante.DeductFees(k.bankKeeper, ctx, signerAcc, fees); err != nil {
|
||||
// return nil, sdkerrors.Wrapf(
|
||||
// err,
|
||||
// "failed to deduct full gas cost %s from the user %s balance",
|
||||
// fees, msgEthTx.From,
|
||||
// )
|
||||
// }
|
||||
return fees, nil
|
||||
}
|
||||
|
||||
|
@ -10,7 +10,8 @@ import (
|
||||
"github.com/cosmos/cosmos-sdk/crypto/keyring"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth/ante"
|
||||
|
||||
// "github.com/cosmos/cosmos-sdk/x/auth/ante"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth/signing"
|
||||
authtx "github.com/cosmos/cosmos-sdk/x/auth/tx"
|
||||
|
||||
@ -22,9 +23,9 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
_ sdk.Msg = &MsgEthereumTx{}
|
||||
_ sdk.Tx = &MsgEthereumTx{}
|
||||
_ ante.GasTx = &MsgEthereumTx{}
|
||||
_ sdk.Msg = &MsgEthereumTx{}
|
||||
_ sdk.Tx = &MsgEthereumTx{}
|
||||
// _ ante.GasTx = &MsgEthereumTx{}
|
||||
|
||||
_ codectypes.UnpackInterfacesMessage = MsgEthereumTx{}
|
||||
)
|
||||
|
@ -6,6 +6,7 @@ import (
|
||||
paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"
|
||||
"github.com/tendermint/tendermint/libs/log"
|
||||
|
||||
storetypes "github.com/cosmos/cosmos-sdk/store/types"
|
||||
"github.com/tharsis/ethermint/x/feemarket/types"
|
||||
)
|
||||
|
||||
@ -14,14 +15,14 @@ type Keeper struct {
|
||||
// Protobuf codec
|
||||
cdc codec.BinaryCodec
|
||||
// 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
|
||||
paramSpace paramtypes.Subspace
|
||||
}
|
||||
|
||||
// NewKeeper generates new fee market module keeper
|
||||
func NewKeeper(
|
||||
cdc codec.BinaryCodec, storeKey sdk.StoreKey, paramSpace paramtypes.Subspace,
|
||||
cdc codec.BinaryCodec, storeKey storetypes.StoreKey, paramSpace paramtypes.Subspace,
|
||||
) Keeper {
|
||||
// set KeyTable if it has not already been set
|
||||
if !paramSpace.HasKeyTable() {
|
||||
|
@ -113,7 +113,7 @@ func (suite *KeeperTestSuite) DoSetupTest(t require.TestingT) {
|
||||
encodingConfig := encoding.MakeConfig(app.ModuleBasics)
|
||||
suite.clientCtx = client.Context{}.WithTxConfig(encodingConfig.TxConfig)
|
||||
suite.ethSigner = ethtypes.LatestSignerForChainID(suite.app.EvmKeeper.ChainID())
|
||||
suite.appCodec = encodingConfig.Marshaler
|
||||
suite.appCodec = encodingConfig.Codec
|
||||
}
|
||||
|
||||
func (suite *KeeperTestSuite) SetupTest() {
|
||||
|
@ -5,6 +5,7 @@ import (
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
|
||||
storetypes "github.com/cosmos/cosmos-sdk/store/types"
|
||||
paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"
|
||||
v09types "github.com/tharsis/ethermint/x/feemarket/migrations/v09/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
|
||||
// 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
|
||||
|
||||
store := ctx.KVStore(storeKey)
|
||||
|
Loading…
Reference in New Issue
Block a user