diff --git a/Makefile.am b/Makefile.am index 4190b9d13..4c4228838 100644 --- a/Makefile.am +++ b/Makefile.am @@ -83,6 +83,7 @@ src_libbitcoin_network_la_SOURCES = \ src/messages/ping.cpp \ src/messages/pong.cpp \ src/messages/reject.cpp \ + src/messages/send_address_v2.cpp \ src/messages/send_compact.cpp \ src/messages/send_headers.cpp \ src/messages/transaction.cpp \ @@ -182,6 +183,7 @@ test_libbitcoin_network_test_SOURCES = \ test/messages/ping.cpp \ test/messages/pong.cpp \ test/messages/reject.cpp \ + test/messages/send_address_v2.cpp \ test/messages/send_compact.cpp \ test/messages/send_headers.cpp \ test/messages/transaction.cpp \ @@ -323,6 +325,7 @@ include_bitcoin_network_messages_HEADERS = \ include/bitcoin/network/messages/ping.hpp \ include/bitcoin/network/messages/pong.hpp \ include/bitcoin/network/messages/reject.hpp \ + include/bitcoin/network/messages/send_address_v2.hpp \ include/bitcoin/network/messages/send_compact.hpp \ include/bitcoin/network/messages/send_headers.hpp \ include/bitcoin/network/messages/transaction.hpp \ diff --git a/builds/cmake/CMakeLists.txt b/builds/cmake/CMakeLists.txt index d2d6afc2b..b246788a2 100644 --- a/builds/cmake/CMakeLists.txt +++ b/builds/cmake/CMakeLists.txt @@ -265,6 +265,7 @@ add_library( ${CANONICAL_LIB_NAME} "../../src/messages/ping.cpp" "../../src/messages/pong.cpp" "../../src/messages/reject.cpp" + "../../src/messages/send_address_v2.cpp" "../../src/messages/send_compact.cpp" "../../src/messages/send_headers.cpp" "../../src/messages/transaction.cpp" @@ -388,6 +389,7 @@ if (with-tests) "../../test/messages/ping.cpp" "../../test/messages/pong.cpp" "../../test/messages/reject.cpp" + "../../test/messages/send_address_v2.cpp" "../../test/messages/send_compact.cpp" "../../test/messages/send_headers.cpp" "../../test/messages/transaction.cpp" diff --git a/builds/msvc/vs2022/libbitcoin-network-test/libbitcoin-network-test.vcxproj b/builds/msvc/vs2022/libbitcoin-network-test/libbitcoin-network-test.vcxproj index 00cd4e710..0c795067c 100644 --- a/builds/msvc/vs2022/libbitcoin-network-test/libbitcoin-network-test.vcxproj +++ b/builds/msvc/vs2022/libbitcoin-network-test/libbitcoin-network-test.vcxproj @@ -176,6 +176,7 @@ + diff --git a/builds/msvc/vs2022/libbitcoin-network-test/libbitcoin-network-test.vcxproj.filters b/builds/msvc/vs2022/libbitcoin-network-test/libbitcoin-network-test.vcxproj.filters index 7f6368f6f..c4ae92dbe 100644 --- a/builds/msvc/vs2022/libbitcoin-network-test/libbitcoin-network-test.vcxproj.filters +++ b/builds/msvc/vs2022/libbitcoin-network-test/libbitcoin-network-test.vcxproj.filters @@ -198,6 +198,9 @@ src\messages + + src\messages + src\messages diff --git a/builds/msvc/vs2022/libbitcoin-network/libbitcoin-network.vcxproj b/builds/msvc/vs2022/libbitcoin-network/libbitcoin-network.vcxproj index 7e20ff9f9..24890a483 100644 --- a/builds/msvc/vs2022/libbitcoin-network/libbitcoin-network.vcxproj +++ b/builds/msvc/vs2022/libbitcoin-network/libbitcoin-network.vcxproj @@ -171,6 +171,7 @@ + @@ -277,6 +278,7 @@ + diff --git a/builds/msvc/vs2022/libbitcoin-network/libbitcoin-network.vcxproj.filters b/builds/msvc/vs2022/libbitcoin-network/libbitcoin-network.vcxproj.filters index ed1332aa9..7be69461f 100644 --- a/builds/msvc/vs2022/libbitcoin-network/libbitcoin-network.vcxproj.filters +++ b/builds/msvc/vs2022/libbitcoin-network/libbitcoin-network.vcxproj.filters @@ -219,6 +219,9 @@ src\messages + + src\messages + src\messages @@ -533,6 +536,9 @@ include\bitcoin\network\messages + + include\bitcoin\network\messages + include\bitcoin\network\messages diff --git a/include/bitcoin/network.hpp b/include/bitcoin/network.hpp index 7f4726cbb..cf9b11382 100644 --- a/include/bitcoin/network.hpp +++ b/include/bitcoin/network.hpp @@ -85,6 +85,7 @@ #include #include #include +#include #include #include #include diff --git a/include/bitcoin/network/messages/enums/identifier.hpp b/include/bitcoin/network/messages/enums/identifier.hpp index 217e7d8ea..3ce3e3e1f 100644 --- a/include/bitcoin/network/messages/enums/identifier.hpp +++ b/include/bitcoin/network/messages/enums/identifier.hpp @@ -56,6 +56,7 @@ enum class identifier ping, pong, reject, + send_address_v2, send_compact, send_headers, transaction, diff --git a/include/bitcoin/network/messages/enums/level.hpp b/include/bitcoin/network/messages/enums/level.hpp index 6c6e64d28..f5f71001f 100644 --- a/include/bitcoin/network/messages/enums/level.hpp +++ b/include/bitcoin/network/messages/enums/level.hpp @@ -148,6 +148,9 @@ enum level: uint32_t /// client filters protocol bip157 = 70015, + /// send_address_v2 + bip155 = 70016, + /// We require at least this of peers (for current address structure). minimum_protocol = address_time, diff --git a/include/bitcoin/network/messages/messages.hpp b/include/bitcoin/network/messages/messages.hpp index 5a5a904d4..dbfb237b6 100644 --- a/include/bitcoin/network/messages/messages.hpp +++ b/include/bitcoin/network/messages/messages.hpp @@ -57,6 +57,7 @@ #include #include #include +#include #include #include #include diff --git a/include/bitcoin/network/messages/send_address_v2.hpp b/include/bitcoin/network/messages/send_address_v2.hpp new file mode 100644 index 000000000..503345fdc --- /dev/null +++ b/include/bitcoin/network/messages/send_address_v2.hpp @@ -0,0 +1,57 @@ +/** + * Copyright (c) 2011-2025 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 . + */ +#ifndef LIBBITCOIN_NETWORK_MESSAGES_SEND_ADDRESS_V2_HPP +#define LIBBITCOIN_NETWORK_MESSAGES_SEND_ADDRESS_V2_HPP + +#include +#include +#include +#include + +namespace libbitcoin { +namespace network { +namespace messages { + +struct BCT_API send_address_v2 +{ + typedef std::shared_ptr cptr; + + static const identifier id; + static const std::string command; + static const uint32_t version_minimum; + static const uint32_t version_maximum; + + static size_t size(uint32_t version) NOEXCEPT; + + static cptr deserialize(uint32_t version, + const system::data_chunk& data) NOEXCEPT; + static send_address_v2 deserialize(uint32_t version, + system::reader& source) NOEXCEPT; + + bool serialize(uint32_t version, + const system::data_slab& data) const NOEXCEPT; + void serialize(uint32_t version, + system::writer& sink) const NOEXCEPT; +}; + +} // namespace messages +} // namespace network +} // namespace libbitcoin + +#endif diff --git a/include/bitcoin/network/net/broadcaster.hpp b/include/bitcoin/network/net/broadcaster.hpp index af5fbe9a9..aee5b1bcb 100644 --- a/include/bitcoin/network/net/broadcaster.hpp +++ b/include/bitcoin/network/net/broadcaster.hpp @@ -81,6 +81,7 @@ class BCT_API broadcaster DEFINE_SUBSCRIBER(ping); DEFINE_SUBSCRIBER(pong); DEFINE_SUBSCRIBER(reject); + DEFINE_SUBSCRIBER(send_address_v2); DEFINE_SUBSCRIBER(send_compact); DEFINE_SUBSCRIBER(send_headers); DEFINE_SUBSCRIBER(transaction); @@ -128,6 +129,7 @@ class BCT_API broadcaster NOTIFY_OVERLOAD(ping); NOTIFY_OVERLOAD(pong); NOTIFY_OVERLOAD(reject); + NOTIFY_OVERLOAD(send_address_v2); NOTIFY_OVERLOAD(send_compact); NOTIFY_OVERLOAD(send_headers); NOTIFY_OVERLOAD(transaction); @@ -171,6 +173,7 @@ class BCT_API broadcaster SUBSCRIBER_OVERLOAD(ping); SUBSCRIBER_OVERLOAD(pong); SUBSCRIBER_OVERLOAD(reject); + SUBSCRIBER_OVERLOAD(send_address_v2); SUBSCRIBER_OVERLOAD(send_compact); SUBSCRIBER_OVERLOAD(send_headers); SUBSCRIBER_OVERLOAD(transaction); @@ -206,6 +209,7 @@ class BCT_API broadcaster DECLARE_SUBSCRIBER(ping); DECLARE_SUBSCRIBER(pong); DECLARE_SUBSCRIBER(reject); + DECLARE_SUBSCRIBER(send_address_v2); DECLARE_SUBSCRIBER(send_compact); DECLARE_SUBSCRIBER(send_headers); DECLARE_SUBSCRIBER(transaction); diff --git a/include/bitcoin/network/net/distributor.hpp b/include/bitcoin/network/net/distributor.hpp index 23b444c65..14bbbf58a 100644 --- a/include/bitcoin/network/net/distributor.hpp +++ b/include/bitcoin/network/net/distributor.hpp @@ -77,6 +77,7 @@ class BCT_API distributor DEFINE_SUBSCRIBER(ping); DEFINE_SUBSCRIBER(pong); DEFINE_SUBSCRIBER(reject); + DEFINE_SUBSCRIBER(send_address_v2); DEFINE_SUBSCRIBER(send_compact); DEFINE_SUBSCRIBER(send_headers); DEFINE_SUBSCRIBER(transaction); @@ -153,6 +154,7 @@ class BCT_API distributor SUBSCRIBER_OVERLOAD(ping); SUBSCRIBER_OVERLOAD(pong); SUBSCRIBER_OVERLOAD(reject); + SUBSCRIBER_OVERLOAD(send_address_v2); SUBSCRIBER_OVERLOAD(send_compact); SUBSCRIBER_OVERLOAD(send_headers); SUBSCRIBER_OVERLOAD(transaction); @@ -188,6 +190,7 @@ class BCT_API distributor DECLARE_SUBSCRIBER(ping); DECLARE_SUBSCRIBER(pong); DECLARE_SUBSCRIBER(reject); + DECLARE_SUBSCRIBER(send_address_v2); DECLARE_SUBSCRIBER(send_compact); DECLARE_SUBSCRIBER(send_headers); DECLARE_SUBSCRIBER(transaction); diff --git a/src/messages/heading.cpp b/src/messages/heading.cpp index 40ccb2bc9..8e3f5992e 100644 --- a/src/messages/heading.cpp +++ b/src/messages/heading.cpp @@ -50,6 +50,7 @@ #include #include #include +#include #include #include #include @@ -194,6 +195,7 @@ identifier heading::id() const NOEXCEPT COMMAND_ID(ping), COMMAND_ID(pong), COMMAND_ID(reject), + COMMAND_ID(send_address_v2), COMMAND_ID(send_compact), COMMAND_ID(send_headers), COMMAND_ID(transaction), diff --git a/src/messages/send_address_v2.cpp b/src/messages/send_address_v2.cpp new file mode 100644 index 000000000..473ba20bb --- /dev/null +++ b/src/messages/send_address_v2.cpp @@ -0,0 +1,80 @@ +/** + * Copyright (c) 2011-2025 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 + +#include +#include +#include +#include + +namespace libbitcoin { +namespace network { +namespace messages { + +using namespace system; + +const std::string send_address_v2::command = "sendaddrv2"; +const identifier send_address_v2::id = identifier::send_address_v2; +const uint32_t send_address_v2::version_minimum = level::bip155; +const uint32_t send_address_v2::version_maximum = level::maximum_protocol; + +// static +size_t send_address_v2::size(uint32_t) NOEXCEPT +{ + return zero; +} + +// static +typename send_address_v2::cptr send_address_v2::deserialize(uint32_t version, + const system::data_chunk& data) NOEXCEPT +{ + system::istream source{ data }; + system::byte_reader reader{ source }; + const auto message = to_shared(deserialize(version, reader)); + return reader ? message : nullptr; +} + +bool send_address_v2::serialize(uint32_t version, + const system::data_slab& data) const NOEXCEPT +{ + system::ostream sink{ data }; + system::byte_writer writer{ sink }; + serialize(version, writer); + return writer; +} + +send_address_v2 send_address_v2::deserialize(uint32_t version, reader& source) NOEXCEPT +{ + if (version < version_minimum || version > version_maximum) + source.invalidate(); + + return {}; +} + +void send_address_v2::serialize(uint32_t BC_DEBUG_ONLY(version), + writer& BC_DEBUG_ONLY(sink)) const NOEXCEPT +{ + BC_DEBUG_ONLY(const auto bytes = size(version);) + BC_DEBUG_ONLY(const auto start = sink.get_write_position();) + BC_ASSERT(sink && sink.get_write_position() - start == bytes); +} + +} // namespace messages +} // namespace network +} // namespace libbitcoin diff --git a/src/net/broadcaster.cpp b/src/net/broadcaster.cpp index debbf1f5d..521de3f47 100644 --- a/src/net/broadcaster.cpp +++ b/src/net/broadcaster.cpp @@ -62,6 +62,7 @@ broadcaster::broadcaster(asio::strand& strand) NOEXCEPT MAKE_SUBSCRIBER(ping), MAKE_SUBSCRIBER(pong), MAKE_SUBSCRIBER(reject), + MAKE_SUBSCRIBER(send_address_v2), MAKE_SUBSCRIBER(send_compact), MAKE_SUBSCRIBER(send_headers), MAKE_SUBSCRIBER(transaction), @@ -100,6 +101,7 @@ void broadcaster::unsubscribe(channel_id subscriber) NOEXCEPT UNSUBSCRIBER(ping); UNSUBSCRIBER(pong); UNSUBSCRIBER(reject); + UNSUBSCRIBER(send_address_v2); UNSUBSCRIBER(send_compact); UNSUBSCRIBER(send_headers); UNSUBSCRIBER(transaction); @@ -137,6 +139,7 @@ void broadcaster::stop(const code& ec) NOEXCEPT STOP_SUBSCRIBER(ping); STOP_SUBSCRIBER(pong); STOP_SUBSCRIBER(reject); + STOP_SUBSCRIBER(send_address_v2); STOP_SUBSCRIBER(send_compact); STOP_SUBSCRIBER(send_headers); STOP_SUBSCRIBER(transaction); diff --git a/src/net/distributor.cpp b/src/net/distributor.cpp index ae62fcfc1..91694634f 100644 --- a/src/net/distributor.cpp +++ b/src/net/distributor.cpp @@ -69,6 +69,7 @@ distributor::distributor(memory& memory, asio::strand& strand) NOEXCEPT MAKE_SUBSCRIBER(ping), MAKE_SUBSCRIBER(pong), MAKE_SUBSCRIBER(reject), + MAKE_SUBSCRIBER(send_address_v2), MAKE_SUBSCRIBER(send_compact), MAKE_SUBSCRIBER(send_headers), MAKE_SUBSCRIBER(transaction), @@ -111,6 +112,7 @@ code distributor::notify(messages::identifier id, uint32_t version, CASE_NOTIFY(ping); CASE_NOTIFY(pong); CASE_NOTIFY(reject); + CASE_NOTIFY(send_address_v2); CASE_NOTIFY(send_compact); CASE_NOTIFY(send_headers); CASE_NOTIFY(transaction); @@ -153,6 +155,7 @@ void distributor::stop(const code& ec) NOEXCEPT STOP_SUBSCRIBER(ping); STOP_SUBSCRIBER(pong); STOP_SUBSCRIBER(reject); + STOP_SUBSCRIBER(send_address_v2); STOP_SUBSCRIBER(send_compact); STOP_SUBSCRIBER(send_headers); STOP_SUBSCRIBER(transaction); diff --git a/test/messages/heading.cpp b/test/messages/heading.cpp index f0652904d..f2ebd82c0 100644 --- a/test/messages/heading.cpp +++ b/test/messages/heading.cpp @@ -211,6 +211,12 @@ BOOST_AUTO_TEST_CASE(heading__reject_id__always__expected) BOOST_REQUIRE(instance.id() == reject::id); } +BOOST_AUTO_TEST_CASE(heading__send_address_v2_id__always__expected) +{ + const auto instance = heading{ 0u, send_address_v2::command, 0u, 0u }; + BOOST_REQUIRE(instance.id() == send_address_v2::id); +} + BOOST_AUTO_TEST_CASE(heading__send_compact_id__always__expected) { const auto instance = heading{ 0u, send_compact::command, 0u, 0u }; diff --git a/test/messages/send_address_v2.cpp b/test/messages/send_address_v2.cpp new file mode 100644 index 000000000..55d6a53f0 --- /dev/null +++ b/test/messages/send_address_v2.cpp @@ -0,0 +1,38 @@ +/** + * Copyright (c) 2011-2025 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(send_address_v2_tests) + +using namespace bc::network::messages; + +BOOST_AUTO_TEST_CASE(send_address_v2__properties__always__expected) +{ + BOOST_REQUIRE_EQUAL(send_address_v2::command, "sendaddrv2"); + BOOST_REQUIRE(send_address_v2::id == identifier::send_address_v2); + BOOST_REQUIRE_EQUAL(send_address_v2::version_minimum, level::bip155); + BOOST_REQUIRE_EQUAL(send_address_v2::version_maximum, level::maximum_protocol); +} + +BOOST_AUTO_TEST_CASE(send_address_v2__size__always__expected) +{ + BOOST_REQUIRE_EQUAL(send_address_v2::size(level::canonical), zero); +} + +BOOST_AUTO_TEST_SUITE_END()