diff --git a/src/currency_core/blockchain_storage.cpp b/src/currency_core/blockchain_storage.cpp index 5941c0fe..9fe5c021 100644 --- a/src/currency_core/blockchain_storage.cpp +++ b/src/currency_core/blockchain_storage.cpp @@ -3773,7 +3773,6 @@ bool blockchain_storage::pop_transaction_from_global_index(const transaction& tx CHECK_AND_ASSERT_MES(res, false, "Internal error: multisig out not found, multisig_out_id " << multisig_out_id << "in multisig outs index"); } VARIANT_CASE_CONST(tx_out_zarcanum, toz) - // TODO: @#@# temporary comment this section and make a test for the corresponding bug if (!do_pop_output(i, 0)) return false; VARIANT_CASE_THROW_ON_OTHER(); @@ -4291,16 +4290,17 @@ bool blockchain_storage::process_blockchain_tx_extra(const transaction& tx, cons bool blockchain_storage::get_outs_index_stat(outs_index_stat& outs_stat) const { CRITICAL_REGION_LOCAL(m_read_lock); - outs_stat.amount_0_001 = m_db_outputs.get_item_size(COIN / 1000); - outs_stat.amount_0_01 = m_db_outputs.get_item_size(COIN / 100); - outs_stat.amount_0_1 = m_db_outputs.get_item_size(COIN / 10); - outs_stat.amount_1 = m_db_outputs.get_item_size(COIN); - outs_stat.amount_10 = m_db_outputs.get_item_size(COIN * 10); - outs_stat.amount_100 = m_db_outputs.get_item_size(COIN * 100); - outs_stat.amount_1000 = m_db_outputs.get_item_size(COIN * 1000); - outs_stat.amount_10000 = m_db_outputs.get_item_size(COIN * 10000); - outs_stat.amount_100000 = m_db_outputs.get_item_size(COIN * 100000); - outs_stat.amount_1000000 = m_db_outputs.get_item_size(COIN * 1000000); + outs_stat.amount_0 = m_db_outputs.get_item_size(0); + outs_stat.amount_0_001 = m_db_outputs.get_item_size(COIN / 1000); + outs_stat.amount_0_01 = m_db_outputs.get_item_size(COIN / 100); + outs_stat.amount_0_1 = m_db_outputs.get_item_size(COIN / 10); + outs_stat.amount_1 = m_db_outputs.get_item_size(COIN); + outs_stat.amount_10 = m_db_outputs.get_item_size(COIN * 10); + outs_stat.amount_100 = m_db_outputs.get_item_size(COIN * 100); + outs_stat.amount_1000 = m_db_outputs.get_item_size(COIN * 1000); + outs_stat.amount_10000 = m_db_outputs.get_item_size(COIN * 10000); + outs_stat.amount_100000 = m_db_outputs.get_item_size(COIN * 100000); + outs_stat.amount_1000000 = m_db_outputs.get_item_size(COIN * 1000000); return true; } //------------------------------------------------------------------ diff --git a/src/rpc/core_rpc_server_commands_defs.h b/src/rpc/core_rpc_server_commands_defs.h index 6ccd37ba..f088ccc6 100644 --- a/src/rpc/core_rpc_server_commands_defs.h +++ b/src/rpc/core_rpc_server_commands_defs.h @@ -661,6 +661,7 @@ namespace currency //----------------------------------------------- struct outs_index_stat { + uint64_t amount_0; uint64_t amount_0_001; uint64_t amount_0_01; uint64_t amount_0_1; @@ -673,6 +674,7 @@ namespace currency uint64_t amount_1000000; BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(amount_0) KV_SERIALIZE(amount_0_001) KV_SERIALIZE(amount_0_01) KV_SERIALIZE(amount_0_1) diff --git a/tests/core_tests/chaingen_main.cpp b/tests/core_tests/chaingen_main.cpp index 01f5c9cc..2287d612 100644 --- a/tests/core_tests/chaingen_main.cpp +++ b/tests/core_tests/chaingen_main.cpp @@ -1249,6 +1249,7 @@ int main(int argc, char* argv[]) GENERATE_AND_PLAY_HF(hard_fork_4_consolidated_txs, "3-*"); GENERATE_AND_PLAY_HF(hardfork_4_wallet_transfer_with_mandatory_mixins, "3-*"); GENERATE_AND_PLAY(hardfork_4_wallet_sweep_bare_outs); + GENERATE_AND_PLAY_HF(hardfork_4_pop_tx_from_global_index, "4-*"); // atomics GENERATE_AND_PLAY(atomic_simple_test); diff --git a/tests/core_tests/hard_fork_4.cpp b/tests/core_tests/hard_fork_4.cpp index 2349167d..396ac2ec 100644 --- a/tests/core_tests/hard_fork_4.cpp +++ b/tests/core_tests/hard_fork_4.cpp @@ -439,3 +439,60 @@ bool hardfork_4_wallet_sweep_bare_outs::c1(currency::core& c, size_t ev_index, c return true; } + +//------------------------------------------------------------------------------ + +hardfork_4_pop_tx_from_global_index::hardfork_4_pop_tx_from_global_index() +{ + REGISTER_CALLBACK_METHOD(hardfork_4_pop_tx_from_global_index, c1); +} + +bool hardfork_4_pop_tx_from_global_index::generate(std::vector& events) const +{ + // Test idea: make sure that pop_transaction_from_global_index works for tx_out_zarcanum as well (m_db_outputs is consistent after pop_transaction_from_global_index() call) + + uint64_t ts = test_core_time::get_time(); + m_accounts.resize(TOTAL_ACCS_COUNT); + account_base& miner_acc = m_accounts[MINER_ACC_IDX]; miner_acc.generate(); miner_acc.set_createtime(ts); + account_base& alice_acc = m_accounts[ALICE_ACC_IDX]; alice_acc.generate(); alice_acc.set_createtime(ts); + + MAKE_GENESIS_BLOCK(events, blk_0, miner_acc, ts); + DO_CALLBACK(events, "configure_core"); // default configure_core callback will initialize core runtime config with m_hardforks + REWIND_BLOCKS_N(events, blk_0r, blk_0, miner_acc, CURRENCY_MINED_MONEY_UNLOCK_WINDOW); + + DO_CALLBACK_PARAMS(events, "check_hardfork_active", static_cast(ZANO_HARDFORK_04_ZARCANUM)); + + MAKE_NEXT_BLOCK(events, blk_1a, blk_0r, miner_acc); // blk_1a will be the alt chain + DO_CALLBACK_PARAMS(events, "check_top_block", params_top_block(blk_1a)); // make sure now it's the main chain + + MAKE_NEXT_BLOCK(events, blk_1, blk_0r, miner_acc); + + MAKE_NEXT_BLOCK(events, blk_2, blk_1, miner_acc); // this should trigger chain switching + DO_CALLBACK_PARAMS(events, "check_top_block", params_top_block(blk_2)); // make sure it did + + // during switching to the alternative chain pop_block_from_blockchain() -> ... -> pop_transaction_from_global_index() will be called + // but abort_transaction() will not, meaning m_db_outputs will be in incorrect state, if pop_transaction_from_global_index() hasn't properly pop all outs + // this will be checked later in c1 + + DO_CALLBACK(events, "c1"); + return true; +} + +bool hardfork_4_pop_tx_from_global_index::c1(currency::core& c, size_t ev_index, const std::vector& events) +{ + auto& bcs = c.get_blockchain_storage(); + bool r = false; + + //currency::outs_index_stat outs_stat{}; + //bcs.get_outs_index_stat(outs_stat); // 24 - bad, 22 - good + + COMMAND_RPC_GET_TX_GLOBAL_OUTPUTS_INDEXES_BY_AMOUNT::response res; + COMMAND_RPC_GET_TX_GLOBAL_OUTPUTS_INDEXES_BY_AMOUNT::request req; + req.amount = 0; + req.i = 22; + CHECK_AND_ASSERT_MES(!bcs.get_global_index_details(req, res), false, "gindex 22 exists which is unexpected"); + req.i = 21; + CHECK_AND_ASSERT_MES(bcs.get_global_index_details(req, res), false, "gindex 21 does not exist which is unexpected"); + + return true; +} diff --git a/tests/core_tests/hard_fork_4.h b/tests/core_tests/hard_fork_4.h index b3684f80..5e9014b8 100644 --- a/tests/core_tests/hard_fork_4.h +++ b/tests/core_tests/hard_fork_4.h @@ -42,3 +42,10 @@ struct hardfork_4_wallet_sweep_bare_outs : public wallet_test bool generate(std::vector& events) const; bool c1(currency::core& c, size_t ev_index, const std::vector& events); }; + +struct hardfork_4_pop_tx_from_global_index : public wallet_test +{ + hardfork_4_pop_tx_from_global_index(); + bool generate(std::vector& events) const; + bool c1(currency::core& c, size_t ev_index, const std::vector& events); +};