Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions include/bitcoin/network/boost.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,13 @@
// Must pull in any base boost configuration before including boost.
#include <bitcoin/system.hpp>

// MSVC false positive in boost.optional 1.91.0.
BC_PUSH_WARNING(UNREACHABLE_CODE)
#include <boost/bimap.hpp>
#include <boost/bimap/set_of.hpp>
#include <boost/bimap/multiset_of.hpp>
BC_POP_WARNING()

#include <boost/circular_buffer.hpp>
#include <boost/system/error_code.hpp>

Expand Down
8 changes: 4 additions & 4 deletions include/bitcoin/network/interfaces/peer_dispatch.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,15 +86,15 @@ struct peer_dispatch

/// TODO: this moves to peer::body::reader
/// Type-erased implementation of peer::deserialize<Message>.
static inline any_t deserialize(memory& allocator,
messages::peer::identifier identifier, const system::data_chunk& data,
uint32_t version_, bool witness) NOEXCEPT
static inline any_t deserialize(messages::peer::identifier identifier,
const system::data_chunk& data, uint32_t version_,
bool witness) NOEXCEPT
{
switch (identifier)
{
RETURN_DESERIALIZED_PTR(address)
RETURN_DESERIALIZED_PTR(alert)
RETURN_DESERIALIZED_PTR(block, witness, *allocator.get_arena())
RETURN_DESERIALIZED_PTR(block, witness)
RETURN_DESERIALIZED_PTR(bloom_filter_add)
RETURN_DESERIALIZED_PTR(bloom_filter_clear)
RETURN_DESERIALIZED_PTR(bloom_filter_load)
Expand Down
6 changes: 1 addition & 5 deletions include/bitcoin/network/messages/peer/detail/block.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,6 @@ struct BCT_API block
static const uint32_t version_minimum;
static const uint32_t version_maximum;

/// Custom deserializer to accomodate memory allocator (arena).
static cptr deserialize(uint32_t version, const system::data_chunk& data,
bool witness, arena& arena) NOEXCEPT;

static cptr deserialize(uint32_t version, const system::data_chunk& data,
bool witness=true) NOEXCEPT;
static block deserialize(uint32_t version, system::reader& source,
Expand All @@ -55,7 +51,7 @@ struct BCT_API block

size_t size(uint32_t version, bool witness=true) const NOEXCEPT;

system::chain::block::cptr block_ptr;
system::chain::block_view block;
};

} // namespace peer
Expand Down
4 changes: 2 additions & 2 deletions src/channels/channel_peer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -284,8 +284,8 @@ void channel_peer::handle_read_payload(const code& ec, size_t payload_size,
// Notify subscribers of the new message.
///////////////////////////////////////////////////////////////////////////
// TODO: hack, move into peer::body::reader.
if (auto any = interface::deserialize(allocator_, head->id(),
payload_buffer_, negotiated_version(), settings().witness_node()))
if (auto any = interface::deserialize(head->id(), payload_buffer_,
negotiated_version(), settings().witness_node()))
{
// If object passes to another thread destruction cost is very high.
if (const auto code = dispatcher_.notify(rpc::request_t
Expand Down
66 changes: 11 additions & 55 deletions src/messages/peer/detail/block.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@
#include <bitcoin/network/messages/peer/detail/block.hpp>

#include <iterator>
#include <memory>
#include <bitcoin/network/memory.hpp>
#include <bitcoin/network/async/async.hpp>
#include <bitcoin/network/messages/peer/detail/transaction.hpp>
#include <bitcoin/network/messages/peer/enums/identifier.hpp>
#include <bitcoin/network/messages/peer/enums/level.hpp>
Expand All @@ -43,70 +42,29 @@ const uint32_t block::version_maximum = level::maximum_protocol;

// static
typename block::cptr block::deserialize(uint32_t version,
const data_chunk& data, bool witness, arena& arena) NOEXCEPT
const data_chunk& data, bool witness) NOEXCEPT
{
if (version < version_minimum || version > version_maximum)
return {};

// Set starting address of block allocation (nullptr if not detachable).
const auto memory = pointer_cast<uint8_t>(arena.start(data.size()));

istream source{ data };
byte_reader reader{ source, &arena };
auto& allocator = reader.get_allocator();
const auto block = allocator.new_object<chain::block>(reader, witness);

// Destruct block if created but failed to deserialize.
if (!reader && !is_null(block))
byte_allocator::deleter<chain::block>(&arena);

// Release memory if block construction or deserialization failed.
if (!reader || is_null(block))
{
arena.release(memory);
return {};
}

// Cache hashes as extracted from serialized block.
block->set_hashes(data);

// Set size of block allocation owned by memory (zero if non-detachable).
block->set_allocation(arena.detach());

// All block and contained object destructors should be optimized out.
return to_shared<messages::peer::block>(std::shared_ptr<chain::block>(block,
[&arena, memory](auto ptr) NOEXCEPT
{
// Destruct and deallocate objects (nop deallocate if detachable).
byte_allocator::deleter<chain::block>(&arena)(ptr);
const auto message = emplace_shared<messages::peer::block>(
chain::block_view{ move_copy(data), witness });

// Deallocate detached memory (nop if not detachable).
arena.release(memory);
}));
}

// static
typename block::cptr block::deserialize(uint32_t version,
const data_chunk& data, bool witness) NOEXCEPT
{
// default_arena::get() returns pointer to static instance of
// system::default_arena, which is not detachable and calls into
// std::malloc() and std::free() for each individual allocation.
return deserialize(version, data, witness, *default_arena::get());
return message->block.is_valid() ? message : nullptr;
}

// static
block block::deserialize(uint32_t version, reader& source,
bool witness) NOEXCEPT
{
if (version < version_minimum || version > version_maximum)
source.invalidate();
return { chain::block_view{ data_chunk{}, witness } };

return { to_shared<chain::block>(source, witness) };
return { chain::block_view{ source.read_bytes(), witness } };
}

bool block::serialize(uint32_t version,
const system::data_slab& data, bool witness) const NOEXCEPT
bool block::serialize(uint32_t version, const data_slab& data,
bool witness) const NOEXCEPT
{
system::ostream sink{ data };
system::byte_writer writer{ sink };
Expand All @@ -120,15 +78,13 @@ void block::serialize(uint32_t BC_DEBUG_ONLY(version), writer& sink,
BC_DEBUG_ONLY(const auto bytes = size(version, witness);)
BC_DEBUG_ONLY(const auto start = sink.get_write_position();)

if (block_ptr)
block_ptr->to_data(sink, witness);

sink.write_bytes(block.to_data(witness));
BC_ASSERT(sink && (sink.get_write_position() - start) == bytes);
}

size_t block::size(uint32_t, bool witness) const NOEXCEPT
{
return block_ptr ? block_ptr->serialized_size(witness) : zero;
return block.is_valid() ? block.serialized_size(witness) : zero;
}

BC_POP_WARNING()
Expand Down
5 changes: 3 additions & 2 deletions test/messages/peer/detail/block.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,9 @@ BOOST_AUTO_TEST_CASE(block__properties__always__expected)

BOOST_AUTO_TEST_CASE(block__size__default__zero)
{
BOOST_REQUIRE_EQUAL(peer::block{}.size(peer::level::canonical, true), zero);
BOOST_REQUIRE_EQUAL(peer::block{}.size(peer::level::canonical, false), zero);
const peer::block default_block{ { {}, {} } };
BOOST_REQUIRE_EQUAL(default_block.size(peer::level::canonical, true), zero);
BOOST_REQUIRE_EQUAL(default_block.size(peer::level::canonical, false), zero);
}

BOOST_AUTO_TEST_SUITE_END()
Loading