Skip to content

Commit

Permalink
single finalizer key
Browse files Browse the repository at this point in the history
  • Loading branch information
fcecin committed May 16, 2023
1 parent 9eb75c3 commit 74295f2
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 68 deletions.
51 changes: 10 additions & 41 deletions libraries/chain/include/eosio/chain/producer_schedule.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -334,15 +334,15 @@ namespace eosio { namespace chain {
shared_finalizer_authority& operator= ( shared_finalizer_authority && ) = default;
shared_finalizer_authority& operator= ( const shared_finalizer_authority & ) = default;

shared_finalizer_authority( const name& finalizer_name, const uint64_t fweight, shared_block_signing_authority&& authority )
shared_finalizer_authority( const name& finalizer_name, const uint64_t fweight, const public_key_type& public_key )
:finalizer_name(finalizer_name)
,fweight(fweight)
,authority(std::move(authority))
,public_key(public_key)
{}

name finalizer_name;
uint64_t fweight;
shared_block_signing_authority authority;
public_key_type public_key;
};

struct shared_finalizer_schedule {
Expand All @@ -365,48 +365,17 @@ namespace eosio { namespace chain {

name finalizer_name;
uint64_t fweight; // weight that this finalizer's vote has for meeting fthreshold
block_signing_authority authority;

template<typename Op>
static void for_each_key( const block_signing_authority& authority, Op&& op ) {
std::visit([&op](const auto &a){
a.for_each_key(std::forward<Op>(op));
}, authority);
}

template<typename Op>
void for_each_key( Op&& op ) const {
for_each_key(authority, std::forward<Op>(op));
}

static std::pair<bool, size_t> keys_satisfy_and_relevant( const std::set<public_key_type>& keys, const block_signing_authority& authority ) {
return std::visit([&keys](const auto &a){
return a.keys_satisfy_and_relevant(keys);
}, authority);
}

std::pair<bool, size_t> keys_satisfy_and_relevant( const std::set<public_key_type>& presented_keys ) const {
return keys_satisfy_and_relevant(presented_keys, authority);
}
public_key_type public_key;

auto to_shared(chainbase::allocator<char> alloc) const {
auto shared_auth = std::visit([&alloc](const auto& a) {
return a.to_shared(alloc);
}, authority);

return shared_finalizer_authority(finalizer_name, fweight, std::move(shared_auth));
return shared_finalizer_authority(finalizer_name, fweight, public_key);
}

static auto from_shared( const shared_finalizer_authority& src ) {
finalizer_authority result;
result.finalizer_name = src.finalizer_name;
result.fweight = src.fweight;
result.authority = std::visit(overloaded {
[](const shared_block_signing_authority_v0& a) {
return block_signing_authority_v0::from_shared(a);
}
}, src.authority);

result.public_key = src.public_key;
return result;
}

Expand All @@ -425,10 +394,10 @@ namespace eosio { namespace chain {
fc::variant get_abi_variant() const;

friend bool operator == ( const finalizer_authority& lhs, const finalizer_authority& rhs ) {
return tie( lhs.finalizer_name, lhs.fweight, lhs.authority ) == tie( rhs.finalizer_name, rhs.fweight, rhs.authority );
return tie( lhs.finalizer_name, lhs.fweight, lhs.public_key ) == tie( rhs.finalizer_name, rhs.fweight, rhs.public_key );
}
friend bool operator != ( const finalizer_authority& lhs, const finalizer_authority& rhs ) {
return tie( lhs.finalizer_name, lhs.fweight, lhs.authority ) != tie( rhs.finalizer_name, rhs.fweight, rhs.authority );
return tie( lhs.finalizer_name, lhs.fweight, lhs.public_key ) != tie( rhs.finalizer_name, rhs.fweight, rhs.public_key );
}
};

Expand Down Expand Up @@ -502,7 +471,7 @@ FC_REFLECT( eosio::chain::shared_producer_authority, (producer_name)(authority)
FC_REFLECT( eosio::chain::shared_producer_authority_schedule, (version)(producers) )

// TODO: move to finalizers.hpp
FC_REFLECT( eosio::chain::finalizer_authority, (finalizer_name)(fweight)(authority) )
FC_REFLECT( eosio::chain::finalizer_authority, (finalizer_name)(fweight)(public_key) )
FC_REFLECT( eosio::chain::finalizer_schedule, (version)(fthreshold)(finalizers) )
FC_REFLECT( eosio::chain::shared_finalizer_authority, (finalizer_name)(fweight)(authority) )
FC_REFLECT( eosio::chain::shared_finalizer_authority, (finalizer_name)(fweight)(public_key) )
FC_REFLECT( eosio::chain::shared_finalizer_schedule, (version)(fthreshold)(finalizers) )
32 changes: 9 additions & 23 deletions libraries/chain/webassembly/privileged.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -196,9 +196,9 @@ namespace eosio { namespace chain { namespace webassembly {
}
finalizer_authority {
name finalizer_name;
uint64 fweight; (among all finalizers)
block_signing_authority authority; // block_signing_authority object ( { int threshold, vector<> keys } ) is existing infrastructure
name finalizer_name;
uint64 fweight; (among all finalizers)
block_finalization_authority authority; // NEW: just one key per finalizer
}
*/

Expand All @@ -213,30 +213,16 @@ namespace eosio { namespace chain { namespace webassembly {

const size_t num_supported_key_types = context.db.get<protocol_state_object>().num_supported_key_types;

// check that finalizers are unique
// check that finalizers are unique and that the keys are valid BLS keys
std::set<account_name> unique_finalizers;
for (const auto& f: finalizers) {
EOS_ASSERT( context.is_account(f.finalizer_name), wasm_execution_error, "Finalizer schedule includes a nonexisting account" );
std::visit([&f, num_supported_key_types](const auto& a) {
uint32_t sum_weights = 0;
std::set<public_key_type> unique_keys;
for (const auto& kw: a.keys ) {
EOS_ASSERT( kw.key.which() < num_supported_key_types, unactivated_key_type, "Unactivated key type used in proposed finalizer schedule" );
EOS_ASSERT( kw.key.valid(), wasm_execution_error, "Finalizer schedule includes an invalid key" );

if (std::numeric_limits<uint32_t>::max() - sum_weights <= kw.weight) {
sum_weights = std::numeric_limits<uint32_t>::max();
} else {
sum_weights += kw.weight;
}

unique_keys.insert(kw.key);
}
EOS_ASSERT( f.public_key.which() < num_supported_key_types, unactivated_key_type, "Unactivated key type used in proposed finalizer schedule" );
EOS_ASSERT( f.public_key.valid(), wasm_execution_error, "Finalizer schedule includes an invalid key" );

EOS_ASSERT( a.keys.size() == unique_keys.size(), wasm_execution_error, "Finalizer schedule includes a duplicated key for ${account}", ("account", f.finalizer_name));
EOS_ASSERT( a.threshold > 0, wasm_execution_error, "Finalizer schedule includes an authority with a threshold of 0 for ${account}", ("account", f.finalizer_name));
EOS_ASSERT( sum_weights >= a.threshold, wasm_execution_error, "Finalizer schedule includes an unsatisfiable authority for ${account}", ("account", f.finalizer_name));
}, f.authority);
// -------------------------------------------
// FIXME/TODO: check for BLS/aggsig key type here
// -------------------------------------------

unique_finalizers.insert(f.finalizer_name);
}
Expand Down
8 changes: 4 additions & 4 deletions libraries/hotstuff/qc_chain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -507,14 +507,14 @@ namespace eosio { namespace hotstuff {

//TODO: check for duplicate or invalid vote. We will return in either case, but keep proposals for evidence of double signing

bool am_leader = am_i_leader();

if (!am_leader)
// only leader need to take action on votes
if (! am_i_leader())
return;

#ifdef QC_CHAIN_TRACE_DEBUG
ilog(" === Process vote from ${finalizer} : current bitset ${value}" , ("finalizer", vote.finalizer)("value", _current_qc.active_finalizers));
#endif
// only leader need to take action on votes

if (vote.proposal_id != _current_qc.proposal_id)
return;

Expand Down

0 comments on commit 74295f2

Please sign in to comment.