diff --git a/nano/core_test/block_store.cpp b/nano/core_test/block_store.cpp index 55f103c8..ef25d75f 100644 --- a/nano/core_test/block_store.cpp +++ b/nano/core_test/block_store.cpp @@ -19,10 +19,8 @@ TEST (block_store, construction) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_TRUE (!init); - auto now (nano::seconds_since_epoch ()); - ASSERT_GT (now, 1408074640); } TEST (block_store, sideband_serialization) @@ -54,23 +52,23 @@ TEST (block_store, add_item) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_TRUE (!init); nano::open_block block (0, 1, 0, nano::keypair ().prv, 0, 0); nano::uint256_union hash1 (block.hash ()); - auto transaction (store.tx_begin_write ()); - auto latest1 (store.block_get (transaction, hash1)); + auto transaction (store->tx_begin_write ()); + auto latest1 (store->block_get (transaction, hash1)); ASSERT_EQ (nullptr, latest1); - ASSERT_FALSE (store.block_exists (transaction, hash1)); + ASSERT_FALSE (store->block_exists (transaction, hash1)); nano::block_sideband sideband (nano::block_type::open, 0, 0, 0, 0, 0); - store.block_put (transaction, hash1, block, sideband); - auto latest2 (store.block_get (transaction, hash1)); + store->block_put (transaction, hash1, block, sideband); + auto latest2 (store->block_get (transaction, hash1)); ASSERT_NE (nullptr, latest2); ASSERT_EQ (block, *latest2); - ASSERT_TRUE (store.block_exists (transaction, hash1)); - ASSERT_FALSE (store.block_exists (transaction, hash1.number () - 1)); - store.block_del (transaction, hash1); - auto latest3 (store.block_get (transaction, hash1)); + ASSERT_TRUE (store->block_exists (transaction, hash1)); + ASSERT_FALSE (store->block_exists (transaction, hash1.number () - 1)); + store->block_del (transaction, hash1); + auto latest3 (store->block_get (transaction, hash1)); ASSERT_EQ (nullptr, latest3); } @@ -78,22 +76,22 @@ TEST (block_store, clear_successor) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_TRUE (!init); nano::open_block block1 (0, 1, 0, nano::keypair ().prv, 0, 0); - auto transaction (store.tx_begin_write ()); + auto transaction (store->tx_begin_write ()); nano::block_sideband sideband (nano::block_type::open, 0, 0, 0, 0, 0); - store.block_put (transaction, block1.hash (), block1, sideband); + store->block_put (transaction, block1.hash (), block1, sideband); nano::open_block block2 (0, 2, 0, nano::keypair ().prv, 0, 0); - store.block_put (transaction, block2.hash (), block2, sideband); - ASSERT_NE (nullptr, store.block_get (transaction, block1.hash (), &sideband)); + store->block_put (transaction, block2.hash (), block2, sideband); + ASSERT_NE (nullptr, store->block_get (transaction, block1.hash (), &sideband)); ASSERT_EQ (0, sideband.successor.number ()); sideband.successor = block2.hash (); - store.block_put (transaction, block1.hash (), block1, sideband); - ASSERT_NE (nullptr, store.block_get (transaction, block1.hash (), &sideband)); + store->block_put (transaction, block1.hash (), block1, sideband); + ASSERT_NE (nullptr, store->block_get (transaction, block1.hash (), &sideband)); ASSERT_EQ (block2.hash (), sideband.successor); - store.block_successor_clear (transaction, block1.hash ()); - ASSERT_NE (nullptr, store.block_get (transaction, block1.hash (), &sideband)); + store->block_successor_clear (transaction, block1.hash ()); + ASSERT_NE (nullptr, store->block_get (transaction, block1.hash (), &sideband)); ASSERT_EQ (0, sideband.successor.number ()); } @@ -101,18 +99,18 @@ TEST (block_store, add_nonempty_block) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_TRUE (!init); nano::keypair key1; nano::open_block block (0, 1, 0, nano::keypair ().prv, 0, 0); nano::uint256_union hash1 (block.hash ()); block.signature = nano::sign_message (key1.prv, key1.pub, hash1); - auto transaction (store.tx_begin_write ()); - auto latest1 (store.block_get (transaction, hash1)); + auto transaction (store->tx_begin_write ()); + auto latest1 (store->block_get (transaction, hash1)); ASSERT_EQ (nullptr, latest1); nano::block_sideband sideband (nano::block_type::open, 0, 0, 0, 0, 0); - store.block_put (transaction, hash1, block, sideband); - auto latest2 (store.block_get (transaction, hash1)); + store->block_put (transaction, hash1, block, sideband); + auto latest2 (store->block_get (transaction, hash1)); ASSERT_NE (nullptr, latest2); ASSERT_EQ (block, *latest2); } @@ -121,29 +119,29 @@ TEST (block_store, add_two_items) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_TRUE (!init); nano::keypair key1; nano::open_block block (0, 1, 1, nano::keypair ().prv, 0, 0); nano::uint256_union hash1 (block.hash ()); block.signature = nano::sign_message (key1.prv, key1.pub, hash1); - auto transaction (store.tx_begin_write ()); - auto latest1 (store.block_get (transaction, hash1)); + auto transaction (store->tx_begin_write ()); + auto latest1 (store->block_get (transaction, hash1)); ASSERT_EQ (nullptr, latest1); nano::open_block block2 (0, 1, 3, nano::keypair ().prv, 0, 0); block2.hashables.account = 3; nano::uint256_union hash2 (block2.hash ()); block2.signature = nano::sign_message (key1.prv, key1.pub, hash2); - auto latest2 (store.block_get (transaction, hash2)); + auto latest2 (store->block_get (transaction, hash2)); ASSERT_EQ (nullptr, latest2); nano::block_sideband sideband (nano::block_type::open, 0, 0, 0, 0, 0); - store.block_put (transaction, hash1, block, sideband); + store->block_put (transaction, hash1, block, sideband); nano::block_sideband sideband2 (nano::block_type::open, 0, 0, 0, 0, 0); - store.block_put (transaction, hash2, block2, sideband2); - auto latest3 (store.block_get (transaction, hash1)); + store->block_put (transaction, hash2, block2, sideband2); + auto latest3 (store->block_get (transaction, hash1)); ASSERT_NE (nullptr, latest3); ASSERT_EQ (block, *latest3); - auto latest4 (store.block_get (transaction, hash2)); + auto latest4 (store->block_get (transaction, hash2)); ASSERT_NE (nullptr, latest4); ASSERT_EQ (block2, *latest4); ASSERT_FALSE (*latest3 == *latest4); @@ -153,21 +151,21 @@ TEST (block_store, add_receive) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_TRUE (!init); nano::keypair key1; nano::keypair key2; nano::open_block block1 (0, 1, 0, nano::keypair ().prv, 0, 0); - auto transaction (store.tx_begin_write ()); + auto transaction (store->tx_begin_write ()); nano::block_sideband sideband1 (nano::block_type::open, 0, 0, 0, 0, 0); - store.block_put (transaction, block1.hash (), block1, sideband1); + store->block_put (transaction, block1.hash (), block1, sideband1); nano::receive_block block (block1.hash (), 1, nano::keypair ().prv, 2, 3); nano::block_hash hash1 (block.hash ()); - auto latest1 (store.block_get (transaction, hash1)); + auto latest1 (store->block_get (transaction, hash1)); ASSERT_EQ (nullptr, latest1); nano::block_sideband sideband (nano::block_type::receive, 0, 0, 0, 0, 0); - store.block_put (transaction, hash1, block, sideband); - auto latest2 (store.block_get (transaction, hash1)); + store->block_put (transaction, hash1, block, sideband); + auto latest2 (store->block_get (transaction, hash1)); ASSERT_NE (nullptr, latest2); ASSERT_EQ (block, *latest2); } @@ -176,32 +174,32 @@ TEST (block_store, add_pending) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_TRUE (!init); nano::keypair key1; nano::pending_key key2 (0, 0); nano::pending_info pending1; - auto transaction (store.tx_begin_write ()); - ASSERT_TRUE (store.pending_get (transaction, key2, pending1)); - store.pending_put (transaction, key2, pending1); + auto transaction (store->tx_begin_write ()); + ASSERT_TRUE (store->pending_get (transaction, key2, pending1)); + store->pending_put (transaction, key2, pending1); nano::pending_info pending2; - ASSERT_FALSE (store.pending_get (transaction, key2, pending2)); + ASSERT_FALSE (store->pending_get (transaction, key2, pending2)); ASSERT_EQ (pending1, pending2); - store.pending_del (transaction, key2); - ASSERT_TRUE (store.pending_get (transaction, key2, pending2)); + store->pending_del (transaction, key2); + ASSERT_TRUE (store->pending_get (transaction, key2, pending2)); } TEST (block_store, pending_iterator) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_TRUE (!init); - auto transaction (store.tx_begin_write ()); - ASSERT_EQ (store.pending_end (), store.pending_begin (transaction)); - store.pending_put (transaction, nano::pending_key (1, 2), { 2, 3, nano::epoch::epoch_1 }); - auto current (store.pending_begin (transaction)); - ASSERT_NE (store.pending_end (), current); + auto transaction (store->tx_begin_write ()); + ASSERT_EQ (store->pending_end (), store->pending_begin (transaction)); + store->pending_put (transaction, nano::pending_key (1, 2), { 2, 3, nano::epoch::epoch_1 }); + auto current (store->pending_begin (transaction)); + ASSERT_NE (store->pending_end (), current); nano::pending_key key1 (current->first); ASSERT_EQ (nano::account (1), key1.account); ASSERT_EQ (nano::block_hash (2), key1.hash); @@ -221,23 +219,23 @@ TEST (block_store, pending_iterator_comparison) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_TRUE (!init); nano::stat stats; - auto transaction (store.tx_begin_write ()); + auto transaction (store->tx_begin_write ()); // Populate pending - store.pending_put (transaction, nano::pending_key (nano::account (3), nano::block_hash (1)), nano::pending_info (nano::account (10), nano::amount (1), nano::epoch::epoch_0)); - store.pending_put (transaction, nano::pending_key (nano::account (3), nano::block_hash (4)), nano::pending_info (nano::account (10), nano::amount (0), nano::epoch::epoch_0)); + store->pending_put (transaction, nano::pending_key (nano::account (3), nano::block_hash (1)), nano::pending_info (nano::account (10), nano::amount (1), nano::epoch::epoch_0)); + store->pending_put (transaction, nano::pending_key (nano::account (3), nano::block_hash (4)), nano::pending_info (nano::account (10), nano::amount (0), nano::epoch::epoch_0)); // Populate pending_v1 - store.pending_put (transaction, nano::pending_key (nano::account (2), nano::block_hash (2)), nano::pending_info (nano::account (10), nano::amount (2), nano::epoch::epoch_1)); - store.pending_put (transaction, nano::pending_key (nano::account (2), nano::block_hash (3)), nano::pending_info (nano::account (10), nano::amount (3), nano::epoch::epoch_1)); + store->pending_put (transaction, nano::pending_key (nano::account (2), nano::block_hash (2)), nano::pending_info (nano::account (10), nano::amount (2), nano::epoch::epoch_1)); + store->pending_put (transaction, nano::pending_key (nano::account (2), nano::block_hash (3)), nano::pending_info (nano::account (10), nano::amount (3), nano::epoch::epoch_1)); // Iterate account 3 (pending) { size_t count = 0; nano::account begin (3); nano::account end (begin.number () + 1); - for (auto i (store.pending_begin (transaction, nano::pending_key (begin, 0))), n (store.pending_begin (transaction, nano::pending_key (end, 0))); i != n; ++i, ++count) + for (auto i (store->pending_begin (transaction, nano::pending_key (begin, 0))), n (store->pending_begin (transaction, nano::pending_key (end, 0))); i != n; ++i, ++count) { nano::pending_key key (i->first); ASSERT_EQ (key.account, begin); @@ -251,7 +249,7 @@ TEST (block_store, pending_iterator_comparison) size_t count = 0; nano::account begin (2); nano::account end (begin.number () + 1); - for (auto i (store.pending_begin (transaction, nano::pending_key (begin, 0))), n (store.pending_begin (transaction, nano::pending_key (end, 0))); i != n; ++i, ++count) + for (auto i (store->pending_begin (transaction, nano::pending_key (begin, 0))), n (store->pending_begin (transaction, nano::pending_key (end, 0))); i != n; ++i, ++count) { nano::pending_key key (i->first); ASSERT_EQ (key.account, begin); @@ -265,16 +263,16 @@ TEST (block_store, genesis) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_TRUE (!init); nano::genesis genesis; auto hash (genesis.hash ()); - auto transaction (store.tx_begin_write ()); - store.initialize (transaction, genesis); + auto transaction (store->tx_begin_write ()); + store->initialize (transaction, genesis); nano::account_info info; - ASSERT_FALSE (store.account_get (transaction, nano::genesis_account, info)); + ASSERT_FALSE (store->account_get (transaction, nano::genesis_account, info)); ASSERT_EQ (hash, info.head); - auto block1 (store.block_get (transaction, info.head)); + auto block1 (store->block_get (transaction, info.head)); ASSERT_NE (nullptr, block1); auto receive1 (dynamic_cast (block1.get ())); ASSERT_NE (nullptr, receive1); @@ -292,33 +290,33 @@ TEST (representation, changes) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_TRUE (!init); nano::keypair key1; - auto transaction (store.tx_begin_write ()); - ASSERT_EQ (0, store.representation_get (transaction, key1.pub)); - store.representation_put (transaction, key1.pub, 1); - ASSERT_EQ (1, store.representation_get (transaction, key1.pub)); - store.representation_put (transaction, key1.pub, 2); - ASSERT_EQ (2, store.representation_get (transaction, key1.pub)); + auto transaction (store->tx_begin_write ()); + ASSERT_EQ (0, store->representation_get (transaction, key1.pub)); + store->representation_put (transaction, key1.pub, 1); + ASSERT_EQ (1, store->representation_get (transaction, key1.pub)); + store->representation_put (transaction, key1.pub, 2); + ASSERT_EQ (2, store->representation_get (transaction, key1.pub)); } TEST (bootstrap, simple) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_TRUE (!init); auto block1 (std::make_shared (0, 1, 2, nano::keypair ().prv, 4, 5)); - auto transaction (store.tx_begin_write ()); - auto block2 (store.unchecked_get (transaction, block1->previous ())); + auto transaction (store->tx_begin_write ()); + auto block2 (store->unchecked_get (transaction, block1->previous ())); ASSERT_TRUE (block2.empty ()); - store.unchecked_put (transaction, block1->previous (), block1); - auto block3 (store.unchecked_get (transaction, block1->previous ())); + store->unchecked_put (transaction, block1->previous (), block1); + auto block3 (store->unchecked_get (transaction, block1->previous ())); ASSERT_FALSE (block3.empty ()); ASSERT_EQ (*block1, *(block3[0].block)); - store.unchecked_del (transaction, nano::unchecked_key (block1->previous (), block1->hash ())); - auto block4 (store.unchecked_get (transaction, block1->previous ())); + store->unchecked_del (transaction, nano::unchecked_key (block1->previous (), block1->hash ())); + auto block4 (store->unchecked_get (transaction, block1->previous ())); ASSERT_TRUE (block4.empty ()); } @@ -344,15 +342,15 @@ TEST (unchecked, double_put) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_TRUE (!init); auto block1 (std::make_shared (4, 1, 2, nano::keypair ().prv, 4, 5)); - auto transaction (store.tx_begin_write ()); - auto block2 (store.unchecked_get (transaction, block1->previous ())); + auto transaction (store->tx_begin_write ()); + auto block2 (store->unchecked_get (transaction, block1->previous ())); ASSERT_TRUE (block2.empty ()); - store.unchecked_put (transaction, block1->previous (), block1); - store.unchecked_put (transaction, block1->previous (), block1); - auto block3 (store.unchecked_get (transaction, block1->previous ())); + store->unchecked_put (transaction, block1->previous (), block1); + store->unchecked_put (transaction, block1->previous (), block1); + auto block3 (store->unchecked_get (transaction, block1->previous ())); ASSERT_EQ (block3.size (), 1); } @@ -360,27 +358,27 @@ TEST (unchecked, multiple_get) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_TRUE (!init); auto block1 (std::make_shared (4, 1, 2, nano::keypair ().prv, 4, 5)); auto block2 (std::make_shared (3, 1, 2, nano::keypair ().prv, 4, 5)); auto block3 (std::make_shared (5, 1, 2, nano::keypair ().prv, 4, 5)); { - auto transaction (store.tx_begin_write ()); - store.unchecked_put (transaction, block1->previous (), block1); // unchecked1 - store.unchecked_put (transaction, block1->hash (), block1); // unchecked2 - store.unchecked_put (transaction, block2->previous (), block2); // unchecked3 - store.unchecked_put (transaction, block1->previous (), block2); // unchecked1 - store.unchecked_put (transaction, block1->hash (), block2); // unchecked2 - store.unchecked_put (transaction, block3->previous (), block3); - store.unchecked_put (transaction, block3->hash (), block3); // unchecked4 - store.unchecked_put (transaction, block1->previous (), block3); // unchecked1 + auto transaction (store->tx_begin_write ()); + store->unchecked_put (transaction, block1->previous (), block1); // unchecked1 + store->unchecked_put (transaction, block1->hash (), block1); // unchecked2 + store->unchecked_put (transaction, block2->previous (), block2); // unchecked3 + store->unchecked_put (transaction, block1->previous (), block2); // unchecked1 + store->unchecked_put (transaction, block1->hash (), block2); // unchecked2 + store->unchecked_put (transaction, block3->previous (), block3); + store->unchecked_put (transaction, block3->hash (), block3); // unchecked4 + store->unchecked_put (transaction, block1->previous (), block3); // unchecked1 } - auto transaction (store.tx_begin_read ()); - auto unchecked_count (store.unchecked_count (transaction)); + auto transaction (store->tx_begin_read ()); + auto unchecked_count (store->unchecked_count (transaction)); ASSERT_EQ (unchecked_count, 8); std::vector unchecked1; - auto unchecked1_blocks (store.unchecked_get (transaction, block1->previous ())); + auto unchecked1_blocks (store->unchecked_get (transaction, block1->previous ())); ASSERT_EQ (unchecked1_blocks.size (), 3); for (auto & i : unchecked1_blocks) { @@ -390,7 +388,7 @@ TEST (unchecked, multiple_get) ASSERT_TRUE (std::find (unchecked1.begin (), unchecked1.end (), block2->hash ()) != unchecked1.end ()); ASSERT_TRUE (std::find (unchecked1.begin (), unchecked1.end (), block3->hash ()) != unchecked1.end ()); std::vector unchecked2; - auto unchecked2_blocks (store.unchecked_get (transaction, block1->hash ())); + auto unchecked2_blocks (store->unchecked_get (transaction, block1->hash ())); ASSERT_EQ (unchecked2_blocks.size (), 2); for (auto & i : unchecked2_blocks) { @@ -398,13 +396,13 @@ TEST (unchecked, multiple_get) } ASSERT_TRUE (std::find (unchecked2.begin (), unchecked2.end (), block1->hash ()) != unchecked2.end ()); ASSERT_TRUE (std::find (unchecked2.begin (), unchecked2.end (), block2->hash ()) != unchecked2.end ()); - auto unchecked3 (store.unchecked_get (transaction, block2->previous ())); + auto unchecked3 (store->unchecked_get (transaction, block2->previous ())); ASSERT_EQ (unchecked3.size (), 1); ASSERT_EQ (unchecked3[0].block->hash (), block2->hash ()); - auto unchecked4 (store.unchecked_get (transaction, block3->hash ())); + auto unchecked4 (store->unchecked_get (transaction, block3->hash ())); ASSERT_EQ (unchecked4.size (), 1); ASSERT_EQ (unchecked4[0].block->hash (), block3->hash ()); - auto unchecked5 (store.unchecked_get (transaction, block2->hash ())); + auto unchecked5 (store->unchecked_get (transaction, block2->hash ())); ASSERT_EQ (unchecked5.size (), 0); } @@ -412,11 +410,11 @@ TEST (block_store, empty_accounts) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_TRUE (!init); - auto transaction (store.tx_begin_read ()); - auto begin (store.latest_begin (transaction)); - auto end (store.latest_end ()); + auto transaction (store->tx_begin_read ()); + auto begin (store->latest_begin (transaction)); + auto end (store->latest_end ()); ASSERT_EQ (end, begin); } @@ -424,24 +422,24 @@ TEST (block_store, one_block) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_TRUE (!init); nano::open_block block1 (0, 1, 0, nano::keypair ().prv, 0, 0); - auto transaction (store.tx_begin_write ()); + auto transaction (store->tx_begin_write ()); nano::block_sideband sideband (nano::block_type::open, 0, 0, 0, 0, 0); - store.block_put (transaction, block1.hash (), block1, sideband); - ASSERT_TRUE (store.block_exists (transaction, block1.hash ())); + store->block_put (transaction, block1.hash (), block1, sideband); + ASSERT_TRUE (store->block_exists (transaction, block1.hash ())); } TEST (block_store, empty_bootstrap) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_TRUE (!init); - auto transaction (store.tx_begin_read ()); - auto begin (store.unchecked_begin (transaction)); - auto end (store.unchecked_end ()); + auto transaction (store->tx_begin_read ()); + auto begin (store->unchecked_begin (transaction)); + auto end (store->unchecked_end ()); ASSERT_EQ (end, begin); } @@ -449,18 +447,18 @@ TEST (block_store, one_bootstrap) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_TRUE (!init); auto block1 (std::make_shared (0, 1, 2, nano::keypair ().prv, 4, 5)); - auto transaction (store.tx_begin_write ()); - store.unchecked_put (transaction, block1->hash (), block1); - store.flush (transaction); - auto begin (store.unchecked_begin (transaction)); - auto end (store.unchecked_end ()); + auto transaction (store->tx_begin_write ()); + store->unchecked_put (transaction, block1->hash (), block1); + store->flush (transaction); + auto begin (store->unchecked_begin (transaction)); + auto end (store->unchecked_end ()); ASSERT_NE (end, begin); nano::uint256_union hash1 (begin->first.key ()); ASSERT_EQ (block1->hash (), hash1); - auto blocks (store.unchecked_get (transaction, hash1)); + auto blocks (store->unchecked_get (transaction, hash1)); ASSERT_EQ (1, blocks.size ()); auto block2 (blocks[0].block); ASSERT_EQ (*block1, *block2); @@ -472,7 +470,7 @@ TEST (block_store, unchecked_begin_search) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_TRUE (!init); nano::keypair key0; nano::send_block block1 (0, 1, 2, key0.prv, key0.pub, 3); @@ -483,14 +481,14 @@ TEST (block_store, frontier_retrieval) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_TRUE (!init); nano::account account1 (0); nano::account_info info1 (0, 0, 0, 0, 0, 0, 0, nano::epoch::epoch_0); - auto transaction (store.tx_begin_write ()); - store.account_put (transaction, account1, info1); + auto transaction (store->tx_begin_write ()); + store->account_put (transaction, account1, info1); nano::account_info info2; - store.account_get (transaction, account1, info2); + store->account_get (transaction, account1, info2); ASSERT_EQ (info1, info2); } @@ -498,14 +496,14 @@ TEST (block_store, one_account) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_TRUE (!init); nano::account account (0); nano::block_hash hash (0); - auto transaction (store.tx_begin_write ()); - store.account_put (transaction, account, { hash, account, hash, 42, 100, 200, 20, nano::epoch::epoch_0 }); - auto begin (store.latest_begin (transaction)); - auto end (store.latest_end ()); + auto transaction (store->tx_begin_write ()); + store->account_put (transaction, account, { hash, account, hash, 42, 100, 200, 20, nano::epoch::epoch_0 }); + auto begin (store->latest_begin (transaction)); + auto end (store->latest_end ()); ASSERT_NE (end, begin); ASSERT_EQ (account, nano::account (begin->first)); nano::account_info info (begin->second); @@ -522,7 +520,7 @@ TEST (block_store, two_block) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_TRUE (!init); nano::open_block block1 (0, 1, 1, nano::keypair ().prv, 0, 0); block1.hashables.account = 1; @@ -530,33 +528,33 @@ TEST (block_store, two_block) std::vector blocks; hashes.push_back (block1.hash ()); blocks.push_back (block1); - auto transaction (store.tx_begin_write ()); + auto transaction (store->tx_begin_write ()); nano::block_sideband sideband1 (nano::block_type::open, 0, 0, 0, 0, 0); - store.block_put (transaction, hashes[0], block1, sideband1); + store->block_put (transaction, hashes[0], block1, sideband1); nano::open_block block2 (0, 1, 2, nano::keypair ().prv, 0, 0); hashes.push_back (block2.hash ()); blocks.push_back (block2); nano::block_sideband sideband2 (nano::block_type::open, 0, 0, 0, 0, 0); - store.block_put (transaction, hashes[1], block2, sideband2); - ASSERT_TRUE (store.block_exists (transaction, block1.hash ())); - ASSERT_TRUE (store.block_exists (transaction, block2.hash ())); + store->block_put (transaction, hashes[1], block2, sideband2); + ASSERT_TRUE (store->block_exists (transaction, block1.hash ())); + ASSERT_TRUE (store->block_exists (transaction, block2.hash ())); } TEST (block_store, two_account) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_TRUE (!init); nano::account account1 (1); nano::block_hash hash1 (2); nano::account account2 (3); nano::block_hash hash2 (4); - auto transaction (store.tx_begin_write ()); - store.account_put (transaction, account1, { hash1, account1, hash1, 42, 100, 300, 20, nano::epoch::epoch_0 }); - store.account_put (transaction, account2, { hash2, account2, hash2, 84, 200, 400, 30, nano::epoch::epoch_0 }); - auto begin (store.latest_begin (transaction)); - auto end (store.latest_end ()); + auto transaction (store->tx_begin_write ()); + store->account_put (transaction, account1, { hash1, account1, hash1, 42, 100, 300, 20, nano::epoch::epoch_0 }); + store->account_put (transaction, account2, { hash2, account2, hash2, 84, 200, 400, 30, nano::epoch::epoch_0 }); + auto begin (store->latest_begin (transaction)); + auto end (store->latest_end ()); ASSERT_NE (end, begin); ASSERT_EQ (account1, nano::account (begin->first)); nano::account_info info1 (begin->second); @@ -582,23 +580,23 @@ TEST (block_store, latest_find) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_TRUE (!init); nano::account account1 (1); nano::block_hash hash1 (2); nano::account account2 (3); nano::block_hash hash2 (4); - auto transaction (store.tx_begin_write ()); - store.account_put (transaction, account1, { hash1, account1, hash1, 100, 0, 300, 0, nano::epoch::epoch_0 }); - store.account_put (transaction, account2, { hash2, account2, hash2, 200, 0, 400, 0, nano::epoch::epoch_0 }); - auto first (store.latest_begin (transaction)); - auto second (store.latest_begin (transaction)); + auto transaction (store->tx_begin_write ()); + store->account_put (transaction, account1, { hash1, account1, hash1, 100, 0, 300, 0, nano::epoch::epoch_0 }); + store->account_put (transaction, account2, { hash2, account2, hash2, 200, 0, 400, 0, nano::epoch::epoch_0 }); + auto first (store->latest_begin (transaction)); + auto second (store->latest_begin (transaction)); ++second; - auto find1 (store.latest_begin (transaction, 1)); + auto find1 (store->latest_begin (transaction, 1)); ASSERT_EQ (first, find1); - auto find2 (store.latest_begin (transaction, 3)); + auto find2 (store->latest_begin (transaction, 3)); ASSERT_EQ (second, find2); - auto find3 (store.latest_begin (transaction, 2)); + auto find3 (store->latest_begin (transaction, 2)); ASSERT_EQ (second, find3); } @@ -606,7 +604,7 @@ TEST (block_store, bad_path) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, boost::filesystem::path ("///")); + auto store = nano::make_store (init, logger, boost::filesystem::path ("///")); ASSERT_TRUE (init); } @@ -620,7 +618,7 @@ TEST (block_store, DISABLED_already_open) // File can be shared ASSERT_TRUE (file.is_open ()); nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, path); + auto store = nano::make_store (init, logger, path); ASSERT_TRUE (init); } @@ -628,7 +626,7 @@ TEST (block_store, roots) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_TRUE (!init); nano::send_block send_block (0, 1, 2, nano::keypair ().prv, 4, 5); ASSERT_EQ (send_block.hashables.previous, send_block.root ()); @@ -644,49 +642,49 @@ TEST (block_store, pending_exists) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_TRUE (!init); nano::pending_key two (2, 0); nano::pending_info pending; - auto transaction (store.tx_begin_write ()); - store.pending_put (transaction, two, pending); + auto transaction (store->tx_begin_write ()); + store->pending_put (transaction, two, pending); nano::pending_key one (1, 0); - ASSERT_FALSE (store.pending_exists (transaction, one)); + ASSERT_FALSE (store->pending_exists (transaction, one)); } TEST (block_store, latest_exists) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_TRUE (!init); nano::block_hash two (2); nano::account_info info; - auto transaction (store.tx_begin_write ()); - store.account_put (transaction, two, info); + auto transaction (store->tx_begin_write ()); + store->account_put (transaction, two, info); nano::block_hash one (1); - ASSERT_FALSE (store.account_exists (transaction, one)); + ASSERT_FALSE (store->account_exists (transaction, one)); } TEST (block_store, large_iteration) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_TRUE (!init); std::unordered_set accounts1; for (auto i (0); i < 1000; ++i) { - auto transaction (store.tx_begin_write ()); + auto transaction (store->tx_begin_write ()); nano::account account; nano::random_pool::generate_block (account.bytes.data (), account.bytes.size ()); accounts1.insert (account); - store.account_put (transaction, account, nano::account_info ()); + store->account_put (transaction, account, nano::account_info ()); } std::unordered_set accounts2; nano::account previous (0); - auto transaction (store.tx_begin_read ()); - for (auto i (store.latest_begin (transaction, 0)), n (store.latest_end ()); i != n; ++i) + auto transaction (store->tx_begin_read ()); + for (auto i (store->latest_begin (transaction, 0)), n (store->latest_end ()); i != n; ++i) { nano::account current (i->first); assert (current.number () > previous.number ()); @@ -700,32 +698,32 @@ TEST (block_store, frontier) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_TRUE (!init); - auto transaction (store.tx_begin_write ()); + auto transaction (store->tx_begin_write ()); nano::block_hash hash (100); nano::account account (200); - ASSERT_TRUE (store.frontier_get (transaction, hash).is_zero ()); - store.frontier_put (transaction, hash, account); - ASSERT_EQ (account, store.frontier_get (transaction, hash)); - store.frontier_del (transaction, hash); - ASSERT_TRUE (store.frontier_get (transaction, hash).is_zero ()); + ASSERT_TRUE (store->frontier_get (transaction, hash).is_zero ()); + store->frontier_put (transaction, hash, account); + ASSERT_EQ (account, store->frontier_get (transaction, hash)); + store->frontier_del (transaction, hash); + ASSERT_TRUE (store->frontier_get (transaction, hash).is_zero ()); } TEST (block_store, block_replace) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_TRUE (!init); nano::send_block send1 (0, 0, 0, nano::keypair ().prv, 0, 1); nano::send_block send2 (0, 0, 0, nano::keypair ().prv, 0, 2); - auto transaction (store.tx_begin_write ()); + auto transaction (store->tx_begin_write ()); nano::block_sideband sideband1 (nano::block_type::send, 0, 0, 0, 0, 0); - store.block_put (transaction, 0, send1, sideband1); + store->block_put (transaction, 0, send1, sideband1); nano::block_sideband sideband2 (nano::block_type::send, 0, 0, 0, 0, 0); - store.block_put (transaction, 0, send2, sideband2); - auto block3 (store.block_get (transaction, 0)); + store->block_put (transaction, 0, send2, sideband2); + auto block3 (store->block_get (transaction, 0)); ASSERT_NE (nullptr, block3); ASSERT_EQ (2, block3->block_work ()); } @@ -734,74 +732,80 @@ TEST (block_store, block_count) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_TRUE (!init); - auto transaction (store.tx_begin_write ()); - ASSERT_EQ (0, store.block_count (transaction).sum ()); - nano::open_block block (0, 1, 0, nano::keypair ().prv, 0, 0); - nano::uint256_union hash1 (block.hash ()); - nano::block_sideband sideband (nano::block_type::open, 0, 0, 0, 0, 0); - store.block_put (transaction, hash1, block, sideband); - ASSERT_EQ (1, store.block_count (transaction).sum ()); + { + auto transaction (store->tx_begin_write ()); + ASSERT_EQ (0, store->block_count (transaction).sum ()); + nano::open_block block (0, 1, 0, nano::keypair ().prv, 0, 0); + nano::uint256_union hash1 (block.hash ()); + nano::block_sideband sideband (nano::block_type::open, 0, 0, 0, 0, 0); + store->block_put (transaction, hash1, block, sideband); + } + auto transaction (store->tx_begin_read ()); + ASSERT_EQ (1, store->block_count (transaction).sum ()); } TEST (block_store, account_count) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_TRUE (!init); - auto transaction (store.tx_begin_write ()); - ASSERT_EQ (0, store.account_count (transaction)); - nano::account account (200); - store.account_put (transaction, account, nano::account_info ()); - ASSERT_EQ (1, store.account_count (transaction)); + { + auto transaction (store->tx_begin_write ()); + ASSERT_EQ (0, store->account_count (transaction)); + nano::account account (200); + store->account_put (transaction, account, nano::account_info ()); + } + auto transaction (store->tx_begin_read ()); + ASSERT_EQ (1, store->account_count (transaction)); } TEST (block_store, cemented_count) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_TRUE (!init); - auto transaction (store.tx_begin_write ()); - ASSERT_EQ (0, store.cemented_count (transaction)); + auto transaction (store->tx_begin_write ()); + ASSERT_EQ (0, store->cemented_count (transaction)); nano::genesis genesis; - store.initialize (transaction, genesis); - ASSERT_EQ (1, store.cemented_count (transaction)); + store->initialize (transaction, genesis); + ASSERT_EQ (1, store->cemented_count (transaction)); } TEST (block_store, sequence_increment) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_TRUE (!init); nano::keypair key1; nano::keypair key2; auto block1 (std::make_shared (0, 1, 0, nano::keypair ().prv, 0, 0)); - auto transaction (store.tx_begin_write ()); - auto vote1 (store.vote_generate (transaction, key1.pub, key1.prv, block1)); + auto transaction (store->tx_begin_write ()); + auto vote1 (store->vote_generate (transaction, key1.pub, key1.prv, block1)); ASSERT_EQ (1, vote1->sequence); - auto vote2 (store.vote_generate (transaction, key1.pub, key1.prv, block1)); + auto vote2 (store->vote_generate (transaction, key1.pub, key1.prv, block1)); ASSERT_EQ (2, vote2->sequence); - auto vote3 (store.vote_generate (transaction, key2.pub, key2.prv, block1)); + auto vote3 (store->vote_generate (transaction, key2.pub, key2.prv, block1)); ASSERT_EQ (1, vote3->sequence); - auto vote4 (store.vote_generate (transaction, key2.pub, key2.prv, block1)); + auto vote4 (store->vote_generate (transaction, key2.pub, key2.prv, block1)); ASSERT_EQ (2, vote4->sequence); vote1->sequence = 20; - auto seq5 (store.vote_max (transaction, vote1)); + auto seq5 (store->vote_max (transaction, vote1)); ASSERT_EQ (20, seq5->sequence); vote3->sequence = 30; - auto seq6 (store.vote_max (transaction, vote3)); + auto seq6 (store->vote_max (transaction, vote3)); ASSERT_EQ (30, seq6->sequence); - auto vote5 (store.vote_generate (transaction, key1.pub, key1.prv, block1)); + auto vote5 (store->vote_generate (transaction, key1.pub, key1.prv, block1)); ASSERT_EQ (21, vote5->sequence); - auto vote6 (store.vote_generate (transaction, key2.pub, key2.prv, block1)); + auto vote6 (store->vote_generate (transaction, key2.pub, key2.prv, block1)); ASSERT_EQ (31, vote6->sequence); } -TEST (block_store, upgrade_v2_v3) +TEST (mdb_block_store, upgrade_v2_v3) { nano::keypair key1; nano::keypair key2; @@ -853,7 +857,7 @@ TEST (block_store, upgrade_v2_v3) ASSERT_EQ (change_hash, info.rep_block); } -TEST (block_store, upgrade_v3_v4) +TEST (mdb_block_store, upgrade_v3_v4) { nano::keypair key1; nano::keypair key2; @@ -887,7 +891,7 @@ TEST (block_store, upgrade_v3_v4) ASSERT_EQ (nano::epoch::epoch_0, info.epoch); } -TEST (block_store, upgrade_v4_v5) +TEST (mdb_block_store, upgrade_v4_v5) { nano::block_hash genesis_hash (0); nano::block_hash hash (0); @@ -928,17 +932,20 @@ TEST (block_store, block_random) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_TRUE (!init); nano::genesis genesis; - auto transaction (store.tx_begin_write ()); - store.initialize (transaction, genesis); - auto block (store.block_random (transaction)); + { + auto transaction (store->tx_begin_write ()); + store->initialize (transaction, genesis); + } + auto transaction (store->tx_begin_read ()); + auto block (store->block_random (transaction)); ASSERT_NE (nullptr, block); ASSERT_EQ (*block, *genesis.open); } -TEST (block_store, upgrade_v5_v6) +TEST (mdb_block_store, upgrade_v5_v6) { auto path (nano::unique_path ()); { @@ -962,7 +969,7 @@ TEST (block_store, upgrade_v5_v6) ASSERT_EQ (1, info.block_count); } -TEST (block_store, upgrade_v6_v7) +TEST (mdb_block_store, upgrade_v6_v7) { auto path (nano::unique_path ()); { @@ -1034,7 +1041,7 @@ TEST (block_store, DISABLED_change_dupsort) // Unchecked is no longer dupsort ta } } -TEST (block_store, upgrade_v7_v8) +TEST (mdb_block_store, upgrade_v7_v8) { auto path (nano::unique_path ()); { @@ -1070,16 +1077,16 @@ TEST (block_store, sequence_flush) auto path (nano::unique_path ()); nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, path); + auto store = nano::make_store (init, logger, path); ASSERT_FALSE (init); - auto transaction (store.tx_begin_write ()); + auto transaction (store->tx_begin_write ()); nano::keypair key1; auto send1 (std::make_shared (0, 0, 0, nano::test_genesis_key.prv, nano::test_genesis_key.pub, 0)); - auto vote1 (store.vote_generate (transaction, key1.pub, key1.prv, send1)); - auto seq2 (store.vote_get (transaction, vote1->account)); + auto vote1 (store->vote_generate (transaction, key1.pub, key1.prv, send1)); + auto seq2 (store->vote_get (transaction, vote1->account)); ASSERT_EQ (nullptr, seq2); - store.flush (transaction); - auto seq3 (store.vote_get (transaction, vote1->account)); + store->flush (transaction); + auto seq3 (store->vote_get (transaction, vote1->account)); ASSERT_EQ (*seq3, *vote1); } @@ -1088,24 +1095,24 @@ TEST (block_store, sequence_flush_by_hash) auto path (nano::unique_path ()); nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, path); + auto store = nano::make_store (init, logger, path); ASSERT_FALSE (init); - auto transaction (store.tx_begin_write ()); + auto transaction (store->tx_begin_write ()); nano::keypair key1; std::vector blocks1; blocks1.push_back (nano::genesis ().hash ()); blocks1.push_back (1234); blocks1.push_back (5678); - auto vote1 (store.vote_generate (transaction, key1.pub, key1.prv, blocks1)); - auto seq2 (store.vote_get (transaction, vote1->account)); + auto vote1 (store->vote_generate (transaction, key1.pub, key1.prv, blocks1)); + auto seq2 (store->vote_get (transaction, vote1->account)); ASSERT_EQ (nullptr, seq2); - store.flush (transaction); - auto seq3 (store.vote_get (transaction, vote1->account)); + store->flush (transaction); + auto seq3 (store->vote_get (transaction, vote1->account)); ASSERT_EQ (*seq3, *vote1); } // Upgrading tracking block sequence numbers to whole vote. -TEST (block_store, upgrade_v8_v9) +TEST (mdb_block_store, upgrade_v8_v9) { auto path (nano::unique_path ()); nano::keypair key; @@ -1135,26 +1142,32 @@ TEST (block_store, state_block) { nano::logger_mt logger; bool error (false); - nano::mdb_store store (error, logger, nano::unique_path ()); + auto store = nano::make_store (error, logger, nano::unique_path ()); ASSERT_FALSE (error); nano::genesis genesis; - auto transaction (store.tx_begin_write ()); - store.initialize (transaction, genesis); nano::keypair key1; nano::state_block block1 (1, genesis.hash (), 3, 4, 6, key1.prv, key1.pub, 7); - ASSERT_EQ (nano::block_type::state, block1.type ()); - nano::block_sideband sideband1 (nano::block_type::state, 0, 0, 0, 0, 0); - store.block_put (transaction, block1.hash (), block1, sideband1); - ASSERT_TRUE (store.block_exists (transaction, block1.hash ())); - auto block2 (store.block_get (transaction, block1.hash ())); - ASSERT_NE (nullptr, block2); - ASSERT_EQ (block1, *block2); - auto count (store.block_count (transaction)); - ASSERT_EQ (1, count.state_v0); - ASSERT_EQ (0, count.state_v1); - store.block_del (transaction, block1.hash ()); - ASSERT_FALSE (store.block_exists (transaction, block1.hash ())); - auto count2 (store.block_count (transaction)); + { + auto transaction (store->tx_begin_write ()); + store->initialize (transaction, genesis); + ASSERT_EQ (nano::block_type::state, block1.type ()); + nano::block_sideband sideband1 (nano::block_type::state, 0, 0, 0, 0, 0); + store->block_put (transaction, block1.hash (), block1, sideband1); + ASSERT_TRUE (store->block_exists (transaction, block1.hash ())); + auto block2 (store->block_get (transaction, block1.hash ())); + ASSERT_NE (nullptr, block2); + ASSERT_EQ (block1, *block2); + } + { + auto transaction (store->tx_begin_write ()); + auto count (store->block_count (transaction)); + ASSERT_EQ (1, count.state_v0); + ASSERT_EQ (0, count.state_v1); + store->block_del (transaction, block1.hash ()); + ASSERT_FALSE (store->block_exists (transaction, block1.hash ())); + } + auto transaction (store->tx_begin_read ()); + auto count2 (store->block_count (transaction)); ASSERT_EQ (0, count2.state_v0); ASSERT_EQ (0, count2.state_v1); } @@ -1180,7 +1193,7 @@ void write_legacy_sideband (nano::mdb_store & store_a, nano::transaction & trans }; } -TEST (block_store, upgrade_sideband_genesis) +TEST (mdb_block_store, upgrade_sideband_genesis) { bool error (false); nano::genesis genesis; @@ -1213,7 +1226,7 @@ TEST (block_store, upgrade_sideband_genesis) ASSERT_EQ (1, sideband.height); } -TEST (block_store, upgrade_sideband_two_blocks) +TEST (mdb_block_store, upgrade_sideband_two_blocks) { bool error (false); nano::genesis genesis; @@ -1251,7 +1264,7 @@ TEST (block_store, upgrade_sideband_two_blocks) ASSERT_EQ (2, sideband2.height); } -TEST (block_store, upgrade_sideband_two_accounts) +TEST (mdb_block_store, upgrade_sideband_two_accounts) { bool error (false); nano::genesis genesis; @@ -1300,7 +1313,7 @@ TEST (block_store, upgrade_sideband_two_accounts) ASSERT_EQ (1, sideband3.height); } -TEST (block_store, insert_after_legacy) +TEST (mdb_block_store, insert_after_legacy) { nano::logger_mt logger; bool error (false); @@ -1319,7 +1332,7 @@ TEST (block_store, insert_after_legacy) } // Account for an open block should be retrievable -TEST (block_store, legacy_account_computed) +TEST (mdb_block_store, legacy_account_computed) { nano::logger_mt logger; bool init (false); @@ -1335,7 +1348,7 @@ TEST (block_store, legacy_account_computed) ASSERT_EQ (nano::genesis_account, ledger.account (transaction, genesis.hash ())); } -TEST (block_store, upgrade_sideband_epoch) +TEST (mdb_block_store, upgrade_sideband_epoch) { bool error (false); nano::genesis genesis; @@ -1375,7 +1388,7 @@ TEST (block_store, upgrade_sideband_epoch) ASSERT_EQ (nano::epoch::epoch_1, store.block_version (transaction, block2.hash ())); } -TEST (block_store, sideband_height) +TEST (mdb_block_store, sideband_height) { nano::logger_mt logger; bool error (false); @@ -1458,38 +1471,66 @@ TEST (block_store, peers) { nano::logger_mt logger; auto init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_TRUE (!init); - auto transaction (store.tx_begin_write ()); nano::endpoint_key endpoint (boost::asio::ip::address_v6::any ().to_bytes (), 100); + { + auto transaction (store->tx_begin_write ()); - // Confirm that the store is empty - ASSERT_FALSE (store.peer_exists (transaction, endpoint)); - ASSERT_EQ (store.peer_count (transaction), 0); + // Confirm that the store is empty + ASSERT_FALSE (store->peer_exists (transaction, endpoint)); + ASSERT_EQ (store->peer_count (transaction), 0); - // Add one, confirm that it can be found - store.peer_put (transaction, endpoint); - ASSERT_TRUE (store.peer_exists (transaction, endpoint)); - ASSERT_EQ (store.peer_count (transaction), 1); + // Add one + store->peer_put (transaction, endpoint); + ASSERT_TRUE (store->peer_exists (transaction, endpoint)); + } + + // Confirm that it can be found + { + auto transaction (store->tx_begin_read ()); + ASSERT_EQ (store->peer_count (transaction), 1); + } // Add another one and check that it (and the existing one) can be found nano::endpoint_key endpoint1 (boost::asio::ip::address_v6::any ().to_bytes (), 101); - store.peer_put (transaction, endpoint1); - ASSERT_TRUE (store.peer_exists (transaction, endpoint1)); // Check new peer is here - ASSERT_TRUE (store.peer_exists (transaction, endpoint)); // Check first peer is still here - ASSERT_EQ (store.peer_count (transaction), 2); + { + auto transaction (store->tx_begin_write ()); + store->peer_put (transaction, endpoint1); + ASSERT_TRUE (store->peer_exists (transaction, endpoint1)); // Check new peer is here + ASSERT_TRUE (store->peer_exists (transaction, endpoint)); // Check first peer is still here + } + + { + auto transaction (store->tx_begin_read ()); + ASSERT_EQ (store->peer_count (transaction), 2); + } // Delete the first one - store.peer_del (transaction, endpoint1); - ASSERT_FALSE (store.peer_exists (transaction, endpoint1)); // Confirm it no longer exists - ASSERT_TRUE (store.peer_exists (transaction, endpoint)); // Check first peer is still here - ASSERT_EQ (store.peer_count (transaction), 1); + { + auto transaction (store->tx_begin_write ()); + store->peer_del (transaction, endpoint1); + ASSERT_FALSE (store->peer_exists (transaction, endpoint1)); // Confirm it no longer exists + ASSERT_TRUE (store->peer_exists (transaction, endpoint)); // Check first peer is still here + } + + { + auto transaction (store->tx_begin_read ()); + ASSERT_EQ (store->peer_count (transaction), 1); + } // Delete original one - store.peer_del (transaction, endpoint); - ASSERT_EQ (store.peer_count (transaction), 0); - ASSERT_FALSE (store.peer_exists (transaction, endpoint)); + { + auto transaction (store->tx_begin_write ()); + store->peer_del (transaction, endpoint); + ASSERT_FALSE (store->peer_exists (transaction, endpoint)); + } + + { + auto transaction (store->tx_begin_read ()); + ASSERT_EQ (store->peer_count (transaction), 0); + } } TEST (block_store, endpoint_key_byte_order) @@ -1529,24 +1570,30 @@ TEST (block_store, online_weight) { nano::logger_mt logger; bool error (false); - nano::mdb_store store (error, logger, nano::unique_path ()); + auto store = nano::make_store (error, logger, nano::unique_path ()); ASSERT_FALSE (error); - auto transaction (store.tx_begin_write ()); - ASSERT_EQ (0, store.online_weight_count (transaction)); - ASSERT_EQ (store.online_weight_end (), store.online_weight_begin (transaction)); - store.online_weight_put (transaction, 1, 2); - ASSERT_EQ (1, store.online_weight_count (transaction)); - auto item (store.online_weight_begin (transaction)); - ASSERT_NE (store.online_weight_end (), item); - ASSERT_EQ (1, item->first); - ASSERT_EQ (2, item->second.number ()); - store.online_weight_del (transaction, 1); - ASSERT_EQ (0, store.online_weight_count (transaction)); - ASSERT_EQ (store.online_weight_end (), store.online_weight_begin (transaction)); + { + auto transaction (store->tx_begin_write ()); + ASSERT_EQ (0, store->online_weight_count (transaction)); + ASSERT_EQ (store->online_weight_end (), store->online_weight_begin (transaction)); + store->online_weight_put (transaction, 1, 2); + } + { + auto transaction (store->tx_begin_write ()); + ASSERT_EQ (1, store->online_weight_count (transaction)); + auto item (store->online_weight_begin (transaction)); + ASSERT_NE (store->online_weight_end (), item); + ASSERT_EQ (1, item->first); + ASSERT_EQ (2, item->second.number ()); + store->online_weight_del (transaction, 1); + } + auto transaction (store->tx_begin_read ()); + ASSERT_EQ (0, store->online_weight_count (transaction)); + ASSERT_EQ (store->online_weight_end (), store->online_weight_begin (transaction)); } // Adding confirmation height to accounts -TEST (block_store, upgrade_v13_v14) +TEST (mdb_block_store, upgrade_v13_v14) { auto path (nano::unique_path ()); { @@ -1594,32 +1641,33 @@ TEST (block_store, confirmation_height) nano::logger_mt logger; auto error (false); nano::mdb_store store (error, logger, path); - auto transaction (store.tx_begin_write ()); nano::account account1 (0); nano::account_info info1 (0, 0, 0, 0, 0, 0, 500, nano::epoch::epoch_0); - store.account_put (transaction, account1, info1); - nano::account account2 (1); nano::account_info info2 (0, 0, 0, 0, 0, 0, std::numeric_limits::max (), nano::epoch::epoch_0); - store.account_put (transaction, account2, info2); - nano::account account3 (2); nano::account_info info3 (0, 0, 0, 0, 0, 0, 10, nano::epoch::epoch_0); - store.account_put (transaction, account3, info3); - nano::account_info stored_account_info; - ASSERT_FALSE (store.account_get (transaction, account1, stored_account_info)); - ASSERT_EQ (stored_account_info.confirmation_height, 500); + { + auto transaction (store.tx_begin_write ()); + store.account_put (transaction, account1, info1); + store.account_put (transaction, account2, info2); + store.account_put (transaction, account3, info3); - ASSERT_FALSE (store.account_get (transaction, account2, stored_account_info)); - ASSERT_EQ (stored_account_info.confirmation_height, std::numeric_limits::max ()); + ASSERT_FALSE (store.account_get (transaction, account1, stored_account_info)); + ASSERT_EQ (stored_account_info.confirmation_height, 500); - ASSERT_FALSE (store.account_get (transaction, account3, stored_account_info)); - ASSERT_EQ (stored_account_info.confirmation_height, 10); + ASSERT_FALSE (store.account_get (transaction, account2, stored_account_info)); + ASSERT_EQ (stored_account_info.confirmation_height, std::numeric_limits::max ()); - // Check cleaning of confirmation heights - store.confirmation_height_clear (transaction); + ASSERT_FALSE (store.account_get (transaction, account3, stored_account_info)); + ASSERT_EQ (stored_account_info.confirmation_height, 10); + + // Check cleaning of confirmation heights + store.confirmation_height_clear (transaction); + } + auto transaction (store.tx_begin_read ()); ASSERT_EQ (store.account_count (transaction), 3); ASSERT_FALSE (store.account_get (transaction, account1, stored_account_info)); @@ -1689,18 +1737,18 @@ TEST (block_store, incompatible_version) nano::logger_mt logger; { auto error (false); - nano::mdb_store store (error, logger, path); + auto store = nano::make_store (error, logger, path); ASSERT_FALSE (error); // Put version to an unreachable number so that it should always be incompatible - auto transaction (store.tx_begin_write ()); - store.version_put (transaction, std::numeric_limits::max ()); + auto transaction (store->tx_begin_write ()); + store->version_put (transaction, std::numeric_limits::max ()); } // Now try and read it, should give an error { auto error (false); - nano::mdb_store store (error, logger, path); + auto store = nano::make_store (error, logger, path); ASSERT_TRUE (error); } } @@ -1709,16 +1757,16 @@ TEST (block_store, reset_renew_existing_transaction) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_TRUE (!init); nano::keypair key1; nano::open_block block (0, 1, 1, nano::keypair ().prv, 0, 0); nano::uint256_union hash1 (block.hash ()); - auto read_transaction = store.tx_begin_read (); + auto read_transaction = store->tx_begin_read (); // Block shouldn't exist yet - auto block_non_existing (store.block_get (read_transaction, hash1)); + auto block_non_existing (store->block_get (read_transaction, hash1)); ASSERT_EQ (nullptr, block_non_existing); // Release resources for the transaction @@ -1726,15 +1774,15 @@ TEST (block_store, reset_renew_existing_transaction) // Write the block { - auto write_transaction (store.tx_begin_write ()); + auto write_transaction (store->tx_begin_write ()); nano::block_sideband sideband (nano::block_type::open, 0, 0, 0, 0, 0); - store.block_put (write_transaction, hash1, block, sideband); + store->block_put (write_transaction, hash1, block, sideband); } read_transaction.renew (); // Block should exist now - auto block_existing (store.block_get (read_transaction, hash1)); + auto block_existing (store->block_get (read_transaction, hash1)); ASSERT_NE (nullptr, block_existing); } @@ -1746,7 +1794,7 @@ void modify_account_info_to_v13 (nano::mdb_store & store, nano::transaction cons nano::account_info info; ASSERT_FALSE (store.account_get (transaction_a, account, info)); nano::account_info_v13 account_info_v13 (info.head, info.rep_block, info.open_block, info.balance, info.modified, info.block_count, info.epoch); - auto status (mdb_put (store.env.tx (transaction_a), store.get_account_db (info.epoch), nano::mdb_val (account), nano::mdb_val (account_info_v13), 0)); + auto status (mdb_put (store.env.tx (transaction_a), store.get_account_db (info.epoch) == nano::block_store_partial::tables::accounts_v0 ? store.accounts_v0 : store.accounts_v1, nano::mdb_val (account), nano::mdb_val (account_info_v13), 0)); (void)status; assert (status == 0); } diff --git a/nano/core_test/ledger.cpp b/nano/core_test/ledger.cpp index e28b111d..cad65f1d 100644 --- a/nano/core_test/ledger.cpp +++ b/nano/core_test/ledger.cpp @@ -13,10 +13,10 @@ TEST (ledger, store_error) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, boost::filesystem::path ("///")); + auto store = nano::make_store (init, logger, boost::filesystem::path ("///")); ASSERT_FALSE (!init); nano::stat stats; - nano::ledger ledger (store, stats); + nano::ledger ledger (*store, stats); } // Ledger can be initialized and returns a basic query for an empty account @@ -24,12 +24,12 @@ TEST (ledger, empty) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_TRUE (!init); nano::stat stats; - nano::ledger ledger (store, stats); + nano::ledger ledger (*store, stats); nano::account account; - auto transaction (store.tx_begin_read ()); + auto transaction (store->tx_begin_read ()); auto balance (ledger.account_balance (transaction, account)); ASSERT_TRUE (balance.is_zero ()); } @@ -39,19 +39,19 @@ TEST (ledger, genesis_balance) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_TRUE (!init); nano::stat stats; - nano::ledger ledger (store, stats); + nano::ledger ledger (*store, stats); nano::genesis genesis; - auto transaction (store.tx_begin_write ()); - store.initialize (transaction, genesis); + auto transaction (store->tx_begin_write ()); + store->initialize (transaction, genesis); auto balance (ledger.account_balance (transaction, nano::genesis_account)); ASSERT_EQ (nano::genesis_amount, balance); auto amount (ledger.amount (transaction, nano::genesis_account)); ASSERT_EQ (nano::genesis_amount, amount); nano::account_info info; - ASSERT_FALSE (store.account_get (transaction, nano::genesis_account, info)); + ASSERT_FALSE (store->account_get (transaction, nano::genesis_account, info)); // Frontier time should have been updated when genesis balance was added ASSERT_GE (nano::seconds_since_epoch (), info.modified); ASSERT_LT (nano::seconds_since_epoch () - info.modified, 10); @@ -75,35 +75,35 @@ TEST (ledger, process_send) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_TRUE (!init); nano::stat stats; - nano::ledger ledger (store, stats); - auto transaction (store.tx_begin_write ()); + nano::ledger ledger (*store, stats); + auto transaction (store->tx_begin_write ()); nano::genesis genesis; - store.initialize (transaction, genesis); + store->initialize (transaction, genesis); nano::work_pool pool (std::numeric_limits::max ()); nano::account_info info1; - ASSERT_FALSE (store.account_get (transaction, nano::test_genesis_key.pub, info1)); + ASSERT_FALSE (store->account_get (transaction, nano::test_genesis_key.pub, info1)); nano::keypair key2; nano::send_block send (info1.head, key2.pub, 50, nano::test_genesis_key.prv, nano::test_genesis_key.pub, pool.generate (info1.head)); nano::block_hash hash1 (send.hash ()); - ASSERT_EQ (nano::test_genesis_key.pub, store.frontier_get (transaction, info1.head)); + ASSERT_EQ (nano::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 (nano::genesis_amount - 50, ledger.amount (transaction, hash1)); - ASSERT_TRUE (store.frontier_get (transaction, info1.head).is_zero ()); - ASSERT_EQ (nano::test_genesis_key.pub, store.frontier_get (transaction, hash1)); + ASSERT_TRUE (store->frontier_get (transaction, info1.head).is_zero ()); + ASSERT_EQ (nano::test_genesis_key.pub, store->frontier_get (transaction, hash1)); ASSERT_EQ (nano::process_result::progress, return1.code); ASSERT_EQ (nano::test_genesis_key.pub, return1.account); ASSERT_EQ (nano::genesis_amount - 50, return1.amount.number ()); ASSERT_EQ (50, ledger.account_balance (transaction, nano::test_genesis_key.pub)); ASSERT_EQ (nano::genesis_amount - 50, ledger.account_pending (transaction, key2.pub)); nano::account_info info2; - ASSERT_FALSE (store.account_get (transaction, nano::test_genesis_key.pub, info2)); + ASSERT_FALSE (store->account_get (transaction, nano::test_genesis_key.pub, info2)); ASSERT_EQ (2, info2.block_count); - auto latest6 (store.block_get (transaction, info2.head)); + auto latest6 (store->block_get (transaction, info2.head)); ASSERT_NE (nullptr, latest6); auto latest7 (dynamic_cast (latest6.get ())); ASSERT_NE (nullptr, latest7); @@ -117,27 +117,27 @@ TEST (ledger, process_send) ASSERT_EQ (nano::process_result::progress, return2.code); ASSERT_EQ (key2.pub, return2.account); ASSERT_EQ (nano::genesis_amount - 50, return2.amount.number ()); - ASSERT_EQ (key2.pub, store.frontier_get (transaction, hash2)); + ASSERT_EQ (key2.pub, store->frontier_get (transaction, hash2)); ASSERT_EQ (nano::genesis_amount - 50, ledger.account_balance (transaction, key2.pub)); ASSERT_EQ (0, ledger.account_pending (transaction, key2.pub)); ASSERT_EQ (50, ledger.weight (transaction, nano::test_genesis_key.pub)); ASSERT_EQ (nano::genesis_amount - 50, ledger.weight (transaction, key2.pub)); nano::account_info info3; - ASSERT_FALSE (store.account_get (transaction, nano::test_genesis_key.pub, info3)); - auto latest2 (store.block_get (transaction, info3.head)); + ASSERT_FALSE (store->account_get (transaction, nano::test_genesis_key.pub, info3)); + auto latest2 (store->block_get (transaction, info3.head)); ASSERT_NE (nullptr, latest2); auto latest3 (dynamic_cast (latest2.get ())); ASSERT_NE (nullptr, latest3); ASSERT_EQ (send, *latest3); nano::account_info info4; - ASSERT_FALSE (store.account_get (transaction, key2.pub, info4)); - auto latest4 (store.block_get (transaction, info4.head)); + ASSERT_FALSE (store->account_get (transaction, key2.pub, info4)); + auto latest4 (store->block_get (transaction, info4.head)); ASSERT_NE (nullptr, latest4); auto latest5 (dynamic_cast (latest4.get ())); ASSERT_NE (nullptr, latest5); ASSERT_EQ (open, *latest5); ASSERT_FALSE (ledger.rollback (transaction, hash2)); - ASSERT_TRUE (store.frontier_get (transaction, hash2).is_zero ()); + ASSERT_TRUE (store->frontier_get (transaction, hash2).is_zero ()); nano::account_info info5; ASSERT_TRUE (ledger.store.account_get (transaction, key2.pub, info5)); nano::pending_info pending1; @@ -154,8 +154,8 @@ TEST (ledger, process_send) ASSERT_EQ (hash1, info6.head); ASSERT_FALSE (ledger.rollback (transaction, info6.head)); ASSERT_EQ (nano::genesis_amount, ledger.weight (transaction, nano::test_genesis_key.pub)); - ASSERT_EQ (nano::test_genesis_key.pub, store.frontier_get (transaction, info1.head)); - ASSERT_TRUE (store.frontier_get (transaction, hash1).is_zero ()); + ASSERT_EQ (nano::test_genesis_key.pub, store->frontier_get (transaction, info1.head)); + ASSERT_TRUE (store->frontier_get (transaction, hash1).is_zero ()); nano::account_info info7; ASSERT_FALSE (ledger.store.account_get (transaction, nano::test_genesis_key.pub, info7)); ASSERT_EQ (1, info7.block_count); @@ -170,16 +170,16 @@ TEST (ledger, process_receive) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_TRUE (!init); nano::stat stats; - nano::ledger ledger (store, stats); + nano::ledger ledger (*store, stats); nano::genesis genesis; - auto transaction (store.tx_begin_write ()); - store.initialize (transaction, genesis); + auto transaction (store->tx_begin_write ()); + store->initialize (transaction, genesis); nano::work_pool pool (std::numeric_limits::max ()); nano::account_info info1; - ASSERT_FALSE (store.account_get (transaction, nano::test_genesis_key.pub, info1)); + ASSERT_FALSE (store->account_get (transaction, nano::test_genesis_key.pub, info1)); nano::keypair key2; nano::send_block send (info1.head, key2.pub, 50, nano::test_genesis_key.prv, nano::test_genesis_key.pub, pool.generate (info1.head)); nano::block_hash hash1 (send.hash ()); @@ -197,11 +197,11 @@ TEST (ledger, process_receive) ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, send2).code); nano::receive_block receive (hash2, hash3, key2.prv, key2.pub, pool.generate (hash2)); auto hash4 (receive.hash ()); - ASSERT_EQ (key2.pub, store.frontier_get (transaction, hash2)); + ASSERT_EQ (key2.pub, store->frontier_get (transaction, hash2)); auto return2 (ledger.process (transaction, receive)); ASSERT_EQ (25, ledger.amount (transaction, hash4)); - ASSERT_TRUE (store.frontier_get (transaction, hash2).is_zero ()); - ASSERT_EQ (key2.pub, store.frontier_get (transaction, hash4)); + ASSERT_TRUE (store->frontier_get (transaction, hash2).is_zero ()); + ASSERT_EQ (key2.pub, store->frontier_get (transaction, hash4)); ASSERT_EQ (nano::process_result::progress, return2.code); ASSERT_EQ (key2.pub, return2.account); ASSERT_EQ (25, return2.amount.number ()); @@ -211,9 +211,9 @@ TEST (ledger, process_receive) ASSERT_EQ (nano::genesis_amount - 25, ledger.account_balance (transaction, key2.pub)); ASSERT_EQ (nano::genesis_amount - 25, ledger.weight (transaction, key3.pub)); ASSERT_FALSE (ledger.rollback (transaction, hash4)); - ASSERT_TRUE (store.block_successor (transaction, hash2).is_zero ()); - ASSERT_EQ (key2.pub, store.frontier_get (transaction, hash2)); - ASSERT_TRUE (store.frontier_get (transaction, hash4).is_zero ()); + ASSERT_TRUE (store->block_successor (transaction, hash2).is_zero ()); + ASSERT_EQ (key2.pub, store->frontier_get (transaction, hash2)); + ASSERT_TRUE (store->frontier_get (transaction, hash4).is_zero ()); ASSERT_EQ (25, ledger.account_balance (transaction, nano::test_genesis_key.pub)); ASSERT_EQ (25, ledger.account_pending (transaction, key2.pub)); ASSERT_EQ (nano::genesis_amount - 50, ledger.account_balance (transaction, key2.pub)); @@ -229,16 +229,16 @@ TEST (ledger, rollback_receiver) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_TRUE (!init); nano::stat stats; - nano::ledger ledger (store, stats); + nano::ledger ledger (*store, stats); nano::genesis genesis; - auto transaction (store.tx_begin_write ()); - store.initialize (transaction, genesis); + auto transaction (store->tx_begin_write ()); + store->initialize (transaction, genesis); nano::work_pool pool (std::numeric_limits::max ()); nano::account_info info1; - ASSERT_FALSE (store.account_get (transaction, nano::test_genesis_key.pub, info1)); + ASSERT_FALSE (store->account_get (transaction, nano::test_genesis_key.pub, info1)); nano::keypair key2; nano::send_block send (info1.head, key2.pub, 50, nano::test_genesis_key.prv, nano::test_genesis_key.pub, pool.generate (info1.head)); nano::block_hash hash1 (send.hash ()); @@ -269,13 +269,13 @@ TEST (ledger, rollback_representation) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_TRUE (!init); nano::stat stats; - nano::ledger ledger (store, stats); + nano::ledger ledger (*store, stats); nano::genesis genesis; - auto transaction (store.tx_begin_write ()); - store.initialize (transaction, genesis); + auto transaction (store->tx_begin_write ()); + store->initialize (transaction, genesis); nano::work_pool pool (std::numeric_limits::max ()); nano::keypair key5; nano::change_block change1 (genesis.hash (), key5.pub, nano::test_genesis_key.prv, nano::test_genesis_key.pub, pool.generate (genesis.hash ())); @@ -296,11 +296,11 @@ TEST (ledger, rollback_representation) ASSERT_EQ (1, ledger.weight (transaction, key3.pub)); ASSERT_EQ (nano::genesis_amount - 1, ledger.weight (transaction, key4.pub)); nano::account_info info1; - ASSERT_FALSE (store.account_get (transaction, key2.pub, info1)); + ASSERT_FALSE (store->account_get (transaction, key2.pub, info1)); ASSERT_EQ (open.hash (), info1.rep_block); ASSERT_FALSE (ledger.rollback (transaction, receive1.hash ())); nano::account_info info2; - ASSERT_FALSE (store.account_get (transaction, key2.pub, info2)); + ASSERT_FALSE (store->account_get (transaction, key2.pub, info2)); ASSERT_EQ (open.hash (), info2.rep_block); ASSERT_EQ (0, ledger.weight (transaction, key2.pub)); ASSERT_EQ (nano::genesis_amount - 50, ledger.weight (transaction, key4.pub)); @@ -310,11 +310,11 @@ TEST (ledger, rollback_representation) ledger.rollback (transaction, send1.hash ()); ASSERT_EQ (nano::genesis_amount, ledger.weight (transaction, key3.pub)); nano::account_info info3; - ASSERT_FALSE (store.account_get (transaction, nano::test_genesis_key.pub, info3)); + ASSERT_FALSE (store->account_get (transaction, nano::test_genesis_key.pub, info3)); ASSERT_EQ (change2.hash (), info3.rep_block); ASSERT_FALSE (ledger.rollback (transaction, change2.hash ())); nano::account_info info4; - ASSERT_FALSE (store.account_get (transaction, nano::test_genesis_key.pub, info4)); + ASSERT_FALSE (store->account_get (transaction, nano::test_genesis_key.pub, info4)); ASSERT_EQ (change1.hash (), info4.rep_block); ASSERT_EQ (nano::genesis_amount, ledger.weight (transaction, key5.pub)); ASSERT_EQ (0, ledger.weight (transaction, key3.pub)); @@ -324,13 +324,13 @@ TEST (ledger, receive_rollback) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_TRUE (!init); nano::stat stats; - nano::ledger ledger (store, stats); + nano::ledger ledger (*store, stats); nano::genesis genesis; - auto transaction (store.tx_begin_write ()); - store.initialize (transaction, genesis); + auto transaction (store->tx_begin_write ()); + store->initialize (transaction, genesis); nano::work_pool pool (std::numeric_limits::max ()); nano::send_block send (genesis.hash (), nano::test_genesis_key.pub, nano::genesis_amount - nano::Gxrb_ratio, nano::test_genesis_key.prv, nano::test_genesis_key.pub, pool.generate (genesis.hash ())); ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, send).code); @@ -343,16 +343,16 @@ TEST (ledger, process_duplicate) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_TRUE (!init); nano::stat stats; - nano::ledger ledger (store, stats); + nano::ledger ledger (*store, stats); nano::genesis genesis; - auto transaction (store.tx_begin_write ()); - store.initialize (transaction, genesis); + auto transaction (store->tx_begin_write ()); + store->initialize (transaction, genesis); nano::work_pool pool (std::numeric_limits::max ()); nano::account_info info1; - ASSERT_FALSE (store.account_get (transaction, nano::test_genesis_key.pub, info1)); + ASSERT_FALSE (store->account_get (transaction, nano::test_genesis_key.pub, info1)); nano::keypair key2; nano::send_block send (info1.head, key2.pub, 50, nano::test_genesis_key.prv, nano::test_genesis_key.pub, pool.generate (info1.head)); nano::block_hash hash1 (send.hash ()); @@ -367,13 +367,13 @@ TEST (ledger, representative_genesis) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_TRUE (!init); nano::stat stats; - nano::ledger ledger (store, stats); + nano::ledger ledger (*store, stats); nano::genesis genesis; - auto transaction (store.tx_begin_write ()); - store.initialize (transaction, genesis); + auto transaction (store->tx_begin_write ()); + store->initialize (transaction, genesis); auto latest (ledger.latest (transaction, nano::test_genesis_key.pub)); ASSERT_FALSE (latest.is_zero ()); ASSERT_EQ (genesis.open->hash (), ledger.representative (transaction, latest)); @@ -383,13 +383,13 @@ TEST (ledger, weight) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_TRUE (!init); nano::stat stats; - nano::ledger ledger (store, stats); + nano::ledger ledger (*store, stats); nano::genesis genesis; - auto transaction (store.tx_begin_write ()); - store.initialize (transaction, genesis); + auto transaction (store->tx_begin_write ()); + store->initialize (transaction, genesis); ASSERT_EQ (nano::genesis_amount, ledger.weight (transaction, nano::genesis_account)); } @@ -397,37 +397,37 @@ TEST (ledger, representative_change) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_TRUE (!init); nano::stat stats; - nano::ledger ledger (store, stats); + nano::ledger ledger (*store, stats); nano::keypair key2; nano::genesis genesis; - auto transaction (store.tx_begin_write ()); - store.initialize (transaction, genesis); + auto transaction (store->tx_begin_write ()); + store->initialize (transaction, genesis); nano::work_pool pool (std::numeric_limits::max ()); ASSERT_EQ (nano::genesis_amount, ledger.weight (transaction, nano::test_genesis_key.pub)); ASSERT_EQ (0, ledger.weight (transaction, key2.pub)); nano::account_info info1; - ASSERT_FALSE (store.account_get (transaction, nano::test_genesis_key.pub, info1)); + ASSERT_FALSE (store->account_get (transaction, nano::test_genesis_key.pub, info1)); nano::change_block block (info1.head, key2.pub, nano::test_genesis_key.prv, nano::test_genesis_key.pub, pool.generate (info1.head)); - ASSERT_EQ (nano::test_genesis_key.pub, store.frontier_get (transaction, info1.head)); + ASSERT_EQ (nano::test_genesis_key.pub, store->frontier_get (transaction, info1.head)); auto return1 (ledger.process (transaction, block)); ASSERT_EQ (0, ledger.amount (transaction, block.hash ())); - ASSERT_TRUE (store.frontier_get (transaction, info1.head).is_zero ()); - ASSERT_EQ (nano::test_genesis_key.pub, store.frontier_get (transaction, block.hash ())); + ASSERT_TRUE (store->frontier_get (transaction, info1.head).is_zero ()); + ASSERT_EQ (nano::test_genesis_key.pub, store->frontier_get (transaction, block.hash ())); ASSERT_EQ (nano::process_result::progress, return1.code); ASSERT_EQ (nano::test_genesis_key.pub, return1.account); ASSERT_EQ (0, ledger.weight (transaction, nano::test_genesis_key.pub)); ASSERT_EQ (nano::genesis_amount, ledger.weight (transaction, key2.pub)); nano::account_info info2; - ASSERT_FALSE (store.account_get (transaction, nano::test_genesis_key.pub, info2)); + ASSERT_FALSE (store->account_get (transaction, nano::test_genesis_key.pub, info2)); ASSERT_EQ (block.hash (), info2.head); ASSERT_FALSE (ledger.rollback (transaction, info2.head)); - ASSERT_EQ (nano::test_genesis_key.pub, store.frontier_get (transaction, info1.head)); - ASSERT_TRUE (store.frontier_get (transaction, block.hash ()).is_zero ()); + ASSERT_EQ (nano::test_genesis_key.pub, store->frontier_get (transaction, info1.head)); + ASSERT_TRUE (store->frontier_get (transaction, block.hash ()).is_zero ()); nano::account_info info3; - ASSERT_FALSE (store.account_get (transaction, nano::test_genesis_key.pub, info3)); + ASSERT_FALSE (store->account_get (transaction, nano::test_genesis_key.pub, info3)); ASSERT_EQ (info1.head, info3.head); ASSERT_EQ (nano::genesis_amount, ledger.weight (transaction, nano::test_genesis_key.pub)); ASSERT_EQ (0, ledger.weight (transaction, key2.pub)); @@ -437,18 +437,18 @@ TEST (ledger, send_fork) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_TRUE (!init); nano::stat stats; - nano::ledger ledger (store, stats); + nano::ledger ledger (*store, stats); nano::keypair key2; nano::keypair key3; nano::genesis genesis; - auto transaction (store.tx_begin_write ()); - store.initialize (transaction, genesis); + auto transaction (store->tx_begin_write ()); + store->initialize (transaction, genesis); nano::work_pool pool (std::numeric_limits::max ()); nano::account_info info1; - ASSERT_FALSE (store.account_get (transaction, nano::test_genesis_key.pub, info1)); + ASSERT_FALSE (store->account_get (transaction, nano::test_genesis_key.pub, info1)); nano::send_block block (info1.head, key2.pub, 100, nano::test_genesis_key.prv, nano::test_genesis_key.pub, pool.generate (info1.head)); ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, block).code); nano::send_block block2 (info1.head, key3.pub, 0, nano::test_genesis_key.prv, nano::test_genesis_key.pub, pool.generate (info1.head)); @@ -459,18 +459,18 @@ TEST (ledger, receive_fork) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_TRUE (!init); nano::stat stats; - nano::ledger ledger (store, stats); + nano::ledger ledger (*store, stats); nano::keypair key2; nano::keypair key3; nano::genesis genesis; - auto transaction (store.tx_begin_write ()); - store.initialize (transaction, genesis); + auto transaction (store->tx_begin_write ()); + store->initialize (transaction, genesis); nano::work_pool pool (std::numeric_limits::max ()); nano::account_info info1; - ASSERT_FALSE (store.account_get (transaction, nano::test_genesis_key.pub, info1)); + ASSERT_FALSE (store->account_get (transaction, nano::test_genesis_key.pub, info1)); nano::send_block block (info1.head, key2.pub, 100, nano::test_genesis_key.prv, nano::test_genesis_key.pub, pool.generate (info1.head)); ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, block).code); nano::open_block block2 (block.hash (), key2.pub, key2.pub, key2.prv, key2.pub, pool.generate (key2.pub)); @@ -487,18 +487,18 @@ TEST (ledger, open_fork) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_TRUE (!init); nano::stat stats; - nano::ledger ledger (store, stats); + nano::ledger ledger (*store, stats); nano::keypair key2; nano::keypair key3; nano::genesis genesis; - auto transaction (store.tx_begin_write ()); - store.initialize (transaction, genesis); + auto transaction (store->tx_begin_write ()); + store->initialize (transaction, genesis); nano::work_pool pool (std::numeric_limits::max ()); nano::account_info info1; - ASSERT_FALSE (store.account_get (transaction, nano::test_genesis_key.pub, info1)); + ASSERT_FALSE (store->account_get (transaction, nano::test_genesis_key.pub, info1)); nano::send_block block (info1.head, key2.pub, 100, nano::test_genesis_key.prv, nano::test_genesis_key.pub, pool.generate (info1.head)); ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, block).code); nano::open_block block2 (block.hash (), key2.pub, key2.pub, key2.prv, key2.pub, pool.generate (key2.pub)); @@ -608,88 +608,88 @@ TEST (ledger, representation) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_TRUE (!init); nano::stat stats; - nano::ledger ledger (store, stats); + nano::ledger ledger (*store, stats); nano::genesis genesis; - auto transaction (store.tx_begin_write ()); - store.initialize (transaction, genesis); + auto transaction (store->tx_begin_write ()); + store->initialize (transaction, genesis); nano::work_pool pool (std::numeric_limits::max ()); - ASSERT_EQ (nano::genesis_amount, store.representation_get (transaction, nano::test_genesis_key.pub)); + ASSERT_EQ (nano::genesis_amount, store->representation_get (transaction, nano::test_genesis_key.pub)); nano::keypair key2; nano::send_block block1 (genesis.hash (), key2.pub, nano::genesis_amount - 100, nano::test_genesis_key.prv, nano::test_genesis_key.pub, pool.generate (genesis.hash ())); ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, block1).code); - ASSERT_EQ (nano::genesis_amount - 100, store.representation_get (transaction, nano::test_genesis_key.pub)); + ASSERT_EQ (nano::genesis_amount - 100, store->representation_get (transaction, nano::test_genesis_key.pub)); nano::keypair key3; nano::open_block block2 (block1.hash (), key3.pub, key2.pub, key2.prv, key2.pub, pool.generate (key2.pub)); ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, block2).code); - ASSERT_EQ (nano::genesis_amount - 100, store.representation_get (transaction, nano::test_genesis_key.pub)); - ASSERT_EQ (0, store.representation_get (transaction, key2.pub)); - ASSERT_EQ (100, store.representation_get (transaction, key3.pub)); + ASSERT_EQ (nano::genesis_amount - 100, store->representation_get (transaction, nano::test_genesis_key.pub)); + ASSERT_EQ (0, store->representation_get (transaction, key2.pub)); + ASSERT_EQ (100, store->representation_get (transaction, key3.pub)); nano::send_block block3 (block1.hash (), key2.pub, nano::genesis_amount - 200, nano::test_genesis_key.prv, nano::test_genesis_key.pub, pool.generate (block1.hash ())); ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, block3).code); - ASSERT_EQ (nano::genesis_amount - 200, store.representation_get (transaction, nano::test_genesis_key.pub)); - ASSERT_EQ (0, store.representation_get (transaction, key2.pub)); - ASSERT_EQ (100, store.representation_get (transaction, key3.pub)); + ASSERT_EQ (nano::genesis_amount - 200, store->representation_get (transaction, nano::test_genesis_key.pub)); + ASSERT_EQ (0, store->representation_get (transaction, key2.pub)); + ASSERT_EQ (100, store->representation_get (transaction, key3.pub)); nano::receive_block block4 (block2.hash (), block3.hash (), key2.prv, key2.pub, pool.generate (block2.hash ())); ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, block4).code); - ASSERT_EQ (nano::genesis_amount - 200, store.representation_get (transaction, nano::test_genesis_key.pub)); - ASSERT_EQ (0, store.representation_get (transaction, key2.pub)); - ASSERT_EQ (200, store.representation_get (transaction, key3.pub)); + ASSERT_EQ (nano::genesis_amount - 200, store->representation_get (transaction, nano::test_genesis_key.pub)); + ASSERT_EQ (0, store->representation_get (transaction, key2.pub)); + ASSERT_EQ (200, store->representation_get (transaction, key3.pub)); nano::keypair key4; nano::change_block block5 (block4.hash (), key4.pub, key2.prv, key2.pub, pool.generate (block4.hash ())); ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, block5).code); - ASSERT_EQ (nano::genesis_amount - 200, store.representation_get (transaction, nano::test_genesis_key.pub)); - ASSERT_EQ (0, store.representation_get (transaction, key2.pub)); - ASSERT_EQ (0, store.representation_get (transaction, key3.pub)); - ASSERT_EQ (200, store.representation_get (transaction, key4.pub)); + ASSERT_EQ (nano::genesis_amount - 200, store->representation_get (transaction, nano::test_genesis_key.pub)); + ASSERT_EQ (0, store->representation_get (transaction, key2.pub)); + ASSERT_EQ (0, store->representation_get (transaction, key3.pub)); + ASSERT_EQ (200, store->representation_get (transaction, key4.pub)); nano::keypair key5; nano::send_block block6 (block5.hash (), key5.pub, 100, key2.prv, key2.pub, pool.generate (block5.hash ())); ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, block6).code); - ASSERT_EQ (nano::genesis_amount - 200, store.representation_get (transaction, nano::test_genesis_key.pub)); - ASSERT_EQ (0, store.representation_get (transaction, key2.pub)); - ASSERT_EQ (0, store.representation_get (transaction, key3.pub)); - ASSERT_EQ (100, store.representation_get (transaction, key4.pub)); - ASSERT_EQ (0, store.representation_get (transaction, key5.pub)); + ASSERT_EQ (nano::genesis_amount - 200, store->representation_get (transaction, nano::test_genesis_key.pub)); + ASSERT_EQ (0, store->representation_get (transaction, key2.pub)); + ASSERT_EQ (0, store->representation_get (transaction, key3.pub)); + ASSERT_EQ (100, store->representation_get (transaction, key4.pub)); + ASSERT_EQ (0, store->representation_get (transaction, key5.pub)); nano::keypair key6; nano::open_block block7 (block6.hash (), key6.pub, key5.pub, key5.prv, key5.pub, pool.generate (key5.pub)); ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, block7).code); - ASSERT_EQ (nano::genesis_amount - 200, store.representation_get (transaction, nano::test_genesis_key.pub)); - ASSERT_EQ (0, store.representation_get (transaction, key2.pub)); - ASSERT_EQ (0, store.representation_get (transaction, key3.pub)); - ASSERT_EQ (100, store.representation_get (transaction, key4.pub)); - ASSERT_EQ (0, store.representation_get (transaction, key5.pub)); - ASSERT_EQ (100, store.representation_get (transaction, key6.pub)); + ASSERT_EQ (nano::genesis_amount - 200, store->representation_get (transaction, nano::test_genesis_key.pub)); + ASSERT_EQ (0, store->representation_get (transaction, key2.pub)); + ASSERT_EQ (0, store->representation_get (transaction, key3.pub)); + ASSERT_EQ (100, store->representation_get (transaction, key4.pub)); + ASSERT_EQ (0, store->representation_get (transaction, key5.pub)); + ASSERT_EQ (100, store->representation_get (transaction, key6.pub)); nano::send_block block8 (block6.hash (), key5.pub, 0, key2.prv, key2.pub, pool.generate (block6.hash ())); ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, block8).code); - ASSERT_EQ (nano::genesis_amount - 200, store.representation_get (transaction, nano::test_genesis_key.pub)); - ASSERT_EQ (0, store.representation_get (transaction, key2.pub)); - ASSERT_EQ (0, store.representation_get (transaction, key3.pub)); - ASSERT_EQ (0, store.representation_get (transaction, key4.pub)); - ASSERT_EQ (0, store.representation_get (transaction, key5.pub)); - ASSERT_EQ (100, store.representation_get (transaction, key6.pub)); + ASSERT_EQ (nano::genesis_amount - 200, store->representation_get (transaction, nano::test_genesis_key.pub)); + ASSERT_EQ (0, store->representation_get (transaction, key2.pub)); + ASSERT_EQ (0, store->representation_get (transaction, key3.pub)); + ASSERT_EQ (0, store->representation_get (transaction, key4.pub)); + ASSERT_EQ (0, store->representation_get (transaction, key5.pub)); + ASSERT_EQ (100, store->representation_get (transaction, key6.pub)); nano::receive_block block9 (block7.hash (), block8.hash (), key5.prv, key5.pub, pool.generate (block7.hash ())); ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, block9).code); - ASSERT_EQ (nano::genesis_amount - 200, store.representation_get (transaction, nano::test_genesis_key.pub)); - ASSERT_EQ (0, store.representation_get (transaction, key2.pub)); - ASSERT_EQ (0, store.representation_get (transaction, key3.pub)); - ASSERT_EQ (0, store.representation_get (transaction, key4.pub)); - ASSERT_EQ (0, store.representation_get (transaction, key5.pub)); - ASSERT_EQ (200, store.representation_get (transaction, key6.pub)); + ASSERT_EQ (nano::genesis_amount - 200, store->representation_get (transaction, nano::test_genesis_key.pub)); + ASSERT_EQ (0, store->representation_get (transaction, key2.pub)); + ASSERT_EQ (0, store->representation_get (transaction, key3.pub)); + ASSERT_EQ (0, store->representation_get (transaction, key4.pub)); + ASSERT_EQ (0, store->representation_get (transaction, key5.pub)); + ASSERT_EQ (200, store->representation_get (transaction, key6.pub)); } TEST (ledger, double_open) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_TRUE (!init); nano::stat stats; - nano::ledger ledger (store, stats); + nano::ledger ledger (*store, stats); nano::genesis genesis; - auto transaction (store.tx_begin_write ()); - store.initialize (transaction, genesis); + auto transaction (store->tx_begin_write ()); + store->initialize (transaction, genesis); nano::work_pool pool (std::numeric_limits::max ()); nano::keypair key2; nano::send_block send1 (genesis.hash (), key2.pub, 1, nano::test_genesis_key.prv, nano::test_genesis_key.pub, pool.generate (genesis.hash ())); @@ -704,13 +704,13 @@ TEST (ledger, double_receive) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_TRUE (!init); nano::stat stats; - nano::ledger ledger (store, stats); + nano::ledger ledger (*store, stats); nano::genesis genesis; - auto transaction (store.tx_begin_write ()); - store.initialize (transaction, genesis); + auto transaction (store->tx_begin_write ()); + store->initialize (transaction, genesis); nano::work_pool pool (std::numeric_limits::max ()); nano::keypair key2; nano::send_block send1 (genesis.hash (), key2.pub, 1, nano::test_genesis_key.prv, nano::test_genesis_key.pub, pool.generate (genesis.hash ())); @@ -979,13 +979,13 @@ TEST (ledger, fail_change_old) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_FALSE (init); nano::stat stats; - nano::ledger ledger (store, stats); + nano::ledger ledger (*store, stats); nano::genesis genesis; - auto transaction (store.tx_begin_write ()); - store.initialize (transaction, genesis); + auto transaction (store->tx_begin_write ()); + store->initialize (transaction, genesis); nano::work_pool pool (std::numeric_limits::max ()); nano::keypair key1; nano::change_block block (genesis.hash (), key1.pub, nano::test_genesis_key.prv, nano::test_genesis_key.pub, pool.generate (genesis.hash ())); @@ -999,13 +999,13 @@ TEST (ledger, fail_change_gap_previous) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_FALSE (init); nano::stat stats; - nano::ledger ledger (store, stats); + nano::ledger ledger (*store, stats); nano::genesis genesis; - auto transaction (store.tx_begin_write ()); - store.initialize (transaction, genesis); + auto transaction (store->tx_begin_write ()); + store->initialize (transaction, genesis); nano::work_pool pool (std::numeric_limits::max ()); nano::keypair key1; nano::change_block block (1, key1.pub, nano::test_genesis_key.prv, nano::test_genesis_key.pub, pool.generate (1)); @@ -1017,13 +1017,13 @@ TEST (ledger, fail_change_bad_signature) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_FALSE (init); nano::stat stats; - nano::ledger ledger (store, stats); + nano::ledger ledger (*store, stats); nano::genesis genesis; - auto transaction (store.tx_begin_write ()); - store.initialize (transaction, genesis); + auto transaction (store->tx_begin_write ()); + store->initialize (transaction, genesis); nano::work_pool pool (std::numeric_limits::max ()); nano::keypair key1; nano::change_block block (genesis.hash (), key1.pub, nano::keypair ().prv, 0, pool.generate (genesis.hash ())); @@ -1035,13 +1035,13 @@ TEST (ledger, fail_change_fork) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_FALSE (init); nano::stat stats; - nano::ledger ledger (store, stats); + nano::ledger ledger (*store, stats); nano::genesis genesis; - auto transaction (store.tx_begin_write ()); - store.initialize (transaction, genesis); + auto transaction (store->tx_begin_write ()); + store->initialize (transaction, genesis); nano::work_pool pool (std::numeric_limits::max ()); nano::keypair key1; nano::change_block block1 (genesis.hash (), key1.pub, nano::test_genesis_key.prv, nano::test_genesis_key.pub, pool.generate (genesis.hash ())); @@ -1057,13 +1057,13 @@ TEST (ledger, fail_send_old) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_FALSE (init); nano::stat stats; - nano::ledger ledger (store, stats); + nano::ledger ledger (*store, stats); nano::genesis genesis; - auto transaction (store.tx_begin_write ()); - store.initialize (transaction, genesis); + auto transaction (store->tx_begin_write ()); + store->initialize (transaction, genesis); nano::work_pool pool (std::numeric_limits::max ()); nano::keypair key1; nano::send_block block (genesis.hash (), key1.pub, 1, nano::test_genesis_key.prv, nano::test_genesis_key.pub, pool.generate (genesis.hash ())); @@ -1077,13 +1077,13 @@ TEST (ledger, fail_send_gap_previous) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_FALSE (init); nano::stat stats; - nano::ledger ledger (store, stats); + nano::ledger ledger (*store, stats); nano::genesis genesis; - auto transaction (store.tx_begin_write ()); - store.initialize (transaction, genesis); + auto transaction (store->tx_begin_write ()); + store->initialize (transaction, genesis); nano::work_pool pool (std::numeric_limits::max ()); nano::keypair key1; nano::send_block block (1, key1.pub, 1, nano::test_genesis_key.prv, nano::test_genesis_key.pub, pool.generate (1)); @@ -1095,13 +1095,13 @@ TEST (ledger, fail_send_bad_signature) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_FALSE (init); nano::stat stats; - nano::ledger ledger (store, stats); + nano::ledger ledger (*store, stats); nano::genesis genesis; - auto transaction (store.tx_begin_write ()); - store.initialize (transaction, genesis); + auto transaction (store->tx_begin_write ()); + store->initialize (transaction, genesis); nano::work_pool pool (std::numeric_limits::max ()); nano::keypair key1; nano::send_block block (genesis.hash (), key1.pub, 1, nano::keypair ().prv, 0, pool.generate (genesis.hash ())); @@ -1113,13 +1113,13 @@ TEST (ledger, fail_send_negative_spend) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_FALSE (init); nano::stat stats; - nano::ledger ledger (store, stats); + nano::ledger ledger (*store, stats); nano::genesis genesis; - auto transaction (store.tx_begin_write ()); - store.initialize (transaction, genesis); + auto transaction (store->tx_begin_write ()); + store->initialize (transaction, genesis); nano::work_pool pool (std::numeric_limits::max ()); nano::keypair key1; nano::send_block block1 (genesis.hash (), key1.pub, 1, nano::test_genesis_key.prv, nano::test_genesis_key.pub, pool.generate (genesis.hash ())); @@ -1133,13 +1133,13 @@ TEST (ledger, fail_send_fork) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_FALSE (init); nano::stat stats; - nano::ledger ledger (store, stats); + nano::ledger ledger (*store, stats); nano::genesis genesis; - auto transaction (store.tx_begin_write ()); - store.initialize (transaction, genesis); + auto transaction (store->tx_begin_write ()); + store->initialize (transaction, genesis); nano::work_pool pool (std::numeric_limits::max ()); nano::keypair key1; nano::send_block block1 (genesis.hash (), key1.pub, 1, nano::test_genesis_key.prv, nano::test_genesis_key.pub, pool.generate (genesis.hash ())); @@ -1153,13 +1153,13 @@ TEST (ledger, fail_open_old) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_FALSE (init); nano::stat stats; - nano::ledger ledger (store, stats); + nano::ledger ledger (*store, stats); nano::genesis genesis; - auto transaction (store.tx_begin_write ()); - store.initialize (transaction, genesis); + auto transaction (store->tx_begin_write ()); + store->initialize (transaction, genesis); nano::work_pool pool (std::numeric_limits::max ()); nano::keypair key1; nano::send_block block1 (genesis.hash (), key1.pub, 1, nano::test_genesis_key.prv, nano::test_genesis_key.pub, pool.generate (genesis.hash ())); @@ -1173,13 +1173,13 @@ TEST (ledger, fail_open_gap_source) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_FALSE (init); nano::stat stats; - nano::ledger ledger (store, stats); + nano::ledger ledger (*store, stats); nano::genesis genesis; - auto transaction (store.tx_begin_write ()); - store.initialize (transaction, genesis); + auto transaction (store->tx_begin_write ()); + store->initialize (transaction, genesis); nano::work_pool pool (std::numeric_limits::max ()); nano::keypair key1; nano::open_block block2 (1, 1, key1.pub, key1.prv, key1.pub, pool.generate (key1.pub)); @@ -1191,13 +1191,13 @@ TEST (ledger, fail_open_bad_signature) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_FALSE (init); nano::stat stats; - nano::ledger ledger (store, stats); + nano::ledger ledger (*store, stats); nano::genesis genesis; - auto transaction (store.tx_begin_write ()); - store.initialize (transaction, genesis); + auto transaction (store->tx_begin_write ()); + store->initialize (transaction, genesis); nano::work_pool pool (std::numeric_limits::max ()); nano::keypair key1; nano::send_block block1 (genesis.hash (), key1.pub, 1, nano::test_genesis_key.prv, nano::test_genesis_key.pub, pool.generate (genesis.hash ())); @@ -1211,13 +1211,13 @@ TEST (ledger, fail_open_fork_previous) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_FALSE (init); nano::stat stats; - nano::ledger ledger (store, stats); + nano::ledger ledger (*store, stats); nano::genesis genesis; - auto transaction (store.tx_begin_write ()); - store.initialize (transaction, genesis); + auto transaction (store->tx_begin_write ()); + store->initialize (transaction, genesis); nano::work_pool pool (std::numeric_limits::max ()); nano::keypair key1; nano::send_block block1 (genesis.hash (), key1.pub, 1, nano::test_genesis_key.prv, nano::test_genesis_key.pub, pool.generate (genesis.hash ())); @@ -1234,13 +1234,13 @@ TEST (ledger, fail_open_account_mismatch) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_FALSE (init); nano::stat stats; - nano::ledger ledger (store, stats); + nano::ledger ledger (*store, stats); nano::genesis genesis; - auto transaction (store.tx_begin_write ()); - store.initialize (transaction, genesis); + auto transaction (store->tx_begin_write ()); + store->initialize (transaction, genesis); nano::work_pool pool (std::numeric_limits::max ()); nano::keypair key1; nano::send_block block1 (genesis.hash (), key1.pub, 1, nano::test_genesis_key.prv, nano::test_genesis_key.pub, pool.generate (genesis.hash ())); @@ -1254,13 +1254,13 @@ TEST (ledger, fail_receive_old) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_FALSE (init); nano::stat stats; - nano::ledger ledger (store, stats); + nano::ledger ledger (*store, stats); nano::genesis genesis; - auto transaction (store.tx_begin_write ()); - store.initialize (transaction, genesis); + auto transaction (store->tx_begin_write ()); + store->initialize (transaction, genesis); nano::work_pool pool (std::numeric_limits::max ()); nano::keypair key1; nano::send_block block1 (genesis.hash (), key1.pub, 1, nano::test_genesis_key.prv, nano::test_genesis_key.pub, pool.generate (genesis.hash ())); @@ -1278,13 +1278,13 @@ TEST (ledger, fail_receive_gap_source) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_FALSE (init); nano::stat stats; - nano::ledger ledger (store, stats); + nano::ledger ledger (*store, stats); nano::genesis genesis; - auto transaction (store.tx_begin_write ()); - store.initialize (transaction, genesis); + auto transaction (store->tx_begin_write ()); + store->initialize (transaction, genesis); nano::work_pool pool (std::numeric_limits::max ()); nano::keypair key1; nano::send_block block1 (genesis.hash (), key1.pub, 1, nano::test_genesis_key.prv, nano::test_genesis_key.pub, pool.generate (genesis.hash ())); @@ -1305,13 +1305,13 @@ TEST (ledger, fail_receive_overreceive) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_FALSE (init); nano::stat stats; - nano::ledger ledger (store, stats); + nano::ledger ledger (*store, stats); nano::genesis genesis; - auto transaction (store.tx_begin_write ()); - store.initialize (transaction, genesis); + auto transaction (store->tx_begin_write ()); + store->initialize (transaction, genesis); nano::work_pool pool (std::numeric_limits::max ()); nano::keypair key1; nano::send_block block1 (genesis.hash (), key1.pub, 1, nano::test_genesis_key.prv, nano::test_genesis_key.pub, pool.generate (genesis.hash ())); @@ -1329,13 +1329,13 @@ TEST (ledger, fail_receive_bad_signature) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_FALSE (init); nano::stat stats; - nano::ledger ledger (store, stats); + nano::ledger ledger (*store, stats); nano::genesis genesis; - auto transaction (store.tx_begin_write ()); - store.initialize (transaction, genesis); + auto transaction (store->tx_begin_write ()); + store->initialize (transaction, genesis); nano::work_pool pool (std::numeric_limits::max ()); nano::keypair key1; nano::send_block block1 (genesis.hash (), key1.pub, 1, nano::test_genesis_key.prv, nano::test_genesis_key.pub, pool.generate (genesis.hash ())); @@ -1356,13 +1356,13 @@ TEST (ledger, fail_receive_gap_previous_opened) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_FALSE (init); nano::stat stats; - nano::ledger ledger (store, stats); + nano::ledger ledger (*store, stats); nano::genesis genesis; - auto transaction (store.tx_begin_write ()); - store.initialize (transaction, genesis); + auto transaction (store->tx_begin_write ()); + store->initialize (transaction, genesis); nano::work_pool pool (std::numeric_limits::max ()); nano::keypair key1; nano::send_block block1 (genesis.hash (), key1.pub, 1, nano::test_genesis_key.prv, nano::test_genesis_key.pub, pool.generate (genesis.hash ())); @@ -1383,13 +1383,13 @@ TEST (ledger, fail_receive_gap_previous_unopened) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_FALSE (init); nano::stat stats; - nano::ledger ledger (store, stats); + nano::ledger ledger (*store, stats); nano::genesis genesis; - auto transaction (store.tx_begin_write ()); - store.initialize (transaction, genesis); + auto transaction (store->tx_begin_write ()); + store->initialize (transaction, genesis); nano::work_pool pool (std::numeric_limits::max ()); nano::keypair key1; nano::send_block block1 (genesis.hash (), key1.pub, 1, nano::test_genesis_key.prv, nano::test_genesis_key.pub, pool.generate (genesis.hash ())); @@ -1407,13 +1407,13 @@ TEST (ledger, fail_receive_fork_previous) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_FALSE (init); nano::stat stats; - nano::ledger ledger (store, stats); + nano::ledger ledger (*store, stats); nano::genesis genesis; - auto transaction (store.tx_begin_write ()); - store.initialize (transaction, genesis); + auto transaction (store->tx_begin_write ()); + store->initialize (transaction, genesis); nano::work_pool pool (std::numeric_limits::max ()); nano::keypair key1; nano::send_block block1 (genesis.hash (), key1.pub, 1, nano::test_genesis_key.prv, nano::test_genesis_key.pub, pool.generate (genesis.hash ())); @@ -1438,13 +1438,13 @@ TEST (ledger, fail_receive_received_source) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_FALSE (init); nano::stat stats; - nano::ledger ledger (store, stats); + nano::ledger ledger (*store, stats); nano::genesis genesis; - auto transaction (store.tx_begin_write ()); - store.initialize (transaction, genesis); + auto transaction (store->tx_begin_write ()); + store->initialize (transaction, genesis); nano::work_pool pool (std::numeric_limits::max ()); nano::keypair key1; nano::send_block block1 (genesis.hash (), key1.pub, 2, nano::test_genesis_key.prv, nano::test_genesis_key.pub, pool.generate (genesis.hash ())); @@ -1475,12 +1475,12 @@ TEST (ledger, latest_empty) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_FALSE (init); nano::stat stats; - nano::ledger ledger (store, stats); + nano::ledger ledger (*store, stats); nano::keypair key; - auto transaction (store.tx_begin_read ()); + auto transaction (store->tx_begin_read ()); auto latest (ledger.latest (transaction, key.pub)); ASSERT_TRUE (latest.is_zero ()); } @@ -1489,13 +1489,13 @@ TEST (ledger, latest_root) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_FALSE (init); nano::stat stats; - nano::ledger ledger (store, stats); + nano::ledger ledger (*store, stats); nano::genesis genesis; - auto transaction (store.tx_begin_write ()); - store.initialize (transaction, genesis); + auto transaction (store->tx_begin_write ()); + store->initialize (transaction, genesis); nano::work_pool pool (std::numeric_limits::max ()); nano::keypair key; ASSERT_EQ (key.pub, ledger.latest_root (transaction, key.pub)); @@ -1509,14 +1509,14 @@ TEST (ledger, change_representative_move_representation) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_TRUE (!init); nano::stat stats; - nano::ledger ledger (store, stats); + nano::ledger ledger (*store, stats); nano::keypair key1; - auto transaction (store.tx_begin_write ()); + auto transaction (store->tx_begin_write ()); nano::genesis genesis; - store.initialize (transaction, genesis); + store->initialize (transaction, genesis); nano::work_pool pool (std::numeric_limits::max ()); auto hash1 (genesis.hash ()); ASSERT_EQ (nano::genesis_amount, ledger.weight (transaction, nano::test_genesis_key.pub)); @@ -1536,16 +1536,16 @@ TEST (ledger, send_open_receive_rollback) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_TRUE (!init); nano::stat stats; - nano::ledger ledger (store, stats); - auto transaction (store.tx_begin_write ()); + nano::ledger ledger (*store, stats); + auto transaction (store->tx_begin_write ()); nano::genesis genesis; - store.initialize (transaction, genesis); + store->initialize (transaction, genesis); nano::work_pool pool (std::numeric_limits::max ()); nano::account_info info1; - ASSERT_FALSE (store.account_get (transaction, nano::test_genesis_key.pub, info1)); + ASSERT_FALSE (store->account_get (transaction, nano::test_genesis_key.pub, info1)); nano::keypair key1; nano::send_block send1 (info1.head, key1.pub, nano::genesis_amount - 50, nano::test_genesis_key.prv, nano::test_genesis_key.pub, pool.generate (info1.head)); auto return1 (ledger.process (transaction, send1)); @@ -1596,35 +1596,35 @@ TEST (ledger, bootstrap_rep_weight) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_TRUE (!init); nano::stat stats; - nano::ledger ledger (store, stats); + nano::ledger ledger (*store, stats); nano::account_info info1; nano::keypair key2; nano::genesis genesis; nano::work_pool pool (std::numeric_limits::max ()); { - auto transaction (store.tx_begin_write ()); - store.initialize (transaction, genesis); - ASSERT_FALSE (store.account_get (transaction, nano::test_genesis_key.pub, info1)); + auto transaction (store->tx_begin_write ()); + store->initialize (transaction, genesis); + ASSERT_FALSE (store->account_get (transaction, nano::test_genesis_key.pub, info1)); nano::send_block send (info1.head, key2.pub, std::numeric_limits::max () - 50, nano::test_genesis_key.prv, nano::test_genesis_key.pub, pool.generate (info1.head)); ledger.process (transaction, send); } { - auto transaction (store.tx_begin_read ()); + auto transaction (store->tx_begin_read ()); ledger.bootstrap_weight_max_blocks = 3; ledger.bootstrap_weights[key2.pub] = 1000; ASSERT_EQ (1000, ledger.weight (transaction, key2.pub)); } { - auto transaction (store.tx_begin_write ()); - ASSERT_FALSE (store.account_get (transaction, nano::test_genesis_key.pub, info1)); + auto transaction (store->tx_begin_write ()); + ASSERT_FALSE (store->account_get (transaction, nano::test_genesis_key.pub, info1)); nano::send_block send (info1.head, key2.pub, std::numeric_limits::max () - 100, nano::test_genesis_key.prv, nano::test_genesis_key.pub, pool.generate (info1.head)); ledger.process (transaction, send); } { - auto transaction (store.tx_begin_read ()); + auto transaction (store->tx_begin_read ()); ASSERT_EQ (0, ledger.weight (transaction, key2.pub)); } } @@ -1633,13 +1633,13 @@ TEST (ledger, block_destination_source) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_TRUE (!init); nano::stat stats; - nano::ledger ledger (store, stats); + nano::ledger ledger (*store, stats); nano::genesis genesis; - auto transaction (store.tx_begin_write ()); - store.initialize (transaction, genesis); + auto transaction (store->tx_begin_write ()); + store->initialize (transaction, genesis); nano::work_pool pool (std::numeric_limits::max ()); nano::keypair dest; nano::uint128_t balance (nano::genesis_amount); @@ -1680,13 +1680,13 @@ TEST (ledger, state_account) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_TRUE (!init); nano::stat stats; - nano::ledger ledger (store, stats); + nano::ledger ledger (*store, stats); nano::genesis genesis; - auto transaction (store.tx_begin_write ()); - store.initialize (transaction, genesis); + auto transaction (store->tx_begin_write ()); + store->initialize (transaction, genesis); nano::work_pool pool (std::numeric_limits::max ()); nano::state_block send1 (nano::genesis_account, genesis.hash (), nano::genesis_account, nano::genesis_amount - nano::Gxrb_ratio, nano::genesis_account, nano::test_genesis_key.prv, nano::test_genesis_key.pub, pool.generate (genesis.hash ())); ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, send1).code); @@ -1697,52 +1697,52 @@ TEST (ledger, state_send_receive) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_TRUE (!init); nano::stat stats; - nano::ledger ledger (store, stats); + nano::ledger ledger (*store, stats); nano::genesis genesis; - auto transaction (store.tx_begin_write ()); - store.initialize (transaction, genesis); + auto transaction (store->tx_begin_write ()); + store->initialize (transaction, genesis); nano::work_pool pool (std::numeric_limits::max ()); nano::state_block send1 (nano::genesis_account, genesis.hash (), nano::genesis_account, nano::genesis_amount - nano::Gxrb_ratio, nano::genesis_account, nano::test_genesis_key.prv, nano::test_genesis_key.pub, pool.generate (genesis.hash ())); ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, send1).code); - ASSERT_TRUE (store.block_exists (transaction, send1.hash ())); - auto send2 (store.block_get (transaction, send1.hash ())); + ASSERT_TRUE (store->block_exists (transaction, send1.hash ())); + auto send2 (store->block_get (transaction, send1.hash ())); ASSERT_NE (nullptr, send2); ASSERT_EQ (send1, *send2); ASSERT_EQ (nano::genesis_amount - nano::Gxrb_ratio, ledger.balance (transaction, send1.hash ())); ASSERT_EQ (nano::Gxrb_ratio, ledger.amount (transaction, send1.hash ())); ASSERT_EQ (nano::genesis_amount - nano::Gxrb_ratio, ledger.weight (transaction, nano::genesis_account)); - ASSERT_TRUE (store.pending_exists (transaction, nano::pending_key (nano::genesis_account, send1.hash ()))); + ASSERT_TRUE (store->pending_exists (transaction, nano::pending_key (nano::genesis_account, send1.hash ()))); nano::state_block receive1 (nano::genesis_account, send1.hash (), nano::genesis_account, nano::genesis_amount, send1.hash (), nano::test_genesis_key.prv, nano::test_genesis_key.pub, pool.generate (send1.hash ())); ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, receive1).code); - ASSERT_TRUE (store.block_exists (transaction, receive1.hash ())); - auto receive2 (store.block_get (transaction, receive1.hash ())); + ASSERT_TRUE (store->block_exists (transaction, receive1.hash ())); + auto receive2 (store->block_get (transaction, receive1.hash ())); ASSERT_NE (nullptr, receive2); ASSERT_EQ (receive1, *receive2); ASSERT_EQ (nano::genesis_amount, ledger.balance (transaction, receive1.hash ())); ASSERT_EQ (nano::Gxrb_ratio, ledger.amount (transaction, receive1.hash ())); ASSERT_EQ (nano::genesis_amount, ledger.weight (transaction, nano::genesis_account)); - ASSERT_FALSE (store.pending_exists (transaction, nano::pending_key (nano::genesis_account, send1.hash ()))); + ASSERT_FALSE (store->pending_exists (transaction, nano::pending_key (nano::genesis_account, send1.hash ()))); } TEST (ledger, state_receive) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_TRUE (!init); nano::stat stats; - nano::ledger ledger (store, stats); + nano::ledger ledger (*store, stats); nano::genesis genesis; - auto transaction (store.tx_begin_write ()); - store.initialize (transaction, genesis); + auto transaction (store->tx_begin_write ()); + store->initialize (transaction, genesis); nano::work_pool pool (std::numeric_limits::max ()); nano::send_block send1 (genesis.hash (), nano::genesis_account, nano::genesis_amount - nano::Gxrb_ratio, nano::test_genesis_key.prv, nano::test_genesis_key.pub, pool.generate (genesis.hash ())); ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, send1).code); - ASSERT_TRUE (store.block_exists (transaction, send1.hash ())); - auto send2 (store.block_get (transaction, send1.hash ())); + ASSERT_TRUE (store->block_exists (transaction, send1.hash ())); + auto send2 (store->block_get (transaction, send1.hash ())); ASSERT_NE (nullptr, send2); ASSERT_EQ (send1, *send2); ASSERT_EQ (nano::genesis_amount - nano::Gxrb_ratio, ledger.balance (transaction, send1.hash ())); @@ -1750,8 +1750,8 @@ TEST (ledger, state_receive) ASSERT_EQ (nano::genesis_amount - nano::Gxrb_ratio, ledger.weight (transaction, nano::genesis_account)); nano::state_block receive1 (nano::genesis_account, send1.hash (), nano::genesis_account, nano::genesis_amount, send1.hash (), nano::test_genesis_key.prv, nano::test_genesis_key.pub, pool.generate (send1.hash ())); ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, receive1).code); - ASSERT_TRUE (store.block_exists (transaction, receive1.hash ())); - auto receive2 (store.block_get (transaction, receive1.hash ())); + ASSERT_TRUE (store->block_exists (transaction, receive1.hash ())); + auto receive2 (store->block_get (transaction, receive1.hash ())); ASSERT_NE (nullptr, receive2); ASSERT_EQ (receive1, *receive2); ASSERT_EQ (nano::genesis_amount, ledger.balance (transaction, receive1.hash ())); @@ -1763,19 +1763,19 @@ TEST (ledger, state_rep_change) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_TRUE (!init); nano::stat stats; - nano::ledger ledger (store, stats); + nano::ledger ledger (*store, stats); nano::genesis genesis; - auto transaction (store.tx_begin_write ()); - store.initialize (transaction, genesis); + auto transaction (store->tx_begin_write ()); + store->initialize (transaction, genesis); nano::work_pool pool (std::numeric_limits::max ()); nano::keypair rep; nano::state_block change1 (nano::genesis_account, genesis.hash (), rep.pub, nano::genesis_amount, 0, nano::test_genesis_key.prv, nano::test_genesis_key.pub, pool.generate (genesis.hash ())); ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, change1).code); - ASSERT_TRUE (store.block_exists (transaction, change1.hash ())); - auto change2 (store.block_get (transaction, change1.hash ())); + ASSERT_TRUE (store->block_exists (transaction, change1.hash ())); + auto change2 (store->block_get (transaction, change1.hash ())); ASSERT_NE (nullptr, change2); ASSERT_EQ (change1, *change2); ASSERT_EQ (nano::genesis_amount, ledger.balance (transaction, change1.hash ())); @@ -1788,30 +1788,30 @@ TEST (ledger, state_open) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_TRUE (!init); nano::stat stats; - nano::ledger ledger (store, stats); + nano::ledger ledger (*store, stats); nano::genesis genesis; - auto transaction (store.tx_begin_write ()); - store.initialize (transaction, genesis); + auto transaction (store->tx_begin_write ()); + store->initialize (transaction, genesis); nano::work_pool pool (std::numeric_limits::max ()); nano::keypair destination; nano::state_block send1 (nano::genesis_account, genesis.hash (), nano::genesis_account, nano::genesis_amount - nano::Gxrb_ratio, destination.pub, nano::test_genesis_key.prv, nano::test_genesis_key.pub, pool.generate (genesis.hash ())); ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, send1).code); - ASSERT_TRUE (store.block_exists (transaction, send1.hash ())); - auto send2 (store.block_get (transaction, send1.hash ())); + ASSERT_TRUE (store->block_exists (transaction, send1.hash ())); + auto send2 (store->block_get (transaction, send1.hash ())); ASSERT_NE (nullptr, send2); ASSERT_EQ (send1, *send2); ASSERT_EQ (nano::genesis_amount - nano::Gxrb_ratio, ledger.balance (transaction, send1.hash ())); ASSERT_EQ (nano::Gxrb_ratio, ledger.amount (transaction, send1.hash ())); ASSERT_EQ (nano::genesis_amount - nano::Gxrb_ratio, ledger.weight (transaction, nano::genesis_account)); - ASSERT_TRUE (store.pending_exists (transaction, nano::pending_key (destination.pub, send1.hash ()))); + ASSERT_TRUE (store->pending_exists (transaction, nano::pending_key (destination.pub, send1.hash ()))); nano::state_block open1 (destination.pub, 0, nano::genesis_account, nano::Gxrb_ratio, send1.hash (), destination.prv, destination.pub, pool.generate (destination.pub)); ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, open1).code); - ASSERT_FALSE (store.pending_exists (transaction, nano::pending_key (destination.pub, send1.hash ()))); - ASSERT_TRUE (store.block_exists (transaction, open1.hash ())); - auto open2 (store.block_get (transaction, open1.hash ())); + ASSERT_FALSE (store->pending_exists (transaction, nano::pending_key (destination.pub, send1.hash ()))); + ASSERT_TRUE (store->block_exists (transaction, open1.hash ())); + auto open2 (store->block_get (transaction, open1.hash ())); ASSERT_NE (nullptr, open2); ASSERT_EQ (open1, *open2); ASSERT_EQ (nano::Gxrb_ratio, ledger.balance (transaction, open1.hash ())); @@ -1824,13 +1824,13 @@ TEST (ledger, send_after_state_fail) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_TRUE (!init); nano::stat stats; - nano::ledger ledger (store, stats); + nano::ledger ledger (*store, stats); nano::genesis genesis; - auto transaction (store.tx_begin_write ()); - store.initialize (transaction, genesis); + auto transaction (store->tx_begin_write ()); + store->initialize (transaction, genesis); nano::work_pool pool (std::numeric_limits::max ()); nano::state_block send1 (nano::genesis_account, genesis.hash (), nano::genesis_account, nano::genesis_amount - nano::Gxrb_ratio, nano::genesis_account, nano::test_genesis_key.prv, nano::test_genesis_key.pub, pool.generate (genesis.hash ())); ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, send1).code); @@ -1843,13 +1843,13 @@ TEST (ledger, receive_after_state_fail) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_TRUE (!init); nano::stat stats; - nano::ledger ledger (store, stats); + nano::ledger ledger (*store, stats); nano::genesis genesis; - auto transaction (store.tx_begin_write ()); - store.initialize (transaction, genesis); + auto transaction (store->tx_begin_write ()); + store->initialize (transaction, genesis); nano::work_pool pool (std::numeric_limits::max ()); nano::state_block send1 (nano::genesis_account, genesis.hash (), nano::genesis_account, nano::genesis_amount - nano::Gxrb_ratio, nano::genesis_account, nano::test_genesis_key.prv, nano::test_genesis_key.pub, pool.generate (genesis.hash ())); ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, send1).code); @@ -1862,13 +1862,13 @@ TEST (ledger, change_after_state_fail) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_TRUE (!init); nano::stat stats; - nano::ledger ledger (store, stats); + nano::ledger ledger (*store, stats); nano::genesis genesis; - auto transaction (store.tx_begin_write ()); - store.initialize (transaction, genesis); + auto transaction (store->tx_begin_write ()); + store->initialize (transaction, genesis); nano::work_pool pool (std::numeric_limits::max ()); nano::state_block send1 (nano::genesis_account, genesis.hash (), nano::genesis_account, nano::genesis_amount - nano::Gxrb_ratio, nano::genesis_account, nano::test_genesis_key.prv, nano::test_genesis_key.pub, pool.generate (genesis.hash ())); ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, send1).code); @@ -1881,18 +1881,18 @@ TEST (ledger, state_unreceivable_fail) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_TRUE (!init); nano::stat stats; - nano::ledger ledger (store, stats); + nano::ledger ledger (*store, stats); nano::genesis genesis; - auto transaction (store.tx_begin_write ()); - store.initialize (transaction, genesis); + auto transaction (store->tx_begin_write ()); + store->initialize (transaction, genesis); nano::work_pool pool (std::numeric_limits::max ()); nano::send_block send1 (genesis.hash (), nano::genesis_account, nano::genesis_amount - nano::Gxrb_ratio, nano::test_genesis_key.prv, nano::test_genesis_key.pub, pool.generate (genesis.hash ())); ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, send1).code); - ASSERT_TRUE (store.block_exists (transaction, send1.hash ())); - auto send2 (store.block_get (transaction, send1.hash ())); + ASSERT_TRUE (store->block_exists (transaction, send1.hash ())); + auto send2 (store->block_get (transaction, send1.hash ())); ASSERT_NE (nullptr, send2); ASSERT_EQ (send1, *send2); ASSERT_EQ (nano::genesis_amount - nano::Gxrb_ratio, ledger.balance (transaction, send1.hash ())); @@ -1906,18 +1906,18 @@ TEST (ledger, state_receive_bad_amount_fail) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_TRUE (!init); nano::stat stats; - nano::ledger ledger (store, stats); + nano::ledger ledger (*store, stats); nano::genesis genesis; - auto transaction (store.tx_begin_write ()); - store.initialize (transaction, genesis); + auto transaction (store->tx_begin_write ()); + store->initialize (transaction, genesis); nano::work_pool pool (std::numeric_limits::max ()); nano::send_block send1 (genesis.hash (), nano::genesis_account, nano::genesis_amount - nano::Gxrb_ratio, nano::test_genesis_key.prv, nano::test_genesis_key.pub, pool.generate (genesis.hash ())); ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, send1).code); - ASSERT_TRUE (store.block_exists (transaction, send1.hash ())); - auto send2 (store.block_get (transaction, send1.hash ())); + ASSERT_TRUE (store->block_exists (transaction, send1.hash ())); + auto send2 (store->block_get (transaction, send1.hash ())); ASSERT_NE (nullptr, send2); ASSERT_EQ (send1, *send2); ASSERT_EQ (nano::genesis_amount - nano::Gxrb_ratio, ledger.balance (transaction, send1.hash ())); @@ -1931,13 +1931,13 @@ TEST (ledger, state_no_link_amount_fail) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_TRUE (!init); nano::stat stats; - nano::ledger ledger (store, stats); + nano::ledger ledger (*store, stats); nano::genesis genesis; - auto transaction (store.tx_begin_write ()); - store.initialize (transaction, genesis); + auto transaction (store->tx_begin_write ()); + store->initialize (transaction, genesis); nano::work_pool pool (std::numeric_limits::max ()); nano::state_block send1 (nano::genesis_account, genesis.hash (), nano::genesis_account, nano::genesis_amount - nano::Gxrb_ratio, nano::genesis_account, nano::test_genesis_key.prv, nano::test_genesis_key.pub, pool.generate (genesis.hash ())); ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, send1).code); @@ -1950,18 +1950,18 @@ TEST (ledger, state_receive_wrong_account_fail) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_TRUE (!init); nano::stat stats; - nano::ledger ledger (store, stats); + nano::ledger ledger (*store, stats); nano::genesis genesis; - auto transaction (store.tx_begin_write ()); - store.initialize (transaction, genesis); + auto transaction (store->tx_begin_write ()); + store->initialize (transaction, genesis); nano::work_pool pool (std::numeric_limits::max ()); nano::state_block send1 (nano::genesis_account, genesis.hash (), nano::genesis_account, nano::genesis_amount - nano::Gxrb_ratio, nano::genesis_account, nano::test_genesis_key.prv, nano::test_genesis_key.pub, pool.generate (genesis.hash ())); ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, send1).code); - ASSERT_TRUE (store.block_exists (transaction, send1.hash ())); - auto send2 (store.block_get (transaction, send1.hash ())); + ASSERT_TRUE (store->block_exists (transaction, send1.hash ())); + auto send2 (store->block_get (transaction, send1.hash ())); ASSERT_NE (nullptr, send2); ASSERT_EQ (send1, *send2); ASSERT_EQ (nano::genesis_amount - nano::Gxrb_ratio, ledger.balance (transaction, send1.hash ())); @@ -1976,13 +1976,13 @@ TEST (ledger, state_open_state_fork) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_TRUE (!init); nano::stat stats; - nano::ledger ledger (store, stats); + nano::ledger ledger (*store, stats); nano::genesis genesis; - auto transaction (store.tx_begin_write ()); - store.initialize (transaction, genesis); + auto transaction (store->tx_begin_write ()); + store->initialize (transaction, genesis); nano::work_pool pool (std::numeric_limits::max ()); nano::keypair destination; nano::state_block send1 (nano::genesis_account, genesis.hash (), nano::genesis_account, nano::genesis_amount - nano::Gxrb_ratio, destination.pub, nano::test_genesis_key.prv, nano::test_genesis_key.pub, pool.generate (genesis.hash ())); @@ -1998,13 +1998,13 @@ TEST (ledger, state_state_open_fork) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_TRUE (!init); nano::stat stats; - nano::ledger ledger (store, stats); + nano::ledger ledger (*store, stats); nano::genesis genesis; - auto transaction (store.tx_begin_write ()); - store.initialize (transaction, genesis); + auto transaction (store->tx_begin_write ()); + store->initialize (transaction, genesis); nano::work_pool pool (std::numeric_limits::max ()); nano::keypair destination; nano::state_block send1 (nano::genesis_account, genesis.hash (), nano::genesis_account, nano::genesis_amount - nano::Gxrb_ratio, destination.pub, nano::test_genesis_key.prv, nano::test_genesis_key.pub, pool.generate (genesis.hash ())); @@ -2020,13 +2020,13 @@ TEST (ledger, state_open_previous_fail) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_TRUE (!init); nano::stat stats; - nano::ledger ledger (store, stats); + nano::ledger ledger (*store, stats); nano::genesis genesis; - auto transaction (store.tx_begin_write ()); - store.initialize (transaction, genesis); + auto transaction (store->tx_begin_write ()); + store->initialize (transaction, genesis); nano::work_pool pool (std::numeric_limits::max ()); nano::keypair destination; nano::state_block send1 (nano::genesis_account, genesis.hash (), nano::genesis_account, nano::genesis_amount - nano::Gxrb_ratio, destination.pub, nano::test_genesis_key.prv, nano::test_genesis_key.pub, pool.generate (genesis.hash ())); @@ -2039,13 +2039,13 @@ TEST (ledger, state_open_source_fail) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_TRUE (!init); nano::stat stats; - nano::ledger ledger (store, stats); + nano::ledger ledger (*store, stats); nano::genesis genesis; - auto transaction (store.tx_begin_write ()); - store.initialize (transaction, genesis); + auto transaction (store->tx_begin_write ()); + store->initialize (transaction, genesis); nano::work_pool pool (std::numeric_limits::max ()); nano::keypair destination; nano::state_block send1 (nano::genesis_account, genesis.hash (), nano::genesis_account, nano::genesis_amount - nano::Gxrb_ratio, destination.pub, nano::test_genesis_key.prv, nano::test_genesis_key.pub, pool.generate (genesis.hash ())); @@ -2058,19 +2058,19 @@ TEST (ledger, state_send_change) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_TRUE (!init); nano::stat stats; - nano::ledger ledger (store, stats); + nano::ledger ledger (*store, stats); nano::genesis genesis; - auto transaction (store.tx_begin_write ()); - store.initialize (transaction, genesis); + auto transaction (store->tx_begin_write ()); + store->initialize (transaction, genesis); nano::work_pool pool (std::numeric_limits::max ()); nano::keypair rep; nano::state_block send1 (nano::genesis_account, genesis.hash (), rep.pub, nano::genesis_amount - nano::Gxrb_ratio, nano::genesis_account, nano::test_genesis_key.prv, nano::test_genesis_key.pub, pool.generate (genesis.hash ())); ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, send1).code); - ASSERT_TRUE (store.block_exists (transaction, send1.hash ())); - auto send2 (store.block_get (transaction, send1.hash ())); + ASSERT_TRUE (store->block_exists (transaction, send1.hash ())); + auto send2 (store->block_get (transaction, send1.hash ())); ASSERT_NE (nullptr, send2); ASSERT_EQ (send1, *send2); ASSERT_EQ (nano::genesis_amount - nano::Gxrb_ratio, ledger.balance (transaction, send1.hash ())); @@ -2083,18 +2083,18 @@ TEST (ledger, state_receive_change) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_TRUE (!init); nano::stat stats; - nano::ledger ledger (store, stats); + nano::ledger ledger (*store, stats); nano::genesis genesis; - auto transaction (store.tx_begin_write ()); - store.initialize (transaction, genesis); + auto transaction (store->tx_begin_write ()); + store->initialize (transaction, genesis); nano::work_pool pool (std::numeric_limits::max ()); nano::state_block send1 (nano::genesis_account, genesis.hash (), nano::genesis_account, nano::genesis_amount - nano::Gxrb_ratio, nano::genesis_account, nano::test_genesis_key.prv, nano::test_genesis_key.pub, pool.generate (genesis.hash ())); ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, send1).code); - ASSERT_TRUE (store.block_exists (transaction, send1.hash ())); - auto send2 (store.block_get (transaction, send1.hash ())); + ASSERT_TRUE (store->block_exists (transaction, send1.hash ())); + auto send2 (store->block_get (transaction, send1.hash ())); ASSERT_NE (nullptr, send2); ASSERT_EQ (send1, *send2); ASSERT_EQ (nano::genesis_amount - nano::Gxrb_ratio, ledger.balance (transaction, send1.hash ())); @@ -2103,8 +2103,8 @@ TEST (ledger, state_receive_change) nano::keypair rep; nano::state_block receive1 (nano::genesis_account, send1.hash (), rep.pub, nano::genesis_amount, send1.hash (), nano::test_genesis_key.prv, nano::test_genesis_key.pub, pool.generate (send1.hash ())); ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, receive1).code); - ASSERT_TRUE (store.block_exists (transaction, receive1.hash ())); - auto receive2 (store.block_get (transaction, receive1.hash ())); + ASSERT_TRUE (store->block_exists (transaction, receive1.hash ())); + auto receive2 (store->block_get (transaction, receive1.hash ())); ASSERT_NE (nullptr, receive2); ASSERT_EQ (receive1, *receive2); ASSERT_EQ (nano::genesis_amount, ledger.balance (transaction, receive1.hash ())); @@ -2117,13 +2117,13 @@ TEST (ledger, state_open_old) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_TRUE (!init); nano::stat stats; - nano::ledger ledger (store, stats); + nano::ledger ledger (*store, stats); nano::genesis genesis; - auto transaction (store.tx_begin_write ()); - store.initialize (transaction, genesis); + auto transaction (store->tx_begin_write ()); + store->initialize (transaction, genesis); nano::work_pool pool (std::numeric_limits::max ()); nano::keypair destination; nano::state_block send1 (nano::genesis_account, genesis.hash (), nano::genesis_account, nano::genesis_amount - nano::Gxrb_ratio, destination.pub, nano::test_genesis_key.prv, nano::test_genesis_key.pub, pool.generate (genesis.hash ())); @@ -2139,13 +2139,13 @@ TEST (ledger, state_receive_old) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_TRUE (!init); nano::stat stats; - nano::ledger ledger (store, stats); + nano::ledger ledger (*store, stats); nano::genesis genesis; - auto transaction (store.tx_begin_write ()); - store.initialize (transaction, genesis); + auto transaction (store->tx_begin_write ()); + store->initialize (transaction, genesis); nano::work_pool pool (std::numeric_limits::max ()); nano::keypair destination; nano::state_block send1 (nano::genesis_account, genesis.hash (), nano::genesis_account, nano::genesis_amount - nano::Gxrb_ratio, destination.pub, nano::test_genesis_key.prv, nano::test_genesis_key.pub, pool.generate (genesis.hash ())); @@ -2165,57 +2165,57 @@ TEST (ledger, state_rollback_send) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_TRUE (!init); nano::stat stats; - nano::ledger ledger (store, stats); + nano::ledger ledger (*store, stats); nano::genesis genesis; - auto transaction (store.tx_begin_write ()); - store.initialize (transaction, genesis); + auto transaction (store->tx_begin_write ()); + store->initialize (transaction, genesis); nano::work_pool pool (std::numeric_limits::max ()); nano::state_block send1 (nano::genesis_account, genesis.hash (), nano::genesis_account, nano::genesis_amount - nano::Gxrb_ratio, nano::genesis_account, nano::test_genesis_key.prv, nano::test_genesis_key.pub, pool.generate (genesis.hash ())); ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, send1).code); - ASSERT_TRUE (store.block_exists (transaction, send1.hash ())); - auto send2 (store.block_get (transaction, send1.hash ())); + ASSERT_TRUE (store->block_exists (transaction, send1.hash ())); + auto send2 (store->block_get (transaction, send1.hash ())); ASSERT_NE (nullptr, send2); ASSERT_EQ (send1, *send2); ASSERT_EQ (nano::genesis_amount - nano::Gxrb_ratio, ledger.account_balance (transaction, nano::genesis_account)); ASSERT_EQ (nano::genesis_amount - nano::Gxrb_ratio, ledger.weight (transaction, nano::genesis_account)); nano::pending_info info; - ASSERT_FALSE (store.pending_get (transaction, nano::pending_key (nano::genesis_account, send1.hash ()), info)); + ASSERT_FALSE (store->pending_get (transaction, nano::pending_key (nano::genesis_account, send1.hash ()), info)); ASSERT_EQ (nano::genesis_account, info.source); ASSERT_EQ (nano::Gxrb_ratio, info.amount.number ()); ASSERT_FALSE (ledger.rollback (transaction, send1.hash ())); - ASSERT_FALSE (store.block_exists (transaction, send1.hash ())); + ASSERT_FALSE (store->block_exists (transaction, send1.hash ())); ASSERT_EQ (nano::genesis_amount, ledger.account_balance (transaction, nano::genesis_account)); ASSERT_EQ (nano::genesis_amount, ledger.weight (transaction, nano::genesis_account)); - ASSERT_FALSE (store.pending_exists (transaction, nano::pending_key (nano::genesis_account, send1.hash ()))); - ASSERT_TRUE (store.block_successor (transaction, genesis.hash ()).is_zero ()); + ASSERT_FALSE (store->pending_exists (transaction, nano::pending_key (nano::genesis_account, send1.hash ()))); + ASSERT_TRUE (store->block_successor (transaction, genesis.hash ()).is_zero ()); } TEST (ledger, state_rollback_receive) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_TRUE (!init); nano::stat stats; - nano::ledger ledger (store, stats); + nano::ledger ledger (*store, stats); nano::genesis genesis; - auto transaction (store.tx_begin_write ()); - store.initialize (transaction, genesis); + auto transaction (store->tx_begin_write ()); + store->initialize (transaction, genesis); nano::work_pool pool (std::numeric_limits::max ()); nano::state_block send1 (nano::genesis_account, genesis.hash (), nano::genesis_account, nano::genesis_amount - nano::Gxrb_ratio, nano::genesis_account, nano::test_genesis_key.prv, nano::test_genesis_key.pub, pool.generate (genesis.hash ())); ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, send1).code); nano::state_block receive1 (nano::genesis_account, send1.hash (), nano::genesis_account, nano::genesis_amount, send1.hash (), nano::test_genesis_key.prv, nano::test_genesis_key.pub, pool.generate (send1.hash ())); ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, receive1).code); - ASSERT_FALSE (store.pending_exists (transaction, nano::pending_key (nano::genesis_account, receive1.hash ()))); + ASSERT_FALSE (store->pending_exists (transaction, nano::pending_key (nano::genesis_account, receive1.hash ()))); ASSERT_FALSE (ledger.rollback (transaction, receive1.hash ())); nano::pending_info info; - ASSERT_FALSE (store.pending_get (transaction, nano::pending_key (nano::genesis_account, send1.hash ()), info)); + ASSERT_FALSE (store->pending_get (transaction, nano::pending_key (nano::genesis_account, send1.hash ()), info)); ASSERT_EQ (nano::genesis_account, info.source); ASSERT_EQ (nano::Gxrb_ratio, info.amount.number ()); - ASSERT_FALSE (store.block_exists (transaction, receive1.hash ())); + ASSERT_FALSE (store->block_exists (transaction, receive1.hash ())); ASSERT_EQ (nano::genesis_amount - nano::Gxrb_ratio, ledger.account_balance (transaction, nano::genesis_account)); ASSERT_EQ (nano::genesis_amount - nano::Gxrb_ratio, ledger.weight (transaction, nano::genesis_account)); } @@ -2224,24 +2224,24 @@ TEST (ledger, state_rollback_received_send) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_TRUE (!init); nano::stat stats; - nano::ledger ledger (store, stats); + nano::ledger ledger (*store, stats); nano::genesis genesis; - auto transaction (store.tx_begin_write ()); - store.initialize (transaction, genesis); + auto transaction (store->tx_begin_write ()); + store->initialize (transaction, genesis); nano::work_pool pool (std::numeric_limits::max ()); nano::keypair key; nano::state_block send1 (nano::genesis_account, genesis.hash (), nano::genesis_account, nano::genesis_amount - nano::Gxrb_ratio, key.pub, nano::test_genesis_key.prv, nano::test_genesis_key.pub, pool.generate (genesis.hash ())); ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, send1).code); nano::state_block receive1 (key.pub, 0, key.pub, nano::Gxrb_ratio, send1.hash (), key.prv, key.pub, pool.generate (key.pub)); ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, receive1).code); - ASSERT_FALSE (store.pending_exists (transaction, nano::pending_key (nano::genesis_account, receive1.hash ()))); + ASSERT_FALSE (store->pending_exists (transaction, nano::pending_key (nano::genesis_account, receive1.hash ()))); ASSERT_FALSE (ledger.rollback (transaction, send1.hash ())); - ASSERT_FALSE (store.pending_exists (transaction, nano::pending_key (nano::genesis_account, send1.hash ()))); - ASSERT_FALSE (store.block_exists (transaction, send1.hash ())); - ASSERT_FALSE (store.block_exists (transaction, receive1.hash ())); + ASSERT_FALSE (store->pending_exists (transaction, nano::pending_key (nano::genesis_account, send1.hash ()))); + ASSERT_FALSE (store->block_exists (transaction, send1.hash ())); + ASSERT_FALSE (store->block_exists (transaction, receive1.hash ())); ASSERT_EQ (nano::genesis_amount, ledger.account_balance (transaction, nano::genesis_account)); ASSERT_EQ (nano::genesis_amount, ledger.weight (transaction, nano::genesis_account)); ASSERT_EQ (0, ledger.account_balance (transaction, key.pub)); @@ -2252,19 +2252,19 @@ TEST (ledger, state_rep_change_rollback) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_TRUE (!init); nano::stat stats; - nano::ledger ledger (store, stats); + nano::ledger ledger (*store, stats); nano::genesis genesis; - auto transaction (store.tx_begin_write ()); - store.initialize (transaction, genesis); + auto transaction (store->tx_begin_write ()); + store->initialize (transaction, genesis); nano::work_pool pool (std::numeric_limits::max ()); nano::keypair rep; nano::state_block change1 (nano::genesis_account, genesis.hash (), rep.pub, nano::genesis_amount, 0, nano::test_genesis_key.prv, nano::test_genesis_key.pub, pool.generate (genesis.hash ())); ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, change1).code); ASSERT_FALSE (ledger.rollback (transaction, change1.hash ())); - ASSERT_FALSE (store.block_exists (transaction, change1.hash ())); + ASSERT_FALSE (store->block_exists (transaction, change1.hash ())); ASSERT_EQ (nano::genesis_amount, ledger.account_balance (transaction, nano::genesis_account)); ASSERT_EQ (nano::genesis_amount, ledger.weight (transaction, nano::genesis_account)); ASSERT_EQ (0, ledger.weight (transaction, rep.pub)); @@ -2274,13 +2274,13 @@ TEST (ledger, state_open_rollback) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_TRUE (!init); nano::stat stats; - nano::ledger ledger (store, stats); + nano::ledger ledger (*store, stats); nano::genesis genesis; - auto transaction (store.tx_begin_write ()); - store.initialize (transaction, genesis); + auto transaction (store->tx_begin_write ()); + store->initialize (transaction, genesis); nano::work_pool pool (std::numeric_limits::max ()); nano::keypair destination; nano::state_block send1 (nano::genesis_account, genesis.hash (), nano::genesis_account, nano::genesis_amount - nano::Gxrb_ratio, destination.pub, nano::test_genesis_key.prv, nano::test_genesis_key.pub, pool.generate (genesis.hash ())); @@ -2288,11 +2288,11 @@ TEST (ledger, state_open_rollback) nano::state_block open1 (destination.pub, 0, nano::genesis_account, nano::Gxrb_ratio, send1.hash (), destination.prv, destination.pub, pool.generate (destination.pub)); ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, open1).code); ASSERT_FALSE (ledger.rollback (transaction, open1.hash ())); - ASSERT_FALSE (store.block_exists (transaction, open1.hash ())); + ASSERT_FALSE (store->block_exists (transaction, open1.hash ())); ASSERT_EQ (0, ledger.account_balance (transaction, destination.pub)); ASSERT_EQ (nano::genesis_amount - nano::Gxrb_ratio, ledger.weight (transaction, nano::genesis_account)); nano::pending_info info; - ASSERT_FALSE (store.pending_get (transaction, nano::pending_key (destination.pub, send1.hash ()), info)); + ASSERT_FALSE (store->pending_get (transaction, nano::pending_key (destination.pub, send1.hash ()), info)); ASSERT_EQ (nano::genesis_account, info.source); ASSERT_EQ (nano::Gxrb_ratio, info.amount.number ()); } @@ -2301,19 +2301,19 @@ TEST (ledger, state_send_change_rollback) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_TRUE (!init); nano::stat stats; - nano::ledger ledger (store, stats); + nano::ledger ledger (*store, stats); nano::genesis genesis; - auto transaction (store.tx_begin_write ()); - store.initialize (transaction, genesis); + auto transaction (store->tx_begin_write ()); + store->initialize (transaction, genesis); nano::work_pool pool (std::numeric_limits::max ()); nano::keypair rep; nano::state_block send1 (nano::genesis_account, genesis.hash (), rep.pub, nano::genesis_amount - nano::Gxrb_ratio, nano::genesis_account, nano::test_genesis_key.prv, nano::test_genesis_key.pub, pool.generate (genesis.hash ())); ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, send1).code); ASSERT_FALSE (ledger.rollback (transaction, send1.hash ())); - ASSERT_FALSE (store.block_exists (transaction, send1.hash ())); + ASSERT_FALSE (store->block_exists (transaction, send1.hash ())); ASSERT_EQ (nano::genesis_amount, ledger.account_balance (transaction, nano::genesis_account)); ASSERT_EQ (nano::genesis_amount, ledger.weight (transaction, nano::genesis_account)); ASSERT_EQ (0, ledger.weight (transaction, rep.pub)); @@ -2323,13 +2323,13 @@ TEST (ledger, state_receive_change_rollback) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_TRUE (!init); nano::stat stats; - nano::ledger ledger (store, stats); + nano::ledger ledger (*store, stats); nano::genesis genesis; - auto transaction (store.tx_begin_write ()); - store.initialize (transaction, genesis); + auto transaction (store->tx_begin_write ()); + store->initialize (transaction, genesis); nano::work_pool pool (std::numeric_limits::max ()); nano::state_block send1 (nano::genesis_account, genesis.hash (), nano::genesis_account, nano::genesis_amount - nano::Gxrb_ratio, nano::genesis_account, nano::test_genesis_key.prv, nano::test_genesis_key.pub, pool.generate (genesis.hash ())); ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, send1).code); @@ -2337,7 +2337,7 @@ TEST (ledger, state_receive_change_rollback) nano::state_block receive1 (nano::genesis_account, send1.hash (), rep.pub, nano::genesis_amount, send1.hash (), nano::test_genesis_key.prv, nano::test_genesis_key.pub, pool.generate (send1.hash ())); ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, receive1).code); ASSERT_FALSE (ledger.rollback (transaction, receive1.hash ())); - ASSERT_FALSE (store.block_exists (transaction, receive1.hash ())); + ASSERT_FALSE (store->block_exists (transaction, receive1.hash ())); ASSERT_EQ (nano::genesis_amount - nano::Gxrb_ratio, ledger.account_balance (transaction, nano::genesis_account)); ASSERT_EQ (nano::genesis_amount - nano::Gxrb_ratio, ledger.weight (transaction, nano::genesis_account)); ASSERT_EQ (0, ledger.weight (transaction, rep.pub)); @@ -2347,14 +2347,14 @@ TEST (ledger, epoch_blocks_general) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_TRUE (!init); nano::stat stats; nano::keypair epoch_key; - nano::ledger ledger (store, stats, 123, epoch_key.pub); + nano::ledger ledger (*store, stats, 123, epoch_key.pub); nano::genesis genesis; - auto transaction (store.tx_begin_write ()); - store.initialize (transaction, genesis); + auto transaction (store->tx_begin_write ()); + store->initialize (transaction, genesis); nano::work_pool pool (std::numeric_limits::max ()); nano::keypair destination; nano::state_block epoch1 (nano::genesis_account, genesis.hash (), nano::genesis_account, nano::genesis_amount, 123, epoch_key.prv, epoch_key.pub, pool.generate (genesis.hash ())); @@ -2395,14 +2395,14 @@ TEST (ledger, epoch_blocks_receive_upgrade) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_TRUE (!init); nano::stat stats; nano::keypair epoch_key; - nano::ledger ledger (store, stats, 123, epoch_key.pub); + nano::ledger ledger (*store, stats, 123, epoch_key.pub); nano::genesis genesis; - auto transaction (store.tx_begin_write ()); - store.initialize (transaction, genesis); + auto transaction (store->tx_begin_write ()); + store->initialize (transaction, genesis); nano::work_pool pool (std::numeric_limits::max ()); nano::keypair destination; nano::state_block send1 (nano::genesis_account, genesis.hash (), nano::genesis_account, nano::genesis_amount - nano::Gxrb_ratio, destination.pub, nano::test_genesis_key.prv, nano::test_genesis_key.pub, pool.generate (genesis.hash ())); @@ -2437,14 +2437,14 @@ TEST (ledger, epoch_blocks_fork) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_TRUE (!init); nano::stat stats; nano::keypair epoch_key; - nano::ledger ledger (store, stats, 123, epoch_key.pub); + nano::ledger ledger (*store, stats, 123, epoch_key.pub); nano::genesis genesis; - auto transaction (store.tx_begin_write ()); - store.initialize (transaction, genesis); + auto transaction (store->tx_begin_write ()); + store->initialize (transaction, genesis); nano::work_pool pool (std::numeric_limits::max ()); nano::keypair destination; nano::send_block send1 (genesis.hash (), nano::account (0), nano::genesis_amount, nano::test_genesis_key.prv, nano::test_genesis_key.pub, pool.generate (genesis.hash ())); @@ -2566,17 +2566,17 @@ TEST (ledger, could_fit) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_TRUE (!init); nano::stat stats; nano::keypair epoch_key; - nano::ledger ledger (store, stats, 123, epoch_key.pub); + nano::ledger ledger (*store, stats, 123, epoch_key.pub); nano::keypair epoch_signer; ledger.epoch_link = 123; ledger.epoch_signer = epoch_signer.pub; nano::genesis genesis; - auto transaction (store.tx_begin_write ()); - store.initialize (transaction, genesis); + auto transaction (store->tx_begin_write ()); + store->initialize (transaction, genesis); nano::work_pool pool (std::numeric_limits::max ()); nano::keypair destination; // Test legacy and state change blocks could_fit @@ -2795,25 +2795,25 @@ TEST (ledger, confirmation_height_not_updated) { bool error (false); nano::logger_mt logger; - nano::mdb_store store (error, logger, nano::unique_path ()); + auto store = nano::make_store (error, logger, nano::unique_path ()); ASSERT_TRUE (!error); nano::stat stats; - nano::ledger ledger (store, stats); - auto transaction (store.tx_begin_write ()); + nano::ledger ledger (*store, stats); + auto transaction (store->tx_begin_write ()); nano::genesis genesis; - store.initialize (transaction, genesis); + store->initialize (transaction, genesis); nano::work_pool pool (std::numeric_limits::max ()); nano::account_info account_info; - ASSERT_FALSE (store.account_get (transaction, nano::test_genesis_key.pub, account_info)); + ASSERT_FALSE (store->account_get (transaction, nano::test_genesis_key.pub, account_info)); nano::keypair key; nano::send_block send1 (account_info.head, key.pub, 50, nano::test_genesis_key.prv, nano::test_genesis_key.pub, pool.generate (account_info.head)); ASSERT_EQ (1, account_info.confirmation_height); ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, send1).code); - ASSERT_FALSE (store.account_get (transaction, nano::test_genesis_key.pub, account_info)); + ASSERT_FALSE (store->account_get (transaction, nano::test_genesis_key.pub, account_info)); ASSERT_EQ (1, account_info.confirmation_height); nano::open_block open1 (send1.hash (), nano::genesis_account, key.pub, key.prv, key.pub, pool.generate (key.pub)); ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, open1).code); nano::account_info account_info1; - ASSERT_FALSE (store.account_get (transaction, key.pub, account_info1)); + ASSERT_FALSE (store->account_get (transaction, key.pub, account_info1)); ASSERT_EQ (0, account_info1.confirmation_height); } diff --git a/nano/core_test/node.cpp b/nano/core_test/node.cpp index 0641e875..277b6c7d 100644 --- a/nano/core_test/node.cpp +++ b/nano/core_test/node.cpp @@ -2041,7 +2041,7 @@ TEST (node, vote_replay) } { auto transaction (system.nodes[0]->store.tx_begin_read ()); - std::lock_guard lock (boost::polymorphic_downcast (system.nodes[0]->store_impl.get ())->cache_mutex); + std::lock_guard lock (system.nodes[0]->store.get_cache_mutex ()); auto vote (system.nodes[0]->store.vote_current (transaction, nano::test_genesis_key.pub)); ASSERT_EQ (nullptr, vote); } @@ -2054,7 +2054,7 @@ TEST (node, vote_replay) { auto ec = system.poll (); auto transaction (system.nodes[0]->store.tx_begin_read ()); - std::lock_guard lock (boost::polymorphic_downcast (system.nodes[0]->store_impl.get ())->cache_mutex); + std::lock_guard lock (system.nodes[0]->store.get_cache_mutex ()); auto vote (system.nodes[0]->store.vote_current (transaction, nano::test_genesis_key.pub)); done = vote && (vote->sequence >= 10000); ASSERT_NO_ERROR (ec); @@ -2284,7 +2284,7 @@ TEST (node, local_votes_cache) node.network.process_message (message2, channel); } { - std::lock_guard lock (boost::polymorphic_downcast (node.store_impl.get ())->cache_mutex); + std::lock_guard lock (node.store.get_cache_mutex ()); auto transaction (node.store.tx_begin_read ()); auto current_vote (node.store.vote_current (transaction, nano::test_genesis_key.pub)); ASSERT_EQ (current_vote->sequence, 2); @@ -2300,7 +2300,7 @@ TEST (node, local_votes_cache) node.network.process_message (message3, channel); } { - std::lock_guard lock (boost::polymorphic_downcast (node.store_impl.get ())->cache_mutex); + std::lock_guard lock (node.store.get_cache_mutex ()); auto transaction (node.store.tx_begin_read ()); auto current_vote (node.store.vote_current (transaction, nano::test_genesis_key.pub)); ASSERT_EQ (current_vote->sequence, 3); @@ -2334,7 +2334,7 @@ TEST (node, local_votes_cache_generate_new_vote) ASSERT_EQ (1, votes1[0]->blocks.size ()); ASSERT_EQ (send1->hash (), boost::get (votes1[0]->blocks[0])); { - std::lock_guard lock (boost::polymorphic_downcast (node.store_impl.get ())->cache_mutex); + std::lock_guard lock (node.store.get_cache_mutex ()); auto transaction (node.store.tx_begin_read ()); auto current_vote (node.store.vote_current (transaction, nano::test_genesis_key.pub)); ASSERT_EQ (current_vote->sequence, 1); @@ -2355,7 +2355,7 @@ TEST (node, local_votes_cache_generate_new_vote) ASSERT_EQ (1, votes2.size ()); ASSERT_EQ (2, votes2[0]->blocks.size ()); { - std::lock_guard lock (boost::polymorphic_downcast (node.store_impl.get ())->cache_mutex); + std::lock_guard lock (node.store.get_cache_mutex ()); auto transaction (node.store.tx_begin_read ()); auto current_vote (node.store.vote_current (transaction, nano::test_genesis_key.pub)); ASSERT_EQ (current_vote->sequence, 2); @@ -2869,10 +2869,14 @@ TEST (node, peer_cache_restart) // Restart node { nano::node_init init; - auto node (std::make_shared (init, system.io_ctx, 24002, path, system.alarm, system.logging, system.work)); + nano::node_flags node_flags; + node_flags.read_only = true; + auto node (std::make_shared (init, system.io_ctx, 24002, path, system.alarm, system.logging, system.work, node_flags)); system.nodes.push_back (node); // Check cached peers after restart - node->start (); + node->network.start (); + node->add_initial_peers (); + auto & store = node->store; { auto transaction (store.tx_begin_read ()); diff --git a/nano/core_test/processor_service.cpp b/nano/core_test/processor_service.cpp index d469c6e6..379e836f 100644 --- a/nano/core_test/processor_service.cpp +++ b/nano/core_test/processor_service.cpp @@ -12,16 +12,16 @@ TEST (processor_service, bad_send_signature) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_FALSE (init); nano::stat stats; - nano::ledger ledger (store, stats); + nano::ledger ledger (*store, stats); nano::genesis genesis; - auto transaction (store.tx_begin_write ()); - store.initialize (transaction, genesis); + auto transaction (store->tx_begin_write ()); + store->initialize (transaction, genesis); nano::work_pool pool (std::numeric_limits::max ()); nano::account_info info1; - ASSERT_FALSE (store.account_get (transaction, nano::test_genesis_key.pub, info1)); + ASSERT_FALSE (store->account_get (transaction, nano::test_genesis_key.pub, info1)); nano::keypair key2; nano::send_block send (info1.head, nano::test_genesis_key.pub, 50, nano::test_genesis_key.prv, nano::test_genesis_key.pub, pool.generate (info1.head)); send.signature.bytes[32] ^= 0x1; @@ -32,21 +32,21 @@ TEST (processor_service, bad_receive_signature) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_FALSE (init); nano::stat stats; - nano::ledger ledger (store, stats); + nano::ledger ledger (*store, stats); nano::genesis genesis; - auto transaction (store.tx_begin_write ()); - store.initialize (transaction, genesis); + auto transaction (store->tx_begin_write ()); + store->initialize (transaction, genesis); nano::work_pool pool (std::numeric_limits::max ()); nano::account_info info1; - ASSERT_FALSE (store.account_get (transaction, nano::test_genesis_key.pub, info1)); + ASSERT_FALSE (store->account_get (transaction, nano::test_genesis_key.pub, info1)); nano::send_block send (info1.head, nano::test_genesis_key.pub, 50, nano::test_genesis_key.prv, nano::test_genesis_key.pub, pool.generate (info1.head)); nano::block_hash hash1 (send.hash ()); ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, send).code); nano::account_info info2; - ASSERT_FALSE (store.account_get (transaction, nano::test_genesis_key.pub, info2)); + ASSERT_FALSE (store->account_get (transaction, nano::test_genesis_key.pub, info2)); nano::receive_block receive (hash1, hash1, nano::test_genesis_key.prv, nano::test_genesis_key.pub, pool.generate (hash1)); receive.signature.bytes[32] ^= 0x1; ASSERT_EQ (nano::process_result::bad_signature, ledger.process (transaction, receive).code); diff --git a/nano/core_test/versioning.cpp b/nano/core_test/versioning.cpp index 299e2e35..3591f1ff 100644 --- a/nano/core_test/versioning.cpp +++ b/nano/core_test/versioning.cpp @@ -1,5 +1,5 @@ #include -#include +#include #include #include diff --git a/nano/core_test/wallet.cpp b/nano/core_test/wallet.cpp index e179ef0c..168d2a66 100644 --- a/nano/core_test/wallet.cpp +++ b/nano/core_test/wallet.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include diff --git a/nano/core_test/wallets.cpp b/nano/core_test/wallets.cpp index 1e837670..c990ae23 100644 --- a/nano/core_test/wallets.cpp +++ b/nano/core_test/wallets.cpp @@ -99,7 +99,7 @@ TEST (wallets, upgrade) nano::account_info info; ASSERT_FALSE (mdb_store.account_get (transaction_destination, nano::genesis_account, info)); nano::account_info_v13 account_info_v13 (info.head, info.rep_block, info.open_block, info.balance, info.modified, info.block_count, info.epoch); - auto status (mdb_put (mdb_store.env.tx (transaction_destination), mdb_store.get_account_db (info.epoch), nano::mdb_val (nano::test_genesis_key.pub), nano::mdb_val (account_info_v13), 0)); + auto status (mdb_put (mdb_store.env.tx (transaction_destination), mdb_store.get_account_db (info.epoch) == nano::block_store_partial::tables::accounts_v0 ? mdb_store.accounts_v0 : mdb_store.accounts_v1, nano::mdb_val (nano::test_genesis_key.pub), nano::mdb_val (account_info_v13), 0)); (void)status; assert (status == 0); } diff --git a/nano/node/CMakeLists.txt b/nano/node/CMakeLists.txt index f4b30140..4883929b 100644 --- a/nano/node/CMakeLists.txt +++ b/nano/node/CMakeLists.txt @@ -49,10 +49,15 @@ add_library (node json_handler.cpp json_payment_observer.hpp json_payment_observer.cpp - lmdb.hpp - lmdb.cpp - lmdb_txn_tracker.hpp - lmdb_txn_tracker.cpp + lmdb/lmdb.hpp + lmdb/lmdb.cpp + lmdb/lmdb_env.hpp + lmdb/lmdb_env.cpp + lmdb/lmdb_iterator.hpp + lmdb/lmdb_txn.hpp + lmdb/lmdb_txn.cpp + lmdb/wallet_value.hpp + lmdb/wallet_value.cpp logging.hpp logging.cpp network.hpp diff --git a/nano/node/lmdb/lmdb.cpp b/nano/node/lmdb/lmdb.cpp new file mode 100644 index 00000000..9166c6ab --- /dev/null +++ b/nano/node/lmdb/lmdb.cpp @@ -0,0 +1,617 @@ +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +namespace nano +{ +template <> +void * mdb_val::data () const +{ + return value.mv_data; +} + +template <> +size_t mdb_val::size () const +{ + return value.mv_size; +} + +template <> +mdb_val::db_val (size_t size_a, void * data_a, nano::epoch epoch_a) : +value ({ size_a, data_a }), +epoch (epoch_a) +{ +} + +template <> +void mdb_val::convert_buffer_to_value () +{ + value = { buffer->size (), const_cast (buffer->data ()) }; +} +} + +nano::mdb_store::mdb_store (bool & error_a, nano::logger_mt & logger_a, boost::filesystem::path const & path_a, nano::txn_tracking_config const & txn_tracking_config_a, std::chrono::milliseconds block_processor_batch_max_time_a, int lmdb_max_dbs, bool drop_unchecked, size_t const batch_size) : +logger (logger_a), +env (error_a, path_a, lmdb_max_dbs, true), +mdb_txn_tracker (logger_a, txn_tracking_config_a, block_processor_batch_max_time_a), +txn_tracking_enabled (txn_tracking_config_a.enable) +{ + if (!error_a) + { + auto is_fully_upgraded (false); + { + auto transaction (tx_begin_read ()); + auto err = mdb_dbi_open (env.tx (transaction), "meta", 0, &meta); + if (err == MDB_SUCCESS) + { + is_fully_upgraded = (version_get (transaction) == version); + mdb_dbi_close (env, meta); + } + } + + // Only open a write lock when upgrades are needed. This is because CLI commands + // open inactive nodes which can otherwise be locked here if there is a long write + // (can be a few minutes with the --fastbootstrap flag for instance) + if (!is_fully_upgraded) + { + auto transaction (tx_begin_write ()); + open_databases (error_a, transaction, MDB_CREATE); + if (!error_a) + { + error_a |= do_upgrades (transaction, batch_size); + } + } + else + { + auto transaction (tx_begin_read ()); + open_databases (error_a, transaction, 0); + } + + if (!error_a && drop_unchecked) + { + auto transaction (tx_begin_write ()); + unchecked_clear (transaction); + } + } +} + +void nano::mdb_store::serialize_mdb_tracker (boost::property_tree::ptree & json, std::chrono::milliseconds min_read_time, std::chrono::milliseconds min_write_time) +{ + mdb_txn_tracker.serialize_json (json, min_read_time, min_write_time); +} + +nano::write_transaction nano::mdb_store::tx_begin_write () +{ + return env.tx_begin_write (create_txn_callbacks ()); +} + +nano::read_transaction nano::mdb_store::tx_begin_read () +{ + return env.tx_begin_read (create_txn_callbacks ()); +} + +nano::mdb_txn_callbacks nano::mdb_store::create_txn_callbacks () +{ + nano::mdb_txn_callbacks mdb_txn_callbacks; + if (txn_tracking_enabled) + { + // clang-format off + mdb_txn_callbacks.txn_start = ([&mdb_txn_tracker = mdb_txn_tracker](const nano::transaction_impl * transaction_impl) { + mdb_txn_tracker.add (transaction_impl); + }); + mdb_txn_callbacks.txn_end = ([&mdb_txn_tracker = mdb_txn_tracker](const nano::transaction_impl * transaction_impl) { + mdb_txn_tracker.erase (transaction_impl); + }); + // clang-format on + } + return mdb_txn_callbacks; +} + +void nano::mdb_store::open_databases (bool & error_a, nano::transaction const & transaction_a, unsigned flags) +{ + error_a |= mdb_dbi_open (env.tx (transaction_a), "frontiers", flags, &frontiers) != 0; + error_a |= mdb_dbi_open (env.tx (transaction_a), "accounts", flags, &accounts_v0) != 0; + error_a |= mdb_dbi_open (env.tx (transaction_a), "accounts_v1", flags, &accounts_v1) != 0; + error_a |= mdb_dbi_open (env.tx (transaction_a), "send", flags, &send_blocks) != 0; + error_a |= mdb_dbi_open (env.tx (transaction_a), "receive", flags, &receive_blocks) != 0; + error_a |= mdb_dbi_open (env.tx (transaction_a), "open", flags, &open_blocks) != 0; + error_a |= mdb_dbi_open (env.tx (transaction_a), "change", flags, &change_blocks) != 0; + error_a |= mdb_dbi_open (env.tx (transaction_a), "state", flags, &state_blocks_v0) != 0; + error_a |= mdb_dbi_open (env.tx (transaction_a), "state_v1", flags, &state_blocks_v1) != 0; + error_a |= mdb_dbi_open (env.tx (transaction_a), "pending", flags, &pending_v0) != 0; + error_a |= mdb_dbi_open (env.tx (transaction_a), "pending_v1", flags, &pending_v1) != 0; + error_a |= mdb_dbi_open (env.tx (transaction_a), "representation", flags, &representation) != 0; + error_a |= mdb_dbi_open (env.tx (transaction_a), "unchecked", flags, &unchecked) != 0; + error_a |= mdb_dbi_open (env.tx (transaction_a), "vote", flags, &vote) != 0; + error_a |= mdb_dbi_open (env.tx (transaction_a), "online_weight", flags, &online_weight) != 0; + error_a |= mdb_dbi_open (env.tx (transaction_a), "meta", flags, &meta) != 0; + error_a |= mdb_dbi_open (env.tx (transaction_a), "peers", flags, &peers) != 0; + if (!full_sideband (transaction_a)) + { + error_a |= mdb_dbi_open (env.tx (transaction_a), "blocks_info", flags, &blocks_info) != 0; + } +} + +bool nano::mdb_store::do_upgrades (nano::write_transaction & transaction_a, size_t batch_size) +{ + auto error (false); + auto version_l = version_get (transaction_a); + switch (version_l) + { + case 1: + upgrade_v1_to_v2 (transaction_a); + case 2: + upgrade_v2_to_v3 (transaction_a); + case 3: + upgrade_v3_to_v4 (transaction_a); + case 4: + upgrade_v4_to_v5 (transaction_a); + case 5: + upgrade_v5_to_v6 (transaction_a); + case 6: + upgrade_v6_to_v7 (transaction_a); + case 7: + upgrade_v7_to_v8 (transaction_a); + case 8: + upgrade_v8_to_v9 (transaction_a); + case 9: + case 10: + upgrade_v10_to_v11 (transaction_a); + case 11: + upgrade_v11_to_v12 (transaction_a); + case 12: + upgrade_v12_to_v13 (transaction_a, batch_size); + case 13: + upgrade_v13_to_v14 (transaction_a); + case 14: + break; + default: + logger.always_log (boost::str (boost::format ("The version of the ledger (%1%) is too high for this node") % version_l)); + error = true; + break; + } + return error; +} + +void nano::mdb_store::upgrade_v1_to_v2 (nano::transaction const & transaction_a) +{ + version_put (transaction_a, 2); + nano::account account (1); + while (!account.is_zero ()) + { + nano::mdb_iterator i (transaction_a, accounts_v0, nano::mdb_val (account)); + std::cerr << std::hex; + if (i != nano::mdb_iterator (nullptr)) + { + account = nano::uint256_union (i->first); + nano::account_info_v1 v1 (i->second); + nano::account_info_v5 v2; + v2.balance = v1.balance; + v2.head = v1.head; + v2.modified = v1.modified; + v2.rep_block = v1.rep_block; + auto block (block_get (transaction_a, v1.head)); + while (!block->previous ().is_zero ()) + { + block = block_get (transaction_a, block->previous ()); + } + v2.open_block = block->hash (); + auto status (mdb_put (env.tx (transaction_a), accounts_v0, nano::mdb_val (account), nano::mdb_val (sizeof (v2), &v2), 0)); + release_assert (status == 0); + account = account.number () + 1; + } + else + { + account.clear (); + } + } +} + +void nano::mdb_store::upgrade_v2_to_v3 (nano::transaction const & transaction_a) +{ + version_put (transaction_a, 3); + mdb_drop (env.tx (transaction_a), representation, 0); + for (auto i (std::make_unique> (transaction_a, accounts_v0)), n (std::make_unique> (nullptr)); *i != *n; ++(*i)) + { + nano::account account_l ((*i)->first); + nano::account_info_v5 info ((*i)->second); + representative_visitor visitor (transaction_a, *this); + visitor.compute (info.head); + assert (!visitor.result.is_zero ()); + info.rep_block = visitor.result; + auto impl (boost::polymorphic_downcast *> (i.get ())); + mdb_cursor_put (impl->cursor, nano::mdb_val (account_l), nano::mdb_val (sizeof (info), &info), MDB_CURRENT); + representation_add (transaction_a, visitor.result, info.balance.number ()); + } +} + +void nano::mdb_store::upgrade_v3_to_v4 (nano::transaction const & transaction_a) +{ + version_put (transaction_a, 4); + std::queue> items; + for (auto i (nano::store_iterator (std::make_unique> (transaction_a, pending_v0))), n (nano::store_iterator (nullptr)); i != n; ++i) + { + nano::block_hash const & hash (i->first); + nano::pending_info_v3 const & info (i->second); + items.push (std::make_pair (nano::pending_key (info.destination, hash), nano::pending_info (info.source, info.amount, nano::epoch::epoch_0))); + } + mdb_drop (env.tx (transaction_a), pending_v0, 0); + while (!items.empty ()) + { + pending_put (transaction_a, items.front ().first, items.front ().second); + items.pop (); + } +} + +void nano::mdb_store::upgrade_v4_to_v5 (nano::transaction const & transaction_a) +{ + version_put (transaction_a, 5); + for (auto i (nano::store_iterator (std::make_unique> (transaction_a, accounts_v0))), n (nano::store_iterator (nullptr)); i != n; ++i) + { + nano::account_info_v5 const & info (i->second); + nano::block_hash successor (0); + auto block (block_get (transaction_a, info.head)); + while (block != nullptr) + { + auto hash (block->hash ()); + if (block_successor (transaction_a, hash).is_zero () && !successor.is_zero ()) + { + std::vector vector; + { + nano::vectorstream stream (vector); + block->serialize (stream); + nano::write (stream, successor.bytes); + } + block_raw_put (transaction_a, vector, block->type (), nano::epoch::epoch_0, hash); + if (!block->previous ().is_zero ()) + { + nano::block_type type; + auto value (block_raw_get (transaction_a, block->previous (), type)); + auto version (block_version (transaction_a, block->previous ())); + assert (value.size () != 0); + std::vector data (static_cast (value.data ()), static_cast (value.data ()) + value.size ()); + std::copy (hash.bytes.begin (), hash.bytes.end (), data.end () - nano::block_sideband::size (type)); + block_raw_put (transaction_a, data, type, version, block->previous ()); + } + } + successor = hash; + block = block_get (transaction_a, block->previous ()); + } + } +} + +void nano::mdb_store::upgrade_v5_to_v6 (nano::transaction const & transaction_a) +{ + version_put (transaction_a, 6); + std::deque> headers; + for (auto i (nano::store_iterator (std::make_unique> (transaction_a, accounts_v0))), n (nano::store_iterator (nullptr)); i != n; ++i) + { + nano::account const & account (i->first); + nano::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 (); + } + headers.emplace_back (account, nano::account_info_v13{ info_old.head, info_old.rep_block, info_old.open_block, info_old.balance, info_old.modified, block_count, nano::epoch::epoch_0 }); + } + for (auto i (headers.begin ()), n (headers.end ()); i != n; ++i) + { + auto status (mdb_put (env.tx (transaction_a), accounts_v0, nano::mdb_val (i->first), nano::mdb_val (i->second), 0)); + release_assert (status == 0); + } +} + +void nano::mdb_store::upgrade_v6_to_v7 (nano::transaction const & transaction_a) +{ + version_put (transaction_a, 7); + mdb_drop (env.tx (transaction_a), unchecked, 0); +} + +void nano::mdb_store::upgrade_v7_to_v8 (nano::transaction const & transaction_a) +{ + version_put (transaction_a, 8); + mdb_drop (env.tx (transaction_a), unchecked, 1); + mdb_dbi_open (env.tx (transaction_a), "unchecked", MDB_CREATE | MDB_DUPSORT, &unchecked); +} + +void nano::mdb_store::upgrade_v8_to_v9 (nano::transaction const & transaction_a) +{ + version_put (transaction_a, 9); + MDB_dbi sequence; + mdb_dbi_open (env.tx (transaction_a), "sequence", MDB_CREATE | MDB_DUPSORT, &sequence); + nano::genesis genesis; + std::shared_ptr block (std::move (genesis.open)); + nano::keypair junk; + for (nano::mdb_iterator i (transaction_a, sequence), n (nano::mdb_iterator (nullptr)); i != n; ++i) + { + nano::bufferstream stream (reinterpret_cast (i->second.data ()), i->second.size ()); + uint64_t sequence; + auto error (nano::try_read (stream, sequence)); + (void)error; + // Create a dummy vote with the same sequence number for easy upgrading. This won't have a valid signature. + nano::vote dummy (nano::account (i->first), junk.prv, sequence, block); + std::vector vector; + { + nano::vectorstream stream (vector); + dummy.serialize (stream); + } + auto status1 (mdb_put (env.tx (transaction_a), vote, nano::mdb_val (i->first), nano::mdb_val (vector.size (), vector.data ()), 0)); + release_assert (status1 == 0); + assert (!error); + } + mdb_drop (env.tx (transaction_a), sequence, 1); +} + +void nano::mdb_store::upgrade_v10_to_v11 (nano::transaction const & transaction_a) +{ + version_put (transaction_a, 11); + MDB_dbi unsynced; + mdb_dbi_open (env.tx (transaction_a), "unsynced", MDB_CREATE | MDB_DUPSORT, &unsynced); + mdb_drop (env.tx (transaction_a), unsynced, 1); +} + +void nano::mdb_store::upgrade_v11_to_v12 (nano::transaction const & transaction_a) +{ + version_put (transaction_a, 12); + mdb_drop (env.tx (transaction_a), unchecked, 1); + mdb_dbi_open (env.tx (transaction_a), "unchecked", MDB_CREATE, &unchecked); + MDB_dbi checksum; + mdb_dbi_open (env.tx (transaction_a), "checksum", MDB_CREATE, &checksum); + mdb_drop (env.tx (transaction_a), checksum, 1); +} + +void nano::mdb_store::upgrade_v12_to_v13 (nano::write_transaction & transaction_a, size_t const batch_size) +{ + size_t cost (0); + nano::account account (0); + auto const & not_an_account (network_params.random.not_an_account); + while (account != not_an_account) + { + nano::account first (0); + nano::account_info_v13 second; + { + nano::store_iterator current (std::make_unique> (transaction_a, accounts_v0, accounts_v1, nano::mdb_val (account))); + nano::store_iterator end (nullptr); + if (current != end) + { + first = current->first; + second = current->second; + } + } + if (!first.is_zero ()) + { + auto hash (second.open_block); + uint64_t height (1); + nano::block_sideband sideband; + while (!hash.is_zero ()) + { + if (cost >= batch_size) + { + logger.always_log (boost::str (boost::format ("Upgrading sideband information for account %1%... height %2%") % first.to_account ().substr (0, 24) % std::to_string (height))); + transaction_a.commit (); + std::this_thread::yield (); + transaction_a.renew (); + cost = 0; + } + auto block (block_get (transaction_a, hash, &sideband)); + assert (block != nullptr); + if (sideband.height == 0) + { + sideband.height = height; + block_put (transaction_a, hash, *block, sideband, block_version (transaction_a, hash)); + cost += 16; + } + else + { + cost += 1; + } + hash = sideband.successor; + ++height; + } + account = first.number () + 1; + } + else + { + account = not_an_account; + } + } + if (account == not_an_account) + { + logger.always_log ("Completed sideband upgrade"); + version_put (transaction_a, 13); + } +} + +void nano::mdb_store::upgrade_v13_to_v14 (nano::transaction const & transaction_a) +{ + // Upgrade all accounts to have a confirmation of 0 (except genesis which should have 1) + version_put (transaction_a, 14); + nano::store_iterator i (std::make_unique> (transaction_a, accounts_v0, accounts_v1)); + nano::store_iterator n (nullptr); + + std::vector> account_infos; + account_infos.reserve (account_count (transaction_a)); + for (; i != n; ++i) + { + nano::account_info_v13 const & account_info_v13 (i->second); + uint64_t confirmation_height = 0; + if (i->first == network_params.ledger.genesis_account) + { + confirmation_height = 1; + } + account_infos.emplace_back (i->first, nano::account_info{ account_info_v13.head, account_info_v13.rep_block, account_info_v13.open_block, account_info_v13.balance, account_info_v13.modified, account_info_v13.block_count, confirmation_height, account_info_v13.epoch }); + } + + for (auto const & account_info : account_infos) + { + account_put (transaction_a, account_info.first, account_info.second); + } + + logger.always_log ("Completed confirmation height upgrade"); + + nano::uint256_union node_id_mdb_key (3); + auto error (mdb_del (env.tx (transaction_a), meta, nano::mdb_val (node_id_mdb_key), nullptr)); + release_assert (!error || error == MDB_NOTFOUND); +} + +void nano::mdb_store::version_put (nano::transaction const & transaction_a, int version_a) +{ + nano::uint256_union version_key (1); + nano::uint256_union version_value (version_a); + auto status (mdb_put (env.tx (transaction_a), meta, nano::mdb_val (version_key), nano::mdb_val (version_value), 0)); + release_assert (status == 0); + if (blocks_info == 0 && !full_sideband (transaction_a)) + { + auto status (mdb_dbi_open (env.tx (transaction_a), "blocks_info", MDB_CREATE, &blocks_info)); + release_assert (status == MDB_SUCCESS); + } + if (blocks_info != 0 && full_sideband (transaction_a)) + { + auto status (mdb_drop (env.tx (transaction_a), blocks_info, 1)); + release_assert (status == MDB_SUCCESS); + blocks_info = 0; + } +} + +bool nano::mdb_store::block_info_get (nano::transaction const & transaction_a, nano::block_hash const & hash_a, nano::block_info & block_info_a) const +{ + assert (!full_sideband (transaction_a)); + nano::mdb_val value; + auto status (mdb_get (env.tx (transaction_a), blocks_info, nano::mdb_val (hash_a), value)); + release_assert (status == 0 || status == MDB_NOTFOUND); + bool result (true); + if (status != MDB_NOTFOUND) + { + result = false; + assert (value.size () == sizeof (block_info_a.account.bytes) + sizeof (block_info_a.balance.bytes)); + nano::bufferstream stream (reinterpret_cast (value.data ()), value.size ()); + auto error1 (nano::try_read (stream, block_info_a.account)); + (void)error1; + assert (!error1); + auto error2 (nano::try_read (stream, block_info_a.balance)); + (void)error2; + assert (!error2); + } + return result; +} + +bool nano::mdb_store::exists (nano::transaction const & transaction_a, tables table_a, nano::mdb_val const & key_a) const +{ + nano::mdb_val junk; + auto status = get (transaction_a, table_a, key_a, junk); + release_assert (status == MDB_SUCCESS || status == MDB_NOTFOUND); + return (status == MDB_SUCCESS); +} + +int nano::mdb_store::get (nano::transaction const & transaction_a, tables table_a, nano::mdb_val const & key_a, nano::mdb_val & value_a) const +{ + return mdb_get (env.tx (transaction_a), table_to_dbi (table_a), key_a, value_a); +} + +int nano::mdb_store::put (nano::transaction const & transaction_a, tables table_a, nano::mdb_val const & key_a, const nano::mdb_val & value_a) const +{ + return (mdb_put (env.tx (transaction_a), table_to_dbi (table_a), key_a, value_a, 0)); +} + +int nano::mdb_store::del (nano::transaction const & transaction_a, tables table_a, nano::mdb_val const & key_a) const +{ + return (mdb_del (env.tx (transaction_a), table_to_dbi (table_a), key_a, nullptr)); +} + +int nano::mdb_store::drop (nano::transaction const & transaction_a, tables table_a) +{ + return clear (transaction_a, table_to_dbi (table_a)); +} + +int nano::mdb_store::clear (nano::transaction const & transaction_a, MDB_dbi handle_a) +{ + return mdb_drop (env.tx (transaction_a), handle_a, 0); +} + +size_t nano::mdb_store::count (nano::transaction const & transaction_a, tables table_a) const +{ + return count (transaction_a, table_to_dbi (table_a)); +} + +size_t nano::mdb_store::count (nano::transaction const & transaction_a, MDB_dbi db_a) const +{ + MDB_stat stats; + auto status (mdb_stat (env.tx (transaction_a), db_a, &stats)); + release_assert (status == 0); + return (stats.ms_entries); +} + +MDB_dbi nano::mdb_store::table_to_dbi (tables table_a) const +{ + switch (table_a) + { + case tables::frontiers: + return frontiers; + case tables::accounts_v0: + return accounts_v0; + case tables::accounts_v1: + return accounts_v1; + case tables::send_blocks: + return send_blocks; + case tables::receive_blocks: + return receive_blocks; + case tables::open_blocks: + return open_blocks; + case tables::change_blocks: + return change_blocks; + case tables::state_blocks_v0: + return state_blocks_v0; + case tables::state_blocks_v1: + return state_blocks_v1; + case tables::pending_v0: + return pending_v0; + case tables::pending_v1: + return pending_v1; + case tables::blocks_info: + return blocks_info; + case tables::representation: + return representation; + case tables::unchecked: + return unchecked; + case tables::vote: + return vote; + case tables::online_weight: + return online_weight; + case tables::meta: + return meta; + case tables::peers: + return peers; + default: + release_assert (false); + return peers; + } +} + +bool nano::mdb_store::not_found (int status) const +{ + return (MDB_NOTFOUND == status); +} + +bool nano::mdb_store::success (int status) const +{ + return (MDB_SUCCESS == status); +} + +int nano::mdb_store::status_code_not_found () const +{ + return MDB_NOTFOUND; +} diff --git a/nano/node/lmdb/lmdb.hpp b/nano/node/lmdb/lmdb.hpp new file mode 100644 index 00000000..0c8f66d6 --- /dev/null +++ b/nano/node/lmdb/lmdb.hpp @@ -0,0 +1,228 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include + +namespace nano +{ +using mdb_val = db_val; + +class logging_mt; +/** + * mdb implementation of the block store + */ +class mdb_store : public block_store_partial +{ +public: + using block_store_partial::block_exists; + using block_store_partial::unchecked_put; + + mdb_store (bool &, nano::logger_mt &, boost::filesystem::path const &, nano::txn_tracking_config const & txn_tracking_config_a = nano::txn_tracking_config{}, std::chrono::milliseconds block_processor_batch_max_time_a = std::chrono::milliseconds (5000), int lmdb_max_dbs = 128, bool drop_unchecked = false, size_t batch_size = 512); + nano::write_transaction tx_begin_write () override; + nano::read_transaction tx_begin_read () override; + + bool block_info_get (nano::transaction const &, nano::block_hash const &, nano::block_info &) const override; + + void version_put (nano::transaction const &, int) override; + + void serialize_mdb_tracker (boost::property_tree::ptree &, std::chrono::milliseconds, std::chrono::milliseconds) override; + + nano::logger_mt & logger; + + nano::mdb_env env; + + /** + * Maps head block to owning account + * nano::block_hash -> nano::account + */ + MDB_dbi frontiers{ 0 }; + + /** + * Maps account v1 to account information, head, rep, open, balance, timestamp and block count. + * nano::account -> nano::block_hash, nano::block_hash, nano::block_hash, nano::amount, uint64_t, uint64_t + */ + MDB_dbi accounts_v0{ 0 }; + + /** + * Maps account v0 to account information, head, rep, open, balance, timestamp and block count. + * nano::account -> nano::block_hash, nano::block_hash, nano::block_hash, nano::amount, uint64_t, uint64_t + */ + MDB_dbi accounts_v1{ 0 }; + + /** + * Maps block hash to send block. + * nano::block_hash -> nano::send_block + */ + MDB_dbi send_blocks{ 0 }; + + /** + * Maps block hash to receive block. + * nano::block_hash -> nano::receive_block + */ + MDB_dbi receive_blocks{ 0 }; + + /** + * Maps block hash to open block. + * nano::block_hash -> nano::open_block + */ + MDB_dbi open_blocks{ 0 }; + + /** + * Maps block hash to change block. + * nano::block_hash -> nano::change_block + */ + MDB_dbi change_blocks{ 0 }; + + /** + * Maps block hash to v0 state block. + * nano::block_hash -> nano::state_block + */ + MDB_dbi state_blocks_v0{ 0 }; + + /** + * Maps block hash to v1 state block. + * nano::block_hash -> nano::state_block + */ + MDB_dbi state_blocks_v1{ 0 }; + + /** + * Maps min_version 0 (destination account, pending block) to (source account, amount). + * nano::account, nano::block_hash -> nano::account, nano::amount + */ + MDB_dbi pending_v0{ 0 }; + + /** + * Maps min_version 1 (destination account, pending block) to (source account, amount). + * nano::account, nano::block_hash -> nano::account, nano::amount + */ + MDB_dbi pending_v1{ 0 }; + + /** + * Maps block hash to account and balance. + * block_hash -> nano::account, nano::amount + */ + MDB_dbi blocks_info{ 0 }; + + /** + * Representative weights. + * nano::account -> nano::uint128_t + */ + MDB_dbi representation{ 0 }; + + /** + * Unchecked bootstrap blocks info. + * nano::block_hash -> nano::unchecked_info + */ + MDB_dbi unchecked{ 0 }; + + /** + * Highest vote observed for account. + * nano::account -> uint64_t + */ + MDB_dbi vote{ 0 }; + + /** + * Samples of online vote weight + * uint64_t -> nano::amount + */ + MDB_dbi online_weight{ 0 }; + + /** + * Meta information about block store, such as versions. + * nano::uint256_union (arbitrary key) -> blob + */ + MDB_dbi meta{ 0 }; + + /* + * Endpoints for peers + * nano::endpoint_key -> no_value + */ + MDB_dbi peers{ 0 }; + + bool exists (nano::transaction const & transaction_a, tables table_a, nano::mdb_val const & key_a) const; + + int get (nano::transaction const & transaction_a, tables table_a, nano::mdb_val const & key_a, nano::mdb_val & value_a) const; + int put (nano::transaction const & transaction_a, tables table_a, nano::mdb_val const & key_a, const nano::mdb_val & value_a) const; + int del (nano::transaction const & transaction_a, tables table_a, nano::mdb_val const & key_a) const; + + template + nano::store_iterator make_iterator (nano::transaction const & transaction_a, tables table_a) + { + return nano::store_iterator (std::make_unique> (transaction_a, table_to_dbi (table_a))); + } + + template + nano::store_iterator make_iterator (nano::transaction const & transaction_a, tables table_a, nano::mdb_val const & key) + { + return nano::store_iterator (std::make_unique> (transaction_a, table_to_dbi (table_a), key)); + } + + template + nano::store_iterator make_merge_iterator (nano::transaction const & transaction_a, tables table1_a, tables table2_a, nano::mdb_val const & key) + { + return nano::store_iterator (std::make_unique> (transaction_a, table_to_dbi (table1_a), table_to_dbi (table2_a), key)); + } + + template + nano::store_iterator make_merge_iterator (nano::transaction const & transaction_a, tables table1_a, tables table2_a) + { + return nano::store_iterator (std::make_unique> (transaction_a, table_to_dbi (table1_a), table_to_dbi (table2_a))); + } + +private: + bool do_upgrades (nano::write_transaction &, size_t); + void upgrade_v1_to_v2 (nano::transaction const &); + void upgrade_v2_to_v3 (nano::transaction const &); + void upgrade_v3_to_v4 (nano::transaction const &); + void upgrade_v4_to_v5 (nano::transaction const &); + void upgrade_v5_to_v6 (nano::transaction const &); + void upgrade_v6_to_v7 (nano::transaction const &); + void upgrade_v7_to_v8 (nano::transaction const &); + void upgrade_v8_to_v9 (nano::transaction const &); + void upgrade_v10_to_v11 (nano::transaction const &); + void upgrade_v11_to_v12 (nano::transaction const &); + void upgrade_v12_to_v13 (nano::write_transaction &, size_t); + void upgrade_v13_to_v14 (nano::transaction const &); + void open_databases (bool &, nano::transaction const &, unsigned); + + int drop (nano::transaction const & transaction_a, tables table_a) override; + int clear (nano::transaction const & transaction_a, MDB_dbi handle_a); + + bool not_found (int status) const override; + bool success (int status) const override; + int status_code_not_found () const override; + + MDB_dbi table_to_dbi (tables table_a) const; + + nano::mdb_txn_tracker mdb_txn_tracker; + nano::mdb_txn_callbacks create_txn_callbacks (); + bool txn_tracking_enabled; + + size_t count (nano::transaction const & transaction_a, tables table_a) const override; + size_t count (nano::transaction const &, MDB_dbi) const; +}; + +template <> +void * mdb_val::data () const; +template <> +size_t mdb_val::size () const; +template <> +mdb_val::db_val (size_t size_a, void * data_a, nano::epoch epoch_a); +template <> +void mdb_val::convert_buffer_to_value (); +} diff --git a/nano/node/lmdb/lmdb_env.cpp b/nano/node/lmdb/lmdb_env.cpp new file mode 100644 index 00000000..ab1aa1b8 --- /dev/null +++ b/nano/node/lmdb/lmdb_env.cpp @@ -0,0 +1,87 @@ +#include + +nano::mdb_env::mdb_env (bool & error_a, boost::filesystem::path const & path_a, int max_dbs_a, bool use_no_mem_init_a, size_t map_size_a) +{ + boost::system::error_code error_mkdir, error_chmod; + if (path_a.has_parent_path ()) + { + boost::filesystem::create_directories (path_a.parent_path (), error_mkdir); + nano::set_secure_perm_directory (path_a.parent_path (), error_chmod); + if (!error_mkdir) + { + auto status1 (mdb_env_create (&environment)); + release_assert (status1 == 0); + auto status2 (mdb_env_set_maxdbs (environment, max_dbs_a)); + release_assert (status2 == 0); + auto map_size = map_size_a; + auto max_valgrind_map_size = 16 * 1024 * 1024; + if (running_within_valgrind () && map_size_a > max_valgrind_map_size) + { + // In order to run LMDB under Valgrind, the maximum map size must be smaller than half your available RAM + map_size = max_valgrind_map_size; + } + auto status3 (mdb_env_set_mapsize (environment, map_size)); + release_assert (status3 == 0); + // It seems if there's ever more threads than mdb_env_set_maxreaders has read slots available, we get failures on transaction creation unless MDB_NOTLS is specified + // This can happen if something like 256 io_threads are specified in the node config + // MDB_NORDAHEAD will allow platforms that support it to load the DB in memory as needed. + // MDB_NOMEMINIT prevents zeroing malloc'ed pages. Can provide improvement for non-sensitive data but may make memory checkers noisy (e.g valgrind). + auto environment_flags = MDB_NOSUBDIR | MDB_NOTLS | MDB_NORDAHEAD; + if (!running_within_valgrind () && use_no_mem_init_a) + { + environment_flags |= MDB_NOMEMINIT; + } + auto status4 (mdb_env_open (environment, path_a.string ().c_str (), environment_flags, 00600)); + if (status4 != 0) + { + std::cerr << "Could not open lmdb environment: " << status4; + char * error_str (mdb_strerror (status4)); + if (error_str) + { + std::cerr << ", " << error_str; + } + std::cerr << std::endl; + } + release_assert (status4 == 0); + error_a = status4 != 0; + } + else + { + error_a = true; + environment = nullptr; + } + } + else + { + error_a = true; + environment = nullptr; + } +} + +nano::mdb_env::~mdb_env () +{ + if (environment != nullptr) + { + mdb_env_close (environment); + } +} + +nano::mdb_env::operator MDB_env * () const +{ + return environment; +} + +nano::read_transaction nano::mdb_env::tx_begin_read (mdb_txn_callbacks mdb_txn_callbacks) const +{ + return nano::read_transaction{ std::make_unique (*this, mdb_txn_callbacks) }; +} + +nano::write_transaction nano::mdb_env::tx_begin_write (mdb_txn_callbacks mdb_txn_callbacks) const +{ + return nano::write_transaction{ std::make_unique (*this, mdb_txn_callbacks) }; +} + +MDB_txn * nano::mdb_env::tx (nano::transaction const & transaction_a) const +{ + return static_cast (transaction_a.get_handle ()); +} diff --git a/nano/node/lmdb/lmdb_env.hpp b/nano/node/lmdb/lmdb_env.hpp new file mode 100644 index 00000000..7dc22b50 --- /dev/null +++ b/nano/node/lmdb/lmdb_env.hpp @@ -0,0 +1,24 @@ +#pragma once + +#include +#include + +namespace nano +{ +/** + * RAII wrapper for MDB_env + */ +class mdb_env final +{ +public: + mdb_env (bool &, boost::filesystem::path const &, int max_dbs = 128, bool use_no_mem_init = false, size_t map_size = 128ULL * 1024 * 1024 * 1024); + ~mdb_env (); + operator MDB_env * () const; + // clang-format off + nano::read_transaction tx_begin_read (mdb_txn_callbacks txn_callbacks = mdb_txn_callbacks{}) const; + nano::write_transaction tx_begin_write (mdb_txn_callbacks txn_callbacks = mdb_txn_callbacks{}) const; + MDB_txn * tx (nano::transaction const & transaction_a) const; + // clang-format on + MDB_env * environment; +}; +} diff --git a/nano/node/lmdb/lmdb_iterator.hpp b/nano/node/lmdb/lmdb_iterator.hpp new file mode 100644 index 00000000..c36e1827 --- /dev/null +++ b/nano/node/lmdb/lmdb_iterator.hpp @@ -0,0 +1,286 @@ +#pragma once + +#include + +#include + +namespace nano +{ +template +class mdb_iterator : public store_iterator_impl +{ +public: + mdb_iterator (nano::transaction const & transaction_a, MDB_dbi db_a, nano::epoch epoch_a = nano::epoch::unspecified) : + cursor (nullptr) + { + current.first.epoch = epoch_a; + current.second.epoch = epoch_a; + auto status (mdb_cursor_open (tx (transaction_a), db_a, &cursor)); + release_assert (status == 0); + auto status2 (mdb_cursor_get (cursor, ¤t.first.value, ¤t.second.value, MDB_FIRST)); + release_assert (status2 == 0 || status2 == MDB_NOTFOUND); + if (status2 != MDB_NOTFOUND) + { + auto status3 (mdb_cursor_get (cursor, ¤t.first.value, ¤t.second.value, MDB_GET_CURRENT)); + release_assert (status3 == 0 || status3 == MDB_NOTFOUND); + if (current.first.size () != sizeof (T)) + { + clear (); + } + } + else + { + clear (); + } + } + + mdb_iterator (std::nullptr_t, nano::epoch epoch_a = nano::epoch::unspecified) : + cursor (nullptr) + { + current.first.epoch = epoch_a; + current.second.epoch = epoch_a; + } + + mdb_iterator (nano::transaction const & transaction_a, MDB_dbi db_a, MDB_val const & val_a, nano::epoch epoch_a = nano::epoch::unspecified) : + cursor (nullptr) + { + current.first.epoch = epoch_a; + current.second.epoch = epoch_a; + auto status (mdb_cursor_open (tx (transaction_a), db_a, &cursor)); + release_assert (status == 0); + current.first = val_a; + auto status2 (mdb_cursor_get (cursor, ¤t.first.value, ¤t.second.value, MDB_SET_RANGE)); + release_assert (status2 == 0 || status2 == MDB_NOTFOUND); + if (status2 != MDB_NOTFOUND) + { + auto status3 (mdb_cursor_get (cursor, ¤t.first.value, ¤t.second.value, MDB_GET_CURRENT)); + release_assert (status3 == 0 || status3 == MDB_NOTFOUND); + if (current.first.size () != sizeof (T)) + { + clear (); + } + } + else + { + clear (); + } + } + + mdb_iterator (nano::mdb_iterator && other_a) + { + cursor = other_a.cursor; + other_a.cursor = nullptr; + current = other_a.current; + } + + mdb_iterator (nano::mdb_iterator const &) = delete; + + ~mdb_iterator () + { + if (cursor != nullptr) + { + mdb_cursor_close (cursor); + } + } + + nano::store_iterator_impl & operator++ () override + { + assert (cursor != nullptr); + auto status (mdb_cursor_get (cursor, ¤t.first.value, ¤t.second.value, MDB_NEXT)); + release_assert (status == 0 || status == MDB_NOTFOUND); + if (status == MDB_NOTFOUND) + { + clear (); + } + if (current.first.size () != sizeof (T)) + { + clear (); + } + return *this; + } + + std::pair, nano::db_val> * operator-> () + { + return ¤t; + } + + bool operator== (nano::store_iterator_impl const & base_a) const override + { + auto const other_a (boost::polymorphic_downcast const *> (&base_a)); + auto result (current.first.data () == other_a->current.first.data ()); + assert (!result || (current.first.size () == other_a->current.first.size ())); + assert (!result || (current.second.data () == other_a->current.second.data ())); + assert (!result || (current.second.size () == other_a->current.second.size ())); + return result; + } + + bool is_end_sentinal () const override + { + return current.first.size () == 0; + } + void fill (std::pair & value_a) const override + { + if (current.first.size () != 0) + { + value_a.first = static_cast (current.first); + } + else + { + value_a.first = T (); + } + if (current.second.size () != 0) + { + value_a.second = static_cast (current.second); + } + else + { + value_a.second = U (); + } + } + void clear () + { + current.first = nano::db_val (current.first.epoch); + current.second = nano::db_val (current.second.epoch); + assert (is_end_sentinal ()); + } + + nano::mdb_iterator & operator= (nano::mdb_iterator && other_a) + { + if (cursor != nullptr) + { + mdb_cursor_close (cursor); + } + cursor = other_a.cursor; + other_a.cursor = nullptr; + current = other_a.current; + other_a.clear (); + return *this; + } + + nano::store_iterator_impl & operator= (nano::store_iterator_impl const &) = delete; + MDB_cursor * cursor; + std::pair, nano::db_val> current; + +private: + MDB_txn * tx (nano::transaction const & transaction_a) const + { + return static_cast (transaction_a.get_handle ()); + } +}; + +/** + * Iterates the key/value pairs of two stores merged together + */ +template +class mdb_merge_iterator : public store_iterator_impl +{ +public: + mdb_merge_iterator (nano::transaction const & transaction_a, MDB_dbi db1_a, MDB_dbi db2_a) : + impl1 (std::make_unique> (transaction_a, db1_a, nano::epoch::epoch_0)), + impl2 (std::make_unique> (transaction_a, db2_a, nano::epoch::epoch_1)) + { + } + + mdb_merge_iterator (std::nullptr_t) : + impl1 (std::make_unique> (nullptr, nano::epoch::epoch_0)), + impl2 (std::make_unique> (nullptr, nano::epoch::epoch_1)) + { + } + + mdb_merge_iterator (nano::transaction const & transaction_a, MDB_dbi db1_a, MDB_dbi db2_a, MDB_val const & val_a) : + impl1 (std::make_unique> (transaction_a, db1_a, val_a, nano::epoch::epoch_0)), + impl2 (std::make_unique> (transaction_a, db2_a, val_a, nano::epoch::epoch_1)) + { + } + + mdb_merge_iterator (nano::mdb_merge_iterator && other_a) + { + impl1 = std::move (other_a.impl1); + impl2 = std::move (other_a.impl2); + } + + mdb_merge_iterator (nano::mdb_merge_iterator const &) = delete; + + nano::store_iterator_impl & operator++ () override + { + ++least_iterator (); + return *this; + } + + std::pair, nano::db_val> * operator-> () + { + return least_iterator ().operator-> (); + } + + bool operator== (nano::store_iterator_impl const & base_a) const override + { + assert ((dynamic_cast const *> (&base_a) != nullptr) && "Incompatible iterator comparison"); + auto & other (static_cast const &> (base_a)); + return *impl1 == *other.impl1 && *impl2 == *other.impl2; + } + + bool is_end_sentinal () const override + { + return least_iterator ().is_end_sentinal (); + } + + void fill (std::pair & value_a) const override + { + auto & current (least_iterator ()); + if (current->first.size () != 0) + { + value_a.first = static_cast (current->first); + } + else + { + value_a.first = T (); + } + if (current->second.size () != 0) + { + value_a.second = static_cast (current->second); + } + else + { + value_a.second = U (); + } + } + nano::mdb_merge_iterator & operator= (nano::mdb_merge_iterator &&) = default; + nano::mdb_merge_iterator & operator= (nano::mdb_merge_iterator const &) = delete; + +private: + nano::mdb_iterator & least_iterator () const + { + nano::mdb_iterator * result; + if (impl1->is_end_sentinal ()) + { + result = impl2.get (); + } + else if (impl2->is_end_sentinal ()) + { + result = impl1.get (); + } + else + { + auto key_cmp (mdb_cmp (mdb_cursor_txn (impl1->cursor), mdb_cursor_dbi (impl1->cursor), impl1->current.first, impl2->current.first)); + + if (key_cmp < 0) + { + result = impl1.get (); + } + else if (key_cmp > 0) + { + result = impl2.get (); + } + else + { + auto val_cmp (mdb_cmp (mdb_cursor_txn (impl1->cursor), mdb_cursor_dbi (impl1->cursor), impl1->current.second, impl2->current.second)); + result = val_cmp < 0 ? impl1.get () : impl2.get (); + } + } + return *result; + } + + std::unique_ptr> impl1; + std::unique_ptr> impl2; +}; +} \ No newline at end of file diff --git a/nano/node/lmdb/lmdb_txn.cpp b/nano/node/lmdb/lmdb_txn.cpp new file mode 100644 index 00000000..12afd01c --- /dev/null +++ b/nano/node/lmdb/lmdb_txn.cpp @@ -0,0 +1,227 @@ +#include +#include +#include +#include +#include +#include + +#include + +// Some builds (mac) fail due to "Boost.Stacktrace requires `_Unwind_Backtrace` function". +#ifndef _WIN32 +#ifndef _GNU_SOURCE +#define BEFORE_GNU_SOURCE 0 +#define _GNU_SOURCE +#else +#define BEFORE_GNU_SOURCE 1 +#endif +#endif +// On Windows this include defines min/max macros, so keep below other includes +// to reduce conflicts with other std functions +#include +#ifndef _WIN32 +#if !BEFORE_GNU_SOURCE +#undef _GNU_SOURCE +#endif +#endif + +namespace +{ +class matches_txn +{ +public: + matches_txn (const nano::transaction_impl * transaction_impl_a) : + transaction_impl (transaction_impl_a) + { + } + + bool operator() (nano::mdb_txn_stats const & mdb_txn_stats) + { + return (mdb_txn_stats.transaction_impl == transaction_impl); + } + +private: + const nano::transaction_impl * transaction_impl; +}; +} + +nano::read_mdb_txn::read_mdb_txn (nano::mdb_env const & environment_a, nano::mdb_txn_callbacks txn_callbacks_a) : +txn_callbacks (txn_callbacks_a) +{ + auto status (mdb_txn_begin (environment_a, nullptr, MDB_RDONLY, &handle)); + release_assert (status == 0); + txn_callbacks.txn_start (this); +} + +nano::read_mdb_txn::~read_mdb_txn () +{ + // This uses commit rather than abort, as it is needed when opening databases with a read only transaction + auto status (mdb_txn_commit (handle)); + release_assert (status == MDB_SUCCESS); + txn_callbacks.txn_end (this); +} + +void nano::read_mdb_txn::reset () +{ + mdb_txn_reset (handle); + txn_callbacks.txn_end (this); +} + +void nano::read_mdb_txn::renew () +{ + auto status (mdb_txn_renew (handle)); + release_assert (status == 0); + txn_callbacks.txn_start (this); +} + +void * nano::read_mdb_txn::get_handle () const +{ + return handle; +} + +nano::write_mdb_txn::write_mdb_txn (nano::mdb_env const & environment_a, nano::mdb_txn_callbacks txn_callbacks_a) : +env (environment_a), +txn_callbacks (txn_callbacks_a) +{ + renew (); +} + +nano::write_mdb_txn::~write_mdb_txn () +{ + commit (); +} + +void nano::write_mdb_txn::commit () const +{ + auto status (mdb_txn_commit (handle)); + release_assert (status == MDB_SUCCESS); + txn_callbacks.txn_end (this); +} + +void nano::write_mdb_txn::renew () +{ + auto status (mdb_txn_begin (env, nullptr, 0, &handle)); + release_assert (status == MDB_SUCCESS); + txn_callbacks.txn_start (this); +} + +void * nano::write_mdb_txn::get_handle () const +{ + return handle; +} + +nano::mdb_txn_tracker::mdb_txn_tracker (nano::logger_mt & logger_a, nano::txn_tracking_config const & txn_tracking_config_a, std::chrono::milliseconds block_processor_batch_max_time_a) : +logger (logger_a), +txn_tracking_config (txn_tracking_config_a), +block_processor_batch_max_time (block_processor_batch_max_time_a) +{ +} + +void nano::mdb_txn_tracker::serialize_json (boost::property_tree::ptree & json, std::chrono::milliseconds min_read_time, std::chrono::milliseconds min_write_time) +{ + // Copying is cheap compared to generating the stack trace strings, so reduce time holding the mutex + std::vector copy_stats; + { + std::lock_guard guard (mutex); + copy_stats = stats; + } + + // Get the time difference now as creating stacktraces (Debug/Windows for instance) can take a while so results won't be as accurate + std::vector times_since_start; + times_since_start.reserve (copy_stats.size ()); + // clang-format off + std::transform (copy_stats.cbegin (), copy_stats.cend (), std::back_inserter (times_since_start), [] (const auto & stat) { + return stat.timer.since_start (); + }); + // clang-format on + assert (times_since_start.size () == copy_stats.size ()); + + for (size_t i = 0; i < times_since_start.size (); ++i) + { + auto const & stat = copy_stats[i]; + auto time_held_open = times_since_start[i]; + + if ((stat.is_write () && time_held_open >= min_write_time) || (!stat.is_write () && time_held_open >= min_read_time)) + { + nano::jsonconfig mdb_lock_config; + + mdb_lock_config.put ("thread", stat.thread_name); + mdb_lock_config.put ("time_held_open", time_held_open.count ()); + mdb_lock_config.put ("write", stat.is_write ()); + + boost::property_tree::ptree stacktrace_config; + for (auto frame : *stat.stacktrace) + { + nano::jsonconfig frame_json; + frame_json.put ("name", frame.name ()); + frame_json.put ("address", frame.address ()); + frame_json.put ("source_file", frame.source_file ()); + frame_json.put ("source_line", frame.source_line ()); + stacktrace_config.push_back (std::make_pair ("", frame_json.get_tree ())); + } + + nano::jsonconfig stack (stacktrace_config); + mdb_lock_config.put_child ("stacktrace", stack); + json.push_back (std::make_pair ("", mdb_lock_config.get_tree ())); + } + } +} + +void nano::mdb_txn_tracker::output_finished (nano::mdb_txn_stats const & mdb_txn_stats) const +{ + // Only output them if transactions were held for longer than a certain period of time + auto is_write = mdb_txn_stats.is_write (); + auto time_open = mdb_txn_stats.timer.since_start (); + + auto should_ignore = false; + // Reduce noise in log files by removing any entries from the block processor (if enabled) which are less than the max batch time (+ a few second buffer) because these are expected writes during bootstrapping. + auto is_below_max_time = time_open <= (block_processor_batch_max_time + std::chrono::seconds (3)); + bool is_blk_processing_thread = mdb_txn_stats.thread_name == nano::thread_role::get_string (nano::thread_role::name::block_processing); + if (txn_tracking_config.ignore_writes_below_block_processor_max_time && is_blk_processing_thread && is_write && is_below_max_time) + { + should_ignore = true; + } + + if (!should_ignore && ((is_write && time_open >= txn_tracking_config.min_write_txn_time) || (!is_write && time_open >= txn_tracking_config.min_read_txn_time))) + { + assert (mdb_txn_stats.stacktrace); + logger.always_log (boost::str (boost::format ("%1%ms %2% held on thread %3%\n%4%") % mdb_txn_stats.timer.since_start ().count () % (is_write ? "write lock" : "read") % mdb_txn_stats.thread_name % *mdb_txn_stats.stacktrace)); + } +} + +void nano::mdb_txn_tracker::add (const nano::transaction_impl * transaction_impl) +{ + std::lock_guard guard (mutex); + // clang-format off + assert (std::find_if (stats.cbegin (), stats.cend (), matches_txn (transaction_impl)) == stats.cend ()); + // clang-format on + stats.emplace_back (transaction_impl); +} + +/** Can be called without error if transaction does not exist */ +void nano::mdb_txn_tracker::erase (const nano::transaction_impl * transaction_impl) +{ + std::lock_guard guard (mutex); + // clang-format off + auto it = std::find_if (stats.begin (), stats.end (), matches_txn (transaction_impl)); + // clang-format on + if (it != stats.end ()) + { + output_finished (*it); + it->timer.stop (); + stats.erase (it); + } +} + +nano::mdb_txn_stats::mdb_txn_stats (const nano::transaction_impl * transaction_impl) : +transaction_impl (transaction_impl), +thread_name (nano::thread_role::get_string ()), +stacktrace (std::make_shared ()) +{ + timer.start (); +} + +bool nano::mdb_txn_stats::is_write () const +{ + return (dynamic_cast (transaction_impl) != nullptr); +} diff --git a/nano/node/lmdb/lmdb_txn.hpp b/nano/node/lmdb/lmdb_txn.hpp new file mode 100644 index 00000000..3830f60e --- /dev/null +++ b/nano/node/lmdb/lmdb_txn.hpp @@ -0,0 +1,84 @@ +#pragma once + +#include +#include +#include + +#include +#include + +#include + +#include + +namespace nano +{ +class transaction_impl; +class logger_mt; +class mdb_env; + +class mdb_txn_callbacks +{ +public: + // clang-format off + std::function txn_start{ [] (const nano::transaction_impl *) {} }; + std::function txn_end{ [] (const nano::transaction_impl *) {} }; + // clang-format on +}; + +class read_mdb_txn final : public read_transaction_impl +{ +public: + read_mdb_txn (nano::mdb_env const &, mdb_txn_callbacks mdb_txn_callbacks); + ~read_mdb_txn (); + void reset () override; + void renew () override; + void * get_handle () const override; + MDB_txn * handle; + mdb_txn_callbacks txn_callbacks; +}; + +class write_mdb_txn final : public write_transaction_impl +{ +public: + write_mdb_txn (nano::mdb_env const &, mdb_txn_callbacks mdb_txn_callbacks); + ~write_mdb_txn (); + void commit () const override; + void renew () override; + void * get_handle () const override; + MDB_txn * handle; + nano::mdb_env const & env; + mdb_txn_callbacks txn_callbacks; +}; + +class mdb_txn_stats +{ +public: + mdb_txn_stats (const nano::transaction_impl * transaction_impl_a); + bool is_write () const; + nano::timer timer; + const nano::transaction_impl * transaction_impl; + std::string thread_name; + + // Smart pointer so that we don't need the full definition which causes min/max issues on Windows + std::shared_ptr stacktrace; +}; + +class mdb_txn_tracker +{ +public: + mdb_txn_tracker (nano::logger_mt & logger_a, nano::txn_tracking_config const & txn_tracking_config_a, std::chrono::milliseconds block_processor_batch_max_time_a); + void serialize_json (boost::property_tree::ptree & json, std::chrono::milliseconds min_read_time, std::chrono::milliseconds min_write_time); + void add (const nano::transaction_impl * transaction_impl); + void erase (const nano::transaction_impl * transaction_impl); + +private: + std::mutex mutex; + std::vector stats; + nano::logger_mt & logger; + nano::txn_tracking_config txn_tracking_config; + std::chrono::milliseconds block_processor_batch_max_time; + + void output_finished (nano::mdb_txn_stats const & mdb_txn_stats) const; +}; +} diff --git a/nano/node/lmdb/wallet_value.cpp b/nano/node/lmdb/wallet_value.cpp new file mode 100644 index 00000000..91c8a679 --- /dev/null +++ b/nano/node/lmdb/wallet_value.cpp @@ -0,0 +1,20 @@ +#include + +nano::wallet_value::wallet_value (nano::db_val const & val_a) +{ + assert (val_a.size () == sizeof (*this)); + std::copy (reinterpret_cast (val_a.data ()), reinterpret_cast (val_a.data ()) + sizeof (key), key.chars.begin ()); + std::copy (reinterpret_cast (val_a.data ()) + sizeof (key), reinterpret_cast (val_a.data ()) + sizeof (key) + sizeof (work), reinterpret_cast (&work)); +} + +nano::wallet_value::wallet_value (nano::uint256_union const & key_a, uint64_t work_a) : +key (key_a), +work (work_a) +{ +} + +nano::db_val nano::wallet_value::val () const +{ + static_assert (sizeof (*this) == sizeof (key) + sizeof (work), "Class not packed"); + return nano::db_val (sizeof (*this), const_cast (this)); +} diff --git a/nano/node/lmdb/wallet_value.hpp b/nano/node/lmdb/wallet_value.hpp new file mode 100644 index 00000000..116b5e4b --- /dev/null +++ b/nano/node/lmdb/wallet_value.hpp @@ -0,0 +1,20 @@ +#pragma once + +#include +#include + +#include + +namespace nano +{ +class wallet_value +{ +public: + wallet_value () = default; + wallet_value (nano::db_val const &); + wallet_value (nano::uint256_union const &, uint64_t); + nano::db_val val () const; + nano::private_key key; + uint64_t work; +}; +} diff --git a/nano/node/node.cpp b/nano/node/node.cpp index af89607c..497de1cc 100644 --- a/nano/node/node.cpp +++ b/nano/node/node.cpp @@ -109,8 +109,8 @@ std::unique_ptr collect_seq_con_info (block_processor & } } -nano::node::node (nano::node_init & init_a, boost::asio::io_context & io_ctx_a, uint16_t peering_port_a, boost::filesystem::path const & application_path_a, nano::alarm & alarm_a, nano::logging const & logging_a, nano::work_pool & work_a) : -node (init_a, io_ctx_a, application_path_a, alarm_a, nano::node_config (peering_port_a, logging_a), work_a) +nano::node::node (nano::node_init & init_a, boost::asio::io_context & io_ctx_a, uint16_t peering_port_a, boost::filesystem::path const & application_path_a, nano::alarm & alarm_a, nano::logging const & logging_a, nano::work_pool & work_a, nano::node_flags flags_a) : +node (init_a, io_ctx_a, application_path_a, alarm_a, nano::node_config (peering_port_a, logging_a), work_a, flags_a) { } @@ -1562,3 +1562,8 @@ nano::inactive_node::~inactive_node () { node->stop (); } + +std::unique_ptr nano::make_store (bool & init, nano::logger_mt & logger, boost::filesystem::path const & path) +{ + return std::make_unique (init, logger, path); +} diff --git a/nano/node/node.hpp b/nano/node/node.hpp index 06052c0d..b3673047 100644 --- a/nano/node/node.hpp +++ b/nano/node/node.hpp @@ -86,7 +86,7 @@ std::unique_ptr collect_seq_con_info (block_processor & class node final : public std::enable_shared_from_this { public: - node (nano::node_init &, boost::asio::io_context &, uint16_t, boost::filesystem::path const &, nano::alarm &, nano::logging const &, nano::work_pool &); + node (nano::node_init &, boost::asio::io_context &, uint16_t, boost::filesystem::path const &, nano::alarm &, nano::logging const &, nano::work_pool &, nano::node_flags = nano::node_flags ()); node (nano::node_init &, boost::asio::io_context &, boost::filesystem::path const &, nano::alarm &, nano::node_config const &, nano::work_pool &, nano::node_flags = nano::node_flags ()); ~node (); template diff --git a/nano/node/nodeconfig.hpp b/nano/node/nodeconfig.hpp index 13734d37..0f1362f3 100644 --- a/nano/node/nodeconfig.hpp +++ b/nano/node/nodeconfig.hpp @@ -97,6 +97,7 @@ public: bool disable_unchecked_drop{ true }; bool fast_bootstrap{ false }; bool delay_frontier_confirmation_height_updating{ false }; + bool read_only{ false }; size_t sideband_batch_size{ 512 }; size_t block_processor_batch_size{ 0 }; size_t block_processor_full_size{ 65536 }; diff --git a/nano/node/wallet.cpp b/nano/node/wallet.cpp index 14544cde..fde674d9 100644 --- a/nano/node/wallet.cpp +++ b/nano/node/wallet.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include #include diff --git a/nano/node/wallet.hpp b/nano/node/wallet.hpp index cad97424..4d825fe4 100644 --- a/nano/node/wallet.hpp +++ b/nano/node/wallet.hpp @@ -1,7 +1,8 @@ #pragma once #include -#include +#include +#include #include #include #include @@ -122,7 +123,6 @@ public: std::shared_ptr change_action (nano::account const &, nano::account const &, uint64_t = 0, bool = true); std::shared_ptr receive_action (nano::block const &, nano::account const &, nano::uint128_union const &, uint64_t = 0, bool = true); std::shared_ptr send_action (nano::account const &, nano::account const &, nano::uint128_t const &, uint64_t = 0, bool = true, boost::optional = {}); - std::shared_ptr regenerate_action (nano::qualified_root const &, std::shared_ptr); wallet (bool &, nano::transaction &, nano::wallets &, std::string const &); wallet (bool &, nano::transaction &, nano::wallets &, std::string const &, std::string const &); void enter_initial_password (); @@ -142,7 +142,6 @@ public: void receive_async (std::shared_ptr, nano::account const &, nano::uint128_t const &, std::function)> const &, uint64_t = 0, bool = true); nano::block_hash send_sync (nano::account const &, nano::account const &, nano::uint128_t const &); void send_async (nano::account const &, nano::account const &, nano::uint128_t const &, std::function)> const &, uint64_t = 0, bool = true, boost::optional = {}); - void work_apply (nano::account const &, std::function); void work_cache_blocking (nano::account const &, nano::block_hash const &); void work_update (nano::transaction const &, nano::account const &, nano::block_hash const &, uint64_t); void work_ensure (nano::account const &, nano::block_hash const &); diff --git a/nano/secure/CMakeLists.txt b/nano/secure/CMakeLists.txt index a612d4a6..e7a8160c 100644 --- a/nano/secure/CMakeLists.txt +++ b/nano/secure/CMakeLists.txt @@ -36,6 +36,7 @@ add_library (secure common.hpp common.cpp blockstore.hpp + blockstore_partial.hpp blockstore.cpp ledger.hpp ledger.cpp diff --git a/nano/secure/blockstore.hpp b/nano/secure/blockstore.hpp index 20b2c848..023c7a8b 100644 --- a/nano/secure/blockstore.hpp +++ b/nano/secure/blockstore.hpp @@ -1,6 +1,8 @@ #pragma once +#include #include +#include #include #include #include @@ -12,21 +14,6 @@ namespace nano { -// Generic container to be used when templated db types cannot -class DB_val -{ -public: - DB_val () = default; - DB_val (size_t size_a, void * data_a) : - size (size_a), - data (data_a) - { - } - - size_t size; - void * data; -}; - /** * Encapsulates database specific container and provides uint256_union conversion of the data. */ @@ -34,22 +21,14 @@ template class db_val { public: - db_val (nano::epoch epoch_a = nano::epoch::unspecified) : - value ({ 0, nullptr }), - epoch (epoch_a) - { - } - db_val (Val const & value_a, nano::epoch epoch_a = nano::epoch::unspecified) : value (value_a), epoch (epoch_a) { } - db_val (DB_val const & value_a, nano::epoch epoch_a = nano::epoch::unspecified); - - db_val (size_t size_a, void * data_a) : - value ({ size_a, data_a }) + db_val (nano::epoch epoch_a = nano::epoch::unspecified) : + db_val (0, nullptr, epoch_a) { } @@ -92,7 +71,7 @@ public: nano::vectorstream stream (*buffer); val_a.serialize (stream); } - value = { buffer->size (), const_cast (buffer->data ()) }; + convert_buffer_to_value (); } db_val (nano::block_info const & val_a) : @@ -114,7 +93,7 @@ public: nano::vectorstream stream (*buffer); nano::serialize_block (stream, *val_a); } - value = { buffer->size (), const_cast (buffer->data ()) }; + convert_buffer_to_value (); } db_val (uint64_t val_a) : @@ -125,7 +104,7 @@ public: nano::vectorstream stream (*buffer); nano::write (stream, val_a); } - value = { buffer->size (), const_cast (buffer->data ()) }; + convert_buffer_to_value (); } explicit operator nano::account_info () const @@ -293,9 +272,11 @@ public: return value; } - /** Must be specialized in the sub-class */ + // Must be specialized void * data () const; size_t size () const; + db_val (size_t size_a, void * data_a, nano::epoch epoch_a = nano::epoch::unspecified); + void convert_buffer_to_value (); Val value; std::shared_ptr> buffer; @@ -491,8 +472,8 @@ public: class read_transaction_impl : public transaction_impl { public: - virtual void reset () const = 0; - virtual void renew () const = 0; + virtual void reset () = 0; + virtual void renew () = 0; }; class write_transaction_impl : public transaction_impl @@ -548,6 +529,28 @@ private: class block_store { public: + enum class tables + { + frontiers, + accounts_v0, + accounts_v1, + send_blocks, + receive_blocks, + open_blocks, + change_blocks, + state_blocks_v0, + state_blocks_v1, + pending_v0, + pending_v1, + blocks_info, + representation, + unchecked, + vote, + online_weight, + meta, + peers + }; + virtual ~block_store () = default; virtual void initialize (nano::transaction const &, nano::genesis const &) = 0; virtual void block_put (nano::transaction const &, nano::block_hash const &, nano::block const &, nano::block_sideband const &, nano::epoch version = nano::epoch::epoch_0) = 0; @@ -650,8 +653,9 @@ public: virtual void peer_clear (nano::transaction const & transaction_a) = 0; virtual nano::store_iterator peers_begin (nano::transaction const & transaction_a) = 0; virtual nano::store_iterator peers_end () = 0; - virtual uint64_t block_account_height (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const = 0; + virtual std::mutex & get_cache_mutex () = 0; + virtual void serialize_mdb_tracker (boost::property_tree::ptree &, std::chrono::milliseconds, std::chrono::milliseconds) = 0; /** Start read-write transaction */ @@ -661,473 +665,5 @@ public: virtual nano::read_transaction tx_begin_read () = 0; }; -template -class block_predecessor_set; - -/** This base class implements the block_store interface functions which have DB agnostic functionality */ -template -class block_store_partial : public block_store -{ -public: - using block_store::block_exists; - using block_store::unchecked_put; - - friend class nano::block_predecessor_set; - - std::mutex cache_mutex; - - /** - * If using a different store version than the latest then you may need - * to modify some of the objects in the store to be appropriate for the version before an upgrade. - */ - void initialize (nano::transaction const & transaction_a, nano::genesis const & genesis_a) override - { - auto hash_l (genesis_a.hash ()); - assert (latest_v0_begin (transaction_a) == latest_v0_end ()); - assert (latest_v1_begin (transaction_a) == latest_v1_end ()); - nano::block_sideband sideband (nano::block_type::open, network_params.ledger.genesis_account, 0, network_params.ledger.genesis_amount, 1, nano::seconds_since_epoch ()); - block_put (transaction_a, hash_l, *genesis_a.open, sideband); - account_put (transaction_a, network_params.ledger.genesis_account, { hash_l, genesis_a.open->hash (), genesis_a.open->hash (), std::numeric_limits::max (), nano::seconds_since_epoch (), 1, 1, nano::epoch::epoch_0 }); - representation_put (transaction_a, network_params.ledger.genesis_account, std::numeric_limits::max ()); - frontier_put (transaction_a, hash_l, network_params.ledger.genesis_account); - } - - nano::uint128_t block_balance (nano::transaction const & transaction_a, nano::block_hash const & hash_a) override - { - nano::block_sideband sideband; - auto block (block_get (transaction_a, hash_a, &sideband)); - nano::uint128_t result (block_balance_calculated (block, sideband)); - return result; - } - - void representation_add (nano::transaction const & transaction_a, nano::block_hash const & source_a, nano::uint128_t const & amount_a) override - { - auto source_block (block_get (transaction_a, source_a)); - assert (source_block != nullptr); - auto source_rep (source_block->representative ()); - auto source_previous (representation_get (transaction_a, source_rep)); - representation_put (transaction_a, source_rep, source_previous + amount_a); - } - - bool account_exists (nano::transaction const & transaction_a, nano::account const & account_a) override - { - auto iterator (latest_begin (transaction_a, account_a)); - return iterator != latest_end () && nano::account (iterator->first) == account_a; - } - - void confirmation_height_clear (nano::transaction const & transaction_a, nano::account const & account, nano::account_info const & account_info) override - { - nano::account_info info_copy (account_info); - if (info_copy.confirmation_height > 0) - { - info_copy.confirmation_height = 0; - account_put (transaction_a, account, info_copy); - } - } - - void confirmation_height_clear (nano::transaction const & transaction_a) override - { - for (auto i (latest_begin (transaction_a)), n (latest_end ()); i != n; ++i) - { - confirmation_height_clear (transaction_a, i->first, i->second); - } - } - - bool pending_exists (nano::transaction const & transaction_a, nano::pending_key const & key_a) override - { - auto iterator (pending_begin (transaction_a, key_a)); - return iterator != pending_end () && nano::pending_key (iterator->first) == key_a; - } - - std::vector unchecked_get (nano::transaction const & transaction_a, nano::block_hash const & hash_a) override - { - std::vector result; - for (auto i (unchecked_begin (transaction_a, nano::unchecked_key (hash_a, 0))), n (unchecked_end ()); i != n && nano::block_hash (i->first.key ()) == hash_a; ++i) - { - nano::unchecked_info const & unchecked_info (i->second); - result.push_back (unchecked_info); - } - return result; - } - - void block_put (nano::transaction const & transaction_a, nano::block_hash const & hash_a, nano::block const & block_a, nano::block_sideband const & sideband_a, nano::epoch epoch_a = nano::epoch::epoch_0) override - { - assert (block_a.type () == sideband_a.type); - assert (sideband_a.successor.is_zero () || block_exists (transaction_a, sideband_a.successor)); - std::vector vector; - { - nano::vectorstream stream (vector); - block_a.serialize (stream); - sideband_a.serialize (stream); - } - block_raw_put (transaction_a, vector, block_a.type (), epoch_a, hash_a); - nano::block_predecessor_set predecessor (transaction_a, *this); - block_a.visit (predecessor); - assert (block_a.previous ().is_zero () || block_successor (transaction_a, block_a.previous ()) == hash_a); - } - - // Converts a block hash to a block height - uint64_t block_account_height (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const override - { - nano::block_sideband sideband; - auto block = block_get (transaction_a, hash_a, &sideband); - assert (block != nullptr); - return sideband.height; - } - - std::shared_ptr block_get (nano::transaction const & transaction_a, nano::block_hash const & hash_a, nano::block_sideband * sideband_a = nullptr) const override - { - nano::block_type type; - auto value (block_raw_get (transaction_a, hash_a, type)); - std::shared_ptr result; - if (value.size () != 0) - { - nano::bufferstream stream (reinterpret_cast (value.data ()), value.size ()); - result = nano::deserialize_block (stream, type); - assert (result != nullptr); - if (sideband_a) - { - sideband_a->type = type; - if (full_sideband (transaction_a) || entry_has_sideband (value.size (), type)) - { - auto error (sideband_a->deserialize (stream)); - (void)error; - assert (!error); - } - else - { - // Reconstruct sideband data for block. - sideband_a->account = block_account_computed (transaction_a, hash_a); - sideband_a->balance = block_balance_computed (transaction_a, hash_a); - sideband_a->successor = block_successor (transaction_a, hash_a); - sideband_a->height = 0; - sideband_a->timestamp = 0; - } - } - } - return result; - } - - bool block_exists (nano::transaction const & tx_a, nano::block_hash const & hash_a) override - { - // Table lookups are ordered by match probability - // clang-format off - return - block_exists (tx_a, nano::block_type::state, hash_a) || - block_exists (tx_a, nano::block_type::send, hash_a) || - block_exists (tx_a, nano::block_type::receive, hash_a) || - block_exists (tx_a, nano::block_type::open, hash_a) || - block_exists (tx_a, nano::block_type::change, hash_a); - // clang-format on - } - - bool root_exists (nano::transaction const & transaction_a, nano::uint256_union const & root_a) override - { - return block_exists (transaction_a, root_a) || account_exists (transaction_a, root_a); - } - - bool source_exists (nano::transaction const & transaction_a, nano::block_hash const & source_a) override - { - return block_exists (transaction_a, nano::block_type::state, source_a) || block_exists (transaction_a, nano::block_type::send, source_a); - } - - nano::account block_account (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const override - { - nano::block_sideband sideband; - auto block (block_get (transaction_a, hash_a, &sideband)); - nano::account result (block->account ()); - if (result.is_zero ()) - { - result = sideband.account; - } - assert (!result.is_zero ()); - return result; - } - - nano::uint128_t block_balance_calculated (std::shared_ptr block_a, nano::block_sideband const & sideband_a) const override - { - nano::uint128_t result; - switch (block_a->type ()) - { - case nano::block_type::open: - case nano::block_type::receive: - case nano::block_type::change: - result = sideband_a.balance.number (); - break; - case nano::block_type::send: - result = boost::polymorphic_downcast (block_a.get ())->hashables.balance.number (); - break; - case nano::block_type::state: - result = boost::polymorphic_downcast (block_a.get ())->hashables.balance.number (); - break; - case nano::block_type::invalid: - case nano::block_type::not_a_block: - release_assert (false); - break; - } - return result; - } - - nano::block_hash block_successor (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const override - { - nano::block_type type; - auto value (block_raw_get (transaction_a, hash_a, type)); - nano::block_hash result; - if (value.size () != 0) - { - assert (value.size () >= result.bytes.size ()); - nano::bufferstream stream (reinterpret_cast (value.data ()) + block_successor_offset (transaction_a, value.size (), type), result.bytes.size ()); - auto error (nano::try_read (stream, result.bytes)); - (void)error; - assert (!error); - } - else - { - result.clear (); - } - return result; - } - - bool full_sideband (nano::transaction const & transaction_a) const - { - return version_get (transaction_a) > 12; - } - - void block_successor_clear (nano::transaction const & transaction_a, nano::block_hash const & hash_a) override - { - nano::block_type type; - auto value (block_raw_get (transaction_a, hash_a, type)); - auto version (block_version (transaction_a, hash_a)); - assert (value.size () != 0); - std::vector data (static_cast (value.data ()), static_cast (value.data ()) + value.size ()); - std::fill_n (data.begin () + block_successor_offset (transaction_a, value.size (), type), sizeof (nano::uint256_union), uint8_t{ 0 }); - block_raw_put (transaction_a, data, type, version, hash_a); - } - - uint64_t cemented_count (nano::transaction const & transaction_a) override - { - uint64_t sum = 0; - for (auto i (latest_begin (transaction_a)), n (latest_end ()); i != n; ++i) - { - nano::account_info const & info (i->second); - sum += info.confirmation_height; - } - return sum; - } - - void unchecked_put (nano::transaction const & transaction_a, nano::block_hash const & hash_a, std::shared_ptr const & block_a) override - { - nano::unchecked_key key (hash_a, block_a->hash ()); - nano::unchecked_info info (block_a, block_a->account (), nano::seconds_since_epoch (), nano::signature_verification::unknown); - unchecked_put (transaction_a, key, info); - } - - std::shared_ptr vote_current (nano::transaction const & transaction_a, nano::account const & account_a) override - { - assert (!cache_mutex.try_lock ()); - std::shared_ptr result; - auto existing (vote_cache_l1.find (account_a)); - auto have_existing (true); - if (existing == vote_cache_l1.end ()) - { - existing = vote_cache_l2.find (account_a); - if (existing == vote_cache_l2.end ()) - { - have_existing = false; - } - } - if (have_existing) - { - result = existing->second; - } - else - { - result = vote_get (transaction_a, account_a); - } - return result; - } - - std::shared_ptr vote_generate (nano::transaction const & transaction_a, nano::account const & account_a, nano::raw_key const & key_a, std::shared_ptr block_a) override - { - std::lock_guard lock (cache_mutex); - auto result (vote_current (transaction_a, account_a)); - uint64_t sequence ((result ? result->sequence : 0) + 1); - result = std::make_shared (account_a, key_a, sequence, block_a); - vote_cache_l1[account_a] = result; - return result; - } - - std::shared_ptr vote_generate (nano::transaction const & transaction_a, nano::account const & account_a, nano::raw_key const & key_a, std::vector blocks_a) override - { - std::lock_guard lock (cache_mutex); - auto result (vote_current (transaction_a, account_a)); - uint64_t sequence ((result ? result->sequence : 0) + 1); - result = std::make_shared (account_a, key_a, sequence, blocks_a); - vote_cache_l1[account_a] = result; - return result; - } - - std::shared_ptr vote_max (nano::transaction const & transaction_a, std::shared_ptr vote_a) override - { - std::lock_guard lock (cache_mutex); - auto current (vote_current (transaction_a, vote_a->account)); - auto result (vote_a); - if (current != nullptr && current->sequence > result->sequence) - { - result = current; - } - vote_cache_l1[vote_a->account] = result; - return result; - } - - virtual void block_raw_put (nano::transaction const & transaction_a, std::vector const & data, nano::block_type block_type_a, nano::epoch epoch_a, nano::block_hash const & hash_a) = 0; - -protected: - nano::network_params network_params; - std::unordered_map> vote_cache_l1; - std::unordered_map> vote_cache_l2; - - bool entry_has_sideband (size_t entry_size_a, nano::block_type type_a) const - { - return entry_size_a == nano::block::size (type_a) + nano::block_sideband::size (type_a); - } - - nano::db_val block_raw_get (nano::transaction const & transaction_a, nano::block_hash const & hash_a, nano::block_type & type_a) const - { - nano::db_val result; - // Table lookups are ordered by match probability - nano::block_type block_types[]{ nano::block_type::state, nano::block_type::send, nano::block_type::receive, nano::block_type::open, nano::block_type::change }; - for (auto current_type : block_types) - { - auto db_val (block_raw_get_by_type (transaction_a, hash_a, current_type)); - if (db_val.is_initialized ()) - { - type_a = current_type; - result = db_val.get (); - break; - } - } - - return result; - } - - // Return account containing hash - nano::account block_account_computed (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const - { - assert (!full_sideband (transaction_a)); - nano::account result (0); - auto hash (hash_a); - while (result.is_zero ()) - { - auto block (block_get (transaction_a, hash)); - assert (block); - result = block->account (); - if (result.is_zero ()) - { - auto type (nano::block_type::invalid); - auto value (block_raw_get (transaction_a, block->previous (), type)); - if (entry_has_sideband (value.size (), type)) - { - result = block_account (transaction_a, block->previous ()); - } - else - { - nano::block_info block_info; - if (!block_info_get (transaction_a, hash, block_info)) - { - result = block_info.account; - } - else - { - result = frontier_get (transaction_a, hash); - if (result.is_zero ()) - { - auto successor (block_successor (transaction_a, hash)); - assert (!successor.is_zero ()); - hash = successor; - } - } - } - } - } - assert (!result.is_zero ()); - return result; - } - - nano::uint128_t block_balance_computed (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const - { - assert (!full_sideband (transaction_a)); - summation_visitor visitor (transaction_a, *this); - return visitor.compute_balance (hash_a); - } - - size_t block_successor_offset (nano::transaction const & transaction_a, size_t entry_size_a, nano::block_type type_a) const - { - size_t result; - if (full_sideband (transaction_a) || entry_has_sideband (entry_size_a, type_a)) - { - result = entry_size_a - nano::block_sideband::size (type_a); - } - else - { - // Read old successor-only sideband - assert (entry_size_a == nano::block::size (type_a) + sizeof (nano::uint256_union)); - result = entry_size_a - sizeof (nano::uint256_union); - } - return result; - } - - virtual boost::optional block_raw_get_by_type (nano::transaction const &, nano::block_hash const &, nano::block_type &) const = 0; -}; - -/** - * Fill in our predecessors - */ -template -class block_predecessor_set : public nano::block_visitor -{ -public: - block_predecessor_set (nano::transaction const & transaction_a, nano::block_store_partial & store_a) : - transaction (transaction_a), - store (store_a) - { - } - virtual ~block_predecessor_set () = default; - void fill_value (nano::block const & block_a) - { - auto hash (block_a.hash ()); - nano::block_type type; - auto value (store.block_raw_get (transaction, block_a.previous (), type)); - auto version (store.block_version (transaction, block_a.previous ())); - assert (value.size () != 0); - std::vector data (static_cast (value.data ()), static_cast (value.data ()) + value.size ()); - std::copy (hash.bytes.begin (), hash.bytes.end (), data.begin () + store.block_successor_offset (transaction, value.size (), type)); - store.block_raw_put (transaction, data, type, version, block_a.previous ()); - } - void send_block (nano::send_block const & block_a) override - { - fill_value (block_a); - } - void receive_block (nano::receive_block const & block_a) override - { - fill_value (block_a); - } - void open_block (nano::open_block const & block_a) override - { - // Open blocks don't have a predecessor - } - void change_block (nano::change_block const & block_a) override - { - fill_value (block_a); - } - void state_block (nano::state_block const & block_a) override - { - if (!block_a.previous ().is_zero ()) - { - fill_value (block_a); - } - } - nano::transaction const & transaction; - nano::block_store_partial & store; -}; +std::unique_ptr make_store (bool & init, nano::logger_mt & logger, boost::filesystem::path const & path); } diff --git a/nano/secure/blockstore_partial.hpp b/nano/secure/blockstore_partial.hpp new file mode 100644 index 00000000..7ac5e4d4 --- /dev/null +++ b/nano/secure/blockstore_partial.hpp @@ -0,0 +1,1233 @@ +#pragma once + +#include + +namespace nano +{ +template +class block_predecessor_set; + +/** This base class implements the block_store interface functions which have DB agnostic functionality */ +template +class block_store_partial : public block_store +{ +public: + using block_store::block_exists; + using block_store::unchecked_put; + + friend class nano::block_predecessor_set; + + std::mutex cache_mutex; + + /** + * If using a different store version than the latest then you may need + * to modify some of the objects in the store to be appropriate for the version before an upgrade. + */ + void initialize (nano::transaction const & transaction_a, nano::genesis const & genesis_a) override + { + auto hash_l (genesis_a.hash ()); + assert (latest_v0_begin (transaction_a) == latest_v0_end ()); + assert (latest_v1_begin (transaction_a) == latest_v1_end ()); + nano::block_sideband sideband (nano::block_type::open, network_params.ledger.genesis_account, 0, network_params.ledger.genesis_amount, 1, nano::seconds_since_epoch ()); + block_put (transaction_a, hash_l, *genesis_a.open, sideband); + account_put (transaction_a, network_params.ledger.genesis_account, { hash_l, genesis_a.open->hash (), genesis_a.open->hash (), std::numeric_limits::max (), nano::seconds_since_epoch (), 1, 1, nano::epoch::epoch_0 }); + representation_put (transaction_a, network_params.ledger.genesis_account, std::numeric_limits::max ()); + frontier_put (transaction_a, hash_l, network_params.ledger.genesis_account); + } + + nano::uint128_t block_balance (nano::transaction const & transaction_a, nano::block_hash const & hash_a) override + { + nano::block_sideband sideband; + auto block (block_get (transaction_a, hash_a, &sideband)); + nano::uint128_t result (block_balance_calculated (block, sideband)); + return result; + } + + void representation_add (nano::transaction const & transaction_a, nano::block_hash const & source_a, nano::uint128_t const & amount_a) override + { + auto source_block (block_get (transaction_a, source_a)); + assert (source_block != nullptr); + auto source_rep (source_block->representative ()); + auto source_previous (representation_get (transaction_a, source_rep)); + representation_put (transaction_a, source_rep, source_previous + amount_a); + } + + bool account_exists (nano::transaction const & transaction_a, nano::account const & account_a) override + { + auto iterator (latest_begin (transaction_a, account_a)); + return iterator != latest_end () && nano::account (iterator->first) == account_a; + } + + void confirmation_height_clear (nano::transaction const & transaction_a, nano::account const & account, nano::account_info const & account_info) override + { + nano::account_info info_copy (account_info); + if (info_copy.confirmation_height > 0) + { + info_copy.confirmation_height = 0; + account_put (transaction_a, account, info_copy); + } + } + + void confirmation_height_clear (nano::transaction const & transaction_a) override + { + for (auto i (latest_begin (transaction_a)), n (latest_end ()); i != n; ++i) + { + confirmation_height_clear (transaction_a, i->first, i->second); + } + } + + bool pending_exists (nano::transaction const & transaction_a, nano::pending_key const & key_a) override + { + auto iterator (pending_begin (transaction_a, key_a)); + return iterator != pending_end () && nano::pending_key (iterator->first) == key_a; + } + + std::vector unchecked_get (nano::transaction const & transaction_a, nano::block_hash const & hash_a) override + { + std::vector result; + for (auto i (unchecked_begin (transaction_a, nano::unchecked_key (hash_a, 0))), n (unchecked_end ()); i != n && nano::block_hash (i->first.key ()) == hash_a; ++i) + { + nano::unchecked_info const & unchecked_info (i->second); + result.push_back (unchecked_info); + } + return result; + } + + void block_put (nano::transaction const & transaction_a, nano::block_hash const & hash_a, nano::block const & block_a, nano::block_sideband const & sideband_a, nano::epoch epoch_a = nano::epoch::epoch_0) override + { + assert (block_a.type () == sideband_a.type); + assert (sideband_a.successor.is_zero () || block_exists (transaction_a, sideband_a.successor)); + std::vector vector; + { + nano::vectorstream stream (vector); + block_a.serialize (stream); + sideband_a.serialize (stream); + } + block_raw_put (transaction_a, vector, block_a.type (), epoch_a, hash_a); + nano::block_predecessor_set predecessor (transaction_a, *this); + block_a.visit (predecessor); + assert (block_a.previous ().is_zero () || block_successor (transaction_a, block_a.previous ()) == hash_a); + } + + // Converts a block hash to a block height + uint64_t block_account_height (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const override + { + nano::block_sideband sideband; + auto block = block_get (transaction_a, hash_a, &sideband); + assert (block != nullptr); + return sideband.height; + } + + std::shared_ptr block_get (nano::transaction const & transaction_a, nano::block_hash const & hash_a, nano::block_sideband * sideband_a = nullptr) const override + { + nano::block_type type; + auto value (block_raw_get (transaction_a, hash_a, type)); + std::shared_ptr result; + if (value.size () != 0) + { + nano::bufferstream stream (reinterpret_cast (value.data ()), value.size ()); + result = nano::deserialize_block (stream, type); + assert (result != nullptr); + if (sideband_a) + { + sideband_a->type = type; + if (full_sideband (transaction_a) || entry_has_sideband (value.size (), type)) + { + auto error (sideband_a->deserialize (stream)); + (void)error; + assert (!error); + } + else + { + // Reconstruct sideband data for block. + sideband_a->account = block_account_computed (transaction_a, hash_a); + sideband_a->balance = block_balance_computed (transaction_a, hash_a); + sideband_a->successor = block_successor (transaction_a, hash_a); + sideband_a->height = 0; + sideband_a->timestamp = 0; + } + } + } + return result; + } + + bool block_exists (nano::transaction const & transaction_a, nano::block_type type, nano::block_hash const & hash_a) override + { + auto junk = block_raw_get_by_type (transaction_a, hash_a, type); + return junk.is_initialized (); + } + + bool block_exists (nano::transaction const & tx_a, nano::block_hash const & hash_a) override + { + // Table lookups are ordered by match probability + // clang-format off + return + block_exists (tx_a, nano::block_type::state, hash_a) || + block_exists (tx_a, nano::block_type::send, hash_a) || + block_exists (tx_a, nano::block_type::receive, hash_a) || + block_exists (tx_a, nano::block_type::open, hash_a) || + block_exists (tx_a, nano::block_type::change, hash_a); + // clang-format on + } + + bool root_exists (nano::transaction const & transaction_a, nano::uint256_union const & root_a) override + { + return block_exists (transaction_a, root_a) || account_exists (transaction_a, root_a); + } + + bool source_exists (nano::transaction const & transaction_a, nano::block_hash const & source_a) override + { + return block_exists (transaction_a, nano::block_type::state, source_a) || block_exists (transaction_a, nano::block_type::send, source_a); + } + + nano::account block_account (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const override + { + nano::block_sideband sideband; + auto block (block_get (transaction_a, hash_a, &sideband)); + nano::account result (block->account ()); + if (result.is_zero ()) + { + result = sideband.account; + } + assert (!result.is_zero ()); + return result; + } + + nano::uint128_t block_balance_calculated (std::shared_ptr block_a, nano::block_sideband const & sideband_a) const override + { + nano::uint128_t result; + switch (block_a->type ()) + { + case nano::block_type::open: + case nano::block_type::receive: + case nano::block_type::change: + result = sideband_a.balance.number (); + break; + case nano::block_type::send: + result = boost::polymorphic_downcast (block_a.get ())->hashables.balance.number (); + break; + case nano::block_type::state: + result = boost::polymorphic_downcast (block_a.get ())->hashables.balance.number (); + break; + case nano::block_type::invalid: + case nano::block_type::not_a_block: + release_assert (false); + break; + } + return result; + } + + nano::block_hash block_successor (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const override + { + nano::block_type type; + auto value (block_raw_get (transaction_a, hash_a, type)); + nano::block_hash result; + if (value.size () != 0) + { + assert (value.size () >= result.bytes.size ()); + nano::bufferstream stream (reinterpret_cast (value.data ()) + block_successor_offset (transaction_a, value.size (), type), result.bytes.size ()); + auto error (nano::try_read (stream, result.bytes)); + (void)error; + assert (!error); + } + else + { + result.clear (); + } + return result; + } + + bool full_sideband (nano::transaction const & transaction_a) const + { + return version_get (transaction_a) > 12; + } + + void block_successor_clear (nano::transaction const & transaction_a, nano::block_hash const & hash_a) override + { + nano::block_type type; + auto value (block_raw_get (transaction_a, hash_a, type)); + auto version (block_version (transaction_a, hash_a)); + assert (value.size () != 0); + std::vector data (static_cast (value.data ()), static_cast (value.data ()) + value.size ()); + std::fill_n (data.begin () + block_successor_offset (transaction_a, value.size (), type), sizeof (nano::uint256_union), uint8_t{ 0 }); + block_raw_put (transaction_a, data, type, version, hash_a); + } + + uint64_t cemented_count (nano::transaction const & transaction_a) override + { + uint64_t sum = 0; + for (auto i (latest_begin (transaction_a)), n (latest_end ()); i != n; ++i) + { + nano::account_info const & info (i->second); + sum += info.confirmation_height; + } + return sum; + } + + void unchecked_put (nano::transaction const & transaction_a, nano::block_hash const & hash_a, std::shared_ptr const & block_a) override + { + nano::unchecked_key key (hash_a, block_a->hash ()); + nano::unchecked_info info (block_a, block_a->account (), nano::seconds_since_epoch (), nano::signature_verification::unknown); + unchecked_put (transaction_a, key, info); + } + + std::shared_ptr vote_current (nano::transaction const & transaction_a, nano::account const & account_a) override + { + assert (!cache_mutex.try_lock ()); + std::shared_ptr result; + auto existing (vote_cache_l1.find (account_a)); + auto have_existing (true); + if (existing == vote_cache_l1.end ()) + { + existing = vote_cache_l2.find (account_a); + if (existing == vote_cache_l2.end ()) + { + have_existing = false; + } + } + if (have_existing) + { + result = existing->second; + } + else + { + result = vote_get (transaction_a, account_a); + } + return result; + } + + std::shared_ptr vote_generate (nano::transaction const & transaction_a, nano::account const & account_a, nano::raw_key const & key_a, std::shared_ptr block_a) override + { + std::lock_guard lock (cache_mutex); + auto result (vote_current (transaction_a, account_a)); + uint64_t sequence ((result ? result->sequence : 0) + 1); + result = std::make_shared (account_a, key_a, sequence, block_a); + vote_cache_l1[account_a] = result; + return result; + } + + std::shared_ptr vote_generate (nano::transaction const & transaction_a, nano::account const & account_a, nano::raw_key const & key_a, std::vector blocks_a) override + { + std::lock_guard lock (cache_mutex); + auto result (vote_current (transaction_a, account_a)); + uint64_t sequence ((result ? result->sequence : 0) + 1); + result = std::make_shared (account_a, key_a, sequence, blocks_a); + vote_cache_l1[account_a] = result; + return result; + } + + std::shared_ptr vote_max (nano::transaction const & transaction_a, std::shared_ptr vote_a) override + { + std::lock_guard lock (cache_mutex); + auto current (vote_current (transaction_a, vote_a->account)); + auto result (vote_a); + if (current != nullptr && current->sequence > result->sequence) + { + result = current; + } + vote_cache_l1[vote_a->account] = result; + return result; + } + + nano::store_iterator representation_end () override + { + return nano::store_iterator (nullptr); + } + + nano::store_iterator unchecked_end () override + { + return nano::store_iterator (nullptr); + } + + nano::store_iterator> vote_end () override + { + return nano::store_iterator> (nullptr); + } + + nano::store_iterator peers_end () override + { + return nano::store_iterator (nano::store_iterator (nullptr)); + } + + nano::store_iterator pending_end () override + { + return nano::store_iterator (nullptr); + } + + nano::store_iterator pending_v0_end () override + { + return nano::store_iterator (nullptr); + } + + nano::store_iterator pending_v1_end () override + { + return nano::store_iterator (nullptr); + } + + nano::store_iterator online_weight_end () override + { + return nano::store_iterator (nullptr); + } + + nano::store_iterator latest_end () override + { + return nano::store_iterator (nullptr); + } + + nano::store_iterator latest_v0_end () override + { + return nano::store_iterator (nullptr); + } + + nano::store_iterator latest_v1_end () override + { + return nano::store_iterator (nullptr); + } + + std::mutex & get_cache_mutex () override + { + return cache_mutex; + } + + void block_del (nano::transaction const & transaction_a, nano::block_hash const & hash_a) override + { + auto status = del (transaction_a, tables::state_blocks_v1, hash_a); + release_assert (success (status) || not_found (status)); + if (!success (status)) + { + auto status = del (transaction_a, tables::state_blocks_v0, hash_a); + release_assert (success (status) || not_found (status)); + if (!success (status)) + { + auto status = del (transaction_a, tables::send_blocks, hash_a); + release_assert (success (status) || not_found (status)); + if (!success (status)) + { + auto status = del (transaction_a, tables::receive_blocks, hash_a); + release_assert (success (status) || not_found (status)); + if (!success (status)) + { + auto status = del (transaction_a, tables::open_blocks, hash_a); + release_assert (success (status) || not_found (status)); + if (!success (status)) + { + auto status = del (transaction_a, tables::change_blocks, hash_a); + release_assert (success (status)); + } + } + } + } + } + } + + int version_get (nano::transaction const & transaction_a) const override + { + nano::uint256_union version_key (1); + nano::db_val data; + auto status = get (transaction_a, tables::meta, nano::db_val (version_key), data); + int result (1); + if (!not_found (status)) + { + nano::uint256_union version_value (data); + assert (version_value.qwords[2] == 0 && version_value.qwords[1] == 0 && version_value.qwords[0] == 0); + result = version_value.number ().convert_to (); + } + return result; + } + + nano::epoch block_version (nano::transaction const & transaction_a, nano::block_hash const & hash_a) override + { + nano::db_val value; + auto status = get (transaction_a, tables::state_blocks_v1, nano::db_val (hash_a), value); + release_assert (success (status) || not_found (status)); + return status == 0 ? nano::epoch::epoch_1 : nano::epoch::epoch_0; + } + + void block_raw_put (nano::transaction const & transaction_a, std::vector const & data, nano::block_type block_type_a, nano::epoch epoch_a, nano::block_hash const & hash_a) + { + auto database_a = block_database (block_type_a, epoch_a); + nano::db_val value{ data.size (), (void *)data.data () }; + auto status = put (transaction_a, database_a, hash_a, value); + release_assert (success (status)); + } + + void pending_put (nano::transaction const & transaction_a, nano::pending_key const & key_a, nano::pending_info const & pending_a) override + { + nano::db_val pending (pending_a); + auto status = put (transaction_a, get_pending_db (pending_a.epoch), key_a, pending); + release_assert (success (status)); + } + + void pending_del (nano::transaction const & transaction_a, nano::pending_key const & key_a) override + { + auto status1 = del (transaction_a, tables::pending_v1, key_a); + if (!success (status1)) + { + release_assert (not_found (status1)); + auto status2 = del (transaction_a, tables::pending_v0, key_a); + release_assert (success (status2)); + } + } + + bool pending_get (nano::transaction const & transaction_a, nano::pending_key const & key_a, nano::pending_info & pending_a) override + { + nano::db_val value; + nano::db_val key (key_a); + auto status1 = get (transaction_a, tables::pending_v1, key, value); + release_assert (success (status1) || not_found (status1)); + bool result (false); + nano::epoch epoch; + if (success (status1)) + { + epoch = nano::epoch::epoch_1; + } + else + { + auto status2 = get (transaction_a, tables::pending_v0, key, value); + release_assert (success (status2) || not_found (status2)); + if (success (status2)) + { + epoch = nano::epoch::epoch_0; + } + else + { + result = true; + } + } + if (!result) + { + nano::bufferstream stream (reinterpret_cast (value.data ()), value.size ()); + pending_a.epoch = epoch; + result = pending_a.deserialize (stream); + } + return result; + } + + void frontier_put (nano::transaction const & transaction_a, nano::block_hash const & block_a, nano::account const & account_a) override + { + nano::db_val account (account_a); + auto status (put (transaction_a, tables::frontiers, block_a, account)); + release_assert (success (status)); + } + + nano::account frontier_get (nano::transaction const & transaction_a, nano::block_hash const & block_a) const override + { + nano::db_val value; + auto status (get (transaction_a, tables::frontiers, nano::db_val (block_a), value)); + release_assert (success (status) || not_found (status)); + nano::account result (0); + if (success (status)) + { + result = nano::uint256_union (value); + } + return result; + } + + void frontier_del (nano::transaction const & transaction_a, nano::block_hash const & block_a) override + { + auto status (del (transaction_a, tables::frontiers, block_a)); + release_assert (success (status)); + } + + nano::uint128_t representation_get (nano::transaction const & transaction_a, nano::account const & account_a) override + { + nano::db_val value; + auto status (get (transaction_a, tables::representation, nano::db_val (account_a), value)); + release_assert (success (status) || not_found (status)); + nano::uint128_t result = 0; + if (success (status)) + { + nano::uint128_union rep; + nano::bufferstream stream (reinterpret_cast (value.data ()), value.size ()); + auto error (nano::try_read (stream, rep)); + (void)error; + assert (!error); + result = rep.number (); + } + return result; + } + + void representation_put (nano::transaction const & transaction_a, nano::account const & account_a, nano::uint128_t const & representation_a) override + { + nano::db_val rep{ nano::uint128_union (representation_a) }; + auto status (put (transaction_a, tables::representation, account_a, rep)); + release_assert (success (status)); + } + + void unchecked_put (nano::transaction const & transaction_a, nano::unchecked_key const & key_a, nano::unchecked_info const & info_a) override + { + nano::db_val info (info_a); + auto status (put (transaction_a, tables::unchecked, key_a, info)); + release_assert (success (status)); + } + + void unchecked_del (nano::transaction const & transaction_a, nano::unchecked_key const & key_a) override + { + auto status (del (transaction_a, tables::unchecked, key_a)); + release_assert (success (status) || not_found (status)); + } + + std::shared_ptr vote_get (nano::transaction const & transaction_a, nano::account const & account_a) override + { + nano::db_val value; + auto status (get (transaction_a, tables::vote, nano::db_val (account_a), value)); + release_assert (success (status) || not_found (status)); + if (success (status)) + { + std::shared_ptr result (value); + assert (result != nullptr); + return result; + } + return nullptr; + } + + void flush (nano::transaction const & transaction_a) override + { + { + std::lock_guard lock (cache_mutex); + vote_cache_l1.swap (vote_cache_l2); + vote_cache_l1.clear (); + } + for (auto i (vote_cache_l2.begin ()), n (vote_cache_l2.end ()); i != n; ++i) + { + std::vector vector; + { + nano::vectorstream stream (vector); + i->second->serialize (stream); + } + nano::db_val value (vector.size (), vector.data ()); + auto status1 (put (transaction_a, tables::vote, i->first, value)); + release_assert (success (status1)); + } + } + + void online_weight_put (nano::transaction const & transaction_a, uint64_t time_a, nano::amount const & amount_a) override + { + nano::db_val value (amount_a); + auto status (put (transaction_a, tables::online_weight, time_a, value)); + release_assert (success (status)); + } + + void online_weight_del (nano::transaction const & transaction_a, uint64_t time_a) override + { + auto status (del (transaction_a, tables::online_weight, time_a)); + release_assert (success (status)); + } + + tables get_account_db (nano::epoch epoch_a) const + { + tables db; + switch (epoch_a) + { + case nano::epoch::invalid: + case nano::epoch::unspecified: + assert (false); + case nano::epoch::epoch_0: + db = tables::accounts_v0; + break; + case nano::epoch::epoch_1: + db = tables::accounts_v1; + break; + } + return db; + } + + void account_put (nano::transaction const & transaction_a, nano::account const & account_a, nano::account_info const & info_a) override + { + nano::db_val info (info_a); + auto status = put (transaction_a, get_account_db (info_a.epoch), account_a, info); + release_assert (success (status)); + } + + void account_del (nano::transaction const & transaction_a, nano::account const & account_a) override + { + auto status1 = del (transaction_a, tables::accounts_v1, account_a); + if (!success (status1)) + { + release_assert (not_found (status1)); + auto status2 (del (transaction_a, tables::accounts_v0, account_a)); + release_assert (success (status2)); + } + } + + bool account_get (nano::transaction const & transaction_a, nano::account const & account_a, nano::account_info & info_a) override + { + nano::db_val value; + nano::db_val account (account_a); + auto status1 (get (transaction_a, tables::accounts_v1, account, value)); + release_assert (success (status1) || not_found (status1)); + bool result (false); + nano::epoch epoch; + if (success (status1)) + { + epoch = nano::epoch::epoch_1; + } + else + { + auto status2 (get (transaction_a, tables::accounts_v0, account, value)); + release_assert (success (status2) || not_found (status2)); + if (success (status2)) + { + epoch = nano::epoch::epoch_0; + } + else + { + result = true; + } + } + if (!result) + { + nano::bufferstream stream (reinterpret_cast (value.data ()), value.size ()); + info_a.epoch = epoch; + result = info_a.deserialize (stream); + } + return result; + } + + void unchecked_clear (nano::transaction const & transaction_a) override + { + auto status = drop (transaction_a, tables::unchecked); + release_assert (success (status)); + } + + size_t online_weight_count (nano::transaction const & transaction_a) const override + { + return count (transaction_a, tables::online_weight); + } + + void online_weight_clear (nano::transaction const & transaction_a) override + { + auto status (drop (transaction_a, tables::online_weight)); + release_assert (success (status)); + } + + void peer_put (nano::transaction const & transaction_a, nano::endpoint_key const & endpoint_a) override + { + nano::db_val zero (static_cast (0)); + auto status = put (transaction_a, tables::peers, endpoint_a, zero); + release_assert (success (status)); + } + + void peer_del (nano::transaction const & transaction_a, nano::endpoint_key const & endpoint_a) override + { + auto status (del (transaction_a, tables::peers, endpoint_a)); + release_assert (success (status)); + } + + bool peer_exists (nano::transaction const & transaction_a, nano::endpoint_key const & endpoint_a) const override + { + return exists (transaction_a, tables::peers, nano::db_val (endpoint_a)); + } + + size_t peer_count (nano::transaction const & transaction_a) const override + { + return count (transaction_a, tables::peers); + } + + void peer_clear (nano::transaction const & transaction_a) override + { + auto status = drop (transaction_a, tables::peers); + release_assert (success (status)); + } + + int exists (nano::transaction const & transaction_a, tables table_a, nano::db_val const & key_a) const + { + return static_cast (*this).exists (transaction_a, table_a, key_a); + } + + nano::block_counts block_count (nano::transaction const & transaction_a) override + { + nano::block_counts result; + result.send = count (transaction_a, tables::send_blocks); + result.receive = count (transaction_a, tables::receive_blocks); + result.open = count (transaction_a, tables::open_blocks); + result.change = count (transaction_a, tables::change_blocks); + result.state_v0 = count (transaction_a, tables::state_blocks_v0); + result.state_v1 = count (transaction_a, tables::state_blocks_v1); + return result; + } + + size_t account_count (nano::transaction const & transaction_a) override + { + return count (transaction_a, { tables::accounts_v0, tables::accounts_v1 }); + } + + std::shared_ptr block_random (nano::transaction const & transaction_a) override + { + auto count (block_count (transaction_a)); + release_assert (std::numeric_limits::max () > count.sum ()); + auto region = static_cast (nano::random_pool::generate_word32 (0, static_cast (count.sum () - 1))); + std::shared_ptr result; + auto & derived_store = static_cast (*this); + if (region < count.send) + { + result = derived_store.template block_random (transaction_a, tables::send_blocks); + } + else + { + region -= count.send; + if (region < count.receive) + { + result = derived_store.template block_random (transaction_a, tables::receive_blocks); + } + else + { + region -= count.receive; + if (region < count.open) + { + result = derived_store.template block_random (transaction_a, tables::open_blocks); + } + else + { + region -= count.open; + if (region < count.change) + { + result = derived_store.template block_random (transaction_a, tables::change_blocks); + } + else + { + region -= count.change; + if (region < count.state_v0) + { + result = derived_store.template block_random (transaction_a, tables::state_blocks_v0); + } + else + { + result = derived_store.template block_random (transaction_a, tables::state_blocks_v1); + } + } + } + } + } + assert (result != nullptr); + return result; + } + + nano::store_iterator latest_begin (nano::transaction const & transaction_a, nano::account const & account_a) override + { + return make_merge_iterator (transaction_a, tables::accounts_v0, tables::accounts_v1, nano::db_val (account_a)); + } + + nano::store_iterator latest_begin (nano::transaction const & transaction_a) override + { + return make_merge_iterator (transaction_a, tables::accounts_v0, tables::accounts_v1); + } + + nano::store_iterator latest_v0_begin (nano::transaction const & transaction_a, nano::account const & account_a) override + { + return make_iterator (transaction_a, tables::accounts_v0, nano::db_val (account_a)); + } + + nano::store_iterator latest_v0_begin (nano::transaction const & transaction_a) override + { + return make_iterator (transaction_a, tables::accounts_v0); + } + + nano::store_iterator latest_v1_begin (nano::transaction const & transaction_a, nano::account const & account_a) override + { + return make_iterator (transaction_a, tables::accounts_v1, nano::db_val (account_a)); + } + + nano::store_iterator latest_v1_begin (nano::transaction const & transaction_a) override + { + return make_iterator (transaction_a, tables::accounts_v1); + } + + nano::store_iterator pending_v0_begin (nano::transaction const & transaction_a, nano::pending_key const & key_a) override + { + return make_iterator (transaction_a, tables::pending_v0, nano::db_val (key_a)); + } + + nano::store_iterator pending_v0_begin (nano::transaction const & transaction_a) override + { + return make_iterator (transaction_a, tables::pending_v0); + } + + nano::store_iterator pending_v1_begin (nano::transaction const & transaction_a, nano::pending_key const & key_a) override + { + return make_iterator (transaction_a, tables::pending_v1, nano::db_val (key_a)); + } + + nano::store_iterator pending_v1_begin (nano::transaction const & transaction_a) override + { + return make_iterator (transaction_a, tables::pending_v1); + } + + nano::store_iterator pending_begin (nano::transaction const & transaction_a, nano::pending_key const & key_a) override + { + return make_merge_iterator (transaction_a, tables::pending_v0, tables::pending_v1, nano::db_val (key_a)); + } + + nano::store_iterator pending_begin (nano::transaction const & transaction_a) override + { + return make_merge_iterator (transaction_a, tables::pending_v0, tables::pending_v1); + } + + nano::store_iterator representation_begin (nano::transaction const & transaction_a) override + { + return make_iterator (transaction_a, tables::representation); + } + + nano::store_iterator unchecked_begin (nano::transaction const & transaction_a) override + { + return make_iterator (transaction_a, tables::unchecked); + } + + nano::store_iterator unchecked_begin (nano::transaction const & transaction_a, nano::unchecked_key const & key_a) override + { + return make_iterator (transaction_a, tables::unchecked, nano::db_val (key_a)); + } + + nano::store_iterator> vote_begin (nano::transaction const & transaction_a) override + { + return make_iterator> (transaction_a, tables::vote); + } + + nano::store_iterator online_weight_begin (nano::transaction const & transaction_a) override + { + return make_iterator (transaction_a, tables::online_weight); + } + + nano::store_iterator peers_begin (nano::transaction const & transaction_a) override + { + return make_iterator (transaction_a, tables::peers); + } + + size_t unchecked_count (nano::transaction const & transaction_a) override + { + return count (transaction_a, tables::unchecked); + } + +protected: + nano::network_params network_params; + std::unordered_map> vote_cache_l1; + std::unordered_map> vote_cache_l2; + static int constexpr version{ 15 }; + + template + std::shared_ptr block_random (nano::transaction const & transaction_a, tables table_a) + { + nano::block_hash hash; + nano::random_pool::generate_block (hash.bytes.data (), hash.bytes.size ()); + auto existing = make_iterator> (transaction_a, table_a, nano::db_val (hash)); + if (existing == nano::store_iterator> (nullptr)) + { + existing = make_iterator> (transaction_a, table_a); + } + auto end (nano::store_iterator> (nullptr)); + assert (existing != end); + return block_get (transaction_a, nano::block_hash (existing->first)); + } + + template + nano::store_iterator make_iterator (nano::transaction const & transaction_a, tables table_a) + { + return static_cast (*this).template make_iterator (transaction_a, table_a); + } + + template + nano::store_iterator make_iterator (nano::transaction const & transaction_a, tables table_a, nano::db_val const & key) + { + return static_cast (*this).template make_iterator (transaction_a, table_a, key); + } + + template + nano::store_iterator make_merge_iterator (nano::transaction const & transaction_a, tables table1_a, tables table2_a) + { + return static_cast (*this).template make_merge_iterator (transaction_a, table1_a, table2_a); + } + + template + nano::store_iterator make_merge_iterator (nano::transaction const & transaction_a, tables table1_a, tables table2_a, nano::db_val const & key) + { + return static_cast (*this).template make_merge_iterator (transaction_a, table1_a, table2_a, key); + } + + bool entry_has_sideband (size_t entry_size_a, nano::block_type type_a) const + { + return entry_size_a == nano::block::size (type_a) + nano::block_sideband::size (type_a); + } + + nano::db_val block_raw_get (nano::transaction const & transaction_a, nano::block_hash const & hash_a, nano::block_type & type_a) const + { + nano::db_val result; + // Table lookups are ordered by match probability + nano::block_type block_types[]{ nano::block_type::state, nano::block_type::send, nano::block_type::receive, nano::block_type::open, nano::block_type::change }; + for (auto current_type : block_types) + { + auto db_val (block_raw_get_by_type (transaction_a, hash_a, current_type)); + if (db_val.is_initialized ()) + { + type_a = current_type; + result = db_val.get (); + break; + } + } + + return result; + } + + // Return account containing hash + nano::account block_account_computed (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const + { + assert (!full_sideband (transaction_a)); + nano::account result (0); + auto hash (hash_a); + while (result.is_zero ()) + { + auto block (block_get (transaction_a, hash)); + assert (block); + result = block->account (); + if (result.is_zero ()) + { + auto type (nano::block_type::invalid); + auto value (block_raw_get (transaction_a, block->previous (), type)); + if (entry_has_sideband (value.size (), type)) + { + result = block_account (transaction_a, block->previous ()); + } + else + { + nano::block_info block_info; + if (!block_info_get (transaction_a, hash, block_info)) + { + result = block_info.account; + } + else + { + result = frontier_get (transaction_a, hash); + if (result.is_zero ()) + { + auto successor (block_successor (transaction_a, hash)); + assert (!successor.is_zero ()); + hash = successor; + } + } + } + } + } + assert (!result.is_zero ()); + return result; + } + + nano::uint128_t block_balance_computed (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const + { + assert (!full_sideband (transaction_a)); + summation_visitor visitor (transaction_a, *this); + return visitor.compute_balance (hash_a); + } + + size_t block_successor_offset (nano::transaction const & transaction_a, size_t entry_size_a, nano::block_type type_a) const + { + size_t result; + if (full_sideband (transaction_a) || entry_has_sideband (entry_size_a, type_a)) + { + result = entry_size_a - nano::block_sideband::size (type_a); + } + else + { + // Read old successor-only sideband + assert (entry_size_a == nano::block::size (type_a) + sizeof (nano::uint256_union)); + result = entry_size_a - sizeof (nano::uint256_union); + } + return result; + } + + boost::optional> block_raw_get_by_type (nano::transaction const & transaction_a, nano::block_hash const & hash_a, nano::block_type & type_a) const + { + nano::db_val value; + nano::db_val hash (hash_a); + int status = status_code_not_found (); + switch (type_a) + { + case nano::block_type::send: + { + status = get (transaction_a, tables::send_blocks, hash, value); + break; + } + case nano::block_type::receive: + { + status = get (transaction_a, tables::receive_blocks, hash, value); + break; + } + case nano::block_type::open: + { + status = get (transaction_a, tables::open_blocks, hash, value); + break; + } + case nano::block_type::change: + { + status = get (transaction_a, tables::change_blocks, hash, value); + break; + } + case nano::block_type::state: + { + status = get (transaction_a, tables::state_blocks_v1, hash, value); + if (!success (status)) + { + status = get (transaction_a, tables::state_blocks_v0, hash, value); + } + break; + } + case nano::block_type::invalid: + case nano::block_type::not_a_block: + { + break; + } + } + + release_assert (success (status) || not_found (status)); + boost::optional> result; + if (success (status)) + { + result = value; + } + return result; + } + + tables block_database (nano::block_type type_a, nano::epoch epoch_a) + { + if (type_a == nano::block_type::state) + { + assert (epoch_a == nano::epoch::epoch_0 || epoch_a == nano::epoch::epoch_1); + } + else + { + assert (epoch_a == nano::epoch::epoch_0); + } + tables result = tables::frontiers; + switch (type_a) + { + case nano::block_type::send: + result = tables::send_blocks; + break; + case nano::block_type::receive: + result = tables::receive_blocks; + break; + case nano::block_type::open: + result = tables::open_blocks; + break; + case nano::block_type::change: + result = tables::change_blocks; + break; + case nano::block_type::state: + switch (epoch_a) + { + case nano::epoch::epoch_0: + result = tables::state_blocks_v0; + break; + case nano::epoch::epoch_1: + result = tables::state_blocks_v1; + break; + default: + assert (false); + } + break; + default: + assert (false); + break; + } + return result; + } + + tables get_pending_db (nano::epoch epoch_a) const + { + tables db; + switch (epoch_a) + { + case nano::epoch::invalid: + case nano::epoch::unspecified: + assert (false); + case nano::epoch::epoch_0: + db = tables::pending_v0; + break; + case nano::epoch::epoch_1: + db = tables::pending_v1; + break; + } + return db; + } + + size_t count (nano::transaction const & transaction_a, std::initializer_list dbs_a) const + { + size_t total_count = 0; + for (auto db : dbs_a) + { + total_count += count (transaction_a, db); + } + return total_count; + } + + int get (nano::transaction const & transaction_a, tables table_a, nano::db_val const & key_a, nano::db_val & value_a) const + { + return static_cast (*this).get (transaction_a, table_a, key_a, value_a); + } + + int put (nano::transaction const & transaction_a, tables table_a, nano::db_val const & key_a, nano::db_val const & value_a) + { + return static_cast (*this).put (transaction_a, table_a, key_a, value_a); + } + + int del (nano::transaction const & transaction_a, tables table_a, nano::db_val const & key_a) + { + return static_cast (*this).del (transaction_a, table_a, key_a); + } + + virtual size_t count (nano::transaction const & transaction_a, tables table_a) const = 0; + virtual int drop (nano::transaction const & transaction_a, tables table_a) = 0; + virtual bool not_found (int status) const = 0; + virtual bool success (int status) const = 0; + virtual int status_code_not_found () const = 0; +}; + +/** + * Fill in our predecessors + */ +template +class block_predecessor_set : public nano::block_visitor +{ +public: + block_predecessor_set (nano::transaction const & transaction_a, nano::block_store_partial & store_a) : + transaction (transaction_a), + store (store_a) + { + } + virtual ~block_predecessor_set () = default; + void fill_value (nano::block const & block_a) + { + auto hash (block_a.hash ()); + nano::block_type type; + auto value (store.block_raw_get (transaction, block_a.previous (), type)); + auto version (store.block_version (transaction, block_a.previous ())); + assert (value.size () != 0); + std::vector data (static_cast (value.data ()), static_cast (value.data ()) + value.size ()); + std::copy (hash.bytes.begin (), hash.bytes.end (), data.begin () + store.block_successor_offset (transaction, value.size (), type)); + store.block_raw_put (transaction, data, type, version, block_a.previous ()); + } + void send_block (nano::send_block const & block_a) override + { + fill_value (block_a); + } + void receive_block (nano::receive_block const & block_a) override + { + fill_value (block_a); + } + void open_block (nano::open_block const & block_a) override + { + // Open blocks don't have a predecessor + } + void change_block (nano::change_block const & block_a) override + { + fill_value (block_a); + } + void state_block (nano::state_block const & block_a) override + { + if (!block_a.previous ().is_zero ()) + { + fill_value (block_a); + } + } + nano::transaction const & transaction; + nano::block_store_partial & store; +}; +} \ No newline at end of file diff --git a/nano/slow_test/node.cpp b/nano/slow_test/node.cpp index 4c0b84ef..b22f937d 100644 --- a/nano/slow_test/node.cpp +++ b/nano/slow_test/node.cpp @@ -95,13 +95,13 @@ TEST (ledger, deep_account_compute) { nano::logger_mt logger; bool init (false); - nano::mdb_store store (init, logger, nano::unique_path ()); + auto store = nano::make_store (init, logger, nano::unique_path ()); ASSERT_FALSE (init); nano::stat stats; - nano::ledger ledger (store, stats); + nano::ledger ledger (*store, stats); nano::genesis genesis; - auto transaction (store.tx_begin_write ()); - store.initialize (transaction, genesis); + auto transaction (store->tx_begin_write ()); + store->initialize (transaction, genesis); nano::work_pool pool (std::numeric_limits::max ()); nano::keypair key; auto balance (nano::genesis_amount - 1); @@ -124,10 +124,8 @@ TEST (ledger, deep_account_compute) { std::cerr << i << ' '; } - auto account (ledger.account (transaction, sprevious)); - (void)account; - auto balance (ledger.balance (transaction, rprevious)); - (void)balance; + ledger.account (transaction, sprevious); + ledger.balance (transaction, rprevious); } }