From 3400b2e6043e116d17e054c2f283a497937816fb Mon Sep 17 00:00:00 2001 From: greg7mdp Date: Sat, 28 Oct 2023 18:16:08 -0400 Subject: [PATCH 01/40] Use new `shared_cow_vector` from chainbase. --- libraries/chain/controller.cpp | 18 ++++++++---- .../chain/include/eosio/chain/authority.hpp | 8 ++--- .../include/eosio/chain/producer_schedule.hpp | 17 ++++------- libraries/chain/include/eosio/chain/types.hpp | 29 ++++++++++++++++++- libraries/chain/protocol_state_object.cpp | 16 ++++------ libraries/chainbase | 2 +- 6 files changed, 56 insertions(+), 34 deletions(-) diff --git a/libraries/chain/controller.cpp b/libraries/chain/controller.cpp index 51e1d4a198..7a8120ac2f 100644 --- a/libraries/chain/controller.cpp +++ b/libraries/chain/controller.cpp @@ -1793,11 +1793,13 @@ struct controller_impl { db.modify( pso, [&]( auto& ps ) { ps.preactivated_protocol_features.clear(); - ps.activated_protocol_features.reserve( ps.activated_protocol_features.size() - + new_protocol_feature_activations.size() ); - for( const auto& feature_digest : new_protocol_feature_activations ) { - ps.activated_protocol_features.emplace_back( feature_digest, pbhs.block_num ); - } + std::size_t current_size = ps.activated_protocol_features.size(); + std::size_t new_size = current_size + new_protocol_feature_activations.size(); + + ps.activated_protocol_features.clear_and_construct(new_size, current_size, [&](void* dest, std::size_t idx) { + new (dest) protocol_state_object::activated_protocol_feature( + new_protocol_feature_activations[idx - current_size], pbhs.block_num); + }); }); } @@ -2902,7 +2904,11 @@ void controller::preactivate_feature( const digest_type& feature_digest, bool is } my->db.modify( pso, [&]( auto& ps ) { - ps.preactivated_protocol_features.push_back( feature_digest ); + std::size_t old_size = ps.preactivated_protocol_features.size(); + ps.preactivated_protocol_features.clear_and_construct(old_size + 1, old_size, [&](void* dest, std::size_t idx) { + assert(idx == old_size); + new (dest) digest_type(feature_digest); + }); } ); } diff --git a/libraries/chain/include/eosio/chain/authority.hpp b/libraries/chain/include/eosio/chain/authority.hpp index a168aaa105..7ffed53b02 100644 --- a/libraries/chain/include/eosio/chain/authority.hpp +++ b/libraries/chain/include/eosio/chain/authority.hpp @@ -226,11 +226,9 @@ struct shared_authority { shared_authority& operator=(const authority& a) { threshold = a.threshold; - keys.clear(); - keys.reserve(a.keys.size()); - for(const key_weight& k : a.keys) { - keys.emplace_back(shared_key_weight::convert(keys.get_allocator(), k)); - } + keys.clear_and_construct(a.keys.size(), 0, [&](void* dest, std::size_t idx) { + new (dest) shared_key_weight(shared_key_weight::convert(keys.get_allocator(), a.keys[idx])); + }); accounts = decltype(accounts)(a.accounts.begin(), a.accounts.end(), accounts.get_allocator()); waits = decltype(waits)(a.waits.begin(), a.waits.end(), waits.get_allocator()); return *this; diff --git a/libraries/chain/include/eosio/chain/producer_schedule.hpp b/libraries/chain/include/eosio/chain/producer_schedule.hpp index 6a12e85791..cb547a90c8 100644 --- a/libraries/chain/include/eosio/chain/producer_schedule.hpp +++ b/libraries/chain/include/eosio/chain/producer_schedule.hpp @@ -130,12 +130,9 @@ namespace eosio { namespace chain { auto to_shared(chainbase::allocator alloc) const { shared_block_signing_authority_v0 result(alloc); result.threshold = threshold; - result.keys.clear(); - result.keys.reserve(keys.size()); - for (const auto& k: keys) { - result.keys.emplace_back(shared_key_weight::convert(alloc, k)); - } - + result.keys.clear_and_construct(keys.size(), 0, [&](void* dest, std::size_t idx) { + new (dest) shared_key_weight(shared_key_weight::convert(alloc, keys[idx])); + }); return result; } @@ -250,11 +247,9 @@ namespace eosio { namespace chain { auto to_shared(chainbase::allocator alloc) const { auto result = shared_producer_authority_schedule(alloc); result.version = version; - result.producers.clear(); - result.producers.reserve( producers.size() ); - for( const auto& p : producers ) { - result.producers.emplace_back(p.to_shared(alloc)); - } + result.producers.clear_and_construct(producers.size(), 0, [&](void* dest, std::size_t idx) { + new (dest) shared_producer_authority(producers[idx].to_shared(alloc)); + }); return result; } diff --git a/libraries/chain/include/eosio/chain/types.hpp b/libraries/chain/include/eosio/chain/types.hpp index 99466395d7..09ebf11cae 100644 --- a/libraries/chain/include/eosio/chain/types.hpp +++ b/libraries/chain/include/eosio/chain/types.hpp @@ -86,8 +86,10 @@ namespace eosio::chain { using chainbase::allocator; using shared_string = chainbase::shared_string; + template - using shared_vector = boost::interprocess::vector>; + using shared_vector = chainbase::shared_vector; + template using shared_set = boost::interprocess::set, allocator>; template @@ -426,6 +428,31 @@ namespace chainbase { v.resize_and_fill(size.value, [&s](char* buf, std::size_t sz) { s.read(buf, sz); }); return s; } + + // chainbase::shared_cow_vector + template inline DataStream& operator<<( DataStream& s, const chainbase::shared_cow_vector& v ) { + FC_ASSERT( v.size() <= MAX_SIZE_OF_BYTE_ARRAYS ); + fc::raw::pack( s, fc::unsigned_int((uint32_t)v.size())); + const auto* data = v.data(); + auto size = v.size(); + for (std::size_t i = 0; i < size; ++i) { + fc::raw::pack(s, &data[i]); + } + return s; + } + + template inline DataStream& operator>>( DataStream& s, chainbase::shared_cow_vector& v ) { + fc::unsigned_int size; + fc::raw::unpack( s, size ); + FC_ASSERT( size.value <= MAX_SIZE_OF_BYTE_ARRAYS ); + FC_ASSERT( v.size() == 0 ); + v.resize_and_fill(size.value, [&](auto* data, std::size_t sz) { + for (std::size_t i = 0; i < sz; ++i) { + fc::raw::unpack(s, &data[i]); + } + }); + return s; + } } FC_REFLECT_EMPTY( eosio::chain::void_t ) diff --git a/libraries/chain/protocol_state_object.cpp b/libraries/chain/protocol_state_object.cpp index 142df3b131..b6c0628620 100644 --- a/libraries/chain/protocol_state_object.cpp +++ b/libraries/chain/protocol_state_object.cpp @@ -32,17 +32,13 @@ namespace eosio { namespace chain { protocol_state_object& value, chainbase::database& db ) { - value.activated_protocol_features.clear(); - value.activated_protocol_features.reserve( row.activated_protocol_features.size() ); - for( const auto& v : row.activated_protocol_features ) { - value.activated_protocol_features.emplace_back( v ); - } + value.activated_protocol_features.clear_and_construct( row.activated_protocol_features.size(), 0, [&](void* dest, std::size_t idx){ + new (dest) protocol_state_object::activated_protocol_feature(row.activated_protocol_features[idx]); + }); - value.preactivated_protocol_features.clear(); - value.preactivated_protocol_features.reserve( row.preactivated_protocol_features.size() ); - for( const auto& v : row.preactivated_protocol_features ) { - value.preactivated_protocol_features.emplace_back( v ); - } + value.preactivated_protocol_features.clear_and_construct(row.preactivated_protocol_features.size(), 0, [&](void* dest, std::size_t idx) { + new (dest) digest_type(row.preactivated_protocol_features[idx]); + }); reset_intrinsic_whitelist( value.whitelisted_intrinsics, row.whitelisted_intrinsics ); diff --git a/libraries/chainbase b/libraries/chainbase index 7615ddab28..5888f3f488 160000 --- a/libraries/chainbase +++ b/libraries/chainbase @@ -1 +1 @@ -Subproject commit 7615ddab287e06fd31f800e66fe39b3a19320ec8 +Subproject commit 5888f3f488c43f7ff778cf51bc45aa41c5f53a1f From 173d1619f1a49522ce64264935b183b4fbf263a1 Mon Sep 17 00:00:00 2001 From: greg7mdp Date: Sun, 29 Oct 2023 08:40:28 -0400 Subject: [PATCH 02/40] Update chainbase to branch tip --- libraries/chainbase | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/chainbase b/libraries/chainbase index 5888f3f488..4ecbb3a519 160000 --- a/libraries/chainbase +++ b/libraries/chainbase @@ -1 +1 @@ -Subproject commit 5888f3f488c43f7ff778cf51bc45aa41c5f53a1f +Subproject commit 4ecbb3a519e5f663bb1acd28302487ab99ee7a38 From 13e396934d9d9ab4a51a91e823be991261460d9f Mon Sep 17 00:00:00 2001 From: greg7mdp Date: Mon, 30 Oct 2023 21:46:07 -0400 Subject: [PATCH 03/40] Update `shared` objects to always be constructed in-place --- libraries/chain/authorization_manager.cpp | 12 +++-- libraries/chain/controller.cpp | 3 +- .../chain/include/eosio/chain/authority.hpp | 40 ++++++++++------- .../include/eosio/chain/database_utils.hpp | 11 +++-- .../eosio/chain/global_property_object.hpp | 12 +++-- .../include/eosio/chain/permission_object.hpp | 2 +- .../include/eosio/chain/producer_schedule.hpp | 44 ++++++------------- .../eosio/chain/protocol_state_object.hpp | 11 ++++- libraries/chain/include/eosio/chain/types.hpp | 22 ++++------ libraries/chain/producer_schedule.cpp | 22 +++++++++- libraries/chain/whitelisted_intrinsics.cpp | 6 +-- libraries/chainbase | 2 +- libraries/libfc/include/fc/io/raw.hpp | 22 ---------- 13 files changed, 106 insertions(+), 103 deletions(-) diff --git a/libraries/chain/authorization_manager.cpp b/libraries/chain/authorization_manager.cpp index 9cb4580a0c..c841797cb2 100644 --- a/libraries/chain/authorization_manager.cpp +++ b/libraries/chain/authorization_manager.cpp @@ -157,7 +157,9 @@ namespace eosio { namespace chain { p.owner = account; p.name = name; p.last_updated = creation_time; - p.auth = auth; + + std::destroy_at(std::addressof(p.auth)); + std::construct_at(std::addressof(p.auth), auth); // make sure we construct `shared` objects in place if (auto dm_logger = _control.get_deep_mind_logger(is_trx_transient)) { dm_logger->on_create_permission(p); @@ -193,7 +195,9 @@ namespace eosio { namespace chain { p.owner = account; p.name = name; p.last_updated = creation_time; - p.auth = std::move(auth); + + std::destroy_at(std::addressof(p.auth)); + std::construct_at(std::addressof(p.auth), auth); // make sure we construct `shared` objects in place if (auto dm_logger = _control.get_deep_mind_logger(is_trx_transient)) { dm_logger->on_create_permission(p); @@ -215,7 +219,9 @@ namespace eosio { namespace chain { old_permission = po; } - po.auth = auth; + std::destroy_at(std::addressof(po.auth)); + std::construct_at(std::addressof(po.auth), auth); // make sure we construct `shared` objects in place + po.last_updated = _control.pending_block_time(); if (auto dm_logger = _control.get_deep_mind_logger(is_trx_transient)) { diff --git a/libraries/chain/controller.cpp b/libraries/chain/controller.cpp index 7a8120ac2f..f9441314f8 100644 --- a/libraries/chain/controller.cpp +++ b/libraries/chain/controller.cpp @@ -3290,7 +3290,8 @@ int64_t controller::set_proposed_producers( vector producers my->db.modify( gpo, [&]( auto& gp ) { gp.proposed_schedule_block_num = cur_block_num; - gp.proposed_schedule = sch.to_shared(gp.proposed_schedule.producers.get_allocator()); + std::destroy_at(std::addressof(gp.proposed_schedule)); + std::construct_at(std::addressof(gp.proposed_schedule), sch); // make sure we construct `shared` objects in place }); return version; } diff --git a/libraries/chain/include/eosio/chain/authority.hpp b/libraries/chain/include/eosio/chain/authority.hpp index 7ffed53b02..3b74e5f523 100644 --- a/libraries/chain/include/eosio/chain/authority.hpp +++ b/libraries/chain/include/eosio/chain/authority.hpp @@ -116,20 +116,17 @@ struct shared_key_weight { return key_weight{key.to_public_key(), weight}; } - static shared_key_weight convert(chainbase::allocator allocator, const key_weight& k) { - return std::visit(overloaded { - [&](const auto& k1r1) { - return shared_key_weight(k1r1, k.weight); + shared_key_weight(const key_weight& k) : key(fc::ecc::public_key_shim()), weight(k.weight) { + std::visit(overloaded { + [&](const T& k1r1) { + key.pubkey.emplace(k1r1); }, [&](const fc::crypto::webauthn::public_key& wa) { size_t psz = fc::raw::pack_size(wa); - shared_string wa_ss(std::move(allocator)); - wa_ss.resize_and_fill( psz, [&wa]( char* data, std::size_t sz ) { - fc::datastream ds(data, sz); - fc::raw::pack(ds, wa); - }); - - return shared_key_weight(std::move(wa_ss), k.weight); + std::string wa_ss(psz, 'a'); + fc::datastream ds(wa_ss.data(), psz); + fc::raw::pack(ds, wa); + key.pubkey.emplace(wa_ss); } }, k.key._storage); } @@ -221,16 +218,27 @@ struct authority { struct shared_authority { - explicit shared_authority( chainbase::allocator alloc ) - :keys(alloc),accounts(alloc),waits(alloc){} + shared_authority() = default; + + shared_authority(const authority& auth) : + threshold(auth.threshold), + keys(auth.keys), + accounts(auth.accounts), + waits(auth.waits) + { + } shared_authority& operator=(const authority& a) { threshold = a.threshold; keys.clear_and_construct(a.keys.size(), 0, [&](void* dest, std::size_t idx) { - new (dest) shared_key_weight(shared_key_weight::convert(keys.get_allocator(), a.keys[idx])); + new (dest) shared_key_weight(a.keys[idx]); + }); + accounts.clear_and_construct(a.accounts.size(), 0, [&](void* dest, std::size_t idx) { + new (dest) permission_level_weight(a.accounts[idx]); + }); + waits.clear_and_construct(a.waits.size(), 0, [&](void* dest, std::size_t idx) { + new (dest) wait_weight(a.waits[idx]); }); - accounts = decltype(accounts)(a.accounts.begin(), a.accounts.end(), accounts.get_allocator()); - waits = decltype(waits)(a.waits.begin(), a.waits.end(), waits.get_allocator()); return *this; } diff --git a/libraries/chain/include/eosio/chain/database_utils.hpp b/libraries/chain/include/eosio/chain/database_utils.hpp index 0ee937e6e1..8f918fafc8 100644 --- a/libraries/chain/include/eosio/chain/database_utils.hpp +++ b/libraries/chain/include/eosio/chain/database_utils.hpp @@ -88,7 +88,7 @@ namespace eosio { namespace chain { template DataStream& operator >> ( DataStream& ds, shared_blob& b ) { - fc::raw::unpack(ds, static_cast(b)); + fc::raw::unpack(ds, static_cast(b)); // [greg tbd] return ds; } } } @@ -172,7 +172,8 @@ namespace fc { void from_variant( const variant& v, eosio::chain::shared_string& s ) { std::string _s; from_variant(v, _s); - s = eosio::chain::shared_string(_s.begin(), _s.end(), s.get_allocator()); + std::destroy_at(std::addressof(s)); + std::construct_at(std::addressof(s), _s.begin(), _s.end()); } inline @@ -183,7 +184,8 @@ namespace fc { inline void from_variant( const variant& v, eosio::chain::shared_blob& b ) { std::string _s = base64_decode(v.as_string()); - b = eosio::chain::shared_blob(_s.begin(), _s.end(), b.get_allocator()); + std::destroy_at(std::addressof(b)); + std::construct_at(std::addressof(b), _s.begin(), _s.end()); } template @@ -195,7 +197,8 @@ namespace fc { void from_variant( const variant& v, eosio::chain::shared_vector& sv ) { std::vector _v; from_variant(v, _v); - sv = eosio::chain::shared_vector(_v.begin(), _v.end(), sv.get_allocator()); + std::destroy_at(std::addressof(sv)); + std::construct_at(std::addressof(sv), _v.begin(), _v.end()); } } diff --git a/libraries/chain/include/eosio/chain/global_property_object.hpp b/libraries/chain/include/eosio/chain/global_property_object.hpp index 7b7497e34e..97a245cb14 100644 --- a/libraries/chain/include/eosio/chain/global_property_object.hpp +++ b/libraries/chain/include/eosio/chain/global_property_object.hpp @@ -75,7 +75,8 @@ namespace eosio { namespace chain { void initalize_from( const legacy::snapshot_global_property_object_v2& legacy, const chain_id_type& chain_id_val, const kv_database_config& kv_config_val, const wasm_config& wasm_config_val ) { proposed_schedule_block_num = legacy.proposed_schedule_block_num; - proposed_schedule = producer_authority_schedule(legacy.proposed_schedule).to_shared(proposed_schedule.producers.get_allocator()); + std::destroy_at(std::addressof(proposed_schedule)); + std::construct_at(std::addressof(proposed_schedule), producer_authority_schedule(legacy.proposed_schedule)); // make sure we construct `shared` objects in place configuration = legacy.configuration; chain_id = chain_id_val; kv_configuration = kv_config_val; @@ -84,7 +85,8 @@ namespace eosio { namespace chain { void initalize_from( const legacy::snapshot_global_property_object_v3& legacy, const kv_database_config& kv_config_val, const wasm_config& wasm_config_val ) { proposed_schedule_block_num = legacy.proposed_schedule_block_num; - proposed_schedule = legacy.proposed_schedule.to_shared(proposed_schedule.producers.get_allocator()); + std::destroy_at(std::addressof(proposed_schedule)); + std::construct_at(std::addressof(proposed_schedule), legacy.proposed_schedule); // make sure we construct `shared` objects in place configuration = legacy.configuration; chain_id = legacy.chain_id; kv_configuration = kv_config_val; @@ -93,7 +95,8 @@ namespace eosio { namespace chain { void initalize_from( const legacy::snapshot_global_property_object_v4& legacy ) { proposed_schedule_block_num = legacy.proposed_schedule_block_num; - proposed_schedule = legacy.proposed_schedule.to_shared(proposed_schedule.producers.get_allocator()); + std::destroy_at(std::addressof(proposed_schedule)); + std::construct_at(std::addressof(proposed_schedule), legacy.proposed_schedule); // make sure we construct `shared` objects in place configuration = legacy.configuration; chain_id = legacy.chain_id; kv_configuration = legacy.kv_configuration; @@ -132,7 +135,8 @@ namespace eosio { namespace chain { static void from_snapshot_row( snapshot_global_property_object&& row, global_property_object& value, chainbase::database& ) { value.proposed_schedule_block_num = row.proposed_schedule_block_num; - value.proposed_schedule = row.proposed_schedule.to_shared(value.proposed_schedule.producers.get_allocator()); + std::destroy_at(std::addressof(value.proposed_schedule)); + std::construct_at(std::addressof(value.proposed_schedule), row.proposed_schedule); // make sure we construct `shared` objects in place value.configuration = row.configuration; value.chain_id = row.chain_id; value.kv_configuration = row.kv_configuration; diff --git a/libraries/chain/include/eosio/chain/permission_object.hpp b/libraries/chain/include/eosio/chain/permission_object.hpp index d323a1ef89..5547dd2860 100644 --- a/libraries/chain/include/eosio/chain/permission_object.hpp +++ b/libraries/chain/include/eosio/chain/permission_object.hpp @@ -23,7 +23,7 @@ namespace eosio { namespace chain { class permission_object : public chainbase::object { - OBJECT_CTOR(permission_object, (auth) ) + OBJECT_CTOR(permission_object, (auth)) id_type id; permission_usage_object::id_type usage_id; diff --git a/libraries/chain/include/eosio/chain/producer_schedule.hpp b/libraries/chain/include/eosio/chain/producer_schedule.hpp index cb547a90c8..6cbaa14b47 100644 --- a/libraries/chain/include/eosio/chain/producer_schedule.hpp +++ b/libraries/chain/include/eosio/chain/producer_schedule.hpp @@ -46,8 +46,11 @@ namespace eosio { namespace chain { }; } + struct block_signing_authority_v0; + struct shared_block_signing_authority_v0 { - shared_block_signing_authority_v0() = delete; + shared_block_signing_authority_v0() = default; + shared_block_signing_authority_v0( const block_signing_authority_v0& ); shared_block_signing_authority_v0( const shared_block_signing_authority_v0& ) = default; shared_block_signing_authority_v0( shared_block_signing_authority_v0&& ) = default; shared_block_signing_authority_v0& operator= ( shared_block_signing_authority_v0 && ) = default; @@ -62,8 +65,12 @@ namespace eosio { namespace chain { using shared_block_signing_authority = std::variant; + struct producer_authority; + struct shared_producer_authority { - shared_producer_authority() = delete; + shared_producer_authority() = default; + explicit shared_producer_authority(const producer_authority& ); + shared_producer_authority( const shared_producer_authority& ) = default; shared_producer_authority( shared_producer_authority&& ) = default; shared_producer_authority& operator= ( shared_producer_authority && ) = default; @@ -78,11 +85,12 @@ namespace eosio { namespace chain { shared_block_signing_authority authority; }; + struct producer_authority_schedule; + struct shared_producer_authority_schedule { - shared_producer_authority_schedule() = delete; + shared_producer_authority_schedule() = default; - explicit shared_producer_authority_schedule( chainbase::allocator alloc ) - :producers(alloc){} + explicit shared_producer_authority_schedule( const producer_authority_schedule& ); shared_producer_authority_schedule( const shared_producer_authority_schedule& ) = default; shared_producer_authority_schedule( shared_producer_authority_schedule&& ) = default; @@ -127,15 +135,6 @@ namespace eosio { namespace chain { return {total_weight >= threshold, num_relevant_keys}; } - auto to_shared(chainbase::allocator alloc) const { - shared_block_signing_authority_v0 result(alloc); - result.threshold = threshold; - result.keys.clear_and_construct(keys.size(), 0, [&](void* dest, std::size_t idx) { - new (dest) shared_key_weight(shared_key_weight::convert(alloc, keys[idx])); - }); - return result; - } - static auto from_shared(const shared_block_signing_authority_v0& src) { block_signing_authority_v0 result; result.threshold = src.threshold; @@ -183,14 +182,6 @@ namespace eosio { namespace chain { return keys_satisfy_and_relevant(presented_keys, authority); } - auto to_shared(chainbase::allocator alloc) const { - auto shared_auth = std::visit([&alloc](const auto& a) { - return a.to_shared(alloc); - }, authority); - - return shared_producer_authority(producer_name, std::move(shared_auth)); - } - static auto from_shared( const shared_producer_authority& src ) { producer_authority result; result.producer_name = src.producer_name; @@ -244,15 +235,6 @@ namespace eosio { namespace chain { ,producers(producers) {} - auto to_shared(chainbase::allocator alloc) const { - auto result = shared_producer_authority_schedule(alloc); - result.version = version; - result.producers.clear_and_construct(producers.size(), 0, [&](void* dest, std::size_t idx) { - new (dest) shared_producer_authority(producers[idx].to_shared(alloc)); - }); - return result; - } - static auto from_shared( const shared_producer_authority_schedule& src ) { producer_authority_schedule result; result.version = src.version; diff --git a/libraries/chain/include/eosio/chain/protocol_state_object.hpp b/libraries/chain/include/eosio/chain/protocol_state_object.hpp index dc0eabd1f1..b91a8cce6e 100644 --- a/libraries/chain/include/eosio/chain/protocol_state_object.hpp +++ b/libraries/chain/include/eosio/chain/protocol_state_object.hpp @@ -16,9 +16,18 @@ namespace eosio { namespace chain { */ class protocol_state_object : public chainbase::object { +#if 0 OBJECT_CTOR(protocol_state_object, (activated_protocol_features)(preactivated_protocol_features)(whitelisted_intrinsics)) - +#else public: + template + protocol_state_object(Constructor&& c, chainbase::constructor_tag) : + id(0), + whitelisted_intrinsics(*activated_protocol_features.get_allocator(this)) { + c(*this); + } +#endif + struct activated_protocol_feature { digest_type feature_digest; uint32_t activation_block_num = 0; diff --git a/libraries/chain/include/eosio/chain/types.hpp b/libraries/chain/include/eosio/chain/types.hpp index 09ebf11cae..1096775af5 100644 --- a/libraries/chain/include/eosio/chain/types.hpp +++ b/libraries/chain/include/eosio/chain/types.hpp @@ -25,17 +25,15 @@ #include #define OBJECT_CTOR1(NAME) \ - NAME() = delete; \ public: \ - template \ - NAME(Constructor&& c, chainbase::allocator) \ + template \ + NAME(Constructor&& c, chainbase::constructor_tag) \ { c(*this); } -#define OBJECT_CTOR2_MACRO(x, y, field) ,field(a) +#define OBJECT_CTOR2_MACRO(x, y, field) ,field() #define OBJECT_CTOR2(NAME, FIELDS) \ - NAME() = delete; \ public: \ - template \ - NAME(Constructor&& c, chainbase::allocator a) \ + template \ + NAME(Constructor&& c, chainbase::constructor_tag) \ : id(0) BOOST_PP_SEQ_FOR_EACH(OBJECT_CTOR2_MACRO, _, FIELDS) \ { c(*this); } #define OBJECT_CTOR(...) BOOST_PP_OVERLOAD(OBJECT_CTOR, __VA_ARGS__)(__VA_ARGS__) @@ -102,23 +100,21 @@ namespace eosio::chain { */ class shared_blob : public shared_string { public: - shared_blob() = delete; shared_blob(shared_blob&&) = default; shared_blob(const shared_blob& s) = default; - shared_blob& operator=(const shared_blob& s) = default; shared_blob& operator=(shared_blob&& ) = default; template - shared_blob(InputIterator f, InputIterator l, const allocator_type& a) - :shared_string(f,l,a) + shared_blob(InputIterator f, InputIterator l) + :shared_string(f,l) {} - shared_blob(const allocator_type& a) - :shared_string(a) + shared_blob() + :shared_string() {} }; diff --git a/libraries/chain/producer_schedule.cpp b/libraries/chain/producer_schedule.cpp index b4c13338d5..e7b8b23345 100644 --- a/libraries/chain/producer_schedule.cpp +++ b/libraries/chain/producer_schedule.cpp @@ -1,6 +1,6 @@ #include -namespace eosio { namespace chain { +namespace eosio::chain { fc::variant producer_authority::get_abi_variant() const { auto authority_variant = std::visit([](const auto& a){ @@ -20,4 +20,22 @@ fc::variant producer_authority::get_abi_variant() const { ("authority", std::move(authority_variant)); } -} } /// eosio::chain +shared_producer_authority::shared_producer_authority(const producer_authority& pa) : + producer_name(pa.producer_name), + authority(std::visit([](const T& a) { return T(a);}, pa.authority)) +{ +} + +shared_block_signing_authority_v0::shared_block_signing_authority_v0(const block_signing_authority_v0& bsa) : + threshold(bsa.threshold), + keys(bsa.keys) +{ +} + +shared_producer_authority_schedule::shared_producer_authority_schedule(const producer_authority_schedule& pas) : + version(pas.version), + producers(pas.producers) +{ +} + +} /// eosio::chain diff --git a/libraries/chain/whitelisted_intrinsics.cpp b/libraries/chain/whitelisted_intrinsics.cpp index 021e93b19d..835f6f4d03 100644 --- a/libraries/chain/whitelisted_intrinsics.cpp +++ b/libraries/chain/whitelisted_intrinsics.cpp @@ -59,8 +59,7 @@ namespace eosio { namespace chain { whitelisted_intrinsics.emplace( std::piecewise_construct, std::forward_as_tuple( h ), - std::forward_as_tuple( name.data(), name.size(), - whitelisted_intrinsics.get_allocator() ) + std::forward_as_tuple( name.data(), name.size() ) ); } @@ -85,8 +84,7 @@ namespace eosio { namespace chain { uint64_t h = static_cast( std::hash{}( name ) ); whitelisted_intrinsics.emplace( std::piecewise_construct, std::forward_as_tuple( h ), - std::forward_as_tuple( name.data(), name.size(), - whitelisted_intrinsics.get_allocator() ) + std::forward_as_tuple( name.data(), name.size() ) ); } } diff --git a/libraries/chainbase b/libraries/chainbase index 4ecbb3a519..257ddf6876 160000 --- a/libraries/chainbase +++ b/libraries/chainbase @@ -1 +1 @@ -Subproject commit 4ecbb3a519e5f663bb1acd28302487ab99ee7a38 +Subproject commit 257ddf68766b23ddd9f5e282cd1023c9c96326d2 diff --git a/libraries/libfc/include/fc/io/raw.hpp b/libraries/libfc/include/fc/io/raw.hpp index dd570fe1fa..b00c9da1f4 100644 --- a/libraries/libfc/include/fc/io/raw.hpp +++ b/libraries/libfc/include/fc/io/raw.hpp @@ -17,17 +17,11 @@ #include #include -#include -#include -#include #include namespace fc { namespace raw { - namespace bip = boost::interprocess; - using shared_string = bip::basic_string< char, std::char_traits< char >, bip::allocator >; - template using UInt = boost::multiprecision::number< boost::multiprecision::cpp_int_backend >; @@ -309,22 +303,6 @@ namespace fc { v = std::string(tmp.data(),tmp.data()+tmp.size()); else v = std::string(); } - - // bip::basic_string - template inline void pack( Stream& s, const shared_string& v ) { - FC_ASSERT( v.size() <= MAX_SIZE_OF_BYTE_ARRAYS ); - fc::raw::pack( s, unsigned_int((uint32_t)v.size())); - if( v.size() ) s.write( v.c_str(), v.size() ); - } - - template inline void unpack( Stream& s, shared_string& v ) { - std::vector tmp; fc::raw::unpack(s,tmp); - FC_ASSERT(v.size() == 0); - if( tmp.size() ) { - v.append(tmp.begin(), tmp.end()); - } - } - // bool template inline void pack( Stream& s, const bool& v ) { fc::raw::pack( s, uint8_t(v) ); } template inline void unpack( Stream& s, bool& v ) From 0d8a47260c42ddec667811a6e25ae3a30b87423b Mon Sep 17 00:00:00 2001 From: greg7mdp Date: Tue, 31 Oct 2023 16:36:00 -0400 Subject: [PATCH 04/40] Fix compilation issue with new updated chainbase tip. Tests now pass except for `plugin_test`. --- libraries/chain/include/eosio/chain/authority.hpp | 4 +++- .../chain/include/eosio/chain/producer_schedule.hpp | 3 --- .../include/eosio/chain/protocol_state_object.hpp | 4 ---- libraries/chain/producer_schedule.cpp | 12 ++++++++---- libraries/chainbase | 2 +- 5 files changed, 12 insertions(+), 13 deletions(-) diff --git a/libraries/chain/include/eosio/chain/authority.hpp b/libraries/chain/include/eosio/chain/authority.hpp index 3b74e5f523..f45bf6026e 100644 --- a/libraries/chain/include/eosio/chain/authority.hpp +++ b/libraries/chain/include/eosio/chain/authority.hpp @@ -222,10 +222,12 @@ struct shared_authority { shared_authority(const authority& auth) : threshold(auth.threshold), - keys(auth.keys), accounts(auth.accounts), waits(auth.waits) { + keys.clear_and_construct(auth.keys.size(), 0, [&](void* dest, std::size_t idx) { + new (dest) shared_key_weight(auth.keys[idx]); + }); } shared_authority& operator=(const authority& a) { diff --git a/libraries/chain/include/eosio/chain/producer_schedule.hpp b/libraries/chain/include/eosio/chain/producer_schedule.hpp index 6cbaa14b47..5b24957d90 100644 --- a/libraries/chain/include/eosio/chain/producer_schedule.hpp +++ b/libraries/chain/include/eosio/chain/producer_schedule.hpp @@ -56,9 +56,6 @@ namespace eosio { namespace chain { shared_block_signing_authority_v0& operator= ( shared_block_signing_authority_v0 && ) = default; shared_block_signing_authority_v0& operator= ( const shared_block_signing_authority_v0 & ) = default; - explicit shared_block_signing_authority_v0( chainbase::allocator alloc ) - :keys(alloc){} - uint32_t threshold = 0; shared_vector keys; }; diff --git a/libraries/chain/include/eosio/chain/protocol_state_object.hpp b/libraries/chain/include/eosio/chain/protocol_state_object.hpp index b91a8cce6e..c2ffae1b76 100644 --- a/libraries/chain/include/eosio/chain/protocol_state_object.hpp +++ b/libraries/chain/include/eosio/chain/protocol_state_object.hpp @@ -16,9 +16,6 @@ namespace eosio { namespace chain { */ class protocol_state_object : public chainbase::object { -#if 0 - OBJECT_CTOR(protocol_state_object, (activated_protocol_features)(preactivated_protocol_features)(whitelisted_intrinsics)) -#else public: template protocol_state_object(Constructor&& c, chainbase::constructor_tag) : @@ -26,7 +23,6 @@ namespace eosio { namespace chain { whitelisted_intrinsics(*activated_protocol_features.get_allocator(this)) { c(*this); } -#endif struct activated_protocol_feature { digest_type feature_digest; diff --git a/libraries/chain/producer_schedule.cpp b/libraries/chain/producer_schedule.cpp index e7b8b23345..a6f0a035b3 100644 --- a/libraries/chain/producer_schedule.cpp +++ b/libraries/chain/producer_schedule.cpp @@ -27,15 +27,19 @@ shared_producer_authority::shared_producer_authority(const producer_authority& p } shared_block_signing_authority_v0::shared_block_signing_authority_v0(const block_signing_authority_v0& bsa) : - threshold(bsa.threshold), - keys(bsa.keys) + threshold(bsa.threshold) { + keys.clear_and_construct(bsa.keys.size(), 0, [&](void* dest, std::size_t idx) { + new (dest) shared_key_weight(bsa.keys[idx]); + }); } shared_producer_authority_schedule::shared_producer_authority_schedule(const producer_authority_schedule& pas) : - version(pas.version), - producers(pas.producers) + version(pas.version) { + producers.clear_and_construct(pas.producers.size(), 0, [&](void* dest, std::size_t idx) { + new (dest) shared_producer_authority(pas.producers[idx]); + }); } } /// eosio::chain diff --git a/libraries/chainbase b/libraries/chainbase index 257ddf6876..81755b6419 160000 --- a/libraries/chainbase +++ b/libraries/chainbase @@ -1 +1 @@ -Subproject commit 257ddf68766b23ddd9f5e282cd1023c9c96326d2 +Subproject commit 81755b64192a2685de3966bdf39a9ee1340ad20a From 893906518c5c700be87d6f1a3303458749b1a1fd Mon Sep 17 00:00:00 2001 From: greg7mdp Date: Tue, 31 Oct 2023 16:53:37 -0400 Subject: [PATCH 05/40] remove unused (and wrong) `shared_blob` stream operators. --- .../chain/include/eosio/chain/database_utils.hpp | 16 ++-------------- libraries/chainbase | 2 +- 2 files changed, 3 insertions(+), 15 deletions(-) diff --git a/libraries/chain/include/eosio/chain/database_utils.hpp b/libraries/chain/include/eosio/chain/database_utils.hpp index 8f918fafc8..5113d714ee 100644 --- a/libraries/chain/include/eosio/chain/database_utils.hpp +++ b/libraries/chain/include/eosio/chain/database_utils.hpp @@ -4,7 +4,7 @@ #include #include -namespace eosio { namespace chain { +namespace eosio::chain { template class index_set; @@ -79,19 +79,7 @@ namespace eosio { namespace chain { index_set::walk_indices(function); } }; - - template - DataStream& operator << ( DataStream& ds, const shared_blob& b ) { - fc::raw::pack(ds, static_cast(b)); - return ds; - } - - template - DataStream& operator >> ( DataStream& ds, shared_blob& b ) { - fc::raw::unpack(ds, static_cast(b)); // [greg tbd] - return ds; - } -} } +} namespace fc { diff --git a/libraries/chainbase b/libraries/chainbase index 81755b6419..9c6b35be66 160000 --- a/libraries/chainbase +++ b/libraries/chainbase @@ -1 +1 @@ -Subproject commit 81755b64192a2685de3966bdf39a9ee1340ad20a +Subproject commit 9c6b35be66ccdc8d1ff2c90c916e76e953889838 From 342c640a33ebaa86ce49505cd8e603464cd0946f Mon Sep 17 00:00:00 2001 From: greg7mdp Date: Tue, 31 Oct 2023 17:47:11 -0400 Subject: [PATCH 06/40] Update chainbase branch to tip --- libraries/chainbase | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/chainbase b/libraries/chainbase index 9c6b35be66..8877dc7f55 160000 --- a/libraries/chainbase +++ b/libraries/chainbase @@ -1 +1 @@ -Subproject commit 9c6b35be66ccdc8d1ff2c90c916e76e953889838 +Subproject commit 8877dc7f55392a4bbad0a69fa8e231a0d35327ae From 917ebee2d657a7b10ea4d9a3b6673c660463a139 Mon Sep 17 00:00:00 2001 From: greg7mdp Date: Wed, 1 Nov 2023 09:22:42 -0400 Subject: [PATCH 07/40] Code update for `shared_vector` api change. --- libraries/chain/controller.cpp | 11 +++-------- .../chain/include/eosio/chain/authority.hpp | 16 ++++++---------- libraries/chain/producer_schedule.cpp | 8 ++++---- libraries/chain/protocol_state_object.cpp | 10 +++------- libraries/chainbase | 2 +- 5 files changed, 17 insertions(+), 30 deletions(-) diff --git a/libraries/chain/controller.cpp b/libraries/chain/controller.cpp index f9441314f8..e71f958c2f 100644 --- a/libraries/chain/controller.cpp +++ b/libraries/chain/controller.cpp @@ -1796,9 +1796,8 @@ struct controller_impl { std::size_t current_size = ps.activated_protocol_features.size(); std::size_t new_size = current_size + new_protocol_feature_activations.size(); - ps.activated_protocol_features.clear_and_construct(new_size, current_size, [&](void* dest, std::size_t idx) { - new (dest) protocol_state_object::activated_protocol_feature( - new_protocol_feature_activations[idx - current_size], pbhs.block_num); + ps.activated_protocol_features.clear_and_construct(new_size, current_size, [&](auto* dest, std::size_t idx) { + std::construct_at(dest, new_protocol_feature_activations[idx - current_size], pbhs.block_num); }); }); } @@ -2904,11 +2903,7 @@ void controller::preactivate_feature( const digest_type& feature_digest, bool is } my->db.modify( pso, [&]( auto& ps ) { - std::size_t old_size = ps.preactivated_protocol_features.size(); - ps.preactivated_protocol_features.clear_and_construct(old_size + 1, old_size, [&](void* dest, std::size_t idx) { - assert(idx == old_size); - new (dest) digest_type(feature_digest); - }); + ps.preactivated_protocol_features.emplace_back(feature_digest); } ); } diff --git a/libraries/chain/include/eosio/chain/authority.hpp b/libraries/chain/include/eosio/chain/authority.hpp index f45bf6026e..a9f3a916a4 100644 --- a/libraries/chain/include/eosio/chain/authority.hpp +++ b/libraries/chain/include/eosio/chain/authority.hpp @@ -225,21 +225,17 @@ struct shared_authority { accounts(auth.accounts), waits(auth.waits) { - keys.clear_and_construct(auth.keys.size(), 0, [&](void* dest, std::size_t idx) { - new (dest) shared_key_weight(auth.keys[idx]); + keys.clear_and_construct(auth.keys.size(), 0, [&](auto* dest, std::size_t idx) { + std::construct_at(dest, auth.keys[idx]); }); } shared_authority& operator=(const authority& a) { threshold = a.threshold; - keys.clear_and_construct(a.keys.size(), 0, [&](void* dest, std::size_t idx) { - new (dest) shared_key_weight(a.keys[idx]); - }); - accounts.clear_and_construct(a.accounts.size(), 0, [&](void* dest, std::size_t idx) { - new (dest) permission_level_weight(a.accounts[idx]); - }); - waits.clear_and_construct(a.waits.size(), 0, [&](void* dest, std::size_t idx) { - new (dest) wait_weight(a.waits[idx]); + accounts = a.accounts; + waits = a.waits; + keys.clear_and_construct(a.keys.size(), 0, [&](auto* dest, std::size_t idx) { + std::construct_at(dest, a.keys[idx]); }); return *this; } diff --git a/libraries/chain/producer_schedule.cpp b/libraries/chain/producer_schedule.cpp index a6f0a035b3..45f4be102d 100644 --- a/libraries/chain/producer_schedule.cpp +++ b/libraries/chain/producer_schedule.cpp @@ -29,16 +29,16 @@ shared_producer_authority::shared_producer_authority(const producer_authority& p shared_block_signing_authority_v0::shared_block_signing_authority_v0(const block_signing_authority_v0& bsa) : threshold(bsa.threshold) { - keys.clear_and_construct(bsa.keys.size(), 0, [&](void* dest, std::size_t idx) { - new (dest) shared_key_weight(bsa.keys[idx]); + keys.clear_and_construct(bsa.keys.size(), 0, [&](auto* dest, std::size_t idx) { + std::construct_at(dest, bsa.keys[idx]); }); } shared_producer_authority_schedule::shared_producer_authority_schedule(const producer_authority_schedule& pas) : version(pas.version) { - producers.clear_and_construct(pas.producers.size(), 0, [&](void* dest, std::size_t idx) { - new (dest) shared_producer_authority(pas.producers[idx]); + producers.clear_and_construct(pas.producers.size(), 0, [&](auto* dest, std::size_t idx) { + std::construct_at(dest, pas.producers[idx]); }); } diff --git a/libraries/chain/protocol_state_object.cpp b/libraries/chain/protocol_state_object.cpp index b6c0628620..028b99b2b2 100644 --- a/libraries/chain/protocol_state_object.cpp +++ b/libraries/chain/protocol_state_object.cpp @@ -32,13 +32,9 @@ namespace eosio { namespace chain { protocol_state_object& value, chainbase::database& db ) { - value.activated_protocol_features.clear_and_construct( row.activated_protocol_features.size(), 0, [&](void* dest, std::size_t idx){ - new (dest) protocol_state_object::activated_protocol_feature(row.activated_protocol_features[idx]); - }); - - value.preactivated_protocol_features.clear_and_construct(row.preactivated_protocol_features.size(), 0, [&](void* dest, std::size_t idx) { - new (dest) digest_type(row.preactivated_protocol_features[idx]); - }); + value.activated_protocol_features = row.activated_protocol_features; + + value.preactivated_protocol_features = row.preactivated_protocol_features; reset_intrinsic_whitelist( value.whitelisted_intrinsics, row.whitelisted_intrinsics ); diff --git a/libraries/chainbase b/libraries/chainbase index 8877dc7f55..1d2617f36c 160000 --- a/libraries/chainbase +++ b/libraries/chainbase @@ -1 +1 @@ -Subproject commit 8877dc7f55392a4bbad0a69fa8e231a0d35327ae +Subproject commit 1d2617f36c1514adf363acaaf69449a5c02cfa0c From 69265aa1a7a7fb50227fc6c4687ca0f9340b33b8 Mon Sep 17 00:00:00 2001 From: greg7mdp Date: Wed, 1 Nov 2023 09:57:10 -0400 Subject: [PATCH 08/40] Update chainbase branch to tip. --- libraries/chainbase | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/chainbase b/libraries/chainbase index 1d2617f36c..d49a728cc7 160000 --- a/libraries/chainbase +++ b/libraries/chainbase @@ -1 +1 @@ -Subproject commit 1d2617f36c1514adf363acaaf69449a5c02cfa0c +Subproject commit d49a728cc704677d10c417f10e36a4edb02da431 From 34d0d47e3be07b30049b972cf010f3b8d9611315 Mon Sep 17 00:00:00 2001 From: greg7mdp Date: Wed, 1 Nov 2023 18:09:23 -0400 Subject: [PATCH 09/40] Update chainbase to branch tip. --- libraries/chainbase | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/chainbase b/libraries/chainbase index d49a728cc7..bcdece7ed1 160000 --- a/libraries/chainbase +++ b/libraries/chainbase @@ -1 +1 @@ -Subproject commit d49a728cc704677d10c417f10e36a4edb02da431 +Subproject commit bcdece7ed10f4079bd721c6b1b1c5a921fcb3456 From 203a3b6a99327f06f06b60e0169fa04942a7d4b7 Mon Sep 17 00:00:00 2001 From: greg7mdp Date: Wed, 1 Nov 2023 18:49:15 -0400 Subject: [PATCH 10/40] Cleanup the code using updated chainbase APIs. --- libraries/chain/authorization_manager.cpp | 12 +++--------- libraries/chain/controller.cpp | 3 +-- .../chain/include/eosio/chain/authority.hpp | 16 ++++++++++------ .../chain/include/eosio/chain/database_utils.hpp | 6 ++---- .../eosio/chain/global_property_object.hpp | 9 +++------ .../include/eosio/chain/producer_schedule.hpp | 2 +- libraries/chainbase | 2 +- 7 files changed, 21 insertions(+), 29 deletions(-) diff --git a/libraries/chain/authorization_manager.cpp b/libraries/chain/authorization_manager.cpp index c841797cb2..9cb4580a0c 100644 --- a/libraries/chain/authorization_manager.cpp +++ b/libraries/chain/authorization_manager.cpp @@ -157,9 +157,7 @@ namespace eosio { namespace chain { p.owner = account; p.name = name; p.last_updated = creation_time; - - std::destroy_at(std::addressof(p.auth)); - std::construct_at(std::addressof(p.auth), auth); // make sure we construct `shared` objects in place + p.auth = auth; if (auto dm_logger = _control.get_deep_mind_logger(is_trx_transient)) { dm_logger->on_create_permission(p); @@ -195,9 +193,7 @@ namespace eosio { namespace chain { p.owner = account; p.name = name; p.last_updated = creation_time; - - std::destroy_at(std::addressof(p.auth)); - std::construct_at(std::addressof(p.auth), auth); // make sure we construct `shared` objects in place + p.auth = std::move(auth); if (auto dm_logger = _control.get_deep_mind_logger(is_trx_transient)) { dm_logger->on_create_permission(p); @@ -219,9 +215,7 @@ namespace eosio { namespace chain { old_permission = po; } - std::destroy_at(std::addressof(po.auth)); - std::construct_at(std::addressof(po.auth), auth); // make sure we construct `shared` objects in place - + po.auth = auth; po.last_updated = _control.pending_block_time(); if (auto dm_logger = _control.get_deep_mind_logger(is_trx_transient)) { diff --git a/libraries/chain/controller.cpp b/libraries/chain/controller.cpp index e71f958c2f..97707635b5 100644 --- a/libraries/chain/controller.cpp +++ b/libraries/chain/controller.cpp @@ -3285,8 +3285,7 @@ int64_t controller::set_proposed_producers( vector producers my->db.modify( gpo, [&]( auto& gp ) { gp.proposed_schedule_block_num = cur_block_num; - std::destroy_at(std::addressof(gp.proposed_schedule)); - std::construct_at(std::addressof(gp.proposed_schedule), sch); // make sure we construct `shared` objects in place + gp.proposed_schedule = sch; }); return version; } diff --git a/libraries/chain/include/eosio/chain/authority.hpp b/libraries/chain/include/eosio/chain/authority.hpp index a9f3a916a4..0b4498a0a5 100644 --- a/libraries/chain/include/eosio/chain/authority.hpp +++ b/libraries/chain/include/eosio/chain/authority.hpp @@ -222,21 +222,25 @@ struct shared_authority { shared_authority(const authority& auth) : threshold(auth.threshold), + keys(auth.keys), accounts(auth.accounts), waits(auth.waits) { - keys.clear_and_construct(auth.keys.size(), 0, [&](auto* dest, std::size_t idx) { - std::construct_at(dest, auth.keys[idx]); - }); + } + + shared_authority(authority&& auth) : + threshold(auth.threshold), + keys(std::move(auth.keys)), + accounts(std::move(auth.accounts)), + waits(std::move(auth.waits)) + { } shared_authority& operator=(const authority& a) { threshold = a.threshold; accounts = a.accounts; waits = a.waits; - keys.clear_and_construct(a.keys.size(), 0, [&](auto* dest, std::size_t idx) { - std::construct_at(dest, a.keys[idx]); - }); + keys = a.keys; return *this; } diff --git a/libraries/chain/include/eosio/chain/database_utils.hpp b/libraries/chain/include/eosio/chain/database_utils.hpp index 5113d714ee..b0f7894003 100644 --- a/libraries/chain/include/eosio/chain/database_utils.hpp +++ b/libraries/chain/include/eosio/chain/database_utils.hpp @@ -160,8 +160,7 @@ namespace fc { void from_variant( const variant& v, eosio::chain::shared_string& s ) { std::string _s; from_variant(v, _s); - std::destroy_at(std::addressof(s)); - std::construct_at(std::addressof(s), _s.begin(), _s.end()); + s = _s; } inline @@ -185,8 +184,7 @@ namespace fc { void from_variant( const variant& v, eosio::chain::shared_vector& sv ) { std::vector _v; from_variant(v, _v); - std::destroy_at(std::addressof(sv)); - std::construct_at(std::addressof(sv), _v.begin(), _v.end()); + sv = v; } } diff --git a/libraries/chain/include/eosio/chain/global_property_object.hpp b/libraries/chain/include/eosio/chain/global_property_object.hpp index 97a245cb14..6b4f5fe550 100644 --- a/libraries/chain/include/eosio/chain/global_property_object.hpp +++ b/libraries/chain/include/eosio/chain/global_property_object.hpp @@ -75,8 +75,7 @@ namespace eosio { namespace chain { void initalize_from( const legacy::snapshot_global_property_object_v2& legacy, const chain_id_type& chain_id_val, const kv_database_config& kv_config_val, const wasm_config& wasm_config_val ) { proposed_schedule_block_num = legacy.proposed_schedule_block_num; - std::destroy_at(std::addressof(proposed_schedule)); - std::construct_at(std::addressof(proposed_schedule), producer_authority_schedule(legacy.proposed_schedule)); // make sure we construct `shared` objects in place + proposed_schedule = producer_authority_schedule(legacy.proposed_schedule); configuration = legacy.configuration; chain_id = chain_id_val; kv_configuration = kv_config_val; @@ -85,8 +84,7 @@ namespace eosio { namespace chain { void initalize_from( const legacy::snapshot_global_property_object_v3& legacy, const kv_database_config& kv_config_val, const wasm_config& wasm_config_val ) { proposed_schedule_block_num = legacy.proposed_schedule_block_num; - std::destroy_at(std::addressof(proposed_schedule)); - std::construct_at(std::addressof(proposed_schedule), legacy.proposed_schedule); // make sure we construct `shared` objects in place + proposed_schedule = legacy.proposed_schedule; configuration = legacy.configuration; chain_id = legacy.chain_id; kv_configuration = kv_config_val; @@ -95,8 +93,7 @@ namespace eosio { namespace chain { void initalize_from( const legacy::snapshot_global_property_object_v4& legacy ) { proposed_schedule_block_num = legacy.proposed_schedule_block_num; - std::destroy_at(std::addressof(proposed_schedule)); - std::construct_at(std::addressof(proposed_schedule), legacy.proposed_schedule); // make sure we construct `shared` objects in place + proposed_schedule = legacy.proposed_schedule; configuration = legacy.configuration; chain_id = legacy.chain_id; kv_configuration = legacy.kv_configuration; diff --git a/libraries/chain/include/eosio/chain/producer_schedule.hpp b/libraries/chain/include/eosio/chain/producer_schedule.hpp index 5b24957d90..bb896f8914 100644 --- a/libraries/chain/include/eosio/chain/producer_schedule.hpp +++ b/libraries/chain/include/eosio/chain/producer_schedule.hpp @@ -87,7 +87,7 @@ namespace eosio { namespace chain { struct shared_producer_authority_schedule { shared_producer_authority_schedule() = default; - explicit shared_producer_authority_schedule( const producer_authority_schedule& ); + shared_producer_authority_schedule( const producer_authority_schedule& ); shared_producer_authority_schedule( const shared_producer_authority_schedule& ) = default; shared_producer_authority_schedule( shared_producer_authority_schedule&& ) = default; diff --git a/libraries/chainbase b/libraries/chainbase index bcdece7ed1..72a6d1deff 160000 --- a/libraries/chainbase +++ b/libraries/chainbase @@ -1 +1 @@ -Subproject commit bcdece7ed10f4079bd721c6b1b1c5a921fcb3456 +Subproject commit 72a6d1deff46dde8686c8ff9eda6c6d14918a34b From 08479df81764511c376d730768556411c1f1d435 Mon Sep 17 00:00:00 2001 From: greg7mdp Date: Wed, 1 Nov 2023 18:59:31 -0400 Subject: [PATCH 11/40] More cleanups thanks to updated chainbase APIs. --- libraries/chain/include/eosio/chain/authority.hpp | 8 -------- .../include/eosio/chain/global_property_object.hpp | 3 +-- libraries/chain/producer_schedule.cpp | 12 ++++-------- 3 files changed, 5 insertions(+), 18 deletions(-) diff --git a/libraries/chain/include/eosio/chain/authority.hpp b/libraries/chain/include/eosio/chain/authority.hpp index 0b4498a0a5..e990e802e2 100644 --- a/libraries/chain/include/eosio/chain/authority.hpp +++ b/libraries/chain/include/eosio/chain/authority.hpp @@ -236,14 +236,6 @@ struct shared_authority { { } - shared_authority& operator=(const authority& a) { - threshold = a.threshold; - accounts = a.accounts; - waits = a.waits; - keys = a.keys; - return *this; - } - uint32_t threshold = 0; shared_vector keys; shared_vector accounts; diff --git a/libraries/chain/include/eosio/chain/global_property_object.hpp b/libraries/chain/include/eosio/chain/global_property_object.hpp index 6b4f5fe550..24180fad6a 100644 --- a/libraries/chain/include/eosio/chain/global_property_object.hpp +++ b/libraries/chain/include/eosio/chain/global_property_object.hpp @@ -132,8 +132,7 @@ namespace eosio { namespace chain { static void from_snapshot_row( snapshot_global_property_object&& row, global_property_object& value, chainbase::database& ) { value.proposed_schedule_block_num = row.proposed_schedule_block_num; - std::destroy_at(std::addressof(value.proposed_schedule)); - std::construct_at(std::addressof(value.proposed_schedule), row.proposed_schedule); // make sure we construct `shared` objects in place + value.proposed_schedule = row.proposed_schedule; value.configuration = row.configuration; value.chain_id = row.chain_id; value.kv_configuration = row.kv_configuration; diff --git a/libraries/chain/producer_schedule.cpp b/libraries/chain/producer_schedule.cpp index 45f4be102d..e7b8b23345 100644 --- a/libraries/chain/producer_schedule.cpp +++ b/libraries/chain/producer_schedule.cpp @@ -27,19 +27,15 @@ shared_producer_authority::shared_producer_authority(const producer_authority& p } shared_block_signing_authority_v0::shared_block_signing_authority_v0(const block_signing_authority_v0& bsa) : - threshold(bsa.threshold) + threshold(bsa.threshold), + keys(bsa.keys) { - keys.clear_and_construct(bsa.keys.size(), 0, [&](auto* dest, std::size_t idx) { - std::construct_at(dest, bsa.keys[idx]); - }); } shared_producer_authority_schedule::shared_producer_authority_schedule(const producer_authority_schedule& pas) : - version(pas.version) + version(pas.version), + producers(pas.producers) { - producers.clear_and_construct(pas.producers.size(), 0, [&](auto* dest, std::size_t idx) { - std::construct_at(dest, pas.producers[idx]); - }); } } /// eosio::chain From a5dd61d9f602337a8eaf5ed763c220196885bb00 Mon Sep 17 00:00:00 2001 From: greg7mdp Date: Thu, 2 Nov 2023 09:13:25 -0400 Subject: [PATCH 12/40] For libtester building with gcc 9.4, don't use c++20 features. --- libraries/chain/include/eosio/chain/database_utils.hpp | 2 +- libraries/chainbase | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/chain/include/eosio/chain/database_utils.hpp b/libraries/chain/include/eosio/chain/database_utils.hpp index b0f7894003..f677615933 100644 --- a/libraries/chain/include/eosio/chain/database_utils.hpp +++ b/libraries/chain/include/eosio/chain/database_utils.hpp @@ -172,7 +172,7 @@ namespace fc { void from_variant( const variant& v, eosio::chain::shared_blob& b ) { std::string _s = base64_decode(v.as_string()); std::destroy_at(std::addressof(b)); - std::construct_at(std::addressof(b), _s.begin(), _s.end()); + new (std::addressof(b)) eosio::chain::shared_blob(_s.begin(), _s.end()); } template diff --git a/libraries/chainbase b/libraries/chainbase index 72a6d1deff..44cde9d430 160000 --- a/libraries/chainbase +++ b/libraries/chainbase @@ -1 +1 @@ -Subproject commit 72a6d1deff46dde8686c8ff9eda6c6d14918a34b +Subproject commit 44cde9d4308f57c6feeff3f30a3bd0ba58fed8f0 From 1c7a99844bc740aa1733c0bdbb103635c4461442 Mon Sep 17 00:00:00 2001 From: greg7mdp Date: Thu, 2 Nov 2023 13:58:45 -0400 Subject: [PATCH 13/40] Pack public key directly into the `shared_string`. --- libraries/chain/include/eosio/chain/authority.hpp | 8 +++++--- libraries/chainbase | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/libraries/chain/include/eosio/chain/authority.hpp b/libraries/chain/include/eosio/chain/authority.hpp index e990e802e2..54feb488e3 100644 --- a/libraries/chain/include/eosio/chain/authority.hpp +++ b/libraries/chain/include/eosio/chain/authority.hpp @@ -123,10 +123,12 @@ struct shared_key_weight { }, [&](const fc::crypto::webauthn::public_key& wa) { size_t psz = fc::raw::pack_size(wa); - std::string wa_ss(psz, 'a'); - fc::datastream ds(wa_ss.data(), psz); + // create a shared_string in the pubkey that we will write (using pack) directly into. + key.pubkey.emplace(psz, boost::container::default_init_t()); + auto& s = std::get(key.pubkey); + assert(s.data()); + fc::datastream ds(s.data(), psz); fc::raw::pack(ds, wa); - key.pubkey.emplace(wa_ss); } }, k.key._storage); } diff --git a/libraries/chainbase b/libraries/chainbase index 44cde9d430..5c250406a9 160000 --- a/libraries/chainbase +++ b/libraries/chainbase @@ -1 +1 @@ -Subproject commit 44cde9d4308f57c6feeff3f30a3bd0ba58fed8f0 +Subproject commit 5c250406a9a5025a340b5786826f4f9637e76e0b From 25df926c68059c4110756b5148ec3e19ed9ca7a2 Mon Sep 17 00:00:00 2001 From: greg7mdp Date: Thu, 2 Nov 2023 14:11:09 -0400 Subject: [PATCH 14/40] Cleanup `shared_blob` class and simplify `from_variant(variant, shared_blob)` --- .../include/eosio/chain/database_utils.hpp | 3 +-- libraries/chain/include/eosio/chain/types.hpp | 22 ++++++++----------- 2 files changed, 10 insertions(+), 15 deletions(-) diff --git a/libraries/chain/include/eosio/chain/database_utils.hpp b/libraries/chain/include/eosio/chain/database_utils.hpp index f677615933..e4531d7cdf 100644 --- a/libraries/chain/include/eosio/chain/database_utils.hpp +++ b/libraries/chain/include/eosio/chain/database_utils.hpp @@ -171,8 +171,7 @@ namespace fc { inline void from_variant( const variant& v, eosio::chain::shared_blob& b ) { std::string _s = base64_decode(v.as_string()); - std::destroy_at(std::addressof(b)); - new (std::addressof(b)) eosio::chain::shared_blob(_s.begin(), _s.end()); + b = std::string_view(_s); } template diff --git a/libraries/chain/include/eosio/chain/types.hpp b/libraries/chain/include/eosio/chain/types.hpp index 1096775af5..59c552b8a6 100644 --- a/libraries/chain/include/eosio/chain/types.hpp +++ b/libraries/chain/include/eosio/chain/types.hpp @@ -99,23 +99,19 @@ namespace eosio::chain { * serialization and to/from variant */ class shared_blob : public shared_string { - public: - shared_blob(shared_blob&&) = default; - - shared_blob(const shared_blob& s) = default; + public: + shared_blob() = default; - shared_blob& operator=(const shared_blob& s) = default; + shared_blob(shared_blob&&) = default; + shared_blob(const shared_blob& s) = default; - shared_blob& operator=(shared_blob&& ) = default; + shared_blob(std::string_view s) : shared_string(s) {} - template - shared_blob(InputIterator f, InputIterator l) - :shared_string(f,l) - {} + template + shared_blob(InputIterator f, InputIterator l) : shared_string(f, l) {} - shared_blob() - :shared_string() - {} + shared_blob& operator=(const shared_blob& s) = default; + shared_blob& operator=(shared_blob&& ) = default; }; using action_name = name; From e36862e9da775cba8c82968b22fd4afcd0e75ca6 Mon Sep 17 00:00:00 2001 From: greg7mdp Date: Thu, 2 Nov 2023 16:35:56 -0400 Subject: [PATCH 15/40] Fix stream `operator<<()` and `>>()` for `shared_string`/`vector` --- libraries/chain/include/eosio/chain/types.hpp | 82 ++++++++++++------- 1 file changed, 54 insertions(+), 28 deletions(-) diff --git a/libraries/chain/include/eosio/chain/types.hpp b/libraries/chain/include/eosio/chain/types.hpp index 59c552b8a6..0919c4117e 100644 --- a/libraries/chain/include/eosio/chain/types.hpp +++ b/libraries/chain/include/eosio/chain/types.hpp @@ -404,47 +404,73 @@ namespace eosio::chain { } // eosio::chain + +namespace fc::raw { + // pack/unpack chainbase::shared_cow_string + // ---------------------------------------- + template inline void pack(Stream& s, const chainbase::shared_string& v) { + FC_ASSERT(v.size() <= MAX_SIZE_OF_BYTE_ARRAYS); + fc::raw::pack(s, fc::unsigned_int((uint32_t)v.size())); + if (v.size()) + s.write(v.data(), v.size()); + } + + template inline void unpack(Stream& s, chainbase::shared_string& v) { + fc::unsigned_int sz; + fc::raw::unpack(s, sz); + if (sz) { + v.resize_and_fill(sz, [&](char* buf, std::size_t sz){ + s.read(buf, sz); + }); + } + } + + // pack/unpack chainbase::shared_cow_vector + // ---------------------------------------- + template inline void pack(Stream& s, const chainbase::shared_cow_vector& v) { + FC_ASSERT(v.size() <= MAX_SIZE_OF_BYTE_ARRAYS); + fc::raw::pack( s, fc::unsigned_int((uint32_t)v.size())); + for (const auto& el : v) + fc::raw::pack(s, el); + } + + template inline void unpack(Stream& s, chainbase::shared_cow_vector& v) { + fc::unsigned_int size; + fc::raw::unpack( s, size ); + FC_ASSERT(size.value <= MAX_SIZE_OF_BYTE_ARRAYS); + FC_ASSERT(v.size() == 0); + v.resize_and_fill(size.value, [&](auto* data, std::size_t sz) { + for (std::size_t i = 0; i < sz; ++i) { + fc::raw::unpack(s, data[i]); + } + }); + } +} + namespace chainbase { // chainbase::shared_cow_string - template inline DataStream& operator<<( DataStream& s, const chainbase::shared_cow_string& v ) { - FC_ASSERT( v.size() <= MAX_SIZE_OF_BYTE_ARRAYS ); - fc::raw::pack( s, fc::unsigned_int((uint32_t)v.size())); - if( v.size() ) s.write( v.data(), v.size() ); + // ---------------------------- + template inline DataStream& operator<<(DataStream& s, const chainbase::shared_cow_string& v) { + fc::raw::pack(s, v); return s; } - template inline DataStream& operator>>( DataStream& s, chainbase::shared_cow_string& v ) { - fc::unsigned_int size; fc::raw::unpack( s, size ); - FC_ASSERT( size.value <= MAX_SIZE_OF_BYTE_ARRAYS ); - FC_ASSERT( v.size() == 0 ); - v.resize_and_fill(size.value, [&s](char* buf, std::size_t sz) { s.read(buf, sz); }); + template inline DataStream& operator>>(DataStream& s, chainbase::shared_cow_string& v) { + fc::raw::unpack(s, v); return s; } // chainbase::shared_cow_vector - template inline DataStream& operator<<( DataStream& s, const chainbase::shared_cow_vector& v ) { - FC_ASSERT( v.size() <= MAX_SIZE_OF_BYTE_ARRAYS ); - fc::raw::pack( s, fc::unsigned_int((uint32_t)v.size())); - const auto* data = v.data(); - auto size = v.size(); - for (std::size_t i = 0; i < size; ++i) { - fc::raw::pack(s, &data[i]); - } + // ---------------------------- + template inline DataStream& operator<<(DataStream& s, const chainbase::shared_cow_vector& v) { + fc::raw::pack(s, v); return s; } - template inline DataStream& operator>>( DataStream& s, chainbase::shared_cow_vector& v ) { - fc::unsigned_int size; - fc::raw::unpack( s, size ); - FC_ASSERT( size.value <= MAX_SIZE_OF_BYTE_ARRAYS ); - FC_ASSERT( v.size() == 0 ); - v.resize_and_fill(size.value, [&](auto* data, std::size_t sz) { - for (std::size_t i = 0; i < sz; ++i) { - fc::raw::unpack(s, &data[i]); - } - }); + template inline DataStream& operator>>(DataStream& s, chainbase::shared_cow_vector& v) { + fc::raw::unpack(s, v); return s; - } + } } FC_REFLECT_EMPTY( eosio::chain::void_t ) From b1e4029510150ae5f5e4fc4fd898615c0a76c4fc Mon Sep 17 00:00:00 2001 From: greg7mdp Date: Thu, 2 Nov 2023 16:54:51 -0400 Subject: [PATCH 16/40] Make `shared_blob(std::string_view s)` constructor explicit. --- libraries/chain/include/eosio/chain/database_utils.hpp | 2 +- libraries/chain/include/eosio/chain/types.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/chain/include/eosio/chain/database_utils.hpp b/libraries/chain/include/eosio/chain/database_utils.hpp index e4531d7cdf..b456c005f3 100644 --- a/libraries/chain/include/eosio/chain/database_utils.hpp +++ b/libraries/chain/include/eosio/chain/database_utils.hpp @@ -171,7 +171,7 @@ namespace fc { inline void from_variant( const variant& v, eosio::chain::shared_blob& b ) { std::string _s = base64_decode(v.as_string()); - b = std::string_view(_s); + new (&b) std::string_view(_s); } template diff --git a/libraries/chain/include/eosio/chain/types.hpp b/libraries/chain/include/eosio/chain/types.hpp index 0919c4117e..583f5b800f 100644 --- a/libraries/chain/include/eosio/chain/types.hpp +++ b/libraries/chain/include/eosio/chain/types.hpp @@ -105,7 +105,7 @@ namespace eosio::chain { shared_blob(shared_blob&&) = default; shared_blob(const shared_blob& s) = default; - shared_blob(std::string_view s) : shared_string(s) {} + explicit shared_blob(std::string_view s) : shared_string(s) {} template shared_blob(InputIterator f, InputIterator l) : shared_string(f, l) {} From d5123bc14f4c9b6ea5f88e577fbbdbbf26b48595 Mon Sep 17 00:00:00 2001 From: greg7mdp Date: Thu, 2 Nov 2023 17:38:50 -0400 Subject: [PATCH 17/40] Make default constructors explicit. --- libraries/chain/include/eosio/chain/authority.hpp | 2 +- libraries/chain/include/eosio/chain/producer_schedule.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/chain/include/eosio/chain/authority.hpp b/libraries/chain/include/eosio/chain/authority.hpp index 54feb488e3..bf1de1f0c9 100644 --- a/libraries/chain/include/eosio/chain/authority.hpp +++ b/libraries/chain/include/eosio/chain/authority.hpp @@ -220,7 +220,7 @@ struct authority { struct shared_authority { - shared_authority() = default; + explicit shared_authority() = default; shared_authority(const authority& auth) : threshold(auth.threshold), diff --git a/libraries/chain/include/eosio/chain/producer_schedule.hpp b/libraries/chain/include/eosio/chain/producer_schedule.hpp index bb896f8914..7a4deddba5 100644 --- a/libraries/chain/include/eosio/chain/producer_schedule.hpp +++ b/libraries/chain/include/eosio/chain/producer_schedule.hpp @@ -49,7 +49,7 @@ namespace eosio { namespace chain { struct block_signing_authority_v0; struct shared_block_signing_authority_v0 { - shared_block_signing_authority_v0() = default; + explicit shared_block_signing_authority_v0() = default; shared_block_signing_authority_v0( const block_signing_authority_v0& ); shared_block_signing_authority_v0( const shared_block_signing_authority_v0& ) = default; shared_block_signing_authority_v0( shared_block_signing_authority_v0&& ) = default; From 5b87bc5660bcbc756213d16af368c22850798cba Mon Sep 17 00:00:00 2001 From: greg7mdp Date: Thu, 2 Nov 2023 18:12:27 -0400 Subject: [PATCH 18/40] Fix issue with commit b1e4029 (was constructing wrong object) That's why we would be better off if we could use c++20's std::construct_at. --- libraries/chain/include/eosio/chain/database_utils.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libraries/chain/include/eosio/chain/database_utils.hpp b/libraries/chain/include/eosio/chain/database_utils.hpp index b456c005f3..e105d97bf0 100644 --- a/libraries/chain/include/eosio/chain/database_utils.hpp +++ b/libraries/chain/include/eosio/chain/database_utils.hpp @@ -171,7 +171,8 @@ namespace fc { inline void from_variant( const variant& v, eosio::chain::shared_blob& b ) { std::string _s = base64_decode(v.as_string()); - new (&b) std::string_view(_s); + std::destroy_at(&b); + new (&b) eosio::chain::shared_blob(std::string_view(_s)); // construct in place } template From 4cccbb6e43c19f58b96891f97f3cd77519e3b751 Mon Sep 17 00:00:00 2001 From: greg7mdp Date: Thu, 2 Nov 2023 18:24:38 -0400 Subject: [PATCH 19/40] Add assignment operator so we don't construct and copy the shared_blob. --- libraries/chain/include/eosio/chain/database_utils.hpp | 3 +-- libraries/chain/include/eosio/chain/types.hpp | 4 ++++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/libraries/chain/include/eosio/chain/database_utils.hpp b/libraries/chain/include/eosio/chain/database_utils.hpp index e105d97bf0..e4531d7cdf 100644 --- a/libraries/chain/include/eosio/chain/database_utils.hpp +++ b/libraries/chain/include/eosio/chain/database_utils.hpp @@ -171,8 +171,7 @@ namespace fc { inline void from_variant( const variant& v, eosio::chain::shared_blob& b ) { std::string _s = base64_decode(v.as_string()); - std::destroy_at(&b); - new (&b) eosio::chain::shared_blob(std::string_view(_s)); // construct in place + b = std::string_view(_s); } template diff --git a/libraries/chain/include/eosio/chain/types.hpp b/libraries/chain/include/eosio/chain/types.hpp index 583f5b800f..50006dbc1c 100644 --- a/libraries/chain/include/eosio/chain/types.hpp +++ b/libraries/chain/include/eosio/chain/types.hpp @@ -112,6 +112,10 @@ namespace eosio::chain { shared_blob& operator=(const shared_blob& s) = default; shared_blob& operator=(shared_blob&& ) = default; + shared_blob& operator=(std::string_view sv) { + static_cast(*this) = sv; + return *this; + } }; using action_name = name; From 873c7811e7190a9c28be90f3c10c40f0eefb229a Mon Sep 17 00:00:00 2001 From: greg7mdp Date: Thu, 2 Nov 2023 18:46:12 -0400 Subject: [PATCH 20/40] Remove unnecessary `explicit` qualifier on default constructor. --- libraries/chain/include/eosio/chain/producer_schedule.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/chain/include/eosio/chain/producer_schedule.hpp b/libraries/chain/include/eosio/chain/producer_schedule.hpp index 7a4deddba5..bb896f8914 100644 --- a/libraries/chain/include/eosio/chain/producer_schedule.hpp +++ b/libraries/chain/include/eosio/chain/producer_schedule.hpp @@ -49,7 +49,7 @@ namespace eosio { namespace chain { struct block_signing_authority_v0; struct shared_block_signing_authority_v0 { - explicit shared_block_signing_authority_v0() = default; + shared_block_signing_authority_v0() = default; shared_block_signing_authority_v0( const block_signing_authority_v0& ); shared_block_signing_authority_v0( const shared_block_signing_authority_v0& ) = default; shared_block_signing_authority_v0( shared_block_signing_authority_v0&& ) = default; From 1eeab6f3cccc66dca7d490a2bd0392c0094756b0 Mon Sep 17 00:00:00 2001 From: greg7mdp Date: Thu, 2 Nov 2023 19:17:19 -0400 Subject: [PATCH 21/40] Add assignment operators to some `shared` classes to avoid copies. --- .../chain/include/eosio/chain/authority.hpp | 16 +++++++++++++++ .../include/eosio/chain/producer_schedule.hpp | 3 +++ libraries/chain/producer_schedule.cpp | 20 ++++++++++++++++++- libraries/chainbase | 2 +- 4 files changed, 39 insertions(+), 2 deletions(-) diff --git a/libraries/chain/include/eosio/chain/authority.hpp b/libraries/chain/include/eosio/chain/authority.hpp index bf1de1f0c9..24317474d1 100644 --- a/libraries/chain/include/eosio/chain/authority.hpp +++ b/libraries/chain/include/eosio/chain/authority.hpp @@ -238,6 +238,22 @@ struct shared_authority { { } + shared_authority& operator=(const authority& auth) { + threshold = auth.threshold; + keys = auth.keys; + accounts = auth.accounts; + waits = auth.waits; + return *this; + } + + shared_authority& operator=(authority&& auth) { + threshold = auth.threshold; + keys = std::move(auth.keys); + accounts = std::move(auth.accounts); + waits = std::move(auth.waits); + return *this; + } + uint32_t threshold = 0; shared_vector keys; shared_vector accounts; diff --git a/libraries/chain/include/eosio/chain/producer_schedule.hpp b/libraries/chain/include/eosio/chain/producer_schedule.hpp index bb896f8914..af4f513bc8 100644 --- a/libraries/chain/include/eosio/chain/producer_schedule.hpp +++ b/libraries/chain/include/eosio/chain/producer_schedule.hpp @@ -55,6 +55,7 @@ namespace eosio { namespace chain { shared_block_signing_authority_v0( shared_block_signing_authority_v0&& ) = default; shared_block_signing_authority_v0& operator= ( shared_block_signing_authority_v0 && ) = default; shared_block_signing_authority_v0& operator= ( const shared_block_signing_authority_v0 & ) = default; + shared_block_signing_authority_v0& operator= ( const block_signing_authority_v0 & ); uint32_t threshold = 0; shared_vector keys; @@ -67,6 +68,7 @@ namespace eosio { namespace chain { struct shared_producer_authority { shared_producer_authority() = default; explicit shared_producer_authority(const producer_authority& ); + shared_producer_authority& operator=(const producer_authority& ); shared_producer_authority( const shared_producer_authority& ) = default; shared_producer_authority( shared_producer_authority&& ) = default; @@ -88,6 +90,7 @@ namespace eosio { namespace chain { shared_producer_authority_schedule() = default; shared_producer_authority_schedule( const producer_authority_schedule& ); + shared_producer_authority_schedule& operator=(const producer_authority_schedule& ); shared_producer_authority_schedule( const shared_producer_authority_schedule& ) = default; shared_producer_authority_schedule( shared_producer_authority_schedule&& ) = default; diff --git a/libraries/chain/producer_schedule.cpp b/libraries/chain/producer_schedule.cpp index e7b8b23345..97619b588f 100644 --- a/libraries/chain/producer_schedule.cpp +++ b/libraries/chain/producer_schedule.cpp @@ -26,11 +26,23 @@ shared_producer_authority::shared_producer_authority(const producer_authority& p { } +shared_producer_authority& shared_producer_authority::operator=(const producer_authority& pa) { + producer_name = pa.producer_name; + authority = std::visit([](const T& a) { return T(a);}, pa.authority); + return *this; +} + shared_block_signing_authority_v0::shared_block_signing_authority_v0(const block_signing_authority_v0& bsa) : threshold(bsa.threshold), keys(bsa.keys) { -} +} + +shared_block_signing_authority_v0& shared_block_signing_authority_v0::operator= (const block_signing_authority_v0 & bsa) { + threshold = bsa.threshold; + keys = bsa.keys; + return *this; +} shared_producer_authority_schedule::shared_producer_authority_schedule(const producer_authority_schedule& pas) : version(pas.version), @@ -38,4 +50,10 @@ shared_producer_authority_schedule::shared_producer_authority_schedule(const pro { } +shared_producer_authority_schedule& shared_producer_authority_schedule::operator=(const producer_authority_schedule& pas) { + version = pas.version; + producers = pas.producers; + return *this; +} + } /// eosio::chain diff --git a/libraries/chainbase b/libraries/chainbase index 5c250406a9..2be7e8e468 160000 --- a/libraries/chainbase +++ b/libraries/chainbase @@ -1 +1 @@ -Subproject commit 5c250406a9a5025a340b5786826f4f9637e76e0b +Subproject commit 2be7e8e468783ef550bb139b6d6c6dc86fc64fc8 From 8726c0e62e5e885f392b2666de28e2ece3a87800 Mon Sep 17 00:00:00 2001 From: greg7mdp Date: Fri, 3 Nov 2023 07:53:20 -0400 Subject: [PATCH 22/40] Fix `unpack(shared_vector)` which was using wrong API. Need to write a test for this. --- libraries/chain/include/eosio/chain/types.hpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libraries/chain/include/eosio/chain/types.hpp b/libraries/chain/include/eosio/chain/types.hpp index 50006dbc1c..3c9ff39c9d 100644 --- a/libraries/chain/include/eosio/chain/types.hpp +++ b/libraries/chain/include/eosio/chain/types.hpp @@ -443,9 +443,10 @@ namespace fc::raw { fc::raw::unpack( s, size ); FC_ASSERT(size.value <= MAX_SIZE_OF_BYTE_ARRAYS); FC_ASSERT(v.size() == 0); - v.resize_and_fill(size.value, [&](auto* data, std::size_t sz) { + v.clear_and_construct(size.value, 0, [&](auto* dest, std::size_t sz) { for (std::size_t i = 0; i < sz; ++i) { - fc::raw::unpack(s, data[i]); + new (dest+i) T(); // unpack expects a constructed variable + fc::raw::unpack(s, dest[i]); } }); } From e7d62af98c95962b5bf22c5da49544cdda2f120d Mon Sep 17 00:00:00 2001 From: greg7mdp Date: Fri, 3 Nov 2023 08:08:07 -0400 Subject: [PATCH 23/40] Support rename `data()` -> `mutable_data()`. --- libraries/chain/include/eosio/chain/authority.hpp | 4 ++-- libraries/chainbase | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/libraries/chain/include/eosio/chain/authority.hpp b/libraries/chain/include/eosio/chain/authority.hpp index 24317474d1..11ae30feb4 100644 --- a/libraries/chain/include/eosio/chain/authority.hpp +++ b/libraries/chain/include/eosio/chain/authority.hpp @@ -126,8 +126,8 @@ struct shared_key_weight { // create a shared_string in the pubkey that we will write (using pack) directly into. key.pubkey.emplace(psz, boost::container::default_init_t()); auto& s = std::get(key.pubkey); - assert(s.data()); - fc::datastream ds(s.data(), psz); + assert(s.mutable_data() && s.size() == psz); + fc::datastream ds(s.mutable_data(), psz); fc::raw::pack(ds, wa); } }, k.key._storage); diff --git a/libraries/chainbase b/libraries/chainbase index 2be7e8e468..30660ec379 160000 --- a/libraries/chainbase +++ b/libraries/chainbase @@ -1 +1 @@ -Subproject commit 2be7e8e468783ef550bb139b6d6c6dc86fc64fc8 +Subproject commit 30660ec37986d09a5df510b2f1646a09f9a888de From 539b4cf5be300d55bbde5aa60359b89535b7b9e8 Mon Sep 17 00:00:00 2001 From: greg7mdp Date: Fri, 3 Nov 2023 16:43:48 -0400 Subject: [PATCH 24/40] Fix mistake in `shared_vector` `unpack` identified with new test. --- libraries/chain/include/eosio/chain/types.hpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/libraries/chain/include/eosio/chain/types.hpp b/libraries/chain/include/eosio/chain/types.hpp index 3c9ff39c9d..1e464d6d5f 100644 --- a/libraries/chain/include/eosio/chain/types.hpp +++ b/libraries/chain/include/eosio/chain/types.hpp @@ -90,6 +90,7 @@ namespace eosio::chain { template using shared_set = boost::interprocess::set, allocator>; + template using shared_flat_multimap = boost::interprocess::flat_multimap< K, V, std::less, allocator< std::pair > >; @@ -443,11 +444,9 @@ namespace fc::raw { fc::raw::unpack( s, size ); FC_ASSERT(size.value <= MAX_SIZE_OF_BYTE_ARRAYS); FC_ASSERT(v.size() == 0); - v.clear_and_construct(size.value, 0, [&](auto* dest, std::size_t sz) { - for (std::size_t i = 0; i < sz; ++i) { - new (dest+i) T(); // unpack expects a constructed variable - fc::raw::unpack(s, dest[i]); - } + v.clear_and_construct(size.value, 0, [&](auto* dest, std::size_t i) { + new (dest) T(); // unpack expects a constructed variable + fc::raw::unpack(s, *dest); }); } } From d540bb2b611f788f43bd82ff8aac38057787c1f7 Mon Sep 17 00:00:00 2001 From: greg7mdp Date: Fri, 3 Nov 2023 16:44:55 -0400 Subject: [PATCH 25/40] Add new test for `pack/unpack` of shared objects. Test also verifies that the objects use the expected allocator. --- libraries/chainbase | 2 +- plugins/chain_plugin/test/CMakeLists.txt | 1 + .../test/test_chainbase_types.cpp | 132 ++++++++++++++++++ 3 files changed, 134 insertions(+), 1 deletion(-) create mode 100644 plugins/chain_plugin/test/test_chainbase_types.cpp diff --git a/libraries/chainbase b/libraries/chainbase index 30660ec379..7bd0fcd763 160000 --- a/libraries/chainbase +++ b/libraries/chainbase @@ -1 +1 @@ -Subproject commit 30660ec37986d09a5df510b2f1646a09f9a888de +Subproject commit 7bd0fcd7637be909374e1735349fb72cf7eda3a1 diff --git a/plugins/chain_plugin/test/CMakeLists.txt b/plugins/chain_plugin/test/CMakeLists.txt index 81473d42e9..33249551fa 100644 --- a/plugins/chain_plugin/test/CMakeLists.txt +++ b/plugins/chain_plugin/test/CMakeLists.txt @@ -2,6 +2,7 @@ add_executable( test_chain_plugin test_account_query_db.cpp test_trx_retry_db.cpp test_trx_finality_status_processing.cpp + test_chainbase_types.cpp plugin_config_test.cpp main.cpp ) diff --git a/plugins/chain_plugin/test/test_chainbase_types.cpp b/plugins/chain_plugin/test/test_chainbase_types.cpp new file mode 100644 index 0000000000..61a8d9fdbb --- /dev/null +++ b/plugins/chain_plugin/test/test_chainbase_types.cpp @@ -0,0 +1,132 @@ +#include +#include + +#include +#include +#include + +class temp_directory { + std::filesystem::path tmp_path; + + public: + temp_directory(const std::filesystem::path& tempFolder = std::filesystem::temp_directory_path()) { + std::filesystem::path template_path{ tempFolder / "chain-tests-XXXXXX" }; + std::string tmp_buf = template_path.string(); + if (mkdtemp(tmp_buf.data()) == nullptr) + throw std::system_error(errno, std::generic_category(), __PRETTY_FUNCTION__); + tmp_path = tmp_buf; + } + + temp_directory(const temp_directory&) = delete; + + temp_directory(temp_directory&& other) noexcept { tmp_path.swap(other.tmp_path); } + + ~temp_directory() { + if (!tmp_path.empty()) { + std::error_code ec; + std::filesystem::remove_all(tmp_path, ec); + } + } + + temp_directory& operator=(const temp_directory&) = delete; + temp_directory& operator=(temp_directory&& other) noexcept { + tmp_path.swap(other.tmp_path); + return *this; + } + const std::filesystem::path& path() const { return tmp_path; } +}; + +namespace bip = boost::interprocess; +namespace fs = std::filesystem; + +using namespace chainbase; + +template +using bip_vector = bip::vector; + +using shared_string_vector = shared_vector; + +struct book { + shared_string title; + shared_string_vector authors; + + bool operator==(const book&) const = default; +}; + +FC_REFLECT(book, (title)(authors)) + +namespace fc::raw { + template inline void pack(Stream& s, const book& b) { + fc::raw::pack(s, b.title); + fc::raw::pack(s, b.authors); + } + + template inline void unpack(Stream& s, book& b) { + fc::raw::unpack(s, b.title); + fc::raw::unpack(s, b.authors); + } +} + +template inline DataStream& operator<<(DataStream& s, const book& b) { + fc::raw::pack(s, b); + return s; +} + +template inline DataStream& operator>>(DataStream& s, book& b) { + fc::raw::unpack(s, b); + return s; +} + + +template +void check_pack_unpack(V &v, V &v2) { + v.emplace_back(shared_string("Moby Dick"), shared_string_vector{ "Herman Melville" }); + v.emplace_back(shared_string("All the President's Men"), shared_string_vector{ "Carl Bernstein", "Bob Woodward" }); + + BOOST_REQUIRE(v[1].title == "All the President's Men"); + BOOST_REQUIRE(v[1].authors[1] == "Bob Woodward"); + + // try pack/unpack + constexpr size_t buffsz = 4096; + char buf[buffsz]; + fc::datastream ds(buf, buffsz); + + fc::raw::pack(ds, v); + ds.seekp(0); + fc::raw::unpack(ds, v2); + BOOST_REQUIRE(v2[1].title == "All the President's Men"); + BOOST_REQUIRE(v2[1].authors[1] == "Bob Woodward"); + BOOST_REQUIRE(v == v2); +} + +BOOST_AUTO_TEST_CASE(chainbase_type_heap_alloc) { + std::vector v, v2; + check_pack_unpack(v, v2); + + // check that objects inside the vectors are allocated within theheap + BOOST_REQUIRE(!v[1].title.get_allocator()); + BOOST_REQUIRE(!v2[1].authors[0].get_allocator()); +} + +BOOST_AUTO_TEST_CASE(chainbase_type_segment_alloc) { + fs::path temp = fs::temp_directory_path() / "pinnable_mapped_file_101"; + try { + pinnable_mapped_file pmf(temp, true, 1024 * 1024, false, pinnable_mapped_file::map_mode::mapped); + chainbase::allocator alloc(reinterpret_cast(pmf.get_segment_manager())); + bip_vector> v(alloc); + bip_vector> v2(alloc); + + check_pack_unpack(v, v2); + auto a = v[1].title.get_allocator(); + auto a2 = v2[1].authors[0].get_allocator(); + + // check that objects inside the vectors are allocated within the pinnable_mapped_file segment + BOOST_REQUIRE(a && (chainbase::allocator)(*a) == alloc); + BOOST_REQUIRE(a2 && (chainbase::allocator)(*a2) == alloc); + + } catch ( ... ) { + fs::remove_all( temp ); + throw; + } + fs::remove_all( temp ); +} From 4c9f1056dd36dd1d5bd3955a979a322ba2ceb07d Mon Sep 17 00:00:00 2001 From: greg7mdp Date: Fri, 3 Nov 2023 17:32:53 -0400 Subject: [PATCH 26/40] Cleanup new test program. --- .../test/test_chainbase_types.cpp | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/plugins/chain_plugin/test/test_chainbase_types.cpp b/plugins/chain_plugin/test/test_chainbase_types.cpp index 61a8d9fdbb..caa7fc9022 100644 --- a/plugins/chain_plugin/test/test_chainbase_types.cpp +++ b/plugins/chain_plugin/test/test_chainbase_types.cpp @@ -46,7 +46,7 @@ using bip_vector = bip::vector; using shared_string_vector = shared_vector; -struct book { +struct book { shared_string title; shared_string_vector authors; @@ -56,28 +56,19 @@ struct book { FC_REFLECT(book, (title)(authors)) namespace fc::raw { - template inline void pack(Stream& s, const book& b) { + template + inline void pack(Stream& s, const book& b) { fc::raw::pack(s, b.title); fc::raw::pack(s, b.authors); } - template inline void unpack(Stream& s, book& b) { + template + inline void unpack(Stream& s, book& b) { fc::raw::unpack(s, b.title); fc::raw::unpack(s, b.authors); } } -template inline DataStream& operator<<(DataStream& s, const book& b) { - fc::raw::pack(s, b); - return s; -} - -template inline DataStream& operator>>(DataStream& s, book& b) { - fc::raw::unpack(s, b); - return s; -} - - template void check_pack_unpack(V &v, V &v2) { v.emplace_back(shared_string("Moby Dick"), shared_string_vector{ "Herman Melville" }); From a43dc59ecc423d73e592a93e04d0d4ce508e9b0b Mon Sep 17 00:00:00 2001 From: greg7mdp Date: Fri, 3 Nov 2023 17:55:52 -0400 Subject: [PATCH 27/40] Update chainbase to branch tip, and minor cleanup in `types.hpp` --- libraries/chain/include/eosio/chain/types.hpp | 24 ++++++++++++------- libraries/chainbase | 2 +- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/libraries/chain/include/eosio/chain/types.hpp b/libraries/chain/include/eosio/chain/types.hpp index 1e464d6d5f..03e69a7805 100644 --- a/libraries/chain/include/eosio/chain/types.hpp +++ b/libraries/chain/include/eosio/chain/types.hpp @@ -413,14 +413,16 @@ namespace eosio::chain { namespace fc::raw { // pack/unpack chainbase::shared_cow_string // ---------------------------------------- - template inline void pack(Stream& s, const chainbase::shared_string& v) { + template + inline void pack(Stream& s, const chainbase::shared_string& v) { FC_ASSERT(v.size() <= MAX_SIZE_OF_BYTE_ARRAYS); fc::raw::pack(s, fc::unsigned_int((uint32_t)v.size())); if (v.size()) s.write(v.data(), v.size()); } - template inline void unpack(Stream& s, chainbase::shared_string& v) { + template + inline void unpack(Stream& s, chainbase::shared_string& v) { fc::unsigned_int sz; fc::raw::unpack(s, sz); if (sz) { @@ -432,14 +434,16 @@ namespace fc::raw { // pack/unpack chainbase::shared_cow_vector // ---------------------------------------- - template inline void pack(Stream& s, const chainbase::shared_cow_vector& v) { + template + inline void pack(Stream& s, const chainbase::shared_cow_vector& v) { FC_ASSERT(v.size() <= MAX_SIZE_OF_BYTE_ARRAYS); fc::raw::pack( s, fc::unsigned_int((uint32_t)v.size())); for (const auto& el : v) fc::raw::pack(s, el); } - template inline void unpack(Stream& s, chainbase::shared_cow_vector& v) { + template + inline void unpack(Stream& s, chainbase::shared_cow_vector& v) { fc::unsigned_int size; fc::raw::unpack( s, size ); FC_ASSERT(size.value <= MAX_SIZE_OF_BYTE_ARRAYS); @@ -454,24 +458,28 @@ namespace fc::raw { namespace chainbase { // chainbase::shared_cow_string // ---------------------------- - template inline DataStream& operator<<(DataStream& s, const chainbase::shared_cow_string& v) { + template + inline Stream& operator<<(Stream& s, const chainbase::shared_cow_string& v) { fc::raw::pack(s, v); return s; } - template inline DataStream& operator>>(DataStream& s, chainbase::shared_cow_string& v) { + template + inline Stream& operator>>(Stream& s, chainbase::shared_cow_string& v) { fc::raw::unpack(s, v); return s; } // chainbase::shared_cow_vector // ---------------------------- - template inline DataStream& operator<<(DataStream& s, const chainbase::shared_cow_vector& v) { + template + inline Stream& operator<<(Stream& s, const chainbase::shared_cow_vector& v) { fc::raw::pack(s, v); return s; } - template inline DataStream& operator>>(DataStream& s, chainbase::shared_cow_vector& v) { + template + inline Stream& operator>>(Stream& s, chainbase::shared_cow_vector& v) { fc::raw::unpack(s, v); return s; } diff --git a/libraries/chainbase b/libraries/chainbase index 7bd0fcd763..cfd0966422 160000 --- a/libraries/chainbase +++ b/libraries/chainbase @@ -1 +1 @@ -Subproject commit 7bd0fcd7637be909374e1735349fb72cf7eda3a1 +Subproject commit cfd096642203c79b0b59b5694086f6b4f8d52443 From 66165e758f7bc32ea64b60019b3ecf767a1e5aa2 Mon Sep 17 00:00:00 2001 From: greg7mdp Date: Tue, 7 Nov 2023 14:15:58 -0500 Subject: [PATCH 28/40] Remove unused `shared_set` type. --- libraries/chain/include/eosio/chain/types.hpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/libraries/chain/include/eosio/chain/types.hpp b/libraries/chain/include/eosio/chain/types.hpp index 03e69a7805..9931d28f10 100644 --- a/libraries/chain/include/eosio/chain/types.hpp +++ b/libraries/chain/include/eosio/chain/types.hpp @@ -88,9 +88,6 @@ namespace eosio::chain { template using shared_vector = chainbase::shared_vector; - template - using shared_set = boost::interprocess::set, allocator>; - template using shared_flat_multimap = boost::interprocess::flat_multimap< K, V, std::less, allocator< std::pair > >; From c8c909560e7b030f1829973fa3a53cb608f3113f Mon Sep 17 00:00:00 2001 From: greg7mdp Date: Tue, 7 Nov 2023 14:21:38 -0500 Subject: [PATCH 29/40] Move serialization function for `shared` types to database_utils.hpp. --- .../include/eosio/chain/database_utils.hpp | 73 ++++++++++++++++++ libraries/chain/include/eosio/chain/types.hpp | 76 ------------------- .../test/test_chainbase_types.cpp | 2 +- 3 files changed, 74 insertions(+), 77 deletions(-) diff --git a/libraries/chain/include/eosio/chain/database_utils.hpp b/libraries/chain/include/eosio/chain/database_utils.hpp index e4531d7cdf..e52bb45e8c 100644 --- a/libraries/chain/include/eosio/chain/database_utils.hpp +++ b/libraries/chain/include/eosio/chain/database_utils.hpp @@ -187,6 +187,51 @@ namespace fc { } } +namespace fc::raw { + // pack/unpack chainbase::shared_cow_string + // ---------------------------------------- + template + inline void pack(Stream& s, const chainbase::shared_string& v) { + FC_ASSERT(v.size() <= MAX_SIZE_OF_BYTE_ARRAYS); + fc::raw::pack(s, fc::unsigned_int((uint32_t)v.size())); + if (v.size()) + s.write(v.data(), v.size()); + } + + template + inline void unpack(Stream& s, chainbase::shared_string& v) { + fc::unsigned_int sz; + fc::raw::unpack(s, sz); + if (sz) { + v.resize_and_fill(sz, [&](char* buf, std::size_t sz){ + s.read(buf, sz); + }); + } + } + + // pack/unpack chainbase::shared_cow_vector + // ---------------------------------------- + template + inline void pack(Stream& s, const chainbase::shared_cow_vector& v) { + FC_ASSERT(v.size() <= MAX_SIZE_OF_BYTE_ARRAYS); + fc::raw::pack( s, fc::unsigned_int((uint32_t)v.size())); + for (const auto& el : v) + fc::raw::pack(s, el); + } + + template + inline void unpack(Stream& s, chainbase::shared_cow_vector& v) { + fc::unsigned_int size; + fc::raw::unpack( s, size ); + FC_ASSERT(size.value <= MAX_SIZE_OF_BYTE_ARRAYS); + FC_ASSERT(v.size() == 0); + v.clear_and_construct(size.value, 0, [&](auto* dest, std::size_t i) { + new (dest) T(); // unpack expects a constructed variable + fc::raw::unpack(s, *dest); + }); + } +} + namespace chainbase { // overloads for OID packing template @@ -200,6 +245,34 @@ namespace chainbase { fc::raw::unpack(ds, oid._id); return ds; } + + // chainbase::shared_cow_string + // ---------------------------- + template + inline Stream& operator<<(Stream& s, const chainbase::shared_cow_string& v) { + fc::raw::pack(s, v); + return s; + } + + template + inline Stream& operator>>(Stream& s, chainbase::shared_cow_string& v) { + fc::raw::unpack(s, v); + return s; + } + + // chainbase::shared_cow_vector + // ---------------------------- + template + inline Stream& operator<<(Stream& s, const chainbase::shared_cow_vector& v) { + fc::raw::pack(s, v); + return s; + } + + template + inline Stream& operator>>(Stream& s, chainbase::shared_cow_vector& v) { + fc::raw::unpack(s, v); + return s; + } } // overloads for softfloat packing diff --git a/libraries/chain/include/eosio/chain/types.hpp b/libraries/chain/include/eosio/chain/types.hpp index 9931d28f10..102b9f0dd6 100644 --- a/libraries/chain/include/eosio/chain/types.hpp +++ b/libraries/chain/include/eosio/chain/types.hpp @@ -406,80 +406,4 @@ namespace eosio::chain { } // eosio::chain - -namespace fc::raw { - // pack/unpack chainbase::shared_cow_string - // ---------------------------------------- - template - inline void pack(Stream& s, const chainbase::shared_string& v) { - FC_ASSERT(v.size() <= MAX_SIZE_OF_BYTE_ARRAYS); - fc::raw::pack(s, fc::unsigned_int((uint32_t)v.size())); - if (v.size()) - s.write(v.data(), v.size()); - } - - template - inline void unpack(Stream& s, chainbase::shared_string& v) { - fc::unsigned_int sz; - fc::raw::unpack(s, sz); - if (sz) { - v.resize_and_fill(sz, [&](char* buf, std::size_t sz){ - s.read(buf, sz); - }); - } - } - - // pack/unpack chainbase::shared_cow_vector - // ---------------------------------------- - template - inline void pack(Stream& s, const chainbase::shared_cow_vector& v) { - FC_ASSERT(v.size() <= MAX_SIZE_OF_BYTE_ARRAYS); - fc::raw::pack( s, fc::unsigned_int((uint32_t)v.size())); - for (const auto& el : v) - fc::raw::pack(s, el); - } - - template - inline void unpack(Stream& s, chainbase::shared_cow_vector& v) { - fc::unsigned_int size; - fc::raw::unpack( s, size ); - FC_ASSERT(size.value <= MAX_SIZE_OF_BYTE_ARRAYS); - FC_ASSERT(v.size() == 0); - v.clear_and_construct(size.value, 0, [&](auto* dest, std::size_t i) { - new (dest) T(); // unpack expects a constructed variable - fc::raw::unpack(s, *dest); - }); - } -} - -namespace chainbase { - // chainbase::shared_cow_string - // ---------------------------- - template - inline Stream& operator<<(Stream& s, const chainbase::shared_cow_string& v) { - fc::raw::pack(s, v); - return s; - } - - template - inline Stream& operator>>(Stream& s, chainbase::shared_cow_string& v) { - fc::raw::unpack(s, v); - return s; - } - - // chainbase::shared_cow_vector - // ---------------------------- - template - inline Stream& operator<<(Stream& s, const chainbase::shared_cow_vector& v) { - fc::raw::pack(s, v); - return s; - } - - template - inline Stream& operator>>(Stream& s, chainbase::shared_cow_vector& v) { - fc::raw::unpack(s, v); - return s; - } -} - FC_REFLECT_EMPTY( eosio::chain::void_t ) diff --git a/plugins/chain_plugin/test/test_chainbase_types.cpp b/plugins/chain_plugin/test/test_chainbase_types.cpp index caa7fc9022..ba6084a9db 100644 --- a/plugins/chain_plugin/test/test_chainbase_types.cpp +++ b/plugins/chain_plugin/test/test_chainbase_types.cpp @@ -1,5 +1,5 @@ #include -#include +#include #include #include From 9c61082fc509f17ebde27ac03a9303993c78ab69 Mon Sep 17 00:00:00 2001 From: greg7mdp Date: Tue, 7 Nov 2023 14:57:06 -0500 Subject: [PATCH 30/40] use `fc::temp_directory` and simplify test. --- .../test/test_chainbase_types.cpp | 64 ++++--------------- 1 file changed, 14 insertions(+), 50 deletions(-) diff --git a/plugins/chain_plugin/test/test_chainbase_types.cpp b/plugins/chain_plugin/test/test_chainbase_types.cpp index ba6084a9db..e0a87ee44d 100644 --- a/plugins/chain_plugin/test/test_chainbase_types.cpp +++ b/plugins/chain_plugin/test/test_chainbase_types.cpp @@ -5,37 +5,6 @@ #include #include -class temp_directory { - std::filesystem::path tmp_path; - - public: - temp_directory(const std::filesystem::path& tempFolder = std::filesystem::temp_directory_path()) { - std::filesystem::path template_path{ tempFolder / "chain-tests-XXXXXX" }; - std::string tmp_buf = template_path.string(); - if (mkdtemp(tmp_buf.data()) == nullptr) - throw std::system_error(errno, std::generic_category(), __PRETTY_FUNCTION__); - tmp_path = tmp_buf; - } - - temp_directory(const temp_directory&) = delete; - - temp_directory(temp_directory&& other) noexcept { tmp_path.swap(other.tmp_path); } - - ~temp_directory() { - if (!tmp_path.empty()) { - std::error_code ec; - std::filesystem::remove_all(tmp_path, ec); - } - } - - temp_directory& operator=(const temp_directory&) = delete; - temp_directory& operator=(temp_directory&& other) noexcept { - tmp_path.swap(other.tmp_path); - return *this; - } - const std::filesystem::path& path() const { return tmp_path; } -}; - namespace bip = boost::interprocess; namespace fs = std::filesystem; @@ -100,24 +69,19 @@ BOOST_AUTO_TEST_CASE(chainbase_type_heap_alloc) { } BOOST_AUTO_TEST_CASE(chainbase_type_segment_alloc) { - fs::path temp = fs::temp_directory_path() / "pinnable_mapped_file_101"; - try { - pinnable_mapped_file pmf(temp, true, 1024 * 1024, false, pinnable_mapped_file::map_mode::mapped); - chainbase::allocator alloc(reinterpret_cast(pmf.get_segment_manager())); - bip_vector> v(alloc); - bip_vector> v2(alloc); - - check_pack_unpack(v, v2); - auto a = v[1].title.get_allocator(); - auto a2 = v2[1].authors[0].get_allocator(); - - // check that objects inside the vectors are allocated within the pinnable_mapped_file segment - BOOST_REQUIRE(a && (chainbase::allocator)(*a) == alloc); - BOOST_REQUIRE(a2 && (chainbase::allocator)(*a2) == alloc); + fc::temp_directory temp_dir; + fs::path temp = temp_dir.path() / "pinnable_mapped_file_101"; + + pinnable_mapped_file pmf(temp, true, 1024 * 1024, false, pinnable_mapped_file::map_mode::mapped); + chainbase::allocator alloc(reinterpret_cast(pmf.get_segment_manager())); + bip_vector> v(alloc); + bip_vector> v2(alloc); + + check_pack_unpack(v, v2); + auto a = v[1].title.get_allocator(); + auto a2 = v2[1].authors[0].get_allocator(); - } catch ( ... ) { - fs::remove_all( temp ); - throw; - } - fs::remove_all( temp ); + // check that objects inside the vectors are allocated within the pinnable_mapped_file segment + BOOST_REQUIRE(a && (chainbase::allocator)(*a) == alloc); + BOOST_REQUIRE(a2 && (chainbase::allocator)(*a2) == alloc); } From aeb64c31a90992447f6ba9b74490488581422e81 Mon Sep 17 00:00:00 2001 From: greg7mdp Date: Tue, 7 Nov 2023 16:02:22 -0500 Subject: [PATCH 31/40] Move `test_chainbase_types.cpp` from `chain_plugin/test` -> unittests --- libraries/chainbase | 2 +- plugins/chain_plugin/test/CMakeLists.txt | 1 - .../chain_plugin/test => unittests}/test_chainbase_types.cpp | 0 3 files changed, 1 insertion(+), 2 deletions(-) rename {plugins/chain_plugin/test => unittests}/test_chainbase_types.cpp (100%) diff --git a/libraries/chainbase b/libraries/chainbase index cfd0966422..a283498ba6 160000 --- a/libraries/chainbase +++ b/libraries/chainbase @@ -1 +1 @@ -Subproject commit cfd096642203c79b0b59b5694086f6b4f8d52443 +Subproject commit a283498ba6d300168ced2093aeaa396579fe329b diff --git a/plugins/chain_plugin/test/CMakeLists.txt b/plugins/chain_plugin/test/CMakeLists.txt index 33249551fa..81473d42e9 100644 --- a/plugins/chain_plugin/test/CMakeLists.txt +++ b/plugins/chain_plugin/test/CMakeLists.txt @@ -2,7 +2,6 @@ add_executable( test_chain_plugin test_account_query_db.cpp test_trx_retry_db.cpp test_trx_finality_status_processing.cpp - test_chainbase_types.cpp plugin_config_test.cpp main.cpp ) diff --git a/plugins/chain_plugin/test/test_chainbase_types.cpp b/unittests/test_chainbase_types.cpp similarity index 100% rename from plugins/chain_plugin/test/test_chainbase_types.cpp rename to unittests/test_chainbase_types.cpp From c97084e626d5010fcc893ea629f4db12c93debe9 Mon Sep 17 00:00:00 2001 From: greg7mdp Date: Tue, 7 Nov 2023 16:12:30 -0500 Subject: [PATCH 32/40] Replace `clear_and_construct` with `emplace_back`. --- libraries/chain/controller.cpp | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/libraries/chain/controller.cpp b/libraries/chain/controller.cpp index 97707635b5..ef6f266dfd 100644 --- a/libraries/chain/controller.cpp +++ b/libraries/chain/controller.cpp @@ -1793,12 +1793,8 @@ struct controller_impl { db.modify( pso, [&]( auto& ps ) { ps.preactivated_protocol_features.clear(); - std::size_t current_size = ps.activated_protocol_features.size(); - std::size_t new_size = current_size + new_protocol_feature_activations.size(); - - ps.activated_protocol_features.clear_and_construct(new_size, current_size, [&](auto* dest, std::size_t idx) { - std::construct_at(dest, new_protocol_feature_activations[idx - current_size], pbhs.block_num); - }); + for (const auto& digest : new_protocol_feature_activations) + ps.activated_protocol_features.emplace_back(digest, pbhs.block_num); }); } From 4b011f3aa088fcd8e4e48bfa704c3a38f8b2a0e4 Mon Sep 17 00:00:00 2001 From: greg7mdp Date: Tue, 7 Nov 2023 16:51:03 -0500 Subject: [PATCH 33/40] Better check for `MAX_SIZE_OF_BYTE_ARRAYS`. --- libraries/chain/include/eosio/chain/database_utils.hpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libraries/chain/include/eosio/chain/database_utils.hpp b/libraries/chain/include/eosio/chain/database_utils.hpp index e52bb45e8c..52bc56a7ae 100644 --- a/libraries/chain/include/eosio/chain/database_utils.hpp +++ b/libraries/chain/include/eosio/chain/database_utils.hpp @@ -202,6 +202,7 @@ namespace fc::raw { inline void unpack(Stream& s, chainbase::shared_string& v) { fc::unsigned_int sz; fc::raw::unpack(s, sz); + FC_ASSERT(sz.value <= MAX_SIZE_OF_BYTE_ARRAYS); if (sz) { v.resize_and_fill(sz, [&](char* buf, std::size_t sz){ s.read(buf, sz); @@ -213,7 +214,7 @@ namespace fc::raw { // ---------------------------------------- template inline void pack(Stream& s, const chainbase::shared_cow_vector& v) { - FC_ASSERT(v.size() <= MAX_SIZE_OF_BYTE_ARRAYS); + FC_ASSERT(v.size() * sizeof(T) <= MAX_SIZE_OF_BYTE_ARRAYS); fc::raw::pack( s, fc::unsigned_int((uint32_t)v.size())); for (const auto& el : v) fc::raw::pack(s, el); @@ -223,7 +224,7 @@ namespace fc::raw { inline void unpack(Stream& s, chainbase::shared_cow_vector& v) { fc::unsigned_int size; fc::raw::unpack( s, size ); - FC_ASSERT(size.value <= MAX_SIZE_OF_BYTE_ARRAYS); + FC_ASSERT(size.value * sizeof(T) <= MAX_SIZE_OF_BYTE_ARRAYS); FC_ASSERT(v.size() == 0); v.clear_and_construct(size.value, 0, [&](auto* dest, std::size_t i) { new (dest) T(); // unpack expects a constructed variable From 8b87b612fed36ce0791a75d813966c4319ef5471 Mon Sep 17 00:00:00 2001 From: greg7mdp Date: Tue, 7 Nov 2023 18:28:52 -0500 Subject: [PATCH 34/40] Better support of pack/unpack size limits. Specialize pack/unpack for `shared_vector` --- .../include/eosio/chain/database_utils.hpp | 25 +++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/libraries/chain/include/eosio/chain/database_utils.hpp b/libraries/chain/include/eosio/chain/database_utils.hpp index 52bc56a7ae..86bdf6598e 100644 --- a/libraries/chain/include/eosio/chain/database_utils.hpp +++ b/libraries/chain/include/eosio/chain/database_utils.hpp @@ -214,7 +214,7 @@ namespace fc::raw { // ---------------------------------------- template inline void pack(Stream& s, const chainbase::shared_cow_vector& v) { - FC_ASSERT(v.size() * sizeof(T) <= MAX_SIZE_OF_BYTE_ARRAYS); + FC_ASSERT(v.size() <= MAX_NUM_ARRAY_ELEMENTS); fc::raw::pack( s, fc::unsigned_int((uint32_t)v.size())); for (const auto& el : v) fc::raw::pack(s, el); @@ -224,13 +224,34 @@ namespace fc::raw { inline void unpack(Stream& s, chainbase::shared_cow_vector& v) { fc::unsigned_int size; fc::raw::unpack( s, size ); - FC_ASSERT(size.value * sizeof(T) <= MAX_SIZE_OF_BYTE_ARRAYS); + FC_ASSERT(size.value <= MAX_NUM_ARRAY_ELEMENTS); FC_ASSERT(v.size() == 0); v.clear_and_construct(size.value, 0, [&](auto* dest, std::size_t i) { new (dest) T(); // unpack expects a constructed variable fc::raw::unpack(s, *dest); }); } + + // pack/unpack chainbase::shared_cow_vector + // ---------------------------------------------- + template + inline void pack(Stream& s, const chainbase::shared_cow_vector& v) { + FC_ASSERT(v.size() <= MAX_SIZE_OF_BYTE_ARRAYS); + fc::raw::pack( s, fc::unsigned_int((uint32_t)v.size())); + if( v.size() ) + s.write((const char*)v.data(), v.size()); + } + + template + inline void unpack(Stream& s, chainbase::shared_cow_vector& v) { + fc::unsigned_int size; + fc::raw::unpack( s, size ); + FC_ASSERT(size.value <= MAX_SIZE_OF_BYTE_ARRAYS); + FC_ASSERT(v.size() == 0); + v.clear_and_construct(size.value, 0, [&](auto* dest, std::size_t i) { + s.read(dest, 1); + }); + } } namespace chainbase { From e776e792d45a031cdfb95f5d3b97d397b5ef9669 Mon Sep 17 00:00:00 2001 From: greg7mdp Date: Thu, 9 Nov 2023 08:50:45 -0500 Subject: [PATCH 35/40] Update chainbase to tip. --- libraries/chainbase | 2 +- unittests/test_chainbase_types.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/chainbase b/libraries/chainbase index a283498ba6..ec98eb162c 160000 --- a/libraries/chainbase +++ b/libraries/chainbase @@ -1 +1 @@ -Subproject commit a283498ba6d300168ced2093aeaa396579fe329b +Subproject commit ec98eb162c7b9db4f982a32c77d030933615724d diff --git a/unittests/test_chainbase_types.cpp b/unittests/test_chainbase_types.cpp index e0a87ee44d..ff4760344f 100644 --- a/unittests/test_chainbase_types.cpp +++ b/unittests/test_chainbase_types.cpp @@ -73,7 +73,7 @@ BOOST_AUTO_TEST_CASE(chainbase_type_segment_alloc) { fs::path temp = temp_dir.path() / "pinnable_mapped_file_101"; pinnable_mapped_file pmf(temp, true, 1024 * 1024, false, pinnable_mapped_file::map_mode::mapped); - chainbase::allocator alloc(reinterpret_cast(pmf.get_segment_manager())); + chainbase::allocator alloc(pmf.get_segment_manager()); bip_vector> v(alloc); bip_vector> v2(alloc); From 224e6b1bbe6eeb3f88fff04196d8b33822a5ef0a Mon Sep 17 00:00:00 2001 From: greg7mdp Date: Thu, 9 Nov 2023 17:56:56 -0500 Subject: [PATCH 36/40] Update chainbase branch to tip. --- libraries/chainbase | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/chainbase b/libraries/chainbase index ec98eb162c..61ea098a80 160000 --- a/libraries/chainbase +++ b/libraries/chainbase @@ -1 +1 @@ -Subproject commit ec98eb162c7b9db4f982a32c77d030933615724d +Subproject commit 61ea098a8059581c279543b96976d32f4e031a6f From 3ff0b4e5060b3efd9ac72017bb2e9ec29c83e75e Mon Sep 17 00:00:00 2001 From: greg7mdp Date: Tue, 14 Nov 2023 07:55:53 -0500 Subject: [PATCH 37/40] Update chainbase to tip of main branch --- libraries/chainbase | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/chainbase b/libraries/chainbase index 61ea098a80..85d33aa1f1 160000 --- a/libraries/chainbase +++ b/libraries/chainbase @@ -1 +1 @@ -Subproject commit 61ea098a8059581c279543b96976d32f4e031a6f +Subproject commit 85d33aa1f193f384ec3aa852bbd84ed420f71f53 From 94f38e817c61162d97e5a0e78691ebdc8cd51ae2 Mon Sep 17 00:00:00 2001 From: greg7mdp Date: Tue, 14 Nov 2023 12:15:05 -0500 Subject: [PATCH 38/40] Operators `<<` and `>>` on stream are enough to serialize `shared_*` classes. --- .../include/eosio/chain/database_utils.hpp | 106 ++++++------------ 1 file changed, 35 insertions(+), 71 deletions(-) diff --git a/libraries/chain/include/eosio/chain/database_utils.hpp b/libraries/chain/include/eosio/chain/database_utils.hpp index 86bdf6598e..0a3b838b9b 100644 --- a/libraries/chain/include/eosio/chain/database_utils.hpp +++ b/libraries/chain/include/eosio/chain/database_utils.hpp @@ -187,73 +187,6 @@ namespace fc { } } -namespace fc::raw { - // pack/unpack chainbase::shared_cow_string - // ---------------------------------------- - template - inline void pack(Stream& s, const chainbase::shared_string& v) { - FC_ASSERT(v.size() <= MAX_SIZE_OF_BYTE_ARRAYS); - fc::raw::pack(s, fc::unsigned_int((uint32_t)v.size())); - if (v.size()) - s.write(v.data(), v.size()); - } - - template - inline void unpack(Stream& s, chainbase::shared_string& v) { - fc::unsigned_int sz; - fc::raw::unpack(s, sz); - FC_ASSERT(sz.value <= MAX_SIZE_OF_BYTE_ARRAYS); - if (sz) { - v.resize_and_fill(sz, [&](char* buf, std::size_t sz){ - s.read(buf, sz); - }); - } - } - - // pack/unpack chainbase::shared_cow_vector - // ---------------------------------------- - template - inline void pack(Stream& s, const chainbase::shared_cow_vector& v) { - FC_ASSERT(v.size() <= MAX_NUM_ARRAY_ELEMENTS); - fc::raw::pack( s, fc::unsigned_int((uint32_t)v.size())); - for (const auto& el : v) - fc::raw::pack(s, el); - } - - template - inline void unpack(Stream& s, chainbase::shared_cow_vector& v) { - fc::unsigned_int size; - fc::raw::unpack( s, size ); - FC_ASSERT(size.value <= MAX_NUM_ARRAY_ELEMENTS); - FC_ASSERT(v.size() == 0); - v.clear_and_construct(size.value, 0, [&](auto* dest, std::size_t i) { - new (dest) T(); // unpack expects a constructed variable - fc::raw::unpack(s, *dest); - }); - } - - // pack/unpack chainbase::shared_cow_vector - // ---------------------------------------------- - template - inline void pack(Stream& s, const chainbase::shared_cow_vector& v) { - FC_ASSERT(v.size() <= MAX_SIZE_OF_BYTE_ARRAYS); - fc::raw::pack( s, fc::unsigned_int((uint32_t)v.size())); - if( v.size() ) - s.write((const char*)v.data(), v.size()); - } - - template - inline void unpack(Stream& s, chainbase::shared_cow_vector& v) { - fc::unsigned_int size; - fc::raw::unpack( s, size ); - FC_ASSERT(size.value <= MAX_SIZE_OF_BYTE_ARRAYS); - FC_ASSERT(v.size() == 0); - v.clear_and_construct(size.value, 0, [&](auto* dest, std::size_t i) { - s.read(dest, 1); - }); - } -} - namespace chainbase { // overloads for OID packing template @@ -272,13 +205,23 @@ namespace chainbase { // ---------------------------- template inline Stream& operator<<(Stream& s, const chainbase::shared_cow_string& v) { - fc::raw::pack(s, v); + FC_ASSERT(v.size() <= MAX_NUM_ARRAY_ELEMENTS); + fc::raw::pack(s, fc::unsigned_int((uint32_t)v.size())); + if( v.size() ) + s.write((const char*)v.data(), v.size()); return s; } template inline Stream& operator>>(Stream& s, chainbase::shared_cow_string& v) { - fc::raw::unpack(s, v); + fc::unsigned_int sz; + fc::raw::unpack(s, sz); + FC_ASSERT(sz.value <= MAX_SIZE_OF_BYTE_ARRAYS); + if (sz) { + v.resize_and_fill(sz, [&](char* buf, std::size_t sz) { + s.read(buf, sz); + }); + } return s; } @@ -286,13 +229,34 @@ namespace chainbase { // ---------------------------- template inline Stream& operator<<(Stream& s, const chainbase::shared_cow_vector& v) { - fc::raw::pack(s, v); + FC_ASSERT(v.size() <= MAX_NUM_ARRAY_ELEMENTS); + fc::raw::pack( s, fc::unsigned_int((uint32_t)v.size())); + for (const auto& el : v) + fc::raw::pack(s, el); return s; } template inline Stream& operator>>(Stream& s, chainbase::shared_cow_vector& v) { - fc::raw::unpack(s, v); + fc::unsigned_int size; + fc::raw::unpack( s, size ); + FC_ASSERT(size.value <= MAX_NUM_ARRAY_ELEMENTS); + FC_ASSERT(v.size() == 0); + v.clear_and_construct(size.value, 0, [&](auto* dest, std::size_t i) { + new (dest) T(); // unpack expects a constructed variable + fc::raw::unpack(s, *dest); + }); + return s; + } + + // chainbase::shared_cow_vector + // ---------------------------------- + template + inline Stream& operator<<(Stream& s, const chainbase::shared_cow_vector& v) { + FC_ASSERT(v.size() <= MAX_NUM_ARRAY_ELEMENTS); + fc::raw::pack( s, fc::unsigned_int((uint32_t)v.size())); + if( v.size() ) + s.write((const char*)v.data(), v.size()); return s; } } From 417fc055289a2613d2fc924ade28d5804cefa34e Mon Sep 17 00:00:00 2001 From: greg7mdp Date: Tue, 14 Nov 2023 12:59:27 -0500 Subject: [PATCH 39/40] Fix compilation issue. --- libraries/chain/include/eosio/chain/database_utils.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/chain/include/eosio/chain/database_utils.hpp b/libraries/chain/include/eosio/chain/database_utils.hpp index 7c29f08199..a53f2749d4 100644 --- a/libraries/chain/include/eosio/chain/database_utils.hpp +++ b/libraries/chain/include/eosio/chain/database_utils.hpp @@ -171,7 +171,7 @@ namespace fc { inline void from_variant( const variant& v, eosio::chain::shared_blob& b ) { std::vector b64 = base64_decode(v.as_string()); - b = eosio::chain::shared_blob(b64.begin(), b64.end(), b.get_allocator()); + b = std::string_view(b64.begin(), b64.end()); } template From f96f3cfe588626dca500c5fb6f99bf100df9b400 Mon Sep 17 00:00:00 2001 From: greg7mdp Date: Tue, 14 Nov 2023 14:34:51 -0500 Subject: [PATCH 40/40] Change `std::string_view` constructor for c++17 compatibility. --- libraries/chain/include/eosio/chain/database_utils.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/chain/include/eosio/chain/database_utils.hpp b/libraries/chain/include/eosio/chain/database_utils.hpp index a53f2749d4..50766601c2 100644 --- a/libraries/chain/include/eosio/chain/database_utils.hpp +++ b/libraries/chain/include/eosio/chain/database_utils.hpp @@ -171,7 +171,7 @@ namespace fc { inline void from_variant( const variant& v, eosio::chain::shared_blob& b ) { std::vector b64 = base64_decode(v.as_string()); - b = std::string_view(b64.begin(), b64.end()); + b = std::string_view(b64.data(), b64.size()); } template