Skip to content

Commit

Permalink
Pass allocator to block shared_ptr constructions.
Browse files Browse the repository at this point in the history
  • Loading branch information
evoskuil committed Aug 18, 2024
1 parent 5938210 commit 831c7dc
Show file tree
Hide file tree
Showing 7 changed files with 44 additions and 42 deletions.
20 changes: 20 additions & 0 deletions include/bitcoin/system/allocator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,26 @@ inline bool operator==(const allocator<Left>& left,

using byte_allocator = allocator<uint8_t>;

#define CREATE(Type, allocate, ...) \
allocate.new_object<Type>(__VA_ARGS__), allocate.deleter<Type>(), allocate
#define POINTER(Type, allocate, ptr) \
ptr, allocate.deleter<Type>(), allocate
#define INPLACE(ptr, Type, allocate, ...) \
allocate.construct<std::shared_ptr<const Type>>(ptr, __VA_ARGS__, \
allocate.deleter<Type>(), allocate)

// TODO: replace above macros with parameter pack expansion.
////template <typename Type, typename Allocator, typename... Args>
////auto shared_ptr(Allocator allocator, Args&&... args) NOEXCEPT
////{
//// return std::make_tuple
//// (
//// allocator.new_object<Type>(std::forward<Args>(args)...),
//// allocator.deleter<Type>(),
//// allocator
//// );
////}

} // namespace libbitcoin

#endif
15 changes: 6 additions & 9 deletions src/chain/block.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ BC_PUSH_WARNING(NO_UNGUARDED_POINTERS)
// ----------------------------------------------------------------------------

block::block() NOEXCEPT
: block(to_shared<chain::header>(), to_shared<chain::transaction_cptrs>(),
: block(to_shared<chain::header>(), to_shared<transaction_cptrs>(),
false)
{
}
Expand All @@ -67,7 +67,7 @@ block::block(const chain::header& header,
}

block::block(const chain::header::cptr& header,
const chain::transactions_cptr& txs) NOEXCEPT
const transactions_cptr& txs) NOEXCEPT
: block(header ? header : to_shared<chain::header>(),
txs ? txs : to_shared<transaction_cptrs>(), true)
{
Expand Down Expand Up @@ -104,17 +104,15 @@ block::block(reader&& source, bool witness) NOEXCEPT
}

block::block(reader& source, bool witness) NOEXCEPT
: header_(source.get_allocator().new_object<chain::header>(source),
source.get_allocator().deleter<chain::header>()),
txs_(source.get_allocator().new_object<transaction_cptrs>(),
source.get_allocator().deleter<transaction_cptrs>())
: header_(CREATE(chain::header, source.get_allocator(), source)),
txs_(CREATE(transaction_cptrs, source.get_allocator()))
{
assign_data(source, witness);
}

// protected
block::block(const chain::header::cptr& header,
const chain::transactions_cptr& txs, bool valid) NOEXCEPT
const transactions_cptr& txs, bool valid) NOEXCEPT
: header_(header),
txs_(txs),
valid_(valid),
Expand Down Expand Up @@ -148,8 +146,7 @@ void block::assign_data(reader& source, bool witness) NOEXCEPT
txs->reserve(count);

for (size_t tx = 0; tx < count; ++tx)
txs->emplace_back(allocator.new_object<transaction>(source, witness),
allocator.deleter<transaction>());
txs->emplace_back(CREATE(transaction, allocator, source, witness));

size_ = serialized_size(*txs_);
valid_ = source;
Expand Down
13 changes: 4 additions & 9 deletions src/chain/input.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -176,11 +176,9 @@ input::input(reader&& source) NOEXCEPT

// Witness is deserialized and assigned by transaction.
input::input(reader& source) NOEXCEPT
: point_(source.get_allocator().new_object<chain::point>(source),
source.get_allocator().deleter<chain::point>()),
script_(source.get_allocator().new_object<chain::script>(source, true),
source.get_allocator().deleter<chain::script>()),
witness_(nullptr),
: point_(CREATE(chain::point, source.get_allocator(), source)),
script_(CREATE(chain::script, source.get_allocator(), source, true)),
witness_(CREATE(chain::witness, source.get_allocator())),
sequence_(source.read_4_bytes_little_endian()),
valid_(source),
size_(serialized_size(*script_))
Expand Down Expand Up @@ -303,10 +301,7 @@ size_t input::witnessed_size() const NOEXCEPT
void input::set_witness(reader& source) NOEXCEPT
{
auto& allocator = source.get_allocator();

witness_.reset(allocator.new_object<chain::witness>(source, true),
allocator.deleter<chain::witness>());

witness_.reset(CREATE(chain::witness, allocator, source, true));
size_.witnessed = ceilinged_add(size_.nominal,
witness_->serialized_size(true));
}
Expand Down
8 changes: 3 additions & 5 deletions src/chain/operation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ void operation::assign_data(reader& source) NOEXCEPT
// Guard against resetting a previously-invalid stream.
if (!source)
{
allocator.construct<chunk_cptr>(&data_, nullptr);
INPLACE(&data_, data_chunk, allocator, nullptr);
return;
}

Expand All @@ -221,9 +221,7 @@ void operation::assign_data(reader& source) NOEXCEPT
source.invalidate();

// An invalid source.read_bytes_raw returns nullptr.
allocator.construct<chunk_cptr>(&data_, source.read_bytes_raw(size),
allocator.deleter<data_chunk>());

INPLACE(&data_, data_chunk, allocator, source.read_bytes_raw(size));
underflow_ = !source;

// This requires that provided stream terminates at the end of the script.
Expand All @@ -236,7 +234,7 @@ void operation::assign_data(reader& source) NOEXCEPT
{
code_ = any_invalid;
source.set_position(start);
data_ = to_shared(source.read_bytes());
data_.reset(POINTER(data_chunk, allocator, source.read_bytes_raw()));
}

// All byte vectors are deserializable, stream indicates own failure.
Expand Down
3 changes: 1 addition & 2 deletions src/chain/output.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,7 @@ output::output(reader&& source) NOEXCEPT

output::output(reader& source) NOEXCEPT
: value_(source.read_8_bytes_little_endian()),
script_(source.get_allocator().new_object<chain::script>(source, true),
source.get_allocator().deleter<chain::script>()),
script_(CREATE(chain::script, source.get_allocator(), source, true)),
valid_(source),
size_(serialized_size(*script_, value_))
{
Expand Down
19 changes: 6 additions & 13 deletions src/chain/transaction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,10 +131,8 @@ transaction::transaction(reader&& source, bool witness) NOEXCEPT

transaction::transaction(reader& source, bool witness) NOEXCEPT
: version_(source.read_4_bytes_little_endian()),
inputs_(source.get_allocator().new_object<input_cptrs>(),
source.get_allocator().deleter<input_cptrs>()),
outputs_(source.get_allocator().new_object<output_cptrs>(),
source.get_allocator().deleter<output_cptrs>())
inputs_(CREATE(input_cptrs, source.get_allocator())),
outputs_(CREATE(output_cptrs, source.get_allocator()))
{
assign_data(source, witness);
}
Expand Down Expand Up @@ -184,9 +182,7 @@ void transaction::assign_data(reader& source, bool witness) NOEXCEPT
auto count = source.read_size(max_block_size);
ins->reserve(count);
for (size_t in = 0; in < count; ++in)
ins->emplace_back(
allocator.new_object<input>(source),
allocator.deleter<input>());
ins->emplace_back(CREATE(input, allocator, source));

// Expensive repeated recomputation, so cache segregated state.
// Detect witness as no inputs (marker) and expected flag (bip144).
Expand All @@ -202,15 +198,13 @@ void transaction::assign_data(reader& source, bool witness) NOEXCEPT
count = source.read_size(max_block_size);
ins->reserve(count);
for (size_t in = 0; in < count; ++in)
ins->emplace_back(allocator.new_object<input>(source),
allocator.deleter<input>());
ins->emplace_back(CREATE(input, allocator, source));

auto outs = to_non_const_raw_ptr(outputs_);
count = source.read_size(max_block_size);
outs->reserve(count);
for (size_t out = 0; out < count; ++out)
outs->emplace_back(allocator.new_object<output>(source),
allocator.deleter<output>());
outs->emplace_back(CREATE(output, allocator, source));

// Read or skip witnesses as specified.
if (witness)
Expand All @@ -231,8 +225,7 @@ void transaction::assign_data(reader& source, bool witness) NOEXCEPT
count = source.read_size(max_block_size);
outs->reserve(count);
for (size_t out = 0; out < count; ++out)
outs->emplace_back(allocator.new_object<output>(source),
allocator.deleter<output>());
outs->emplace_back(CREATE(output, allocator, source));
}

locktime_ = source.read_4_bytes_little_endian();
Expand Down
8 changes: 4 additions & 4 deletions src/chain/witness.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -177,8 +177,8 @@ void witness::assign_data(reader& source, bool prefix) NOEXCEPT
for (size_t element = 0; element < count; ++element)
{
const auto size = source.read_size(max_block_weight);
stack_.emplace_back(source.read_bytes_raw(size),
allocator.deleter<data_chunk>());
stack_.emplace_back(POINTER(data_chunk, allocator,
source.read_bytes_raw(size)));
size_ = element_size(size_, stack_.back());
}
}
Expand All @@ -187,8 +187,8 @@ void witness::assign_data(reader& source, bool prefix) NOEXCEPT
while (!source.is_exhausted())
{
const auto size = source.read_size(max_block_weight);
stack_.emplace_back(source.read_bytes_raw(size),
allocator.deleter<data_chunk>());
stack_.emplace_back(POINTER(data_chunk, allocator,
source.read_bytes_raw(size)));
size_ = element_size(size_, stack_.back());
}
}
Expand Down

0 comments on commit 831c7dc

Please sign in to comment.