Remove node v18 and earlier upgrade support (#2770)

* Remove node v18 and earlier upgrade support

* Remove DBv13 upgrade and add tests for checking upgrade

* block_account_computed no longer used
This commit is contained in:
Wesley Shillingford 2020-06-19 13:29:09 +01:00 committed by GitHub
commit 7c9614ecf4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
30 changed files with 98 additions and 2576 deletions

View file

@ -38,7 +38,6 @@ add_executable (core_test
timer.cpp
uint256_union.cpp
utility.cpp
versioning.cpp
vote_processor.cpp
wallet.cpp
wallets.cpp

View file

@ -27,11 +27,8 @@
namespace
{
void modify_account_info_to_v13 (nano::mdb_store & store, nano::transaction const & transaction_a, nano::account const & account_a, nano::block_hash const & rep_block);
void modify_account_info_to_v14 (nano::mdb_store & store, nano::transaction const & transaction_a, nano::account const & account_a, uint64_t confirmation_height, nano::block_hash const & rep_block);
void modify_genesis_account_info_to_v5 (nano::mdb_store & store, nano::transaction const & transaction_a);
void modify_confirmation_height_to_v15 (nano::mdb_store & store, nano::transaction const & transaction, nano::account const & account, uint64_t confirmation_height);
void write_sideband_v12 (nano::mdb_store & store_a, nano::transaction & transaction_a, nano::block & block_a, nano::block_hash const & successor_a, MDB_dbi db_a);
void write_sideband_v14 (nano::mdb_store & store_a, nano::transaction & transaction_a, nano::block const & block_a, MDB_dbi db_a);
void write_sideband_v15 (nano::mdb_store & store_a, nano::transaction & transaction_a, nano::block const & block_a);
}
@ -653,6 +650,50 @@ TEST (block_store, latest_find)
ASSERT_EQ (second, find3);
}
TEST (mdb_block_store, supported_version_upgrades)
{
// Check that upgrading from an unsupported version is not supported
auto path (nano::unique_path ());
nano::genesis genesis;
nano::logger_mt logger;
{
nano::mdb_store store (logger, path);
nano::stat stats;
nano::ledger ledger (store, stats);
auto transaction (store.tx_begin_write ());
store.initialize (transaction, genesis, ledger.cache);
// Lower the database to the max version unsupported for upgrades
store.version_put (transaction, store.minimum_version - 1);
}
// Upgrade should fail
{
nano::mdb_store store (logger, path);
ASSERT_TRUE (store.init_error ());
}
auto path1 (nano::unique_path ());
// Now try with the minimum version
{
nano::mdb_store store (logger, path1);
nano::stat stats;
nano::ledger ledger (store, stats);
auto transaction (store.tx_begin_write ());
store.initialize (transaction, genesis, ledger.cache);
// Lower the database version to the minimum version supported for upgrade.
store.version_put (transaction, store.minimum_version);
store.confirmation_height_del (transaction, nano::genesis_account);
ASSERT_FALSE (mdb_dbi_open (store.env.tx (transaction), "accounts_v1", MDB_CREATE, &store.accounts_v1));
modify_account_info_to_v14 (store, transaction, nano::genesis_account, 1, nano::genesis_hash);
}
// Upgrade should work
{
nano::mdb_store store (logger, path1);
ASSERT_FALSE (store.init_error ());
}
}
TEST (mdb_block_store, bad_path)
{
nano::logger_mt logger;
@ -849,127 +890,6 @@ TEST (block_store, sequence_increment)
ASSERT_EQ (31, vote6->sequence);
}
TEST (mdb_block_store, upgrade_v2_v3)
{
nano::keypair key1;
nano::keypair key2;
nano::block_hash change_hash;
auto path (nano::unique_path ());
{
nano::logger_mt logger;
nano::mdb_store store (logger, path);
ASSERT_TRUE (!store.init_error ());
auto transaction (store.tx_begin_write ());
nano::genesis genesis;
auto hash (genesis.hash ());
nano::stat stats;
nano::ledger ledger (store, stats);
store.initialize (transaction, genesis, ledger.cache);
nano::work_pool pool (std::numeric_limits<unsigned>::max ());
nano::change_block change (hash, key1.pub, nano::test_genesis_key.prv, nano::test_genesis_key.pub, *pool.generate (hash));
change_hash = change.hash ();
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, change).code);
ASSERT_EQ (0, ledger.weight (nano::test_genesis_key.pub));
ASSERT_EQ (nano::genesis_amount, ledger.weight (key1.pub));
store.version_put (transaction, 2);
ledger.cache.rep_weights.representation_put (key1.pub, 7);
ASSERT_EQ (7, ledger.weight (key1.pub));
ASSERT_EQ (2, store.version_get (transaction));
ledger.cache.rep_weights.representation_put (key2.pub, 6);
ASSERT_EQ (6, ledger.weight (key2.pub));
nano::account_info info;
ASSERT_FALSE (store.account_get (transaction, nano::test_genesis_key.pub, info));
auto rep_block = ledger.representative (transaction, ledger.latest (transaction, nano::test_genesis_key.pub));
nano::account_info_v5 info_old (info.head, rep_block, info.open_block, info.balance, info.modified);
auto status (mdb_put (store.env.tx (transaction), store.accounts_v0, nano::mdb_val (nano::test_genesis_key.pub), nano::mdb_val (sizeof (info_old), &info_old), 0));
ASSERT_EQ (status, 0);
store.confirmation_height_del (transaction, nano::genesis_account);
}
nano::logger_mt logger;
nano::mdb_store store (logger, path);
nano::stat stats;
nano::ledger ledger (store, stats);
auto transaction (store.tx_begin_write ());
ASSERT_TRUE (!store.init_error ());
ASSERT_LT (2, store.version_get (transaction));
ASSERT_EQ (nano::genesis_amount, ledger.weight (key1.pub));
ASSERT_EQ (0, ledger.weight (key2.pub));
nano::account_info info;
ASSERT_FALSE (store.account_get (transaction, nano::test_genesis_key.pub, info));
ASSERT_EQ (change_hash, ledger.representative (transaction, ledger.latest (transaction, nano::test_genesis_key.pub)));
}
TEST (mdb_block_store, upgrade_v3_v4)
{
nano::keypair key1;
nano::keypair key2;
nano::keypair key3;
auto path (nano::unique_path ());
{
nano::logger_mt logger;
nano::mdb_store store (logger, path);
ASSERT_FALSE (store.init_error ());
auto transaction (store.tx_begin_write ());
store.version_put (transaction, 3);
nano::pending_info_v3 info (key1.pub, 100, key2.pub);
auto status (mdb_put (store.env.tx (transaction), store.pending_v0, nano::mdb_val (key3.pub), nano::mdb_val (sizeof (info), &info), 0));
ASSERT_EQ (0, status);
}
nano::logger_mt logger;
nano::mdb_store store (logger, path);
nano::stat stats;
nano::ledger ledger (store, stats);
auto transaction (store.tx_begin_write ());
ASSERT_FALSE (store.init_error ());
ASSERT_LT (3, store.version_get (transaction));
nano::pending_key key (key2.pub, reinterpret_cast<nano::block_hash const &> (key3.pub));
nano::pending_info info;
auto error (store.pending_get (transaction, key, info));
ASSERT_FALSE (error);
ASSERT_EQ (key1.pub, info.source);
ASSERT_EQ (nano::amount (100), info.amount);
ASSERT_EQ (nano::epoch::epoch_0, info.epoch);
}
TEST (mdb_block_store, upgrade_v4_v5)
{
nano::block_hash genesis_hash (0);
nano::block_hash hash (0);
auto path (nano::unique_path ());
{
nano::logger_mt logger;
nano::mdb_store store (logger, path);
ASSERT_FALSE (store.init_error ());
auto transaction (store.tx_begin_write ());
nano::genesis genesis;
nano::stat stats;
nano::ledger ledger (store, stats);
store.initialize (transaction, genesis, ledger.cache);
store.version_put (transaction, 4);
nano::account_info info;
ASSERT_FALSE (store.account_get (transaction, nano::test_genesis_key.pub, info));
nano::keypair key0;
nano::work_pool pool (std::numeric_limits<unsigned>::max ());
nano::send_block block0 (info.head, key0.pub, nano::genesis_amount - nano::Gxrb_ratio, nano::test_genesis_key.prv, nano::test_genesis_key.pub, *pool.generate (info.head));
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, block0).code);
hash = block0.hash ();
auto original (store.block_get (transaction, info.head));
genesis_hash = info.head;
store.block_successor_clear (transaction, info.head);
ASSERT_TRUE (store.block_successor (transaction, genesis_hash).is_zero ());
modify_genesis_account_info_to_v5 (store, transaction);
// The pending send needs to be the correct version
auto status (mdb_put (store.env.tx (transaction), store.pending_v0, nano::mdb_val (nano::pending_key (key0.pub, block0.hash ())), nano::mdb_val (nano::pending_info_v14 (nano::genesis_account, nano::Gxrb_ratio, nano::epoch::epoch_0)), 0));
ASSERT_EQ (status, MDB_SUCCESS);
store.confirmation_height_del (transaction, nano::genesis_account);
}
nano::logger_mt logger;
nano::mdb_store store (logger, path);
ASSERT_FALSE (store.init_error ());
auto transaction (store.tx_begin_read ());
ASSERT_EQ (hash, store.block_successor (transaction, genesis_hash));
}
TEST (block_store, block_random)
{
nano::logger_mt logger;
@ -987,56 +907,6 @@ TEST (block_store, block_random)
ASSERT_EQ (*block, *genesis.open);
}
TEST (mdb_block_store, upgrade_v5_v6)
{
auto path (nano::unique_path ());
{
nano::logger_mt logger;
nano::mdb_store store (logger, path);
ASSERT_FALSE (store.init_error ());
auto transaction (store.tx_begin_write ());
nano::genesis genesis;
nano::ledger_cache ledger_cache;
store.initialize (transaction, genesis, ledger_cache);
store.version_put (transaction, 5);
modify_genesis_account_info_to_v5 (store, transaction);
store.confirmation_height_del (transaction, nano::genesis_account);
}
nano::logger_mt logger;
nano::mdb_store store (logger, path);
ASSERT_FALSE (store.init_error ());
auto transaction (store.tx_begin_read ());
nano::account_info info;
store.account_get (transaction, nano::test_genesis_key.pub, info);
ASSERT_EQ (1, info.block_count);
}
TEST (mdb_block_store, upgrade_v6_v7)
{
auto path (nano::unique_path ());
{
nano::logger_mt logger;
nano::mdb_store store (logger, path);
ASSERT_FALSE (store.init_error ());
auto transaction (store.tx_begin_write ());
nano::genesis genesis;
nano::ledger_cache ledger_cache;
store.initialize (transaction, genesis, ledger_cache);
store.version_put (transaction, 6);
modify_account_info_to_v13 (store, transaction, nano::genesis_account, nano::genesis_hash);
auto send1 (std::make_shared<nano::send_block> (0, 0, 0, nano::test_genesis_key.prv, nano::test_genesis_key.pub, 0));
store.unchecked_put (transaction, send1->hash (), send1);
store.flush (transaction);
ASSERT_NE (store.unchecked_end (), store.unchecked_begin (transaction));
store.confirmation_height_del (transaction, nano::genesis_account);
}
nano::logger_mt logger;
nano::mdb_store store (logger, path);
ASSERT_FALSE (store.init_error ());
auto transaction (store.tx_begin_read ());
ASSERT_EQ (store.unchecked_end (), store.unchecked_begin (transaction));
}
// Databases need to be dropped in order to convert to dupsort compatible
TEST (block_store, DISABLED_change_dupsort) // Unchecked is no longer dupsort table
{
@ -1082,35 +952,6 @@ TEST (block_store, DISABLED_change_dupsort) // Unchecked is no longer dupsort ta
}
}
TEST (mdb_block_store, upgrade_v7_v8)
{
auto path (nano::unique_path ());
{
nano::logger_mt logger;
nano::mdb_store store (logger, path);
auto transaction (store.tx_begin_write ());
ASSERT_EQ (0, mdb_drop (store.env.tx (transaction), store.unchecked, 1));
ASSERT_EQ (0, mdb_dbi_open (store.env.tx (transaction), "unchecked", MDB_CREATE, &store.unchecked));
store.version_put (transaction, 7);
}
nano::logger_mt logger;
nano::mdb_store store (logger, path);
ASSERT_FALSE (store.init_error ());
auto transaction (store.tx_begin_write ());
auto send1 (std::make_shared<nano::send_block> (0, 0, 0, nano::test_genesis_key.prv, nano::test_genesis_key.pub, 0));
auto send2 (std::make_shared<nano::send_block> (1, 0, 0, nano::test_genesis_key.prv, nano::test_genesis_key.pub, 0));
store.unchecked_put (transaction, send1->hash (), send1);
store.unchecked_put (transaction, send1->hash (), send2);
store.flush (transaction);
{
auto iterator1 (store.unchecked_begin (transaction));
++iterator1;
ASSERT_NE (store.unchecked_end (), iterator1);
++iterator1;
ASSERT_EQ (store.unchecked_end (), iterator1);
}
}
TEST (block_store, sequence_flush)
{
auto path (nano::unique_path ());
@ -1148,31 +989,6 @@ TEST (block_store, sequence_flush_by_hash)
ASSERT_EQ (*seq3, *vote1);
}
// Upgrading tracking block sequence numbers to whole vote.
TEST (mdb_block_store, upgrade_v8_v9)
{
auto path (nano::unique_path ());
nano::keypair key;
{
nano::logger_mt logger;
nano::mdb_store store (logger, path);
auto transaction (store.tx_begin_write ());
ASSERT_EQ (0, mdb_drop (store.env.tx (transaction), store.vote, 1));
ASSERT_EQ (0, mdb_dbi_open (store.env.tx (transaction), "sequence", MDB_CREATE, &store.vote));
uint64_t sequence (10);
ASSERT_EQ (0, mdb_put (store.env.tx (transaction), store.vote, nano::mdb_val (key.pub), nano::mdb_val (sizeof (sequence), &sequence), 0));
store.version_put (transaction, 8);
}
nano::logger_mt logger;
nano::mdb_store store (logger, path);
ASSERT_FALSE (store.init_error ());
auto transaction (store.tx_begin_read ());
ASSERT_LT (8, store.version_get (transaction));
auto vote (store.vote_get (transaction, key.pub));
ASSERT_NE (nullptr, vote);
ASSERT_EQ (10, vote->sequence);
}
TEST (block_store, state_block)
{
nano::logger_mt logger;
@ -1205,216 +1021,6 @@ TEST (block_store, state_block)
ASSERT_EQ (0, count2.state);
}
TEST (mdb_block_store, upgrade_sideband_genesis)
{
nano::genesis genesis;
auto path (nano::unique_path ());
{
nano::logger_mt logger;
nano::mdb_store store (logger, path);
ASSERT_FALSE (store.init_error ());
auto transaction (store.tx_begin_write ());
store.version_put (transaction, 11);
nano::ledger_cache ledger_cache;
store.initialize (transaction, genesis, ledger_cache);
modify_account_info_to_v13 (store, transaction, nano::genesis_account, nano::genesis_hash);
auto genesis_block (store.block_get (transaction, genesis.hash ()));
ASSERT_NE (nullptr, genesis_block);
ASSERT_EQ (1, genesis_block->sideband ().height);
ASSERT_FALSE (mdb_dbi_open (store.env.tx (transaction), "state_v1", MDB_CREATE, &store.state_blocks_v1));
write_sideband_v12 (store, transaction, *genesis_block, 0, store.open_blocks);
nano::block_sideband_v14 sideband1;
auto genesis_block2 (store.block_get_v14 (transaction, genesis.hash (), &sideband1));
ASSERT_NE (nullptr, genesis_block);
ASSERT_EQ (0, sideband1.height);
store.confirmation_height_del (transaction, nano::genesis_account);
}
nano::logger_mt logger;
nano::mdb_store store (logger, path);
ASSERT_FALSE (store.init_error ());
auto transaction (store.tx_begin_read ());
ASSERT_TRUE (store.full_sideband (transaction));
auto genesis_block (store.block_get (transaction, genesis.hash ()));
ASSERT_NE (nullptr, genesis_block);
ASSERT_EQ (1, genesis_block->sideband ().height);
}
TEST (mdb_block_store, upgrade_sideband_two_blocks)
{
nano::genesis genesis;
nano::block_hash hash2;
auto path (nano::unique_path ());
{
nano::logger_mt logger;
nano::mdb_store store (logger, path);
ASSERT_FALSE (store.init_error ());
nano::stat stat;
nano::ledger ledger (store, stat);
auto transaction (store.tx_begin_write ());
store.version_put (transaction, 11);
store.initialize (transaction, genesis, ledger.cache);
nano::work_pool pool (std::numeric_limits<unsigned>::max ());
nano::state_block block (nano::test_genesis_key.pub, genesis.hash (), nano::test_genesis_key.pub, nano::genesis_amount - nano::Gxrb_ratio, nano::test_genesis_key.pub, nano::test_genesis_key.prv, nano::test_genesis_key.pub, *pool.generate (genesis.hash ()));
hash2 = block.hash ();
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, block).code);
store.block_del (transaction, hash2, block.type ());
mdb_dbi_open (store.env.tx (transaction), "state_v1", MDB_CREATE, &store.state_blocks_v1);
mdb_dbi_open (store.env.tx (transaction), "state", MDB_CREATE, &store.state_blocks_v0);
write_sideband_v12 (store, transaction, *genesis.open, hash2, store.open_blocks);
write_sideband_v12 (store, transaction, block, 0, store.state_blocks_v0);
modify_account_info_to_v13 (store, transaction, nano::genesis_account, hash2);
auto status (mdb_put (store.env.tx (transaction), store.pending_v0, nano::mdb_val (nano::pending_key (nano::test_genesis_key.pub, block.hash ())), nano::mdb_val (nano::pending_info_v14 (nano::genesis_account, nano::Gxrb_ratio, nano::epoch::epoch_0)), 0));
ASSERT_EQ (status, MDB_SUCCESS);
store.confirmation_height_del (transaction, nano::genesis_account);
}
nano::logger_mt logger;
nano::mdb_store store (logger, path);
ASSERT_FALSE (store.init_error ());
auto transaction (store.tx_begin_read ());
ASSERT_TRUE (store.full_sideband (transaction));
auto genesis_block (store.block_get (transaction, genesis.hash ()));
ASSERT_NE (nullptr, genesis_block);
ASSERT_EQ (1, genesis_block->sideband ().height);
auto block2 (store.block_get (transaction, hash2));
ASSERT_NE (nullptr, block2);
ASSERT_EQ (2, block2->sideband ().height);
}
TEST (mdb_block_store, upgrade_sideband_two_accounts)
{
nano::genesis genesis;
nano::block_hash hash2;
nano::block_hash hash3;
nano::keypair key;
auto path (nano::unique_path ());
{
nano::logger_mt logger;
nano::mdb_store store (logger, path);
nano::stat stat;
nano::ledger ledger (store, stat);
auto transaction (store.tx_begin_write ());
store.version_put (transaction, 11);
store.initialize (transaction, genesis, ledger.cache);
nano::work_pool pool (std::numeric_limits<unsigned>::max ());
nano::state_block block1 (nano::test_genesis_key.pub, genesis.hash (), nano::test_genesis_key.pub, nano::genesis_amount - nano::Gxrb_ratio, key.pub, nano::test_genesis_key.prv, nano::test_genesis_key.pub, *pool.generate (genesis.hash ()));
hash2 = block1.hash ();
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, block1).code);
nano::state_block block2 (key.pub, 0, nano::test_genesis_key.pub, nano::Gxrb_ratio, hash2, key.prv, key.pub, *pool.generate (key.pub));
hash3 = block2.hash ();
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, block2).code);
store.block_del (transaction, hash2, block1.type ());
store.block_del (transaction, hash3, block2.type ());
mdb_dbi_open (store.env.tx (transaction), "state_v1", MDB_CREATE, &store.state_blocks_v1);
mdb_dbi_open (store.env.tx (transaction), "state", MDB_CREATE, &store.state_blocks_v0);
write_sideband_v12 (store, transaction, *genesis.open, hash2, store.open_blocks);
write_sideband_v12 (store, transaction, block1, 0, store.state_blocks_v0);
write_sideband_v12 (store, transaction, block2, 0, store.state_blocks_v0);
modify_account_info_to_v13 (store, transaction, nano::genesis_account, hash2);
modify_account_info_to_v13 (store, transaction, block2.account (), hash3);
store.confirmation_height_del (transaction, nano::genesis_account);
store.confirmation_height_del (transaction, key.pub);
}
nano::logger_mt logger;
nano::mdb_store store (logger, path);
ASSERT_FALSE (store.init_error ());
auto transaction (store.tx_begin_read ());
ASSERT_TRUE (store.full_sideband (transaction));
auto genesis_block (store.block_get (transaction, genesis.hash ()));
ASSERT_NE (nullptr, genesis_block);
ASSERT_EQ (1, genesis_block->sideband ().height);
auto block2 (store.block_get (transaction, hash2));
ASSERT_NE (nullptr, block2);
ASSERT_EQ (2, block2->sideband ().height);
auto block3 (store.block_get (transaction, hash3));
ASSERT_NE (nullptr, block3);
ASSERT_EQ (1, block3->sideband ().height);
}
TEST (mdb_block_store, insert_after_legacy)
{
nano::logger_mt logger;
nano::genesis genesis;
nano::mdb_store store (logger, nano::unique_path ());
ASSERT_FALSE (store.init_error ());
nano::stat stat;
nano::ledger ledger (store, stat);
auto transaction (store.tx_begin_write ());
store.version_put (transaction, 11);
store.initialize (transaction, genesis, ledger.cache);
mdb_dbi_open (store.env.tx (transaction), "state_v1", MDB_CREATE, &store.state_blocks_v1);
write_sideband_v12 (store, transaction, *genesis.open, 0, store.open_blocks);
nano::work_pool pool (std::numeric_limits<unsigned>::max ());
nano::state_block block (nano::test_genesis_key.pub, genesis.hash (), nano::test_genesis_key.pub, nano::genesis_amount - nano::Gxrb_ratio, nano::test_genesis_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, block).code);
}
// Account for an open block should be retrievable
TEST (mdb_block_store, legacy_account_computed)
{
nano::logger_mt logger;
nano::mdb_store store (logger, nano::unique_path ());
ASSERT_TRUE (!store.init_error ());
nano::stat stats;
nano::ledger ledger (store, stats);
nano::genesis genesis;
auto transaction (store.tx_begin_write ());
store.initialize (transaction, genesis, ledger.cache);
store.version_put (transaction, 11);
mdb_dbi_open (store.env.tx (transaction), "state_v1", MDB_CREATE, &store.state_blocks_v1);
write_sideband_v12 (store, transaction, *genesis.open, 0, store.open_blocks);
ASSERT_EQ (nano::genesis_account, ledger.account (transaction, genesis.hash ()));
}
TEST (mdb_block_store, upgrade_sideband_epoch)
{
bool error (false);
nano::genesis genesis;
nano::block_hash hash2;
auto path (nano::unique_path ());
nano::work_pool pool (std::numeric_limits<unsigned>::max ());
{
nano::logger_mt logger;
nano::mdb_store store (logger, path);
ASSERT_FALSE (error);
nano::stat stat;
nano::ledger ledger (store, stat);
auto transaction (store.tx_begin_write ());
store.version_put (transaction, 11);
store.initialize (transaction, genesis, ledger.cache);
nano::state_block block1 (nano::test_genesis_key.pub, genesis.hash (), nano::test_genesis_key.pub, nano::genesis_amount, ledger.epoch_link (nano::epoch::epoch_1), nano::test_genesis_key.prv, nano::test_genesis_key.pub, *pool.generate (genesis.hash ()));
hash2 = block1.hash ();
ASSERT_FALSE (mdb_dbi_open (store.env.tx (transaction), "state_v1", MDB_CREATE, &store.state_blocks_v1));
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, block1).code);
ASSERT_EQ (nano::epoch::epoch_1, store.block_version (transaction, hash2));
store.block_del (transaction, hash2, block1.type ());
store.block_del (transaction, genesis.open->hash (), genesis.open->type ());
write_sideband_v12 (store, transaction, *genesis.open, hash2, store.open_blocks);
write_sideband_v12 (store, transaction, block1, 0, store.state_blocks_v1);
nano::mdb_val value;
ASSERT_FALSE (mdb_get (store.env.tx (transaction), store.state_blocks_v1, nano::mdb_val (hash2), value));
ASSERT_FALSE (mdb_get (store.env.tx (transaction), store.open_blocks, nano::mdb_val (nano::genesis_hash), value));
ASSERT_FALSE (mdb_dbi_open (store.env.tx (transaction), "accounts_v1", MDB_CREATE, &store.accounts_v1));
modify_account_info_to_v13 (store, transaction, nano::genesis_account, hash2);
store.account_del (transaction, nano::genesis_account);
store.confirmation_height_del (transaction, nano::genesis_account);
}
nano::logger_mt logger;
nano::mdb_store store (logger, path);
nano::stat stat;
nano::ledger ledger (store, stat);
ASSERT_FALSE (error);
auto transaction (store.tx_begin_write ());
ASSERT_TRUE (store.full_sideband (transaction));
ASSERT_EQ (nano::epoch::epoch_1, store.block_version (transaction, hash2));
auto block1 (store.block_get (transaction, hash2));
ASSERT_NE (0, block1->sideband ().height);
nano::state_block block2 (nano::test_genesis_key.pub, hash2, nano::test_genesis_key.pub, nano::genesis_amount - nano::Gxrb_ratio, nano::test_genesis_key.pub, nano::test_genesis_key.prv, nano::test_genesis_key.pub, *pool.generate (hash2));
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, block2).code);
ASSERT_EQ (nano::epoch::epoch_1, store.block_version (transaction, block2.hash ()));
}
TEST (mdb_block_store, sideband_height)
{
nano::logger_mt logger;
@ -1602,57 +1208,6 @@ TEST (block_store, online_weight)
ASSERT_EQ (store->online_weight_end (), store->online_weight_begin (transaction));
}
// Adding confirmation height to accounts
TEST (mdb_block_store, upgrade_v13_v14)
{
auto path (nano::unique_path ());
nano::genesis genesis;
{
nano::logger_mt logger;
nano::mdb_store store (logger, path);
auto transaction (store.tx_begin_write ());
nano::ledger_cache ledger_cache;
store.initialize (transaction, genesis, ledger_cache);
nano::account_info account_info;
ASSERT_FALSE (store.account_get (transaction, nano::genesis_account, account_info));
store.version_put (transaction, 13);
modify_account_info_to_v13 (store, transaction, nano::genesis_account, nano::genesis_hash);
// This should fail as sizes are no longer correct for account_info_v14
nano::mdb_val value;
ASSERT_FALSE (mdb_get (store.env.tx (transaction), store.accounts_v0, nano::mdb_val (nano::genesis_account), value));
nano::account_info_v14 info;
ASSERT_NE (value.size (), info.db_size ());
store.confirmation_height_del (transaction, nano::genesis_account);
}
// Now do the upgrade
nano::logger_mt logger;
auto error (false);
nano::mdb_store store (logger, path);
ASSERT_FALSE (error);
auto transaction (store.tx_begin_read ());
// Size of account_info should now equal that set in db
nano::mdb_val value;
ASSERT_FALSE (mdb_get (store.env.tx (transaction), store.accounts_v0, nano::mdb_val (nano::genesis_account), value));
nano::account_info info;
ASSERT_EQ (value.size (), info.db_size ());
// Confirmation height should exist and be correct
nano::confirmation_height_info confirmation_height_info;
ASSERT_FALSE (store.confirmation_height_get (transaction, nano::genesis_account, confirmation_height_info));
ASSERT_EQ (confirmation_height_info.height, 1);
ASSERT_EQ (confirmation_height_info.frontier, genesis.hash ());
// Test deleting node ID
nano::uint256_union node_id_mdb_key (3);
auto error_node_id (mdb_get (store.env.tx (transaction), store.meta, nano::mdb_val (node_id_mdb_key), value));
ASSERT_EQ (error_node_id, MDB_NOTFOUND);
ASSERT_LT (13, store.version_get (transaction));
}
TEST (mdb_block_store, upgrade_v14_v15)
{
// Extract confirmation height to a separate database
@ -1676,7 +1231,7 @@ TEST (mdb_block_store, upgrade_v14_v15)
ASSERT_FALSE (store.confirmation_height_get (transaction, nano::genesis_account, confirmation_height_info));
ASSERT_EQ (confirmation_height_info.height, 1);
ASSERT_EQ (confirmation_height_info.frontier, genesis.hash ());
// These databases get remove after an upgrade, so readd them
// 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));
ASSERT_FALSE (mdb_dbi_open (store.env.tx (transaction), "accounts_v1", MDB_CREATE, &store.accounts_v1));
ASSERT_FALSE (mdb_dbi_open (store.env.tx (transaction), "pending_v1", MDB_CREATE, &store.pending_v1));
@ -1714,9 +1269,8 @@ TEST (mdb_block_store, upgrade_v14_v15)
// Now do the upgrade
nano::logger_mt logger;
auto error (false);
nano::mdb_store store (logger, path);
ASSERT_FALSE (error);
ASSERT_FALSE (store.init_error ());
auto transaction (store.tx_begin_read ());
// Size of account_info should now equal that set in db
@ -1783,9 +1337,8 @@ TEST (mdb_block_store, upgrade_v15_v16)
// Now do the upgrade
nano::logger_mt logger;
auto error (false);
nano::mdb_store store (logger, path);
ASSERT_FALSE (error);
ASSERT_FALSE (store.init_error ());
auto transaction (store.tx_begin_read ());
// The representation table should now be deleted
@ -1827,9 +1380,8 @@ TEST (mdb_block_store, upgrade_v16_v17)
// Now do the upgrade
nano::logger_mt logger;
auto error (false);
nano::mdb_store store (logger, path);
ASSERT_FALSE (error);
ASSERT_FALSE (store.init_error ());
auto transaction (store.tx_begin_read ());
nano::confirmation_height_info confirmation_height_info;
@ -1911,9 +1463,8 @@ TEST (mdb_block_store, upgrade_v17_v18)
// Now do the upgrade
nano::logger_mt logger;
auto error (false);
nano::mdb_store store (logger, path);
ASSERT_FALSE (error);
ASSERT_FALSE (store.init_error ());
auto transaction (store.tx_begin_read ());
// Size of state block should equal that set in db (no change)
@ -2064,7 +1615,7 @@ TEST (mdb_block_store, upgrade_backup)
// Now do the upgrade and confirm that backup is saved
nano::logger_mt logger;
nano::mdb_store store (logger, path, nano::txn_tracking_config{}, std::chrono::seconds (5), nano::lmdb_config{}, 512, true);
nano::mdb_store store (logger, path, nano::txn_tracking_config{}, std::chrono::seconds (5), nano::lmdb_config{}, true);
ASSERT_FALSE (store.init_error ());
auto transaction (store.tx_begin_read ());
ASSERT_LT (14, store.version_get (transaction));
@ -2118,54 +1669,6 @@ TEST (block_store, confirmation_height)
ASSERT_EQ (confirmation_height_info.frontier, nano::block_hash (0));
}
// Upgrade many accounts and check they all have a confirmation height of 0 (except genesis which should have 1)
TEST (mdb_block_store, upgrade_confirmation_height_many)
{
auto error (false);
nano::genesis genesis;
auto total_num_accounts = 1000; // Includes the genesis account
auto path (nano::unique_path ());
{
nano::logger_mt logger;
nano::mdb_store store (logger, path);
ASSERT_FALSE (error);
auto transaction (store.tx_begin_write ());
store.version_put (transaction, 13);
nano::ledger_cache ledger_cache;
store.initialize (transaction, genesis, ledger_cache);
modify_account_info_to_v13 (store, transaction, nano::genesis_account, nano::genesis_hash);
// Add many accounts
for (auto i = 0; i < total_num_accounts - 1; ++i)
{
nano::account account (i);
nano::open_block open (1, nano::genesis_account, 3, nullptr);
open.sideband_set ({});
store.block_put (transaction, open.hash (), open);
nano::account_info_v13 account_info_v13 (open.hash (), open.hash (), open.hash (), 3, 4, 1, nano::epoch::epoch_0);
auto status (mdb_put (store.env.tx (transaction), store.accounts_v0, nano::mdb_val (account), nano::mdb_val (account_info_v13), 0));
ASSERT_EQ (status, 0);
}
store.confirmation_height_del (transaction, nano::genesis_account);
ASSERT_EQ (store.count (transaction, store.accounts_v0), total_num_accounts);
}
// Loop over them all and confirm they all have the correct confirmation heights
nano::logger_mt logger;
nano::mdb_store store (logger, path);
auto transaction (store.tx_begin_read ());
ASSERT_EQ (store.account_count (transaction), total_num_accounts);
ASSERT_EQ (store.confirmation_height_count (transaction), total_num_accounts);
for (auto i (store.confirmation_height_begin (transaction)), n (store.confirmation_height_end ()); i != n; ++i)
{
ASSERT_EQ (i->second.height, (i->first == nano::genesis_account) ? 1 : 0);
ASSERT_EQ (i->second.frontier, (i->first == nano::genesis_account) ? genesis.hash () : nano::block_hash (0));
}
}
// Ledger versions are not forward compatible
TEST (block_store, incompatible_version)
{
@ -2252,24 +1755,6 @@ TEST (block_store, rocksdb_force_test_env_variable)
namespace
{
void write_sideband_v12 (nano::mdb_store & store_a, nano::transaction & transaction_a, nano::block & block_a, nano::block_hash const & successor_a, MDB_dbi db_a)
{
std::vector<uint8_t> vector;
{
nano::vectorstream stream (vector);
block_a.serialize (stream);
nano::write (stream, successor_a);
}
MDB_val val{ vector.size (), vector.data () };
auto hash (block_a.hash ());
auto status (mdb_put (store_a.env.tx (transaction_a), db_a, nano::mdb_val (hash), &val, 0));
ASSERT_EQ (0, status);
nano::block_sideband_v14 sideband_v14;
auto block (store_a.block_get_v14 (transaction_a, hash, &sideband_v14));
ASSERT_NE (nullptr, block);
ASSERT_EQ (0, sideband_v14.height);
};
void write_sideband_v14 (nano::mdb_store & store_a, nano::transaction & transaction_a, nano::block const & block_a, MDB_dbi db_a)
{
auto block = store_a.block_get (transaction_a, block_a.hash ());
@ -2306,16 +1791,6 @@ void write_sideband_v15 (nano::mdb_store & store_a, nano::transaction & transact
ASSERT_FALSE (mdb_put (store_a.env.tx (transaction_a), store_a.state_blocks, nano::mdb_val (block_a.hash ()), &val, 0));
}
// These functions take the latest account_info and create a legacy one so that upgrade tests can be emulated more easily.
void modify_account_info_to_v13 (nano::mdb_store & store, nano::transaction const & transaction, nano::account const & account, nano::block_hash const & rep_block)
{
nano::account_info info;
ASSERT_FALSE (store.account_get (transaction, account, info));
nano::account_info_v13 account_info_v13 (info.head, rep_block, info.open_block, info.balance, info.modified, info.block_count, info.epoch ());
auto status (mdb_put (store.env.tx (transaction), (info.epoch () == nano::epoch::epoch_0) ? store.accounts_v0 : store.accounts_v1, nano::mdb_val (account), nano::mdb_val (account_info_v13), 0));
ASSERT_EQ (status, 0);
}
void modify_account_info_to_v14 (nano::mdb_store & store, nano::transaction const & transaction, nano::account const & account, uint64_t confirmation_height, nano::block_hash const & rep_block)
{
nano::account_info info;
@ -2330,15 +1805,4 @@ void modify_confirmation_height_to_v15 (nano::mdb_store & store, nano::transacti
auto status (mdb_put (store.env.tx (transaction), store.confirmation_height, nano::mdb_val (account), nano::mdb_val (confirmation_height), 0));
ASSERT_EQ (status, 0);
}
void modify_genesis_account_info_to_v5 (nano::mdb_store & store, nano::transaction const & transaction)
{
nano::account_info info;
store.account_get (transaction, nano::test_genesis_key.pub, info);
nano::representative_visitor visitor (transaction, store);
visitor.compute (info.head);
nano::account_info_v5 info_old (info.head, visitor.result, info.open_block, info.balance, info.modified);
auto status (mdb_put (store.env.tx (transaction), store.accounts_v0, nano::mdb_val (nano::test_genesis_key.pub), nano::mdb_val (sizeof (info_old), &info_old), 0));
ASSERT_EQ (status, 0);
}
}

View file

@ -86,25 +86,6 @@ TEST (ipc, synchronous)
ipc.stop ();
}
TEST (ipc, config_upgrade_v0_v1)
{
auto path1 (nano::unique_path ());
auto path2 (nano::unique_path ());
nano::ipc::ipc_config config1;
nano::ipc::ipc_config config2;
nano::jsonconfig tree;
config1.serialize_json (tree);
nano::jsonconfig local = tree.get_required_child ("local");
local.erase ("version");
local.erase ("allow_unsafe");
bool upgraded (false);
ASSERT_FALSE (config2.deserialize_json (upgraded, tree));
nano::jsonconfig local2 = tree.get_required_child ("local");
ASSERT_TRUE (upgraded);
ASSERT_LE (1, local2.get<int> ("version"));
ASSERT_FALSE (local2.get<bool> ("allow_unsafe"));
}
TEST (ipc, permissions_default_user)
{
// Test empty/nonexistant access config. The default user still exists with default permissions.

View file

@ -58,64 +58,6 @@ TEST (logging, serialization)
ASSERT_EQ (logging1.min_time_between_log_output, logging2.min_time_between_log_output);
}
TEST (logging, upgrade_v1_v2)
{
auto path1 (nano::unique_path ());
auto path2 (nano::unique_path ());
nano::logging logging1;
logging1.init (path1);
nano::logging logging2;
logging2.init (path2);
nano::jsonconfig tree;
logging1.serialize_json (tree);
tree.erase ("version");
tree.erase ("vote");
bool upgraded (false);
ASSERT_FALSE (logging2.deserialize_json (upgraded, tree));
ASSERT_LE (2, tree.get<int> ("version"));
ASSERT_FALSE (tree.get<bool> ("vote"));
}
TEST (logging, upgrade_v6_v7)
{
auto path1 (nano::unique_path ());
auto path2 (nano::unique_path ());
nano::logging logging1;
logging1.init (path1);
nano::logging logging2;
logging2.init (path2);
nano::jsonconfig tree;
logging1.serialize_json (tree);
tree.erase ("version");
tree.erase ("min_time_between_output");
tree.erase ("network_timeout_logging_value");
bool upgraded (false);
ASSERT_FALSE (logging2.deserialize_json (upgraded, tree));
ASSERT_TRUE (upgraded);
ASSERT_LE (7, tree.get<int> ("version"));
ASSERT_EQ (5, tree.get<uintmax_t> ("min_time_between_output"));
ASSERT_EQ (false, tree.get<bool> ("network_timeout_logging_value"));
}
TEST (logging, upgrade_v7_v8)
{
auto path1 (nano::unique_path ());
auto path2 (nano::unique_path ());
nano::logging logging1;
logging1.init (path1);
nano::logging logging2;
logging2.init (path2);
nano::jsonconfig tree;
logging1.serialize_json (tree);
tree.erase ("version");
tree.erase ("single_line_record");
bool upgraded (false);
ASSERT_FALSE (logging2.deserialize_json (upgraded, tree));
ASSERT_TRUE (upgraded);
ASSERT_LE (8, tree.get<int> ("version"));
ASSERT_EQ (false, tree.get<bool> ("single_line_record"));
}
TEST (logger, changing_time_interval)
{
auto path1 (nano::unique_path ());

View file

@ -562,197 +562,6 @@ TEST (node_config, serialization)
ASSERT_EQ (config2.deprecated_lmdb_max_dbs, config1.deprecated_lmdb_max_dbs);
}
TEST (node_config, v1_v2_upgrade)
{
auto path (nano::unique_path ());
nano::logging logging1;
logging1.init (path);
nano::jsonconfig tree;
tree.put ("peering_port", std::to_string (0));
tree.put ("packet_delay_microseconds", std::to_string (0));
tree.put ("bootstrap_fraction_numerator", std::to_string (0));
tree.put ("creation_rebroadcast", std::to_string (0));
tree.put ("rebroadcast_delay", std::to_string (0));
tree.put ("receive_minimum", nano::amount (0).to_string_dec ());
nano::jsonconfig logging_l;
logging1.serialize_json (logging_l);
tree.put_child ("logging", logging_l);
nano::jsonconfig preconfigured_peers_l;
tree.put_child ("preconfigured_peers", preconfigured_peers_l);
nano::jsonconfig preconfigured_representatives_l;
tree.put_child ("preconfigured_representatives", preconfigured_representatives_l);
bool upgraded (false);
nano::node_config config1;
config1.logging.init (path);
ASSERT_FALSE (tree.get_optional_child ("work_peers"));
config1.deserialize_json (upgraded, tree);
ASSERT_TRUE (upgraded);
ASSERT_TRUE (!!tree.get_optional_child ("work_peers"));
}
TEST (node_config, v2_v3_upgrade)
{
nano::jsonconfig tree;
add_required_children_node_config_tree (tree);
tree.put ("peering_port", std::to_string (0));
tree.put ("packet_delay_microseconds", std::to_string (0));
tree.put ("bootstrap_fraction_numerator", std::to_string (0));
tree.put ("creation_rebroadcast", std::to_string (0));
tree.put ("rebroadcast_delay", std::to_string (0));
tree.put ("receive_minimum", nano::amount (0).to_string_dec ());
tree.put ("version", "2");
nano::jsonconfig preconfigured_representatives_l;
preconfigured_representatives_l.push ("TR6ZJ4pdp6HC76xMRpVDny5x2s8AEbrhFue3NKVxYYdmKuTEib");
tree.replace_child ("preconfigured_representatives", preconfigured_representatives_l);
bool upgraded (false);
nano::node_config config1;
auto path (nano::unique_path ());
config1.logging.init (path);
ASSERT_FALSE (tree.get_optional<std::string> ("inactive_supply"));
ASSERT_FALSE (tree.get_optional<std::string> ("password_fanout"));
ASSERT_FALSE (tree.get_optional<std::string> ("io_threads"));
ASSERT_FALSE (tree.get_optional<std::string> ("work_threads"));
config1.deserialize_json (upgraded, tree);
//ASSERT_EQ (nano::uint128_union (0).to_string_dec (), tree.get<std::string> ("inactive_supply"));
ASSERT_EQ ("1024", tree.get<std::string> ("password_fanout"));
ASSERT_NE (0, std::stoul (tree.get<std::string> ("password_fanout")));
ASSERT_TRUE (upgraded);
auto version (tree.get<std::string> ("version"));
ASSERT_GT (std::stoull (version), 2);
}
TEST (node_config, v15_v16_upgrade)
{
auto test_upgrade = [](auto old_preconfigured_peers_url, auto new_preconfigured_peers_url) {
auto path (nano::unique_path ());
nano::jsonconfig tree;
add_required_children_node_config_tree (tree);
tree.put ("version", "15");
const char * dummy_peer = "127.5.2.1";
nano::jsonconfig preconfigured_peers_json;
preconfigured_peers_json.push (old_preconfigured_peers_url);
preconfigured_peers_json.push (dummy_peer);
tree.replace_child ("preconfigured_peers", preconfigured_peers_json);
auto upgraded (false);
nano::node_config config;
config.logging.init (path);
// These config options should not be present at version 15
ASSERT_FALSE (tree.get_optional_child ("allow_local_peers"));
ASSERT_FALSE (tree.get_optional_child ("signature_checker_threads"));
ASSERT_FALSE (tree.get_optional_child ("vote_minimum"));
config.deserialize_json (upgraded, tree);
// The config options should be added after the upgrade
ASSERT_TRUE (!!tree.get_optional_child ("allow_local_peers"));
ASSERT_TRUE (!!tree.get_optional_child ("signature_checker_threads"));
ASSERT_TRUE (!!tree.get_optional_child ("vote_minimum"));
ASSERT_TRUE (upgraded);
auto version (tree.get<std::string> ("version"));
auto read_preconfigured_peers_json (tree.get_required_child ("preconfigured_peers"));
std::vector<std::string> preconfigured_peers;
read_preconfigured_peers_json.array_entries<std::string> ([&preconfigured_peers](const auto & entry) {
preconfigured_peers.push_back (entry);
});
// Check that the new peer is updated while the other peer is untouched
ASSERT_EQ (preconfigured_peers.size (), 2);
ASSERT_EQ (preconfigured_peers.front (), new_preconfigured_peers_url);
ASSERT_EQ (preconfigured_peers.back (), dummy_peer);
// Check version is updated
ASSERT_GT (std::stoull (version), 15);
};
// Check that upgrades work with both
test_upgrade ("rai.raiblocks.net", "peering.nano.org");
test_upgrade ("rai-beta.raiblocks.net", "peering-beta.nano.org");
}
TEST (node_config, v16_values)
{
nano::jsonconfig tree;
add_required_children_node_config_tree (tree);
auto path (nano::unique_path ());
auto upgraded (false);
nano::node_config config;
config.logging.init (path);
// Check config is correct
tree.put ("allow_local_peers", false);
tree.put ("signature_checker_threads", 1);
tree.put ("vote_minimum", nano::Gxrb_ratio.convert_to<std::string> ());
config.deserialize_json (upgraded, tree);
ASSERT_FALSE (upgraded);
ASSERT_FALSE (config.allow_local_peers);
ASSERT_EQ (config.signature_checker_threads, 1);
ASSERT_EQ (config.vote_minimum.number (), nano::Gxrb_ratio);
// Check config is correct with other values
tree.put ("allow_local_peers", true);
tree.put ("signature_checker_threads", 4);
tree.put ("vote_minimum", (std::numeric_limits<nano::uint128_t>::max () - 100).convert_to<std::string> ());
upgraded = false;
config.deserialize_json (upgraded, tree);
ASSERT_FALSE (upgraded);
ASSERT_TRUE (config.allow_local_peers);
ASSERT_EQ (config.signature_checker_threads, 4);
ASSERT_EQ (config.vote_minimum.number (), std::numeric_limits<nano::uint128_t>::max () - 100);
}
TEST (node_config, v16_v17_upgrade)
{
auto path (nano::unique_path ());
nano::jsonconfig tree;
add_required_children_node_config_tree (tree);
tree.put ("version", "16");
auto upgraded (false);
nano::node_config config;
config.logging.init (path);
// These config options should not be present
ASSERT_FALSE (tree.get_optional_child ("tcp_io_timeout"));
ASSERT_FALSE (tree.get_optional_child ("pow_sleep_interval"));
ASSERT_FALSE (tree.get_optional_child ("external_address"));
ASSERT_FALSE (tree.get_optional_child ("external_port"));
ASSERT_FALSE (tree.get_optional_child ("tcp_incoming_connections_max"));
ASSERT_FALSE (tree.get_optional_child ("vote_generator_delay"));
ASSERT_FALSE (tree.get_optional_child ("vote_generator_threshold"));
ASSERT_FALSE (tree.get_optional_child ("diagnostics"));
ASSERT_FALSE (tree.get_optional_child ("use_memory_pools"));
ASSERT_FALSE (tree.get_optional_child ("confirmation_history_size"));
ASSERT_FALSE (tree.get_optional_child ("active_elections_size"));
ASSERT_FALSE (tree.get_optional_child ("bandwidth_limit"));
ASSERT_FALSE (tree.get_optional_child ("conf_height_processor_batch_min_time"));
config.deserialize_json (upgraded, tree);
// The config options should be added after the upgrade
ASSERT_TRUE (!!tree.get_optional_child ("tcp_io_timeout"));
ASSERT_TRUE (!!tree.get_optional_child ("pow_sleep_interval"));
ASSERT_TRUE (!!tree.get_optional_child ("external_address"));
ASSERT_TRUE (!!tree.get_optional_child ("external_port"));
ASSERT_TRUE (!!tree.get_optional_child ("tcp_incoming_connections_max"));
ASSERT_TRUE (!!tree.get_optional_child ("vote_generator_delay"));
ASSERT_TRUE (!!tree.get_optional_child ("vote_generator_threshold"));
ASSERT_TRUE (!!tree.get_optional_child ("diagnostics"));
ASSERT_TRUE (!!tree.get_optional_child ("use_memory_pools"));
ASSERT_TRUE (!!tree.get_optional_child ("confirmation_history_size"));
ASSERT_TRUE (!!tree.get_optional_child ("active_elections_size"));
ASSERT_TRUE (!!tree.get_optional_child ("bandwidth_limit"));
ASSERT_TRUE (!!tree.get_optional_child ("conf_height_processor_batch_min_time"));
ASSERT_TRUE (upgraded);
auto version (tree.get<std::string> ("version"));
// Check version is updated
ASSERT_GT (std::stoull (version), 16);
}
TEST (node_config, v17_values)
{
nano::jsonconfig tree;
@ -954,6 +763,23 @@ TEST (node_config, random_rep)
ASSERT_NE (config1.preconfigured_representatives.end (), std::find (config1.preconfigured_representatives.begin (), config1.preconfigured_representatives.end (), rep));
}
TEST (node_config, unsupported_version_upgrade)
{
auto path (nano::unique_path ());
nano::logging logging1;
logging1.init (path);
nano::node_config node_config (100, logging1);
nano::jsonconfig config;
node_config.serialize_json (config);
config.put ("version", "16"); // Version 16 and earlier is no longer supported for direct upgrade
nano::node_config node_config1;
bool upgraded{ false };
auto err = node_config1.deserialize_json (upgraded, config);
ASSERT_FALSE (upgraded);
ASSERT_TRUE (err);
}
class json_initial_value_test final
{
public:

View file

@ -1,115 +0,0 @@
#include <nano/lib/logger_mt.hpp>
#include <nano/node/lmdb/lmdb.hpp>
#include <nano/secure/blockstore.hpp>
#include <nano/secure/utility.hpp>
#include <nano/secure/versioning.hpp>
#include <gtest/gtest.h>
TEST (versioning, account_info_v1)
{
auto file (nano::unique_path ());
nano::account account (1);
nano::open_block open (1, 2, 3, nullptr);
open.sideband_set ({});
nano::account_info_v1 v1 (open.hash (), open.hash (), 3, 4);
{
nano::logger_mt logger;
nano::mdb_store store (logger, file);
ASSERT_FALSE (store.init_error ());
auto transaction (store.tx_begin_write ());
store.block_put (transaction, open.hash (), open);
auto status (mdb_put (store.env.tx (transaction), store.accounts_v0, nano::mdb_val (account), nano::mdb_val (sizeof (v1), &v1), 0));
ASSERT_EQ (0, status);
store.version_put (transaction, 1);
}
nano::logger_mt logger;
nano::mdb_store store (logger, file);
ASSERT_FALSE (store.init_error ());
auto transaction (store.tx_begin_read ());
nano::account_info v_latest;
ASSERT_FALSE (store.account_get (transaction, account, v_latest));
ASSERT_EQ (open.hash (), v_latest.open_block);
ASSERT_EQ (v1.balance, v_latest.balance);
ASSERT_EQ (v1.head, v_latest.head);
ASSERT_EQ (v1.modified, v_latest.modified);
ASSERT_EQ (v1.rep_block, open.hash ());
ASSERT_EQ (1, v_latest.block_count);
nano::confirmation_height_info confirmation_height_info;
ASSERT_FALSE (store.confirmation_height_get (transaction, account, confirmation_height_info));
ASSERT_EQ (0, confirmation_height_info.height);
ASSERT_EQ (nano::epoch::epoch_0, v_latest.epoch ());
}
TEST (versioning, account_info_v5)
{
auto file (nano::unique_path ());
nano::account account (1);
nano::open_block open (1, 2, 3, nullptr);
open.sideband_set ({});
nano::account_info_v5 v5 (open.hash (), open.hash (), open.hash (), 3, 4);
{
nano::logger_mt logger;
nano::mdb_store store (logger, file);
ASSERT_FALSE (store.init_error ());
auto transaction (store.tx_begin_write ());
store.block_put (transaction, open.hash (), open);
auto status (mdb_put (store.env.tx (transaction), store.accounts_v0, nano::mdb_val (account), nano::mdb_val (sizeof (v5), &v5), 0));
ASSERT_EQ (0, status);
store.version_put (transaction, 5);
}
nano::logger_mt logger;
nano::mdb_store store (logger, file);
ASSERT_FALSE (store.init_error ());
auto transaction (store.tx_begin_read ());
nano::account_info v_latest;
ASSERT_FALSE (store.account_get (transaction, account, v_latest));
ASSERT_EQ (v5.open_block, v_latest.open_block);
ASSERT_EQ (v5.balance, v_latest.balance);
ASSERT_EQ (v5.head, v_latest.head);
ASSERT_EQ (v5.modified, v_latest.modified);
ASSERT_EQ (v5.rep_block, open.hash ());
ASSERT_EQ (1, v_latest.block_count);
nano::confirmation_height_info confirmation_height_info;
ASSERT_FALSE (store.confirmation_height_get (transaction, account, confirmation_height_info));
ASSERT_EQ (0, confirmation_height_info.height);
ASSERT_EQ (nano::epoch::epoch_0, v_latest.epoch ());
}
TEST (versioning, account_info_v13)
{
auto file (nano::unique_path ());
nano::account account (1);
nano::open_block open (1, 2, 3, nullptr);
open.sideband_set ({});
nano::account_info_v13 v13 (open.hash (), open.hash (), open.hash (), 3, 4, 10, nano::epoch::epoch_0);
{
nano::logger_mt logger;
nano::mdb_store store (logger, file);
ASSERT_FALSE (store.init_error ());
auto transaction (store.tx_begin_write ());
store.block_put (transaction, open.hash (), open);
auto status (mdb_put (store.env.tx (transaction), store.accounts_v0, nano::mdb_val (account), nano::mdb_val (v13), 0));
ASSERT_EQ (0, status);
store.version_put (transaction, 13);
}
nano::logger_mt logger;
nano::mdb_store store (logger, file);
ASSERT_FALSE (store.init_error ());
auto transaction (store.tx_begin_read ());
nano::account_info v_latest;
ASSERT_FALSE (store.account_get (transaction, account, v_latest));
ASSERT_EQ (v13.open_block, v_latest.open_block);
ASSERT_EQ (v13.balance, v_latest.balance);
ASSERT_EQ (v13.head, v_latest.head);
ASSERT_EQ (v13.modified, v_latest.modified);
ASSERT_EQ (v13.rep_block, open.hash ());
ASSERT_EQ (v13.block_count, v_latest.block_count);
nano::confirmation_height_info confirmation_height_info;
ASSERT_FALSE (store.confirmation_height_get (transaction, account, confirmation_height_info));
ASSERT_EQ (0, confirmation_height_info.height);
ASSERT_EQ (v13.epoch, v_latest.epoch ());
}

View file

@ -726,46 +726,6 @@ TEST (wallet, insert_locked)
ASSERT_TRUE (wallet->insert_adhoc (nano::keypair ().prv).is_zero ());
}
TEST (wallet, version_1_upgrade)
{
nano::system system (1);
auto wallet (system.wallet (0));
wallet->enter_initial_password ();
nano::keypair key;
auto transaction (wallet->wallets.tx_begin_write ());
ASSERT_TRUE (wallet->store.valid_password (transaction));
wallet->store.rekey (transaction, "1");
wallet->enter_password (transaction, "");
ASSERT_FALSE (wallet->store.valid_password (transaction));
nano::raw_key password_l;
nano::wallet_value value (wallet->store.entry_get_raw (transaction, nano::wallet_store::wallet_key_special));
nano::raw_key kdf;
kdf.data.clear ();
password_l.decrypt (value.key, kdf, wallet->store.salt (transaction).owords[0]);
nano::uint256_union ciphertext;
ciphertext.encrypt (key.prv, password_l, wallet->store.salt (transaction).owords[0]);
wallet->store.entry_put_raw (transaction, key.pub, nano::wallet_value (ciphertext, 0));
wallet->store.version_put (transaction, 1);
wallet->enter_password (transaction, "1");
ASSERT_TRUE (wallet->store.valid_password (transaction));
ASSERT_EQ (nano::wallet_store::version_current, wallet->store.version (transaction));
nano::raw_key prv;
ASSERT_FALSE (wallet->store.fetch (transaction, key.pub, prv));
ASSERT_EQ (key.prv, prv);
value = wallet->store.entry_get_raw (transaction, nano::wallet_store::wallet_key_special);
wallet->store.derive_key (kdf, transaction, "");
password_l.decrypt (value.key, kdf, wallet->store.salt (transaction).owords[0]);
ciphertext.encrypt (key.prv, password_l, wallet->store.salt (transaction).owords[0]);
wallet->store.entry_put_raw (transaction, key.pub, nano::wallet_value (ciphertext, 0));
wallet->store.version_put (transaction, 1);
wallet->enter_password (transaction, "1");
ASSERT_TRUE (wallet->store.valid_password (transaction));
ASSERT_EQ (nano::wallet_store::version_current, wallet->store.version (transaction));
nano::raw_key prv2;
ASSERT_FALSE (wallet->store.fetch (transaction, key.pub, prv2));
ASSERT_EQ (key.prv, prv2);
}
TEST (wallet, deterministic_keys)
{
bool init;
@ -854,117 +814,6 @@ TEST (wallet, insert_deterministic_locked)
ASSERT_TRUE (wallet->deterministic_insert (transaction).is_zero ());
}
TEST (wallet, version_2_upgrade)
{
nano::system system (1);
auto wallet (system.wallet (0));
auto transaction (wallet->wallets.tx_begin_write ());
wallet->store.rekey (transaction, "1");
ASSERT_TRUE (wallet->store.attempt_password (transaction, ""));
wallet->store.erase (transaction, nano::wallet_store::deterministic_index_special);
wallet->store.erase (transaction, nano::wallet_store::seed_special);
wallet->store.version_put (transaction, 2);
ASSERT_EQ (2, wallet->store.version (transaction));
ASSERT_EQ (wallet->store.find (transaction, nano::wallet_store::deterministic_index_special), wallet->store.end ());
ASSERT_EQ (wallet->store.find (transaction, nano::wallet_store::seed_special), wallet->store.end ());
wallet->store.attempt_password (transaction, "1");
ASSERT_EQ (nano::wallet_store::version_current, wallet->store.version (transaction));
ASSERT_NE (wallet->store.find (transaction, nano::wallet_store::deterministic_index_special), wallet->store.end ());
ASSERT_NE (wallet->store.find (transaction, nano::wallet_store::seed_special), wallet->store.end ());
ASSERT_FALSE (wallet->deterministic_insert (transaction).is_zero ());
}
TEST (wallet, version_3_upgrade)
{
nano::system system (1);
auto wallet (system.wallet (0));
auto transaction (wallet->wallets.tx_begin_write ());
wallet->store.rekey (transaction, "1");
wallet->enter_password (transaction, "1");
ASSERT_TRUE (wallet->store.valid_password (transaction));
ASSERT_EQ (nano::wallet_store::version_current, wallet->store.version (transaction));
nano::keypair key;
nano::raw_key seed;
nano::uint256_union seed_ciphertext;
nano::random_pool::generate_block (seed.data.bytes.data (), seed.data.bytes.size ());
nano::raw_key password_l;
nano::wallet_value value (wallet->store.entry_get_raw (transaction, nano::wallet_store::wallet_key_special));
nano::raw_key kdf;
wallet->store.derive_key (kdf, transaction, "1");
password_l.decrypt (value.key, kdf, wallet->store.salt (transaction).owords[0]);
nano::uint256_union ciphertext;
ciphertext.encrypt (key.prv, password_l, wallet->store.salt (transaction).owords[0]);
wallet->store.entry_put_raw (transaction, key.pub, nano::wallet_value (ciphertext, 0));
seed_ciphertext.encrypt (seed, password_l, wallet->store.salt (transaction).owords[0]);
wallet->store.entry_put_raw (transaction, nano::wallet_store::seed_special, nano::wallet_value (seed_ciphertext, 0));
wallet->store.version_put (transaction, 3);
wallet->enter_password (transaction, "1");
ASSERT_TRUE (wallet->store.valid_password (transaction));
ASSERT_EQ (nano::wallet_store::version_current, wallet->store.version (transaction));
nano::raw_key prv;
ASSERT_FALSE (wallet->store.fetch (transaction, key.pub, prv));
ASSERT_EQ (key.prv, prv);
nano::raw_key seed_compare;
wallet->store.seed (seed_compare, transaction);
ASSERT_EQ (seed, seed_compare);
ASSERT_NE (seed_ciphertext, wallet->store.entry_get_raw (transaction, nano::wallet_store::seed_special).key);
}
TEST (wallet, upgrade_backup)
{
nano::system system (1);
auto dir (nano::unique_path ());
namespace fs = boost::filesystem;
fs::create_directory (dir);
/** Returns 'dir' if backup file cannot be found */
auto get_backup_path = [&dir]() {
for (fs::directory_iterator itr (dir); itr != fs::directory_iterator (); ++itr)
{
if (itr->path ().filename ().string ().find ("wallets_backup_") != std::string::npos)
{
return itr->path ();
}
}
return dir;
};
auto wallet_id = nano::random_wallet_id ();
{
auto node1 (std::make_shared<nano::node> (system.io_ctx, nano::get_available_port (), dir, system.alarm, system.logging, system.work));
ASSERT_FALSE (node1->init_error ());
auto wallet (node1->wallets.create (wallet_id));
ASSERT_NE (nullptr, wallet);
auto transaction (node1->wallets.tx_begin_write ());
wallet->store.version_put (transaction, 3);
}
ASSERT_EQ (get_backup_path ().string (), dir.string ());
// Check with config backup_before_upgrade = false
{
auto node1 (std::make_shared<nano::node> (system.io_ctx, nano::get_available_port (), dir, system.alarm, system.logging, system.work));
ASSERT_FALSE (node1->init_error ());
auto wallet (node1->wallets.open (wallet_id));
ASSERT_NE (nullptr, wallet);
auto transaction (node1->wallets.tx_begin_write ());
ASSERT_LT (3u, wallet->store.version (transaction));
wallet->store.version_put (transaction, 3);
}
ASSERT_EQ (get_backup_path ().string (), dir.string ());
// Now do the upgrade and confirm that backup is saved
{
nano::node_config node_config (nano::get_available_port (), system.logging);
node_config.backup_before_upgrade = true;
auto node1 (std::make_shared<nano::node> (system.io_ctx, dir, system.alarm, node_config, system.work));
ASSERT_FALSE (node1->init_error ());
auto wallet (node1->wallets.open (wallet_id));
ASSERT_NE (nullptr, wallet);
auto transaction (node1->wallets.tx_begin_read ());
ASSERT_LT (3u, wallet->store.version (transaction));
}
ASSERT_NE (get_backup_path ().string (), dir.string ());
}
TEST (wallet, no_work)
{
nano::system system (1);

View file

@ -74,58 +74,6 @@ TEST (wallets, remove)
}
}
TEST (wallets, upgrade)
{
// Don't test this in rocksdb mode
auto use_rocksdb_str = std::getenv ("TEST_USE_ROCKSDB");
if (use_rocksdb_str && boost::lexical_cast<int> (use_rocksdb_str) == 1)
{
return;
}
nano::system system;
nano::node_config node_config (nano::get_available_port (), system.logging);
node_config.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled;
system.add_node (node_config);
auto path (nano::unique_path ());
auto id = nano::random_wallet_id ();
nano::node_config node_config1 (nano::get_available_port (), system.logging);
node_config1.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled;
{
auto node1 (std::make_shared<nano::node> (system.io_ctx, path, system.alarm, node_config1, system.work));
ASSERT_FALSE (node1->init_error ());
bool error (false);
nano::wallets wallets (error, *node1);
wallets.create (id);
auto transaction_source (node1->wallets.env.tx_begin_write ());
auto tx_source = static_cast<MDB_txn *> (transaction_source.get_handle ());
auto & mdb_store (dynamic_cast<nano::mdb_store &> (node1->store));
auto transaction_destination (mdb_store.tx_begin_write ());
auto tx_destination = static_cast<MDB_txn *> (transaction_destination.get_handle ());
wallets.move_table (id.to_string (), tx_source, tx_destination);
node1->store.version_put (transaction_destination, 11);
nano::account_info info;
ASSERT_FALSE (mdb_store.account_get (transaction_destination, nano::genesis_account, info));
auto rep_block = node1->rep_block (nano::genesis_account);
nano::account_info_v13 account_info_v13 (info.head, rep_block, info.open_block, info.balance, info.modified, info.block_count, info.epoch ());
auto status (mdb_put (mdb_store.env.tx (transaction_destination), info.epoch () == nano::epoch::epoch_0 ? mdb_store.accounts_v0 : mdb_store.accounts_v1, nano::mdb_val (nano::test_genesis_key.pub), nano::mdb_val (account_info_v13), 0));
ASSERT_EQ (status, 0);
mdb_store.confirmation_height_del (transaction_destination, nano::genesis_account);
}
auto node1 (std::make_shared<nano::node> (system.io_ctx, path, system.alarm, node_config1, system.work));
ASSERT_EQ (1, node1->wallets.items.size ());
ASSERT_EQ (id, node1->wallets.items.begin ()->first);
auto transaction_new (node1->wallets.env.tx_begin_write ());
auto tx_new = static_cast<MDB_txn *> (transaction_new.get_handle ());
auto transaction_old (node1->store.tx_begin_write ());
auto tx_old = static_cast<MDB_txn *> (transaction_old.get_handle ());
MDB_dbi old_handle;
ASSERT_EQ (MDB_NOTFOUND, mdb_dbi_open (tx_old, id.to_string ().c_str (), 0, &old_handle));
MDB_dbi new_handle;
ASSERT_EQ (0, mdb_dbi_open (tx_new, id.to_string ().c_str (), 0, &new_handle));
}
// Keeps breaking whenever we add new DBs
TEST (wallets, DISABLED_wallet_create_max)
{

View file

@ -89,25 +89,6 @@ nano::error nano::rpc_config::deserialize_json (bool & upgraded_a, nano::jsoncon
{
if (!json.empty ())
{
auto version_l (json.get_optional<unsigned> ("version"));
if (!version_l)
{
version_l = 1;
json.put ("version", *version_l);
json.put ("max_request_size", max_request_size);
json.erase ("frontier_request_limit");
json.erase ("chain_request_limit");
nano::jsonconfig rpc_process_l;
rpc_process_l.put ("version", *version_l);
rpc_process_l.put ("io_threads", rpc_process.io_threads);
rpc_process_l.put ("ipc_address", rpc_process.ipc_address);
rpc_process_l.put ("ipc_port", rpc_process.ipc_port);
rpc_process_l.put ("num_ipc_connections", rpc_process.num_ipc_connections);
json.put_child ("process", rpc_process_l);
upgraded_a = true;
}
auto rpc_secure_l (json.get_optional_child ("secure"));
if (rpc_secure_l)
{
@ -125,15 +106,6 @@ nano::error nano::rpc_config::deserialize_json (bool & upgraded_a, nano::jsoncon
auto rpc_process_l (json.get_optional_child ("process"));
if (rpc_process_l)
{
auto version_l (rpc_process_l->get_optional<unsigned> ("version"));
if (!version_l)
{
version_l = 1;
rpc_process_l->put ("version", *version_l);
rpc_process_l->put ("ipc_address", rpc_process.ipc_address);
upgraded_a = true;
}
rpc_process_l->get_optional<unsigned> ("io_threads", rpc_process.io_threads);
rpc_process_l->get_optional<uint16_t> ("ipc_port", rpc_process.ipc_port);
boost::asio::ip::address_v6 ipc_address_l;

View file

@ -98,7 +98,6 @@ void nano::add_node_flag_options (boost::program_options::options_description &
("disable_block_processor_unchecked_deletion", "Disable deletion of unchecked blocks after processing")
("allow_bootstrap_peers_duplicates", "Allow multiple connections to same peer in bootstrap attempts")
("fast_bootstrap", "Increase bootstrap speed for high end nodes with higher limits")
("batch_size", boost::program_options::value<std::size_t>(), "(Deprecated) Increase sideband batch size, default 512. This change only affects nodes upgrading from v17 (or earlier) of the node.")
("block_processor_batch_size", boost::program_options::value<std::size_t>(), "Increase block processor transaction batch write size, default 0 (limited by config block_processor_batch_max_time), 256k for fast_bootstrap")
("block_processor_full_size", boost::program_options::value<std::size_t>(), "Increase block processor allowed blocks queue size before dropping live network packets and holding bootstrap download, default 65536, 1 million for fast_bootstrap")
("block_processor_verification_size", boost::program_options::value<std::size_t>(), "Increase batch signature verification size in block processor, default 0 (limited by config signature_checker_threads), unlimited for fast_bootstrap")
@ -111,11 +110,6 @@ void nano::add_node_flag_options (boost::program_options::options_description &
std::error_code nano::update_flags (nano::node_flags & flags_a, boost::program_options::variables_map const & vm)
{
std::error_code ec;
auto batch_size_it = vm.find ("batch_size");
if (batch_size_it != vm.end ())
{
flags_a.sideband_batch_size = batch_size_it->second.as<size_t> ();
}
flags_a.disable_backup = (vm.count ("disable_backup") > 0);
flags_a.disable_lazy_bootstrap = (vm.count ("disable_lazy_bootstrap") > 0);
flags_a.disable_legacy_bootstrap = (vm.count ("disable_legacy_bootstrap") > 0);

View file

@ -97,8 +97,6 @@ nano::error nano::daemon_config::deserialize_json (bool & upgraded_a, nano::json
{
if (!json.empty ())
{
int version_l;
json.get_optional<int> ("version", version_l);
json.get_optional<bool> ("rpc_enable", rpc_enable);
auto rpc_l (json.get_required_child ("rpc"));

View file

@ -108,15 +108,6 @@ nano::error nano::ipc::ipc_config::deserialize_json (bool & upgraded_a, nano::js
auto domain_l (json.get_optional_child ("local"));
if (domain_l)
{
auto version_l (domain_l->get_optional<unsigned> ("version"));
if (!version_l)
{
version_l = 1;
domain_l->put ("version", *version_l);
domain_l->put ("allow_unsafe", transport_domain.allow_unsafe);
upgraded_a = true;
}
domain_l->get_optional<long> ("io_threads", transport_domain.io_threads, -1);
domain_l->get_optional<bool> ("allow_unsafe", transport_domain.allow_unsafe);
domain_l->get<bool> ("enable", transport_domain.enabled);

View file

@ -40,7 +40,7 @@ void mdb_val::convert_buffer_to_value ()
}
}
nano::mdb_store::mdb_store (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, nano::lmdb_config const & lmdb_config_a, size_t const batch_size_a, bool backup_before_upgrade_a) :
nano::mdb_store::mdb_store (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, nano::lmdb_config const & lmdb_config_a, bool backup_before_upgrade_a) :
logger (logger_a),
env (error, path_a, nano::mdb_env::options::make ().set_config (lmdb_config_a).set_use_no_mem_init (true)),
mdb_txn_tracker (logger_a, txn_tracking_config_a, block_processor_batch_max_time_a),
@ -84,7 +84,7 @@ txn_tracking_enabled (txn_tracking_config_a.enable)
open_databases (error, transaction, MDB_CREATE);
if (!error)
{
error |= do_upgrades (transaction, needs_vacuuming, batch_size_a);
error |= do_upgrades (transaction, needs_vacuuming);
}
}
@ -186,11 +186,6 @@ void nano::mdb_store::open_databases (bool & error_a, nano::transaction const &
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;
error_a |= mdb_dbi_open (env.tx (transaction_a), "confirmation_height", flags, &confirmation_height) != 0;
if (!full_sideband (transaction_a))
{
// The blocks_info database is no longer used, but need opening so that it can be deleted during an upgrade
error_a |= mdb_dbi_open (env.tx (transaction_a), "blocks_info", flags, &blocks_info) != 0;
}
error_a |= mdb_dbi_open (env.tx (transaction_a), "accounts", flags, &accounts_v0) != 0;
accounts = accounts_v0;
error_a |= mdb_dbi_open (env.tx (transaction_a), "pending", flags, &pending_v0) != 0;
@ -218,37 +213,28 @@ void nano::mdb_store::open_databases (bool & error_a, nano::transaction const &
}
}
bool nano::mdb_store::do_upgrades (nano::write_transaction & transaction_a, bool & needs_vacuuming, size_t batch_size_a)
bool nano::mdb_store::do_upgrades (nano::write_transaction & transaction_a, bool & needs_vacuuming)
{
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_a);
case 13:
upgrade_v13_to_v14 (transaction_a);
logger.always_log (boost::str (boost::format ("The version of the ledger (%1%) is lower than the minimum (%2%) which is supported for upgrades. Either upgrade to a v19, v20 or v21 node first or delete the ledger.") % version_l % minimum_version));
error = true;
break;
case 14:
upgrade_v14_to_v15 (transaction_a);
needs_vacuuming = true;
@ -270,312 +256,6 @@ bool nano::mdb_store::do_upgrades (nano::write_transaction & transaction_a, bool
return error;
}
void nano::mdb_store::upgrade_v1_to_v2 (nano::write_transaction const & transaction_a)
{
version_put (transaction_a, 2);
nano::account account (1);
while (!account.is_zero ())
{
nano::mdb_iterator<nano::account, nano::account_info_v1> i (transaction_a, accounts_v0, nano::mdb_val (account));
std::cerr << std::hex;
if (i != nano::mdb_iterator<nano::account, nano::account_info_v1>{})
{
account = nano::account (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::write_transaction const & transaction_a)
{
version_put (transaction_a, 3);
mdb_drop (env.tx (transaction_a), representation, 0);
for (auto i (std::make_unique<nano::mdb_iterator<nano::account, nano::account_info_v5>> (transaction_a, accounts_v0)), n (std::make_unique<nano::mdb_iterator<nano::account, nano::account_info_v5>> ()); *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);
debug_assert (!visitor.result.is_zero ());
info.rep_block = visitor.result;
auto impl (boost::polymorphic_downcast<nano::mdb_iterator<nano::account, nano::account_info_v5> *> (i.get ()));
mdb_cursor_put (impl->cursor, nano::mdb_val (account_l), nano::mdb_val (sizeof (info), &info), MDB_CURRENT);
}
}
void nano::mdb_store::upgrade_v3_to_v4 (nano::write_transaction const & transaction_a)
{
version_put (transaction_a, 4);
std::queue<std::pair<nano::pending_key, nano::pending_info_v14>> items;
for (auto i (nano::store_iterator<nano::block_hash, nano::pending_info_v3> (std::make_unique<nano::mdb_iterator<nano::block_hash, nano::pending_info_v3>> (transaction_a, pending_v0))), n (nano::store_iterator<nano::block_hash, nano::pending_info_v3> (nullptr)); i != n; ++i)
{
nano::block_hash const & hash (i->first);
nano::pending_info_v3 const & info (i->second);
items.emplace (nano::pending_key (info.destination, hash), nano::pending_info_v14 (info.source, info.amount, nano::epoch::epoch_0));
}
mdb_drop (env.tx (transaction_a), pending_v0, 0);
while (!items.empty ())
{
auto status (mdb_put (env.tx (transaction_a), pending, nano::mdb_val (items.front ().first), nano::mdb_val (items.front ().second), 0));
debug_assert (success (status));
items.pop ();
}
}
void nano::mdb_store::upgrade_v4_to_v5 (nano::write_transaction const & transaction_a)
{
version_put (transaction_a, 5);
for (auto i (nano::store_iterator<nano::account, nano::account_info_v5> (std::make_unique<nano::mdb_iterator<nano::account, nano::account_info_v5>> (transaction_a, accounts_v0))), n (nano::store_iterator<nano::account, nano::account_info_v5> (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<uint8_t> vector;
{
nano::vectorstream stream (vector);
block->serialize (stream);
nano::write (stream, successor.bytes);
}
block_raw_put (transaction_a, vector, block->type (), hash);
if (!block->previous ().is_zero ())
{
nano::block_type type;
auto value (block_raw_get (transaction_a, block->previous (), type));
debug_assert (value.size () != 0);
std::vector<uint8_t> data (static_cast<uint8_t *> (value.data ()), static_cast<uint8_t *> (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, block->previous ());
}
}
successor = hash;
block = block_get (transaction_a, block->previous ());
}
}
}
void nano::mdb_store::upgrade_v5_to_v6 (nano::write_transaction const & transaction_a)
{
version_put (transaction_a, 6);
std::deque<std::pair<nano::account, nano::account_info_v13>> headers;
for (auto i (nano::store_iterator<nano::account, nano::account_info_v5> (std::make_unique<nano::mdb_iterator<nano::account, nano::account_info_v5>> (transaction_a, accounts_v0))), n (nano::store_iterator<nano::account, nano::account_info_v5> (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));
debug_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::write_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::write_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::write_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<nano::block> block (std::move (genesis.open));
nano::keypair junk;
for (nano::mdb_iterator<nano::account, uint64_t> i (transaction_a, sequence), n (nano::mdb_iterator<nano::account, uint64_t>{}); i != n; ++i)
{
nano::bufferstream stream (reinterpret_cast<uint8_t const *> (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<uint8_t> 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);
debug_assert (!error);
}
mdb_drop (env.tx (transaction_a), sequence, 1);
}
void nano::mdb_store::upgrade_v10_to_v11 (nano::write_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::write_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::mdb_merge_iterator<nano::account, nano::account_info_v13> current (transaction_a, accounts_v0, accounts_v1, nano::mdb_val (account));
nano::mdb_merge_iterator<nano::account, nano::account_info_v13> end{};
if (current != end)
{
first = nano::account (current->first);
second = nano::account_info_v13 (current->second);
}
}
if (!first.is_zero ())
{
auto hash (second.open_block);
uint64_t height (1);
nano::block_sideband_v14 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;
}
bool is_state_block_v1 = false;
auto block = block_get_v14 (transaction_a, hash, &sideband, &is_state_block_v1);
debug_assert (block != nullptr);
if (sideband.height == 0)
{
sideband.height = height;
std::vector<uint8_t> vector;
{
nano::vectorstream stream (vector);
block->serialize (stream);
sideband.serialize (stream);
}
nano::mdb_val value{ vector.size (), (void *)vector.data () };
MDB_dbi database = is_state_block_v1 ? state_blocks_v1 : table_to_dbi (block_database (block->type ()));
auto status = mdb_put (env.tx (transaction_a), database, nano::mdb_val (hash), value, 0);
release_assert (success (status));
nano::block_predecessor_set<MDB_val, nano::mdb_store> predecessor (transaction_a, *this);
block->visit (predecessor);
debug_assert (block->previous ().is_zero () || block_successor (transaction_a, block->previous ()) == 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::write_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::mdb_merge_iterator<nano::account, nano::account_info_v13> i (transaction_a, accounts_v0, accounts_v1);
nano::mdb_merge_iterator<nano::account, nano::account_info_v13> n{};
std::vector<std::pair<nano::account, nano::account_info_v14>> account_infos;
account_infos.reserve (count (transaction_a, accounts_v0) + count (transaction_a, accounts_v1));
for (; i != n; ++i)
{
nano::account account (i->first);
nano::account_info_v13 account_info_v13 (i->second);
uint64_t confirmation_height = 0;
if (account == network_params.ledger.genesis_account)
{
confirmation_height = 1;
}
account_infos.emplace_back (account, nano::account_info_v14{ 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, i.from_first_database ? nano::epoch::epoch_0 : nano::epoch::epoch_1 });
}
for (auto const & account_info : account_infos)
{
auto status1 (mdb_put (env.tx (transaction_a), account_info.second.epoch == nano::epoch::epoch_0 ? accounts_v0 : accounts_v1, nano::mdb_val (account_info.first), nano::mdb_val (account_info.second), 0));
release_assert (status1 == 0);
}
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::upgrade_v14_to_v15 (nano::write_transaction & transaction_a)
{
logger.always_log ("Preparing v14 to v15 database upgrade...");
@ -885,39 +565,6 @@ void nano::mdb_store::version_put (nano::write_transaction const & transaction_a
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
{
debug_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;
debug_assert (value.size () == sizeof (block_info_a.account.bytes) + sizeof (block_info_a.balance.bytes));
nano::bufferstream stream (reinterpret_cast<uint8_t const *> (value.data ()), value.size ());
auto error1 (nano::try_read (stream, block_info_a.account));
(void)error1;
debug_assert (!error1);
auto error2 (nano::try_read (stream, block_info_a.balance));
(void)error2;
debug_assert (!error2);
}
return result;
}
bool nano::mdb_store::exists (nano::transaction const & transaction_a, tables table_a, nano::mdb_val const & key_a) const
@ -986,8 +633,6 @@ MDB_dbi nano::mdb_store::table_to_dbi (tables table_a) const
return state_blocks;
case tables::pending:
return pending;
case tables::blocks_info:
return blocks_info;
case tables::unchecked:
return unchecked;
case tables::vote:
@ -1082,25 +727,9 @@ bool nano::mdb_store::init_error () const
}
// All the v14 functions below are only needed during upgrades
bool nano::mdb_store::entry_has_sideband_v14 (size_t entry_size_a, nano::block_type type_a) const
{
return (entry_size_a == nano::block::size (type_a) + nano::block_sideband_v14::size (type_a));
}
size_t nano::mdb_store::block_successor_offset_v14 (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_v14 (entry_size_a, type_a))
{
result = entry_size_a - nano::block_sideband_v14::size (type_a);
}
else
{
// Read old successor-only sideband
debug_assert (entry_size_a == nano::block::size (type_a) + sizeof (nano::uint256_union));
result = entry_size_a - sizeof (nano::uint256_union);
}
return result;
return entry_size_a - nano::block_sideband_v14::size (type_a);
}
nano::block_hash nano::mdb_store::block_successor_v14 (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const
@ -1198,69 +827,6 @@ boost::optional<nano::mdb_val> nano::mdb_store::block_raw_get_by_type_v14 (nano:
return result;
}
nano::account nano::mdb_store::block_account_v14 (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const
{
nano::block_sideband_v14 sideband;
auto block (block_get_v14 (transaction_a, hash_a, &sideband));
nano::account result (block->account ());
if (result.is_zero ())
{
result = sideband.account;
}
debug_assert (!result.is_zero ());
return result;
}
// Return account containing hash
nano::account nano::mdb_store::block_account_computed_v14 (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const
{
debug_assert (!full_sideband (transaction_a));
nano::account result (0);
auto hash (hash_a);
while (result.is_zero ())
{
auto block (block_get_v14 (transaction_a, hash));
debug_assert (block);
result = block->account ();
if (result.is_zero ())
{
auto type (nano::block_type::invalid);
auto value (block_raw_get_v14 (transaction_a, block->previous (), type));
if (entry_has_sideband_v14 (value.size (), type))
{
result = block_account_v14 (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_v14 (transaction_a, hash));
debug_assert (!successor.is_zero ());
hash = successor;
}
}
}
}
}
debug_assert (!result.is_zero ());
return result;
}
nano::uint128_t nano::mdb_store::block_balance_computed_v14 (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const
{
debug_assert (!full_sideband (transaction_a));
summation_visitor visitor (transaction_a, *this, true);
return visitor.compute_balance (hash_a);
}
std::shared_ptr<nano::block> nano::mdb_store::block_get_v14 (nano::transaction const & transaction_a, nano::block_hash const & hash_a, nano::block_sideband_v14 * sideband_a, bool * is_state_v1) const
{
nano::block_type type;
@ -1274,21 +840,9 @@ std::shared_ptr<nano::block> nano::mdb_store::block_get_v14 (nano::transaction c
if (sideband_a)
{
sideband_a->type = type;
if (full_sideband (transaction_a) || entry_has_sideband_v14 (value.size (), type))
{
bool error = sideband_a->deserialize (stream);
(void)error;
debug_assert (!error);
}
else
{
// Reconstruct sideband data for block.
sideband_a->account = block_account_computed_v14 (transaction_a, hash_a);
sideband_a->balance = block_balance_computed_v14 (transaction_a, hash_a);
sideband_a->successor = block_successor_v14 (transaction_a, hash_a);
sideband_a->height = 0;
sideband_a->timestamp = 0;
}
bool error = sideband_a->deserialize (stream);
(void)error;
debug_assert (!error);
}
}
return result;

View file

@ -37,14 +37,12 @@ public:
using block_store_partial::block_exists;
using block_store_partial::unchecked_put;
mdb_store (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), nano::lmdb_config const & lmdb_config_a = nano::lmdb_config{}, size_t batch_size = 512, bool backup_before_upgrade = false);
mdb_store (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), nano::lmdb_config const & lmdb_config_a = nano::lmdb_config{}, bool backup_before_upgrade = false);
nano::write_transaction tx_begin_write (std::vector<nano::tables> const & tables_requiring_lock = {}, std::vector<nano::tables> const & tables_no_lock = {}) override;
nano::read_transaction tx_begin_read () override;
std::string vendor_get () const override;
bool block_info_get (nano::transaction const &, nano::block_hash const &, nano::block_info &) const override;
void version_put (nano::write_transaction const &, int) override;
void serialize_mdb_tracker (boost::property_tree::ptree &, std::chrono::milliseconds, std::chrono::milliseconds) override;
@ -77,7 +75,7 @@ public:
MDB_dbi accounts_v1{ 0 };
/**
* Maps account v0 to account information, head, rep, open, balance, timestamp, block count and epoch. (Removed)
* Maps account v0 to account information, head, rep, open, balance, timestamp, block count and epoch
* nano::account -> nano::block_hash, nano::block_hash, nano::block_hash, nano::amount, uint64_t, uint64_t, nano::epoch
*/
MDB_dbi accounts{ 0 };
@ -142,12 +140,6 @@ public:
*/
MDB_dbi pending{ 0 };
/**
* Maps block hash to account and balance. (Removed)
* block_hash -> nano::account, nano::amount
*/
MDB_dbi blocks_info{ 0 };
/**
* Representative weights. (Removed)
* nano::account -> nano::uint128_t
@ -217,29 +209,13 @@ public:
// These are only use in the upgrade process.
std::shared_ptr<nano::block> block_get_v14 (nano::transaction const & transaction_a, nano::block_hash const & hash_a, nano::block_sideband_v14 * sideband_a = nullptr, bool * is_state_v1 = nullptr) const override;
bool entry_has_sideband_v14 (size_t entry_size_a, nano::block_type type_a) const;
size_t block_successor_offset_v14 (nano::transaction const & transaction_a, size_t entry_size_a, nano::block_type type_a) const;
nano::block_hash block_successor_v14 (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const;
nano::mdb_val block_raw_get_v14 (nano::transaction const & transaction_a, nano::block_hash const & hash_a, nano::block_type & type_a, bool * is_state_v1 = nullptr) const;
boost::optional<nano::mdb_val> block_raw_get_by_type_v14 (nano::transaction const & transaction_a, nano::block_hash const & hash_a, nano::block_type & type_a, bool * is_state_v1) const;
nano::account block_account_computed_v14 (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const;
nano::account block_account_v14 (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const;
nano::uint128_t block_balance_computed_v14 (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const;
private:
bool do_upgrades (nano::write_transaction &, bool &, size_t);
void upgrade_v1_to_v2 (nano::write_transaction const &);
void upgrade_v2_to_v3 (nano::write_transaction const &);
void upgrade_v3_to_v4 (nano::write_transaction const &);
void upgrade_v4_to_v5 (nano::write_transaction const &);
void upgrade_v5_to_v6 (nano::write_transaction const &);
void upgrade_v6_to_v7 (nano::write_transaction const &);
void upgrade_v7_to_v8 (nano::write_transaction const &);
void upgrade_v8_to_v9 (nano::write_transaction const &);
void upgrade_v10_to_v11 (nano::write_transaction const &);
void upgrade_v11_to_v12 (nano::write_transaction const &);
void upgrade_v12_to_v13 (nano::write_transaction &, size_t);
void upgrade_v13_to_v14 (nano::write_transaction const &);
bool do_upgrades (nano::write_transaction &, bool &);
void upgrade_v14_to_v15 (nano::write_transaction &);
void upgrade_v15_to_v16 (nano::write_transaction const &);
void upgrade_v16_to_v17 (nano::write_transaction const &);

View file

@ -226,26 +226,12 @@ bool nano::logging::upgrade_json (unsigned version_a, nano::jsonconfig & json)
switch (version_a)
{
case 1:
json.put ("vote", vote_logging_value);
case 2:
json.put ("rotation_size", rotation_size);
json.put ("flush", true);
case 3:
json.put ("network_node_id_handshake", false);
case 4:
json.put ("upnp_details", "false");
json.put ("timing", "false");
case 5:
uintmax_t config_max_size;
json.get<uintmax_t> ("max_size", config_max_size);
max_size = std::max (max_size, config_max_size);
json.put ("max_size", max_size);
json.put ("log_ipc", true);
case 6:
json.put ("min_time_between_output", min_time_between_log_output.count ());
json.put ("network_timeout", network_timeout_logging_value);
json.erase ("log_rpc");
break;
throw std::runtime_error ("logging_config version is unsupported for upgrade. Upgrade to a v19, v20 or v21 node first, or delete the config and ledger files");
case 7:
json.put ("single_line_record", single_line_record_value);
case 8:
@ -260,23 +246,7 @@ bool nano::logging::upgrade_json (unsigned version_a, nano::jsonconfig & json)
nano::error nano::logging::deserialize_json (bool & upgraded_a, nano::jsonconfig & json)
{
int version_l{ 1 };
if (!json.has_key ("version"))
{
json.put ("version", version_l);
auto work_peers_l (json.get_optional_child ("work_peers"));
if (!work_peers_l)
{
nano::jsonconfig peers;
json.put_child ("work_peers", peers);
}
upgraded_a = true;
}
else
{
json.get_required<int> ("version", version_l);
}
json.get_required<int> ("version", version_l);
upgraded_a |= upgrade_json (version_l, json);
json.get<bool> ("ledger", ledger_logging_value);
json.get<bool> ("ledger_duplicate", ledger_duplicate_logging_value);

View file

@ -98,7 +98,7 @@ alarm (alarm_a),
work (work_a),
distributed_work (*this),
logger (config_a.logging.min_time_between_log_output),
store_impl (nano::make_store (logger, application_path_a, flags.read_only, true, config_a.rocksdb_config, config_a.diagnostics_config.txn_tracking, config_a.block_processor_batch_max_time, config_a.lmdb_config, flags.sideband_batch_size, config_a.backup_before_upgrade, config_a.rocksdb_config.enable)),
store_impl (nano::make_store (logger, application_path_a, flags.read_only, true, config_a.rocksdb_config, config_a.diagnostics_config.txn_tracking, config_a.block_processor_batch_max_time, config_a.lmdb_config, config_a.backup_before_upgrade, config_a.rocksdb_config.enable)),
store (*store_impl),
wallets_store_impl (std::make_unique<nano::mdb_wallets_store> (application_path_a / "wallets.ldb", config_a.lmdb_config)),
wallets_store (*wallets_store_impl),
@ -1694,7 +1694,7 @@ nano::node_flags const & nano::inactive_node_flag_defaults ()
return node_flags;
}
std::unique_ptr<nano::block_store> nano::make_store (nano::logger_mt & logger, boost::filesystem::path const & path, bool read_only, bool add_db_postfix, nano::rocksdb_config const & rocksdb_config, nano::txn_tracking_config const & txn_tracking_config_a, std::chrono::milliseconds block_processor_batch_max_time_a, nano::lmdb_config const & lmdb_config_a, size_t batch_size, bool backup_before_upgrade, bool use_rocksdb_backend)
std::unique_ptr<nano::block_store> nano::make_store (nano::logger_mt & logger, boost::filesystem::path const & path, bool read_only, bool add_db_postfix, nano::rocksdb_config const & rocksdb_config, nano::txn_tracking_config const & txn_tracking_config_a, std::chrono::milliseconds block_processor_batch_max_time_a, nano::lmdb_config const & lmdb_config_a, bool backup_before_upgrade, bool use_rocksdb_backend)
{
#if NANO_ROCKSDB
auto make_rocksdb = [&logger, add_db_postfix, &path, &rocksdb_config, read_only]() {
@ -1725,5 +1725,5 @@ std::unique_ptr<nano::block_store> nano::make_store (nano::logger_mt & logger, b
#endif
}
return std::make_unique<nano::mdb_store> (logger, add_db_postfix ? path / "data.ldb" : path, txn_tracking_config_a, block_processor_batch_max_time_a, lmdb_config_a, batch_size, backup_before_upgrade);
return std::make_unique<nano::mdb_store> (logger, add_db_postfix ? path / "data.ldb" : path, txn_tracking_config_a, block_processor_batch_max_time_a, lmdb_config_a, backup_before_upgrade);
}

View file

@ -43,39 +43,6 @@ nano::error nano::node_rpc_config::deserialize_toml (nano::tomlconfig & toml)
nano::error nano::node_rpc_config::deserialize_json (bool & upgraded_a, nano::jsonconfig & json, boost::filesystem::path const & data_path)
{
auto version_l (json.get_optional<unsigned> ("version"));
if (!version_l)
{
json.erase ("frontier_request_limit");
json.erase ("chain_request_limit");
// Don't migrate enable_sign_hash as this is not needed by the external rpc process, but first save it.
json.get_optional ("enable_sign_hash", enable_sign_hash, false);
json.erase ("enable_sign_hash");
json.erase ("max_work_generate_difficulty");
migrate (json, data_path);
json.put ("enable_sign_hash", enable_sign_hash);
// Remove options no longer needed after migration
json.erase ("enable_control");
json.erase ("address");
json.erase ("port");
json.erase ("max_json_depth");
json.erase ("max_request_size");
version_l = 1;
json.put ("version", *version_l);
nano::jsonconfig child_process_l;
child_process_l.put ("enable", child_process.enable);
child_process_l.put ("rpc_path", child_process.rpc_path);
json.put_child ("child_process", child_process_l);
upgraded_a = true;
}
json.get_optional<bool> ("enable_sign_hash", enable_sign_hash);
auto child_process_l (json.get_optional_child ("child_process"));
@ -87,15 +54,3 @@ nano::error nano::node_rpc_config::deserialize_json (bool & upgraded_a, nano::js
return json.get_error ();
}
void nano::node_rpc_config::migrate (nano::jsonconfig & json, boost::filesystem::path const & data_path)
{
nano::jsonconfig rpc_json;
auto rpc_config_path = nano::get_rpc_config_path (data_path);
auto rpc_error (rpc_json.read (rpc_config_path));
if (rpc_error || rpc_json.empty ())
{
// Migrate RPC info across
json.write (rpc_config_path);
}
}

View file

@ -36,8 +36,5 @@ public:
{
return 1;
}
private:
void migrate (nano::jsonconfig & json, boost::filesystem::path const & data_path);
};
}

View file

@ -513,119 +513,22 @@ bool nano::node_config::upgrade_json (unsigned version_a, nano::jsonconfig & jso
switch (version_a)
{
case 1:
{
auto reps_l (json.get_required_child ("preconfigured_representatives"));
nano::jsonconfig reps;
reps_l.array_entries<std::string> ([&reps](std::string entry) {
nano::account account;
account.decode_account (entry);
reps.push (account.to_account ());
});
json.replace_child ("preconfigured_representatives", reps);
}
case 2:
{
json.put ("inactive_supply", nano::uint128_union (0).to_string_dec ());
json.put ("password_fanout", std::to_string (1024));
json.put ("io_threads", std::to_string (io_threads));
json.put ("work_threads", std::to_string (work_threads));
}
case 3:
json.erase ("receive_minimum");
json.put ("receive_minimum", nano::xrb_ratio.convert_to<std::string> ());
case 4:
json.erase ("receive_minimum");
json.put ("receive_minimum", nano::xrb_ratio.convert_to<std::string> ());
case 5:
json.put ("enable_voting", enable_voting);
json.erase ("packet_delay_microseconds");
json.erase ("rebroadcast_delay");
json.erase ("creation_rebroadcast");
case 6:
json.put ("bootstrap_connections", 16);
json.put ("callback_address", "");
json.put ("callback_port", 0);
json.put ("callback_target", "");
case 7:
json.put ("lmdb_max_dbs", 128);
case 8:
json.put ("bootstrap_connections_max", "64");
case 9:
json.put ("state_block_parse_canary", nano::block_hash (0).to_string ());
json.put ("state_block_generate_canary", nano::block_hash (0).to_string ());
case 10:
json.put ("online_weight_minimum", online_weight_minimum.to_string_dec ());
json.put ("online_weight_quorom", std::to_string (online_weight_quorum));
json.erase ("inactive_supply");
case 11:
{
// Rename
std::string online_weight_quorum_l;
json.get<std::string> ("online_weight_quorom", online_weight_quorum_l);
json.erase ("online_weight_quorom");
json.put ("online_weight_quorum", online_weight_quorum_l);
}
case 12:
json.erase ("state_block_parse_canary");
json.erase ("state_block_generate_canary");
case 13:
json.put ("generate_hash_votes_at", 0);
case 14:
json.put ("network_threads", std::to_string (network_threads));
json.erase ("generate_hash_votes_at");
json.put ("block_processor_batch_max_time", block_processor_batch_max_time.count ());
case 15:
{
json.put ("allow_local_peers", allow_local_peers);
// Update to the new preconfigured_peers url for rebrand if it is found (rai -> nano)
auto peers_l (json.get_required_child (preconfigured_peers_key));
nano::jsonconfig peers;
peers_l.array_entries<std::string> ([&peers](std::string entry) {
if (entry == "rai-beta.raiblocks.net")
{
entry = default_beta_peer_network;
}
else if (entry == "rai.raiblocks.net")
{
entry = default_live_peer_network;
}
peers.push (std::move (entry));
});
json.replace_child (preconfigured_peers_key, peers);
json.put ("vote_minimum", vote_minimum.to_string_dec ());
nano::jsonconfig ipc_l;
ipc_config.serialize_json (ipc_l);
json.put_child ("ipc", ipc_l);
json.put (signature_checker_threads_key, signature_checker_threads);
json.put ("unchecked_cutoff_time", unchecked_cutoff_time.count ());
}
case 16:
{
nano::jsonconfig websocket_l;
websocket_config.serialize_json (websocket_l);
json.put_child ("websocket", websocket_l);
nano::jsonconfig diagnostics_l;
diagnostics_config.serialize_json (diagnostics_l);
json.put_child ("diagnostics", diagnostics_l);
json.put ("tcp_io_timeout", tcp_io_timeout.count ());
json.put (pow_sleep_interval_key, pow_sleep_interval.count ());
json.put ("external_address", external_address);
json.put ("external_port", external_port);
json.put ("tcp_incoming_connections_max", tcp_incoming_connections_max);
json.put ("vote_generator_delay", vote_generator_delay.count ());
json.put ("vote_generator_threshold", vote_generator_threshold);
json.put ("use_memory_pools", use_memory_pools);
json.put ("confirmation_history_size", confirmation_history_size);
json.put ("active_elections_size", active_elections_size);
json.put ("bandwidth_limit", bandwidth_limit);
json.put ("conf_height_processor_batch_min_time", conf_height_processor_batch_min_time.count ());
}
throw std::runtime_error ("node_config version unsupported for upgrade. Upgrade to a v19, v20 or v21 node first, or delete the config and ledger files");
case 17:
{
json.put ("active_elections_size", 10000); // Update value
@ -645,21 +548,8 @@ nano::error nano::node_config::deserialize_json (bool & upgraded_a, nano::jsonco
{
try
{
auto version_l (json.get_optional<unsigned> ("version"));
if (!version_l)
{
version_l = 1;
json.put ("version", version_l);
auto work_peers_l (json.get_optional_child ("work_peers"));
if (!work_peers_l)
{
nano::jsonconfig empty;
json.put_child ("work_peers", empty);
}
upgraded_a = true;
}
upgraded_a |= upgrade_json (version_l.get (), json);
auto version_l (json.get<unsigned> ("version"));
upgraded_a |= upgrade_json (version_l, json);
auto logging_l (json.get_required_child ("logging"));
logging.deserialize_json (upgraded_a, logging_l);

View file

@ -142,7 +142,6 @@ public:
nano::confirmation_height_mode confirmation_height_processor_mode{ nano::confirmation_height_mode::automatic };
nano::generate_cache generate_cache;
bool inactive_node{ false };
size_t sideband_batch_size{ 512 };
size_t block_processor_batch_size{ 0 };
size_t block_processor_full_size{ 65536 };
size_t block_processor_verification_size{ 0 };

View file

@ -171,8 +171,6 @@ rocksdb::ColumnFamilyHandle * nano::rocksdb_store::table_to_column_family (table
return get_handle ("state_blocks");
case tables::pending:
return get_handle ("pending");
case tables::blocks_info:
debug_assert (false);
case tables::representation:
return get_handle ("representation");
case tables::unchecked:
@ -191,7 +189,7 @@ rocksdb::ColumnFamilyHandle * nano::rocksdb_store::table_to_column_family (table
return get_handle ("confirmation_height");
default:
release_assert (false);
return get_handle ("peers");
return get_handle ("");
}
}
@ -227,13 +225,6 @@ int nano::rocksdb_store::del (nano::write_transaction const & transaction_a, tab
return tx (transaction_a)->Delete (table_to_column_family (table_a), key_a).code ();
}
bool nano::rocksdb_store::block_info_get (nano::transaction const &, nano::block_hash const &, nano::block_info &) const
{
// Should not be called as the RocksDB backend does not use this table
debug_assert (false);
return true;
}
void nano::rocksdb_store::version_put (nano::write_transaction const & transaction_a, int version_a)
{
debug_assert (transaction_a.contains (tables::meta));

View file

@ -33,7 +33,6 @@ public:
std::string vendor_get () const override;
bool block_info_get (nano::transaction const &, nano::block_hash const &, nano::block_info &) const override;
size_t count (nano::transaction const & transaction_a, tables table_a) const override;
void version_put (nano::write_transaction const &, int) override;

View file

@ -157,12 +157,6 @@ bool nano::wallet_store::attempt_password (nano::transaction const & transaction
{
switch (version (transaction_a))
{
case version_1:
upgrade_v1_v2 (transaction_a);
case version_2:
upgrade_v2_v3 (transaction_a);
case version_3:
upgrade_v3_v4 (transaction_a);
case version_4:
break;
default:
@ -651,102 +645,6 @@ void nano::wallet_store::version_put (nano::transaction const & transaction_a, u
entry_put_raw (transaction_a, nano::wallet_store::version_special, nano::wallet_value (entry, 0));
}
void nano::wallet_store::upgrade_v1_v2 (nano::transaction const & transaction_a)
{
debug_assert (version (transaction_a) == 1);
nano::raw_key zero_password;
nano::wallet_value value (entry_get_raw (transaction_a, nano::wallet_store::wallet_key_special));
nano::raw_key kdf;
kdf.data.clear ();
zero_password.decrypt (value.key, kdf, salt (transaction_a).owords[0]);
derive_key (kdf, transaction_a, "");
nano::raw_key empty_password;
empty_password.decrypt (value.key, kdf, salt (transaction_a).owords[0]);
for (auto i (begin (transaction_a)), n (end ()); i != n; ++i)
{
nano::public_key const & key (i->first);
nano::raw_key prv;
if (fetch (transaction_a, key, prv))
{
// Key failed to decrypt despite valid password
nano::wallet_value data (entry_get_raw (transaction_a, key));
prv.decrypt (data.key, zero_password, salt (transaction_a).owords[0]);
nano::public_key compare (nano::pub_key (prv.as_private_key ()));
if (compare == key)
{
// If we successfully decrypted it, rewrite the key back with the correct wallet key
insert_adhoc (transaction_a, prv);
}
else
{
// Also try the empty password
nano::wallet_value data (entry_get_raw (transaction_a, key));
prv.decrypt (data.key, empty_password, salt (transaction_a).owords[0]);
nano::public_key compare (nano::pub_key (prv.as_private_key ()));
if (compare == key)
{
// If we successfully decrypted it, rewrite the key back with the correct wallet key
insert_adhoc (transaction_a, prv);
}
}
}
}
version_put (transaction_a, 2);
}
void nano::wallet_store::upgrade_v2_v3 (nano::transaction const & transaction_a)
{
debug_assert (version (transaction_a) == 2);
nano::raw_key seed;
random_pool::generate_block (seed.data.bytes.data (), seed.data.bytes.size ());
seed_set (transaction_a, seed);
entry_put_raw (transaction_a, nano::wallet_store::deterministic_index_special, nano::wallet_value (nano::uint256_union (0), 0));
version_put (transaction_a, 3);
}
void nano::wallet_store::upgrade_v3_v4 (nano::transaction const & transaction_a)
{
debug_assert (version (transaction_a) == 3);
version_put (transaction_a, 4);
debug_assert (valid_password (transaction_a));
nano::raw_key seed;
nano::wallet_value value (entry_get_raw (transaction_a, nano::wallet_store::seed_special));
nano::raw_key password_l;
wallet_key (password_l, transaction_a);
seed.decrypt (value.key, password_l, salt (transaction_a).owords[0]);
nano::uint256_union ciphertext;
ciphertext.encrypt (seed, password_l, salt (transaction_a).owords[seed_iv_index]);
entry_put_raw (transaction_a, nano::wallet_store::seed_special, nano::wallet_value (ciphertext, 0));
for (auto i (begin (transaction_a)), n (end ()); i != n; ++i)
{
nano::wallet_value value (i->second);
if (!value.key.is_zero ())
{
switch (key_type (i->second))
{
case nano::key_type::adhoc:
{
nano::raw_key key;
if (fetch (transaction_a, nano::public_key (i->first), key))
{
// Key failed to decrypt despite valid password
key.decrypt (value.key, password_l, salt (transaction_a).owords[0]);
nano::uint256_union new_key_ciphertext;
new_key_ciphertext.encrypt (key, password_l, (nano::uint256_union (i->first)).owords[0].number ());
nano::wallet_value new_value (new_key_ciphertext, value.work);
erase (transaction_a, nano::public_key (i->first));
entry_put_raw (transaction_a, nano::public_key (i->first), new_value);
}
}
case nano::key_type::deterministic:
break;
default:
debug_assert (false);
}
}
}
}
void nano::kdf::phs (nano::raw_key & result_a, std::string const & password_a, nano::uint256_union const & salt_a)
{
static nano::network_params network_params;

View file

@ -91,9 +91,6 @@ public:
void work_put (nano::transaction const &, nano::public_key const &, uint64_t);
unsigned version (nano::transaction const &);
void version_put (nano::transaction const &, unsigned);
void upgrade_v1_v2 (nano::transaction const &);
void upgrade_v2_v3 (nano::transaction const &);
void upgrade_v3_v4 (nano::transaction const &);
nano::fan password;
nano::fan wallet_key_mem;
static unsigned const version_1 = 1;

View file

@ -7061,30 +7061,6 @@ TEST (rpc_config, serialization)
ASSERT_EQ (config2.rpc_process.num_ipc_connections, config1.rpc_process.num_ipc_connections);
}
TEST (rpc_config, migrate)
{
nano::jsonconfig rpc;
rpc.put ("address", "::1");
rpc.put ("port", 11111);
bool updated = false;
auto data_path = nano::unique_path ();
boost::filesystem::create_directory (data_path);
nano::node_rpc_config nano_rpc_config;
nano_rpc_config.deserialize_json (updated, rpc, data_path);
ASSERT_TRUE (updated);
// Check that the rpc config file is created
auto rpc_path = nano::get_rpc_config_path (data_path);
nano::rpc_config rpc_config;
nano::jsonconfig json;
updated = false;
ASSERT_FALSE (json.read_and_update (rpc_config, rpc_path));
ASSERT_FALSE (updated);
ASSERT_EQ (rpc_config.port, 11111);
}
TEST (rpc, deprecated_account_format)
{
nano::system system;

View file

@ -1,249 +1,6 @@
#include <nano/lib/threading.hpp>
#include <nano/secure/blockstore.hpp>
nano::summation_visitor::summation_visitor (nano::transaction const & transaction_a, nano::block_store const & store_a, bool is_v14_upgrade_a) :
transaction (transaction_a),
store (store_a),
is_v14_upgrade (is_v14_upgrade_a)
{
}
void nano::summation_visitor::send_block (nano::send_block const & block_a)
{
debug_assert (current->type != summation_type::invalid && current != nullptr);
if (current->type == summation_type::amount)
{
sum_set (block_a.hashables.balance.number ());
current->balance_hash = block_a.hashables.previous;
current->amount_hash = 0;
}
else
{
sum_add (block_a.hashables.balance.number ());
current->balance_hash = 0;
}
}
void nano::summation_visitor::state_block (nano::state_block const & block_a)
{
debug_assert (current->type != summation_type::invalid && current != nullptr);
sum_set (block_a.hashables.balance.number ());
if (current->type == summation_type::amount)
{
current->balance_hash = block_a.hashables.previous;
current->amount_hash = 0;
}
else
{
current->balance_hash = 0;
}
}
void nano::summation_visitor::receive_block (nano::receive_block const & block_a)
{
debug_assert (current->type != summation_type::invalid && current != nullptr);
if (current->type == summation_type::amount)
{
current->amount_hash = block_a.hashables.source;
}
else
{
nano::block_info block_info;
if (!store.block_info_get (transaction, block_a.hash (), block_info))
{
sum_add (block_info.balance.number ());
current->balance_hash = 0;
}
else
{
current->amount_hash = block_a.hashables.source;
current->balance_hash = block_a.hashables.previous;
}
}
}
void nano::summation_visitor::open_block (nano::open_block const & block_a)
{
debug_assert (current->type != summation_type::invalid && current != nullptr);
if (current->type == summation_type::amount)
{
if (block_a.hashables.source != network_params.ledger.genesis_account)
{
current->amount_hash = block_a.hashables.source;
}
else
{
sum_set (network_params.ledger.genesis_amount);
current->amount_hash = 0;
}
}
else
{
current->amount_hash = block_a.hashables.source;
current->balance_hash = 0;
}
}
void nano::summation_visitor::change_block (nano::change_block const & block_a)
{
debug_assert (current->type != summation_type::invalid && current != nullptr);
if (current->type == summation_type::amount)
{
sum_set (0);
current->amount_hash = 0;
}
else
{
nano::block_info block_info;
if (!store.block_info_get (transaction, block_a.hash (), block_info))
{
sum_add (block_info.balance.number ());
current->balance_hash = 0;
}
else
{
current->balance_hash = block_a.hashables.previous;
}
}
}
nano::summation_visitor::frame nano::summation_visitor::push (nano::summation_visitor::summation_type type_a, nano::block_hash const & hash_a)
{
frames.emplace (type_a, type_a == summation_type::balance ? hash_a : 0, type_a == summation_type::amount ? hash_a : 0);
return frames.top ();
}
void nano::summation_visitor::sum_add (nano::uint128_t addend_a)
{
current->sum += addend_a;
result = current->sum;
}
void nano::summation_visitor::sum_set (nano::uint128_t value_a)
{
current->sum = value_a;
result = current->sum;
}
nano::uint128_t nano::summation_visitor::compute_internal (nano::summation_visitor::summation_type type_a, nano::block_hash const & hash_a)
{
push (type_a, hash_a);
/*
Invocation loop representing balance and amount computations calling each other.
This is usually better done by recursion or something like boost::coroutine2, but
segmented stacks are not supported on all platforms so we do it manually to avoid
stack overflow (the mutual calls are not tail-recursive so we cannot rely on the
compiler optimizing that into a loop, though a future alternative is to do a
CPS-style implementation to enforce tail calls.)
*/
while (!frames.empty ())
{
current = &frames.top ();
debug_assert (current->type != summation_type::invalid && current != nullptr);
if (current->type == summation_type::balance)
{
if (current->awaiting_result)
{
sum_add (current->incoming_result);
current->awaiting_result = false;
}
while (!current->awaiting_result && (!current->balance_hash.is_zero () || !current->amount_hash.is_zero ()))
{
if (!current->amount_hash.is_zero ())
{
// Compute amount
current->awaiting_result = true;
push (summation_type::amount, current->amount_hash);
current->amount_hash = 0;
}
else
{
auto block (block_get (transaction, current->balance_hash));
debug_assert (block != nullptr);
block->visit (*this);
}
}
epilogue ();
}
else if (current->type == summation_type::amount)
{
if (current->awaiting_result)
{
sum_set (current->sum < current->incoming_result ? current->incoming_result - current->sum : current->sum - current->incoming_result);
current->awaiting_result = false;
}
while (!current->awaiting_result && (!current->amount_hash.is_zero () || !current->balance_hash.is_zero ()))
{
if (!current->amount_hash.is_zero ())
{
auto block = block_get (transaction, current->amount_hash);
if (block != nullptr)
{
block->visit (*this);
}
else
{
if (current->amount_hash == network_params.ledger.genesis_account)
{
sum_set ((std::numeric_limits<nano::uint128_t>::max) ());
current->amount_hash = 0;
}
else
{
debug_assert (false);
sum_set (0);
current->amount_hash = 0;
}
}
}
else
{
// Compute balance
current->awaiting_result = true;
push (summation_type::balance, current->balance_hash);
current->balance_hash = 0;
}
}
epilogue ();
}
}
return result;
}
void nano::summation_visitor::epilogue ()
{
if (!current->awaiting_result)
{
frames.pop ();
if (!frames.empty ())
{
frames.top ().incoming_result = current->sum;
}
}
}
nano::uint128_t nano::summation_visitor::compute_amount (nano::block_hash const & block_hash)
{
return compute_internal (summation_type::amount, block_hash);
}
nano::uint128_t nano::summation_visitor::compute_balance (nano::block_hash const & block_hash)
{
return compute_internal (summation_type::balance, block_hash);
}
std::shared_ptr<nano::block> nano::summation_visitor::block_get (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const
{
return is_v14_upgrade ? store.block_get_v14 (transaction, hash_a) : store.block_get_no_sideband (transaction, hash_a);
}
nano::representative_visitor::representative_visitor (nano::transaction const & transaction_a, nano::block_store & store_a) :
transaction (transaction_a),
store (store_a),

View file

@ -57,11 +57,6 @@ public:
{
}
db_val (nano::account_info_v13 const & val_a) :
db_val (val_a.db_size (), const_cast<nano::account_info_v13 *> (&val_a))
{
}
db_val (nano::account_info_v14 const & val_a) :
db_val (val_a.db_size (), const_cast<nano::account_info_v14 *> (&val_a))
{
@ -152,14 +147,6 @@ public:
return result;
}
explicit operator nano::account_info_v13 () const
{
nano::account_info_v13 result;
debug_assert (size () == result.db_size ());
std::copy (reinterpret_cast<uint8_t const *> (data ()), reinterpret_cast<uint8_t const *> (data ()) + result.db_size (), reinterpret_cast<uint8_t *> (&result));
return result;
}
explicit operator nano::account_info_v14 () const
{
nano::account_info_v14 result;
@ -403,82 +390,6 @@ private:
class transaction;
class block_store;
/**
* Summation visitor for blocks, supporting amount and balance computations. These
* computations are mutually dependant. The natural solution is to use mutual recursion
* between balance and amount visitors, but this leads to very deep stacks. Hence, the
* summation visitor uses an iterative approach.
*/
class summation_visitor final : public nano::block_visitor
{
enum summation_type
{
invalid = 0,
balance = 1,
amount = 2
};
/** Represents an invocation frame */
class frame final
{
public:
frame (summation_type type_a, nano::block_hash balance_hash_a, nano::block_hash amount_hash_a) :
type (type_a), balance_hash (balance_hash_a), amount_hash (amount_hash_a)
{
}
/** The summation type guides the block visitor handlers */
summation_type type{ invalid };
/** Accumulated balance or amount */
nano::uint128_t sum{ 0 };
/** The current balance hash */
nano::block_hash balance_hash{ 0 };
/** The current amount hash */
nano::block_hash amount_hash{ 0 };
/** If true, this frame is awaiting an invocation result */
bool awaiting_result{ false };
/** Set by the invoked frame, representing the return value */
nano::uint128_t incoming_result{ 0 };
};
public:
summation_visitor (nano::transaction const &, nano::block_store const &, bool is_v14_upgrade = false);
virtual ~summation_visitor () = default;
/** Computes the balance as of \p block_hash */
nano::uint128_t compute_balance (nano::block_hash const & block_hash);
/** Computes the amount delta between \p block_hash and its predecessor */
nano::uint128_t compute_amount (nano::block_hash const & block_hash);
protected:
nano::transaction const & transaction;
nano::block_store const & store;
nano::network_params network_params;
/** The final result */
nano::uint128_t result{ 0 };
/** The current invocation frame */
frame * current{ nullptr };
/** Invocation frames */
std::stack<frame> frames;
/** Push a copy of \p hash of the given summation \p type */
nano::summation_visitor::frame push (nano::summation_visitor::summation_type type, nano::block_hash const & hash);
void sum_add (nano::uint128_t addend_a);
void sum_set (nano::uint128_t value_a);
/** The epilogue yields the result to previous frame, if any */
void epilogue ();
nano::uint128_t compute_internal (nano::summation_visitor::summation_type type, nano::block_hash const &);
void send_block (nano::send_block const &) override;
void receive_block (nano::receive_block const &) override;
void open_block (nano::open_block const &) override;
void change_block (nano::change_block const &) override;
void state_block (nano::state_block const &) override;
private:
bool is_v14_upgrade;
std::shared_ptr<nano::block> block_get (nano::transaction const &, nano::block_hash const &) const;
};
/**
* Determine the representative for this block
*/
@ -572,7 +483,6 @@ private:
enum class tables
{
accounts,
blocks_info, // LMDB only
cached_counts, // RocksDB only
change_blocks,
confirmation_height,
@ -703,7 +613,6 @@ public:
virtual nano::store_iterator<nano::pending_key, nano::pending_info> pending_begin (nano::transaction const &) = 0;
virtual nano::store_iterator<nano::pending_key, nano::pending_info> pending_end () = 0;
virtual bool block_info_get (nano::transaction const &, nano::block_hash const &, nano::block_info &) const = 0;
virtual nano::uint128_t block_balance (nano::transaction const &, nano::block_hash const &) = 0;
virtual nano::uint128_t block_balance_calculated (std::shared_ptr<nano::block> const &) const = 0;
virtual nano::epoch block_version (nano::transaction const &, nano::block_hash const &) = 0;
@ -779,7 +688,7 @@ public:
virtual std::string vendor_get () const = 0;
};
std::unique_ptr<nano::block_store> make_store (nano::logger_mt & logger, boost::filesystem::path const & path, bool open_read_only = false, bool add_db_postfix = false, nano::rocksdb_config const & rocksdb_config = nano::rocksdb_config{}, 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), nano::lmdb_config const & lmdb_config_a = nano::lmdb_config{}, size_t batch_size = 512, bool backup_before_upgrade = false, bool rocksdb_backend = false);
std::unique_ptr<nano::block_store> make_store (nano::logger_mt & logger, boost::filesystem::path const & path, bool open_read_only = false, bool add_db_postfix = false, nano::rocksdb_config const & rocksdb_config = nano::rocksdb_config{}, 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), nano::lmdb_config const & lmdb_config_a = nano::lmdb_config{}, bool backup_before_upgrade = false, bool rocksdb_backend = false);
}
namespace std

View file

@ -137,21 +137,9 @@ public:
result = nano::deserialize_block (stream, type);
debug_assert (result != nullptr);
nano::block_sideband sideband;
if (full_sideband (transaction_a) || entry_has_sideband (value.size (), type))
{
auto error (sideband.deserialize (stream, type));
(void)error;
debug_assert (!error);
}
else
{
// Reconstruct sideband data for block.
sideband.account = block_account_computed (transaction_a, hash_a);
sideband.balance = block_balance_computed (transaction_a, hash_a);
sideband.successor = block_successor (transaction_a, hash_a);
sideband.height = 0;
sideband.timestamp = 0;
}
auto error (sideband.deserialize (stream, type));
(void)error;
debug_assert (!error);
result->sideband_set (sideband);
}
return result;
@ -263,11 +251,6 @@ public:
return result;
}
bool full_sideband (nano::transaction const & transaction_a) const
{
return version_get (transaction_a) > 12;
}
void block_successor_clear (nano::write_transaction const & transaction_a, nano::block_hash const & hash_a) override
{
nano::block_type type;
@ -416,7 +399,7 @@ public:
nano::uint256_union version_key (1);
nano::db_val<Val> data;
auto status = get (transaction_a, tables::meta, nano::db_val<Val> (version_key), data);
int result (1);
int result (minimum_version);
if (!not_found (status))
{
nano::uint256_union version_value (data);
@ -797,11 +780,13 @@ public:
return count (transaction_a, tables::unchecked);
}
int const minimum_version{ 14 };
protected:
nano::network_params network_params;
std::unordered_map<nano::account, std::shared_ptr<nano::vote>> vote_cache_l1;
std::unordered_map<nano::account, std::shared_ptr<nano::vote>> vote_cache_l2;
static int constexpr version{ 18 };
int const version{ 18 };
template <typename T>
std::shared_ptr<nano::block> block_random (nano::transaction const & transaction_a, tables table_a)
@ -830,11 +815,6 @@ protected:
return static_cast<Derived_Store const &> (*this).template make_iterator<Key, Value> (transaction_a, table_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<Val> block_raw_get (nano::transaction const & transaction_a, nano::block_hash const & hash_a, nano::block_type & type_a) const
{
nano::db_val<Val> result;
@ -854,70 +834,9 @@ protected:
return result;
}
// Return account containing hash
nano::account block_account_computed (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const
{
debug_assert (!full_sideband (transaction_a));
nano::account result (0);
auto hash (hash_a);
while (result.is_zero ())
{
auto block (block_get_no_sideband (transaction_a, hash));
debug_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));
debug_assert (!successor.is_zero ());
hash = successor;
}
}
}
}
}
debug_assert (!result.is_zero ());
return result;
}
nano::uint128_t block_balance_computed (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const
{
debug_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
debug_assert (entry_size_a == nano::block::size (type_a) + sizeof (nano::block_hash));
result = entry_size_a - sizeof (nano::block_hash);
}
return result;
return entry_size_a - nano::block_sideband::size (type_a);
}
boost::optional<nano::db_val<Val>> block_raw_get_by_type (nano::transaction const & transaction_a, nano::block_hash const & hash_a, nano::block_type & type_a) const

View file

@ -4,35 +4,6 @@
#include <lmdb/libraries/liblmdb/lmdb.h>
nano::account_info_v1::account_info_v1 (MDB_val const & val_a)
{
debug_assert (val_a.mv_size == sizeof (*this));
static_assert (sizeof (head) + sizeof (rep_block) + sizeof (balance) + sizeof (modified) == sizeof (*this), "Class not packed");
std::copy (reinterpret_cast<uint8_t const *> (val_a.mv_data), reinterpret_cast<uint8_t const *> (val_a.mv_data) + sizeof (*this), reinterpret_cast<uint8_t *> (this));
}
nano::account_info_v1::account_info_v1 (nano::block_hash const & head_a, nano::block_hash const & rep_block_a, nano::amount const & balance_a, uint64_t modified_a) :
head (head_a),
rep_block (rep_block_a),
balance (balance_a),
modified (modified_a)
{
}
nano::pending_info_v3::pending_info_v3 (MDB_val const & val_a)
{
debug_assert (val_a.mv_size == sizeof (*this));
static_assert (sizeof (source) + sizeof (amount) + sizeof (destination) == sizeof (*this), "Packed class");
std::copy (reinterpret_cast<uint8_t const *> (val_a.mv_data), reinterpret_cast<uint8_t const *> (val_a.mv_data) + sizeof (*this), reinterpret_cast<uint8_t *> (this));
}
nano::pending_info_v3::pending_info_v3 (nano::account const & source_a, nano::amount const & amount_a, nano::account const & destination_a) :
source (source_a),
amount (amount_a),
destination (destination_a)
{
}
nano::pending_info_v14::pending_info_v14 (nano::account const & source_a, nano::amount const & amount_a, nano::epoch epoch_a) :
source (source_a),
amount (amount_a),
@ -66,44 +37,6 @@ bool nano::pending_info_v14::operator== (nano::pending_info_v14 const & other_a)
return source == other_a.source && amount == other_a.amount && epoch == other_a.epoch;
}
nano::account_info_v5::account_info_v5 (MDB_val const & val_a)
{
debug_assert (val_a.mv_size == sizeof (*this));
static_assert (sizeof (head) + sizeof (rep_block) + sizeof (open_block) + sizeof (balance) + sizeof (modified) == sizeof (*this), "Class not packed");
std::copy (reinterpret_cast<uint8_t const *> (val_a.mv_data), reinterpret_cast<uint8_t const *> (val_a.mv_data) + sizeof (*this), reinterpret_cast<uint8_t *> (this));
}
nano::account_info_v5::account_info_v5 (nano::block_hash const & head_a, nano::block_hash const & rep_block_a, nano::block_hash const & open_block_a, nano::amount const & balance_a, uint64_t modified_a) :
head (head_a),
rep_block (rep_block_a),
open_block (open_block_a),
balance (balance_a),
modified (modified_a)
{
}
nano::account_info_v13::account_info_v13 (nano::block_hash const & head_a, nano::block_hash const & rep_block_a, nano::block_hash const & open_block_a, nano::amount const & balance_a, uint64_t modified_a, uint64_t block_count_a, nano::epoch epoch_a) :
head (head_a),
rep_block (rep_block_a),
open_block (open_block_a),
balance (balance_a),
modified (modified_a),
block_count (block_count_a),
epoch (epoch_a)
{
}
size_t nano::account_info_v13::db_size () const
{
debug_assert (reinterpret_cast<const uint8_t *> (this) == reinterpret_cast<const uint8_t *> (&head));
debug_assert (reinterpret_cast<const uint8_t *> (&head) + sizeof (head) == reinterpret_cast<const uint8_t *> (&rep_block));
debug_assert (reinterpret_cast<const uint8_t *> (&rep_block) + sizeof (rep_block) == reinterpret_cast<const uint8_t *> (&open_block));
debug_assert (reinterpret_cast<const uint8_t *> (&open_block) + sizeof (open_block) == reinterpret_cast<const uint8_t *> (&balance));
debug_assert (reinterpret_cast<const uint8_t *> (&balance) + sizeof (balance) == reinterpret_cast<const uint8_t *> (&modified));
debug_assert (reinterpret_cast<const uint8_t *> (&modified) + sizeof (modified) == reinterpret_cast<const uint8_t *> (&block_count));
return sizeof (head) + sizeof (rep_block) + sizeof (open_block) + sizeof (balance) + sizeof (modified) + sizeof (block_count);
}
nano::account_info_v14::account_info_v14 (nano::block_hash const & head_a, nano::block_hash const & rep_block_a, nano::block_hash const & open_block_a, nano::amount const & balance_a, uint64_t modified_a, uint64_t block_count_a, uint64_t confirmation_height_a, nano::epoch epoch_a) :
head (head_a),
rep_block (rep_block_a),

View file

@ -7,27 +7,6 @@ struct MDB_val;
namespace nano
{
class account_info_v1 final
{
public:
account_info_v1 () = default;
explicit account_info_v1 (MDB_val const &);
account_info_v1 (nano::block_hash const &, nano::block_hash const &, nano::amount const &, uint64_t);
nano::block_hash head{ 0 };
nano::block_hash rep_block{ 0 };
nano::amount balance{ 0 };
uint64_t modified{ 0 };
};
class pending_info_v3 final
{
public:
pending_info_v3 () = default;
explicit pending_info_v3 (MDB_val const &);
pending_info_v3 (nano::account const &, nano::amount const &, nano::account const &);
nano::account source{ 0 };
nano::amount amount{ 0 };
nano::account destination{ 0 };
};
class pending_info_v14 final
{
public:
@ -40,32 +19,6 @@ public:
nano::amount amount{ 0 };
nano::epoch epoch{ nano::epoch::epoch_0 };
};
class account_info_v5 final
{
public:
account_info_v5 () = default;
explicit account_info_v5 (MDB_val const &);
account_info_v5 (nano::block_hash const &, nano::block_hash const &, nano::block_hash const &, nano::amount const &, uint64_t);
nano::block_hash head{ 0 };
nano::block_hash rep_block{ 0 };
nano::block_hash open_block{ 0 };
nano::amount balance{ 0 };
uint64_t modified{ 0 };
};
class account_info_v13 final
{
public:
account_info_v13 () = default;
account_info_v13 (nano::block_hash const &, nano::block_hash const &, nano::block_hash const &, nano::amount const &, uint64_t, uint64_t, nano::epoch);
size_t db_size () const;
nano::block_hash head{ 0 };
nano::block_hash rep_block{ 0 };
nano::block_hash open_block{ 0 };
nano::amount balance{ 0 };
uint64_t modified{ 0 };
uint64_t block_count{ 0 };
nano::epoch epoch{ nano::epoch::epoch_0 };
};
class account_info_v14 final
{
public: