Skip to content
This repository was archived by the owner on Nov 30, 2021. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions app/ethermint.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"github.com/cosmos/cosmos-sdk/x/staking"
"github.com/cosmos/cosmos-sdk/x/supply"

eminttypes "github.com/cosmos/ethermint/types"
evmtypes "github.com/cosmos/ethermint/x/evm/types"

abci "github.com/tendermint/tendermint/abci/types"
Expand Down Expand Up @@ -79,6 +80,8 @@ func MakeCodec() *codec.Codec {
ModuleBasics.RegisterCodec(cdc)
sdk.RegisterCodec(cdc)
codec.RegisterCrypto(cdc)
eminttypes.RegisterCodec(cdc)

return cdc
}

Expand Down Expand Up @@ -128,7 +131,7 @@ func NewEthermintApp(

keys := sdk.NewKVStoreKeys(bam.MainStoreKey, auth.StoreKey, staking.StoreKey,
supply.StoreKey, mint.StoreKey, distr.StoreKey, slashing.StoreKey,
gov.StoreKey, params.StoreKey)
gov.StoreKey, params.StoreKey, evmtypes.EvmStoreKey, evmtypes.EvmCodeKey)
tkeys := sdk.NewTransientStoreKeys(staking.TStoreKey, params.TStoreKey)

app := &EthermintApp{
Expand All @@ -151,7 +154,7 @@ func NewEthermintApp(
crisisSubspace := app.paramsKeeper.Subspace(crisis.DefaultParamspace)

// add keepers
app.accountKeeper = auth.NewAccountKeeper(app.cdc, keys[auth.StoreKey], authSubspace, auth.ProtoBaseAccount)
app.accountKeeper = auth.NewAccountKeeper(app.cdc, keys[auth.StoreKey], authSubspace, eminttypes.ProtoBaseAccount)
app.bankKeeper = bank.NewBaseKeeper(app.accountKeeper, bankSubspace, bank.DefaultCodespace, app.ModuleAccountAddrs())
app.supplyKeeper = supply.NewKeeper(app.cdc, keys[supply.StoreKey], app.accountKeeper, app.bankKeeper, maccPerms)
stakingKeeper := staking.NewKeeper(app.cdc, keys[staking.StoreKey], tkeys[staking.TStoreKey],
Expand All @@ -162,6 +165,7 @@ func NewEthermintApp(
app.slashingKeeper = slashing.NewKeeper(app.cdc, keys[slashing.StoreKey], &stakingKeeper,
slashingSubspace, slashing.DefaultCodespace)
app.crisisKeeper = crisis.NewKeeper(crisisSubspace, invCheckPeriod, app.supplyKeeper, auth.FeeCollectorName)
app.evmKeeper = evm.NewKeeper(app.accountKeeper, keys[evmtypes.EvmStoreKey], keys[evmtypes.EvmCodeKey], cdc)

// register the proposal types
govRouter := gov.NewRouter()
Expand Down Expand Up @@ -204,7 +208,7 @@ func NewEthermintApp(
app.mm.SetOrderInitGenesis(
genaccounts.ModuleName, distr.ModuleName, staking.ModuleName,
auth.ModuleName, bank.ModuleName, slashing.ModuleName, gov.ModuleName,
mint.ModuleName, supply.ModuleName, crisis.ModuleName, genutil.ModuleName,
mint.ModuleName, supply.ModuleName, crisis.ModuleName, genutil.ModuleName, evmtypes.ModuleName,
)

app.mm.RegisterInvariants(&app.crisisKeeper)
Expand Down
4 changes: 2 additions & 2 deletions types/account.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ type Account struct {

// merkle root of the storage trie
//
// TODO: good chance we may not need this
Root ethcmn.Hash
// TODO: add back root if needed (marshalling is broken if not initializing)
// Root ethcmn.Hash

CodeHash []byte
}
Expand Down
77 changes: 77 additions & 0 deletions types/account_retriever.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package types

import (
"fmt"

"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/auth/exported"
auth "github.com/cosmos/cosmos-sdk/x/auth/types"
)

// ** Modified version of github.com/cosmos/cosmos-sdk/x/auth/types/account_retriever.go
// ** to allow passing in a codec for decoding Account types
// AccountRetriever defines the properties of a type that can be used to
// retrieve accounts.
type AccountRetriever struct {
querier auth.NodeQuerier
codec *codec.Codec
}

// * Modified to allow a codec to be passed in
// NewAccountRetriever initialises a new AccountRetriever instance.
func NewAccountRetriever(querier auth.NodeQuerier, codec *codec.Codec) AccountRetriever {
if codec == nil {
codec = auth.ModuleCdc
}
return AccountRetriever{querier: querier, codec: codec}
}

// GetAccount queries for an account given an address and a block height. An
// error is returned if the query or decoding fails.
func (ar AccountRetriever) GetAccount(addr sdk.AccAddress) (exported.Account, error) {
account, _, err := ar.GetAccountWithHeight(addr)
return account, err
}

// GetAccountWithHeight queries for an account given an address. Returns the
// height of the query with the account. An error is returned if the query
// or decoding fails.
func (ar AccountRetriever) GetAccountWithHeight(addr sdk.AccAddress) (exported.Account, int64, error) {
// ** This line was changed to use non-static codec
bs, err := ar.codec.MarshalJSON(auth.NewQueryAccountParams(addr))
if err != nil {
return nil, 0, err
}

res, height, err := ar.querier.QueryWithData(fmt.Sprintf("custom/%s/%s", auth.QuerierRoute, auth.QueryAccount), bs)
if err != nil {
return nil, 0, err
}

var account exported.Account
// ** This line was changed to use non-static codec
if err := ar.codec.UnmarshalJSON(res, &account); err != nil {
return nil, 0, err
}

return account, height, nil
}

// EnsureExists returns an error if no account exists for the given address else nil.
func (ar AccountRetriever) EnsureExists(addr sdk.AccAddress) error {
if _, err := ar.GetAccount(addr); err != nil {
return err
}
return nil
}

// GetAccountNumberSequence returns sequence and account number for the given address.
// It returns an error if the account couldn't be retrieved from the state.
func (ar AccountRetriever) GetAccountNumberSequence(addr sdk.AccAddress) (uint64, uint64, error) {
acc, err := ar.GetAccount(addr)
if err != nil {
return 0, 0, err
}
return acc.GetAccountNumber(), acc.GetSequence(), nil
}
34 changes: 28 additions & 6 deletions types/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,11 @@ const (
// DefaultCodespace reserves a Codespace for Ethermint.
DefaultCodespace sdk.CodespaceType = "ethermint"

CodeInvalidValue sdk.CodeType = 1
CodeInvalidChainID sdk.CodeType = 2
CodeInvalidValue sdk.CodeType = 1
CodeInvalidChainID sdk.CodeType = 2
CodeInvalidSender sdk.CodeType = 3
CodeVMExecution sdk.CodeType = 4
CodeInvalidIntrinsicGas sdk.CodeType = 5
)

// CodeToDefaultMsg takes the CodeType variable and returns the error string
Expand All @@ -20,19 +23,38 @@ func CodeToDefaultMsg(code sdk.CodeType) string {
return "invalid value"
case CodeInvalidChainID:
return "invalid chain ID"
case CodeInvalidSender:
return "could not derive sender from transaction"
case CodeVMExecution:
return "error while executing evm transaction"
case CodeInvalidIntrinsicGas:
return "invalid intrinsic gas"
default:
return sdk.CodeToDefaultMsg(code)
}
}

// ErrInvalidValue returns a standardized SDK error resulting from an invalid
// value.
// ErrInvalidValue returns a standardized SDK error resulting from an invalid value.
func ErrInvalidValue(msg string) sdk.Error {
return sdk.NewError(DefaultCodespace, CodeInvalidValue, msg)
}

// ErrInvalidChainID returns a standardized SDK error resulting from an invalid
// chain ID.
// ErrInvalidChainID returns a standardized SDK error resulting from an invalid chain ID.
func ErrInvalidChainID(msg string) sdk.Error {
return sdk.NewError(DefaultCodespace, CodeInvalidChainID, msg)
}

// ErrInvalidSender returns a standardized SDK error resulting from an invalid transaction sender.
func ErrInvalidSender(msg string) sdk.Error {
return sdk.NewError(DefaultCodespace, CodeInvalidSender, msg)
}

// ErrVMExecution returns a standardized SDK error resulting from an error in EVM execution.
func ErrVMExecution(msg string) sdk.Error {
return sdk.NewError(DefaultCodespace, CodeVMExecution, msg)
}

// ErrVMExecution returns a standardized SDK error resulting from an error in EVM execution.
func ErrInvalidIntrinsicGas(msg string) sdk.Error {
return sdk.NewError(DefaultCodespace, CodeInvalidIntrinsicGas, msg)
}
26 changes: 16 additions & 10 deletions x/evm/client/cli/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,9 +88,9 @@ func GetCmdGenTx(cdc *codec.Codec) *cobra.Command {
// GetCmdGenTx generates an ethereum transaction
func GetCmdGenETHTx(cdc *codec.Codec) *cobra.Command {
return &cobra.Command{
Use: "generate-eth-tx [nonce] [ethaddress] [amount] [gaslimit] [gasprice] [payload]",
Short: "geberate and broadcast an Ethereum tx",
Args: cobra.ExactArgs(6),
Use: "generate-eth-tx [amount] [gaslimit] [gasprice] [payload] [<ethereum-address>]",
Short: "generate and broadcast an Ethereum tx. If address is not specified, contract will be created",
Args: cobra.RangeArgs(4, 5),
RunE: func(cmd *cobra.Command, args []string) error {
cliCtx := emintUtils.NewETHCLIContext().WithCodec(cdc)

Expand All @@ -101,35 +101,41 @@ func GetCmdGenETHTx(cdc *codec.Codec) *cobra.Command {
panic(err)
}

nonce, err := strconv.ParseUint(args[0], 0, 64)
coins, err := sdk.ParseCoins(args[0])
if err != nil {
return err
}

coins, err := sdk.ParseCoins(args[2])
gasLimit, err := strconv.ParseUint(args[1], 0, 64)
if err != nil {
return err
}

gasLimit, err := strconv.ParseUint(args[3], 0, 64)
gasPrice, err := strconv.ParseUint(args[2], 0, 64)
if err != nil {
return err
}

gasPrice, err := strconv.ParseUint(args[4], 0, 64)
payload := args[3]

txBldr, err = emintUtils.PrepareTxBuilder(txBldr, cliCtx)
if err != nil {
return err
}

payload := args[5]
var tx *types.EthereumTxMsg
if len(args) == 5 {
tx = types.NewEthereumTxMsg(txBldr.Sequence(), ethcmn.HexToAddress(args[4]), big.NewInt(coins.AmountOf(emintTypes.DenomDefault).Int64()), gasLimit, new(big.Int).SetUint64(gasPrice), []byte(payload))
} else {
tx = types.NewEthereumTxMsgContract(txBldr.Sequence(), big.NewInt(coins.AmountOf(emintTypes.DenomDefault).Int64()), gasLimit, new(big.Int).SetUint64(gasPrice), []byte(payload))
}

tx := types.NewEthereumTxMsg(nonce, ethcmn.HexToAddress(args[1]), big.NewInt(coins.AmountOf(emintTypes.DenomDefault).Int64()), gasLimit, new(big.Int).SetUint64(gasPrice), []byte(payload))
err = tx.ValidateBasic()
if err != nil {
return err
}

return emintUtils.BroadcastETHTx(cliCtx, txBldr.WithSequence(nonce).WithKeybase(kb), tx)
return emintUtils.BroadcastETHTx(cliCtx, txBldr.WithKeybase(kb), tx)
},
}
}
35 changes: 31 additions & 4 deletions x/evm/client/utils/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,6 @@ func GenerateOrBroadcastETHMsgs(cliCtx context.CLIContext, txBldr authtypes.TxBu

// BroadcastETHTx Broadcasts an Ethereum Tx not wrapped in a Std Tx
func BroadcastETHTx(cliCtx context.CLIContext, txBldr authtypes.TxBuilder, tx *evmtypes.EthereumTxMsg) error {
txBldr, err := utils.PrepareTxBuilder(txBldr, cliCtx)
if err != nil {
return err
}

fromName := cliCtx.GetFromName()

Expand Down Expand Up @@ -346,3 +342,34 @@ func getFromFields(from string, genOnly bool) (sdk.AccAddress, string, error) {

return info.GetAddress(), info.GetName(), nil
}

// * Overriden function from cosmos-sdk/auth/client/utils/tx.go
// PrepareTxBuilder populates a TxBuilder in preparation for the build of a Tx.
func PrepareTxBuilder(txBldr authtypes.TxBuilder, cliCtx context.CLIContext) (authtypes.TxBuilder, error) {
from := cliCtx.GetFromAddress()

// * Function is needed to override to use different account getter (to not use static codec)
accGetter := emint.NewAccountRetriever(cliCtx, cliCtx.Codec)
if err := accGetter.EnsureExists(from); err != nil {
return txBldr, err
}

txbldrAccNum, txbldrAccSeq := txBldr.AccountNumber(), txBldr.Sequence()
// TODO: (ref #1903) Allow for user supplied account number without
// automatically doing a manual lookup.
if txbldrAccNum == 0 || txbldrAccSeq == 0 {
num, seq, err := accGetter.GetAccountNumberSequence(from)
if err != nil {
return txBldr, err
}

if txbldrAccNum == 0 {
txBldr = txBldr.WithAccountNumber(num)
}
if txbldrAccSeq == 0 {
txBldr = txBldr.WithSequence(seq)
}
}

return txBldr, nil
}
Loading