From c4e1cdd03043c3f210fab029ef5796068b420e23 Mon Sep 17 00:00:00 2001 From: abitmore Date: Tue, 13 Sep 2022 22:09:55 +0000 Subject: [PATCH 1/2] Add creation block num and time for accnts, assets --- libraries/chain/account_evaluator.cpp | 6 ++++- libraries/chain/account_object.cpp | 1 + libraries/chain/asset_evaluator.cpp | 4 ++- libraries/chain/db_block.cpp | 2 ++ libraries/chain/db_genesis.cpp | 27 ++++++++++++++++--- .../include/graphene/chain/account_object.hpp | 5 ++++ .../include/graphene/chain/asset_object.hpp | 8 +++++- .../chain/include/graphene/chain/config.hpp | 2 +- .../chain/include/graphene/chain/database.hpp | 3 +++ 9 files changed, 51 insertions(+), 7 deletions(-) diff --git a/libraries/chain/account_evaluator.cpp b/libraries/chain/account_evaluator.cpp index b9070c91a9..7fc5dda0ec 100644 --- a/libraries/chain/account_evaluator.cpp +++ b/libraries/chain/account_evaluator.cpp @@ -177,7 +177,8 @@ object_id_type account_create_evaluator::do_apply( const account_create_operatio const auto& global_properties = d.get_global_properties(); - const auto& new_acnt_object = d.create( [&o,&d,&global_properties,referrer_percent]( account_object& obj ) + const auto& new_acnt_object = d.create( [&o,&d,&global_properties,referrer_percent] + ( account_object& obj ) { obj.registrar = o.registrar; obj.referrer = o.referrer; @@ -208,6 +209,9 @@ object_id_type account_create_evaluator::do_apply( const account_create_operatio obj.allowed_assets = o.extensions.value.buyback_options->markets; obj.allowed_assets->emplace( o.extensions.value.buyback_options->asset_to_buy ); } + + obj.creation_block_num = d._current_block_num; + obj.creation_time = d._current_block_time; }); const auto& dynamic_properties = d.get_dynamic_global_properties(); diff --git a/libraries/chain/account_object.cpp b/libraries/chain/account_object.cpp index 627de8e899..0d98b774cd 100644 --- a/libraries/chain/account_object.cpp +++ b/libraries/chain/account_object.cpp @@ -312,6 +312,7 @@ FC_REFLECT_DERIVED_NO_TYPENAME( graphene::chain::account_object, (owner_special_authority)(active_special_authority) (top_n_control_flags) (allowed_assets) + (creation_block_num)(creation_time) ) FC_REFLECT_DERIVED_NO_TYPENAME( graphene::chain::account_balance_object, diff --git a/libraries/chain/asset_evaluator.cpp b/libraries/chain/asset_evaluator.cpp index cca9f351a4..e17b4b8fdf 100644 --- a/libraries/chain/asset_evaluator.cpp +++ b/libraries/chain/asset_evaluator.cpp @@ -310,7 +310,7 @@ object_id_type asset_create_evaluator::do_apply( const asset_create_operation& o }).id; const asset_object& new_asset = - d.create( [&op,next_asset_id,&dyn_asset,bit_asset_id]( asset_object& a ) { + d.create( [&op,next_asset_id,&dyn_asset,bit_asset_id,&d]( asset_object& a ) { a.issuer = op.issuer; a.symbol = op.symbol; a.precision = op.precision; @@ -322,6 +322,8 @@ object_id_type asset_create_evaluator::do_apply( const asset_create_operation& o a.dynamic_asset_data_id = dyn_asset.id; if( op.bitasset_opts.valid() ) a.bitasset_data_id = bit_asset_id; + a.creation_block_num = d._current_block_num; + a.creation_time = d._current_block_time; }); FC_ASSERT( new_asset.id == next_asset_id, "Unexpected object database error, object id mismatch" ); diff --git a/libraries/chain/db_block.cpp b/libraries/chain/db_block.cpp index 7dab0b27d6..2a9ebfb22d 100644 --- a/libraries/chain/db_block.cpp +++ b/libraries/chain/db_block.cpp @@ -611,6 +611,8 @@ void database::_apply_block( const signed_block& next_block ) _current_block_num = next_block_num; _current_trx_in_block = 0; + _current_block_time = next_block.timestamp; + _issue_453_affected_assets.clear(); signed_block processed_block( next_block ); // make a copy diff --git a/libraries/chain/db_genesis.cpp b/libraries/chain/db_genesis.cpp index b3267fbffd..4624c16d81 100644 --- a/libraries/chain/db_genesis.cpp +++ b/libraries/chain/db_genesis.cpp @@ -70,6 +70,8 @@ void database::init_genesis(const genesis_state_type& genesis_state) transaction_evaluation_state genesis_eval_state(this); + _current_block_time = genesis_state.initial_timestamp; + // Create blockchain accounts fc::ecc::private_key null_private_key = fc::ecc::private_key::regenerate(fc::sha256::hash(string("null_key"))); create([](account_balance_object& b) { @@ -88,6 +90,8 @@ void database::init_genesis(const genesis_state_type& genesis_state) s.name = n.name; s.core_in_balance = GRAPHENE_MAX_SHARE_SUPPLY; }).id; + n.creation_block_num = 0; + n.creation_time = _current_block_time; }); FC_ASSERT(committee_account.get_id() == GRAPHENE_COMMITTEE_ACCOUNT); FC_ASSERT(create([this](account_object& a) { @@ -104,6 +108,8 @@ void database::init_genesis(const genesis_state_type& genesis_state) a.membership_expiration_date = time_point_sec::maximum(); a.network_fee_percentage = GRAPHENE_DEFAULT_NETWORK_PERCENT_OF_FEE; a.lifetime_referrer_fee_percentage = GRAPHENE_100_PERCENT - GRAPHENE_DEFAULT_NETWORK_PERCENT_OF_FEE; + a.creation_block_num = 0; + a.creation_time = _current_block_time; }).get_id() == GRAPHENE_WITNESS_ACCOUNT); FC_ASSERT(create([this](account_object& a) { a.name = "relaxed-committee-account"; @@ -119,6 +125,8 @@ void database::init_genesis(const genesis_state_type& genesis_state) a.membership_expiration_date = time_point_sec::maximum(); a.network_fee_percentage = GRAPHENE_DEFAULT_NETWORK_PERCENT_OF_FEE; a.lifetime_referrer_fee_percentage = GRAPHENE_100_PERCENT - GRAPHENE_DEFAULT_NETWORK_PERCENT_OF_FEE; + a.creation_block_num = 0; + a.creation_time = _current_block_time; }).get_id() == GRAPHENE_RELAXED_COMMITTEE_ACCOUNT); // The same data set is assigned to more than one account auto init_account_data_as_null = [this](account_object& a) { @@ -134,6 +142,8 @@ void database::init_genesis(const genesis_state_type& genesis_state) a.membership_expiration_date = time_point_sec::maximum(); a.network_fee_percentage = 0; a.lifetime_referrer_fee_percentage = GRAPHENE_100_PERCENT; + a.creation_block_num = 0; + a.creation_time = _current_block_time; }; FC_ASSERT(create([&init_account_data_as_null](account_object& a) { a.name = "null-account"; @@ -153,6 +163,8 @@ void database::init_genesis(const genesis_state_type& genesis_state) a.membership_expiration_date = time_point_sec::maximum(); a.network_fee_percentage = GRAPHENE_DEFAULT_NETWORK_PERCENT_OF_FEE; a.lifetime_referrer_fee_percentage = GRAPHENE_100_PERCENT - GRAPHENE_DEFAULT_NETWORK_PERCENT_OF_FEE; + a.creation_block_num = 0; + a.creation_time = _current_block_time; }).get_id() == GRAPHENE_TEMP_ACCOUNT); FC_ASSERT(create([&init_account_data_as_null](account_object& a) { a.name = "proxy-to-self"; @@ -179,6 +191,8 @@ void database::init_genesis(const genesis_state_type& genesis_state) a.membership_expiration_date = time_point_sec::maximum(); a.network_fee_percentage = GRAPHENE_DEFAULT_NETWORK_PERCENT_OF_FEE; a.lifetime_referrer_fee_percentage = GRAPHENE_100_PERCENT - GRAPHENE_DEFAULT_NETWORK_PERCENT_OF_FEE; + a.creation_block_num = 0; + a.creation_time = _current_block_time; }); FC_ASSERT( acct.get_id() == account_id_type(id) ); remove( acct.statistics(*this) ); @@ -191,7 +205,7 @@ void database::init_genesis(const genesis_state_type& genesis_state) a.current_supply = GRAPHENE_MAX_SHARE_SUPPLY; }); const asset_object& core_asset = - create( [&genesis_state,&core_dyn_asset]( asset_object& a ) { + create( [&genesis_state,&core_dyn_asset,this]( asset_object& a ) { a.symbol = GRAPHENE_SYMBOL; a.options.max_supply = genesis_state.max_core_supply; a.precision = GRAPHENE_BLOCKCHAIN_PRECISION_DIGITS; @@ -203,6 +217,8 @@ void database::init_genesis(const genesis_state_type& genesis_state) a.options.core_exchange_rate.quote.amount = 1; a.options.core_exchange_rate.quote.asset_id = asset_id_type(0); a.dynamic_asset_data_id = core_dyn_asset.id; + a.creation_block_num = 0; + a.creation_time = _current_block_time; }); FC_ASSERT( core_dyn_asset.id == asset_dynamic_data_id_type() ); FC_ASSERT( asset_id_type(core_asset.id) == asset().asset_id ); @@ -219,7 +235,7 @@ void database::init_genesis(const genesis_state_type& genesis_state) create([](asset_dynamic_data_object& a) { a.current_supply = 0; }); - const asset_object& asset_obj = create( [id,&dyn_asset]( asset_object& a ) { + const asset_object& asset_obj = create( [id,&dyn_asset,this]( asset_object& a ) { a.symbol = "SPECIAL" + std::to_string( id ); a.options.max_supply = 0; a.precision = GRAPHENE_BLOCKCHAIN_PRECISION_DIGITS; @@ -231,6 +247,8 @@ void database::init_genesis(const genesis_state_type& genesis_state) a.options.core_exchange_rate.quote.amount = 1; a.options.core_exchange_rate.quote.asset_id = asset_id_type(0); a.dynamic_asset_data_id = dyn_asset.id; + a.creation_block_num = 0; + a.creation_time = _current_block_time; }); FC_ASSERT( asset_obj.get_id() == asset_id_type(id) ); remove( dyn_asset ); @@ -378,7 +396,8 @@ void database::init_genesis(const genesis_state_type& genesis_state) total_supplies[ new_asset_id ] += asst.accumulated_fees; - create([&asst,&get_account_id,&dynamic_data_id,&bitasset_data_id](asset_object& a) { + create([&asst,&get_account_id,&dynamic_data_id,&bitasset_data_id,this](asset_object& a) + { a.symbol = asst.symbol; a.options.description = asst.description; a.precision = asst.precision; @@ -390,6 +409,8 @@ void database::init_genesis(const genesis_state_type& genesis_state) : DEFAULT_UIA_ASSET_ISSUER_PERMISSION ); a.dynamic_asset_data_id = dynamic_data_id; a.bitasset_data_id = bitasset_data_id; + a.creation_block_num = 0; + a.creation_time = _current_block_time; }); } diff --git a/libraries/chain/include/graphene/chain/account_object.hpp b/libraries/chain/include/graphene/chain/account_object.hpp index 8b1982cf49..66aefa2dcd 100644 --- a/libraries/chain/include/graphene/chain/account_object.hpp +++ b/libraries/chain/include/graphene/chain/account_object.hpp @@ -287,6 +287,11 @@ namespace graphene { namespace chain { */ optional< flat_set > allowed_assets; + /// The block number when the account was created + uint32_t creation_block_num = 0; + /// The time when the account was created + time_point_sec creation_time; + bool has_special_authority()const { return (!owner_special_authority.is_type< no_special_authority >()) diff --git a/libraries/chain/include/graphene/chain/asset_object.hpp b/libraries/chain/include/graphene/chain/asset_object.hpp index fcd675a829..3dd11bb344 100644 --- a/libraries/chain/include/graphene/chain/asset_object.hpp +++ b/libraries/chain/include/graphene/chain/asset_object.hpp @@ -141,7 +141,6 @@ namespace graphene { namespace chain { asset_options options; - /// Current supply, fee pool, and collected fees are stored in a separate object as they change frequently. asset_dynamic_data_id_type dynamic_asset_data_id; /// Extra data associated with BitAssets. This field is non-null if and only if is_market_issued() returns true @@ -152,6 +151,11 @@ namespace graphene { namespace chain { /// The ID of the liquidity pool if the asset is the share asset of a liquidity pool optional for_liquidity_pool; + /// The block number when the asset object was created + uint32_t creation_block_num = 0; + /// The time when the asset object was created + time_point_sec creation_time; + asset_id_type get_id()const { return id; } void validate()const @@ -486,6 +490,8 @@ FC_REFLECT_DERIVED( graphene::chain::asset_object, (graphene::db::object), (bitasset_data_id) (buyback_account) (for_liquidity_pool) + (creation_block_num) + (creation_time) ) FC_REFLECT_TYPENAME( graphene::chain::asset_bitasset_data_object ) diff --git a/libraries/chain/include/graphene/chain/config.hpp b/libraries/chain/include/graphene/chain/config.hpp index 99b7da3599..598df91053 100644 --- a/libraries/chain/include/graphene/chain/config.hpp +++ b/libraries/chain/include/graphene/chain/config.hpp @@ -32,7 +32,7 @@ #define GRAPHENE_MAX_NESTED_OBJECTS (200) -const std::string GRAPHENE_CURRENT_DB_VERSION = "20210806"; +const std::string GRAPHENE_CURRENT_DB_VERSION = "20220913"; #define GRAPHENE_RECENTLY_MISSED_COUNT_INCREMENT 4 #define GRAPHENE_RECENTLY_MISSED_COUNT_DECREMENT 3 diff --git a/libraries/chain/include/graphene/chain/database.hpp b/libraries/chain/include/graphene/chain/database.hpp index f51574dcb0..cbcbadb61a 100644 --- a/libraries/chain/include/graphene/chain/database.hpp +++ b/libraries/chain/include/graphene/chain/database.hpp @@ -768,7 +768,10 @@ namespace graphene { namespace chain { */ vector > _applied_ops; + public: + fc::time_point_sec _current_block_time; uint32_t _current_block_num = 0; + private: uint16_t _current_trx_in_block = 0; uint16_t _current_op_in_trx = 0; uint32_t _current_virtual_op = 0; From 0dc888b3b2d3b3cd89fb095dd29ece3d2ef2be32 Mon Sep 17 00:00:00 2001 From: abitmore Date: Wed, 14 Sep 2022 23:19:55 +0000 Subject: [PATCH 2/2] Add tests for account and asset creation time --- tests/common/database_fixture.hpp | 9 +++++++++ tests/tests/operation_tests.cpp | 14 ++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/tests/common/database_fixture.hpp b/tests/common/database_fixture.hpp index 9ab8ec757b..bf88a7bc83 100644 --- a/tests/common/database_fixture.hpp +++ b/tests/common/database_fixture.hpp @@ -585,6 +585,15 @@ struct database_fixture_init : database_fixture_base { asset_id_type mpa1_id(1); BOOST_REQUIRE( mpa1_id(db).is_market_issued() ); BOOST_CHECK( mpa1_id(db).bitasset_data(db).asset_id == mpa1_id ); + + BOOST_CHECK_EQUAL( account_id_type()(db).creation_block_num, 0 ); + BOOST_CHECK( account_id_type()(db).creation_time == genesis_state.initial_timestamp ); + + BOOST_CHECK_EQUAL( asset_id_type()(db).creation_block_num, 0 ); + BOOST_CHECK( asset_id_type()(db).creation_time == genesis_state.initial_timestamp ); + + BOOST_CHECK_EQUAL( mpa1_id(db).creation_block_num, 0 ); + BOOST_CHECK( mpa1_id(db).creation_time == genesis_state.initial_timestamp ); } static void init( database_fixture_init& fixture ) diff --git a/tests/tests/operation_tests.cpp b/tests/tests/operation_tests.cpp index 399da7b374..81f678d3c2 100644 --- a/tests/tests/operation_tests.cpp +++ b/tests/tests/operation_tests.cpp @@ -1974,6 +1974,14 @@ BOOST_AUTO_TEST_CASE( create_account_test ) const account_statistics_object& statistics = nathan_account.statistics(db); BOOST_CHECK(statistics.id.space() == implementation_ids); BOOST_CHECK(statistics.id.type() == impl_account_statistics_object_type); + + account_id_type nathan_id = nathan_account.id; + + generate_block(); + + BOOST_CHECK_EQUAL( nathan_id(db).creation_block_num, db.head_block_num() ); + BOOST_CHECK( nathan_id(db).creation_time == db.head_block_time() ); + } catch (fc::exception& e) { edump((e.to_detail_string())); throw; @@ -2216,6 +2224,12 @@ BOOST_AUTO_TEST_CASE( create_uia ) REQUIRE_THROW_WITH_VALUE(op, symbol, "ABCDEFGHIJKLMNOPQRSTUVWXYZ"); REQUIRE_THROW_WITH_VALUE(op, common_options.core_exchange_rate, price(asset(-100), asset(1))); REQUIRE_THROW_WITH_VALUE(op, common_options.core_exchange_rate, price(asset(100),asset(-1))); + + generate_block(); + + BOOST_CHECK_EQUAL( test_asset_id(db).creation_block_num, db.head_block_num() ); + BOOST_CHECK( test_asset_id(db).creation_time == db.head_block_time() ); + } catch(fc::exception& e) { edump((e.to_detail_string())); throw;