From 31857119863739f8c2c66ae749848aac16241fa4 Mon Sep 17 00:00:00 2001 From: Eric Voskuil Date: Mon, 24 Aug 2026 20:47:54 -0400 Subject: [PATCH 1/2] Remove dead code and use network message types. --- builds/gnu/Makefile.am | 11 ---- .../libbitcoin-node-test.vcxproj | 1 - .../libbitcoin-node-test.vcxproj.filters | 10 +-- .../libbitcoin-node/libbitcoin-node.vcxproj | 5 -- .../libbitcoin-node.vcxproj.filters | 37 +++-------- .../libbitcoin-node-test.vcxproj | 1 - .../libbitcoin-node-test.vcxproj.filters | 10 +-- .../libbitcoin-node/libbitcoin-node.vcxproj | 5 -- .../libbitcoin-node.vcxproj.filters | 37 +++-------- include/bitcoin/node.hpp | 3 - include/bitcoin/node/messages/block.hpp | 60 ----------------- include/bitcoin/node/messages/messages.hpp | 25 ------- include/bitcoin/node/messages/transaction.hpp | 65 ------------------- src/messages/block.cpp | 56 ---------------- src/messages/transaction.cpp | 64 ------------------ src/protocols/protocol_block_out_106.cpp | 3 +- test/messages/block.cpp | 64 ------------------ 17 files changed, 21 insertions(+), 436 deletions(-) delete mode 100644 include/bitcoin/node/messages/block.hpp delete mode 100644 include/bitcoin/node/messages/messages.hpp delete mode 100644 include/bitcoin/node/messages/transaction.hpp delete mode 100644 src/messages/block.cpp delete mode 100644 src/messages/transaction.cpp delete mode 100644 test/messages/block.cpp diff --git a/builds/gnu/Makefile.am b/builds/gnu/Makefile.am index da9fe3c7..36da4e65 100644 --- a/builds/gnu/Makefile.am +++ b/builds/gnu/Makefile.am @@ -73,8 +73,6 @@ src_libbitcoin_node_la_SOURCES = \ ${srcdir}/../../src/chasers/chaser_validate_batch.cpp \ ${srcdir}/../../src/chasers/chaser_validate_capture.cpp \ ${srcdir}/../../src/chasers/chaser_validate_parallel.cpp \ - ${srcdir}/../../src/messages/block.cpp \ - ${srcdir}/../../src/messages/transaction.cpp \ ${srcdir}/../../src/protocols/protocol.cpp \ ${srcdir}/../../src/protocols/protocol_block_in_106.cpp \ ${srcdir}/../../src/protocols/protocol_block_in_31800.cpp \ @@ -156,14 +154,6 @@ include_bitcoin_node_impl_sessionsdir = \ include_bitcoin_node_impl_sessions_HEADERS = \ ${srcdir}/../../include/bitcoin/node/impl/sessions/session_peer.ipp -include_bitcoin_node_messagesdir = \ - ${includedir}/bitcoin/node/messages - -include_bitcoin_node_messages_HEADERS = \ - ${srcdir}/../../include/bitcoin/node/messages/block.hpp \ - ${srcdir}/../../include/bitcoin/node/messages/messages.hpp \ - ${srcdir}/../../include/bitcoin/node/messages/transaction.hpp - include_bitcoin_node_protocolsdir = \ ${includedir}/bitcoin/node/protocols @@ -240,7 +230,6 @@ test_libbitcoin_node_test_SOURCES = \ ${srcdir}/../../test/chasers/chaser_template.cpp \ ${srcdir}/../../test/chasers/chaser_transaction.cpp \ ${srcdir}/../../test/chasers/chaser_validate.cpp \ - ${srcdir}/../../test/messages/block.cpp \ ${srcdir}/../../test/protocols/protocol.cpp \ ${srcdir}/../../test/sessions/session.cpp diff --git a/builds/msvc/vs2022/libbitcoin-node-test/libbitcoin-node-test.vcxproj b/builds/msvc/vs2022/libbitcoin-node-test/libbitcoin-node-test.vcxproj index 5eaccba2..de485540 100644 --- a/builds/msvc/vs2022/libbitcoin-node-test/libbitcoin-node-test.vcxproj +++ b/builds/msvc/vs2022/libbitcoin-node-test/libbitcoin-node-test.vcxproj @@ -135,7 +135,6 @@ - diff --git a/builds/msvc/vs2022/libbitcoin-node-test/libbitcoin-node-test.vcxproj.filters b/builds/msvc/vs2022/libbitcoin-node-test/libbitcoin-node-test.vcxproj.filters index 7a4755f8..3e9441ba 100644 --- a/builds/msvc/vs2022/libbitcoin-node-test/libbitcoin-node-test.vcxproj.filters +++ b/builds/msvc/vs2022/libbitcoin-node-test/libbitcoin-node-test.vcxproj.filters @@ -13,14 +13,11 @@ {4BD50864-D3BC-4F64-0000-000000000001} - - {4BD50864-D3BC-4F64-0000-000000000002} - - {4BD50864-D3BC-4F64-0000-000000000003} + {4BD50864-D3BC-4F64-0000-000000000002} - {4BD50864-D3BC-4F64-0000-000000000004} + {4BD50864-D3BC-4F64-0000-000000000003} @@ -75,9 +72,6 @@ src - - src\messages - src\protocols diff --git a/builds/msvc/vs2022/libbitcoin-node/libbitcoin-node.vcxproj b/builds/msvc/vs2022/libbitcoin-node/libbitcoin-node.vcxproj index c9de9cbf..c355ac35 100644 --- a/builds/msvc/vs2022/libbitcoin-node/libbitcoin-node.vcxproj +++ b/builds/msvc/vs2022/libbitcoin-node/libbitcoin-node.vcxproj @@ -142,8 +142,6 @@ - - @@ -194,9 +192,6 @@ - - - diff --git a/builds/msvc/vs2022/libbitcoin-node/libbitcoin-node.vcxproj.filters b/builds/msvc/vs2022/libbitcoin-node/libbitcoin-node.vcxproj.filters index ada1ec44..a6dbdb30 100644 --- a/builds/msvc/vs2022/libbitcoin-node/libbitcoin-node.vcxproj.filters +++ b/builds/msvc/vs2022/libbitcoin-node/libbitcoin-node.vcxproj.filters @@ -31,35 +31,29 @@ {5FFB5F52-0772-4404-0000-000000000007} - - {5FFB5F52-0772-4404-0000-000000000008} - - {5FFB5F52-0772-4404-0000-000000000009} + {5FFB5F52-0772-4404-0000-000000000008} - {5FFB5F52-0772-4404-0000-00000000000A} + {5FFB5F52-0772-4404-0000-000000000009} - {5FFB5F52-0772-4404-0000-00000000000B} + {5FFB5F52-0772-4404-0000-00000000000A} - {5FFB5F52-0772-4404-0000-00000000000C} + {5FFB5F52-0772-4404-0000-00000000000B} - {5FFB5F52-0772-4404-0000-00000000000D} + {5FFB5F52-0772-4404-0000-00000000000C} - {5FFB5F52-0772-4404-0000-00000000000E} - - - {5FFB5F52-0772-4404-0000-00000000000F} + {5FFB5F52-0772-4404-0000-00000000000D} - {5FFB5F52-0772-4404-0000-000000000001} + {5FFB5F52-0772-4404-0000-00000000000E} - {5FFB5F52-0772-4404-0000-000000000002} + {5FFB5F52-0772-4404-0000-00000000000F} @@ -126,12 +120,6 @@ src - - src\messages - - - src\messages - src\protocols @@ -278,15 +266,6 @@ include\bitcoin\node - - include\bitcoin\node\messages - - - include\bitcoin\node\messages - - - include\bitcoin\node\messages - include\bitcoin\node\protocols diff --git a/builds/msvc/vs2026/libbitcoin-node-test/libbitcoin-node-test.vcxproj b/builds/msvc/vs2026/libbitcoin-node-test/libbitcoin-node-test.vcxproj index aa83f3bf..06bb9e22 100644 --- a/builds/msvc/vs2026/libbitcoin-node-test/libbitcoin-node-test.vcxproj +++ b/builds/msvc/vs2026/libbitcoin-node-test/libbitcoin-node-test.vcxproj @@ -135,7 +135,6 @@ - diff --git a/builds/msvc/vs2026/libbitcoin-node-test/libbitcoin-node-test.vcxproj.filters b/builds/msvc/vs2026/libbitcoin-node-test/libbitcoin-node-test.vcxproj.filters index 7a4755f8..3e9441ba 100644 --- a/builds/msvc/vs2026/libbitcoin-node-test/libbitcoin-node-test.vcxproj.filters +++ b/builds/msvc/vs2026/libbitcoin-node-test/libbitcoin-node-test.vcxproj.filters @@ -13,14 +13,11 @@ {4BD50864-D3BC-4F64-0000-000000000001} - - {4BD50864-D3BC-4F64-0000-000000000002} - - {4BD50864-D3BC-4F64-0000-000000000003} + {4BD50864-D3BC-4F64-0000-000000000002} - {4BD50864-D3BC-4F64-0000-000000000004} + {4BD50864-D3BC-4F64-0000-000000000003} @@ -75,9 +72,6 @@ src - - src\messages - src\protocols diff --git a/builds/msvc/vs2026/libbitcoin-node/libbitcoin-node.vcxproj b/builds/msvc/vs2026/libbitcoin-node/libbitcoin-node.vcxproj index 37eda379..2d05d8d6 100644 --- a/builds/msvc/vs2026/libbitcoin-node/libbitcoin-node.vcxproj +++ b/builds/msvc/vs2026/libbitcoin-node/libbitcoin-node.vcxproj @@ -142,8 +142,6 @@ - - @@ -194,9 +192,6 @@ - - - diff --git a/builds/msvc/vs2026/libbitcoin-node/libbitcoin-node.vcxproj.filters b/builds/msvc/vs2026/libbitcoin-node/libbitcoin-node.vcxproj.filters index ada1ec44..a6dbdb30 100644 --- a/builds/msvc/vs2026/libbitcoin-node/libbitcoin-node.vcxproj.filters +++ b/builds/msvc/vs2026/libbitcoin-node/libbitcoin-node.vcxproj.filters @@ -31,35 +31,29 @@ {5FFB5F52-0772-4404-0000-000000000007} - - {5FFB5F52-0772-4404-0000-000000000008} - - {5FFB5F52-0772-4404-0000-000000000009} + {5FFB5F52-0772-4404-0000-000000000008} - {5FFB5F52-0772-4404-0000-00000000000A} + {5FFB5F52-0772-4404-0000-000000000009} - {5FFB5F52-0772-4404-0000-00000000000B} + {5FFB5F52-0772-4404-0000-00000000000A} - {5FFB5F52-0772-4404-0000-00000000000C} + {5FFB5F52-0772-4404-0000-00000000000B} - {5FFB5F52-0772-4404-0000-00000000000D} + {5FFB5F52-0772-4404-0000-00000000000C} - {5FFB5F52-0772-4404-0000-00000000000E} - - - {5FFB5F52-0772-4404-0000-00000000000F} + {5FFB5F52-0772-4404-0000-00000000000D} - {5FFB5F52-0772-4404-0000-000000000001} + {5FFB5F52-0772-4404-0000-00000000000E} - {5FFB5F52-0772-4404-0000-000000000002} + {5FFB5F52-0772-4404-0000-00000000000F} @@ -126,12 +120,6 @@ src - - src\messages - - - src\messages - src\protocols @@ -278,15 +266,6 @@ include\bitcoin\node - - include\bitcoin\node\messages - - - include\bitcoin\node\messages - - - include\bitcoin\node\messages - include\bitcoin\node\protocols diff --git a/include/bitcoin/node.hpp b/include/bitcoin/node.hpp index 1b8f31b1..b7d31740 100644 --- a/include/bitcoin/node.hpp +++ b/include/bitcoin/node.hpp @@ -44,9 +44,6 @@ #include #include #include -#include -#include -#include #include #include #include diff --git a/include/bitcoin/node/messages/block.hpp b/include/bitcoin/node/messages/block.hpp deleted file mode 100644 index 0823ed46..00000000 --- a/include/bitcoin/node/messages/block.hpp +++ /dev/null @@ -1,60 +0,0 @@ -/** - * Copyright (c) 2011-2026 libbitcoin developers - * - * This file is part of libbitcoin. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ -#ifndef LIBBITCOIN_NODE_MESSAGES_BLOCK_HPP -#define LIBBITCOIN_NODE_MESSAGES_BLOCK_HPP - -#include - -namespace libbitcoin { -namespace node { -namespace messages { - -/// Based on network::messages::peer::block. -struct BCN_API block -{ - typedef std::shared_ptr cptr; - - static const std::string command; - static const uint32_t version_minimum; - static const uint32_t version_maximum; - - // TODO: optimized translation direct to store. - ////static cptr deserialize(uint32_t version, const system::data_chunk& data, - //// bool witness=true) NOEXCEPT; - ////static block deserialize(uint32_t version, system::reader& source, - //// bool witness=true) NOEXCEPT; - - /// The held block is serialized in the requested form; a witnessed view - /// is stripped when serialized without witness. - /// The bool overload returns false only on a short output buffer. - bool serialize(uint32_t version, const system::data_slab& data, - bool witness=true) const NOEXCEPT; - void serialize(uint32_t version, system::writer& sink, - bool witness=true) const NOEXCEPT; - size_t size(uint32_t version, bool witness=true) const NOEXCEPT; - - /// The block, serialized on demand as witnessed or stripped. - system::chain::block_view block; -}; - -} // namespace messages -} // namespace node -} // namespace libbitcoin - -#endif diff --git a/include/bitcoin/node/messages/messages.hpp b/include/bitcoin/node/messages/messages.hpp deleted file mode 100644 index a5a5278e..00000000 --- a/include/bitcoin/node/messages/messages.hpp +++ /dev/null @@ -1,25 +0,0 @@ -/** - * Copyright (c) 2011-2026 libbitcoin developers - * - * This file is part of libbitcoin. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ -#ifndef LIBBITCOIN_NODE_MESSAGES_MESSAGES_HPP -#define LIBBITCOIN_NODE_MESSAGES_MESSAGES_HPP - -#include -#include - -#endif diff --git a/include/bitcoin/node/messages/transaction.hpp b/include/bitcoin/node/messages/transaction.hpp deleted file mode 100644 index 11c3fa29..00000000 --- a/include/bitcoin/node/messages/transaction.hpp +++ /dev/null @@ -1,65 +0,0 @@ -/** - * Copyright (c) 2011-2026 libbitcoin developers - * - * This file is part of libbitcoin. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ -#ifndef LIBBITCOIN_NODE_MESSAGES_TRANSACTION_HPP -#define LIBBITCOIN_NODE_MESSAGES_TRANSACTION_HPP - -#include -#include - -namespace libbitcoin { -namespace node { -namespace messages { - -/// Based on network::messages::peer::transaction. -struct BCN_API transaction -{ - typedef std::shared_ptr cptr; - - static const std::string command; - static const uint32_t version_minimum; - static const uint32_t version_maximum; - - // TODO: optimized translation direct to store. - ////static cptr deserialize(uint32_t version, const system::data_chunk& data, - //// bool witness=true) NOEXCEPT; - ////static transaction deserialize(uint32_t version, system::reader& source, - //// bool witness=true) NOEXCEPT; - - /// These return false if witness or version is inconsistent with tx data. - bool serialize(uint32_t version, const system::data_slab& data, - bool witness=true) const NOEXCEPT; - void serialize(uint32_t version, system::writer& sink, - bool witness=true) const NOEXCEPT; - size_t size(uint32_t version, bool witness=true) const NOEXCEPT; - - /// Wire serialized transaction. - system::data_chunk tx_data{}; - - /// Non-witness hash of the transaction (for non-witness send optimize). - system::hash_digest hash{}; - - /// Transaction contains witness data (if applicable). - const bool witnessed_{}; -}; - -} // namespace messages -} // namespace node -} // namespace libbitcoin - -#endif diff --git a/src/messages/block.cpp b/src/messages/block.cpp deleted file mode 100644 index 196249f7..00000000 --- a/src/messages/block.cpp +++ /dev/null @@ -1,56 +0,0 @@ -/** - * Copyright (c) 2011-2026 libbitcoin developers - * - * This file is part of libbitcoin. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ -#include - -#include - -namespace libbitcoin { -namespace node { -namespace messages { - -using namespace system; -using namespace network::messages::peer; - -const std::string block::command = "block"; -const uint32_t block::version_minimum = level::minimum_protocol; -const uint32_t block::version_maximum = level::maximum_protocol; - -// data_slab is preallocated after the message header using size(). -bool block::serialize(uint32_t version, const data_slab& data, - bool witness) const NOEXCEPT -{ - system::stream::out::fast out{ data }; - system::write::bytes::fast writer{ out }; - serialize(version, writer, witness); - return writer; -} - -void block::serialize(uint32_t, writer& sink, bool witness) const NOEXCEPT -{ - block.to_data(sink, witness); -} - -size_t block::size(uint32_t, bool witness) const NOEXCEPT -{ - return block.is_valid() ? block.serialized_size(witness) : zero; -} - -} // namespace messages -} // namespace node -} // namespace libbitcoin diff --git a/src/messages/transaction.cpp b/src/messages/transaction.cpp deleted file mode 100644 index 0a0359ff..00000000 --- a/src/messages/transaction.cpp +++ /dev/null @@ -1,64 +0,0 @@ -/** - * Copyright (c) 2011-2026 libbitcoin developers - * - * This file is part of libbitcoin. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ -#include - -#include - -namespace libbitcoin { -namespace node { -namespace messages { - -using namespace system; -using namespace network::messages::peer; - -const std::string transaction::command = "tx"; -const uint32_t transaction::version_minimum = level::minimum_protocol; -const uint32_t transaction::version_maximum = level::maximum_protocol; - -// data_slab is preallocated after the message header using size(). -bool transaction::serialize(uint32_t version, const data_slab& data, - bool witness) const NOEXCEPT -{ - if (witness != witnessed_) - return false; - - system::stream::out::fast out{ data }; - system::write::bytes::fast writer{ out }; - serialize(version, writer, witness); - return writer; -} - -// Sender must ensure that version/witness are consistent with channel. -void transaction::serialize(uint32_t, writer& sink, - bool BC_DEBUG_ONLY(witness)) const NOEXCEPT -{ - BC_ASSERT(witness == witnessed_); - sink.write_bytes(tx_data); -} - -// Sender must ensure that version/witness are consistent with channel. -size_t transaction::size(uint32_t, bool BC_DEBUG_ONLY(witness)) const NOEXCEPT -{ - BC_ASSERT(witness == witnessed_); - return tx_data.size(); -} - -} // namespace messages -} // namespace node -} // namespace libbitcoin diff --git a/src/protocols/protocol_block_out_106.cpp b/src/protocols/protocol_block_out_106.cpp index fa928133..51495482 100644 --- a/src/protocols/protocol_block_out_106.cpp +++ b/src/protocols/protocol_block_out_106.cpp @@ -20,7 +20,6 @@ #include #include -#include namespace libbitcoin { namespace node { @@ -226,7 +225,7 @@ void protocol_block_out_106::send_block(const code& ec) NOEXCEPT } const auto start = logger::now(); - node::messages::block out + messages::peer::block out { { query.get_wire_block(link, witness), witness } }; diff --git a/test/messages/block.cpp b/test/messages/block.cpp deleted file mode 100644 index 4ae27b0e..00000000 --- a/test/messages/block.cpp +++ /dev/null @@ -1,64 +0,0 @@ -/** - * Copyright (c) 2011-2026 libbitcoin developers (see AUTHORS) - * - * This file is part of libbitcoin. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ -#include "../test.hpp" - -BOOST_AUTO_TEST_SUITE(block_tests) - -using namespace network::messages; - -// The message holds a block_view and serializes in the requested form. Genesis -// is non-witness (witnessed and stripped forms are identical); the witnessed -// strip is covered by the libbitcoin-system block_view to_data tests. - -BOOST_AUTO_TEST_CASE(block__serialize__witness__expected) -{ - const system::settings settings{ system::chain::selection::mainnet }; - const node::messages::block instance - { - { settings.genesis_block.to_data(true), true } - }; - system::data_chunk buffer(instance.size(peer::level::canonical, true)); - BOOST_REQUIRE(instance.serialize(peer::level::canonical, { buffer }, true)); - BOOST_REQUIRE_EQUAL(buffer, settings.genesis_block.to_data(true)); -} - -BOOST_AUTO_TEST_CASE(block__serialize__non_witness__expected) -{ - const system::settings settings{ system::chain::selection::mainnet }; - const node::messages::block instance - { - { settings.genesis_block.to_data(true), false } - }; - system::data_chunk buffer(instance.size(peer::level::canonical, false)); - BOOST_REQUIRE(instance.serialize(peer::level::canonical, { buffer }, false)); - BOOST_REQUIRE_EQUAL(buffer, settings.genesis_block.to_data(false)); -} - -BOOST_AUTO_TEST_CASE(block__serialize__short_buffer__false) -{ - const system::settings settings{ system::chain::selection::mainnet }; - const node::messages::block instance - { - { settings.genesis_block.to_data(true), true } - }; - system::data_chunk buffer(sub1(instance.size(peer::level::canonical, true))); - BOOST_REQUIRE(!instance.serialize(peer::level::canonical, { buffer }, true)); -} - -BOOST_AUTO_TEST_SUITE_END() From a53ff53ae5ae119c9d1b2e8d757ed84c94e4644f Mon Sep 17 00:00:00 2001 From: Eric Voskuil Date: Tue, 25 Aug 2026 10:30:06 -0400 Subject: [PATCH 2/2] Add p2p setup fixture and a few test cases. --- builds/gnu/Makefile.am | 2 + .../libbitcoin-node-test.vcxproj | 3 + .../libbitcoin-node-test.vcxproj.filters | 16 +- .../libbitcoin-node-test.vcxproj | 3 + .../libbitcoin-node-test.vcxproj.filters | 16 +- test/functional/p2p.cpp | 62 +++++++ test/functional/p2p_setup_fixture.cpp | 173 ++++++++++++++++++ test/functional/p2p_setup_fixture.hpp | 75 ++++++++ 8 files changed, 346 insertions(+), 4 deletions(-) create mode 100644 test/functional/p2p.cpp create mode 100644 test/functional/p2p_setup_fixture.cpp create mode 100644 test/functional/p2p_setup_fixture.hpp diff --git a/builds/gnu/Makefile.am b/builds/gnu/Makefile.am index 36da4e65..8daa8051 100644 --- a/builds/gnu/Makefile.am +++ b/builds/gnu/Makefile.am @@ -230,6 +230,8 @@ test_libbitcoin_node_test_SOURCES = \ ${srcdir}/../../test/chasers/chaser_template.cpp \ ${srcdir}/../../test/chasers/chaser_transaction.cpp \ ${srcdir}/../../test/chasers/chaser_validate.cpp \ + ${srcdir}/../../test/functional/p2p.cpp \ + ${srcdir}/../../test/functional/p2p_setup_fixture.cpp \ ${srcdir}/../../test/protocols/protocol.cpp \ ${srcdir}/../../test/sessions/session.cpp diff --git a/builds/msvc/vs2022/libbitcoin-node-test/libbitcoin-node-test.vcxproj b/builds/msvc/vs2022/libbitcoin-node-test/libbitcoin-node-test.vcxproj index de485540..9e8a8fec 100644 --- a/builds/msvc/vs2022/libbitcoin-node-test/libbitcoin-node-test.vcxproj +++ b/builds/msvc/vs2022/libbitcoin-node-test/libbitcoin-node-test.vcxproj @@ -134,6 +134,8 @@ + + @@ -141,6 +143,7 @@ + diff --git a/builds/msvc/vs2022/libbitcoin-node-test/libbitcoin-node-test.vcxproj.filters b/builds/msvc/vs2022/libbitcoin-node-test/libbitcoin-node-test.vcxproj.filters index 3e9441ba..d1511e0f 100644 --- a/builds/msvc/vs2022/libbitcoin-node-test/libbitcoin-node-test.vcxproj.filters +++ b/builds/msvc/vs2022/libbitcoin-node-test/libbitcoin-node-test.vcxproj.filters @@ -13,12 +13,15 @@ {4BD50864-D3BC-4F64-0000-000000000001} - + {4BD50864-D3BC-4F64-0000-000000000002} - + {4BD50864-D3BC-4F64-0000-000000000003} + + {4BD50864-D3BC-4F64-0000-000000000004} + @@ -69,6 +72,12 @@ src + + src\functional + + + src\functional + src @@ -86,6 +95,9 @@ + + src\functional + src diff --git a/builds/msvc/vs2026/libbitcoin-node-test/libbitcoin-node-test.vcxproj b/builds/msvc/vs2026/libbitcoin-node-test/libbitcoin-node-test.vcxproj index 06bb9e22..d52609c3 100644 --- a/builds/msvc/vs2026/libbitcoin-node-test/libbitcoin-node-test.vcxproj +++ b/builds/msvc/vs2026/libbitcoin-node-test/libbitcoin-node-test.vcxproj @@ -134,6 +134,8 @@ + + @@ -141,6 +143,7 @@ + diff --git a/builds/msvc/vs2026/libbitcoin-node-test/libbitcoin-node-test.vcxproj.filters b/builds/msvc/vs2026/libbitcoin-node-test/libbitcoin-node-test.vcxproj.filters index 3e9441ba..d1511e0f 100644 --- a/builds/msvc/vs2026/libbitcoin-node-test/libbitcoin-node-test.vcxproj.filters +++ b/builds/msvc/vs2026/libbitcoin-node-test/libbitcoin-node-test.vcxproj.filters @@ -13,12 +13,15 @@ {4BD50864-D3BC-4F64-0000-000000000001} - + {4BD50864-D3BC-4F64-0000-000000000002} - + {4BD50864-D3BC-4F64-0000-000000000003} + + {4BD50864-D3BC-4F64-0000-000000000004} + @@ -69,6 +72,12 @@ src + + src\functional + + + src\functional + src @@ -86,6 +95,9 @@ + + src\functional + src diff --git a/test/functional/p2p.cpp b/test/functional/p2p.cpp new file mode 100644 index 00000000..0d244a86 --- /dev/null +++ b/test/functional/p2p.cpp @@ -0,0 +1,62 @@ +/** + * Copyright (c) 2011-2026 libbitcoin developers + * + * This file is part of libbitcoin. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +#include "p2p_setup_fixture.hpp" + +BOOST_FIXTURE_TEST_SUITE(functional_p2p_tests, p2p_setup_fixture) + +using namespace network::messages::peer; + +BOOST_AUTO_TEST_CASE(functional_p2p__handshake__default__provides_network_and_witness) +{ + BOOST_REQUIRE(handshake()); + BOOST_REQUIRE_EQUAL(node_version->value, config_.network.protocol_maximum); + BOOST_REQUIRE_EQUAL(node_version->services, + service::node_network | service::node_witness); +} + +BOOST_AUTO_TEST_CASE(functional_p2p__ping__nonce__pong_echo) +{ + BOOST_REQUIRE(handshake()); + + constexpr uint64_t expected = 42; + send(ping{ expected }, node_version->value); + + const auto payload = receive(pong::command); + const auto message = pong::deserialize(node_version->value, payload); + BOOST_REQUIRE(message); + BOOST_REQUIRE_EQUAL(message->nonce, expected); +} + +// The block send regression (github.com/libbitcoin/libbitcoin-network/862). +BOOST_AUTO_TEST_CASE(functional_p2p__get_data__genesis_block__expected_bytes) +{ + BOOST_REQUIRE(handshake()); + + const system::chain::block& genesis = config_.bitcoin.genesis_block; + const auto expected = genesis.to_data(true); + + const get_data get{ { { inventory_item::type_id::block, genesis.hash() } } }; + send(get, node_version->value); + + const auto payload = receive(block::command); + BOOST_REQUIRE_EQUAL(payload.size(), expected.size()); + BOOST_REQUIRE(payload == expected); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/test/functional/p2p_setup_fixture.cpp b/test/functional/p2p_setup_fixture.cpp new file mode 100644 index 00000000..a4acf10d --- /dev/null +++ b/test/functional/p2p_setup_fixture.cpp @@ -0,0 +1,173 @@ +/** + * Copyright (c) 2011-2026 libbitcoin developers + * + * This file is part of libbitcoin. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +#include "p2p_setup_fixture.hpp" +#include + +using namespace bc::system; +using namespace bc::network::messages::peer; + +BC_PUSH_WARNING(NO_THROW_IN_NOEXCEPT) + +p2p_setup_fixture::p2p_setup_fixture(const initializer& setup, + const configurator& configure) + : config_{ chain::selection::mainnet }, + store_ + { + [&]() NOEXCEPT -> const database::settings& + { + config_.database.path = TEST_DIRECTORY; + return config_.database; + }() + }, + query_{ store_ }, + node_{ query_, config_, log_ } +{ + test::clear(test::directory); + + auto& network_settings = config_.network; + auto& node_settings = config_.node; + + network_settings.path = TEST_DIRECTORY; + network_settings.inbound.connections = 1; + network_settings.inbound.binds.clear(); + network_settings.inbound.binds.emplace_back(P2P_FUNCTIONAL_ENDPOINT); + network_settings.outbound.connections = 0; + network_settings.outbound.seeds.clear(); + node_settings.delay_inbound = false; + + // Apply test-specific configuration overrides. + if (configure) + configure(config_); + + // Create and populate the store. + auto ec = store_.create([](auto, auto) {}); + BOOST_REQUIRE_MESSAGE(!ec, ec.message()); + + const chain::block& genesis = config_.bitcoin.genesis_block; + BOOST_REQUIRE(query_.initialize(genesis)); + + if (setup) + BOOST_REQUIRE(setup(query_)); + + std::promise started{}; + node_.start([&](const code& ec) NOEXCEPT + { + started.set_value(ec); + }); + + // Block until the node is started. + ec = started.get_future().get(); + BOOST_REQUIRE_MESSAGE(!ec, ec.message()); + + std::promise running{}; + node_.run([&](const code& ec) NOEXCEPT + { + running.set_value(ec); + }); + + // Block until the node is running. + ec = running.get_future().get(); + BOOST_REQUIRE_MESSAGE(!ec, ec.message()); + socket_.connect(network_settings.inbound.binds.back().to_endpoint()); +} + +p2p_setup_fixture::~p2p_setup_fixture() +{ + socket_.close(); + node_.close(); + const auto ec = store_.close([](auto, auto) {}); + BOOST_WARN_MESSAGE(!ec, ec.message()); + test::clear(test::directory); +} + +void p2p_setup_fixture::send(const std::string& command, + const data_chunk& payload) +{ + const auto head = heading::factory(config_.network.identifier, command, + payload); + data_chunk frame(heading::size() + payload.size()); + BOOST_REQUIRE(head.serialize({ frame.data(), + std::next(frame.data(), heading::size()) })); + + std::copy(payload.begin(), payload.end(), + std::next(frame.begin(), heading::size())); + boost::asio::write(socket_, boost::asio::buffer(frame)); +} + +std::pair p2p_setup_fixture::receive() +{ + data_array head_data{}; + boost::asio::read(socket_, boost::asio::buffer(head_data)); + const auto head = heading::deserialize(head_data); + BOOST_REQUIRE(head); + + data_chunk payload(head->payload_size); + if (!payload.empty()) + boost::asio::read(socket_, boost::asio::buffer(payload)); + + return { head->command, std::move(payload) }; +} + +data_chunk p2p_setup_fixture::receive(const std::string& command) +{ + while (true) + { + auto message = receive(); + if (message.first == command) + return std::move(message.second); + } +} + +bool p2p_setup_fixture::handshake(uint64_t services, uint32_t value) +{ + version out{}; + out.value = value; + out.services = services; + out.timestamp = sign_cast(network::zulu_time()); + out.nonce = 42424242; + out.user_agent = "/test/"; + out.start_height = 0; + out.relay = false; + send(out, value); + + // The node sends its version upon attach and verack upon our version. + auto got_version = false; + auto got_acknowledge = false; + while (!got_version || !got_acknowledge) + { + const auto message = receive(); + if (message.first == version::command) + { + node_version = version::deserialize(value, message.second); + if (!node_version) + return false; + + got_version = true; + } + else if (message.first == version_acknowledge::command) + { + got_acknowledge = true; + } + } + + send(version_acknowledge{}, value); + return true; +} + +BC_POP_WARNING() diff --git a/test/functional/p2p_setup_fixture.hpp b/test/functional/p2p_setup_fixture.hpp new file mode 100644 index 00000000..b4a7f80c --- /dev/null +++ b/test/functional/p2p_setup_fixture.hpp @@ -0,0 +1,75 @@ +/** + * Copyright (c) 2011-2026 libbitcoin developers + * + * This file is part of libbitcoin. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +#ifndef LIBBITCOIN_NODE_TEST_FUNCTIONAL_P2P_SETUP_FIXTURE +#define LIBBITCOIN_NODE_TEST_FUNCTIONAL_P2P_SETUP_FIXTURE + +#include "../test.hpp" + +#define P2P_FUNCTIONAL_ENDPOINT "127.0.0.1:65009" + +// Runs a real full node accepting on loopback, with the test acting as the +// remote peer over a raw blocking socket (framing via peer messages). +struct p2p_setup_fixture +{ + DELETE_COPY_MOVE(p2p_setup_fixture); + + using initializer = std::function; + using configurator = std::function; + explicit p2p_setup_fixture(const initializer& setup={}, + const configurator& configure={}); + ~p2p_setup_fixture(); + + /// Write a framed message to the node. + void send(const std::string& command, const system::data_chunk& payload); + + /// Serialize and write a framed message to the node. + template + void send(const Message& message, uint32_t version) + { + system::data_chunk payload(message.size(version)); + BOOST_REQUIRE(message.serialize(version, payload)); + send(Message::command, payload); + } + + /// Read one framed message from the node. + std::pair receive(); + + /// Read framed messages from the node until the command matches. + system::data_chunk receive(const std::string& command); + + /// Perform the version handshake, retains the node's version message. + bool handshake(uint64_t services=0, + uint32_t version=network::messages::peer::level::maximum_protocol); + + /// The node's version message (set by handshake). + network::messages::peer::version::cptr node_version{}; + +protected: + configuration config_; + node::store store_; + node::query query_; + network::logger log_{}; + full_node node_; + +private: + boost::asio::io_context io_{}; + boost::asio::ip::tcp::socket socket_{ io_ }; +}; + +#endif