Skip to content

Commit

Permalink
GH-97 Update set_finalizers host function to take a packed_finalizer_…
Browse files Browse the repository at this point in the history
…format.
  • Loading branch information
heifner committed May 2, 2024
1 parent 5a3550a commit 1f52cfe
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 40 deletions.
20 changes: 12 additions & 8 deletions libraries/chain/include/eosio/chain/webassembly/interface.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -176,22 +176,26 @@ namespace webassembly {
/**
* Submits a finalizer set change.
*
* // format for packed finalizer_policy
* struct abi_finalizer_authority {
* // V0 format for packed finalizer_policy
* struct finalizer_authority {
* std::string description;
* uint64_t fweight = 0; // weight that this finalizer's vote has for meeting fthreshold
* std::array<uint8_t, 96> public_key_g1_affine_le;
* uint64_t weight = 0; // weight that this finalizer's vote has for meeting fthreshold
* std::vector<uint8_t> public_key; // Affine little endian non-montgomery g1, cdt/abi_serializer has issues with std::array, size 96
* };
* struct abi_finalizer_policy {
* uint64_t fthreshold = 0;
* std::vector<abi_finalizer_authority> finalizers;
* struct finalizer_policy {
* uint64_t threshold = 0;
* std::vector<finalizer_authority> finalizers;
* };
*
* Valid formats:
* 0 : serialized finalizer_policy
*
* @ingroup privileged
*
* @param packed_finalizer_format - format of the finalizer_policy data blob.
* @param packed_finalizer_policy - a serialized finalizer_policy object.
*/
void set_finalizers(span<const char> packed_finalizer_policy);
void set_finalizers(uint64_t packed_finalizer_format, span<const char> packed_finalizer_policy);

/**
* Retrieve the blockchain config parameters.
Expand Down
23 changes: 17 additions & 6 deletions libraries/chain/webassembly/privileged.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -163,15 +163,21 @@ namespace eosio { namespace chain { namespace webassembly {
std::vector<finalizer_authority> finalizers;
};

void interface::set_finalizers(span<const char> packed_finalizer_policy) {
EOS_ASSERT(!context.trx_context.is_read_only(), wasm_execution_error, "set_finalizers not allowed in a readonly transaction");
void interface::set_finalizers(uint64_t packed_finalizer_format, span<const char> packed_finalizer_policy) {
EOS_ASSERT(!context.trx_context.is_read_only(), wasm_execution_error,
"set_finalizers not allowed in a readonly transaction");
if (packed_finalizer_format != 0) {
EOS_THROW(wasm_execution_error, "Finalizer policy is in an unknown format!");
}

fc::datastream<const char*> ds( packed_finalizer_policy.data(), packed_finalizer_policy.size() );
finalizer_policy abi_finpol;
fc::raw::unpack(ds, abi_finpol);

std::vector<finalizer_authority>& finalizers = abi_finpol.finalizers;

EOS_ASSERT( finalizers.size() <= config::max_finalizers, wasm_execution_error, "Finalizer policy exceeds the maximum finalizer count for this chain" );
EOS_ASSERT( finalizers.size() <= config::max_finalizers, wasm_execution_error,
"Finalizer policy exceeds the maximum finalizer count for this chain" );
EOS_ASSERT( finalizers.size() > 0, wasm_execution_error, "Finalizers cannot be empty" );

std::set<fc::crypto::blslib::bls_public_key> unique_finalizer_keys;
Expand All @@ -183,17 +189,22 @@ namespace eosio { namespace chain { namespace webassembly {
for (auto& f: finalizers) {
EOS_ASSERT( f.description.size() <= config::max_finalizer_description_size, wasm_execution_error,
"Finalizer description greater than ${s}", ("s", config::max_finalizer_description_size) );
EOS_ASSERT(std::numeric_limits<uint64_t>::max() - weight_sum >= f.weight, wasm_execution_error, "sum of weights causes uint64_t overflow");
EOS_ASSERT(std::numeric_limits<uint64_t>::max() - weight_sum >= f.weight, wasm_execution_error,
"sum of weights causes uint64_t overflow");
weight_sum += f.weight;
EOS_ASSERT(f.public_key.size() == 96, wasm_execution_error, "Invalid bls public key length");
fc::crypto::blslib::bls_public_key pk(std::span<const uint8_t,96>(f.public_key.data(), 96));
EOS_ASSERT( unique_finalizer_keys.insert(pk).second, wasm_execution_error, "Duplicate public key: ${pk}", ("pk", pk.to_string()) );
EOS_ASSERT( unique_finalizer_keys.insert(pk).second, wasm_execution_error,
"Duplicate public key: ${pk}", ("pk", pk.to_string()) );
finpol.finalizers.push_back(chain::finalizer_authority{.description = std::move(f.description),
.weight = f.weight,
.public_key{pk}});
}

EOS_ASSERT( weight_sum >= finpol.threshold && finpol.threshold > weight_sum / 2, wasm_execution_error, "Finalizer policy threshold (${t}) must be greater than half of the sum of the weights (${w}), and less than or equal to the sum of the weights", ("t", finpol.threshold)("w", weight_sum) );
EOS_ASSERT( weight_sum >= finpol.threshold && finpol.threshold > weight_sum / 2, wasm_execution_error,
"Finalizer policy threshold (${t}) must be greater than half of the sum of the weights (${w}), "
"and less than or equal to the sum of the weights",
("t", finpol.threshold)("w", weight_sum) );

context.control.set_proposed_finalizers( std::move(finpol) );
}
Expand Down
10 changes: 5 additions & 5 deletions libraries/testing/contracts/eosio.bios/eosio.bios.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ void bios::setfinalizer( const finalizer_policy& finalizer_policy ) {
check(finalizer_policy.finalizers.size() <= max_finalizers, "number of finalizers exceeds the maximum allowed");
check(finalizer_policy.finalizers.size() > 0, "require at least one finalizer");

eosio::abi_finalizer_policy abi_finalizer_policy;
abi_finalizer_policy.fthreshold = finalizer_policy.threshold;
abi_finalizer_policy.finalizers.reserve(finalizer_policy.finalizers.size());
eosio::finalizer_policy fin_policy;
fin_policy.threshold = finalizer_policy.threshold;
fin_policy.finalizers.reserve(finalizer_policy.finalizers.size());

const std::string pk_prefix = "PUB_BLS";
const std::string sig_prefix = "SIG_BLS";
Expand Down Expand Up @@ -74,12 +74,12 @@ void bios::setfinalizer( const finalizer_policy& finalizer_policy ) {
check(eosio::bls_pop_verify(pk, signature), "proof of possession failed");

std::vector<char> pk_vector(pk.begin(), pk.end());
abi_finalizer_policy.finalizers.emplace_back(eosio::abi_finalizer_authority{f.description, f.weight, std::move(pk_vector)});
fin_policy.finalizers.emplace_back(eosio::finalizer_authority{f.description, f.weight, std::move(pk_vector)});
}

check(finalizer_policy.threshold > weight_sum / 2, "finalizer policy threshold must be greater than half of the sum of the weights");

set_finalizers(std::move(abi_finalizer_policy));
set_finalizers(std::move(fin_policy));
}

void bios::onerror( ignore<uint128_t>, ignore<std::vector<char>> ) {
Expand Down
Binary file modified libraries/testing/contracts/eosio.bios/eosio.bios.wasm
100644 → 100755
Binary file not shown.
38 changes: 19 additions & 19 deletions unittests/deep-mind/deep-mind.log

Large diffs are not rendered by default.

5 changes: 3 additions & 2 deletions unittests/protocol_feature_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ BOOST_AUTO_TEST_CASE( activate_preactivate_feature ) try {

// Cannot set latest bios contract since it requires intrinsics that have not yet been whitelisted.
BOOST_CHECK_EXCEPTION( c.set_code( config::system_account_name, contracts::eosio_bios_wasm() ),
wasm_exception, fc_exception_message_is("env.bls_fp_mod unresolveable")
wasm_exception, fc_exception_message_contains("unresolveable")
);

// But the old bios contract can still be set.
Expand Down Expand Up @@ -2360,11 +2360,12 @@ BOOST_AUTO_TEST_CASE( block_validation_after_stage_1_test ) { try {

static const char import_set_finalizers_wast[] = R"=====(
(module
(import "env" "set_finalizers" (func $set_finalizers (param i32 i32)))
(import "env" "set_finalizers" (func $set_finalizers (param i64 i32 i32)))
(memory $0 1)
(export "apply" (func $apply))
(func $apply (param $0 i64) (param $1 i64) (param $2 i64)
(call $set_finalizers
(i64.const 0)
(i32.const 0)
(i32.const 4)
)
Expand Down

0 comments on commit 1f52cfe

Please sign in to comment.