Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

basic supernode stakes unit tests #322

Open
wants to merge 8 commits into
base: develop
Choose a base branch
from
4 changes: 2 additions & 2 deletions src/cryptonote_basic/cryptonote_basic_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
22 changes: 20 additions & 2 deletions src/cryptonote_core/cryptonote_core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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;
}
//-----------------------------------------------------------------------------------------------
Expand Down Expand Up @@ -1354,6 +1367,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<block_complete_entry> &blocks)
{
Expand Down
6 changes: 6 additions & 0 deletions src/cryptonote_core/cryptonote_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -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:

/**
Expand Down
20 changes: 5 additions & 15 deletions src/cryptonote_core/stake_transaction_processor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<uint64_t>().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);

Expand All @@ -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<transaction> txs;
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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;
}
14 changes: 11 additions & 3 deletions src/cryptonote_core/stake_transaction_processor.h
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -62,12 +68,14 @@ class StakeTransactionProcessor
Blockchain& m_blockchain;
std::unique_ptr<StakeTransactionStorage> m_storage;
std::unique_ptr<BlockchainBasedList> 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};
};

}
6 changes: 4 additions & 2 deletions tests/core_tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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}
Expand Down
83 changes: 83 additions & 0 deletions tests/core_tests/README.md
Original file line number Diff line number Diff line change
@@ -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<test_event_entry>& events) const;


bool check1(cryptonote::core& c, size_t ev_index, const std::vector<test_event_entry>& events);
bool check_stake_registered(cryptonote::core& c, size_t ev_index, const std::vector<test_event_entry>& events);
};
```


1.1. implement test sequence in `bool generate(std::vector<test_event_entry>& events) const;` method;

1.2. "check" functions should follow the interface:
```
bool check_function(cryptonote::core& c, size_t ev_index, const std::vector<test_event_entry>& 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<gen_rta_tests> {
const std::pair<uint8_t, uint64_t> 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<test_event_entry>& 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");
```

26 changes: 26 additions & 0 deletions tests/core_tests/chaingen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -567,6 +567,21 @@ bool construct_tx_to_key(const std::vector<test_event_entry>& events, cryptonote
return construct_tx(from.get_keys(), sources, destinations, from.get_keys().m_account_address, std::vector<uint8_t>(), tx, 0);
}


bool construct_stake_tx_to_key(const std::vector<test_event_entry> &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)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think unlock_height should be unlock_time, which is what is used everywhere else

{
vector<tx_source_entry> sources;
vector<tx_destination_entry> destinations;
fill_tx_sources_and_destinations(events, blk_head, from, to, amount, fee, nmix, sources, destinations);
std::vector<uint8_t> 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<test_event_entry>& events, const block& blk_head,
const account_base& acc_from, const account_base& acc_to, uint64_t amount, uint64_t fee)
{
Expand All @@ -576,6 +591,17 @@ transaction construct_tx_with_fee(std::vector<test_event_entry>& events, const b
return tx;
}

transaction construct_stake_tx_with_fee(std::vector<test_event_entry>& 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<cryptonote::block>& blockchain, const map_hash2tx_t& mtx) {
uint64_t res = 0;
std::map<uint64_t, std::vector<output_index> > outs;
Expand Down
18 changes: 18 additions & 0 deletions tests/core_tests/chaingen.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<test_event_entry>& 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<test_event_entry>& 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<test_event_entry>& 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<test_event_entry>& 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<cryptonote::block>& blockchain, const map_hash2tx_t& mtx, map_hash2tx_t& confirmed_txs);
bool find_block_chain(const std::vector<test_event_entry>& events, std::vector<cryptonote::block>& blockchain, map_hash2tx_t& mtx, const crypto::hash& head);
void fill_tx_sources_and_destinations(const std::vector<test_event_entry>& events, const cryptonote::block& blk_head,
Expand Down
4 changes: 4 additions & 0 deletions tests/core_tests/chaingen_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
1 change: 1 addition & 0 deletions tests/core_tests/chaingen_tests_list.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
#include "rct.h"
#include "multisig.h"
#include "bulletproofs.h"
#include "rta_tests.h"
/************************************************************************/
/* */
/************************************************************************/
Expand Down
Loading