Fixing any corruption in representation table.

This commit is contained in:
clemahieu 2016-04-29 17:18:18 -05:00
commit a9040740ea
3 changed files with 66 additions and 15 deletions

View file

@ -590,4 +590,40 @@ TEST (block_store, sequence_increment)
ASSERT_EQ (21, seq7);
auto seq8 (store.sequence_atomic_inc (transaction, account2));
ASSERT_EQ (31, seq8);
}
TEST (block_store, upgrade_v2_v3)
{
rai::keypair key1;
rai::keypair key2;
auto path (rai::unique_path ());
{
bool init (false);
rai::block_store store (init, path);
ASSERT_TRUE (!init);
rai::genesis genesis;
auto hash (genesis.hash ());
rai::transaction transaction (store.environment, nullptr, true);
genesis.initialize (transaction, store);
rai::ledger ledger (store);
rai::change_block change (hash, key1.pub, rai::test_genesis_key.prv, rai::test_genesis_key.pub, 0);
ASSERT_EQ (rai::process_result::progress, ledger.process (transaction, change).code);
ASSERT_EQ (0, ledger.weight(transaction, rai::test_genesis_key.pub));
ASSERT_EQ (rai::genesis_amount, ledger.weight (transaction, key1.pub));
store.version_put (transaction, 2);
store.representation_put (transaction, key1.pub, 7);
ASSERT_EQ (7, ledger.weight (transaction, key1.pub));
ASSERT_EQ (2, store.version_get (transaction));
store.representation_put (transaction, key2.pub, 6);
ASSERT_EQ (6, ledger.weight (transaction, key2.pub));
}
bool init (false);
rai::block_store store (init, path);
rai::ledger ledger (store);
rai::transaction transaction (store.environment, nullptr, true);
ASSERT_TRUE (!init);
ASSERT_EQ (3, store.version_get (transaction));
ASSERT_EQ (rai::genesis_amount, ledger.weight (transaction, key1.pub));
ASSERT_EQ (0, ledger.weight (transaction, key2.pub));
}

View file

@ -1563,6 +1563,9 @@ void rai::block_store::do_upgrades (MDB_txn * transaction_a)
upgrade_v1_to_v2 (transaction_a);
break;
case 2:
upgrade_v2_to_v3 (transaction_a);
break;
case 3:
break;
default:
assert (false);
@ -1603,6 +1606,17 @@ void rai::block_store::upgrade_v1_to_v2 (MDB_txn * transaction_a)
}
}
void rai::block_store::upgrade_v2_to_v3 (MDB_txn * transaction_a)
{
version_put (transaction_a, 3);
mdb_drop (transaction_a, representation, 0);
for (auto i (latest_begin (transaction_a)), n (latest_end ()); i != n; ++i)
{
account_info info (i->second);
representation_add (transaction_a, info.rep_block, info.balance.number());
}
}
void rai::block_store::clear (MDB_dbi db_a)
{
rai::transaction transaction (environment, nullptr, true);
@ -2492,7 +2506,7 @@ public:
rai::account_info info;
ledger.store.account_get (transaction, pending.source, info);
ledger.store.pending_del (transaction, hash);
ledger.add_representation (transaction, ledger.representative (transaction, hash), pending.amount.number ());
ledger.store.representation_add (transaction, ledger.representative (transaction, hash), pending.amount.number ());
ledger.change_latest (transaction, pending.source, block_a.hashables.previous, info.rep_block, ledger.balance (transaction, block_a.hashables.previous));
ledger.store.block_del (transaction, hash);
ledger.store.frontier_del (transaction, hash);
@ -2505,7 +2519,7 @@ public:
auto representative (ledger.representative (transaction, block_a.hashables.source));
auto amount (ledger.amount (transaction, block_a.hashables.source));
auto destination_account (ledger.account (transaction, hash));
ledger.add_representation (transaction, ledger.representative (transaction, hash), 0 - amount);
ledger.store.representation_add (transaction, ledger.representative (transaction, hash), 0 - amount);
ledger.change_latest (transaction, destination_account, block_a.hashables.previous, representative, ledger.balance (transaction, block_a.hashables.previous));
ledger.store.block_del (transaction, hash);
ledger.store.pending_put (transaction, block_a.hashables.source, {ledger.account (transaction, block_a.hashables.source), amount, destination_account});
@ -2519,7 +2533,7 @@ public:
auto representative (ledger.representative (transaction, block_a.hashables.source));
auto amount (ledger.amount (transaction, block_a.hashables.source));
auto destination_account (ledger.account (transaction, hash));
ledger.add_representation (transaction, ledger.representative (transaction, hash), 0 - amount);
ledger.store.representation_add (transaction, ledger.representative (transaction, hash), 0 - amount);
ledger.change_latest (transaction, destination_account, 0, representative, 0);
ledger.store.block_del (transaction, hash);
ledger.store.pending_put (transaction, block_a.hashables.source, {ledger.account (transaction, block_a.hashables.source), amount, destination_account});
@ -2533,8 +2547,8 @@ public:
rai::account_info info;
ledger.store.account_get (transaction, account, info);
auto balance (ledger.balance (transaction, block_a.hashables.previous));
ledger.add_representation (transaction, representative, balance);
ledger.add_representation (transaction, hash, 0 - balance);
ledger.store.representation_add (transaction, representative, balance);
ledger.store.representation_add (transaction, hash, 0 - balance);
ledger.store.block_del (transaction, hash);
ledger.change_latest (transaction, account, block_a.hashables.previous, representative, info.balance);
ledger.store.frontier_del (transaction, hash);
@ -2685,14 +2699,14 @@ rai::uint128_t rai::ledger::amount (MDB_txn * transaction_a, rai::block_hash con
return amount.result;
}
void rai::ledger::add_representation (MDB_txn * transaction_a, rai::block_hash const & source_a, rai::uint128_t const & amount_a)
void rai::block_store::representation_add (MDB_txn * transaction_a, rai::block_hash const & source_a, rai::uint128_t const & amount_a)
{
auto source_block (store.block_get (transaction_a, source_a));
auto source_block (block_get (transaction_a, source_a));
assert (source_block != nullptr);
auto source_rep (source_block->representative ());
assert (!source_rep.is_zero ());
auto source_previous (store.representation_get (transaction_a, source_rep));
store.representation_put (transaction_a, source_rep, source_previous + amount_a);
auto source_previous (representation_get (transaction_a, source_rep));
representation_put (transaction_a, source_rep, source_previous + amount_a);
}
// Return latest block for account
@ -2824,8 +2838,8 @@ void ledger_processor::change_block (rai::change_block const & block_a)
{
ledger.store.block_put (transaction, hash, block_a);
auto balance (ledger.balance (transaction, block_a.hashables.previous));
ledger.add_representation (transaction, hash, balance);
ledger.add_representation (transaction, info.rep_block, 0 - balance);
ledger.store.representation_add (transaction, hash, balance);
ledger.store.representation_add (transaction, info.rep_block, 0 - balance);
ledger.change_latest (transaction, account, hash, hash, info.balance);
ledger.store.frontier_del (transaction, block_a.hashables.previous);
ledger.store.frontier_put (transaction, hash, account);
@ -2863,7 +2877,7 @@ void ledger_processor::send_block (rai::send_block const & block_a)
if (result.code == rai::process_result::progress)
{
auto amount (info.balance.number () - block_a.hashables.balance.number ());
ledger.add_representation (transaction, info.rep_block, 0 - amount);
ledger.store.representation_add (transaction, info.rep_block, 0 - amount);
ledger.store.block_put (transaction, hash, block_a);
ledger.change_latest (transaction, account, hash, info.rep_block, block_a.hashables.balance);
ledger.store.pending_put (transaction, hash, {account, amount, block_a.hashables.destination});
@ -2914,7 +2928,7 @@ void ledger_processor::receive_block (rai::receive_block const & block_a)
ledger.store.pending_del (transaction, block_a.hashables.source);
ledger.store.block_put (transaction, hash, block_a);
ledger.change_latest (transaction, pending.destination, hash, info.rep_block, new_balance);
ledger.add_representation (transaction, info.rep_block, pending.amount.number ());
ledger.store.representation_add (transaction, info.rep_block, pending.amount.number ());
ledger.store.frontier_del (transaction, block_a.hashables.previous);
ledger.store.frontier_put (transaction, hash, pending.destination);
result.account = pending.destination;
@ -2962,7 +2976,7 @@ void ledger_processor::open_block (rai::open_block const & block_a)
ledger.store.pending_del (transaction, block_a.hashables.source);
ledger.store.block_put (transaction, hash, block_a);
ledger.change_latest (transaction, pending.destination, hash, hash, pending.amount.number ());
ledger.add_representation (transaction, hash, pending.amount.number ());
ledger.store.representation_add (transaction, hash, pending.amount.number ());
ledger.store.frontier_put (transaction, hash, pending.destination);
result.account = pending.destination;
result.amount = pending.amount;

View file

@ -335,6 +335,7 @@ public:
rai::uint128_t representation_get (MDB_txn *, rai::account const &);
void representation_put (MDB_txn *, rai::account const &, rai::uint128_t const &);
void representation_add (MDB_txn *, rai::account const &, rai::uint128_t const &);
void unchecked_put (MDB_txn *, rai::block_hash const &, rai::block const &);
std::unique_ptr <rai::block> unchecked_get (MDB_txn *, rai::block_hash const &);
@ -364,6 +365,7 @@ public:
int version_get (MDB_txn *);
void do_upgrades (MDB_txn *);
void upgrade_v1_to_v2 (MDB_txn *);
void upgrade_v2_to_v3 (MDB_txn *);
void clear (MDB_dbi);
@ -463,7 +465,6 @@ public:
rai::process_return process (MDB_txn *, rai::block const &);
void rollback (MDB_txn *, rai::block_hash const &);
void change_latest (MDB_txn *, rai::account const &, rai::block_hash const &, rai::account const &, rai::uint128_union const &);
void add_representation (MDB_txn *, rai::account const &, rai::uint128_t const &);
void checksum_update (MDB_txn *, rai::block_hash const &);
rai::checksum checksum (MDB_txn *, rai::account const &, rai::account const &);
void dump_account_chain (rai::account const &);