RPC epoch_upgrade (#2304)
* RPC epoch_upgrade * Better naming of ledger epoch link & signer * Allow count limit for epoch_upgrade command
This commit is contained in:
parent
a0b4977531
commit
16f00cb14e
17 changed files with 417 additions and 46 deletions
|
@ -1326,7 +1326,7 @@ TEST (mdb_block_store, upgrade_sideband_epoch)
|
|||
auto transaction (store.tx_begin_write ());
|
||||
store.version_put (transaction, 11);
|
||||
store.initialize (transaction, genesis, ledger.rep_weights, ledger.cemented_count, ledger.block_count_cache);
|
||||
nano::state_block block1 (nano::test_genesis_key.pub, genesis.hash (), nano::test_genesis_key.pub, nano::genesis_amount, ledger.link (nano::epoch::epoch_1), nano::test_genesis_key.prv, nano::test_genesis_key.pub, *pool.generate (genesis.hash ()));
|
||||
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);
|
||||
|
@ -1388,10 +1388,10 @@ TEST (mdb_block_store, sideband_height)
|
|||
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, state_send3).code);
|
||||
nano::state_block state_open (key1.pub, 0, 0, nano::Gxrb_ratio, state_send1.hash (), key1.prv, key1.pub, *pool.generate (key1.pub));
|
||||
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, state_open).code);
|
||||
nano::state_block epoch (key1.pub, state_open.hash (), 0, nano::Gxrb_ratio, ledger.link (nano::epoch::epoch_1), nano::test_genesis_key.prv, nano::test_genesis_key.pub, *pool.generate (state_open.hash ()));
|
||||
nano::state_block epoch (key1.pub, state_open.hash (), 0, nano::Gxrb_ratio, ledger.epoch_link (nano::epoch::epoch_1), nano::test_genesis_key.prv, nano::test_genesis_key.pub, *pool.generate (state_open.hash ()));
|
||||
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, epoch).code);
|
||||
ASSERT_EQ (nano::epoch::epoch_1, store.block_version (transaction, epoch.hash ()));
|
||||
nano::state_block epoch_open (key2.pub, 0, 0, 0, ledger.link (nano::epoch::epoch_1), nano::test_genesis_key.prv, nano::test_genesis_key.pub, *pool.generate (key2.pub));
|
||||
nano::state_block epoch_open (key2.pub, 0, 0, 0, ledger.epoch_link (nano::epoch::epoch_1), nano::test_genesis_key.prv, nano::test_genesis_key.pub, *pool.generate (key2.pub));
|
||||
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, epoch_open).code);
|
||||
ASSERT_EQ (nano::epoch::epoch_1, store.block_version (transaction, epoch_open.hash ()));
|
||||
nano::state_block state_receive (key2.pub, epoch_open.hash (), 0, nano::Gxrb_ratio, state_send2.hash (), key2.prv, key2.pub, *pool.generate (epoch_open.hash ()));
|
||||
|
|
|
@ -512,9 +512,9 @@ TEST (confirmation_height, all_block_types)
|
|||
|
||||
nano::state_block state_change (key2.pub, state_send.hash (), nano::test_genesis_key.pub, nano::Gxrb_ratio, 0, key2.prv, key2.pub, *system.work.generate (state_send.hash ()));
|
||||
|
||||
nano::state_block epoch (key2.pub, state_change.hash (), nano::test_genesis_key.pub, nano::Gxrb_ratio, node->ledger.link (nano::epoch::epoch_1), nano::test_genesis_key.prv, nano::test_genesis_key.pub, *system.work.generate (state_change.hash ()));
|
||||
nano::state_block epoch (key2.pub, state_change.hash (), nano::test_genesis_key.pub, nano::Gxrb_ratio, node->ledger.epoch_link (nano::epoch::epoch_1), nano::test_genesis_key.prv, nano::test_genesis_key.pub, *system.work.generate (state_change.hash ()));
|
||||
|
||||
nano::state_block epoch1 (key1.pub, change.hash (), key2.pub, nano::Gxrb_ratio, node->ledger.link (nano::epoch::epoch_1), nano::test_genesis_key.prv, nano::test_genesis_key.pub, *system.work.generate (change.hash ()));
|
||||
nano::state_block epoch1 (key1.pub, change.hash (), key2.pub, nano::Gxrb_ratio, node->ledger.epoch_link (nano::epoch::epoch_1), nano::test_genesis_key.prv, nano::test_genesis_key.pub, *system.work.generate (change.hash ()));
|
||||
nano::state_block state_send1 (key1.pub, epoch1.hash (), 0, nano::Gxrb_ratio - 1, key2.pub, key1.prv, key1.pub, *system.work.generate (epoch1.hash ()));
|
||||
nano::state_block state_receive2 (key2.pub, epoch.hash (), 0, nano::Gxrb_ratio + 1, state_send1.hash (), key2.prv, key2.pub, *system.work.generate (epoch.hash ()));
|
||||
|
||||
|
|
|
@ -241,8 +241,8 @@ TEST (conflicts, adjusted_difficulty)
|
|||
node1.process_active (send3);
|
||||
auto send4 (std::make_shared<nano::state_block> (key1.pub, send3->hash (), key1.pub, 0, key3.pub, key1.prv, key1.pub, *system.work.generate (send3->hash ())));
|
||||
node1.process_active (send4);
|
||||
ASSERT_EQ (node1.ledger.signer (node1.ledger.link (nano::epoch::epoch_1)), nano::test_genesis_key.pub);
|
||||
auto open_epoch1 (std::make_shared<nano::state_block> (key2.pub, 0, 0, 0, node1.ledger.link (nano::epoch::epoch_1), nano::test_genesis_key.prv, nano::test_genesis_key.pub, *system.work.generate (key2.pub)));
|
||||
ASSERT_EQ (node1.ledger.epoch_signer (node1.ledger.epoch_link (nano::epoch::epoch_1)), nano::test_genesis_key.pub);
|
||||
auto open_epoch1 (std::make_shared<nano::state_block> (key2.pub, 0, 0, 0, node1.ledger.epoch_link (nano::epoch::epoch_1), nano::test_genesis_key.prv, nano::test_genesis_key.pub, *system.work.generate (key2.pub)));
|
||||
node1.process_active (open_epoch1);
|
||||
auto receive2 (std::make_shared<nano::state_block> (key2.pub, open_epoch1->hash (), 0, nano::xrb_ratio, send3->hash (), key2.prv, key2.pub, *system.work.generate (open_epoch1->hash ())));
|
||||
node1.process_active (receive2);
|
||||
|
@ -280,7 +280,7 @@ TEST (conflicts, adjusted_difficulty)
|
|||
ASSERT_GT (adjusted_difficulties.find (open2->hash ())->second, adjusted_difficulties.find (change1->hash ())->second);
|
||||
// Independent elections can have higher difficulty than adjusted tree
|
||||
nano::keypair key4;
|
||||
auto open_epoch2 (std::make_shared<nano::state_block> (key4.pub, 0, 0, 0, node1.ledger.link (nano::epoch::epoch_1), nano::test_genesis_key.prv, nano::test_genesis_key.pub, *system.work.generate (key4.pub, adjusted_difficulties.find (send1->hash ())->second)));
|
||||
auto open_epoch2 (std::make_shared<nano::state_block> (key4.pub, 0, 0, 0, node1.ledger.epoch_link (nano::epoch::epoch_1), nano::test_genesis_key.prv, nano::test_genesis_key.pub, *system.work.generate (key4.pub, adjusted_difficulties.find (send1->hash ())->second)));
|
||||
uint64_t difficulty;
|
||||
ASSERT_FALSE (nano::work_validate (*open_epoch2, &difficulty));
|
||||
ASSERT_GT (difficulty, adjusted_difficulties.find (send1->hash ())->second);
|
||||
|
|
|
@ -2296,9 +2296,9 @@ TEST (ledger, epoch_blocks_v1_general)
|
|||
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_1), nano::test_genesis_key.prv, nano::test_genesis_key.pub, *pool.generate (genesis.hash ()));
|
||||
nano::state_block epoch1 (nano::genesis_account, genesis.hash (), nano::genesis_account, nano::genesis_amount, ledger.epoch_link (nano::epoch::epoch_1), nano::test_genesis_key.prv, nano::test_genesis_key.pub, *pool.generate (genesis.hash ()));
|
||||
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_1), nano::test_genesis_key.prv, nano::test_genesis_key.pub, *pool.generate (epoch1.hash ()));
|
||||
nano::state_block epoch2 (nano::genesis_account, epoch1.hash (), nano::genesis_account, nano::genesis_amount, ledger.epoch_link (nano::epoch::epoch_1), nano::test_genesis_key.prv, nano::test_genesis_key.pub, *pool.generate (epoch1.hash ()));
|
||||
ASSERT_EQ (nano::process_result::block_position, ledger.process (transaction, epoch2).code);
|
||||
nano::account_info genesis_info;
|
||||
ASSERT_FALSE (ledger.store.account_get (transaction, nano::genesis_account, genesis_info));
|
||||
|
@ -2315,9 +2315,9 @@ TEST (ledger, epoch_blocks_v1_general)
|
|||
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 epoch3 (destination.pub, 0, nano::genesis_account, 0, ledger.link (nano::epoch::epoch_1), nano::test_genesis_key.prv, nano::test_genesis_key.pub, *pool.generate (destination.pub));
|
||||
nano::state_block epoch3 (destination.pub, 0, nano::genesis_account, 0, ledger.epoch_link (nano::epoch::epoch_1), nano::test_genesis_key.prv, nano::test_genesis_key.pub, *pool.generate (destination.pub));
|
||||
ASSERT_EQ (nano::process_result::representative_mismatch, ledger.process (transaction, epoch3).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));
|
||||
nano::state_block epoch4 (destination.pub, 0, 0, 0, ledger.epoch_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::receive_block receive1 (epoch4.hash (), send1.hash (), destination.prv, destination.pub, *pool.generate (epoch4.hash ()));
|
||||
ASSERT_EQ (nano::process_result::block_position, ledger.process (transaction, receive1).code);
|
||||
|
@ -2342,15 +2342,15 @@ TEST (ledger, epoch_blocks_v2_general)
|
|||
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 ()));
|
||||
nano::state_block epoch1 (nano::genesis_account, genesis.hash (), nano::genesis_account, nano::genesis_amount, ledger.epoch_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 epoch upgrades are sequential unless the account is unopened
|
||||
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);
|
||||
epoch1 = nano::state_block (nano::genesis_account, genesis.hash (), nano::genesis_account, nano::genesis_amount, ledger.epoch_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 ()));
|
||||
nano::state_block epoch2 (nano::genesis_account, epoch1.hash (), nano::genesis_account, nano::genesis_amount, ledger.epoch_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 ()));
|
||||
nano::state_block epoch3 (nano::genesis_account, epoch2.hash (), nano::genesis_account, nano::genesis_amount, ledger.epoch_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));
|
||||
|
@ -2367,11 +2367,11 @@ TEST (ledger, epoch_blocks_v2_general)
|
|||
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));
|
||||
nano::state_block epoch4 (destination.pub, 0, 0, 0, ledger.epoch_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 ()));
|
||||
nano::state_block epoch5 (destination.pub, epoch4.hash (), nano::genesis_account, 0, ledger.epoch_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 ()));
|
||||
nano::state_block epoch6 (destination.pub, epoch4.hash (), 0, 0, ledger.epoch_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);
|
||||
|
@ -2398,7 +2398,7 @@ TEST (ledger, epoch_blocks_receive_upgrade)
|
|||
nano::keypair destination;
|
||||
nano::state_block send1 (nano::genesis_account, genesis.hash (), nano::genesis_account, nano::genesis_amount - nano::Gxrb_ratio, destination.pub, nano::test_genesis_key.prv, nano::test_genesis_key.pub, *pool.generate (genesis.hash ()));
|
||||
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, send1).code);
|
||||
nano::state_block epoch1 (nano::genesis_account, send1.hash (), nano::genesis_account, nano::genesis_amount - nano::Gxrb_ratio, ledger.link (nano::epoch::epoch_1), nano::test_genesis_key.prv, nano::test_genesis_key.pub, *pool.generate (send1.hash ()));
|
||||
nano::state_block epoch1 (nano::genesis_account, send1.hash (), nano::genesis_account, nano::genesis_amount - nano::Gxrb_ratio, ledger.epoch_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, epoch1).code);
|
||||
nano::state_block send2 (nano::genesis_account, epoch1.hash (), nano::genesis_account, nano::genesis_amount - nano::Gxrb_ratio * 2, 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, send2).code);
|
||||
|
@ -2424,7 +2424,7 @@ TEST (ledger, epoch_blocks_receive_upgrade)
|
|||
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 ()));
|
||||
nano::state_block epoch2 (nano::genesis_account, send2.hash (), nano::genesis_account, nano::genesis_amount - nano::Gxrb_ratio * 2, ledger.epoch_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);
|
||||
|
@ -2443,7 +2443,7 @@ TEST (ledger, epoch_blocks_receive_upgrade)
|
|||
nano::keypair destination4;
|
||||
nano::state_block send6 (nano::genesis_account, send5.hash (), nano::genesis_account, nano::genesis_amount - nano::Gxrb_ratio * 5, destination4.pub, nano::test_genesis_key.prv, nano::test_genesis_key.pub, *pool.generate (send5.hash ()));
|
||||
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, send6).code);
|
||||
nano::state_block epoch4 (destination4.pub, 0, 0, 0, ledger.link (nano::epoch::epoch_2), nano::test_genesis_key.prv, nano::test_genesis_key.pub, *pool.generate (destination4.pub));
|
||||
nano::state_block epoch4 (destination4.pub, 0, 0, 0, ledger.epoch_link (nano::epoch::epoch_2), nano::test_genesis_key.prv, nano::test_genesis_key.pub, *pool.generate (destination4.pub));
|
||||
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, epoch4).code);
|
||||
}
|
||||
|
||||
|
@ -2461,13 +2461,13 @@ TEST (ledger, epoch_blocks_fork)
|
|||
nano::keypair destination;
|
||||
nano::send_block send1 (genesis.hash (), nano::account (0), nano::genesis_amount, nano::test_genesis_key.prv, nano::test_genesis_key.pub, *pool.generate (genesis.hash ()));
|
||||
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 ()));
|
||||
nano::state_block epoch1 (nano::genesis_account, genesis.hash (), nano::genesis_account, nano::genesis_amount, ledger.epoch_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 ()));
|
||||
nano::state_block epoch2 (nano::genesis_account, genesis.hash (), nano::genesis_account, nano::genesis_amount, ledger.epoch_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 ()));
|
||||
nano::state_block epoch3 (nano::genesis_account, send1.hash (), nano::genesis_account, nano::genesis_amount, ledger.epoch_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 ()));
|
||||
nano::state_block epoch4 (nano::genesis_account, send1.hash (), nano::genesis_account, nano::genesis_amount, ledger.epoch_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);
|
||||
}
|
||||
|
||||
|
@ -2481,7 +2481,7 @@ TEST (ledger, successor_epoch)
|
|||
nano::state_block open (key1.pub, 0, key1.pub, 1, send1.hash (), key1.prv, key1.pub, *pool.generate (key1.pub));
|
||||
nano::state_block change (key1.pub, open.hash (), key1.pub, 1, 0, key1.prv, key1.pub, *pool.generate (open.hash ()));
|
||||
auto open_hash = open.hash ();
|
||||
nano::state_block epoch_open (reinterpret_cast<nano::account const &> (open_hash), 0, 0, 0, system.nodes[0]->ledger.link (nano::epoch::epoch_1), nano::test_genesis_key.prv, nano::test_genesis_key.pub, *pool.generate (open.hash ()));
|
||||
nano::state_block epoch_open (reinterpret_cast<nano::account const &> (open_hash), 0, 0, 0, system.nodes[0]->ledger.epoch_link (nano::epoch::epoch_1), nano::test_genesis_key.prv, nano::test_genesis_key.pub, *pool.generate (open.hash ()));
|
||||
auto transaction (system.nodes[0]->store.tx_begin_write ());
|
||||
ASSERT_EQ (nano::process_result::progress, system.nodes[0]->ledger.process (transaction, send1).code);
|
||||
ASSERT_EQ (nano::process_result::progress, system.nodes[0]->ledger.process (transaction, open).code);
|
||||
|
@ -2550,7 +2550,7 @@ TEST (ledger, block_hash_account_conflict)
|
|||
.previous (0)
|
||||
.representative (0)
|
||||
.balance (0)
|
||||
.link (node1.ledger.link (nano::epoch::epoch_1))
|
||||
.link (node1.ledger.epoch_link (nano::epoch::epoch_1))
|
||||
.sign (nano::test_genesis_key.prv, nano::test_genesis_key.pub)
|
||||
.work (*pool.generate (receive1->hash ()))
|
||||
.build ();
|
||||
|
@ -2634,7 +2634,7 @@ TEST (ledger, could_fit)
|
|||
ASSERT_TRUE (ledger.could_fit (transaction, receive1));
|
||||
ASSERT_TRUE (ledger.could_fit (transaction, receive2));
|
||||
// Test epoch (state)
|
||||
nano::state_block epoch1 (key1.pub, receive1.hash (), nano::genesis_account, 2, ledger.link (nano::epoch::epoch_1), nano::test_genesis_key.prv, nano::test_genesis_key.pub, *pool.generate (receive1.hash ()));
|
||||
nano::state_block epoch1 (key1.pub, receive1.hash (), nano::genesis_account, 2, ledger.epoch_link (nano::epoch::epoch_1), nano::test_genesis_key.prv, nano::test_genesis_key.pub, *pool.generate (receive1.hash ()));
|
||||
ASSERT_FALSE (ledger.could_fit (transaction, epoch1));
|
||||
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, receive1).code);
|
||||
ASSERT_TRUE (ledger.could_fit (transaction, receive1));
|
||||
|
@ -2654,7 +2654,7 @@ TEST (ledger, unchecked_epoch)
|
|||
node1.work_generate_blocking (*send1);
|
||||
auto open1 (std::make_shared<nano::state_block> (destination.pub, 0, destination.pub, nano::Gxrb_ratio, send1->hash (), destination.prv, destination.pub, 0));
|
||||
node1.work_generate_blocking (*open1);
|
||||
auto epoch1 (std::make_shared<nano::state_block> (destination.pub, open1->hash (), destination.pub, nano::Gxrb_ratio, node1.ledger.link (nano::epoch::epoch_1), nano::test_genesis_key.prv, nano::test_genesis_key.pub, 0));
|
||||
auto epoch1 (std::make_shared<nano::state_block> (destination.pub, open1->hash (), destination.pub, nano::Gxrb_ratio, node1.ledger.epoch_link (nano::epoch::epoch_1), nano::test_genesis_key.prv, nano::test_genesis_key.pub, 0));
|
||||
node1.work_generate_blocking (*epoch1);
|
||||
node1.block_processor.add (epoch1);
|
||||
node1.block_processor.flush ();
|
||||
|
@ -2693,10 +2693,10 @@ TEST (ledger, unchecked_epoch_invalid)
|
|||
auto open1 (std::make_shared<nano::state_block> (destination.pub, 0, destination.pub, nano::Gxrb_ratio, send1->hash (), destination.prv, destination.pub, 0));
|
||||
node1.work_generate_blocking (*open1);
|
||||
// Epoch block with account own signature
|
||||
auto epoch1 (std::make_shared<nano::state_block> (destination.pub, open1->hash (), destination.pub, nano::Gxrb_ratio, node1.ledger.link (nano::epoch::epoch_1), destination.prv, destination.pub, 0));
|
||||
auto epoch1 (std::make_shared<nano::state_block> (destination.pub, open1->hash (), destination.pub, nano::Gxrb_ratio, node1.ledger.epoch_link (nano::epoch::epoch_1), destination.prv, destination.pub, 0));
|
||||
node1.work_generate_blocking (*epoch1);
|
||||
// Pseudo epoch block (send subtype, destination - epoch link)
|
||||
auto epoch2 (std::make_shared<nano::state_block> (destination.pub, open1->hash (), destination.pub, nano::Gxrb_ratio - 1, node1.ledger.link (nano::epoch::epoch_1), destination.prv, destination.pub, 0));
|
||||
auto epoch2 (std::make_shared<nano::state_block> (destination.pub, open1->hash (), destination.pub, nano::Gxrb_ratio - 1, node1.ledger.epoch_link (nano::epoch::epoch_1), destination.prv, destination.pub, 0));
|
||||
node1.work_generate_blocking (*epoch2);
|
||||
node1.block_processor.add (epoch1);
|
||||
node1.block_processor.add (epoch2);
|
||||
|
|
|
@ -2554,7 +2554,7 @@ TEST (node, vote_by_hash_epoch_block_republish)
|
|||
system.wallet (1)->insert_adhoc (key2.prv);
|
||||
nano::genesis genesis;
|
||||
auto send1 (std::make_shared<nano::send_block> (genesis.hash (), key2.pub, std::numeric_limits<nano::uint128_t>::max () - system.nodes[0]->config.receive_minimum.number (), nano::test_genesis_key.prv, nano::test_genesis_key.pub, *system.work.generate (genesis.hash ())));
|
||||
auto epoch1 (std::make_shared<nano::state_block> (nano::genesis_account, genesis.hash (), nano::genesis_account, nano::genesis_amount, system.nodes[0]->ledger.link (nano::epoch::epoch_1), nano::test_genesis_key.prv, nano::test_genesis_key.pub, *system.work.generate (genesis.hash ())));
|
||||
auto epoch1 (std::make_shared<nano::state_block> (nano::genesis_account, genesis.hash (), nano::genesis_account, nano::genesis_amount, system.nodes[0]->ledger.epoch_link (nano::epoch::epoch_1), nano::test_genesis_key.prv, nano::test_genesis_key.pub, *system.work.generate (genesis.hash ())));
|
||||
system.nodes[0]->process_active (send1);
|
||||
system.deadline_set (5s);
|
||||
while (!system.nodes[1]->block (send1->hash ()))
|
||||
|
@ -2594,7 +2594,7 @@ TEST (node, epoch_conflict_confirm)
|
|||
auto send (std::make_shared<nano::state_block> (nano::test_genesis_key.pub, genesis.hash (), nano::test_genesis_key.pub, nano::genesis_amount - 1, key.pub, nano::test_genesis_key.prv, nano::test_genesis_key.pub, *system.work.generate (genesis.hash ())));
|
||||
auto open (std::make_shared<nano::state_block> (key.pub, 0, key.pub, 1, send->hash (), key.prv, key.pub, *system.work.generate (key.pub)));
|
||||
auto change (std::make_shared<nano::state_block> (key.pub, open->hash (), key.pub, 1, 0, key.prv, key.pub, *system.work.generate (open->hash ())));
|
||||
auto epoch (std::make_shared<nano::state_block> (change->root (), 0, 0, 0, node0->ledger.link (nano::epoch::epoch_1), epoch_signer.prv, epoch_signer.pub, *system.work.generate (open->hash ())));
|
||||
auto epoch (std::make_shared<nano::state_block> (change->root (), 0, 0, 0, node0->ledger.epoch_link (nano::epoch::epoch_1), epoch_signer.prv, epoch_signer.pub, *system.work.generate (open->hash ())));
|
||||
{
|
||||
auto transaction (node0->store.tx_begin_write ());
|
||||
ASSERT_EQ (nano::process_result::progress, node0->block_processor.process_one (transaction, send).code);
|
||||
|
|
|
@ -170,6 +170,10 @@ std::string nano::error_rpc_messages::message (int ev) const
|
|||
return "Invalid balance number";
|
||||
case nano::error_rpc::invalid_destinations:
|
||||
return "Invalid destinations number";
|
||||
case nano::error_rpc::invalid_epoch:
|
||||
return "Invalid epoch number";
|
||||
case nano::error_rpc::invalid_epoch_signer:
|
||||
return "Incorrect epoch signer";
|
||||
case nano::error_rpc::invalid_offset:
|
||||
return "Invalid offset";
|
||||
case nano::error_rpc::invalid_missing_type:
|
||||
|
|
|
@ -98,6 +98,8 @@ enum class error_rpc
|
|||
disabled_bootstrap_legacy,
|
||||
invalid_balance,
|
||||
invalid_destinations,
|
||||
invalid_epoch,
|
||||
invalid_epoch_signer,
|
||||
invalid_offset,
|
||||
invalid_missing_type,
|
||||
invalid_root,
|
||||
|
|
|
@ -887,7 +887,7 @@ int main (int argc, char * const * argv)
|
|||
}
|
||||
if (node.node->ledger.is_epoch_link (state_block.hashables.link) && state_block.hashables.balance == prev_balance)
|
||||
{
|
||||
invalid = validate_message (node.node->ledger.signer (block->link ()), hash, block->block_signature ());
|
||||
invalid = validate_message (node.node->ledger.epoch_signer (block->link ()), hash, block->block_signature ());
|
||||
}
|
||||
}
|
||||
if (invalid)
|
||||
|
|
|
@ -184,7 +184,7 @@ void nano::block_processor::verify_state_blocks (nano::unique_lock<std::mutex> &
|
|||
nano::account account (item.block->account ());
|
||||
if (!item.block->link ().is_zero () && node.ledger.is_epoch_link (item.block->link ()))
|
||||
{
|
||||
account = node.ledger.signer (item.block->link ());
|
||||
account = node.ledger.epoch_signer (item.block->link ());
|
||||
}
|
||||
else if (!item.account.is_zero ())
|
||||
{
|
||||
|
|
|
@ -2040,6 +2040,247 @@ void nano::json_handler::deterministic_key ()
|
|||
response_errors ();
|
||||
}
|
||||
|
||||
void epoch_upgrader (std::shared_ptr<nano::node> node_a, nano::private_key const & prv_a, nano::epoch epoch_a, uint64_t count_limit)
|
||||
{
|
||||
uint64_t const upgrade_batch_size = 1000;
|
||||
nano::block_builder builder;
|
||||
auto link (node_a->ledger.epoch_link (epoch_a));
|
||||
nano::raw_key raw_key;
|
||||
raw_key.data = prv_a;
|
||||
auto signer (nano::pub_key (prv_a));
|
||||
assert (signer == node_a->ledger.epoch_signer (link));
|
||||
|
||||
class account_upgrade_item final
|
||||
{
|
||||
public:
|
||||
nano::account account{ 0 };
|
||||
uint64_t modified{ 0 };
|
||||
};
|
||||
class account_tag
|
||||
{
|
||||
};
|
||||
class modified_tag
|
||||
{
|
||||
};
|
||||
boost::multi_index_container<
|
||||
account_upgrade_item,
|
||||
boost::multi_index::indexed_by<
|
||||
boost::multi_index::ordered_non_unique<boost::multi_index::tag<modified_tag>, boost::multi_index::member<account_upgrade_item, uint64_t, &account_upgrade_item::modified>, std::greater<uint64_t>>,
|
||||
boost::multi_index::hashed_unique<boost::multi_index::tag<account_tag>, boost::multi_index::member<account_upgrade_item, nano::account, &account_upgrade_item::account>>>>
|
||||
accounts_list;
|
||||
|
||||
bool finished_upgrade (false);
|
||||
|
||||
while (!finished_upgrade && !node_a->stopped)
|
||||
{
|
||||
bool finished_accounts (false);
|
||||
uint64_t total_upgraded_accounts (0);
|
||||
while (!finished_accounts && count_limit != 0 && !node_a->stopped)
|
||||
{
|
||||
{
|
||||
auto transaction (node_a->store.tx_begin_read ());
|
||||
// Collect accounts to upgrade
|
||||
for (auto i (node_a->store.latest_begin (transaction)), n (node_a->store.latest_end ()); i != n; ++i)
|
||||
{
|
||||
nano::account const & account (i->first);
|
||||
nano::account_info const & info (i->second);
|
||||
if (info.epoch () < epoch_a)
|
||||
{
|
||||
release_assert (nano::epochs::is_sequential (info.epoch (), epoch_a));
|
||||
accounts_list.insert (account_upgrade_item{ account, info.modified });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Upgrade accounts
|
||||
Repeat until accounts with previous epoch exist in latest table */
|
||||
uint64_t upgraded_accounts (0);
|
||||
for (auto i (accounts_list.get<modified_tag> ().begin ()), n (accounts_list.get<modified_tag> ().end ()); i != n && upgraded_accounts < upgrade_batch_size && upgraded_accounts < count_limit && !node_a->stopped; ++i)
|
||||
{
|
||||
auto transaction (node_a->store.tx_begin_read ());
|
||||
nano::account_info info;
|
||||
if (!node_a->store.account_get (transaction, i->account, info) && info.epoch () < epoch_a)
|
||||
{
|
||||
auto epoch = builder.state ()
|
||||
.account (i->account)
|
||||
.previous (info.head)
|
||||
.representative (info.representative)
|
||||
.balance (info.balance)
|
||||
.link (link)
|
||||
.sign (raw_key, signer)
|
||||
.work (node_a->work_generate_blocking (info.head).value_or (0))
|
||||
.build ();
|
||||
bool valid_signature (!nano::validate_message (signer, epoch->hash (), epoch->block_signature ()));
|
||||
bool valid_work (!nano::work_validate (*epoch.get ()));
|
||||
nano::process_result result (nano::process_result::old);
|
||||
if (valid_signature && valid_work)
|
||||
{
|
||||
result = node_a->process_local (std::move (epoch)).code;
|
||||
}
|
||||
if (result == nano::process_result::progress)
|
||||
{
|
||||
++upgraded_accounts;
|
||||
}
|
||||
else
|
||||
{
|
||||
bool fork (result == nano::process_result::fork);
|
||||
node_a->logger.always_log (boost::str (boost::format ("Failed to upgrade account %1%. Valid signature: %2%. Valid work: %3%. Block processor fork: %4%") % i->account.to_account () % valid_signature % valid_work % fork));
|
||||
}
|
||||
}
|
||||
}
|
||||
total_upgraded_accounts += upgraded_accounts;
|
||||
count_limit -= upgraded_accounts;
|
||||
|
||||
if (!accounts_list.empty ())
|
||||
{
|
||||
node_a->logger.always_log (boost::str (boost::format ("%1% accounts were upgraded to new epoch, %2% remain...") % total_upgraded_accounts % (accounts_list.size () - upgraded_accounts)));
|
||||
accounts_list.clear ();
|
||||
}
|
||||
else
|
||||
{
|
||||
node_a->logger.always_log (boost::str (boost::format ("%1% total accounts were upgraded to new epoch") % total_upgraded_accounts));
|
||||
finished_accounts = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Pending blocks upgrade
|
||||
bool finished_pending (false);
|
||||
uint64_t total_upgraded_pending (0);
|
||||
while (!finished_pending && count_limit != 0 && !node_a->stopped)
|
||||
{
|
||||
uint64_t upgraded_pending (0);
|
||||
auto transaction (node_a->store.tx_begin_read ());
|
||||
for (auto i (node_a->store.pending_begin (transaction, nano::pending_key (1, 0))), n (node_a->store.pending_end ()); i != n && upgraded_pending < upgrade_batch_size && upgraded_pending < count_limit && !node_a->stopped;)
|
||||
{
|
||||
bool to_next_account (false);
|
||||
nano::pending_key const & key (i->first);
|
||||
if (!node_a->store.account_exists (transaction, key.account))
|
||||
{
|
||||
nano::pending_info const & info (i->second);
|
||||
if (info.epoch < epoch_a)
|
||||
{
|
||||
release_assert (nano::epochs::is_sequential (info.epoch, epoch_a));
|
||||
auto epoch = builder.state ()
|
||||
.account (key.account)
|
||||
.previous (0)
|
||||
.representative (0)
|
||||
.balance (0)
|
||||
.link (link)
|
||||
.sign (raw_key, signer)
|
||||
.work (node_a->work_generate_blocking (key.account).value_or (0))
|
||||
.build ();
|
||||
bool valid_signature (!nano::validate_message (signer, epoch->hash (), epoch->block_signature ()));
|
||||
bool valid_work (!nano::work_validate (*epoch.get ()));
|
||||
nano::process_result result (nano::process_result::old);
|
||||
if (valid_signature && valid_work)
|
||||
{
|
||||
result = node_a->process_local (std::move (epoch)).code;
|
||||
}
|
||||
if (result == nano::process_result::progress)
|
||||
{
|
||||
++upgraded_pending;
|
||||
to_next_account = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
bool fork (result == nano::process_result::fork);
|
||||
node_a->logger.always_log (boost::str (boost::format ("Failed to upgrade account with pending blocks %1%. Valid signature: %2%. Valid work: %3%. Block processor fork: %4%") % key.account.to_account () % valid_signature % valid_work % fork));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
to_next_account = true;
|
||||
}
|
||||
if (to_next_account)
|
||||
{
|
||||
// Move to next account if pending account exists or was upgraded
|
||||
if (key.account.number () == std::numeric_limits<nano::uint256_t>::max ())
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
i = node_a->store.pending_begin (transaction, nano::pending_key (key.account.number () + 1, 0));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Move to next pending item
|
||||
++i;
|
||||
}
|
||||
}
|
||||
total_upgraded_pending += upgraded_pending;
|
||||
count_limit -= upgraded_pending;
|
||||
|
||||
// Repeat if some pending accounts were upgraded
|
||||
if (upgraded_pending != 0)
|
||||
{
|
||||
node_a->logger.always_log (boost::str (boost::format ("%1% unopened accounts with pending blocks were upgraded to new epoch...") % total_upgraded_pending));
|
||||
}
|
||||
else
|
||||
{
|
||||
node_a->logger.always_log (boost::str (boost::format ("%1% total unopened accounts with pending blocks were upgraded to new epoch") % total_upgraded_pending));
|
||||
finished_pending = true;
|
||||
}
|
||||
}
|
||||
|
||||
finished_upgrade = (total_upgraded_accounts == 0) && (total_upgraded_pending == 0);
|
||||
}
|
||||
|
||||
node_a->logger.always_log ("Epoch upgrade is completed");
|
||||
}
|
||||
|
||||
/*
|
||||
* @warning This is an internal/diagnostic RPC, do not rely on its interface being stable
|
||||
*/
|
||||
void nano::json_handler::epoch_upgrade ()
|
||||
{
|
||||
nano::epoch epoch (nano::epoch::invalid);
|
||||
uint8_t epoch_int (request.get<uint8_t> ("epoch"));
|
||||
switch (epoch_int)
|
||||
{
|
||||
case 1:
|
||||
epoch = nano::epoch::epoch_1;
|
||||
break;
|
||||
case 2:
|
||||
epoch = nano::epoch::epoch_2;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (epoch != nano::epoch::invalid)
|
||||
{
|
||||
uint64_t count_limit (count_optional_impl ());
|
||||
std::string key_text (request.get<std::string> ("key"));
|
||||
nano::private_key prv;
|
||||
if (!prv.decode_hex (key_text))
|
||||
{
|
||||
if (nano::pub_key (prv) == node.ledger.epoch_signer (node.ledger.epoch_link (epoch)))
|
||||
{
|
||||
auto node_l (node.shared ());
|
||||
node.worker.push_task ([node_l, prv, epoch, count_limit]() {
|
||||
epoch_upgrader (node_l, prv, epoch, count_limit);
|
||||
});
|
||||
response_l.put ("started", "1");
|
||||
}
|
||||
else
|
||||
{
|
||||
ec = nano::error_rpc::invalid_epoch_signer;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ec = nano::error_common::bad_private_key;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ec = nano::error_rpc::invalid_epoch;
|
||||
}
|
||||
response_errors ();
|
||||
}
|
||||
|
||||
void nano::json_handler::frontiers ()
|
||||
{
|
||||
auto start (account_impl ());
|
||||
|
@ -2189,7 +2430,7 @@ public:
|
|||
if (raw && accounts_filter.empty ())
|
||||
{
|
||||
tree.put ("subtype", "epoch");
|
||||
tree.put ("account", handler.node.ledger.signer (block_a.link ()).to_account ());
|
||||
tree.put ("account", handler.node.ledger.epoch_signer (block_a.link ()).to_account ());
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -4765,6 +5006,7 @@ ipc_json_handler_no_arg_func_map create_ipc_json_handler_no_arg_func_map ()
|
|||
no_arg_funcs.emplace ("delegators", &nano::json_handler::delegators);
|
||||
no_arg_funcs.emplace ("delegators_count", &nano::json_handler::delegators_count);
|
||||
no_arg_funcs.emplace ("deterministic_key", &nano::json_handler::deterministic_key);
|
||||
no_arg_funcs.emplace ("epoch_upgrade", &nano::json_handler::epoch_upgrade);
|
||||
no_arg_funcs.emplace ("frontiers", &nano::json_handler::frontiers);
|
||||
no_arg_funcs.emplace ("frontier_count", &nano::json_handler::account_count);
|
||||
no_arg_funcs.emplace ("keepalive", &nano::json_handler::keepalive);
|
||||
|
|
|
@ -63,6 +63,7 @@ public:
|
|||
void delegators ();
|
||||
void delegators_count ();
|
||||
void deterministic_key ();
|
||||
void epoch_upgrade ();
|
||||
void frontiers ();
|
||||
void keepalive ();
|
||||
void key_create ();
|
||||
|
|
|
@ -1302,7 +1302,7 @@ bool nano::node::validate_block_by_previous (nano::transaction const & transacti
|
|||
{
|
||||
if (block_l->hashables.balance == prev_balance && ledger.is_epoch_link (block_l->hashables.link))
|
||||
{
|
||||
account = ledger.signer (block_l->link ());
|
||||
account = ledger.epoch_signer (block_l->link ());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -571,7 +571,7 @@ public:
|
|||
else if (balance == previous_balance && ledger.is_epoch_link (block_a.hashables.link))
|
||||
{
|
||||
type = "Epoch";
|
||||
account = ledger.signer (block_a.hashables.link);
|
||||
account = ledger.epoch_signer (block_a.hashables.link);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -127,6 +127,7 @@ std::unordered_set<std::string> create_rpc_control_impls ()
|
|||
set.emplace ("bootstrap_lazy");
|
||||
set.emplace ("confirmation_height_currently_processing");
|
||||
set.emplace ("database_txn_tracker");
|
||||
set.emplace ("epoch_upgrade");
|
||||
set.emplace ("keepalive");
|
||||
set.emplace ("ledger");
|
||||
set.emplace ("node_id");
|
||||
|
|
|
@ -7147,3 +7147,124 @@ TEST (rpc, deprecated_account_format)
|
|||
boost::optional<std::string> deprecated_account_format2 (response2.json.get_optional<std::string> ("deprecated_account_format"));
|
||||
ASSERT_TRUE (deprecated_account_format2.is_initialized ());
|
||||
}
|
||||
|
||||
TEST (rpc, epoch_upgrade)
|
||||
{
|
||||
nano::system system (24000, 1);
|
||||
auto node = system.nodes.front ();
|
||||
nano::keypair key1, key2, key3;
|
||||
nano::genesis genesis;
|
||||
nano::keypair epoch_signer (nano::test_genesis_key);
|
||||
auto send1 (std::make_shared<nano::state_block> (nano::test_genesis_key.pub, genesis.hash (), nano::test_genesis_key.pub, nano::genesis_amount - 1, key1.pub, nano::test_genesis_key.prv, nano::test_genesis_key.pub, *system.work.generate (genesis.hash ()))); // to opened account
|
||||
ASSERT_EQ (nano::process_result::progress, node->process (*send1).code);
|
||||
auto send2 (std::make_shared<nano::state_block> (nano::test_genesis_key.pub, send1->hash (), nano::test_genesis_key.pub, nano::genesis_amount - 2, key2.pub, nano::test_genesis_key.prv, nano::test_genesis_key.pub, *system.work.generate (send1->hash ()))); // to unopened account (pending)
|
||||
ASSERT_EQ (nano::process_result::progress, node->process (*send2).code);
|
||||
auto send3 (std::make_shared<nano::state_block> (nano::test_genesis_key.pub, send2->hash (), nano::test_genesis_key.pub, nano::genesis_amount - 3, 0, nano::test_genesis_key.prv, nano::test_genesis_key.pub, *system.work.generate (send2->hash ()))); // to burn (0)
|
||||
ASSERT_EQ (nano::process_result::progress, node->process (*send3).code);
|
||||
nano::account max_account (std::numeric_limits<nano::uint256_t>::max ());
|
||||
auto send4 (std::make_shared<nano::state_block> (nano::test_genesis_key.pub, send3->hash (), nano::test_genesis_key.pub, nano::genesis_amount - 4, max_account, nano::test_genesis_key.prv, nano::test_genesis_key.pub, *system.work.generate (send3->hash ()))); // to max account
|
||||
ASSERT_EQ (nano::process_result::progress, node->process (*send4).code);
|
||||
auto open (std::make_shared<nano::state_block> (key1.pub, 0, key1.pub, 1, send1->hash (), key1.prv, key1.pub, *system.work.generate (key1.pub)));
|
||||
ASSERT_EQ (nano::process_result::progress, node->process (*open).code);
|
||||
// Check accounts epochs
|
||||
{
|
||||
auto transaction (node->store.tx_begin_read ());
|
||||
ASSERT_EQ (2, node->store.account_count (transaction));
|
||||
for (auto i (node->store.latest_begin (transaction)); i != node->store.latest_end (); ++i)
|
||||
{
|
||||
nano::account_info info (i->second);
|
||||
ASSERT_EQ (info.epoch (), nano::epoch::epoch_0);
|
||||
}
|
||||
}
|
||||
enable_ipc_transport_tcp (node->config.ipc_config.transport_tcp);
|
||||
nano::node_rpc_config node_rpc_config;
|
||||
nano::ipc::ipc_server ipc_server (*node, node_rpc_config);
|
||||
nano::rpc_config rpc_config (true);
|
||||
nano::ipc_rpc_processor ipc_rpc_processor (system.io_ctx, rpc_config);
|
||||
nano::rpc rpc (system.io_ctx, rpc_config, ipc_rpc_processor);
|
||||
rpc.start ();
|
||||
boost::property_tree::ptree request;
|
||||
request.put ("action", "epoch_upgrade");
|
||||
request.put ("epoch", 1);
|
||||
request.put ("key", epoch_signer.prv.data.to_string ());
|
||||
test_response response (request, rpc.config.port, system.io_ctx);
|
||||
system.deadline_set (5s);
|
||||
while (response.status == 0)
|
||||
{
|
||||
ASSERT_NO_ERROR (system.poll ());
|
||||
}
|
||||
ASSERT_EQ (200, response.status);
|
||||
ASSERT_EQ ("1", response.json.get<std::string> ("started"));
|
||||
system.deadline_set (5s);
|
||||
bool done (false);
|
||||
while (!done)
|
||||
{
|
||||
auto transaction (node->store.tx_begin_read ());
|
||||
done = (4 == node->store.account_count (transaction));
|
||||
ASSERT_NO_ERROR (system.poll ());
|
||||
}
|
||||
// Check upgrade
|
||||
{
|
||||
auto transaction (node->store.tx_begin_read ());
|
||||
ASSERT_EQ (4, node->store.account_count (transaction));
|
||||
for (auto i (node->store.latest_begin (transaction)); i != node->store.latest_end (); ++i)
|
||||
{
|
||||
nano::account_info info (i->second);
|
||||
ASSERT_EQ (info.epoch (), nano::epoch::epoch_1);
|
||||
}
|
||||
ASSERT_TRUE (node->store.account_exists (transaction, key1.pub));
|
||||
ASSERT_TRUE (node->store.account_exists (transaction, key2.pub));
|
||||
ASSERT_TRUE (node->store.account_exists (transaction, std::numeric_limits<nano::uint256_t>::max ()));
|
||||
ASSERT_FALSE (node->store.account_exists (transaction, 0));
|
||||
}
|
||||
|
||||
// Epoch 2 upgrade
|
||||
auto genesis_latest (node->latest (nano::test_genesis_key.pub));
|
||||
auto send5 (std::make_shared<nano::state_block> (nano::test_genesis_key.pub, genesis_latest, nano::test_genesis_key.pub, nano::genesis_amount - 5, 0, nano::test_genesis_key.prv, nano::test_genesis_key.pub, *system.work.generate (genesis_latest))); // to burn (0)
|
||||
ASSERT_EQ (nano::process_result::progress, node->process (*send5).code);
|
||||
auto send6 (std::make_shared<nano::state_block> (nano::test_genesis_key.pub, send5->hash (), nano::test_genesis_key.pub, nano::genesis_amount - 6, key1.pub, nano::test_genesis_key.prv, nano::test_genesis_key.pub, *system.work.generate (send5->hash ()))); // to key1 (again)
|
||||
ASSERT_EQ (nano::process_result::progress, node->process (*send6).code);
|
||||
auto key1_latest (node->latest (key1.pub));
|
||||
auto send7 (std::make_shared<nano::state_block> (key1.pub, key1_latest, key1.pub, 0, key3.pub, key1.prv, key1.pub, *system.work.generate (key1_latest))); // to key3
|
||||
ASSERT_EQ (nano::process_result::progress, node->process (*send7).code);
|
||||
{
|
||||
// Check pending entry
|
||||
auto transaction (node->store.tx_begin_read ());
|
||||
nano::pending_info info;
|
||||
ASSERT_FALSE (node->store.pending_get (transaction, nano::pending_key (key3.pub, send7->hash ()), info));
|
||||
ASSERT_EQ (nano::epoch::epoch_1, info.epoch);
|
||||
}
|
||||
|
||||
request.put ("epoch", 2);
|
||||
test_response response2 (request, rpc.config.port, system.io_ctx);
|
||||
system.deadline_set (5s);
|
||||
while (response2.status == 0)
|
||||
{
|
||||
ASSERT_NO_ERROR (system.poll ());
|
||||
}
|
||||
ASSERT_EQ (200, response2.status);
|
||||
ASSERT_EQ ("1", response2.json.get<std::string> ("started"));
|
||||
system.deadline_set (5s);
|
||||
bool done2 (false);
|
||||
while (!done2)
|
||||
{
|
||||
auto transaction (node->store.tx_begin_read ());
|
||||
done2 = (5 == node->store.account_count (transaction));
|
||||
ASSERT_NO_ERROR (system.poll ());
|
||||
}
|
||||
// Check upgrade
|
||||
{
|
||||
auto transaction (node->store.tx_begin_read ());
|
||||
ASSERT_EQ (5, node->store.account_count (transaction));
|
||||
for (auto i (node->store.latest_begin (transaction)); i != node->store.latest_end (); ++i)
|
||||
{
|
||||
nano::account_info info (i->second);
|
||||
ASSERT_EQ (info.epoch (), nano::epoch::epoch_2);
|
||||
}
|
||||
ASSERT_TRUE (node->store.account_exists (transaction, key1.pub));
|
||||
ASSERT_TRUE (node->store.account_exists (transaction, key2.pub));
|
||||
ASSERT_TRUE (node->store.account_exists (transaction, key3.pub));
|
||||
ASSERT_TRUE (node->store.account_exists (transaction, std::numeric_limits<nano::uint256_t>::max ()));
|
||||
ASSERT_FALSE (node->store.account_exists (transaction, 0));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -211,7 +211,7 @@ bool ledger_processor::validate_epoch_block (nano::state_block const & block_a)
|
|||
if (validate_message (block_a.hashables.account, block_a.hash (), block_a.signature))
|
||||
{
|
||||
// Is epoch block signed correctly
|
||||
if (validate_message (ledger.signer (block_a.link ()), block_a.hash (), block_a.signature))
|
||||
if (validate_message (ledger.epoch_signer (block_a.link ()), block_a.hash (), block_a.signature))
|
||||
{
|
||||
result.verified = nano::signature_verification::invalid;
|
||||
result.code = nano::process_result::bad_signature;
|
||||
|
@ -378,11 +378,11 @@ void ledger_processor::epoch_block_impl (nano::state_block const & block_a)
|
|||
// Validate block if not verified outside of ledger
|
||||
if (result.verified != nano::signature_verification::valid_epoch)
|
||||
{
|
||||
result.code = validate_message (ledger.signer (block_a.hashables.link), hash, block_a.signature) ? nano::process_result::bad_signature : nano::process_result::progress; // Is this block signed correctly (Unambiguous)
|
||||
result.code = validate_message (ledger.epoch_signer (block_a.hashables.link), hash, block_a.signature) ? nano::process_result::bad_signature : nano::process_result::progress; // Is this block signed correctly (Unambiguous)
|
||||
}
|
||||
if (result.code == nano::process_result::progress)
|
||||
{
|
||||
assert (!validate_message (ledger.signer (block_a.hashables.link), hash, block_a.signature));
|
||||
assert (!validate_message (ledger.epoch_signer (block_a.hashables.link), hash, block_a.signature));
|
||||
result.verified = nano::signature_verification::valid_epoch;
|
||||
result.code = block_a.hashables.account.is_zero () ? nano::process_result::opened_burn_account : nano::process_result::progress; // Is this for the burn account? (Unambiguous)
|
||||
if (result.code == nano::process_result::progress)
|
||||
|
@ -1021,12 +1021,12 @@ bool nano::ledger::is_epoch_link (nano::link const & link_a)
|
|||
return network_params.ledger.epochs.is_epoch_link (link_a);
|
||||
}
|
||||
|
||||
nano::account const & nano::ledger::signer (nano::link const & link_a) const
|
||||
nano::account const & nano::ledger::epoch_signer (nano::link const & link_a) const
|
||||
{
|
||||
return network_params.ledger.epochs.signer (network_params.ledger.epochs.epoch (link_a));
|
||||
}
|
||||
|
||||
nano::link const & nano::ledger::link (nano::epoch epoch_a) const
|
||||
nano::link const & nano::ledger::epoch_link (nano::epoch epoch_a) const
|
||||
{
|
||||
return network_params.ledger.epochs.link (epoch_a);
|
||||
}
|
||||
|
|
|
@ -43,8 +43,8 @@ public:
|
|||
void dump_account_chain (nano::account const &);
|
||||
bool could_fit (nano::transaction const &, nano::block const &);
|
||||
bool is_epoch_link (nano::link const &);
|
||||
nano::account const & signer (nano::link const &) const;
|
||||
nano::link const & link (nano::epoch) const;
|
||||
nano::account const & epoch_signer (nano::link const &) const;
|
||||
nano::link const & epoch_link (nano::epoch) const;
|
||||
static nano::uint128_t const unit;
|
||||
nano::network_params network_params;
|
||||
nano::block_store & store;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue