Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support epoch 2 #2310

Merged
merged 9 commits into from
Sep 29, 2019
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
267 changes: 175 additions & 92 deletions nano/core_test/block_store.cpp

Large diffs are not rendered by default.

23 changes: 18 additions & 5 deletions nano/core_test/epochs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,24 @@
TEST (epochs, is_epoch_link)
{
nano::epochs epochs;
// Test epoch 1
nano::keypair key1;
auto link1 = 42;
auto link2 = 43;
ASSERT_FALSE (epochs.is_epoch_link (link1));
ASSERT_FALSE (epochs.is_epoch_link (link2));
epochs.add (nano::epoch::epoch_1, key1.pub, link1);
ASSERT_TRUE (epochs.is_epoch_link (link1));
ASSERT_FALSE (epochs.is_epoch_link (link2));
ASSERT_EQ (key1.pub, epochs.signer (nano::epoch::epoch_1));
ASSERT_EQ (epochs.epoch (link1), nano::epoch::epoch_1);

// Test epoch 2
nano::keypair key2;
ASSERT_FALSE (epochs.is_epoch_link (42));
ASSERT_FALSE (epochs.is_epoch_link (43));
epochs.add (nano::epoch::epoch_1, key1.pub, 42);
ASSERT_TRUE (epochs.is_epoch_link (42));
ASSERT_FALSE (epochs.is_epoch_link (43));
epochs.add (nano::epoch::epoch_2, key2.pub, link2);
ASSERT_TRUE (epochs.is_epoch_link (link2));
ASSERT_EQ (key2.pub, epochs.signer (nano::epoch::epoch_2));
ASSERT_EQ (nano::uint256_union (link1), epochs.link (nano::epoch::epoch_1));
ASSERT_EQ (nano::uint256_union (link2), epochs.link (nano::epoch::epoch_2));
ASSERT_EQ (epochs.epoch (link2), nano::epoch::epoch_2);
}
87 changes: 81 additions & 6 deletions nano/core_test/ledger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,15 @@

using namespace std::chrono_literals;

#if !NANO_ROCKSDB
// Init returns an error if it can't open files at the path
TEST (ledger, store_error)
{
nano::logger_mt logger;
auto store = nano::make_store (logger, boost::filesystem::path ("///"));
ASSERT_TRUE (store->init_error ());
nano::mdb_store store (logger, boost::filesystem::path ("///"));
ASSERT_TRUE (store.init_error ());
nano::stat stats;
nano::ledger ledger (*store, stats);
nano::ledger ledger (store, stats);
}
#endif

// Ledger can be initialized and returns a basic query for an empty account
TEST (ledger, empty)
Expand Down Expand Up @@ -2286,7 +2284,7 @@ TEST (ledger, state_receive_change_rollback)
ASSERT_EQ (0, ledger.weight (rep.pub));
}

TEST (ledger, epoch_blocks_general)
TEST (ledger, epoch_blocks_v1_general)
{
nano::logger_mt logger;
auto store = nano::make_store (logger, nano::unique_path ());
Expand Down Expand Up @@ -2332,6 +2330,60 @@ TEST (ledger, epoch_blocks_general)
ASSERT_EQ (nano::Gxrb_ratio, ledger.weight (destination.pub));
}

TEST (ledger, epoch_blocks_v2_general)
{
nano::logger_mt logger;
auto store = nano::make_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.rep_weights, ledger.cemented_count, ledger.block_count_cache);
nano::work_pool pool (std::numeric_limits<unsigned>::max ());
nano::keypair destination;
nano::state_block epoch1 (nano::genesis_account, genesis.hash (), nano::genesis_account, nano::genesis_amount, ledger.link (nano::epoch::epoch_2), nano::test_genesis_key.prv, nano::test_genesis_key.pub, pool.generate (genesis.hash ()));
// Trying to upgrade from epoch 0 to epoch 2. It is a requirement (at least for epoch 2) that it can only upgrade an epoch 1 account
ASSERT_EQ (nano::process_result::block_position, ledger.process (transaction, epoch1).code);
// Set it to the first epoch and it should now succeed
epoch1 = nano::state_block (nano::genesis_account, genesis.hash (), nano::genesis_account, nano::genesis_amount, ledger.link (nano::epoch::epoch_1), nano::test_genesis_key.prv, nano::test_genesis_key.pub, epoch1.work);
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, epoch1).code);
nano::state_block epoch2 (nano::genesis_account, epoch1.hash (), nano::genesis_account, nano::genesis_amount, ledger.link (nano::epoch::epoch_2), nano::test_genesis_key.prv, nano::test_genesis_key.pub, pool.generate (epoch1.hash ()));
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, epoch2).code);
nano::state_block epoch3 (nano::genesis_account, epoch2.hash (), nano::genesis_account, nano::genesis_amount, ledger.link (nano::epoch::epoch_2), nano::test_genesis_key.prv, nano::test_genesis_key.pub, pool.generate (epoch2.hash ()));
ASSERT_EQ (nano::process_result::block_position, ledger.process (transaction, epoch3).code);
nano::account_info genesis_info;
ASSERT_FALSE (ledger.store.account_get (transaction, nano::genesis_account, genesis_info));
ASSERT_EQ (genesis_info.epoch (), nano::epoch::epoch_2);
ASSERT_FALSE (ledger.rollback (transaction, epoch1.hash ()));
ASSERT_FALSE (ledger.store.account_get (transaction, nano::genesis_account, genesis_info));
ASSERT_EQ (genesis_info.epoch (), nano::epoch::epoch_0);
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, epoch1).code);
ASSERT_FALSE (ledger.store.account_get (transaction, nano::genesis_account, genesis_info));
ASSERT_EQ (genesis_info.epoch (), nano::epoch::epoch_1);
nano::change_block change1 (epoch1.hash (), nano::genesis_account, nano::test_genesis_key.prv, nano::test_genesis_key.pub, pool.generate (epoch1.hash ()));
ASSERT_EQ (nano::process_result::block_position, ledger.process (transaction, change1).code);
nano::state_block send1 (nano::genesis_account, epoch1.hash (), nano::genesis_account, nano::genesis_amount - nano::Gxrb_ratio, destination.pub, nano::test_genesis_key.prv, nano::test_genesis_key.pub, pool.generate (epoch1.hash ()));
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, send1).code);
nano::open_block open1 (send1.hash (), nano::genesis_account, destination.pub, destination.prv, destination.pub, pool.generate (destination.pub));
ASSERT_EQ (nano::process_result::unreceivable, ledger.process (transaction, open1).code);
nano::state_block epoch4 (destination.pub, 0, 0, 0, ledger.link (nano::epoch::epoch_1), nano::test_genesis_key.prv, nano::test_genesis_key.pub, pool.generate (destination.pub));
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, epoch4).code);
nano::state_block epoch5 (destination.pub, epoch4.hash (), nano::genesis_account, 0, ledger.link (nano::epoch::epoch_2), nano::test_genesis_key.prv, nano::test_genesis_key.pub, pool.generate (epoch4.hash ()));
ASSERT_EQ (nano::process_result::representative_mismatch, ledger.process (transaction, epoch5).code);
nano::state_block epoch6 (destination.pub, epoch4.hash (), 0, 0, ledger.link (nano::epoch::epoch_2), nano::test_genesis_key.prv, nano::test_genesis_key.pub, pool.generate (epoch4.hash ()));
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, epoch6).code);
nano::receive_block receive1 (epoch6.hash (), send1.hash (), destination.prv, destination.pub, pool.generate (epoch6.hash ()));
ASSERT_EQ (nano::process_result::block_position, ledger.process (transaction, receive1).code);
nano::state_block receive2 (destination.pub, epoch6.hash (), destination.pub, nano::Gxrb_ratio, send1.hash (), destination.prv, destination.pub, pool.generate (epoch6.hash ()));
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, receive2).code);
ASSERT_EQ (0, ledger.balance (transaction, epoch6.hash ()));
ASSERT_EQ (nano::Gxrb_ratio, ledger.balance (transaction, receive2.hash ()));
ASSERT_EQ (nano::Gxrb_ratio, ledger.amount (transaction, receive2.hash ()));
ASSERT_EQ (nano::genesis_amount - nano::Gxrb_ratio, ledger.weight (nano::genesis_account));
ASSERT_EQ (nano::Gxrb_ratio, ledger.weight (destination.pub));
}

TEST (ledger, epoch_blocks_receive_upgrade)
{
nano::logger_mt logger;
Expand Down Expand Up @@ -2370,6 +2422,23 @@ TEST (ledger, epoch_blocks_receive_upgrade)
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, send3).code);
nano::open_block open2 (send3.hash (), destination2.pub, destination2.pub, destination2.prv, destination2.pub, pool.generate (destination2.pub));
ASSERT_EQ (nano::process_result::unreceivable, ledger.process (transaction, open2).code);
// Upgrade to epoch 2 and send to destination. Try to create an open block from an epoch 2 source block.
nano::keypair destination3;
nano::state_block epoch2 (nano::genesis_account, send2.hash (), nano::genesis_account, nano::genesis_amount - nano::Gxrb_ratio * 2, ledger.link (nano::epoch::epoch_2), nano::test_genesis_key.prv, nano::test_genesis_key.pub, pool.generate (send2.hash ()));
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, epoch2).code);
nano::state_block send4 (nano::genesis_account, epoch2.hash (), nano::genesis_account, nano::genesis_amount - nano::Gxrb_ratio * 3, destination3.pub, nano::test_genesis_key.prv, nano::test_genesis_key.pub, pool.generate (epoch2.hash ()));
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, send4).code);
nano::open_block open3 (send4.hash (), destination3.pub, destination3.pub, destination3.prv, destination3.pub, pool.generate (destination3.pub));
ASSERT_EQ (nano::process_result::unreceivable, ledger.process (transaction, open3).code);
// Send it to an epoch 1 account
nano::state_block send5 (nano::genesis_account, send4.hash (), nano::genesis_account, nano::genesis_amount - nano::Gxrb_ratio * 4, destination.pub, nano::test_genesis_key.prv, nano::test_genesis_key.pub, pool.generate (send4.hash ()));
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, send5).code);
ASSERT_FALSE (ledger.store.account_get (transaction, destination.pub, destination_info));
ASSERT_EQ (destination_info.epoch (), nano::epoch::epoch_1);
nano::state_block receive3 (destination.pub, send3.hash (), destination.pub, nano::Gxrb_ratio * 2, send5.hash (), destination.prv, destination.pub, pool.generate (send3.hash ()));
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, receive3).code);
ASSERT_FALSE (ledger.store.account_get (transaction, destination.pub, destination_info));
ASSERT_EQ (destination_info.epoch (), nano::epoch::epoch_2);
}

TEST (ledger, epoch_blocks_fork)
Expand All @@ -2388,6 +2457,12 @@ TEST (ledger, epoch_blocks_fork)
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, send1).code);
nano::state_block epoch1 (nano::genesis_account, genesis.hash (), nano::genesis_account, nano::genesis_amount, ledger.link (nano::epoch::epoch_1), nano::test_genesis_key.prv, nano::test_genesis_key.pub, pool.generate (genesis.hash ()));
ASSERT_EQ (nano::process_result::fork, ledger.process (transaction, epoch1).code);
nano::state_block epoch2 (nano::genesis_account, genesis.hash (), nano::genesis_account, nano::genesis_amount, ledger.link (nano::epoch::epoch_2), nano::test_genesis_key.prv, nano::test_genesis_key.pub, pool.generate (genesis.hash ()));
ASSERT_EQ (nano::process_result::fork, ledger.process (transaction, epoch2).code);
nano::state_block epoch3 (nano::genesis_account, send1.hash (), nano::genesis_account, nano::genesis_amount, ledger.link (nano::epoch::epoch_1), nano::test_genesis_key.prv, nano::test_genesis_key.pub, pool.generate (send1.hash ()));
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, epoch3).code);
nano::state_block epoch4 (nano::genesis_account, send1.hash (), nano::genesis_account, nano::genesis_amount, ledger.link (nano::epoch::epoch_2), nano::test_genesis_key.prv, nano::test_genesis_key.pub, pool.generate (send1.hash ()));
ASSERT_EQ (nano::process_result::fork, ledger.process (transaction, epoch2).code);
}

TEST (ledger, successor_epoch)
Expand Down
6 changes: 3 additions & 3 deletions nano/core_test/versioning.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ TEST (versioning, account_info_v1)
nano::mdb_store store (logger, file);
ASSERT_FALSE (store.init_error ());
auto transaction (store.tx_begin_write ());
nano::block_sideband sideband (nano::block_type::open, 0, 0, 0, 0, 0);
nano::block_sideband sideband (nano::block_type::open, 0, 0, 0, 0, 0, nano::epoch::epoch_0);
store.block_put (transaction, open.hash (), open, sideband);
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);
Expand Down Expand Up @@ -52,7 +52,7 @@ TEST (versioning, account_info_v5)
nano::mdb_store store (logger, file);
ASSERT_FALSE (store.init_error ());
auto transaction (store.tx_begin_write ());
nano::block_sideband sideband (nano::block_type::open, 0, 0, 0, 0, 0);
nano::block_sideband sideband (nano::block_type::open, 0, 0, 0, 0, 0, nano::epoch::epoch_0);
store.block_put (transaction, open.hash (), open, sideband);
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);
Expand Down Expand Up @@ -88,7 +88,7 @@ TEST (versioning, account_info_v13)
nano::mdb_store store (logger, file);
ASSERT_FALSE (store.init_error ());
auto transaction (store.tx_begin_write ());
nano::block_sideband sideband (nano::block_type::open, 0, 0, 0, 0, 0);
nano::block_sideband sideband (nano::block_type::open, 0, 0, 0, 0, 0, nano::epoch::epoch_0);
store.block_put (transaction, open.hash (), open, sideband);
auto status (mdb_put (store.env.tx (transaction), store.accounts_v0, nano::mdb_val (account), nano::mdb_val (v13), 0));
ASSERT_EQ (0, status);
Expand Down
23 changes: 17 additions & 6 deletions nano/core_test/wallets.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,14 +78,26 @@ TEST (wallets, remove)
}
}

#if !NANO_ROCKSDB
TEST (wallets, upgrade)
{
nano::system system (24000, 1);
// Don't test this in rocksdb mode
static nano::network_constants network_constants;
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 (24000, system.logging);
node_config.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled;
system.add_node (node_config);
auto path (nano::unique_path ());
nano::keypair id;
nano::node_config node_config1 (24001, system.logging);
node_config1.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled;
{
auto node1 (std::make_shared<nano::node> (system.io_ctx, 24001, path, system.alarm, system.logging, system.work));
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);
Expand All @@ -102,11 +114,11 @@ TEST (wallets, upgrade)
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), mdb_store.get_account_db (info.epoch ()) == nano::tables::accounts_v0 ? mdb_store.accounts_v0 : mdb_store.accounts_v1, nano::mdb_val (nano::test_genesis_key.pub), nano::mdb_val (account_info_v13), 0));
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));
(void)status;
assert (status == 0);
}
auto node1 (std::make_shared<nano::node> (system.io_ctx, 24001, path, system.alarm, system.logging, system.work));
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.pub, node1->wallets.items.begin ()->first);
auto transaction_new (node1->wallets.env.tx_begin_write ());
Expand All @@ -118,7 +130,6 @@ TEST (wallets, upgrade)
MDB_dbi new_handle;
ASSERT_EQ (0, mdb_dbi_open (tx_new, id.pub.to_string ().c_str (), 0, &new_handle));
}
#endif

// Keeps breaking whenever we add new DBs
TEST (wallets, DISABLED_wallet_create_max)
Expand Down
2 changes: 1 addition & 1 deletion nano/lib/blocks.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ namespace nano
{
// We operate on streams of uint8_t by convention
using stream = std::basic_streambuf<uint8_t>;
// Read a raw byte stream the size of `T' and fill value.
// Read a raw byte stream the size of `T' and fill value. Returns true if there was an error, false otherwise
template <typename T>
bool try_read (nano::stream & stream_a, T & value)
{
Expand Down
2 changes: 1 addition & 1 deletion nano/node/blockprocessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ void nano::block_processor::process_batch (nano::unique_lock<std::mutex> & lock_
}
lock_a.unlock ();
auto scoped_write_guard = write_database_queue.wait (nano::writer::process_batch);
auto transaction (node.store.tx_begin_write ({ nano::tables::accounts_v0, nano::tables::accounts_v1, nano::tables::cached_counts, nano::tables::change_blocks, nano::tables::frontiers, nano::tables::open_blocks, nano::tables::pending_v0, nano::tables::pending_v1, nano::tables::receive_blocks, nano::tables::representation, nano::tables::send_blocks, nano::tables::state_blocks_v0, nano::tables::state_blocks_v1, nano::tables::unchecked }, { nano::tables::confirmation_height }));
auto transaction (node.store.tx_begin_write ({ nano::tables::accounts, nano::tables::cached_counts, nano::tables::change_blocks, nano::tables::frontiers, nano::tables::open_blocks, nano::tables::pending, nano::tables::receive_blocks, nano::tables::representation, nano::tables::send_blocks, nano::tables::state_blocks, nano::tables::unchecked }, { nano::tables::confirmation_height }));
timer_l.restart ();
lock_a.lock ();
// Processing blocks
Expand Down
24 changes: 18 additions & 6 deletions nano/node/json_handler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ using ipc_json_handler_no_arg_func_map = std::unordered_map<std::string, std::fu
ipc_json_handler_no_arg_func_map create_ipc_json_handler_no_arg_func_map ();
auto ipc_json_handler_no_arg_funcs = create_ipc_json_handler_no_arg_func_map ();
bool block_confirmed (nano::node & node, nano::transaction & transaction, nano::block_hash const & hash, bool include_active, bool include_only_confirmed);
const char * epoch_as_string (nano::epoch);
}

nano::json_handler::json_handler (nano::node & node_a, nano::node_rpc_config const & node_rpc_config_a, std::string const & body_a, std::function<void(std::string const &)> const & response_a, std::function<void()> stop_callback_a) :
Expand Down Expand Up @@ -534,7 +535,7 @@ void nano::json_handler::account_info ()
response_l.put ("balance", balance);
response_l.put ("modified_timestamp", std::to_string (info.modified));
response_l.put ("block_count", std::to_string (info.block_count));
response_l.put ("account_version", info.epoch () == nano::epoch::epoch_1 ? "1" : "0");
response_l.put ("account_version", epoch_as_string (info.epoch ()));
response_l.put ("confirmation_height", std::to_string (confirmation_height));
if (representative)
{
Expand Down Expand Up @@ -1214,9 +1215,7 @@ void nano::json_handler::block_count_type ()
response_l.put ("receive", std::to_string (count.receive));
response_l.put ("open", std::to_string (count.open));
response_l.put ("change", std::to_string (count.change));
response_l.put ("state_v0", std::to_string (count.state_v0));
response_l.put ("state_v1", std::to_string (count.state_v1));
response_l.put ("state", std::to_string (count.state_v0 + count.state_v1));
response_l.put ("state", std::to_string (count.state));
response_errors ();
}

Expand Down Expand Up @@ -2686,7 +2685,7 @@ void nano::json_handler::pending ()
}
if (min_version)
{
pending_tree.put ("min_version", info.epoch == nano::epoch::epoch_1 ? "1" : "0");
pending_tree.put ("min_version", epoch_as_string (info.epoch));
}
peers_l.add_child (key.hash.to_string (), pending_tree);
}
Expand Down Expand Up @@ -4314,7 +4313,7 @@ void nano::json_handler::wallet_pending ()
}
if (min_version)
{
pending_tree.put ("min_version", info.epoch == nano::epoch::epoch_1 ? "1" : "0");
pending_tree.put ("min_version", epoch_as_string (info.epoch));
}
peers_l.add_child (key.hash.to_string (), pending_tree);
}
Expand Down Expand Up @@ -4810,4 +4809,17 @@ bool block_confirmed (nano::node & node, nano::transaction & transaction, nano::

return is_confirmed;
}

const char * epoch_as_string (nano::epoch epoch)
{
switch (epoch)
{
case nano::epoch::epoch_2:
return "2";
case nano::epoch::epoch_1:
return "1";
default:
return "0";
}
}
}
Loading