forked from cerc-io/laconicd-deprecated
		
	eth_estimateGas (#128)
* Draft eth_estimateGas * implemented eth_estimateGas * refactored doCall to be used for both eth_call and eth_estiamteGas * updated to reflect requested changes * moved GenerateFromArgs func * removed todo * revert comment * fixes dereference issue * gofmted
This commit is contained in:
		
							parent
							
								
									741dfeb461
								
							
						
					
					
						commit
						69e0873dd9
					
				
							
								
								
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -16,4 +16,5 @@ vendor/ | |||||||
| build/ | build/ | ||||||
| 
 | 
 | ||||||
| # Goland | # Goland | ||||||
| .idea/ | .idea/ | ||||||
|  | start.sh | ||||||
| @ -68,7 +68,7 @@ func TestValidEthTx(t *testing.T) { | |||||||
| 	to := ethcmn.BytesToAddress(addr2.Bytes()) | 	to := ethcmn.BytesToAddress(addr2.Bytes()) | ||||||
| 	amt := big.NewInt(32) | 	amt := big.NewInt(32) | ||||||
| 	gas := big.NewInt(20) | 	gas := big.NewInt(20) | ||||||
| 	ethMsg := evmtypes.NewEthereumTxMsg(0, to, amt, 22000, gas, []byte("test")) | 	ethMsg := evmtypes.NewEthereumTxMsg(0, &to, amt, 22000, gas, []byte("test")) | ||||||
| 
 | 
 | ||||||
| 	tx := newTestEthTx(input.ctx, ethMsg, priv1) | 	tx := newTestEthTx(input.ctx, ethMsg, priv1) | ||||||
| 	requireValidTx(t, input.anteHandler, input.ctx, tx, false) | 	requireValidTx(t, input.anteHandler, input.ctx, tx, false) | ||||||
| @ -204,7 +204,7 @@ func TestEthInvalidSig(t *testing.T) { | |||||||
| 	to := ethcmn.BytesToAddress(addr2.Bytes()) | 	to := ethcmn.BytesToAddress(addr2.Bytes()) | ||||||
| 	amt := big.NewInt(32) | 	amt := big.NewInt(32) | ||||||
| 	gas := big.NewInt(20) | 	gas := big.NewInt(20) | ||||||
| 	ethMsg := evmtypes.NewEthereumTxMsg(0, to, amt, 22000, gas, []byte("test")) | 	ethMsg := evmtypes.NewEthereumTxMsg(0, &to, amt, 22000, gas, []byte("test")) | ||||||
| 
 | 
 | ||||||
| 	tx := newTestEthTx(input.ctx, ethMsg, priv1) | 	tx := newTestEthTx(input.ctx, ethMsg, priv1) | ||||||
| 	ctx := input.ctx.WithChainID("4") | 	ctx := input.ctx.WithChainID("4") | ||||||
| @ -229,7 +229,7 @@ func TestEthInvalidNonce(t *testing.T) { | |||||||
| 	to := ethcmn.BytesToAddress(addr2.Bytes()) | 	to := ethcmn.BytesToAddress(addr2.Bytes()) | ||||||
| 	amt := big.NewInt(32) | 	amt := big.NewInt(32) | ||||||
| 	gas := big.NewInt(20) | 	gas := big.NewInt(20) | ||||||
| 	ethMsg := evmtypes.NewEthereumTxMsg(0, to, amt, 22000, gas, []byte("test")) | 	ethMsg := evmtypes.NewEthereumTxMsg(0, &to, amt, 22000, gas, []byte("test")) | ||||||
| 
 | 
 | ||||||
| 	tx := newTestEthTx(input.ctx, ethMsg, priv1) | 	tx := newTestEthTx(input.ctx, ethMsg, priv1) | ||||||
| 	requireInvalidTx(t, input.anteHandler, input.ctx, tx, false, sdk.CodeInvalidSequence) | 	requireInvalidTx(t, input.anteHandler, input.ctx, tx, false, sdk.CodeInvalidSequence) | ||||||
| @ -249,7 +249,7 @@ func TestEthInsufficientBalance(t *testing.T) { | |||||||
| 	to := ethcmn.BytesToAddress(addr2.Bytes()) | 	to := ethcmn.BytesToAddress(addr2.Bytes()) | ||||||
| 	amt := big.NewInt(32) | 	amt := big.NewInt(32) | ||||||
| 	gas := big.NewInt(20) | 	gas := big.NewInt(20) | ||||||
| 	ethMsg := evmtypes.NewEthereumTxMsg(0, to, amt, 22000, gas, []byte("test")) | 	ethMsg := evmtypes.NewEthereumTxMsg(0, &to, amt, 22000, gas, []byte("test")) | ||||||
| 
 | 
 | ||||||
| 	tx := newTestEthTx(input.ctx, ethMsg, priv1) | 	tx := newTestEthTx(input.ctx, ethMsg, priv1) | ||||||
| 	requireInvalidTx(t, input.anteHandler, input.ctx, tx, false, sdk.CodeInsufficientFunds) | 	requireInvalidTx(t, input.anteHandler, input.ctx, tx, false, sdk.CodeInsufficientFunds) | ||||||
| @ -272,7 +272,7 @@ func TestEthInvalidIntrinsicGas(t *testing.T) { | |||||||
| 	amt := big.NewInt(32) | 	amt := big.NewInt(32) | ||||||
| 	gas := big.NewInt(20) | 	gas := big.NewInt(20) | ||||||
| 	gasLimit := uint64(1000) | 	gasLimit := uint64(1000) | ||||||
| 	ethMsg := evmtypes.NewEthereumTxMsg(0, to, amt, gasLimit, gas, []byte("test")) | 	ethMsg := evmtypes.NewEthereumTxMsg(0, &to, amt, gasLimit, gas, []byte("test")) | ||||||
| 
 | 
 | ||||||
| 	tx := newTestEthTx(input.ctx, ethMsg, priv1) | 	tx := newTestEthTx(input.ctx, ethMsg, priv1) | ||||||
| 	requireInvalidTx(t, input.anteHandler, input.ctx, tx, false, sdk.CodeInternal) | 	requireInvalidTx(t, input.anteHandler, input.ctx, tx, false, sdk.CodeInternal) | ||||||
| @ -295,7 +295,7 @@ func TestEthInvalidMempoolFees(t *testing.T) { | |||||||
| 	to := ethcmn.BytesToAddress(addr2.Bytes()) | 	to := ethcmn.BytesToAddress(addr2.Bytes()) | ||||||
| 	amt := big.NewInt(32) | 	amt := big.NewInt(32) | ||||||
| 	gas := big.NewInt(20) | 	gas := big.NewInt(20) | ||||||
| 	ethMsg := evmtypes.NewEthereumTxMsg(0, to, amt, 22000, gas, []byte("test")) | 	ethMsg := evmtypes.NewEthereumTxMsg(0, &to, amt, 22000, gas, []byte("test")) | ||||||
| 
 | 
 | ||||||
| 	tx := newTestEthTx(input.ctx, ethMsg, priv1) | 	tx := newTestEthTx(input.ctx, ethMsg, priv1) | ||||||
| 	requireInvalidTx(t, input.anteHandler, input.ctx, tx, false, sdk.CodeInsufficientFee) | 	requireInvalidTx(t, input.anteHandler, input.ctx, tx, false, sdk.CodeInsufficientFee) | ||||||
| @ -317,7 +317,7 @@ func TestEthInvalidChainID(t *testing.T) { | |||||||
| 	to := ethcmn.BytesToAddress(addr2.Bytes()) | 	to := ethcmn.BytesToAddress(addr2.Bytes()) | ||||||
| 	amt := big.NewInt(32) | 	amt := big.NewInt(32) | ||||||
| 	gas := big.NewInt(20) | 	gas := big.NewInt(20) | ||||||
| 	ethMsg := evmtypes.NewEthereumTxMsg(0, to, amt, 22000, gas, []byte("test")) | 	ethMsg := evmtypes.NewEthereumTxMsg(0, &to, amt, 22000, gas, []byte("test")) | ||||||
| 
 | 
 | ||||||
| 	tx := newTestEthTx(input.ctx, ethMsg, priv1) | 	tx := newTestEthTx(input.ctx, ethMsg, priv1) | ||||||
| 	ctx := input.ctx.WithChainID("bad-chain-id") | 	ctx := input.ctx.WithChainID("bad-chain-id") | ||||||
|  | |||||||
							
								
								
									
										106
									
								
								rpc/eth_api.go
									
									
									
									
									
								
							
							
						
						
									
										106
									
								
								rpc/eth_api.go
									
									
									
									
									
								
							| @ -9,8 +9,9 @@ import ( | |||||||
| 
 | 
 | ||||||
| 	emintcrypto "github.com/cosmos/ethermint/crypto" | 	emintcrypto "github.com/cosmos/ethermint/crypto" | ||||||
| 	emintkeys "github.com/cosmos/ethermint/keys" | 	emintkeys "github.com/cosmos/ethermint/keys" | ||||||
| 	"github.com/cosmos/ethermint/rpc/args" | 	params "github.com/cosmos/ethermint/rpc/args" | ||||||
| 	emint "github.com/cosmos/ethermint/types" | 	emint "github.com/cosmos/ethermint/types" | ||||||
|  | 	etypes "github.com/cosmos/ethermint/types" | ||||||
| 	"github.com/cosmos/ethermint/utils" | 	"github.com/cosmos/ethermint/utils" | ||||||
| 	"github.com/cosmos/ethermint/version" | 	"github.com/cosmos/ethermint/version" | ||||||
| 	"github.com/cosmos/ethermint/x/evm" | 	"github.com/cosmos/ethermint/x/evm" | ||||||
| @ -23,7 +24,6 @@ import ( | |||||||
| 	"github.com/ethereum/go-ethereum/common" | 	"github.com/ethereum/go-ethereum/common" | ||||||
| 	"github.com/ethereum/go-ethereum/common/hexutil" | 	"github.com/ethereum/go-ethereum/common/hexutil" | ||||||
| 	ethtypes "github.com/ethereum/go-ethereum/core/types" | 	ethtypes "github.com/ethereum/go-ethereum/core/types" | ||||||
| 	"github.com/ethereum/go-ethereum/core/vm" |  | ||||||
| 	"github.com/ethereum/go-ethereum/rlp" | 	"github.com/ethereum/go-ethereum/rlp" | ||||||
| 	"github.com/ethereum/go-ethereum/rpc" | 	"github.com/ethereum/go-ethereum/rpc" | ||||||
| 
 | 
 | ||||||
| @ -32,7 +32,6 @@ import ( | |||||||
| 	sdk "github.com/cosmos/cosmos-sdk/types" | 	sdk "github.com/cosmos/cosmos-sdk/types" | ||||||
| 	authutils "github.com/cosmos/cosmos-sdk/x/auth/client/utils" | 	authutils "github.com/cosmos/cosmos-sdk/x/auth/client/utils" | ||||||
| 	authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" | 	authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" | ||||||
| 
 |  | ||||||
| 	"github.com/spf13/viper" | 	"github.com/spf13/viper" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| @ -249,7 +248,7 @@ func (e *PublicEthAPI) Sign(address common.Address, data hexutil.Bytes) (hexutil | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // SendTransaction sends an Ethereum transaction.
 | // SendTransaction sends an Ethereum transaction.
 | ||||||
| func (e *PublicEthAPI) SendTransaction(args args.SendTxArgs) (common.Hash, error) { | func (e *PublicEthAPI) SendTransaction(args params.SendTxArgs) (common.Hash, error) { | ||||||
| 	// TODO: Change this functionality to find an unlocked account by address
 | 	// TODO: Change this functionality to find an unlocked account by address
 | ||||||
| 	if e.key == nil || !bytes.Equal(e.key.PubKey().Address().Bytes(), args.From.Bytes()) { | 	if e.key == nil || !bytes.Equal(e.key.PubKey().Address().Bytes(), args.From.Bytes()) { | ||||||
| 		return common.Hash{}, keystore.ErrLocked | 		return common.Hash{}, keystore.ErrLocked | ||||||
| @ -262,7 +261,7 @@ func (e *PublicEthAPI) SendTransaction(args args.SendTxArgs) (common.Hash, error | |||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// Assemble transaction from fields
 | 	// Assemble transaction from fields
 | ||||||
| 	tx, err := types.GenerateFromArgs(args, e.cliCtx) | 	tx, err := e.GenerateFromArgs(args) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return common.Hash{}, err | 		return common.Hash{}, err | ||||||
| 	} | 	} | ||||||
| @ -341,8 +340,14 @@ type CallArgs struct { | |||||||
| 
 | 
 | ||||||
| // Call performs a raw contract call.
 | // Call performs a raw contract call.
 | ||||||
| func (e *PublicEthAPI) Call(args CallArgs, blockNr rpc.BlockNumber, overrides *map[common.Address]account) (hexutil.Bytes, error) { | func (e *PublicEthAPI) Call(args CallArgs, blockNr rpc.BlockNumber, overrides *map[common.Address]account) (hexutil.Bytes, error) { | ||||||
| 	result, err := e.doCall(args, blockNr, vm.Config{}, big.NewInt(emint.DefaultRPCGasLimit)) | 	result, err := e.doCall(args, blockNr, big.NewInt(emint.DefaultRPCGasLimit)) | ||||||
| 	return (hexutil.Bytes)(result), err | 	if err != nil { | ||||||
|  | 		return []byte{}, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	_, _, ret, err := types.DecodeReturnData(result.Data) | ||||||
|  | 
 | ||||||
|  | 	return (hexutil.Bytes)(ret), err | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // account indicates the overriding fields of account during the execution of
 | // account indicates the overriding fields of account during the execution of
 | ||||||
| @ -360,7 +365,7 @@ type account struct { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // DoCall performs a simulated call operation through the evm
 | // DoCall performs a simulated call operation through the evm
 | ||||||
| func (e *PublicEthAPI) doCall(args CallArgs, blockNr rpc.BlockNumber, vmCfg vm.Config, globalGasCap *big.Int) ([]byte, error) { | func (e *PublicEthAPI) doCall(args CallArgs, blockNr rpc.BlockNumber, globalGasCap *big.Int) (sdk.Result, error) { | ||||||
| 	// Set height for historical queries
 | 	// Set height for historical queries
 | ||||||
| 	ctx := e.cliCtx.WithHeight(blockNr.Int64()) | 	ctx := e.cliCtx.WithHeight(blockNr.Int64()) | ||||||
| 
 | 
 | ||||||
| @ -421,28 +426,31 @@ func (e *PublicEthAPI) doCall(args CallArgs, blockNr rpc.BlockNumber, vmCfg vm.C | |||||||
| 	txEncoder := authutils.GetTxEncoder(ctx.Codec) | 	txEncoder := authutils.GetTxEncoder(ctx.Codec) | ||||||
| 	txBytes, err := txEncoder(tx) | 	txBytes, err := txEncoder(tx) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return []byte{}, err | 		return sdk.Result{}, err | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// Transaction simulation through query
 | 	// Transaction simulation through query
 | ||||||
| 	res, _, err := ctx.QueryWithData("app/simulate", txBytes) | 	res, _, err := ctx.QueryWithData("app/simulate", txBytes) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return []byte{}, err | 		return sdk.Result{}, err | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	var simResult sdk.Result | 	var simResult sdk.Result | ||||||
| 	if err = ctx.Codec.UnmarshalBinaryLengthPrefixed(res, &simResult); err != nil { | 	if err = e.cliCtx.Codec.UnmarshalBinaryLengthPrefixed(res, &simResult); err != nil { | ||||||
| 		return nil, err | 		return sdk.Result{}, err | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	_, _, ret, err := types.DecodeReturnData(simResult.Data) | 	return simResult, nil | ||||||
| 
 |  | ||||||
| 	return ret, err |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // EstimateGas estimates gas usage for the given smart contract call.
 | // EstimateGas estimates gas usage for the given smart contract call.
 | ||||||
| func (e *PublicEthAPI) EstimateGas(args CallArgs, blockNum BlockNumber) hexutil.Uint64 { | func (e *PublicEthAPI) EstimateGas(args CallArgs, blockNr rpc.BlockNumber) (hexutil.Uint64, error) { | ||||||
| 	return 0 | 	result, err := e.doCall(args, blockNr, big.NewInt(emint.DefaultRPCGasLimit)) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return 0, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return hexutil.Uint64(result.GasUsed), nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // GetBlockByHash returns the block identified by hash.
 | // GetBlockByHash returns the block identified by hash.
 | ||||||
| @ -844,3 +852,67 @@ func (e *PublicEthAPI) getGasLimit() (int64, error) { | |||||||
| 	e.gasLimit = &gasLimit | 	e.gasLimit = &gasLimit | ||||||
| 	return gasLimit, nil | 	return gasLimit, nil | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | // GenerateFromArgs populates tx message with args (used in RPC API)
 | ||||||
|  | func (e *PublicEthAPI) GenerateFromArgs(args params.SendTxArgs) (msg *types.EthereumTxMsg, err error) { | ||||||
|  | 	var nonce uint64 | ||||||
|  | 
 | ||||||
|  | 	var gasLimit uint64 | ||||||
|  | 
 | ||||||
|  | 	amount := (*big.Int)(args.Value) | ||||||
|  | 
 | ||||||
|  | 	gasPrice := (*big.Int)(args.GasPrice) | ||||||
|  | 
 | ||||||
|  | 	if args.GasPrice == nil { | ||||||
|  | 
 | ||||||
|  | 		// Set default gas price
 | ||||||
|  | 		// TODO: Change to min gas price from context once available through server/daemon
 | ||||||
|  | 		gasPrice = big.NewInt(etypes.DefaultGasPrice) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if args.Nonce == nil { | ||||||
|  | 		// Get nonce (sequence) from account
 | ||||||
|  | 		from := sdk.AccAddress(args.From.Bytes()) | ||||||
|  | 		_, nonce, err = authtypes.NewAccountRetriever(e.cliCtx).GetAccountNumberSequence(from) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return nil, err | ||||||
|  | 		} | ||||||
|  | 	} else { | ||||||
|  | 		nonce = (uint64)(*args.Nonce) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if args.Data != nil && args.Input != nil && !bytes.Equal(*args.Data, *args.Input) { | ||||||
|  | 		return nil, fmt.Errorf(`both "data" and "input" are set and not equal. Please use "input" to pass transaction call data`) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// Sets input to either Input or Data, if both are set and not equal error above returns
 | ||||||
|  | 	var input []byte | ||||||
|  | 	if args.Input != nil { | ||||||
|  | 		input = *args.Input | ||||||
|  | 	} else if args.Data != nil { | ||||||
|  | 		input = *args.Data | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if args.To == nil { | ||||||
|  | 		// Contract creation
 | ||||||
|  | 		if len(input) == 0 { | ||||||
|  | 			return nil, fmt.Errorf("contract creation without any data provided") | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	if args.Gas == nil { | ||||||
|  | 		callArgs := CallArgs{ | ||||||
|  | 			From:     &args.From, | ||||||
|  | 			To:       args.To, | ||||||
|  | 			Gas:      args.Gas, | ||||||
|  | 			GasPrice: args.GasPrice, | ||||||
|  | 			Value:    args.Value, | ||||||
|  | 			Data:     args.Data, | ||||||
|  | 		} | ||||||
|  | 		g, _ := e.EstimateGas(callArgs, rpc.BlockNumber(e.cliCtx.Height)) | ||||||
|  | 		gasLimit = uint64(g) | ||||||
|  | 	} else { | ||||||
|  | 		gasLimit = (uint64)(*args.Gas) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return types.NewEthereumTxMsg(nonce, args.To, amount, gasLimit, gasPrice, input), nil | ||||||
|  | } | ||||||
|  | |||||||
| @ -71,9 +71,9 @@ func GetCmdGenTx(cdc *codec.Codec) *cobra.Command { | |||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			payload := args[4] | 			payload := args[4] | ||||||
| 
 | 			addr := ethcmn.HexToAddress(args[0]) | ||||||
| 			// TODO: Remove explicit photon check and check variables
 | 			// TODO: Remove explicit photon check and check variables
 | ||||||
| 			msg := types.NewEthereumTxMsg(0, ethcmn.HexToAddress(args[0]), big.NewInt(coins.AmountOf(emintTypes.DenomDefault).Int64()), gasLimit, new(big.Int).SetUint64(gasPrice), []byte(payload)) | 			msg := types.NewEthereumTxMsg(0, &addr, big.NewInt(coins.AmountOf(emintTypes.DenomDefault).Int64()), gasLimit, new(big.Int).SetUint64(gasPrice), []byte(payload)) | ||||||
| 			err = msg.ValidateBasic() | 			err = msg.ValidateBasic() | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				return err | 				return err | ||||||
| @ -125,7 +125,8 @@ func GetCmdGenETHTx(cdc *codec.Codec) *cobra.Command { | |||||||
| 
 | 
 | ||||||
| 			var tx *types.EthereumTxMsg | 			var tx *types.EthereumTxMsg | ||||||
| 			if len(args) == 5 { | 			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)) | 				addr := ethcmn.HexToAddress(args[4]) | ||||||
|  | 				tx = types.NewEthereumTxMsg(txBldr.Sequence(), &addr, big.NewInt(coins.AmountOf(emintTypes.DenomDefault).Int64()), gasLimit, new(big.Int).SetUint64(gasPrice), []byte(payload)) | ||||||
| 			} else { | 			} else { | ||||||
| 				tx = types.NewEthereumTxMsgContract(txBldr.Sequence(), big.NewInt(coins.AmountOf(emintTypes.DenomDefault).Int64()), gasLimit, new(big.Int).SetUint64(gasPrice), []byte(payload)) | 				tx = types.NewEthereumTxMsgContract(txBldr.Sequence(), big.NewInt(coins.AmountOf(emintTypes.DenomDefault).Int64()), gasLimit, new(big.Int).SetUint64(gasPrice), []byte(payload)) | ||||||
| 			} | 			} | ||||||
|  | |||||||
| @ -1,21 +1,16 @@ | |||||||
| package types | package types | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"bytes" |  | ||||||
| 	"crypto/ecdsa" | 	"crypto/ecdsa" | ||||||
| 	"errors" | 	"errors" | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"io" | 	"io" | ||||||
| 	"math/big" | 	"math/big" | ||||||
| 	"sync/atomic" | 	"sync/atomic" | ||||||
| 
 |  | ||||||
| 	"github.com/cosmos/cosmos-sdk/codec" | 	"github.com/cosmos/cosmos-sdk/codec" | ||||||
| 	sdk "github.com/cosmos/cosmos-sdk/types" | 	sdk "github.com/cosmos/cosmos-sdk/types" | ||||||
| 	authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" |  | ||||||
| 	"github.com/cosmos/ethermint/rpc/args" |  | ||||||
| 	"github.com/cosmos/ethermint/types" | 	"github.com/cosmos/ethermint/types" | ||||||
| 
 | 
 | ||||||
| 	"github.com/cosmos/cosmos-sdk/client/context" |  | ||||||
| 	ethcmn "github.com/ethereum/go-ethereum/common" | 	ethcmn "github.com/ethereum/go-ethereum/common" | ||||||
| 	ethtypes "github.com/ethereum/go-ethereum/core/types" | 	ethtypes "github.com/ethereum/go-ethereum/core/types" | ||||||
| 	ethcrypto "github.com/ethereum/go-ethereum/crypto" | 	ethcrypto "github.com/ethereum/go-ethereum/crypto" | ||||||
| @ -75,11 +70,11 @@ type ( | |||||||
| 
 | 
 | ||||||
| // NewEthereumTxMsg returns a reference to a new Ethereum transaction message.
 | // NewEthereumTxMsg returns a reference to a new Ethereum transaction message.
 | ||||||
| func NewEthereumTxMsg( | func NewEthereumTxMsg( | ||||||
| 	nonce uint64, to ethcmn.Address, amount *big.Int, | 	nonce uint64, to *ethcmn.Address, amount *big.Int, | ||||||
| 	gasLimit uint64, gasPrice *big.Int, payload []byte, | 	gasLimit uint64, gasPrice *big.Int, payload []byte, | ||||||
| ) *EthereumTxMsg { | ) *EthereumTxMsg { | ||||||
| 
 | 
 | ||||||
| 	return newEthereumTxMsg(nonce, &to, amount, gasLimit, gasPrice, payload) | 	return newEthereumTxMsg(nonce, to, amount, gasLimit, gasPrice, payload) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // NewEthereumTxMsgContract returns a reference to a new Ethereum transaction
 | // NewEthereumTxMsgContract returns a reference to a new Ethereum transaction
 | ||||||
| @ -376,61 +371,4 @@ func recoverEthSig(R, S, Vb *big.Int, sigHash ethcmn.Hash) (ethcmn.Address, erro | |||||||
| 	copy(addr[:], ethcrypto.Keccak256(pub[1:])[12:]) | 	copy(addr[:], ethcrypto.Keccak256(pub[1:])[12:]) | ||||||
| 
 | 
 | ||||||
| 	return addr, nil | 	return addr, nil | ||||||
| } | } | ||||||
| 
 |  | ||||||
| // GenerateFromArgs populates tx message with args (used in RPC API)
 |  | ||||||
| func GenerateFromArgs(args args.SendTxArgs, ctx context.CLIContext) (msg *EthereumTxMsg, err error) { |  | ||||||
| 	var nonce uint64 |  | ||||||
| 
 |  | ||||||
| 	var gasLimit uint64 |  | ||||||
| 
 |  | ||||||
| 	amount := (*big.Int)(args.Value) |  | ||||||
| 
 |  | ||||||
| 	gasPrice := (*big.Int)(args.GasPrice) |  | ||||||
| 
 |  | ||||||
| 	if args.GasPrice == nil { |  | ||||||
| 		// Set default gas price
 |  | ||||||
| 		// TODO: Change to min gas price from context once available through server/daemon
 |  | ||||||
| 		gasPrice = big.NewInt(types.DefaultGasPrice) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if args.Nonce == nil { |  | ||||||
| 		// Get nonce (sequence) from account
 |  | ||||||
| 		from := sdk.AccAddress(args.From.Bytes()) |  | ||||||
| 		_, nonce, err = authtypes.NewAccountRetriever(ctx).GetAccountNumberSequence(from) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return nil, err |  | ||||||
| 		} |  | ||||||
| 	} else { |  | ||||||
| 		nonce = (uint64)(*args.Nonce) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if args.Data != nil && args.Input != nil && !bytes.Equal(*args.Data, *args.Input) { |  | ||||||
| 		return nil, fmt.Errorf(`both "data" and "input" are set and not equal. Please use "input" to pass transaction call data`) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	// Sets input to either Input or Data, if both are set and not equal error above returns
 |  | ||||||
| 	var input []byte |  | ||||||
| 	if args.Input != nil { |  | ||||||
| 		input = *args.Input |  | ||||||
| 	} else if args.Data != nil { |  | ||||||
| 		input = *args.Data |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if args.To == nil { |  | ||||||
| 		// Contract creation
 |  | ||||||
| 		if len(input) == 0 { |  | ||||||
| 			return nil, fmt.Errorf("contract creation without any data provided") |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if args.Gas == nil { |  | ||||||
| 		// Estimate the gas usage if necessary.
 |  | ||||||
| 		// TODO: Set gas based on estimate when simulating txs are setup
 |  | ||||||
| 		gasLimit = 60000 |  | ||||||
| 	} else { |  | ||||||
| 		gasLimit = (uint64)(*args.Gas) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	return newEthereumTxMsg(nonce, args.To, amount, gasLimit, gasPrice, input), nil |  | ||||||
| } |  | ||||||
| @ -19,7 +19,7 @@ import ( | |||||||
| func TestMsgEthereumTx(t *testing.T) { | func TestMsgEthereumTx(t *testing.T) { | ||||||
| 	addr := GenerateEthAddress() | 	addr := GenerateEthAddress() | ||||||
| 
 | 
 | ||||||
| 	msg1 := NewEthereumTxMsg(0, addr, nil, 100000, nil, []byte("test")) | 	msg1 := NewEthereumTxMsg(0, &addr, nil, 100000, nil, []byte("test")) | ||||||
| 	require.NotNil(t, msg1) | 	require.NotNil(t, msg1) | ||||||
| 	require.Equal(t, *msg1.Data.Recipient, addr) | 	require.Equal(t, *msg1.Data.Recipient, addr) | ||||||
| 
 | 
 | ||||||
| @ -27,7 +27,7 @@ func TestMsgEthereumTx(t *testing.T) { | |||||||
| 	require.NotNil(t, msg2) | 	require.NotNil(t, msg2) | ||||||
| 	require.Nil(t, msg2.Data.Recipient) | 	require.Nil(t, msg2.Data.Recipient) | ||||||
| 
 | 
 | ||||||
| 	msg3 := NewEthereumTxMsg(0, addr, nil, 100000, nil, []byte("test")) | 	msg3 := NewEthereumTxMsg(0, &addr, nil, 100000, nil, []byte("test")) | ||||||
| 	require.Equal(t, msg3.Route(), RouteEthereumTxMsg) | 	require.Equal(t, msg3.Route(), RouteEthereumTxMsg) | ||||||
| 	require.Equal(t, msg3.Type(), TypeEthereumTxMsg) | 	require.Equal(t, msg3.Type(), TypeEthereumTxMsg) | ||||||
| 	require.Panics(t, func() { msg3.GetSigners() }) | 	require.Panics(t, func() { msg3.GetSigners() }) | ||||||
| @ -50,7 +50,7 @@ func TestMsgEthereumTxValidation(t *testing.T) { | |||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	for i, tc := range testCases { | 	for i, tc := range testCases { | ||||||
| 		msg := NewEthereumTxMsg(tc.nonce, tc.to, tc.amount, tc.gasLimit, tc.gasPrice, tc.payload) | 		msg := NewEthereumTxMsg(tc.nonce, &tc.to, tc.amount, tc.gasLimit, tc.gasPrice, tc.payload) | ||||||
| 
 | 
 | ||||||
| 		if tc.expectPass { | 		if tc.expectPass { | ||||||
| 			require.Nil(t, msg.ValidateBasic(), "test: %v", i) | 			require.Nil(t, msg.ValidateBasic(), "test: %v", i) | ||||||
| @ -64,14 +64,14 @@ func TestMsgEthereumTxRLPSignBytes(t *testing.T) { | |||||||
| 	addr := ethcmn.BytesToAddress([]byte("test_address")) | 	addr := ethcmn.BytesToAddress([]byte("test_address")) | ||||||
| 	chainID := big.NewInt(3) | 	chainID := big.NewInt(3) | ||||||
| 
 | 
 | ||||||
| 	msg := NewEthereumTxMsg(0, addr, nil, 100000, nil, []byte("test")) | 	msg := NewEthereumTxMsg(0, &addr, nil, 100000, nil, []byte("test")) | ||||||
| 	hash := msg.RLPSignBytes(chainID) | 	hash := msg.RLPSignBytes(chainID) | ||||||
| 	require.Equal(t, "5BD30E35AD27449390B14C91E6BCFDCAADF8FE44EF33680E3BC200FC0DC083C7", fmt.Sprintf("%X", hash)) | 	require.Equal(t, "5BD30E35AD27449390B14C91E6BCFDCAADF8FE44EF33680E3BC200FC0DC083C7", fmt.Sprintf("%X", hash)) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func TestMsgEthereumTxRLPEncode(t *testing.T) { | func TestMsgEthereumTxRLPEncode(t *testing.T) { | ||||||
| 	addr := ethcmn.BytesToAddress([]byte("test_address")) | 	addr := ethcmn.BytesToAddress([]byte("test_address")) | ||||||
| 	msg := NewEthereumTxMsg(0, addr, nil, 100000, nil, []byte("test")) | 	msg := NewEthereumTxMsg(0, &addr, nil, 100000, nil, []byte("test")) | ||||||
| 
 | 
 | ||||||
| 	raw, err := rlp.EncodeToBytes(msg) | 	raw, err := rlp.EncodeToBytes(msg) | ||||||
| 	require.NoError(t, err) | 	require.NoError(t, err) | ||||||
| @ -83,7 +83,7 @@ func TestMsgEthereumTxRLPDecode(t *testing.T) { | |||||||
| 
 | 
 | ||||||
| 	raw := ethcmn.FromHex("E48080830186A0940000000000000000746573745F61646472657373808474657374808080") | 	raw := ethcmn.FromHex("E48080830186A0940000000000000000746573745F61646472657373808474657374808080") | ||||||
| 	addr := ethcmn.BytesToAddress([]byte("test_address")) | 	addr := ethcmn.BytesToAddress([]byte("test_address")) | ||||||
| 	expectedMsg := NewEthereumTxMsg(0, addr, nil, 100000, nil, []byte("test")) | 	expectedMsg := NewEthereumTxMsg(0, &addr, nil, 100000, nil, []byte("test")) | ||||||
| 
 | 
 | ||||||
| 	err := rlp.Decode(bytes.NewReader(raw), &msg) | 	err := rlp.Decode(bytes.NewReader(raw), &msg) | ||||||
| 	require.NoError(t, err) | 	require.NoError(t, err) | ||||||
| @ -92,7 +92,7 @@ func TestMsgEthereumTxRLPDecode(t *testing.T) { | |||||||
| 
 | 
 | ||||||
| func TestMsgEthereumTxHash(t *testing.T) { | func TestMsgEthereumTxHash(t *testing.T) { | ||||||
| 	addr := ethcmn.BytesToAddress([]byte("test_address")) | 	addr := ethcmn.BytesToAddress([]byte("test_address")) | ||||||
| 	msg := NewEthereumTxMsg(0, addr, nil, 100000, nil, []byte("test")) | 	msg := NewEthereumTxMsg(0, &addr, nil, 100000, nil, []byte("test")) | ||||||
| 
 | 
 | ||||||
| 	hash := msg.Hash() | 	hash := msg.Hash() | ||||||
| 	require.Equal(t, "E2AA2E68E7586AE9700F1D3D643330866B6AC2B6CA4C804F7C85ECB11D0B0B29", fmt.Sprintf("%X", hash)) | 	require.Equal(t, "E2AA2E68E7586AE9700F1D3D643330866B6AC2B6CA4C804F7C85ECB11D0B0B29", fmt.Sprintf("%X", hash)) | ||||||
| @ -107,7 +107,7 @@ func TestMsgEthereumTxSig(t *testing.T) { | |||||||
| 	addr2 := ethcmn.BytesToAddress(priv2.PubKey().Address().Bytes()) | 	addr2 := ethcmn.BytesToAddress(priv2.PubKey().Address().Bytes()) | ||||||
| 
 | 
 | ||||||
| 	// require valid signature passes validation
 | 	// require valid signature passes validation
 | ||||||
| 	msg := NewEthereumTxMsg(0, addr1, nil, 100000, nil, []byte("test")) | 	msg := NewEthereumTxMsg(0, &addr1, nil, 100000, nil, []byte("test")) | ||||||
| 	msg.Sign(chainID, priv1.ToECDSA()) | 	msg.Sign(chainID, priv1.ToECDSA()) | ||||||
| 
 | 
 | ||||||
| 	signer, err := msg.VerifySig(chainID) | 	signer, err := msg.VerifySig(chainID) | ||||||
| @ -116,7 +116,7 @@ func TestMsgEthereumTxSig(t *testing.T) { | |||||||
| 	require.NotEqual(t, addr2, signer) | 	require.NotEqual(t, addr2, signer) | ||||||
| 
 | 
 | ||||||
| 	// require invalid chain ID fail validation
 | 	// require invalid chain ID fail validation
 | ||||||
| 	msg = NewEthereumTxMsg(0, addr1, nil, 100000, nil, []byte("test")) | 	msg = NewEthereumTxMsg(0, &addr1, nil, 100000, nil, []byte("test")) | ||||||
| 	msg.Sign(chainID, priv1.ToECDSA()) | 	msg.Sign(chainID, priv1.ToECDSA()) | ||||||
| 
 | 
 | ||||||
| 	signer, err = msg.VerifySig(big.NewInt(4)) | 	signer, err = msg.VerifySig(big.NewInt(4)) | ||||||
| @ -126,7 +126,7 @@ func TestMsgEthereumTxSig(t *testing.T) { | |||||||
| 
 | 
 | ||||||
| func TestMsgEthereumTxAmino(t *testing.T) { | func TestMsgEthereumTxAmino(t *testing.T) { | ||||||
| 	addr := GenerateEthAddress() | 	addr := GenerateEthAddress() | ||||||
| 	msg := NewEthereumTxMsg(5, addr, big.NewInt(1), 100000, big.NewInt(3), []byte("test")) | 	msg := NewEthereumTxMsg(5, &addr, big.NewInt(1), 100000, big.NewInt(3), []byte("test")) | ||||||
| 
 | 
 | ||||||
| 	msg.Data.V = big.NewInt(1) | 	msg.Data.V = big.NewInt(1) | ||||||
| 	msg.Data.R = big.NewInt(2) | 	msg.Data.R = big.NewInt(2) | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user