From c572425c76a706a479a09e24ace22886cf619e78 Mon Sep 17 00:00:00 2001 From: lupin012 <58134934+lupin012@users.noreply.github.com> Date: Sat, 24 Jun 2023 22:41:27 +0200 Subject: [PATCH] rpcdaemon: Transaction as json module (#1280) --- silkworm/silkrpc/json/transaction.cpp | 86 +++++++ silkworm/silkrpc/json/transaction.hpp | 34 +++ silkworm/silkrpc/json/transaction_test.cpp | 284 +++++++++++++++++++++ silkworm/silkrpc/json/types.cpp | 53 ---- silkworm/silkrpc/json/types.hpp | 5 +- silkworm/silkrpc/json/types_test.cpp | 257 ------------------- 6 files changed, 405 insertions(+), 314 deletions(-) create mode 100644 silkworm/silkrpc/json/transaction.cpp create mode 100644 silkworm/silkrpc/json/transaction.hpp create mode 100644 silkworm/silkrpc/json/transaction_test.cpp diff --git a/silkworm/silkrpc/json/transaction.cpp b/silkworm/silkrpc/json/transaction.cpp new file mode 100644 index 0000000000..9e4283ac67 --- /dev/null +++ b/silkworm/silkrpc/json/transaction.cpp @@ -0,0 +1,86 @@ +/* + Copyright 2023 The Silkworm Authors + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "transaction.hpp" + +#include +#include + +#include +#include + +#include "filter.hpp" + +namespace silkworm { + +void to_json(nlohmann::json& json, const Transaction& transaction) { + if (!transaction.from) { + (const_cast(transaction)).recover_sender(); + } + if (transaction.from) { + json["from"] = transaction.from.value(); + } + json["gas"] = rpc::to_quantity(transaction.gas_limit); + auto ethash_hash{hash_of_transaction(transaction)}; + json["hash"] = silkworm::to_bytes32({ethash_hash.bytes, silkworm::kHashLength}); + json["input"] = "0x" + silkworm::to_hex(transaction.data); + json["nonce"] = rpc::to_quantity(transaction.nonce); + if (transaction.to) { + json["to"] = transaction.to.value(); + } else { + json["to"] = nullptr; + } + json["type"] = rpc::to_quantity(uint64_t(transaction.type)); + + if (transaction.type == silkworm::TransactionType::kDynamicFee) { + json["maxPriorityFeePerGas"] = rpc::to_quantity(transaction.max_priority_fee_per_gas); + json["maxFeePerGas"] = rpc::to_quantity(transaction.max_fee_per_gas); + } + if (transaction.type != silkworm::TransactionType::kLegacy) { + json["chainId"] = rpc::to_quantity(*transaction.chain_id); + json["v"] = rpc::to_quantity(uint64_t(transaction.odd_y_parity)); + json["accessList"] = transaction.access_list; // EIP2930 + } else if (transaction.chain_id) { + json["chainId"] = rpc::to_quantity(*transaction.chain_id); + json["v"] = rpc::to_quantity(silkworm::endian::to_big_compact(transaction.v())); + } else { + json["v"] = rpc::to_quantity(silkworm::endian::to_big_compact(transaction.v())); + } + json["value"] = rpc::to_quantity(transaction.value); + json["r"] = rpc::to_quantity(silkworm::endian::to_big_compact(transaction.r)); + json["s"] = rpc::to_quantity(silkworm::endian::to_big_compact(transaction.s)); +} + +} // namespace silkworm + +namespace silkworm::rpc { + +void to_json(nlohmann::json& json, const Transaction& transaction) { + to_json(json, static_cast(transaction)); + + json["gasPrice"] = to_quantity(transaction.effective_gas_price()); + if (transaction.queued_in_pool) { + json["blockHash"] = nullptr; + json["blockNumber"] = nullptr; + json["transactionIndex"] = nullptr; + } else { + json["blockHash"] = transaction.block_hash; + json["blockNumber"] = to_quantity(transaction.block_number); + json["transactionIndex"] = to_quantity(transaction.transaction_index); + } +} + +} // namespace silkworm::rpc diff --git a/silkworm/silkrpc/json/transaction.hpp b/silkworm/silkrpc/json/transaction.hpp new file mode 100644 index 0000000000..0843c76012 --- /dev/null +++ b/silkworm/silkrpc/json/transaction.hpp @@ -0,0 +1,34 @@ +/* + Copyright 2023 The Silkworm Authors + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#pragma once + +#include + +#include +#include + +namespace silkworm { + +void to_json(nlohmann::json& json, const Transaction& transaction); + +} // namespace silkworm + +namespace silkworm::rpc { + +void to_json(nlohmann::json& json, const Transaction& transaction); + +} // namespace silkworm::rpc diff --git a/silkworm/silkrpc/json/transaction_test.cpp b/silkworm/silkrpc/json/transaction_test.cpp new file mode 100644 index 0000000000..8d1b0eb1ef --- /dev/null +++ b/silkworm/silkrpc/json/transaction_test.cpp @@ -0,0 +1,284 @@ +/* + Copyright 2023 The Silkworm Authors + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "transaction.hpp" + +#include +#include + +namespace silkworm::rpc { + +using Catch::Matchers::Message; +using evmc::literals::operator""_address, evmc::literals::operator""_bytes32; + +TEST_CASE("serialize empty transaction", "[silkrpc][to_json]") { + silkworm::Transaction txn{}; + nlohmann::json j = txn; + CHECK(j == R"({ + "nonce":"0x0", + "gas":"0x0", + "to":null, + "type":"0x0", + "value":"0x0", + "input":"0x", + "hash":"0x3763e4f6e4198413383534c763f3f5dac5c5e939f0a81724e3beb96d6e2ad0d5", + "r":"0x0", + "s":"0x0", + "v":"0x1b" + })"_json); +} + +TEST_CASE("serialize legacy transaction (type=0)", "[silkrpc][to_json]") { + // https://etherscan.io/tx/0x5c504ed432cb51138bcf09aa5e8a410dd4a1e204ef84bfed1be16dfba1b22060 + // Block 46147 + silkworm::Transaction txn1{ + {.type = TransactionType::kLegacy, + .nonce = 0, + .max_priority_fee_per_gas = 50'000 * kGiga, + .max_fee_per_gas = 50'000 * kGiga, + .gas_limit = 21'000, + .to = 0x5df9b87991262f6ba471f09758cde1c0fc1de734_address, + .value = 31337}, + true, // odd_y_parity + intx::from_string("0x88ff6cf0fefd94db46111149ae4bfc179e9b94721fffd821d38d16464b3f71d0"), // r + intx::from_string("0x45e0aff800961cfce805daef7016b9b675c137a6a41a548f7b60a3484c06a33a"), // s + }; + nlohmann::json j1 = txn1; + CHECK(j1 == R"({ + "from":"0xa1e4380a3b1f749673e270229993ee55f35663b4", + "gas":"0x5208", + "hash":"0x5c504ed432cb51138bcf09aa5e8a410dd4a1e204ef84bfed1be16dfba1b22060", + "input":"0x", + "nonce":"0x0", + "r":"0x88ff6cf0fefd94db46111149ae4bfc179e9b94721fffd821d38d16464b3f71d0", + "s":"0x45e0aff800961cfce805daef7016b9b675c137a6a41a548f7b60a3484c06a33a", + "to":"0x5df9b87991262f6ba471f09758cde1c0fc1de734", + "type":"0x0", + "v":"0x1c", + "value":"0x7a69" + })"_json); + + silkworm::rpc::Transaction txn2{ + { + {.type = TransactionType::kLegacy, + .nonce = 0, + .max_priority_fee_per_gas = 50'000 * kGiga, + .max_fee_per_gas = 50'000 * kGiga, + .gas_limit = 21'000, + .to = 0x5df9b87991262f6ba471f09758cde1c0fc1de734_address, + .value = 31337}, + true, // odd_y_parity + intx::from_string("0x88ff6cf0fefd94db46111149ae4bfc179e9b94721fffd821d38d16464b3f71d0"), // r + intx::from_string("0x45e0aff800961cfce805daef7016b9b675c137a6a41a548f7b60a3484c06a33a"), // s + 0x007fb8417eb9ad4d958b050fc3720d5b46a2c053_address, // from + }, + 0x4e3a3754410177e6937ef1f84bba68ea139e8d1a2258c5f85db9f1cd715a1bdd_bytes32, // block_hash + 46147, // block_number + intx::uint256{0}, // block_base_fee_per_gas + 0 // transactionIndex + }; + nlohmann::json j2 = txn2; + CHECK(j2 == R"({ + "blockHash":"0x4e3a3754410177e6937ef1f84bba68ea139e8d1a2258c5f85db9f1cd715a1bdd", + "blockNumber":"0xb443", + "from":"0x007fb8417eb9ad4d958b050fc3720d5b46a2c053", + "gas":"0x5208", + "gasPrice":"0x2d79883d2000", + "hash":"0x5c504ed432cb51138bcf09aa5e8a410dd4a1e204ef84bfed1be16dfba1b22060", + "input":"0x", + "nonce":"0x0", + "r":"0x88ff6cf0fefd94db46111149ae4bfc179e9b94721fffd821d38d16464b3f71d0", + "s":"0x45e0aff800961cfce805daef7016b9b675c137a6a41a548f7b60a3484c06a33a", + "to":"0x5df9b87991262f6ba471f09758cde1c0fc1de734", + "transactionIndex":"0x0", + "type":"0x0", + "v":"0x1c", + "value":"0x7a69" + })"_json); + silkworm::rpc::Transaction txn3{ + { + {.type = TransactionType::kLegacy, + .nonce = 0, + .max_priority_fee_per_gas = 50'000 * kGiga, + .max_fee_per_gas = 50'000 * kGiga, + .gas_limit = 21'000, + .to = 0x5df9b87991262f6ba471f09758cde1c0fc1de734_address, + .value = 31337}, + true, // odd_y_parity + intx::from_string("0x88ff6cf0fefd94db46111149ae4bfc179e9b94721fffd821d38d16464b3f71d0"), // r + intx::from_string("0x45e0aff800961cfce805daef7016b9b675c137a6a41a548f7b60a3484c06a33a"), // s + 0x007fb8417eb9ad4d958b050fc3720d5b46a2c053_address, // from + }, + 0x4e3a3754410177e6937ef1f84bba68ea139e8d1a2258c5f85db9f1cd715a1bdd_bytes32, // block_hash + 46147, // block_number + intx::uint256{0}, // block_base_fee_per_gas + 0, // transactionIndex + true // queued_in_pool + }; + nlohmann::json j3 = txn3; + CHECK(j3 == R"({ + "blockHash":null, + "blockNumber":null, + "from":"0x007fb8417eb9ad4d958b050fc3720d5b46a2c053", + "gas":"0x5208", + "gasPrice":"0x2d79883d2000", + "hash":"0x5c504ed432cb51138bcf09aa5e8a410dd4a1e204ef84bfed1be16dfba1b22060", + "input":"0x", + "nonce":"0x0", + "r":"0x88ff6cf0fefd94db46111149ae4bfc179e9b94721fffd821d38d16464b3f71d0", + "s":"0x45e0aff800961cfce805daef7016b9b675c137a6a41a548f7b60a3484c06a33a", + "to":"0x5df9b87991262f6ba471f09758cde1c0fc1de734", + "transactionIndex":null, + "type":"0x0", + "v":"0x1c", + "value":"0x7a69" + })"_json); +} + +TEST_CASE("serialize EIP-2930 transaction (type=1)", "[silkrpc][to_json]") { + silkworm::Transaction txn1{ + {.type = TransactionType::kAccessList, + .chain_id = 1, + .nonce = 0, + .max_priority_fee_per_gas = 20000000000, + .max_fee_per_gas = 20000000000, + .gas_limit = 0, + .to = 0x0715a7794a1dc8e42615f059dd6e406a6594651a_address, + .value = 0, + .data = *from_hex("001122aabbcc")}, + false, // odd_y_parity + 18, // r + 36, // s + 0x007fb8417eb9ad4d958b050fc3720d5b46a2c053_address, // from + }; + nlohmann::json j1 = txn1; + CHECK(j1 == R"({ + "nonce":"0x0", + "chainId":"0x1", + "gas":"0x0", + "to":"0x0715a7794a1dc8e42615f059dd6e406a6594651a", + "from":"0x007fb8417eb9ad4d958b050fc3720d5b46a2c053", + "type":"0x1", + "value":"0x0", + "input":"0x001122aabbcc", + "hash":"0xe976a1c7600ed37c7aeea9b34de01b2424a68a4c9dfb0a0315a3db3cd9975512", + "accessList":[], + "r":"0x12", + "s":"0x24", + "v":"0x0" + })"_json); + + std::vector access_list{ + {0xde0b295669a9fd93d5f28d9ec85e40f4cb697bae_address, + { + 0x0000000000000000000000000000000000000000000000000000000000000003_bytes32, + 0x0000000000000000000000000000000000000000000000000000000000000007_bytes32, + }}, + {0xbb9bc244d798123fde783fcc1c72d3bb8c189413_address, {}}, + }; + + silkworm::rpc::Transaction txn2{ + { + {.type = TransactionType::kAccessList, + .chain_id = 1, + .nonce = 0, + .max_priority_fee_per_gas = 20000000000, + .max_fee_per_gas = 30000000000, + .gas_limit = 0, + .to = 0x0715a7794a1dc8e42615f059dd6e406a6594651a_address, + .value = 0, + .data = *from_hex("001122aabbcc"), + .access_list = access_list}, + false, // odd_y_parity + 18, // r + 36, // s + 0x007fb8417eb9ad4d958b050fc3720d5b46a2c053_address, // from + }, + 0x374f3a049e006f36f6cf91b02a3b0ee16c858af2f75858733eb0e927b5b7126c_bytes32, + 123123, + intx::uint256{12}, + 3}; + nlohmann::json j2 = txn2; + CHECK(j2 == R"({ + "nonce":"0x0", + "gasPrice":"0x4a817c80c", + "chainId":"0x1", + "gas":"0x0", + "to":"0x0715a7794a1dc8e42615f059dd6e406a6594651a", + "from":"0x007fb8417eb9ad4d958b050fc3720d5b46a2c053", + "type":"0x1", + "value":"0x0", + "input":"0x001122aabbcc", + "hash":"0xae1aea7493cc9a029710b601f62538993ebc6281ac63a241b83a218bd060b291", + "r":"0x12", + "s":"0x24", + "v":"0x0", + "blockHash":"0x374f3a049e006f36f6cf91b02a3b0ee16c858af2f75858733eb0e927b5b7126c", + "blockNumber":"0x1e0f3", + "transactionIndex":"0x3", + "accessList":[ + { + "address":"0xde0b295669a9fd93d5f28d9ec85e40f4cb697bae", + "storageKeys":[ + "0x0000000000000000000000000000000000000000000000000000000000000003", + "0x0000000000000000000000000000000000000000000000000000000000000007" + ] + }, + { + "address":"0xbb9bc244d798123fde783fcc1c72d3bb8c189413", + "storageKeys":[] + } + ] + })"_json); +} + +TEST_CASE("serialize EIP-1559 transaction (type=2)", "[silkrpc][to_json]") { + silkworm::Transaction txn1{ + {.type = TransactionType::kDynamicFee, + .chain_id = 1, + .nonce = 0, + .max_priority_fee_per_gas = 50'000 * kGiga, + .max_fee_per_gas = 50'000 * kGiga, + .gas_limit = 21'000, + .to = 0x5df9b87991262f6ba471f09758cde1c0fc1de734_address, + .value = 31337, + .data = *from_hex("001122aabbcc")}, + true, // odd_y_parity + intx::from_string("0x88ff6cf0fefd94db46111149ae4bfc179e9b94721fffd821d38d16464b3f71d0"), // r + intx::from_string("0x45e0aff800961cfce805daef7016b9b675c137a6a41a548f7b60a3484c06a33a"), // s + 0x007fb8417eb9ad4d958b050fc3720d5b46a2c053_address, // from + }; + nlohmann::json j1 = txn1; + CHECK(j1 == R"({ + "nonce":"0x0", + "chainId":"0x1", + "gas":"0x5208", + "to":"0x5df9b87991262f6ba471f09758cde1c0fc1de734", + "from":"0x007fb8417eb9ad4d958b050fc3720d5b46a2c053", + "type":"0x2", + "value":"0x7a69", + "input":"0x001122aabbcc", + "hash":"0x64ab530a48c64d248b85dd6952539cae03cad7a001ed32ba5d358aca20eef0a8", + "accessList":[], + "r":"0x88ff6cf0fefd94db46111149ae4bfc179e9b94721fffd821d38d16464b3f71d0", + "s":"0x45e0aff800961cfce805daef7016b9b675c137a6a41a548f7b60a3484c06a33a", + "v":"0x1", + "maxPriorityFeePerGas":"0x2d79883d2000", + "maxFeePerGas":"0x2d79883d2000" + })"_json); +} + +} // namespace silkworm::rpc diff --git a/silkworm/silkrpc/json/types.cpp b/silkworm/silkrpc/json/types.cpp index 08b39e4601..68aebba6d5 100644 --- a/silkworm/silkrpc/json/types.cpp +++ b/silkworm/silkrpc/json/types.cpp @@ -219,44 +219,6 @@ void to_json(nlohmann::json& json, const BlockHeader& header) { json["withdrawalsRoot"] = nullptr; // waiting EIP-4895 } -void to_json(nlohmann::json& json, const Transaction& transaction) { - if (!transaction.from) { - (const_cast(transaction)).recover_sender(); - } - if (transaction.from) { - json["from"] = transaction.from.value(); - } - json["gas"] = rpc::to_quantity(transaction.gas_limit); - auto ethash_hash{hash_of_transaction(transaction)}; - json["hash"] = silkworm::to_bytes32({ethash_hash.bytes, silkworm::kHashLength}); - json["input"] = "0x" + silkworm::to_hex(transaction.data); - json["nonce"] = rpc::to_quantity(transaction.nonce); - if (transaction.to) { - json["to"] = transaction.to.value(); - } else { - json["to"] = nullptr; - } - json["type"] = rpc::to_quantity(uint64_t(transaction.type)); - - if (transaction.type == silkworm::TransactionType::kDynamicFee) { - json["maxPriorityFeePerGas"] = rpc::to_quantity(transaction.max_priority_fee_per_gas); - json["maxFeePerGas"] = rpc::to_quantity(transaction.max_fee_per_gas); - } - if (transaction.type != silkworm::TransactionType::kLegacy) { - json["chainId"] = rpc::to_quantity(*transaction.chain_id); - json["v"] = rpc::to_quantity(uint64_t(transaction.odd_y_parity)); - json["accessList"] = transaction.access_list; // EIP2930 - } else if (transaction.chain_id) { - json["chainId"] = rpc::to_quantity(*transaction.chain_id); - json["v"] = rpc::to_quantity(silkworm::endian::to_big_compact(transaction.v())); - } else { - json["v"] = rpc::to_quantity(silkworm::endian::to_big_compact(transaction.v())); - } - json["value"] = rpc::to_quantity(transaction.value); - json["r"] = rpc::to_quantity(silkworm::endian::to_big_compact(transaction.r)); - json["s"] = rpc::to_quantity(silkworm::endian::to_big_compact(transaction.s)); -} - } // namespace silkworm namespace silkworm::rpc { @@ -416,21 +378,6 @@ void to_json(nlohmann::json& json, const BlockTransactionsResponse& b) { } } -void to_json(nlohmann::json& json, const Transaction& transaction) { - to_json(json, static_cast(transaction)); - - json["gasPrice"] = to_quantity(transaction.effective_gas_price()); - if (transaction.queued_in_pool) { - json["blockHash"] = nullptr; - json["blockNumber"] = nullptr; - json["transactionIndex"] = nullptr; - } else { - json["blockHash"] = transaction.block_hash; - json["blockNumber"] = to_quantity(transaction.block_number); - json["transactionIndex"] = to_quantity(transaction.transaction_index); - } -} - void to_json(nlohmann::json& json, const PayloadStatus& payload_status) { json["status"] = payload_status.status; diff --git a/silkworm/silkrpc/json/types.hpp b/silkworm/silkrpc/json/types.hpp index 7c53489bc1..f38c676e80 100644 --- a/silkworm/silkrpc/json/types.hpp +++ b/silkworm/silkrpc/json/types.hpp @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -74,8 +75,6 @@ namespace silkworm { void to_json(nlohmann::json& json, const BlockHeader& ommer); -void to_json(nlohmann::json& json, const Transaction& transaction); - } // namespace silkworm namespace silkworm::rpc { @@ -109,8 +108,6 @@ void to_json(nlohmann::json& json, const BlockDetailsResponse& b); void to_json(nlohmann::json& json, const BlockTransactionsResponse& b); -void to_json(nlohmann::json& json, const Transaction& transaction); - void to_json(nlohmann::json& json, const PayloadStatus& payload_status); void to_json(nlohmann::json& json, const Forks& forks); diff --git a/silkworm/silkrpc/json/types_test.cpp b/silkworm/silkrpc/json/types_test.cpp index 0658c2686a..f98faa355d 100644 --- a/silkworm/silkrpc/json/types_test.cpp +++ b/silkworm/silkrpc/json/types_test.cpp @@ -494,23 +494,6 @@ TEST_CASE("serialize block body with ommers", "[silkrpc][to_json]") { })"_json); } -TEST_CASE("serialize empty transaction", "[silkrpc][to_json]") { - silkworm::Transaction txn{}; - nlohmann::json j = txn; - CHECK(j == R"({ - "nonce":"0x0", - "gas":"0x0", - "to":null, - "type":"0x0", - "value":"0x0", - "input":"0x", - "hash":"0x3763e4f6e4198413383534c763f3f5dac5c5e939f0a81724e3beb96d6e2ad0d5", - "r":"0x0", - "s":"0x0", - "v":"0x1b" - })"_json); -} - TEST_CASE("serialize empty call_bundle", "[silkrpc][to_json]") { struct CallBundleInfo bundle_info {}; @@ -570,246 +553,6 @@ TEST_CASE("serialize filled SyncingData", "[silkrpc][to_json]") { })"_json); } -TEST_CASE("serialize legacy transaction (type=0)", "[silkrpc][to_json]") { - // https://etherscan.io/tx/0x5c504ed432cb51138bcf09aa5e8a410dd4a1e204ef84bfed1be16dfba1b22060 - // Block 46147 - silkworm::Transaction txn1{ - {.type = TransactionType::kLegacy, - .nonce = 0, - .max_priority_fee_per_gas = 50'000 * kGiga, - .max_fee_per_gas = 50'000 * kGiga, - .gas_limit = 21'000, - .to = 0x5df9b87991262f6ba471f09758cde1c0fc1de734_address, - .value = 31337}, - true, // odd_y_parity - intx::from_string("0x88ff6cf0fefd94db46111149ae4bfc179e9b94721fffd821d38d16464b3f71d0"), // r - intx::from_string("0x45e0aff800961cfce805daef7016b9b675c137a6a41a548f7b60a3484c06a33a"), // s - }; - nlohmann::json j1 = txn1; - CHECK(j1 == R"({ - "from":"0xa1e4380a3b1f749673e270229993ee55f35663b4", - "gas":"0x5208", - "hash":"0x5c504ed432cb51138bcf09aa5e8a410dd4a1e204ef84bfed1be16dfba1b22060", - "input":"0x", - "nonce":"0x0", - "r":"0x88ff6cf0fefd94db46111149ae4bfc179e9b94721fffd821d38d16464b3f71d0", - "s":"0x45e0aff800961cfce805daef7016b9b675c137a6a41a548f7b60a3484c06a33a", - "to":"0x5df9b87991262f6ba471f09758cde1c0fc1de734", - "type":"0x0", - "v":"0x1c", - "value":"0x7a69" - })"_json); - - silkworm::rpc::Transaction txn2{ - { - {.type = TransactionType::kLegacy, - .nonce = 0, - .max_priority_fee_per_gas = 50'000 * kGiga, - .max_fee_per_gas = 50'000 * kGiga, - .gas_limit = 21'000, - .to = 0x5df9b87991262f6ba471f09758cde1c0fc1de734_address, - .value = 31337}, - true, // odd_y_parity - intx::from_string("0x88ff6cf0fefd94db46111149ae4bfc179e9b94721fffd821d38d16464b3f71d0"), // r - intx::from_string("0x45e0aff800961cfce805daef7016b9b675c137a6a41a548f7b60a3484c06a33a"), // s - 0x007fb8417eb9ad4d958b050fc3720d5b46a2c053_address, // from - }, - 0x4e3a3754410177e6937ef1f84bba68ea139e8d1a2258c5f85db9f1cd715a1bdd_bytes32, // block_hash - 46147, // block_number - intx::uint256{0}, // block_base_fee_per_gas - 0 // transactionIndex - }; - nlohmann::json j2 = txn2; - CHECK(j2 == R"({ - "blockHash":"0x4e3a3754410177e6937ef1f84bba68ea139e8d1a2258c5f85db9f1cd715a1bdd", - "blockNumber":"0xb443", - "from":"0x007fb8417eb9ad4d958b050fc3720d5b46a2c053", - "gas":"0x5208", - "gasPrice":"0x2d79883d2000", - "hash":"0x5c504ed432cb51138bcf09aa5e8a410dd4a1e204ef84bfed1be16dfba1b22060", - "input":"0x", - "nonce":"0x0", - "r":"0x88ff6cf0fefd94db46111149ae4bfc179e9b94721fffd821d38d16464b3f71d0", - "s":"0x45e0aff800961cfce805daef7016b9b675c137a6a41a548f7b60a3484c06a33a", - "to":"0x5df9b87991262f6ba471f09758cde1c0fc1de734", - "transactionIndex":"0x0", - "type":"0x0", - "v":"0x1c", - "value":"0x7a69" - })"_json); - silkworm::rpc::Transaction txn3{ - { - {.type = TransactionType::kLegacy, - .nonce = 0, - .max_priority_fee_per_gas = 50'000 * kGiga, - .max_fee_per_gas = 50'000 * kGiga, - .gas_limit = 21'000, - .to = 0x5df9b87991262f6ba471f09758cde1c0fc1de734_address, - .value = 31337}, - true, // odd_y_parity - intx::from_string("0x88ff6cf0fefd94db46111149ae4bfc179e9b94721fffd821d38d16464b3f71d0"), // r - intx::from_string("0x45e0aff800961cfce805daef7016b9b675c137a6a41a548f7b60a3484c06a33a"), // s - 0x007fb8417eb9ad4d958b050fc3720d5b46a2c053_address, // from - }, - 0x4e3a3754410177e6937ef1f84bba68ea139e8d1a2258c5f85db9f1cd715a1bdd_bytes32, // block_hash - 46147, // block_number - intx::uint256{0}, // block_base_fee_per_gas - 0, // transactionIndex - true // queued_in_pool - }; - nlohmann::json j3 = txn3; - CHECK(j3 == R"({ - "blockHash":null, - "blockNumber":null, - "from":"0x007fb8417eb9ad4d958b050fc3720d5b46a2c053", - "gas":"0x5208", - "gasPrice":"0x2d79883d2000", - "hash":"0x5c504ed432cb51138bcf09aa5e8a410dd4a1e204ef84bfed1be16dfba1b22060", - "input":"0x", - "nonce":"0x0", - "r":"0x88ff6cf0fefd94db46111149ae4bfc179e9b94721fffd821d38d16464b3f71d0", - "s":"0x45e0aff800961cfce805daef7016b9b675c137a6a41a548f7b60a3484c06a33a", - "to":"0x5df9b87991262f6ba471f09758cde1c0fc1de734", - "transactionIndex":null, - "type":"0x0", - "v":"0x1c", - "value":"0x7a69" - })"_json); -} - -TEST_CASE("serialize EIP-2930 transaction (type=1)", "[silkrpc][to_json]") { - silkworm::Transaction txn1{ - {.type = TransactionType::kAccessList, - .chain_id = 1, - .nonce = 0, - .max_priority_fee_per_gas = 20000000000, - .max_fee_per_gas = 20000000000, - .gas_limit = 0, - .to = 0x0715a7794a1dc8e42615f059dd6e406a6594651a_address, - .value = 0, - .data = *from_hex("001122aabbcc")}, - false, // odd_y_parity - 18, // r - 36, // s - 0x007fb8417eb9ad4d958b050fc3720d5b46a2c053_address, // from - }; - nlohmann::json j1 = txn1; - CHECK(j1 == R"({ - "nonce":"0x0", - "chainId":"0x1", - "gas":"0x0", - "to":"0x0715a7794a1dc8e42615f059dd6e406a6594651a", - "from":"0x007fb8417eb9ad4d958b050fc3720d5b46a2c053", - "type":"0x1", - "value":"0x0", - "input":"0x001122aabbcc", - "hash":"0xe976a1c7600ed37c7aeea9b34de01b2424a68a4c9dfb0a0315a3db3cd9975512", - "accessList":[], - "r":"0x12", - "s":"0x24", - "v":"0x0" - })"_json); - - std::vector access_list{ - {0xde0b295669a9fd93d5f28d9ec85e40f4cb697bae_address, - { - 0x0000000000000000000000000000000000000000000000000000000000000003_bytes32, - 0x0000000000000000000000000000000000000000000000000000000000000007_bytes32, - }}, - {0xbb9bc244d798123fde783fcc1c72d3bb8c189413_address, {}}, - }; - - silkworm::rpc::Transaction txn2{ - { - {.type = TransactionType::kAccessList, - .chain_id = 1, - .nonce = 0, - .max_priority_fee_per_gas = 20000000000, - .max_fee_per_gas = 30000000000, - .gas_limit = 0, - .to = 0x0715a7794a1dc8e42615f059dd6e406a6594651a_address, - .value = 0, - .data = *from_hex("001122aabbcc"), - .access_list = access_list}, - false, // odd_y_parity - 18, // r - 36, // s - 0x007fb8417eb9ad4d958b050fc3720d5b46a2c053_address, // from - }, - 0x374f3a049e006f36f6cf91b02a3b0ee16c858af2f75858733eb0e927b5b7126c_bytes32, - 123123, - intx::uint256{12}, - 3}; - nlohmann::json j2 = txn2; - CHECK(j2 == R"({ - "nonce":"0x0", - "gasPrice":"0x4a817c80c", - "chainId":"0x1", - "gas":"0x0", - "to":"0x0715a7794a1dc8e42615f059dd6e406a6594651a", - "from":"0x007fb8417eb9ad4d958b050fc3720d5b46a2c053", - "type":"0x1", - "value":"0x0", - "input":"0x001122aabbcc", - "hash":"0xae1aea7493cc9a029710b601f62538993ebc6281ac63a241b83a218bd060b291", - "r":"0x12", - "s":"0x24", - "v":"0x0", - "blockHash":"0x374f3a049e006f36f6cf91b02a3b0ee16c858af2f75858733eb0e927b5b7126c", - "blockNumber":"0x1e0f3", - "transactionIndex":"0x3", - "accessList":[ - { - "address":"0xde0b295669a9fd93d5f28d9ec85e40f4cb697bae", - "storageKeys":[ - "0x0000000000000000000000000000000000000000000000000000000000000003", - "0x0000000000000000000000000000000000000000000000000000000000000007" - ] - }, - { - "address":"0xbb9bc244d798123fde783fcc1c72d3bb8c189413", - "storageKeys":[] - } - ] - })"_json); -} - -TEST_CASE("serialize EIP-1559 transaction (type=2)", "[silkrpc][to_json]") { - silkworm::Transaction txn1{ - {.type = TransactionType::kDynamicFee, - .chain_id = 1, - .nonce = 0, - .max_priority_fee_per_gas = 50'000 * kGiga, - .max_fee_per_gas = 50'000 * kGiga, - .gas_limit = 21'000, - .to = 0x5df9b87991262f6ba471f09758cde1c0fc1de734_address, - .value = 31337, - .data = *from_hex("001122aabbcc")}, - true, // odd_y_parity - intx::from_string("0x88ff6cf0fefd94db46111149ae4bfc179e9b94721fffd821d38d16464b3f71d0"), // r - intx::from_string("0x45e0aff800961cfce805daef7016b9b675c137a6a41a548f7b60a3484c06a33a"), // s - 0x007fb8417eb9ad4d958b050fc3720d5b46a2c053_address, // from - }; - nlohmann::json j1 = txn1; - CHECK(j1 == R"({ - "nonce":"0x0", - "chainId":"0x1", - "gas":"0x5208", - "to":"0x5df9b87991262f6ba471f09758cde1c0fc1de734", - "from":"0x007fb8417eb9ad4d958b050fc3720d5b46a2c053", - "type":"0x2", - "value":"0x7a69", - "input":"0x001122aabbcc", - "hash":"0x64ab530a48c64d248b85dd6952539cae03cad7a001ed32ba5d358aca20eef0a8", - "accessList":[], - "r":"0x88ff6cf0fefd94db46111149ae4bfc179e9b94721fffd821d38d16464b3f71d0", - "s":"0x45e0aff800961cfce805daef7016b9b675c137a6a41a548f7b60a3484c06a33a", - "v":"0x1", - "maxPriorityFeePerGas":"0x2d79883d2000", - "maxFeePerGas":"0x2d79883d2000" - })"_json); -} - TEST_CASE("serialize error", "[silkrpc][to_json]") { Error err{100, {"generic error"}}; nlohmann::json j = err;