diff --git a/libraries/chain/include/graphene/chain/config.hpp b/libraries/chain/include/graphene/chain/config.hpp index e905050d7c..c7d322801c 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 = "20230319"; +const std::string GRAPHENE_CURRENT_DB_VERSION = "20230320"; #define GRAPHENE_RECENTLY_MISSED_COUNT_INCREMENT 4 #define GRAPHENE_RECENTLY_MISSED_COUNT_DECREMENT 3 diff --git a/libraries/plugins/elasticsearch/elasticsearch_plugin.cpp b/libraries/plugins/elasticsearch/elasticsearch_plugin.cpp index 205bbf78f3..14529fb3fb 100644 --- a/libraries/plugins/elasticsearch/elasticsearch_plugin.cpp +++ b/libraries/plugins/elasticsearch/elasticsearch_plugin.cpp @@ -272,6 +272,7 @@ void elasticsearch_plugin_impl::doOperationHistory( const optional trx_in_block; os.op_in_trx = oho->op_in_trx; os.virtual_op = oho->virtual_op; + os.is_virtual = oho->is_virtual; os.fee_payer = oho->op.visit( get_fee_payer_visitor() ); if(_options.operation_string) @@ -611,6 +612,9 @@ static operation_history_object fromEStoOperation(const variant& source) result.trx_in_block = source["operation_history"]["trx_in_block"].as_uint64(); result.op_in_trx = source["operation_history"]["op_in_trx"].as_uint64(); result.trx_in_block = source["operation_history"]["virtual_op"].as_uint64(); + result.is_virtual = source["operation_history"]["is_virtual"].as_bool(); + + result.block_time = fc::time_point_sec::from_iso_string( source["block_data"]["block_time"].as_string() ); return result; } diff --git a/libraries/plugins/elasticsearch/include/graphene/elasticsearch/elasticsearch_plugin.hpp b/libraries/plugins/elasticsearch/include/graphene/elasticsearch/elasticsearch_plugin.hpp index 797fe3b8c0..e2ad5bf483 100644 --- a/libraries/plugins/elasticsearch/include/graphene/elasticsearch/elasticsearch_plugin.hpp +++ b/libraries/plugins/elasticsearch/include/graphene/elasticsearch/elasticsearch_plugin.hpp @@ -83,6 +83,7 @@ struct operation_history_struct { uint16_t trx_in_block; uint16_t op_in_trx; uint32_t virtual_op; + bool is_virtual; account_id_type fee_payer; std::string op; std::string operation_result; @@ -147,7 +148,7 @@ struct bulk_struct { FC_REFLECT_ENUM( graphene::elasticsearch::mode, (only_save)(only_query)(all) ) FC_REFLECT( graphene::elasticsearch::operation_history_struct, - (trx_in_block)(op_in_trx)(virtual_op)(fee_payer) + (trx_in_block)(op_in_trx)(virtual_op)(is_virtual)(fee_payer) (op)(operation_result)(op_object)(operation_result_object) ) FC_REFLECT( graphene::elasticsearch::block_struct, (block_num)(block_time)(trx_id) ) FC_REFLECT( graphene::elasticsearch::fee_struct, (asset)(asset_name)(amount)(amount_units) ) diff --git a/tests/elasticsearch/main.cpp b/tests/elasticsearch/main.cpp index bba0ce1889..5794d7f433 100644 --- a/tests/elasticsearch/main.cpp +++ b/tests/elasticsearch/main.cpp @@ -129,6 +129,8 @@ BOOST_AUTO_TEST_CASE(elasticsearch_account_history) { BOOST_CHECK_EQUAL(last_transfer_amount, "300"); auto last_transfer_payer = j["_source"]["operation_history"]["fee_payer"].as_string(); BOOST_CHECK_EQUAL(last_transfer_payer, "1.2.0"); + auto is_virtual = j["_source"]["operation_history"]["is_virtual"].as_bool(); + BOOST_CHECK( !is_virtual ); // To test credit offers generate_blocks( HARDFORK_CORE_2362_TIME ); @@ -375,6 +377,9 @@ BOOST_AUTO_TEST_CASE(elasticsearch_history_api) { BOOST_CHECK_EQUAL(histories[2].id.instance(), 1u); BOOST_CHECK_EQUAL(histories[3].id.instance(), 0u); + BOOST_CHECK( !histories[0].is_virtual ); + BOOST_CHECK( histories[0].block_time == db.head_block_time() ); + // f(A, 0, 4, 6) = { 5, 3, 1, 0 } histories = hist_api.get_account_history("1.2.0", operation_history_id_type(), 4, operation_history_id_type(6)); BOOST_REQUIRE_EQUAL(histories.size(), 4u); @@ -627,7 +632,8 @@ BOOST_AUTO_TEST_CASE(elasticsearch_history_api) { BOOST_CHECK_EQUAL(histories.size(), 0u); // create a new account C = alice { 7 } - create_account("alice"); + auto alice = create_account("alice"); + account_id_type alice_id = alice.get_id(); generate_block(); @@ -662,6 +668,47 @@ BOOST_AUTO_TEST_CASE(elasticsearch_history_api) { }, "thread invoke for method " BOOST_PP_STRINGIZE(method_name)).wait(); BOOST_REQUIRE( his_obj7.op.is_type() ); BOOST_CHECK_EQUAL( his_obj7.op.get().name, "alice" ); + + // Test virtual operation + + // Prepare funds + transfer( account_id_type()(db), alice_id(db), asset(100) ); + // Create a limit order that expires in 300 seconds + create_sell_order( alice_id, asset(1), asset(1, asset_id_type(1)), db.head_block_time() + 300 ); + + generate_block(); + + // f(C, 0, 4, 0) = { 9, 8, 7 } + fc::wait_for( ES_WAIT_TIME, [&]() { + histories = hist_api.get_account_history( + "alice", operation_history_id_type(0), 4, operation_history_id_type(0)); + return (histories.size() == 3u); + }); + BOOST_REQUIRE_EQUAL(histories.size(), 3u); + BOOST_CHECK( histories[0].op.is_type() ); + BOOST_CHECK( !histories[0].is_virtual ); + BOOST_CHECK( histories[0].block_time == db.head_block_time() ); + BOOST_CHECK( histories[1].op.is_type() ); + BOOST_CHECK( !histories[1].is_virtual ); + + // Let the limit order expire + generate_blocks( db.head_block_time() + 300 ); + generate_block(); + + // f(C, 0, 4, 0) = { 10, 9, 8, 7 } + fc::wait_for( ES_WAIT_TIME, [&]() { + histories = hist_api.get_account_history( + "alice", operation_history_id_type(0), 4, operation_history_id_type(0)); + return (histories.size() == 4u); + }); + BOOST_REQUIRE_EQUAL(histories.size(), 4u); + BOOST_CHECK( histories[0].op.is_type() ); + BOOST_CHECK( histories[0].is_virtual ); + BOOST_CHECK( histories[1].op.is_type() ); + BOOST_CHECK( !histories[1].is_virtual ); + BOOST_CHECK( histories[2].op.is_type() ); + BOOST_CHECK( !histories[2].is_virtual ); + } } catch (fc::exception &e) {