diff --git a/rai/core_test/ledger.cpp b/rai/core_test/ledger.cpp index 3f811ee7a4..4898eab54a 100644 --- a/rai/core_test/ledger.cpp +++ b/rai/core_test/ledger.cpp @@ -1399,33 +1399,12 @@ TEST (ledger, change_representative_move_representation) ASSERT_EQ (rai::genesis_amount, ledger.weight (transaction, key3.pub)); } -TEST (ledger, stopped_rollback) -{ - bool init (false); - rai::block_store store (init, rai::unique_path ()); - ASSERT_TRUE (!init); - rai::ledger ledger (store, 0, [] (rai::block const &) { return true; }); - rai::transaction transaction (store.environment, nullptr, true); - rai::genesis genesis; - genesis.initialize (transaction, store); - rai::account_info info1; - ASSERT_FALSE (store.account_get (transaction, rai::test_genesis_key.pub, info1)); - rai::keypair key2; - rai::send_block send (info1.head, key2.pub, 50, rai::test_genesis_key.prv, rai::test_genesis_key.pub, 0); - rai::block_hash hash1 (send.hash ()); - auto return1 (ledger.process (transaction, send)); - ASSERT_EQ (rai::process_result::progress, return1.code); - ASSERT_TRUE (store.block_exists (transaction, hash1)); - ASSERT_TRUE (ledger.rollback (transaction, send.hash ())); - ASSERT_TRUE (store.block_exists (transaction, hash1)); -} - TEST (ledger, send_open_receive_rollback) { bool init (false); rai::block_store store (init, rai::unique_path ()); ASSERT_TRUE (!init); - rai::ledger ledger (store, 0, [] (rai::block const &) { return false; }); + rai::ledger ledger (store, 0); rai::transaction transaction (store.environment, nullptr, true); rai::genesis genesis; genesis.initialize (transaction, store); @@ -1455,23 +1434,23 @@ TEST (ledger, send_open_receive_rollback) ASSERT_EQ (100, ledger.weight (transaction, key2.pub)); ASSERT_EQ (0, ledger.weight (transaction, rai::test_genesis_key.pub)); ASSERT_EQ (rai::genesis_amount - 100, ledger.weight (transaction, key3.pub)); - ASSERT_FALSE (ledger.rollback (transaction, receive.hash ())); + ledger.rollback (transaction, receive.hash ()); ASSERT_EQ (50, ledger.weight (transaction, key2.pub)); ASSERT_EQ (0, ledger.weight (transaction, rai::test_genesis_key.pub)); ASSERT_EQ (rai::genesis_amount - 100, ledger.weight (transaction, key3.pub)); - ASSERT_FALSE (ledger.rollback (transaction, open.hash ())); + ledger.rollback (transaction, open.hash ()); ASSERT_EQ (0, ledger.weight (transaction, key2.pub)); ASSERT_EQ (0, ledger.weight (transaction, rai::test_genesis_key.pub)); ASSERT_EQ (rai::genesis_amount - 100, ledger.weight (transaction, key3.pub)); - ASSERT_FALSE (ledger.rollback (transaction, change1.hash ())); + ledger.rollback (transaction, change1.hash ()); ASSERT_EQ (0, ledger.weight (transaction, key2.pub)); ASSERT_EQ (0, ledger.weight (transaction, key3.pub)); ASSERT_EQ (rai::genesis_amount - 100, ledger.weight (transaction, rai::test_genesis_key.pub)); - ASSERT_FALSE (ledger.rollback (transaction, send2.hash ())); + ledger.rollback (transaction, send2.hash ()); ASSERT_EQ (0, ledger.weight (transaction, key2.pub)); ASSERT_EQ (0, ledger.weight (transaction, key3.pub)); ASSERT_EQ (rai::genesis_amount - 50, ledger.weight (transaction, rai::test_genesis_key.pub)); - ASSERT_FALSE (ledger.rollback (transaction, send1.hash ())); + ledger.rollback (transaction, send1.hash ()); ASSERT_EQ (0, ledger.weight (transaction, key2.pub)); ASSERT_EQ (0, ledger.weight (transaction, key3.pub)); ASSERT_EQ (rai::genesis_amount - 0, ledger.weight (transaction, rai::test_genesis_key.pub)); diff --git a/rai/core_test/node.cpp b/rai/core_test/node.cpp index 3c65b0c64b..455426aad4 100644 --- a/rai/core_test/node.cpp +++ b/rai/core_test/node.cpp @@ -1037,47 +1037,6 @@ TEST (node, fork_no_vote_quorum) ASSERT_TRUE (node3.latest (rai::test_genesis_key.pub) == send1.hash ()); } -TEST (node, stopped_rollback) -{ - rai::system system (24000, 3); - auto & node1 (*system.nodes [0]); - auto & node2 (*system.nodes [1]); - auto & node3 (*system.nodes [2]); - system.wallet (0)->insert_adhoc (rai::test_genesis_key.prv); - auto key1 (system.wallet (0)->deterministic_insert ()); - auto amount1 (rai::genesis_amount / 4); - auto block1 (system.wallet (0)->send_action (rai::test_genesis_key.pub, key1, amount1)); - ASSERT_NE (nullptr, block1); - auto iterations (0); - while (node3.balance (key1) != amount1 || node2.balance (key1) != amount1 || node1.balance (key1) != amount1 || !node1.rollback_predicate (*block1) || !node2.rollback_predicate (*block1) || !node3.rollback_predicate (*block1)) - { - system.poll (); - ++iterations; - ASSERT_LT (iterations, 200); - } - { - rai::transaction transaction (node1.store.environment, nullptr, true); - auto original (node1.ledger.rollback_predicate); - node1.ledger.rollback_predicate = [] (rai::block const &) { return false; }; - ASSERT_FALSE (node1.ledger.rollback (transaction, block1->hash ())); - ASSERT_FALSE (node1.store.block_exists (transaction, block1->hash ())); - node1.ledger.rollback_predicate = original; - } - auto key2 (system.wallet (0)->deterministic_insert ()); - auto block2 (system.wallet (0)->send_action (rai::test_genesis_key.pub, key2, amount1)); - ASSERT_NE (nullptr, block2); - auto iterations2 (0); - while (iterations2 < 50) - { - system.poll (); - ++iterations2; - ASSERT_TRUE (node2.ledger.block_exists (block1->hash ())); - ASSERT_FALSE (node2.ledger.block_exists (block2->hash ())); - ASSERT_TRUE (node3.ledger.block_exists (block1->hash ())); - ASSERT_FALSE (node3.ledger.block_exists (block2->hash ())); - } -} - TEST (node, broadcast_elected) { rai::system system (24000, 3); diff --git a/rai/node/node.cpp b/rai/node/node.cpp index c9368c33aa..7ec60ae7b4 100755 --- a/rai/node/node.cpp +++ b/rai/node/node.cpp @@ -834,7 +834,7 @@ alarm (alarm_a), work (work_a), store (init_a.block_store_init, application_path_a / "data.ldb"), gap_cache (*this), -ledger (store, config_a.inactive_supply.number (), [this] (rai::block const & block_a) { return rollback_predicate (block_a); } ), +ledger (store, config_a.inactive_supply.number ()), active (*this), wallets (init_a.block_store_init, *this), network (service_a, config.peering_port, *this), @@ -888,12 +888,6 @@ port_mapping (*this) } } -bool rai::node::rollback_predicate (rai::block const & block_a) -{ - auto error (bootstrap_initiator.warmed_up && !active.active (block_a)); - return error; -} - rai::node::~node () { if (config.logging.node_lifetime_tracing ()) @@ -2225,16 +2219,9 @@ bool rai::election::recalculate_winner (MDB_txn * transaction_a) BOOST_LOG (node.log) << boost::str (boost::format ("%1% %2%") % i->first.to_account () % i->second->hash ().to_string ()); } // Replace our block with the winner and roll back any dependent blocks - auto error (node.ledger.rollback (transaction_a, last_winner->hash ())); - if (!error) - { - node.ledger.process (transaction_a, *winner->second); - last_winner = std::move (winner->second); - } - else - { - BOOST_LOG (node.log) << boost::str (boost::format ("Rollback consistency violation rolling back %1% trying to replace with %2%") % last_winner->to_json () % winner->second->to_json ()); - } + node.ledger.rollback (transaction_a, last_winner->hash ()); + node.ledger.process (transaction_a, *winner->second); + last_winner = std::move (winner->second); } // Check if we can do a fast confirm for the usual case of good actors if (tally_l.size () == 1) diff --git a/rai/node/node.hpp b/rai/node/node.hpp index fbf5d3a631..54ab325f57 100644 --- a/rai/node/node.hpp +++ b/rai/node/node.hpp @@ -402,7 +402,6 @@ class node : public std::enable_shared_from_this void generate_work (rai::block &); uint64_t generate_work (rai::uint256_union const &); void generate_work (rai::uint256_union const &, std::function ); - bool rollback_predicate (rai::block const &); rai::node_config config; rai::alarm & alarm; rai::work_pool & work; diff --git a/rai/secure.cpp b/rai/secure.cpp index 41d2d78d7f..5c5a9eb54d 100644 --- a/rai/secure.cpp +++ b/rai/secure.cpp @@ -208,10 +208,9 @@ rai::keypair::keypair (std::string const & prv_a) ed25519_publickey (prv.data.bytes.data (), pub.bytes.data ()); } -rai::ledger::ledger (rai::block_store & store_a, rai::uint128_t const & inactive_supply_a, std::function rollback_predicate_a) : +rai::ledger::ledger (rai::block_store & store_a, rai::uint128_t const & inactive_supply_a) : store (store_a), -inactive_supply (inactive_supply_a), -rollback_predicate (rollback_predicate_a) +inactive_supply (inactive_supply_a) { } @@ -2606,107 +2605,74 @@ class rollback_visitor : public rai::block_visitor public: rollback_visitor (MDB_txn * transaction_a, rai::ledger & ledger_a) : transaction (transaction_a), - ledger (ledger_a), - error (false) + ledger (ledger_a) { } void send_block (rai::send_block const & block_a) override { - if (!ledger.rollback_predicate (block_a)) - { - auto hash (block_a.hash ()); - rai::pending_info pending; - rai::pending_key key (block_a.hashables.destination, hash); - while (ledger.store.pending_get (transaction, key, pending) && !error) - { - error = ledger.rollback (transaction, ledger.latest (transaction, block_a.hashables.destination)); - } - if (!error) - { - rai::account_info info; - auto error (ledger.store.account_get (transaction, pending.source, info)); - assert (!error); - ledger.store.pending_del (transaction, key); - ledger.store.representation_add (transaction, ledger.representative (transaction, hash), pending.amount.number ()); - ledger.change_latest (transaction, pending.source, block_a.hashables.previous, info.rep_block, ledger.balance (transaction, block_a.hashables.previous)); - ledger.store.block_del (transaction, hash); - ledger.store.frontier_del (transaction, hash); - ledger.store.frontier_put (transaction, block_a.hashables.previous, pending.source); - ledger.store.block_successor_clear (transaction, block_a.hashables.previous); - } - } - else + auto hash (block_a.hash ()); + rai::pending_info pending; + rai::pending_key key (block_a.hashables.destination, hash); + while (ledger.store.pending_get (transaction, key, pending)) { - error = true; + ledger.rollback (transaction, ledger.latest (transaction, block_a.hashables.destination)); } + rai::account_info info; + auto error (ledger.store.account_get (transaction, pending.source, info)); + assert (!error); + ledger.store.pending_del (transaction, key); + ledger.store.representation_add (transaction, ledger.representative (transaction, hash), pending.amount.number ()); + ledger.change_latest (transaction, pending.source, block_a.hashables.previous, info.rep_block, ledger.balance (transaction, block_a.hashables.previous)); + ledger.store.block_del (transaction, hash); + ledger.store.frontier_del (transaction, hash); + ledger.store.frontier_put (transaction, block_a.hashables.previous, pending.source); + ledger.store.block_successor_clear (transaction, block_a.hashables.previous); } void receive_block (rai::receive_block const & block_a) override { - if (!ledger.rollback_predicate (block_a)) - { - auto hash (block_a.hash ()); - auto representative (ledger.representative (transaction, block_a.hashables.previous)); - auto amount (ledger.amount (transaction, block_a.hashables.source)); - auto destination_account (ledger.account (transaction, hash)); - ledger.store.representation_add (transaction, ledger.representative (transaction, hash), 0 - amount); - ledger.change_latest (transaction, destination_account, block_a.hashables.previous, representative, ledger.balance (transaction, block_a.hashables.previous)); - ledger.store.block_del (transaction, hash); - ledger.store.pending_put (transaction, rai::pending_key (destination_account, block_a.hashables.source), {ledger.account (transaction, block_a.hashables.source), amount}); - ledger.store.frontier_del (transaction, hash); - ledger.store.frontier_put (transaction, block_a.hashables.previous, destination_account); - ledger.store.block_successor_clear (transaction, block_a.hashables.previous); - } - else - { - error = true; - } + auto hash (block_a.hash ()); + auto representative (ledger.representative (transaction, block_a.hashables.previous)); + auto amount (ledger.amount (transaction, block_a.hashables.source)); + auto destination_account (ledger.account (transaction, hash)); + ledger.store.representation_add (transaction, ledger.representative (transaction, hash), 0 - amount); + ledger.change_latest (transaction, destination_account, block_a.hashables.previous, representative, ledger.balance (transaction, block_a.hashables.previous)); + ledger.store.block_del (transaction, hash); + ledger.store.pending_put (transaction, rai::pending_key (destination_account, block_a.hashables.source), {ledger.account (transaction, block_a.hashables.source), amount}); + ledger.store.frontier_del (transaction, hash); + ledger.store.frontier_put (transaction, block_a.hashables.previous, destination_account); + ledger.store.block_successor_clear (transaction, block_a.hashables.previous); } void open_block (rai::open_block const & block_a) override { - if (!ledger.rollback_predicate (block_a)) - { - auto hash (block_a.hash ()); - auto representative (ledger.representative (transaction, block_a.hashables.source)); - auto amount (ledger.amount (transaction, block_a.hashables.source)); - auto destination_account (ledger.account (transaction, hash)); - ledger.store.representation_add (transaction, ledger.representative (transaction, hash), 0 - amount); - ledger.change_latest (transaction, destination_account, 0, representative, 0); - ledger.store.block_del (transaction, hash); - ledger.store.pending_put (transaction, rai::pending_key (destination_account, block_a.hashables.source), {ledger.account (transaction, block_a.hashables.source), amount}); - ledger.store.frontier_del (transaction, hash); - } - else - { - error = true; - } + auto hash (block_a.hash ()); + auto representative (ledger.representative (transaction, block_a.hashables.source)); + auto amount (ledger.amount (transaction, block_a.hashables.source)); + auto destination_account (ledger.account (transaction, hash)); + ledger.store.representation_add (transaction, ledger.representative (transaction, hash), 0 - amount); + ledger.change_latest (transaction, destination_account, 0, representative, 0); + ledger.store.block_del (transaction, hash); + ledger.store.pending_put (transaction, rai::pending_key (destination_account, block_a.hashables.source), {ledger.account (transaction, block_a.hashables.source), amount}); + ledger.store.frontier_del (transaction, hash); } void change_block (rai::change_block const & block_a) override { - if (!ledger.rollback_predicate (block_a)) - { - auto hash (block_a.hash ()); - auto representative (ledger.representative (transaction, block_a.hashables.previous)); - auto account (ledger.account (transaction, block_a.hashables.previous)); - rai::account_info info; - auto error (ledger.store.account_get (transaction, account, info)); - assert (!error); - auto balance (ledger.balance (transaction, block_a.hashables.previous)); - ledger.store.representation_add (transaction, representative, balance); - ledger.store.representation_add (transaction, hash, 0 - balance); - ledger.store.block_del (transaction, hash); - ledger.change_latest (transaction, account, block_a.hashables.previous, representative, info.balance); - ledger.store.frontier_del (transaction, hash); - ledger.store.frontier_put (transaction, block_a.hashables.previous, account); - ledger.store.block_successor_clear (transaction, block_a.hashables.previous); - } - else - { - error = true; - } + auto hash (block_a.hash ()); + auto representative (ledger.representative (transaction, block_a.hashables.previous)); + auto account (ledger.account (transaction, block_a.hashables.previous)); + rai::account_info info; + auto error (ledger.store.account_get (transaction, account, info)); + assert (!error); + auto balance (ledger.balance (transaction, block_a.hashables.previous)); + ledger.store.representation_add (transaction, representative, balance); + ledger.store.representation_add (transaction, hash, 0 - balance); + ledger.store.block_del (transaction, hash); + ledger.change_latest (transaction, account, block_a.hashables.previous, representative, info.balance); + ledger.store.frontier_del (transaction, hash); + ledger.store.frontier_put (transaction, block_a.hashables.previous, account); + ledger.store.block_successor_clear (transaction, block_a.hashables.previous); } MDB_txn * transaction; rai::ledger & ledger; - bool error; }; } @@ -2836,20 +2802,19 @@ rai::uint128_t rai::ledger::weight (MDB_txn * transaction_a, rai::account const } // Rollback blocks until `block_a' doesn't exist -bool rai::ledger::rollback (MDB_txn * transaction_a, rai::block_hash const & block_a) +void rai::ledger::rollback (MDB_txn * transaction_a, rai::block_hash const & block_a) { assert (store.block_exists (transaction_a, block_a)); auto account_l (account (transaction_a, block_a)); rollback_visitor rollback (transaction_a, *this); rai::account_info info; - while (store.block_exists (transaction_a, block_a) && !rollback.error) + while (store.block_exists (transaction_a, block_a)) { auto latest_error (store.account_get (transaction_a, account_l, info)); assert (!latest_error); auto block (store.block_get (transaction_a, info.head)); block->visit (rollback); } - return rollback.error; } // Return account containing hash diff --git a/rai/secure.hpp b/rai/secure.hpp index 21a11be5f7..70988f6d3f 100644 --- a/rai/secure.hpp +++ b/rai/secure.hpp @@ -466,7 +466,7 @@ class votes class ledger { public: - ledger (rai::block_store &, rai::uint128_t const & = 0, std::function = [] (rai::block const &) { return false; }); + ledger (rai::block_store &, rai::uint128_t const & = 0); std::pair > winner (MDB_txn *, rai::votes const & votes_a); std::map , std::greater > tally (MDB_txn *, rai::votes const &); rai::account account (MDB_txn *, rai::block_hash const &); @@ -486,7 +486,7 @@ class ledger std::string block_text (rai::block_hash const &); rai::uint128_t supply (MDB_txn *); rai::process_return process (MDB_txn *, rai::block const &); - bool rollback (MDB_txn *, rai::block_hash const &); + void rollback (MDB_txn *, rai::block_hash const &); void change_latest (MDB_txn *, rai::account const &, rai::block_hash const &, rai::account const &, rai::uint128_union const &); void checksum_update (MDB_txn *, rai::block_hash const &); rai::checksum checksum (MDB_txn *, rai::account const &, rai::account const &); @@ -494,7 +494,6 @@ class ledger static rai::uint128_t const unit; rai::block_store & store; rai::uint128_t inactive_supply; - std::function rollback_predicate; }; extern rai::keypair const & zero_key; extern rai::keypair const & test_genesis_key;