From ee24c63c985e8a7665b5093f84068788f9dfd2d2 Mon Sep 17 00:00:00 2001 From: evoskuil Date: Sun, 29 Mar 2026 18:50:38 -0400 Subject: [PATCH 1/2] Add block and tx optimization message types. --- Makefile.am | 8 +++ .../libbitcoin-node/libbitcoin-node.vcxproj | 5 ++ .../libbitcoin-node.vcxproj.filters | 45 +++++++++---- include/bitcoin/node.hpp | 3 + include/bitcoin/node/define.hpp | 1 + include/bitcoin/node/messages/block.hpp | 62 +++++++++++++++++ include/bitcoin/node/messages/messages.hpp | 25 +++++++ include/bitcoin/node/messages/transaction.hpp | 66 +++++++++++++++++++ .../bitcoin/node/sessions/session_peer.hpp | 2 +- src/messages/block.cpp | 65 ++++++++++++++++++ src/messages/transaction.cpp | 65 ++++++++++++++++++ 11 files changed, 334 insertions(+), 13 deletions(-) create mode 100644 include/bitcoin/node/messages/block.hpp create mode 100644 include/bitcoin/node/messages/messages.hpp create mode 100644 include/bitcoin/node/messages/transaction.hpp create mode 100644 src/messages/block.cpp create mode 100644 src/messages/transaction.cpp diff --git a/Makefile.am b/Makefile.am index f9f99f84..7c15cfbc 100644 --- a/Makefile.am +++ b/Makefile.am @@ -52,6 +52,8 @@ src_libbitcoin_node_la_SOURCES = \ src/chasers/chaser_template.cpp \ src/chasers/chaser_transaction.cpp \ src/chasers/chaser_validate.cpp \ + src/messages/block.cpp \ + src/messages/transaction.cpp \ src/protocols/protocol.cpp \ src/protocols/protocol_block_in_106.cpp \ src/protocols/protocol_block_in_31800.cpp \ @@ -149,6 +151,12 @@ include_bitcoin_node_impl_chasersdir = ${includedir}/bitcoin/node/impl/chasers include_bitcoin_node_impl_chasers_HEADERS = \ include/bitcoin/node/impl/chasers/chaser_organize.ipp +include_bitcoin_node_messagesdir = ${includedir}/bitcoin/node/messages +include_bitcoin_node_messages_HEADERS = \ + include/bitcoin/node/messages/block.hpp \ + include/bitcoin/node/messages/messages.hpp \ + include/bitcoin/node/messages/transaction.hpp + include_bitcoin_node_protocolsdir = ${includedir}/bitcoin/node/protocols include_bitcoin_node_protocols_HEADERS = \ include/bitcoin/node/protocols/protocol.hpp \ diff --git a/builds/msvc/vs2022/libbitcoin-node/libbitcoin-node.vcxproj b/builds/msvc/vs2022/libbitcoin-node/libbitcoin-node.vcxproj index 5e7f49b2..6a9d4dfb 100644 --- a/builds/msvc/vs2022/libbitcoin-node/libbitcoin-node.vcxproj +++ b/builds/msvc/vs2022/libbitcoin-node/libbitcoin-node.vcxproj @@ -137,6 +137,8 @@ + + @@ -183,6 +185,9 @@ + + + diff --git a/builds/msvc/vs2022/libbitcoin-node/libbitcoin-node.vcxproj.filters b/builds/msvc/vs2022/libbitcoin-node/libbitcoin-node.vcxproj.filters index 7ca22c13..3b8d601c 100644 --- a/builds/msvc/vs2022/libbitcoin-node/libbitcoin-node.vcxproj.filters +++ b/builds/msvc/vs2022/libbitcoin-node/libbitcoin-node.vcxproj.filters @@ -8,34 +8,37 @@ - {5FFB5F52-0772-4404-0000-000000000005} + {5FFB5F52-0772-4404-0000-000000000006} - {5FFB5F52-0772-4404-0000-000000000006} + {5FFB5F52-0772-4404-0000-000000000007} - {5FFB5F52-0772-4404-0000-000000000007} + {5FFB5F52-0772-4404-0000-000000000008} - {5FFB5F52-0772-4404-0000-000000000008} + {5FFB5F52-0772-4404-0000-000000000009} - {5FFB5F52-0772-4404-0000-000000000009} + {5FFB5F52-0772-4404-0000-00000000000A} - {5FFB5F52-0772-4404-0000-00000000000A} + {5FFB5F52-0772-4404-0000-00000000000B} - {5FFB5F52-0772-4404-0000-00000000000D} + {5FFB5F52-0772-4404-0000-00000000000F} + + + {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-00000000000E} + {5FFB5F52-0772-4404-0000-000000000001} {5FFB5F52-0772-4404-0000-000000000000} @@ -46,12 +49,15 @@ {5FFB5F52-0772-4404-0000-000000000002} - + {5FFB5F52-0772-4404-0000-000000000003} - + {5FFB5F52-0772-4404-0000-000000000004} + + {5FFB5F52-0772-4404-0000-000000000005} + @@ -102,6 +108,12 @@ src + + src\messages + + + src\messages + src\protocols @@ -236,6 +248,15 @@ 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 064c8ee9..cef48d1b 100644 --- a/include/bitcoin/node.hpp +++ b/include/bitcoin/node.hpp @@ -41,6 +41,9 @@ #include #include #include +#include +#include +#include #include #include #include diff --git a/include/bitcoin/node/define.hpp b/include/bitcoin/node/define.hpp index c6e1ba4a..ac433205 100644 --- a/include/bitcoin/node/define.hpp +++ b/include/bitcoin/node/define.hpp @@ -123,5 +123,6 @@ using type_id = network::messages::peer::inventory_item::type_id; // /channels : define configuration // full_node : define /chasers // session : define [forward: full_node] +// /messages : define // /protocols : define /channels [session.hpp] // /sessions : define /protocols [forward: full_node] \ No newline at end of file diff --git a/include/bitcoin/node/messages/block.hpp b/include/bitcoin/node/messages/block.hpp new file mode 100644 index 00000000..9e57a419 --- /dev/null +++ b/include/bitcoin/node/messages/block.hpp @@ -0,0 +1,62 @@ +/** + * 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 . + */ +#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 network::messages::peer::identifier id; + 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; + + /// These return false if witness or version is inconsistent with block 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 block. + system::data_chunk block_data{}; + + /// Block contains witness data (if applicable). + const bool witnessed_{}; +}; + +} // namespace messages +} // namespace node +} // namespace libbitcoin + +#endif diff --git a/include/bitcoin/node/messages/messages.hpp b/include/bitcoin/node/messages/messages.hpp new file mode 100644 index 00000000..3424295b --- /dev/null +++ b/include/bitcoin/node/messages/messages.hpp @@ -0,0 +1,25 @@ +/** + * 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 . + */ +#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 new file mode 100644 index 00000000..49d8f614 --- /dev/null +++ b/include/bitcoin/node/messages/transaction.hpp @@ -0,0 +1,66 @@ +/** + * 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 . + */ +#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 network::messages::peer::identifier id; + 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/include/bitcoin/node/sessions/session_peer.hpp b/include/bitcoin/node/sessions/session_peer.hpp index b630f913..22c103d0 100644 --- a/include/bitcoin/node/sessions/session_peer.hpp +++ b/include/bitcoin/node/sessions/session_peer.hpp @@ -89,7 +89,7 @@ class session_peer using namespace system; using namespace network; - using namespace messages::peer; + using namespace network::messages::peer; using base = session_peer; const auto self = this->template shared_from_base(); diff --git a/src/messages/block.cpp b/src/messages/block.cpp new file mode 100644 index 00000000..9409442e --- /dev/null +++ b/src/messages/block.cpp @@ -0,0 +1,65 @@ +/** + * 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 + +#include + +namespace libbitcoin { +namespace node { +namespace messages { + +using namespace system; +using namespace network::messages::peer; + +const std::string block::command = "block"; +const identifier block::id = identifier::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 +{ + 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 block::serialize(uint32_t, writer& sink, + bool BC_DEBUG_ONLY(witness)) const NOEXCEPT +{ + BC_ASSERT(witness == witnessed_); + sink.write_bytes(block_data); +} + +// Sender must ensure that version/witness are consistent with channel. +size_t block::size(uint32_t, bool BC_DEBUG_ONLY(witness)) const NOEXCEPT +{ + BC_ASSERT(witness == witnessed_); + return block_data.size(); +} + +} // namespace messages +} // namespace node +} // namespace libbitcoin diff --git a/src/messages/transaction.cpp b/src/messages/transaction.cpp new file mode 100644 index 00000000..17131d95 --- /dev/null +++ b/src/messages/transaction.cpp @@ -0,0 +1,65 @@ +/** + * 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 + +#include + +namespace libbitcoin { +namespace node { +namespace messages { + +using namespace system; +using namespace network::messages::peer; + +const std::string transaction::command = "tx"; +const identifier transaction::id = identifier::transaction; +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 From 1a8b668cca5370300f73d5e467db219170ddb7ce Mon Sep 17 00:00:00 2001 From: evoskuil Date: Sun, 29 Mar 2026 18:51:01 -0400 Subject: [PATCH 2/2] Integrate new optimizing block message. --- src/protocols/protocol_block_out_106.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/protocols/protocol_block_out_106.cpp b/src/protocols/protocol_block_out_106.cpp index d3664461..32a906e5 100644 --- a/src/protocols/protocol_block_out_106.cpp +++ b/src/protocols/protocol_block_out_106.cpp @@ -20,6 +20,7 @@ #include #include +#include namespace libbitcoin { namespace node { @@ -158,7 +159,7 @@ bool protocol_block_out_106::handle_receive_get_data(const code& ec, return true; const auto total = ceilinged_add(backlog_.size(), size); - if (total > messages::peer::max_inventory) + if (total > network::messages::peer::max_inventory) { LOGR("Blocks requested (" << total << ") exceeds inv limit [" << opposite() << "]."); @@ -210,8 +211,10 @@ void protocol_block_out_106::send_block(const code& ec) NOEXCEPT const auto& query = archive(); const auto start = logger::now(); - const auto ptr = query.get_block(query.to_header(item.hash), witness); - if (!ptr) + const auto link = query.to_header(item.hash); + + node::messages::block out{ query.get_wire_block(link, witness), witness }; + if (out.block_data.empty()) { LOGR("Requested block " << encode_hash(item.hash) << " from [" << opposite() << "] not found."); @@ -223,7 +226,7 @@ void protocol_block_out_106::send_block(const code& ec) NOEXCEPT backlog_.pop_front(); span(events::block_usecs, start); - SEND(messages::peer::block{ ptr }, send_block, _1); + SEND(std::move(out), send_block, _1); } // utilities @@ -247,7 +250,7 @@ protocol_block_out_106::inventory protocol_block_out_106::create_inventory( return inventory::factory ( archive().get_blocks(locator.start_hashes, locator.stop_hash, - messages::peer::max_get_blocks), type_id::block + network::messages::peer::max_get_blocks), type_id::block ); }