Moved the block LMDB table handlers to their store class
This commit is contained in:
parent
b075c9459b
commit
26700460a7
4 changed files with 462 additions and 467 deletions
|
@ -734,10 +734,10 @@ namespace lmdb
|
|||
store.confirmation_height.del (transaction, nano::dev::genesis->account ());
|
||||
ASSERT_FALSE (mdb_dbi_open (store.env.tx (transaction), "accounts_v1", MDB_CREATE,
|
||||
&store.account_store.accounts_v1_handle));
|
||||
ASSERT_FALSE (mdb_dbi_open (store.env.tx (transaction), "open", MDB_CREATE, &store.open_blocks_handle));
|
||||
ASSERT_FALSE (mdb_dbi_open (store.env.tx (transaction), "open", MDB_CREATE, &store.block_store.open_blocks_handle));
|
||||
modify_account_info_to_v14 (store, transaction, nano::dev::genesis->account (), 1,
|
||||
nano::dev::genesis->hash ());
|
||||
write_block_w_sideband_v18 (store, store.open_blocks_handle, transaction, *nano::dev::genesis);
|
||||
write_block_w_sideband_v18 (store, store.block_store.open_blocks_handle, transaction, *nano::dev::genesis);
|
||||
}
|
||||
|
||||
// Upgrade should work
|
||||
|
@ -1328,16 +1328,16 @@ namespace lmdb
|
|||
ASSERT_EQ (confirmation_height_info.frontier, nano::dev::genesis->hash ());
|
||||
// These databases get removed after an upgrade, so readd them
|
||||
ASSERT_FALSE (
|
||||
mdb_dbi_open (store.env.tx (transaction), "state_v1", MDB_CREATE, &store.state_blocks_v1_handle));
|
||||
mdb_dbi_open (store.env.tx (transaction), "state_v1", MDB_CREATE, &store.block_store.state_blocks_v1_handle));
|
||||
ASSERT_FALSE (mdb_dbi_open (store.env.tx (transaction), "accounts_v1", MDB_CREATE,
|
||||
&store.account_store.accounts_v1_handle));
|
||||
ASSERT_FALSE (
|
||||
mdb_dbi_open (store.env.tx (transaction), "pending_v1", MDB_CREATE, &store.pending_store.pending_v1_handle));
|
||||
ASSERT_FALSE (mdb_dbi_open (store.env.tx (transaction), "open", MDB_CREATE, &store.open_blocks_handle));
|
||||
ASSERT_FALSE (mdb_dbi_open (store.env.tx (transaction), "send", MDB_CREATE, &store.send_blocks_handle));
|
||||
ASSERT_FALSE (mdb_dbi_open (store.env.tx (transaction), "open", MDB_CREATE, &store.block_store.open_blocks_handle));
|
||||
ASSERT_FALSE (mdb_dbi_open (store.env.tx (transaction), "send", MDB_CREATE, &store.block_store.send_blocks_handle));
|
||||
ASSERT_FALSE (
|
||||
mdb_dbi_open (store.env.tx (transaction), "state_blocks", MDB_CREATE,
|
||||
&store.state_blocks_handle));
|
||||
&store.block_store.state_blocks_handle));
|
||||
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, send).code);
|
||||
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, epoch).code);
|
||||
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, state_send).code);
|
||||
|
@ -1349,10 +1349,10 @@ namespace lmdb
|
|||
|
||||
store.pending.del (transaction, nano::pending_key (nano::dev::genesis->account (), state_send.hash ()));
|
||||
|
||||
write_sideband_v14 (store, transaction, state_send, store.state_blocks_v1_handle);
|
||||
write_sideband_v14 (store, transaction, epoch, store.state_blocks_v1_handle);
|
||||
write_block_w_sideband_v18 (store, store.open_blocks_handle, transaction, *nano::dev::genesis);
|
||||
write_block_w_sideband_v18 (store, store.send_blocks_handle, transaction, send);
|
||||
write_sideband_v14 (store, transaction, state_send, store.block_store.state_blocks_v1_handle);
|
||||
write_sideband_v14 (store, transaction, epoch, store.block_store.state_blocks_v1_handle);
|
||||
write_block_w_sideband_v18 (store, store.block_store.open_blocks_handle, transaction, *nano::dev::genesis);
|
||||
write_block_w_sideband_v18 (store, store.block_store.send_blocks_handle, transaction, send);
|
||||
|
||||
// Remove from blocks table
|
||||
store.block.del (transaction, state_send.hash ());
|
||||
|
@ -1413,7 +1413,7 @@ namespace lmdb
|
|||
auto error_get_pending_v1 (mdb_get (store.env.tx (transaction), store.pending_store.pending_v1_handle, nano::mdb_val (nano::pending_key (nano::dev::genesis_key.pub, state_send.hash ())), value));
|
||||
ASSERT_NE (error_get_pending_v1, MDB_SUCCESS);
|
||||
auto error_get_state_v1 (
|
||||
mdb_get (store.env.tx (transaction), store.state_blocks_v1_handle, nano::mdb_val (state_send.hash ()),
|
||||
mdb_get (store.env.tx (transaction), store.block_store.state_blocks_v1_handle, nano::mdb_val (state_send.hash ()),
|
||||
value));
|
||||
ASSERT_NE (error_get_state_v1, MDB_SUCCESS);
|
||||
|
||||
|
@ -1458,8 +1458,8 @@ namespace lmdb
|
|||
mdb_dbi_open (txn, "representation", MDB_CREATE, &store.account_store.representation_handle));
|
||||
auto weight = ledger.cache.rep_weights.representation_get (nano::dev::genesis->account ());
|
||||
ASSERT_EQ (MDB_SUCCESS, mdb_put (txn, store.account_store.representation_handle, nano::mdb_val (nano::dev::genesis->account ()), nano::mdb_val (nano::uint128_union (weight)), 0));
|
||||
ASSERT_FALSE (mdb_dbi_open (store.env.tx (transaction), "open", MDB_CREATE, &store.open_blocks_handle));
|
||||
write_block_w_sideband_v18 (store, store.open_blocks_handle, transaction, *nano::dev::genesis);
|
||||
ASSERT_FALSE (mdb_dbi_open (store.env.tx (transaction), "open", MDB_CREATE, &store.block_store.open_blocks_handle));
|
||||
write_block_w_sideband_v18 (store, store.block_store.open_blocks_handle, transaction, *nano::dev::genesis);
|
||||
// Lower the database to the previous version
|
||||
store.version.put (transaction, 15);
|
||||
// Confirm the rep weight exists in the database
|
||||
|
@ -1482,45 +1482,144 @@ namespace lmdb
|
|||
// Version should be correct
|
||||
ASSERT_LT (15, store.version.get (transaction));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST (mdb_block_store, upgrade_v16_v17)
|
||||
{
|
||||
if (nano::rocksdb_config::using_rocksdb_in_tests ())
|
||||
TEST (mdb_block_store, upgrade_v16_v17)
|
||||
{
|
||||
// Don't test this in rocksdb mode
|
||||
return;
|
||||
}
|
||||
nano::work_pool pool{ nano::dev::network_params.network, std::numeric_limits<unsigned>::max () };
|
||||
nano::state_block block1 (nano::dev::genesis_key.pub, nano::dev::genesis->hash (), nano::dev::genesis_key.pub, nano::dev::constants.genesis_amount - nano::Gxrb_ratio, nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::dev::genesis_key.pub, *pool.generate (nano::dev::genesis->hash ()));
|
||||
nano::state_block block2 (nano::dev::genesis_key.pub, block1.hash (), nano::dev::genesis_key.pub, nano::dev::constants.genesis_amount - nano::Gxrb_ratio - 1, nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::dev::genesis_key.pub, *pool.generate (block1.hash ()));
|
||||
nano::state_block block3 (nano::dev::genesis_key.pub, block2.hash (), nano::dev::genesis_key.pub, nano::dev::constants.genesis_amount - nano::Gxrb_ratio - 2, nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::dev::genesis_key.pub, *pool.generate (block2.hash ()));
|
||||
if (nano::rocksdb_config::using_rocksdb_in_tests ())
|
||||
{
|
||||
// Don't test this in rocksdb mode
|
||||
return;
|
||||
}
|
||||
nano::work_pool pool{ nano::dev::network_params.network, std::numeric_limits<unsigned>::max () };
|
||||
nano::state_block block1 (nano::dev::genesis_key.pub, nano::dev::genesis->hash (), nano::dev::genesis_key.pub, nano::dev::constants.genesis_amount - nano::Gxrb_ratio, nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::dev::genesis_key.pub, *pool.generate (nano::dev::genesis->hash ()));
|
||||
nano::state_block block2 (nano::dev::genesis_key.pub, block1.hash (), nano::dev::genesis_key.pub, nano::dev::constants.genesis_amount - nano::Gxrb_ratio - 1, nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::dev::genesis_key.pub, *pool.generate (block1.hash ()));
|
||||
nano::state_block block3 (nano::dev::genesis_key.pub, block2.hash (), nano::dev::genesis_key.pub, nano::dev::constants.genesis_amount - nano::Gxrb_ratio - 2, nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::dev::genesis_key.pub, *pool.generate (block2.hash ()));
|
||||
|
||||
auto code = [&block1, &block2, &block3] (auto confirmation_height, nano::block_hash const & expected_cemented_frontier) {
|
||||
auto code = [&block1, &block2, &block3] (auto confirmation_height, nano::block_hash const & expected_cemented_frontier) {
|
||||
auto path (nano::unique_path ());
|
||||
nano::mdb_val value;
|
||||
{
|
||||
nano::logger_mt logger;
|
||||
nano::lmdb::store store (logger, path, nano::dev::constants);
|
||||
nano::stat stats;
|
||||
nano::ledger ledger (store, stats, nano::dev::constants);
|
||||
auto transaction (store.tx_begin_write ());
|
||||
store.initialize (transaction, ledger.cache, nano::dev::constants);
|
||||
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, block1).code);
|
||||
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, block2).code);
|
||||
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, block3).code);
|
||||
modify_confirmation_height_to_v15 (store, transaction, nano::dev::genesis->account (), confirmation_height);
|
||||
|
||||
ASSERT_FALSE (mdb_dbi_open (store.env.tx (transaction), "open", MDB_CREATE, &store.block_store.open_blocks_handle));
|
||||
write_block_w_sideband_v18 (store, store.block_store.open_blocks_handle, transaction, *nano::dev::genesis);
|
||||
ASSERT_FALSE (mdb_dbi_open (store.env.tx (transaction), "state_blocks", MDB_CREATE, &store.block_store.state_blocks_handle));
|
||||
write_block_w_sideband_v18 (store, store.block_store.state_blocks_handle, transaction, block1);
|
||||
write_block_w_sideband_v18 (store, store.block_store.state_blocks_handle, transaction, block2);
|
||||
write_block_w_sideband_v18 (store, store.block_store.state_blocks_handle, transaction, block3);
|
||||
|
||||
// Lower the database to the previous version
|
||||
store.version.put (transaction, 16);
|
||||
}
|
||||
|
||||
// Now do the upgrade
|
||||
nano::logger_mt logger;
|
||||
nano::lmdb::store store (logger, path, nano::dev::constants);
|
||||
ASSERT_FALSE (store.init_error ());
|
||||
auto transaction (store.tx_begin_read ());
|
||||
|
||||
nano::confirmation_height_info confirmation_height_info;
|
||||
ASSERT_FALSE (store.confirmation_height.get (transaction, nano::dev::genesis->account (), confirmation_height_info));
|
||||
ASSERT_EQ (confirmation_height_info.height, confirmation_height);
|
||||
|
||||
// Check confirmation height frontier is correct
|
||||
ASSERT_EQ (confirmation_height_info.frontier, expected_cemented_frontier);
|
||||
|
||||
// Version should be correct
|
||||
ASSERT_LT (16, store.version.get (transaction));
|
||||
};
|
||||
|
||||
code (0, nano::block_hash (0));
|
||||
code (1, nano::dev::genesis->hash ());
|
||||
code (2, block1.hash ());
|
||||
code (3, block2.hash ());
|
||||
code (4, block3.hash ());
|
||||
}
|
||||
|
||||
TEST (mdb_block_store, upgrade_v17_v18)
|
||||
{
|
||||
if (nano::rocksdb_config::using_rocksdb_in_tests ())
|
||||
{
|
||||
// Don't test this in rocksdb mode
|
||||
return;
|
||||
}
|
||||
auto path (nano::unique_path ());
|
||||
nano::mdb_val value;
|
||||
nano::keypair key1;
|
||||
nano::keypair key2;
|
||||
nano::keypair key3;
|
||||
nano::work_pool pool{ nano::dev::network_params.network, std::numeric_limits<unsigned>::max () };
|
||||
nano::send_block send_zero (nano::dev::genesis->hash (), nano::dev::genesis_key.pub, nano::dev::constants.genesis_amount, nano::dev::genesis_key.prv, nano::dev::genesis_key.pub, *pool.generate (nano::dev::genesis->hash ()));
|
||||
nano::state_block state_receive_zero (nano::dev::genesis_key.pub, send_zero.hash (), nano::dev::genesis_key.pub, nano::dev::constants.genesis_amount, send_zero.hash (), nano::dev::genesis_key.prv, nano::dev::genesis_key.pub, *pool.generate (send_zero.hash ()));
|
||||
nano::state_block epoch (nano::dev::genesis_key.pub, state_receive_zero.hash (), nano::dev::genesis_key.pub, nano::dev::constants.genesis_amount, nano::dev::network_params.ledger.epochs.link (nano::epoch::epoch_1), nano::dev::genesis_key.prv, nano::dev::genesis_key.pub, *pool.generate (state_receive_zero.hash ()));
|
||||
nano::state_block state_send (nano::dev::genesis_key.pub, epoch.hash (), nano::dev::genesis_key.pub, nano::dev::constants.genesis_amount - nano::Gxrb_ratio, nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::dev::genesis_key.pub, *pool.generate (epoch.hash ()));
|
||||
nano::state_block state_receive (nano::dev::genesis_key.pub, state_send.hash (), nano::dev::genesis_key.pub, nano::dev::constants.genesis_amount, state_send.hash (), nano::dev::genesis_key.prv, nano::dev::genesis_key.pub, *pool.generate (state_send.hash ()));
|
||||
nano::state_block state_change (nano::dev::genesis_key.pub, state_receive.hash (), nano::dev::genesis_key.pub, nano::dev::constants.genesis_amount, 0, nano::dev::genesis_key.prv, nano::dev::genesis_key.pub, *pool.generate (state_receive.hash ()));
|
||||
nano::state_block state_send_change (nano::dev::genesis_key.pub, state_change.hash (), key1.pub, nano::dev::constants.genesis_amount - nano::Gxrb_ratio, key1.pub, nano::dev::genesis_key.prv, nano::dev::genesis_key.pub, *pool.generate (state_change.hash ()));
|
||||
nano::state_block epoch_first (key1.pub, 0, 0, 0, nano::dev::network_params.ledger.epochs.link (nano::epoch::epoch_2), nano::dev::genesis_key.prv, nano::dev::genesis_key.pub, *pool.generate (key1.pub));
|
||||
nano::state_block state_receive2 (key1.pub, epoch_first.hash (), key1.pub, nano::Gxrb_ratio, state_send_change.hash (), key1.prv, key1.pub, *pool.generate (epoch_first.hash ()));
|
||||
nano::state_block state_send2 (nano::dev::genesis_key.pub, state_send_change.hash (), key1.pub, nano::dev::constants.genesis_amount - nano::Gxrb_ratio * 2, key2.pub, nano::dev::genesis_key.prv, nano::dev::genesis_key.pub, *pool.generate (state_send_change.hash ()));
|
||||
nano::state_block state_open (key2.pub, 0, key2.pub, nano::Gxrb_ratio, state_send2.hash (), key2.prv, key2.pub, *pool.generate (key2.pub));
|
||||
nano::state_block state_send_epoch_link (key2.pub, state_open.hash (), key2.pub, 0, nano::dev::network_params.ledger.epochs.link (nano::epoch::epoch_2), key2.prv, key2.pub, *pool.generate (state_open.hash ()));
|
||||
{
|
||||
nano::logger_mt logger;
|
||||
nano::lmdb::store store (logger, path, nano::dev::constants);
|
||||
auto transaction (store.tx_begin_write ());
|
||||
nano::stat stats;
|
||||
nano::ledger ledger (store, stats, nano::dev::constants);
|
||||
auto transaction (store.tx_begin_write ());
|
||||
store.initialize (transaction, ledger.cache, nano::dev::constants);
|
||||
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, block1).code);
|
||||
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, block2).code);
|
||||
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, block3).code);
|
||||
modify_confirmation_height_to_v15 (store, transaction, nano::dev::genesis->account (), confirmation_height);
|
||||
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, send_zero).code);
|
||||
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, state_receive_zero).code);
|
||||
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, epoch).code);
|
||||
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, state_send).code);
|
||||
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, state_receive).code);
|
||||
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, state_change).code);
|
||||
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, state_send_change).code);
|
||||
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, epoch_first).code);
|
||||
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, state_receive2).code);
|
||||
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, state_send2).code);
|
||||
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, state_open).code);
|
||||
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, state_send_epoch_link).code);
|
||||
|
||||
ASSERT_FALSE (mdb_dbi_open (store.env.tx (transaction), "open", MDB_CREATE, &store.open_blocks_handle));
|
||||
write_block_w_sideband_v18 (store, store.open_blocks_handle, transaction, *nano::dev::genesis);
|
||||
ASSERT_FALSE (mdb_dbi_open (store.env.tx (transaction), "state_blocks", MDB_CREATE, &store.state_blocks_handle));
|
||||
write_block_w_sideband_v18 (store, store.state_blocks_handle, transaction, block1);
|
||||
write_block_w_sideband_v18 (store, store.state_blocks_handle, transaction, block2);
|
||||
write_block_w_sideband_v18 (store, store.state_blocks_handle, transaction, block3);
|
||||
ASSERT_FALSE (mdb_dbi_open (store.env.tx (transaction), "open", MDB_CREATE, &store.block_store.open_blocks_handle));
|
||||
ASSERT_FALSE (mdb_dbi_open (store.env.tx (transaction), "send", MDB_CREATE, &store.block_store.send_blocks_handle));
|
||||
ASSERT_FALSE (mdb_dbi_open (store.env.tx (transaction), "state_blocks", MDB_CREATE, &store.block_store.state_blocks_handle));
|
||||
|
||||
// Lower the database to the previous version
|
||||
store.version.put (transaction, 16);
|
||||
// Downgrade the store
|
||||
store.version.put (transaction, 17);
|
||||
|
||||
write_block_w_sideband_v18 (store, store.block_store.state_blocks_handle, transaction, state_receive);
|
||||
write_block_w_sideband_v18 (store, store.block_store.state_blocks_handle, transaction, epoch_first);
|
||||
write_block_w_sideband_v18 (store, store.block_store.state_blocks_handle, transaction, state_send2);
|
||||
write_block_w_sideband_v18 (store, store.block_store.state_blocks_handle, transaction, state_send_epoch_link);
|
||||
write_block_w_sideband_v18 (store, store.block_store.open_blocks_handle, transaction, *nano::dev::genesis);
|
||||
write_block_w_sideband_v18 (store, store.block_store.send_blocks_handle, transaction, send_zero);
|
||||
|
||||
// Replace with the previous sideband version for state blocks
|
||||
// The upgrade can resume after upgrading some blocks, test this by only downgrading some of them
|
||||
write_sideband_v15 (store, transaction, state_receive_zero);
|
||||
write_sideband_v15 (store, transaction, epoch);
|
||||
write_sideband_v15 (store, transaction, state_send);
|
||||
write_sideband_v15 (store, transaction, state_change);
|
||||
write_sideband_v15 (store, transaction, state_send_change);
|
||||
write_sideband_v15 (store, transaction, state_receive2);
|
||||
write_sideband_v15 (store, transaction, state_open);
|
||||
|
||||
store.block.del (transaction, state_receive_zero.hash ());
|
||||
store.block.del (transaction, epoch.hash ());
|
||||
store.block.del (transaction, state_send.hash ());
|
||||
store.block.del (transaction, state_change.hash ());
|
||||
store.block.del (transaction, state_send_change.hash ());
|
||||
store.block.del (transaction, state_receive2.hash ());
|
||||
store.block.del (transaction, state_open.hash ());
|
||||
}
|
||||
|
||||
// Now do the upgrade
|
||||
|
@ -1529,321 +1628,216 @@ TEST (mdb_block_store, upgrade_v16_v17)
|
|||
ASSERT_FALSE (store.init_error ());
|
||||
auto transaction (store.tx_begin_read ());
|
||||
|
||||
nano::confirmation_height_info confirmation_height_info;
|
||||
ASSERT_FALSE (store.confirmation_height.get (transaction, nano::dev::genesis->account (), confirmation_height_info));
|
||||
ASSERT_EQ (confirmation_height_info.height, confirmation_height);
|
||||
// Size of state block should equal that set in db (no change)
|
||||
nano::mdb_val value;
|
||||
ASSERT_FALSE (mdb_get (store.env.tx (transaction), store.block_store.blocks_handle, nano::mdb_val (state_send.hash ()), value));
|
||||
ASSERT_EQ (value.size (), sizeof (nano::block_type) + nano::state_block::size + nano::block_sideband::size (nano::block_type::state));
|
||||
|
||||
// Check confirmation height frontier is correct
|
||||
ASSERT_EQ (confirmation_height_info.frontier, expected_cemented_frontier);
|
||||
// Check that sidebands are correctly populated
|
||||
{
|
||||
// Non-state unaffected
|
||||
auto block = store.block.get (transaction, send_zero.hash ());
|
||||
ASSERT_NE (block, nullptr);
|
||||
// All defaults
|
||||
ASSERT_EQ (block->sideband ().details.epoch, nano::epoch::epoch_0);
|
||||
ASSERT_FALSE (block->sideband ().details.is_epoch);
|
||||
ASSERT_FALSE (block->sideband ().details.is_send);
|
||||
ASSERT_FALSE (block->sideband ().details.is_receive);
|
||||
}
|
||||
{
|
||||
// State receive from old zero send
|
||||
auto block = store.block.get (transaction, state_receive_zero.hash ());
|
||||
ASSERT_NE (block, nullptr);
|
||||
ASSERT_EQ (block->sideband ().details.epoch, nano::epoch::epoch_0);
|
||||
ASSERT_FALSE (block->sideband ().details.is_epoch);
|
||||
ASSERT_FALSE (block->sideband ().details.is_send);
|
||||
ASSERT_TRUE (block->sideband ().details.is_receive);
|
||||
}
|
||||
{
|
||||
// Epoch
|
||||
auto block = store.block.get (transaction, epoch.hash ());
|
||||
ASSERT_NE (block, nullptr);
|
||||
ASSERT_EQ (block->sideband ().details.epoch, nano::epoch::epoch_1);
|
||||
ASSERT_TRUE (block->sideband ().details.is_epoch);
|
||||
ASSERT_FALSE (block->sideband ().details.is_send);
|
||||
ASSERT_FALSE (block->sideband ().details.is_receive);
|
||||
}
|
||||
{
|
||||
// State send
|
||||
auto block = store.block.get (transaction, state_send.hash ());
|
||||
ASSERT_NE (block, nullptr);
|
||||
ASSERT_EQ (block->sideband ().details.epoch, nano::epoch::epoch_1);
|
||||
ASSERT_FALSE (block->sideband ().details.is_epoch);
|
||||
ASSERT_TRUE (block->sideband ().details.is_send);
|
||||
ASSERT_FALSE (block->sideband ().details.is_receive);
|
||||
}
|
||||
{
|
||||
// State receive
|
||||
auto block = store.block.get (transaction, state_receive.hash ());
|
||||
ASSERT_NE (block, nullptr);
|
||||
ASSERT_EQ (block->sideband ().details.epoch, nano::epoch::epoch_1);
|
||||
ASSERT_FALSE (block->sideband ().details.is_epoch);
|
||||
ASSERT_FALSE (block->sideband ().details.is_send);
|
||||
ASSERT_TRUE (block->sideband ().details.is_receive);
|
||||
}
|
||||
{
|
||||
// State change
|
||||
auto block = store.block.get (transaction, state_change.hash ());
|
||||
ASSERT_NE (block, nullptr);
|
||||
ASSERT_EQ (block->sideband ().details.epoch, nano::epoch::epoch_1);
|
||||
ASSERT_FALSE (block->sideband ().details.is_epoch);
|
||||
ASSERT_FALSE (block->sideband ().details.is_send);
|
||||
ASSERT_FALSE (block->sideband ().details.is_receive);
|
||||
}
|
||||
{
|
||||
// State send + change
|
||||
auto block = store.block.get (transaction, state_send_change.hash ());
|
||||
ASSERT_NE (block, nullptr);
|
||||
ASSERT_EQ (block->sideband ().details.epoch, nano::epoch::epoch_1);
|
||||
ASSERT_FALSE (block->sideband ().details.is_epoch);
|
||||
ASSERT_TRUE (block->sideband ().details.is_send);
|
||||
ASSERT_FALSE (block->sideband ().details.is_receive);
|
||||
}
|
||||
{
|
||||
// Epoch on unopened account
|
||||
auto block = store.block.get (transaction, epoch_first.hash ());
|
||||
ASSERT_NE (block, nullptr);
|
||||
ASSERT_EQ (block->sideband ().details.epoch, nano::epoch::epoch_2);
|
||||
ASSERT_TRUE (block->sideband ().details.is_epoch);
|
||||
ASSERT_FALSE (block->sideband ().details.is_send);
|
||||
ASSERT_FALSE (block->sideband ().details.is_receive);
|
||||
}
|
||||
{
|
||||
// State open following epoch
|
||||
auto block = store.block.get (transaction, state_receive2.hash ());
|
||||
ASSERT_NE (block, nullptr);
|
||||
ASSERT_EQ (block->sideband ().details.epoch, nano::epoch::epoch_2);
|
||||
ASSERT_FALSE (block->sideband ().details.is_epoch);
|
||||
ASSERT_FALSE (block->sideband ().details.is_send);
|
||||
ASSERT_TRUE (block->sideband ().details.is_receive);
|
||||
}
|
||||
{
|
||||
// Another state send
|
||||
auto block = store.block.get (transaction, state_send2.hash ());
|
||||
ASSERT_NE (block, nullptr);
|
||||
ASSERT_EQ (block->sideband ().details.epoch, nano::epoch::epoch_1);
|
||||
ASSERT_FALSE (block->sideband ().details.is_epoch);
|
||||
ASSERT_TRUE (block->sideband ().details.is_send);
|
||||
ASSERT_FALSE (block->sideband ().details.is_receive);
|
||||
}
|
||||
{
|
||||
// State open
|
||||
auto block = store.block.get (transaction, state_open.hash ());
|
||||
ASSERT_NE (block, nullptr);
|
||||
ASSERT_EQ (block->sideband ().details.epoch, nano::epoch::epoch_1);
|
||||
ASSERT_FALSE (block->sideband ().details.is_epoch);
|
||||
ASSERT_FALSE (block->sideband ().details.is_send);
|
||||
ASSERT_TRUE (block->sideband ().details.is_receive);
|
||||
}
|
||||
{
|
||||
// State send to an epoch link
|
||||
auto block = store.block.get (transaction, state_send_epoch_link.hash ());
|
||||
ASSERT_NE (block, nullptr);
|
||||
ASSERT_EQ (block->sideband ().details.epoch, nano::epoch::epoch_1);
|
||||
ASSERT_FALSE (block->sideband ().details.is_epoch);
|
||||
ASSERT_TRUE (block->sideband ().details.is_send);
|
||||
ASSERT_FALSE (block->sideband ().details.is_receive);
|
||||
}
|
||||
// Version should be correct
|
||||
ASSERT_LT (17, store.version.get (transaction));
|
||||
}
|
||||
|
||||
TEST (mdb_block_store, upgrade_v18_v19)
|
||||
{
|
||||
if (nano::rocksdb_config::using_rocksdb_in_tests ())
|
||||
{
|
||||
// Don't test this in rocksdb mode
|
||||
return;
|
||||
}
|
||||
auto path (nano::unique_path ());
|
||||
nano::keypair key1;
|
||||
nano::work_pool pool{ nano::dev::network_params.network, std::numeric_limits<unsigned>::max () };
|
||||
nano::send_block send (nano::dev::genesis->hash (), nano::dev::genesis_key.pub, nano::dev::constants.genesis_amount - nano::Gxrb_ratio, nano::dev::genesis_key.prv, nano::dev::genesis_key.pub, *pool.generate (nano::dev::genesis->hash ()));
|
||||
nano::receive_block receive (send.hash (), send.hash (), nano::dev::genesis_key.prv, nano::dev::genesis_key.pub, *pool.generate (send.hash ()));
|
||||
nano::change_block change (receive.hash (), 0, nano::dev::genesis_key.prv, nano::dev::genesis_key.pub, *pool.generate (receive.hash ()));
|
||||
nano::state_block state_epoch (nano::dev::genesis_key.pub, change.hash (), 0, nano::dev::constants.genesis_amount, nano::dev::network_params.ledger.epochs.link (nano::epoch::epoch_1), nano::dev::genesis_key.prv, nano::dev::genesis_key.pub, *pool.generate (change.hash ()));
|
||||
nano::state_block state_send (nano::dev::genesis_key.pub, state_epoch.hash (), 0, nano::dev::constants.genesis_amount - nano::Gxrb_ratio, key1.pub, nano::dev::genesis_key.prv, nano::dev::genesis_key.pub, *pool.generate (state_epoch.hash ()));
|
||||
nano::state_block state_open (key1.pub, 0, 0, nano::Gxrb_ratio, state_send.hash (), key1.prv, key1.pub, *pool.generate (key1.pub));
|
||||
|
||||
{
|
||||
nano::logger_mt logger;
|
||||
nano::lmdb::store store (logger, path, nano::dev::constants);
|
||||
nano::stat stats;
|
||||
nano::ledger ledger (store, stats, nano::dev::constants);
|
||||
auto transaction (store.tx_begin_write ());
|
||||
store.initialize (transaction, ledger.cache, nano::dev::constants);
|
||||
|
||||
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, send).code);
|
||||
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, receive).code);
|
||||
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, change).code);
|
||||
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, state_epoch).code);
|
||||
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, state_send).code);
|
||||
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, state_open).code);
|
||||
|
||||
// These tables need to be re-opened and populated so that an upgrade can be done
|
||||
auto txn = store.env.tx (transaction);
|
||||
ASSERT_FALSE (mdb_dbi_open (txn, "open", MDB_CREATE, &store.block_store.open_blocks_handle));
|
||||
ASSERT_FALSE (mdb_dbi_open (txn, "receive", MDB_CREATE, &store.block_store.receive_blocks_handle));
|
||||
ASSERT_FALSE (mdb_dbi_open (txn, "send", MDB_CREATE, &store.block_store.send_blocks_handle));
|
||||
ASSERT_FALSE (mdb_dbi_open (txn, "change", MDB_CREATE, &store.block_store.change_blocks_handle));
|
||||
ASSERT_FALSE (mdb_dbi_open (txn, "state_blocks", MDB_CREATE, &store.block_store.state_blocks_handle));
|
||||
|
||||
// Modify blocks back to the old tables
|
||||
write_block_w_sideband_v18 (store, store.block_store.open_blocks_handle, transaction, *nano::dev::genesis);
|
||||
write_block_w_sideband_v18 (store, store.block_store.send_blocks_handle, transaction, send);
|
||||
write_block_w_sideband_v18 (store, store.block_store.receive_blocks_handle, transaction, receive);
|
||||
write_block_w_sideband_v18 (store, store.block_store.change_blocks_handle, transaction, change);
|
||||
write_block_w_sideband_v18 (store, store.block_store.state_blocks_handle, transaction, state_epoch);
|
||||
write_block_w_sideband_v18 (store, store.block_store.state_blocks_handle, transaction, state_send);
|
||||
write_block_w_sideband_v18 (store, store.block_store.state_blocks_handle, transaction, state_open);
|
||||
|
||||
store.version.put (transaction, 18);
|
||||
}
|
||||
|
||||
// Now do the upgrade
|
||||
nano::logger_mt logger;
|
||||
nano::lmdb::store store (logger, path, nano::dev::constants);
|
||||
ASSERT_FALSE (store.init_error ());
|
||||
auto transaction (store.tx_begin_read ());
|
||||
|
||||
// These tables should be deleted
|
||||
ASSERT_EQ (store.block_store.send_blocks_handle, 0);
|
||||
ASSERT_EQ (store.block_store.receive_blocks_handle, 0);
|
||||
ASSERT_EQ (store.block_store.change_blocks_handle, 0);
|
||||
ASSERT_EQ (store.block_store.open_blocks_handle, 0);
|
||||
ASSERT_EQ (store.block_store.state_blocks_handle, 0);
|
||||
|
||||
// Confirm these blocks all exist after the upgrade
|
||||
ASSERT_TRUE (store.block.get (transaction, send.hash ()));
|
||||
ASSERT_TRUE (store.block.get (transaction, receive.hash ()));
|
||||
ASSERT_TRUE (store.block.get (transaction, change.hash ()));
|
||||
ASSERT_TRUE (store.block.get (transaction, nano::dev::genesis->hash ()));
|
||||
auto state_epoch_disk (store.block.get (transaction, state_epoch.hash ()));
|
||||
ASSERT_NE (nullptr, state_epoch_disk);
|
||||
ASSERT_EQ (nano::epoch::epoch_1, state_epoch_disk->sideband ().details.epoch);
|
||||
ASSERT_EQ (nano::epoch::epoch_0, state_epoch_disk->sideband ().source_epoch); // Not used for epoch state blocks
|
||||
ASSERT_TRUE (store.block.get (transaction, state_send.hash ()));
|
||||
auto state_send_disk (store.block.get (transaction, state_send.hash ()));
|
||||
ASSERT_NE (nullptr, state_send_disk);
|
||||
ASSERT_EQ (nano::epoch::epoch_1, state_send_disk->sideband ().details.epoch);
|
||||
ASSERT_EQ (nano::epoch::epoch_0, state_send_disk->sideband ().source_epoch); // Not used for send state blocks
|
||||
ASSERT_TRUE (store.block.get (transaction, state_open.hash ()));
|
||||
auto state_open_disk (store.block.get (transaction, state_open.hash ()));
|
||||
ASSERT_NE (nullptr, state_open_disk);
|
||||
ASSERT_EQ (nano::epoch::epoch_1, state_open_disk->sideband ().details.epoch);
|
||||
ASSERT_EQ (nano::epoch::epoch_1, state_open_disk->sideband ().source_epoch);
|
||||
|
||||
ASSERT_EQ (7, store.count (transaction, store.block_store.blocks_handle));
|
||||
|
||||
// Version should be correct
|
||||
ASSERT_LT (16, store.version.get (transaction));
|
||||
};
|
||||
|
||||
code (0, nano::block_hash (0));
|
||||
code (1, nano::dev::genesis->hash ());
|
||||
code (2, block1.hash ());
|
||||
code (3, block2.hash ());
|
||||
code (4, block3.hash ());
|
||||
}
|
||||
|
||||
TEST (mdb_block_store, upgrade_v17_v18)
|
||||
{
|
||||
if (nano::rocksdb_config::using_rocksdb_in_tests ())
|
||||
{
|
||||
// Don't test this in rocksdb mode
|
||||
return;
|
||||
}
|
||||
auto path (nano::unique_path ());
|
||||
nano::keypair key1;
|
||||
nano::keypair key2;
|
||||
nano::keypair key3;
|
||||
nano::work_pool pool{ nano::dev::network_params.network, std::numeric_limits<unsigned>::max () };
|
||||
nano::send_block send_zero (nano::dev::genesis->hash (), nano::dev::genesis_key.pub, nano::dev::constants.genesis_amount, nano::dev::genesis_key.prv, nano::dev::genesis_key.pub, *pool.generate (nano::dev::genesis->hash ()));
|
||||
nano::state_block state_receive_zero (nano::dev::genesis_key.pub, send_zero.hash (), nano::dev::genesis_key.pub, nano::dev::constants.genesis_amount, send_zero.hash (), nano::dev::genesis_key.prv, nano::dev::genesis_key.pub, *pool.generate (send_zero.hash ()));
|
||||
nano::state_block epoch (nano::dev::genesis_key.pub, state_receive_zero.hash (), nano::dev::genesis_key.pub, nano::dev::constants.genesis_amount, nano::dev::network_params.ledger.epochs.link (nano::epoch::epoch_1), nano::dev::genesis_key.prv, nano::dev::genesis_key.pub, *pool.generate (state_receive_zero.hash ()));
|
||||
nano::state_block state_send (nano::dev::genesis_key.pub, epoch.hash (), nano::dev::genesis_key.pub, nano::dev::constants.genesis_amount - nano::Gxrb_ratio, nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::dev::genesis_key.pub, *pool.generate (epoch.hash ()));
|
||||
nano::state_block state_receive (nano::dev::genesis_key.pub, state_send.hash (), nano::dev::genesis_key.pub, nano::dev::constants.genesis_amount, state_send.hash (), nano::dev::genesis_key.prv, nano::dev::genesis_key.pub, *pool.generate (state_send.hash ()));
|
||||
nano::state_block state_change (nano::dev::genesis_key.pub, state_receive.hash (), nano::dev::genesis_key.pub, nano::dev::constants.genesis_amount, 0, nano::dev::genesis_key.prv, nano::dev::genesis_key.pub, *pool.generate (state_receive.hash ()));
|
||||
nano::state_block state_send_change (nano::dev::genesis_key.pub, state_change.hash (), key1.pub, nano::dev::constants.genesis_amount - nano::Gxrb_ratio, key1.pub, nano::dev::genesis_key.prv, nano::dev::genesis_key.pub, *pool.generate (state_change.hash ()));
|
||||
nano::state_block epoch_first (key1.pub, 0, 0, 0, nano::dev::network_params.ledger.epochs.link (nano::epoch::epoch_2), nano::dev::genesis_key.prv, nano::dev::genesis_key.pub, *pool.generate (key1.pub));
|
||||
nano::state_block state_receive2 (key1.pub, epoch_first.hash (), key1.pub, nano::Gxrb_ratio, state_send_change.hash (), key1.prv, key1.pub, *pool.generate (epoch_first.hash ()));
|
||||
nano::state_block state_send2 (nano::dev::genesis_key.pub, state_send_change.hash (), key1.pub, nano::dev::constants.genesis_amount - nano::Gxrb_ratio * 2, key2.pub, nano::dev::genesis_key.prv, nano::dev::genesis_key.pub, *pool.generate (state_send_change.hash ()));
|
||||
nano::state_block state_open (key2.pub, 0, key2.pub, nano::Gxrb_ratio, state_send2.hash (), key2.prv, key2.pub, *pool.generate (key2.pub));
|
||||
nano::state_block state_send_epoch_link (key2.pub, state_open.hash (), key2.pub, 0, nano::dev::network_params.ledger.epochs.link (nano::epoch::epoch_2), key2.prv, key2.pub, *pool.generate (state_open.hash ()));
|
||||
{
|
||||
nano::logger_mt logger;
|
||||
nano::lmdb::store store (logger, path, nano::dev::constants);
|
||||
auto transaction (store.tx_begin_write ());
|
||||
nano::stat stats;
|
||||
nano::ledger ledger (store, stats, nano::dev::constants);
|
||||
store.initialize (transaction, ledger.cache, nano::dev::constants);
|
||||
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, send_zero).code);
|
||||
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, state_receive_zero).code);
|
||||
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, epoch).code);
|
||||
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, state_send).code);
|
||||
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, state_receive).code);
|
||||
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, state_change).code);
|
||||
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, state_send_change).code);
|
||||
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, epoch_first).code);
|
||||
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, state_receive2).code);
|
||||
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, state_send2).code);
|
||||
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, state_open).code);
|
||||
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, state_send_epoch_link).code);
|
||||
|
||||
ASSERT_FALSE (mdb_dbi_open (store.env.tx (transaction), "open", MDB_CREATE, &store.open_blocks_handle));
|
||||
ASSERT_FALSE (mdb_dbi_open (store.env.tx (transaction), "send", MDB_CREATE, &store.send_blocks_handle));
|
||||
ASSERT_FALSE (mdb_dbi_open (store.env.tx (transaction), "state_blocks", MDB_CREATE, &store.state_blocks_handle));
|
||||
|
||||
// Downgrade the store
|
||||
store.version.put (transaction, 17);
|
||||
|
||||
write_block_w_sideband_v18 (store, store.state_blocks_handle, transaction, state_receive);
|
||||
write_block_w_sideband_v18 (store, store.state_blocks_handle, transaction, epoch_first);
|
||||
write_block_w_sideband_v18 (store, store.state_blocks_handle, transaction, state_send2);
|
||||
write_block_w_sideband_v18 (store, store.state_blocks_handle, transaction, state_send_epoch_link);
|
||||
write_block_w_sideband_v18 (store, store.open_blocks_handle, transaction, *nano::dev::genesis);
|
||||
write_block_w_sideband_v18 (store, store.send_blocks_handle, transaction, send_zero);
|
||||
|
||||
// Replace with the previous sideband version for state blocks
|
||||
// The upgrade can resume after upgrading some blocks, test this by only downgrading some of them
|
||||
write_sideband_v15 (store, transaction, state_receive_zero);
|
||||
write_sideband_v15 (store, transaction, epoch);
|
||||
write_sideband_v15 (store, transaction, state_send);
|
||||
write_sideband_v15 (store, transaction, state_change);
|
||||
write_sideband_v15 (store, transaction, state_send_change);
|
||||
write_sideband_v15 (store, transaction, state_receive2);
|
||||
write_sideband_v15 (store, transaction, state_open);
|
||||
|
||||
store.block.del (transaction, state_receive_zero.hash ());
|
||||
store.block.del (transaction, epoch.hash ());
|
||||
store.block.del (transaction, state_send.hash ());
|
||||
store.block.del (transaction, state_change.hash ());
|
||||
store.block.del (transaction, state_send_change.hash ());
|
||||
store.block.del (transaction, state_receive2.hash ());
|
||||
store.block.del (transaction, state_open.hash ());
|
||||
ASSERT_LT (18, store.version.get (transaction));
|
||||
}
|
||||
|
||||
// Now do the upgrade
|
||||
nano::logger_mt logger;
|
||||
nano::lmdb::store store (logger, path, nano::dev::constants);
|
||||
ASSERT_FALSE (store.init_error ());
|
||||
auto transaction (store.tx_begin_read ());
|
||||
|
||||
// Size of state block should equal that set in db (no change)
|
||||
nano::mdb_val value;
|
||||
ASSERT_FALSE (mdb_get (store.env.tx (transaction), store.blocks_handle, nano::mdb_val (state_send.hash ()), value));
|
||||
ASSERT_EQ (value.size (), sizeof (nano::block_type) + nano::state_block::size + nano::block_sideband::size (nano::block_type::state));
|
||||
|
||||
// Check that sidebands are correctly populated
|
||||
{
|
||||
// Non-state unaffected
|
||||
auto block = store.block.get (transaction, send_zero.hash ());
|
||||
ASSERT_NE (block, nullptr);
|
||||
// All defaults
|
||||
ASSERT_EQ (block->sideband ().details.epoch, nano::epoch::epoch_0);
|
||||
ASSERT_FALSE (block->sideband ().details.is_epoch);
|
||||
ASSERT_FALSE (block->sideband ().details.is_send);
|
||||
ASSERT_FALSE (block->sideband ().details.is_receive);
|
||||
}
|
||||
{
|
||||
// State receive from old zero send
|
||||
auto block = store.block.get (transaction, state_receive_zero.hash ());
|
||||
ASSERT_NE (block, nullptr);
|
||||
ASSERT_EQ (block->sideband ().details.epoch, nano::epoch::epoch_0);
|
||||
ASSERT_FALSE (block->sideband ().details.is_epoch);
|
||||
ASSERT_FALSE (block->sideband ().details.is_send);
|
||||
ASSERT_TRUE (block->sideband ().details.is_receive);
|
||||
}
|
||||
{
|
||||
// Epoch
|
||||
auto block = store.block.get (transaction, epoch.hash ());
|
||||
ASSERT_NE (block, nullptr);
|
||||
ASSERT_EQ (block->sideband ().details.epoch, nano::epoch::epoch_1);
|
||||
ASSERT_TRUE (block->sideband ().details.is_epoch);
|
||||
ASSERT_FALSE (block->sideband ().details.is_send);
|
||||
ASSERT_FALSE (block->sideband ().details.is_receive);
|
||||
}
|
||||
{
|
||||
// State send
|
||||
auto block = store.block.get (transaction, state_send.hash ());
|
||||
ASSERT_NE (block, nullptr);
|
||||
ASSERT_EQ (block->sideband ().details.epoch, nano::epoch::epoch_1);
|
||||
ASSERT_FALSE (block->sideband ().details.is_epoch);
|
||||
ASSERT_TRUE (block->sideband ().details.is_send);
|
||||
ASSERT_FALSE (block->sideband ().details.is_receive);
|
||||
}
|
||||
{
|
||||
// State receive
|
||||
auto block = store.block.get (transaction, state_receive.hash ());
|
||||
ASSERT_NE (block, nullptr);
|
||||
ASSERT_EQ (block->sideband ().details.epoch, nano::epoch::epoch_1);
|
||||
ASSERT_FALSE (block->sideband ().details.is_epoch);
|
||||
ASSERT_FALSE (block->sideband ().details.is_send);
|
||||
ASSERT_TRUE (block->sideband ().details.is_receive);
|
||||
}
|
||||
{
|
||||
// State change
|
||||
auto block = store.block.get (transaction, state_change.hash ());
|
||||
ASSERT_NE (block, nullptr);
|
||||
ASSERT_EQ (block->sideband ().details.epoch, nano::epoch::epoch_1);
|
||||
ASSERT_FALSE (block->sideband ().details.is_epoch);
|
||||
ASSERT_FALSE (block->sideband ().details.is_send);
|
||||
ASSERT_FALSE (block->sideband ().details.is_receive);
|
||||
}
|
||||
{
|
||||
// State send + change
|
||||
auto block = store.block.get (transaction, state_send_change.hash ());
|
||||
ASSERT_NE (block, nullptr);
|
||||
ASSERT_EQ (block->sideband ().details.epoch, nano::epoch::epoch_1);
|
||||
ASSERT_FALSE (block->sideband ().details.is_epoch);
|
||||
ASSERT_TRUE (block->sideband ().details.is_send);
|
||||
ASSERT_FALSE (block->sideband ().details.is_receive);
|
||||
}
|
||||
{
|
||||
// Epoch on unopened account
|
||||
auto block = store.block.get (transaction, epoch_first.hash ());
|
||||
ASSERT_NE (block, nullptr);
|
||||
ASSERT_EQ (block->sideband ().details.epoch, nano::epoch::epoch_2);
|
||||
ASSERT_TRUE (block->sideband ().details.is_epoch);
|
||||
ASSERT_FALSE (block->sideband ().details.is_send);
|
||||
ASSERT_FALSE (block->sideband ().details.is_receive);
|
||||
}
|
||||
{
|
||||
// State open following epoch
|
||||
auto block = store.block.get (transaction, state_receive2.hash ());
|
||||
ASSERT_NE (block, nullptr);
|
||||
ASSERT_EQ (block->sideband ().details.epoch, nano::epoch::epoch_2);
|
||||
ASSERT_FALSE (block->sideband ().details.is_epoch);
|
||||
ASSERT_FALSE (block->sideband ().details.is_send);
|
||||
ASSERT_TRUE (block->sideband ().details.is_receive);
|
||||
}
|
||||
{
|
||||
// Another state send
|
||||
auto block = store.block.get (transaction, state_send2.hash ());
|
||||
ASSERT_NE (block, nullptr);
|
||||
ASSERT_EQ (block->sideband ().details.epoch, nano::epoch::epoch_1);
|
||||
ASSERT_FALSE (block->sideband ().details.is_epoch);
|
||||
ASSERT_TRUE (block->sideband ().details.is_send);
|
||||
ASSERT_FALSE (block->sideband ().details.is_receive);
|
||||
}
|
||||
{
|
||||
// State open
|
||||
auto block = store.block.get (transaction, state_open.hash ());
|
||||
ASSERT_NE (block, nullptr);
|
||||
ASSERT_EQ (block->sideband ().details.epoch, nano::epoch::epoch_1);
|
||||
ASSERT_FALSE (block->sideband ().details.is_epoch);
|
||||
ASSERT_FALSE (block->sideband ().details.is_send);
|
||||
ASSERT_TRUE (block->sideband ().details.is_receive);
|
||||
}
|
||||
{
|
||||
// State send to an epoch link
|
||||
auto block = store.block.get (transaction, state_send_epoch_link.hash ());
|
||||
ASSERT_NE (block, nullptr);
|
||||
ASSERT_EQ (block->sideband ().details.epoch, nano::epoch::epoch_1);
|
||||
ASSERT_FALSE (block->sideband ().details.is_epoch);
|
||||
ASSERT_TRUE (block->sideband ().details.is_send);
|
||||
ASSERT_FALSE (block->sideband ().details.is_receive);
|
||||
}
|
||||
// Version should be correct
|
||||
ASSERT_LT (17, store.version.get (transaction));
|
||||
}
|
||||
|
||||
TEST (mdb_block_store, upgrade_v18_v19)
|
||||
{
|
||||
if (nano::rocksdb_config::using_rocksdb_in_tests ())
|
||||
{
|
||||
// Don't test this in rocksdb mode
|
||||
return;
|
||||
}
|
||||
auto path (nano::unique_path ());
|
||||
nano::keypair key1;
|
||||
nano::work_pool pool{ nano::dev::network_params.network, std::numeric_limits<unsigned>::max () };
|
||||
nano::send_block send (nano::dev::genesis->hash (), nano::dev::genesis_key.pub, nano::dev::constants.genesis_amount - nano::Gxrb_ratio, nano::dev::genesis_key.prv, nano::dev::genesis_key.pub, *pool.generate (nano::dev::genesis->hash ()));
|
||||
nano::receive_block receive (send.hash (), send.hash (), nano::dev::genesis_key.prv, nano::dev::genesis_key.pub, *pool.generate (send.hash ()));
|
||||
nano::change_block change (receive.hash (), 0, nano::dev::genesis_key.prv, nano::dev::genesis_key.pub, *pool.generate (receive.hash ()));
|
||||
nano::state_block state_epoch (nano::dev::genesis_key.pub, change.hash (), 0, nano::dev::constants.genesis_amount, nano::dev::network_params.ledger.epochs.link (nano::epoch::epoch_1), nano::dev::genesis_key.prv, nano::dev::genesis_key.pub, *pool.generate (change.hash ()));
|
||||
nano::state_block state_send (nano::dev::genesis_key.pub, state_epoch.hash (), 0, nano::dev::constants.genesis_amount - nano::Gxrb_ratio, key1.pub, nano::dev::genesis_key.prv, nano::dev::genesis_key.pub, *pool.generate (state_epoch.hash ()));
|
||||
nano::state_block state_open (key1.pub, 0, 0, nano::Gxrb_ratio, state_send.hash (), key1.prv, key1.pub, *pool.generate (key1.pub));
|
||||
|
||||
{
|
||||
nano::logger_mt logger;
|
||||
nano::lmdb::store store (logger, path, nano::dev::constants);
|
||||
nano::stat stats;
|
||||
nano::ledger ledger (store, stats, nano::dev::constants);
|
||||
auto transaction (store.tx_begin_write ());
|
||||
store.initialize (transaction, ledger.cache, nano::dev::constants);
|
||||
|
||||
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, send).code);
|
||||
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, receive).code);
|
||||
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, change).code);
|
||||
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, state_epoch).code);
|
||||
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, state_send).code);
|
||||
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, state_open).code);
|
||||
|
||||
// These tables need to be re-opened and populated so that an upgrade can be done
|
||||
auto txn = store.env.tx (transaction);
|
||||
ASSERT_FALSE (mdb_dbi_open (txn, "open", MDB_CREATE, &store.open_blocks_handle));
|
||||
ASSERT_FALSE (mdb_dbi_open (txn, "receive", MDB_CREATE, &store.receive_blocks_handle));
|
||||
ASSERT_FALSE (mdb_dbi_open (txn, "send", MDB_CREATE, &store.send_blocks_handle));
|
||||
ASSERT_FALSE (mdb_dbi_open (txn, "change", MDB_CREATE, &store.change_blocks_handle));
|
||||
ASSERT_FALSE (mdb_dbi_open (txn, "state_blocks", MDB_CREATE, &store.state_blocks_handle));
|
||||
|
||||
// Modify blocks back to the old tables
|
||||
write_block_w_sideband_v18 (store, store.open_blocks_handle, transaction, *nano::dev::genesis);
|
||||
write_block_w_sideband_v18 (store, store.send_blocks_handle, transaction, send);
|
||||
write_block_w_sideband_v18 (store, store.receive_blocks_handle, transaction, receive);
|
||||
write_block_w_sideband_v18 (store, store.change_blocks_handle, transaction, change);
|
||||
write_block_w_sideband_v18 (store, store.state_blocks_handle, transaction, state_epoch);
|
||||
write_block_w_sideband_v18 (store, store.state_blocks_handle, transaction, state_send);
|
||||
write_block_w_sideband_v18 (store, store.state_blocks_handle, transaction, state_open);
|
||||
|
||||
store.version.put (transaction, 18);
|
||||
}
|
||||
|
||||
// Now do the upgrade
|
||||
nano::logger_mt logger;
|
||||
nano::lmdb::store store (logger, path, nano::dev::constants);
|
||||
ASSERT_FALSE (store.init_error ());
|
||||
auto transaction (store.tx_begin_read ());
|
||||
|
||||
// These tables should be deleted
|
||||
ASSERT_EQ (store.send_blocks_handle, 0);
|
||||
ASSERT_EQ (store.receive_blocks_handle, 0);
|
||||
ASSERT_EQ (store.change_blocks_handle, 0);
|
||||
ASSERT_EQ (store.open_blocks_handle, 0);
|
||||
ASSERT_EQ (store.state_blocks_handle, 0);
|
||||
|
||||
// Confirm these blocks all exist after the upgrade
|
||||
ASSERT_TRUE (store.block.get (transaction, send.hash ()));
|
||||
ASSERT_TRUE (store.block.get (transaction, receive.hash ()));
|
||||
ASSERT_TRUE (store.block.get (transaction, change.hash ()));
|
||||
ASSERT_TRUE (store.block.get (transaction, nano::dev::genesis->hash ()));
|
||||
auto state_epoch_disk (store.block.get (transaction, state_epoch.hash ()));
|
||||
ASSERT_NE (nullptr, state_epoch_disk);
|
||||
ASSERT_EQ (nano::epoch::epoch_1, state_epoch_disk->sideband ().details.epoch);
|
||||
ASSERT_EQ (nano::epoch::epoch_0, state_epoch_disk->sideband ().source_epoch); // Not used for epoch state blocks
|
||||
ASSERT_TRUE (store.block.get (transaction, state_send.hash ()));
|
||||
auto state_send_disk (store.block.get (transaction, state_send.hash ()));
|
||||
ASSERT_NE (nullptr, state_send_disk);
|
||||
ASSERT_EQ (nano::epoch::epoch_1, state_send_disk->sideband ().details.epoch);
|
||||
ASSERT_EQ (nano::epoch::epoch_0, state_send_disk->sideband ().source_epoch); // Not used for send state blocks
|
||||
ASSERT_TRUE (store.block.get (transaction, state_open.hash ()));
|
||||
auto state_open_disk (store.block.get (transaction, state_open.hash ()));
|
||||
ASSERT_NE (nullptr, state_open_disk);
|
||||
ASSERT_EQ (nano::epoch::epoch_1, state_open_disk->sideband ().details.epoch);
|
||||
ASSERT_EQ (nano::epoch::epoch_1, state_open_disk->sideband ().source_epoch);
|
||||
|
||||
ASSERT_EQ (7, store.count (transaction, store.blocks_handle));
|
||||
|
||||
// Version should be correct
|
||||
ASSERT_LT (18, store.version.get (transaction));
|
||||
}
|
||||
|
||||
namespace nano
|
||||
{
|
||||
namespace lmdb
|
||||
{
|
||||
TEST (mdb_block_store, upgrade_v19_v20)
|
||||
{
|
||||
if (nano::rocksdb_config::using_rocksdb_in_tests ())
|
||||
|
@ -1872,13 +1866,7 @@ namespace lmdb
|
|||
auto transaction (store.tx_begin_read ());
|
||||
ASSERT_LT (19, store.version.get (transaction));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace nano
|
||||
{
|
||||
namespace lmdb
|
||||
{
|
||||
TEST (mdb_block_store, upgrade_v20_v21)
|
||||
{
|
||||
if (nano::rocksdb_config::using_rocksdb_in_tests ())
|
||||
|
@ -2151,7 +2139,7 @@ namespace lmdb
|
|||
}
|
||||
|
||||
MDB_val val{ data.size (), data.data () };
|
||||
ASSERT_FALSE (mdb_put (store_a.env.tx (transaction_a), block->sideband ().details.epoch == nano::epoch::epoch_0 ? store_a.state_blocks_v0_handle : store_a.state_blocks_v1_handle, nano::mdb_val (block_a.hash ()), &val, 0));
|
||||
ASSERT_FALSE (mdb_put (store_a.env.tx (transaction_a), block->sideband ().details.epoch == nano::epoch::epoch_0 ? store_a.block_store.state_blocks_v0_handle : store_a.block_store.state_blocks_v1_handle, nano::mdb_val (block_a.hash ()), &val, 0));
|
||||
}
|
||||
|
||||
void write_sideband_v15 (nano::lmdb::store & store_a, nano::transaction & transaction_a, nano::block const & block_a)
|
||||
|
@ -2170,7 +2158,7 @@ namespace lmdb
|
|||
}
|
||||
|
||||
MDB_val val{ data.size (), data.data () };
|
||||
ASSERT_FALSE (mdb_put (store_a.env.tx (transaction_a), store_a.state_blocks_handle, nano::mdb_val (block_a.hash ()), &val, 0));
|
||||
ASSERT_FALSE (mdb_put (store_a.env.tx (transaction_a), store_a.block_store.state_blocks_handle, nano::mdb_val (block_a.hash ()), &val, 0));
|
||||
}
|
||||
|
||||
void write_block_w_sideband_v18 (nano::lmdb::store & store_a, MDB_dbi database, nano::write_transaction & transaction_a, nano::block const & block_a)
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
#include <nano/secure/store.hpp>
|
||||
|
||||
#include <lmdb/libraries/liblmdb/lmdb.h>
|
||||
|
||||
namespace nano
|
||||
{
|
||||
using mdb_val = db_val<MDB_val>;
|
||||
|
@ -38,6 +40,60 @@ namespace lmdb
|
|||
// Converts a block hash to a block height
|
||||
uint64_t account_height (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const override;
|
||||
|
||||
/**
|
||||
* Maps block hash to send block. (Removed)
|
||||
* nano::block_hash -> nano::send_block
|
||||
*/
|
||||
MDB_dbi send_blocks_handle{ 0 };
|
||||
|
||||
/**
|
||||
* Maps block hash to receive block. (Removed)
|
||||
* nano::block_hash -> nano::receive_block
|
||||
*/
|
||||
MDB_dbi receive_blocks_handle{ 0 };
|
||||
|
||||
/**
|
||||
* Maps block hash to open block. (Removed)
|
||||
* nano::block_hash -> nano::open_block
|
||||
*/
|
||||
MDB_dbi open_blocks_handle{ 0 };
|
||||
|
||||
/**
|
||||
* Maps block hash to change block. (Removed)
|
||||
* nano::block_hash -> nano::change_block
|
||||
*/
|
||||
MDB_dbi change_blocks_handle{ 0 };
|
||||
|
||||
/**
|
||||
* Maps block hash to v0 state block. (Removed)
|
||||
* nano::block_hash -> nano::state_block
|
||||
*/
|
||||
MDB_dbi state_blocks_v0_handle{ 0 };
|
||||
|
||||
/**
|
||||
* Maps block hash to v1 state block. (Removed)
|
||||
* nano::block_hash -> nano::state_block
|
||||
*/
|
||||
MDB_dbi state_blocks_v1_handle{ 0 };
|
||||
|
||||
/**
|
||||
* Maps block hash to state block. (Removed)
|
||||
* nano::block_hash -> nano::state_block
|
||||
*/
|
||||
MDB_dbi state_blocks_handle{ 0 };
|
||||
|
||||
/**
|
||||
* Meta information about block store, such as versions.
|
||||
* nano::uint256_union (arbitrary key) -> blob
|
||||
*/
|
||||
MDB_dbi meta_handle{ 0 };
|
||||
|
||||
/**
|
||||
* Contains block_sideband and block for all block types (legacy send/change/open/receive & state blocks)
|
||||
* nano::block_hash -> nano::block_sideband, nano::block
|
||||
*/
|
||||
MDB_dbi blocks_handle{ 0 };
|
||||
|
||||
protected:
|
||||
void block_raw_get (nano::transaction const & transaction_a, nano::block_hash const & hash_a, nano::mdb_val & value) const;
|
||||
size_t block_successor_offset (nano::transaction const & transaction_a, size_t entry_size_a, nano::block_type type_a) const;
|
||||
|
|
|
@ -78,12 +78,12 @@ nano::lmdb::store::store (nano::logger_mt & logger_a, boost::filesystem::path co
|
|||
auto is_fresh_db (false);
|
||||
{
|
||||
auto transaction (tx_begin_read ());
|
||||
auto err = mdb_dbi_open (env.tx (transaction), "meta", 0, &meta_handle);
|
||||
auto err = mdb_dbi_open (env.tx (transaction), "meta", 0, &block_store.meta_handle);
|
||||
is_fresh_db = err != MDB_SUCCESS;
|
||||
if (err == MDB_SUCCESS)
|
||||
{
|
||||
is_fully_upgraded = (version.get (transaction) == version_current);
|
||||
mdb_dbi_close (env, meta_handle);
|
||||
mdb_dbi_close (env, block_store.meta_handle);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -213,7 +213,7 @@ void nano::lmdb::store::open_databases (bool & error_a, nano::transaction const
|
|||
error_a |= mdb_dbi_open (env.tx (transaction_a), "frontiers", flags, &frontier_store.frontiers_handle) != 0;
|
||||
error_a |= mdb_dbi_open (env.tx (transaction_a), "unchecked", flags, &unchecked_store.unchecked_handle) != 0;
|
||||
error_a |= mdb_dbi_open (env.tx (transaction_a), "online_weight", flags, &online_weight_store.online_weight_handle) != 0;
|
||||
error_a |= mdb_dbi_open (env.tx (transaction_a), "meta", flags, &meta_handle) != 0;
|
||||
error_a |= mdb_dbi_open (env.tx (transaction_a), "meta", flags, &block_store.meta_handle) != 0;
|
||||
error_a |= mdb_dbi_open (env.tx (transaction_a), "peers", flags, &peer_store.peers_handle) != 0;
|
||||
error_a |= mdb_dbi_open (env.tx (transaction_a), "pruned", flags, &pruned_store.pruned_handle) != 0;
|
||||
error_a |= mdb_dbi_open (env.tx (transaction_a), "confirmation_height", flags, &confirmation_height_store.confirmation_height_handle) != 0;
|
||||
|
@ -227,19 +227,19 @@ void nano::lmdb::store::open_databases (bool & error_a, nano::transaction const
|
|||
if (version_l < 19)
|
||||
{
|
||||
// These legacy (and state) block databases are no longer used, but need opening so they can be deleted during an upgrade
|
||||
error_a |= mdb_dbi_open (env.tx (transaction_a), "send", flags, &send_blocks_handle) != 0;
|
||||
error_a |= mdb_dbi_open (env.tx (transaction_a), "receive", flags, &receive_blocks_handle) != 0;
|
||||
error_a |= mdb_dbi_open (env.tx (transaction_a), "open", flags, &open_blocks_handle) != 0;
|
||||
error_a |= mdb_dbi_open (env.tx (transaction_a), "change", flags, &change_blocks_handle) != 0;
|
||||
error_a |= mdb_dbi_open (env.tx (transaction_a), "send", flags, &block_store.send_blocks_handle) != 0;
|
||||
error_a |= mdb_dbi_open (env.tx (transaction_a), "receive", flags, &block_store.receive_blocks_handle) != 0;
|
||||
error_a |= mdb_dbi_open (env.tx (transaction_a), "open", flags, &block_store.open_blocks_handle) != 0;
|
||||
error_a |= mdb_dbi_open (env.tx (transaction_a), "change", flags, &block_store.change_blocks_handle) != 0;
|
||||
if (version_l >= 15)
|
||||
{
|
||||
error_a |= mdb_dbi_open (env.tx (transaction_a), "state_blocks", flags, &state_blocks_handle) != 0;
|
||||
state_blocks_v0_handle = state_blocks_handle;
|
||||
error_a |= mdb_dbi_open (env.tx (transaction_a), "state_blocks", flags, &block_store.state_blocks_handle) != 0;
|
||||
block_store.state_blocks_v0_handle = block_store.state_blocks_handle;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
error_a |= mdb_dbi_open (env.tx (transaction_a), "blocks", MDB_CREATE, &blocks_handle) != 0;
|
||||
error_a |= mdb_dbi_open (env.tx (transaction_a), "blocks", MDB_CREATE, &block_store.blocks_handle) != 0;
|
||||
}
|
||||
|
||||
if (version_l < 16)
|
||||
|
@ -251,11 +251,11 @@ void nano::lmdb::store::open_databases (bool & error_a, nano::transaction const
|
|||
if (version_l < 15)
|
||||
{
|
||||
// These databases are no longer used, but need opening so they can be deleted during an upgrade
|
||||
error_a |= mdb_dbi_open (env.tx (transaction_a), "state", flags, &state_blocks_v0_handle) != 0;
|
||||
state_blocks_handle = state_blocks_v0_handle;
|
||||
error_a |= mdb_dbi_open (env.tx (transaction_a), "state", flags, &block_store.state_blocks_v0_handle) != 0;
|
||||
block_store.state_blocks_handle = block_store.state_blocks_v0_handle;
|
||||
error_a |= mdb_dbi_open (env.tx (transaction_a), "accounts_v1", flags, &account_store.accounts_v1_handle) != 0;
|
||||
error_a |= mdb_dbi_open (env.tx (transaction_a), "pending_v1", flags, &pending_store.pending_v1_handle) != 0;
|
||||
error_a |= mdb_dbi_open (env.tx (transaction_a), "state_v1", flags, &state_blocks_v1_handle) != 0;
|
||||
error_a |= mdb_dbi_open (env.tx (transaction_a), "state_v1", flags, &block_store.state_blocks_v1_handle) != 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -360,9 +360,9 @@ void nano::lmdb::store::upgrade_v14_to_v15 (nano::write_transaction & transactio
|
|||
MDB_dbi state_blocks_new;
|
||||
mdb_dbi_open (env.tx (transaction_a), "state_blocks", MDB_CREATE, &state_blocks_new);
|
||||
|
||||
upgrade_counters state_counters (count (transaction_a, state_blocks_v0_handle), count (transaction_a, state_blocks_v1_handle));
|
||||
upgrade_counters state_counters (count (transaction_a, block_store.state_blocks_v0_handle), count (transaction_a, block_store.state_blocks_v1_handle));
|
||||
|
||||
nano::mdb_merge_iterator<nano::block_hash, nano::state_block_w_sideband_v14> i_state (transaction_a, state_blocks_v0_handle, state_blocks_v1_handle);
|
||||
nano::mdb_merge_iterator<nano::block_hash, nano::state_block_w_sideband_v14> i_state (transaction_a, block_store.state_blocks_v0_handle, block_store.state_blocks_v1_handle);
|
||||
nano::mdb_merge_iterator<nano::block_hash, nano::state_block_w_sideband_v14> n_state{};
|
||||
auto num = 0u;
|
||||
for (; i_state != n_state; ++i_state, ++num)
|
||||
|
@ -397,13 +397,13 @@ void nano::lmdb::store::upgrade_v14_to_v15 (nano::write_transaction & transactio
|
|||
debug_assert (state_counters.are_equal ());
|
||||
logger.always_log ("Epoch merge upgrade: Finished state blocks, now doing pending blocks");
|
||||
|
||||
state_blocks_handle = state_blocks_new;
|
||||
block_store.state_blocks_handle = state_blocks_new;
|
||||
|
||||
// No longer need states v0/v1 databases
|
||||
mdb_drop (env.tx (transaction_a), state_blocks_v1_handle, 1);
|
||||
mdb_drop (env.tx (transaction_a), state_blocks_v0_handle, 1);
|
||||
mdb_drop (env.tx (transaction_a), block_store.state_blocks_v1_handle, 1);
|
||||
mdb_drop (env.tx (transaction_a), block_store.state_blocks_v0_handle, 1);
|
||||
|
||||
state_blocks_v0_handle = state_blocks_handle;
|
||||
block_store.state_blocks_v0_handle = block_store.state_blocks_handle;
|
||||
|
||||
upgrade_counters pending_counters (count (transaction_a, pending_store.pending_v0_handle), count (transaction_a, pending_store.pending_v1_handle));
|
||||
std::vector<std::pair<nano::pending_key, nano::pending_info>> pending_infos;
|
||||
|
@ -529,10 +529,10 @@ void nano::lmdb::store::upgrade_v17_to_v18 (nano::write_transaction const & tran
|
|||
{
|
||||
logger.always_log ("Preparing v17 to v18 database upgrade...");
|
||||
|
||||
auto count_pre (count (transaction_a, state_blocks_handle));
|
||||
auto count_pre (count (transaction_a, block_store.state_blocks_handle));
|
||||
|
||||
auto num = 0u;
|
||||
for (nano::mdb_iterator<nano::block_hash, nano::block_w_sideband_v18<nano::state_block>> state_i (transaction_a, state_blocks_handle), state_n{}; state_i != state_n; ++state_i, ++num)
|
||||
for (nano::mdb_iterator<nano::block_hash, nano::block_w_sideband_v18<nano::state_block>> state_i (transaction_a, block_store.state_blocks_handle), state_n{}; state_i != state_n; ++state_i, ++num)
|
||||
{
|
||||
nano::block_w_sideband_v18<nano::state_block> block_w_sideband (state_i->second);
|
||||
auto & block (block_w_sideband.block);
|
||||
|
@ -580,7 +580,7 @@ void nano::lmdb::store::upgrade_v17_to_v18 (nano::write_transaction const & tran
|
|||
}
|
||||
}
|
||||
|
||||
auto count_post (count (transaction_a, state_blocks_handle));
|
||||
auto count_post (count (transaction_a, block_store.state_blocks_handle));
|
||||
release_assert (count_pre == count_post);
|
||||
|
||||
version.put (transaction_a, 18);
|
||||
|
@ -590,38 +590,38 @@ void nano::lmdb::store::upgrade_v17_to_v18 (nano::write_transaction const & tran
|
|||
void nano::lmdb::store::upgrade_v18_to_v19 (nano::write_transaction const & transaction_a)
|
||||
{
|
||||
logger.always_log ("Preparing v18 to v19 database upgrade...");
|
||||
auto count_pre (count (transaction_a, state_blocks_handle) + count (transaction_a, send_blocks_handle) + count (transaction_a, receive_blocks_handle) + count (transaction_a, change_blocks_handle) + count (transaction_a, open_blocks_handle));
|
||||
auto count_pre (count (transaction_a, block_store.state_blocks_handle) + count (transaction_a, block_store.send_blocks_handle) + count (transaction_a, block_store.receive_blocks_handle) + count (transaction_a, block_store.change_blocks_handle) + count (transaction_a, block_store.open_blocks_handle));
|
||||
|
||||
// Combine in order of likeliness of counts
|
||||
std::map<nano::block_hash, nano::block_w_sideband> legacy_open_receive_change_blocks;
|
||||
|
||||
for (auto i (nano::store_iterator<nano::block_hash, nano::block_w_sideband_v18<nano::change_block>> (std::make_unique<nano::mdb_iterator<nano::block_hash, nano::block_w_sideband_v18<nano::change_block>>> (transaction_a, change_blocks_handle))), n (nano::store_iterator<nano::block_hash, nano::block_w_sideband_v18<nano::change_block>> (nullptr)); i != n; ++i)
|
||||
for (auto i (nano::store_iterator<nano::block_hash, nano::block_w_sideband_v18<nano::change_block>> (std::make_unique<nano::mdb_iterator<nano::block_hash, nano::block_w_sideband_v18<nano::change_block>>> (transaction_a, block_store.change_blocks_handle))), n (nano::store_iterator<nano::block_hash, nano::block_w_sideband_v18<nano::change_block>> (nullptr)); i != n; ++i)
|
||||
{
|
||||
nano::block_sideband_v18 const & old_sideband (i->second.sideband);
|
||||
nano::block_sideband new_sideband (old_sideband.account, old_sideband.successor, old_sideband.balance, old_sideband.height, old_sideband.timestamp, nano::epoch::epoch_0, false, false, false, nano::epoch::epoch_0);
|
||||
legacy_open_receive_change_blocks[i->first] = { nano::block_w_sideband{ i->second.block, new_sideband } };
|
||||
}
|
||||
|
||||
for (auto i (nano::store_iterator<nano::block_hash, nano::block_w_sideband_v18<nano::open_block>> (std::make_unique<nano::mdb_iterator<nano::block_hash, nano::block_w_sideband_v18<nano::open_block>>> (transaction_a, open_blocks_handle))), n (nano::store_iterator<nano::block_hash, nano::block_w_sideband_v18<nano::open_block>> (nullptr)); i != n; ++i)
|
||||
for (auto i (nano::store_iterator<nano::block_hash, nano::block_w_sideband_v18<nano::open_block>> (std::make_unique<nano::mdb_iterator<nano::block_hash, nano::block_w_sideband_v18<nano::open_block>>> (transaction_a, block_store.open_blocks_handle))), n (nano::store_iterator<nano::block_hash, nano::block_w_sideband_v18<nano::open_block>> (nullptr)); i != n; ++i)
|
||||
{
|
||||
nano::block_sideband_v18 const & old_sideband (i->second.sideband);
|
||||
nano::block_sideband new_sideband (old_sideband.account, old_sideband.successor, old_sideband.balance, old_sideband.height, old_sideband.timestamp, nano::epoch::epoch_0, false, false, false, nano::epoch::epoch_0);
|
||||
legacy_open_receive_change_blocks[i->first] = { nano::block_w_sideband{ i->second.block, new_sideband } };
|
||||
}
|
||||
|
||||
for (auto i (nano::store_iterator<nano::block_hash, nano::block_w_sideband_v18<nano::receive_block>> (std::make_unique<nano::mdb_iterator<nano::block_hash, nano::block_w_sideband_v18<nano::receive_block>>> (transaction_a, receive_blocks_handle))), n (nano::store_iterator<nano::block_hash, nano::block_w_sideband_v18<nano::receive_block>> (nullptr)); i != n; ++i)
|
||||
for (auto i (nano::store_iterator<nano::block_hash, nano::block_w_sideband_v18<nano::receive_block>> (std::make_unique<nano::mdb_iterator<nano::block_hash, nano::block_w_sideband_v18<nano::receive_block>>> (transaction_a, block_store.receive_blocks_handle))), n (nano::store_iterator<nano::block_hash, nano::block_w_sideband_v18<nano::receive_block>> (nullptr)); i != n; ++i)
|
||||
{
|
||||
nano::block_sideband_v18 const & old_sideband (i->second.sideband);
|
||||
nano::block_sideband new_sideband (old_sideband.account, old_sideband.successor, old_sideband.balance, old_sideband.height, old_sideband.timestamp, nano::epoch::epoch_0, false, false, false, nano::epoch::epoch_0);
|
||||
legacy_open_receive_change_blocks[i->first] = { nano::block_w_sideband{ i->second.block, new_sideband } };
|
||||
}
|
||||
|
||||
release_assert (!mdb_drop (env.tx (transaction_a), receive_blocks_handle, 1));
|
||||
receive_blocks_handle = 0;
|
||||
release_assert (!mdb_drop (env.tx (transaction_a), open_blocks_handle, 1));
|
||||
open_blocks_handle = 0;
|
||||
release_assert (!mdb_drop (env.tx (transaction_a), change_blocks_handle, 1));
|
||||
change_blocks_handle = 0;
|
||||
release_assert (!mdb_drop (env.tx (transaction_a), block_store.receive_blocks_handle, 1));
|
||||
block_store.receive_blocks_handle = 0;
|
||||
release_assert (!mdb_drop (env.tx (transaction_a), block_store.open_blocks_handle, 1));
|
||||
block_store.open_blocks_handle = 0;
|
||||
release_assert (!mdb_drop (env.tx (transaction_a), block_store.change_blocks_handle, 1));
|
||||
block_store.change_blocks_handle = 0;
|
||||
|
||||
logger.always_log ("Write legacy open/receive/change to new format");
|
||||
|
||||
|
@ -651,7 +651,7 @@ void nano::lmdb::store::upgrade_v18_to_v19 (nano::write_transaction const & tran
|
|||
{
|
||||
mdb_dbi_open (env.tx (transaction_a), "temp_legacy_send_blocks", MDB_CREATE, &temp_legacy_send_blocks);
|
||||
|
||||
for (auto i (nano::store_iterator<nano::block_hash, nano::block_w_sideband_v18<nano::send_block>> (std::make_unique<nano::mdb_iterator<nano::block_hash, nano::block_w_sideband_v18<nano::send_block>>> (transaction_a, send_blocks_handle))), n (nano::store_iterator<nano::block_hash, nano::block_w_sideband_v18<nano::send_block>> (nullptr)); i != n; ++i)
|
||||
for (auto i (nano::store_iterator<nano::block_hash, nano::block_w_sideband_v18<nano::send_block>> (std::make_unique<nano::mdb_iterator<nano::block_hash, nano::block_w_sideband_v18<nano::send_block>>> (transaction_a, block_store.send_blocks_handle))), n (nano::store_iterator<nano::block_hash, nano::block_w_sideband_v18<nano::send_block>> (nullptr)); i != n; ++i)
|
||||
{
|
||||
auto const & block_w_sideband_v18 (i->second);
|
||||
|
||||
|
@ -668,8 +668,8 @@ void nano::lmdb::store::upgrade_v18_to_v19 (nano::write_transaction const & tran
|
|||
}
|
||||
}
|
||||
|
||||
release_assert (!mdb_drop (env.tx (transaction_a), send_blocks_handle, 1));
|
||||
send_blocks_handle = 0;
|
||||
release_assert (!mdb_drop (env.tx (transaction_a), block_store.send_blocks_handle, 1));
|
||||
block_store.send_blocks_handle = 0;
|
||||
|
||||
logger.always_log ("Merge legacy open/receive/change with legacy send blocks");
|
||||
|
||||
|
@ -698,7 +698,7 @@ void nano::lmdb::store::upgrade_v18_to_v19 (nano::write_transaction const & tran
|
|||
auto type_state (nano::block_type::state);
|
||||
mdb_dbi_open (env.tx (transaction_a), "temp_state_blocks", MDB_CREATE, &temp_state_blocks);
|
||||
|
||||
for (auto i (nano::store_iterator<nano::block_hash, nano::block_w_sideband_v18<nano::state_block>> (std::make_unique<nano::mdb_iterator<nano::block_hash, nano::block_w_sideband_v18<nano::state_block>>> (transaction_a, state_blocks_handle))), n (nano::store_iterator<nano::block_hash, nano::block_w_sideband_v18<nano::state_block>> (nullptr)); i != n; ++i)
|
||||
for (auto i (nano::store_iterator<nano::block_hash, nano::block_w_sideband_v18<nano::state_block>> (std::make_unique<nano::mdb_iterator<nano::block_hash, nano::block_w_sideband_v18<nano::state_block>>> (transaction_a, block_store.state_blocks_handle))), n (nano::store_iterator<nano::block_hash, nano::block_w_sideband_v18<nano::state_block>> (nullptr)); i != n; ++i)
|
||||
{
|
||||
auto const & block_w_sideband_v18 (i->second);
|
||||
nano::block_sideband_v18 const & old_sideband (block_w_sideband_v18.sideband);
|
||||
|
@ -733,18 +733,18 @@ void nano::lmdb::store::upgrade_v18_to_v19 (nano::write_transaction const & tran
|
|||
}
|
||||
}
|
||||
|
||||
release_assert (!mdb_drop (env.tx (transaction_a), state_blocks_handle, 1));
|
||||
state_blocks_handle = 0;
|
||||
release_assert (!mdb_drop (env.tx (transaction_a), block_store.state_blocks_handle, 1));
|
||||
block_store.state_blocks_handle = 0;
|
||||
|
||||
logger.always_log ("Merging all legacy blocks with state blocks");
|
||||
|
||||
// Merge all legacy blocks with state blocks into the final table
|
||||
nano::mdb_merge_iterator<nano::block_hash, nano::block_w_sideband> i (transaction_a, temp_legacy_send_open_receive_change_blocks, temp_state_blocks);
|
||||
nano::mdb_merge_iterator<nano::block_hash, nano::block_w_sideband> n{};
|
||||
mdb_dbi_open (env.tx (transaction_a), "blocks", MDB_CREATE, &blocks_handle);
|
||||
mdb_dbi_open (env.tx (transaction_a), "blocks", MDB_CREATE, &block_store.blocks_handle);
|
||||
for (; i != n; ++i)
|
||||
{
|
||||
auto s = mdb_put (env.tx (transaction_a), blocks_handle, nano::mdb_val (i->first), nano::mdb_val (i->second), MDB_APPEND);
|
||||
auto s = mdb_put (env.tx (transaction_a), block_store.blocks_handle, nano::mdb_val (i->first), nano::mdb_val (i->second), MDB_APPEND);
|
||||
release_assert_success (s);
|
||||
}
|
||||
|
||||
|
@ -752,7 +752,7 @@ void nano::lmdb::store::upgrade_v18_to_v19 (nano::write_transaction const & tran
|
|||
mdb_drop (env.tx (transaction_a), temp_legacy_send_open_receive_change_blocks, 1);
|
||||
mdb_drop (env.tx (transaction_a), temp_state_blocks, 1);
|
||||
|
||||
auto count_post (count (transaction_a, blocks_handle));
|
||||
auto count_post (count (transaction_a, block_store.blocks_handle));
|
||||
release_assert (count_pre == count_post);
|
||||
|
||||
MDB_dbi vote{ 0 };
|
||||
|
@ -865,7 +865,7 @@ MDB_dbi nano::lmdb::store::table_to_dbi (tables table_a) const
|
|||
case tables::accounts:
|
||||
return account_store.accounts_handle;
|
||||
case tables::blocks:
|
||||
return blocks_handle;
|
||||
return block_store.blocks_handle;
|
||||
case tables::pending:
|
||||
return pending_store.pending_handle;
|
||||
case tables::unchecked:
|
||||
|
@ -873,7 +873,7 @@ MDB_dbi nano::lmdb::store::table_to_dbi (tables table_a) const
|
|||
case tables::online_weight:
|
||||
return online_weight_store.online_weight_handle;
|
||||
case tables::meta:
|
||||
return meta_handle;
|
||||
return block_store.meta_handle;
|
||||
case tables::peers:
|
||||
return peer_store.peers_handle;
|
||||
case tables::pruned:
|
||||
|
@ -916,7 +916,7 @@ bool nano::lmdb::store::copy_db (boost::filesystem::path const & destination_fil
|
|||
void nano::lmdb::store::rebuild_db (nano::write_transaction const & transaction_a)
|
||||
{
|
||||
// Tables with uint256_union key
|
||||
std::vector<MDB_dbi> tables = { account_store.accounts_handle, blocks_handle, pruned_store.pruned_handle, confirmation_height_store.confirmation_height_handle };
|
||||
std::vector<MDB_dbi> tables = { account_store.accounts_handle, block_store.blocks_handle, pruned_store.pruned_handle, confirmation_height_store.confirmation_height_handle };
|
||||
for (auto const & table : tables)
|
||||
{
|
||||
MDB_dbi temp;
|
||||
|
@ -1014,27 +1014,27 @@ boost::optional<nano::mdb_val> nano::lmdb::store::block_raw_get_by_type_v18 (nan
|
|||
{
|
||||
case nano::block_type::send:
|
||||
{
|
||||
status = mdb_get (env.tx (transaction_a), send_blocks_handle, hash, value);
|
||||
status = mdb_get (env.tx (transaction_a), block_store.send_blocks_handle, hash, value);
|
||||
break;
|
||||
}
|
||||
case nano::block_type::receive:
|
||||
{
|
||||
status = mdb_get (env.tx (transaction_a), receive_blocks_handle, hash, value);
|
||||
status = mdb_get (env.tx (transaction_a), block_store.receive_blocks_handle, hash, value);
|
||||
break;
|
||||
}
|
||||
case nano::block_type::open:
|
||||
{
|
||||
status = mdb_get (env.tx (transaction_a), open_blocks_handle, hash, value);
|
||||
status = mdb_get (env.tx (transaction_a), block_store.open_blocks_handle, hash, value);
|
||||
break;
|
||||
}
|
||||
case nano::block_type::change:
|
||||
{
|
||||
status = mdb_get (env.tx (transaction_a), change_blocks_handle, hash, value);
|
||||
status = mdb_get (env.tx (transaction_a), block_store.change_blocks_handle, hash, value);
|
||||
break;
|
||||
}
|
||||
case nano::block_type::state:
|
||||
{
|
||||
status = mdb_get (env.tx (transaction_a), state_blocks_handle, hash, value);
|
||||
status = mdb_get (env.tx (transaction_a), block_store.state_blocks_handle, hash, value);
|
||||
break;
|
||||
}
|
||||
case nano::block_type::invalid:
|
||||
|
@ -1115,34 +1115,34 @@ boost::optional<nano::mdb_val> nano::lmdb::store::block_raw_get_by_type_v14 (nan
|
|||
{
|
||||
case nano::block_type::send:
|
||||
{
|
||||
status = mdb_get (env.tx (transaction_a), send_blocks_handle, hash, value);
|
||||
status = mdb_get (env.tx (transaction_a), block_store.send_blocks_handle, hash, value);
|
||||
break;
|
||||
}
|
||||
case nano::block_type::receive:
|
||||
{
|
||||
status = mdb_get (env.tx (transaction_a), receive_blocks_handle, hash, value);
|
||||
status = mdb_get (env.tx (transaction_a), block_store.receive_blocks_handle, hash, value);
|
||||
break;
|
||||
}
|
||||
case nano::block_type::open:
|
||||
{
|
||||
status = mdb_get (env.tx (transaction_a), open_blocks_handle, hash, value);
|
||||
status = mdb_get (env.tx (transaction_a), block_store.open_blocks_handle, hash, value);
|
||||
break;
|
||||
}
|
||||
case nano::block_type::change:
|
||||
{
|
||||
status = mdb_get (env.tx (transaction_a), change_blocks_handle, hash, value);
|
||||
status = mdb_get (env.tx (transaction_a), block_store.change_blocks_handle, hash, value);
|
||||
break;
|
||||
}
|
||||
case nano::block_type::state:
|
||||
{
|
||||
status = mdb_get (env.tx (transaction_a), state_blocks_v1_handle, hash, value);
|
||||
status = mdb_get (env.tx (transaction_a), block_store.state_blocks_v1_handle, hash, value);
|
||||
if (is_state_v1 != nullptr)
|
||||
{
|
||||
*is_state_v1 = success (status);
|
||||
}
|
||||
if (not_found (status))
|
||||
{
|
||||
status = mdb_get (env.tx (transaction_a), state_blocks_v0_handle, hash, value);
|
||||
status = mdb_get (env.tx (transaction_a), block_store.state_blocks_v0_handle, hash, value);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -94,60 +94,6 @@ namespace lmdb
|
|||
public:
|
||||
nano::mdb_env env;
|
||||
|
||||
/**
|
||||
* Maps block hash to send block. (Removed)
|
||||
* nano::block_hash -> nano::send_block
|
||||
*/
|
||||
MDB_dbi send_blocks_handle{ 0 };
|
||||
|
||||
/**
|
||||
* Maps block hash to receive block. (Removed)
|
||||
* nano::block_hash -> nano::receive_block
|
||||
*/
|
||||
MDB_dbi receive_blocks_handle{ 0 };
|
||||
|
||||
/**
|
||||
* Maps block hash to open block. (Removed)
|
||||
* nano::block_hash -> nano::open_block
|
||||
*/
|
||||
MDB_dbi open_blocks_handle{ 0 };
|
||||
|
||||
/**
|
||||
* Maps block hash to change block. (Removed)
|
||||
* nano::block_hash -> nano::change_block
|
||||
*/
|
||||
MDB_dbi change_blocks_handle{ 0 };
|
||||
|
||||
/**
|
||||
* Maps block hash to v0 state block. (Removed)
|
||||
* nano::block_hash -> nano::state_block
|
||||
*/
|
||||
MDB_dbi state_blocks_v0_handle{ 0 };
|
||||
|
||||
/**
|
||||
* Maps block hash to v1 state block. (Removed)
|
||||
* nano::block_hash -> nano::state_block
|
||||
*/
|
||||
MDB_dbi state_blocks_v1_handle{ 0 };
|
||||
|
||||
/**
|
||||
* Maps block hash to state block. (Removed)
|
||||
* nano::block_hash -> nano::state_block
|
||||
*/
|
||||
MDB_dbi state_blocks_handle{ 0 };
|
||||
|
||||
/**
|
||||
* Meta information about block store, such as versions.
|
||||
* nano::uint256_union (arbitrary key) -> blob
|
||||
*/
|
||||
MDB_dbi meta_handle{ 0 };
|
||||
|
||||
/*
|
||||
* Contains block_sideband and block for all block types (legacy send/change/open/receive & state blocks)
|
||||
* nano::block_hash -> nano::block_sideband, nano::block
|
||||
*/
|
||||
MDB_dbi blocks_handle{ 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;
|
||||
|
@ -237,9 +183,14 @@ namespace lmdb
|
|||
friend class mdb_block_store_supported_version_upgrades_Test;
|
||||
friend class mdb_block_store_upgrade_v14_v15_Test;
|
||||
friend class mdb_block_store_upgrade_v15_v16_Test;
|
||||
friend class mdb_block_store_upgrade_v16_v17_Test;
|
||||
friend class mdb_block_store_upgrade_v17_v18_Test;
|
||||
friend class mdb_block_store_upgrade_v18_v19_Test;
|
||||
friend class mdb_block_store_upgrade_v19_v20_Test;
|
||||
friend class mdb_block_store_upgrade_v20_v21_Test;
|
||||
friend class block_store_DISABLED_change_dupsort_Test;
|
||||
friend void write_sideband_v14 (nano::lmdb::store &, nano::transaction &, nano::block const &, MDB_dbi);
|
||||
friend void write_sideband_v15 (nano::lmdb::store &, nano::transaction &, nano::block const &);
|
||||
friend void modify_account_info_to_v14 (nano::lmdb::store &, nano::transaction const &, nano::account const &, uint64_t, nano::block_hash const &);
|
||||
friend void modify_confirmation_height_to_v15 (nano::lmdb::store &, nano::transaction const &, nano::account const &, uint64_t);
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue