Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/gh_2034_part2' into GH-1980-prop…
Browse files Browse the repository at this point in the history
…oser
  • Loading branch information
heifner committed Jan 12, 2024
2 parents d2af863 + be875ee commit 2c98018
Show file tree
Hide file tree
Showing 22 changed files with 408 additions and 386 deletions.
52 changes: 52 additions & 0 deletions libraries/chain/block_header_state.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,13 @@ block_header_state block_header_state::next(block_header_state_input& input) con
else
result.core = core;

if (!input.new_protocol_feature_activations.empty()) {
result.activated_protocol_features = std::make_shared<protocol_feature_activation_set>(
*activated_protocol_features, input.new_protocol_feature_activations);
} else {
result.activated_protocol_features = activated_protocol_features;
}

// add block header extensions
// ---------------------------
if (input.new_finalizer_policy)
Expand All @@ -110,5 +117,50 @@ block_header_state block_header_state::next(block_header_state_input& input) con
return result;
}

/**
* Transitions the current header state into the next header state given the supplied signed block header.
*
* Given a signed block header, generate the expected template based upon the header time,
* then validate that the provided header matches the template.
*
* If the header specifies new_producers then apply them accordingly.
*/
block_header_state block_header_state::next(const signed_block_header& h, const protocol_feature_set& pfs,
validator_t& validator) const {
auto producer = detail::get_scheduled_producer(proposer_policy->proposer_schedule.producers, h.timestamp).producer_name;

EOS_ASSERT( h.previous == id, unlinkable_block_exception, "previous mismatch" );
EOS_ASSERT( h.producer == producer, wrong_producer, "wrong producer specified" );

auto exts = h.validate_and_extract_header_extensions();

// handle protocol_feature_activation from incoming block
// ------------------------------------------------------
vector<digest_type> new_protocol_feature_activations;
if( exts.count(protocol_feature_activation::extension_id() > 0) ) {
const auto& entry = exts.lower_bound(protocol_feature_activation::extension_id());
new_protocol_feature_activations = std::move(std::get<protocol_feature_activation>(entry->second).protocol_features);
}

// retrieve instant_finality_extension data from block extension
// -------------------------------------------------------------
EOS_ASSERT(exts.count(instant_finality_extension::extension_id() > 0), misc_exception,
"Instant Finality Extension is expected to be present in all block headers after switch to IF");
const auto& if_entry = exts.lower_bound(instant_finality_extension::extension_id());
const auto& if_ext = std::get<instant_finality_extension>(if_entry->second);

building_block_input bb_input{
.parent_id = id,
.timestamp = h.timestamp,
.producer = producer,
.new_protocol_feature_activations = std::move(new_protocol_feature_activations)
};

block_header_state_input bhs_input{
bb_input, h.transaction_mroot, h.action_mroot, if_ext.new_proposer_policy, if_ext.new_finalizer_policy,
if_ext.qc_info};

return next(bhs_input);
}

} // namespace eosio::chain
9 changes: 4 additions & 5 deletions libraries/chain/block_header_state_legacy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -293,15 +293,15 @@ namespace eosio::chain {

if( maybe_new_producer_schedule ) {
result.pending_schedule.schedule = std::move(*maybe_new_producer_schedule);
result.pending_schedule.schedule_hash = std::move(*maybe_new_producer_schedule_hash);
result.pending_schedule.schedule_hash = *maybe_new_producer_schedule_hash;
result.pending_schedule.schedule_lib_num = block_number;
} else {
if( was_pending_promoted ) {
result.pending_schedule.schedule.version = prev_pending_schedule.schedule.version;
} else {
result.pending_schedule.schedule = std::move( prev_pending_schedule.schedule );
}
result.pending_schedule.schedule_hash = std::move( prev_pending_schedule.schedule_hash );
result.pending_schedule.schedule_hash = prev_pending_schedule.schedule_hash ;
result.pending_schedule.schedule_lib_num = prev_pending_schedule.schedule_lib_num;
}

Expand Down Expand Up @@ -369,13 +369,12 @@ namespace eosio::chain {
*/
block_header_state_legacy block_header_state_legacy::next(
const signed_block_header& h,
vector<signature_type>&& _additional_signatures,
vector<signature_type>&& additional_signatures,
const protocol_feature_set& pfs,
bool hotstuff_activated,
validator_t& validator,
bool skip_validate_signee )const
{
return next( h.timestamp, h.confirmed ).finish_next( h, std::move(_additional_signatures), pfs, validator, skip_validate_signee );
return next( h.timestamp, h.confirmed ).finish_next( h, std::move(additional_signatures), pfs, validator, skip_validate_signee );
}

digest_type block_header_state_legacy::sig_digest()const {
Expand Down
90 changes: 6 additions & 84 deletions libraries/chain/block_state.cpp
Original file line number Diff line number Diff line change
@@ -1,94 +1,16 @@
#include <eosio/chain/block_state.hpp>
#include <eosio/chain/block_header_state_utils.hpp>
#include <eosio/chain/exceptions.hpp>

namespace eosio::chain {

namespace {
constexpr auto additional_sigs_eid = additional_block_signatures_extension::extension_id();

/**
* Given a complete signed block, extract the validated additional signatures if present;
*
* @param b complete signed block
* @param pfs protocol feature set for digest access
* @param pfa activated protocol feature set to determine if extensions are allowed
* @return the list of additional signatures
* @throws if additional signatures are present before being supported by protocol feature activations
*/
vector<signature_type> extract_additional_signatures( const signed_block_ptr& b,
const protocol_feature_set& pfs,
const protocol_feature_activation_set_ptr& pfa )
{
auto exts = b->validate_and_extract_extensions();

if ( exts.count(additional_sigs_eid) > 0 ) {
auto& additional_sigs = std::get<additional_block_signatures_extension>(exts.lower_bound(additional_sigs_eid)->second);

return std::move(additional_sigs.signatures);
}

return {};
}

/**
* Given a pending block header state, wrap the promotion to a block header state such that additional signatures
* can be allowed based on activations *prior* to the promoted block and properly injected into the signed block
* that is previously constructed and mutated by the promotion
*
* This cleans up lifetime issues involved with accessing activated protocol features and moving from the
* pending block header state
*
* @param cur the pending block header state to promote
* @param b the signed block that will receive signatures during this process
* @param pfs protocol feature set for digest access
* @param extras all the remaining parameters that pass through
* @return the block header state
* @throws if the block was signed with multiple signatures before the extension is allowed
*/

template<typename ...Extras>
block_header_state inject_additional_signatures(block_header_state&& cur,
signed_block& b,
const protocol_feature_set& pfs,
Extras&& ... extras)
{

block_header_state result;
#if 0
result = std::move(cur).finish_next(b, pfs, std::forward<Extras>(extras)...);
auto pfa = cur.prev_activated_protocol_features;

if (!result.additional_signatures.empty()) {
bool wtmsig_enabled = detail::is_builtin_activated(pfa, pfs, builtin_protocol_feature_t::wtmsig_block_signatures);

EOS_ASSERT(wtmsig_enabled, block_validate_exception,
"Block has multiple signatures before activation of WTMsig Block Signatures");

// as an optimization we don't copy this out into the legitimate extension structure as it serializes
// the same way as the vector of signatures
static_assert(fc::reflector<additional_block_signatures_extension>::total_member_count == 1);
static_assert(std::is_same_v<decltype(additional_block_signatures_extension::signatures), std::vector<signature_type>>);

emplace_extension(b.block_extensions, additional_sigs_eid, fc::raw::pack( result.additional_signatures ));
}
#endif
return result;
}

}
#if 0

block_state::block_state(const block_header_state& prev,
signed_block_ptr b,
const protocol_feature_set& pfs,
bool hotstuff_activated,
const validator_t& validator,
bool skip_validate_signee
)
:block_header_state( prev.next( *b, extract_additional_signatures(b, pfs, prev.activated_protocol_features), pfs, hotstuff_activated, validator, skip_validate_signee ) )
,block( std::move(b) )
block_state::block_state(const block_header_state& prev, signed_block_ptr b, const protocol_feature_set& pfs,
const validator_t& validator, bool skip_validate_signee)
: block_header_state(prev.next(*b, pfs, validator))
, block(std::move(b))
{}

#if 0
block_state::block_state(pending_block_header_state&& cur,
signed_block_ptr&& b,
deque<transaction_metadata_ptr>&& trx_metas,
Expand Down
27 changes: 1 addition & 26 deletions libraries/chain/block_state_legacy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,30 +7,6 @@ namespace eosio { namespace chain {
namespace {
constexpr auto additional_sigs_eid = additional_block_signatures_extension::extension_id();

/**
* Given a complete signed block, extract the validated additional signatures if present;
*
* @param b complete signed block
* @param pfs protocol feature set for digest access
* @param pfa activated protocol feature set to determine if extensions are allowed
* @return the list of additional signatures
* @throws if additional signatures are present before being supported by protocol feature activations
*/
vector<signature_type> extract_additional_signatures( const signed_block_ptr& b,
const protocol_feature_set& pfs,
const protocol_feature_activation_set_ptr& pfa )
{
auto exts = b->validate_and_extract_extensions();

if ( exts.count(additional_sigs_eid) > 0 ) {
auto& additional_sigs = std::get<additional_block_signatures_extension>(exts.lower_bound(additional_sigs_eid)->second);

return std::move(additional_sigs.signatures);
}

return {};
}

/**
* Given a pending block header state, wrap the promotion to a block header state such that additional signatures
* can be allowed based on activations *prior* to the promoted block and properly injected into the signed block
Expand Down Expand Up @@ -78,11 +54,10 @@ namespace eosio { namespace chain {
block_state_legacy::block_state_legacy( const block_header_state_legacy& prev,
signed_block_ptr b,
const protocol_feature_set& pfs,
bool hotstuff_activated,
const validator_t& validator,
bool skip_validate_signee
)
:block_header_state_legacy( prev.next( *b, extract_additional_signatures(b, pfs, prev.activated_protocol_features), pfs, hotstuff_activated, validator, skip_validate_signee ) )
:block_header_state_legacy( prev.next( *b, detail::extract_additional_signatures(b), pfs, validator, skip_validate_signee ) )
,block( std::move(b) )
{}

Expand Down
Loading

0 comments on commit 2c98018

Please sign in to comment.