Attach sideband to block (#2596)
* Move epoch from secure to nano_lib * Attach sideband to block and always (de)serialize along with it Using the sideband is only valid for blocks that were processed with code `progress`, otherwise they may not be set (important examples: old, fork). * Make sideband optional to ensure usage correctness * Interim * Use new nano::optional_ptr to hold the sideband * Adjust some tests to ensure two nodes don't simultaneously process the same block object * Update comment
This commit is contained in:
parent
90f1c862a8
commit
62fc659143
30 changed files with 705 additions and 687 deletions
|
@ -90,7 +90,6 @@ TEST (block_store, block_details_serialization)
|
|||
TEST (block_store, sideband_serialization)
|
||||
{
|
||||
nano::block_sideband sideband1;
|
||||
sideband1.type = nano::block_type::receive;
|
||||
sideband1.account = 1;
|
||||
sideband1.balance = 2;
|
||||
sideband1.height = 3;
|
||||
|
@ -99,12 +98,11 @@ TEST (block_store, sideband_serialization)
|
|||
std::vector<uint8_t> vector;
|
||||
{
|
||||
nano::vectorstream stream1 (vector);
|
||||
sideband1.serialize (stream1);
|
||||
sideband1.serialize (stream1, nano::block_type::receive);
|
||||
}
|
||||
nano::bufferstream stream2 (vector.data (), vector.size ());
|
||||
nano::block_sideband sideband2;
|
||||
sideband2.type = nano::block_type::receive;
|
||||
ASSERT_FALSE (sideband2.deserialize (stream2));
|
||||
ASSERT_FALSE (sideband2.deserialize (stream2, nano::block_type::receive));
|
||||
ASSERT_EQ (sideband1.account, sideband2.account);
|
||||
ASSERT_EQ (sideband1.balance, sideband2.balance);
|
||||
ASSERT_EQ (sideband1.height, sideband2.height);
|
||||
|
@ -118,13 +116,13 @@ TEST (block_store, add_item)
|
|||
auto store = nano::make_store (logger, nano::unique_path ());
|
||||
ASSERT_TRUE (!store->init_error ());
|
||||
nano::open_block block (0, 1, 0, nano::keypair ().prv, 0, 0);
|
||||
block.sideband_set ({});
|
||||
auto hash1 (block.hash ());
|
||||
auto transaction (store->tx_begin_write ());
|
||||
auto latest1 (store->block_get (transaction, hash1));
|
||||
ASSERT_EQ (nullptr, latest1);
|
||||
ASSERT_FALSE (store->block_exists (transaction, hash1));
|
||||
nano::block_sideband sideband (nano::block_type::open, 0, 0, 0, 0, 0, nano::epoch::epoch_0, false, false, false);
|
||||
store->block_put (transaction, hash1, block, sideband);
|
||||
store->block_put (transaction, hash1, block);
|
||||
auto latest2 (store->block_get (transaction, hash1));
|
||||
ASSERT_NE (nullptr, latest2);
|
||||
ASSERT_EQ (block, *latest2);
|
||||
|
@ -141,20 +139,30 @@ TEST (block_store, clear_successor)
|
|||
auto store = nano::make_store (logger, nano::unique_path ());
|
||||
ASSERT_TRUE (!store->init_error ());
|
||||
nano::open_block block1 (0, 1, 0, nano::keypair ().prv, 0, 0);
|
||||
block1.sideband_set ({});
|
||||
auto transaction (store->tx_begin_write ());
|
||||
nano::block_sideband sideband (nano::block_type::open, 0, 0, 0, 0, 0, nano::epoch::epoch_0, false, false, false);
|
||||
store->block_put (transaction, block1.hash (), block1, sideband);
|
||||
store->block_put (transaction, block1.hash (), block1);
|
||||
nano::open_block block2 (0, 2, 0, nano::keypair ().prv, 0, 0);
|
||||
store->block_put (transaction, block2.hash (), block2, sideband);
|
||||
ASSERT_NE (nullptr, store->block_get (transaction, block1.hash (), &sideband));
|
||||
ASSERT_EQ (0, sideband.successor.number ());
|
||||
sideband.successor = block2.hash ();
|
||||
store->block_put (transaction, block1.hash (), block1, sideband);
|
||||
ASSERT_NE (nullptr, store->block_get (transaction, block1.hash (), &sideband));
|
||||
ASSERT_EQ (block2.hash (), sideband.successor);
|
||||
block2.sideband_set ({});
|
||||
store->block_put (transaction, block2.hash (), block2);
|
||||
auto block2_store (store->block_get (transaction, block1.hash ()));
|
||||
ASSERT_NE (nullptr, block2_store);
|
||||
ASSERT_EQ (0, block2_store->sideband ().successor.number ());
|
||||
auto modified_sideband = block2_store->sideband ();
|
||||
modified_sideband.successor = block2.hash ();
|
||||
block1.sideband_set (modified_sideband);
|
||||
store->block_put (transaction, block1.hash (), block1);
|
||||
{
|
||||
auto block1_store (store->block_get (transaction, block1.hash ()));
|
||||
ASSERT_NE (nullptr, block1_store);
|
||||
ASSERT_EQ (block2.hash (), block1_store->sideband ().successor);
|
||||
}
|
||||
store->block_successor_clear (transaction, block1.hash ());
|
||||
ASSERT_NE (nullptr, store->block_get (transaction, block1.hash (), &sideband));
|
||||
ASSERT_EQ (0, sideband.successor.number ());
|
||||
{
|
||||
auto block1_store (store->block_get (transaction, block1.hash ()));
|
||||
ASSERT_NE (nullptr, block1_store);
|
||||
ASSERT_EQ (0, block1_store->sideband ().successor.number ());
|
||||
}
|
||||
}
|
||||
|
||||
TEST (block_store, add_nonempty_block)
|
||||
|
@ -164,13 +172,13 @@ TEST (block_store, add_nonempty_block)
|
|||
ASSERT_TRUE (!store->init_error ());
|
||||
nano::keypair key1;
|
||||
nano::open_block block (0, 1, 0, nano::keypair ().prv, 0, 0);
|
||||
block.sideband_set ({});
|
||||
auto hash1 (block.hash ());
|
||||
block.signature = nano::sign_message (key1.prv, key1.pub, hash1);
|
||||
auto transaction (store->tx_begin_write ());
|
||||
auto latest1 (store->block_get (transaction, hash1));
|
||||
ASSERT_EQ (nullptr, latest1);
|
||||
nano::block_sideband sideband (nano::block_type::open, 0, 0, 0, 0, 0, nano::epoch::epoch_0, false, false, false);
|
||||
store->block_put (transaction, hash1, block, sideband);
|
||||
store->block_put (transaction, hash1, block);
|
||||
auto latest2 (store->block_get (transaction, hash1));
|
||||
ASSERT_NE (nullptr, latest2);
|
||||
ASSERT_EQ (block, *latest2);
|
||||
|
@ -183,21 +191,21 @@ TEST (block_store, add_two_items)
|
|||
ASSERT_TRUE (!store->init_error ());
|
||||
nano::keypair key1;
|
||||
nano::open_block block (0, 1, 1, nano::keypair ().prv, 0, 0);
|
||||
block.sideband_set ({});
|
||||
auto hash1 (block.hash ());
|
||||
block.signature = nano::sign_message (key1.prv, key1.pub, hash1);
|
||||
auto transaction (store->tx_begin_write ());
|
||||
auto latest1 (store->block_get (transaction, hash1));
|
||||
ASSERT_EQ (nullptr, latest1);
|
||||
nano::open_block block2 (0, 1, 3, nano::keypair ().prv, 0, 0);
|
||||
block2.sideband_set ({});
|
||||
block2.hashables.account = 3;
|
||||
auto hash2 (block2.hash ());
|
||||
block2.signature = nano::sign_message (key1.prv, key1.pub, hash2);
|
||||
auto latest2 (store->block_get (transaction, hash2));
|
||||
ASSERT_EQ (nullptr, latest2);
|
||||
nano::block_sideband sideband (nano::block_type::open, 0, 0, 0, 0, 0, nano::epoch::epoch_0, false, false, false);
|
||||
store->block_put (transaction, hash1, block, sideband);
|
||||
nano::block_sideband sideband2 (nano::block_type::open, 0, 0, 0, 0, 0, nano::epoch::epoch_0, false, false, false);
|
||||
store->block_put (transaction, hash2, block2, sideband2);
|
||||
store->block_put (transaction, hash1, block);
|
||||
store->block_put (transaction, hash2, block2);
|
||||
auto latest3 (store->block_get (transaction, hash1));
|
||||
ASSERT_NE (nullptr, latest3);
|
||||
ASSERT_EQ (block, *latest3);
|
||||
|
@ -215,15 +223,15 @@ TEST (block_store, add_receive)
|
|||
nano::keypair key1;
|
||||
nano::keypair key2;
|
||||
nano::open_block block1 (0, 1, 0, nano::keypair ().prv, 0, 0);
|
||||
block1.sideband_set ({});
|
||||
auto transaction (store->tx_begin_write ());
|
||||
nano::block_sideband sideband1 (nano::block_type::open, 0, 0, 0, 0, 0, nano::epoch::epoch_0, false, false, false);
|
||||
store->block_put (transaction, block1.hash (), block1, sideband1);
|
||||
store->block_put (transaction, block1.hash (), block1);
|
||||
nano::receive_block block (block1.hash (), 1, nano::keypair ().prv, 2, 3);
|
||||
block.sideband_set ({});
|
||||
nano::block_hash hash1 (block.hash ());
|
||||
auto latest1 (store->block_get (transaction, hash1));
|
||||
ASSERT_EQ (nullptr, latest1);
|
||||
nano::block_sideband sideband (nano::block_type::receive, 0, 0, 0, 0, 0, nano::epoch::epoch_0, false, false, false);
|
||||
store->block_put (transaction, hash1, block, sideband);
|
||||
store->block_put (transaction, hash1, block);
|
||||
auto latest2 (store->block_get (transaction, hash1));
|
||||
ASSERT_NE (nullptr, latest2);
|
||||
ASSERT_EQ (block, *latest2);
|
||||
|
@ -463,9 +471,9 @@ TEST (block_store, one_block)
|
|||
auto store = nano::make_store (logger, nano::unique_path ());
|
||||
ASSERT_TRUE (!store->init_error ());
|
||||
nano::open_block block1 (0, 1, 0, nano::keypair ().prv, 0, 0);
|
||||
block1.sideband_set ({});
|
||||
auto transaction (store->tx_begin_write ());
|
||||
nano::block_sideband sideband (nano::block_type::open, 0, 0, 0, 0, 0, nano::epoch::epoch_0, false, false, false);
|
||||
store->block_put (transaction, block1.hash (), block1, sideband);
|
||||
store->block_put (transaction, block1.hash (), block1);
|
||||
ASSERT_TRUE (store->block_exists (transaction, block1.hash ()));
|
||||
}
|
||||
|
||||
|
@ -560,19 +568,19 @@ TEST (block_store, two_block)
|
|||
auto store = nano::make_store (logger, nano::unique_path ());
|
||||
ASSERT_TRUE (!store->init_error ());
|
||||
nano::open_block block1 (0, 1, 1, nano::keypair ().prv, 0, 0);
|
||||
block1.sideband_set ({});
|
||||
block1.hashables.account = 1;
|
||||
std::vector<nano::block_hash> hashes;
|
||||
std::vector<nano::open_block> blocks;
|
||||
hashes.push_back (block1.hash ());
|
||||
blocks.push_back (block1);
|
||||
auto transaction (store->tx_begin_write ());
|
||||
nano::block_sideband sideband1 (nano::block_type::open, 0, 0, 0, 0, 0, nano::epoch::epoch_0, false, false, false);
|
||||
store->block_put (transaction, hashes[0], block1, sideband1);
|
||||
store->block_put (transaction, hashes[0], block1);
|
||||
nano::open_block block2 (0, 1, 2, nano::keypair ().prv, 0, 0);
|
||||
block2.sideband_set ({});
|
||||
hashes.push_back (block2.hash ());
|
||||
blocks.push_back (block2);
|
||||
nano::block_sideband sideband2 (nano::block_type::open, 0, 0, 0, 0, 0, nano::epoch::epoch_0, false, false, false);
|
||||
store->block_put (transaction, hashes[1], block2, sideband2);
|
||||
store->block_put (transaction, hashes[1], block2);
|
||||
ASSERT_TRUE (store->block_exists (transaction, block1.hash ()));
|
||||
ASSERT_TRUE (store->block_exists (transaction, block2.hash ()));
|
||||
}
|
||||
|
@ -755,12 +763,12 @@ TEST (block_store, block_replace)
|
|||
auto store = nano::make_store (logger, nano::unique_path ());
|
||||
ASSERT_TRUE (!store->init_error ());
|
||||
nano::send_block send1 (0, 0, 0, nano::keypair ().prv, 0, 1);
|
||||
send1.sideband_set ({});
|
||||
nano::send_block send2 (0, 0, 0, nano::keypair ().prv, 0, 2);
|
||||
send2.sideband_set ({});
|
||||
auto transaction (store->tx_begin_write ());
|
||||
nano::block_sideband sideband1 (nano::block_type::send, 0, 0, 0, 0, 0, nano::epoch::epoch_0, false, false, false);
|
||||
store->block_put (transaction, 0, send1, sideband1);
|
||||
nano::block_sideband sideband2 (nano::block_type::send, 0, 0, 0, 0, 0, nano::epoch::epoch_0, false, false, false);
|
||||
store->block_put (transaction, 0, send2, sideband2);
|
||||
store->block_put (transaction, 0, send1);
|
||||
store->block_put (transaction, 0, send2);
|
||||
auto block3 (store->block_get (transaction, 0));
|
||||
ASSERT_NE (nullptr, block3);
|
||||
ASSERT_EQ (2, block3->block_work ());
|
||||
|
@ -775,9 +783,9 @@ TEST (block_store, block_count)
|
|||
auto transaction (store->tx_begin_write ());
|
||||
ASSERT_EQ (0, store->block_count (transaction).sum ());
|
||||
nano::open_block block (0, 1, 0, nano::keypair ().prv, 0, 0);
|
||||
block.sideband_set ({});
|
||||
auto hash1 (block.hash ());
|
||||
nano::block_sideband sideband (nano::block_type::open, 0, 0, 0, 0, 0, nano::epoch::epoch_0, false, false, false);
|
||||
store->block_put (transaction, hash1, block, sideband);
|
||||
store->block_put (transaction, hash1, block);
|
||||
}
|
||||
auto transaction (store->tx_begin_read ());
|
||||
ASSERT_EQ (1, store->block_count (transaction).sum ());
|
||||
|
@ -1172,13 +1180,13 @@ TEST (block_store, state_block)
|
|||
nano::genesis genesis;
|
||||
nano::keypair key1;
|
||||
nano::state_block block1 (1, genesis.hash (), 3, 4, 6, key1.prv, key1.pub, 7);
|
||||
block1.sideband_set ({});
|
||||
{
|
||||
nano::ledger_cache ledger_cache;
|
||||
auto transaction (store->tx_begin_write ());
|
||||
store->initialize (transaction, genesis, ledger_cache);
|
||||
ASSERT_EQ (nano::block_type::state, block1.type ());
|
||||
nano::block_sideband sideband1 (nano::block_type::state, 0, 0, 0, 0, 0, nano::epoch::epoch_0, false, false, false);
|
||||
store->block_put (transaction, block1.hash (), block1, sideband1);
|
||||
store->block_put (transaction, block1.hash (), block1);
|
||||
ASSERT_TRUE (store->block_exists (transaction, block1.hash ()));
|
||||
auto block2 (store->block_get (transaction, block1.hash ()));
|
||||
ASSERT_NE (nullptr, block2);
|
||||
|
@ -1209,10 +1217,9 @@ TEST (mdb_block_store, upgrade_sideband_genesis)
|
|||
nano::ledger_cache ledger_cache;
|
||||
store.initialize (transaction, genesis, ledger_cache);
|
||||
modify_account_info_to_v13 (store, transaction, nano::genesis_account, nano::genesis_hash);
|
||||
nano::block_sideband sideband;
|
||||
auto genesis_block (store.block_get (transaction, genesis.hash (), &sideband));
|
||||
auto genesis_block (store.block_get (transaction, genesis.hash ()));
|
||||
ASSERT_NE (nullptr, genesis_block);
|
||||
ASSERT_EQ (1, sideband.height);
|
||||
ASSERT_EQ (1, genesis_block->sideband ().height);
|
||||
ASSERT_FALSE (mdb_dbi_open (store.env.tx (transaction), "state_v1", MDB_CREATE, &store.state_blocks_v1));
|
||||
write_sideband_v12 (store, transaction, *genesis_block, 0, store.open_blocks);
|
||||
nano::block_sideband_v14 sideband1;
|
||||
|
@ -1226,10 +1233,9 @@ TEST (mdb_block_store, upgrade_sideband_genesis)
|
|||
ASSERT_FALSE (store.init_error ());
|
||||
auto transaction (store.tx_begin_read ());
|
||||
ASSERT_TRUE (store.full_sideband (transaction));
|
||||
nano::block_sideband sideband;
|
||||
auto genesis_block (store.block_get (transaction, genesis.hash (), &sideband));
|
||||
auto genesis_block (store.block_get (transaction, genesis.hash ()));
|
||||
ASSERT_NE (nullptr, genesis_block);
|
||||
ASSERT_EQ (1, sideband.height);
|
||||
ASSERT_EQ (1, genesis_block->sideband ().height);
|
||||
}
|
||||
|
||||
TEST (mdb_block_store, upgrade_sideband_two_blocks)
|
||||
|
@ -1265,14 +1271,12 @@ TEST (mdb_block_store, upgrade_sideband_two_blocks)
|
|||
ASSERT_FALSE (store.init_error ());
|
||||
auto transaction (store.tx_begin_read ());
|
||||
ASSERT_TRUE (store.full_sideband (transaction));
|
||||
nano::block_sideband sideband;
|
||||
auto genesis_block (store.block_get (transaction, genesis.hash (), &sideband));
|
||||
auto genesis_block (store.block_get (transaction, genesis.hash ()));
|
||||
ASSERT_NE (nullptr, genesis_block);
|
||||
ASSERT_EQ (1, sideband.height);
|
||||
nano::block_sideband sideband2;
|
||||
auto block2 (store.block_get (transaction, hash2, &sideband2));
|
||||
ASSERT_EQ (1, genesis_block->sideband ().height);
|
||||
auto block2 (store.block_get (transaction, hash2));
|
||||
ASSERT_NE (nullptr, block2);
|
||||
ASSERT_EQ (2, sideband2.height);
|
||||
ASSERT_EQ (2, block2->sideband ().height);
|
||||
}
|
||||
|
||||
TEST (mdb_block_store, upgrade_sideband_two_accounts)
|
||||
|
@ -1314,18 +1318,15 @@ TEST (mdb_block_store, upgrade_sideband_two_accounts)
|
|||
ASSERT_FALSE (store.init_error ());
|
||||
auto transaction (store.tx_begin_read ());
|
||||
ASSERT_TRUE (store.full_sideband (transaction));
|
||||
nano::block_sideband sideband;
|
||||
auto genesis_block (store.block_get (transaction, genesis.hash (), &sideband));
|
||||
auto genesis_block (store.block_get (transaction, genesis.hash ()));
|
||||
ASSERT_NE (nullptr, genesis_block);
|
||||
ASSERT_EQ (1, sideband.height);
|
||||
nano::block_sideband sideband2;
|
||||
auto block2 (store.block_get (transaction, hash2, &sideband2));
|
||||
ASSERT_EQ (1, genesis_block->sideband ().height);
|
||||
auto block2 (store.block_get (transaction, hash2));
|
||||
ASSERT_NE (nullptr, block2);
|
||||
ASSERT_EQ (2, sideband2.height);
|
||||
nano::block_sideband sideband3;
|
||||
auto block3 (store.block_get (transaction, hash3, &sideband3));
|
||||
ASSERT_EQ (2, block2->sideband ().height);
|
||||
auto block3 (store.block_get (transaction, hash3));
|
||||
ASSERT_NE (nullptr, block3);
|
||||
ASSERT_EQ (1, sideband3.height);
|
||||
ASSERT_EQ (1, block3->sideband ().height);
|
||||
}
|
||||
|
||||
TEST (mdb_block_store, insert_after_legacy)
|
||||
|
@ -1406,9 +1407,8 @@ TEST (mdb_block_store, upgrade_sideband_epoch)
|
|||
auto transaction (store.tx_begin_write ());
|
||||
ASSERT_TRUE (store.full_sideband (transaction));
|
||||
ASSERT_EQ (nano::epoch::epoch_1, store.block_version (transaction, hash2));
|
||||
nano::block_sideband sideband;
|
||||
auto block1 (store.block_get (transaction, hash2, &sideband));
|
||||
ASSERT_NE (0, sideband.height);
|
||||
auto block1 (store.block_get (transaction, hash2));
|
||||
ASSERT_NE (0, block1->sideband ().height);
|
||||
nano::state_block block2 (nano::test_genesis_key.pub, hash2, nano::test_genesis_key.pub, nano::genesis_amount - nano::Gxrb_ratio, nano::test_genesis_key.pub, nano::test_genesis_key.prv, nano::test_genesis_key.pub, *pool.generate (hash2));
|
||||
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, block2).code);
|
||||
ASSERT_EQ (nano::epoch::epoch_1, store.block_version (transaction, block2.hash ()));
|
||||
|
@ -1452,42 +1452,30 @@ TEST (mdb_block_store, sideband_height)
|
|||
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, state_receive).code);
|
||||
nano::open_block open (state_send3.hash (), nano::test_genesis_key.pub, key3.pub, key3.prv, key3.pub, *pool.generate (key3.pub));
|
||||
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, open).code);
|
||||
nano::block_sideband sideband1;
|
||||
auto block1 (store.block_get (transaction, genesis.hash (), &sideband1));
|
||||
ASSERT_EQ (sideband1.height, 1);
|
||||
nano::block_sideband sideband2;
|
||||
auto block2 (store.block_get (transaction, send.hash (), &sideband2));
|
||||
ASSERT_EQ (sideband2.height, 2);
|
||||
nano::block_sideband sideband3;
|
||||
auto block3 (store.block_get (transaction, receive.hash (), &sideband3));
|
||||
ASSERT_EQ (sideband3.height, 3);
|
||||
nano::block_sideband sideband4;
|
||||
auto block4 (store.block_get (transaction, change.hash (), &sideband4));
|
||||
ASSERT_EQ (sideband4.height, 4);
|
||||
nano::block_sideband sideband5;
|
||||
auto block5 (store.block_get (transaction, state_send1.hash (), &sideband5));
|
||||
ASSERT_EQ (sideband5.height, 5);
|
||||
nano::block_sideband sideband6;
|
||||
auto block6 (store.block_get (transaction, state_send2.hash (), &sideband6));
|
||||
ASSERT_EQ (sideband6.height, 6);
|
||||
nano::block_sideband sideband7;
|
||||
auto block7 (store.block_get (transaction, state_send3.hash (), &sideband7));
|
||||
ASSERT_EQ (sideband7.height, 7);
|
||||
nano::block_sideband sideband8;
|
||||
auto block8 (store.block_get (transaction, state_open.hash (), &sideband8));
|
||||
ASSERT_EQ (sideband8.height, 1);
|
||||
nano::block_sideband sideband9;
|
||||
auto block9 (store.block_get (transaction, epoch.hash (), &sideband9));
|
||||
ASSERT_EQ (sideband9.height, 2);
|
||||
nano::block_sideband sideband10;
|
||||
auto block10 (store.block_get (transaction, epoch_open.hash (), &sideband10));
|
||||
ASSERT_EQ (sideband10.height, 1);
|
||||
nano::block_sideband sideband11;
|
||||
auto block11 (store.block_get (transaction, state_receive.hash (), &sideband11));
|
||||
ASSERT_EQ (sideband11.height, 2);
|
||||
nano::block_sideband sideband12;
|
||||
auto block12 (store.block_get (transaction, open.hash (), &sideband12));
|
||||
ASSERT_EQ (sideband12.height, 1);
|
||||
auto block1 (store.block_get (transaction, genesis.hash ()));
|
||||
ASSERT_EQ (block1->sideband ().height, 1);
|
||||
auto block2 (store.block_get (transaction, send.hash ()));
|
||||
ASSERT_EQ (block2->sideband ().height, 2);
|
||||
auto block3 (store.block_get (transaction, receive.hash ()));
|
||||
ASSERT_EQ (block3->sideband ().height, 3);
|
||||
auto block4 (store.block_get (transaction, change.hash ()));
|
||||
ASSERT_EQ (block4->sideband ().height, 4);
|
||||
auto block5 (store.block_get (transaction, state_send1.hash ()));
|
||||
ASSERT_EQ (block5->sideband ().height, 5);
|
||||
auto block6 (store.block_get (transaction, state_send2.hash ()));
|
||||
ASSERT_EQ (block6->sideband ().height, 6);
|
||||
auto block7 (store.block_get (transaction, state_send3.hash ()));
|
||||
ASSERT_EQ (block7->sideband ().height, 7);
|
||||
auto block8 (store.block_get (transaction, state_open.hash ()));
|
||||
ASSERT_EQ (block8->sideband ().height, 1);
|
||||
auto block9 (store.block_get (transaction, epoch.hash ()));
|
||||
ASSERT_EQ (block9->sideband ().height, 2);
|
||||
auto block10 (store.block_get (transaction, epoch_open.hash ()));
|
||||
ASSERT_EQ (block10->sideband ().height, 1);
|
||||
auto block11 (store.block_get (transaction, state_receive.hash ()));
|
||||
ASSERT_EQ (block11->sideband ().height, 2);
|
||||
auto block12 (store.block_get (transaction, open.hash ()));
|
||||
ASSERT_EQ (block12->sideband ().height, 1);
|
||||
}
|
||||
|
||||
TEST (block_store, peers)
|
||||
|
@ -1751,14 +1739,12 @@ TEST (mdb_block_store, upgrade_v14_v15)
|
|||
ASSERT_NE (error_get_state_v1, MDB_SUCCESS);
|
||||
|
||||
// Check that the epochs are set correctly for the sideband, accounts and pending entries
|
||||
nano::block_sideband sideband;
|
||||
auto block = store.block_get (transaction, state_send.hash (), &sideband);
|
||||
auto block = store.block_get (transaction, state_send.hash ());
|
||||
ASSERT_NE (block, nullptr);
|
||||
ASSERT_EQ (sideband.details.epoch, nano::epoch::epoch_1);
|
||||
block = store.block_get (transaction, send.hash (), &sideband);
|
||||
ASSERT_EQ (block->sideband ().details.epoch, nano::epoch::epoch_1);
|
||||
block = store.block_get (transaction, send.hash ());
|
||||
ASSERT_NE (block, nullptr);
|
||||
nano::block_sideband sideband1;
|
||||
ASSERT_EQ (sideband1.details.epoch, nano::epoch::epoch_0);
|
||||
ASSERT_EQ (block->sideband ().details.epoch, nano::epoch::epoch_0);
|
||||
ASSERT_EQ (info.epoch (), nano::epoch::epoch_1);
|
||||
nano::pending_info pending_info;
|
||||
store.pending_get (transaction, nano::pending_key (nano::test_genesis_key.pub, send.hash ()), pending_info);
|
||||
|
@ -1818,7 +1804,7 @@ TEST (mdb_block_store, upgrade_v16_v17)
|
|||
nano::state_block block2 (nano::test_genesis_key.pub, block1.hash (), nano::test_genesis_key.pub, nano::genesis_amount - nano::Gxrb_ratio - 1, nano::test_genesis_key.pub, nano::test_genesis_key.prv, nano::test_genesis_key.pub, *pool.generate (block1.hash ()));
|
||||
nano::state_block block3 (nano::test_genesis_key.pub, block2.hash (), nano::test_genesis_key.pub, nano::genesis_amount - nano::Gxrb_ratio - 2, nano::test_genesis_key.pub, nano::test_genesis_key.prv, nano::test_genesis_key.pub, *pool.generate (block2.hash ()));
|
||||
|
||||
auto code = [block1, block2, block3](auto confirmation_height, nano::block_hash const & expected_cemented_frontier) {
|
||||
auto code = [&block1, &block2, &block3](auto confirmation_height, nano::block_hash const & expected_cemented_frontier) {
|
||||
auto path (nano::unique_path ());
|
||||
nano::mdb_val value;
|
||||
{
|
||||
|
@ -1937,124 +1923,112 @@ TEST (mdb_block_store, upgrade_v17_v18)
|
|||
// Check that sidebands are correctly populated
|
||||
{
|
||||
// Non-state unaffected
|
||||
nano::block_sideband sideband;
|
||||
auto block = store.block_get (transaction, send_zero.hash (), &sideband);
|
||||
auto block = store.block_get (transaction, send_zero.hash ());
|
||||
ASSERT_NE (block, nullptr);
|
||||
// All defaults
|
||||
ASSERT_EQ (sideband.details.epoch, nano::epoch::epoch_0);
|
||||
ASSERT_FALSE (sideband.details.is_epoch);
|
||||
ASSERT_FALSE (sideband.details.is_send);
|
||||
ASSERT_FALSE (sideband.details.is_receive);
|
||||
ASSERT_EQ (block->sideband ().details.epoch, nano::epoch::epoch_0);
|
||||
ASSERT_FALSE (block->sideband ().details.is_epoch);
|
||||
ASSERT_FALSE (block->sideband ().details.is_send);
|
||||
ASSERT_FALSE (block->sideband ().details.is_receive);
|
||||
}
|
||||
{
|
||||
// State receive from old zero send
|
||||
nano::block_sideband sideband;
|
||||
auto block = store.block_get (transaction, state_receive_zero.hash (), &sideband);
|
||||
auto block = store.block_get (transaction, state_receive_zero.hash ());
|
||||
ASSERT_NE (block, nullptr);
|
||||
ASSERT_EQ (sideband.details.epoch, nano::epoch::epoch_0);
|
||||
ASSERT_FALSE (sideband.details.is_epoch);
|
||||
ASSERT_FALSE (sideband.details.is_send);
|
||||
ASSERT_TRUE (sideband.details.is_receive);
|
||||
ASSERT_EQ (block->sideband ().details.epoch, nano::epoch::epoch_0);
|
||||
ASSERT_FALSE (block->sideband ().details.is_epoch);
|
||||
ASSERT_FALSE (block->sideband ().details.is_send);
|
||||
ASSERT_TRUE (block->sideband ().details.is_receive);
|
||||
}
|
||||
{
|
||||
// Epoch
|
||||
nano::block_sideband sideband;
|
||||
auto block = store.block_get (transaction, epoch.hash (), &sideband);
|
||||
auto block = store.block_get (transaction, epoch.hash ());
|
||||
ASSERT_NE (block, nullptr);
|
||||
ASSERT_EQ (sideband.details.epoch, nano::epoch::epoch_1);
|
||||
ASSERT_TRUE (sideband.details.is_epoch);
|
||||
ASSERT_FALSE (sideband.details.is_send);
|
||||
ASSERT_FALSE (sideband.details.is_receive);
|
||||
ASSERT_EQ (block->sideband ().details.epoch, nano::epoch::epoch_1);
|
||||
ASSERT_TRUE (block->sideband ().details.is_epoch);
|
||||
ASSERT_FALSE (block->sideband ().details.is_send);
|
||||
ASSERT_FALSE (block->sideband ().details.is_receive);
|
||||
}
|
||||
{
|
||||
// State send
|
||||
nano::block_sideband sideband;
|
||||
auto block = store.block_get (transaction, state_send.hash (), &sideband);
|
||||
auto block = store.block_get (transaction, state_send.hash ());
|
||||
ASSERT_NE (block, nullptr);
|
||||
ASSERT_EQ (sideband.details.epoch, nano::epoch::epoch_1);
|
||||
ASSERT_FALSE (sideband.details.is_epoch);
|
||||
ASSERT_TRUE (sideband.details.is_send);
|
||||
ASSERT_FALSE (sideband.details.is_receive);
|
||||
ASSERT_EQ (block->sideband ().details.epoch, nano::epoch::epoch_1);
|
||||
ASSERT_FALSE (block->sideband ().details.is_epoch);
|
||||
ASSERT_TRUE (block->sideband ().details.is_send);
|
||||
ASSERT_FALSE (block->sideband ().details.is_receive);
|
||||
}
|
||||
{
|
||||
// State receive
|
||||
nano::block_sideband sideband;
|
||||
auto block = store.block_get (transaction, state_receive.hash (), &sideband);
|
||||
auto block = store.block_get (transaction, state_receive.hash ());
|
||||
ASSERT_NE (block, nullptr);
|
||||
ASSERT_EQ (sideband.details.epoch, nano::epoch::epoch_1);
|
||||
ASSERT_FALSE (sideband.details.is_epoch);
|
||||
ASSERT_FALSE (sideband.details.is_send);
|
||||
ASSERT_TRUE (sideband.details.is_receive);
|
||||
ASSERT_EQ (block->sideband ().details.epoch, nano::epoch::epoch_1);
|
||||
ASSERT_FALSE (block->sideband ().details.is_epoch);
|
||||
ASSERT_FALSE (block->sideband ().details.is_send);
|
||||
ASSERT_TRUE (block->sideband ().details.is_receive);
|
||||
}
|
||||
{
|
||||
// State change
|
||||
nano::block_sideband sideband;
|
||||
auto block = store.block_get (transaction, state_change.hash (), &sideband);
|
||||
auto block = store.block_get (transaction, state_change.hash ());
|
||||
ASSERT_NE (block, nullptr);
|
||||
ASSERT_EQ (sideband.details.epoch, nano::epoch::epoch_1);
|
||||
ASSERT_FALSE (sideband.details.is_epoch);
|
||||
ASSERT_FALSE (sideband.details.is_send);
|
||||
ASSERT_FALSE (sideband.details.is_receive);
|
||||
ASSERT_EQ (block->sideband ().details.epoch, nano::epoch::epoch_1);
|
||||
ASSERT_FALSE (block->sideband ().details.is_epoch);
|
||||
ASSERT_FALSE (block->sideband ().details.is_send);
|
||||
ASSERT_FALSE (block->sideband ().details.is_receive);
|
||||
}
|
||||
{
|
||||
// State send + change
|
||||
nano::block_sideband sideband;
|
||||
auto block = store.block_get (transaction, state_send_change.hash (), &sideband);
|
||||
auto block = store.block_get (transaction, state_send_change.hash ());
|
||||
ASSERT_NE (block, nullptr);
|
||||
ASSERT_EQ (sideband.details.epoch, nano::epoch::epoch_1);
|
||||
ASSERT_FALSE (sideband.details.is_epoch);
|
||||
ASSERT_TRUE (sideband.details.is_send);
|
||||
ASSERT_FALSE (sideband.details.is_receive);
|
||||
ASSERT_EQ (block->sideband ().details.epoch, nano::epoch::epoch_1);
|
||||
ASSERT_FALSE (block->sideband ().details.is_epoch);
|
||||
ASSERT_TRUE (block->sideband ().details.is_send);
|
||||
ASSERT_FALSE (block->sideband ().details.is_receive);
|
||||
}
|
||||
{
|
||||
// Epoch on unopened account
|
||||
nano::block_sideband sideband;
|
||||
auto block = store.block_get (transaction, epoch_first.hash (), &sideband);
|
||||
auto block = store.block_get (transaction, epoch_first.hash ());
|
||||
ASSERT_NE (block, nullptr);
|
||||
ASSERT_EQ (sideband.details.epoch, nano::epoch::epoch_2);
|
||||
ASSERT_TRUE (sideband.details.is_epoch);
|
||||
ASSERT_FALSE (sideband.details.is_send);
|
||||
ASSERT_FALSE (sideband.details.is_receive);
|
||||
ASSERT_EQ (block->sideband ().details.epoch, nano::epoch::epoch_2);
|
||||
ASSERT_TRUE (block->sideband ().details.is_epoch);
|
||||
ASSERT_FALSE (block->sideband ().details.is_send);
|
||||
ASSERT_FALSE (block->sideband ().details.is_receive);
|
||||
}
|
||||
{
|
||||
// State open following epoch
|
||||
nano::block_sideband sideband;
|
||||
auto block = store.block_get (transaction, state_receive2.hash (), &sideband);
|
||||
auto block = store.block_get (transaction, state_receive2.hash ());
|
||||
ASSERT_NE (block, nullptr);
|
||||
ASSERT_EQ (sideband.details.epoch, nano::epoch::epoch_2);
|
||||
ASSERT_FALSE (sideband.details.is_epoch);
|
||||
ASSERT_FALSE (sideband.details.is_send);
|
||||
ASSERT_TRUE (sideband.details.is_receive);
|
||||
ASSERT_EQ (block->sideband ().details.epoch, nano::epoch::epoch_2);
|
||||
ASSERT_FALSE (block->sideband ().details.is_epoch);
|
||||
ASSERT_FALSE (block->sideband ().details.is_send);
|
||||
ASSERT_TRUE (block->sideband ().details.is_receive);
|
||||
}
|
||||
{
|
||||
// Another state send
|
||||
nano::block_sideband sideband;
|
||||
auto block = store.block_get (transaction, state_send2.hash (), &sideband);
|
||||
auto block = store.block_get (transaction, state_send2.hash ());
|
||||
ASSERT_NE (block, nullptr);
|
||||
ASSERT_EQ (sideband.details.epoch, nano::epoch::epoch_1);
|
||||
ASSERT_FALSE (sideband.details.is_epoch);
|
||||
ASSERT_TRUE (sideband.details.is_send);
|
||||
ASSERT_FALSE (sideband.details.is_receive);
|
||||
ASSERT_EQ (block->sideband ().details.epoch, nano::epoch::epoch_1);
|
||||
ASSERT_FALSE (block->sideband ().details.is_epoch);
|
||||
ASSERT_TRUE (block->sideband ().details.is_send);
|
||||
ASSERT_FALSE (block->sideband ().details.is_receive);
|
||||
}
|
||||
{
|
||||
// State open
|
||||
nano::block_sideband sideband;
|
||||
auto block = store.block_get (transaction, state_open.hash (), &sideband);
|
||||
auto block = store.block_get (transaction, state_open.hash ());
|
||||
ASSERT_NE (block, nullptr);
|
||||
ASSERT_EQ (sideband.details.epoch, nano::epoch::epoch_1);
|
||||
ASSERT_FALSE (sideband.details.is_epoch);
|
||||
ASSERT_FALSE (sideband.details.is_send);
|
||||
ASSERT_TRUE (sideband.details.is_receive);
|
||||
ASSERT_EQ (block->sideband ().details.epoch, nano::epoch::epoch_1);
|
||||
ASSERT_FALSE (block->sideband ().details.is_epoch);
|
||||
ASSERT_FALSE (block->sideband ().details.is_send);
|
||||
ASSERT_TRUE (block->sideband ().details.is_receive);
|
||||
}
|
||||
{
|
||||
// State send to an epoch link
|
||||
nano::block_sideband sideband;
|
||||
auto block = store.block_get (transaction, state_send_epoch_link.hash (), &sideband);
|
||||
auto block = store.block_get (transaction, state_send_epoch_link.hash ());
|
||||
ASSERT_NE (block, nullptr);
|
||||
ASSERT_EQ (sideband.details.epoch, nano::epoch::epoch_1);
|
||||
ASSERT_FALSE (sideband.details.is_epoch);
|
||||
ASSERT_TRUE (sideband.details.is_send);
|
||||
ASSERT_FALSE (sideband.details.is_receive);
|
||||
ASSERT_EQ (block->sideband ().details.epoch, nano::epoch::epoch_1);
|
||||
ASSERT_FALSE (block->sideband ().details.is_epoch);
|
||||
ASSERT_TRUE (block->sideband ().details.is_send);
|
||||
ASSERT_FALSE (block->sideband ().details.is_receive);
|
||||
}
|
||||
// Version should be correct
|
||||
ASSERT_LT (17, store.version_get (transaction));
|
||||
|
@ -2166,8 +2140,8 @@ TEST (mdb_block_store, upgrade_confirmation_height_many)
|
|||
{
|
||||
nano::account account (i);
|
||||
nano::open_block open (1, nano::genesis_account, 3, nullptr);
|
||||
nano::block_sideband sideband (nano::block_type::open, 0, 0, 0, 0, 0, nano::epoch::epoch_0, false, false, false);
|
||||
store.block_put (transaction, open.hash (), open, sideband);
|
||||
open.sideband_set ({});
|
||||
store.block_put (transaction, open.hash (), open);
|
||||
nano::account_info_v13 account_info_v13 (open.hash (), open.hash (), open.hash (), 3, 4, 1, nano::epoch::epoch_0);
|
||||
auto status (mdb_put (store.env.tx (transaction), store.accounts_v0, nano::mdb_val (account), nano::mdb_val (account_info_v13), 0));
|
||||
ASSERT_EQ (status, 0);
|
||||
|
@ -2224,6 +2198,7 @@ TEST (block_store, reset_renew_existing_transaction)
|
|||
|
||||
nano::keypair key1;
|
||||
nano::open_block block (0, 1, 1, nano::keypair ().prv, 0, 0);
|
||||
block.sideband_set ({});
|
||||
auto hash1 (block.hash ());
|
||||
auto read_transaction = store->tx_begin_read ();
|
||||
|
||||
|
@ -2237,8 +2212,7 @@ TEST (block_store, reset_renew_existing_transaction)
|
|||
// Write the block
|
||||
{
|
||||
auto write_transaction (store->tx_begin_write ());
|
||||
nano::block_sideband sideband (nano::block_type::open, 0, 0, 0, 0, 0, nano::epoch::epoch_0, false, false, false);
|
||||
store->block_put (write_transaction, hash1, block, sideband);
|
||||
store->block_put (write_transaction, hash1, block);
|
||||
}
|
||||
|
||||
read_transaction.renew ();
|
||||
|
@ -2297,11 +2271,10 @@ void write_sideband_v12 (nano::mdb_store & store_a, nano::transaction & transact
|
|||
|
||||
void write_sideband_v14 (nano::mdb_store & store_a, nano::transaction & transaction_a, nano::block const & block_a, MDB_dbi db_a)
|
||||
{
|
||||
nano::block_sideband sideband;
|
||||
auto block = store_a.block_get (transaction_a, block_a.hash (), &sideband);
|
||||
auto block = store_a.block_get (transaction_a, block_a.hash ());
|
||||
ASSERT_NE (block, nullptr);
|
||||
|
||||
nano::block_sideband_v14 sideband_v14 (sideband.type, sideband.account, sideband.successor, sideband.balance, sideband.timestamp, sideband.height);
|
||||
nano::block_sideband_v14 sideband_v14 (block->type (), block->sideband ().account, block->sideband ().successor, block->sideband ().balance, block->sideband ().timestamp, block->sideband ().height);
|
||||
std::vector<uint8_t> data;
|
||||
{
|
||||
nano::vectorstream stream (data);
|
||||
|
@ -2310,23 +2283,22 @@ void write_sideband_v14 (nano::mdb_store & store_a, nano::transaction & transact
|
|||
}
|
||||
|
||||
MDB_val val{ data.size (), data.data () };
|
||||
ASSERT_FALSE (mdb_put (store_a.env.tx (transaction_a), sideband.details.epoch == nano::epoch::epoch_0 ? store_a.state_blocks_v0 : store_a.state_blocks_v1, nano::mdb_val (block_a.hash ()), &val, 0));
|
||||
ASSERT_FALSE (mdb_put (store_a.env.tx (transaction_a), block->sideband ().details.epoch == nano::epoch::epoch_0 ? store_a.state_blocks_v0 : store_a.state_blocks_v1, nano::mdb_val (block_a.hash ()), &val, 0));
|
||||
}
|
||||
|
||||
void write_sideband_v15 (nano::mdb_store & store_a, nano::transaction & transaction_a, nano::block const & block_a)
|
||||
{
|
||||
nano::block_sideband sideband;
|
||||
auto block = store_a.block_get (transaction_a, block_a.hash (), &sideband);
|
||||
auto block = store_a.block_get (transaction_a, block_a.hash ());
|
||||
ASSERT_NE (block, nullptr);
|
||||
|
||||
ASSERT_LE (sideband.details.epoch, nano::epoch::max);
|
||||
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 (sideband.type, sideband.account, sideband.successor, sideband.balance, sideband.timestamp, sideband.height, sideband.details.epoch, false, false, false);
|
||||
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);
|
||||
std::vector<uint8_t> data;
|
||||
{
|
||||
nano::vectorstream stream (data);
|
||||
block_a.serialize (stream);
|
||||
sideband_v15.serialize (stream);
|
||||
sideband_v15.serialize (stream, block_a.type ());
|
||||
}
|
||||
|
||||
MDB_val val{ data.size (), data.data () };
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include <nano/lib/epoch.hpp>
|
||||
#include <nano/secure/common.hpp>
|
||||
#include <nano/secure/epoch.hpp>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
|
|
|
@ -71,6 +71,21 @@ TEST (system, system_genesis)
|
|||
}
|
||||
}
|
||||
|
||||
TEST (ledger, process_modifies_sideband)
|
||||
{
|
||||
nano::logger_mt logger;
|
||||
auto store = nano::make_store (logger, nano::unique_path ());
|
||||
ASSERT_TRUE (!store->init_error ());
|
||||
nano::stat stats;
|
||||
nano::ledger ledger (*store, stats);
|
||||
nano::genesis genesis;
|
||||
store->initialize (store->tx_begin_write (), genesis, ledger.cache);
|
||||
nano::work_pool pool (std::numeric_limits<unsigned>::max ());
|
||||
nano::state_block send1 (nano::genesis_account, genesis.hash (), nano::genesis_account, nano::genesis_amount - nano::Gxrb_ratio, nano::genesis_account, nano::test_genesis_key.prv, nano::test_genesis_key.pub, *pool.generate (genesis.hash ()));
|
||||
ASSERT_EQ (nano::process_result::progress, ledger.process (store->tx_begin_write (), send1).code);
|
||||
ASSERT_EQ (send1.sideband ().timestamp, store->block_get (store->tx_begin_read (), send1.hash ())->sideband ().timestamp);
|
||||
}
|
||||
|
||||
// Create a send block and publish it.
|
||||
TEST (ledger, process_send)
|
||||
{
|
||||
|
@ -92,6 +107,8 @@ TEST (ledger, process_send)
|
|||
ASSERT_EQ (1, info1.block_count);
|
||||
// This was a valid block, it should progress.
|
||||
auto return1 (ledger.process (transaction, send));
|
||||
ASSERT_EQ (nano::test_genesis_key.pub, send.sideband ().account);
|
||||
ASSERT_EQ (2, send.sideband ().height);
|
||||
ASSERT_EQ (nano::genesis_amount - 50, ledger.amount (transaction, hash1));
|
||||
ASSERT_TRUE (store->frontier_get (transaction, info1.head).is_zero ());
|
||||
ASSERT_EQ (nano::test_genesis_key.pub, store->frontier_get (transaction, hash1));
|
||||
|
@ -113,6 +130,10 @@ TEST (ledger, process_send)
|
|||
nano::block_hash hash2 (open.hash ());
|
||||
// This was a valid block, it should progress.
|
||||
auto return2 (ledger.process (transaction, open));
|
||||
ASSERT_EQ (nano::process_result::progress, return2.code);
|
||||
ASSERT_EQ (key2.pub, open.sideband ().account);
|
||||
ASSERT_EQ (nano::genesis_amount - 50, open.sideband ().balance.number ());
|
||||
ASSERT_EQ (1, open.sideband ().height);
|
||||
ASSERT_EQ (nano::genesis_amount - 50, ledger.amount (transaction, hash2));
|
||||
ASSERT_EQ (nano::process_result::progress, return2.code);
|
||||
ASSERT_EQ (key2.pub, return2.account);
|
||||
|
@ -190,6 +211,9 @@ TEST (ledger, process_receive)
|
|||
auto return1 (ledger.process (transaction, open));
|
||||
ASSERT_EQ (nano::process_result::progress, return1.code);
|
||||
ASSERT_EQ (key2.pub, return1.account);
|
||||
ASSERT_EQ (key2.pub, open.sideband ().account);
|
||||
ASSERT_EQ (nano::genesis_amount - 50, open.sideband ().balance.number ());
|
||||
ASSERT_EQ (1, open.sideband ().height);
|
||||
ASSERT_EQ (nano::genesis_amount - 50, return1.amount.number ());
|
||||
ASSERT_EQ (nano::genesis_amount - 50, ledger.weight (key3.pub));
|
||||
nano::send_block send2 (hash1, key2.pub, 25, nano::test_genesis_key.prv, nano::test_genesis_key.pub, *pool.generate (hash1));
|
||||
|
@ -199,6 +223,9 @@ TEST (ledger, process_receive)
|
|||
auto hash4 (receive.hash ());
|
||||
ASSERT_EQ (key2.pub, store->frontier_get (transaction, hash2));
|
||||
auto return2 (ledger.process (transaction, receive));
|
||||
ASSERT_EQ (key2.pub, receive.sideband ().account);
|
||||
ASSERT_EQ (nano::genesis_amount - 25, receive.sideband ().balance.number ());
|
||||
ASSERT_EQ (2, receive.sideband ().height);
|
||||
ASSERT_EQ (25, ledger.amount (transaction, hash4));
|
||||
ASSERT_TRUE (store->frontier_get (transaction, hash2).is_zero ());
|
||||
ASSERT_EQ (key2.pub, store->frontier_get (transaction, hash4));
|
||||
|
@ -1680,22 +1707,21 @@ TEST (ledger, state_send_receive)
|
|||
nano::state_block send1 (nano::genesis_account, genesis.hash (), nano::genesis_account, nano::genesis_amount - nano::Gxrb_ratio, nano::genesis_account, 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);
|
||||
ASSERT_TRUE (store->block_exists (transaction, send1.hash ()));
|
||||
nano::block_sideband sideband;
|
||||
auto send2 (store->block_get (transaction, send1.hash (), &sideband));
|
||||
auto send2 (store->block_get (transaction, send1.hash ()));
|
||||
ASSERT_NE (nullptr, send2);
|
||||
ASSERT_EQ (send1, *send2);
|
||||
ASSERT_EQ (nano::genesis_amount - nano::Gxrb_ratio, ledger.balance (transaction, send1.hash ()));
|
||||
ASSERT_EQ (nano::Gxrb_ratio, ledger.amount (transaction, send1.hash ()));
|
||||
ASSERT_EQ (nano::genesis_amount - nano::Gxrb_ratio, ledger.weight (nano::genesis_account));
|
||||
ASSERT_TRUE (store->pending_exists (transaction, nano::pending_key (nano::genesis_account, send1.hash ())));
|
||||
ASSERT_TRUE (sideband.details.is_send);
|
||||
ASSERT_FALSE (sideband.details.is_receive);
|
||||
ASSERT_FALSE (sideband.details.is_epoch);
|
||||
ASSERT_EQ (2, send2->sideband ().height);
|
||||
ASSERT_TRUE (send2->sideband ().details.is_send);
|
||||
ASSERT_FALSE (send2->sideband ().details.is_receive);
|
||||
ASSERT_FALSE (send2->sideband ().details.is_epoch);
|
||||
nano::state_block receive1 (nano::genesis_account, send1.hash (), nano::genesis_account, nano::genesis_amount, send1.hash (), nano::test_genesis_key.prv, nano::test_genesis_key.pub, *pool.generate (send1.hash ()));
|
||||
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, receive1).code);
|
||||
ASSERT_TRUE (store->block_exists (transaction, receive1.hash ()));
|
||||
nano::block_sideband sideband2;
|
||||
auto receive2 (store->block_get (transaction, receive1.hash (), &sideband2));
|
||||
auto receive2 (store->block_get (transaction, receive1.hash ()));
|
||||
ASSERT_NE (nullptr, receive2);
|
||||
ASSERT_EQ (receive1, *receive2);
|
||||
ASSERT_EQ (nano::genesis_amount, ledger.balance (transaction, receive1.hash ()));
|
||||
|
@ -1703,9 +1729,10 @@ TEST (ledger, state_send_receive)
|
|||
ASSERT_EQ (nano::genesis_amount, ledger.weight (nano::genesis_account));
|
||||
ASSERT_FALSE (store->pending_exists (transaction, nano::pending_key (nano::genesis_account, send1.hash ())));
|
||||
ASSERT_EQ (store->account_count (transaction), ledger.cache.account_count);
|
||||
ASSERT_FALSE (sideband2.details.is_send);
|
||||
ASSERT_TRUE (sideband2.details.is_receive);
|
||||
ASSERT_FALSE (sideband2.details.is_epoch);
|
||||
ASSERT_EQ (3, receive2->sideband ().height);
|
||||
ASSERT_FALSE (receive2->sideband ().details.is_send);
|
||||
ASSERT_TRUE (receive2->sideband ().details.is_receive);
|
||||
ASSERT_FALSE (receive2->sideband ().details.is_epoch);
|
||||
}
|
||||
|
||||
TEST (ledger, state_receive)
|
||||
|
@ -1731,16 +1758,16 @@ TEST (ledger, state_receive)
|
|||
nano::state_block receive1 (nano::genesis_account, send1.hash (), nano::genesis_account, nano::genesis_amount, send1.hash (), nano::test_genesis_key.prv, nano::test_genesis_key.pub, *pool.generate (send1.hash ()));
|
||||
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, receive1).code);
|
||||
ASSERT_TRUE (store->block_exists (transaction, receive1.hash ()));
|
||||
nano::block_sideband sideband;
|
||||
auto receive2 (store->block_get (transaction, receive1.hash (), &sideband));
|
||||
auto receive2 (store->block_get (transaction, receive1.hash ()));
|
||||
ASSERT_NE (nullptr, receive2);
|
||||
ASSERT_EQ (receive1, *receive2);
|
||||
ASSERT_EQ (nano::genesis_amount, ledger.balance (transaction, receive1.hash ()));
|
||||
ASSERT_EQ (nano::Gxrb_ratio, ledger.amount (transaction, receive1.hash ()));
|
||||
ASSERT_EQ (nano::genesis_amount, ledger.weight (nano::genesis_account));
|
||||
ASSERT_FALSE (sideband.details.is_send);
|
||||
ASSERT_TRUE (sideband.details.is_receive);
|
||||
ASSERT_FALSE (sideband.details.is_epoch);
|
||||
ASSERT_EQ (3, receive2->sideband ().height);
|
||||
ASSERT_FALSE (receive2->sideband ().details.is_send);
|
||||
ASSERT_TRUE (receive2->sideband ().details.is_receive);
|
||||
ASSERT_FALSE (receive2->sideband ().details.is_epoch);
|
||||
}
|
||||
|
||||
TEST (ledger, state_rep_change)
|
||||
|
@ -1758,17 +1785,17 @@ TEST (ledger, state_rep_change)
|
|||
nano::state_block change1 (nano::genesis_account, genesis.hash (), rep.pub, nano::genesis_amount, 0, nano::test_genesis_key.prv, nano::test_genesis_key.pub, *pool.generate (genesis.hash ()));
|
||||
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, change1).code);
|
||||
ASSERT_TRUE (store->block_exists (transaction, change1.hash ()));
|
||||
nano::block_sideband sideband;
|
||||
auto change2 (store->block_get (transaction, change1.hash (), &sideband));
|
||||
auto change2 (store->block_get (transaction, change1.hash ()));
|
||||
ASSERT_NE (nullptr, change2);
|
||||
ASSERT_EQ (change1, *change2);
|
||||
ASSERT_EQ (nano::genesis_amount, ledger.balance (transaction, change1.hash ()));
|
||||
ASSERT_EQ (0, ledger.amount (transaction, change1.hash ()));
|
||||
ASSERT_EQ (0, ledger.weight (nano::genesis_account));
|
||||
ASSERT_EQ (nano::genesis_amount, ledger.weight (rep.pub));
|
||||
ASSERT_FALSE (sideband.details.is_send);
|
||||
ASSERT_FALSE (sideband.details.is_receive);
|
||||
ASSERT_FALSE (sideband.details.is_epoch);
|
||||
ASSERT_EQ (2, change2->sideband ().height);
|
||||
ASSERT_FALSE (change2->sideband ().details.is_send);
|
||||
ASSERT_FALSE (change2->sideband ().details.is_receive);
|
||||
ASSERT_FALSE (change2->sideband ().details.is_epoch);
|
||||
}
|
||||
|
||||
TEST (ledger, state_open)
|
||||
|
@ -1797,17 +1824,17 @@ TEST (ledger, state_open)
|
|||
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, open1).code);
|
||||
ASSERT_FALSE (store->pending_exists (transaction, nano::pending_key (destination.pub, send1.hash ())));
|
||||
ASSERT_TRUE (store->block_exists (transaction, open1.hash ()));
|
||||
nano::block_sideband sideband;
|
||||
auto open2 (store->block_get (transaction, open1.hash (), &sideband));
|
||||
auto open2 (store->block_get (transaction, open1.hash ()));
|
||||
ASSERT_NE (nullptr, open2);
|
||||
ASSERT_EQ (open1, *open2);
|
||||
ASSERT_EQ (nano::Gxrb_ratio, ledger.balance (transaction, open1.hash ()));
|
||||
ASSERT_EQ (nano::Gxrb_ratio, ledger.amount (transaction, open1.hash ()));
|
||||
ASSERT_EQ (nano::genesis_amount, ledger.weight (nano::genesis_account));
|
||||
ASSERT_EQ (ledger.cache.account_count, store->account_count (transaction));
|
||||
ASSERT_FALSE (sideband.details.is_send);
|
||||
ASSERT_TRUE (sideband.details.is_receive);
|
||||
ASSERT_FALSE (sideband.details.is_epoch);
|
||||
ASSERT_EQ (1, open2->sideband ().height);
|
||||
ASSERT_FALSE (open2->sideband ().details.is_send);
|
||||
ASSERT_TRUE (open2->sideband ().details.is_receive);
|
||||
ASSERT_FALSE (open2->sideband ().details.is_epoch);
|
||||
}
|
||||
|
||||
// Make sure old block types can't be inserted after a state block.
|
||||
|
@ -2050,17 +2077,17 @@ TEST (ledger, state_send_change)
|
|||
nano::state_block send1 (nano::genesis_account, genesis.hash (), rep.pub, nano::genesis_amount - nano::Gxrb_ratio, nano::genesis_account, 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);
|
||||
ASSERT_TRUE (store->block_exists (transaction, send1.hash ()));
|
||||
nano::block_sideband sideband;
|
||||
auto send2 (store->block_get (transaction, send1.hash (), &sideband));
|
||||
auto send2 (store->block_get (transaction, send1.hash ()));
|
||||
ASSERT_NE (nullptr, send2);
|
||||
ASSERT_EQ (send1, *send2);
|
||||
ASSERT_EQ (nano::genesis_amount - nano::Gxrb_ratio, ledger.balance (transaction, send1.hash ()));
|
||||
ASSERT_EQ (nano::Gxrb_ratio, ledger.amount (transaction, send1.hash ()));
|
||||
ASSERT_EQ (0, ledger.weight (nano::genesis_account));
|
||||
ASSERT_EQ (nano::genesis_amount - nano::Gxrb_ratio, ledger.weight (rep.pub));
|
||||
ASSERT_TRUE (sideband.details.is_send);
|
||||
ASSERT_FALSE (sideband.details.is_receive);
|
||||
ASSERT_FALSE (sideband.details.is_epoch);
|
||||
ASSERT_EQ (2, send2->sideband ().height);
|
||||
ASSERT_TRUE (send2->sideband ().details.is_send);
|
||||
ASSERT_FALSE (send2->sideband ().details.is_receive);
|
||||
ASSERT_FALSE (send2->sideband ().details.is_epoch);
|
||||
}
|
||||
|
||||
TEST (ledger, state_receive_change)
|
||||
|
@ -2087,17 +2114,17 @@ TEST (ledger, state_receive_change)
|
|||
nano::state_block receive1 (nano::genesis_account, send1.hash (), rep.pub, nano::genesis_amount, send1.hash (), nano::test_genesis_key.prv, nano::test_genesis_key.pub, *pool.generate (send1.hash ()));
|
||||
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, receive1).code);
|
||||
ASSERT_TRUE (store->block_exists (transaction, receive1.hash ()));
|
||||
nano::block_sideband sideband2;
|
||||
auto receive2 (store->block_get (transaction, receive1.hash (), &sideband2));
|
||||
auto receive2 (store->block_get (transaction, receive1.hash ()));
|
||||
ASSERT_NE (nullptr, receive2);
|
||||
ASSERT_EQ (receive1, *receive2);
|
||||
ASSERT_EQ (nano::genesis_amount, ledger.balance (transaction, receive1.hash ()));
|
||||
ASSERT_EQ (nano::Gxrb_ratio, ledger.amount (transaction, receive1.hash ()));
|
||||
ASSERT_EQ (0, ledger.weight (nano::genesis_account));
|
||||
ASSERT_EQ (nano::genesis_amount, ledger.weight (rep.pub));
|
||||
ASSERT_FALSE (sideband2.details.is_send);
|
||||
ASSERT_TRUE (sideband2.details.is_receive);
|
||||
ASSERT_FALSE (sideband2.details.is_epoch);
|
||||
ASSERT_EQ (3, receive2->sideband ().height);
|
||||
ASSERT_FALSE (receive2->sideband ().details.is_send);
|
||||
ASSERT_TRUE (receive2->sideband ().details.is_receive);
|
||||
ASSERT_FALSE (receive2->sideband ().details.is_epoch);
|
||||
}
|
||||
|
||||
TEST (ledger, state_open_old)
|
||||
|
@ -2341,13 +2368,9 @@ TEST (ledger, epoch_blocks_v1_general)
|
|||
nano::keypair destination;
|
||||
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::block_sideband sideband;
|
||||
(void)ledger.store.block_get (transaction, epoch1.hash (), &sideband);
|
||||
ASSERT_FALSE (sideband.details.is_send);
|
||||
ASSERT_FALSE (sideband.details.is_receive);
|
||||
ASSERT_TRUE (sideband.details.is_epoch);
|
||||
}
|
||||
ASSERT_FALSE (epoch1.sideband ().details.is_send);
|
||||
ASSERT_FALSE (epoch1.sideband ().details.is_receive);
|
||||
ASSERT_TRUE (epoch1.sideband ().details.is_epoch);
|
||||
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;
|
||||
|
@ -2359,37 +2382,25 @@ TEST (ledger, epoch_blocks_v1_general)
|
|||
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, epoch1).code);
|
||||
ASSERT_FALSE (ledger.store.account_get (transaction, nano::genesis_account, genesis_info));
|
||||
ASSERT_EQ (genesis_info.epoch (), nano::epoch::epoch_1);
|
||||
{
|
||||
nano::block_sideband sideband;
|
||||
(void)ledger.store.block_get (transaction, epoch1.hash (), &sideband);
|
||||
ASSERT_FALSE (sideband.details.is_send);
|
||||
ASSERT_FALSE (sideband.details.is_receive);
|
||||
ASSERT_TRUE (sideband.details.is_epoch);
|
||||
}
|
||||
ASSERT_FALSE (epoch1.sideband ().details.is_send);
|
||||
ASSERT_FALSE (epoch1.sideband ().details.is_receive);
|
||||
ASSERT_TRUE (epoch1.sideband ().details.is_epoch);
|
||||
nano::change_block change1 (epoch1.hash (), nano::genesis_account, nano::test_genesis_key.prv, nano::test_genesis_key.pub, *pool.generate (epoch1.hash ()));
|
||||
ASSERT_EQ (nano::process_result::block_position, ledger.process (transaction, change1).code);
|
||||
nano::state_block send1 (nano::genesis_account, epoch1.hash (), nano::genesis_account, nano::genesis_amount - nano::Gxrb_ratio, destination.pub, nano::test_genesis_key.prv, nano::test_genesis_key.pub, *pool.generate (epoch1.hash ()));
|
||||
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, send1).code);
|
||||
{
|
||||
nano::block_sideband sideband;
|
||||
(void)ledger.store.block_get (transaction, send1.hash (), &sideband);
|
||||
ASSERT_TRUE (sideband.details.is_send);
|
||||
ASSERT_FALSE (sideband.details.is_receive);
|
||||
ASSERT_FALSE (sideband.details.is_epoch);
|
||||
}
|
||||
ASSERT_TRUE (send1.sideband ().details.is_send);
|
||||
ASSERT_FALSE (send1.sideband ().details.is_receive);
|
||||
ASSERT_FALSE (send1.sideband ().details.is_epoch);
|
||||
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));
|
||||
ASSERT_EQ (nano::process_result::representative_mismatch, ledger.process (transaction, epoch3).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);
|
||||
{
|
||||
nano::block_sideband sideband;
|
||||
(void)ledger.store.block_get (transaction, epoch4.hash (), &sideband);
|
||||
ASSERT_FALSE (sideband.details.is_send);
|
||||
ASSERT_FALSE (sideband.details.is_receive);
|
||||
ASSERT_TRUE (sideband.details.is_epoch);
|
||||
}
|
||||
ASSERT_FALSE (epoch4.sideband ().details.is_send);
|
||||
ASSERT_FALSE (epoch4.sideband ().details.is_receive);
|
||||
ASSERT_TRUE (epoch4.sideband ().details.is_epoch);
|
||||
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 ()));
|
||||
|
@ -2399,13 +2410,9 @@ TEST (ledger, epoch_blocks_v1_general)
|
|||
ASSERT_EQ (nano::Gxrb_ratio, ledger.amount (transaction, receive2.hash ()));
|
||||
ASSERT_EQ (nano::genesis_amount - nano::Gxrb_ratio, ledger.weight (nano::genesis_account));
|
||||
ASSERT_EQ (nano::Gxrb_ratio, ledger.weight (destination.pub));
|
||||
{
|
||||
nano::block_sideband sideband;
|
||||
(void)ledger.store.block_get (transaction, receive2.hash (), &sideband);
|
||||
ASSERT_FALSE (sideband.details.is_send);
|
||||
ASSERT_TRUE (sideband.details.is_receive);
|
||||
ASSERT_FALSE (sideband.details.is_epoch);
|
||||
}
|
||||
ASSERT_FALSE (receive2.sideband ().details.is_send);
|
||||
ASSERT_TRUE (receive2.sideband ().details.is_receive);
|
||||
ASSERT_FALSE (receive2.sideband ().details.is_epoch);
|
||||
}
|
||||
|
||||
TEST (ledger, epoch_blocks_v2_general)
|
||||
|
@ -2804,12 +2811,12 @@ TEST (ledger, unchecked_epoch_invalid)
|
|||
nano::account_info info;
|
||||
ASSERT_FALSE (node1.store.account_get (transaction, destination.pub, info));
|
||||
ASSERT_NE (info.epoch (), nano::epoch::epoch_1);
|
||||
nano::block_sideband sideband;
|
||||
ASSERT_NE (nullptr, node1.store.block_get (transaction, epoch2->hash (), &sideband));
|
||||
ASSERT_EQ (nano::epoch::epoch_0, sideband.details.epoch);
|
||||
ASSERT_TRUE (sideband.details.is_send);
|
||||
ASSERT_FALSE (sideband.details.is_epoch);
|
||||
ASSERT_FALSE (sideband.details.is_receive);
|
||||
auto epoch2_store (node1.store.block_get (transaction, epoch2->hash ()));
|
||||
ASSERT_NE (nullptr, epoch2_store);
|
||||
ASSERT_EQ (nano::epoch::epoch_0, epoch2_store->sideband ().details.epoch);
|
||||
ASSERT_TRUE (epoch2_store->sideband ().details.is_send);
|
||||
ASSERT_FALSE (epoch2_store->sideband ().details.is_epoch);
|
||||
ASSERT_FALSE (epoch2_store->sideband ().details.is_receive);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1506,8 +1506,10 @@ TEST (node, fork_open_flip)
|
|||
nano::keypair rep1;
|
||||
nano::keypair rep2;
|
||||
auto send1 (std::make_shared<nano::send_block> (genesis.hash (), key1.pub, nano::genesis_amount - 1, nano::test_genesis_key.prv, nano::test_genesis_key.pub, *system.work.generate (genesis.hash ())));
|
||||
// A copy is necessary to avoid data races during ledger processing, which sets the sideband
|
||||
auto send1_copy (std::make_shared<nano::send_block> (*send1));
|
||||
node1.process_active (send1);
|
||||
node2.process_active (send1);
|
||||
node2.process_active (send1_copy);
|
||||
// We should be keeping this block
|
||||
auto open1 (std::make_shared<nano::open_block> (send1->hash (), rep1.pub, key1.pub, key1.prv, key1.pub, *system.work.generate (key1.pub)));
|
||||
// This block should be evicted
|
||||
|
@ -1741,9 +1743,6 @@ TEST (node, broadcast_elected)
|
|||
nano::keypair rep_big;
|
||||
nano::keypair rep_small;
|
||||
nano::keypair rep_other;
|
||||
//std::cerr << "Big: " << rep_big.pub.to_account () << std::endl;
|
||||
//std::cerr << "Small: " << rep_small.pub.to_account () << std::endl;
|
||||
//std::cerr << "Other: " << rep_other.pub.to_account () << std::endl;
|
||||
{
|
||||
auto transaction0 (node0->store.tx_begin_write ());
|
||||
auto transaction1 (node1->store.tx_begin_write ());
|
||||
|
@ -1784,14 +1783,14 @@ TEST (node, broadcast_elected)
|
|||
system.wallet (2)->insert_adhoc (rep_other.prv);
|
||||
auto fork0 (std::make_shared<nano::send_block> (node2->latest (nano::test_genesis_key.pub), rep_small.pub, 0, nano::test_genesis_key.prv, nano::test_genesis_key.pub, 0));
|
||||
node0->work_generate_blocking (*fork0);
|
||||
// A copy is necessary to avoid data races during ledger processing, which sets the sideband
|
||||
auto fork0_copy (std::make_shared<nano::send_block> (*fork0));
|
||||
node0->process_active (fork0);
|
||||
node1->process_active (fork0);
|
||||
node1->process_active (fork0_copy);
|
||||
auto fork1 (std::make_shared<nano::send_block> (node2->latest (nano::test_genesis_key.pub), rep_big.pub, 0, nano::test_genesis_key.prv, nano::test_genesis_key.pub, 0));
|
||||
node0->work_generate_blocking (*fork1);
|
||||
system.wallet (2)->insert_adhoc (rep_small.prv);
|
||||
node2->process_active (fork1);
|
||||
//std::cerr << "fork0: " << fork_hash.to_string () << std::endl;
|
||||
//std::cerr << "fork1: " << fork1.hash ().to_string () << std::endl;
|
||||
system.deadline_set (10s);
|
||||
while (!node0->ledger.block_exists (fork0->hash ()) || !node1->ledger.block_exists (fork0->hash ()))
|
||||
{
|
||||
|
@ -2486,15 +2485,17 @@ TEST (node, block_confirm)
|
|||
nano::keypair key;
|
||||
system.wallet (1)->insert_adhoc (nano::test_genesis_key.prv);
|
||||
auto send1 (std::make_shared<nano::state_block> (nano::test_genesis_key.pub, genesis.hash (), nano::test_genesis_key.pub, nano::genesis_amount - nano::Gxrb_ratio, key.pub, nano::test_genesis_key.prv, nano::test_genesis_key.pub, *node1.work_generate_blocking (genesis.hash ())));
|
||||
// A copy is necessary to avoid data races during ledger processing, which sets the sideband
|
||||
auto send1_copy (std::make_shared<nano::state_block> (*send1));
|
||||
node1.block_processor.add (send1, nano::seconds_since_epoch ());
|
||||
node2.block_processor.add (send1, nano::seconds_since_epoch ());
|
||||
node2.block_processor.add (send1_copy, nano::seconds_since_epoch ());
|
||||
system.deadline_set (std::chrono::seconds (5));
|
||||
while (!node1.ledger.block_exists (send1->hash ()) || !node2.ledger.block_exists (send1->hash ()))
|
||||
while (!node1.ledger.block_exists (send1->hash ()) || !node2.ledger.block_exists (send1_copy->hash ()))
|
||||
{
|
||||
ASSERT_NO_ERROR (system.poll ());
|
||||
}
|
||||
ASSERT_TRUE (node1.ledger.block_exists (send1->hash ()));
|
||||
ASSERT_TRUE (node2.ledger.block_exists (send1->hash ()));
|
||||
ASSERT_TRUE (node2.ledger.block_exists (send1_copy->hash ()));
|
||||
auto send2 (std::make_shared<nano::state_block> (nano::test_genesis_key.pub, send1->hash (), nano::test_genesis_key.pub, nano::genesis_amount - nano::Gxrb_ratio * 2, key.pub, nano::test_genesis_key.prv, nano::test_genesis_key.pub, *node1.work_generate_blocking (send1->hash ())));
|
||||
{
|
||||
auto transaction (node1.store.tx_begin_write ());
|
||||
|
|
|
@ -11,14 +11,14 @@ TEST (versioning, account_info_v1)
|
|||
auto file (nano::unique_path ());
|
||||
nano::account account (1);
|
||||
nano::open_block open (1, 2, 3, nullptr);
|
||||
open.sideband_set ({});
|
||||
nano::account_info_v1 v1 (open.hash (), open.hash (), 3, 4);
|
||||
{
|
||||
nano::logger_mt logger;
|
||||
nano::mdb_store store (logger, file);
|
||||
ASSERT_FALSE (store.init_error ());
|
||||
auto transaction (store.tx_begin_write ());
|
||||
nano::block_sideband sideband (nano::block_type::open, 0, 0, 0, 0, 0, nano::epoch::epoch_0, false, false, false);
|
||||
store.block_put (transaction, open.hash (), open, sideband);
|
||||
store.block_put (transaction, open.hash (), open);
|
||||
auto status (mdb_put (store.env.tx (transaction), store.accounts_v0, nano::mdb_val (account), nano::mdb_val (sizeof (v1), &v1), 0));
|
||||
ASSERT_EQ (0, status);
|
||||
store.version_put (transaction, 1);
|
||||
|
@ -47,14 +47,14 @@ TEST (versioning, account_info_v5)
|
|||
auto file (nano::unique_path ());
|
||||
nano::account account (1);
|
||||
nano::open_block open (1, 2, 3, nullptr);
|
||||
open.sideband_set ({});
|
||||
nano::account_info_v5 v5 (open.hash (), open.hash (), open.hash (), 3, 4);
|
||||
{
|
||||
nano::logger_mt logger;
|
||||
nano::mdb_store store (logger, file);
|
||||
ASSERT_FALSE (store.init_error ());
|
||||
auto transaction (store.tx_begin_write ());
|
||||
nano::block_sideband sideband (nano::block_type::open, 0, 0, 0, 0, 0, nano::epoch::epoch_0, false, false, false);
|
||||
store.block_put (transaction, open.hash (), open, sideband);
|
||||
store.block_put (transaction, open.hash (), open);
|
||||
auto status (mdb_put (store.env.tx (transaction), store.accounts_v0, nano::mdb_val (account), nano::mdb_val (sizeof (v5), &v5), 0));
|
||||
ASSERT_EQ (0, status);
|
||||
store.version_put (transaction, 5);
|
||||
|
@ -83,14 +83,14 @@ TEST (versioning, account_info_v13)
|
|||
auto file (nano::unique_path ());
|
||||
nano::account account (1);
|
||||
nano::open_block open (1, 2, 3, nullptr);
|
||||
open.sideband_set ({});
|
||||
nano::account_info_v13 v13 (open.hash (), open.hash (), open.hash (), 3, 4, 10, nano::epoch::epoch_0);
|
||||
{
|
||||
nano::logger_mt logger;
|
||||
nano::mdb_store store (logger, file);
|
||||
ASSERT_FALSE (store.init_error ());
|
||||
auto transaction (store.tx_begin_write ());
|
||||
nano::block_sideband sideband (nano::block_type::open, 0, 0, 0, 0, 0, nano::epoch::epoch_0, false, false, false);
|
||||
store.block_put (transaction, open.hash (), open, sideband);
|
||||
store.block_put (transaction, open.hash (), open);
|
||||
auto status (mdb_put (store.env.tx (transaction), store.accounts_v0, nano::mdb_val (account), nano::mdb_val (v13), 0));
|
||||
ASSERT_EQ (0, status);
|
||||
store.version_put (transaction, 13);
|
||||
|
|
|
@ -25,6 +25,8 @@ add_library (nano_lib
|
|||
configbase.hpp
|
||||
diagnosticsconfig.hpp
|
||||
diagnosticsconfig.cpp
|
||||
epoch.hpp
|
||||
epoch.cpp
|
||||
errors.hpp
|
||||
errors.cpp
|
||||
ipc.hpp
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
#include <boost/endian/conversion.hpp>
|
||||
#include <boost/property_tree/json_parser.hpp>
|
||||
|
||||
#include <bitset>
|
||||
|
||||
/** Compare blocks, first by type, then content. This is an optimization over dynamic_cast, which is very slow on some platforms. */
|
||||
namespace
|
||||
{
|
||||
|
@ -136,6 +138,17 @@ nano::block_hash nano::block::full_hash () const
|
|||
return result;
|
||||
}
|
||||
|
||||
nano::block_sideband const & nano::block::sideband () const
|
||||
{
|
||||
debug_assert (sideband_m.is_initialized ());
|
||||
return *sideband_m;
|
||||
}
|
||||
|
||||
void nano::block::sideband_set (nano::block_sideband const & sideband_a)
|
||||
{
|
||||
sideband_m = sideband_a;
|
||||
}
|
||||
|
||||
nano::account const & nano::block::representative () const
|
||||
{
|
||||
static nano::account rep{ 0 };
|
||||
|
@ -176,6 +189,11 @@ void nano::send_block::visit (nano::block_visitor & visitor_a) const
|
|||
visitor_a.send_block (*this);
|
||||
}
|
||||
|
||||
void nano::send_block::visit (nano::mutable_block_visitor & visitor_a)
|
||||
{
|
||||
visitor_a.send_block (*this);
|
||||
}
|
||||
|
||||
void nano::send_block::hash (blake2b_state & hash_a) const
|
||||
{
|
||||
hashables.hash (hash_a);
|
||||
|
@ -660,6 +678,11 @@ void nano::open_block::visit (nano::block_visitor & visitor_a) const
|
|||
visitor_a.open_block (*this);
|
||||
}
|
||||
|
||||
void nano::open_block::visit (nano::mutable_block_visitor & visitor_a)
|
||||
{
|
||||
visitor_a.open_block (*this);
|
||||
}
|
||||
|
||||
nano::block_type nano::open_block::type () const
|
||||
{
|
||||
return nano::block_type::open;
|
||||
|
@ -896,6 +919,11 @@ void nano::change_block::visit (nano::block_visitor & visitor_a) const
|
|||
visitor_a.change_block (*this);
|
||||
}
|
||||
|
||||
void nano::change_block::visit (nano::mutable_block_visitor & visitor_a)
|
||||
{
|
||||
visitor_a.change_block (*this);
|
||||
}
|
||||
|
||||
nano::block_type nano::change_block::type () const
|
||||
{
|
||||
return nano::block_type::change;
|
||||
|
@ -1203,6 +1231,11 @@ void nano::state_block::visit (nano::block_visitor & visitor_a) const
|
|||
visitor_a.state_block (*this);
|
||||
}
|
||||
|
||||
void nano::state_block::visit (nano::mutable_block_visitor & visitor_a)
|
||||
{
|
||||
visitor_a.state_block (*this);
|
||||
}
|
||||
|
||||
nano::block_type nano::state_block::type () const
|
||||
{
|
||||
return nano::block_type::state;
|
||||
|
@ -1364,6 +1397,11 @@ void nano::receive_block::visit (nano::block_visitor & visitor_a) const
|
|||
visitor_a.receive_block (*this);
|
||||
}
|
||||
|
||||
void nano::receive_block::visit (nano::mutable_block_visitor & visitor_a)
|
||||
{
|
||||
visitor_a.receive_block (*this);
|
||||
}
|
||||
|
||||
bool nano::receive_block::operator== (nano::receive_block const & other_a) const
|
||||
{
|
||||
auto result (hashables.previous == other_a.hashables.previous && hashables.source == other_a.hashables.source && work == other_a.work && signature == other_a.signature);
|
||||
|
@ -1608,6 +1646,157 @@ void nano::receive_hashables::hash (blake2b_state & hash_a) const
|
|||
blake2b_update (&hash_a, source.bytes.data (), sizeof (source.bytes));
|
||||
}
|
||||
|
||||
nano::block_details::block_details (nano::epoch const epoch_a, bool const is_send_a, bool const is_receive_a, bool const is_epoch_a) :
|
||||
epoch (epoch_a), is_send (is_send_a), is_receive (is_receive_a), is_epoch (is_epoch_a)
|
||||
{
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
uint8_t nano::block_details::packed () const
|
||||
{
|
||||
std::bitset<8> result (static_cast<uint8_t> (epoch));
|
||||
result.set (7, is_send);
|
||||
result.set (6, is_receive);
|
||||
result.set (5, is_epoch);
|
||||
return static_cast<uint8_t> (result.to_ulong ());
|
||||
}
|
||||
|
||||
void nano::block_details::unpack (uint8_t details_a)
|
||||
{
|
||||
constexpr std::bitset<8> epoch_mask{ 0b00011111 };
|
||||
auto as_bitset = static_cast<std::bitset<8>> (details_a);
|
||||
is_send = as_bitset.test (7);
|
||||
is_receive = as_bitset.test (6);
|
||||
is_epoch = as_bitset.test (5);
|
||||
epoch = static_cast<nano::epoch> ((as_bitset & epoch_mask).to_ulong ());
|
||||
}
|
||||
|
||||
void nano::block_details::serialize (nano::stream & stream_a) const
|
||||
{
|
||||
nano::write (stream_a, packed ());
|
||||
}
|
||||
|
||||
bool nano::block_details::deserialize (nano::stream & stream_a)
|
||||
{
|
||||
bool result (false);
|
||||
try
|
||||
{
|
||||
uint8_t packed{ 0 };
|
||||
nano::read (stream_a, packed);
|
||||
unpack (packed);
|
||||
}
|
||||
catch (std::runtime_error &)
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
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) :
|
||||
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::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 is larger than the epoch enum");
|
||||
result += nano::block_details::size ();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void nano::block_sideband::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::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;
|
||||
}
|
||||
|
||||
std::shared_ptr<nano::block> nano::block_uniquer::unique (std::shared_ptr<nano::block> block_a)
|
||||
{
|
||||
auto result (block_a);
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
#pragma once
|
||||
|
||||
#include <nano/crypto/blake2/blake2.h>
|
||||
#include <nano/lib/epoch.hpp>
|
||||
#include <nano/lib/errors.hpp>
|
||||
#include <nano/lib/numbers.hpp>
|
||||
#include <nano/lib/optional_ptr.hpp>
|
||||
#include <nano/lib/stream.hpp>
|
||||
#include <nano/lib/utility.hpp>
|
||||
#include <nano/lib/work.hpp>
|
||||
|
@ -14,6 +16,7 @@
|
|||
namespace nano
|
||||
{
|
||||
class block_visitor;
|
||||
class mutable_block_visitor;
|
||||
enum class block_type : uint8_t
|
||||
{
|
||||
invalid = 0,
|
||||
|
@ -24,6 +27,43 @@ enum class block_type : uint8_t
|
|||
change = 5,
|
||||
state = 6
|
||||
};
|
||||
class block_details
|
||||
{
|
||||
static_assert (std::is_same<std::underlying_type<nano::epoch>::type, uint8_t> (), "Epoch enum is not the proper type");
|
||||
static_assert (static_cast<uint8_t> (nano::epoch::max) < (1 << 5), "Epoch max is too large for the sideband");
|
||||
|
||||
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 ();
|
||||
bool operator== (block_details const & other_a) const;
|
||||
void serialize (nano::stream &) const;
|
||||
bool deserialize (nano::stream &);
|
||||
nano::epoch epoch{ nano::epoch::epoch_0 };
|
||||
bool is_send{ false };
|
||||
bool is_receive{ false };
|
||||
bool is_epoch{ false };
|
||||
|
||||
private:
|
||||
uint8_t packed () const;
|
||||
void unpack (uint8_t);
|
||||
};
|
||||
|
||||
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::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;
|
||||
};
|
||||
class block
|
||||
{
|
||||
public:
|
||||
|
@ -31,6 +71,8 @@ public:
|
|||
nano::block_hash const & hash () const;
|
||||
// Return a digest of hashables and non-hashables in this block.
|
||||
nano::block_hash full_hash () const;
|
||||
nano::block_sideband const & sideband () const;
|
||||
void sideband_set (nano::block_sideband const &);
|
||||
std::string to_json () const;
|
||||
virtual void hash (blake2b_state &) const = 0;
|
||||
virtual uint64_t block_work () const = 0;
|
||||
|
@ -52,6 +94,7 @@ public:
|
|||
virtual void serialize_json (std::string &, bool = false) const = 0;
|
||||
virtual void serialize_json (boost::property_tree::ptree &) const = 0;
|
||||
virtual void visit (nano::block_visitor &) const = 0;
|
||||
virtual void visit (nano::mutable_block_visitor &) = 0;
|
||||
virtual bool operator== (nano::block const &) const = 0;
|
||||
virtual nano::block_type type () const = 0;
|
||||
virtual nano::signature const & block_signature () const = 0;
|
||||
|
@ -66,6 +109,12 @@ public:
|
|||
|
||||
protected:
|
||||
mutable nano::block_hash cached_hash{ 0 };
|
||||
/**
|
||||
* Contextual details about a block, some fields may or may not be set depending on block type.
|
||||
* This field is set via sideband_set in ledger processing or deserializing blocks from the database.
|
||||
* Otherwise it may be null (for example, an old block or fork).
|
||||
*/
|
||||
nano::optional_ptr<nano::block_sideband> sideband_m;
|
||||
|
||||
private:
|
||||
nano::block_hash generate_hash () const;
|
||||
|
@ -104,6 +153,7 @@ public:
|
|||
void serialize_json (boost::property_tree::ptree &) const override;
|
||||
bool deserialize_json (boost::property_tree::ptree const &);
|
||||
void visit (nano::block_visitor &) const override;
|
||||
void visit (nano::mutable_block_visitor &) override;
|
||||
nano::block_type type () const override;
|
||||
nano::signature const & block_signature () const override;
|
||||
void signature_set (nano::signature const &) override;
|
||||
|
@ -148,6 +198,7 @@ public:
|
|||
void serialize_json (boost::property_tree::ptree &) const override;
|
||||
bool deserialize_json (boost::property_tree::ptree const &);
|
||||
void visit (nano::block_visitor &) const override;
|
||||
void visit (nano::mutable_block_visitor &) override;
|
||||
nano::block_type type () const override;
|
||||
nano::signature const & block_signature () const override;
|
||||
void signature_set (nano::signature const &) override;
|
||||
|
@ -196,6 +247,7 @@ public:
|
|||
void serialize_json (boost::property_tree::ptree &) const override;
|
||||
bool deserialize_json (boost::property_tree::ptree const &);
|
||||
void visit (nano::block_visitor &) const override;
|
||||
void visit (nano::mutable_block_visitor &) override;
|
||||
nano::block_type type () const override;
|
||||
nano::signature const & block_signature () const override;
|
||||
void signature_set (nano::signature const &) override;
|
||||
|
@ -240,6 +292,7 @@ public:
|
|||
void serialize_json (boost::property_tree::ptree &) const override;
|
||||
bool deserialize_json (boost::property_tree::ptree const &);
|
||||
void visit (nano::block_visitor &) const override;
|
||||
void visit (nano::mutable_block_visitor &) override;
|
||||
nano::block_type type () const override;
|
||||
nano::signature const & block_signature () const override;
|
||||
void signature_set (nano::signature const &) override;
|
||||
|
@ -300,6 +353,7 @@ public:
|
|||
void serialize_json (boost::property_tree::ptree &) const override;
|
||||
bool deserialize_json (boost::property_tree::ptree const &);
|
||||
void visit (nano::block_visitor &) const override;
|
||||
void visit (nano::mutable_block_visitor &) override;
|
||||
nano::block_type type () const override;
|
||||
nano::signature const & block_signature () const override;
|
||||
void signature_set (nano::signature const &) override;
|
||||
|
@ -321,6 +375,16 @@ public:
|
|||
virtual void state_block (nano::state_block const &) = 0;
|
||||
virtual ~block_visitor () = default;
|
||||
};
|
||||
class mutable_block_visitor
|
||||
{
|
||||
public:
|
||||
virtual void send_block (nano::send_block &) = 0;
|
||||
virtual void receive_block (nano::receive_block &) = 0;
|
||||
virtual void open_block (nano::open_block &) = 0;
|
||||
virtual void change_block (nano::change_block &) = 0;
|
||||
virtual void state_block (nano::state_block &) = 0;
|
||||
virtual ~mutable_block_visitor () = default;
|
||||
};
|
||||
/**
|
||||
* This class serves to find and return unique variants of a block in order to minimize memory usage
|
||||
*/
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include <nano/lib/epoch.hpp>
|
||||
#include <nano/lib/utility.hpp>
|
||||
#include <nano/secure/epoch.hpp>
|
||||
|
||||
nano::link const & nano::epochs::link (nano::epoch epoch_a) const
|
||||
{
|
|
@ -995,14 +995,14 @@ int main (int argc, char * const * argv)
|
|||
|
||||
auto hash (info.open_block);
|
||||
nano::block_hash calculated_hash (0);
|
||||
nano::block_sideband sideband;
|
||||
auto block (node.node->store.block_get (transaction, hash, &sideband)); // Block data
|
||||
auto block (node.node->store.block_get (transaction, hash)); // Block data
|
||||
uint64_t height (0);
|
||||
uint64_t previous_timestamp (0);
|
||||
nano::account calculated_representative (0);
|
||||
while (!hash.is_zero () && block != nullptr)
|
||||
{
|
||||
++block_count;
|
||||
auto const & sideband (block->sideband ());
|
||||
// Check for state & open blocks if account field is correct
|
||||
if (block->type () == nano::block_type::open || block->type () == nano::block_type::state)
|
||||
{
|
||||
|
@ -1125,7 +1125,7 @@ int main (int argc, char * const * argv)
|
|||
// Retrieving block data
|
||||
if (!hash.is_zero ())
|
||||
{
|
||||
block = node.node->store.block_get (transaction, hash, &sideband);
|
||||
block = node.node->store.block_get (transaction, hash);
|
||||
}
|
||||
}
|
||||
// Check if required block exists
|
||||
|
|
|
@ -24,8 +24,8 @@ thread ([this]() {
|
|||
})
|
||||
{
|
||||
// Register a callback which will get called after a block is cemented
|
||||
confirmation_height_processor.add_cemented_observer ([this](nano::block_w_sideband const & callback_data_a) {
|
||||
this->block_cemented_callback (callback_data_a.block, callback_data_a.sideband);
|
||||
confirmation_height_processor.add_cemented_observer ([this](std::shared_ptr<nano::block> callback_block_a) {
|
||||
this->block_cemented_callback (callback_block_a);
|
||||
});
|
||||
|
||||
// Register a callback which will get called after a batch of blocks is written and observer calls finished
|
||||
|
@ -119,7 +119,7 @@ void nano::active_transactions::search_frontiers (nano::transaction const & tran
|
|||
}
|
||||
}
|
||||
|
||||
void nano::active_transactions::block_cemented_callback (std::shared_ptr<nano::block> const & block_a, nano::block_sideband const & sideband_a)
|
||||
void nano::active_transactions::block_cemented_callback (std::shared_ptr<nano::block> const & block_a)
|
||||
{
|
||||
auto transaction = node.store.tx_begin_read ();
|
||||
|
||||
|
@ -142,7 +142,7 @@ void nano::active_transactions::block_cemented_callback (std::shared_ptr<nano::b
|
|||
nano::uint128_t amount (0);
|
||||
bool is_state_send (false);
|
||||
nano::account pending_account (0);
|
||||
node.process_confirmed_data (transaction, block_a, block_a->hash (), sideband_a, account, amount, is_state_send, pending_account);
|
||||
node.process_confirmed_data (transaction, block_a, block_a->hash (), account, amount, is_state_send, pending_account);
|
||||
node.observers.blocks.notify (nano::election_status{ block_a, 0, std::chrono::duration_cast<std::chrono::milliseconds> (std::chrono::system_clock::now ().time_since_epoch ()), std::chrono::duration_values<std::chrono::milliseconds>::zero (), 0, 1, 0, nano::election_status_type::inactive_confirmation_height }, account, amount, is_state_send);
|
||||
}
|
||||
else
|
||||
|
@ -167,7 +167,7 @@ void nano::active_transactions::block_cemented_callback (std::shared_ptr<nano::b
|
|||
nano::uint128_t amount (0);
|
||||
bool is_state_send (false);
|
||||
nano::account pending_account (0);
|
||||
node.process_confirmed_data (transaction, block_a, hash, sideband_a, account, amount, is_state_send, pending_account);
|
||||
node.process_confirmed_data (transaction, block_a, hash, account, amount, is_state_send, pending_account);
|
||||
election->status.type = *election_status_type;
|
||||
election->status.confirmation_request_count = election->confirmation_request_count;
|
||||
node.observers.blocks.notify (election->status, account, amount, is_state_send);
|
||||
|
|
|
@ -112,7 +112,7 @@ public:
|
|||
void stop ();
|
||||
bool publish (std::shared_ptr<nano::block> block_a);
|
||||
boost::optional<nano::election_status_type> confirm_block (nano::transaction const &, std::shared_ptr<nano::block>);
|
||||
void block_cemented_callback (std::shared_ptr<nano::block> const & block_a, nano::block_sideband const & sideband_a);
|
||||
void block_cemented_callback (std::shared_ptr<nano::block> const & block_a);
|
||||
void block_already_cemented_callback (nano::block_hash const &);
|
||||
// clang-format off
|
||||
boost::multi_index_container<nano::conflict_info,
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
#include <numeric>
|
||||
|
||||
nano::confirmation_height_bounded::confirmation_height_bounded (nano::ledger & ledger_a, nano::write_database_queue & write_database_queue_a, std::chrono::milliseconds batch_separate_pending_min_time_a, nano::logger_mt & logger_a, std::atomic<bool> & stopped_a, nano::block_hash const & original_hash_a, std::function<void(std::vector<nano::block_w_sideband> const &)> const & notify_observers_callback_a, std::function<void(nano::block_hash const &)> const & notify_block_already_cemented_observers_callback_a, std::function<uint64_t ()> const & awaiting_processing_size_callback_a) :
|
||||
nano::confirmation_height_bounded::confirmation_height_bounded (nano::ledger & ledger_a, nano::write_database_queue & write_database_queue_a, std::chrono::milliseconds batch_separate_pending_min_time_a, nano::logger_mt & logger_a, std::atomic<bool> & stopped_a, nano::block_hash const & original_hash_a, std::function<void(std::vector<std::shared_ptr<nano::block>> const &)> const & notify_observers_callback_a, std::function<void(nano::block_hash const &)> const & notify_block_already_cemented_observers_callback_a, std::function<uint64_t ()> const & awaiting_processing_size_callback_a) :
|
||||
ledger (ledger_a),
|
||||
write_database_queue (write_database_queue_a),
|
||||
batch_separate_pending_min_time (batch_separate_pending_min_time_a),
|
||||
|
@ -67,13 +67,12 @@ void nano::confirmation_height_bounded::process ()
|
|||
current = hash_to_process.top;
|
||||
|
||||
auto top_level_hash = current;
|
||||
nano::block_sideband sideband;
|
||||
auto block = ledger.store.block_get (transaction, current, &sideband);
|
||||
auto block = ledger.store.block_get (transaction, current);
|
||||
debug_assert (block != nullptr);
|
||||
nano::account account (block->account ());
|
||||
if (account.is_zero ())
|
||||
{
|
||||
account = sideband.account;
|
||||
account = block->sideband ().account;
|
||||
}
|
||||
|
||||
// Checks if we have encountered this account before but not commited changes yet, if so then update the cached confirmation height
|
||||
|
@ -90,13 +89,13 @@ void nano::confirmation_height_bounded::process ()
|
|||
(void)error;
|
||||
debug_assert (!error);
|
||||
// This block was added to the confirmation height processor but is already confirmed
|
||||
if (first_iter && confirmation_height_info.height >= sideband.height && current == original_hash)
|
||||
if (first_iter && confirmation_height_info.height >= block->sideband ().height && current == original_hash)
|
||||
{
|
||||
notify_block_already_cemented_observers_callback (original_hash);
|
||||
}
|
||||
}
|
||||
|
||||
auto block_height = sideband.height;
|
||||
auto block_height = block->sideband ().height;
|
||||
bool already_cemented = confirmation_height_info.height >= block_height;
|
||||
|
||||
// If we are not already at the bottom of the account chain (1 above cemented frontier) then find it
|
||||
|
@ -199,14 +198,14 @@ void nano::confirmation_height_bounded::process ()
|
|||
nano::block_hash nano::confirmation_height_bounded::get_least_unconfirmed_hash_from_top_level (nano::transaction const & transaction_a, nano::block_hash const & hash_a, nano::account const & account_a, nano::confirmation_height_info const & confirmation_height_info_a, uint64_t & block_height_a)
|
||||
{
|
||||
nano::block_hash least_unconfirmed_hash = hash_a;
|
||||
nano::block_sideband sideband;
|
||||
if (confirmation_height_info_a.height != 0)
|
||||
{
|
||||
if (block_height_a > confirmation_height_info_a.height)
|
||||
{
|
||||
release_assert (ledger.store.block_get (transaction_a, confirmation_height_info_a.frontier, &sideband) != nullptr);
|
||||
least_unconfirmed_hash = sideband.successor;
|
||||
block_height_a = sideband.height + 1;
|
||||
auto block (ledger.store.block_get (transaction_a, confirmation_height_info_a.frontier));
|
||||
release_assert (block != nullptr);
|
||||
least_unconfirmed_hash = block->sideband ().successor;
|
||||
block_height_a = block->sideband ().height + 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -225,14 +224,13 @@ bool nano::confirmation_height_bounded::iterate (nano::read_transaction const &
|
|||
bool reached_target = false;
|
||||
bool hit_receive = false;
|
||||
auto hash = bottom_hash_a;
|
||||
nano::block_sideband sideband;
|
||||
uint64_t num_blocks = 0;
|
||||
while (!hash.is_zero () && !reached_target && !stopped)
|
||||
{
|
||||
// Keep iterating upwards until we either reach the desired block or the second receive.
|
||||
// Once a receive is cemented, we can cement all blocks above it until the next receive, so store those details for later.
|
||||
++num_blocks;
|
||||
auto block = ledger.store.block_get (transaction_a, hash, &sideband);
|
||||
auto block = ledger.store.block_get (transaction_a, hash);
|
||||
auto source (block->source ());
|
||||
if (source.is_zero ())
|
||||
{
|
||||
|
@ -243,6 +241,7 @@ bool nano::confirmation_height_bounded::iterate (nano::read_transaction const &
|
|||
{
|
||||
hit_receive = true;
|
||||
reached_target = true;
|
||||
auto const & sideband (block->sideband ());
|
||||
auto next = !sideband.successor.is_zero () && sideband.successor != top_level_hash_a ? boost::optional<nano::block_hash> (sideband.successor) : boost::none;
|
||||
receive_source_pairs_a.push_back ({ receive_chain_details{ account_a, sideband.height, hash, top_level_hash_a, next, bottom_height_a, bottom_hash_a }, source });
|
||||
// Store a checkpoint every max_items so that we can always traverse a long number of accounts to genesis
|
||||
|
@ -261,7 +260,7 @@ bool nano::confirmation_height_bounded::iterate (nano::read_transaction const &
|
|||
}
|
||||
else
|
||||
{
|
||||
hash = sideband.successor;
|
||||
hash = block->sideband ().successor;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -337,7 +336,7 @@ bool nano::confirmation_height_bounded::cement_blocks ()
|
|||
{
|
||||
// Will contain all blocks that have been cemented (bounded by batch_write_size)
|
||||
// and will get run through the cemented observer callback
|
||||
std::vector<block_w_sideband> cemented_blocks;
|
||||
std::vector<std::shared_ptr<nano::block>> cemented_blocks;
|
||||
{
|
||||
// This only writes to the confirmation_height table and is the only place to do so in a single process
|
||||
auto transaction (ledger.store.tx_begin_write ({}, { nano::tables::confirmation_height }));
|
||||
|
@ -354,9 +353,9 @@ bool nano::confirmation_height_bounded::cement_blocks ()
|
|||
// Extra debug checks
|
||||
nano::confirmation_height_info confirmation_height_info;
|
||||
debug_assert (!ledger.store.confirmation_height_get (transaction, account, confirmation_height_info));
|
||||
nano::block_sideband sideband;
|
||||
debug_assert (ledger.store.block_get (transaction, confirmed_frontier, &sideband));
|
||||
debug_assert (sideband.height == confirmation_height_info.height + num_blocks_cemented);
|
||||
auto block (ledger.store.block_get (transaction, confirmed_frontier));
|
||||
debug_assert (block != nullptr);
|
||||
debug_assert (block->sideband ().height == confirmation_height_info.height + num_blocks_cemented);
|
||||
#endif
|
||||
ledger.store.confirmation_height_put (transaction, account, nano::confirmation_height_info{ confirmation_height, confirmed_frontier });
|
||||
ledger.cache.cemented_count += num_blocks_cemented;
|
||||
|
@ -370,7 +369,6 @@ bool nano::confirmation_height_bounded::cement_blocks ()
|
|||
// Some blocks need to be cemented at least
|
||||
if (pending.top_height > confirmation_height_info.height)
|
||||
{
|
||||
nano::block_sideband sideband;
|
||||
// The highest hash which will be cemented
|
||||
nano::block_hash new_cemented_frontier;
|
||||
uint64_t num_blocks_confirmed = 0;
|
||||
|
@ -385,8 +383,8 @@ bool nano::confirmation_height_bounded::cement_blocks ()
|
|||
}
|
||||
else
|
||||
{
|
||||
auto block = ledger.store.block_get (transaction, confirmation_height_info.frontier, &sideband);
|
||||
new_cemented_frontier = sideband.successor;
|
||||
auto block = ledger.store.block_get (transaction, confirmation_height_info.frontier);
|
||||
new_cemented_frontier = block->sideband ().successor;
|
||||
num_blocks_confirmed = pending.top_height - confirmation_height_info.height;
|
||||
start_height = confirmation_height_info.height + 1;
|
||||
}
|
||||
|
@ -394,7 +392,7 @@ bool nano::confirmation_height_bounded::cement_blocks ()
|
|||
auto total_blocks_cemented = 0;
|
||||
auto num_blocks_iterated = 0;
|
||||
|
||||
auto block = ledger.store.block_get (transaction, new_cemented_frontier, &sideband);
|
||||
auto block = ledger.store.block_get (transaction, new_cemented_frontier);
|
||||
|
||||
// Cementing starts from the bottom of the chain and works upwards. This is because chains can have effectively
|
||||
// an infinite number of send/change blocks in a row. We don't want to hold the write transaction open for too long.
|
||||
|
@ -409,7 +407,7 @@ bool nano::confirmation_height_bounded::cement_blocks ()
|
|||
return true;
|
||||
}
|
||||
|
||||
cemented_blocks.emplace_back (block, sideband);
|
||||
cemented_blocks.emplace_back (block);
|
||||
|
||||
// We have likely hit a long chain, flush these callbacks and continue
|
||||
if (cemented_blocks.size () == confirmation_height::batch_write_size)
|
||||
|
@ -427,8 +425,8 @@ bool nano::confirmation_height_bounded::cement_blocks ()
|
|||
auto last_iteration = (num_blocks_confirmed - num_blocks_iterated) == 1;
|
||||
if (!last_iteration)
|
||||
{
|
||||
new_cemented_frontier = sideband.successor;
|
||||
block = ledger.store.block_get (transaction, new_cemented_frontier, &sideband);
|
||||
new_cemented_frontier = block->sideband ().successor;
|
||||
block = ledger.store.block_get (transaction, new_cemented_frontier);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -15,7 +15,7 @@ class write_database_queue;
|
|||
class confirmation_height_bounded final
|
||||
{
|
||||
public:
|
||||
confirmation_height_bounded (nano::ledger &, nano::write_database_queue &, std::chrono::milliseconds, nano::logger_mt &, std::atomic<bool> &, nano::block_hash const &, std::function<void(std::vector<nano::block_w_sideband> const &)> const &, std::function<void(nano::block_hash const &)> const &, std::function<uint64_t ()> const &);
|
||||
confirmation_height_bounded (nano::ledger &, nano::write_database_queue &, std::chrono::milliseconds, nano::logger_mt &, std::atomic<bool> &, nano::block_hash const &, std::function<void(std::vector<std::shared_ptr<nano::block>> const &)> const &, std::function<void(nano::block_hash const &)> const &, std::function<uint64_t ()> const &);
|
||||
bool pending_empty () const;
|
||||
void prepare_new ();
|
||||
void process ();
|
||||
|
@ -114,7 +114,7 @@ private:
|
|||
nano::logger_mt & logger;
|
||||
std::atomic<bool> & stopped;
|
||||
nano::block_hash const & original_hash;
|
||||
std::function<void(std::vector<block_w_sideband> const &)> notify_observers_callback;
|
||||
std::function<void(std::vector<std::shared_ptr<nano::block>> const &)> notify_observers_callback;
|
||||
std::function<void(nano::block_hash const &)> notify_block_already_cemented_observers_callback;
|
||||
std::function<uint64_t ()> awaiting_processing_size_callback;
|
||||
|
||||
|
|
|
@ -165,7 +165,7 @@ void nano::confirmation_height_processor::set_next_hash ()
|
|||
}
|
||||
|
||||
// Not thread-safe, only call before this processor has begun cementing
|
||||
void nano::confirmation_height_processor::add_cemented_observer (std::function<void(block_w_sideband)> const & callback_a)
|
||||
void nano::confirmation_height_processor::add_cemented_observer (std::function<void(std::shared_ptr<nano::block>)> const & callback_a)
|
||||
{
|
||||
cemented_observers.push_back (callback_a);
|
||||
}
|
||||
|
@ -176,7 +176,7 @@ void nano::confirmation_height_processor::add_block_already_cemented_observer (s
|
|||
block_already_cemented_observers.push_back (callback_a);
|
||||
}
|
||||
|
||||
void nano::confirmation_height_processor::notify_observers (std::vector<nano::block_w_sideband> const & cemented_blocks)
|
||||
void nano::confirmation_height_processor::notify_observers (std::vector<std::shared_ptr<nano::block>> const & cemented_blocks)
|
||||
{
|
||||
for (auto const & block_callback_data : cemented_blocks)
|
||||
{
|
||||
|
|
|
@ -35,7 +35,7 @@ public:
|
|||
bool is_processing_block (nano::block_hash const &);
|
||||
nano::block_hash current ();
|
||||
|
||||
void add_cemented_observer (std::function<void(block_w_sideband)> const &);
|
||||
void add_cemented_observer (std::function<void(std::shared_ptr<nano::block>)> const &);
|
||||
void add_block_already_cemented_observer (std::function<void(nano::block_hash const &)> const &);
|
||||
|
||||
private:
|
||||
|
@ -51,7 +51,7 @@ private:
|
|||
|
||||
nano::condition_variable condition;
|
||||
std::atomic<bool> stopped{ false };
|
||||
std::vector<std::function<void(nano::block_w_sideband)>> cemented_observers;
|
||||
std::vector<std::function<void(std::shared_ptr<nano::block>)>> cemented_observers;
|
||||
std::vector<std::function<void(nano::block_hash const &)>> block_already_cemented_observers;
|
||||
|
||||
nano::ledger & ledger;
|
||||
|
@ -61,7 +61,7 @@ private:
|
|||
std::thread thread;
|
||||
|
||||
void set_next_hash ();
|
||||
void notify_observers (std::vector<nano::block_w_sideband> const &);
|
||||
void notify_observers (std::vector<std::shared_ptr<nano::block>> const &);
|
||||
void notify_observers (nano::block_hash const &);
|
||||
|
||||
friend std::unique_ptr<container_info_component> collect_container_info (confirmation_height_processor &, const std::string &);
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
#include <numeric>
|
||||
|
||||
nano::confirmation_height_unbounded::confirmation_height_unbounded (nano::ledger & ledger_a, nano::write_database_queue & write_database_queue_a, std::chrono::milliseconds batch_separate_pending_min_time_a, nano::logger_mt & logger_a, std::atomic<bool> & stopped_a, nano::block_hash const & original_hash_a, std::function<void(std::vector<nano::block_w_sideband> const &)> const & notify_observers_callback_a, std::function<void(nano::block_hash const &)> const & notify_block_already_cemented_observers_callback_a, std::function<uint64_t ()> const & awaiting_processing_size_callback_a) :
|
||||
nano::confirmation_height_unbounded::confirmation_height_unbounded (nano::ledger & ledger_a, nano::write_database_queue & write_database_queue_a, std::chrono::milliseconds batch_separate_pending_min_time_a, nano::logger_mt & logger_a, std::atomic<bool> & stopped_a, nano::block_hash const & original_hash_a, std::function<void(std::vector<std::shared_ptr<nano::block>> const &)> const & notify_observers_callback_a, std::function<void(nano::block_hash const &)> const & notify_block_already_cemented_observers_callback_a, std::function<uint64_t ()> const & awaiting_processing_size_callback_a) :
|
||||
ledger (ledger_a),
|
||||
write_database_queue (write_database_queue_a),
|
||||
batch_separate_pending_min_time (batch_separate_pending_min_time_a),
|
||||
|
@ -49,16 +49,14 @@ void nano::confirmation_height_unbounded::process ()
|
|||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<nano::block> block;
|
||||
nano::block_sideband sideband;
|
||||
get_block_and_sideband (current, read_transaction, block, sideband);
|
||||
auto block (get_block_and_sideband (current, read_transaction));
|
||||
nano::account account (block->account ());
|
||||
if (account.is_zero ())
|
||||
{
|
||||
account = sideband.account;
|
||||
account = block->sideband ().account;
|
||||
}
|
||||
|
||||
auto block_height = sideband.height;
|
||||
auto block_height = block->sideband ().height;
|
||||
uint64_t confirmation_height = 0;
|
||||
auto account_it = confirmed_iterated_pairs.find (account);
|
||||
if (account_it != confirmed_iterated_pairs.cend ())
|
||||
|
@ -164,10 +162,7 @@ void nano::confirmation_height_unbounded::collect_unconfirmed_receive_and_source
|
|||
bool hit_receive = false;
|
||||
while ((num_to_confirm > 0) && !hash.is_zero () && !stopped)
|
||||
{
|
||||
std::shared_ptr<nano::block> block;
|
||||
nano::block_sideband sideband;
|
||||
get_block_and_sideband (hash, transaction_a, block, sideband);
|
||||
|
||||
auto block (get_block_and_sideband (hash, transaction_a));
|
||||
if (block)
|
||||
{
|
||||
auto source (block->source ());
|
||||
|
@ -330,11 +325,10 @@ bool nano::confirmation_height_unbounded::cement_blocks ()
|
|||
{
|
||||
#ifndef NDEBUG
|
||||
// Do more thorough checking in Debug mode, indicates programming error.
|
||||
nano::block_sideband sideband;
|
||||
auto block = ledger.store.block_get (transaction, pending.hash, &sideband);
|
||||
auto block = ledger.store.block_get (transaction, pending.hash);
|
||||
static nano::network_constants network_constants;
|
||||
debug_assert (network_constants.is_test_network () || block != nullptr);
|
||||
debug_assert (network_constants.is_test_network () || sideband.height == pending.height);
|
||||
debug_assert (network_constants.is_test_network () || block->sideband ().height == pending.height);
|
||||
|
||||
if (!block)
|
||||
{
|
||||
|
@ -355,7 +349,7 @@ bool nano::confirmation_height_unbounded::cement_blocks ()
|
|||
// Reverse it so that the callbacks start from the lowest newly cemented block and move upwards
|
||||
std::reverse (pending.block_callback_data.begin (), pending.block_callback_data.end ());
|
||||
|
||||
std::vector<nano::block_w_sideband> callback_data;
|
||||
std::vector<std::shared_ptr<nano::block>> callback_data;
|
||||
callback_data.reserve (pending.block_callback_data.size ());
|
||||
std::transform (pending.block_callback_data.begin (), pending.block_callback_data.end (), std::back_inserter (callback_data), [& block_cache = block_cache](auto const & hash_a) {
|
||||
debug_assert (block_cache.find (hash_a) != block_cache.end ());
|
||||
|
@ -373,19 +367,19 @@ bool nano::confirmation_height_unbounded::cement_blocks ()
|
|||
return false;
|
||||
}
|
||||
|
||||
void nano::confirmation_height_unbounded::get_block_and_sideband (nano::block_hash const & hash_a, nano::transaction const & transaction_a, std::shared_ptr<nano::block> & block_a, nano::block_sideband & sideband_a)
|
||||
std::shared_ptr<nano::block> nano::confirmation_height_unbounded::get_block_and_sideband (nano::block_hash const & hash_a, nano::transaction const & transaction_a)
|
||||
{
|
||||
auto block_cache_it = block_cache.find (hash_a);
|
||||
if (block_cache_it != block_cache.cend ())
|
||||
{
|
||||
block_a = block_cache_it->second.block;
|
||||
sideband_a = block_cache_it->second.sideband;
|
||||
return block_cache_it->second;
|
||||
}
|
||||
else
|
||||
{
|
||||
block_a = ledger.store.block_get (transaction_a, hash_a, &sideband_a);
|
||||
block_cache.emplace (std::piecewise_construct, std::forward_as_tuple (hash_a), std::forward_as_tuple (block_a, sideband_a));
|
||||
auto block (ledger.store.block_get (transaction_a, hash_a));
|
||||
block_cache.emplace (hash_a, block);
|
||||
++block_cache_size;
|
||||
return block;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ class write_database_queue;
|
|||
class confirmation_height_unbounded final
|
||||
{
|
||||
public:
|
||||
confirmation_height_unbounded (nano::ledger &, nano::write_database_queue &, std::chrono::milliseconds, nano::logger_mt &, std::atomic<bool> &, nano::block_hash const &, std::function<void(std::vector<nano::block_w_sideband> const &)> const &, std::function<void(nano::block_hash const &)> const &, std::function<uint64_t ()> const &);
|
||||
confirmation_height_unbounded (nano::ledger &, nano::write_database_queue &, std::chrono::milliseconds, nano::logger_mt &, std::atomic<bool> &, nano::block_hash const &, std::function<void(std::vector<std::shared_ptr<nano::block>> const &)> const &, std::function<void(nano::block_hash const &)> const &, std::function<uint64_t ()> const &);
|
||||
bool pending_empty () const;
|
||||
void prepare_new ();
|
||||
void process ();
|
||||
|
@ -55,9 +55,9 @@ private:
|
|||
|
||||
std::unordered_map<account, confirmed_iterated_pair> confirmed_iterated_pairs;
|
||||
std::atomic<uint64_t> confirmed_iterated_pairs_size{ 0 };
|
||||
std::unordered_map<nano::block_hash, block_w_sideband> block_cache;
|
||||
std::unordered_map<nano::block_hash, std::shared_ptr<nano::block>> block_cache;
|
||||
std::atomic<uint64_t> block_cache_size{ 0 };
|
||||
void get_block_and_sideband (nano::block_hash const &, nano::transaction const &, std::shared_ptr<nano::block> &, nano::block_sideband &);
|
||||
std::shared_ptr<nano::block> get_block_and_sideband (nano::block_hash const &, nano::transaction const &);
|
||||
std::deque<conf_height_details> pending_writes;
|
||||
std::atomic<uint64_t> pending_writes_size{ 0 };
|
||||
std::vector<nano::block_hash> orig_block_callback_data;
|
||||
|
@ -90,7 +90,7 @@ private:
|
|||
nano::logger_mt & logger;
|
||||
std::atomic<bool> & stopped;
|
||||
nano::block_hash const & original_hash;
|
||||
std::function<void(std::vector<nano::block_w_sideband> const &)> notify_observers_callback;
|
||||
std::function<void(std::vector<std::shared_ptr<nano::block>> const &)> notify_observers_callback;
|
||||
std::function<void(nano::block_hash const &)> notify_block_already_cemented_observers_callback;
|
||||
std::function<uint64_t ()> awaiting_processing_size_callback;
|
||||
|
||||
|
|
|
@ -970,19 +970,18 @@ void nano::json_handler::block_info ()
|
|||
auto hash (hash_impl ());
|
||||
if (!ec)
|
||||
{
|
||||
nano::block_sideband sideband;
|
||||
auto transaction (node.store.tx_begin_read ());
|
||||
auto block (node.store.block_get (transaction, hash, &sideband));
|
||||
auto block (node.store.block_get (transaction, hash));
|
||||
if (block != nullptr)
|
||||
{
|
||||
nano::account account (block->account ().is_zero () ? sideband.account : block->account ());
|
||||
nano::account account (block->account ().is_zero () ? block->sideband ().account : block->account ());
|
||||
response_l.put ("block_account", account.to_account ());
|
||||
auto amount (node.ledger.amount (transaction, hash));
|
||||
response_l.put ("amount", amount.convert_to<std::string> ());
|
||||
auto balance (node.ledger.balance (transaction, hash));
|
||||
response_l.put ("balance", balance.convert_to<std::string> ());
|
||||
response_l.put ("height", std::to_string (sideband.height));
|
||||
response_l.put ("local_timestamp", std::to_string (sideband.timestamp));
|
||||
response_l.put ("height", std::to_string (block->sideband ().height));
|
||||
response_l.put ("local_timestamp", std::to_string (block->sideband ().timestamp));
|
||||
auto confirmed (node.ledger.block_confirmed (transaction, hash));
|
||||
response_l.put ("confirmed", confirmed);
|
||||
|
||||
|
@ -1121,19 +1120,18 @@ void nano::json_handler::blocks_info ()
|
|||
nano::block_hash hash;
|
||||
if (!hash.decode_hex (hash_text))
|
||||
{
|
||||
nano::block_sideband sideband;
|
||||
auto block (node.store.block_get (transaction, hash, &sideband));
|
||||
auto block (node.store.block_get (transaction, hash));
|
||||
if (block != nullptr)
|
||||
{
|
||||
boost::property_tree::ptree entry;
|
||||
nano::account account (block->account ().is_zero () ? sideband.account : block->account ());
|
||||
nano::account account (block->account ().is_zero () ? block->sideband ().account : block->account ());
|
||||
entry.put ("block_account", account.to_account ());
|
||||
auto amount (node.ledger.amount (transaction, hash));
|
||||
entry.put ("amount", amount.convert_to<std::string> ());
|
||||
auto balance (node.ledger.balance (transaction, hash));
|
||||
entry.put ("balance", balance.convert_to<std::string> ());
|
||||
entry.put ("height", std::to_string (sideband.height));
|
||||
entry.put ("local_timestamp", std::to_string (sideband.timestamp));
|
||||
entry.put ("height", std::to_string (block->sideband ().height));
|
||||
entry.put ("local_timestamp", std::to_string (block->sideband ().timestamp));
|
||||
auto confirmed (node.ledger.block_confirmed (transaction, hash));
|
||||
entry.put ("confirmed", confirmed);
|
||||
|
||||
|
@ -2557,8 +2555,7 @@ void nano::json_handler::account_history ()
|
|||
boost::property_tree::ptree history;
|
||||
bool output_raw (request.get_optional<bool> ("raw") == true);
|
||||
response_l.put ("account", account.to_account ());
|
||||
nano::block_sideband sideband;
|
||||
auto block (node.store.block_get (transaction, hash, &sideband));
|
||||
auto block (node.store.block_get (transaction, hash));
|
||||
while (block != nullptr && count > 0)
|
||||
{
|
||||
if (offset > 0)
|
||||
|
@ -2572,8 +2569,8 @@ void nano::json_handler::account_history ()
|
|||
block->visit (visitor);
|
||||
if (!entry.empty ())
|
||||
{
|
||||
entry.put ("local_timestamp", std::to_string (sideband.timestamp));
|
||||
entry.put ("height", std::to_string (sideband.height));
|
||||
entry.put ("local_timestamp", std::to_string (block->sideband ().timestamp));
|
||||
entry.put ("height", std::to_string (block->sideband ().height));
|
||||
entry.put ("hash", hash.to_string ());
|
||||
if (output_raw)
|
||||
{
|
||||
|
@ -2585,7 +2582,7 @@ void nano::json_handler::account_history ()
|
|||
}
|
||||
}
|
||||
hash = reverse ? node.store.block_successor (transaction, hash) : block->previous ();
|
||||
block = node.store.block_get (transaction, hash, &sideband);
|
||||
block = node.store.block_get (transaction, hash);
|
||||
}
|
||||
response_l.add_child ("history", history);
|
||||
if (!hash.is_zero ())
|
||||
|
@ -4589,9 +4586,8 @@ void nano::json_handler::wallet_history ()
|
|||
auto hash (info.head);
|
||||
while (timestamp >= modified_since && !hash.is_zero ())
|
||||
{
|
||||
nano::block_sideband sideband;
|
||||
auto block (node.store.block_get (block_transaction, hash, &sideband));
|
||||
timestamp = sideband.timestamp;
|
||||
auto block (node.store.block_get (block_transaction, hash));
|
||||
timestamp = block->sideband ().timestamp;
|
||||
if (block != nullptr && timestamp >= modified_since)
|
||||
{
|
||||
boost::property_tree::ptree entry;
|
||||
|
|
|
@ -507,7 +507,7 @@ void nano::mdb_store::upgrade_v12_to_v13 (nano::write_transaction & transaction_
|
|||
}
|
||||
|
||||
nano::mdb_val value{ vector.size (), (void *)vector.data () };
|
||||
MDB_dbi database = is_state_block_v1 ? state_blocks_v1 : table_to_dbi (block_database (sideband.type));
|
||||
MDB_dbi database = is_state_block_v1 ? state_blocks_v1 : table_to_dbi (block_database (block->type ()));
|
||||
|
||||
auto status = mdb_put (env.tx (transaction_a), database, nano::mdb_val (hash), value, 0);
|
||||
release_assert (success (status));
|
||||
|
@ -628,14 +628,14 @@ 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.type, 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 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;
|
||||
{
|
||||
nano::vectorstream stream (data);
|
||||
state_block_w_sideband_v14.state_block->serialize (stream);
|
||||
sideband.serialize (stream);
|
||||
sideband.serialize (stream, sideband_v14.type);
|
||||
}
|
||||
|
||||
nano::mdb_val value{ data.size (), (void *)data.data () };
|
||||
|
@ -732,27 +732,25 @@ void nano::mdb_store::upgrade_v16_to_v17 (nano::write_transaction const & transa
|
|||
if (account_info_i->second.block_count / 2 >= confirmation_height)
|
||||
{
|
||||
// The confirmation height of the account is closer to the bottom of the chain, so start there and work up
|
||||
nano::block_sideband sideband;
|
||||
auto block = block_get (transaction_a, account_info.open_block, &sideband);
|
||||
auto block = block_get (transaction_a, account_info.open_block);
|
||||
debug_assert (block);
|
||||
auto height = 1;
|
||||
|
||||
while (height != confirmation_height)
|
||||
{
|
||||
block = block_get (transaction_a, sideband.successor, &sideband);
|
||||
block = block_get (transaction_a, block->sideband ().successor);
|
||||
debug_assert (block);
|
||||
++height;
|
||||
}
|
||||
|
||||
debug_assert (sideband.height == confirmation_height);
|
||||
debug_assert (block->sideband ().height == confirmation_height);
|
||||
confirmation_height_infos.emplace_back (account, confirmation_height_info{ confirmation_height, block->hash () });
|
||||
}
|
||||
else
|
||||
{
|
||||
// The confirmation height of the account is closer to the top of the chain so start there and work down
|
||||
nano::block_sideband sideband;
|
||||
auto block = block_get (transaction_a, account_info.head, &sideband);
|
||||
auto height = sideband.height;
|
||||
auto block = block_get (transaction_a, account_info.head);
|
||||
auto height = block->sideband ().height;
|
||||
while (height != confirmation_height)
|
||||
{
|
||||
block = block_get (transaction_a, block->previous ());
|
||||
|
@ -820,13 +818,13 @@ void nano::mdb_store::upgrade_v17_to_v18 (nano::write_transaction const & transa
|
|||
is_receive = true;
|
||||
}
|
||||
|
||||
nano::block_sideband new_sideband (sideband.type, sideband.account, sideband.successor, sideband.balance, sideband.height, sideband.timestamp, sideband.details.epoch, is_send, is_receive, is_epoch);
|
||||
nano::block_sideband 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;
|
||||
{
|
||||
nano::vectorstream stream (data);
|
||||
block->serialize (stream);
|
||||
new_sideband.serialize (stream);
|
||||
new_sideband.serialize (stream, block->type ());
|
||||
}
|
||||
nano::mdb_val value{ data.size (), (void *)data.data () };
|
||||
auto s = mdb_cursor_put (state_i.cursor, state_i->first, value, MDB_CURRENT);
|
||||
|
|
|
@ -616,7 +616,7 @@ void nano::node::process_active (std::shared_ptr<nano::block> incoming)
|
|||
block_processor.add (incoming, nano::seconds_since_epoch ());
|
||||
}
|
||||
|
||||
nano::process_return nano::node::process (nano::block const & block_a)
|
||||
nano::process_return nano::node::process (nano::block & block_a)
|
||||
{
|
||||
auto transaction (store.tx_begin_write ({ tables::accounts, tables::cached_counts, tables::change_blocks, tables::frontiers, tables::open_blocks, tables::pending, tables::receive_blocks, tables::representation, tables::send_blocks, tables::state_blocks }, { tables::confirmation_height }));
|
||||
auto result (ledger.process (transaction, block_a));
|
||||
|
@ -1225,18 +1225,18 @@ void nano::node::receive_confirmed (nano::transaction const & transaction_a, std
|
|||
block_a->visit (visitor);
|
||||
}
|
||||
|
||||
void nano::node::process_confirmed_data (nano::transaction const & transaction_a, std::shared_ptr<nano::block> block_a, nano::block_hash const & hash_a, nano::block_sideband const & sideband_a, nano::account & account_a, nano::uint128_t & amount_a, bool & is_state_send_a, nano::account & pending_account_a)
|
||||
void nano::node::process_confirmed_data (nano::transaction const & transaction_a, std::shared_ptr<nano::block> block_a, nano::block_hash const & hash_a, nano::account & account_a, nano::uint128_t & amount_a, bool & is_state_send_a, nano::account & pending_account_a)
|
||||
{
|
||||
// Faster account calculation
|
||||
account_a = block_a->account ();
|
||||
if (account_a.is_zero ())
|
||||
{
|
||||
account_a = sideband_a.account;
|
||||
account_a = block_a->sideband ().account;
|
||||
}
|
||||
// Faster amount calculation
|
||||
auto previous (block_a->previous ());
|
||||
auto previous_balance (ledger.balance (transaction_a, previous));
|
||||
auto block_balance (store.block_balance_calculated (block_a, sideband_a));
|
||||
auto block_balance (store.block_balance_calculated (block_a));
|
||||
if (hash_a != ledger.network_params.ledger.genesis_account)
|
||||
{
|
||||
amount_a = block_balance > previous_balance ? block_balance - previous_balance : previous_balance - block_balance;
|
||||
|
|
|
@ -103,10 +103,10 @@ public:
|
|||
std::shared_ptr<nano::node> shared ();
|
||||
int store_version ();
|
||||
void receive_confirmed (nano::transaction const &, std::shared_ptr<nano::block>, nano::block_hash const &);
|
||||
void process_confirmed_data (nano::transaction const &, std::shared_ptr<nano::block>, nano::block_hash const &, nano::block_sideband const &, nano::account &, nano::uint128_t &, bool &, nano::account &);
|
||||
void process_confirmed_data (nano::transaction const &, std::shared_ptr<nano::block>, nano::block_hash const &, nano::account &, nano::uint128_t &, bool &, nano::account &);
|
||||
void process_confirmed (nano::election_status const &, std::shared_ptr<nano::election> const &, uint8_t = 0);
|
||||
void process_active (std::shared_ptr<nano::block>);
|
||||
nano::process_return process (nano::block const &);
|
||||
nano::process_return process (nano::block &);
|
||||
nano::process_return process_local (std::shared_ptr<nano::block>, bool const = false);
|
||||
void keepalive_preconfigured (std::vector<std::string> const &);
|
||||
nano::block_hash latest (nano::account const &);
|
||||
|
|
|
@ -41,8 +41,6 @@ add_library (secure
|
|||
buffer.hpp
|
||||
common.hpp
|
||||
common.cpp
|
||||
epoch.hpp
|
||||
epoch.cpp
|
||||
ledger.hpp
|
||||
ledger.cpp
|
||||
network_filter.hpp
|
||||
|
|
|
@ -1,162 +1,6 @@
|
|||
#include <nano/lib/threading.hpp>
|
||||
#include <nano/secure/blockstore.hpp>
|
||||
|
||||
#include <boost/endian/conversion.hpp>
|
||||
|
||||
#include <bitset>
|
||||
|
||||
nano::block_details::block_details (nano::epoch const epoch_a, bool const is_send_a, bool const is_receive_a, bool const is_epoch_a) :
|
||||
epoch (epoch_a), is_send (is_send_a), is_receive (is_receive_a), is_epoch (is_epoch_a)
|
||||
{
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
uint8_t nano::block_details::packed () const
|
||||
{
|
||||
std::bitset<8> result (static_cast<uint8_t> (epoch));
|
||||
result.set (7, is_send);
|
||||
result.set (6, is_receive);
|
||||
result.set (5, is_epoch);
|
||||
return static_cast<uint8_t> (result.to_ulong ());
|
||||
}
|
||||
|
||||
void nano::block_details::unpack (uint8_t details_a)
|
||||
{
|
||||
constexpr std::bitset<8> epoch_mask{ 0b00011111 };
|
||||
auto as_bitset = static_cast<std::bitset<8>> (details_a);
|
||||
is_send = as_bitset.test (7);
|
||||
is_receive = as_bitset.test (6);
|
||||
is_epoch = as_bitset.test (5);
|
||||
epoch = static_cast<nano::epoch> ((as_bitset & epoch_mask).to_ulong ());
|
||||
}
|
||||
|
||||
void nano::block_details::serialize (nano::stream & stream_a) const
|
||||
{
|
||||
nano::write (stream_a, packed ());
|
||||
}
|
||||
|
||||
bool nano::block_details::deserialize (nano::stream & stream_a)
|
||||
{
|
||||
bool result (false);
|
||||
try
|
||||
{
|
||||
uint8_t packed{ 0 };
|
||||
nano::read (stream_a, packed);
|
||||
unpack (packed);
|
||||
}
|
||||
catch (std::runtime_error &)
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
nano::block_sideband::block_sideband (nano::block_type type_a, 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) :
|
||||
type (type_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)
|
||||
{
|
||||
}
|
||||
|
||||
size_t nano::block_sideband::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 is larger than the epoch enum");
|
||||
result += nano::block_details::size ();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void nano::block_sideband::serialize (nano::stream & stream_a) const
|
||||
{
|
||||
nano::write (stream_a, successor.bytes);
|
||||
if (type != nano::block_type::state && type != nano::block_type::open)
|
||||
{
|
||||
nano::write (stream_a, account.bytes);
|
||||
}
|
||||
if (type != nano::block_type::open)
|
||||
{
|
||||
nano::write (stream_a, boost::endian::native_to_big (height));
|
||||
}
|
||||
if (type == nano::block_type::receive || type == nano::block_type::change || type == nano::block_type::open)
|
||||
{
|
||||
nano::write (stream_a, balance.bytes);
|
||||
}
|
||||
nano::write (stream_a, boost::endian::native_to_big (timestamp));
|
||||
if (type == nano::block_type::state)
|
||||
{
|
||||
details.serialize (stream_a);
|
||||
}
|
||||
}
|
||||
|
||||
bool nano::block_sideband::deserialize (nano::stream & stream_a)
|
||||
{
|
||||
bool result (false);
|
||||
try
|
||||
{
|
||||
nano::read (stream_a, successor.bytes);
|
||||
if (type != nano::block_type::state && type != nano::block_type::open)
|
||||
{
|
||||
nano::read (stream_a, account.bytes);
|
||||
}
|
||||
if (type != nano::block_type::open)
|
||||
{
|
||||
nano::read (stream_a, height);
|
||||
boost::endian::big_to_native_inplace (height);
|
||||
}
|
||||
else
|
||||
{
|
||||
height = 1;
|
||||
}
|
||||
if (type == nano::block_type::receive || type == nano::block_type::change || type == nano::block_type::open)
|
||||
{
|
||||
nano::read (stream_a, balance.bytes);
|
||||
}
|
||||
nano::read (stream_a, timestamp);
|
||||
boost::endian::big_to_native_inplace (timestamp);
|
||||
if (type == nano::block_type::state)
|
||||
{
|
||||
result = details.deserialize (stream_a);
|
||||
}
|
||||
}
|
||||
catch (std::runtime_error &)
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
nano::summation_visitor::summation_visitor (nano::transaction const & transaction_a, nano::block_store const & store_a, bool is_v14_upgrade_a) :
|
||||
transaction (transaction_a),
|
||||
store (store_a),
|
||||
|
@ -397,7 +241,7 @@ nano::uint128_t nano::summation_visitor::compute_balance (nano::block_hash const
|
|||
|
||||
std::shared_ptr<nano::block> nano::summation_visitor::block_get (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const
|
||||
{
|
||||
return is_v14_upgrade ? store.block_get_v14 (transaction, hash_a) : store.block_get (transaction, hash_a);
|
||||
return is_v14_upgrade ? store.block_get_v14 (transaction, hash_a) : store.block_get_no_sideband (transaction, hash_a);
|
||||
}
|
||||
|
||||
nano::representative_visitor::representative_visitor (nano::transaction const & transaction_a, nano::block_store & store_a) :
|
||||
|
|
|
@ -16,45 +16,6 @@
|
|||
|
||||
namespace nano
|
||||
{
|
||||
class block_details
|
||||
{
|
||||
static_assert (std::is_same<std::underlying_type<nano::epoch>::type, uint8_t> (), "Epoch enum is not the proper type");
|
||||
static_assert (static_cast<uint8_t> (nano::epoch::max) < (1 << 5), "Epoch max is too large for the sideband");
|
||||
|
||||
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 ();
|
||||
bool operator== (block_details const & other_a) const;
|
||||
void serialize (nano::stream &) const;
|
||||
bool deserialize (nano::stream &);
|
||||
nano::epoch epoch{ nano::epoch::epoch_0 };
|
||||
bool is_send{ false };
|
||||
bool is_receive{ false };
|
||||
bool is_epoch{ false };
|
||||
|
||||
private:
|
||||
uint8_t packed () const;
|
||||
void unpack (uint8_t);
|
||||
};
|
||||
|
||||
class block_sideband final
|
||||
{
|
||||
public:
|
||||
block_sideband () = default;
|
||||
block_sideband (nano::block_type, 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 &) const;
|
||||
bool deserialize (nano::stream &);
|
||||
static size_t size (nano::block_type);
|
||||
nano::block_type type{ nano::block_type::invalid };
|
||||
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;
|
||||
};
|
||||
|
||||
// Move to versioning with a specific version if required for a future upgrade
|
||||
class state_block_w_sideband
|
||||
{
|
||||
|
@ -311,14 +272,25 @@ public:
|
|||
return result;
|
||||
}
|
||||
|
||||
private:
|
||||
// Common usage for versioning
|
||||
template <typename T, typename = std::enable_if<std::is_same<T, state_block_w_sideband>::value || std::is_same<T, state_block_w_sideband_v14>::value>>
|
||||
T as () const
|
||||
explicit operator state_block_w_sideband () const
|
||||
{
|
||||
nano::bufferstream stream (reinterpret_cast<uint8_t const *> (data ()), size ());
|
||||
auto error (false);
|
||||
T block_w_sideband;
|
||||
nano::state_block_w_sideband block_w_sideband;
|
||||
block_w_sideband.state_block = std::make_shared<nano::state_block> (error, stream);
|
||||
debug_assert (!error);
|
||||
|
||||
error = block_w_sideband.sideband.deserialize (stream, nano::block_type::state);
|
||||
debug_assert (!error);
|
||||
|
||||
return block_w_sideband;
|
||||
}
|
||||
|
||||
explicit operator state_block_w_sideband_v14 () const
|
||||
{
|
||||
nano::bufferstream stream (reinterpret_cast<uint8_t const *> (data ()), size ());
|
||||
auto error (false);
|
||||
nano::state_block_w_sideband_v14 block_w_sideband;
|
||||
block_w_sideband.state_block = std::make_shared<nano::state_block> (error, stream);
|
||||
debug_assert (!error);
|
||||
|
||||
|
@ -329,17 +301,6 @@ private:
|
|||
return block_w_sideband;
|
||||
}
|
||||
|
||||
public:
|
||||
explicit operator state_block_w_sideband () const
|
||||
{
|
||||
return as<state_block_w_sideband> ();
|
||||
}
|
||||
|
||||
explicit operator state_block_w_sideband_v14 () const
|
||||
{
|
||||
return as<state_block_w_sideband_v14> ();
|
||||
}
|
||||
|
||||
explicit operator nano::no_value () const
|
||||
{
|
||||
return no_value::dummy;
|
||||
|
@ -441,19 +402,6 @@ private:
|
|||
class transaction;
|
||||
class block_store;
|
||||
|
||||
class block_w_sideband final
|
||||
{
|
||||
public:
|
||||
block_w_sideband (std::shared_ptr<nano::block> const & block_a, nano::block_sideband const & sideband_a) :
|
||||
block (block_a),
|
||||
sideband (sideband_a)
|
||||
{
|
||||
}
|
||||
|
||||
std::shared_ptr<nano::block> block;
|
||||
nano::block_sideband sideband;
|
||||
};
|
||||
|
||||
/**
|
||||
* Summation visitor for blocks, supporting amount and balance computations. These
|
||||
* computations are mutually dependant. The natural solution is to use mutual recursion
|
||||
|
@ -714,10 +662,11 @@ class block_store
|
|||
public:
|
||||
virtual ~block_store () = default;
|
||||
virtual void initialize (nano::write_transaction const &, nano::genesis const &, nano::ledger_cache &) = 0;
|
||||
virtual void block_put (nano::write_transaction const &, nano::block_hash const &, nano::block const &, nano::block_sideband const &) = 0;
|
||||
virtual void block_put (nano::write_transaction const &, nano::block_hash const &, nano::block const &) = 0;
|
||||
virtual nano::block_hash block_successor (nano::transaction const &, nano::block_hash const &) const = 0;
|
||||
virtual void block_successor_clear (nano::write_transaction const &, nano::block_hash const &) = 0;
|
||||
virtual std::shared_ptr<nano::block> block_get (nano::transaction const &, nano::block_hash const &, nano::block_sideband * = nullptr) const = 0;
|
||||
virtual std::shared_ptr<nano::block> block_get (nano::transaction const &, nano::block_hash const &) const = 0;
|
||||
virtual std::shared_ptr<nano::block> block_get_no_sideband (nano::transaction const &, nano::block_hash const &) const = 0;
|
||||
virtual std::shared_ptr<nano::block> block_get_v14 (nano::transaction const &, nano::block_hash const &, nano::block_sideband_v14 * = nullptr, bool * = nullptr) const = 0;
|
||||
virtual std::shared_ptr<nano::block> block_random (nano::transaction const &) = 0;
|
||||
virtual void block_del (nano::write_transaction const &, nano::block_hash const &, nano::block_type) = 0;
|
||||
|
@ -753,7 +702,7 @@ public:
|
|||
|
||||
virtual bool block_info_get (nano::transaction const &, nano::block_hash const &, nano::block_info &) const = 0;
|
||||
virtual nano::uint128_t block_balance (nano::transaction const &, nano::block_hash const &) = 0;
|
||||
virtual nano::uint128_t block_balance_calculated (std::shared_ptr<nano::block>, nano::block_sideband const &) const = 0;
|
||||
virtual nano::uint128_t block_balance_calculated (std::shared_ptr<nano::block> const &) const = 0;
|
||||
virtual nano::epoch block_version (nano::transaction const &, nano::block_hash const &) = 0;
|
||||
|
||||
virtual void unchecked_clear (nano::write_transaction const &) = 0;
|
||||
|
|
|
@ -31,8 +31,8 @@ public:
|
|||
{
|
||||
auto hash_l (genesis_a.hash ());
|
||||
debug_assert (latest_begin (transaction_a) == latest_end ());
|
||||
nano::block_sideband sideband (nano::block_type::open, network_params.ledger.genesis_account, 0, network_params.ledger.genesis_amount, 1, nano::seconds_since_epoch (), nano::epoch::epoch_0, false, false, false);
|
||||
block_put (transaction_a, hash_l, *genesis_a.open, sideband);
|
||||
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));
|
||||
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 () });
|
||||
++ledger_cache_a.cemented_count;
|
||||
|
@ -44,9 +44,8 @@ public:
|
|||
|
||||
nano::uint128_t block_balance (nano::transaction const & transaction_a, nano::block_hash const & hash_a) override
|
||||
{
|
||||
nano::block_sideband sideband;
|
||||
auto block (block_get (transaction_a, hash_a, &sideband));
|
||||
nano::uint128_t result (block_balance_calculated (block, sideband));
|
||||
auto block (block_get (transaction_a, hash_a));
|
||||
nano::uint128_t result (block_balance_calculated (block));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -97,15 +96,14 @@ public:
|
|||
return result;
|
||||
}
|
||||
|
||||
void block_put (nano::write_transaction const & transaction_a, nano::block_hash const & hash_a, nano::block const & block_a, nano::block_sideband const & sideband_a) override
|
||||
void block_put (nano::write_transaction const & transaction_a, nano::block_hash const & hash_a, nano::block const & block_a) override
|
||||
{
|
||||
debug_assert (block_a.type () == sideband_a.type);
|
||||
debug_assert (sideband_a.successor.is_zero () || block_exists (transaction_a, sideband_a.successor));
|
||||
debug_assert (block_a.sideband ().successor.is_zero () || block_exists (transaction_a, block_a.sideband ().successor));
|
||||
std::vector<uint8_t> vector;
|
||||
{
|
||||
nano::vectorstream stream (vector);
|
||||
block_a.serialize (stream);
|
||||
sideband_a.serialize (stream);
|
||||
block_a.sideband ().serialize (stream, block_a.type ());
|
||||
}
|
||||
block_raw_put (transaction_a, vector, block_a.type (), hash_a);
|
||||
nano::block_predecessor_set<Val, Derived_Store> predecessor (transaction_a, *this);
|
||||
|
@ -116,13 +114,12 @@ public:
|
|||
// Converts a block hash to a block height
|
||||
uint64_t block_account_height (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const override
|
||||
{
|
||||
nano::block_sideband sideband;
|
||||
auto block = block_get (transaction_a, hash_a, &sideband);
|
||||
auto block = block_get (transaction_a, hash_a);
|
||||
debug_assert (block != nullptr);
|
||||
return sideband.height;
|
||||
return block->sideband ().height;
|
||||
}
|
||||
|
||||
std::shared_ptr<nano::block> block_get (nano::transaction const & transaction_a, nano::block_hash const & hash_a, nano::block_sideband * sideband_a = nullptr) const override
|
||||
std::shared_ptr<nano::block> block_get (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const override
|
||||
{
|
||||
nano::block_type type;
|
||||
auto value (block_raw_get (transaction_a, hash_a, type));
|
||||
|
@ -132,25 +129,37 @@ public:
|
|||
nano::bufferstream stream (reinterpret_cast<uint8_t const *> (value.data ()), value.size ());
|
||||
result = nano::deserialize_block (stream, type);
|
||||
debug_assert (result != nullptr);
|
||||
if (sideband_a)
|
||||
nano::block_sideband sideband;
|
||||
if (full_sideband (transaction_a) || entry_has_sideband (value.size (), type))
|
||||
{
|
||||
sideband_a->type = type;
|
||||
if (full_sideband (transaction_a) || entry_has_sideband (value.size (), type))
|
||||
{
|
||||
auto error (sideband_a->deserialize (stream));
|
||||
(void)error;
|
||||
debug_assert (!error);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Reconstruct sideband data for block.
|
||||
sideband_a->account = block_account_computed (transaction_a, hash_a);
|
||||
sideband_a->balance = block_balance_computed (transaction_a, hash_a);
|
||||
sideband_a->successor = block_successor (transaction_a, hash_a);
|
||||
sideband_a->height = 0;
|
||||
sideband_a->timestamp = 0;
|
||||
}
|
||||
auto error (sideband.deserialize (stream, type));
|
||||
(void)error;
|
||||
debug_assert (!error);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Reconstruct sideband data for block.
|
||||
sideband.account = block_account_computed (transaction_a, hash_a);
|
||||
sideband.balance = block_balance_computed (transaction_a, hash_a);
|
||||
sideband.successor = block_successor (transaction_a, hash_a);
|
||||
sideband.height = 0;
|
||||
sideband.timestamp = 0;
|
||||
}
|
||||
result->sideband_set (sideband);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::shared_ptr<nano::block> block_get_no_sideband (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const override
|
||||
{
|
||||
nano::block_type type;
|
||||
auto value (block_raw_get (transaction_a, hash_a, type));
|
||||
std::shared_ptr<nano::block> result;
|
||||
if (value.size () != 0)
|
||||
{
|
||||
nano::bufferstream stream (reinterpret_cast<uint8_t const *> (value.data ()), value.size ());
|
||||
result = nano::deserialize_block (stream, type);
|
||||
debug_assert (result != nullptr);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -186,18 +195,17 @@ public:
|
|||
|
||||
nano::account block_account (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const override
|
||||
{
|
||||
nano::block_sideband sideband;
|
||||
auto block (block_get (transaction_a, hash_a, &sideband));
|
||||
auto block (block_get (transaction_a, hash_a));
|
||||
nano::account result (block->account ());
|
||||
if (result.is_zero ())
|
||||
{
|
||||
result = sideband.account;
|
||||
result = block->sideband ().account;
|
||||
}
|
||||
debug_assert (!result.is_zero ());
|
||||
return result;
|
||||
}
|
||||
|
||||
nano::uint128_t block_balance_calculated (std::shared_ptr<nano::block> block_a, nano::block_sideband const & sideband_a) const override
|
||||
nano::uint128_t block_balance_calculated (std::shared_ptr<nano::block> const & block_a) const override
|
||||
{
|
||||
nano::uint128_t result;
|
||||
switch (block_a->type ())
|
||||
|
@ -205,7 +213,7 @@ public:
|
|||
case nano::block_type::open:
|
||||
case nano::block_type::receive:
|
||||
case nano::block_type::change:
|
||||
result = sideband_a.balance.number ();
|
||||
result = block_a->sideband ().balance.number ();
|
||||
break;
|
||||
case nano::block_type::send:
|
||||
result = boost::polymorphic_downcast<nano::send_block *> (block_a.get ())->hashables.balance.number ();
|
||||
|
@ -407,11 +415,10 @@ public:
|
|||
nano::epoch block_version (nano::transaction const & transaction_a, nano::block_hash const & hash_a) override
|
||||
{
|
||||
nano::db_val<Val> value;
|
||||
nano::block_sideband sideband;
|
||||
auto block = block_get (transaction_a, hash_a, &sideband);
|
||||
if (sideband.type == nano::block_type::state)
|
||||
auto block = block_get (transaction_a, hash_a);
|
||||
if (block && block->type () == nano::block_type::state)
|
||||
{
|
||||
return sideband.details.epoch;
|
||||
return block->sideband ().details.epoch;
|
||||
}
|
||||
|
||||
return nano::epoch::epoch_0;
|
||||
|
@ -842,7 +849,7 @@ protected:
|
|||
auto hash (hash_a);
|
||||
while (result.is_zero ())
|
||||
{
|
||||
auto block (block_get (transaction_a, hash));
|
||||
auto block (block_get_no_sideband (transaction_a, hash));
|
||||
debug_assert (block);
|
||||
result = block->account ();
|
||||
if (result.is_zero ())
|
||||
|
|
|
@ -4,10 +4,10 @@
|
|||
#include <nano/lib/blockbuilders.hpp>
|
||||
#include <nano/lib/blocks.hpp>
|
||||
#include <nano/lib/config.hpp>
|
||||
#include <nano/lib/epoch.hpp>
|
||||
#include <nano/lib/numbers.hpp>
|
||||
#include <nano/lib/rep_weights.hpp>
|
||||
#include <nano/lib/utility.hpp>
|
||||
#include <nano/secure/epoch.hpp>
|
||||
|
||||
#include <boost/iterator/transform_iterator.hpp>
|
||||
#include <boost/optional/optional.hpp>
|
||||
|
|
|
@ -172,18 +172,18 @@ public:
|
|||
bool error{ false };
|
||||
};
|
||||
|
||||
class ledger_processor : public nano::block_visitor
|
||||
class ledger_processor : public nano::mutable_block_visitor
|
||||
{
|
||||
public:
|
||||
ledger_processor (nano::ledger &, nano::write_transaction const &, nano::signature_verification = nano::signature_verification::unknown);
|
||||
virtual ~ledger_processor () = default;
|
||||
void send_block (nano::send_block const &) override;
|
||||
void receive_block (nano::receive_block const &) override;
|
||||
void open_block (nano::open_block const &) override;
|
||||
void change_block (nano::change_block const &) override;
|
||||
void state_block (nano::state_block const &) override;
|
||||
void state_block_impl (nano::state_block const &);
|
||||
void epoch_block_impl (nano::state_block const &);
|
||||
void send_block (nano::send_block &) override;
|
||||
void receive_block (nano::receive_block &) override;
|
||||
void open_block (nano::open_block &) override;
|
||||
void change_block (nano::change_block &) override;
|
||||
void state_block (nano::state_block &) override;
|
||||
void state_block_impl (nano::state_block &);
|
||||
void epoch_block_impl (nano::state_block &);
|
||||
nano::ledger & ledger;
|
||||
nano::write_transaction const & transaction;
|
||||
nano::signature_verification verification;
|
||||
|
@ -230,7 +230,7 @@ bool ledger_processor::validate_epoch_block (nano::state_block const & block_a)
|
|||
return (block_a.hashables.balance == prev_balance);
|
||||
}
|
||||
|
||||
void ledger_processor::state_block (nano::state_block const & block_a)
|
||||
void ledger_processor::state_block (nano::state_block & block_a)
|
||||
{
|
||||
result.code = nano::process_result::progress;
|
||||
auto is_epoch_block = false;
|
||||
|
@ -253,7 +253,7 @@ void ledger_processor::state_block (nano::state_block const & block_a)
|
|||
}
|
||||
}
|
||||
|
||||
void ledger_processor::state_block_impl (nano::state_block const & block_a)
|
||||
void ledger_processor::state_block_impl (nano::state_block & block_a)
|
||||
{
|
||||
auto hash (block_a.hash ());
|
||||
auto existing (ledger.store.block_exists (transaction, block_a.type (), hash));
|
||||
|
@ -334,9 +334,8 @@ void ledger_processor::state_block_impl (nano::state_block const & block_a)
|
|||
if (result.code == nano::process_result::progress)
|
||||
{
|
||||
ledger.stats.inc (nano::stat::type::ledger, nano::stat::detail::state_block);
|
||||
result.state_is_send = is_send;
|
||||
nano::block_sideband sideband (nano::block_type::state, block_a.hashables.account /* unused */, 0, 0 /* unused */, info.block_count + 1, nano::seconds_since_epoch (), epoch, is_send, is_receive, false);
|
||||
ledger.store.block_put (transaction, hash, block_a, sideband);
|
||||
block_a.sideband_set (nano::block_sideband (block_a.hashables.account /* unused */, 0, 0 /* unused */, info.block_count + 1, nano::seconds_since_epoch (), epoch, is_send, is_receive, false));
|
||||
ledger.store.block_put (transaction, hash, block_a);
|
||||
|
||||
if (!info.head.is_zero ())
|
||||
{
|
||||
|
@ -371,7 +370,7 @@ void ledger_processor::state_block_impl (nano::state_block const & block_a)
|
|||
}
|
||||
}
|
||||
|
||||
void ledger_processor::epoch_block_impl (nano::state_block const & block_a)
|
||||
void ledger_processor::epoch_block_impl (nano::state_block & block_a)
|
||||
{
|
||||
auto hash (block_a.hash ());
|
||||
auto existing (ledger.store.block_exists (transaction, block_a.type (), hash));
|
||||
|
@ -423,8 +422,8 @@ void ledger_processor::epoch_block_impl (nano::state_block const & block_a)
|
|||
ledger.stats.inc (nano::stat::type::ledger, nano::stat::detail::epoch_block);
|
||||
result.account = block_a.hashables.account;
|
||||
result.amount = 0;
|
||||
nano::block_sideband sideband (nano::block_type::state, block_a.hashables.account /* unused */, 0, 0 /* unused */, info.block_count + 1, nano::seconds_since_epoch (), epoch, false, false, true);
|
||||
ledger.store.block_put (transaction, hash, block_a, sideband);
|
||||
block_a.sideband_set (nano::block_sideband (block_a.hashables.account /* unused */, 0, 0 /* unused */, info.block_count + 1, nano::seconds_since_epoch (), epoch, false, false, true));
|
||||
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);
|
||||
if (!ledger.store.frontier_get (transaction, info.head).is_zero ())
|
||||
|
@ -439,7 +438,7 @@ void ledger_processor::epoch_block_impl (nano::state_block const & block_a)
|
|||
}
|
||||
}
|
||||
|
||||
void ledger_processor::change_block (nano::change_block const & block_a)
|
||||
void ledger_processor::change_block (nano::change_block & block_a)
|
||||
{
|
||||
auto hash (block_a.hash ());
|
||||
auto existing (ledger.store.block_exists (transaction, block_a.type (), hash));
|
||||
|
@ -471,8 +470,8 @@ void ledger_processor::change_block (nano::change_block const & block_a)
|
|||
{
|
||||
debug_assert (!validate_message (account, hash, block_a.signature));
|
||||
result.verified = nano::signature_verification::valid;
|
||||
nano::block_sideband sideband (nano::block_type::change, account, 0, info.balance, info.block_count + 1, nano::seconds_since_epoch (), nano::epoch::epoch_0, false, false, false);
|
||||
ledger.store.block_put (transaction, hash, block_a, sideband);
|
||||
block_a.sideband_set (nano::block_sideband (account, 0, info.balance, info.block_count + 1, nano::seconds_since_epoch (), nano::epoch::epoch_0, false /* unused */, false /* unused */, false /* 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);
|
||||
ledger.cache.rep_weights.representation_add (info.representative, 0 - balance);
|
||||
|
@ -490,7 +489,7 @@ void ledger_processor::change_block (nano::change_block const & block_a)
|
|||
}
|
||||
}
|
||||
|
||||
void ledger_processor::send_block (nano::send_block const & block_a)
|
||||
void ledger_processor::send_block (nano::send_block & block_a)
|
||||
{
|
||||
auto hash (block_a.hash ());
|
||||
auto existing (ledger.store.block_exists (transaction, block_a.type (), hash));
|
||||
|
@ -527,8 +526,8 @@ void ledger_processor::send_block (nano::send_block const & block_a)
|
|||
{
|
||||
auto amount (info.balance.number () - block_a.hashables.balance.number ());
|
||||
ledger.cache.rep_weights.representation_add (info.representative, 0 - amount);
|
||||
nano::block_sideband sideband (nano::block_type::send, account, 0, block_a.hashables.balance /* unused */, info.block_count + 1, nano::seconds_since_epoch (), nano::epoch::epoch_0, false /* unused */, false /* unused */, false /* unused */);
|
||||
ledger.store.block_put (transaction, hash, block_a, sideband);
|
||||
block_a.sideband_set (nano::block_sideband (account, 0, block_a.hashables.balance /* unused */, info.block_count + 1, nano::seconds_since_epoch (), nano::epoch::epoch_0, false /* unused */, false /* unused */, false /* 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);
|
||||
ledger.store.pending_put (transaction, nano::pending_key (block_a.hashables.destination, hash), { account, amount, nano::epoch::epoch_0 });
|
||||
|
@ -546,7 +545,7 @@ void ledger_processor::send_block (nano::send_block const & block_a)
|
|||
}
|
||||
}
|
||||
|
||||
void ledger_processor::receive_block (nano::receive_block const & block_a)
|
||||
void ledger_processor::receive_block (nano::receive_block & block_a)
|
||||
{
|
||||
auto hash (block_a.hash ());
|
||||
auto existing (ledger.store.block_exists (transaction, block_a.type (), hash));
|
||||
|
@ -595,8 +594,8 @@ void ledger_processor::receive_block (nano::receive_block const & block_a)
|
|||
(void)error;
|
||||
debug_assert (!error);
|
||||
ledger.store.pending_del (transaction, key);
|
||||
nano::block_sideband sideband (nano::block_type::receive, account, 0, new_balance, info.block_count + 1, nano::seconds_since_epoch (), nano::epoch::epoch_0, false /* unused */, false /* unused */, false /* unused */);
|
||||
ledger.store.block_put (transaction, hash, block_a, sideband);
|
||||
block_a.sideband_set (nano::block_sideband (account, 0, new_balance, info.block_count + 1, nano::seconds_since_epoch (), nano::epoch::epoch_0, false /* unused */, false /* unused */, false /* 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);
|
||||
ledger.cache.rep_weights.representation_add (info.representative, pending.amount.number ());
|
||||
|
@ -620,7 +619,7 @@ void ledger_processor::receive_block (nano::receive_block const & block_a)
|
|||
}
|
||||
}
|
||||
|
||||
void ledger_processor::open_block (nano::open_block const & block_a)
|
||||
void ledger_processor::open_block (nano::open_block & block_a)
|
||||
{
|
||||
auto hash (block_a.hash ());
|
||||
auto existing (ledger.store.block_exists (transaction, block_a.type (), hash));
|
||||
|
@ -659,8 +658,8 @@ void ledger_processor::open_block (nano::open_block const & block_a)
|
|||
(void)error;
|
||||
debug_assert (!error);
|
||||
ledger.store.pending_del (transaction, key);
|
||||
nano::block_sideband sideband (nano::block_type::open, block_a.hashables.account, 0, pending.amount, 1, nano::seconds_since_epoch (), nano::epoch::epoch_0, false /* unused */, false /* unused */, false /* unused */);
|
||||
ledger.store.block_put (transaction, hash, block_a, sideband);
|
||||
block_a.sideband_set (nano::block_sideband (block_a.hashables.account, 0, pending.amount, 1, nano::seconds_since_epoch (), nano::epoch::epoch_0, false /* unused */, false /* unused */, false /* 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);
|
||||
ledger.cache.rep_weights.representation_add (block_a.representative (), pending.amount.number ());
|
||||
|
@ -752,7 +751,7 @@ nano::uint128_t nano::ledger::account_pending (nano::transaction const & transac
|
|||
return result;
|
||||
}
|
||||
|
||||
nano::process_return nano::ledger::process (nano::write_transaction const & transaction_a, nano::block const & block_a, nano::signature_verification verification)
|
||||
nano::process_return nano::ledger::process (nano::write_transaction const & transaction_a, nano::block & block_a, nano::signature_verification verification)
|
||||
{
|
||||
debug_assert (!nano::work_validate (block_a));
|
||||
ledger_processor processor (*this, transaction_a, verification);
|
||||
|
|
|
@ -38,7 +38,7 @@ public:
|
|||
bool is_send (nano::transaction const &, nano::state_block const &) const;
|
||||
nano::account const & block_destination (nano::transaction const &, nano::block const &);
|
||||
nano::block_hash block_source (nano::transaction const &, nano::block const &);
|
||||
nano::process_return process (nano::write_transaction const &, nano::block const &, nano::signature_verification = nano::signature_verification::unknown);
|
||||
nano::process_return process (nano::write_transaction const &, nano::block &, nano::signature_verification = nano::signature_verification::unknown);
|
||||
bool rollback (nano::write_transaction const &, nano::block_hash const &, std::vector<std::shared_ptr<nano::block>> &);
|
||||
bool rollback (nano::write_transaction const &, nano::block_hash const &);
|
||||
void change_latest (nano::write_transaction const &, nano::account const &, nano::account_info const &, nano::account_info const &);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue