From 632559c3138f71f6908bf24f6bccbac8feea8dd9 Mon Sep 17 00:00:00 2001 From: Ilya Kitaev Date: Fri, 14 Jun 2019 17:18:19 +0300 Subject: [PATCH 1/8] core_tests: introducing rta tests for stake transactions --- tests/core_tests/CMakeLists.txt | 6 +- tests/core_tests/rta_tests.cpp | 111 ++++++++++++++++++++++++++++++++ tests/core_tests/rta_tests.h | 62 ++++++++++++++++++ 3 files changed, 177 insertions(+), 2 deletions(-) create mode 100644 tests/core_tests/rta_tests.cpp create mode 100644 tests/core_tests/rta_tests.h diff --git a/tests/core_tests/CMakeLists.txt b/tests/core_tests/CMakeLists.txt index 1ac0e7864..167261a7f 100644 --- a/tests/core_tests/CMakeLists.txt +++ b/tests/core_tests/CMakeLists.txt @@ -42,7 +42,8 @@ set(core_tests_sources tx_validation.cpp v2_tests.cpp rct.cpp - bulletproofs.cpp) + bulletproofs.cpp + rta_tests.cpp) set(core_tests_headers block_reward.h @@ -60,7 +61,8 @@ set(core_tests_headers tx_validation.h v2_tests.h rct.h - bulletproofs.h) + bulletproofs.h + rta_tests.h) add_executable(core_tests ${core_tests_sources} diff --git a/tests/core_tests/rta_tests.cpp b/tests/core_tests/rta_tests.cpp new file mode 100644 index 000000000..169656042 --- /dev/null +++ b/tests/core_tests/rta_tests.cpp @@ -0,0 +1,111 @@ +// Copyright (c) 2019, Graft Project +// Copyright (c) 2014-2018, The Monero Project +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list +// of conditions and the following disclaimer in the documentation and/or other +// materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be +// used to endorse or promote products derived from this software without specific +// prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers + +#include "chaingen.h" +#include "rta_tests.h" + +using namespace epee; +using namespace cryptonote; + +namespace +{ + + +} + +gen_rta_tests::gen_rta_tests() +{ + + REGISTER_CALLBACK_METHOD(gen_rta_tests, check_supernode_stake1); + +} + +bool gen_rta_tests::generate(std::vector& events) const +{ + uint64_t ts_start = 1338224400; + + GENERATE_ACCOUNT(miner); + GENERATE_ACCOUNT(alice); + + MAKE_GENESIS_BLOCK(events, blk_0, miner, ts_start); + MAKE_ACCOUNT(events, miner0); + MAKE_ACCOUNT(events, alice0); + MAKE_NEXT_BLOCK(events, blk_1, blk_0, miner0); + MAKE_NEXT_BLOCK(events, blk_1_side, blk_0, miner0); // alternative chain + MAKE_NEXT_BLOCK(events, blk_2, blk_1, miner0); + //MAKE_TX(events, tx_0, first_miner_account, alice, 151, blk_2); + +#if 0 + //// works like this - alice has a 70 coins in + REWIND_BLOCKS(events, blk_2r, blk_2, miner0); + MAKE_TX_LIST_START(events, txlist_0, miner0, alice0, MK_COINS(1), blk_2); + MAKE_TX_LIST(events, txlist_0, miner0, alice0, MK_COINS(2), blk_2); + MAKE_TX_LIST(events, txlist_0, miner0, alice0, MK_COINS(4), blk_2); + MAKE_NEXT_BLOCK_TX_LIST(events, blk_3, blk_2r, miner0, txlist_0); + REWIND_BLOCKS(events, blk_3r, blk_3, miner0); + MAKE_TX(events, tx_1, miner0, alice0, MK_COINS(50), blk_3); + DO_CALLBACK(events, "verify_callback_1"); + return true; + //// +#endif + DO_CALLBACK(events, "verify_callback_1"); + REWIND_BLOCKS(events, blk_2r, blk_2, miner0); + DO_CALLBACK(events, "verify_callback_1"); + transaction tx_0(construct_tx_with_fee(events, blk_2, miner0, alice0, MK_COINS(1000), TESTS_DEFAULT_FEE)); + MAKE_NEXT_BLOCK_TX1(events, blk_22, blk_2r, miner0, tx_0); + + + return true; + +} + +bool gen_rta_tests::check_supernode_stake1(core &c, size_t ev_index, const std::vector &events) +{ + cryptonote::account_base miner0 = boost::get(events[1]); + cryptonote::account_base alice0 = boost::get(events[2]); + std::vector chain; + map_hash2tx_t mtx; + std::vector block_list; + bool r = c.get_blocks(0, 1000 + 2 * CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW, block_list); + + /*bool r = */find_block_chain(events, chain, mtx, get_block_hash(block_list.back())); + MDEBUG("chain size: " << chain.size()); + MDEBUG("events size: " << events.size()); + MDEBUG("ev_index: " << ev_index); + MDEBUG("BALANCE = " << print_money(get_balance(miner0, chain, mtx))); + MDEBUG("BALANCE = " << print_money(get_balance(alice0, chain, mtx))); + for (const auto & tx : mtx) { + MDEBUG("tx: " << tx.first); + } + return true; +} + + diff --git a/tests/core_tests/rta_tests.h b/tests/core_tests/rta_tests.h new file mode 100644 index 000000000..e4f0d2bc3 --- /dev/null +++ b/tests/core_tests/rta_tests.h @@ -0,0 +1,62 @@ +// Copyright (c) 2019, Graft Project +// Copyright (c) 2014-2018, The Monero Project +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list +// of conditions and the following disclaimer in the documentation and/or other +// materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be +// used to endorse or promote products derived from this software without specific +// prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers + +#pragma once +#include "chaingen.h" +#include "misc_log_ex.h" + +struct gen_rta_tests : public test_chain_unit_base +{ + gen_rta_tests(); + + // test generator method: here we define the test sequence + bool generate(std::vector& events) const; + + // bool check_block_verification_context(const cryptonote::block_verification_context& bvc, size_t event_idx, const cryptonote::block& blk); + + bool check_supernode_stake1(cryptonote::core& c, size_t ev_index, const std::vector& events); + +private: + cryptonote::account_base m_miner; + cryptonote::account_base m_supernode1; + +}; + +// this is how to define hardforks table for the cryptonote::core +//template<> +//struct get_test_options { +// // first element is hf number, second is the height for this hf; last element in array should be {0,0} +// const std::pair hard_forks[2] = {std::make_pair(1, 0), std::make_pair(0, 0)}; +// //const std::pair hard_forks[3] = {std::make_pair(1, 0), std::make_pair(2, 1), std::make_pair(0, 0)}; +// const cryptonote::test_options test_options = { +// hard_forks +// }; +//}; From dcf8f3d18dd59376a9ce148eef4c6564551961f9 Mon Sep 17 00:00:00 2001 From: Ilya Kitaev Date: Mon, 17 Jun 2019 18:05:11 +0300 Subject: [PATCH 2/8] get_block_reward: pre-mine works for every hf version (for core_tests) --- src/cryptonote_basic/cryptonote_basic_impl.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cryptonote_basic/cryptonote_basic_impl.cpp b/src/cryptonote_basic/cryptonote_basic_impl.cpp index 884250261..f5a22c4ab 100644 --- a/src/cryptonote_basic/cryptonote_basic_impl.cpp +++ b/src/cryptonote_basic/cryptonote_basic_impl.cpp @@ -93,9 +93,9 @@ namespace cryptonote { const int emission_speed_factor = EMISSION_SPEED_FACTOR_PER_MINUTE - (target_minutes-1); const uint64_t first_reward = 8301030000000000000U; - - if (version >= 6 && median_weight > 0 && already_generated_coins < first_reward) { + if ((version >= 6 || already_generated_coins > 0) && median_weight > 0 && already_generated_coins < first_reward) { reward = first_reward; + MDEBUG("premine triggered"); return true; } From 039e6d622a44f33fe8d9793ead625a673990faaf Mon Sep 17 00:00:00 2001 From: Ilya Kitaev Date: Mon, 17 Jun 2019 19:26:20 +0300 Subject: [PATCH 3/8] cryptonote::core: return StakeTransactionProcessor for tests --- src/cryptonote_core/cryptonote_core.cpp | 5 +++++ src/cryptonote_core/cryptonote_core.h | 6 ++++++ 2 files changed, 11 insertions(+) diff --git a/src/cryptonote_core/cryptonote_core.cpp b/src/cryptonote_core/cryptonote_core.cpp index 516d18cc1..2b6a64fad 100644 --- a/src/cryptonote_core/cryptonote_core.cpp +++ b/src/cryptonote_core/cryptonote_core.cpp @@ -1354,6 +1354,11 @@ namespace cryptonote uint64_t depth = m_blockchain_storage.get_current_blockchain_height() - last_received_block_height; m_graft_stake_transaction_processor.invoke_update_blockchain_based_list_handler(true, depth); } + + StakeTransactionProcessor *core::get_stake_tx_processor() + { + return &m_graft_stake_transaction_processor; + } //----------------------------------------------------------------------------------------------- bool core::prepare_handle_incoming_blocks(const std::vector &blocks) { diff --git a/src/cryptonote_core/cryptonote_core.h b/src/cryptonote_core/cryptonote_core.h index b5996e0e6..d7a58fa4e 100644 --- a/src/cryptonote_core/cryptonote_core.h +++ b/src/cryptonote_core/cryptonote_core.h @@ -801,6 +801,12 @@ namespace cryptonote */ void invoke_update_blockchain_based_list_handler(uint64_t last_received_block_height); + /** + * @brief get_stake_tx_processor - returns stake tx processor + * @return pointer to StakeTransactionProcerssor + */ + StakeTransactionProcessor * get_stake_tx_processor(); + private: /** From fbc58a4d2664cc6bba61bc6381136a881f1e7a43 Mon Sep 17 00:00:00 2001 From: Ilya Kitaev Date: Mon, 17 Jun 2019 19:30:35 +0300 Subject: [PATCH 4/8] StakeTransactionProcessor: set_active_from_height method added --- src/cryptonote_core/cryptonote_core.cpp | 17 ++++++++++++++-- .../stake_transaction_processor.cpp | 20 +++++-------------- .../stake_transaction_processor.h | 14 ++++++++++--- 3 files changed, 31 insertions(+), 20 deletions(-) diff --git a/src/cryptonote_core/cryptonote_core.cpp b/src/cryptonote_core/cryptonote_core.cpp index 2b6a64fad..a6bdb8b34 100644 --- a/src/cryptonote_core/cryptonote_core.cpp +++ b/src/cryptonote_core/cryptonote_core.cpp @@ -56,6 +56,7 @@ using namespace epee; #include "ringct/rctSigs.h" #include "common/notify.h" #include "version.h" +#include "graft_rta_config.h" #undef MONERO_DEFAULT_LOG_CATEGORY #define MONERO_DEFAULT_LOG_CATEGORY "cn" @@ -342,9 +343,21 @@ namespace cryptonote if (get_arg(vm, arg_disable_stake_tx_processing)) { MWARNING("stake transaction processing disabled"); - m_graft_stake_transaction_processor.set_enabled(false); + m_graft_stake_transaction_processor.set_active_from_height(CRYPTONOTE_MAX_BLOCK_NUMBER); + } else { + const auto & hardforks = m_blockchain_storage.get_hard_fork_heights(m_nettype); + uint64_t stakes_active_height = 1; + for (const auto & hf: hardforks) { + if (hf.version == config::graft::STAKE_TRANSACTION_PROCESSING_DB_VERSION) { + stakes_active_height = hf.height; + break; + } + } + if (stakes_active_height == 1) { + MWARNING("Stake transaction processor: activation height not defined for nettype: " << m_nettype); + } + m_graft_stake_transaction_processor.set_active_from_height(stakes_active_height); } - return true; } //----------------------------------------------------------------------------------------------- diff --git a/src/cryptonote_core/stake_transaction_processor.cpp b/src/cryptonote_core/stake_transaction_processor.cpp index b774ca5f4..e800f920d 100644 --- a/src/cryptonote_core/stake_transaction_processor.cpp +++ b/src/cryptonote_core/stake_transaction_processor.cpp @@ -136,11 +136,7 @@ void StakeTransactionProcessor::init_storages_impl() if (m_storage || m_blockchain_based_list) throw std::runtime_error("StakeTransactionProcessor storages have been already initialized"); - uint64_t first_block_number = m_enabled ? m_blockchain.get_earliest_ideal_height_for_version(config::graft::STAKE_TRANSACTION_PROCESSING_DB_VERSION) - : std::numeric_limits().max(); - - if (first_block_number) - first_block_number--; + uint64_t first_block_number = m_active_height; MDEBUG("Initialize stake processing storages. First block height is " << first_block_number); @@ -153,10 +149,9 @@ void StakeTransactionProcessor::process_block_stake_transaction(uint64_t block_i if (block_index <= m_storage->get_last_processed_block_index()) return; - if (m_blockchain.get_hard_fork_version(block_index) >= config::graft::STAKE_TRANSACTION_PROCESSING_DB_VERSION) + if (block_index >= m_active_height) { - //analyze block transactions and add new stake transactions if exist - + //analyze block transactions and add new stake transactions if exist stake_transaction stake_tx; std::vector txs; @@ -295,7 +290,7 @@ void StakeTransactionProcessor::synchronize() uint64_t height = m_blockchain.get_current_blockchain_height(); - if (!height || m_blockchain.get_hard_fork_version(height - 1) < config::graft::STAKE_TRANSACTION_PROCESSING_DB_VERSION) + if (!height || height < m_active_height) return; if (!m_storage || !m_blockchain_based_list) @@ -492,12 +487,7 @@ void StakeTransactionProcessor::invoke_update_blockchain_based_list_handler(bool invoke_update_blockchain_based_list_handler_impl(depth); } -void StakeTransactionProcessor::set_enabled(bool arg) -{ - m_enabled = arg; -} - bool StakeTransactionProcessor::is_enabled() const { - return m_enabled; + return m_active_height < CRYPTONOTE_MAX_BLOCK_NUMBER; } diff --git a/src/cryptonote_core/stake_transaction_processor.h b/src/cryptonote_core/stake_transaction_processor.h index 5d8bff0a7..cd5f70c0e 100644 --- a/src/cryptonote_core/stake_transaction_processor.h +++ b/src/cryptonote_core/stake_transaction_processor.h @@ -43,11 +43,17 @@ class StakeTransactionProcessor /// Force invoke update handler for blockchain based list void invoke_update_blockchain_based_list_handler(bool force = true, size_t depth = 1); - /// Turns on/off processing - void set_enabled(bool arg); + // checks if stake tx procesing enabled + bool is_enabled() const; + /// activate stake processing from specific height + void set_active_from_height(uint64_t height) { m_active_height = height; } - bool is_enabled() const; + /// return height stake processing active from + uint64_t active_from_height() const { return m_active_height; } + + StakeTransactionStorage * get_storage() const { return m_storage.get(); } + BlockchainBasedList * get_blockchain_based_list() const { return m_blockchain_based_list.get(); } private: void init_storages_impl(); @@ -62,12 +68,14 @@ class StakeTransactionProcessor Blockchain& m_blockchain; std::unique_ptr m_storage; std::unique_ptr m_blockchain_based_list; + // TODO: move lock to storage? mutable epee::critical_section m_storage_lock; supernode_stakes_update_handler m_on_stakes_update; blockchain_based_list_update_handler m_on_blockchain_based_list_update; bool m_stakes_need_update; bool m_blockchain_based_list_need_update; bool m_enabled {true}; + uint64_t m_active_height {1}; }; } From 76571ca49010d52073b1ee5b9129932930f8fb54 Mon Sep 17 00:00:00 2001 From: Ilya Kitaev Date: Mon, 17 Jun 2019 19:37:50 +0300 Subject: [PATCH 5/8] add: construct_stake_tx_* functions --- tests/core_tests/chaingen.cpp | 26 ++++++++++++++++++++++++++ tests/core_tests/chaingen.h | 18 ++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/tests/core_tests/chaingen.cpp b/tests/core_tests/chaingen.cpp index d3cb52246..520f8b255 100644 --- a/tests/core_tests/chaingen.cpp +++ b/tests/core_tests/chaingen.cpp @@ -567,6 +567,21 @@ bool construct_tx_to_key(const std::vector& events, cryptonote return construct_tx(from.get_keys(), sources, destinations, from.get_keys().m_account_address, std::vector(), tx, 0); } + +bool construct_stake_tx_to_key(const std::vector &events, transaction &tx, const block &blk_head, const account_base &from, const account_base &to, + uint64_t amount, uint64_t fee, size_t nmix, + const public_key &supernode_id, const signature &supernode_sign, uint64_t unlock_height) +{ + vector sources; + vector destinations; + fill_tx_sources_and_destinations(events, blk_head, from, to, amount, fee, nmix, sources, destinations); + std::vector extra; + add_graft_stake_tx_extra_to_extra(extra, epee::string_tools::pod_to_hex(supernode_id), + to.get_keys().m_account_address, supernode_sign); + return construct_tx(from.get_keys(), sources, destinations, from.get_keys().m_account_address, extra, tx, unlock_height); +} + + transaction construct_tx_with_fee(std::vector& events, const block& blk_head, const account_base& acc_from, const account_base& acc_to, uint64_t amount, uint64_t fee) { @@ -576,6 +591,17 @@ transaction construct_tx_with_fee(std::vector& events, const b return tx; } +transaction construct_stake_tx_with_fee(std::vector& events, const block& blk_head, + const account_base& acc_from, const account_base& acc_to, uint64_t amount, uint64_t fee, + const public_key &supernode_id, const signature &supernode_sign, uint64_t unlock_height) +{ + transaction tx; + construct_stake_tx_to_key(events, tx, blk_head, acc_from, acc_to, amount, fee, 0, supernode_id, supernode_sign, unlock_height); + events.push_back(tx); + return tx; +} + + uint64_t get_balance(const cryptonote::account_base& addr, const std::vector& blockchain, const map_hash2tx_t& mtx) { uint64_t res = 0; std::map > outs; diff --git a/tests/core_tests/chaingen.h b/tests/core_tests/chaingen.h index 6b9277a30..823ccf1cf 100644 --- a/tests/core_tests/chaingen.h +++ b/tests/core_tests/chaingen.h @@ -225,10 +225,28 @@ bool construct_miner_tx_manually(size_t height, uint64_t already_generated_coins bool construct_tx_to_key(const std::vector& events, cryptonote::transaction& tx, const cryptonote::block& blk_head, const cryptonote::account_base& from, const cryptonote::account_base& to, uint64_t amount, uint64_t fee, size_t nmix); + +bool construct_stake_tx_to_key(const std::vector& events, cryptonote::transaction& tx, + const cryptonote::block& blk_head, const cryptonote::account_base& from, const cryptonote::account_base& to, + uint64_t amount, uint64_t fee, size_t nmix, + const crypto::public_key &supernode_id, + const crypto::signature &supernode_sign, + uint64_t unlock_height); + + + cryptonote::transaction construct_tx_with_fee(std::vector& events, const cryptonote::block& blk_head, const cryptonote::account_base& acc_from, const cryptonote::account_base& acc_to, uint64_t amount, uint64_t fee); + +cryptonote::transaction construct_stake_tx_with_fee(std::vector& events, const cryptonote::block& blk_head, + const cryptonote::account_base& acc_from, const cryptonote::account_base& acc_to, + uint64_t amount, uint64_t fee, + const crypto::public_key &supernode_id, + const crypto::signature &supernode_sign, + uint64_t unlock_height); + void get_confirmed_txs(const std::vector& blockchain, const map_hash2tx_t& mtx, map_hash2tx_t& confirmed_txs); bool find_block_chain(const std::vector& events, std::vector& blockchain, map_hash2tx_t& mtx, const crypto::hash& head); void fill_tx_sources_and_destinations(const std::vector& events, const cryptonote::block& blk_head, From 6d3ff94500efa6689c3f9eccc2b033892a239056 Mon Sep 17 00:00:00 2001 From: Ilya Kitaev Date: Mon, 17 Jun 2019 19:38:48 +0300 Subject: [PATCH 6/8] simple supernode stake tests --- tests/core_tests/README.md | 83 +++++++++++ tests/core_tests/chaingen_main.cpp | 4 + tests/core_tests/chaingen_tests_list.h | 1 + tests/core_tests/rta_tests.cpp | 196 ++++++++++++++++++++++--- tests/core_tests/rta_tests.h | 38 ++++- 5 files changed, 298 insertions(+), 24 deletions(-) create mode 100644 tests/core_tests/README.md diff --git a/tests/core_tests/README.md b/tests/core_tests/README.md new file mode 100644 index 000000000..68cff77bb --- /dev/null +++ b/tests/core_tests/README.md @@ -0,0 +1,83 @@ +# How to use 'core-tests' framework + +## Steps needed to create another test case; + +1. create a struct as a subclass `test_chain_unit_base` class, implement it in "my_test.h|cpp" files, + e.g.: + + ``` + struct gen_rta_tests : public test_chain_unit_base + { + gen_rta_tests(); + + // test generator method: here we define the test sequence + bool generate(std::vector& events) const; + + + bool check1(cryptonote::core& c, size_t ev_index, const std::vector& events); + bool check_stake_registered(cryptonote::core& c, size_t ev_index, const std::vector& events); + }; + ``` + + + 1.1. implement test sequence in `bool generate(std::vector& events) const;` method; + + 1.2. "check" functions should follow the interface: + ``` + bool check_function(cryptonote::core& c, size_t ev_index, const std::vector& events); + ``` + + 1.3. register "check" functions with `REGISTER_CALLBACK_METHOD` macro invoked in constructor: + ``` + REGISTER_CALLBACK_METHOD(gen_rta_tests, check_function); + ``` + + +2. add + + ``` + #include "your_test.h" to the "chaingen_test_list.h" + ``` + +3. add + + ``` + GENERATE_AND_PLAY(gen_rta_tests); + ``` + + to the `chaingen_main.cpp` inside + + ``` + else if (command_line::get_arg(vm, arg_generate_and_play_test_data)) + { + ``` + + block + + +4. (optional) define a `gen_test_options` struct representing testing hardfork table, which will be passed to cryptonote::core instance, e.g.: + + ``` + template<> + struct get_test_options { + const std::pair hard_forks[4] = {std::make_pair(1, 0), std::make_pair(13, 14), std::make_pair(14, 73)}; + const cryptonote::test_options test_options = { + hard_forks + }; + }; + ``` + + +5. implement `bool generate(std::vector& events) const;` method where you place your test flow. Your job is to generate blocks and transactions which will be played through 'cryptonote::core' instance; +Blocks and transactions to be added to the `events` vector. Normally it added by macros so you don't have to add it manually. + + 5.1. use `MAKE_GENESIS_BLOCK` macro to make a genesis block and add it the chain + 5.2. use `MAKE_NEXT_BLOCK` macro to create and add block to the chain + 5.3. use `construct_tx_with_fee` function to create transaction + 5.4. use `MAKE_NEXT_BLOCK_TX1` macro to add transaction to a block and add block to the chain + +6. schedule a "check" function call at the specific blockchain state inside `generate` method + ``` + DO_CALLBACK(events, "check_function"); + ``` + diff --git a/tests/core_tests/chaingen_main.cpp b/tests/core_tests/chaingen_main.cpp index 576187db8..87061f69b 100644 --- a/tests/core_tests/chaingen_main.cpp +++ b/tests/core_tests/chaingen_main.cpp @@ -250,6 +250,10 @@ int main(int argc, char* argv[]) GENERATE_AND_PLAY(gen_bp_tx_invalid_wrong_amount); GENERATE_AND_PLAY(gen_bp_tx_invalid_borromean_type); + // RTA tests + GENERATE_AND_PLAY(gen_rta_tests); + + el::Level level = (failed_tests.empty() ? el::Level::Info : el::Level::Error); MLOG(level, "\nREPORT:"); MLOG(level, " Test run: " << tests_count); diff --git a/tests/core_tests/chaingen_tests_list.h b/tests/core_tests/chaingen_tests_list.h index c12e97f95..59c3f6cfb 100644 --- a/tests/core_tests/chaingen_tests_list.h +++ b/tests/core_tests/chaingen_tests_list.h @@ -43,6 +43,7 @@ #include "rct.h" #include "multisig.h" #include "bulletproofs.h" +#include "rta_tests.h" /************************************************************************/ /* */ /************************************************************************/ diff --git a/tests/core_tests/rta_tests.cpp b/tests/core_tests/rta_tests.cpp index 169656042..5ab9e7fe8 100644 --- a/tests/core_tests/rta_tests.cpp +++ b/tests/core_tests/rta_tests.cpp @@ -31,40 +31,91 @@ #include "chaingen.h" #include "rta_tests.h" +#include "graft_rta_config.h" +#include using namespace epee; using namespace cryptonote; namespace { +// for future use +static const std::pair supernode_keys[] = { +{ "6efc0beb23adbe47b762350ec58e7d5054164b900af1d24bb77456b98062a906", + "f4957a1914119a20106b94fd88f25dd073f452a5199d493807263169c5b9db0b" }, +{ "4ae19dcd25fc3b023cc9ff168df0e5057ad3a6f12571707a455d0929ee35ee18", + "c7e61be8c0fe0198869dd6515b84b0075c962d5fb597d2cadd724a180ce39307" }, +{ "90b39f1406a53bddbc3e78883b418e75ecd4c9f8000a0b53ae881dcc4099f3b7", + "e02313e01503f1e7398f904fdcf1ab3ac4616161df4d7b8fd8cd3e7d0587b409" }, +{ "5a8786b55979d5c5b0b2cc162354f00c39d916583d2b97fe9426a99d1c473932", + "ebcab40d42a47cf52e5deb7f9aa27f7d92913f32644e5b3f38ac436cb32c2d00" }, +{ "ef842787b6733ca14de77db5f3f3a6a1c97e1bc9f046f57d3ed3b19484c541ea", + "1c78b4f2b33b51ba62595dbcc8225dfddd31afbdcdc9c99f4578433c2e6f4f05" }, +{ "be01835610894c1deb35160b683b7e267f93cde3d5a7ccfdcec8e9450c5ea22e", + "bd9b1ca21340093cc7802f7c69323b3079a3b2b9e248d6313b09e664d15bd40c" }, +{ "ad07ebf9a0e68a0333c76f12c2231bb04666d2773c8a7926562bf4e01e369111", + "994f8f0b9cf31591f8e587eb2af7c2be6bc53624e5dbfc6473758bc1027e360d" }, +{ "e8f00430416fa44aa032d0134e2c5f349a917d0f6330ae3ebe9a90586ce152db", + "17cbe82211fa7eca514b78965ceb9981a85d25fe7e0f516ead4509fc94034804" }, +{ "328430dfe107a6086239016b7d40b8b2c9856f6cb067326e77a96870475794fc", + "898498cac3a0ed7c84ca17dbf58777c05687f576220d7286fcaf9016de24b20c" }, +{ "0a84b00abe165eccea53064392202f1ea2df572a5b2adc18dcd20940011df5c1", + "d22b0808cfaa4fccf05762372aaf2063b047ed02374367d07c04eca57633a400" }, +{ "13a6cb678edec88e32b001b1959d2ac545b682156301db1710d07beb806a6d66", + "5eaa4be628b0112c1622711c956e5c5b1dd2bb8f7f6a7be55c3ae2b09d063308" }, +{ "e5d9b010fff2f8570eead1ebdd640663816c6cdafde114a9ba6c7154da7b867e", + "2db7f9bb92d9f768207ea8532b21c39b08c62baa544e8c1d5985bc32697e2d05" }, +{ "33134b18123ba123d7b394ef73f8a84d11e9442cf09017c8bbbb94fd24ab2a04", + "a71398ba703a9ec7b4ee7e4456ff287e1a091901b5789cf74ec55d265525a10b" }, +{ "dd6803f71150d96a3e5a02abfa014547e7e23f10a4d04d48d35288760d91d6b8", + "4265ff3b0f55b18a4cfa1591c89a09ac9c2d2a4a5ec062e02fde2714c0585c0e" }, +{ "ebb359bdac313ed773df8e79dd6fa05f2cac10e1fc47de998bc338eec001288b", + "49d71ad2603ca2924c0187096fe00cf4e261caff5922b9ff33b9f8606163d00a" }, +{ "688b66d57adeb2c8f07bb46b975ac94d90db82096cae5b2c52f3f02f1d3d6243", + "ea333672055c6133cbbabff55dd3482f19b863eba29d90effc5cc2ab71e1bd04" }, +}; +std::vector g_supernode_list; } + gen_rta_tests::gen_rta_tests() { - - REGISTER_CALLBACK_METHOD(gen_rta_tests, check_supernode_stake1); - + // validation calls own constructor so we can't use members here + if (g_supernode_list.size() == 0) { + static const size_t LIST_SIZE = 1; + for (size_t i = 0; i < LIST_SIZE; ++i) { + g_supernode_list.push_back(Supernode()); + } + } + REGISTER_CALLBACK_METHOD(gen_rta_tests, check_stake_registered); + REGISTER_CALLBACK_METHOD(gen_rta_tests, check_stake_expired); } bool gen_rta_tests::generate(std::vector& events) const { uint64_t ts_start = 1338224400; + // create one account GENERATE_ACCOUNT(miner); + // create another account GENERATE_ACCOUNT(alice); - - MAKE_GENESIS_BLOCK(events, blk_0, miner, ts_start); + // generate genesis block + MAKE_GENESIS_BLOCK(events, blk_0, miner, ts_start); // height = 1 + // create another account and add it to 'events' MAKE_ACCOUNT(events, miner0); MAKE_ACCOUNT(events, alice0); - MAKE_NEXT_BLOCK(events, blk_1, blk_0, miner0); - MAKE_NEXT_BLOCK(events, blk_1_side, blk_0, miner0); // alternative chain - MAKE_NEXT_BLOCK(events, blk_2, blk_1, miner0); + + // generate one block and add it to the chain + MAKE_NEXT_BLOCK(events, blk_1, blk_0, miner0); // height = 2 + // MAKE_NEXT_BLOCK(events, blk_1_side, blk_0, miner0); // alternative chain + MAKE_NEXT_BLOCK(events, blk_2, blk_1, miner0); // height = 3 //MAKE_TX(events, tx_0, first_miner_account, alice, 151, blk_2); + #if 0 - //// works like this - alice has a 70 coins in + //// how to send multiple txes in one block REWIND_BLOCKS(events, blk_2r, blk_2, miner0); MAKE_TX_LIST_START(events, txlist_0, miner0, alice0, MK_COINS(1), blk_2); MAKE_TX_LIST(events, txlist_0, miner0, alice0, MK_COINS(2), blk_2); @@ -76,35 +127,142 @@ bool gen_rta_tests::generate(std::vector& events) const return true; //// #endif - DO_CALLBACK(events, "verify_callback_1"); - REWIND_BLOCKS(events, blk_2r, blk_2, miner0); - DO_CALLBACK(events, "verify_callback_1"); - transaction tx_0(construct_tx_with_fee(events, blk_2, miner0, alice0, MK_COINS(1000), TESTS_DEFAULT_FEE)); - MAKE_NEXT_BLOCK_TX1(events, blk_22, blk_2r, miner0, tx_0); + // mine N blocks + REWIND_BLOCKS_N(events, blk_3, blk_2, miner0, 60); // height = 63 + //cryptonote::block blk_3 = blk_2; + // create transaction + transaction tx_0(construct_tx_with_fee(events, blk_3, miner0, alice0, MK_COINS(1000), TESTS_DEFAULT_FEE)); + // add it to the new block followed by 'blk_3', mined by 'miner0' + MAKE_NEXT_BLOCK_TX1(events, blk_4, blk_3, miner0, tx_0); // height = 64 - return true; + const size_t STAKE_PERIOD = 100; + // deposit stakes + cryptonote::block prev_block; + for (Supernode & sn : g_supernode_list) { + // create stake transaction + transaction tx(construct_stake_tx_with_fee(events, blk_4, miner0, sn.account, MK_COINS(50000), TESTS_DEFAULT_FEE, + sn.keys.pkey, sn.signature(), 64 + STAKE_PERIOD)); + MAKE_NEXT_BLOCK_TX1(events, blk_5, blk_4, miner0, tx); // height = 64 + REWIND_BLOCKS_N(events, blk_6, blk_5, miner0, config::graft::STAKE_VALIDATION_PERIOD); // height = 70; + prev_block = blk_6; + } + // schedule a 'check_stake_registered' check (checking if stake is registered) + DO_CALLBACK(events, "check_stake_registered"); + + // rewind for 'STAKE_PERIOD' blocks + REWIND_BLOCKS_N(events, bkl_7, prev_block, miner0, STAKE_PERIOD /* + config::graft::TRUSTED_RESTAKING_PERIOD*/); // TODO: check why TRUSTED_RESTAKING_PERIOD is not applied + // schedule a 'check_stake_expired' check (checking if stake is expired) + DO_CALLBACK(events, "check_stake_expired"); + return true; } -bool gen_rta_tests::check_supernode_stake1(core &c, size_t ev_index, const std::vector &events) +// Not used, just to show how to get balances +bool gen_rta_tests::check1(core &c, size_t ev_index, const std::vector &events) { + DEFINE_TESTS_ERROR_CONTEXT("gen_rta_tests::check1"); cryptonote::account_base miner0 = boost::get(events[1]); cryptonote::account_base alice0 = boost::get(events[2]); std::vector chain; map_hash2tx_t mtx; std::vector block_list; - bool r = c.get_blocks(0, 1000 + 2 * CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW, block_list); + bool r = c.get_blocks(0, 5 * CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW, block_list); /*bool r = */find_block_chain(events, chain, mtx, get_block_hash(block_list.back())); + MDEBUG("chain size: " << chain.size()); + MDEBUG("chain height (core): " << c.get_current_blockchain_height()); MDEBUG("events size: " << events.size()); MDEBUG("ev_index: " << ev_index); - MDEBUG("BALANCE = " << print_money(get_balance(miner0, chain, mtx))); - MDEBUG("BALANCE = " << print_money(get_balance(alice0, chain, mtx))); + MDEBUG("miner BALANCE: " << print_money(get_balance(miner0, chain, mtx))); + MDEBUG("alice BALANCE: " << print_money(get_balance(alice0, chain, mtx))); + + return true; +} + + +bool gen_rta_tests::check_stake_registered(core &c, size_t ev_index, const std::vector &events) +{ + DEFINE_TESTS_ERROR_CONTEXT("gen_rta_tests::check_stake_registered"); + cryptonote::account_base miner0 = boost::get(events[1]); + cryptonote::account_base alice0 = boost::get(events[2]); + std::vector chain; + map_hash2tx_t mtx; + std::vector block_list; + bool r = c.get_blocks(0, 5 * CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW, block_list); + + /*bool r = */find_block_chain(events, chain, mtx, get_block_hash(block_list.back())); + for (const auto & tx : mtx) { MDEBUG("tx: " << tx.first); + std::string supernode_public_id; + cryptonote::account_public_address supernode_public_address; + crypto::signature supernode_signature; + crypto::secret_key tx_secret_key; + bool is_stake_tx = get_graft_stake_tx_extra_from_extra(*tx.second, + supernode_public_id, + supernode_public_address, + supernode_signature, + tx_secret_key); + if (is_stake_tx) { + MDEBUG(" is stake tx for id: " << supernode_public_id); + } } + + StakeTransactionProcessor * stp = c.get_stake_tx_processor(); + MDEBUG("blockchain height: " << c.get_current_blockchain_height()); + + CHECK_NOT_EQ(stp->get_blockchain_based_list(), 0); + CHECK_EQ(stp->get_blockchain_based_list()->block_height(), block_list.size() - 1); + + MDEBUG("stp->get_blockchain_based_list()->block_height(): " << stp->get_blockchain_based_list()->block_height()); + + CHECK_EQ(stp->get_blockchain_based_list()->tiers().size(), 4); + uint64_t stake_amount = 0; + for (const auto & tier : stp->get_blockchain_based_list()->tiers()) { + for (const auto & sn: tier) { + MDEBUG("sn: " << sn.supernode_public_id << ", stake_amount: " << sn.amount << ", expired at height: " << sn.unlock_time); + stake_amount += sn.amount; + } + } + CHECK_EQ(stake_amount, MK_COINS(50000)); + + MDEBUG("stake_tx_storage->get_tx_count: " << stp->get_storage()->get_tx_count()); + MDEBUG("stake_tx_storage->get_last_processed_block_index: " << stp->get_storage()->get_last_processed_block_index()); + return true; +} + +bool gen_rta_tests::check_stake_expired(core &c, size_t ev_index, const std::vector &events) +{ + DEFINE_TESTS_ERROR_CONTEXT("gen_rta_tests::check_stake_expired"); + cryptonote::account_base miner0 = boost::get(events[1]); + cryptonote::account_base alice0 = boost::get(events[2]); + std::vector chain; + map_hash2tx_t mtx; + std::vector block_list; + + // request count doesn't have to be exact value + bool r = c.get_blocks(0, 5 * CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW, block_list); + + find_block_chain(events, chain, mtx, get_block_hash(block_list.back())); + + StakeTransactionProcessor * stp = c.get_stake_tx_processor(); + + CHECK_EQ(stp->get_blockchain_based_list()->block_height(), block_list.size() - 1); + MDEBUG("stp->get_blockchain_based_list()->block_height(): " << stp->get_blockchain_based_list()->block_height()); + CHECK_EQ(stp->get_blockchain_based_list()->tiers().size(), 4); + uint64_t stake_amount = 0; + for (const auto & tier : stp->get_blockchain_based_list()->tiers()) { + for (const auto & sn: tier) { + MDEBUG("sn: " << sn.supernode_public_id << ", stake_amount: " << sn.amount << ", expired at height: " << sn.unlock_time); + stake_amount += sn.amount; + } + } + CHECK_EQ(stake_amount, 0); + MDEBUG("stake_tx_storage->get_tx_count: " << stp->get_storage()->get_tx_count()); + MDEBUG("stake_tx_storage->get_last_processed_block_index: " << stp->get_storage()->get_last_processed_block_index()); + return true; } diff --git a/tests/core_tests/rta_tests.h b/tests/core_tests/rta_tests.h index e4f0d2bc3..b52a2665a 100644 --- a/tests/core_tests/rta_tests.h +++ b/tests/core_tests/rta_tests.h @@ -32,6 +32,36 @@ #pragma once #include "chaingen.h" #include "misc_log_ex.h" +#include + +struct Supernode { + struct Keypair { + crypto::public_key pkey; + crypto::secret_key skey; + }; + cryptonote::account_base account; + Keypair keys; + Supernode() + { + account.generate(); + crypto::generate_keys(keys.pkey, keys.skey); + } + crypto::signature signature() + { + std::string address = cryptonote::get_account_address_as_str( + cryptonote::MAINNET, false, account.get_keys().m_account_address); + std::string msg = address + ":" + epee::string_tools::pod_to_hex(keys.pkey); + crypto::signature result; + sign_message(msg, result); + return result; + } + void sign_message(const std::string msg, crypto::signature &signature) + { + crypto::hash hash; + crypto::cn_fast_hash(msg.data(), msg.size(), hash); + crypto::generate_signature(hash, keys.pkey, keys.skey, signature); + } +}; struct gen_rta_tests : public test_chain_unit_base { @@ -42,12 +72,10 @@ struct gen_rta_tests : public test_chain_unit_base // bool check_block_verification_context(const cryptonote::block_verification_context& bvc, size_t event_idx, const cryptonote::block& blk); - bool check_supernode_stake1(cryptonote::core& c, size_t ev_index, const std::vector& events); - + bool check1(cryptonote::core& c, size_t ev_index, const std::vector& events); + bool check_stake_registered(cryptonote::core& c, size_t ev_index, const std::vector& events); + bool check_stake_expired(cryptonote::core& c, size_t ev_index, const std::vector& events); private: - cryptonote::account_base m_miner; - cryptonote::account_base m_supernode1; - }; // this is how to define hardforks table for the cryptonote::core From 67cb74a77174fdde38c0f18c89f684f7ecd68566 Mon Sep 17 00:00:00 2001 From: Ilya Kitaev Date: Thu, 20 Jun 2019 21:21:10 +0300 Subject: [PATCH 7/8] renamed unlock_height to be consistent with the existing terminology --- tests/core_tests/chaingen.cpp | 8 ++++---- tests/core_tests/chaingen.h | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/core_tests/chaingen.cpp b/tests/core_tests/chaingen.cpp index 520f8b255..e18512231 100644 --- a/tests/core_tests/chaingen.cpp +++ b/tests/core_tests/chaingen.cpp @@ -570,7 +570,7 @@ bool construct_tx_to_key(const std::vector& events, cryptonote bool construct_stake_tx_to_key(const std::vector &events, transaction &tx, const block &blk_head, const account_base &from, const account_base &to, uint64_t amount, uint64_t fee, size_t nmix, - const public_key &supernode_id, const signature &supernode_sign, uint64_t unlock_height) + const public_key &supernode_id, const signature &supernode_sign, uint64_t unlock_time) { vector sources; vector destinations; @@ -578,7 +578,7 @@ bool construct_stake_tx_to_key(const std::vector &events, tran std::vector extra; add_graft_stake_tx_extra_to_extra(extra, epee::string_tools::pod_to_hex(supernode_id), to.get_keys().m_account_address, supernode_sign); - return construct_tx(from.get_keys(), sources, destinations, from.get_keys().m_account_address, extra, tx, unlock_height); + return construct_tx(from.get_keys(), sources, destinations, from.get_keys().m_account_address, extra, tx, unlock_time); } @@ -593,10 +593,10 @@ transaction construct_tx_with_fee(std::vector& events, const b transaction construct_stake_tx_with_fee(std::vector& events, const block& blk_head, const account_base& acc_from, const account_base& acc_to, uint64_t amount, uint64_t fee, - const public_key &supernode_id, const signature &supernode_sign, uint64_t unlock_height) + const public_key &supernode_id, const signature &supernode_sign, uint64_t unlock_time) { transaction tx; - construct_stake_tx_to_key(events, tx, blk_head, acc_from, acc_to, amount, fee, 0, supernode_id, supernode_sign, unlock_height); + construct_stake_tx_to_key(events, tx, blk_head, acc_from, acc_to, amount, fee, 0, supernode_id, supernode_sign, unlock_time); events.push_back(tx); return tx; } diff --git a/tests/core_tests/chaingen.h b/tests/core_tests/chaingen.h index 823ccf1cf..30b784a20 100644 --- a/tests/core_tests/chaingen.h +++ b/tests/core_tests/chaingen.h @@ -231,7 +231,7 @@ bool construct_stake_tx_to_key(const std::vector& events, cryp uint64_t amount, uint64_t fee, size_t nmix, const crypto::public_key &supernode_id, const crypto::signature &supernode_sign, - uint64_t unlock_height); + uint64_t unlock_time); @@ -245,7 +245,7 @@ cryptonote::transaction construct_stake_tx_with_fee(std::vector& blockchain, const map_hash2tx_t& mtx, map_hash2tx_t& confirmed_txs); bool find_block_chain(const std::vector& events, std::vector& blockchain, map_hash2tx_t& mtx, const crypto::hash& head); From aba7fd115b344f8afc8ebfb0004b222d6a47ab40 Mon Sep 17 00:00:00 2001 From: Ilya Kitaev Date: Fri, 21 Jun 2019 18:10:51 +0300 Subject: [PATCH 8/8] [WIP] generating many stake txes --- tests/core_tests/rta_tests.cpp | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/tests/core_tests/rta_tests.cpp b/tests/core_tests/rta_tests.cpp index 5ab9e7fe8..5c7273d9c 100644 --- a/tests/core_tests/rta_tests.cpp +++ b/tests/core_tests/rta_tests.cpp @@ -84,7 +84,7 @@ gen_rta_tests::gen_rta_tests() { // validation calls own constructor so we can't use members here if (g_supernode_list.size() == 0) { - static const size_t LIST_SIZE = 1; + static const size_t LIST_SIZE = 2; for (size_t i = 0; i < LIST_SIZE; ++i) { g_supernode_list.push_back(Supernode()); } @@ -139,19 +139,27 @@ bool gen_rta_tests::generate(std::vector& events) const const size_t STAKE_PERIOD = 100; // deposit stakes cryptonote::block prev_block; + std::list stake_txes; for (Supernode & sn : g_supernode_list) { // create stake transaction transaction tx(construct_stake_tx_with_fee(events, blk_4, miner0, sn.account, MK_COINS(50000), TESTS_DEFAULT_FEE, sn.keys.pkey, sn.signature(), 64 + STAKE_PERIOD)); - MAKE_NEXT_BLOCK_TX1(events, blk_5, blk_4, miner0, tx); // height = 64 - REWIND_BLOCKS_N(events, blk_6, blk_5, miner0, config::graft::STAKE_VALIDATION_PERIOD); // height = 70; - prev_block = blk_6; + stake_txes.push_back(tx); +// MAKE_NEXT_BLOCK_TX1(events, blk_5, blk_4, miner0, tx); // height = 64 +// REWIND_BLOCKS_N(events, blk_6, blk_5, miner0, config::graft::STAKE_VALIDATION_PERIOD); // height = 70; +// prev_block = blk_6; } + MAKE_NEXT_BLOCK_TX_LIST(events, blk_5, blk_4, miner0, stake_txes); + + MDEBUG("stake tx list constructed"); + + + REWIND_BLOCKS_N(events, blk_6, blk_5, miner0, config::graft::STAKE_VALIDATION_PERIOD); // height = 70; // schedule a 'check_stake_registered' check (checking if stake is registered) DO_CALLBACK(events, "check_stake_registered"); // rewind for 'STAKE_PERIOD' blocks - REWIND_BLOCKS_N(events, bkl_7, prev_block, miner0, STAKE_PERIOD /* + config::graft::TRUSTED_RESTAKING_PERIOD*/); // TODO: check why TRUSTED_RESTAKING_PERIOD is not applied + REWIND_BLOCKS_N(events, bkl_7, blk_6, miner0, STAKE_PERIOD /* + config::graft::TRUSTED_RESTAKING_PERIOD*/); // TODO: check why TRUSTED_RESTAKING_PERIOD is not applied // schedule a 'check_stake_expired' check (checking if stake is expired) DO_CALLBACK(events, "check_stake_expired"); @@ -226,7 +234,7 @@ bool gen_rta_tests::check_stake_registered(core &c, size_t ev_index, const std:: stake_amount += sn.amount; } } - CHECK_EQ(stake_amount, MK_COINS(50000)); + CHECK_EQ(stake_amount, MK_COINS(50000) * g_supernode_list.size()); MDEBUG("stake_tx_storage->get_tx_count: " << stp->get_storage()->get_tx_count()); MDEBUG("stake_tx_storage->get_last_processed_block_index: " << stp->get_storage()->get_last_processed_block_index());