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
This commit is contained in:
Austin Abell 2019-09-18 16:14:39 -04:00 committed by GitHub
parent 69567e29d5
commit 2ca42cc155
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 31 additions and 5 deletions

View File

@ -3,6 +3,7 @@ package rpc
import ( import (
"fmt" "fmt"
"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/client/lcd" "github.com/cosmos/cosmos-sdk/client/lcd"
"github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/codec"
emintcrypto "github.com/cosmos/ethermint/crypto" emintcrypto "github.com/cosmos/ethermint/crypto"
@ -35,8 +36,8 @@ type Config struct {
// Web3RpcCmd creates a CLI command to start RPC server // Web3RpcCmd creates a CLI command to start RPC server
func Web3RpcCmd(cdc *codec.Codec) *cobra.Command { func Web3RpcCmd(cdc *codec.Codec) *cobra.Command {
cmd := lcd.ServeCommand(cdc, registerRoutes) 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().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 return cmd
} }

View File

@ -6,6 +6,7 @@ import (
"math/big" "math/big"
"github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/client/context"
authutils "github.com/cosmos/cosmos-sdk/x/auth/client/utils"
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/version" "github.com/cosmos/ethermint/version"
@ -14,6 +15,7 @@ import (
"github.com/ethereum/go-ethereum/accounts/keystore" "github.com/ethereum/go-ethereum/accounts/keystore"
"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"
"github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/rpc" "github.com/ethereum/go-ethereum/rpc"
"github.com/ethereum/go-ethereum/signer/core" "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. // SendRawTransaction send a raw Ethereum transaction.
func (e *PublicEthAPI) SendRawTransaction(data hexutil.Bytes) common.Hash { func (e *PublicEthAPI) SendRawTransaction(data hexutil.Bytes) (common.Hash, error) {
var h common.Hash tx := new(types.EthereumTxMsg)
return h
// 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. // CallArgs represents arguments to a smart contract call as provided by RPC clients.

View File

@ -131,7 +131,8 @@ func (msg EthereumTxMsg) ValidateBasic() sdk.Error {
return types.ErrInvalidValue(fmt.Sprintf("Price must be positive: %x", msg.Data.Price)) 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)) return types.ErrInvalidValue(fmt.Sprintf("amount must be positive: %x", msg.Data.Amount))
} }