From 712c426a420c666cfe0a3907b3eb0ca78dfd0841 Mon Sep 17 00:00:00 2001 From: kstdl Date: Thu, 9 Jan 2025 09:45:35 +0100 Subject: [PATCH 1/3] feat: perform intrinsic gas check on trx insertion --- libraries/common/include/common/constants.hpp | 5 +++ .../src/transaction/transaction_manager.cpp | 6 ++++ .../network/rpc/jsonrpc_ws_server.cpp | 2 ++ .../include/transaction/transaction.hpp | 2 ++ .../types/transaction/src/transaction.cpp | 33 +++++++++++++++++++ tests/transaction_test.cpp | 11 +++++++ 6 files changed, 59 insertions(+) diff --git a/libraries/common/include/common/constants.hpp b/libraries/common/include/common/constants.hpp index aea008f1ac..ccc2e64b70 100644 --- a/libraries/common/include/common/constants.hpp +++ b/libraries/common/include/common/constants.hpp @@ -35,6 +35,11 @@ const size_t kV3NetworkVersion = 3; const uint32_t kRecentlyFinalizedTransactionsFactor = 2; +constexpr uint64_t kTxGas = 21000; +constexpr uint64_t kTxGasContractCreation = 53000; +constexpr uint64_t kTxDataZeroGas = 4; +constexpr uint64_t kTxDataNonZeroGas = 68; + // The various denominations; here for ease of use where needed within code. static const u256 kOneTara = dev::exp10<18>(); // static const u256 kFinney = exp10<15>(); diff --git a/libraries/core_libs/consensus/src/transaction/transaction_manager.cpp b/libraries/core_libs/consensus/src/transaction/transaction_manager.cpp index e524a43c78..f09abdee84 100644 --- a/libraries/core_libs/consensus/src/transaction/transaction_manager.cpp +++ b/libraries/core_libs/consensus/src/transaction/transaction_manager.cpp @@ -73,6 +73,12 @@ std::pair TransactionManager::verifyTransaction(const std::sh return {false, "gas_price too low"}; } + if (this->kConf.genesis.state.hardforks.isOnCornusHardfork(this->final_chain_->lastBlockNumber())) { + if (!trx->intrinsicGasCovered()) { + return {false, "intrinsic gas too low"}; + } + } + return {true, ""}; } diff --git a/libraries/core_libs/network/rpc/jsonrpc_ws_server.cpp b/libraries/core_libs/network/rpc/jsonrpc_ws_server.cpp index 44ebc709a3..adf06d1ea7 100644 --- a/libraries/core_libs/network/rpc/jsonrpc_ws_server.cpp +++ b/libraries/core_libs/network/rpc/jsonrpc_ws_server.cpp @@ -84,6 +84,8 @@ std::string JsonRpcWsSession::handleSubscription(const Json::Value &req) { if (params.size() == 2 && params[1].asString() == "includeSignatures") { include_pillar_block_signatures = true; } + } else { + throw std::runtime_error("Invalid subscription type"); } } diff --git a/libraries/types/transaction/include/transaction/transaction.hpp b/libraries/types/transaction/include/transaction/transaction.hpp index 04c8477e48..e9a7c10e9d 100644 --- a/libraries/types/transaction/include/transaction/transaction.hpp +++ b/libraries/types/transaction/include/transaction/transaction.hpp @@ -57,6 +57,7 @@ struct Transaction { explicit Transaction(const bytes &_rlp, bool verify_strict = false, const h256 &hash = {}); virtual ~Transaction() = default; + bool intrinsicGasCovered() const; auto isZero() const { return is_zero_; } const trx_hash_t &getHash() const; auto getNonce() const { return nonce_; } @@ -85,6 +86,7 @@ using Transactions = std::vector; using SharedTransactions = std::vector; using TransactionHashes = std::vector; +uint64_t IntrinsicGas(const std::vector &data, bool is_contract_creation); TransactionHashes hashes_from_transactions(const SharedTransactions &transactions); } // namespace taraxa diff --git a/libraries/types/transaction/src/transaction.cpp b/libraries/types/transaction/src/transaction.cpp index df928fbf3d..5ffeddf643 100644 --- a/libraries/types/transaction/src/transaction.cpp +++ b/libraries/types/transaction/src/transaction.cpp @@ -7,6 +7,7 @@ #include #include +#include "common/constants.hpp" #include "common/encoding_rlp.hpp" namespace taraxa { @@ -178,4 +179,36 @@ void Transaction::rlp(::taraxa::util::RLPDecoderRef encoding) { fromRLP(encoding void Transaction::rlp(::taraxa::util::RLPEncoderRef encoding) const { encoding.appendRaw(rlp()); } +uint64_t IntrinsicGas(const std::vector &data, bool is_contract_creation) { + uint64_t gas; + if (is_contract_creation) { + gas = kTxGasContractCreation; + } else { + gas = kTxGas; + } + // Bump the required gas by the amount of transactional data + if (!data.empty()) { + // Zero and non-zero bytes are priced differently + uint64_t nz = std::count_if(data.begin(), data.end(), [](uint8_t b) { return b != 0; }); + + // Make sure we don't exceed uint64 for all data combinations + if ((std::numeric_limits::max() - gas) / kTxDataNonZeroGas < nz) { + throw std::runtime_error("Out of gas"); + } + gas += nz * kTxDataNonZeroGas; + + uint64_t z = static_cast(data.size()) - nz; + if ((std::numeric_limits::max() - gas) / kTxDataZeroGas < z) { + throw std::runtime_error("Out of gas"); + } + gas += z * kTxDataZeroGas; + } + return gas; +} + +bool Transaction::intrinsicGasCovered() const { + uint64_t gas = IntrinsicGas(data_, !receiver_.has_value()); + return gas <= gas_; +} + } // namespace taraxa diff --git a/tests/transaction_test.cpp b/tests/transaction_test.cpp index 66a4312e13..d546d3e788 100644 --- a/tests/transaction_test.cpp +++ b/tests/transaction_test.cpp @@ -714,6 +714,17 @@ TEST_F(TransactionTest, signature_performance) { << "ms" << std::endl; } +TEST_F(TransactionTest, intrinsic_gas) { + EXPECT_EQ(IntrinsicGas(dev::bytes(), false), kTxGas); + EXPECT_EQ(IntrinsicGas(dev::bytes(), true), kTxGasContractCreation); + const auto data = dev::bytes(100000, 1); + EXPECT_EQ(IntrinsicGas(data, false), kTxGas + 100000 * kTxDataNonZeroGas); + EXPECT_EQ(IntrinsicGas(data, true), kTxGasContractCreation + 100000 * kTxDataNonZeroGas); + const auto data2 = dev::bytes(100000, 0); + EXPECT_EQ(IntrinsicGas(data2, false), kTxGas + 100000 * kTxDataZeroGas); + EXPECT_EQ(IntrinsicGas(data2, true), kTxGasContractCreation + 100000 * kTxDataZeroGas); +} + } // namespace taraxa::core_tests using namespace taraxa; From 65a6906d5e33e4e55a3ed072f476abfb7e16dd9f Mon Sep 17 00:00:00 2001 From: kstdl Date: Thu, 9 Jan 2025 10:53:50 +0100 Subject: [PATCH 2/3] chore: resolve discussions --- .../consensus/src/transaction/transaction_manager.cpp | 11 ++++++----- libraries/types/transaction/src/transaction.cpp | 10 +++++++--- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/libraries/core_libs/consensus/src/transaction/transaction_manager.cpp b/libraries/core_libs/consensus/src/transaction/transaction_manager.cpp index f09abdee84..fc4b78b9d7 100644 --- a/libraries/core_libs/consensus/src/transaction/transaction_manager.cpp +++ b/libraries/core_libs/consensus/src/transaction/transaction_manager.cpp @@ -62,6 +62,12 @@ std::pair TransactionManager::verifyTransaction(const std::sh return {false, "invalid gas"}; } + if (kConf.genesis.state.hardforks.isOnCornusHardfork(this->final_chain_->lastBlockNumber())) { + if (!trx->intrinsicGasCovered()) { + return {false, "intrinsic gas too low"}; + } + } + try { trx->getSender(); } catch (Transaction::InvalidSignature const &) { @@ -73,11 +79,6 @@ std::pair TransactionManager::verifyTransaction(const std::sh return {false, "gas_price too low"}; } - if (this->kConf.genesis.state.hardforks.isOnCornusHardfork(this->final_chain_->lastBlockNumber())) { - if (!trx->intrinsicGasCovered()) { - return {false, "intrinsic gas too low"}; - } - } return {true, ""}; } diff --git a/libraries/types/transaction/src/transaction.cpp b/libraries/types/transaction/src/transaction.cpp index 5ffeddf643..736da8410a 100644 --- a/libraries/types/transaction/src/transaction.cpp +++ b/libraries/types/transaction/src/transaction.cpp @@ -179,7 +179,7 @@ void Transaction::rlp(::taraxa::util::RLPDecoderRef encoding) { fromRLP(encoding void Transaction::rlp(::taraxa::util::RLPEncoderRef encoding) const { encoding.appendRaw(rlp()); } -uint64_t IntrinsicGas(const std::vector &data, bool is_contract_creation) { +inline uint64_t IntrinsicGas(const std::vector &data, bool is_contract_creation) { uint64_t gas; if (is_contract_creation) { gas = kTxGasContractCreation; @@ -207,8 +207,12 @@ uint64_t IntrinsicGas(const std::vector &data, bool is_contract_creatio } bool Transaction::intrinsicGasCovered() const { - uint64_t gas = IntrinsicGas(data_, !receiver_.has_value()); - return gas <= gas_; + try { + uint64_t gas = IntrinsicGas(data_, !receiver_.has_value()); + return gas <= gas_; + } catch (const std::runtime_error&) { + return false; + } } } // namespace taraxa From 60155b86bd6ebe9e2332656a0a3ce8b531602ca8 Mon Sep 17 00:00:00 2001 From: kstdl Date: Thu, 9 Jan 2025 10:59:25 +0100 Subject: [PATCH 3/3] chore: update devnet conrnus block number --- .../include/cli/config_jsons/devnet/devnet_genesis.json | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/libraries/cli/include/cli/config_jsons/devnet/devnet_genesis.json b/libraries/cli/include/cli/config_jsons/devnet/devnet_genesis.json index 112ef5e0a7..55b595145f 100644 --- a/libraries/cli/include/cli/config_jsons/devnet/devnet_genesis.json +++ b/libraries/cli/include/cli/config_jsons/devnet/devnet_genesis.json @@ -247,10 +247,7 @@ }, "sortition": { "changes_count_for_average": 10, - "dag_efficiency_targets": [ - 4900, - 5100 - ], + "dag_efficiency_targets": [4900, 5100], "changing_interval": 200, "computation_interval": 50, "vrf": { @@ -286,10 +283,10 @@ "bridge_contract_address": "0xcAF2b453FE8382a4B8110356DF0508f6d71F22BF" }, "cornus_hf": { - "block_num": 0, + "block_num": 1000, "delegation_locking_period": 5, "dag_gas_limit": "0x1908B100", "pbft_gas_limit": "0x7d2b7500" } } -} \ No newline at end of file +}