diff --git a/rai/core_test/block_store.cpp b/rai/core_test/block_store.cpp index d7a0dfdd..b1d31c17 100644 --- a/rai/core_test/block_store.cpp +++ b/rai/core_test/block_store.cpp @@ -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)); } \ No newline at end of file diff --git a/rai/secure.cpp b/rai/secure.cpp index fc37f7f5..af7b058a 100644 --- a/rai/secure.cpp +++ b/rai/secure.cpp @@ -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; diff --git a/rai/secure.hpp b/rai/secure.hpp index 3d91c721..f8e4d60f 100644 --- a/rai/secure.hpp +++ b/rai/secure.hpp @@ -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 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 &);