diff --git a/libraries/chain/finality/finalizer.cpp b/libraries/chain/finality/finalizer.cpp index 2ef20ec618..8acd73d41b 100644 --- a/libraries/chain/finality/finalizer.cpp +++ b/libraries/chain/finality/finalizer.cpp @@ -393,7 +393,7 @@ void my_finalizers_t::set_keys(const std::map& finaliz auto public_key {bls_public_key{pub_key_str}}; auto it = safety_info.find(public_key); const auto& fsi = it != safety_info.end() ? it->second : default_fsi; - finalizers[public_key] = finalizer{bls_private_key{priv_key_str}, fsi}; + finalizers.emplace(public_key, finalizer{bls_private_key{priv_key_str}, fsi}); } // Now that we have updated the finalizer_safety_info of our local finalizers, diff --git a/libraries/chain/include/eosio/chain/abi_serializer.hpp b/libraries/chain/include/eosio/chain/abi_serializer.hpp index dade07a795..f5dd4096f0 100644 --- a/libraries/chain/include/eosio/chain/abi_serializer.hpp +++ b/libraries/chain/include/eosio/chain/abi_serializer.hpp @@ -934,7 +934,7 @@ namespace impl { { auto itr = _vo.find(name); if( itr != _vo.end() ) - abi_from_variant::extract( itr->value(), this->obj.*member, _resolver, _ctx ); + abi_from_variant::extract( itr->value(), const_cast&>(this->obj.*member), _resolver, _ctx ); } private: diff --git a/libraries/chain/include/eosio/chain/finality/finalizer.hpp b/libraries/chain/include/eosio/chain/finality/finalizer.hpp index 5c4e8fff96..e646bbfacf 100644 --- a/libraries/chain/include/eosio/chain/finality/finalizer.hpp +++ b/libraries/chain/include/eosio/chain/finality/finalizer.hpp @@ -59,13 +59,18 @@ namespace eosio::chain { bool monotony_check {false}; }; - bls_private_key priv_key; + const bls_private_key priv_key; finalizer_safety_information fsi; vote_result decide_vote(const block_state_ptr& bsp); vote_message_ptr maybe_vote(const bls_public_key& pub_key, const block_state_ptr& bsp, const digest_type& digest); + // finalizer has voted strong, update fsi if it does not already contain vote or better bool maybe_update_fsi(const block_state_ptr& bsp); + + finalizer(const bls_private_key& priv_key, const finalizer_safety_information& fsi) + : priv_key(priv_key) + , fsi(fsi) {} }; // ---------------------------------------------------------------------------------------- @@ -84,7 +89,7 @@ namespace eosio::chain { static constexpr uint64_t current_safety_file_version = safety_file_version_1; using fsi_t = finalizer_safety_information; - using fsi_map = std::map; + using fsi_map = std::map; using vote_t = std::tuple; private: @@ -184,7 +189,12 @@ namespace eosio::chain { // for testing purposes only, not thread safe const fsi_t& get_fsi(const bls_public_key& k) const { return finalizers.at(k).fsi; } - void set_fsi(const bls_public_key& k, const fsi_t& fsi) { finalizers[k].fsi = fsi; } + void set_fsi(const bls_public_key& k, const fsi_t& fsi) { + if (auto it = finalizers.find(k); it != finalizers.end()) + it->second.fsi = fsi; + else + assert(0); + } private: void load_finalizer_safety_info_v0(fsi_map& res); diff --git a/libraries/libfc/include/fc/io/raw.hpp b/libraries/libfc/include/fc/io/raw.hpp index 51458ff5ff..561ec5c3aa 100644 --- a/libraries/libfc/include/fc/io/raw.hpp +++ b/libraries/libfc/include/fc/io/raw.hpp @@ -349,7 +349,11 @@ namespace fc { template inline void operator()( const char* name )const { try { - fc::raw::unpack( s, this->obj.*p ); + // `const_cast` because we want to be able to populate `const` members of a class, which + // are typically set only in the constructor, but because of the `reflect` and `raw` + // interfaces, we have to create the object first and then populate the members. + // ------------------------------------------------------------------------------------- + fc::raw::unpack( s, const_cast&>(this->obj.*p) ); } FC_RETHROW_EXCEPTIONS( warn, "Error unpacking field ${field}", ("field",name) ) } private: diff --git a/libraries/libfc/include/fc/reflect/variant.hpp b/libraries/libfc/include/fc/reflect/variant.hpp index 15b4e309b1..07a16f03eb 100644 --- a/libraries/libfc/include/fc/reflect/variant.hpp +++ b/libraries/libfc/include/fc/reflect/variant.hpp @@ -51,7 +51,7 @@ namespace fc { auto itr = vo.find(name); if( itr != vo.end() ) - from_variant( itr->value(), this->obj.*member ); + from_variant( itr->value(), const_cast&>(this->obj.*member) ); } const variant_object& vo; diff --git a/libraries/libfc/test/io/test_raw.cpp b/libraries/libfc/test/io/test_raw.cpp index 40b9801040..30c94e5bb7 100644 --- a/libraries/libfc/test/io/test_raw.cpp +++ b/libraries/libfc/test/io/test_raw.cpp @@ -6,6 +6,15 @@ using namespace fc; +struct A { + int x; + const float y; + const std::optional z; + + bool operator==(const A&) const = default; +}; +FC_REFLECT(A, (x)(y)(z)) + BOOST_AUTO_TEST_SUITE(raw_test_suite) @@ -74,4 +83,19 @@ BOOST_AUTO_TEST_CASE(dynamic_bitset_small_test) BOOST_TEST(unpacked.none()); } +BOOST_AUTO_TEST_CASE(struct_serialization) { + char buff[512]; + datastream ds(buff, sizeof(buff)); + + A a{2, 2.2, "abc"}; + fc::raw::pack(ds, a); + + A a2{0, 0}; + ds.seekp(0); + fc::raw::unpack(ds, a2); + bool same = a == a2; + BOOST_TEST(same); + +} + BOOST_AUTO_TEST_SUITE_END() diff --git a/libraries/testing/tester.cpp b/libraries/testing/tester.cpp index 6f0b2840ad..4d090482a4 100644 --- a/libraries/testing/tester.cpp +++ b/libraries/testing/tester.cpp @@ -841,12 +841,9 @@ namespace eosio::testing { string action_type_name = abis.get_action_type(acttype); FC_ASSERT( action_type_name != string(), "unknown action type ${a}", ("a",acttype) ); - - action act; - act.account = code; - act.name = acttype; - act.authorization = auths; - act.data = abis.variant_to_binary(action_type_name, data, abi_serializer::create_yield_function( abi_serializer_max_time )); + action act(std::move(auths), code, acttype, + abis.variant_to_binary(action_type_name, data, + abi_serializer::create_yield_function(abi_serializer_max_time))); return act; } FC_CAPTURE_AND_RETHROW() } diff --git a/tests/test_chain_plugin.cpp b/tests/test_chain_plugin.cpp index 3678780dd0..aa371cc118 100644 --- a/tests/test_chain_plugin.cpp +++ b/tests/test_chain_plugin.cpp @@ -29,10 +29,9 @@ class chain_plugin_tester : public validating_tester { action_result push_action( const account_name& signer, const action_name &name, const variant_object &data, bool auth = true ) { string action_type_name = abi_ser.get_action_type(name); - action act; - act.account = config::system_account_name; - act.name = name; - act.data = abi_ser.variant_to_binary( action_type_name, data, abi_serializer::create_yield_function(abi_serializer_max_time) ); + action act({}, config::system_account_name, name, + abi_ser.variant_to_binary(action_type_name, data, + abi_serializer::create_yield_function(abi_serializer_max_time))); return base_tester::push_action( std::move(act), (auth ? signer : signer == "bob111111111"_n ? "alice1111111"_n : "bob111111111"_n).to_uint64_t() ); } diff --git a/unittests/eosio_system_tester.hpp b/unittests/eosio_system_tester.hpp index 99c41dbc01..15ad0221ea 100644 --- a/unittests/eosio_system_tester.hpp +++ b/unittests/eosio_system_tester.hpp @@ -223,13 +223,12 @@ class eosio_system_tester : public T { T::action_result push_action( const account_name& signer, const action_name &name, const variant_object &data, bool auth = true ) { string action_type_name = abi_ser.get_action_type(name); - action act; - act.account = config::system_account_name; - act.name = name; - act.data = abi_ser.variant_to_binary( action_type_name, data, abi_serializer::create_yield_function( T::abi_serializer_max_time ) ); + action act({}, config::system_account_name, name, + abi_ser.variant_to_binary(action_type_name, data, + abi_serializer::create_yield_function(T::abi_serializer_max_time))); return base_tester::push_action( std::move(act), auth ? signer.to_uint64_t() : - signer == "bob111111111"_n ? "alice1111111"_n.to_uint64_t() : "bob111111111"_n.to_uint64_t() ); + signer == "bob111111111"_n ? "alice1111111"_n.to_uint64_t() : "bob111111111"_n.to_uint64_t() ); } T::action_result stake( const account_name& from, const account_name& to, const asset& net, const asset& cpu ) { diff --git a/unittests/finalizer_vote_tests.cpp b/unittests/finalizer_vote_tests.cpp index d26f022514..ddbf14a4ec 100644 --- a/unittests/finalizer_vote_tests.cpp +++ b/unittests/finalizer_vote_tests.cpp @@ -131,7 +131,7 @@ struct simulator_t { simulator_t() : keys("alice"_n), - my_finalizer(keys.privkey) { + my_finalizer(keys.privkey, finalizer_safety_information{}) { finalizer_policy fin_policy; fin_policy.threshold = 1;