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
147 changes: 34 additions & 113 deletions include/bitcoin/database/impl/query/validate.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ bool CLASS::is_unconfirmable(const header_link& link) const NOEXCEPT
TEMPLATE
code CLASS::get_header_state(const header_link& link) const NOEXCEPT
{
table::validated_bk::slab_get_code valid{};
table::validated_bk::record valid{};
if (!store_.validated_bk.at(to_validated_bk(link), valid))
return error::unvalidated;

Expand All @@ -133,7 +133,7 @@ code CLASS::get_header_state(const header_link& link) const NOEXCEPT
TEMPLATE
code CLASS::get_block_state(const header_link& link) const NOEXCEPT
{
table::validated_bk::slab_get_code valid{};
table::validated_bk::record valid{};
if (!store_.validated_bk.at(to_validated_bk(link), valid))
return is_associated(link) ? error::unvalidated : error::unassociated;

Expand Down Expand Up @@ -305,171 +305,92 @@ bool CLASS::get_context(system::chain::context& ctx,
return true;
}

// Setters.
// set_block_state
// ----------------------------------------------------------------------------

TEMPLATE
bool CLASS::set_block_valid(const header_link& link, uint64_t fees) NOEXCEPT
bool CLASS::set_block_valid(const header_link& link) NOEXCEPT
{
// ========================================================================
const auto scope = store_.get_transactor();

// Clean single allocation failure (e.g. disk full).
return store_.validated_bk.put(to_validated_bk(link),
table::validated_bk::slab
{
{},
schema::block_state::valid,
fees
});
// ========================================================================
return set_block_state(link, schema::block_state::valid);
}

TEMPLATE
bool CLASS::set_block_confirmable(const header_link& link) NOEXCEPT
{
// ========================================================================
const auto scope = store_.get_transactor();

// Clean single allocation failure (e.g. disk full).
return store_.validated_bk.put(to_validated_bk(link),
table::validated_bk::slab
{
{},
schema::block_state::confirmable,
0 // fees
});
// ========================================================================
return set_block_state(link, schema::block_state::confirmable);
}

TEMPLATE
bool CLASS::set_block_unconfirmable(const header_link& link) NOEXCEPT
{
// ========================================================================
const auto scope = store_.get_transactor();

// Clean single allocation failure (e.g. disk full).
return store_.validated_bk.put(to_validated_bk(link),
table::validated_bk::slab
{
{},
schema::block_state::unconfirmable,
0 // fees
});
// ========================================================================
return set_block_state(link, schema::block_state::unconfirmable);
}

TEMPLATE
bool CLASS::set_block_unknown(const header_link& link) NOEXCEPT
{
return set_block_state(link, schema::block_state::block_unknown);
}

// private
TEMPLATE
bool CLASS::set_block_state(const header_link& link,
schema::block_state state) NOEXCEPT
{
const auto record = to_validated_bk(link);

// ========================================================================
const auto scope = store_.get_transactor();

// Clean single allocation failure (e.g. disk full).
return store_.validated_bk.put(to_validated_bk(link),
table::validated_bk::slab
{
{},
schema::block_state::block_unknown,
0 // fees
});
return store_.validated_bk.put(record,
table::validated_bk::record{ {}, state });
// ========================================================================
}

// set_tx_state
// ----------------------------------------------------------------------------

TEMPLATE
bool CLASS::set_tx_unknown(const tx_link& link) NOEXCEPT
{
// ========================================================================
const auto scope = store_.get_transactor();

// Clean single allocation failure (e.g. disk full).
return store_.validated_tx.put(link, table::validated_tx::slab
{
{},
{},
schema::tx_state::tx_unknown,
0, // fee
0 // sigops
});
// ========================================================================
return set_tx_state(link, {}, {}, {}, schema::tx_state::tx_unknown);
}

TEMPLATE
bool CLASS::set_tx_disconnected(const tx_link& link,
const context& ctx) NOEXCEPT
{
// ========================================================================
const auto scope = store_.get_transactor();

// Clean single allocation failure (e.g. disk full).
return store_.validated_tx.put(link, table::validated_tx::slab
{
{},
ctx,
schema::tx_state::disconnected,
0, // fee
0 // sigops
});
// ========================================================================
return set_tx_state(link, ctx, {}, {}, schema::tx_state::disconnected);
}

TEMPLATE
bool CLASS::set_tx_connected(const tx_link& link, const context& ctx,
uint64_t fee, size_t sigops) NOEXCEPT
{
return set_tx_state(link, ctx, fee, sigops, schema::tx_state::connected);
}

// private
TEMPLATE
bool CLASS::set_tx_state(const tx_link& link, const context& ctx,
uint64_t fee, size_t sigops, schema::tx_state state) NOEXCEPT
{
using sigs = linkage<schema::sigops>;
BC_ASSERT(sigops<system::power2<sigs::integer>(to_bits(sigs::size)));

// ========================================================================
const auto scope = store_.get_transactor();
using namespace system;

// Clean single allocation failure (e.g. disk full).
return store_.validated_tx.put(link, table::validated_tx::slab
{
{},
ctx,
schema::tx_state::connected,
fee,
system::possible_narrow_cast<sigs::integer>(sigops)
{}, ctx, state, fee, possible_narrow_cast<sigs::integer>(sigops)
});
// ========================================================================
}

////TEMPLATE
////bool CLASS::set_txs_connected(const header_link& link) NOEXCEPT
////{
//// context ctx{};
//// if (!get_context(ctx, link))
//// return false;
////
//// const auto txs = to_transactions(link);
//// if (txs.empty())
//// return false;
////
//// // FOR PERFORMANCE EVALUATION ONLY.
//// constexpr uint64_t fee = 99;
//// constexpr size_t sigops = 42;
//// using sigs = linkage<schema::sigops>;
////
//// // ========================================================================
//// const auto scope = store_.get_transactor();
////
//// // Clean single allocation failure (e.g. disk full).
//// return std_all_of(bc::seq, txs.begin(), txs.end(),
//// [&](const tx_link& fk) NOEXCEPT
//// {
//// return store_.validated_tx.put(fk, table::validated_tx::slab
//// {
//// {},
//// ctx,
//// schema::tx_state::connected,
//// fee,
//// system::possible_narrow_cast<sigs::integer>(sigops)
//// });
//// });
//// // ========================================================================
////}

} // namespace database
} // namespace libbitcoin

Expand Down
9 changes: 8 additions & 1 deletion include/bitcoin/database/query.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -502,7 +502,7 @@ class query
const header_link& link) const NOEXCEPT;

/// Setters.
bool set_block_valid(const header_link& link, uint64_t fees) NOEXCEPT;
bool set_block_valid(const header_link& link) NOEXCEPT;
bool set_block_unconfirmable(const header_link& link) NOEXCEPT;
bool set_block_confirmable(const header_link& link) NOEXCEPT;
bool set_block_unknown(const header_link& link) NOEXCEPT;
Expand Down Expand Up @@ -654,6 +654,13 @@ class query
bool is_block_validated(code& state, const header_link& link,
size_t height, size_t checkpoint) const NOEXCEPT;

/// Setters.
/// -----------------------------------------------------------------------
bool set_block_state(const header_link& link,
schema::block_state state) NOEXCEPT;
bool set_tx_state(const tx_link& link, const context& ctx,
uint64_t fee, size_t sigops, schema::tx_state state) NOEXCEPT;

/// Confirm.
/// -----------------------------------------------------------------------
bool is_confirmed_unspent(const output_link& link) const NOEXCEPT;
Expand Down
39 changes: 5 additions & 34 deletions include/bitcoin/database/tables/caches/validated_bk.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,57 +34,28 @@ struct validated_bk
using coding = linkage<schema::code>;
using array_map<schema::validated_bk>::arraymap;

struct slab
struct record
: public schema::validated_bk
{
inline link count() const NOEXCEPT
{
using namespace system;
return possible_narrow_cast<link::integer>(coding::size +
variable_size(fees));
}

inline bool from_data(reader& source) NOEXCEPT
{
code = source.read_little_endian<coding::integer, coding::size>();
fees = source.read_variable();
BC_ASSERT(!source || source.get_read_position() == count());
BC_ASSERT(!source || source.get_read_position() == count() * minrow);
return source;
}

inline bool to_data(finalizer& sink) const NOEXCEPT
{
sink.write_little_endian<coding::integer, coding::size>(code);
sink.write_variable(fees);
BC_ASSERT(!sink || sink.get_write_position() == count());
BC_ASSERT(!sink || sink.get_write_position() == count() * minrow);
return sink;
}

inline bool operator==(const slab& other) const NOEXCEPT
{
return code == other.code
&& fees == other.fees;
}

coding::integer code{};
uint64_t fees{};
};

struct slab_get_code
: public schema::validated_bk
{
inline link count() const NOEXCEPT
inline bool operator==(const record& other) const NOEXCEPT
{
BC_ASSERT(false);
return {};
return code == other.code;
}

inline bool from_data(reader& source) NOEXCEPT
{
code = source.read_little_endian<coding::integer, coding::size>();
return source;
}

coding::integer code{};
};
};
Expand Down
1 change: 1 addition & 0 deletions include/bitcoin/database/tables/optionals/filter_bk.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ struct filter_bk
{
hash = source.read_hash();
head = source.read_hash();
BC_ASSERT(!source || source.get_read_position() == count() * minrow);
return source;
}

Expand Down
22 changes: 13 additions & 9 deletions include/bitcoin/database/tables/schema.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,17 @@ constexpr size_t prevout_ = 5; // ->prevout slab.
constexpr size_t txs_ = 5; // ->txs slab.
constexpr size_t tx = 4; // ->tx record.
constexpr size_t block = 3; // ->header record.
constexpr size_t bk_slab = 4; // ->validated_bk record.
constexpr size_t tx_slab = 5; // ->validated_tx record.
constexpr size_t filter_ = 5; // ->filter record.
constexpr size_t doubles_ = 4; // doubles bucket (no actual keys).

/// Archive tables.
/// -----------------------------------------------------------------------

// size_t `cell` sets the hashmap bucket size (minimum size of link type).
// bool `align` causes arraymap bucket size to be expanded to nearest word.
// Memory fencing used (vs. mutex) when array/hashmap bucket is word sized.

// record hashmap
struct header
{
Expand Down Expand Up @@ -295,20 +298,20 @@ struct prevout
static_assert(link::size == 5u);
};

// slab arraymap
// record arraymap
struct validated_bk
{
static constexpr size_t align = false;
static constexpr size_t pk = schema::bk_slab;
static constexpr size_t pk = schema::block;
using link = linkage<pk, to_bits(pk)>;
static constexpr size_t minsize =
schema::code + // TODO: change code to variable.
one;
schema::code;
static constexpr size_t minrow = minsize;
static constexpr size_t size = max_size_t;
static_assert(minsize == 2u);
static_assert(minrow == 2u);
static_assert(link::size == 4u);
static constexpr size_t size = minsize;
static constexpr link count() NOEXCEPT { return 1; }
static_assert(minsize == 1u);
static_assert(minrow == 1u);
static_assert(link::size == 3u);
};

// slab modest (sk:4) multimap, with low multiple rate.
Expand All @@ -331,6 +334,7 @@ struct validated_tx
static inline link count() NOEXCEPT;
static_assert(minsize == 14u);
static_assert(minrow == 23u);
static_assert(link::size == 5u);
};

/// Optional tables.
Expand Down
2 changes: 1 addition & 1 deletion test/query/validate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ BOOST_AUTO_TEST_CASE(query_validate__get_block_state__valid__block_valid)
BOOST_REQUIRE(query.initialize(test::genesis));
BOOST_REQUIRE(query.set(test::block1, context{}, false, false));

BOOST_REQUIRE(query.set_block_valid(1, 42));
BOOST_REQUIRE(query.set_block_valid(1));
BOOST_REQUIRE_EQUAL(query.get_header_state(1), error::block_valid);
BOOST_REQUIRE_EQUAL(query.get_block_state(1), error::block_valid);
}
Expand Down
Loading
Loading