Skip to content

Commit

Permalink
GH-1510 Copy over eosio.bios contract with setfinalizer from Antelope…
Browse files Browse the repository at this point in the history
  • Loading branch information
heifner committed Dec 14, 2023
1 parent ec65222 commit 2a4ae34
Show file tree
Hide file tree
Showing 4 changed files with 123 additions and 178 deletions.
24 changes: 14 additions & 10 deletions libraries/testing/contracts/eosio.bios/eosio.bios.abi
Original file line number Diff line number Diff line change
Expand Up @@ -179,21 +179,25 @@
"type": "string"
},
{
"name": "fweight",
"name": "weight",
"type": "uint64"
},
{
"name": "public_key_g1_affine_le",
"type": "bytes"
"name": "public_key",
"type": "string"
},
{
"name": "pop",
"type": "string"
}
]
},
{
"name": "finalizer_set",
"name": "finalizer_policy",
"base": "",
"fields": [
{
"name": "fthreshold",
"name": "threshold",
"type": "uint64"
},
{
Expand Down Expand Up @@ -395,12 +399,12 @@
]
},
{
"name": "setfinset",
"name": "setfinalizer",
"base": "",
"fields": [
{
"name": "fin_set",
"type": "finalizer_set"
"name": "finalizer_policy",
"type": "finalizer_policy"
}
]
},
Expand Down Expand Up @@ -550,8 +554,8 @@
"ricardian_contract": ""
},
{
"name": "setfinset",
"type": "setfinset",
"name": "setfinalizer",
"type": "setfinalizer",
"ricardian_contract": ""
},
{
Expand Down
78 changes: 65 additions & 13 deletions libraries/testing/contracts/eosio.bios/eosio.bios.cpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
#include "eosio.bios.hpp"
#include <eosio/crypto_bls_ext.hpp>

extern "C" {
__attribute__((eosio_wasm_import))
void set_finalizers( void* params, size_t params_size );
};
#include <unordered_set>

namespace eosiobios {

Expand All @@ -22,6 +20,69 @@ void bios::setabi( name account, const std::vector<char>& abi ) {
}
}

void bios::setfinalizer( const finalizer_policy& finalizer_policy ) {
// exensive checks are performed to make sure setfinalizer host function
// will never fail

require_auth( get_self() );

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());

const std::string pk_prefix = "PUB_BLS";
const std::string sig_prefix = "SIG_BLS";

// use raw affine format (bls_g1 is std::array<char, 96>) for uniqueness check
struct g1_hash {
std::size_t operator()(const eosio::bls_g1& g1) const {
std::hash<const char*> hash_func;
return hash_func(g1.data());
}
};
struct g1_equal {
bool operator()(const eosio::bls_g1& lhs, const eosio::bls_g1& rhs) const {
return std::memcmp(lhs.data(), rhs.data(), lhs.size()) == 0;
}
};
std::unordered_set<eosio::bls_g1, g1_hash, g1_equal> unique_finalizer_keys;

uint64_t weight_sum = 0;

for (const auto& f: finalizer_policy.finalizers) {
check(f.description.size() <= max_finalizer_description_size, "Finalizer description greater than max allowed size");

// basic key format checks
check(f.public_key.substr(0, pk_prefix.length()) == pk_prefix, "public key not started with PUB_BLS");
check(f.pop.substr(0, sig_prefix.length()) == sig_prefix, "proof of possession signature not started with SIG_BLS");

// check overflow
check(std::numeric_limits<uint64_t>::max() - weight_sum >= f.weight, "sum of weights causes uint64_t overflow");
weight_sum += f.weight;

// decode_bls_public_key_to_g1 will fail ("check" function fails)
// if the key is invalid
const auto pk = eosio::decode_bls_public_key_to_g1(f.public_key);
// duplicate key check
check(unique_finalizer_keys.insert(pk).second, "duplicate public key");

const auto signature = eosio::decode_bls_signature_to_g2(f.pop);

// proof of possession of private key check
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)});
}

check(finalizer_policy.threshold > weight_sum / 2, "finalizer policy threshold cannot be met by finalizer weights");

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

void bios::onerror( ignore<uint128_t>, ignore<std::vector<char>> ) {
check( false, "the onerror action cannot be called directly" );
}
Expand All @@ -41,14 +102,6 @@ void bios::setprods( const std::vector<eosio::producer_authority>& schedule ) {
set_proposed_producers( schedule );
}

void bios::setfinset( const finalizer_set& fin_set ) {
require_auth( get_self() );

// until CDT provides a set_finalizers
auto packed_fin_set = eosio::pack( fin_set );
set_finalizers((void*)packed_fin_set.data(), packed_fin_set.size());
}

void bios::setparams( const eosio::blockchain_parameters& params ) {
require_auth( get_self() );
set_blockchain_parameters( params );
Expand All @@ -61,7 +114,6 @@ void bios::reqauth( name from ) {
void bios::activate( const eosio::checksum256& feature_digest ) {
require_auth( get_self() );
preactivate_feature( feature_digest );
print( "feature digest activated: ", feature_digest, "\n" );
}

void bios::reqactivated( const eosio::checksum256& feature_digest ) {
Expand Down
Loading

0 comments on commit 2a4ae34

Please sign in to comment.