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

Rollback source announce #1030

Merged
merged 4 commits into from
Aug 6, 2018
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
40 changes: 40 additions & 0 deletions rai/core_test/conflicts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,43 @@ TEST (votes, contested)
votes.rep_votes[rai::test_genesis_key.pub] = block2;
ASSERT_FALSE (votes.uncontested ());
}

TEST (conflicts, rollback_source)
{
rai::system system (24000, 2);
auto & node1 (*system.nodes[0]);
auto & node2 (*system.nodes[1]);
rai::genesis genesis;
rai::keypair key1;
system.wallet (0)->insert_adhoc (rai::test_genesis_key.prv);
auto send1 (std::make_shared<rai::state_block> (rai::test_genesis_key.pub, genesis.hash (), rai::test_genesis_key.pub, rai::genesis_amount - rai::Gxrb_ratio, key1.pub, rai::test_genesis_key.prv, rai::test_genesis_key.pub, system.work.generate (genesis.hash ())));
ASSERT_EQ (rai::process_result::progress, node2.process (*send1).code);
ASSERT_FALSE (node2.active.start (send1));
ASSERT_EQ (rai::process_result::progress, node1.process (*send1).code);
ASSERT_FALSE (node1.active.start (send1));
auto send2 (std::make_shared<rai::state_block> (rai::test_genesis_key.pub, send1->hash (), rai::test_genesis_key.pub, rai::genesis_amount - 2 * rai::Gxrb_ratio, key1.pub, rai::test_genesis_key.prv, rai::test_genesis_key.pub, system.work.generate (send1->hash ())));
ASSERT_EQ (rai::process_result::progress, node2.process (*send2).code);
ASSERT_FALSE (node2.active.start (send2));
auto send3 (std::make_shared<rai::state_block> (key1.pub, 0, key1.pub, rai::Gxrb_ratio, send1->hash (), key1.prv, key1.pub, system.work.generate (key1.pub)));
ASSERT_EQ (rai::process_result::progress, node2.process (*send3).code);
ASSERT_FALSE (node2.active.start (send3));
auto send4 (std::make_shared<rai::state_block> (key1.pub, send3->hash (), key1.pub, 2 * rai::Gxrb_ratio, send2->hash (), key1.prv, key1.pub, system.work.generate (send3->hash ())));
ASSERT_EQ (rai::process_result::progress, node2.process (*send4).code);
ASSERT_FALSE (node2.active.start (send4));
auto send5 (std::make_shared<rai::state_block> (rai::test_genesis_key.pub, send1->hash (), rai::test_genesis_key.pub, rai::genesis_amount - 3 * rai::Gxrb_ratio, key1.pub, rai::test_genesis_key.prv, rai::test_genesis_key.pub, system.work.generate (send1->hash ())));
ASSERT_EQ (rai::process_result::progress, node1.process (*send5).code);
ASSERT_FALSE (node1.active.start (send5));
auto iterations (0);
while (!node2.active.active (*send4))
{
system.poll ();
++iterations;
ASSERT_LT (iterations, 200);
}
while (node2.active.active (*send4))
{
system.poll ();
++iterations;
ASSERT_LT (iterations, 200);
}
}
18 changes: 15 additions & 3 deletions rai/node/node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3472,8 +3472,15 @@ void rai::election::compute_rep_votes (MDB_txn * transaction_a)

void rai::election::broadcast_winner (MDB_txn * transaction_a)
{
compute_rep_votes (transaction_a);
node.network.republish_block (transaction_a, status.winner);
if (node.ledger.could_fit (transaction_a, *status.winner))
{
compute_rep_votes (transaction_a);
node.network.republish_block (transaction_a, status.winner);
}
else
{
abort ();
}
}

void rai::election::confirm_once (MDB_txn * transaction_a)
Expand All @@ -3490,6 +3497,11 @@ void rai::election::confirm_once (MDB_txn * transaction_a)
}
}

void rai::election::abort ()
{
confirmed = true;
}

bool rai::election::have_quorum (rai::tally_t const & tally_a)
{
auto i (tally_a.begin ());
Expand Down Expand Up @@ -3605,7 +3617,7 @@ void rai::active_transactions::announce_votes ()
for (auto i (roots.begin ()), n (roots.end ()); i != n; ++i)
{
auto election_l (i->election);
if ((!node.store.root_exists (transaction, election_l->votes.id) || election_l->confirmed) && i->announcements >= announcement_min - 1)
if (election_l->confirmed && i->announcements >= announcement_min - 1)
{
if (election_l->confirmed)
{
Expand Down
1 change: 1 addition & 0 deletions rai/node/node.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ class election : public std::enable_shared_from_this<rai::election>
{
std::function<void(std::shared_ptr<rai::block>)> confirmation_action;
void confirm_once (MDB_txn *);
void abort ();

public:
election (rai::node &, std::shared_ptr<rai::block>, std::function<void(std::shared_ptr<rai::block>)> const &);
Expand Down
46 changes: 46 additions & 0 deletions rai/secure/ledger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -891,6 +891,52 @@ void rai::ledger::dump_account_chain (rai::account const & account_a)
}
}

class block_fit_visitor : public rai::block_visitor
{
public:
block_fit_visitor (rai::ledger & ledger_a, MDB_txn * transaction_a) :
ledger (ledger_a),
transaction (transaction_a),
result (false)
{
}
void send_block (rai::send_block const & block_a) override
{
result = ledger.store.block_exists (transaction, block_a.previous ());
}
void receive_block (rai::receive_block const & block_a) override
{
result = ledger.store.block_exists (transaction, block_a.previous ());
result &= ledger.store.block_exists (transaction, block_a.source ());
}
void open_block (rai::open_block const & block_a) override
{
result = ledger.store.block_exists (transaction, block_a.source ());
}
void change_block (rai::change_block const & block_a) override
{
result = ledger.store.block_exists (transaction, block_a.previous ());
}
void state_block (rai::state_block const & block_a) override
{
result = block_a.previous ().is_zero () || ledger.store.block_exists (transaction, block_a.previous ());
if (result && !ledger.is_send (transaction, block_a))
{
result &= ledger.store.block_exists (transaction, block_a.hashables.link);
}
}
rai::ledger & ledger;
MDB_txn * transaction;
bool result;
};

bool rai::ledger::could_fit (MDB_txn * transaction_a, rai::block const & block_a)
{
block_fit_visitor visitor (*this, transaction_a);
block_a.visit (visitor);
return visitor.result;
}

void rai::ledger::checksum_update (MDB_txn * transaction_a, rai::block_hash const & hash_a)
{
rai::checksum value;
Expand Down
1 change: 1 addition & 0 deletions rai/secure/ledger.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ class ledger
void checksum_update (MDB_txn *, rai::block_hash const &);
rai::checksum checksum (MDB_txn *, rai::account const &, rai::account const &);
void dump_account_chain (rai::account const &);
bool could_fit (MDB_txn *, rai::block const &);
static rai::uint128_t const unit;
rai::block_store & store;
rai::stat & stats;
Expand Down