Skip to content

Commit

Permalink
Fixing issue where fork wouldn't be resolved.
Browse files Browse the repository at this point in the history
  • Loading branch information
clemahieu committed Apr 27, 2016
1 parent 3fea6d2 commit b6fe5eb
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 19 deletions.
34 changes: 34 additions & 0 deletions rai/core_test/ledger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1247,6 +1247,40 @@ TEST (ledger, fail_receive_fork_previous)
ASSERT_EQ (rai::process_result::fork, result5.code);
}

TEST (ledger, fail_receive_received_source)
{
bool init (false);
rai::block_store store (init, rai::unique_path ());
ASSERT_FALSE (init);
rai::ledger ledger (store);
rai::genesis genesis;
rai::transaction transaction (store.environment, nullptr, true);
genesis.initialize (transaction, store);
rai::keypair key1;
rai::send_block block1 (genesis.hash (), key1.pub, 2, rai::test_genesis_key.prv, rai::test_genesis_key.pub, 0);
auto result1 (ledger.process (transaction, block1));
ASSERT_EQ (rai::process_result::progress, result1.code);
rai::send_block block2 (block1.hash (), key1.pub, 1, rai::test_genesis_key.prv, rai::test_genesis_key.pub, 0);
auto result2 (ledger.process (transaction, block2));
ASSERT_EQ (rai::process_result::progress, result2.code);
rai::send_block block6 (block2.hash (), key1.pub, 0, rai::test_genesis_key.prv, rai::test_genesis_key.pub, 0);
auto result6 (ledger.process (transaction, block6));
ASSERT_EQ (rai::process_result::progress, result6.code);
rai::open_block block3 (block1.hash (), 1, key1.pub, key1.prv, key1.pub, 0);
auto result3 (ledger.process (transaction, block3));
ASSERT_EQ (rai::process_result::progress, result3.code);
rai::keypair key2;
rai::send_block block4 (block3.hash (), key1.pub, 1, key1.prv, key1.pub, 0);
auto result4 (ledger.process (transaction, block4));
ASSERT_EQ (rai::process_result::progress, result4.code);
rai::receive_block block5 (block4.hash (), block2.hash (), key1.prv, key1.pub, 0);
auto result5 (ledger.process (transaction, block5));
ASSERT_EQ (rai::process_result::progress, result5.code);
rai::receive_block block7 (block3.hash (), block2.hash (), key1.prv, key1.pub, 0);
auto result7 (ledger.process (transaction, block7));
ASSERT_EQ (rai::process_result::fork, result7.code);
}

TEST (ledger, latest_empty)
{
bool init (false);
Expand Down
41 changes: 22 additions & 19 deletions rai/secure.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2886,24 +2886,27 @@ void ledger_processor::receive_block (rai::receive_block const & block_a)
result.code = existing ? rai::process_result::old : rai::process_result::progress; // Have we seen this block already? (Harmless)
if (result.code == rai::process_result::progress)
{
auto source_missing (!ledger.store.block_exists (transaction, block_a.hashables.source));
auto block (ledger.store.block_get (transaction, block_a.hashables.source));
auto source_missing (block == nullptr);
result.code = source_missing ? rai::process_result::gap_source : rai::process_result::progress; // Have we seen the source block already? (Harmless)
if (result.code == rai::process_result::progress)
{
rai::pending_info pending;
result.code = ledger.store.pending_get (transaction, block_a.hashables.source, pending) ? rai::process_result::unreceivable : rai::process_result::progress; // Has this source already been received (Malformed)
if (result.code == rai::process_result::progress)
{
result.code = rai::validate_message (pending.destination, hash, block_a.signature) ? rai::process_result::bad_signature : rai::process_result::progress; // Is the signature valid (Malformed)
if (result.code == rai::process_result::progress)
{
rai::account_info info;
result.code = ledger.store.account_get (transaction, pending.destination, info) ? rai::process_result::gap_previous : rai::process_result::progress; //Have we seen the previous block? No entries for account at all (Harmless)
if (result.code == rai::process_result::progress)
{
result.code = info.head == block_a.hashables.previous ? rai::process_result::progress : rai::process_result::gap_previous; // Block doesn't immediately follow latest block (Harmless)
if (result.code == rai::process_result::progress)
{
assert (dynamic_cast <rai::send_block *> (block.get ()) != nullptr);
auto source (static_cast <rai::send_block *> (block.get ()));
result.code = rai::validate_message (source->hashables.destination, hash, block_a.signature) ? rai::process_result::bad_signature : rai::process_result::progress; // Is the signature valid (Malformed)
if (result.code == rai::process_result::progress)
{
rai::account_info info;
result.code = ledger.store.account_get (transaction, source->hashables.destination, info) ? rai::process_result::gap_previous : rai::process_result::progress; //Have we seen the previous block? No entries for account at all (Harmless)
if (result.code == rai::process_result::progress)
{
result.code = info.head == block_a.hashables.previous ? rai::process_result::progress : rai::process_result::gap_previous; // Block doesn't immediately follow latest block (Harmless)
if (result.code == rai::process_result::progress)
{
rai::pending_info pending;
result.code = ledger.store.pending_get (transaction, block_a.hashables.source, pending) ? rai::process_result::unreceivable : rai::process_result::progress; // Has this source already been received (Malformed)
if (result.code == rai::process_result::progress)
{
assert (ledger.store.frontier_get (transaction, block_a.hashables.previous) == pending.destination);
auto new_balance (info.balance.number () + pending.amount.number ());
rai::account_info source_info;
Expand All @@ -2918,11 +2921,11 @@ void ledger_processor::receive_block (rai::receive_block const & block_a)
result.account = pending.destination;
result.amount = pending.amount;
}
else
{
result.code = ledger.store.block_exists (transaction, block_a.hashables.previous) ? rai::process_result::fork : rai::process_result::gap_previous; // If we have the block but it's not the latest we have a signed fork (Malicious)
}
}
else
{
result.code = ledger.store.block_exists (transaction, block_a.hashables.previous) ? rai::process_result::fork : rai::process_result::gap_previous; // If we have the block but it's not the latest we have a signed fork (Malicious)
}
}
}
}
Expand Down

0 comments on commit b6fe5eb

Please sign in to comment.