Implements eth_getTransactionByHash (#108)

* Implement eth_getTransactionByHash and add function for converting bytes to eth tx

* Fix nil return on invalid hash

* Fix error check
This commit is contained in:
Austin Abell 2019-09-24 21:58:29 -04:00 committed by GitHub
parent 9383c743dd
commit cfca4d10e6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -387,10 +387,8 @@ func convertTransactionsToRPC(cliCtx context.CLIContext, txs []tmtypes.Tx, block
transactions := make([]interface{}, len(txs)) transactions := make([]interface{}, len(txs))
gasUsed := big.NewInt(0) gasUsed := big.NewInt(0)
for i, tx := range txs { for i, tx := range txs {
var stdTx sdk.Tx ethTx, err := bytesToEthTx(cliCtx, tx)
err := cliCtx.Codec.UnmarshalBinaryLengthPrefixed(tx, &stdTx) if err != nil {
ethTx, ok := stdTx.(*types.EthereumTxMsg)
if !ok || err != nil {
continue continue
} }
// TODO: Remove gas usage calculation if saving gasUsed per block // TODO: Remove gas usage calculation if saving gasUsed per block
@ -418,6 +416,16 @@ type Transaction struct {
S *hexutil.Big `json:"s"` S *hexutil.Big `json:"s"`
} }
func bytesToEthTx(cliCtx context.CLIContext, bz []byte) (*types.EthereumTxMsg, error) {
var stdTx sdk.Tx
err := cliCtx.Codec.UnmarshalBinaryLengthPrefixed(bz, &stdTx)
ethTx, ok := stdTx.(*types.EthereumTxMsg)
if !ok || err != nil {
return nil, fmt.Errorf("Invalid transaction type, must be an amino encoded Ethereum transaction")
}
return ethTx, nil
}
// newRPCTransaction returns a transaction that will serialize to the RPC // newRPCTransaction returns a transaction that will serialize to the RPC
// representation, with the given location metadata set (if available). // representation, with the given location metadata set (if available).
func newRPCTransaction(tx *types.EthereumTxMsg, blockHash common.Hash, blockNumber uint64, index uint64) *Transaction { func newRPCTransaction(tx *types.EthereumTxMsg, blockHash common.Hash, blockNumber uint64, index uint64) *Transaction {
@ -446,8 +454,26 @@ func newRPCTransaction(tx *types.EthereumTxMsg, blockHash common.Hash, blockNumb
} }
// GetTransactionByHash returns the transaction identified by hash. // GetTransactionByHash returns the transaction identified by hash.
func (e *PublicEthAPI) GetTransactionByHash(hash common.Hash) *Transaction { func (e *PublicEthAPI) GetTransactionByHash(hash common.Hash) (*Transaction, error) {
return nil tx, err := e.cliCtx.Client.Tx(hash.Bytes(), false)
if err != nil {
// Return nil for transaction when not found
return nil, nil
}
// Can either cache or just leave this out if not necessary
block, err := e.cliCtx.Client.Block(&tx.Height)
if err != nil {
return nil, err
}
blockHash := common.BytesToHash(block.BlockMeta.Header.ConsensusHash)
ethTx, err := bytesToEthTx(e.cliCtx, tx.Tx)
if err != nil {
return nil, err
}
return newRPCTransaction(ethTx, blockHash, uint64(tx.Height), uint64(tx.Index)), nil
} }
// GetTransactionByBlockHashAndIndex returns the transaction identified by hash and index. // GetTransactionByBlockHashAndIndex returns the transaction identified by hash and index.