Add source block epoch to sideband information (#2873)
* Add source block epoch to sideband information With v18->v19 DB upgrade To prevent rollback issues for pruned ledger in future versions. * Fix build error & warnings * Clang formatting * Move source epoch out of block details & more tests * Remove unused header
This commit is contained in:
parent
d772c34fb1
commit
b795fd1cba
15 changed files with 277 additions and 45 deletions
|
|
@ -909,7 +909,7 @@ TEST (active_transactions, dropped_cleanup)
|
|||
|
||||
nano::genesis genesis;
|
||||
auto block = genesis.open;
|
||||
block->sideband_set (nano::block_sideband (nano::genesis_account, 0, nano::genesis_amount, 1, nano::seconds_since_epoch (), nano::epoch::epoch_0, false, false, false));
|
||||
block->sideband_set (nano::block_sideband (nano::genesis_account, 0, nano::genesis_amount, 1, nano::seconds_since_epoch (), nano::epoch::epoch_0, false, false, false, nano::epoch::epoch_0));
|
||||
|
||||
// Add to network filter to ensure proper cleanup after the election is dropped
|
||||
std::vector<uint8_t> block_bytes;
|
||||
|
|
|
|||
|
|
@ -1623,10 +1623,13 @@ TEST (mdb_block_store, upgrade_v18_v19)
|
|||
auto path (nano::unique_path ());
|
||||
nano::keypair key1;
|
||||
nano::work_pool pool (std::numeric_limits<unsigned>::max ());
|
||||
nano::network_params network_params;
|
||||
nano::send_block send (nano::genesis_hash, nano::test_genesis_key.pub, nano::genesis_amount - nano::Gxrb_ratio, nano::test_genesis_key.prv, nano::test_genesis_key.pub, *pool.generate (nano::genesis_hash));
|
||||
nano::receive_block receive (send.hash (), send.hash (), nano::test_genesis_key.prv, nano::test_genesis_key.pub, *pool.generate (send.hash ()));
|
||||
nano::change_block change (receive.hash (), 0, nano::test_genesis_key.prv, nano::test_genesis_key.pub, *pool.generate (receive.hash ()));
|
||||
nano::state_block state (nano::test_genesis_key.pub, change.hash (), 0, nano::genesis_amount - nano::Gxrb_ratio, key1.pub, nano::test_genesis_key.prv, nano::test_genesis_key.pub, *pool.generate (change.hash ()));
|
||||
nano::state_block state_epoch (nano::test_genesis_key.pub, change.hash (), 0, nano::genesis_amount, network_params.ledger.epochs.link (nano::epoch::epoch_1), nano::test_genesis_key.prv, nano::test_genesis_key.pub, *pool.generate (change.hash ()));
|
||||
nano::state_block state_send (nano::test_genesis_key.pub, state_epoch.hash (), 0, nano::genesis_amount - nano::Gxrb_ratio, key1.pub, nano::test_genesis_key.prv, nano::test_genesis_key.pub, *pool.generate (state_epoch.hash ()));
|
||||
nano::state_block state_open (key1.pub, 0, 0, nano::Gxrb_ratio, state_send.hash (), key1.prv, key1.pub, *pool.generate (key1.pub));
|
||||
|
||||
{
|
||||
nano::genesis genesis;
|
||||
|
|
@ -1640,7 +1643,9 @@ TEST (mdb_block_store, upgrade_v18_v19)
|
|||
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, send).code);
|
||||
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, receive).code);
|
||||
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, change).code);
|
||||
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, state).code);
|
||||
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, state_epoch).code);
|
||||
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, state_send).code);
|
||||
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, state_open).code);
|
||||
|
||||
// These tables need to be re-opened and populated so that an upgrade can be done
|
||||
auto txn = store.env.tx (transaction);
|
||||
|
|
@ -1655,7 +1660,9 @@ TEST (mdb_block_store, upgrade_v18_v19)
|
|||
write_block_w_sideband_v18 (store, store.send_blocks, transaction, send);
|
||||
write_block_w_sideband_v18 (store, store.receive_blocks, transaction, receive);
|
||||
write_block_w_sideband_v18 (store, store.change_blocks, transaction, change);
|
||||
write_block_w_sideband_v18 (store, store.state_blocks, transaction, state);
|
||||
write_block_w_sideband_v18 (store, store.state_blocks, transaction, state_epoch);
|
||||
write_block_w_sideband_v18 (store, store.state_blocks, transaction, state_send);
|
||||
write_block_w_sideband_v18 (store, store.state_blocks, transaction, state_open);
|
||||
|
||||
store.version_put (transaction, 18);
|
||||
}
|
||||
|
|
@ -1678,9 +1685,22 @@ TEST (mdb_block_store, upgrade_v18_v19)
|
|||
ASSERT_TRUE (store.block_get (transaction, receive.hash ()));
|
||||
ASSERT_TRUE (store.block_get (transaction, change.hash ()));
|
||||
ASSERT_TRUE (store.block_get (transaction, nano::genesis_hash));
|
||||
ASSERT_TRUE (store.block_get (transaction, state.hash ()));
|
||||
auto state_epoch_disk (store.block_get (transaction, state_epoch.hash ()));
|
||||
ASSERT_NE (nullptr, state_epoch_disk);
|
||||
ASSERT_EQ (nano::epoch::epoch_1, state_epoch_disk->sideband ().details.epoch);
|
||||
ASSERT_EQ (nano::epoch::epoch_0, state_epoch_disk->sideband ().source_epoch); // Not used for epoch state blocks
|
||||
ASSERT_TRUE (store.block_get (transaction, state_send.hash ()));
|
||||
auto state_send_disk (store.block_get (transaction, state_send.hash ()));
|
||||
ASSERT_NE (nullptr, state_send_disk);
|
||||
ASSERT_EQ (nano::epoch::epoch_1, state_send_disk->sideband ().details.epoch);
|
||||
ASSERT_EQ (nano::epoch::epoch_0, state_send_disk->sideband ().source_epoch); // Not used for send state blocks
|
||||
ASSERT_TRUE (store.block_get (transaction, state_open.hash ()));
|
||||
auto state_open_disk (store.block_get (transaction, state_open.hash ()));
|
||||
ASSERT_NE (nullptr, state_open_disk);
|
||||
ASSERT_EQ (nano::epoch::epoch_1, state_open_disk->sideband ().details.epoch);
|
||||
ASSERT_EQ (nano::epoch::epoch_1, state_open_disk->sideband ().source_epoch);
|
||||
|
||||
ASSERT_EQ (5, store.count (transaction, store.blocks));
|
||||
ASSERT_EQ (7, store.count (transaction, store.blocks));
|
||||
|
||||
// Version should be correct
|
||||
ASSERT_LT (18, store.version_get (transaction));
|
||||
|
|
@ -1879,7 +1899,7 @@ void write_sideband_v15 (nano::mdb_store & store_a, nano::transaction & transact
|
|||
|
||||
ASSERT_LE (block->sideband ().details.epoch, nano::epoch::max);
|
||||
// Simulated by writing 0 on every of the most significant bits, leaving out epoch only, as if pre-upgrade
|
||||
nano::block_sideband sideband_v15 (block->sideband ().account, block->sideband ().successor, block->sideband ().balance, block->sideband ().timestamp, block->sideband ().height, block->sideband ().details.epoch, false, false, false);
|
||||
nano::block_sideband_v18 sideband_v15 (block->sideband ().account, block->sideband ().successor, block->sideband ().balance, block->sideband ().timestamp, block->sideband ().height, block->sideband ().details.epoch, false, false, false);
|
||||
std::vector<uint8_t> data;
|
||||
{
|
||||
nano::vectorstream stream (data);
|
||||
|
|
@ -1895,12 +1915,14 @@ void write_block_w_sideband_v18 (nano::mdb_store & store_a, MDB_dbi database, na
|
|||
{
|
||||
auto block = store_a.block_get (transaction_a, block_a.hash ());
|
||||
ASSERT_NE (block, nullptr);
|
||||
auto new_sideband (block->sideband ());
|
||||
nano::block_sideband_v18 sideband_v18 (new_sideband.account, new_sideband.successor, new_sideband.balance, new_sideband.height, new_sideband.timestamp, new_sideband.details.epoch, new_sideband.details.is_send, new_sideband.details.is_receive, new_sideband.details.is_epoch);
|
||||
|
||||
std::vector<uint8_t> data;
|
||||
{
|
||||
nano::vectorstream stream (data);
|
||||
block->serialize (stream);
|
||||
block->sideband ().serialize (stream, block->type ());
|
||||
sideband_v18.serialize (stream, block->type ());
|
||||
}
|
||||
|
||||
MDB_val val{ data.size (), data.data () };
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ TEST (election, construction)
|
|||
nano::system system (1);
|
||||
nano::genesis genesis;
|
||||
auto & node = *system.nodes[0];
|
||||
genesis.open->sideband_set (nano::block_sideband (nano::genesis_account, 0, nano::genesis_amount, 1, nano::seconds_since_epoch (), nano::epoch::epoch_0, false, false, false));
|
||||
genesis.open->sideband_set (nano::block_sideband (nano::genesis_account, 0, nano::genesis_amount, 1, nano::seconds_since_epoch (), nano::epoch::epoch_0, false, false, false, nano::epoch::epoch_0));
|
||||
auto election = node.active.insert (genesis.open).election;
|
||||
ASSERT_TRUE (election->idle ());
|
||||
election->transition_active ();
|
||||
|
|
|
|||
|
|
@ -2369,6 +2369,8 @@ TEST (ledger, epoch_blocks_v1_general)
|
|||
ASSERT_FALSE (epoch1.sideband ().details.is_send);
|
||||
ASSERT_FALSE (epoch1.sideband ().details.is_receive);
|
||||
ASSERT_TRUE (epoch1.sideband ().details.is_epoch);
|
||||
ASSERT_EQ (nano::epoch::epoch_1, epoch1.sideband ().details.epoch);
|
||||
ASSERT_EQ (nano::epoch::epoch_0, epoch1.sideband ().source_epoch); // Not used for epoch blocks
|
||||
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;
|
||||
|
|
@ -2383,6 +2385,8 @@ TEST (ledger, epoch_blocks_v1_general)
|
|||
ASSERT_FALSE (epoch1.sideband ().details.is_send);
|
||||
ASSERT_FALSE (epoch1.sideband ().details.is_receive);
|
||||
ASSERT_TRUE (epoch1.sideband ().details.is_epoch);
|
||||
ASSERT_EQ (nano::epoch::epoch_1, epoch1.sideband ().details.epoch);
|
||||
ASSERT_EQ (nano::epoch::epoch_0, epoch1.sideband ().source_epoch); // Not used for epoch blocks
|
||||
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 ()));
|
||||
|
|
@ -2390,6 +2394,8 @@ TEST (ledger, epoch_blocks_v1_general)
|
|||
ASSERT_TRUE (send1.sideband ().details.is_send);
|
||||
ASSERT_FALSE (send1.sideband ().details.is_receive);
|
||||
ASSERT_FALSE (send1.sideband ().details.is_epoch);
|
||||
ASSERT_EQ (nano::epoch::epoch_1, send1.sideband ().details.epoch);
|
||||
ASSERT_EQ (nano::epoch::epoch_0, send1.sideband ().source_epoch); // Not used for send blocks
|
||||
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.epoch_link (nano::epoch::epoch_1), nano::test_genesis_key.prv, nano::test_genesis_key.pub, *pool.generate (destination.pub));
|
||||
|
|
@ -2399,10 +2405,14 @@ TEST (ledger, epoch_blocks_v1_general)
|
|||
ASSERT_FALSE (epoch4.sideband ().details.is_send);
|
||||
ASSERT_FALSE (epoch4.sideband ().details.is_receive);
|
||||
ASSERT_TRUE (epoch4.sideband ().details.is_epoch);
|
||||
ASSERT_EQ (nano::epoch::epoch_1, epoch4.sideband ().details.epoch);
|
||||
ASSERT_EQ (nano::epoch::epoch_0, epoch4.sideband ().source_epoch); // Not used for epoch blocks
|
||||
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);
|
||||
nano::state_block receive2 (destination.pub, epoch4.hash (), destination.pub, nano::Gxrb_ratio, send1.hash (), destination.prv, destination.pub, *pool.generate (epoch4.hash ()));
|
||||
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, receive2).code);
|
||||
ASSERT_EQ (nano::epoch::epoch_1, receive2.sideband ().details.epoch);
|
||||
ASSERT_EQ (nano::epoch::epoch_1, receive2.sideband ().source_epoch);
|
||||
ASSERT_EQ (0, ledger.balance (transaction, epoch4.hash ()));
|
||||
ASSERT_EQ (nano::Gxrb_ratio, ledger.balance (transaction, receive2.hash ()));
|
||||
ASSERT_EQ (nano::Gxrb_ratio, ledger.amount (transaction, receive2.hash ()));
|
||||
|
|
@ -2431,8 +2441,12 @@ TEST (ledger, epoch_blocks_v2_general)
|
|||
// 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.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);
|
||||
ASSERT_EQ (nano::epoch::epoch_1, epoch1.sideband ().details.epoch);
|
||||
ASSERT_EQ (nano::epoch::epoch_0, epoch1.sideband ().source_epoch); // Not used for epoch blocks
|
||||
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);
|
||||
ASSERT_EQ (nano::epoch::epoch_2, epoch2.sideband ().details.epoch);
|
||||
ASSERT_EQ (nano::epoch::epoch_0, epoch2.sideband ().source_epoch); // Not used for epoch blocks
|
||||
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;
|
||||
|
|
@ -2448,18 +2462,26 @@ TEST (ledger, epoch_blocks_v2_general)
|
|||
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);
|
||||
ASSERT_EQ (nano::epoch::epoch_1, send1.sideband ().details.epoch);
|
||||
ASSERT_EQ (nano::epoch::epoch_0, send1.sideband ().source_epoch); // Not used for send blocks
|
||||
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.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);
|
||||
ASSERT_EQ (nano::epoch::epoch_1, epoch4.sideband ().details.epoch);
|
||||
ASSERT_EQ (nano::epoch::epoch_0, epoch4.sideband ().source_epoch); // Not used for epoch blocks
|
||||
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.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);
|
||||
ASSERT_EQ (nano::epoch::epoch_2, epoch6.sideband ().details.epoch);
|
||||
ASSERT_EQ (nano::epoch::epoch_0, epoch6.sideband ().source_epoch); // Not used for epoch blocks
|
||||
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 (nano::epoch::epoch_2, receive2.sideband ().details.epoch);
|
||||
ASSERT_EQ (nano::epoch::epoch_1, receive2.sideband ().source_epoch);
|
||||
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 ()));
|
||||
|
|
@ -2485,19 +2507,32 @@ TEST (ledger, epoch_blocks_receive_upgrade)
|
|||
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);
|
||||
ASSERT_EQ (nano::epoch::epoch_1, send2.sideband ().details.epoch);
|
||||
ASSERT_EQ (nano::epoch::epoch_0, send2.sideband ().source_epoch); // Not used for send blocks
|
||||
nano::open_block open1 (send1.hash (), destination.pub, destination.pub, destination.prv, destination.pub, *pool.generate (destination.pub));
|
||||
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, open1).code);
|
||||
ASSERT_EQ (nano::epoch::epoch_0, open1.sideband ().details.epoch);
|
||||
ASSERT_EQ (nano::epoch::epoch_0, open1.sideband ().source_epoch);
|
||||
nano::receive_block receive1 (open1.hash (), send2.hash (), destination.prv, destination.pub, *pool.generate (open1.hash ()));
|
||||
ASSERT_EQ (nano::process_result::unreceivable, ledger.process (transaction, receive1).code);
|
||||
nano::state_block receive2 (destination.pub, open1.hash (), destination.pub, nano::Gxrb_ratio * 2, send2.hash (), destination.prv, destination.pub, *pool.generate (open1.hash ()));
|
||||
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, receive2).code);
|
||||
ASSERT_EQ (nano::epoch::epoch_1, receive2.sideband ().details.epoch);
|
||||
ASSERT_EQ (nano::epoch::epoch_1, receive2.sideband ().source_epoch);
|
||||
nano::account_info destination_info;
|
||||
ASSERT_FALSE (ledger.store.account_get (transaction, destination.pub, destination_info));
|
||||
ASSERT_EQ (destination_info.epoch (), nano::epoch::epoch_1);
|
||||
ASSERT_FALSE (ledger.rollback (transaction, receive2.hash ()));
|
||||
ASSERT_FALSE (ledger.store.account_get (transaction, destination.pub, destination_info));
|
||||
ASSERT_EQ (destination_info.epoch (), nano::epoch::epoch_0);
|
||||
nano::pending_info pending_send2;
|
||||
ASSERT_FALSE (ledger.store.pending_get (transaction, nano::pending_key (destination.pub, send2.hash ()), pending_send2));
|
||||
ASSERT_EQ (nano::test_genesis_key.pub, pending_send2.source);
|
||||
ASSERT_EQ (nano::Gxrb_ratio, pending_send2.amount.number ());
|
||||
ASSERT_EQ (nano::epoch::epoch_1, pending_send2.epoch);
|
||||
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, receive2).code);
|
||||
ASSERT_EQ (nano::epoch::epoch_1, receive2.sideband ().details.epoch);
|
||||
ASSERT_EQ (nano::epoch::epoch_1, receive2.sideband ().source_epoch);
|
||||
ASSERT_FALSE (ledger.store.account_get (transaction, destination.pub, destination_info));
|
||||
ASSERT_EQ (destination_info.epoch (), nano::epoch::epoch_1);
|
||||
nano::keypair destination2;
|
||||
|
|
@ -2520,6 +2555,8 @@ TEST (ledger, epoch_blocks_receive_upgrade)
|
|||
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_EQ (nano::epoch::epoch_2, receive3.sideband ().details.epoch);
|
||||
ASSERT_EQ (nano::epoch::epoch_2, receive3.sideband ().source_epoch);
|
||||
ASSERT_FALSE (ledger.store.account_get (transaction, destination.pub, destination_info));
|
||||
ASSERT_EQ (destination_info.epoch (), nano::epoch::epoch_2);
|
||||
// Upgrade an unopened account straight to epoch 2
|
||||
|
|
@ -2528,6 +2565,8 @@ TEST (ledger, epoch_blocks_receive_upgrade)
|
|||
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, send6).code);
|
||||
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);
|
||||
ASSERT_EQ (nano::epoch::epoch_2, epoch4.sideband ().details.epoch);
|
||||
ASSERT_EQ (nano::epoch::epoch_0, epoch4.sideband ().source_epoch); // Not used for epoch blocks
|
||||
ASSERT_EQ (store->account_count (transaction), ledger.cache.account_count);
|
||||
}
|
||||
|
||||
|
|
@ -2551,6 +2590,8 @@ TEST (ledger, epoch_blocks_fork)
|
|||
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.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);
|
||||
ASSERT_EQ (nano::epoch::epoch_1, epoch3.sideband ().details.epoch);
|
||||
ASSERT_EQ (nano::epoch::epoch_0, epoch3.sideband ().source_epoch); // Not used for epoch state blocks
|
||||
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);
|
||||
}
|
||||
|
|
@ -2576,6 +2617,8 @@ TEST (ledger, successor_epoch)
|
|||
ASSERT_EQ (nano::process_result::progress, node1.ledger.process (transaction, epoch_open).code);
|
||||
ASSERT_EQ (change, *node1.ledger.successor (transaction, change.qualified_root ()));
|
||||
ASSERT_EQ (epoch_open, *node1.ledger.successor (transaction, epoch_open.qualified_root ()));
|
||||
ASSERT_EQ (nano::epoch::epoch_1, epoch_open.sideband ().details.epoch);
|
||||
ASSERT_EQ (nano::epoch::epoch_0, epoch_open.sideband ().source_epoch); // Not used for epoch state blocks
|
||||
}
|
||||
|
||||
TEST (ledger, epoch_open_pending)
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ TEST (vote_processor, codes)
|
|||
ASSERT_EQ (nano::vote_code::indeterminate, node.vote_processor.vote_blocking (vote, channel));
|
||||
|
||||
// First vote from an account for an ongoing election
|
||||
genesis.open->sideband_set (nano::block_sideband (nano::genesis_account, 0, nano::genesis_amount, 1, nano::seconds_since_epoch (), nano::epoch::epoch_0, false, false, false));
|
||||
genesis.open->sideband_set (nano::block_sideband (nano::genesis_account, 0, nano::genesis_amount, 1, nano::seconds_since_epoch (), nano::epoch::epoch_0, false, false, false, nano::epoch::epoch_0));
|
||||
ASSERT_TRUE (node.active.insert (genesis.open).inserted);
|
||||
ASSERT_EQ (nano::vote_code::vote, node.vote_processor.vote_blocking (vote, channel));
|
||||
|
||||
|
|
@ -77,7 +77,7 @@ TEST (vote_processor, invalid_signature)
|
|||
vote_invalid->signature.bytes[0] ^= 1;
|
||||
auto channel (std::make_shared<nano::transport::channel_udp> (node.network.udp_channels, node.network.endpoint (), node.network_params.protocol.protocol_version));
|
||||
|
||||
genesis.open->sideband_set (nano::block_sideband (nano::genesis_account, 0, nano::genesis_amount, 1, nano::seconds_since_epoch (), nano::epoch::epoch_0, false, false, false));
|
||||
genesis.open->sideband_set (nano::block_sideband (nano::genesis_account, 0, nano::genesis_amount, 1, nano::seconds_since_epoch (), nano::epoch::epoch_0, false, false, false, nano::epoch::epoch_0));
|
||||
auto election (node.active.insert (genesis.open));
|
||||
ASSERT_TRUE (election.election && election.inserted);
|
||||
ASSERT_EQ (1, election.election->last_votes.size ());
|
||||
|
|
|
|||
|
|
@ -1240,6 +1240,8 @@ TEST (wallet, limited_difficulty)
|
|||
ASSERT_EQ (node.max_work_generate_difficulty (nano::work_version::work_1), node.active.limited_active_difficulty (*genesis.open));
|
||||
auto send = wallet.send_action (nano::test_genesis_key.pub, nano::keypair ().pub, 1, 1);
|
||||
ASSERT_NE (nullptr, send);
|
||||
ASSERT_EQ (nano::epoch::epoch_2, send->sideband ().details.epoch);
|
||||
ASSERT_EQ (nano::epoch::epoch_0, send->sideband ().source_epoch); // Not used for send state blocks
|
||||
}
|
||||
|
||||
TEST (wallet, epoch_2_validation)
|
||||
|
|
@ -1263,12 +1265,16 @@ TEST (wallet, epoch_2_validation)
|
|||
{
|
||||
auto send = wallet.send_action (nano::test_genesis_key.pub, nano::test_genesis_key.pub, amount, 1);
|
||||
ASSERT_NE (nullptr, send);
|
||||
ASSERT_EQ (nano::epoch::epoch_2, send->sideband ().details.epoch);
|
||||
ASSERT_EQ (nano::epoch::epoch_0, send->sideband ().source_epoch); // Not used for send state blocks
|
||||
|
||||
auto receive = wallet.receive_action (*send, nano::test_genesis_key.pub, amount, 1);
|
||||
ASSERT_NE (nullptr, receive);
|
||||
if (receive->difficulty () < node.network_params.network.publish_thresholds.base)
|
||||
{
|
||||
ASSERT_GE (receive->difficulty (), node.network_params.network.publish_thresholds.epoch_2_receive);
|
||||
ASSERT_EQ (nano::epoch::epoch_2, receive->sideband ().details.epoch);
|
||||
ASSERT_EQ (nano::epoch::epoch_2, receive->sideband ().source_epoch);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -1325,6 +1331,7 @@ TEST (wallet, epoch_2_receive_propagation)
|
|||
{
|
||||
ASSERT_GE (receive2->difficulty (), node.network_params.network.publish_thresholds.epoch_2_receive);
|
||||
ASSERT_EQ (nano::epoch::epoch_2, node.store.block_version (node.store.tx_begin_read (), receive2->hash ()));
|
||||
ASSERT_EQ (nano::epoch::epoch_2, receive2->sideband ().source_epoch);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -1374,6 +1381,7 @@ TEST (wallet, epoch_2_receive_unopened)
|
|||
{
|
||||
ASSERT_GE (receive1->difficulty (), node.network_params.network.publish_thresholds.epoch_2_receive);
|
||||
ASSERT_EQ (nano::epoch::epoch_2, node.store.block_version (node.store.tx_begin_read (), receive1->hash ()));
|
||||
ASSERT_EQ (nano::epoch::epoch_1, receive1->sideband ().source_epoch);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1656,11 +1656,6 @@ epoch (epoch_a), is_send (is_send_a), is_receive (is_receive_a), is_epoch (is_ep
|
|||
{
|
||||
}
|
||||
|
||||
constexpr size_t nano::block_details::size ()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool nano::block_details::operator== (nano::block_details const & other_a) const
|
||||
{
|
||||
return epoch == other_a.epoch && is_send == other_a.is_send && is_receive == other_a.is_receive && is_epoch == other_a.is_epoch;
|
||||
|
|
@ -1728,23 +1723,25 @@ std::string nano::state_subtype (nano::block_details const details_a)
|
|||
}
|
||||
}
|
||||
|
||||
nano::block_sideband::block_sideband (nano::account const & account_a, nano::block_hash const & successor_a, nano::amount const & balance_a, uint64_t height_a, uint64_t timestamp_a, nano::block_details const & details_a) :
|
||||
nano::block_sideband::block_sideband (nano::account const & account_a, nano::block_hash const & successor_a, nano::amount const & balance_a, uint64_t const height_a, uint64_t const timestamp_a, nano::block_details const & details_a, nano::epoch const source_epoch_a) :
|
||||
successor (successor_a),
|
||||
account (account_a),
|
||||
balance (balance_a),
|
||||
height (height_a),
|
||||
timestamp (timestamp_a),
|
||||
details (details_a)
|
||||
details (details_a),
|
||||
source_epoch (source_epoch_a)
|
||||
{
|
||||
}
|
||||
|
||||
nano::block_sideband::block_sideband (nano::account const & account_a, nano::block_hash const & successor_a, nano::amount const & balance_a, uint64_t height_a, uint64_t timestamp_a, nano::epoch epoch_a, bool is_send, bool is_receive, bool is_epoch) :
|
||||
nano::block_sideband::block_sideband (nano::account const & account_a, nano::block_hash const & successor_a, nano::amount const & balance_a, uint64_t const height_a, uint64_t const timestamp_a, nano::epoch const epoch_a, bool const is_send, bool const is_receive, bool const is_epoch, nano::epoch const source_epoch_a) :
|
||||
successor (successor_a),
|
||||
account (account_a),
|
||||
balance (balance_a),
|
||||
height (height_a),
|
||||
timestamp (timestamp_a),
|
||||
details (epoch_a, is_send, is_receive, is_epoch)
|
||||
details (epoch_a, is_send, is_receive, is_epoch),
|
||||
source_epoch (source_epoch_a)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -1768,7 +1765,7 @@ size_t nano::block_sideband::size (nano::block_type type_a)
|
|||
if (type_a == nano::block_type::state)
|
||||
{
|
||||
static_assert (sizeof (nano::epoch) == nano::block_details::size (), "block_details is larger than the epoch enum");
|
||||
result += nano::block_details::size ();
|
||||
result += nano::block_details::size () + sizeof (nano::epoch);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
@ -1792,6 +1789,7 @@ void nano::block_sideband::serialize (nano::stream & stream_a, nano::block_type
|
|||
if (type_a == nano::block_type::state)
|
||||
{
|
||||
details.serialize (stream_a);
|
||||
nano::write (stream_a, static_cast<uint8_t> (source_epoch));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1823,6 +1821,9 @@ bool nano::block_sideband::deserialize (nano::stream & stream_a, nano::block_typ
|
|||
if (type_a == nano::block_type::state)
|
||||
{
|
||||
result = details.deserialize (stream_a);
|
||||
uint8_t source_epoch_uint8_t{ 0 };
|
||||
nano::read (stream_a, source_epoch_uint8_t);
|
||||
source_epoch = static_cast<nano::epoch> (source_epoch_uint8_t);
|
||||
}
|
||||
}
|
||||
catch (std::runtime_error &)
|
||||
|
|
|
|||
|
|
@ -35,7 +35,10 @@ class block_details
|
|||
public:
|
||||
block_details () = default;
|
||||
block_details (nano::epoch const epoch_a, bool const is_send_a, bool const is_receive_a, bool const is_epoch_a);
|
||||
static constexpr size_t size ();
|
||||
static constexpr size_t size ()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
bool operator== (block_details const & other_a) const;
|
||||
void serialize (nano::stream &) const;
|
||||
bool deserialize (nano::stream &);
|
||||
|
|
@ -55,8 +58,8 @@ class block_sideband final
|
|||
{
|
||||
public:
|
||||
block_sideband () = default;
|
||||
block_sideband (nano::account const &, nano::block_hash const &, nano::amount const &, uint64_t, uint64_t, nano::block_details const &);
|
||||
block_sideband (nano::account const &, nano::block_hash const &, nano::amount const &, uint64_t, uint64_t, nano::epoch, bool is_send, bool is_receive, bool is_epoch);
|
||||
block_sideband (nano::account const &, nano::block_hash const &, nano::amount const &, uint64_t const, uint64_t const, nano::block_details const &, nano::epoch const source_epoch_a);
|
||||
block_sideband (nano::account const &, nano::block_hash const &, nano::amount const &, uint64_t const, uint64_t const, nano::epoch const epoch_a, bool const is_send, bool const is_receive, bool const is_epoch, nano::epoch const source_epoch_a);
|
||||
void serialize (nano::stream &, nano::block_type) const;
|
||||
bool deserialize (nano::stream &, nano::block_type);
|
||||
static size_t size (nano::block_type);
|
||||
|
|
@ -66,6 +69,7 @@ public:
|
|||
uint64_t height{ 0 };
|
||||
uint64_t timestamp{ 0 };
|
||||
nano::block_details details;
|
||||
nano::epoch source_epoch{ nano::epoch::epoch_0 };
|
||||
};
|
||||
class block
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1544,6 +1544,14 @@ int main (int argc, char * const * argv)
|
|||
{
|
||||
print_error_message (boost::str (boost::format ("Incorrect sideband block details for block %1%\n") % hash.to_string ()));
|
||||
}
|
||||
// Check link epoch version
|
||||
if (sideband.details.is_receive)
|
||||
{
|
||||
if (sideband.source_epoch != node->store.block_version (transaction, block->link ()))
|
||||
{
|
||||
print_error_message (boost::str (boost::format ("Incorrect source epoch for block %1%\n") % hash.to_string ()));
|
||||
}
|
||||
}
|
||||
// Check if block work value is correct
|
||||
if (block->difficulty () < nano::work_threshold (block->work_version (), block->sideband ().details))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -325,7 +325,7 @@ void nano::mdb_store::upgrade_v14_to_v15 (nano::write_transaction & transaction_
|
|||
nano::state_block_w_sideband_v14 state_block_w_sideband_v14 (i_state->second);
|
||||
auto & sideband_v14 = state_block_w_sideband_v14.sideband;
|
||||
|
||||
nano::block_sideband sideband (sideband_v14.account, sideband_v14.successor, sideband_v14.balance, sideband_v14.height, sideband_v14.timestamp, i_state.from_first_database ? nano::epoch::epoch_0 : nano::epoch::epoch_1, false, false, false);
|
||||
nano::block_sideband_v18 sideband (sideband_v14.account, sideband_v14.successor, sideband_v14.balance, sideband_v14.height, sideband_v14.timestamp, i_state.from_first_database ? nano::epoch::epoch_0 : nano::epoch::epoch_1, false, false, false);
|
||||
|
||||
// Write these out
|
||||
std::vector<uint8_t> data;
|
||||
|
|
@ -514,7 +514,7 @@ void nano::mdb_store::upgrade_v17_to_v18 (nano::write_transaction const & transa
|
|||
is_receive = true;
|
||||
}
|
||||
|
||||
nano::block_sideband new_sideband (sideband.account, sideband.successor, sideband.balance, sideband.height, sideband.timestamp, sideband.details.epoch, is_send, is_receive, is_epoch);
|
||||
nano::block_sideband_v18 new_sideband (sideband.account, sideband.successor, sideband.balance, sideband.height, sideband.timestamp, sideband.details.epoch, is_send, is_receive, is_epoch);
|
||||
// Write these out
|
||||
std::vector<uint8_t> data;
|
||||
{
|
||||
|
|
@ -551,17 +551,23 @@ void nano::mdb_store::upgrade_v18_to_v19 (nano::write_transaction const & transa
|
|||
|
||||
for (auto i (nano::store_iterator<nano::block_hash, nano::block_w_sideband_v18<nano::change_block>> (std::make_unique<nano::mdb_iterator<nano::block_hash, nano::block_w_sideband_v18<nano::change_block>>> (transaction_a, change_blocks))), n (nano::store_iterator<nano::block_hash, nano::block_w_sideband_v18<nano::change_block>> (nullptr)); i != n; ++i)
|
||||
{
|
||||
legacy_open_receive_change_blocks[i->first] = { nano::block_w_sideband{ i->second.block, i->second.sideband } };
|
||||
nano::block_sideband_v18 const & old_sideband (i->second.sideband);
|
||||
nano::block_sideband new_sideband (old_sideband.account, old_sideband.successor, old_sideband.balance, old_sideband.height, old_sideband.timestamp, nano::epoch::epoch_0, false, false, false, nano::epoch::epoch_0);
|
||||
legacy_open_receive_change_blocks[i->first] = { nano::block_w_sideband{ i->second.block, new_sideband } };
|
||||
}
|
||||
|
||||
for (auto i (nano::store_iterator<nano::block_hash, nano::block_w_sideband_v18<nano::open_block>> (std::make_unique<nano::mdb_iterator<nano::block_hash, nano::block_w_sideband_v18<nano::open_block>>> (transaction_a, open_blocks))), n (nano::store_iterator<nano::block_hash, nano::block_w_sideband_v18<nano::open_block>> (nullptr)); i != n; ++i)
|
||||
{
|
||||
legacy_open_receive_change_blocks[i->first] = { nano::block_w_sideband{ i->second.block, i->second.sideband } };
|
||||
nano::block_sideband_v18 const & old_sideband (i->second.sideband);
|
||||
nano::block_sideband new_sideband (old_sideband.account, old_sideband.successor, old_sideband.balance, old_sideband.height, old_sideband.timestamp, nano::epoch::epoch_0, false, false, false, nano::epoch::epoch_0);
|
||||
legacy_open_receive_change_blocks[i->first] = { nano::block_w_sideband{ i->second.block, new_sideband } };
|
||||
}
|
||||
|
||||
for (auto i (nano::store_iterator<nano::block_hash, nano::block_w_sideband_v18<nano::receive_block>> (std::make_unique<nano::mdb_iterator<nano::block_hash, nano::block_w_sideband_v18<nano::receive_block>>> (transaction_a, receive_blocks))), n (nano::store_iterator<nano::block_hash, nano::block_w_sideband_v18<nano::receive_block>> (nullptr)); i != n; ++i)
|
||||
{
|
||||
legacy_open_receive_change_blocks[i->first] = { nano::block_w_sideband{ i->second.block, i->second.sideband } };
|
||||
nano::block_sideband_v18 const & old_sideband (i->second.sideband);
|
||||
nano::block_sideband new_sideband (old_sideband.account, old_sideband.successor, old_sideband.balance, old_sideband.height, old_sideband.timestamp, nano::epoch::epoch_0, false, false, false, nano::epoch::epoch_0);
|
||||
legacy_open_receive_change_blocks[i->first] = { nano::block_w_sideband{ i->second.block, new_sideband } };
|
||||
}
|
||||
|
||||
release_assert (!mdb_drop (env.tx (transaction_a), receive_blocks, 1));
|
||||
|
|
@ -607,7 +613,7 @@ void nano::mdb_store::upgrade_v18_to_v19 (nano::write_transaction const & transa
|
|||
{
|
||||
nano::vectorstream stream (data);
|
||||
nano::serialize_block (stream, *block_w_sideband_v18.block);
|
||||
block_w_sideband_v18.sideband.serialize (stream, nano::block_type::send);
|
||||
block_w_sideband_v18.sideband.serialize (stream, nano::block_type::send); // Equal to new version for legacy blocks
|
||||
}
|
||||
|
||||
nano::mdb_val value{ data.size (), (void *)data.data () };
|
||||
|
|
@ -643,17 +649,36 @@ void nano::mdb_store::upgrade_v18_to_v19 (nano::write_transaction const & transa
|
|||
// Write state blocks to a new table (this was not done in memory as it would push us above memory requirements)
|
||||
MDB_dbi temp_state_blocks;
|
||||
{
|
||||
auto type_state (nano::block_type::state);
|
||||
mdb_dbi_open (env.tx (transaction_a), "temp_state_blocks", MDB_CREATE, &temp_state_blocks);
|
||||
|
||||
for (auto i (nano::store_iterator<nano::block_hash, nano::block_w_sideband_v18<nano::state_block>> (std::make_unique<nano::mdb_iterator<nano::block_hash, nano::block_w_sideband_v18<nano::state_block>>> (transaction_a, state_blocks))), n (nano::store_iterator<nano::block_hash, nano::block_w_sideband_v18<nano::state_block>> (nullptr)); i != n; ++i)
|
||||
{
|
||||
auto const & block_w_sideband_v18 (i->second);
|
||||
nano::block_sideband_v18 const & old_sideband (block_w_sideband_v18.sideband);
|
||||
nano::epoch source_epoch (nano::epoch::epoch_0);
|
||||
// Source block v18 epoch
|
||||
if (old_sideband.details.is_receive)
|
||||
{
|
||||
auto db_val (block_raw_get_by_type_v18 (transaction_a, block_w_sideband_v18.block->link (), type_state));
|
||||
if (db_val.is_initialized ())
|
||||
{
|
||||
nano::bufferstream stream (reinterpret_cast<uint8_t const *> (db_val.get ().data ()), db_val.get ().size ());
|
||||
auto source_block (nano::deserialize_block (stream, type_state));
|
||||
release_assert (source_block != nullptr);
|
||||
nano::block_sideband_v18 source_sideband;
|
||||
auto error (source_sideband.deserialize (stream, type_state));
|
||||
release_assert (!error);
|
||||
source_epoch = source_sideband.details.epoch;
|
||||
}
|
||||
}
|
||||
nano::block_sideband new_sideband (old_sideband.account, old_sideband.successor, old_sideband.balance, old_sideband.height, old_sideband.timestamp, old_sideband.details.epoch, old_sideband.details.is_send, old_sideband.details.is_receive, old_sideband.details.is_epoch, source_epoch);
|
||||
|
||||
std::vector<uint8_t> data;
|
||||
{
|
||||
nano::vectorstream stream (data);
|
||||
nano::serialize_block (stream, *block_w_sideband_v18.block);
|
||||
block_w_sideband_v18.sideband.serialize (stream, nano::block_type::state);
|
||||
new_sideband.serialize (stream, nano::block_type::state);
|
||||
}
|
||||
|
||||
nano::mdb_val value{ data.size (), (void *)data.data () };
|
||||
|
|
@ -888,10 +913,10 @@ std::shared_ptr<nano::block> nano::mdb_store::block_get_v18 (nano::transaction c
|
|||
nano::bufferstream stream (reinterpret_cast<uint8_t const *> (value.data ()), value.size ());
|
||||
result = nano::deserialize_block (stream, type);
|
||||
release_assert (result != nullptr);
|
||||
nano::block_sideband sideband;
|
||||
nano::block_sideband_v18 sideband;
|
||||
auto error = (sideband.deserialize (stream, type));
|
||||
release_assert (!error);
|
||||
result->sideband_set (sideband);
|
||||
result->sideband_set (nano::block_sideband (sideband.account, sideband.successor, sideband.balance, sideband.height, sideband.timestamp, sideband.details.epoch, sideband.details.is_send, sideband.details.is_receive, sideband.details.is_epoch, nano::epoch::epoch_0));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ class block_w_sideband_v18
|
|||
{
|
||||
public:
|
||||
std::shared_ptr<T> block;
|
||||
nano::block_sideband sideband;
|
||||
nano::block_sideband_v18 sideband;
|
||||
};
|
||||
|
||||
class block_w_sideband
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ public:
|
|||
{
|
||||
auto hash_l (genesis_a.hash ());
|
||||
debug_assert (latest_begin (transaction_a) == latest_end ());
|
||||
genesis_a.open->sideband_set (nano::block_sideband (network_params.ledger.genesis_account, 0, network_params.ledger.genesis_amount, 1, nano::seconds_since_epoch (), nano::epoch::epoch_0, false, false, false));
|
||||
genesis_a.open->sideband_set (nano::block_sideband (network_params.ledger.genesis_account, 0, network_params.ledger.genesis_amount, 1, nano::seconds_since_epoch (), nano::epoch::epoch_0, false, false, false, nano::epoch::epoch_0));
|
||||
block_put (transaction_a, hash_l, *genesis_a.open);
|
||||
++ledger_cache_a.block_count;
|
||||
confirmation_height_put (transaction_a, network_params.ledger.genesis_account, nano::confirmation_height_info{ 1, genesis_a.hash () });
|
||||
|
|
@ -371,7 +371,6 @@ public:
|
|||
|
||||
nano::epoch block_version (nano::transaction const & transaction_a, nano::block_hash const & hash_a) override
|
||||
{
|
||||
nano::db_val<Val> value;
|
||||
auto block = block_get (transaction_a, hash_a);
|
||||
if (block && block->type () == nano::block_type::state)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -141,8 +141,7 @@ public:
|
|||
}
|
||||
else if (!block_a.hashables.link.is_zero () && !ledger.is_epoch_link (block_a.hashables.link))
|
||||
{
|
||||
auto source_version (ledger.store.block_version (transaction, block_a.hashables.link));
|
||||
nano::pending_info pending_info (ledger.account (transaction, block_a.hashables.link), block_a.hashables.balance.number () - balance, source_version);
|
||||
nano::pending_info pending_info (ledger.account (transaction, block_a.hashables.link), block_a.hashables.balance.number () - balance, block_a.sideband ().source_epoch);
|
||||
ledger.store.pending_put (transaction, nano::pending_key (block_a.hashables.account, block_a.hashables.link), pending_info);
|
||||
ledger.stats.inc (nano::stat::type::rollback, nano::stat::detail::receive);
|
||||
}
|
||||
|
|
@ -274,6 +273,7 @@ void ledger_processor::state_block_impl (nano::state_block & block_a)
|
|||
if (result.code == nano::process_result::progress)
|
||||
{
|
||||
nano::epoch epoch (nano::epoch::epoch_0);
|
||||
nano::epoch source_epoch (nano::epoch::epoch_0);
|
||||
nano::account_info info;
|
||||
nano::amount amount (block_a.hashables.balance);
|
||||
auto is_send (false);
|
||||
|
|
@ -323,7 +323,8 @@ void ledger_processor::state_block_impl (nano::state_block & block_a)
|
|||
if (result.code == nano::process_result::progress)
|
||||
{
|
||||
result.code = amount == pending.amount ? nano::process_result::progress : nano::process_result::balance_mismatch;
|
||||
epoch = std::max (epoch, pending.epoch);
|
||||
source_epoch = pending.epoch;
|
||||
epoch = std::max (epoch, source_epoch);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -341,7 +342,7 @@ void ledger_processor::state_block_impl (nano::state_block & block_a)
|
|||
if (result.code == nano::process_result::progress)
|
||||
{
|
||||
ledger.stats.inc (nano::stat::type::ledger, nano::stat::detail::state_block);
|
||||
block_a.sideband_set (nano::block_sideband (block_a.hashables.account /* unused */, 0, 0 /* unused */, info.block_count + 1, nano::seconds_since_epoch (), block_details));
|
||||
block_a.sideband_set (nano::block_sideband (block_a.hashables.account /* unused */, 0, 0 /* unused */, info.block_count + 1, nano::seconds_since_epoch (), block_details, source_epoch));
|
||||
ledger.store.block_put (transaction, hash, block_a);
|
||||
|
||||
if (!info.head.is_zero ())
|
||||
|
|
@ -438,7 +439,7 @@ void ledger_processor::epoch_block_impl (nano::state_block & block_a)
|
|||
if (result.code == nano::process_result::progress)
|
||||
{
|
||||
ledger.stats.inc (nano::stat::type::ledger, nano::stat::detail::epoch_block);
|
||||
block_a.sideband_set (nano::block_sideband (block_a.hashables.account /* unused */, 0, 0 /* unused */, info.block_count + 1, nano::seconds_since_epoch (), block_details));
|
||||
block_a.sideband_set (nano::block_sideband (block_a.hashables.account /* unused */, 0, 0 /* unused */, info.block_count + 1, nano::seconds_since_epoch (), block_details, nano::epoch::epoch_0 /* unused */));
|
||||
ledger.store.block_put (transaction, hash, block_a);
|
||||
nano::account_info new_info (hash, block_a.representative (), info.open_block.is_zero () ? hash : info.open_block, info.balance, nano::seconds_since_epoch (), info.block_count + 1, epoch);
|
||||
ledger.change_latest (transaction, block_a.hashables.account, info, new_info);
|
||||
|
|
@ -502,7 +503,7 @@ void ledger_processor::change_block (nano::change_block & block_a)
|
|||
{
|
||||
debug_assert (!validate_message (account, hash, block_a.signature));
|
||||
result.verified = nano::signature_verification::valid;
|
||||
block_a.sideband_set (nano::block_sideband (account, 0, info.balance, info.block_count + 1, nano::seconds_since_epoch (), block_details));
|
||||
block_a.sideband_set (nano::block_sideband (account, 0, info.balance, info.block_count + 1, nano::seconds_since_epoch (), block_details, nano::epoch::epoch_0 /* unused */));
|
||||
ledger.store.block_put (transaction, hash, block_a);
|
||||
auto balance (ledger.balance (transaction, block_a.hashables.previous));
|
||||
ledger.cache.rep_weights.representation_add (block_a.representative (), balance);
|
||||
|
|
@ -562,7 +563,7 @@ void ledger_processor::send_block (nano::send_block & block_a)
|
|||
{
|
||||
auto amount (info.balance.number () - block_a.hashables.balance.number ());
|
||||
ledger.cache.rep_weights.representation_add (info.representative, 0 - amount);
|
||||
block_a.sideband_set (nano::block_sideband (account, 0, block_a.hashables.balance /* unused */, info.block_count + 1, nano::seconds_since_epoch (), block_details));
|
||||
block_a.sideband_set (nano::block_sideband (account, 0, block_a.hashables.balance /* unused */, info.block_count + 1, nano::seconds_since_epoch (), block_details, nano::epoch::epoch_0 /* unused */));
|
||||
ledger.store.block_put (transaction, hash, block_a);
|
||||
nano::account_info new_info (hash, info.representative, info.open_block, block_a.hashables.balance, nano::seconds_since_epoch (), info.block_count + 1, nano::epoch::epoch_0);
|
||||
ledger.change_latest (transaction, account, info, new_info);
|
||||
|
|
@ -633,7 +634,7 @@ void ledger_processor::receive_block (nano::receive_block & block_a)
|
|||
(void)error;
|
||||
debug_assert (!error);
|
||||
ledger.store.pending_del (transaction, key);
|
||||
block_a.sideband_set (nano::block_sideband (account, 0, new_balance, info.block_count + 1, nano::seconds_since_epoch (), block_details));
|
||||
block_a.sideband_set (nano::block_sideband (account, 0, new_balance, info.block_count + 1, nano::seconds_since_epoch (), block_details, nano::epoch::epoch_0 /* unused */));
|
||||
ledger.store.block_put (transaction, hash, block_a);
|
||||
nano::account_info new_info (hash, info.representative, info.open_block, new_balance, nano::seconds_since_epoch (), info.block_count + 1, nano::epoch::epoch_0);
|
||||
ledger.change_latest (transaction, account, info, new_info);
|
||||
|
|
@ -701,7 +702,7 @@ void ledger_processor::open_block (nano::open_block & block_a)
|
|||
(void)error;
|
||||
debug_assert (!error);
|
||||
ledger.store.pending_del (transaction, key);
|
||||
block_a.sideband_set (nano::block_sideband (block_a.hashables.account, 0, pending.amount, 1, nano::seconds_since_epoch (), block_details));
|
||||
block_a.sideband_set (nano::block_sideband (block_a.hashables.account, 0, pending.amount, 1, nano::seconds_since_epoch (), block_details, nano::epoch::epoch_0 /* unused */));
|
||||
ledger.store.block_put (transaction, hash, block_a);
|
||||
nano::account_info new_info (hash, block_a.representative (), hash, pending.amount.number (), nano::seconds_since_epoch (), 1, nano::epoch::epoch_0);
|
||||
ledger.change_latest (transaction, block_a.hashables.account, info, new_info);
|
||||
|
|
|
|||
|
|
@ -142,3 +142,108 @@ bool nano::block_sideband_v14::deserialize (nano::stream & stream_a)
|
|||
|
||||
return result;
|
||||
}
|
||||
|
||||
nano::block_sideband_v18::block_sideband_v18 (nano::account const & account_a, nano::block_hash const & successor_a, nano::amount const & balance_a, uint64_t height_a, uint64_t timestamp_a, nano::block_details const & details_a) :
|
||||
successor (successor_a),
|
||||
account (account_a),
|
||||
balance (balance_a),
|
||||
height (height_a),
|
||||
timestamp (timestamp_a),
|
||||
details (details_a)
|
||||
{
|
||||
}
|
||||
|
||||
nano::block_sideband_v18::block_sideband_v18 (nano::account const & account_a, nano::block_hash const & successor_a, nano::amount const & balance_a, uint64_t height_a, uint64_t timestamp_a, nano::epoch epoch_a, bool is_send, bool is_receive, bool is_epoch) :
|
||||
successor (successor_a),
|
||||
account (account_a),
|
||||
balance (balance_a),
|
||||
height (height_a),
|
||||
timestamp (timestamp_a),
|
||||
details (epoch_a, is_send, is_receive, is_epoch)
|
||||
{
|
||||
}
|
||||
|
||||
size_t nano::block_sideband_v18::size (nano::block_type type_a)
|
||||
{
|
||||
size_t result (0);
|
||||
result += sizeof (successor);
|
||||
if (type_a != nano::block_type::state && type_a != nano::block_type::open)
|
||||
{
|
||||
result += sizeof (account);
|
||||
}
|
||||
if (type_a != nano::block_type::open)
|
||||
{
|
||||
result += sizeof (height);
|
||||
}
|
||||
if (type_a == nano::block_type::receive || type_a == nano::block_type::change || type_a == nano::block_type::open)
|
||||
{
|
||||
result += sizeof (balance);
|
||||
}
|
||||
result += sizeof (timestamp);
|
||||
if (type_a == nano::block_type::state)
|
||||
{
|
||||
static_assert (sizeof (nano::epoch) == nano::block_details::size (), "block_details_v18 is larger than the epoch enum");
|
||||
result += nano::block_details::size ();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void nano::block_sideband_v18::serialize (nano::stream & stream_a, nano::block_type type_a) const
|
||||
{
|
||||
nano::write (stream_a, successor.bytes);
|
||||
if (type_a != nano::block_type::state && type_a != nano::block_type::open)
|
||||
{
|
||||
nano::write (stream_a, account.bytes);
|
||||
}
|
||||
if (type_a != nano::block_type::open)
|
||||
{
|
||||
nano::write (stream_a, boost::endian::native_to_big (height));
|
||||
}
|
||||
if (type_a == nano::block_type::receive || type_a == nano::block_type::change || type_a == nano::block_type::open)
|
||||
{
|
||||
nano::write (stream_a, balance.bytes);
|
||||
}
|
||||
nano::write (stream_a, boost::endian::native_to_big (timestamp));
|
||||
if (type_a == nano::block_type::state)
|
||||
{
|
||||
details.serialize (stream_a);
|
||||
}
|
||||
}
|
||||
|
||||
bool nano::block_sideband_v18::deserialize (nano::stream & stream_a, nano::block_type type_a)
|
||||
{
|
||||
bool result (false);
|
||||
try
|
||||
{
|
||||
nano::read (stream_a, successor.bytes);
|
||||
if (type_a != nano::block_type::state && type_a != nano::block_type::open)
|
||||
{
|
||||
nano::read (stream_a, account.bytes);
|
||||
}
|
||||
if (type_a != nano::block_type::open)
|
||||
{
|
||||
nano::read (stream_a, height);
|
||||
boost::endian::big_to_native_inplace (height);
|
||||
}
|
||||
else
|
||||
{
|
||||
height = 1;
|
||||
}
|
||||
if (type_a == nano::block_type::receive || type_a == nano::block_type::change || type_a == nano::block_type::open)
|
||||
{
|
||||
nano::read (stream_a, balance.bytes);
|
||||
}
|
||||
nano::read (stream_a, timestamp);
|
||||
boost::endian::big_to_native_inplace (timestamp);
|
||||
if (type_a == nano::block_type::state)
|
||||
{
|
||||
result = details.deserialize (stream_a);
|
||||
}
|
||||
}
|
||||
catch (std::runtime_error &)
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,4 +55,20 @@ public:
|
|||
std::shared_ptr<nano::state_block> state_block;
|
||||
nano::block_sideband_v14 sideband;
|
||||
};
|
||||
class block_sideband_v18 final
|
||||
{
|
||||
public:
|
||||
block_sideband_v18 () = default;
|
||||
block_sideband_v18 (nano::account const &, nano::block_hash const &, nano::amount const &, uint64_t, uint64_t, nano::block_details const &);
|
||||
block_sideband_v18 (nano::account const &, nano::block_hash const &, nano::amount const &, uint64_t, uint64_t, nano::epoch, bool is_send, bool is_receive, bool is_epoch);
|
||||
void serialize (nano::stream &, nano::block_type) const;
|
||||
bool deserialize (nano::stream &, nano::block_type);
|
||||
static size_t size (nano::block_type);
|
||||
nano::block_hash successor{ 0 };
|
||||
nano::account account{ 0 };
|
||||
nano::amount balance{ 0 };
|
||||
uint64_t height{ 0 };
|
||||
uint64_t timestamp{ 0 };
|
||||
nano::block_details details;
|
||||
};
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue