Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[1.0.1 -> main] Make signed_block_ptr const #761

Merged
merged 10 commits into from
Sep 12, 2024
66 changes: 36 additions & 30 deletions libraries/chain/block_state.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ namespace eosio::chain {

namespace detail {

inline void verify_signee(const signed_block_ptr& block, const block_id_type& block_id,
inline void verify_signee(const signature_type& producer_signature, const block_id_type& block_id,
const std::vector<signature_type>& additional_signatures,
const block_signing_authority& valid_block_signing_authority)
{
Expand All @@ -24,7 +24,7 @@ namespace detail {
("authority", valid_block_signing_authority));

std::set<public_key_type> keys;
keys.emplace(fc::crypto::public_key(block->producer_signature, block_id, true));
keys.emplace(fc::crypto::public_key(producer_signature, block_id, true));

for (const auto& s : additional_signatures) {
auto res = keys.emplace(s, block_id, true);
Expand All @@ -51,11 +51,36 @@ namespace detail {
if (!skip_validate_signee) {
auto sigs = detail::extract_additional_signatures(block);
const auto& valid_block_signing_authority = prev.get_producer_for_block_at(block->timestamp).authority;
verify_signee(block, block->calculate_id(), sigs, valid_block_signing_authority);
verify_signee(block->producer_signature, block->calculate_id(), sigs, valid_block_signing_authority);
}
return true;
};

void inject_additional_signatures( signed_block& b, const std::vector<signature_type>& additional_signatures) {
if (!additional_signatures.empty()) {
// 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_block_signatures_extension::extension_id(),
fc::raw::pack(additional_signatures));
}
}

void sign(signed_block& block, const block_id_type& block_id,
const signer_callback_type& signer, const block_signing_authority& valid_block_signing_authority) {
auto sigs = signer(block_id);

EOS_ASSERT(!sigs.empty(), no_block_signatures, "Signer returned no signatures");
block.producer_signature = sigs.back();
// last is producer signature, rest are additional signatures to inject in the block extension
sigs.pop_back();

verify_signee(block.producer_signature, block_id, sigs, valid_block_signing_authority);
inject_additional_signatures(block, sigs);
}

} // namespace detail

using namespace eosio::chain::detail;
Expand All @@ -80,7 +105,7 @@ block_state::block_state(const block_header_state& bhs,
const block_signing_authority& valid_block_signing_authority,
const digest_type& action_mroot)
: block_header_state(bhs)
, block(std::make_shared<signed_block>(signed_block_header{bhs.header}))
, block()
, strong_digest(compute_finality_digest())
, weak_digest(create_weak_digest(strong_digest))
, aggregating_qc(active_finalizer_policy, pending_finalizer_policy ? pending_finalizer_policy->second : finalizer_policy_ptr{})
Expand All @@ -89,14 +114,18 @@ block_state::block_state(const block_header_state& bhs,
, cached_trxs(std::move(trx_metas))
, action_mroot(action_mroot)
{
block->transactions = std::move(trx_receipts);
mutable_signed_block_ptr new_block = std::make_shared<signed_block>(signed_block_header{bhs.header});
new_block->transactions = std::move(trx_receipts);

if( qc ) {
fc_dlog(vote_logger, "integrate qc ${qc} into block ${bn} ${id}", ("qc", qc->to_qc_claim())("bn", block_num())("id", id()));
emplace_extension(block->block_extensions, quorum_certificate_extension::extension_id(), fc::raw::pack( *qc ));
emplace_extension(new_block->block_extensions,
quorum_certificate_extension::extension_id(), fc::raw::pack( *qc ));
}

sign(signer, valid_block_signing_authority);
sign(*new_block, block_id, signer, valid_block_signing_authority);

block = std::move(new_block);
}

// Used for transition from dpos to Savanna.
Expand Down Expand Up @@ -352,27 +381,4 @@ finality_data_t block_state::get_finality_data() {
};
}

void inject_additional_signatures( signed_block& b, const std::vector<signature_type>& additional_signatures)
{
if (!additional_signatures.empty()) {
// 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_block_signatures_extension::extension_id(), fc::raw::pack( additional_signatures ));
}
}

void block_state::sign(const signer_callback_type& signer, const block_signing_authority& valid_block_signing_authority ) {
auto sigs = signer( block_id );

EOS_ASSERT(!sigs.empty(), no_block_signatures, "Signer returned no signatures");
block->producer_signature = sigs.back(); // last is producer signature, rest are additional signatures to inject in the block extension
sigs.pop_back();

verify_signee(block, block_id, sigs, valid_block_signing_authority);
inject_additional_signatures(*block, sigs);
}

} /// eosio::chain
2 changes: 1 addition & 1 deletion libraries/chain/block_state_legacy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ namespace eosio::chain {
{}

block_state_legacy::block_state_legacy( pending_block_header_state_legacy&& cur,
signed_block_ptr&& b,
mutable_signed_block_ptr&& b,
deque<transaction_metadata_ptr>&& trx_metas,
const std::optional<digests_t>& action_receipt_digests_savanna,
const protocol_feature_set& pfs,
Expand Down
4 changes: 2 additions & 2 deletions libraries/chain/controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ struct assembled_block {
block_id_type id;
pending_block_header_state_legacy pending_block_header_state;
deque<transaction_metadata_ptr> trx_metas;
signed_block_ptr unsigned_block;
mutable_signed_block_ptr unsigned_block;

// if the unsigned_block pre-dates block-signing authorities this may be present.
std::optional<producer_authority_schedule> new_producer_authority_cache;
Expand Down Expand Up @@ -5519,7 +5519,7 @@ bool controller::validated_block_exists(const block_id_type& id) const {

std::optional<signed_block_header> controller::fetch_block_header_by_id( const block_id_type& id )const {
auto sb_ptr = my->fork_db_fetch_block_by_id(id);
if( sb_ptr ) return std::optional<signed_block_header>{*static_cast<signed_block_header*>(sb_ptr.get())};
if( sb_ptr ) return std::optional<signed_block_header>{*static_cast<const signed_block_header*>(sb_ptr.get())};
auto result = my->blog.read_block_header_by_num( block_header::num_from_id(id) );
if( result && result->calculate_id() == id ) return result;
return {};
Expand Down
3 changes: 2 additions & 1 deletion libraries/chain/include/eosio/chain/block.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,8 @@ namespace eosio { namespace chain {
}
bool contains_extension(uint16_t extension_id)const;
};
using signed_block_ptr = std::shared_ptr<signed_block>;
using signed_block_ptr = std::shared_ptr<const signed_block>;
using mutable_signed_block_ptr = std::shared_ptr<signed_block>;

struct producer_confirmation {
block_id_type block_id;
Expand Down
2 changes: 0 additions & 2 deletions libraries/chain/include/eosio/chain/block_state.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -184,8 +184,6 @@ struct block_state : public block_header_state { // block_header_state provi

explicit block_state(snapshot_detail::snapshot_block_state_v8&& sbs);

void sign(const signer_callback_type& signer, const block_signing_authority& valid_block_signing_authority);

// Only defined for latest_qc_block_num() <= num <= block_num()
finalizer_policies_t get_finalizer_policies(block_num_type num) const {
if (num == block_num())
Expand Down
2 changes: 1 addition & 1 deletion libraries/chain/include/eosio/chain/block_state_legacy.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ namespace eosio::chain {
);

block_state_legacy( pending_block_header_state_legacy&& cur,
signed_block_ptr&& b, // unsigned block
mutable_signed_block_ptr&& b, // unsigned block
deque<transaction_metadata_ptr>&& trx_metas,
const std::optional<digests_t>& action_receipt_digests_savanna,
const protocol_feature_set& pfs,
Expand Down
12 changes: 6 additions & 6 deletions libraries/libfc/include/fc/io/raw.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,12 @@ namespace fc {
inline void unpack( Stream& s, std::shared_ptr<T>& v)
{ try {
bool b; fc::raw::unpack( s, b );
if( b ) { v = std::make_shared<T>(); fc::raw::unpack( s, *v ); }
if( b ) {
// want to be able to unpack std::shared_ptr<const T>
auto tmp = std::make_shared<std::remove_const_t<T>>();
fc::raw::unpack( s, *tmp );
v = std::move(tmp);
}
} FC_RETHROW_EXCEPTIONS( warn, "std::shared_ptr<T>", ("type",fc::get_typename<T>::name()) ) }

template<typename Stream> inline void pack( Stream& s, const signed_int& v ) {
Expand Down Expand Up @@ -245,11 +250,6 @@ namespace fc {
vi.value = static_cast<uint32_t>(v);
}

template<typename Stream, typename T> inline void unpack( Stream& s, const T& vi )
{
static_assert(not std::is_same_v<const T, const T>, "can't unpack const type");
}

template<typename Stream> inline void pack( Stream& s, const char* v ) {
size_t sz = std::strlen(v);
FC_ASSERT( sz <= MAX_SIZE_OF_BYTE_ARRAYS );
Expand Down
1 change: 0 additions & 1 deletion libraries/libfc/include/fc/io/raw_fwd.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,6 @@ namespace fc {


template<typename Stream, typename T> void unpack( Stream& s, std::optional<T>& v );
template<typename Stream, typename T> void unpack( Stream& s, const T& v );
template<typename Stream, typename T> void pack( Stream& s, const std::optional<T>& v );
template<typename Stream, typename T> void pack( Stream& s, const safe<T>& v );
template<typename Stream, typename T> void unpack( Stream& s, fc::safe<T>& v );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ chain::transaction_trace_ptr make_transaction_trace( const packed_transaction_pt

auto make_block( uint32_t block_num ) {
name producer = "brianj"_n;
chain::signed_block_ptr block = std::make_shared<chain::signed_block>();
auto block = std::make_shared<chain::signed_block>();
block->producer = producer;
block->timestamp = fc::time_point::now();

Expand Down
2 changes: 1 addition & 1 deletion plugins/chain_plugin/test/test_trx_retry_db.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ uint64_t get_id( const packed_transaction_ptr& ptr ) {

auto make_block( uint32_t block_num, std::vector<chain::packed_transaction_ptr> trxs ) {
name producer = "kevinh"_n;
chain::signed_block_ptr block = std::make_shared<chain::signed_block>();
auto block = std::make_shared<chain::signed_block>();
for( auto& trx : trxs ) {
block->transactions.emplace_back( *trx );
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ namespace eosio::trace_api {

inline auto make_block( chain::block_id_type previous, uint32_t height, uint32_t slot, chain::name producer,
std::vector<chain::packed_transaction> trxs ) {
chain::signed_block_ptr block = std::make_shared<chain::signed_block>();
auto block = std::make_shared<chain::signed_block>();
for( auto& trx : trxs ) {
block->transactions.emplace_back( trx );
}
Expand Down
2 changes: 1 addition & 1 deletion tests/block_log.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ struct block_log_fixture {
std::vector<char> a;
a.assign(size, fillchar);

eosio::chain::signed_block_ptr p = std::make_shared<eosio::chain::signed_block>();
auto p = std::make_shared<eosio::chain::signed_block>();
p->previous._hash[0] = fc::endian_reverse_u32(index-1);
p->header_extensions.push_back(std::make_pair<uint16_t, std::vector<char>>(0, std::vector<char>(a)));

Expand Down
2 changes: 1 addition & 1 deletion tests/chain_plugin_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ BOOST_FIXTURE_TEST_CASE( get_block_with_invalid_abi, validating_tester ) try {

BOOST_TEST(get_bh_result.id == block->calculate_id());
BOOST_TEST(json::to_string(get_bh_result.signed_block_header, fc::time_point::maximum()) ==
json::to_string(fc::variant{static_cast<signed_block_header&>(*block)}, fc::time_point::maximum()));
json::to_string(fc::variant{static_cast<const signed_block_header&>(*block)}, fc::time_point::maximum()));

} FC_LOG_AND_RETHROW() /// get_block_with_invalid_abi

Expand Down
2 changes: 1 addition & 1 deletion unittests/block_log_extract.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ struct block_log_extract_fixture {
};

void add(uint32_t index) {
signed_block_ptr p = std::make_shared<signed_block>();
auto p = std::make_shared<signed_block>();
p->previous._hash[0] = fc::endian_reverse_u32(index-1);
log->append(p, p->calculate_id());
}
Expand Down
7 changes: 4 additions & 3 deletions unittests/producer_schedule_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -678,7 +678,7 @@ BOOST_AUTO_TEST_CASE( extra_signatures_test ) try {
main.produce_blocks(3);
BOOST_REQUIRE( main.control->pending_block_producer() == "alice"_n );

std::shared_ptr<signed_block> b;
mutable_signed_block_ptr b;

// Generate a valid block and then corrupt it by adding an extra signature.
{
Expand All @@ -694,7 +694,7 @@ BOOST_AUTO_TEST_CASE( extra_signatures_test ) try {
BOOST_REQUIRE( valid_block->producer == "alice"_n );

// Make a copy of pointer to the valid block.
b = valid_block;
b = std::make_shared<signed_block>(valid_block->clone());
BOOST_REQUIRE_EQUAL( b->block_extensions.size(), 1u );

// Extract the existing signatures.
Expand All @@ -712,7 +712,8 @@ BOOST_AUTO_TEST_CASE( extra_signatures_test ) try {

// Serialize the augmented additional signatures back into the block extensions.
b->block_extensions.clear();
emplace_extension(b->block_extensions, additional_sigs_eid, fc::raw::pack( additional_sigs ));
emplace_extension(b->block_extensions,
additional_sigs_eid, fc::raw::pack( additional_sigs ));
}

// Push block with extra signature to the main chain.
Expand Down
2 changes: 1 addition & 1 deletion unittests/unapplied_transaction_queue_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ auto next( unapplied_transaction_queue& q ) {
}

auto create_test_block_state( deque<transaction_metadata_ptr> trx_metas ) {
signed_block_ptr block = std::make_shared<signed_block>();
auto block = std::make_shared<signed_block>();
for( auto& trx_meta : trx_metas ) {
block->transactions.emplace_back( *trx_meta->packed_trx() );
}
Expand Down
6 changes: 3 additions & 3 deletions unittests/vote_processor_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ bls_private_key bls_priv_key_2 = bls_private_key::generate();
std::vector<bls_private_key> bls_priv_keys{bls_priv_key_0, bls_priv_key_1, bls_priv_key_2};

auto create_genesis_block_state() { // block 2
signed_block_ptr block = std::make_shared<signed_block>();
auto block = std::make_shared<signed_block>();

block->producer = eosio::chain::config::system_account_name;
auto pub_key = eosio::testing::base_tester::get_public_key( block->producer, "active" );
Expand All @@ -53,10 +53,10 @@ auto create_genesis_block_state() { // block 2

producer_authority_schedule schedule = { 0, { producer_authority{block->producer, block_signing_authority_v0{ 1, {{pub_key, 1}} } } } };
auto genesis = std::make_shared<block_state>();
block->previous = make_block_id(1);
genesis->block = block;
genesis->activated_protocol_features = std::make_shared<protocol_feature_activation_set>();
genesis->active_finalizer_policy = std::make_shared<finalizer_policy>(new_finalizer_policy);
genesis->block->previous = make_block_id(1);
genesis->active_proposer_policy = std::make_shared<proposer_policy>(proposer_policy{.proposer_schedule = schedule});
genesis->core = finality_core::create_core_for_genesis_block(genesis->block_id, genesis->header.timestamp);
genesis->block_id = genesis->block->calculate_id();
Expand All @@ -66,7 +66,7 @@ auto create_genesis_block_state() { // block 2
auto create_test_block_state(const block_state_ptr& prev) {
static block_timestamp_type timestamp;
timestamp = timestamp.next(); // each test block state will be unique
signed_block_ptr block = std::make_shared<signed_block>(prev->block->clone());
auto block = std::make_shared<signed_block>(prev->block->clone());
block->producer = eosio::chain::config::system_account_name;
block->previous = prev->id();
block->timestamp = timestamp;
Expand Down