From 6c11debe8779c2fe0fd878fe905390019e25c31d Mon Sep 17 00:00:00 2001 From: evoskuil Date: Tue, 21 May 2024 22:00:21 -0400 Subject: [PATCH] Add txs, inputs, outputs count properties. --- include/bitcoin/system/chain/block.hpp | 1 + include/bitcoin/system/chain/transaction.hpp | 2 ++ include/bitcoin/system/impl/machine/interpreter.ipp | 2 +- src/chain/block.cpp | 7 ++++++- src/chain/transaction.cpp | 10 ++++++++++ test/chain/script.cpp | 2 ++ test/chain/transaction.cpp | 4 ++-- test/wallet/neutrino_filter.cpp | 2 +- 8 files changed, 25 insertions(+), 5 deletions(-) diff --git a/include/bitcoin/system/chain/block.hpp b/include/bitcoin/system/chain/block.hpp index 0a8e865e48..8c3436acf6 100644 --- a/include/bitcoin/system/chain/block.hpp +++ b/include/bitcoin/system/chain/block.hpp @@ -82,6 +82,7 @@ class BC_API block /// Native properties. bool is_valid() const NOEXCEPT; + size_t transactions() const NOEXCEPT; const chain::header& header() const NOEXCEPT; const chain::header::cptr header_ptr() const NOEXCEPT; const inputs_cptr inputs_ptr() const NOEXCEPT; diff --git a/include/bitcoin/system/chain/transaction.hpp b/include/bitcoin/system/chain/transaction.hpp index 46f8b64970..c0a4897796 100644 --- a/include/bitcoin/system/chain/transaction.hpp +++ b/include/bitcoin/system/chain/transaction.hpp @@ -92,6 +92,8 @@ class BC_API transaction /// Native properties. bool is_valid() const NOEXCEPT; + size_t inputs() const NOEXCEPT; + size_t outputs() const NOEXCEPT; uint32_t version() const NOEXCEPT; const inputs_cptr& inputs_ptr() const NOEXCEPT; const outputs_cptr& outputs_ptr() const NOEXCEPT; diff --git a/include/bitcoin/system/impl/machine/interpreter.ipp b/include/bitcoin/system/impl/machine/interpreter.ipp index 3d16eaad85..68f6f74a45 100644 --- a/include/bitcoin/system/impl/machine/interpreter.ipp +++ b/include/bitcoin/system/impl/machine/interpreter.ipp @@ -1589,7 +1589,7 @@ template code interpreter:: connect(const context& state, const transaction& tx, uint32_t index) NOEXCEPT { - if (index >= tx.inputs_ptr()->size()) + if (index >= tx.inputs()) return error::inputs_overflow; return connect(state, tx, std::next(tx.inputs_ptr()->begin(), index)); diff --git a/src/chain/block.cpp b/src/chain/block.cpp index 8627c620a8..c1ce8e65c2 100644 --- a/src/chain/block.cpp +++ b/src/chain/block.cpp @@ -199,6 +199,11 @@ bool block::is_valid() const NOEXCEPT return valid_; } +size_t block::transactions() const NOEXCEPT +{ + return txs_->size(); +} + const chain::header& block::header() const NOEXCEPT { return *header_; @@ -339,7 +344,7 @@ size_t block::non_coinbase_inputs() const NOEXCEPT // Overflow returns max_size_t. const auto inputs = [](size_t total, const transaction::cptr& tx) NOEXCEPT { - return ceilinged_add(total, tx->inputs_ptr()->size()); + return ceilinged_add(total, tx->inputs()); }; return std::accumulate(std::next(txs_->begin()), txs_->end(), zero, inputs); diff --git a/src/chain/transaction.cpp b/src/chain/transaction.cpp index 3258742ba8..aaeb372c55 100644 --- a/src/chain/transaction.cpp +++ b/src/chain/transaction.cpp @@ -370,6 +370,16 @@ bool transaction::is_valid() const NOEXCEPT return valid_; } +size_t transaction::inputs() const NOEXCEPT +{ + return inputs_->size(); +} + +size_t transaction::outputs() const NOEXCEPT +{ + return outputs_->size(); +} + uint32_t transaction::version() const NOEXCEPT { return version_; diff --git a/test/chain/script.cpp b/test/chain/script.cpp index d96fdc3d21..7e1e47625e 100644 --- a/test/chain/script.cpp +++ b/test/chain/script.cpp @@ -657,6 +657,7 @@ BOOST_AUTO_TEST_CASE(script__verify__testnet_block_23428_multisig_tx__success) const auto decoded_tx = base16_chunk("0100000002c0cd5346700d18a937575424eb84888bdc277bdbfade39b3bb9a4ce31fd4455101000000fdf60100483045022100f681bb660ef85bb191e337450f2ba3493c37b90a8622864d932cec5b40a74428022007cab269d846b7e63899b8e7082bdea94375d4b1c197b7c50365823c9ffd935e01483045022100b4d3be95b088c8ef176b25c9cee0b16ac7f91c10ccf645ab7421ad3de1d8aba802205c6b3bd9df0b19271abefc47997ce7bd113a6f069674003c821c01440d49a48b0148304502207fad219634211fb614cef1654bdb956a9ed751a352e47c2b64d4ac8459e05ec2022100bd4ae53e76f266938f2ec09d1b2d515eaf5e21b990e5c7df0779ca61f24a10de014830450221009f2dd7fa5eafdf9f660e764750aabffd86628bb19501d49007551151f6409266022019fad776d46c6896a849bf7fcacefa73da6d5db22680c7bacdd055d8d8547858014ccf542102d7dafdc7f5d63bc1e5210a93a93c57e96acfb123df06ca02318be689791fa634210204affb8e9fd6228d370aed6b8fff2fc33bbe9603e2933ae3b92b11a67d7e7d3d210269fa9a07b38c01440ecabc74481fdd2ede1591e293a1108ba1ac511d85e40ca62102f24bda0faab218a98c5975cb7eb035b37020ec3758e454d95f382e1f274da2112102795716e51a5539961872b559f2e938a29862565c1d0c70ed6a748adb8541c82b2103828209539e87cc72694e0d397a00ae1c1b3aa3aa7931df3bb72c71172758ed7756aeffffffffca1ea035fedd045da687f8219f6d76982b47fd3edab01212d3def0dc917d321801000000fdf40100473044022050cf9d0bf024af1780af7ce91a8cac62fd54a3df96cc1eb27889a58aaf82f09e02205f85c010faa5978963f569cfa6bd7202363841ad82bab0a6044c1092140ba49001483045022100f3f5076e1f233acf3fd2bb1188da82f3259224ee29a50af287b707c71503543f02202e82db849e59f8eb836ec6c55dab6a3d61b6511e9d25e550901d5534276432320148304502210094ff0cd6c74dd756a07334c2b76373dd4fb8f5ef7c1da7e09a168d54cf79a7770220114337de0ac0edd7871c079b796ad422d2d5e50d350d3b9f7371b0f1bd66fe7a01473044022022bc92872b6c680da40aa6388e28ef396c7ffa410317ae574c1f31836c85b28602203b43a7d2cdcc2ba1afaf53c1a0c0b474933581b0e359aed788ad7ad819260dfb014ccf542102d7dafdc7f5d63bc1e5210a93a93c57e96acfb123df06ca02318be689791fa634210204affb8e9fd6228d370aed6b8fff2fc33bbe9603e2933ae3b92b11a67d7e7d3d210269fa9a07b38c01440ecabc74481fdd2ede1591e293a1108ba1ac511d85e40ca62102f24bda0faab218a98c5975cb7eb035b37020ec3758e454d95f382e1f274da2112102795716e51a5539961872b559f2e938a29862565c1d0c70ed6a748adb8541c82b2103828209539e87cc72694e0d397a00ae1c1b3aa3aa7931df3bb72c71172758ed7756aeffffffff02605af405000000001976a914bb6754a948265de730c60fbd745aeb5868ea921e88ac00e1f5050000000017a9144aba54e2541475f91659ccdbb13ce0b490778c7f8700000000"); const transaction_accessor tx(decoded_tx, true); BOOST_REQUIRE(tx.is_valid()); + BOOST_REQUIRE_GT(tx.inputs(), index); BOOST_REQUIRE_GT(tx.inputs_ptr()->size(), index); constexpr auto value = 100000000u; @@ -822,6 +823,7 @@ BOOST_AUTO_TEST_CASE(script__verify__bip143_native_p2wpkh_tx__success) const auto decoded_tx = base16_chunk("01000000000102fff7f7881a8099afa6940d42d1e7f6362bec38171ea3edf433541db4e4ad969f00000000494830450221008b9d1dc26ba6a9cb62127b02742fa9d754cd3bebf337f7a55d114c8e5cdd30be022040529b194ba3f9281a99f2b1c0a19c0489bc22ede944ccf4ecbab4cc618ef3ed01eeffffffef51e1b804cc89d182d279655c3aa89e815b1b309fe287d9b2b55d57b90ec68a0100000000ffffffff02202cb206000000001976a9148280b37df378db99f66f85c95a783a76ac7a6d5988ac9093510d000000001976a9143bde42dbee7e4dbe6a21b2d50ce2f0167faa815988ac000247304402203609e17b84f6a7d30c80bfa610b5b4542f32a8a0d5447a12fb1366d7f01cc44a0220573a954c4518331561406f90300e8f3358f51928d43c212a8caed02de67eebee0121025476c2e83188368da1ff3e292e7acafcdb3566bb0ad253f62fc70f07aeee635711000000"); const transaction_accessor tx(decoded_tx, true); BOOST_REQUIRE(tx.is_valid()); + BOOST_REQUIRE_EQUAL(tx.inputs(), 2u); BOOST_REQUIRE_EQUAL(tx.inputs_ptr()->size(), 2u); BOOST_REQUIRE((*tx.inputs_ptr())[0]->witness().stack().empty()); BOOST_REQUIRE(!(*tx.inputs_ptr())[1]->witness().stack().empty()); diff --git a/test/chain/transaction.cpp b/test/chain/transaction.cpp index 1e9aa29be0..fa8767216f 100644 --- a/test/chain/transaction.cpp +++ b/test/chain/transaction.cpp @@ -211,8 +211,8 @@ BOOST_AUTO_TEST_CASE(transaction__constructor__move_parameters__expected) BOOST_REQUIRE(instance.is_valid()); BOOST_REQUIRE_EQUAL(version, instance.version()); BOOST_REQUIRE_EQUAL(locktime, instance.locktime()); - BOOST_REQUIRE_EQUAL(instance.inputs_ptr()->size(), 1u); - BOOST_REQUIRE_EQUAL(instance.outputs_ptr()->size(), 1u); + BOOST_REQUIRE_EQUAL(instance.inputs(), 1u); + BOOST_REQUIRE_EQUAL(instance.outputs(), 1u); BOOST_REQUIRE(*instance.inputs_ptr()->front() == input); BOOST_REQUIRE(*instance.outputs_ptr()->front() == output); } diff --git a/test/wallet/neutrino_filter.cpp b/test/wallet/neutrino_filter.cpp index 1607b1260d..e42ca692ce 100644 --- a/test/wallet/neutrino_filter.cpp +++ b/test/wallet/neutrino_filter.cpp @@ -41,7 +41,7 @@ struct prevout_data //// for (const auto& tx: *block.transactions_ptr()) //// { //// std::cout << "tx: " << tx->hash(false) << "\t\t\tis_coinbase: " << tx->is_coinbase() << std::endl; -//// for (size_t index = 0; index < tx->inputs_ptr()->size(); index++) +//// for (size_t index = 0; index < tx->inputs(); index++) //// { //// auto& output = (*tx->inputs_ptr())[index]->prevout; //// std::cout << " input: " << index << std::endl;