Skip to content

Commit f50f726

Browse files
authored
Merge pull request #571 from evoskuil/master
Move spend index to point table and delete spend table.
2 parents a02507c + b7438e2 commit f50f726

27 files changed

Lines changed: 309 additions & 567 deletions

include/bitcoin/database/error.hpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,6 @@ enum error_t : uint8_t
116116
/// tx archive
117117
tx_empty,
118118
tx_tx_allocate,
119-
tx_spend_allocate,
120119
tx_input_put,
121120
tx_point_allocate,
122121
tx_point_put,
@@ -125,7 +124,6 @@ enum error_t : uint8_t
125124
tx_output_put,
126125
tx_puts_put,
127126
tx_tx_set,
128-
tx_spend_put,
129127
tx_address_allocate,
130128
tx_address_put,
131129
tx_tx_commit,

include/bitcoin/database/impl/query/archive_read.ipp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -112,23 +112,23 @@ inline hash_digest CLASS::get_tx_key(const tx_link& link) const NOEXCEPT
112112
}
113113

114114
TEMPLATE
115-
inline hash_digest CLASS::get_point_key(const point_link& link) const NOEXCEPT
115+
inline point_key CLASS::get_point_key(const point_link& link) const NOEXCEPT
116116
{
117-
table::point::record point{};
117+
table::point::get_composed point{};
118118
if (!store_.point.get(link, point))
119119
return {};
120120

121-
return point.hash;
121+
return point.key;
122122
}
123123

124124
TEMPLATE
125-
inline spend_key CLASS::get_spend_key(const spend_link& link) const NOEXCEPT
125+
inline hash_digest CLASS::get_point_hash(const point_link& link) const NOEXCEPT
126126
{
127-
table::spend::get_key spend{};
128-
if (!store_.spend.get(link, spend))
127+
table::point::record point{};
128+
if (!store_.point.get(link, point))
129129
return {};
130130

131-
return spend.key;
131+
return point.hash;
132132
}
133133

134134
// False implies not confirmed.

include/bitcoin/database/impl/query/archive_write.ipp

Lines changed: 15 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ code CLASS::set_code(tx_link& tx_fk, const transaction& tx) NOEXCEPT
122122
// Commit input and ins|point records.
123123
for (const auto& in: *ins)
124124
{
125+
// TODO: preallocate (requires input sizes).
125126
input_link input_fk{};
126127
if (!store_.input.put_link(input_fk, table::input::put_ref
127128
{
@@ -132,28 +133,19 @@ code CLASS::set_code(tx_link& tx_fk, const transaction& tx) NOEXCEPT
132133
return error::tx_input_put;
133134
}
134135

135-
if (!store_.ins.put(point_it, table::ins::record
136+
if (!store_.ins.put(point_it++, table::ins::record
136137
{
137138
{},
138-
in->point().index(),
139139
in->sequence(),
140140
input_fk,
141141
tx_fk
142142
}))
143143
{
144144
return error::tx_ins_put;
145145
}
146-
147-
if (!store_.point.put(point_it++, table::point::record_ref
148-
{
149-
{},
150-
in->point().hash()
151-
}))
152-
{
153-
return error::tx_point_put;
154-
}
155146
}
156147

148+
// TODO: preallocate (requires output sizes).
157149
// Commit output records.
158150
for (const auto& out: *outs)
159151
{
@@ -177,8 +169,19 @@ code CLASS::set_code(tx_link& tx_fk, const transaction& tx) NOEXCEPT
177169
if (puts_fk.is_terminal())
178170
return error::tx_puts_put;
179171

172+
// Commit accumulated points.
173+
point_it = point_fk;
174+
for (const auto& in: *ins)
175+
{
176+
const auto key = table::point::compose(in->point());
177+
if (!store_.point.put(point_it++, key, table::point::record{}))
178+
{
179+
return error::tx_point_put;
180+
}
181+
}
182+
180183
// Create tx record.
181-
// Commit is deferred for spend/address index consistency.
184+
// Commit is deferred for point/address index consistency.
182185
if (!store_.tx.set(tx_fk, table::transaction::record_put_ref
183186
{
184187
{},
@@ -192,30 +195,6 @@ code CLASS::set_code(tx_link& tx_fk, const transaction& tx) NOEXCEPT
192195
return error::tx_tx_set;
193196
}
194197

195-
// Commit spend index records.
196-
if (!tx.is_coinbase())
197-
{
198-
auto sp_fk = store_.spend.allocate(inputs);
199-
if (sp_fk.is_terminal())
200-
return error::tx_spend_allocate;
201-
202-
auto in = ins->begin();
203-
const auto ptr = store_.spend.get_memory();
204-
205-
for (auto pt_fk = point_fk; pt_fk < (point_fk + inputs); ++pt_fk)
206-
{
207-
const auto key = table::spend::compose((*in++)->point());
208-
if (!store_.spend.put(ptr, sp_fk++, key, table::spend::record
209-
{
210-
{},
211-
pt_fk
212-
}))
213-
{
214-
return error::tx_spend_put;
215-
}
216-
}
217-
}
218-
219198
// Commit address index records.
220199
if (address_enabled())
221200
{

include/bitcoin/database/impl/query/confirm.ipp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ bool CLASS::is_confirmed_tx(const tx_link& link) const NOEXCEPT
7373
}
7474

7575
TEMPLATE
76-
bool CLASS::is_confirmed_input(const spend_link& link) const NOEXCEPT
76+
bool CLASS::is_confirmed_input(const point_link& link) const NOEXCEPT
7777
{
7878
// The spend.tx is strong *and* its block is confirmed (by height).
7979
const auto fk = to_spending_tx(link);
@@ -132,7 +132,7 @@ bool CLASS::is_strong_block(const header_link& link) const NOEXCEPT
132132

133133
// unused
134134
TEMPLATE
135-
bool CLASS::is_strong_spend(const spend_link& link) const NOEXCEPT
135+
bool CLASS::is_strong_spend(const point_link& link) const NOEXCEPT
136136
{
137137
return is_strong_tx(to_spending_tx(link));
138138
}
@@ -141,7 +141,7 @@ bool CLASS::is_strong_spend(const spend_link& link) const NOEXCEPT
141141
TEMPLATE
142142
bool CLASS::is_mature(const point_link& link, size_t height) const NOEXCEPT
143143
{
144-
const auto key = get_point_key(link);
144+
const auto key = get_point_hash(link);
145145
if (key == system::null_hash)
146146
return true;
147147

@@ -189,7 +189,7 @@ code CLASS::locked_prevout(const point_link& link, uint32_t sequence,
189189

190190
// Get hash from point, search for prevout tx and get its link.
191191
table::transaction::get_version tx{};
192-
const auto tx_fk = store_.tx.find(get_point_key(link), tx);
192+
const auto tx_fk = store_.tx.find(get_point_hash(link), tx);
193193
if (tx_fk.is_terminal())
194194
return error::missing_previous_output;
195195

include/bitcoin/database/impl/query/consensus.ipp

Lines changed: 10 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -199,81 +199,34 @@ code CLASS::unspent_duplicates(const header_link& link,
199199

200200
// protected
201201
TEMPLATE
202-
code CLASS::get_conflicts(point_links& points, const point& point,
202+
code CLASS::push_spenders(tx_links& out, const point& point,
203203
const point_link& self) const NOEXCEPT
204204
{
205-
// Iterate to all matching spend table keys. Since these are stubs of the
206-
// full tx hash there will be false positives at the rate of the original
207-
// "foreign point" indexation. This means two sets of conflicts, first the
208-
// spend table and then the stubs. But this dramatically reduces paging in
209-
// the double spend search. The spend table load controls for primary but
210-
// not secondary conflicts. Reducing secondary conflicts requires increase
211-
// to the stub hash portion of the spend key. Given that the spend key has
212-
// two parts (stub|index) there is never a secondary conflict produced by
213-
// the existence of multiple spends of outputs in the same transaction.
214-
auto it = store_.spend.it(table::spend::compose(point));
205+
auto it = store_.point.it(table::point::compose(point));
215206
if (!it)
216207
return error::integrity4;
217208

209+
point_links points{};
218210
do
219211
{
220-
table::spend::record get{};
221-
if (!store_.spend.get(it, get))
222-
return error::integrity5;
223-
224-
if (get.point_fk != self)
225-
points.push_back(get.point_fk);
212+
if (it.self() != self)
213+
points.push_back(it.self());
226214
}
227215
while (it.advance());
228-
return error::success;
229-
}
230-
231-
// protected
232-
TEMPLATE
233-
code CLASS::push_doubles(tx_links& out, const point& point,
234-
const point_links& points) const NOEXCEPT
235-
{
236-
if (points.empty())
237-
return error::success;
216+
it.reset();
238217

239-
// The expected self spend and primary conflicts are removed. This serves
240-
// to remove secondary conflicts, leaving only actual additional spends.
241-
auto ptr = store_.point.get_memory();
242218
for (auto link: points)
243219
{
244-
table::point::record get{};
245-
if (!store_.point.get(ptr, link, get))
246-
return error::integrity6;
247-
248-
// Extremely rare, normally implies a duplicate tx.
249-
if (get.hash == point.hash())
250-
{
251-
ptr.reset();
252-
table::ins::get_parent ins{};
253-
if (!store_.ins.get(link, ins))
254-
return error::integrity6;
220+
table::ins::get_parent get{};
221+
if (!store_.ins.get(link, get))
222+
return error::integrity5;
255223

256-
out.push_back(ins.parent_fk);
257-
ptr = store_.point.get_memory();
258-
}
224+
out.push_back(get.parent_fk);
259225
}
260226

261227
return error::success;
262228
}
263229

264-
// protected
265-
TEMPLATE
266-
code CLASS::push_spenders(tx_links& out, const point& point,
267-
const point_link& self) const NOEXCEPT
268-
{
269-
code ec{};
270-
point_links points{};
271-
if ((ec = get_conflicts(points, point, self)))
272-
return ec;
273-
274-
return push_doubles(out, point, points);
275-
}
276-
277230
TEMPLATE
278231
code CLASS::get_double_spenders(tx_links& out,
279232
const block& block) const NOEXCEPT

include/bitcoin/database/impl/query/extent.ipp

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,6 @@ size_t CLASS::archive_body_size() const NOEXCEPT
9595
+ point_body_size()
9696
+ ins_body_size()
9797
+ puts_body_size()
98-
+ spend_body_size()
9998
+ txs_body_size()
10099
+ tx_body_size();
101100
}
@@ -123,7 +122,6 @@ size_t CLASS::archive_head_size() const NOEXCEPT
123122
+ point_head_size()
124123
+ ins_head_size()
125124
+ puts_head_size()
126-
+ spend_head_size()
127125
+ txs_head_size()
128126
+ tx_head_size();
129127
}
@@ -137,7 +135,6 @@ DEFINE_SIZES(input)
137135
DEFINE_SIZES(point)
138136
DEFINE_SIZES(ins)
139137
DEFINE_SIZES(puts)
140-
DEFINE_SIZES(spend)
141138
DEFINE_SIZES(txs)
142139
DEFINE_SIZES(tx)
143140

@@ -154,7 +151,7 @@ DEFINE_SIZES(neutrino)
154151
// ----------------------------------------------------------------------------
155152

156153
DEFINE_BUCKETS(header)
157-
DEFINE_BUCKETS(spend)
154+
DEFINE_BUCKETS(point)
158155
DEFINE_BUCKETS(txs)
159156
DEFINE_BUCKETS(tx)
160157

@@ -173,7 +170,6 @@ DEFINE_RECORDS(tx)
173170
DEFINE_RECORDS(point)
174171
DEFINE_RECORDS(ins)
175172
DEFINE_RECORDS(puts)
176-
DEFINE_RECORDS(spend)
177173

178174
DEFINE_RECORDS(candidate)
179175
DEFINE_RECORDS(confirmed)

include/bitcoin/database/impl/query/objects.ipp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ typename CLASS::input::cptr CLASS::get_input(
231231

232232
const auto ptr = to_shared<input>
233233
(
234-
make_point(std::move(point.hash), ins.index),
234+
make_point(std::move(point.hash), point.index),
235235
in.script,
236236
in.witness,
237237
ins.sequence

0 commit comments

Comments
 (0)