Skip to content
This repository was archived by the owner on Jan 9, 2024. It is now read-only.

Commit 7781182

Browse files
authored
Implementation of the API eth_getTransactionByBlockHashAndIndex (#61)
1 parent 234a099 commit 7781182

File tree

7 files changed

+113
-2
lines changed

7 files changed

+113
-2
lines changed

docs/API.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ The following table shows the current [JSON RPC API](https://eth.wiki/json-rpc/A
2727
| eth_getUncleCountByBlockNumber | Yes | |
2828
| | | |
2929
| eth_getTransactionByHash | - | not yet implemented |
30-
| eth_getTransactionByBlockHashAndIndex | - | not yet implemented |
30+
| eth_getTransactionByBlockHashAndIndex | Yes | |
3131
| eth_getTransactionByBlockNumberAndIndex | Yes | |
3232
| eth_getTransactionReceipt | - | not yet implemented |
3333
| | | |

silkrpc/commands/eth_api.cpp

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
#include <silkrpc/types/block.hpp>
4040
#include <silkrpc/types/call.hpp>
4141
#include <silkrpc/types/filter.hpp>
42+
#include <silkrpc/types/transaction.hpp>
4243

4344
namespace silkrpc::commands {
4445

@@ -456,12 +457,36 @@ asio::awaitable<void> EthereumRpcApi::handle_eth_get_transaction_by_hash(const n
456457

457458
// https://eth.wiki/json-rpc/API#eth_gettransactionbyblockhashandindex
458459
asio::awaitable<void> EthereumRpcApi::handle_eth_get_transaction_by_block_hash_and_index(const nlohmann::json& request, nlohmann::json& reply) {
460+
auto params = request["params"];
461+
if (params.size() != 2) {
462+
auto error_msg = "invalid eth_getTransactionByBlockHashAndIndex params: " + params.dump();
463+
SILKRPC_ERROR << error_msg << "\n";
464+
reply = make_json_error(request["id"], 100, error_msg);
465+
co_return;
466+
}
467+
auto block_hash = params[0].get<evmc::bytes32>();
468+
auto index_string = params[1].get<std::string>();
469+
SILKRPC_DEBUG << "block_hash: " << block_hash << " index: " << index_string << "\n";
470+
459471
auto tx = co_await database_->begin();
460472

461473
try {
462474
ethdb::TransactionDatabase tx_database{*tx};
475+
const auto block_with_hash = co_await core::rawdb::read_block_by_hash(tx_database, block_hash);
463476

464-
reply = make_json_content(request["id"], "0x" + to_hex_no_leading_zeros(0));
477+
const auto transactions = block_with_hash.block.transactions;
478+
479+
auto index = std::stoul(index_string, 0, 16);
480+
if (index >= transactions.size()) {
481+
const auto error_msg = "Requested transaction not found " + index_string;
482+
SILKRPC_DEBUG << error_msg << "\n";
483+
reply = make_json_content(request["id"], nullptr);
484+
co_return;
485+
}
486+
487+
silkrpc::Transaction new_transaction{{transactions[index]}, {block_with_hash.hash}, {block_with_hash.block.header.number}, {index}};
488+
489+
reply = make_json_content(request["id"], new_transaction);
465490
} catch (const std::exception& e) {
466491
SILKRPC_ERROR << "exception: " << e.what() << "\n";
467492
reply = make_json_error(request["id"], 100, e.what());

silkrpc/json/types.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,15 @@ void to_json(nlohmann::json& json, const Block& b) {
163163
json["uncles"] = b.block.ommers;
164164
}
165165

166+
void to_json(nlohmann::json& json, const Transaction& transaction) {
167+
to_json(json, silkworm::Transaction(transaction));
168+
169+
const auto block_number = "0x" + silkrpc::to_hex_no_leading_zeros(transaction.block_number);
170+
json["blockHash"] = transaction.block_hash;
171+
json["blockNumber"] = block_number;
172+
json["transactionIndex"] = "0x" + silkrpc::to_hex_no_leading_zeros(transaction.transaction_index);
173+
}
174+
166175
void from_json(const nlohmann::json& json, Call& call) {
167176
if (json.count("from") != 0) {
168177
call.from = json.at("from").get<evmc::address>();

silkrpc/json/types.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include <silkrpc/types/error.hpp>
3030
#include <silkrpc/types/filter.hpp>
3131
#include <silkrpc/types/log.hpp>
32+
#include <silkrpc/types/transaction.hpp>
3233
#include <silkrpc/types/receipt.hpp>
3334
#include <silkworm/types/block.hpp>
3435
#include <silkworm/types/transaction.hpp>
@@ -55,6 +56,8 @@ namespace silkrpc {
5556

5657
void to_json(nlohmann::json& json, const Block& b);
5758

59+
void to_json(nlohmann::json& json, const Transaction& transaction);
60+
5861
void from_json(const nlohmann::json& json, Call& call);
5962

6063
void to_json(nlohmann::json& json, const Log& log);

silkrpc/types/transaction.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/*
2+
Copyright 2020 The Silkrpc Authors
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
#include "transaction.hpp"
18+
19+
#include <iomanip>
20+
21+
#include <silkrpc/common/util.hpp>
22+
23+
namespace silkrpc {
24+
25+
std::ostream& operator<<(std::ostream& out, const Transaction& t) {
26+
out << " block_hash: " << t.block_hash;
27+
out << " block_number: " << t.block_number;
28+
out << " transaction_index: " << t.transaction_index;
29+
30+
return out;
31+
}
32+
33+
} // namespace silkrpc

silkrpc/types/transaction.hpp

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
Copyright 2020 The Silkrpc Authors
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
#ifndef SILKRPC_TYPES_TRANSACTION_HPP_
18+
#define SILKRPC_TYPES_TRANSACTION_HPP_
19+
20+
#include <iostream>
21+
22+
#include <intx/intx.hpp>
23+
24+
#include <silkworm/common/base.hpp>
25+
#include <silkworm/types/transaction.hpp>
26+
27+
namespace silkrpc {
28+
29+
struct Transaction : public silkworm::Transaction {
30+
evmc::bytes32 block_hash;
31+
uint64_t block_number{0};
32+
uint64_t transaction_index{0};
33+
};
34+
35+
std::ostream& operator<<(std::ostream& out, const Transaction& t);
36+
37+
} // namespace silkrpc
38+
39+
#endif // SILKRPC_TYPES_TRANSACTION_HPP_

tests/integration/run_jsonrpc_commands.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,3 +44,5 @@ def run_shell_command(command: str) -> int:
4444

4545

4646
run_shell_command('''curl --silent -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"eth_getLogs","params":[{"fromBlock": "0x3d0900", "toBlock": "0x3d0964", "address": "0x2a89f54a9f8e727a7be754fd055bb8ea93d0557d"}],"id":3}' localhost:51515''')
47+
48+
run_shell_command('''curl --silent -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"eth_getTransactionByBlockHashAndIndex","params":["0x814672e6913a3879217169c6ba461114fa032d9510a56a409d3aab19f668e299", "0x0"],"id":1}' localhost:51515''')

0 commit comments

Comments
 (0)