diff --git a/libraries/chain/chain_controller.cpp b/libraries/chain/chain_controller.cpp index 08f90a61eca716e4071918274c9dae579eddb33c..5cc87c4e729991f86a86f77e641eb37aff2fbd63 100644 --- a/libraries/chain/chain_controller.cpp +++ b/libraries/chain/chain_controller.cpp @@ -395,6 +395,12 @@ signed_block chain_controller::_generate_block( pending_block.producer = producer_obj.owner; + // If this block is last in a round, calculate the schedule for the new round + if (pending_block.block_num() % config::BlocksPerRound == 0) { + auto new_schedule = _admin->get_next_round(_db); + pending_block.producer_changes = get_global_properties().active_producers - new_schedule; + } + if( !(skip & skip_producer_signature) ) pending_block.sign( block_signing_private_key ); diff --git a/tests/common/database_fixture.cpp b/tests/common/database_fixture.cpp index 6fb053642e2a423ea4bb8c7e09a2493e9238fb6d..1c0aed086afe71e3716a648471730e96d05fe8e8 100644 --- a/tests/common/database_fixture.cpp +++ b/tests/common/database_fixture.cpp @@ -54,12 +54,12 @@ testing_fixture::testing_fixture() { auto private_key = fc::ecc::private_key::regenerate(fc::sha256::hash(name)); public_key_type public_key = private_key.get_public_key(); default_genesis_state.initial_accounts.emplace_back(name, 0, 100000, public_key, public_key); - key_ring[public_key] = private_key; + store_private_key(private_key); private_key = fc::ecc::private_key::regenerate(fc::sha256::hash(name + ".producer")); public_key = private_key.get_public_key(); default_genesis_state.initial_producers.emplace_back(name, public_key); - key_ring[public_key] = private_key; + store_private_key(private_key); } } @@ -81,6 +81,10 @@ native_contract::genesis_state_type& testing_fixture::genesis_state() { return default_genesis_state; } +void testing_fixture::store_private_key(const private_key_type& key) { + key_ring[key.get_public_key()] = key; +} + private_key_type testing_fixture::get_private_key(const public_key_type& public_key) const { auto itr = key_ring.find(public_key); EOS_ASSERT(itr != key_ring.end(), missing_key_exception, @@ -143,6 +147,10 @@ std::set testing_database::get_approved_producers(const type return {set.begin(), set.end()}; } +types::PublicKey testing_database::get_block_signing_key(const types::AccountName& producerName) { + return get_database().get(producerName).signing_key; +} + void testing_network::connect_database(testing_database& new_database) { if (databases.count(&new_database)) return; diff --git a/tests/common/database_fixture.hpp b/tests/common/database_fixture.hpp index 6d32995a117291cce536bff54e5e900e92caca20..3cc4133a86bf0879e893dfe7bf99136540dc44c9 100644 --- a/tests/common/database_fixture.hpp +++ b/tests/common/database_fixture.hpp @@ -114,6 +114,7 @@ public: const native_contract::genesis_state_type& genesis_state() const; native_contract::genesis_state_type& genesis_state(); + void store_private_key(const private_key_type& key); private_key_type get_private_key(const public_key_type& public_key) const; protected: @@ -170,6 +171,8 @@ public: /// @brief Get the set of producers approved by the named account std::set get_approved_producers(const AccountName& account); + /// @brief Get the specified block producer's signing key + PublicKey get_block_signing_key(const AccountName& producerName); protected: testing_fixture& fixture; @@ -284,6 +287,7 @@ protected: * @endcode */ #define Make_Key(name) auto name ## _private_key = private_key_type::regenerate(fc::digest(#name "_private_key")); \ + store_private_key(name ## _private_key); \ PublicKey name ## _public_key = name ## _private_key.get_public_key(); /** diff --git a/tests/tests/database_tests.cpp b/tests/tests/database_tests.cpp index c72d69d1732c236a4256b34edb486a1bfa35970c..d9d80273bc6610dd8d559f39f66d35b3a898ed24 100644 --- a/tests/tests/database_tests.cpp +++ b/tests/tests/database_tests.cpp @@ -185,7 +185,7 @@ BOOST_FIXTURE_TEST_CASE(producer_voting_parameters_2, testing_fixture) } FC_LOG_AND_RETHROW() } // Test that if I create a producer and vote for him, he gets in on the next round (but not before) -BOOST_FIXTURE_TEST_CASE(producer_voting_1, testing_fixture, *boost::unit_test::expected_failures(1)) { +BOOST_FIXTURE_TEST_CASE(producer_voting_1, testing_fixture) { try { Make_Database(db) db.produce_blocks(); @@ -210,7 +210,6 @@ BOOST_FIXTURE_TEST_CASE(producer_voting_1, testing_fixture, *boost::unit_test::e db.produce_blocks(); const auto& gpo = db.get_global_properties(); -#warning TODO: expected failure because chain_controller::generate_block does not update round BOOST_REQUIRE(boost::find(gpo.active_producers, "joe") != gpo.active_producers.end()); Approve_Producer(db, bob, joe, false); @@ -226,7 +225,7 @@ BOOST_FIXTURE_TEST_CASE(producer_voting_1, testing_fixture, *boost::unit_test::e } // Same as producer_voting_1, except we first cast the vote for the producer, _then_ get a stake -BOOST_FIXTURE_TEST_CASE(producer_voting_2, testing_fixture, *boost::unit_test::expected_failures(1)) { +BOOST_FIXTURE_TEST_CASE(producer_voting_2, testing_fixture) { try { Make_Database(db) db.produce_blocks(); @@ -261,7 +260,6 @@ BOOST_FIXTURE_TEST_CASE(producer_voting_2, testing_fixture, *boost::unit_test::e db.produce_blocks(); const auto& gpo = db.get_global_properties(); -#warning TODO: expected failure because chain_controller::generate_block does not update round BOOST_REQUIRE(boost::find(gpo.active_producers, "joe") != gpo.active_producers.end()); Approve_Producer(db, bob, joe, false);