From 0bcf6d4d65c323f07de85ccda44ade4c80ddf06d Mon Sep 17 00:00:00 2001 From: cifer Date: Sun, 25 Feb 2018 12:14:01 +0800 Subject: [PATCH 1/5] Fix #436 object_database created outside of witness data directory --- libraries/chain/db_management.cpp | 7 ++++++- libraries/chain/include/graphene/chain/database.hpp | 8 ++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/libraries/chain/db_management.cpp b/libraries/chain/db_management.cpp index 68f6fad1..f22a46df 100644 --- a/libraries/chain/db_management.cpp +++ b/libraries/chain/db_management.cpp @@ -119,7 +119,9 @@ void database::reindex(fc::path data_dir, const genesis_state_type& initial_allo void database::wipe(const fc::path& data_dir, bool include_blocks) { ilog("Wiping database", ("include_blocks", include_blocks)); - close(); + if (_opened) { + close(); + } object_database::wipe(data_dir); if( include_blocks ) fc::remove_all( data_dir / "database" ); @@ -148,6 +150,7 @@ void database::open( ("last_block->id", last_block->id())("head_block_num",head_block_num()) ); } } + _opened = true; } FC_CAPTURE_LOG_AND_RETHROW( (data_dir) ) } @@ -198,6 +201,8 @@ void database::close(bool rewind) _block_id_to_block.close(); _fork_db.reset(); + + _opened = false; } void database::force_slow_replays() diff --git a/libraries/chain/include/graphene/chain/database.hpp b/libraries/chain/include/graphene/chain/database.hpp index 84d1ea9b..6b9d973a 100644 --- a/libraries/chain/include/graphene/chain/database.hpp +++ b/libraries/chain/include/graphene/chain/database.hpp @@ -561,6 +561,14 @@ namespace graphene { namespace chain { node_property_object _node_property_object; fc::hash_ctr_rng _random_number_generator; bool _slow_replays = false; + + /** + * Whether database is successfully opened or not. + * + * The database is considered open when there's no exception + * or assertion fail during database::open() method. + */ + bool _opened = false; }; namespace detail From f1ffd52e1e7c764513a3bfe53ee941643ad5b66e Mon Sep 17 00:00:00 2001 From: cifer Date: Mon, 26 Feb 2018 10:59:51 +0800 Subject: [PATCH 2/5] supplement more comments on database::_opened variable --- libraries/chain/include/graphene/chain/database.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libraries/chain/include/graphene/chain/database.hpp b/libraries/chain/include/graphene/chain/database.hpp index 6b9d973a..b513fd2f 100644 --- a/libraries/chain/include/graphene/chain/database.hpp +++ b/libraries/chain/include/graphene/chain/database.hpp @@ -566,7 +566,8 @@ namespace graphene { namespace chain { * Whether database is successfully opened or not. * * The database is considered open when there's no exception - * or assertion fail during database::open() method. + * or assertion fail during database::open() method, and + * database::close() has not been called, or failed during execution. */ bool _opened = false; }; From b3c64c83b248c1549c825bdf14717adc7f07b5c5 Mon Sep 17 00:00:00 2001 From: John Jones Date: Mon, 14 Jan 2019 13:55:13 -0500 Subject: [PATCH 3/5] prevent segfault when destructing application obj --- libraries/chain/db_management.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libraries/chain/db_management.cpp b/libraries/chain/db_management.cpp index f22a46df..a0a78682 100644 --- a/libraries/chain/db_management.cpp +++ b/libraries/chain/db_management.cpp @@ -157,6 +157,9 @@ void database::open( void database::close(bool rewind) { + if (!_opened) + return; + // TODO: Save pending tx's on close() clear_pending(); From cde18342da05d09f2f9c2becb0ab844d47a22b0b Mon Sep 17 00:00:00 2001 From: Sandip Patel Date: Thu, 5 Sep 2019 18:38:21 +0530 Subject: [PATCH 4/5] minor performance improvement --- libraries/chain/account_object.cpp | 6 +++--- libraries/chain/db_block.cpp | 13 +++++++++---- .../include/graphene/chain/account_object.hpp | 14 +++++++++++--- 3 files changed, 23 insertions(+), 10 deletions(-) diff --git a/libraries/chain/account_object.cpp b/libraries/chain/account_object.cpp index 90d97692..c19eedb6 100644 --- a/libraries/chain/account_object.cpp +++ b/libraries/chain/account_object.cpp @@ -119,9 +119,9 @@ set account_member_index::get_account_members(const account_obj result.insert(auth.first); return result; } -set account_member_index::get_key_members(const account_object& a)const +set account_member_index::get_key_members(const account_object& a)const { - set result; + set result; for( auto auth : a.owner.key_auths ) result.insert(auth.first); for( auto auth : a.active.key_auths ) @@ -213,7 +213,7 @@ void account_member_index::object_modified(const object& after) { - set after_key_members = get_key_members(a); + set after_key_members = get_key_members(a); vector removed; removed.reserve(before_key_members.size()); std::set_difference(before_key_members.begin(), before_key_members.end(), diff --git a/libraries/chain/db_block.cpp b/libraries/chain/db_block.cpp index e9124594..42c15dc3 100644 --- a/libraries/chain/db_block.cpp +++ b/libraries/chain/db_block.cpp @@ -672,9 +672,14 @@ processed_transaction database::_apply_transaction(const signed_transaction& trx auto& trx_idx = get_mutable_index_type(); const chain_id_type& chain_id = get_chain_id(); - auto trx_id = trx.id(); - FC_ASSERT( (skip & skip_transaction_dupe_check) || - trx_idx.indices().get().find(trx_id) == trx_idx.indices().get().end() ); + transaction_id_type trx_id; + + if( !(skip & skip_transaction_dupe_check) ) + { + trx_id = trx.id(); + FC_ASSERT( trx_idx.indices().get().find(trx_id) == trx_idx.indices().get().end() ); + } + transaction_evaluation_state eval_state(this); const chain_parameters& chain_parameters = get_global_properties().parameters; eval_state._trx = &trx; @@ -708,7 +713,7 @@ processed_transaction database::_apply_transaction(const signed_transaction& trx //Insert transaction into unique transactions database. if( !(skip & skip_transaction_dupe_check) ) { - create([&](transaction_object& transaction) { + create([&trx_id,&trx](transaction_object& transaction) { transaction.trx_id = trx_id; transaction.trx = trx; }); diff --git a/libraries/chain/include/graphene/chain/account_object.hpp b/libraries/chain/include/graphene/chain/account_object.hpp index 914ade33..34e8593f 100644 --- a/libraries/chain/include/graphene/chain/account_object.hpp +++ b/libraries/chain/include/graphene/chain/account_object.hpp @@ -278,6 +278,14 @@ namespace graphene { namespace chain { */ class account_member_index : public secondary_index { + class key_compare { + public: + inline bool operator()( const public_key_type& a, const public_key_type& b )const + { + return a.key_data < b.key_data; + } + }; + public: virtual void object_inserted( const object& obj ) override; virtual void object_removed( const object& obj ) override; @@ -287,18 +295,18 @@ namespace graphene { namespace chain { /** given an account or key, map it to the set of accounts that reference it in an active or owner authority */ map< account_id_type, set > account_to_account_memberships; - map< public_key_type, set > account_to_key_memberships; + map< public_key_type, set, key_compare > account_to_key_memberships; /** some accounts use address authorities in the genesis block */ map< address, set > account_to_address_memberships; protected: set get_account_members( const account_object& a )const; - set get_key_members( const account_object& a )const; + set get_key_members( const account_object& a )const; set
get_address_members( const account_object& a )const; set before_account_members; - set before_key_members; + set before_key_members; set
before_address_members; }; From 5ce9f8c8de06c8e9e72148b2f28d0e9bc817f7d3 Mon Sep 17 00:00:00 2001 From: Sandip Patel Date: Mon, 9 Sep 2019 13:56:35 +0530 Subject: [PATCH 5/5] Added comment --- .../chain/include/graphene/chain/account_object.hpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/libraries/chain/include/graphene/chain/account_object.hpp b/libraries/chain/include/graphene/chain/account_object.hpp index 34e8593f..36412d88 100644 --- a/libraries/chain/include/graphene/chain/account_object.hpp +++ b/libraries/chain/include/graphene/chain/account_object.hpp @@ -278,6 +278,17 @@ namespace graphene { namespace chain { */ class account_member_index : public secondary_index { + /* std::less::operator() is less efficient so using key_compare here. + * Let assume that it has two keys key1 and key2 and we want to insert key3. + * the insert function needs to first call std::less::operator() with key1 and key3. + * Assume std::less::operator()(key1, key3) returns false. + * It has to call std::less::operator() again with the keys switched, + * std::less::operator()(key3, key1), to decide whether key1 is equal to key3 or + * key3 is greater than key1. There are two calls to std::less::operator() to make + * a decision if the first call returns false. + * std::map::insert and std::set used key_compare, + * there would be sufficient information to make the right decision using just one call. + */ class key_compare { public: inline bool operator()( const public_key_type& a, const public_key_type& b )const