From 2ca42cc155a68f1e700a2c123e3706c82b6f9aaa Mon Sep 17 00:00:00 2001 From: Austin Abell Date: Wed, 18 Sep 2019 16:14:39 -0400 Subject: [PATCH] Implement eth_sendRawTransaction (#101) * Implement sendRawTransaction (tx not being broadcasted to node from server) * Add broadcast type flag to rpc API and fixed amount validation * Add documentation --- rpc/config.go | 3 ++- rpc/eth_api.go | 30 +++++++++++++++++++++++++++--- x/evm/types/msg.go | 3 ++- 3 files changed, 31 insertions(+), 5 deletions(-) diff --git a/rpc/config.go b/rpc/config.go index 790b1a5d..72afbae1 100644 --- a/rpc/config.go +++ b/rpc/config.go @@ -3,6 +3,7 @@ package rpc import ( "fmt" + "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/client/lcd" "github.com/cosmos/cosmos-sdk/codec" emintcrypto "github.com/cosmos/ethermint/crypto" @@ -35,8 +36,8 @@ type Config struct { // Web3RpcCmd creates a CLI command to start RPC server func Web3RpcCmd(cdc *codec.Codec) *cobra.Command { cmd := lcd.ServeCommand(cdc, registerRoutes) - // Attach flag to cmd output to be handled in registerRoutes cmd.Flags().String(flagUnlockKey, "", "Select a key to unlock on the RPC server") + cmd.Flags().StringP(flags.FlagBroadcastMode, "b", flags.BroadcastSync, "Transaction broadcasting mode (sync|async|block)") return cmd } diff --git a/rpc/eth_api.go b/rpc/eth_api.go index f01997a5..4acc00e2 100644 --- a/rpc/eth_api.go +++ b/rpc/eth_api.go @@ -6,6 +6,7 @@ import ( "math/big" "github.com/cosmos/cosmos-sdk/client/context" + authutils "github.com/cosmos/cosmos-sdk/x/auth/client/utils" emintcrypto "github.com/cosmos/ethermint/crypto" emintkeys "github.com/cosmos/ethermint/keys" "github.com/cosmos/ethermint/version" @@ -14,6 +15,7 @@ import ( "github.com/ethereum/go-ethereum/accounts/keystore" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rpc" "github.com/ethereum/go-ethereum/signer/core" ) @@ -204,9 +206,31 @@ func (e *PublicEthAPI) SendTransaction(args core.SendTxArgs) common.Hash { } // SendRawTransaction send a raw Ethereum transaction. -func (e *PublicEthAPI) SendRawTransaction(data hexutil.Bytes) common.Hash { - var h common.Hash - return h +func (e *PublicEthAPI) SendRawTransaction(data hexutil.Bytes) (common.Hash, error) { + tx := new(types.EthereumTxMsg) + + // RLP decode raw transaction bytes + if err := rlp.DecodeBytes(data, tx); err != nil { + // Return nil is for when gasLimit overflows uint64 + return common.Hash{}, nil + } + + // Encode transaction by default Tx encoder + txEncoder := authutils.GetTxEncoder(e.cliCtx.Codec) + txBytes, err := txEncoder(tx) + if err != nil { + return common.Hash{}, err + } + + // TODO: Possibly log the contract creation address (if recipient address is nil) or tx data + res, err := e.cliCtx.BroadcastTx(txBytes) + // If error is encountered on the node, the broadcast will not return an error + fmt.Println(res.RawLog) + if err != nil { + return common.Hash{}, err + } + + return common.HexToHash(res.TxHash), nil } // CallArgs represents arguments to a smart contract call as provided by RPC clients. diff --git a/x/evm/types/msg.go b/x/evm/types/msg.go index b2383102..b9ecd9a3 100644 --- a/x/evm/types/msg.go +++ b/x/evm/types/msg.go @@ -131,7 +131,8 @@ func (msg EthereumTxMsg) ValidateBasic() sdk.Error { return types.ErrInvalidValue(fmt.Sprintf("Price must be positive: %x", msg.Data.Price)) } - if msg.Data.Amount.Sign() != 1 { + // Amount can be 0 + if msg.Data.Amount.Sign() == -1 { return types.ErrInvalidValue(fmt.Sprintf("amount must be positive: %x", msg.Data.Amount)) }