diff --git a/api/api.go b/api/api.go index 3fde8bf8f..6eb97cfd7 100644 --- a/api/api.go +++ b/api/api.go @@ -290,31 +290,54 @@ func (s *BlockChainAPI) GetTransactionCount( // eth_getTransactionByHash // GetTransactionByHash returns the transaction for the given hash -func (s *BlockChainAPI) GetTransactionByHash( +func (b *BlockChainAPI) GetTransactionByHash( ctx context.Context, hash common.Hash, ) (*RPCTransaction, error) { + txPayload, err := b.Store.GetTransactionByHash(ctx, hash) + if err != nil { + return nil, err + } + + decodedTx, err := hex.DecodeString(txPayload.Transaction) + if err != nil { + return nil, err + } + tx := &types.Transaction{} + encodedLen := uint(len(txPayload.Transaction)) + err = tx.DecodeRLP( + rlp.NewStream( + bytes.NewReader(decodedTx), + uint64(encodedLen), + ), + ) + if err != nil { + return nil, err + } + + // TODO(m-Peter): Add BlockHash to storage blockHash := common.HexToHash("0x1d59ff54b1eb26b013ce3cb5fc9dab3705b415a67127a003c3e61eb445bb8df2") - to := common.HexToAddress("0xf02c1c8e6114b1dbe8937a39260b5b0a374432bb") - index := uint64(64) + index := uint64(0) + v, r, s := tx.RawSignatureValues() - tx := &RPCTransaction{ + txResult := &RPCTransaction{ BlockHash: (*common.Hash)(&blockHash), - BlockNumber: (*hexutil.Big)(big.NewInt(6139707)), + BlockNumber: (*hexutil.Big)(big.NewInt(int64(txPayload.BlockHeight))), From: common.HexToAddress("0xa7d9ddbe1f17865597fbd27ec712455208b6b76d"), - Gas: hexutil.Uint64(50000), - GasPrice: (*hexutil.Big)(big.NewInt(20000000000)), - Hash: common.HexToHash("0x88df016429689c079f3b2f6ad39fa052532c56795b733da78a91ebe6a713944b"), - Input: hexutil.Bytes("0x68656c6c6f21"), - Nonce: hexutil.Uint64(21), - To: &to, + Gas: hexutil.Uint64(txPayload.GasConsumed), + GasPrice: (*hexutil.Big)(tx.GasPrice()), + Hash: tx.Hash(), + Input: hexutil.Bytes(tx.Data()), + Nonce: hexutil.Uint64(tx.Nonce()), + To: tx.To(), TransactionIndex: (*hexutil.Uint64)(&index), - Value: (*hexutil.Big)(big.NewInt(4290000000000000)), - V: (*hexutil.Big)(big.NewInt(37)), - R: (*hexutil.Big)(big.NewInt(150)), - S: (*hexutil.Big)(big.NewInt(250)), + Value: (*hexutil.Big)(tx.Value()), + Type: hexutil.Uint64(uint64(tx.Type())), + V: (*hexutil.Big)(v), + R: (*hexutil.Big)(r), + S: (*hexutil.Big)(s), } - return tx, nil + return txResult, nil } // eth_getTransactionByBlockHashAndIndex diff --git a/api/api_test.go b/api/api_test.go index 43e404672..8a69d396e 100644 --- a/api/api_test.go +++ b/api/api_test.go @@ -275,31 +275,54 @@ func TestBlockChainAPI(t *testing.T) { }) t.Run("GetTransactionByHash", func(t *testing.T) { + event := transactionExecutedEvent( + 3, + "0xb47d74ea64221eb941490bdc0c9a404dacd0a8573379a45c992ac60ee3e83c3c", + "b88c02f88982029a01808083124f809499466ed2e37b892a2ee3e9cd55a98b68f5735db280a4c6888fa10000000000000000000000000000000000000000000000000000000000000006c001a0f84168f821b427dc158c4d8083bdc4b43e178cf0977a2c5eefbcbedcc4e351b0a066a747a38c6c266b9dc2136523cef04395918de37773db63d574aabde59c12eb", + false, + 2, + 22514, + "0000000000000000000000000000000000000000", + "000000000000000000000000000000000000000000000000000000000000002a", + "f85af8589499466ed2e37b892a2ee3e9cd55a98b68f5735db2e1a024abdb5865df5079dcc5ac590ff6f01d5c16edbc5fab4e195d9febd1114503daa0000000000000000000000000000000000000000000000000000000000000002a", + ) + + store := blockchainAPI.Store + store.StoreTransaction(context.Background(), event) + tx, err := blockchainAPI.GetTransactionByHash( context.Background(), - common.Hash{0, 1, 2}, + common.HexToHash("0xb47d74ea64221eb941490bdc0c9a404dacd0a8573379a45c992ac60ee3e83c3c"), ) require.NoError(t, err) blockHash := common.HexToHash("0x1d59ff54b1eb26b013ce3cb5fc9dab3705b415a67127a003c3e61eb445bb8df2") - to := common.HexToAddress("0xf02c1c8e6114b1dbe8937a39260b5b0a374432bb") - index := uint64(64) + to := common.HexToAddress("0x99466ED2E37B892A2Ee3E9CD55a98b68f5735db2") + index := uint64(0) + input, err := hex.DecodeString("c6888fa10000000000000000000000000000000000000000000000000000000000000006") + require.NoError(t, err) + + r, err := hexutil.DecodeBig("0xf84168f821b427dc158c4d8083bdc4b43e178cf0977a2c5eefbcbedcc4e351b0") + require.NoError(t, err) + s, err := hexutil.DecodeBig("0x66a747a38c6c266b9dc2136523cef04395918de37773db63d574aabde59c12eb") + require.NoError(t, err) expectedTx := &api.RPCTransaction{ BlockHash: (*common.Hash)(&blockHash), - BlockNumber: (*hexutil.Big)(big.NewInt(6139707)), - From: common.HexToAddress("0xa7d9ddbe1f17865597fbd27ec712455208b6b76d"), - Gas: hexutil.Uint64(50000), - GasPrice: (*hexutil.Big)(big.NewInt(20000000000)), - Hash: common.HexToHash("0x88df016429689c079f3b2f6ad39fa052532c56795b733da78a91ebe6a713944b"), - Input: hexutil.Bytes("0x68656c6c6f21"), - Nonce: hexutil.Uint64(21), + BlockNumber: (*hexutil.Big)(big.NewInt(3)), + From: common.HexToAddress("0xa7d9ddBE1f17865597fBD27EC712455208B6B76d"), + Gas: hexutil.Uint64(22514), + GasPrice: (*hexutil.Big)(big.NewInt(0)), + Hash: common.HexToHash("0xb47d74ea64221eb941490bdc0c9a404dacd0a8573379a45c992ac60ee3e83c3c"), + Input: hexutil.Bytes(input), + Nonce: hexutil.Uint64(1), To: &to, TransactionIndex: (*hexutil.Uint64)(&index), - Value: (*hexutil.Big)(big.NewInt(4290000000000000)), - V: (*hexutil.Big)(big.NewInt(37)), - R: (*hexutil.Big)(big.NewInt(150)), - S: (*hexutil.Big)(big.NewInt(250)), + Value: (*hexutil.Big)(big.NewInt(0)), + Type: hexutil.Uint64(2), + V: (*hexutil.Big)(big.NewInt(1)), + R: (*hexutil.Big)(r), + S: (*hexutil.Big)(s), } assert.Equal(t, expectedTx, tx) diff --git a/api/fixtures/eth_json_rpc_requests.json b/api/fixtures/eth_json_rpc_requests.json index c2fad8a8b..c85bec0d6 100644 --- a/api/fixtures/eth_json_rpc_requests.json +++ b/api/fixtures/eth_json_rpc_requests.json @@ -6,7 +6,6 @@ {"jsonrpc":"2.0","id":1,"method":"eth_getCode","params":["0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b","0x2"]} {"jsonrpc":"2.0","id":1,"method":"eth_getStorageAt","params":["0x295a70b2de5e3953354a6a8344e616ed314d7251","0x6661e9d6d8b923d5bbaab1b96e1dd51ff6ea2a93520fdc9eb75d059238b8c5e9","latest"]} {"jsonrpc":"2.0","id":1,"method":"eth_getTransactionCount","params":["0x407d73d8a49eeb85d32cf465507dd71d507100c1","latest"]} -{"jsonrpc":"2.0","id":1,"method":"eth_getTransactionByHash","params":["0x88df016429689c079f3b2f6ad39fa052532c56795b733da78a91ebe6a713944b"]} {"jsonrpc":"2.0","id":1,"method":"eth_getTransactionByBlockHashAndIndex","params":["0xc6ef2fc5426d6ad6fd9e2a26abeab0aa2411b7ab17f30a99d3cb96aed1d1055b", "0x0"]} {"jsonrpc":"2.0","id":1,"method":"eth_getTransactionByBlockNumberAndIndex","params":["0x29c", "0x0"]} {"jsonrpc":"2.0","id":1,"method":"eth_coinbase"} diff --git a/api/fixtures/eth_json_rpc_responses.json b/api/fixtures/eth_json_rpc_responses.json index e5bed6052..dedab33b2 100644 --- a/api/fixtures/eth_json_rpc_responses.json +++ b/api/fixtures/eth_json_rpc_responses.json @@ -6,7 +6,6 @@ {"jsonrpc":"2.0","id":1,"result":"0x600160008035811a818181146012578301005b601b6001356025565b8060005260206000f25b600060078202905091905056"} {"jsonrpc":"2.0","id":1,"result":"0x600160008035811a818181146012578301005b601b6001356025565b8060005260206000f25b600060078202905091905056"} {"jsonrpc":"2.0","id":1,"result":"0x0"} -{"jsonrpc":"2.0","id":1,"result":{"blockHash":"0x1d59ff54b1eb26b013ce3cb5fc9dab3705b415a67127a003c3e61eb445bb8df2","blockNumber":"0x5daf3b","from":"0xa7d9ddbe1f17865597fbd27ec712455208b6b76d","gas":"0xc350","gasPrice":"0x4a817c800","hash":"0x88df016429689c079f3b2f6ad39fa052532c56795b733da78a91ebe6a713944b","input":"0x3078363836353663366336663231","nonce":"0x15","to":"0xf02c1c8e6114b1dbe8937a39260b5b0a374432bb","transactionIndex":"0x40","value":"0xf3dbb76162000","type":"0x0","v":"0x25","r":"0x96","s":"0xfa"}} {"jsonrpc":"2.0","id":1,"result":{"blockHash":"0xc6ef2fc5426d6ad6fd9e2a26abeab0aa2411b7ab17f30a99d3cb96aed1d1055b","blockNumber":"0x5daf3b","from":"0xa7d9ddbe1f17865597fbd27ec712455208b6b76d","gas":"0xc350","gasPrice":"0x4a817c800","hash":"0x88df016429689c079f3b2f6ad39fa052532c56795b733da78a91ebe6a713944b","input":"0x3078363836353663366336663231","nonce":"0x15","to":"0xf02c1c8e6114b1dbe8937a39260b5b0a374432bb","transactionIndex":"0x40","value":"0xf3dbb76162000","type":"0x0","v":"0x25","r":"0x96","s":"0xfa"}} {"jsonrpc":"2.0","id":1,"result":{"blockHash":"0x1d59ff54b1eb26b013ce3cb5fc9dab3705b415a67127a003c3e61eb445bb8df2","blockNumber":"0x5daf3b","from":"0xa7d9ddbe1f17865597fbd27ec712455208b6b76d","gas":"0xc350","gasPrice":"0x4a817c800","hash":"0x88df016429689c079f3b2f6ad39fa052532c56795b733da78a91ebe6a713944b","input":"0x3078363836353663366336663231","nonce":"0x15","to":"0xf02c1c8e6114b1dbe8937a39260b5b0a374432bb","transactionIndex":"0x40","value":"0xf3dbb76162000","type":"0x0","v":"0x25","r":"0x96","s":"0xfa"}} {"jsonrpc":"2.0","id":1,"result":"0xf02c1c8e6114b1dbe8937a39260b5b0a374432bb"} diff --git a/api/server_test.go b/api/server_test.go index 4b5fd67b2..19c0af99f 100644 --- a/api/server_test.go +++ b/api/server_test.go @@ -192,6 +192,36 @@ func TestServerJSONRPCOveHTTPHandler(t *testing.T) { assert.Equal(t, expectedResponse, strings.TrimSuffix(string(content), "\n")) }) + + t.Run("eth_getTransactionByHash", func(t *testing.T) { + request := `{"jsonrpc":"2.0","id":1,"method":"eth_getTransactionByHash","params":["0xb47d74ea64221eb941490bdc0c9a404dacd0a8573379a45c992ac60ee3e83c3c"]}` + expectedResponse := `{"jsonrpc":"2.0","id":1,"result":{"blockHash":"0x1d59ff54b1eb26b013ce3cb5fc9dab3705b415a67127a003c3e61eb445bb8df2","blockNumber":"0x3","from":"0xa7d9ddbe1f17865597fbd27ec712455208b6b76d","gas":"0x57f2","gasPrice":"0x0","hash":"0xb47d74ea64221eb941490bdc0c9a404dacd0a8573379a45c992ac60ee3e83c3c","input":"0xc6888fa10000000000000000000000000000000000000000000000000000000000000006","nonce":"0x1","to":"0x99466ed2e37b892a2ee3e9cd55a98b68f5735db2","transactionIndex":"0x0","value":"0x0","type":"0x2","v":"0x1","r":"0xf84168f821b427dc158c4d8083bdc4b43e178cf0977a2c5eefbcbedcc4e351b0","s":"0x66a747a38c6c266b9dc2136523cef04395918de37773db63d574aabde59c12eb"}}` + + event := transactionExecutedEvent( + 3, + "0xb47d74ea64221eb941490bdc0c9a404dacd0a8573379a45c992ac60ee3e83c3c", + "b88c02f88982029a01808083124f809499466ed2e37b892a2ee3e9cd55a98b68f5735db280a4c6888fa10000000000000000000000000000000000000000000000000000000000000006c001a0f84168f821b427dc158c4d8083bdc4b43e178cf0977a2c5eefbcbedcc4e351b0a066a747a38c6c266b9dc2136523cef04395918de37773db63d574aabde59c12eb", + false, + 2, + 22514, + "0000000000000000000000000000000000000000", + "000000000000000000000000000000000000000000000000000000000000002a", + "f85af8589499466ed2e37b892a2ee3e9cd55a98b68f5735db2e1a024abdb5865df5079dcc5ac590ff6f01d5c16edbc5fab4e195d9febd1114503daa0000000000000000000000000000000000000000000000000000000000000002a", + ) + + err := store.StoreTransaction(context.Background(), event) + require.NoError(t, err) + + resp := rpcRequest(url, request, "origin", "test.com") + defer resp.Body.Close() + + content, err := io.ReadAll(resp.Body) + if err != nil { + panic(err) + } + + assert.Equal(t, expectedResponse, strings.TrimSuffix(string(content), "\n")) + }) } func TestServerJSONRPCOveWebSocketHandler(t *testing.T) {