account_exists needs to be transactional
Adding ledger::forked_block as a utility function to retrieve the block with which block_a conflicts in the local ledger. Since this could be either an open_block fork or normal fork, which have different semantics.
This commit is contained in:
parent
a175ac93c3
commit
4a661979ce
5 changed files with 61 additions and 10 deletions
|
@ -428,7 +428,7 @@ TEST (block_store, latest_exists)
|
|||
rai::transaction transaction (store.environment, nullptr, true);
|
||||
store.account_put (transaction, two, info);
|
||||
rai::block_hash one (1);
|
||||
ASSERT_FALSE (store.account_exists (one));
|
||||
ASSERT_FALSE (store.account_exists (transaction, one));
|
||||
}
|
||||
|
||||
TEST (block_store, stack)
|
||||
|
@ -635,4 +635,4 @@ TEST (block_store, upgrade_v2_v3)
|
|||
rai::account_info info;
|
||||
ASSERT_FALSE (store.account_get (transaction, rai::test_genesis_key.pub, info));
|
||||
ASSERT_EQ (change_hash, info.rep_block);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1204,3 +1204,37 @@ TEST (node, bootstrap_no_publish)
|
|||
ASSERT_TRUE (node1->active.roots.empty ());
|
||||
}
|
||||
}
|
||||
|
||||
// Bootstrapping a forked open block should succeed.
|
||||
TEST (node, bootstrap_fork_open)
|
||||
{
|
||||
rai::system system0 (24000, 2);
|
||||
system0.wallet(0)->insert_adhoc (rai::test_genesis_key.prv);
|
||||
auto node0 (system0.nodes [0]);
|
||||
auto node1 (system0.nodes [1]);
|
||||
rai::keypair key0;
|
||||
rai::send_block send0 (system0.nodes [0]->latest (rai::test_genesis_key.pub), key0.pub, rai::genesis_amount - 500, rai::test_genesis_key.prv, rai::test_genesis_key.pub, 0);
|
||||
rai::open_block open0 (send0.hash (), 1, key0.pub, key0.prv, key0.pub, 0);
|
||||
rai::open_block open1 (send0.hash (), 2, key0.pub, key0.prv, key0.pub, 0);
|
||||
node0->generate_work (send0);
|
||||
node0->generate_work (open0);
|
||||
node0->generate_work (open1);
|
||||
{
|
||||
rai::transaction transaction0 (node0->store.environment, nullptr, true);
|
||||
rai::transaction transaction1 (node1->store.environment, nullptr, true);
|
||||
ASSERT_EQ (rai::process_result::progress, node0->ledger.process (transaction0, send0).code);
|
||||
ASSERT_EQ (rai::process_result::progress, node1->ledger.process (transaction1, send0).code);
|
||||
ASSERT_EQ (rai::process_result::progress, node0->ledger.process (transaction0, open0).code);
|
||||
ASSERT_EQ (rai::process_result::progress, node1->ledger.process (transaction1, open1).code);
|
||||
}
|
||||
node1->bootstrap_initiator.bootstrap (node0->network.endpoint ());
|
||||
ASSERT_TRUE (node1->bootstrap_initiator.in_progress ());
|
||||
ASSERT_TRUE (node1->active.roots.empty ());
|
||||
int iterations (0);
|
||||
while (node1->ledger.block_exists (open1.hash ()))
|
||||
{
|
||||
system0.poll ();
|
||||
ASSERT_LT (iterations, 200);
|
||||
++iterations;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -537,7 +537,7 @@ void rai::bulk_pull_client::process_end ()
|
|||
case rai::process_result::fork:
|
||||
{
|
||||
auto node_l (connection->connection->node);
|
||||
auto block (node_l->store.block_get (transaction_a, node_l->store.block_successor (transaction_a, block_a.root ())));
|
||||
auto block (node_l->ledger.forked_block (transaction_a, block_a));
|
||||
node_l->active.start (transaction_a, *block, [node_l] (rai::block & block_a)
|
||||
{
|
||||
node_l->process_confirmed (block_a);
|
||||
|
|
|
@ -1911,10 +1911,9 @@ void rai::block_store::account_del (MDB_txn * transaction_a, rai::account const
|
|||
assert (status == 0);
|
||||
}
|
||||
|
||||
bool rai::block_store::account_exists (rai::account const & account_a)
|
||||
bool rai::block_store::account_exists (MDB_txn * transaction_a, rai::account const & account_a)
|
||||
{
|
||||
rai::transaction transaction (environment, nullptr, false);
|
||||
auto iterator (latest_begin (transaction, account_a));
|
||||
auto iterator (latest_begin (transaction_a, account_a));
|
||||
return iterator != rai::store_iterator (nullptr) && rai::account (iterator->first) == account_a;
|
||||
}
|
||||
|
||||
|
@ -2866,10 +2865,10 @@ void rai::ledger::change_latest (MDB_txn * transaction_a, rai::account const & a
|
|||
|
||||
std::unique_ptr <rai::block> rai::ledger::successor (MDB_txn * transaction_a, rai::block_hash const & block_a)
|
||||
{
|
||||
assert (store.account_exists (block_a) || store.block_exists (transaction_a, block_a));
|
||||
assert (store.account_exists (block_a) || latest (transaction_a, account (transaction_a, block_a)) != block_a);
|
||||
assert (store.account_exists (transaction_a, block_a) || store.block_exists (transaction_a, block_a));
|
||||
assert (store.account_exists (transaction_a, block_a) || latest (transaction_a, account (transaction_a, block_a)) != block_a);
|
||||
rai::block_hash successor;
|
||||
if (store.account_exists (block_a))
|
||||
if (store.account_exists (transaction_a, block_a))
|
||||
{
|
||||
rai::account_info info;
|
||||
auto error (store.account_get (transaction_a, block_a, info));
|
||||
|
@ -2886,6 +2885,23 @@ std::unique_ptr <rai::block> rai::ledger::successor (MDB_txn * transaction_a, ra
|
|||
return result;
|
||||
}
|
||||
|
||||
std::unique_ptr <rai::block> rai::ledger::forked_block (MDB_txn * transaction_a, rai::block const & block_a)
|
||||
{
|
||||
assert (!store.block_exists (transaction_a, block_a.hash ()));
|
||||
auto root (block_a.root ());
|
||||
assert (store.block_exists (transaction_a, root) || store.account_exists (transaction_a, root));
|
||||
std::unique_ptr <rai::block> result (store.block_get (transaction_a, store.block_successor (transaction_a, root)));
|
||||
if (result == nullptr)
|
||||
{
|
||||
rai::account_info info;
|
||||
auto error (store.account_get (transaction_a, root, info));
|
||||
assert (!error);
|
||||
result = store.block_get (transaction_a, info.open_block);
|
||||
assert (result != nullptr);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void ledger_processor::change_block (rai::change_block const & block_a)
|
||||
{
|
||||
auto hash (block_a.hash ());
|
||||
|
|
|
@ -320,7 +320,7 @@ public:
|
|||
void account_put (MDB_txn *, rai::account const &, rai::account_info const &);
|
||||
bool account_get (MDB_txn *, rai::account const &, rai::account_info &);
|
||||
void account_del (MDB_txn *, rai::account const &);
|
||||
bool account_exists (rai::account const &);
|
||||
bool account_exists (MDB_txn *, rai::account const &);
|
||||
rai::store_iterator latest_begin (MDB_txn *, rai::account const &);
|
||||
rai::store_iterator latest_begin (MDB_txn *);
|
||||
rai::store_iterator latest_end ();
|
||||
|
@ -458,6 +458,7 @@ public:
|
|||
rai::uint128_t account_balance (MDB_txn *, rai::account const &);
|
||||
rai::uint128_t weight (MDB_txn *, rai::account const &);
|
||||
std::unique_ptr <rai::block> successor (MDB_txn *, rai::block_hash const &);
|
||||
std::unique_ptr <rai::block> forked_block (MDB_txn *, rai::block const &);
|
||||
rai::block_hash latest (MDB_txn *, rai::account const &);
|
||||
rai::block_hash latest_root (MDB_txn *, rai::account const &);
|
||||
rai::block_hash representative (MDB_txn *, rai::block_hash const &);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue