Skip to content

Commit aef40bf

Browse files
committed
Merge coinbase flag into tx.heavy table field.
1 parent f17bcba commit aef40bf

4 files changed

Lines changed: 654 additions & 637 deletions

File tree

include/bitcoin/database/tables/archives/transaction.hpp

Lines changed: 40 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,6 @@ namespace libbitcoin {
2929
namespace database {
3030
namespace table {
3131

32-
// TODO: merge coinbase bit (saves about 1GB).
33-
3432
/// Transaction is a canonical record hash table.
3533
struct transaction
3634
: public hash_map<schema::transaction>
@@ -39,13 +37,17 @@ struct transaction
3937
using outs = schema::outs::link;
4038
using out = schema::output::link;
4139
using ix = linkage<schema::index>;
42-
using bytes = linkage<schema::size>;
40+
using bytes = linkage<schema::size, sub1(to_bits(schema::size))>;
4341
using hash_map<schema::transaction>::hashmap;
42+
static constexpr auto offset = bytes::bits;
43+
static_assert(offset < to_bits(bytes::size));
4444

45-
static constexpr size_t skip_to_version =
46-
schema::bit +
47-
bytes::size +
45+
static constexpr size_t skip_to_locktime =
4846
bytes::size +
47+
bytes::size;
48+
49+
static constexpr size_t skip_to_version =
50+
skip_to_locktime +
4951
sizeof(uint32_t);
5052

5153
static constexpr size_t skip_to_ins =
@@ -56,13 +58,31 @@ struct transaction
5658
skip_to_ins +
5759
ix::size;
5860

61+
static constexpr bytes::integer merge(bool is_coinbase,
62+
bytes::integer light) NOEXCEPT
63+
{
64+
BC_ASSERT_MSG(!system::get_right(light, offset), "overflow");
65+
return system::set_right(light, offset, is_coinbase);
66+
}
67+
68+
static constexpr bool is_coinbase(bytes::integer merged) NOEXCEPT
69+
{
70+
return system::get_right(merged, offset);
71+
}
72+
73+
static constexpr bytes::integer to_light(bytes::integer merged) NOEXCEPT
74+
{
75+
return system::set_right(merged, offset, false);
76+
}
77+
5978
struct record
6079
: public schema::transaction
6180
{
6281
inline bool from_data(reader& source) NOEXCEPT
6382
{
64-
coinbase = to_bool(source.read_byte());
65-
light = source.read_little_endian<bytes::integer, bytes::size>();
83+
const auto merged = source.read_little_endian<bytes::integer, bytes::size>();
84+
coinbase = is_coinbase(merged);
85+
light = to_light(merged);
6686
heavy = source.read_little_endian<bytes::integer, bytes::size>();
6787
locktime = source.read_little_endian<uint32_t>();
6888
version = source.read_little_endian<uint32_t>();
@@ -76,8 +96,7 @@ struct transaction
7696

7797
inline bool to_data(finalizer& sink) const NOEXCEPT
7898
{
79-
sink.write_byte(to_int<uint8_t>(coinbase));
80-
sink.write_little_endian<bytes::integer, bytes::size>(light);
99+
sink.write_little_endian<bytes::integer, bytes::size>(merge(coinbase, light));
81100
sink.write_little_endian<bytes::integer, bytes::size>(heavy);
82101
sink.write_little_endian<uint32_t>(locktime);
83102
sink.write_little_endian<uint32_t>(version);
@@ -103,8 +122,8 @@ struct transaction
103122
}
104123

105124
bool coinbase{};
106-
bytes::integer light{}; // tx.serialized_size(false)
107-
bytes::integer heavy{}; // tx.serialized_size(true)
125+
bytes::integer light{};
126+
bytes::integer heavy{};
108127
uint32_t locktime{};
109128
uint32_t version{};
110129
ix::integer ins_count{};
@@ -118,12 +137,7 @@ struct transaction
118137
{
119138
inline bool from_data(reader& source) NOEXCEPT
120139
{
121-
static constexpr size_t skip_size =
122-
schema::bit +
123-
bytes::size +
124-
bytes::size;
125-
126-
source.skip_bytes(skip_size);
140+
source.skip_bytes(skip_to_locktime);
127141
locktime = source.read_little_endian<uint32_t>();
128142
version = source.read_little_endian<uint32_t>();
129143
ins_count = source.read_little_endian<ix::integer, ix::size>();
@@ -148,13 +162,12 @@ struct transaction
148162
inline bool to_data(finalizer& sink) const NOEXCEPT
149163
{
150164
using namespace system;
151-
const auto light = possible_narrow_cast<bytes::integer>(
152-
tx.serialized_size(false));
153-
const auto heavy = possible_narrow_cast<bytes::integer>
154-
(tx.serialized_size(true));
155-
156-
sink.write_byte(to_int<uint8_t>(tx.is_coinbase()));
157-
sink.write_little_endian<bytes::integer, bytes::size>(light);
165+
const auto coinbase = tx.is_coinbase();
166+
const auto light_ = tx.serialized_size(false);
167+
const auto heavy_ = tx.serialized_size(true);
168+
const auto light = possible_narrow_cast<bytes::integer>(light_);
169+
const auto heavy = possible_narrow_cast<bytes::integer>(heavy_);
170+
sink.write_little_endian<bytes::integer, bytes::size>(merge(coinbase, light));
158171
sink.write_little_endian<bytes::integer, bytes::size>(heavy);
159172
sink.write_little_endian<uint32_t>(tx.locktime());
160173
sink.write_little_endian<uint32_t>(tx.version());
@@ -304,7 +317,7 @@ struct transaction
304317
{
305318
inline bool from_data(reader& source) NOEXCEPT
306319
{
307-
coinbase = to_bool(source.read_byte());
320+
coinbase = is_coinbase(source.read_little_endian<bytes::integer, bytes::size>());
308321
return source;
309322
}
310323

@@ -316,8 +329,7 @@ struct transaction
316329
{
317330
inline bool from_data(reader& source) NOEXCEPT
318331
{
319-
source.skip_byte();
320-
light = source.read_little_endian<bytes::integer, bytes::size>();
332+
light = to_light(source.read_little_endian<bytes::integer, bytes::size>());
321333
heavy = source.read_little_endian<bytes::integer, bytes::size>();
322334
return source;
323335
}

include/bitcoin/database/tables/schema.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ struct transaction
9595
using link = linkage<pk, sub1(to_bits(pk))>; // reduced for prevout merge.
9696
using key = system::data_array<sk>;
9797
static constexpr size_t minsize =
98-
schema::bit + // coinbase [TODO: merge into light]
98+
////schema::bit + // coinbase (merged into light)
9999
schema::size + // light
100100
schema::size + // heavy
101101
sizeof(uint32_t) + // locktime
@@ -108,8 +108,8 @@ struct transaction
108108
static constexpr size_t size = minsize;
109109
static constexpr size_t cell = link::size;
110110
static constexpr link count() NOEXCEPT { return 1; }
111-
static_assert(minsize == 29u);
112-
static_assert(minrow == 65u);
111+
static_assert(minsize == 28u);
112+
static_assert(minrow == 64u);
113113
static_assert(link::size == 4u);
114114
static_assert(cell == 4u);
115115
};

0 commit comments

Comments
 (0)