diff --git a/builds/cmake/CMakeLists.txt b/builds/cmake/CMakeLists.txt
index 351fb6f5..82e81bf7 100644
--- a/builds/cmake/CMakeLists.txt
+++ b/builds/cmake/CMakeLists.txt
@@ -61,7 +61,7 @@ project( libbitcoin-node
LANGUAGES C CXX )
-set( repository_root_dir "${CMAKE_CURRENT_SOURCE_DIR}/../../" )
+set( repository_root_dir "${CMAKE_CURRENT_SOURCE_DIR}/../.." )
if ( MSVC )
set( CMAKE_STATIC_LIBRARY_PREFIX "lib" )
diff --git a/builds/gnu/Makefile.am b/builds/gnu/Makefile.am
index 753dc613..2f59415c 100644
--- a/builds/gnu/Makefile.am
+++ b/builds/gnu/Makefile.am
@@ -57,7 +57,6 @@ src_libbitcoin_node_la_SOURCES = \
${srcdir}/../../src/estimator.cpp \
${srcdir}/../../src/full_node.cpp \
${srcdir}/../../src/settings.cpp \
- ${srcdir}/../../src/validate.cpp \
${srcdir}/../../src/channels/channel_peer.cpp \
${srcdir}/../../src/chasers/chaser.cpp \
${srcdir}/../../src/chasers/chaser_block.cpp \
@@ -115,7 +114,6 @@ include_bitcoin_node_HEADERS = \
${srcdir}/../../include/bitcoin/node/events.hpp \
${srcdir}/../../include/bitcoin/node/full_node.hpp \
${srcdir}/../../include/bitcoin/node/settings.hpp \
- ${srcdir}/../../include/bitcoin/node/validate.hpp \
${srcdir}/../../include/bitcoin/node/version.hpp
include_bitcoin_node_channelsdir = \
diff --git a/builds/gnu/configure.ac b/builds/gnu/configure.ac
index ce72f06e..4c67e1c4 100644
--- a/builds/gnu/configure.ac
+++ b/builds/gnu/configure.ac
@@ -68,7 +68,7 @@ AC_ARG_VAR([CC], "C compiler to use, such as gcc or clang")
AC_ARG_VAR([CXX], "C++ compiler to use, such as g++ or clang++")
AC_ARG_VAR([PKG_CONFIG_PATH], "Additional directories for package discovery.")
-repository_root_dir="@abs_top_srcdir@/../.."
+repository_root_dir=`cd "${srcdir}/../.." && pwd`
# Check for baseline language coverage in the compiler for the C++20 standard.
#------------------------------------------------------------------------------
diff --git a/builds/msvc/vs2022/libbitcoin-node/libbitcoin-node.vcxproj b/builds/msvc/vs2022/libbitcoin-node/libbitcoin-node.vcxproj
index 750d08b1..6d92f85f 100644
--- a/builds/msvc/vs2022/libbitcoin-node/libbitcoin-node.vcxproj
+++ b/builds/msvc/vs2022/libbitcoin-node/libbitcoin-node.vcxproj
@@ -164,7 +164,6 @@
-
@@ -219,7 +218,6 @@
-
diff --git a/builds/msvc/vs2022/libbitcoin-node/libbitcoin-node.vcxproj.filters b/builds/msvc/vs2022/libbitcoin-node/libbitcoin-node.vcxproj.filters
index 10876c36..7bbae4c3 100644
--- a/builds/msvc/vs2022/libbitcoin-node/libbitcoin-node.vcxproj.filters
+++ b/builds/msvc/vs2022/libbitcoin-node/libbitcoin-node.vcxproj.filters
@@ -186,9 +186,6 @@
src
-
- src
-
@@ -347,9 +344,6 @@
include\bitcoin\node
-
- include\bitcoin\node
-
include\bitcoin\node
diff --git a/builds/msvc/vs2026/libbitcoin-node/libbitcoin-node.vcxproj b/builds/msvc/vs2026/libbitcoin-node/libbitcoin-node.vcxproj
index c43c94a9..5a3101e5 100644
--- a/builds/msvc/vs2026/libbitcoin-node/libbitcoin-node.vcxproj
+++ b/builds/msvc/vs2026/libbitcoin-node/libbitcoin-node.vcxproj
@@ -164,7 +164,6 @@
-
@@ -219,7 +218,6 @@
-
diff --git a/builds/msvc/vs2026/libbitcoin-node/libbitcoin-node.vcxproj.filters b/builds/msvc/vs2026/libbitcoin-node/libbitcoin-node.vcxproj.filters
index 10876c36..7bbae4c3 100644
--- a/builds/msvc/vs2026/libbitcoin-node/libbitcoin-node.vcxproj.filters
+++ b/builds/msvc/vs2026/libbitcoin-node/libbitcoin-node.vcxproj.filters
@@ -186,9 +186,6 @@
src
-
- src
-
@@ -347,9 +344,6 @@
include\bitcoin\node
-
- include\bitcoin\node
-
include\bitcoin\node
diff --git a/include/bitcoin/node.hpp b/include/bitcoin/node.hpp
index 7ce08dfe..27ee6414 100644
--- a/include/bitcoin/node.hpp
+++ b/include/bitcoin/node.hpp
@@ -26,7 +26,6 @@
#include
#include
#include
-#include
#include
#include
#include
diff --git a/include/bitcoin/node/chasers/chaser_transaction.hpp b/include/bitcoin/node/chasers/chaser_transaction.hpp
index 637c1865..8b0ec9c8 100644
--- a/include/bitcoin/node/chasers/chaser_transaction.hpp
+++ b/include/bitcoin/node/chasers/chaser_transaction.hpp
@@ -38,15 +38,29 @@ class BCN_API chaser_transaction
code start() NOEXCEPT override;
- virtual void store(const system::chain::transaction::cptr& block) NOEXCEPT;
+ /// Validate and archive a submitted package, accepted as a whole.
+ /// The package is only validated when test, so nothing is archived.
+ virtual void submit(const system::chain::transactions_cptr& txs,
+ bool test, submit_handler&& handler) NOEXCEPT;
protected:
virtual bool handle_chase(const code& ec, chase event_,
event_value value) NOEXCEPT;
- virtual void do_confirmed(header_t link) NOEXCEPT;
- virtual void do_store(
- const system::chain::transaction::cptr& header) NOEXCEPT;
+ virtual void do_submit(const system::chain::transactions_cptr& txs,
+ bool test, const submit_handler& handler) NOEXCEPT;
+
+ /// Recompute the pool context, closing the pool if not current.
+ virtual void do_bump() NOEXCEPT;
+
+private:
+ code validate(size_t& index,
+ const system::chain::transaction_cptrs& txs) NOEXCEPT;
+ code validate(const system::chain::transaction& tx) NOEXCEPT;
+
+ // These are protected by strand.
+ system::chain::context pool_{};
+ bool pooling_{};
};
} // namespace node
diff --git a/include/bitcoin/node/define.hpp b/include/bitcoin/node/define.hpp
index 7fa8f00d..91e4f3a5 100644
--- a/include/bitcoin/node/define.hpp
+++ b/include/bitcoin/node/define.hpp
@@ -54,6 +54,7 @@ typedef std::function estimate_handler;
/// Organization types.
typedef std::function organize_handler;
+typedef std::function submit_handler;
typedef database::store store;
typedef database::query query;
diff --git a/include/bitcoin/node/error.hpp b/include/bitcoin/node/error.hpp
index 42c68e88..3c2e2e49 100644
--- a/include/bitcoin/node/error.hpp
+++ b/include/bitcoin/node/error.hpp
@@ -59,6 +59,10 @@ enum error_t : uint8_t
duplicate_block,
duplicate_header,
+ /// transaction pool
+ pooling_disabled,
+ empty_package,
+
/// fee estimation
estimate_disabled,
estimate_premature,
@@ -105,6 +109,7 @@ enum error_t : uint8_t
confirm10,
confirm11,
confirm12,
+ transaction1,
estimates_initialize,
estimates_push1,
estimates_push2,
diff --git a/include/bitcoin/node/full_node.hpp b/include/bitcoin/node/full_node.hpp
index 0f36eb57..9eba4fa9 100644
--- a/include/bitcoin/node/full_node.hpp
+++ b/include/bitcoin/node/full_node.hpp
@@ -73,6 +73,11 @@ class BCN_API full_node
virtual void prioritize(const system::hash_digest& hash,
organize_handler&& handler) NOEXCEPT;
+ /// Validate and archive a submitted package, accepted as a whole.
+ /// The package is only validated when test, so nothing is archived.
+ virtual void submit(const system::chain::transactions_cptr& txs,
+ bool test, submit_handler&& handler) NOEXCEPT;
+
/// Manage download queue.
virtual void get_hashes(map_handler&& handler) NOEXCEPT;
virtual void put_hashes(const map_ptr& map,
diff --git a/include/bitcoin/node/protocols/protocol.hpp b/include/bitcoin/node/protocols/protocol.hpp
index 4822057c..a6f580a9 100644
--- a/include/bitcoin/node/protocols/protocol.hpp
+++ b/include/bitcoin/node/protocols/protocol.hpp
@@ -112,6 +112,11 @@ class BCN_API protocol
virtual void prioritize(const system::hash_digest& hash,
organize_handler&& handler) NOEXCEPT;
+ /// Validate and archive a submitted package, accepted as a whole.
+ /// The package is only validated when test, so nothing is archived.
+ virtual void submit(const system::chain::transactions_cptr& txs,
+ bool test, submit_handler&& handler) NOEXCEPT;
+
/// Events subscription.
/// -----------------------------------------------------------------------
diff --git a/include/bitcoin/node/protocols/protocol_transaction_out_106.hpp b/include/bitcoin/node/protocols/protocol_transaction_out_106.hpp
index 192ae5f0..b7b858b8 100644
--- a/include/bitcoin/node/protocols/protocol_transaction_out_106.hpp
+++ b/include/bitcoin/node/protocols/protocol_transaction_out_106.hpp
@@ -36,7 +36,6 @@ class BCN_API protocol_transaction_out_106
const network::channel::ptr& channel) NOEXCEPT
: node::protocol_peer(session, channel),
node_witness_(session->node_settings().provide_witness),
- broadcast_(maximum_retained),
network::tracker(session->log)
{
}
@@ -55,10 +54,6 @@ class BCN_API protocol_transaction_out_106
/// Process tx announcement.
virtual bool do_announce(transaction_t link) NOEXCEPT;
- virtual bool handle_broadcast_transaction(const code& ec,
- const network::messages::peer::transaction::cptr& message,
- uint64_t sender) NOEXCEPT;
-
virtual bool handle_receive_get_data(const code& ec,
const network::messages::peer::get_data::cptr& message) NOEXCEPT;
virtual void send_transaction(const code& ec, size_t index,
@@ -71,28 +66,9 @@ class BCN_API protocol_transaction_out_106
virtual bool announce(const system::hash_digest& hash) NOEXCEPT;
- /// Retain a broadcast tx, pending request by the peer.
- virtual void retain(const system::hash_digest& hash,
- const system::chain::transaction::cptr& tx) NOEXCEPT;
-
- /// Obtain and drop a retained tx, or nullptr.
- virtual system::chain::transaction::cptr release(
- const system::hash_digest& hash) NOEXCEPT;
-
private:
- using retained_t = std::pair;
- using retained_txs = boost::circular_buffer;
-
- static constexpr size_t maximum_retained = 42;
-
- retained_txs::iterator find(const system::hash_digest& hash) NOEXCEPT;
-
// These are thread safe.
const bool node_witness_;
-
- // This is protected by strand.
- retained_txs broadcast_;
};
} // namespace node
diff --git a/include/bitcoin/node/sessions/session.hpp b/include/bitcoin/node/sessions/session.hpp
index 14644fe9..97ceaaf9 100644
--- a/include/bitcoin/node/sessions/session.hpp
+++ b/include/bitcoin/node/sessions/session.hpp
@@ -51,6 +51,11 @@ class BCN_API session
virtual void prioritize(const system::hash_digest& hash,
organize_handler&& handler) NOEXCEPT;
+ /// Validate and archive a submitted package, accepted as a whole.
+ /// The package is only validated when test, so nothing is archived.
+ virtual void submit(const system::chain::transactions_cptr& txs,
+ bool test, submit_handler&& handler) NOEXCEPT;
+
/// Manage download queue.
virtual void get_hashes(map_handler&& handler) NOEXCEPT;
virtual void put_hashes(const map_ptr& map,
diff --git a/include/bitcoin/node/validate.hpp b/include/bitcoin/node/validate.hpp
deleted file mode 100644
index 306192ed..00000000
--- a/include/bitcoin/node/validate.hpp
+++ /dev/null
@@ -1,40 +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_VALIDATE_HPP
-#define LIBBITCOIN_NODE_VALIDATE_HPP
-
-#include
-#include
-
-namespace libbitcoin {
-namespace node {
-
-/// Transaction validation against the confirmed chain, for services that
-/// accept transactions from clients (there is no tx pool until v5). Shared
-/// by the server protocols, which obtain the context of the next block.
-
-/// Validate tx in the given context, populating its prevout metadata.
-/// Includes the block-rule guards, a DoS guard for standalone validation.
-BCN_API code validate_transaction(const system::chain::transaction& tx,
- const query& query, const system::chain::context& pool) NOEXCEPT;
-
-} // namespace node
-} // namespace libbitcoin
-
-#endif
diff --git a/src/chasers/chaser_transaction.cpp b/src/chasers/chaser_transaction.cpp
index f1f2af0b..d59354ec 100644
--- a/src/chasers/chaser_transaction.cpp
+++ b/src/chasers/chaser_transaction.cpp
@@ -26,11 +26,13 @@ namespace libbitcoin {
namespace node {
#define CLASS chaser_transaction
-
+
+using namespace system;
using namespace system::chain;
using namespace std::placeholders;
BC_PUSH_WARNING(NO_THROW_IN_NOEXCEPT)
+BC_PUSH_WARNING(NO_VALUE_OR_CONST_REF_SHARED_PTR)
chaser_transaction::chaser_transaction(full_node& node) NOEXCEPT
: chaser(node)
@@ -40,10 +42,10 @@ chaser_transaction::chaser_transaction(full_node& node) NOEXCEPT
// start
// ----------------------------------------------------------------------------
-// TODO: initialize tx graph from store, log and stop on error.
code chaser_transaction::start() NOEXCEPT
{
SUBSCRIBE_CHASE(handle_chase, _1, _2, _3);
+ POST(do_bump);
return error::success;
}
@@ -56,14 +58,14 @@ bool chaser_transaction::handle_chase(const code&, chase event_,
if (closed())
return false;
- // TODO: allow required messages.
- ////// Stop generating query during suspension.
- ////// Incoming events may already be flushed to the strand at this point.
- ////if (suspended())
- //// return true;
-
switch (event_)
{
+ case chase::organized:
+ case chase::reorganized:
+ {
+ POST(do_bump);
+ break;
+ }
case chase::stop:
{
return false;
@@ -77,34 +79,137 @@ bool chaser_transaction::handle_chase(const code&, chase event_,
return true;
}
-// TODO: handle the new confirmed blocks (may issue 'transaction').
-void chaser_transaction::do_confirmed(header_t) NOEXCEPT
+// The pool is closed until the confirmed chain is current, and closes again if
+// currency is lost, though the store latch is one way, since the txs archived
+// while it was open outlive it.
+void chaser_transaction::do_bump() NOEXCEPT
{
BC_ASSERT(stranded());
+ pooling_ = false;
+
+ if (closed() || !is_current_chain(true))
+ return;
- notify(error::success, chase::transaction, transaction_t{});
+ auto& query = archive();
+ const auto top = query.get_top_confirmed();
+ const auto state = query.get_confirmed_chain_state(system_settings(),
+ query.to_confirmed(top), top);
+
+ if (!state)
+ {
+ fault(error::transaction1);
+ return;
+ }
+
+ // The context of the next block, in which a pool tx would confirm.
+ pool_ = chain_state{ *state, system_settings() }.context();
+ query.set_pooling();
+ pooling_ = true;
}
// methods
// ----------------------------------------------------------------------------
-void chaser_transaction::store(const transaction::cptr&) NOEXCEPT
+void chaser_transaction::submit(const transactions_cptr& txs, bool test,
+ submit_handler&& handler) NOEXCEPT
{
- // Push new checked tx into store and update DAG. Issue transaction event
- // so that candidate may construct a new template.
+ if (closed())
+ return;
+
+ POST(do_submit, txs, test, std::move(handler));
}
// private
-void chaser_transaction::do_store(const transaction::cptr&) NOEXCEPT
+void chaser_transaction::do_submit(const transactions_cptr& txs, bool test,
+ const submit_handler& handler) NOEXCEPT
{
BC_ASSERT(stranded());
- // TODO: validate and store transaction.
+ if (closed())
+ {
+ handler(network::error::service_stopped, {});
+ return;
+ }
- // Relay notification.
- ////notify(error::success, chase::transaction, link);
+ if (!pooling_)
+ {
+ handler(error::pooling_disabled, {});
+ return;
+ }
+
+ size_t index{};
+ if (const auto ec = validate(index, *txs))
+ {
+ handler(ec, index);
+ return;
+ }
+
+ if (test)
+ {
+ handler(error::success, {});
+ return;
+ }
+
+ auto& query = archive();
+ for (index = {}; index < txs->size(); ++index)
+ {
+ database::tx_link link{};
+
+ // Disk full may leave package partly archived, resolves by resubmit.
+ if (const auto ec = query.set_code(link, *txs->at(index)))
+ {
+ handler(fault(ec), index);
+ return;
+ }
+
+ fire(events::tx_archived, link);
+ notify(error::success, chase::transaction, transaction_t{ link });
+ }
+
+ handler(error::success, {});
}
+// validation
+// ----------------------------------------------------------------------------
+
+code chaser_transaction::validate(size_t& index,
+ const transaction_cptrs& txs) NOEXCEPT
+{
+ index = zero;
+ if (txs.empty())
+ return error::empty_package;
+
+ if (const auto ec = block::populate(txs, pool_, false))
+ return ec;
+
+ for (; index < txs.size(); ++index)
+ if (const auto ec = validate(*txs.at(index)))
+ return ec;
+
+ return {};
+}
+
+code chaser_transaction::validate(const chain::transaction& tx) NOEXCEPT
+{
+ code ec{};
+
+ // Ensure tx does not violate tx consensus rules.
+ if (!ec) ec = tx.check();
+ if (!ec) ec = tx.check(pool_);
+ if (!ec) archive().populate_with_metadata(tx, true);
+ if (!ec) ec = tx.accept(pool_);
+ if (!ec) ec = tx.confirm(pool_);
+ if (!ec) ec = tx.connect(pool_);
+
+ // Ensure tx does not violate presumed block consensus rules.
+ // This is a DoS guard when validating a tx outside of a block.
+ if (!ec) ec = tx.check_guard();
+ if (!ec) ec = tx.check_guard(pool_);
+ if (!ec) ec = tx.accept_guard(pool_);
+ return ec;
+}
+
+BC_POP_WARNING()
BC_POP_WARNING()
} // namespace node
diff --git a/src/error.cpp b/src/error.cpp
index 80953428..00fca068 100644
--- a/src/error.cpp
+++ b/src/error.cpp
@@ -49,6 +49,10 @@ DEFINE_ERROR_T_MESSAGE_MAP(error)
{ duplicate_block, "duplicate block" },
{ duplicate_header, "duplicate header" },
+ // transaction pool
+ { pooling_disabled, "pooling disabled" },
+ { empty_package, "empty package" },
+
// fee estimation
{ estimate_disabled, "estimate_disabled" },
{ estimate_premature, "estimate_premature" },
@@ -95,6 +99,7 @@ DEFINE_ERROR_T_MESSAGE_MAP(error)
{ confirm10, "confirm10" },
{ confirm11, "confirm11" },
{ confirm12, "confirm12" },
+ { transaction1, "transaction1" },
{ estimates_initialize, "estimates_initialize" },
{ estimates_push1, "estimates_push1" },
{ estimates_push2, "estimates_push2" },
diff --git a/src/full_node.cpp b/src/full_node.cpp
index 315c587d..3312fcd5 100644
--- a/src/full_node.cpp
+++ b/src/full_node.cpp
@@ -183,6 +183,12 @@ void full_node::prioritize(const system::hash_digest& hash,
chaser_block_.prioritize(hash, std::move(handler));
}
+void full_node::submit(const system::chain::transactions_cptr& txs, bool test,
+ submit_handler&& handler) NOEXCEPT
+{
+ chaser_transaction_.submit(txs, test, std::move(handler));
+}
+
void full_node::get_hashes(map_handler&& handler) NOEXCEPT
{
chaser_check_.get_hashes(std::move(handler));
diff --git a/src/protocols/protocol.cpp b/src/protocols/protocol.cpp
index 99dad0f2..7eaa3c41 100644
--- a/src/protocols/protocol.cpp
+++ b/src/protocols/protocol.cpp
@@ -139,6 +139,12 @@ void protocol::prioritize(const system::hash_digest& hash,
session_->prioritize(hash, std::move(handler));
}
+void protocol::submit(const system::chain::transactions_cptr& txs, bool test,
+ submit_handler&& handler) NOEXCEPT
+{
+ session_->submit(txs, test, std::move(handler));
+}
+
void protocol::subscribe_chase(event_notifier&& handler) NOEXCEPT
{
// This is a shared instance multiply-derived from network::protocol.
diff --git a/src/protocols/protocol_transaction_out_106.cpp b/src/protocols/protocol_transaction_out_106.cpp
index ca0faabb..4ea50d1c 100644
--- a/src/protocols/protocol_transaction_out_106.cpp
+++ b/src/protocols/protocol_transaction_out_106.cpp
@@ -18,7 +18,6 @@
*/
#include
-#include
#include
namespace libbitcoin {
@@ -47,7 +46,6 @@ void protocol_transaction_out_106::start() NOEXCEPT
// Events subscription is asynchronous, events may be missed.
subscribe_chase(BIND(handle_chase, _1, _2, _3));
- SUBSCRIBE_BROADCAST(transaction, handle_broadcast_transaction, _1, _2, _3);
SUBSCRIBE_CHANNEL(get_data, handle_receive_get_data, _1, _2);
protocol_peer::start();
}
@@ -58,8 +56,6 @@ void protocol_transaction_out_106::stopping(const code& ec) NOEXCEPT
// Unsubscriber race is ok.
unsubscribe_chase();
-
- UNSUBSCRIBE_BROADCAST();
protocol_peer::stopping(ec);
}
@@ -106,26 +102,6 @@ bool protocol_transaction_out_106::do_announce(transaction_t link) NOEXCEPT
return announce(archive().get_tx_key(link));
}
-bool protocol_transaction_out_106::handle_broadcast_transaction(const code& ec,
- const transaction::cptr& message, uint64_t sender) NOEXCEPT
-{
- BC_ASSERT(stranded());
-
- if (stopped(ec))
- return false;
-
- if (sender == identifier())
- return true;
-
- const auto& tx = message->transaction_ptr;
- const auto hash = tx->hash(false);
- if (was_announced(hash))
- return true;
-
- retain(hash, tx);
- return announce(hash);
-}
-
bool protocol_transaction_out_106::announce(const hash_digest& hash) NOEXCEPT
{
BC_ASSERT(stranded());
@@ -146,45 +122,6 @@ bool protocol_transaction_out_106::announce(const hash_digest& hash) NOEXCEPT
return true;
}
-// Retention.
-// ----------------------------------------------------------------------------
-
-void protocol_transaction_out_106::retain(const hash_digest& hash,
- const chain::transaction::cptr& tx) NOEXCEPT
-{
- BC_ASSERT(stranded());
-
- if (find(hash) != broadcast_.end())
- return;
-
- broadcast_.push_back({ hash, tx });
-}
-
-chain::transaction::cptr protocol_transaction_out_106::release(
- const hash_digest& hash) NOEXCEPT
-{
- BC_ASSERT(stranded());
-
- const auto it = find(hash);
- if (it == broadcast_.end())
- return {};
-
- const auto tx = it->second;
- broadcast_.erase(it);
- return tx;
-}
-
-protocol_transaction_out_106::retained_txs::iterator
-protocol_transaction_out_106::find(const hash_digest& hash) NOEXCEPT
-{
- const auto match = [&hash](const auto& entry) NOEXCEPT
- {
- return entry.first == hash;
- };
-
- return std::find_if(broadcast_.begin(), broadcast_.end(), match);
-}
-
// Inbound (get_data).
// ----------------------------------------------------------------------------
@@ -238,13 +175,6 @@ void protocol_transaction_out_106::send_transaction(const code& ec,
return;
}
- // A broadcast tx is not archived, so is served from retention, once.
- if (const auto retained = release(item.hash))
- {
- SEND(transaction{ retained }, send_transaction, _1, add1(index), message);
- return;
- }
-
// Tx could be always queried with witness and therefore safely cached.
// If can then be serialized according to channel configuration, however
// that is currently fixed to witness as available in the object.
diff --git a/src/sessions/session.cpp b/src/sessions/session.cpp
index 9643c009..a01275ec 100644
--- a/src/sessions/session.cpp
+++ b/src/sessions/session.cpp
@@ -57,6 +57,12 @@ void session::prioritize(const hash_digest& hash,
node_.prioritize(hash, std::move(handler));
}
+void session::submit(const transactions_cptr& txs, bool test,
+ submit_handler&& handler) NOEXCEPT
+{
+ node_.submit(txs, test, std::move(handler));
+}
+
void session::get_hashes(map_handler&& handler) NOEXCEPT
{
node_.get_hashes(std::move(handler));
diff --git a/src/validate.cpp b/src/validate.cpp
deleted file mode 100644
index e84ba92e..00000000
--- a/src/validate.cpp
+++ /dev/null
@@ -1,50 +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 {
-
-using namespace system;
-
-code validate_transaction(const chain::transaction& tx, const query& query,
- const chain::context& pool) NOEXCEPT
-{
- code ec{};
-
- // Ensure tx does not violate tx consensus rules.
- if (!ec) ec = tx.check();
- if (!ec) ec = tx.check(pool);
- if (!ec) query.populate_with_metadata(tx, true);
- if (!ec) ec = tx.accept(pool);
- if (!ec) ec = tx.confirm(pool);
- if (!ec) ec = tx.connect(pool);
-
- // Ensure tx does not violate presumed block consensus rules.
- // This is a DoS guard when validating a tx outside of a block.
- if (!ec) ec = tx.check_guard();
- if (!ec) ec = tx.check_guard(pool);
- if (!ec) ec = tx.accept_guard(pool);
- return ec;
-}
-
-} // namespace node
-} // namespace libbitcoin