Skip to content

Commit

Permalink
Merge pull request #2011 from AntelopeIO/block_extension_qc
Browse files Browse the repository at this point in the history
IF: add latest commit QC known to proposer to block extension (part 1)
  • Loading branch information
linh2931 authored Jan 4, 2024
2 parents d86c721 + 2a30c5e commit a25a8c4
Show file tree
Hide file tree
Showing 12 changed files with 178 additions and 4 deletions.
5 changes: 5 additions & 0 deletions libraries/chain/block.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ namespace eosio { namespace chain {
}
}

void quorum_certificate_extension::reflector_init() {
static_assert( fc::raw::has_feature_reflector_init_on_unpacked_reflected_types, "quorum_certificate_extension expects FC to support reflector_init" );
static_assert( extension_id() == 3, "extension id for quorum_certificate_extension must be 3" );
}

flat_multimap<uint16_t, block_extension> signed_block::validate_and_extract_extensions()const {
using decompose_t = block_extension_types::decompose_t;

Expand Down
7 changes: 7 additions & 0 deletions libraries/chain/include/eosio/chain/abi_serializer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <eosio/chain/exceptions.hpp>
#include <utility>
#include <fc/variant_object.hpp>
#include <fc/variant_dynamic_bitset.hpp>
#include <fc/scoped_exit.hpp>
#include <fc/time.hpp>

Expand Down Expand Up @@ -690,6 +691,12 @@ namespace impl {
std::get<additional_block_signatures_extension>(block_exts.lower_bound(additional_block_signatures_extension::extension_id())->second);
mvo("additional_signatures", additional_signatures);
}
auto qc_extension_count = block_exts.count(quorum_certificate_extension::extension_id());
if ( qc_extension_count > 0) {
const auto& qc_extension =
std::get<quorum_certificate_extension>(block_exts.lower_bound(quorum_certificate_extension::extension_id())->second);
mvo("qc_extension", qc_extension);
}

out(name, std::move(mvo));
}
Expand Down
23 changes: 22 additions & 1 deletion libraries/chain/include/eosio/chain/block.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once
#include <eosio/chain/block_header.hpp>
#include <eosio/chain/transaction.hpp>
#include <eosio/chain/hotstuff/hotstuff.hpp>

namespace eosio { namespace chain {

Expand Down Expand Up @@ -70,6 +71,25 @@ namespace eosio { namespace chain {
vector<signature_type> signatures;
};

struct quorum_certificate_extension : fc::reflect_init {
static constexpr uint16_t extension_id() { return 3; }
static constexpr bool enforce_unique() { return true; }

quorum_certificate_extension() = default;

quorum_certificate_extension( const quorum_certificate& qc)
:qc( qc )
{}

quorum_certificate_extension( quorum_certificate&& qc)
:qc( std::move(qc) )
{}

void reflector_init();

quorum_certificate qc;
};

namespace detail {
template<typename... Ts>
struct block_extension_types {
Expand All @@ -79,7 +99,7 @@ namespace eosio { namespace chain {
}

using block_extension_types = detail::block_extension_types<
additional_block_signatures_extension
additional_block_signatures_extension, quorum_certificate_extension
>;

using block_extension = block_extension_types::block_extension_t;
Expand Down Expand Up @@ -119,4 +139,5 @@ FC_REFLECT_ENUM( eosio::chain::transaction_receipt::status_enum,
FC_REFLECT(eosio::chain::transaction_receipt_header, (status)(cpu_usage_us)(net_usage_words) )
FC_REFLECT_DERIVED(eosio::chain::transaction_receipt, (eosio::chain::transaction_receipt_header), (trx) )
FC_REFLECT(eosio::chain::additional_block_signatures_extension, (signatures));
FC_REFLECT(eosio::chain::quorum_certificate_extension, (qc));
FC_REFLECT_DERIVED(eosio::chain::signed_block, (eosio::chain::signed_block_header), (transactions)(block_extensions) )
1 change: 0 additions & 1 deletion libraries/chain/include/eosio/chain/exceptions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,6 @@ namespace eosio { namespace chain {
FC_DECLARE_DERIVED_EXCEPTION( ill_formed_additional_block_signatures_extension, block_validate_exception,
3030013, "Block includes an ill-formed additional block signature extension" )


FC_DECLARE_DERIVED_EXCEPTION( transaction_exception, chain_exception,
3040000, "Transaction exception" )

Expand Down
2 changes: 2 additions & 0 deletions libraries/chain/include/eosio/chain/hotstuff/hotstuff.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -243,3 +243,5 @@ FC_REFLECT(eosio::chain::hs_proposal_message, (proposal_id)(block_id)(parent_id)
FC_REFLECT(eosio::chain::hs_new_view_message, (high_qc));
FC_REFLECT(eosio::chain::finalizer_state, (b_leaf)(b_lock)(b_exec)(b_finality_violation)(block_exec)(pending_proposal_block)(v_height)(high_qc)(current_qc)(schedule)(proposals));
FC_REFLECT(eosio::chain::hs_message, (msg));
FC_REFLECT(eosio::chain::valid_quorum_certificate, (_proposal_id)(_proposal_digest)(_strong_votes)(_weak_votes)(_sig));
FC_REFLECT(eosio::chain::quorum_certificate, (block_height)(qc));
1 change: 1 addition & 0 deletions libraries/libfc/include/fc/io/datastream.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,7 @@ inline datastream<ST>& operator>>(datastream<ST>& ds, uint8_t& d) {
ds.read((char*)&d, sizeof(d) );
return ds;
}

/*
template<typename ST, typename T>
inline datastream<ST>& operator<<(datastream<ST>& ds, const boost::multiprecision::number<T>& n) {
Expand Down
31 changes: 31 additions & 0 deletions libraries/libfc/include/fc/io/raw.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include <list>

#include <boost/multiprecision/cpp_int.hpp>
#include <boost/dynamic_bitset.hpp>
#include <fc/crypto/hex.hpp>

namespace fc {
Expand All @@ -34,6 +35,8 @@ namespace fc {
template<typename Stream> void unpack( Stream& s, Int<256>& n );
template<typename Stream, typename T> void pack( Stream& s, const boost::multiprecision::number<T>& n );
template<typename Stream, typename T> void unpack( Stream& s, boost::multiprecision::number<T>& n );
template<typename Stream, typename T> void pack( Stream& s, const boost::dynamic_bitset<T>& bs );
template<typename Stream, typename T> void unpack( Stream& s, boost::dynamic_bitset<T>& bs );

template<typename Stream, typename Arg0, typename... Args>
inline void pack( Stream& s, const Arg0& a0, const Args&... args ) {
Expand Down Expand Up @@ -564,6 +567,34 @@ namespace fc {
}
}

template<typename Stream, typename T>
inline void pack( Stream& s, const boost::dynamic_bitset<T>& value ) {
const auto num_blocks = value.num_blocks();
FC_ASSERT( num_blocks <= MAX_NUM_ARRAY_ELEMENTS );
fc::raw::pack( s, unsigned_int((uint32_t)num_blocks) );

// convert bitset to a vector of blocks
std::vector<T> blocks;
blocks.resize(num_blocks);
boost::to_block_range(value, blocks.begin());

// pack the blocks
for (const auto& b: blocks) {
fc::raw::pack( s, b );
}
}

template<typename Stream, typename T>
inline void unpack( Stream& s, boost::dynamic_bitset<T>& value ) {
unsigned_int size; fc::raw::unpack( s, size );
FC_ASSERT( size.value <= MAX_NUM_ARRAY_ELEMENTS );
std::vector<T> blocks((size_t)size.value);
for( uint64_t i = 0; i < size.value; ++i ) {
fc::raw::unpack( s, blocks[i] );
}
value = { blocks.cbegin(), blocks.cend() };
}

template<typename Stream, typename T>
inline void pack( Stream& s, const std::vector<T>& value ) {
FC_ASSERT( value.size() <= MAX_NUM_ARRAY_ELEMENTS );
Expand Down
31 changes: 31 additions & 0 deletions libraries/libfc/include/fc/variant_dynamic_bitset.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#pragma once

#include <fc/variant.hpp>
#include <boost/dynamic_bitset.hpp>

namespace fc
{
template<typename T> void to_variant( const boost::dynamic_bitset<T>& bs, fc::variant& v ) {
auto num_blocks = bs.num_blocks();
if ( num_blocks > MAX_NUM_ARRAY_ELEMENTS ) throw std::range_error( "number of blocks of dynamic_bitset cannot be greather than MAX_NUM_ARRAY_ELEMENTS" );

std::vector<T> blocks(num_blocks);
boost::to_block_range(bs, blocks.begin());

v = fc::variant(blocks);
}

template<typename T> void from_variant( const fc::variant& v, boost::dynamic_bitset<T>& bs ) {
const std::vector<fc::variant>& vars = v.get_array();
auto num_vars = vars.size();
if( num_vars > MAX_NUM_ARRAY_ELEMENTS ) throw std::range_error( "number of variants for dynamic_bitset cannot be greather than MAX_NUM_ARRAY_ELEMENTS" );

std::vector<T> blocks;
blocks.reserve(num_vars);
for( const auto& var: vars ) {
blocks.push_back( var.as<T>() );
}

bs = { blocks.cbegin(), blocks.cend() };
}
} // namespace fc
2 changes: 2 additions & 0 deletions libraries/libfc/test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,13 @@ add_executable( test_fc
crypto/test_webauthn.cpp
io/test_cfile.cpp
io/test_json.cpp
io/test_raw.cpp
io/test_tracked_storage.cpp
network/test_message_buffer.cpp
scoped_exit/test_scoped_exit.cpp
static_variant/test_static_variant.cpp
variant/test_variant.cpp
variant/test_variant_dynamic_bitset.cpp
variant_estimated_size/test_variant_estimated_size.cpp
test_base64.cpp
test_escape_str.cpp
Expand Down
38 changes: 38 additions & 0 deletions libraries/libfc/test/io/test_raw.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#include <fc/exception/exception.hpp>
#include <fc/io/raw.hpp>

#include <boost/test/unit_test.hpp>
#include <boost/dynamic_bitset.hpp>

using namespace fc;

BOOST_AUTO_TEST_SUITE(raw_test_suite)


BOOST_AUTO_TEST_CASE(dynamic_bitset_test)
{
constexpr uint8_t bits = 0b00011110;
boost::dynamic_bitset<uint8_t> bs1(8, bits); // bit set size 8

char buff[4];
datastream<char*> ds(buff, sizeof(buff));

fc::raw::pack( ds, bs1 );

boost::dynamic_bitset<uint8_t> bs2(8);
ds.seekp(0);
fc::raw::unpack( ds, bs2 );

// 0b00011110
BOOST_CHECK(!bs2.test(0));
BOOST_CHECK(bs2.test(1));
BOOST_CHECK(bs2.test(2));
BOOST_CHECK(bs2.test(2));
BOOST_CHECK(bs2.test(3));
BOOST_CHECK(bs2.test(4));
BOOST_CHECK(!bs2.test(5));
BOOST_CHECK(!bs2.test(6));
BOOST_CHECK(!bs2.test(7));
}

BOOST_AUTO_TEST_SUITE_END()
5 changes: 3 additions & 2 deletions libraries/libfc/test/variant/test_variant.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
#include <boost/test/unit_test.hpp>

#include <fc/variant_object.hpp>
#include <fc/exception/exception.hpp>
#include <fc/crypto/base64.hpp>

#include <boost/test/unit_test.hpp>

#include <string>

using namespace fc;
Expand Down
36 changes: 36 additions & 0 deletions libraries/libfc/test/variant/test_variant_dynamic_bitset.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#include <fc/variant_dynamic_bitset.hpp>
#include <fc/variant_object.hpp>
#include <fc/exception/exception.hpp>

#include <boost/test/unit_test.hpp>

#include <string>

using namespace fc;
using std::string;

BOOST_AUTO_TEST_SUITE(dynamic_bitset_test_suite)

BOOST_AUTO_TEST_CASE(dynamic_bitset_test)
{
constexpr uint8_t bits = 0b0000000001010100;
boost::dynamic_bitset<uint8_t> bs(16, bits); // 2 blocks of uint8_t

fc::mutable_variant_object mu;
mu("bs", bs);

// a vector of 2 blocks
const variants& vars = mu["bs"].get_array();
BOOST_CHECK_EQUAL(vars.size(), 2u);

// blocks can be in any order
if (vars[0].as<uint32_t>() == bits ) {
BOOST_CHECK_EQUAL(vars[1].as<uint32_t>(), 0u);
} else if (vars[1].as<uint32_t>() == bits ) {
BOOST_CHECK_EQUAL(vars[0].as<uint32_t>(), 0u);
} else {
BOOST_CHECK(false);
}
}

BOOST_AUTO_TEST_SUITE_END()

0 comments on commit a25a8c4

Please sign in to comment.