From 499159f4966a8c5ad28b3d3e778c4acd83c263fa Mon Sep 17 00:00:00 2001 From: evoskuil Date: Sat, 27 Jan 2024 13:04:04 -0500 Subject: [PATCH 01/12] Work around internal compiler error in latest MSVC. --- test/hash/sha/sha256.cpp | 7 ++++++- test/hash/sha/sha512.cpp | 14 ++++++++++++-- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/test/hash/sha/sha256.cpp b/test/hash/sha/sha256.cpp index 781d95886e..86f21553f4 100644 --- a/test/hash/sha/sha256.cpp +++ b/test/hash/sha/sha256.cpp @@ -232,7 +232,12 @@ BOOST_AUTO_TEST_CASE(sha256__merkle_root__two__expected) { constexpr auto expected = sha256::double_hash({ 0 }, { 1 }); #if defined (HAVE_VECTOR_CONSTEXPR) - static_assert(sha256::merkle_root({ { 0 }, { 1 } }) == expected); + + // MSVC Debug build internal compiler error. + #if !(defined(HAVE_MSC) && !defined(NDEBUG)) + static_assert(sha256::merkle_root({ { 0 }, { 1 } }) == expected); + #endif + #endif BOOST_CHECK_EQUAL(sha256::merkle_root({ { 0 }, { 1 } }), expected); } diff --git a/test/hash/sha/sha512.cpp b/test/hash/sha/sha512.cpp index 16b368a6b5..5956291e94 100644 --- a/test/hash/sha/sha512.cpp +++ b/test/hash/sha/sha512.cpp @@ -232,7 +232,12 @@ BOOST_AUTO_TEST_CASE(sha512__merkle_root__two__expected) { constexpr auto expected = sha512::double_hash({ 0 }, { 1 }); #if defined (HAVE_VECTOR_CONSTEXPR) - static_assert(sha512::merkle_root({ { 0 }, { 1 } }) == expected); + + // MSVC Debug build internal compiler error. + #if !(defined(HAVE_MSC) && !defined(NDEBUG)) + static_assert(sha512::merkle_root({ { 0 }, { 1 } }) == expected); + #endif + #endif BOOST_CHECK_EQUAL(sha512::merkle_root({ { 0 }, { 1 } }), expected); } @@ -254,7 +259,12 @@ BOOST_AUTO_TEST_CASE(sha512__merkle_root__four__expected) constexpr auto expected2 = sha512::double_hash({ 2 }, { 3 }); constexpr auto expected = sha512::double_hash(expected1, expected2); #if defined (HAVE_VECTOR_CONSTEXPR) - static_assert(sha512::merkle_root({ { 0 }, { 1 }, { 2 }, { 3 } }) == expected); + + // MSVC Debug build internal compiler error. + #if !(defined(HAVE_MSC) && !defined(NDEBUG)) + static_assert(sha512::merkle_root({ { 0 }, { 1 }, { 2 }, { 3 } }) == expected); + #endif + #endif BOOST_CHECK_EQUAL(sha512::merkle_root({ { 0 }, { 1 }, { 2 }, { 3 } }), expected); } From 577f3d43dd8cd1fd38a86bb97097b06da5157bf7 Mon Sep 17 00:00:00 2001 From: evoskuil Date: Sat, 27 Jan 2024 17:51:24 -0500 Subject: [PATCH 02/12] Define, apply, and test fast stream aliases. --- include/bitcoin/system/chain/block.hpp | 2 + include/bitcoin/system/chain/header.hpp | 2 + include/bitcoin/system/chain/input.hpp | 2 + include/bitcoin/system/chain/operation.hpp | 2 + include/bitcoin/system/chain/output.hpp | 2 + include/bitcoin/system/chain/point.hpp | 2 + include/bitcoin/system/chain/script.hpp | 2 + include/bitcoin/system/chain/transaction.hpp | 2 + include/bitcoin/system/chain/witness.hpp | 2 + .../system/stream/iostream/iostream.hpp | 2 + .../system/stream/iostream/istream.hpp | 4 +- .../system/stream/iostream/ostream.hpp | 4 +- include/bitcoin/system/stream/streamers.hpp | 47 ++++++++++--- include/bitcoin/system/stream/streams.hpp | 20 ++++-- src/chain/block.cpp | 10 +++ src/chain/header.cpp | 19 +++++- src/chain/input.cpp | 10 +++ src/chain/operation.cpp | 10 +++ src/chain/output.cpp | 10 +++ src/chain/point.cpp | 10 +++ src/chain/script.cpp | 10 +++ src/chain/transaction.cpp | 41 ++++++----- src/chain/witness.cpp | 10 +++ test/chain/block.cpp | 10 +++ test/chain/header.cpp | 9 +++ test/chain/input.cpp | 8 +++ test/chain/operation.cpp | 7 ++ test/chain/script.cpp | 8 +++ test/chain/transaction.cpp | 20 ++++++ test/stream/streamers.cpp | 68 +++++++++++++++++++ 30 files changed, 320 insertions(+), 35 deletions(-) diff --git a/include/bitcoin/system/chain/block.hpp b/include/bitcoin/system/chain/block.hpp index 45c0e39dd1..3f8f76bdaa 100644 --- a/include/bitcoin/system/chain/block.hpp +++ b/include/bitcoin/system/chain/block.hpp @@ -54,6 +54,8 @@ class BC_API block const transactions_cptr& txs) NOEXCEPT; block(const data_slice& data, bool witness) NOEXCEPT; + block(stream::in::fast&& stream, bool witness) NOEXCEPT; + block(stream::in::fast& stream, bool witness) NOEXCEPT; block(std::istream&& stream, bool witness) NOEXCEPT; block(std::istream& stream, bool witness) NOEXCEPT; block(reader&& source, bool witness) NOEXCEPT; diff --git a/include/bitcoin/system/chain/header.hpp b/include/bitcoin/system/chain/header.hpp index ff1eefca64..df385f8231 100644 --- a/include/bitcoin/system/chain/header.hpp +++ b/include/bitcoin/system/chain/header.hpp @@ -65,6 +65,8 @@ class BC_API header uint32_t nonce) NOEXCEPT; header(const data_slice& data) NOEXCEPT; + header(stream::in::fast&& stream) NOEXCEPT; + header(stream::in::fast& stream) NOEXCEPT; header(std::istream&& stream) NOEXCEPT; header(std::istream& stream) NOEXCEPT; header(reader&& source) NOEXCEPT; diff --git a/include/bitcoin/system/chain/input.hpp b/include/bitcoin/system/chain/input.hpp index 884f7f7d1c..b678d0e582 100644 --- a/include/bitcoin/system/chain/input.hpp +++ b/include/bitcoin/system/chain/input.hpp @@ -68,6 +68,8 @@ class BC_API input const chain::witness::cptr& witness, uint32_t sequence) NOEXCEPT; input(const data_slice& data) NOEXCEPT; + input(stream::in::fast&& stream) NOEXCEPT; + input(stream::in::fast& stream) NOEXCEPT; input(std::istream&& stream) NOEXCEPT; input(std::istream& stream) NOEXCEPT; input(reader&& source) NOEXCEPT; diff --git a/include/bitcoin/system/chain/operation.hpp b/include/bitcoin/system/chain/operation.hpp index 15cbe05a14..9af54dc185 100644 --- a/include/bitcoin/system/chain/operation.hpp +++ b/include/bitcoin/system/chain/operation.hpp @@ -365,6 +365,8 @@ class BC_API operation /// These deserialize operations (with codes), not from push-data. operation(const data_slice& op_data) NOEXCEPT; + operation(stream::in::fast&& stream) NOEXCEPT; + operation(stream::in::fast& stream) NOEXCEPT; operation(std::istream&& stream) NOEXCEPT; operation(std::istream& stream) NOEXCEPT; operation(reader&& source) NOEXCEPT; diff --git a/include/bitcoin/system/chain/output.hpp b/include/bitcoin/system/chain/output.hpp index 1bb8cbd92c..123a8966c1 100644 --- a/include/bitcoin/system/chain/output.hpp +++ b/include/bitcoin/system/chain/output.hpp @@ -51,6 +51,8 @@ class BC_API output output(uint64_t value, const chain::script::cptr& script) NOEXCEPT; output(const data_slice& data) NOEXCEPT; + output(stream::in::fast&& stream) NOEXCEPT; + output(stream::in::fast& stream) NOEXCEPT; output(std::istream&& stream) NOEXCEPT; output(std::istream& stream) NOEXCEPT; output(reader&& source) NOEXCEPT; diff --git a/include/bitcoin/system/chain/point.hpp b/include/bitcoin/system/chain/point.hpp index 18b3fff22c..8963239696 100644 --- a/include/bitcoin/system/chain/point.hpp +++ b/include/bitcoin/system/chain/point.hpp @@ -57,6 +57,8 @@ class BC_API point point(const hash_digest& hash, uint32_t index) NOEXCEPT; point(const data_slice& data) NOEXCEPT; + point(stream::in::fast&& stream) NOEXCEPT; + point(stream::in::fast& stream) NOEXCEPT; point(std::istream&& stream) NOEXCEPT; point(std::istream& stream) NOEXCEPT; point(reader&& source) NOEXCEPT; diff --git a/include/bitcoin/system/chain/script.hpp b/include/bitcoin/system/chain/script.hpp index 7a9854b63a..f6a6987d56 100644 --- a/include/bitcoin/system/chain/script.hpp +++ b/include/bitcoin/system/chain/script.hpp @@ -443,6 +443,8 @@ class BC_API script script(operations&& ops, bool prefail) NOEXCEPT; script(const operations& ops, bool prefail) NOEXCEPT; script(const data_slice& data, bool prefix) NOEXCEPT; + script(stream::in::fast&& stream, bool prefix) NOEXCEPT; + script(stream::in::fast& stream, bool prefix) NOEXCEPT; script(std::istream&& stream, bool prefix) NOEXCEPT; script(std::istream& stream, bool prefix) NOEXCEPT; script(reader&& source, bool prefix) NOEXCEPT; diff --git a/include/bitcoin/system/chain/transaction.hpp b/include/bitcoin/system/chain/transaction.hpp index 79fc2d2627..6235b613b3 100644 --- a/include/bitcoin/system/chain/transaction.hpp +++ b/include/bitcoin/system/chain/transaction.hpp @@ -63,6 +63,8 @@ class BC_API transaction const outputs_cptr& outputs, uint32_t locktime) NOEXCEPT; transaction(const data_slice& data, bool witness) NOEXCEPT; + transaction(stream::in::fast&& stream, bool witness) NOEXCEPT; + transaction(stream::in::fast& stream, bool witness) NOEXCEPT; transaction(std::istream&& stream, bool witness) NOEXCEPT; transaction(std::istream& stream, bool witness) NOEXCEPT; transaction(reader&& source, bool witness) NOEXCEPT; diff --git a/include/bitcoin/system/chain/witness.hpp b/include/bitcoin/system/chain/witness.hpp index a554b3cbb6..2002193971 100644 --- a/include/bitcoin/system/chain/witness.hpp +++ b/include/bitcoin/system/chain/witness.hpp @@ -56,6 +56,8 @@ class BC_API witness witness(const chunk_cptrs& stack) NOEXCEPT; witness(const data_slice& data, bool prefix) NOEXCEPT; + witness(stream::in::fast&& stream, bool prefix) NOEXCEPT; + witness(stream::in::fast& stream, bool prefix) NOEXCEPT; witness(std::istream&& stream, bool prefix) NOEXCEPT; witness(std::istream& stream, bool prefix) NOEXCEPT; witness(reader&& source, bool prefix) NOEXCEPT; diff --git a/include/bitcoin/system/stream/iostream/iostream.hpp b/include/bitcoin/system/stream/iostream/iostream.hpp index 579b727847..055baa91c9 100644 --- a/include/bitcoin/system/stream/iostream/iostream.hpp +++ b/include/bitcoin/system/stream/iostream/iostream.hpp @@ -26,6 +26,8 @@ namespace libbitcoin { namespace system { /// Support for high level input/output operations on a byte buffer. +/// Cannot derive from iostream and cannot make both share an interface. +/// So this is duck-typed to the subset of std::iostream required by flippers. template class iostream { diff --git a/include/bitcoin/system/stream/iostream/istream.hpp b/include/bitcoin/system/stream/iostream/istream.hpp index 10d9fd37b2..2b544dbecf 100644 --- a/include/bitcoin/system/stream/iostream/istream.hpp +++ b/include/bitcoin/system/stream/iostream/istream.hpp @@ -25,7 +25,9 @@ namespace libbitcoin { namespace system { -/// Support for high level input/output operations on a byte buffer. +/// Support for high level input operations on a byte buffer. +/// Cannot derive from istream and cannot make both share an interface. +/// So this is duck-typed to the subset of std::istream required by readers. template class istream { diff --git a/include/bitcoin/system/stream/iostream/ostream.hpp b/include/bitcoin/system/stream/iostream/ostream.hpp index 37ba85f03e..85a891d8e2 100644 --- a/include/bitcoin/system/stream/iostream/ostream.hpp +++ b/include/bitcoin/system/stream/iostream/ostream.hpp @@ -25,7 +25,9 @@ namespace libbitcoin { namespace system { -/// Support for high level input/output operations on a byte buffer. +/// Support for high level output operations on a byte buffer. +/// Cannot derive from ostream and cannot make both share an interface. +/// So this is duck-typed to the subset of std::ostream required by writers. template class ostream { diff --git a/include/bitcoin/system/stream/streamers.hpp b/include/bitcoin/system/stream/streamers.hpp index c0586c3c16..d218f43ab6 100644 --- a/include/bitcoin/system/stream/streamers.hpp +++ b/include/bitcoin/system/stream/streamers.hpp @@ -28,6 +28,9 @@ #include #include #include +#include +#include +#include #include #include #include @@ -67,19 +70,25 @@ namespace read { namespace bytes { - /// A byte reader that reads data from a std::istream. + /// A byte reader that reads from a std::istream. using istream = byte_reader; - /// A byte reader that copies data from a data_reference. + /// A fast byte reader that reads from a system::istream. + using fast = byte_reader>; + + /// A byte reader that copies from a data_reference via std::istream. using copy = make_streamer, byte_reader>; } namespace bits { - /// A bit reader that reads data from a std::istream. + /// A bit reader that reads from a std::istream. using istream = bit_reader; - /// A bit reader that copies data from a data_reference. + /// A fast bit reader that reads from a system::istream. + using fast = bit_reader>; + + /// A bit reader that copies from a data_reference via std::istream. using copy = make_streamer, bit_reader>; } } @@ -88,13 +97,16 @@ namespace write { namespace bytes { - /// A byte writer that writes data to a std::ostream. + /// A byte writer that writes to a std::ostream. using ostream = byte_writer; - /// A byte writer that copies data to a data_slab. + /// A fast byte writer that writes to a system::ostream. + using fast = byte_writer>; + + /// A byte writer that copies to a data_slab via std::ostream. using copy = make_streamer, byte_writer>; - /// A byte writer that inserts data into a container. + /// A byte writer that inserts into a container via std::ostream. template using push = make_streamer, byte_writer>; using text = push; @@ -103,13 +115,16 @@ namespace write namespace bits { - /// A bit writer that writes data to a std::ostream. + /// A bit writer that writes to a std::ostream. using ostream = bit_writer; - /// A bit writer that copies data to a data_slab. + /// A fast bit writer that writes to a std::ostream. + using fast = bit_writer>; + + /// A bit writer that copies to a data_slab. using copy = make_streamer, bit_writer>; - /// A bit writer that inserts data into a container. + /// A bit writer that inserts into a container via std::ostream. template using push = make_streamer, bit_writer>; using text = push; @@ -124,6 +139,9 @@ namespace flip /// A byte reader/writer of a std::iostream. using iostream = byte_flipper; + /// A fast byte reader/writer of a system::iostream. + using fast = byte_flipper>; + /// A byte reader/writer of a data_slab (no push and requires own sink). using copy = make_streamer, byte_flipper>; } @@ -133,6 +151,9 @@ namespace flip /// A bit reader/writer of a std::iostream. using iostream = bit_flipper; + /// A fast bit reader/writer of a system::iostream. + using fast = bit_flipper>; + /// A bit reader/writer of a data_slab (no push and requires own sink). using copy = make_streamer, bit_flipper>; } @@ -145,6 +166,9 @@ namespace hash /// A hash writer that writes a sha256 hash to a std::ostream. using ostream = sha256_writer; + /// A fast hash writer that writes a sha256 hash to a system::ostream. + using fast = sha256_writer>; + /// A hash writer that copies a sha256 hash to a data_slab. using copy = make_streamer, sha256_writer>; @@ -160,6 +184,9 @@ namespace hash /// A hash writer that writes a bitcoin hash to a std::ostream. using ostream = sha256x2_writer; + /// A fast hash writer that writes a bitcoin hash to a system::ostream. + using fast = sha256x2_writer>; + /// A hash writer that copies a bitcoin hash to a data_slab. using copy = make_streamer, sha256x2_writer>; diff --git a/include/bitcoin/system/stream/streams.hpp b/include/bitcoin/system/stream/streams.hpp index b78400e834..f1fe085184 100644 --- a/include/bitcoin/system/stream/streams.hpp +++ b/include/bitcoin/system/stream/streams.hpp @@ -26,6 +26,9 @@ #include #include #include +#include +#include +#include #include namespace libbitcoin { @@ -41,16 +44,22 @@ namespace stream { namespace in { - /// An input stream that copies data from a data_reference. + /// A std::istream that copies data from a data_reference. using copy = make_stream>; + + /// A fast input stream that copies data from a data_reference. + using fast = system::istream<>; } namespace out { - /// An output stream that copies data to a data_slab. + /// A std::ostream that copies data to a data_slab. using copy = make_stream>; - /// An output stream that inserts data to a container. + /// A fast output stream that copies data to a data_slab. + using fast = system:: ostream<>; + + /// A std::output stream that inserts data to a container. template using push = make_stream>; using text = push; @@ -59,8 +68,11 @@ namespace stream namespace flip { - /// An input/output stream that copies data to a data_slab. + /// A std::iostream that copies data to a data_slab. using copy = make_stream>; + + /// A fast input/output stream that copies data to a data_slab. + using fast = system::iostream<>; } } diff --git a/src/chain/block.cpp b/src/chain/block.cpp index c2d9f13813..4fc20f4f5d 100644 --- a/src/chain/block.cpp +++ b/src/chain/block.cpp @@ -79,6 +79,16 @@ block::block(const data_slice& data, bool witness) NOEXCEPT { } +block::block(stream::in::fast&& stream, bool witness) NOEXCEPT + : block(read::bytes::fast(stream), witness) +{ +} + +block::block(stream::in::fast& stream, bool witness) NOEXCEPT + : block(read::bytes::fast(stream), witness) +{ +} + block::block(std::istream&& stream, bool witness) NOEXCEPT : block(read::bytes::istream(stream), witness) { diff --git a/src/chain/header.cpp b/src/chain/header.cpp index c1ea98f96a..6f3d2285f1 100644 --- a/src/chain/header.cpp +++ b/src/chain/header.cpp @@ -66,6 +66,16 @@ header::header(const data_slice& data) NOEXCEPT { } +header::header(stream::in::fast&& stream) NOEXCEPT + : header(read::bytes::fast(stream)) +{ +} + +header::header(stream::in::fast& stream) NOEXCEPT + : header(read::bytes::fast(stream)) +{ +} + header::header(std::istream&& stream) NOEXCEPT : header(read::bytes::istream(stream)) { @@ -230,9 +240,12 @@ hash_digest header::hash() const NOEXCEPT if (hash_) return *hash_; - hash_digest digest{}; - ostream stream{ digest }; - sha256x2_writer sink{ stream }; + BC_PUSH_WARNING(LOCAL_VARIABLE_NOT_INITIALIZED) + hash_digest digest; + BC_POP_WARNING() + + stream::out::fast stream{ digest }; + hash::sha256x2::fast sink{ stream }; to_data(sink); sink.flush(); return digest; diff --git a/src/chain/input.cpp b/src/chain/input.cpp index e5b203db29..f727edde12 100644 --- a/src/chain/input.cpp +++ b/src/chain/input.cpp @@ -117,6 +117,16 @@ input::input(const data_slice& data) NOEXCEPT { } +input::input(stream::in::fast&& stream) NOEXCEPT + : input(read::bytes::fast(stream)) +{ +} + +input::input(stream::in::fast& stream) NOEXCEPT + : input(read::bytes::fast(stream)) +{ +} + input::input(std::istream&& stream) NOEXCEPT : input(read::bytes::istream(stream)) { diff --git a/src/chain/operation.cpp b/src/chain/operation.cpp index e1ca27ff38..c384d61149 100644 --- a/src/chain/operation.cpp +++ b/src/chain/operation.cpp @@ -88,6 +88,16 @@ operation::operation(const data_slice& op_data) NOEXCEPT { } +operation::operation(stream::in::fast&& stream) NOEXCEPT + : operation(read::bytes::fast(stream)) +{ +} + +operation::operation(stream::in::fast& stream) NOEXCEPT + : operation(read::bytes::fast(stream)) +{ +} + operation::operation(std::istream&& stream) NOEXCEPT : operation(read::bytes::istream(stream)) { diff --git a/src/chain/output.cpp b/src/chain/output.cpp index da5a4de213..002d381264 100644 --- a/src/chain/output.cpp +++ b/src/chain/output.cpp @@ -65,6 +65,16 @@ output::output(const data_slice& data) NOEXCEPT { } +output::output(stream::in::fast&& stream) NOEXCEPT + : output(read::bytes::fast(stream)) +{ +} + +output::output(stream::in::fast& stream) NOEXCEPT + : output(read::bytes::fast(stream)) +{ +} + output::output(std::istream&& stream) NOEXCEPT : output(read::bytes::istream(stream)) { diff --git a/src/chain/point.cpp b/src/chain/point.cpp index ea17b0477b..a8055e2e84 100644 --- a/src/chain/point.cpp +++ b/src/chain/point.cpp @@ -58,6 +58,16 @@ point::point(const data_slice& data) NOEXCEPT { } +point::point(stream::in::fast&& stream) NOEXCEPT + : point(read::bytes::fast(stream)) +{ +} + +point::point(stream::in::fast& stream) NOEXCEPT + : point(read::bytes::fast(stream)) +{ +} + point::point(std::istream&& stream) NOEXCEPT : point(read::bytes::istream(stream)) { diff --git a/src/chain/script.cpp b/src/chain/script.cpp index b63c562d48..136d4646a5 100644 --- a/src/chain/script.cpp +++ b/src/chain/script.cpp @@ -109,6 +109,16 @@ script::script(const data_slice& data, bool prefix) NOEXCEPT { } +script::script(stream::in::fast&& stream, bool prefix) NOEXCEPT + : script(read::bytes::fast(stream), prefix) +{ +} + +script::script(stream::in::fast& stream, bool prefix) NOEXCEPT + : script(read::bytes::fast(stream), prefix) +{ +} + script::script(std::istream&& stream, bool prefix) NOEXCEPT : script(read::bytes::istream(stream), prefix) { diff --git a/src/chain/transaction.cpp b/src/chain/transaction.cpp index 8d5ba70aee..a3e27d45c7 100644 --- a/src/chain/transaction.cpp +++ b/src/chain/transaction.cpp @@ -127,6 +127,16 @@ transaction::transaction(const data_slice& data, bool witness) NOEXCEPT { } +transaction::transaction(stream::in::fast&& stream, bool witness) NOEXCEPT + : transaction(read::bytes::fast(stream), witness) +{ +} + +transaction::transaction(stream::in::fast& stream, bool witness) NOEXCEPT + : transaction(read::bytes::fast(stream), witness) +{ +} + transaction::transaction(std::istream&& stream, bool witness) NOEXCEPT : transaction(read::bytes::istream(stream), witness) { @@ -424,13 +434,12 @@ hash_digest transaction::hash(bool witness) const NOEXCEPT if (witness_hash_) return *witness_hash_; } - // This is an out parameter. BC_PUSH_WARNING(LOCAL_VARIABLE_NOT_INITIALIZED) hash_digest digest; BC_POP_WARNING() - - ostream stream{ digest }; - sha256x2_writer sink{ stream }; + + stream::out::fast stream{ digest }; + hash::sha256x2::fast sink{ stream }; to_data(sink, witness); sink.flush(); return digest; @@ -487,8 +496,8 @@ hash_digest transaction::outputs_hash() const NOEXCEPT hash_digest digest; BC_POP_WARNING() - ostream stream{ digest }; - sha256x2_writer sink{ stream }; + stream::out::fast stream{ digest }; + hash::sha256x2::fast sink{ stream }; const auto& outs = *outputs_; for (const auto& output: outs) @@ -504,8 +513,8 @@ hash_digest transaction::points_hash() const NOEXCEPT hash_digest digest; BC_POP_WARNING() - ostream stream{ digest }; - sha256x2_writer sink{ stream }; + stream::out::fast stream{ digest }; + hash::sha256x2::fast sink{ stream }; const auto& ins = *inputs_; for (const auto& input: ins) @@ -521,8 +530,8 @@ hash_digest transaction::sequences_hash() const NOEXCEPT hash_digest digest; BC_POP_WARNING() - ostream stream{ digest }; - sha256x2_writer sink{ stream }; + stream::out::fast stream{ digest }; + hash::sha256x2::fast sink{ stream }; const auto& ins = *inputs_; for (const auto& input: ins) @@ -726,8 +735,8 @@ hash_digest transaction::unversioned_signature_hash( hash_digest digest; BC_POP_WARNING() - ostream stream{ digest }; - sha256x2_writer sink{ stream }; + stream::out::fast stream{ digest }; + hash::sha256x2::fast sink{ stream }; switch (flag) { @@ -795,8 +804,8 @@ hash_digest transaction::output_hash(const input_iterator& input) const NOEXCEPT hash_digest digest; BC_POP_WARNING() - ostream stream{ digest }; - sha256x2_writer sink{ stream }; + stream::out::fast stream{ digest }; + hash::sha256x2::fast sink{ stream }; outputs_->at(index)->to_data(sink); sink.flush(); return digest; @@ -824,8 +833,8 @@ hash_digest transaction::version_0_signature_hash(const input_iterator& input, hash_digest digest; BC_POP_WARNING() - ostream stream{ digest }; - sha256x2_writer sink{ stream }; + stream::out::fast stream{ digest }; + hash::sha256x2::fast sink{ stream }; // Create signature hash. sink.write_little_endian(version_); diff --git a/src/chain/witness.cpp b/src/chain/witness.cpp index 8e5b4d4531..8d739d6b5d 100644 --- a/src/chain/witness.cpp +++ b/src/chain/witness.cpp @@ -75,6 +75,16 @@ witness::witness(const data_slice& data, bool prefix) NOEXCEPT { } +witness::witness(stream::in::fast&& stream, bool prefix) NOEXCEPT + : witness(read::bytes::fast(stream), prefix) +{ +} + +witness::witness(stream::in::fast& stream, bool prefix) NOEXCEPT + : witness(read::bytes::fast(stream), prefix) +{ +} + witness::witness(std::istream&& stream, bool prefix) NOEXCEPT : witness(read::bytes::istream(stream), prefix) { diff --git a/test/chain/block.cpp b/test/chain/block.cpp index eceda12500..02e774eab5 100644 --- a/test/chain/block.cpp +++ b/test/chain/block.cpp @@ -185,6 +185,16 @@ BOOST_AUTO_TEST_CASE(block__constructor__data__expected) BOOST_REQUIRE(!block.is_invalid_merkle_root()); } +BOOST_AUTO_TEST_CASE(block__constructor__fast__success) +{ + const auto genesis = settings(selection::mainnet).genesis_block; + const auto data = genesis.to_data(true); + stream::in::fast stream(data); + const accessor block(stream, true); + BOOST_REQUIRE(block.is_valid()); + BOOST_REQUIRE(!block.is_invalid_merkle_root()); +} + BOOST_AUTO_TEST_CASE(block__constructor__stream__success) { const auto genesis = settings(selection::mainnet).genesis_block; diff --git a/test/chain/header.cpp b/test/chain/header.cpp index bda61da1a2..63221fd886 100644 --- a/test/chain/header.cpp +++ b/test/chain/header.cpp @@ -128,6 +128,15 @@ BOOST_AUTO_TEST_CASE(header__constructor__data__expected) BOOST_REQUIRE(instance == expected_header); } +BOOST_AUTO_TEST_CASE(header__constructor__fast__expected) +{ + const auto data = expected_header.to_data(); + stream::in::fast stream(data); + const header instance(stream); + BOOST_REQUIRE(instance.is_valid()); + BOOST_REQUIRE(instance == expected_header); +} + BOOST_AUTO_TEST_CASE(header__constructor__stream__expected) { const auto data = expected_header.to_data(); diff --git a/test/chain/input.cpp b/test/chain/input.cpp index f6bb5046b9..024eddfaeb 100644 --- a/test/chain/input.cpp +++ b/test/chain/input.cpp @@ -111,6 +111,14 @@ BOOST_AUTO_TEST_CASE(input__constructor__data__expected) BOOST_REQUIRE(instance == expected_input); } +BOOST_AUTO_TEST_CASE(input__constructor__fast__success) +{ + stream::in::fast stream(input_data); + const input instance(stream); + BOOST_REQUIRE(instance.is_valid()); + BOOST_REQUIRE(instance == expected_input); +} + BOOST_AUTO_TEST_CASE(input__constructor__stream__success) { stream::in::copy stream(input_data); diff --git a/test/chain/operation.cpp b/test/chain/operation.cpp index e37273a20a..7979fa6bcd 100644 --- a/test/chain/operation.cpp +++ b/test/chain/operation.cpp @@ -138,6 +138,13 @@ BOOST_AUTO_TEST_CASE(operation__constructor__op_data__expected) BOOST_REQUIRE_EQUAL(instance.to_data(), op_data); } +BOOST_AUTO_TEST_CASE(operation__constructor__fast__expected) +{ + stream::in::fast istream(op_data); + const operation instance(istream); + BOOST_REQUIRE_EQUAL(instance.to_data(), op_data); +} + BOOST_AUTO_TEST_CASE(operation__constructor__stream__expected) { stream::in::copy istream(op_data); diff --git a/test/chain/script.cpp b/test/chain/script.cpp index 09aef7b8da..5044ed988c 100644 --- a/test/chain/script.cpp +++ b/test/chain/script.cpp @@ -252,6 +252,14 @@ BOOST_AUTO_TEST_CASE(script__factory_chunk_test) BOOST_REQUIRE(instance.is_valid()); } +BOOST_AUTO_TEST_CASE(script__factory_fast_test) +{ + const auto raw = base16_chunk("76a914fc7b44566256621affb1541cc9d59f08336d276b88ac"); + stream::in::fast istream(raw); + const script instance(istream, false); + BOOST_REQUIRE(instance.is_valid()); +} + BOOST_AUTO_TEST_CASE(script__factory_stream_test) { const auto raw = base16_chunk("76a914fc7b44566256621affb1541cc9d59f08336d276b88ac"); diff --git a/test/chain/transaction.cpp b/test/chain/transaction.cpp index a79333af7d..1e9aa29be0 100644 --- a/test/chain/transaction.cpp +++ b/test/chain/transaction.cpp @@ -256,6 +256,26 @@ BOOST_AUTO_TEST_CASE(transaction__constructor__data_2__expected) BOOST_REQUIRE_EQUAL(tx.serialized_size(true), tx2_data.size()); } +BOOST_AUTO_TEST_CASE(transaction__constructor__fast_1__success) +{ + stream::in::fast stream(tx1_data); + const transaction tx(stream, true); + BOOST_REQUIRE(tx.is_valid()); + BOOST_REQUIRE_EQUAL(tx.to_data(true), tx1_data); + BOOST_REQUIRE_EQUAL(tx.hash(false), tx1_hash); + BOOST_REQUIRE_EQUAL(tx.serialized_size(true), tx1_data.size()); +} + +BOOST_AUTO_TEST_CASE(transaction__constructor___fast_2__success) +{ + stream::in::fast stream(tx2_data); + const transaction tx(stream, true); + BOOST_REQUIRE(tx.is_valid()); + BOOST_REQUIRE_EQUAL(tx.hash(false), tx2_hash); + BOOST_REQUIRE_EQUAL(tx.to_data(true), tx2_data); + BOOST_REQUIRE_EQUAL(tx.serialized_size(true), tx2_data.size()); +} + BOOST_AUTO_TEST_CASE(transaction__constructor__stream_1__success) { stream::in::copy stream(tx1_data); diff --git a/test/stream/streamers.cpp b/test/stream/streamers.cpp index c67eddbbf7..17b739d532 100644 --- a/test/stream/streamers.cpp +++ b/test/stream/streamers.cpp @@ -36,6 +36,14 @@ BOOST_AUTO_TEST_CASE(read__bytes__istream__expected) BOOST_REQUIRE_EQUAL(reader.read_byte(), '*'); } +BOOST_AUTO_TEST_CASE(read__bytes__fast__expected) +{ + const data_chunk source{ '*' }; + stream::in::fast istream(source); + read::bytes::fast reader(istream); + BOOST_REQUIRE_EQUAL(reader.read_byte(), '*'); +} + BOOST_AUTO_TEST_CASE(read__bytes__copy__expected) { const data_chunk source{ '*' }; @@ -52,6 +60,14 @@ BOOST_AUTO_TEST_CASE(read__bits__istream__expected) BOOST_REQUIRE_EQUAL(reader.read_byte(), '*'); } +BOOST_AUTO_TEST_CASE(read__bits__fast__expected) +{ + const data_chunk source{ '*' }; + stream::in::fast istream(source); + read::bits::fast reader(istream); + BOOST_REQUIRE_EQUAL(reader.read_byte(), '*'); +} + BOOST_AUTO_TEST_CASE(read__bits__copy__expected) { const data_chunk source{ '*' }; @@ -70,6 +86,15 @@ BOOST_AUTO_TEST_CASE(write__bytes__ostream__expected) BOOST_REQUIRE_EQUAL(ostream.str(), "*"); } +BOOST_AUTO_TEST_CASE(write__bytes__fast__expected) +{ + data_chunk sink{ 'x' }; + stream::out::fast ostream(sink); + write::bytes::fast writer(ostream); + writer.write_byte('*'); + BOOST_REQUIRE_EQUAL(sink[0], '*'); +} + BOOST_AUTO_TEST_CASE(write__bytes__copy__expected) { data_chunk sink{ 'x' }; @@ -130,6 +155,15 @@ BOOST_AUTO_TEST_CASE(write__bits__ostream__expected) BOOST_REQUIRE_EQUAL(ostream.str(), "*"); } +BOOST_AUTO_TEST_CASE(write__bits__fast__expected) +{ + data_chunk sink{ 'x' }; + stream::out::fast ostream(sink); + write::bits::fast writer(ostream); + writer.write_byte('*'); + BOOST_REQUIRE_EQUAL(sink.front(), '*'); +} + BOOST_AUTO_TEST_CASE(write__bits__copy__expected) { data_chunk sink{ 'x' }; @@ -189,6 +223,15 @@ BOOST_AUTO_TEST_CASE(flip__bytes__iostream_write__expected) BOOST_REQUIRE_EQUAL(iostream.str(), "*"); } +BOOST_AUTO_TEST_CASE(flip__bytes__fast_write__expected) +{ + data_chunk data{ 'x' }; + stream::flip::fast iostream(data); + flip::bytes::fast flipper(iostream); + flipper.write_byte('*'); + BOOST_REQUIRE_EQUAL(data.front(), '*'); +} + BOOST_AUTO_TEST_CASE(flip__bytes__copy_write__expected) { data_chunk data{ 'x' }; @@ -206,6 +249,14 @@ BOOST_AUTO_TEST_CASE(flip__bytes__iostream_read__expected) BOOST_REQUIRE_EQUAL(flipper.read_byte(), '*'); } +BOOST_AUTO_TEST_CASE(flip__bytes__fast_read__expected) +{ + data_chunk data{ '*' }; + stream::flip::fast iostream(data); + flip::bytes::fast flipper(iostream); + BOOST_REQUIRE_EQUAL(flipper.read_byte(), '*'); +} + BOOST_AUTO_TEST_CASE(flip__bytes__copy_read__expected) { data_chunk data{ '*' }; @@ -223,6 +274,15 @@ BOOST_AUTO_TEST_CASE(flip__bits__iostream_write__expected) BOOST_REQUIRE_EQUAL(iostream.str(), "*"); } +BOOST_AUTO_TEST_CASE(flip__bits__fast_write__expected) +{ + data_chunk data{ 'x' }; + stream::flip::fast iostream(data); + flip::bits::fast flipper(iostream); + flipper.write_byte('*'); + BOOST_REQUIRE_EQUAL(data.front(), '*'); +} + BOOST_AUTO_TEST_CASE(flip__bits__copy_write__expected) { data_chunk data{ 'x' }; @@ -240,6 +300,14 @@ BOOST_AUTO_TEST_CASE(flip__bits__iostream_read__expected) BOOST_REQUIRE_EQUAL(flipper.read_byte(), '*'); } +BOOST_AUTO_TEST_CASE(flip__bits__iostream_fast__expected) +{ + data_chunk data{ '*' }; + stream::flip::fast iostream(data); + flip::bits::fast flipper(iostream); + BOOST_REQUIRE_EQUAL(flipper.read_byte(), '*'); +} + BOOST_AUTO_TEST_CASE(flip__bits__copy_read__expected) { data_chunk data{ '*' }; From 5ca83e4188ea7e07cf731bda66ed34e606a5c0de Mon Sep 17 00:00:00 2001 From: evoskuil Date: Mon, 29 Jan 2024 11:39:30 -0500 Subject: [PATCH 03/12] Expect shan-ni support on windows builds. --- test/intrinsics/haves.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/intrinsics/haves.cpp b/test/intrinsics/haves.cpp index 5dacbc15f9..1b2b38697e 100644 --- a/test/intrinsics/haves.cpp +++ b/test/intrinsics/haves.cpp @@ -242,7 +242,7 @@ BOOST_AUTO_TEST_CASE(intrinsics__have_lanes__sse41__expected) // ---------------------------------------------------------------------------- // These use BOOST_WARN to let us know if vectorization did not execute due to // CI platform processor configuration. Currently all CI platforms have SSE41 -// and AVX2, while about 50% have AVX512BW. +// and AVX2, while about 50% have AVX512BW. Windows platforms now have SHANI. BOOST_AUTO_TEST_CASE(intrinsics_haves__have_avx512__when_defined__true) { @@ -280,9 +280,9 @@ BOOST_AUTO_TEST_CASE(intrinsics_haves__have_sse41a__when_x64__true_except_msc) #endif } -BOOST_AUTO_TEST_CASE(intrinsics_haves__have_shani__when_defined__true_except_msc) +BOOST_AUTO_TEST_CASE(intrinsics_haves__have_shani__when_defined__true) { -#if defined(HAVE_SHANI) && !defined(HAVE_MSC) +#if defined(HAVE_SHANI) BOOST_WARN(have_shani()); #else BOOST_REQUIRE(!have_shani()); From a01f4063fca4a53c337af5aa3d01e2819a3e8bd2 Mon Sep 17 00:00:00 2001 From: evoskuil Date: Mon, 29 Jan 2024 12:04:10 -0500 Subject: [PATCH 04/12] Make prvalue return explicit for xcode. --- src/chain/input.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/chain/input.cpp b/src/chain/input.cpp index f727edde12..268fd06866 100644 --- a/src/chain/input.cpp +++ b/src/chain/input.cpp @@ -341,7 +341,9 @@ bool input::extract_sigop_script(chain::script& out, // Parse the embedded script from the last input script item (data). // This cannot fail because there is no prefix to invalidate the length. - out = { ops.back().data(), false }; + // Workaround: XCode inteprets this as both prvalue and rvalue (ambiguous). + ////out = { ops.back().data(), false }; + out = chain::script{ ops.back().data(), false }; return true; } From 51795131755dbc270c2823205c5f0b645b6c87a0 Mon Sep 17 00:00:00 2001 From: evoskuil Date: Mon, 29 Jan 2024 12:17:52 -0500 Subject: [PATCH 05/12] Make prvalue return explicit for xcode (second attempt). --- src/chain/input.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/chain/input.cpp b/src/chain/input.cpp index 268fd06866..3db30b6c67 100644 --- a/src/chain/input.cpp +++ b/src/chain/input.cpp @@ -343,7 +343,7 @@ bool input::extract_sigop_script(chain::script& out, // This cannot fail because there is no prefix to invalidate the length. // Workaround: XCode inteprets this as both prvalue and rvalue (ambiguous). ////out = { ops.back().data(), false }; - out = chain::script{ ops.back().data(), false }; + out = std::move(chain::script{ ops.back().data(), false }); return true; } From c4746765588e14d650697e679d7248519c2567a6 Mon Sep 17 00:00:00 2001 From: evoskuil Date: Mon, 29 Jan 2024 13:00:11 -0500 Subject: [PATCH 06/12] Remove forced inlining from fast streams. --- .../system/impl/stream/iostream/iostream.ipp | 30 +++++++++---------- .../system/impl/stream/iostream/istream.ipp | 21 +++++++------ .../system/impl/stream/iostream/ostream.ipp | 14 ++++----- .../system/stream/iostream/iostream.hpp | 26 ++++++++-------- .../system/stream/iostream/istream.hpp | 20 ++++++------- .../system/stream/iostream/ostream.hpp | 18 +++++------ 6 files changed, 64 insertions(+), 65 deletions(-) diff --git a/include/bitcoin/system/impl/stream/iostream/iostream.ipp b/include/bitcoin/system/impl/stream/iostream/iostream.ipp index 64066b822c..ae51ef7b75 100644 --- a/include/bitcoin/system/impl/stream/iostream/iostream.ipp +++ b/include/bitcoin/system/impl/stream/iostream/iostream.ipp @@ -28,7 +28,7 @@ BC_PUSH_WARNING(NO_POINTER_ARITHMETIC) template template -INLINE iostream::iostream(Buffer& buffer) NOEXCEPT +iostream::iostream(Buffer& buffer) NOEXCEPT : position_(buffer.data()), begin_(position_), end_(begin_ + buffer.size()), @@ -37,7 +37,7 @@ INLINE iostream::iostream(Buffer& buffer) NOEXCEPT } template -INLINE iostream::iostream(uint8_t* begin, +iostream::iostream(uint8_t* begin, ptrdiff_t size) NOEXCEPT : position_(begin), begin_(position_), @@ -47,21 +47,21 @@ INLINE iostream::iostream(uint8_t* begin, } template -INLINE typename iostream::iostate +inline typename iostream::iostate iostream::rdstate() const NOEXCEPT { return state_; } template -INLINE void +inline void iostream::setstate(iostate state) NOEXCEPT { state_ |= state; } template -INLINE void +inline void iostream::clear(iostate state) NOEXCEPT { state_ = state; @@ -69,21 +69,21 @@ iostream::clear(iostate state) NOEXCEPT template -INLINE typename iostream::pos_type +inline typename iostream::pos_type iostream::tellg() const NOEXCEPT { return static_cast(position_ - begin_); } template -INLINE typename iostream::pos_type +inline typename iostream::pos_type iostream::tellp() const NOEXCEPT { return static_cast(position_ - begin_); } template -INLINE iostream& +iostream& iostream::seekg(off_type offset, seekdir direction) NOEXCEPT { if (state_ != goodbit) @@ -137,7 +137,7 @@ iostream::seekg(off_type offset, seekdir direction) NOEXCEPT } template -INLINE typename iostream::int_type +typename iostream::int_type iostream::peek() NOEXCEPT { constexpr auto eof = std::char_traits::eof(); @@ -153,7 +153,7 @@ iostream::peek() NOEXCEPT } template -INLINE void +void iostream::read(char_type* data, pos_type size) NOEXCEPT { if (is_overflow(size)) @@ -170,7 +170,7 @@ iostream::read(char_type* data, pos_type size) NOEXCEPT } template -INLINE void +void iostream::write(const char_type* data, pos_type size) NOEXCEPT { @@ -181,14 +181,14 @@ iostream::write(const char_type* data, } BC_PUSH_WARNING(NO_UNSAFE_COPY_N) - std::copy_n(data, size, position_); + std::copy_n(data, size, position_); BC_POP_WARNING() - position_ += size; + position_ += size; } template -INLINE void +void iostream::flush() NOEXCEPT { } @@ -203,7 +203,7 @@ iostream::is_positive(off_type value) NOEXCEPT // private template -INLINE bool +bool iostream::is_overflow(pos_type size) const NOEXCEPT { return (state_ != goodbit) || (size > (end_ - position_)); diff --git a/include/bitcoin/system/impl/stream/iostream/istream.ipp b/include/bitcoin/system/impl/stream/iostream/istream.ipp index 56692b8f44..7739395289 100644 --- a/include/bitcoin/system/impl/stream/iostream/istream.ipp +++ b/include/bitcoin/system/impl/stream/iostream/istream.ipp @@ -30,7 +30,7 @@ BC_PUSH_WARNING(NO_POINTER_ARITHMETIC) template template -INLINE istream::istream(const Buffer& buffer) NOEXCEPT +istream::istream(const Buffer& buffer) NOEXCEPT : position_(buffer.data()), begin_(position_), end_(begin_ + buffer.size()), @@ -39,8 +39,7 @@ INLINE istream::istream(const Buffer& buffer) NOEXCEPT } template -INLINE istream::istream(const uint8_t* begin, - ptrdiff_t size) NOEXCEPT +istream::istream(const uint8_t* begin, ptrdiff_t size) NOEXCEPT : position_(begin), begin_(position_), end_(begin_ + size), @@ -49,35 +48,35 @@ INLINE istream::istream(const uint8_t* begin, } template -INLINE typename istream::iostate +inline typename istream::iostate istream::rdstate() const NOEXCEPT { return state_; } template -INLINE void +inline void istream::setstate(iostate state) NOEXCEPT { state_ |= state; } template -INLINE void +inline void istream::clear(iostate state) NOEXCEPT { state_ = state; } template -INLINE typename istream::pos_type +inline typename istream::pos_type istream::tellg() const NOEXCEPT { return static_cast(position_ - begin_); } template -INLINE istream& +istream& istream::seekg(off_type offset, seekdir direction) NOEXCEPT { if (state_ != goodbit) @@ -131,7 +130,7 @@ istream::seekg(off_type offset, seekdir direction) NOEXCEPT } template -INLINE typename istream::int_type +typename istream::int_type istream::peek() NOEXCEPT { constexpr auto eof = std::char_traits::eof(); @@ -147,7 +146,7 @@ istream::peek() NOEXCEPT } template -INLINE void +void istream::read(char_type* data, pos_type size) NOEXCEPT { if (is_overflow(size)) @@ -173,7 +172,7 @@ istream::is_positive(off_type value) NOEXCEPT // private template -INLINE bool +bool istream::is_overflow(pos_type size) const NOEXCEPT { return (state_ != goodbit) || (size > (end_ - position_)); diff --git a/include/bitcoin/system/impl/stream/iostream/ostream.ipp b/include/bitcoin/system/impl/stream/iostream/ostream.ipp index db7c49f3f6..70bcefd79e 100644 --- a/include/bitcoin/system/impl/stream/iostream/ostream.ipp +++ b/include/bitcoin/system/impl/stream/iostream/ostream.ipp @@ -48,35 +48,35 @@ ostream::ostream(uint8_t* begin, } template -INLINE typename ostream::iostate +inline typename ostream::iostate ostream::rdstate() const NOEXCEPT { return state_; } template -INLINE void +inline void ostream::setstate(iostate state) NOEXCEPT { state_ |= state; } template -INLINE void +inline void ostream::clear(iostate state) NOEXCEPT { state_ = state; } template -INLINE typename ostream::pos_type +inline typename ostream::pos_type ostream::tellp() const NOEXCEPT { return static_cast(position_ - begin_); } template -INLINE void +void ostream::write(const char_type* data, pos_type size) NOEXCEPT { @@ -94,14 +94,14 @@ ostream::write(const char_type* data, } template -INLINE void +void ostream::flush() NOEXCEPT { } // private template -INLINE bool +bool ostream::is_overflow(pos_type size) const NOEXCEPT { return (state_ != goodbit) || (size > (end_ - position_)); diff --git a/include/bitcoin/system/stream/iostream/iostream.hpp b/include/bitcoin/system/stream/iostream/iostream.hpp index 055baa91c9..82984843f3 100644 --- a/include/bitcoin/system/stream/iostream/iostream.hpp +++ b/include/bitcoin/system/stream/iostream/iostream.hpp @@ -53,42 +53,42 @@ class iostream /// Construct the object. template - INLINE iostream(Buffer& buffer) NOEXCEPT; - INLINE iostream(uint8_t* begin, ptrdiff_t size) NOEXCEPT; + iostream(Buffer& buffer) NOEXCEPT; + iostream(uint8_t* begin, ptrdiff_t size) NOEXCEPT; /// Return state flags. - virtual INLINE iostate rdstate() const NOEXCEPT; + virtual inline iostate rdstate() const NOEXCEPT; /// Set the stream error flags state in addition to currently set flags. - virtual INLINE void setstate(iostate state) NOEXCEPT; + virtual inline void setstate(iostate state) NOEXCEPT; /// Set the stream error state flags by assigning the state value. - virtual INLINE void clear(iostate state = goodbit) NOEXCEPT; + virtual inline void clear(iostate state = goodbit) NOEXCEPT; /// Return the relative input position indicator (zero-based). - virtual INLINE pos_type tellg() const NOEXCEPT; + virtual inline pos_type tellg() const NOEXCEPT; /// Return the relative output position indicator (zero-based). - virtual INLINE pos_type tellp() const NOEXCEPT; + virtual inline pos_type tellp() const NOEXCEPT; /// Set the relative input position indicator (zero-based). - virtual INLINE iostream& seekg(off_type offset, seekdir direction) NOEXCEPT; + virtual iostream& seekg(off_type offset, seekdir direction) NOEXCEPT; /// Read the next character without advancing, sets badbit on underflow. - virtual INLINE int_type peek() NOEXCEPT; + virtual int_type peek() NOEXCEPT; /// Read a block of characters, sets badbit on underflow. - virtual INLINE void read(char_type* data, pos_type size) NOEXCEPT; + virtual void read(char_type* data, pos_type size) NOEXCEPT; /// Write a block of characters, sets badbit on overflow. - virtual INLINE void write(const char_type* data, pos_type size) NOEXCEPT; + virtual void write(const char_type* data, pos_type size) NOEXCEPT; /// Synchronize with the underlying storage device (no-op). - virtual INLINE void flush() NOEXCEPT; + virtual void flush() NOEXCEPT; private: static constexpr bool is_positive(off_type value) NOEXCEPT; - INLINE bool is_overflow(pos_type size) const NOEXCEPT; + bool is_overflow(pos_type size) const NOEXCEPT; uint8_t* position_; uint8_t* begin_; diff --git a/include/bitcoin/system/stream/iostream/istream.hpp b/include/bitcoin/system/stream/iostream/istream.hpp index 2b544dbecf..16b0bfc645 100644 --- a/include/bitcoin/system/stream/iostream/istream.hpp +++ b/include/bitcoin/system/stream/iostream/istream.hpp @@ -53,33 +53,33 @@ class istream /// Construct the object. template - INLINE istream(const Buffer& buffer) NOEXCEPT; - INLINE istream(const uint8_t* begin, ptrdiff_t size) NOEXCEPT; + istream(const Buffer& buffer) NOEXCEPT; + istream(const uint8_t* begin, ptrdiff_t size) NOEXCEPT; /// Return state flags. - virtual INLINE iostate rdstate() const NOEXCEPT; + virtual inline iostate rdstate() const NOEXCEPT; /// Set the stream error flags state in addition to currently set flags. - virtual INLINE void setstate(iostate state) NOEXCEPT; + virtual inline void setstate(iostate state) NOEXCEPT; /// Set the stream error state flags by assigning the state value. - virtual INLINE void clear(iostate state=goodbit) NOEXCEPT; + virtual inline void clear(iostate state=goodbit) NOEXCEPT; /// Return the relative input position indicator (zero-based). - virtual INLINE pos_type tellg() const NOEXCEPT; + virtual inline pos_type tellg() const NOEXCEPT; /// Set the relative input position indicator (zero-based). - virtual INLINE istream& seekg(off_type offset, seekdir direction) NOEXCEPT; + virtual istream& seekg(off_type offset, seekdir direction) NOEXCEPT; /// Read the next character without advancing, sets badbit on underflow. - virtual INLINE int_type peek() NOEXCEPT; + virtual int_type peek() NOEXCEPT; /// Read a block of characters, sets badbit on underflow. - virtual INLINE void read(char_type* data, pos_type size) NOEXCEPT; + virtual void read(char_type* data, pos_type size) NOEXCEPT; private: static constexpr bool is_positive(off_type value) NOEXCEPT; - INLINE bool is_overflow(pos_type size) const NOEXCEPT; + bool is_overflow(pos_type size) const NOEXCEPT; const uint8_t* position_; const uint8_t* begin_; diff --git a/include/bitcoin/system/stream/iostream/ostream.hpp b/include/bitcoin/system/stream/iostream/ostream.hpp index 85a891d8e2..f4976add14 100644 --- a/include/bitcoin/system/stream/iostream/ostream.hpp +++ b/include/bitcoin/system/stream/iostream/ostream.hpp @@ -48,29 +48,29 @@ class ostream /// Construct the object. template - INLINE ostream(Buffer& buffer) NOEXCEPT; - INLINE ostream(uint8_t* begin, ptrdiff_t size) NOEXCEPT; + ostream(Buffer& buffer) NOEXCEPT; + ostream(uint8_t* begin, ptrdiff_t size) NOEXCEPT; /// Return state flags. - virtual INLINE iostate rdstate() const NOEXCEPT; + virtual inline iostate rdstate() const NOEXCEPT; /// Set the stream error flags state in addition to currently set flags. - virtual INLINE void setstate(iostate state) NOEXCEPT; + virtual inline void setstate(iostate state) NOEXCEPT; /// Set the stream error state flags by assigning the state value. - virtual INLINE void clear(iostate state=goodbit) NOEXCEPT; + virtual inline void clear(iostate state=goodbit) NOEXCEPT; /// Return the relative output position indicator (zero-based). - virtual INLINE pos_type tellp() const NOEXCEPT; + virtual inline pos_type tellp() const NOEXCEPT; /// Write a block of characters, sets badbit on overflow. - virtual INLINE void write(const char_type* data, pos_type size) NOEXCEPT; + virtual void write(const char_type* data, pos_type size) NOEXCEPT; /// Synchronize with the underlying storage device (no-op). - virtual INLINE void flush() NOEXCEPT; + virtual void flush() NOEXCEPT; private: - INLINE bool is_overflow(pos_type size) const NOEXCEPT; + bool is_overflow(pos_type size) const NOEXCEPT; uint8_t* position_; uint8_t* begin_; From b34e78875a6f70f44dd7c91b5d73ada89cd3473a Mon Sep 17 00:00:00 2001 From: evoskuil Date: Mon, 29 Jan 2024 13:16:46 -0500 Subject: [PATCH 07/12] Disable chain object construction from moved fast streams. --- include/bitcoin/system/chain/block.hpp | 2 +- include/bitcoin/system/chain/header.hpp | 2 +- include/bitcoin/system/chain/input.hpp | 2 +- include/bitcoin/system/chain/operation.hpp | 2 +- include/bitcoin/system/chain/output.hpp | 2 +- include/bitcoin/system/chain/point.hpp | 2 +- include/bitcoin/system/chain/script.hpp | 2 +- include/bitcoin/system/chain/transaction.hpp | 2 +- include/bitcoin/system/chain/witness.hpp | 2 +- src/chain/block.cpp | 8 ++++---- src/chain/header.cpp | 8 ++++---- src/chain/input.cpp | 12 +++++------- src/chain/operation.cpp | 8 ++++---- src/chain/output.cpp | 8 ++++---- src/chain/point.cpp | 8 ++++---- src/chain/script.cpp | 8 ++++---- src/chain/transaction.cpp | 8 ++++---- src/chain/witness.cpp | 8 ++++---- 18 files changed, 46 insertions(+), 48 deletions(-) diff --git a/include/bitcoin/system/chain/block.hpp b/include/bitcoin/system/chain/block.hpp index 3f8f76bdaa..fbe555a29a 100644 --- a/include/bitcoin/system/chain/block.hpp +++ b/include/bitcoin/system/chain/block.hpp @@ -54,7 +54,7 @@ class BC_API block const transactions_cptr& txs) NOEXCEPT; block(const data_slice& data, bool witness) NOEXCEPT; - block(stream::in::fast&& stream, bool witness) NOEXCEPT; + ////block(stream::in::fast&& stream, bool witness) NOEXCEPT; block(stream::in::fast& stream, bool witness) NOEXCEPT; block(std::istream&& stream, bool witness) NOEXCEPT; block(std::istream& stream, bool witness) NOEXCEPT; diff --git a/include/bitcoin/system/chain/header.hpp b/include/bitcoin/system/chain/header.hpp index df385f8231..9dee4ec8fb 100644 --- a/include/bitcoin/system/chain/header.hpp +++ b/include/bitcoin/system/chain/header.hpp @@ -65,7 +65,7 @@ class BC_API header uint32_t nonce) NOEXCEPT; header(const data_slice& data) NOEXCEPT; - header(stream::in::fast&& stream) NOEXCEPT; + ////header(stream::in::fast&& stream) NOEXCEPT; header(stream::in::fast& stream) NOEXCEPT; header(std::istream&& stream) NOEXCEPT; header(std::istream& stream) NOEXCEPT; diff --git a/include/bitcoin/system/chain/input.hpp b/include/bitcoin/system/chain/input.hpp index b678d0e582..7e2f19b6d5 100644 --- a/include/bitcoin/system/chain/input.hpp +++ b/include/bitcoin/system/chain/input.hpp @@ -68,7 +68,7 @@ class BC_API input const chain::witness::cptr& witness, uint32_t sequence) NOEXCEPT; input(const data_slice& data) NOEXCEPT; - input(stream::in::fast&& stream) NOEXCEPT; + ////input(stream::in::fast&& stream) NOEXCEPT; input(stream::in::fast& stream) NOEXCEPT; input(std::istream&& stream) NOEXCEPT; input(std::istream& stream) NOEXCEPT; diff --git a/include/bitcoin/system/chain/operation.hpp b/include/bitcoin/system/chain/operation.hpp index 9af54dc185..46c7f21092 100644 --- a/include/bitcoin/system/chain/operation.hpp +++ b/include/bitcoin/system/chain/operation.hpp @@ -365,7 +365,7 @@ class BC_API operation /// These deserialize operations (with codes), not from push-data. operation(const data_slice& op_data) NOEXCEPT; - operation(stream::in::fast&& stream) NOEXCEPT; + ////operation(stream::in::fast&& stream) NOEXCEPT; operation(stream::in::fast& stream) NOEXCEPT; operation(std::istream&& stream) NOEXCEPT; operation(std::istream& stream) NOEXCEPT; diff --git a/include/bitcoin/system/chain/output.hpp b/include/bitcoin/system/chain/output.hpp index 123a8966c1..42273880ee 100644 --- a/include/bitcoin/system/chain/output.hpp +++ b/include/bitcoin/system/chain/output.hpp @@ -51,7 +51,7 @@ class BC_API output output(uint64_t value, const chain::script::cptr& script) NOEXCEPT; output(const data_slice& data) NOEXCEPT; - output(stream::in::fast&& stream) NOEXCEPT; + ////output(stream::in::fast&& stream) NOEXCEPT; output(stream::in::fast& stream) NOEXCEPT; output(std::istream&& stream) NOEXCEPT; output(std::istream& stream) NOEXCEPT; diff --git a/include/bitcoin/system/chain/point.hpp b/include/bitcoin/system/chain/point.hpp index 8963239696..c34281cdde 100644 --- a/include/bitcoin/system/chain/point.hpp +++ b/include/bitcoin/system/chain/point.hpp @@ -57,7 +57,7 @@ class BC_API point point(const hash_digest& hash, uint32_t index) NOEXCEPT; point(const data_slice& data) NOEXCEPT; - point(stream::in::fast&& stream) NOEXCEPT; + ////point(stream::in::fast&& stream) NOEXCEPT; point(stream::in::fast& stream) NOEXCEPT; point(std::istream&& stream) NOEXCEPT; point(std::istream& stream) NOEXCEPT; diff --git a/include/bitcoin/system/chain/script.hpp b/include/bitcoin/system/chain/script.hpp index f6a6987d56..ddc43ec42b 100644 --- a/include/bitcoin/system/chain/script.hpp +++ b/include/bitcoin/system/chain/script.hpp @@ -443,7 +443,7 @@ class BC_API script script(operations&& ops, bool prefail) NOEXCEPT; script(const operations& ops, bool prefail) NOEXCEPT; script(const data_slice& data, bool prefix) NOEXCEPT; - script(stream::in::fast&& stream, bool prefix) NOEXCEPT; + ////script(stream::in::fast&& stream, bool prefix) NOEXCEPT; script(stream::in::fast& stream, bool prefix) NOEXCEPT; script(std::istream&& stream, bool prefix) NOEXCEPT; script(std::istream& stream, bool prefix) NOEXCEPT; diff --git a/include/bitcoin/system/chain/transaction.hpp b/include/bitcoin/system/chain/transaction.hpp index 6235b613b3..60ec216367 100644 --- a/include/bitcoin/system/chain/transaction.hpp +++ b/include/bitcoin/system/chain/transaction.hpp @@ -63,7 +63,7 @@ class BC_API transaction const outputs_cptr& outputs, uint32_t locktime) NOEXCEPT; transaction(const data_slice& data, bool witness) NOEXCEPT; - transaction(stream::in::fast&& stream, bool witness) NOEXCEPT; + ////transaction(stream::in::fast&& stream, bool witness) NOEXCEPT; transaction(stream::in::fast& stream, bool witness) NOEXCEPT; transaction(std::istream&& stream, bool witness) NOEXCEPT; transaction(std::istream& stream, bool witness) NOEXCEPT; diff --git a/include/bitcoin/system/chain/witness.hpp b/include/bitcoin/system/chain/witness.hpp index 2002193971..6c9a45e1cb 100644 --- a/include/bitcoin/system/chain/witness.hpp +++ b/include/bitcoin/system/chain/witness.hpp @@ -56,7 +56,7 @@ class BC_API witness witness(const chunk_cptrs& stack) NOEXCEPT; witness(const data_slice& data, bool prefix) NOEXCEPT; - witness(stream::in::fast&& stream, bool prefix) NOEXCEPT; + ////witness(stream::in::fast&& stream, bool prefix) NOEXCEPT; witness(stream::in::fast& stream, bool prefix) NOEXCEPT; witness(std::istream&& stream, bool prefix) NOEXCEPT; witness(std::istream& stream, bool prefix) NOEXCEPT; diff --git a/src/chain/block.cpp b/src/chain/block.cpp index 4fc20f4f5d..30f1597140 100644 --- a/src/chain/block.cpp +++ b/src/chain/block.cpp @@ -79,10 +79,10 @@ block::block(const data_slice& data, bool witness) NOEXCEPT { } -block::block(stream::in::fast&& stream, bool witness) NOEXCEPT - : block(read::bytes::fast(stream), witness) -{ -} +////block::block(stream::in::fast&& stream, bool witness) NOEXCEPT +//// : block(read::bytes::fast(stream), witness) +////{ +////} block::block(stream::in::fast& stream, bool witness) NOEXCEPT : block(read::bytes::fast(stream), witness) diff --git a/src/chain/header.cpp b/src/chain/header.cpp index 6f3d2285f1..fd16f59903 100644 --- a/src/chain/header.cpp +++ b/src/chain/header.cpp @@ -66,10 +66,10 @@ header::header(const data_slice& data) NOEXCEPT { } -header::header(stream::in::fast&& stream) NOEXCEPT - : header(read::bytes::fast(stream)) -{ -} +////header::header(stream::in::fast&& stream) NOEXCEPT +//// : header(read::bytes::fast(stream)) +////{ +////} header::header(stream::in::fast& stream) NOEXCEPT : header(read::bytes::fast(stream)) diff --git a/src/chain/input.cpp b/src/chain/input.cpp index 3db30b6c67..0634e95944 100644 --- a/src/chain/input.cpp +++ b/src/chain/input.cpp @@ -117,10 +117,10 @@ input::input(const data_slice& data) NOEXCEPT { } -input::input(stream::in::fast&& stream) NOEXCEPT - : input(read::bytes::fast(stream)) -{ -} +////input::input(stream::in::fast&& stream) NOEXCEPT +//// : input(read::bytes::fast(stream)) +////{ +////} input::input(stream::in::fast& stream) NOEXCEPT : input(read::bytes::fast(stream)) @@ -341,9 +341,7 @@ bool input::extract_sigop_script(chain::script& out, // Parse the embedded script from the last input script item (data). // This cannot fail because there is no prefix to invalidate the length. - // Workaround: XCode inteprets this as both prvalue and rvalue (ambiguous). - ////out = { ops.back().data(), false }; - out = std::move(chain::script{ ops.back().data(), false }); + out = { ops.back().data(), false }; return true; } diff --git a/src/chain/operation.cpp b/src/chain/operation.cpp index c384d61149..9cbd3c0f9c 100644 --- a/src/chain/operation.cpp +++ b/src/chain/operation.cpp @@ -88,10 +88,10 @@ operation::operation(const data_slice& op_data) NOEXCEPT { } -operation::operation(stream::in::fast&& stream) NOEXCEPT - : operation(read::bytes::fast(stream)) -{ -} +////operation::operation(stream::in::fast&& stream) NOEXCEPT +//// : operation(read::bytes::fast(stream)) +////{ +////} operation::operation(stream::in::fast& stream) NOEXCEPT : operation(read::bytes::fast(stream)) diff --git a/src/chain/output.cpp b/src/chain/output.cpp index 002d381264..02cbb79653 100644 --- a/src/chain/output.cpp +++ b/src/chain/output.cpp @@ -65,10 +65,10 @@ output::output(const data_slice& data) NOEXCEPT { } -output::output(stream::in::fast&& stream) NOEXCEPT - : output(read::bytes::fast(stream)) -{ -} +////output::output(stream::in::fast&& stream) NOEXCEPT +//// : output(read::bytes::fast(stream)) +////{ +////} output::output(stream::in::fast& stream) NOEXCEPT : output(read::bytes::fast(stream)) diff --git a/src/chain/point.cpp b/src/chain/point.cpp index a8055e2e84..6443caa183 100644 --- a/src/chain/point.cpp +++ b/src/chain/point.cpp @@ -58,10 +58,10 @@ point::point(const data_slice& data) NOEXCEPT { } -point::point(stream::in::fast&& stream) NOEXCEPT - : point(read::bytes::fast(stream)) -{ -} +////point::point(stream::in::fast&& stream) NOEXCEPT +//// : point(read::bytes::fast(stream)) +////{ +////} point::point(stream::in::fast& stream) NOEXCEPT : point(read::bytes::fast(stream)) diff --git a/src/chain/script.cpp b/src/chain/script.cpp index 136d4646a5..d9310516eb 100644 --- a/src/chain/script.cpp +++ b/src/chain/script.cpp @@ -109,10 +109,10 @@ script::script(const data_slice& data, bool prefix) NOEXCEPT { } -script::script(stream::in::fast&& stream, bool prefix) NOEXCEPT - : script(read::bytes::fast(stream), prefix) -{ -} +////script::script(stream::in::fast&& stream, bool prefix) NOEXCEPT +//// : script(read::bytes::fast(stream), prefix) +////{ +////} script::script(stream::in::fast& stream, bool prefix) NOEXCEPT : script(read::bytes::fast(stream), prefix) diff --git a/src/chain/transaction.cpp b/src/chain/transaction.cpp index a3e27d45c7..e33a5242d3 100644 --- a/src/chain/transaction.cpp +++ b/src/chain/transaction.cpp @@ -127,10 +127,10 @@ transaction::transaction(const data_slice& data, bool witness) NOEXCEPT { } -transaction::transaction(stream::in::fast&& stream, bool witness) NOEXCEPT - : transaction(read::bytes::fast(stream), witness) -{ -} +////transaction::transaction(stream::in::fast&& stream, bool witness) NOEXCEPT +//// : transaction(read::bytes::fast(stream), witness) +////{ +////} transaction::transaction(stream::in::fast& stream, bool witness) NOEXCEPT : transaction(read::bytes::fast(stream), witness) diff --git a/src/chain/witness.cpp b/src/chain/witness.cpp index 8d739d6b5d..963168b8a9 100644 --- a/src/chain/witness.cpp +++ b/src/chain/witness.cpp @@ -75,10 +75,10 @@ witness::witness(const data_slice& data, bool prefix) NOEXCEPT { } -witness::witness(stream::in::fast&& stream, bool prefix) NOEXCEPT - : witness(read::bytes::fast(stream), prefix) -{ -} +////witness::witness(stream::in::fast&& stream, bool prefix) NOEXCEPT +//// : witness(read::bytes::fast(stream), prefix) +////{ +////} witness::witness(stream::in::fast& stream, bool prefix) NOEXCEPT : witness(read::bytes::fast(stream), prefix) From 24b8a70c57523d0f60c965add9d0a4717c38b151 Mon Sep 17 00:00:00 2001 From: evoskuil Date: Mon, 29 Jan 2024 13:40:53 -0500 Subject: [PATCH 08/12] Regenerate artifacts, bumps to clang15. --- .github/workflows/ci.yml | 70 +++++++++++++++++++++++++--------------- install-cmake.sh | 15 +++------ install-cmakepresets.sh | 15 +++------ install.sh | 2 ++ 4 files changed, 56 insertions(+), 46 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2e6335e697..e08f04143c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,28 +18,28 @@ jobs: matrix: include: - os: ubuntu-22.04 - cxx: "clang++-14" + cxx: "clang++-15" link: "dynamic" optimization: "size" assert: "debug" coverage: "nocov" boost: "--build-boost" icu: "" - cc: "clang-14" + cc: "clang-15" flags: "-Os -fPIE" options: "--enable-isystem --enable-avx2 --enable-sse4" packager: "apt" packages: "" - os: ubuntu-22.04 - cxx: "clang++-14" + cxx: "clang++-15" link: "static" optimization: "size" assert: "ndebug" coverage: "nocov" boost: "--build-boost" icu: "--build-icu --with-icu" - cc: "clang-14" + cc: "clang-15" flags: "-Os -fPIE" options: "--enable-isystem --enable-avx2" packager: "apt" @@ -74,28 +74,28 @@ jobs: packages: "lcov" - os: macos-latest - cxx: "clang++-14" + cxx: "clang++" link: "dynamic" optimization: "size" assert: "ndebug" coverage: "nocov" boost: "--build-boost" icu: "--with-icu" - cc: "clang-14" + cc: "clang" flags: "-Os -fPIE" options: "--enable-isystem" packager: "brew" packages: "icu4c" - os: macos-latest - cxx: "clang++-14" + cxx: "clang++" link: "static" optimization: "size" assert: "ndebug" coverage: "nocov" boost: "--build-boost" icu: "--build-icu --with-icu" - cc: "clang-14" + cc: "clang" flags: "-Os -fvisibility=hidden -fPIE" options: "--enable-isystem" packager: "brew" @@ -149,6 +149,12 @@ jobs: echo "LDFLAGS=-Wl,-rpath,$WORKSPACE_SUBPATH/prefix/lib" >> $GITHUB_ENV fi + - name: Display Compiler details + shell: bash + run: | + ${CC} -v + ${CXX} -v + - name: Display CPU details if: ${{ (runner.os == 'Linux') }} shell: bash @@ -158,8 +164,8 @@ jobs: - name: Execute install.sh run: > ./install.sh - --build-dir=$LIBBITCOIN_SRC_PATH ${{ matrix.options }} - --prefix=$LIBBITCOIN_SRC_PATH/prefix + --build-dir=${{ env.LIBBITCOIN_SRC_PATH }} ${{ matrix.options }} + --prefix=${{ env.LIBBITCOIN_SRC_PATH }}prefix ${{ env.LINKAGE }} ${{ env.ASSERT_NDEBUG }} ${{ matrix.boost }} @@ -235,28 +241,28 @@ jobs: matrix: include: - os: ubuntu-22.04 - cxx: "clang++-14" + cxx: "clang++-15" link: "dynamic" optimization: "size" assert: "debug" coverage: "nocov" boost: "--build-boost" icu: "" - cc: "clang-14" + cc: "clang-15" flags: "-Os -fPIE" options: "-Denable-avx2=on -Denable-sse4=on" packager: "apt" packages: "" - os: ubuntu-22.04 - cxx: "clang++-14" + cxx: "clang++-15" link: "static" optimization: "size" assert: "ndebug" coverage: "nocov" boost: "--build-boost" icu: "--build-icu --with-icu" - cc: "clang-14" + cc: "clang-15" flags: "-Os -fPIE" options: "-Denable-avx2=on" packager: "apt" @@ -291,28 +297,28 @@ jobs: packages: "" - os: macos-latest - cxx: "clang++-14" + cxx: "clang++" link: "dynamic" optimization: "size" assert: "ndebug" coverage: "nocov" boost: "--build-boost" icu: "--with-icu" - cc: "clang-14" + cc: "clang" flags: "-Os -fPIE" options: "" packager: "brew" packages: "icu4c" - os: macos-latest - cxx: "clang++-14" + cxx: "clang++" link: "static" optimization: "size" assert: "ndebug" coverage: "nocov" boost: "--build-boost" icu: "--build-icu --with-icu" - cc: "clang-14" + cc: "clang" flags: "-Os -fvisibility=hidden -fPIE" options: "" packager: "brew" @@ -369,6 +375,12 @@ jobs: echo "LDFLAGS=-Wl,-rpath,$WORKSPACE_SUBPATH/prefix/lib" >> $GITHUB_ENV fi + - name: Display Compiler details + shell: bash + run: | + ${CC} -v + ${CXX} -v + - name: Display CPU details if: ${{ (runner.os == 'Linux') }} shell: bash @@ -378,8 +390,8 @@ jobs: - name: Execute install-cmake.sh run: > ./install-cmake.sh - --build-dir=$LIBBITCOIN_SRC_PATH ${{ matrix.options }} - --prefix=$LIBBITCOIN_SRC_PATH/prefix + --build-dir=${{ env.LIBBITCOIN_SRC_PATH }} ${{ matrix.options }} + --prefix=${{ env.LIBBITCOIN_SRC_PATH }}prefix ${{ env.LINKAGE }} ${{ env.ASSERT_NDEBUG }} ${{ matrix.boost }} @@ -466,14 +478,14 @@ jobs: include: - os: ubuntu-22.04 preset: "nix-gnu-debug-shared-without_icu" - cxx: "clang++-14" + cxx: "clang++-15" link: "dynamic" optimization: "size" assert: "debug" coverage: "nocov" boost: "--build-boost" icu: "" - cc: "clang-14" + cc: "clang-15" flags: "-Os -fPIE" options: "-Denable-avx2=on -Denable-sse4=on" packager: "apt" @@ -481,14 +493,14 @@ jobs: - os: ubuntu-22.04 preset: "nix-gnu-release-static-size-with_icu" - cxx: "clang++-14" + cxx: "clang++-15" link: "static" optimization: "size" assert: "ndebug" coverage: "nocov" boost: "--build-boost" icu: "--build-icu --with-icu" - cc: "clang-14" + cc: "clang-15" flags: "-Os -fPIE" options: "-Denable-avx2=on" packager: "apt" @@ -560,6 +572,12 @@ jobs: echo "LDFLAGS=-Wl,-rpath,$WORKSPACE_SUBPATH/prefix/${{ matrix.preset }}/lib" >> $GITHUB_ENV fi + - name: Display Compiler details + shell: bash + run: | + ${CC} -v + ${CXX} -v + - name: Display CPU details if: ${{ (runner.os == 'Linux') }} shell: bash @@ -569,8 +587,8 @@ jobs: - name: Execute install-cmakepresets.sh run: > ./install-cmakepresets.sh - --build-dir=$LIBBITCOIN_SRC_PATH ${{ matrix.options }} - --prefix=$LIBBITCOIN_SRC_PATH/prefix/${{ matrix.preset }} + --build-dir=${{ env.LIBBITCOIN_SRC_PATH }} ${{ matrix.options }} + --prefix=${{ env.LIBBITCOIN_SRC_PATH }}prefix/${{ matrix.preset }} --preset=${{ matrix.preset }} ${{ env.LINKAGE }} ${{ env.ASSERT_NDEBUG }} diff --git a/install-cmake.sh b/install-cmake.sh index 810612cbb9..8496d53eee 100755 --- a/install-cmake.sh +++ b/install-cmake.sh @@ -442,15 +442,9 @@ set_pkgconfigdir() set_with_boost_prefix() { if [[ $BUILD_BOOST ]]; then - # Boost has no pkg-config, m4 searches in the following order: - # --with-boost=, /usr, /usr/local, /opt, /opt/local, $BOOST_ROOT. - # We use --with-boost to prioritize the --prefix path when we build it. - # Otherwise standard paths suffice for Linux, Homebrew and MacPorts. - # ax_boost_base.m4 appends /include and adds to BOOST_CPPFLAGS - # ax_boost_base.m4 searches for /lib /lib64 and adds to BOOST_LDFLAGS - # - # cmake does not process this argument, so it has been zeroed out. - with_boost="" + # Boost detection via FindBoost.cmake provides for path hint via + # $BOOT_ROOT environment variable only. + export BOOST_ROOT="$PREFIX" fi } @@ -470,6 +464,7 @@ display_configuration() display_message "WITH_ICU : $WITH_ICU" display_message "BUILD_ICU : $BUILD_ICU" display_message "BUILD_BOOST : $BUILD_BOOST" + display_message "BOOST_ROOT : $BOOST_ROOT" display_message "BUILD_DIR : $BUILD_DIR" display_message "CUMULATIVE_FILTERED_ARGS : $CUMULATIVE_FILTERED_ARGS" display_message "CUMULATIVE_FILTERED_ARGS_CMAKE : $CUMULATIVE_FILTERED_ARGS_CMAKE" @@ -714,7 +709,7 @@ cmake_project_directory() local PROJ_CONFIG_DIR PROJ_CONFIG_DIR=$(pwd) - cmake $@ builds/cmake + cmake -LA $@ builds/cmake make_jobs "$JOBS" if [[ $TEST == true ]]; then diff --git a/install-cmakepresets.sh b/install-cmakepresets.sh index e54f6330f4..87b99ed67c 100755 --- a/install-cmakepresets.sh +++ b/install-cmakepresets.sh @@ -503,15 +503,9 @@ set_pkgconfigdir() set_with_boost_prefix() { if [[ $BUILD_BOOST ]]; then - # Boost has no pkg-config, m4 searches in the following order: - # --with-boost=, /usr, /usr/local, /opt, /opt/local, $BOOST_ROOT. - # We use --with-boost to prioritize the --prefix path when we build it. - # Otherwise standard paths suffice for Linux, Homebrew and MacPorts. - # ax_boost_base.m4 appends /include and adds to BOOST_CPPFLAGS - # ax_boost_base.m4 searches for /lib /lib64 and adds to BOOST_LDFLAGS - # - # cmake does not process this argument, so it has been zeroed out. - with_boost="" + # Boost detection via FindBoost.cmake provides for path hint via + # $BOOT_ROOT environment variable only. + export BOOST_ROOT="$PREFIX" fi } @@ -531,6 +525,7 @@ display_configuration() display_message "WITH_ICU : $WITH_ICU" display_message "BUILD_ICU : $BUILD_ICU" display_message "BUILD_BOOST : $BUILD_BOOST" + display_message "BOOST_ROOT : $BOOST_ROOT" display_message "BUILD_DIR : $BUILD_DIR" display_message "PRESET_ID : $PRESET_ID" display_message "CUMULATIVE_FILTERED_ARGS : $CUMULATIVE_FILTERED_ARGS" @@ -779,7 +774,7 @@ cmake_project_directory() push_directory "builds/cmake" display_message "Preparing cmake --preset=$PRESET $@" - cmake --preset=$PRESET $@ + cmake -LA --preset=$PRESET $@ popd push_directory "obj/$PRESET" diff --git a/install.sh b/install.sh index 88da3d478e..7613fc6966 100755 --- a/install.sh +++ b/install.sh @@ -389,6 +389,7 @@ set_with_boost_prefix() # ax_boost_base.m4 appends /include and adds to BOOST_CPPFLAGS # ax_boost_base.m4 searches for /lib /lib64 and adds to BOOST_LDFLAGS with_boost="--with-boost=$PREFIX" + export BOOST_ROOT="$PREFIX" fi } @@ -408,6 +409,7 @@ display_configuration() display_message "WITH_ICU : $WITH_ICU" display_message "BUILD_ICU : $BUILD_ICU" display_message "BUILD_BOOST : $BUILD_BOOST" + display_message "BOOST_ROOT : $BOOST_ROOT" display_message "BUILD_DIR : $BUILD_DIR" display_message "PREFIX : $PREFIX" display_message "DISABLE_SHARED : $DISABLE_SHARED" From 650696fec113b80072c314fe725d1f78ae6d328b Mon Sep 17 00:00:00 2001 From: evoskuil Date: Mon, 29 Jan 2024 14:41:58 -0500 Subject: [PATCH 09/12] Use std::streamsize for i/ostreams read/write parameter. --- .../system/impl/stream/iostream/iostream.ipp | 17 +++++++++-------- .../system/impl/stream/iostream/istream.ipp | 9 +++++---- .../system/impl/stream/iostream/ostream.ipp | 9 +++++---- .../bitcoin/system/stream/iostream/iostream.hpp | 4 ++-- .../bitcoin/system/stream/iostream/istream.hpp | 2 +- .../bitcoin/system/stream/iostream/ostream.hpp | 2 +- 6 files changed, 23 insertions(+), 20 deletions(-) diff --git a/include/bitcoin/system/impl/stream/iostream/iostream.ipp b/include/bitcoin/system/impl/stream/iostream/iostream.ipp index ae51ef7b75..7cd735496e 100644 --- a/include/bitcoin/system/impl/stream/iostream/iostream.ipp +++ b/include/bitcoin/system/impl/stream/iostream/iostream.ipp @@ -24,6 +24,7 @@ namespace libbitcoin { namespace system { +// Alowed here for low level performance benefit. BC_PUSH_WARNING(NO_POINTER_ARITHMETIC) template @@ -154,37 +155,37 @@ iostream::peek() NOEXCEPT template void -iostream::read(char_type* data, pos_type size) NOEXCEPT +iostream::read(char_type* data, std::streamsize count) NOEXCEPT { - if (is_overflow(size)) + if (is_overflow(count)) { setstate(badbit); return; } BC_PUSH_WARNING(NO_UNSAFE_COPY_N) - std::copy_n(position_, size, data); + std::copy_n(position_, count, data); BC_POP_WARNING() - position_ += size; + position_ += count; } template void iostream::write(const char_type* data, - pos_type size) NOEXCEPT + std::streamsize count) NOEXCEPT { - if (is_overflow(size)) + if (is_overflow(count)) { setstate(badbit); return; } BC_PUSH_WARNING(NO_UNSAFE_COPY_N) - std::copy_n(data, size, position_); + std::copy_n(data, count, position_); BC_POP_WARNING() - position_ += size; + position_ += count; } template diff --git a/include/bitcoin/system/impl/stream/iostream/istream.ipp b/include/bitcoin/system/impl/stream/iostream/istream.ipp index 7739395289..99ee1e883e 100644 --- a/include/bitcoin/system/impl/stream/iostream/istream.ipp +++ b/include/bitcoin/system/impl/stream/iostream/istream.ipp @@ -26,6 +26,7 @@ namespace libbitcoin { namespace system { +// Alowed here for low level performance benefit. BC_PUSH_WARNING(NO_POINTER_ARITHMETIC) template @@ -147,19 +148,19 @@ istream::peek() NOEXCEPT template void -istream::read(char_type* data, pos_type size) NOEXCEPT +istream::read(char_type* data, std::streamsize count) NOEXCEPT { - if (is_overflow(size)) + if (is_overflow(count)) { setstate(badbit); return; } BC_PUSH_WARNING(NO_UNSAFE_COPY_N) - std::copy_n(position_, size, data); + std::copy_n(position_, count, data); BC_POP_WARNING() - position_ += size; + position_ += count; } // private diff --git a/include/bitcoin/system/impl/stream/iostream/ostream.ipp b/include/bitcoin/system/impl/stream/iostream/ostream.ipp index 70bcefd79e..2c91429d4b 100644 --- a/include/bitcoin/system/impl/stream/iostream/ostream.ipp +++ b/include/bitcoin/system/impl/stream/iostream/ostream.ipp @@ -25,6 +25,7 @@ namespace libbitcoin { namespace system { +// Alowed here for low level performance benefit. BC_PUSH_WARNING(NO_POINTER_ARITHMETIC) template @@ -78,19 +79,19 @@ ostream::tellp() const NOEXCEPT template void ostream::write(const char_type* data, - pos_type size) NOEXCEPT + std::streamsize count) NOEXCEPT { - if (is_overflow(size)) + if (is_overflow(count)) { setstate(badbit); return; } BC_PUSH_WARNING(NO_UNSAFE_COPY_N) - std::copy_n(data, size, position_); + std::copy_n(data, count, position_); BC_POP_WARNING() - position_ += size; + position_ += count; } template diff --git a/include/bitcoin/system/stream/iostream/iostream.hpp b/include/bitcoin/system/stream/iostream/iostream.hpp index 82984843f3..de99924a43 100644 --- a/include/bitcoin/system/stream/iostream/iostream.hpp +++ b/include/bitcoin/system/stream/iostream/iostream.hpp @@ -78,10 +78,10 @@ class iostream virtual int_type peek() NOEXCEPT; /// Read a block of characters, sets badbit on underflow. - virtual void read(char_type* data, pos_type size) NOEXCEPT; + virtual void read(char_type* data, std::streamsize count) NOEXCEPT; /// Write a block of characters, sets badbit on overflow. - virtual void write(const char_type* data, pos_type size) NOEXCEPT; + virtual void write(const char_type* data, std::streamsize count) NOEXCEPT; /// Synchronize with the underlying storage device (no-op). virtual void flush() NOEXCEPT; diff --git a/include/bitcoin/system/stream/iostream/istream.hpp b/include/bitcoin/system/stream/iostream/istream.hpp index 16b0bfc645..57f6bef5e1 100644 --- a/include/bitcoin/system/stream/iostream/istream.hpp +++ b/include/bitcoin/system/stream/iostream/istream.hpp @@ -75,7 +75,7 @@ class istream virtual int_type peek() NOEXCEPT; /// Read a block of characters, sets badbit on underflow. - virtual void read(char_type* data, pos_type size) NOEXCEPT; + virtual void read(char_type* data, std::streamsize count) NOEXCEPT; private: static constexpr bool is_positive(off_type value) NOEXCEPT; diff --git a/include/bitcoin/system/stream/iostream/ostream.hpp b/include/bitcoin/system/stream/iostream/ostream.hpp index f4976add14..5e8e6b6544 100644 --- a/include/bitcoin/system/stream/iostream/ostream.hpp +++ b/include/bitcoin/system/stream/iostream/ostream.hpp @@ -64,7 +64,7 @@ class ostream virtual inline pos_type tellp() const NOEXCEPT; /// Write a block of characters, sets badbit on overflow. - virtual void write(const char_type* data, pos_type size) NOEXCEPT; + virtual void write(const char_type* data, std::streamsize count) NOEXCEPT; /// Synchronize with the underlying storage device (no-op). virtual void flush() NOEXCEPT; From 12f8b7fb33aeb349da1c24bf20d4db0f7d693acc Mon Sep 17 00:00:00 2001 From: evoskuil Date: Mon, 29 Jan 2024 15:24:13 -0500 Subject: [PATCH 10/12] Disable failing test. --- test/chain/chain_state.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/test/chain/chain_state.cpp b/test/chain/chain_state.cpp index 0b860d2124..0d7d6154f4 100644 --- a/test/chain/chain_state.cpp +++ b/test/chain/chain_state.cpp @@ -36,15 +36,15 @@ chain::chain_state::data get_values(size_t retargeting_interval) return values; } -BOOST_AUTO_TEST_CASE(chain_state__work_required_retarget__overflow_patch_disabled__lower_value) -{ - settings settings(chain::selection::mainnet); - settings.proof_of_work_limit = 0x1e0fffff; - const auto values = get_values(settings.retargeting_interval()); - const auto forks = chain::forks::retarget; - const auto work = test_chain_state::work_required(values, forks, settings); - BOOST_REQUIRE_EQUAL(work, 0x1e0884d1u); -} +////BOOST_AUTO_TEST_CASE(chain_state__work_required_retarget__overflow_patch_disabled__lower_value) +////{ +//// settings settings(chain::selection::mainnet); +//// settings.proof_of_work_limit = 0x1e0fffff; +//// const auto values = get_values(settings.retargeting_interval()); +//// const auto forks = chain::forks::retarget; +//// const auto work = test_chain_state::work_required(values, forks, settings); +//// BOOST_REQUIRE_EQUAL(work, 0x1e0884d1u); +////} BOOST_AUTO_TEST_CASE(chain_state__work_required_retarget__overflow_patch_enabled__correct_value) { From e284f206c14f33d769b37275e13c0fce708b1282 Mon Sep 17 00:00:00 2001 From: evoskuil Date: Mon, 29 Jan 2024 16:00:14 -0500 Subject: [PATCH 11/12] Cast std::streamsize to std::size_t for fast stream copies. --- .../system/impl/stream/iostream/iostream.ipp | 19 +++++++++++++------ .../system/impl/stream/iostream/istream.ipp | 8 +++++--- .../system/impl/stream/iostream/ostream.ipp | 9 ++++++--- 3 files changed, 24 insertions(+), 12 deletions(-) diff --git a/include/bitcoin/system/impl/stream/iostream/iostream.ipp b/include/bitcoin/system/impl/stream/iostream/iostream.ipp index 7cd735496e..e40ef671dc 100644 --- a/include/bitcoin/system/impl/stream/iostream/iostream.ipp +++ b/include/bitcoin/system/impl/stream/iostream/iostream.ipp @@ -19,7 +19,10 @@ #ifndef LIBBITCOIN_SYSTEM_STREAM_IOSTREAM_IOSTREAM_IPP #define LIBBITCOIN_SYSTEM_STREAM_IOSTREAM_IOSTREAM_IPP +#include +#include #include +#include namespace libbitcoin { namespace system { @@ -157,17 +160,19 @@ template void iostream::read(char_type* data, std::streamsize count) NOEXCEPT { - if (is_overflow(count)) + const auto bytes = possible_narrow_sign_cast(count); + + if (is_overflow(bytes)) { setstate(badbit); return; } BC_PUSH_WARNING(NO_UNSAFE_COPY_N) - std::copy_n(position_, count, data); + std::copy_n(position_, bytes, data); BC_POP_WARNING() - position_ += count; + position_ += bytes; } template @@ -175,17 +180,19 @@ void iostream::write(const char_type* data, std::streamsize count) NOEXCEPT { - if (is_overflow(count)) + const auto bytes = possible_narrow_sign_cast(count); + + if (is_overflow(bytes)) { setstate(badbit); return; } BC_PUSH_WARNING(NO_UNSAFE_COPY_N) - std::copy_n(data, count, position_); + std::copy_n(data, bytes, position_); BC_POP_WARNING() - position_ += count; + position_ += bytes; } template diff --git a/include/bitcoin/system/impl/stream/iostream/istream.ipp b/include/bitcoin/system/impl/stream/iostream/istream.ipp index 99ee1e883e..94ba61b09e 100644 --- a/include/bitcoin/system/impl/stream/iostream/istream.ipp +++ b/include/bitcoin/system/impl/stream/iostream/istream.ipp @@ -150,17 +150,19 @@ template void istream::read(char_type* data, std::streamsize count) NOEXCEPT { - if (is_overflow(count)) + const auto bytes = possible_narrow_sign_cast(count); + + if (is_overflow(bytes)) { setstate(badbit); return; } BC_PUSH_WARNING(NO_UNSAFE_COPY_N) - std::copy_n(position_, count, data); + std::copy_n(position_, bytes, data); BC_POP_WARNING() - position_ += count; + position_ += bytes; } // private diff --git a/include/bitcoin/system/impl/stream/iostream/ostream.ipp b/include/bitcoin/system/impl/stream/iostream/ostream.ipp index 2c91429d4b..43e90fe906 100644 --- a/include/bitcoin/system/impl/stream/iostream/ostream.ipp +++ b/include/bitcoin/system/impl/stream/iostream/ostream.ipp @@ -21,6 +21,7 @@ #include #include +#include namespace libbitcoin { namespace system { @@ -81,17 +82,19 @@ void ostream::write(const char_type* data, std::streamsize count) NOEXCEPT { - if (is_overflow(count)) + const auto bytes = possible_narrow_sign_cast(count); + + if (is_overflow(bytes)) { setstate(badbit); return; } BC_PUSH_WARNING(NO_UNSAFE_COPY_N) - std::copy_n(data, count, position_); + std::copy_n(data, bytes, position_); BC_POP_WARNING() - position_ += count; + position_ += bytes; } template From 89480790f198e7107c969de625e4a726fde8f573 Mon Sep 17 00:00:00 2001 From: evoskuil Date: Mon, 29 Jan 2024 16:09:31 -0500 Subject: [PATCH 12/12] Revert test disable. --- test/chain/chain_state.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/test/chain/chain_state.cpp b/test/chain/chain_state.cpp index 0d7d6154f4..0b860d2124 100644 --- a/test/chain/chain_state.cpp +++ b/test/chain/chain_state.cpp @@ -36,15 +36,15 @@ chain::chain_state::data get_values(size_t retargeting_interval) return values; } -////BOOST_AUTO_TEST_CASE(chain_state__work_required_retarget__overflow_patch_disabled__lower_value) -////{ -//// settings settings(chain::selection::mainnet); -//// settings.proof_of_work_limit = 0x1e0fffff; -//// const auto values = get_values(settings.retargeting_interval()); -//// const auto forks = chain::forks::retarget; -//// const auto work = test_chain_state::work_required(values, forks, settings); -//// BOOST_REQUIRE_EQUAL(work, 0x1e0884d1u); -////} +BOOST_AUTO_TEST_CASE(chain_state__work_required_retarget__overflow_patch_disabled__lower_value) +{ + settings settings(chain::selection::mainnet); + settings.proof_of_work_limit = 0x1e0fffff; + const auto values = get_values(settings.retargeting_interval()); + const auto forks = chain::forks::retarget; + const auto work = test_chain_state::work_required(values, forks, settings); + BOOST_REQUIRE_EQUAL(work, 0x1e0884d1u); +} BOOST_AUTO_TEST_CASE(chain_state__work_required_retarget__overflow_patch_enabled__correct_value) {