mirror of
https://github.com/monero-project/monero.git
synced 2024-11-17 08:17:37 +00:00
tests: fix HF12 chaingen - construct bc object from events
This commit is contained in:
parent
fe3f6a3e6b
commit
da6c807f8b
3 changed files with 180 additions and 22 deletions
|
@ -47,6 +47,12 @@
|
||||||
#include "cryptonote_basic/cryptonote_format_utils.h"
|
#include "cryptonote_basic/cryptonote_format_utils.h"
|
||||||
#include "cryptonote_basic/miner.h"
|
#include "cryptonote_basic/miner.h"
|
||||||
|
|
||||||
|
#include "blockchain_db/blockchain_db.h"
|
||||||
|
#include "cryptonote_core/cryptonote_core.h"
|
||||||
|
#include "cryptonote_core/tx_pool.h"
|
||||||
|
#include "cryptonote_core/blockchain.h"
|
||||||
|
#include "blockchain_db/testdb.h"
|
||||||
|
|
||||||
#include "chaingen.h"
|
#include "chaingen.h"
|
||||||
#include "device/device.hpp"
|
#include "device/device.hpp"
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
@ -55,6 +61,126 @@ using namespace epee;
|
||||||
using namespace crypto;
|
using namespace crypto;
|
||||||
using namespace cryptonote;
|
using namespace cryptonote;
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Dummy TestDB to store height -> (block, hash) information
|
||||||
|
* for the use only in the test_generator::fill_nonce() function,
|
||||||
|
* which requires blockchain object to correctly compute PoW on HF12+ blocks
|
||||||
|
* as the mining function requires it to obtain a valid seedhash.
|
||||||
|
*/
|
||||||
|
class TestDB: public cryptonote::BaseTestDB
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
struct block_t
|
||||||
|
{
|
||||||
|
cryptonote::block bl;
|
||||||
|
crypto::hash hash;
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
TestDB() { m_open = true; }
|
||||||
|
|
||||||
|
virtual void add_block( const cryptonote::block& blk
|
||||||
|
, size_t block_weight
|
||||||
|
, uint64_t long_term_block_weight
|
||||||
|
, const cryptonote::difficulty_type& cumulative_difficulty
|
||||||
|
, const uint64_t& coins_generated
|
||||||
|
, uint64_t num_rct_outs
|
||||||
|
, const crypto::hash& blk_hash
|
||||||
|
) override
|
||||||
|
{
|
||||||
|
blocks.push_back({blk, blk_hash});
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual uint64_t height() const override { return blocks.empty() ? 0 : blocks.size() - 1; }
|
||||||
|
|
||||||
|
// Required for randomx
|
||||||
|
virtual crypto::hash get_block_hash_from_height(const uint64_t &height) const override
|
||||||
|
{
|
||||||
|
if (height < blocks.size())
|
||||||
|
{
|
||||||
|
MDEBUG("Get hash for block height: " << height << " hash: " << blocks[height].hash);
|
||||||
|
return blocks[height].hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
MDEBUG("Get hash for block height: " << height << " zero-hash");
|
||||||
|
crypto::hash hash = crypto::null_hash;
|
||||||
|
*(uint64_t*)&hash = height;
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual crypto::hash top_block_hash(uint64_t *block_height = NULL) const override
|
||||||
|
{
|
||||||
|
const uint64_t h = height();
|
||||||
|
if (block_height != nullptr)
|
||||||
|
{
|
||||||
|
*block_height = h;
|
||||||
|
}
|
||||||
|
|
||||||
|
return get_block_hash_from_height(h);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual cryptonote::block get_top_block() const override
|
||||||
|
{
|
||||||
|
if (blocks.empty())
|
||||||
|
{
|
||||||
|
cryptonote::block b;
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
return blocks[blocks.size()-1].bl;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void pop_block(cryptonote::block &blk, std::vector<cryptonote::transaction> &txs) override { if (!blocks.empty()) blocks.pop_back(); }
|
||||||
|
virtual void set_hard_fork_version(uint64_t height, uint8_t version) override { if (height >= hf.size()) hf.resize(height + 1); hf[height] = version; }
|
||||||
|
virtual uint8_t get_hard_fork_version(uint64_t height) const override { if (height >= hf.size()) return 255; return hf[height]; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<block_t> blocks;
|
||||||
|
std::vector<uint8_t> hf;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::unique_ptr<cryptonote::Blockchain> init_blockchain(const std::vector<test_event_entry> & events, cryptonote::network_type nettype)
|
||||||
|
{
|
||||||
|
std::unique_ptr<cryptonote::Blockchain> bc;
|
||||||
|
v_hardforks_t hardforks;
|
||||||
|
cryptonote::test_options test_options_tmp{nullptr, 0};
|
||||||
|
const cryptonote::test_options * test_options = &test_options_tmp;
|
||||||
|
if (!extract_hard_forks(events, hardforks))
|
||||||
|
{
|
||||||
|
MDEBUG("Extracting hard-forks from blocks");
|
||||||
|
extract_hard_forks_from_blocks(events, hardforks);
|
||||||
|
}
|
||||||
|
|
||||||
|
hardforks.push_back(std::make_pair((uint8_t)0, (uint64_t)0)); // terminator
|
||||||
|
test_options_tmp.hard_forks = hardforks.data();
|
||||||
|
test_options = &test_options_tmp;
|
||||||
|
|
||||||
|
cryptonote::tx_memory_pool txpool(*bc);
|
||||||
|
bc.reset(new cryptonote::Blockchain(txpool));
|
||||||
|
|
||||||
|
cryptonote::Blockchain *blockchain = bc.get();
|
||||||
|
auto bdb = new TestDB();
|
||||||
|
|
||||||
|
BOOST_FOREACH(const test_event_entry &ev, events)
|
||||||
|
{
|
||||||
|
if (typeid(block) != ev.type())
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const block *blk = &boost::get<block>(ev);
|
||||||
|
auto blk_hash = get_block_hash(*blk);
|
||||||
|
bdb->add_block(*blk, 1, 1, 1, 0, 0, blk_hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool r = blockchain->init(bdb, nettype, true, test_options, 2, nullptr);
|
||||||
|
CHECK_AND_ASSERT_THROW_MES(r, "could not init blockchain from events");
|
||||||
|
return bc;
|
||||||
|
}
|
||||||
|
|
||||||
void test_generator::get_block_chain(std::vector<block_info>& blockchain, const crypto::hash& head, size_t n) const
|
void test_generator::get_block_chain(std::vector<block_info>& blockchain, const crypto::hash& head, size_t n) const
|
||||||
{
|
{
|
||||||
|
@ -184,13 +310,7 @@ bool test_generator::construct_block(cryptonote::block& blk, uint64_t height, co
|
||||||
|
|
||||||
//blk.tree_root_hash = get_tx_tree_hash(blk);
|
//blk.tree_root_hash = get_tx_tree_hash(blk);
|
||||||
|
|
||||||
// Nonce search...
|
fill_nonce(blk, get_test_difficulty(hf_ver), height);
|
||||||
blk.nonce = 0;
|
|
||||||
while (!miner::find_nonce_for_given_block([](const cryptonote::block &b, uint64_t height, unsigned int threads, crypto::hash &hash){
|
|
||||||
return cryptonote::get_block_longhash(NULL, b, hash, height, threads);
|
|
||||||
}, blk, get_test_difficulty(hf_ver), height))
|
|
||||||
blk.timestamp++;
|
|
||||||
|
|
||||||
add_block(blk, txs_weight, block_weights, already_generated_coins, hf_ver ? hf_ver.get() : 1);
|
add_block(blk, txs_weight, block_weights, already_generated_coins, hf_ver ? hf_ver.get() : 1);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -268,6 +388,26 @@ bool test_generator::construct_block_manually_tx(cryptonote::block& blk, const c
|
||||||
return construct_block_manually(blk, prev_block, miner_acc, bf_tx_hashes, 0, 0, 0, crypto::hash(), 0, transaction(), tx_hashes, txs_weight);
|
return construct_block_manually(blk, prev_block, miner_acc, bf_tx_hashes, 0, 0, 0, crypto::hash(), 0, transaction(), tx_hashes, txs_weight);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void test_generator::fill_nonce(cryptonote::block& blk, const difficulty_type& diffic, uint64_t height)
|
||||||
|
{
|
||||||
|
const cryptonote::Blockchain *blockchain = nullptr;
|
||||||
|
std::unique_ptr<cryptonote::Blockchain> bc;
|
||||||
|
|
||||||
|
if (blk.major_version >= RX_BLOCK_VERSION)
|
||||||
|
{
|
||||||
|
CHECK_AND_ASSERT_THROW_MES(m_events != nullptr, "events not set, cannot compute valid RandomX PoW");
|
||||||
|
bc = init_blockchain(*m_events, m_nettype);
|
||||||
|
blockchain = bc.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
blk.nonce = 0;
|
||||||
|
while (!miner::find_nonce_for_given_block([blockchain](const cryptonote::block &b, uint64_t height, unsigned int threads, crypto::hash &hash){
|
||||||
|
return cryptonote::get_block_longhash(blockchain, b, hash, height, threads);
|
||||||
|
}, blk, diffic, height)) {
|
||||||
|
blk.timestamp++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
uint64_t get_inputs_amount(const vector<tx_source_entry> &s)
|
uint64_t get_inputs_amount(const vector<tx_source_entry> &s)
|
||||||
|
@ -796,15 +936,6 @@ void fill_tx_sources_and_destinations(const std::vector<test_event_entry>& event
|
||||||
fill_tx_sources_and_destinations(events, blk_head, from, to.get_keys().m_account_address, amount, fee, nmix, sources, destinations);
|
fill_tx_sources_and_destinations(events, blk_head, from, to.get_keys().m_account_address, amount, fee, nmix, sources, destinations);
|
||||||
}
|
}
|
||||||
|
|
||||||
void fill_nonce(cryptonote::block& blk, const difficulty_type& diffic, uint64_t height)
|
|
||||||
{
|
|
||||||
blk.nonce = 0;
|
|
||||||
while (!miner::find_nonce_for_given_block([](const cryptonote::block &b, uint64_t height, unsigned int threads, crypto::hash &hash){
|
|
||||||
return cryptonote::get_block_longhash(NULL, b, hash, height, threads);
|
|
||||||
}, blk, diffic, height))
|
|
||||||
blk.timestamp++;
|
|
||||||
}
|
|
||||||
|
|
||||||
cryptonote::tx_destination_entry build_dst(const var_addr_t& to, bool is_subaddr, uint64_t amount)
|
cryptonote::tx_destination_entry build_dst(const var_addr_t& to, bool is_subaddr, uint64_t amount)
|
||||||
{
|
{
|
||||||
tx_destination_entry de;
|
tx_destination_entry de;
|
||||||
|
@ -983,6 +1114,31 @@ bool extract_hard_forks(const std::vector<test_event_entry>& events, v_hardforks
|
||||||
return !hard_forks.empty();
|
return !hard_forks.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool extract_hard_forks_from_blocks(const std::vector<test_event_entry>& events, v_hardforks_t& hard_forks)
|
||||||
|
{
|
||||||
|
int hf = -1;
|
||||||
|
int64_t height = 0;
|
||||||
|
|
||||||
|
for(auto & ev : events)
|
||||||
|
{
|
||||||
|
if (typeid(block) != ev.type())
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const block *blk = &boost::get<block>(ev);
|
||||||
|
if (blk->major_version != hf)
|
||||||
|
{
|
||||||
|
hf = blk->major_version;
|
||||||
|
hard_forks.push_back(std::make_pair(blk->major_version, (uint64_t)height));
|
||||||
|
}
|
||||||
|
|
||||||
|
height += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return !hard_forks.empty();
|
||||||
|
}
|
||||||
|
|
||||||
void get_confirmed_txs(const std::vector<cryptonote::block>& blockchain, const map_hash2tx_t& mtx, map_hash2tx_t& confirmed_txs)
|
void get_confirmed_txs(const std::vector<cryptonote::block>& blockchain, const map_hash2tx_t& mtx, map_hash2tx_t& confirmed_txs)
|
||||||
{
|
{
|
||||||
std::unordered_set<crypto::hash> confirmed_hashes;
|
std::unordered_set<crypto::hash> confirmed_hashes;
|
||||||
|
|
|
@ -227,8 +227,8 @@ public:
|
||||||
bf_hf_version= 1 << 8
|
bf_hf_version= 1 << 8
|
||||||
};
|
};
|
||||||
|
|
||||||
test_generator() {}
|
test_generator(): m_events(nullptr) {}
|
||||||
test_generator(const test_generator &other): m_blocks_info(other.m_blocks_info) {}
|
test_generator(const test_generator &other): m_blocks_info(other.m_blocks_info), m_events(other.m_events), m_nettype(other.m_nettype) {}
|
||||||
void get_block_chain(std::vector<block_info>& blockchain, const crypto::hash& head, size_t n) const;
|
void get_block_chain(std::vector<block_info>& blockchain, const crypto::hash& head, size_t n) const;
|
||||||
void get_last_n_block_weights(std::vector<size_t>& block_weights, const crypto::hash& head, size_t n) const;
|
void get_last_n_block_weights(std::vector<size_t>& block_weights, const crypto::hash& head, size_t n) const;
|
||||||
uint64_t get_already_generated_coins(const crypto::hash& blk_id) const;
|
uint64_t get_already_generated_coins(const crypto::hash& blk_id) const;
|
||||||
|
@ -253,9 +253,14 @@ public:
|
||||||
uint8_t hf_version = 1);
|
uint8_t hf_version = 1);
|
||||||
bool construct_block_manually_tx(cryptonote::block& blk, const cryptonote::block& prev_block,
|
bool construct_block_manually_tx(cryptonote::block& blk, const cryptonote::block& prev_block,
|
||||||
const cryptonote::account_base& miner_acc, const std::vector<crypto::hash>& tx_hashes, size_t txs_size);
|
const cryptonote::account_base& miner_acc, const std::vector<crypto::hash>& tx_hashes, size_t txs_size);
|
||||||
|
void fill_nonce(cryptonote::block& blk, const cryptonote::difficulty_type& diffic, uint64_t height);
|
||||||
|
void set_events(const std::vector<test_event_entry> * events) { m_events = events; }
|
||||||
|
void set_network_type(const cryptonote::network_type nettype) { m_nettype = nettype; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unordered_map<crypto::hash, block_info> m_blocks_info;
|
std::unordered_map<crypto::hash, block_info> m_blocks_info;
|
||||||
|
const std::vector<test_event_entry> * m_events;
|
||||||
|
cryptonote::network_type m_nettype;
|
||||||
|
|
||||||
friend class boost::serialization::access;
|
friend class boost::serialization::access;
|
||||||
|
|
||||||
|
@ -407,7 +412,6 @@ cryptonote::account_public_address get_address(const cryptonote::tx_destination_
|
||||||
|
|
||||||
inline cryptonote::difficulty_type get_test_difficulty(const boost::optional<uint8_t>& hf_ver=boost::none) {return !hf_ver || hf_ver.get() <= 1 ? 1 : 2;}
|
inline cryptonote::difficulty_type get_test_difficulty(const boost::optional<uint8_t>& hf_ver=boost::none) {return !hf_ver || hf_ver.get() <= 1 ? 1 : 2;}
|
||||||
inline uint64_t current_difficulty_window(const boost::optional<uint8_t>& hf_ver=boost::none){ return !hf_ver || hf_ver.get() <= 1 ? DIFFICULTY_TARGET_V1 : DIFFICULTY_TARGET_V2; }
|
inline uint64_t current_difficulty_window(const boost::optional<uint8_t>& hf_ver=boost::none){ return !hf_ver || hf_ver.get() <= 1 ? DIFFICULTY_TARGET_V1 : DIFFICULTY_TARGET_V2; }
|
||||||
void fill_nonce(cryptonote::block& blk, const cryptonote::difficulty_type& diffic, uint64_t height);
|
|
||||||
|
|
||||||
cryptonote::tx_destination_entry build_dst(const var_addr_t& to, bool is_subaddr=false, uint64_t amount=0);
|
cryptonote::tx_destination_entry build_dst(const var_addr_t& to, bool is_subaddr=false, uint64_t amount=0);
|
||||||
std::vector<cryptonote::tx_destination_entry> build_dsts(const var_addr_t& to1, bool sub1=false, uint64_t am1=0);
|
std::vector<cryptonote::tx_destination_entry> build_dsts(const var_addr_t& to1, bool sub1=false, uint64_t am1=0);
|
||||||
|
@ -490,6 +494,7 @@ void fill_tx_sources_and_destinations(const std::vector<test_event_entry>& event
|
||||||
uint64_t get_balance(const cryptonote::account_base& addr, const std::vector<cryptonote::block>& blockchain, const map_hash2tx_t& mtx);
|
uint64_t get_balance(const cryptonote::account_base& addr, const std::vector<cryptonote::block>& blockchain, const map_hash2tx_t& mtx);
|
||||||
|
|
||||||
bool extract_hard_forks(const std::vector<test_event_entry>& events, v_hardforks_t& hard_forks);
|
bool extract_hard_forks(const std::vector<test_event_entry>& events, v_hardforks_t& hard_forks);
|
||||||
|
bool extract_hard_forks_from_blocks(const std::vector<test_event_entry>& events, v_hardforks_t& hard_forks);
|
||||||
|
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
/* */
|
/* */
|
||||||
|
|
|
@ -10,9 +10,6 @@ using namespace epee;
|
||||||
using namespace crypto;
|
using namespace crypto;
|
||||||
using namespace cryptonote;
|
using namespace cryptonote;
|
||||||
|
|
||||||
// Shared random generator
|
|
||||||
static std::default_random_engine RND(crypto::rand<unsigned>());
|
|
||||||
|
|
||||||
void wallet_accessor_test::set_account(tools::wallet2 * wallet, cryptonote::account_base& account)
|
void wallet_accessor_test::set_account(tools::wallet2 * wallet, cryptonote::account_base& account)
|
||||||
{
|
{
|
||||||
wallet->clear();
|
wallet->clear();
|
||||||
|
|
Loading…
Reference in a new issue