@@ -199,81 +199,34 @@ code CLASS::unspent_duplicates(const header_link& link,
199199
200200// protected
201201TEMPLATE
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-
277230TEMPLATE
278231code CLASS::get_double_spenders (tx_links& out,
279232 const block& block) const NOEXCEPT
0 commit comments