From bb100272870d5d82634133d13f4b4d1b2380fb70 Mon Sep 17 00:00:00 2001 From: clemahieu Date: Tue, 11 Apr 2017 10:13:26 -0500 Subject: [PATCH] Tracking block count for each account. --- rai/core_test/block_store.cpp | 50 +++++++++++++++++++---- rai/core_test/ledger.cpp | 3 ++ rai/core_test/rpc.cpp | 8 ++-- rai/node/bootstrap.cpp | 2 +- rai/secure.cpp | 75 ++++++++++++++++++++++++++--------- rai/secure.hpp | 6 ++- rai/versioning.cpp | 61 ++++++++++++++++++++++++++++ rai/versioning.hpp | 17 ++++++++ 8 files changed, 190 insertions(+), 32 deletions(-) diff --git a/rai/core_test/block_store.cpp b/rai/core_test/block_store.cpp index 6f5a297b..928472b2 100644 --- a/rai/core_test/block_store.cpp +++ b/rai/core_test/block_store.cpp @@ -279,7 +279,7 @@ TEST (block_store, frontier_retrieval) rai::block_store store (init, rai::unique_path ()); ASSERT_TRUE (!init); rai::account account1 (0); - rai::account_info info1 (0, 0, 0, 0, 0); + rai::account_info info1 (0, 0, 0, 0, 0, 0); rai::transaction transaction (store.environment, nullptr, true); store.account_put (transaction, account1, info1); rai::account_info info2; @@ -295,7 +295,7 @@ TEST (block_store, one_account) rai::account account (0); rai::block_hash hash (0); rai::transaction transaction (store.environment, nullptr, true); - store.account_put (transaction, account, {hash, account, hash, 42, 100}); + store.account_put (transaction, account, {hash, account, hash, 42, 100, 200}); auto begin (store.latest_begin (transaction)); auto end (store.latest_end ()); ASSERT_NE (end, begin); @@ -304,6 +304,7 @@ TEST (block_store, one_account) ASSERT_EQ (hash, info.head); ASSERT_EQ (42, info.balance.number ()); ASSERT_EQ (100, info.modified); + ASSERT_EQ (200, info.block_count); ++begin; ASSERT_EQ (end, begin); } @@ -339,8 +340,8 @@ TEST (block_store, two_account) rai::account account2 (3); rai::block_hash hash2 (4); rai::transaction transaction (store.environment, nullptr, true); - store.account_put (transaction, account1, {hash1, account1, hash1, 42, 100}); - store.account_put (transaction, account2, {hash2, account2, hash2, 84, 200}); + store.account_put (transaction, account1, {hash1, account1, hash1, 42, 100, 300}); + store.account_put (transaction, account2, {hash2, account2, hash2, 84, 200, 400}); auto begin (store.latest_begin (transaction)); auto end (store.latest_end ()); ASSERT_NE (end, begin); @@ -349,6 +350,7 @@ TEST (block_store, two_account) ASSERT_EQ (hash1, info1.head); ASSERT_EQ (42, info1.balance.number ()); ASSERT_EQ (100, info1.modified); + ASSERT_EQ (300, info1.block_count); ++begin; ASSERT_NE (end, begin); ASSERT_EQ (account2, begin->first); @@ -356,6 +358,7 @@ TEST (block_store, two_account) ASSERT_EQ (hash2, info2.head); ASSERT_EQ (84, info2.balance.number ()); ASSERT_EQ (200, info2.modified); + ASSERT_EQ (400, info2.block_count); ++begin; ASSERT_EQ (end, begin); } @@ -370,8 +373,8 @@ TEST (block_store, latest_find) rai::account account2 (3); rai::block_hash hash2 (4); rai::transaction transaction (store.environment, nullptr, true); - store.account_put (transaction, account1, {hash1, account1, hash1, 100, 0}); - store.account_put (transaction, account2, {hash2, account2, hash2, 200, 0}); + store.account_put (transaction, account1, {hash1, account1, hash1, 100, 0, 300}); + store.account_put (transaction, account2, {hash2, account2, hash2, 200, 0, 400}); auto first (store.latest_begin (transaction)); auto second (store.latest_begin (transaction)); ++second; @@ -618,7 +621,9 @@ TEST (block_store, upgrade_v2_v3) rai::account_info info; ASSERT_FALSE (store.account_get (transaction, rai::test_genesis_key.pub, info)); info.rep_block = 42; - store.account_put (transaction, rai::test_genesis_key.pub, info); + rai::account_info_v5 info_old (info.head, info.rep_block, info.open_block, info.balance, info.modified); + auto status (mdb_put (transaction, store.accounts, rai::test_genesis_key.pub.val (), info_old.val (), 0)); + assert (status == 0); } bool init (false); rai::block_store store (init, path); @@ -687,6 +692,11 @@ TEST (block_store, upgrade_v4_v5) genesis_hash = info.head; store.block_successor_clear (transaction, info.head); ASSERT_TRUE (store.block_successor (transaction, genesis_hash).is_zero ()); + rai::account_info info2; + store.account_get (transaction, rai::test_genesis_key.pub, info2); + rai::account_info_v5 info_old (info2.head, info2.rep_block, info2.open_block, info2.balance, info2.modified); + auto status (mdb_put (transaction, store.accounts, rai::test_genesis_key.pub.val (), info_old.val (), 0)); + assert (status == 0); } bool init (false); rai::block_store store (init, path); @@ -724,3 +734,29 @@ TEST (vote, validate) ASSERT_EQ (rai::vote_result::replay, vote2.validate (transaction, store)); } +TEST (block_store, upgrade_v5_v6) +{ + auto path (rai::unique_path ()); + { + bool init (false); + rai::block_store store (init, path); + ASSERT_FALSE (init); + rai::transaction transaction (store.environment, nullptr, true); + rai::genesis genesis;; + genesis.initialize (transaction, store); + store.version_put (transaction, 5); + rai::account_info info; + store.account_get (transaction, rai::test_genesis_key.pub, info); + rai::account_info_v5 info_old (info.head, info.rep_block, info.open_block, info.balance, info.modified); + auto status (mdb_put (transaction, store.accounts, rai::test_genesis_key.pub.val (), info_old.val (), 0)); + assert (status == 0); + } + bool init (false); + rai::block_store store (init, path); + ASSERT_FALSE (init); + rai::transaction transaction (store.environment, nullptr, false); + rai::account_info info; + store.account_get (transaction, rai::test_genesis_key.pub, info); + ASSERT_EQ (1, info.block_count); +} + diff --git a/rai/core_test/ledger.cpp b/rai/core_test/ledger.cpp index e4d98530..17e7f22d 100644 --- a/rai/core_test/ledger.cpp +++ b/rai/core_test/ledger.cpp @@ -100,6 +100,7 @@ TEST (ledger, process_send) rai::send_block send (info1.head, key2.pub, 50, rai::test_genesis_key.prv, rai::test_genesis_key.pub, 0); rai::block_hash hash1 (send.hash ()); ASSERT_EQ (rai::test_genesis_key.pub, store.frontier_get (transaction, info1.head)); + ASSERT_EQ (1, info1.block_count); // This was a valid block, it should progress. auto return1 (ledger.process (transaction, send)); ASSERT_EQ (rai::genesis_amount - 50, ledger.amount (transaction, hash1)); @@ -112,6 +113,7 @@ TEST (ledger, process_send) ASSERT_EQ (rai::genesis_amount - 50, ledger.account_pending (transaction, key2.pub)); rai::account_info info2; ASSERT_FALSE (store.account_get (transaction, rai::test_genesis_key.pub, info2)); + ASSERT_EQ (2, info2.block_count); auto latest6 (store.block_get (transaction, info2.head)); ASSERT_NE (nullptr, latest6); auto latest7 (dynamic_cast (latest6.get ())); @@ -167,6 +169,7 @@ TEST (ledger, process_send) ASSERT_TRUE (store.frontier_get (transaction, hash1).is_zero ()); rai::account_info info7; ASSERT_FALSE (ledger.store.account_get (transaction, rai::test_genesis_key.pub, info7)); + ASSERT_EQ (1, info7.block_count); ASSERT_EQ (info1.head, info7.head); rai::pending_info pending2; ASSERT_TRUE (ledger.store.pending_get (transaction, rai::pending_key (key2.pub, hash1), pending2)); diff --git a/rai/core_test/rpc.cpp b/rai/core_test/rpc.cpp index dbe255eb..0c646268 100644 --- a/rai/core_test/rpc.cpp +++ b/rai/core_test/rpc.cpp @@ -720,7 +720,7 @@ TEST (rpc, frontier) { rai::keypair key; source [key.pub] = key.prv.data; - system.nodes [0]->store.account_put (transaction, key.pub, rai::account_info (key.prv.data, 0, 0, 0, 0)); + system.nodes [0]->store.account_put (transaction, key.pub, rai::account_info (key.prv.data, 0, 0, 0, 0, 0)); } } rai::keypair key; @@ -760,7 +760,7 @@ TEST (rpc, frontier_limited) { rai::keypair key; source [key.pub] = key.prv.data; - system.nodes [0]->store.account_put (transaction, key.pub, rai::account_info (key.prv.data, 0, 0, 0, 0)); + system.nodes [0]->store.account_put (transaction, key.pub, rai::account_info (key.prv.data, 0, 0, 0, 0, 0)); } } rai::keypair key; @@ -790,7 +790,7 @@ TEST (rpc, frontier_startpoint) { rai::keypair key; source [key.pub] = key.prv.data; - system.nodes [0]->store.account_put (transaction, key.pub, rai::account_info (key.prv.data, 0, 0, 0, 0)); + system.nodes [0]->store.account_put (transaction, key.pub, rai::account_info (key.prv.data, 0, 0, 0, 0, 0)); } } rai::keypair key; @@ -1313,7 +1313,7 @@ TEST (rpc, version) ASSERT_EQ (200, response1.status); ASSERT_EQ ("1", response1.json.get ("rpc_version")); ASSERT_EQ (200, response1.status); - ASSERT_EQ ("5", response1.json.get ("store_version")); + ASSERT_EQ ("6", response1.json.get ("store_version")); ASSERT_EQ (boost::str (boost::format ("RaiBlocks %1%.%2%.%3%") % RAIBLOCKS_VERSION_MAJOR % RAIBLOCKS_VERSION_MINOR % RAIBLOCKS_VERSION_PATCH), response1.json.get ("node_vendor")); auto & headers (response1.resp.fields); auto access_control (std::find_if (headers.begin (), headers.end (), [] (decltype (*headers.begin ()) & header_a) { return boost::iequals (header_a.first, "Access-Control-Allow-Origin"); })); diff --git a/rai/node/bootstrap.cpp b/rai/node/bootstrap.cpp index 687fbb6a..07cfba18 100755 --- a/rai/node/bootstrap.cpp +++ b/rai/node/bootstrap.cpp @@ -1549,7 +1549,7 @@ void rai::bulk_push_server::received_block (boost::system::error_code const & ec rai::frontier_req_server::frontier_req_server (std::shared_ptr const & connection_a, std::unique_ptr request_a) : connection (connection_a), current (request_a->start.number () - 1), -info (0, 0, 0, 0, 0), +info (0, 0, 0, 0, 0, 0), request (std::move (request_a)) { next (); diff --git a/rai/secure.cpp b/rai/secure.cpp index 3e6d08e9..391b8251 100644 --- a/rai/secure.cpp +++ b/rai/secure.cpp @@ -1315,23 +1315,25 @@ head (0), rep_block (0), open_block (0), balance (0), -modified (0) +modified (0), +block_count (0) { } rai::account_info::account_info (MDB_val const & val_a) { assert (val_a.mv_size == sizeof (*this)); - static_assert (sizeof (head) + sizeof (rep_block) + sizeof (open_block) + sizeof (balance) + sizeof (modified) == sizeof (*this), "Class not packed"); + static_assert (sizeof (head) + sizeof (rep_block) + sizeof (open_block) + sizeof (balance) + sizeof (modified) + sizeof (block_count) == sizeof (*this), "Class not packed"); std::copy (reinterpret_cast (val_a.mv_data), reinterpret_cast (val_a.mv_data) + sizeof (*this), reinterpret_cast (this)); } -rai::account_info::account_info (rai::block_hash const & head_a, rai::block_hash const & rep_block_a, rai::block_hash const & open_block_a, rai::amount const & balance_a, uint64_t modified_a) : +rai::account_info::account_info (rai::block_hash const & head_a, rai::block_hash const & rep_block_a, rai::block_hash const & open_block_a, rai::amount const & balance_a, uint64_t modified_a, uint64_t block_count_a) : head (head_a), rep_block (rep_block_a), open_block (open_block_a), balance (balance_a), -modified (modified_a) +modified (modified_a), +block_count (block_count_a) { } @@ -1342,6 +1344,7 @@ void rai::account_info::serialize (rai::stream & stream_a) const write (stream_a, open_block.bytes); write (stream_a, balance.bytes); write (stream_a, modified); + write (stream_a, block_count); } bool rai::account_info::deserialize (rai::stream & stream_a) @@ -1359,6 +1362,10 @@ bool rai::account_info::deserialize (rai::stream & stream_a) if (!result) { result = read (stream_a, modified); + if (!result) + { + result = read (stream_a, block_count); + } } } } @@ -1368,7 +1375,7 @@ bool rai::account_info::deserialize (rai::stream & stream_a) bool rai::account_info::operator == (rai::account_info const & other_a) const { - return head == other_a.head && rep_block == other_a.rep_block && open_block == other_a.open_block && balance == other_a.balance && modified == other_a.modified; + return head == other_a.head && rep_block == other_a.rep_block && open_block == other_a.open_block && balance == other_a.balance && modified == other_a.modified && block_count == other_a.block_count; } bool rai::account_info::operator != (rai::account_info const & other_a) const @@ -1588,6 +1595,8 @@ void rai::block_store::do_upgrades (MDB_txn * transaction_a) case 4: upgrade_v4_to_v5 (transaction_a); case 5: + upgrade_v5_to_v6 (transaction_a); + case 6: break; default: assert (false); @@ -1606,7 +1615,7 @@ void rai::block_store::upgrade_v1_to_v2 (MDB_txn * transaction_a) { account = i->first; rai::account_info_v1 v1 (i->second); - rai::account_info v2; + rai::account_info_v5 v2; v2.balance = v1.balance; v2.head = v1.head; v2.modified = v1.modified; @@ -1677,7 +1686,7 @@ void rai::block_store::upgrade_v2_to_v3 (MDB_txn * transaction_a) for (auto i (latest_begin (transaction_a)), n (latest_end ()); i != n; ++i) { rai::account account_l (i->first); - account_info info (i->second); + rai::account_info_v5 info (i->second); representative_visitor visitor (transaction_a, *this); visitor.compute (info.head); assert (!visitor.result.is_zero ()); @@ -1712,7 +1721,7 @@ void rai::block_store::upgrade_v4_to_v5 (MDB_txn * transaction_a) for (auto i (latest_begin (transaction_a)), n (latest_end ()); i != n; ++i) { rai::account account (i->first); - rai::account_info info (i->second); + rai::account_info_v5 info (i->second); rai::block_hash successor (0); auto block (block_get (transaction_a, info.head)); while (block != nullptr) @@ -1731,6 +1740,32 @@ void rai::block_store::upgrade_v4_to_v5 (MDB_txn * transaction_a) //std::cerr << boost::str (boost::format ("Fixed up %1% blocks\n") % fixes); } +void rai::block_store::upgrade_v5_to_v6 (MDB_txn * transaction_a) +{ + version_put (transaction_a, 6); + std::deque > headers; + for (auto i (latest_begin (transaction_a)), n (latest_end ()); i != n; ++i) + { + rai::account account (i->first); + rai::account_info_v5 info_old (i->second); + uint64_t block_count (0); + auto hash (info_old.head); + while (!hash.is_zero ()) + { + ++block_count; + auto block (block_get (transaction_a, hash)); + assert (block != nullptr); + hash = block->previous (); + } + rai::account_info info (info_old.head, info_old.rep_block, info_old.open_block, info_old.balance, info_old.modified, block_count); + headers.push_back (std::make_pair (account, info)); + } + for (auto i (headers.begin ()), n (headers.end ()); i != n; ++i) + { + account_put (transaction_a, i->first, i->second); + } +} + void rai::block_store::clear (MDB_dbi db_a) { rai::transaction transaction (environment, nullptr, true); @@ -2671,7 +2706,7 @@ public: assert (!error); ledger.store.pending_del (transaction, key); 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.change_latest (transaction, pending.source, block_a.hashables.previous, info.rep_block, ledger.balance (transaction, block_a.hashables.previous), info.block_count - 1); ledger.store.block_del (transaction, hash); ledger.store.frontier_del (transaction, hash); ledger.store.frontier_put (transaction, block_a.hashables.previous, pending.source); @@ -2683,8 +2718,11 @@ public: auto representative (ledger.representative (transaction, block_a.hashables.previous)); auto amount (ledger.amount (transaction, block_a.hashables.source)); auto destination_account (ledger.account (transaction, hash)); + rai::account_info info; + auto error (ledger.store.account_get (transaction, destination_account, info)); + assert (!error); 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.change_latest (transaction, destination_account, block_a.hashables.previous, representative, ledger.balance (transaction, block_a.hashables.previous), info.block_count - 1); ledger.store.block_del (transaction, hash); ledger.store.pending_put (transaction, rai::pending_key (destination_account, block_a.hashables.source), {ledger.account (transaction, block_a.hashables.source), amount}); ledger.store.frontier_del (transaction, hash); @@ -2698,7 +2736,7 @@ public: auto amount (ledger.amount (transaction, block_a.hashables.source)); auto destination_account (ledger.account (transaction, hash)); ledger.store.representation_add (transaction, ledger.representative (transaction, hash), 0 - amount); - ledger.change_latest (transaction, destination_account, 0, representative, 0); + ledger.change_latest (transaction, destination_account, 0, representative, 0, 0); ledger.store.block_del (transaction, hash); ledger.store.pending_put (transaction, rai::pending_key (destination_account, block_a.hashables.source), {ledger.account (transaction, block_a.hashables.source), amount}); ledger.store.frontier_del (transaction, hash); @@ -2715,7 +2753,7 @@ public: 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.change_latest (transaction, account, block_a.hashables.previous, representative, info.balance, info.block_count - 1); ledger.store.frontier_del (transaction, hash); ledger.store.frontier_put (transaction, block_a.hashables.previous, account); ledger.store.block_successor_clear (transaction, block_a.hashables.previous); @@ -2958,7 +2996,7 @@ void rai::ledger::checksum_update (MDB_txn * transaction_a, rai::block_hash cons store.checksum_put (transaction_a, 0, 0, value); } -void rai::ledger::change_latest (MDB_txn * transaction_a, rai::account const & account_a, rai::block_hash const & hash_a, rai::block_hash const & rep_block_a, rai::amount const & balance_a) +void rai::ledger::change_latest (MDB_txn * transaction_a, rai::account const & account_a, rai::block_hash const & hash_a, rai::block_hash const & rep_block_a, rai::amount const & balance_a, uint64_t block_count_a) { rai::account_info info; auto exists (!store.account_get (transaction_a, account_a, info)); @@ -2977,6 +3015,7 @@ void rai::ledger::change_latest (MDB_txn * transaction_a, rai::account const & a info.rep_block = rep_block_a; info.balance = balance_a; info.modified = store.now (); + info.block_count = block_count_a; store.account_put (transaction_a, account_a, info); checksum_update (transaction_a, hash_a); } @@ -3051,7 +3090,7 @@ void ledger_processor::change_block (rai::change_block const & block_a) auto balance (ledger.balance (transaction, block_a.hashables.previous)); 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.change_latest (transaction, account, hash, hash, info.balance, info.block_count + 1); ledger.store.frontier_del (transaction, block_a.hashables.previous); ledger.store.frontier_put (transaction, hash, account); result.account = account; @@ -3090,7 +3129,7 @@ void ledger_processor::send_block (rai::send_block const & block_a) auto amount (info.balance.number () - block_a.hashables.balance.number ()); 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.change_latest (transaction, account, hash, info.rep_block, block_a.hashables.balance, info.block_count + 1); ledger.store.pending_put (transaction, rai::pending_key (block_a.hashables.destination, hash), {account, amount}); ledger.store.frontier_del (transaction, block_a.hashables.previous); ledger.store.frontier_put (transaction, hash, account); @@ -3136,7 +3175,7 @@ void ledger_processor::receive_block (rai::receive_block const & block_a) assert (!error); ledger.store.pending_del (transaction, key); ledger.store.block_put (transaction, hash, block_a); - ledger.change_latest (transaction, account, hash, info.rep_block, new_balance); + ledger.change_latest (transaction, account, hash, info.rep_block, new_balance, info.block_count + 1); 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, account); @@ -3182,7 +3221,7 @@ void ledger_processor::open_block (rai::open_block const & block_a) assert (!error); ledger.store.pending_del (transaction, key); ledger.store.block_put (transaction, hash, block_a); - ledger.change_latest (transaction, block_a.hashables.account, hash, hash, pending.amount.number ()); + ledger.change_latest (transaction, block_a.hashables.account, hash, hash, pending.amount.number (), info.block_count + 1); ledger.store.representation_add (transaction, hash, pending.amount.number ()); ledger.store.frontier_put (transaction, hash, block_a.hashables.account); result.account = block_a.hashables.account; @@ -3284,7 +3323,7 @@ void rai::genesis::initialize (MDB_txn * transaction_a, rai::block_store & store auto hash_l (hash ()); assert (store_a.latest_begin (transaction_a) == store_a.latest_end ()); store_a.block_put (transaction_a, hash_l, *open); - store_a.account_put (transaction_a, genesis_account, {hash_l, open->hash (), open->hash (), std::numeric_limits ::max (), store_a.now ()}); + store_a.account_put (transaction_a, genesis_account, {hash_l, open->hash (), open->hash (), std::numeric_limits ::max (), store_a.now (), 1}); store_a.representation_put (transaction_a, genesis_account, std::numeric_limits ::max ()); store_a.checksum_put (transaction_a, 0, 0, hash_l); store_a.frontier_put (transaction_a, hash_l, genesis_account); diff --git a/rai/secure.hpp b/rai/secure.hpp index 997557ba..a868ac14 100644 --- a/rai/secure.hpp +++ b/rai/secure.hpp @@ -241,7 +241,7 @@ public: account_info (); account_info (MDB_val const &); account_info (rai::account_info const &) = default; - account_info (rai::block_hash const &, rai::block_hash const &, rai::block_hash const &, rai::amount const &, uint64_t); + account_info (rai::block_hash const &, rai::block_hash const &, rai::block_hash const &, rai::amount const &, uint64_t, uint64_t); void serialize (rai::stream &) const; bool deserialize (rai::stream &); bool operator == (rai::account_info const &) const; @@ -252,6 +252,7 @@ public: rai::block_hash open_block; rai::amount balance; uint64_t modified; + uint64_t block_count; }; class store_entry { @@ -392,6 +393,7 @@ public: void upgrade_v2_to_v3 (MDB_txn *); void upgrade_v3_to_v4 (MDB_txn *); void upgrade_v4_to_v5 (MDB_txn *); + void upgrade_v5_to_v6 (MDB_txn *); void clear (MDB_dbi); @@ -507,7 +509,7 @@ public: rai::uint128_t supply (MDB_txn *); 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 change_latest (MDB_txn *, rai::account const &, rai::block_hash const &, rai::account const &, rai::uint128_union const &, uint64_t); 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 &); diff --git a/rai/versioning.cpp b/rai/versioning.cpp index f748c12f..8762ecbf 100644 --- a/rai/versioning.cpp +++ b/rai/versioning.cpp @@ -105,3 +105,64 @@ rai::mdb_val rai::pending_info_v3::val () const { return rai::mdb_val (sizeof (*this), const_cast (this)); } + +rai::account_info_v5::account_info_v5 () : +head (0), +rep_block (0), +open_block (0), +balance (0), +modified (0) +{ +} + +rai::account_info_v5::account_info_v5 (MDB_val const & val_a) +{ + assert (val_a.mv_size == sizeof (*this)); + static_assert (sizeof (head) + sizeof (rep_block) + sizeof (open_block) + sizeof (balance) + sizeof (modified) == sizeof (*this), "Class not packed"); + std::copy (reinterpret_cast (val_a.mv_data), reinterpret_cast (val_a.mv_data) + sizeof (*this), reinterpret_cast (this)); +} + +rai::account_info_v5::account_info_v5 (rai::block_hash const & head_a, rai::block_hash const & rep_block_a, rai::block_hash const & open_block_a, rai::amount const & balance_a, uint64_t modified_a) : +head (head_a), +rep_block (rep_block_a), +open_block (open_block_a), +balance (balance_a), +modified (modified_a) +{ +} + +void rai::account_info_v5::serialize (rai::stream & stream_a) const +{ + write (stream_a, head.bytes); + write (stream_a, rep_block.bytes); + write (stream_a, open_block.bytes); + write (stream_a, balance.bytes); + write (stream_a, modified); +} + +bool rai::account_info_v5::deserialize (rai::stream & stream_a) +{ + auto result (read (stream_a, head.bytes)); + if (!result) + { + result = read (stream_a, rep_block.bytes); + if (!result) + { + result = read (stream_a, open_block.bytes); + if (!result) + { + result = read (stream_a, balance.bytes); + if (!result) + { + result = read (stream_a, modified); + } + } + } + } + return result; +} + +rai::mdb_val rai::account_info_v5::val () const +{ + return rai::mdb_val (sizeof (*this), const_cast (this)); +} diff --git a/rai/versioning.hpp b/rai/versioning.hpp index 63f748d0..45a4a74d 100644 --- a/rai/versioning.hpp +++ b/rai/versioning.hpp @@ -33,4 +33,21 @@ public: rai::amount amount; rai::account destination; }; +// Latest information about an account +class account_info_v5 +{ +public: + account_info_v5 (); + account_info_v5 (MDB_val const &); + account_info_v5 (rai::account_info_v5 const &) = default; + account_info_v5 (rai::block_hash const &, rai::block_hash const &, rai::block_hash const &, rai::amount const &, uint64_t); + void serialize (rai::stream &) const; + bool deserialize (rai::stream &); + rai::mdb_val val () const; + rai::block_hash head; + rai::block_hash rep_block; + rai::block_hash open_block; + rai::amount balance; + uint64_t modified; +}; }