From 83ec46fb979808a9cf9596a25e3ea7ec57aae001 Mon Sep 17 00:00:00 2001 From: Kevin Heifner Date: Sat, 17 Feb 2024 20:21:54 -0600 Subject: [PATCH] GH-2142 Use the correct producer schedule for finding block signing authorization. --- libraries/chain/block_header_state.cpp | 2 +- libraries/chain/block_header_state_legacy.cpp | 4 ++-- libraries/chain/block_state.cpp | 15 +++++++-------- libraries/chain/controller.cpp | 9 ++++++--- .../include/eosio/chain/block_header_state.hpp | 2 +- .../eosio/chain/block_header_state_legacy.hpp | 2 +- .../eosio/chain/block_header_state_utils.hpp | 2 +- .../chain/include/eosio/chain/block_state.hpp | 6 +++--- 8 files changed, 22 insertions(+), 20 deletions(-) diff --git a/libraries/chain/block_header_state.cpp b/libraries/chain/block_header_state.cpp index 4209e6ac20..78922138f6 100644 --- a/libraries/chain/block_header_state.cpp +++ b/libraries/chain/block_header_state.cpp @@ -12,7 +12,7 @@ namespace eosio::chain { // digest_type compute_finalizer_digest() const { return id; }; -producer_authority block_header_state::get_scheduled_producer(block_timestamp_type t) const { +const producer_authority& block_header_state::get_scheduled_producer(block_timestamp_type t) const { return detail::get_scheduled_producer(active_proposer_policy->proposer_schedule.producers, t); } diff --git a/libraries/chain/block_header_state_legacy.cpp b/libraries/chain/block_header_state_legacy.cpp index 0266ec75f6..958bd4f01e 100644 --- a/libraries/chain/block_header_state_legacy.cpp +++ b/libraries/chain/block_header_state_legacy.cpp @@ -19,7 +19,7 @@ namespace eosio::chain { return blocknums[ index ]; } - producer_authority block_header_state_legacy::get_scheduled_producer( block_timestamp_type t ) const { + const producer_authority& block_header_state_legacy::get_scheduled_producer( block_timestamp_type t ) const { return detail::get_scheduled_producer(active_schedule.producers, t); } @@ -34,7 +34,7 @@ namespace eosio::chain { (when = header.timestamp).slot++; } - auto proauth = get_scheduled_producer(when); + const auto& proauth = get_scheduled_producer(when); auto itr = producer_to_last_produced.find( proauth.producer_name ); if( itr != producer_to_last_produced.end() ) { diff --git a/libraries/chain/block_state.cpp b/libraries/chain/block_state.cpp index 35c77e78d1..275a8fdd95 100644 --- a/libraries/chain/block_state.cpp +++ b/libraries/chain/block_state.cpp @@ -19,13 +19,14 @@ block_state::block_state(const block_header_state& prev, signed_block_ptr b, con // ASSUMPTION FROM controller_impl::apply_block = all untrusted blocks will have their signatures pre-validated here if( !skip_validate_signee ) { auto sigs = detail::extract_additional_signatures(block); - verify_signee(sigs); + const auto& valid_block_signing_authority = prev.get_scheduled_producer(timestamp()).authority; + verify_signee(sigs, valid_block_signing_authority); } } block_state::block_state(const block_header_state& bhs, deque&& trx_metas, deque&& trx_receipts, const std::optional& qc, - const signer_callback_type& signer) + const signer_callback_type& signer, const block_signing_authority& valid_block_signing_authority) : block_header_state(bhs) , block(std::make_shared(signed_block_header{bhs.header})) // [greg todo] do we need signatures? , strong_digest(compute_finalizer_digest()) @@ -40,7 +41,7 @@ block_state::block_state(const block_header_state& bhs, dequeblock_extensions, quorum_certificate_extension::extension_id(), fc::raw::pack( *qc )); } - sign(signer); + sign(signer, valid_block_signing_authority); } // Used for transition from dpos to instant-finality @@ -214,20 +215,18 @@ void inject_additional_signatures( signed_block& b, const std::vectorproducer_signature = sigs.back(); sigs.pop_back(); - verify_signee(sigs); + verify_signee(sigs, valid_block_signing_authority); inject_additional_signatures(*block, sigs); } -void block_state::verify_signee(const std::vector& additional_signatures) const { - auto valid_block_signing_authority = get_scheduled_producer(timestamp()).authority; - +void block_state::verify_signee(const std::vector& additional_signatures, const block_signing_authority& valid_block_signing_authority) const { auto num_keys_in_authority = std::visit([](const auto &a){ return a.keys.size(); }, valid_block_signing_authority); EOS_ASSERT(1 + additional_signatures.size() <= num_keys_in_authority, wrong_signing_key, "number of block signatures (${num_block_signatures}) exceeds number of keys in block signing authority (${num_keys})", diff --git a/libraries/chain/controller.cpp b/libraries/chain/controller.cpp index 5722ec37d4..f04bd31622 100644 --- a/libraries/chain/controller.cpp +++ b/libraries/chain/controller.cpp @@ -322,7 +322,7 @@ struct assembled_block { } completed_block complete_block(const protocol_feature_set& pfs, validator_t validator, - const signer_callback_type& signer) { + const signer_callback_type& signer, const block_signing_authority& valid_block_signing_authority) { return std::visit(overloaded{[&](assembled_block_legacy& ab) { auto bsp = std::make_shared( std::move(ab.pending_block_header_state), std::move(ab.unsigned_block), @@ -332,7 +332,8 @@ struct assembled_block { }, [&](assembled_block_if& ab) { auto bsp = std::make_shared(ab.bhs, std::move(ab.trx_metas), - std::move(ab.trx_receipts), ab.qc, signer); + std::move(ab.trx_receipts), ab.qc, signer, + valid_block_signing_authority); return completed_block{std::move(bsp)}; }}, v); @@ -4205,10 +4206,12 @@ void controller::assemble_and_complete_block( block_report& br, const signer_cal my->assemble_block(); auto& ab = std::get(my->pending->_block_stage); + const auto& valid_block_signing_authority = my->head_active_schedule_auth().get_scheduled_producer(ab.timestamp()).authority; my->pending->_block_stage = ab.complete_block( my->protocol_features.get_protocol_feature_set(), [](block_timestamp_type timestamp, const flat_set& cur_features, const vector& new_features) {}, - signer_callback); + signer_callback, + valid_block_signing_authority); br = my->pending->_block_report; } diff --git a/libraries/chain/include/eosio/chain/block_header_state.hpp b/libraries/chain/include/eosio/chain/block_header_state.hpp index 62cba6ee03..dcb8d91366 100644 --- a/libraries/chain/include/eosio/chain/block_header_state.hpp +++ b/libraries/chain/include/eosio/chain/block_header_state.hpp @@ -82,7 +82,7 @@ struct block_header_state { flat_set get_activated_protocol_features() const { return activated_protocol_features->protocol_features; } const vector& get_new_protocol_feature_activations() const; - producer_authority get_scheduled_producer(block_timestamp_type t) const; + const producer_authority& get_scheduled_producer(block_timestamp_type t) const; }; using block_header_state_ptr = std::shared_ptr; diff --git a/libraries/chain/include/eosio/chain/block_header_state_legacy.hpp b/libraries/chain/include/eosio/chain/block_header_state_legacy.hpp index 964ac9ecb6..ee534a4954 100644 --- a/libraries/chain/include/eosio/chain/block_header_state_legacy.hpp +++ b/libraries/chain/include/eosio/chain/block_header_state_legacy.hpp @@ -170,7 +170,7 @@ struct block_header_state_legacy : public detail::block_header_state_legacy_comm uint32_t calc_dpos_last_irreversible( account_name producer_of_next_block )const; - producer_authority get_scheduled_producer( block_timestamp_type t )const; + const producer_authority& get_scheduled_producer( block_timestamp_type t )const; const block_id_type& previous()const { return header.previous; } digest_type sig_digest()const; void sign( const signer_callback_type& signer ); diff --git a/libraries/chain/include/eosio/chain/block_header_state_utils.hpp b/libraries/chain/include/eosio/chain/block_header_state_utils.hpp index 72c700bca9..1f4deeef65 100644 --- a/libraries/chain/include/eosio/chain/block_header_state_utils.hpp +++ b/libraries/chain/include/eosio/chain/block_header_state_utils.hpp @@ -20,7 +20,7 @@ namespace eosio::chain::detail { return block_timestamp_type{t.slot + (config::producer_repetitions - index) + config::producer_repetitions}; } - inline producer_authority get_scheduled_producer(const vector& producers, block_timestamp_type t) { + inline const producer_authority& get_scheduled_producer(const vector& producers, block_timestamp_type t) { auto index = t.slot % (producers.size() * config::producer_repetitions); index /= config::producer_repetitions; return producers[index]; diff --git a/libraries/chain/include/eosio/chain/block_state.hpp b/libraries/chain/include/eosio/chain/block_state.hpp index bb462fdb1a..575d419447 100644 --- a/libraries/chain/include/eosio/chain/block_state.hpp +++ b/libraries/chain/include/eosio/chain/block_state.hpp @@ -66,12 +66,12 @@ struct block_state : public block_header_state { // block_header_state provi block_state(const block_header_state& bhs, deque&& trx_metas, deque&& trx_receipts, const std::optional& qc, - const signer_callback_type& signer); + const signer_callback_type& signer, const block_signing_authority& valid_block_signing_authority); explicit block_state(const block_state_legacy& bsp); - void sign(const signer_callback_type& signer); - void verify_signee(const std::vector& additional_signatures) const; + void sign(const signer_callback_type& signer, const block_signing_authority& valid_block_signing_authority); + void verify_signee(const std::vector& additional_signatures, const block_signing_authority& valid_block_signing_authority) const; }; using block_state_ptr = std::shared_ptr;