Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Sideband upgrade using epoch byte for is_send/receive/epoch #2545

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
301 changes: 282 additions & 19 deletions nano/core_test/block_store.cpp

Large diffs are not rendered by default.

83 changes: 76 additions & 7 deletions nano/core_test/ledger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1695,24 +1695,32 @@ 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 ()));
auto send2 (store->block_get (transaction, send1.hash ()));
nano::block_sideband sideband;
auto send2 (store->block_get (transaction, send1.hash (), &sideband));
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);
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 ()));
auto receive2 (store->block_get (transaction, receive1.hash ()));
nano::block_sideband sideband2;
auto receive2 (store->block_get (transaction, receive1.hash (), &sideband2));
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 (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);
}

TEST (ledger, state_receive)
Expand All @@ -1738,12 +1746,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 ()));
auto receive2 (store->block_get (transaction, receive1.hash ()));
nano::block_sideband sideband;
auto receive2 (store->block_get (transaction, receive1.hash (), &sideband));
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);
}

TEST (ledger, state_rep_change)
Expand All @@ -1761,13 +1773,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 ()));
auto change2 (store->block_get (transaction, change1.hash ()));
nano::block_sideband sideband;
auto change2 (store->block_get (transaction, change1.hash (), &sideband));
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);
}

TEST (ledger, state_open)
Expand Down Expand Up @@ -1796,13 +1812,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 ()));
auto open2 (store->block_get (transaction, open1.hash ()));
nano::block_sideband sideband;
auto open2 (store->block_get (transaction, open1.hash (), &sideband));
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);
}

// Make sure old block types can't be inserted after a state block.
Expand Down Expand Up @@ -2045,13 +2065,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 ()));
auto send2 (store->block_get (transaction, send1.hash ()));
nano::block_sideband sideband;
auto send2 (store->block_get (transaction, send1.hash (), &sideband));
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);
}

TEST (ledger, state_receive_change)
Expand All @@ -2078,13 +2102,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 ()));
auto receive2 (store->block_get (transaction, receive1.hash ()));
nano::block_sideband sideband2;
auto receive2 (store->block_get (transaction, receive1.hash (), &sideband2));
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);
}

TEST (ledger, state_open_old)
Expand Down Expand Up @@ -2328,6 +2356,13 @@ 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);
}
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;
Expand All @@ -2339,16 +2374,37 @@ 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);
}
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);
}
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);
}
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 ()));
Expand All @@ -2358,6 +2414,13 @@ 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);
}
}

TEST (ledger, epoch_blocks_v2_general)
Expand Down Expand Up @@ -2759,6 +2822,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);
}
}

Expand Down
6 changes: 3 additions & 3 deletions nano/core_test/versioning.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ TEST (versioning, account_info_v1)
nano::mdb_store store (logger, file);
ASSERT_FALSE (store.init_error ());
auto transaction (store.tx_begin_write ());
nano::block_sideband sideband (nano::block_type::open, 0, 0, 0, 0, 0, nano::epoch::epoch_0);
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);
auto status (mdb_put (store.env.tx (transaction), store.accounts_v0, nano::mdb_val (account), nano::mdb_val (sizeof (v1), &v1), 0));
ASSERT_EQ (0, status);
Expand Down Expand Up @@ -53,7 +53,7 @@ TEST (versioning, account_info_v5)
nano::mdb_store store (logger, file);
ASSERT_FALSE (store.init_error ());
auto transaction (store.tx_begin_write ());
nano::block_sideband sideband (nano::block_type::open, 0, 0, 0, 0, 0, nano::epoch::epoch_0);
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);
auto status (mdb_put (store.env.tx (transaction), store.accounts_v0, nano::mdb_val (account), nano::mdb_val (sizeof (v5), &v5), 0));
ASSERT_EQ (0, status);
Expand Down Expand Up @@ -89,7 +89,7 @@ TEST (versioning, account_info_v13)
nano::mdb_store store (logger, file);
ASSERT_FALSE (store.init_error ());
auto transaction (store.tx_begin_write ());
nano::block_sideband sideband (nano::block_type::open, 0, 0, 0, 0, 0, nano::epoch::epoch_0);
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);
auto status (mdb_put (store.env.tx (transaction), store.accounts_v0, nano::mdb_val (account), nano::mdb_val (v13), 0));
ASSERT_EQ (0, status);
Expand Down
39 changes: 39 additions & 0 deletions nano/nano_node/entry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1050,6 +1050,45 @@ int main (int argc, char * const * argv)
std::cerr << boost::str (boost::format ("Invalid signature for block %1%\n") % hash.to_string ());
}
}
// Validate block details set in the sideband
bool block_details_error = false;
if (block->type () != nano::block_type::state)
{
// Not state
block_details_error = sideband.details.is_send || sideband.details.is_receive || sideband.details.is_epoch;
}
else
{
auto prev_balance (node.node->ledger.balance (transaction, block->previous ()));
if (block->balance () < prev_balance)
{
// State send
block_details_error = !sideband.details.is_send || sideband.details.is_receive || sideband.details.is_epoch;
}
else
{
if (block->link ().is_zero ())
{
// State change
block_details_error = sideband.details.is_send || sideband.details.is_receive || sideband.details.is_epoch;
}
else if (block->balance () == prev_balance && node.node->ledger.is_epoch_link (block->link ()))
{
// State epoch
block_details_error = !sideband.details.is_epoch || sideband.details.is_send || sideband.details.is_receive;
}
else
{
// State receive
block_details_error = !sideband.details.is_receive || sideband.details.is_send || sideband.details.is_epoch;
block_details_error |= !node.node->store.source_exists (transaction, block->link ());
}
}
}
if (block_details_error)
{
std::cerr << boost::str (boost::format ("Incorrect sideband block details for block %1%\n") % hash.to_string ());
}
// Check if block work value is correct
if (nano::work_validate (*block.get ()))
{
Expand Down
Loading