mirror of
https://github.com/monero-project/monero.git
synced 2024-12-29 12:56:12 -05:00
Merge pull request #651
5cb03a1
unit_tests: fix blockchain unit test after hard fork import fix (moneromooo-monero)759383c
hardfork: add a default fork entry for v1 if none exist (moneromooo-monero)c7f82ec
blockchain: initialize m_hardfork to NULL (moneromooo-monero)8649b9f
blockchain_db: pass hard fork object as a simple pointer (moneromooo-monero)a333c42
core_tests: add tests for hard fork behaviors (MRL-0004) (moneromooo-monero)945fe90
core_tests: allow setting miner tx max_outs when creating a block (moneromooo-monero)8e4c2e6
unit_tests: fix hard fork unit test compilation (moneromooo-monero)9ef5794
blockchain_utilities: remove unused num_blocks variable (moneromooo-monero)6c8e5c3
blockchain: reset hardfork object when resetting blockchain (moneromooo-monero)
This commit is contained in:
commit
59c1a3316e
@ -139,7 +139,7 @@ uint64_t BlockchainDB::add_block( const block& blk
|
||||
return prev_height;
|
||||
}
|
||||
|
||||
void BlockchainDB::set_hard_fork(HardFork*& hf)
|
||||
void BlockchainDB::set_hard_fork(HardFork* hf)
|
||||
{
|
||||
m_hardfork = hf;
|
||||
}
|
||||
|
@ -377,7 +377,7 @@ public:
|
||||
virtual void block_txn_stop() = 0;
|
||||
virtual void block_txn_abort() = 0;
|
||||
|
||||
virtual void set_hard_fork(HardFork*& hf);
|
||||
virtual void set_hard_fork(HardFork* hf);
|
||||
|
||||
// adds a block with the given metadata to the top of the blockchain, returns the new height
|
||||
// NOTE: subclass implementations of this (or the functions it calls) need
|
||||
|
@ -66,8 +66,6 @@ bool BlocksdatFile::open_writer(const boost::filesystem::path& file_path, uint64
|
||||
|
||||
m_raw_data_file = new std::ofstream();
|
||||
|
||||
uint64_t num_blocks = 0;
|
||||
|
||||
LOG_PRINT_L0("creating file");
|
||||
|
||||
m_raw_data_file->open(file_path.string(), std::ios_base::binary | std::ios_base::out | std::ios::trunc);
|
||||
|
@ -91,9 +91,4 @@ namespace command_line
|
||||
, "Show time-stats when processing blocks/txs and disk synchronization."
|
||||
, 0
|
||||
};
|
||||
const command_line::arg_descriptor<bool> arg_fakechain = {
|
||||
"fakechain"
|
||||
, "Use a fake chain for testing purposes."
|
||||
, false
|
||||
};
|
||||
}
|
||||
|
@ -215,5 +215,4 @@ namespace command_line
|
||||
extern const arg_descriptor<uint64_t> arg_prep_blocks_threads;
|
||||
extern const arg_descriptor<uint64_t> arg_db_auto_remove_logs;
|
||||
extern const arg_descriptor<uint64_t> arg_show_time_stats;
|
||||
extern const arg_descriptor<bool> arg_fakechain;
|
||||
}
|
||||
|
@ -50,6 +50,7 @@
|
||||
#include "warnings.h"
|
||||
#include "crypto/hash.h"
|
||||
#include "cryptonote_core/checkpoints_create.h"
|
||||
#include "cryptonote_core/cryptonote_core.h"
|
||||
#if defined(PER_BLOCK_CHECKPOINT)
|
||||
#include "blocks/blocks.h"
|
||||
#endif
|
||||
@ -99,7 +100,7 @@ static const uint64_t testnet_hard_fork_version_1_till = 624633;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
Blockchain::Blockchain(tx_memory_pool& tx_pool) :
|
||||
m_db(), m_tx_pool(tx_pool), m_hardfork(), m_timestamps_and_difficulties_height(0), m_current_block_cumul_sz_limit(0), m_is_in_checkpoint_zone(false),
|
||||
m_db(), m_tx_pool(tx_pool), m_hardfork(NULL), m_timestamps_and_difficulties_height(0), m_current_block_cumul_sz_limit(0), m_is_in_checkpoint_zone(false),
|
||||
m_is_blockchain_storing(false), m_enforce_dns_checkpoints(false), m_max_prepare_blocks_threads(4), m_db_blocks_per_sync(1), m_db_sync_mode(db_async), m_fast_sync(true), m_sync_counter(0)
|
||||
{
|
||||
LOG_PRINT_L3("Blockchain::" << __func__);
|
||||
@ -252,11 +253,13 @@ uint64_t Blockchain::get_current_blockchain_height() const
|
||||
//------------------------------------------------------------------
|
||||
//FIXME: possibly move this into the constructor, to avoid accidentally
|
||||
// dereferencing a null BlockchainDB pointer
|
||||
bool Blockchain::init(BlockchainDB* db, const bool testnet, const bool fakechain)
|
||||
bool Blockchain::init(BlockchainDB* db, const bool testnet, const cryptonote::test_options *test_options)
|
||||
{
|
||||
LOG_PRINT_L3("Blockchain::" << __func__);
|
||||
CRITICAL_REGION_LOCAL(m_blockchain_lock);
|
||||
|
||||
bool fakechain = test_options != NULL;
|
||||
|
||||
if (db == nullptr)
|
||||
{
|
||||
LOG_ERROR("Attempted to init Blockchain with null DB");
|
||||
@ -273,12 +276,19 @@ bool Blockchain::init(BlockchainDB* db, const bool testnet, const bool fakechain
|
||||
m_testnet = testnet;
|
||||
if (m_hardfork == nullptr)
|
||||
{
|
||||
if (m_testnet)
|
||||
if (fakechain)
|
||||
m_hardfork = new HardFork(*db, 1, 0);
|
||||
else if (m_testnet)
|
||||
m_hardfork = new HardFork(*db, 1, testnet_hard_fork_version_1_till);
|
||||
else
|
||||
m_hardfork = new HardFork(*db, 1, mainnet_hard_fork_version_1_till);
|
||||
}
|
||||
if (m_testnet)
|
||||
if (fakechain)
|
||||
{
|
||||
for (size_t n = 0; test_options->hard_forks[n].first; ++n)
|
||||
m_hardfork->add_fork(test_options->hard_forks[n].first, test_options->hard_forks[n].second, 0, n + 1);
|
||||
}
|
||||
else if (m_testnet)
|
||||
{
|
||||
for (size_t n = 0; n < sizeof(testnet_hard_forks) / sizeof(testnet_hard_forks[0]); ++n)
|
||||
m_hardfork->add_fork(testnet_hard_forks[n].version, testnet_hard_forks[n].height, testnet_hard_forks[n].threshold, testnet_hard_forks[n].time);
|
||||
@ -348,11 +358,11 @@ bool Blockchain::init(BlockchainDB* db, const bool testnet, const bool fakechain
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------
|
||||
bool Blockchain::init(BlockchainDB* db, HardFork*& hf, const bool testnet, const bool fakechain)
|
||||
bool Blockchain::init(BlockchainDB* db, HardFork*& hf, const bool testnet)
|
||||
{
|
||||
if (hf != nullptr)
|
||||
m_hardfork = hf;
|
||||
bool res = init(db, testnet, fakechain);
|
||||
bool res = init(db, testnet, NULL);
|
||||
if (hf == nullptr)
|
||||
hf = m_hardfork;
|
||||
return res;
|
||||
@ -494,6 +504,7 @@ bool Blockchain::reset_and_set_genesis_block(const block& b)
|
||||
CRITICAL_REGION_LOCAL(m_blockchain_lock);
|
||||
m_alternative_chains.clear();
|
||||
m_db->reset();
|
||||
m_hardfork->init();
|
||||
|
||||
block_verification_context bvc = boost::value_initialized<block_verification_context>();
|
||||
add_new_block(b, bvc);
|
||||
|
@ -58,6 +58,7 @@
|
||||
namespace cryptonote
|
||||
{
|
||||
class tx_memory_pool;
|
||||
struct test_options;
|
||||
|
||||
enum blockchain_db_sync_mode
|
||||
{
|
||||
@ -91,8 +92,8 @@ namespace cryptonote
|
||||
|
||||
Blockchain(tx_memory_pool& tx_pool);
|
||||
|
||||
bool init(BlockchainDB* db, const bool testnet = false, const bool fakechain = false);
|
||||
bool init(BlockchainDB* db, HardFork*& hf, const bool testnet = false, const bool fakechain = false);
|
||||
bool init(BlockchainDB* db, const bool testnet = false, const cryptonote::test_options *test_options = NULL);
|
||||
bool init(BlockchainDB* db, HardFork*& hf, const bool testnet = false);
|
||||
bool deinit();
|
||||
|
||||
void set_checkpoints(checkpoints&& chk_pts) { m_checkpoints = chk_pts; }
|
||||
|
@ -145,13 +145,11 @@ namespace cryptonote
|
||||
command_line::add_arg(desc, command_line::arg_db_sync_mode);
|
||||
command_line::add_arg(desc, command_line::arg_show_time_stats);
|
||||
command_line::add_arg(desc, command_line::arg_db_auto_remove_logs);
|
||||
command_line::add_arg(desc, command_line::arg_fakechain);
|
||||
}
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
bool core::handle_command_line(const boost::program_options::variables_map& vm)
|
||||
{
|
||||
m_testnet = command_line::get_arg(vm, command_line::arg_testnet_on);
|
||||
m_fakechain = command_line::get_arg(vm, command_line::arg_fakechain);
|
||||
|
||||
auto data_dir_arg = m_testnet ? command_line::arg_testnet_data_dir : command_line::arg_data_dir;
|
||||
m_config_folder = command_line::get_arg(vm, data_dir_arg);
|
||||
@ -251,8 +249,9 @@ namespace cryptonote
|
||||
return true;
|
||||
}
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
bool core::init(const boost::program_options::variables_map& vm)
|
||||
bool core::init(const boost::program_options::variables_map& vm, const cryptonote::test_options *test_options)
|
||||
{
|
||||
m_fakechain = test_options != NULL;
|
||||
bool r = handle_command_line(vm);
|
||||
|
||||
r = m_mempool.init(m_fakechain ? std::string() : m_config_folder);
|
||||
@ -398,7 +397,7 @@ namespace cryptonote
|
||||
m_blockchain_storage.set_user_options(blocks_threads,
|
||||
blocks_per_sync, sync_mode, fast_sync);
|
||||
|
||||
r = m_blockchain_storage.init(db, m_testnet, m_fakechain);
|
||||
r = m_blockchain_storage.init(db, m_testnet, test_options);
|
||||
|
||||
// now that we have a valid m_blockchain_storage, we can clean out any
|
||||
// transactions in the pool that do not conform to the current fork
|
||||
|
@ -56,6 +56,10 @@ DISABLE_VS_WARNINGS(4355)
|
||||
|
||||
namespace cryptonote
|
||||
{
|
||||
struct test_options {
|
||||
const std::pair<uint8_t, uint64_t> *hard_forks;
|
||||
};
|
||||
|
||||
/************************************************************************/
|
||||
/* */
|
||||
/************************************************************************/
|
||||
@ -81,7 +85,7 @@ namespace cryptonote
|
||||
miner& get_miner(){return m_miner;}
|
||||
const miner& get_miner()const{return m_miner;}
|
||||
static void init_options(boost::program_options::options_description& desc);
|
||||
bool init(const boost::program_options::variables_map& vm);
|
||||
bool init(const boost::program_options::variables_map& vm, const test_options *test_options = NULL);
|
||||
bool set_genesis_block(const block& b);
|
||||
bool deinit();
|
||||
static void set_fast_exit();
|
||||
|
@ -155,6 +155,11 @@ bool HardFork::add(const cryptonote::block &block, uint64_t height)
|
||||
void HardFork::init()
|
||||
{
|
||||
CRITICAL_REGION_LOCAL(lock);
|
||||
|
||||
// add a placeholder for the default version, to avoid special cases
|
||||
if (heights.empty())
|
||||
heights.push_back(Params(original_version, 0, 0, 0));
|
||||
|
||||
versions.clear();
|
||||
for (size_t n = 0; n < 256; ++n)
|
||||
last_versions[n] = 0;
|
||||
|
@ -38,7 +38,8 @@ set(core_tests_sources
|
||||
integer_overflow.cpp
|
||||
ring_signature_1.cpp
|
||||
transaction_tests.cpp
|
||||
tx_validation.cpp)
|
||||
tx_validation.cpp
|
||||
v2_tests.cpp)
|
||||
|
||||
set(core_tests_headers
|
||||
block_reward.h
|
||||
@ -52,7 +53,8 @@ set(core_tests_headers
|
||||
integer_overflow.h
|
||||
ring_signature_1.h
|
||||
transaction_tests.h
|
||||
tx_validation.h)
|
||||
tx_validation.h
|
||||
v2_tests.h)
|
||||
|
||||
add_executable(coretests
|
||||
${core_tests_sources}
|
||||
|
@ -215,13 +215,14 @@ bool test_generator::construct_block_manually(block& blk, const block& prev_bloc
|
||||
const crypto::hash& prev_id/* = crypto::hash()*/, const difficulty_type& diffic/* = 1*/,
|
||||
const transaction& miner_tx/* = transaction()*/,
|
||||
const std::vector<crypto::hash>& tx_hashes/* = std::vector<crypto::hash>()*/,
|
||||
size_t txs_sizes/* = 0*/)
|
||||
size_t txs_sizes/* = 0*/, size_t max_outs/* = 0*/)
|
||||
{
|
||||
blk.major_version = actual_params & bf_major_ver ? major_ver : CURRENT_BLOCK_MAJOR_VERSION;
|
||||
blk.minor_version = actual_params & bf_minor_ver ? minor_ver : CURRENT_BLOCK_MINOR_VERSION;
|
||||
blk.timestamp = actual_params & bf_timestamp ? timestamp : prev_block.timestamp + DIFFICULTY_BLOCKS_ESTIMATE_TIMESPAN; // Keep difficulty unchanged
|
||||
blk.prev_id = actual_params & bf_prev_id ? prev_id : get_block_hash(prev_block);
|
||||
blk.tx_hashes = actual_params & bf_tx_hashes ? tx_hashes : std::vector<crypto::hash>();
|
||||
max_outs = actual_params & bf_max_outs ? max_outs : 1;
|
||||
|
||||
size_t height = get_block_height(prev_block) + 1;
|
||||
uint64_t already_generated_coins = get_already_generated_coins(prev_block);
|
||||
@ -235,7 +236,7 @@ bool test_generator::construct_block_manually(block& blk, const block& prev_bloc
|
||||
{
|
||||
size_t current_block_size = txs_sizes + get_object_blobsize(blk.miner_tx);
|
||||
// TODO: This will work, until size of constructed block is less then CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE
|
||||
if (!construct_miner_tx(height, misc_utils::median(block_sizes), already_generated_coins, current_block_size, 0, miner_acc.get_keys().m_account_address, blk.miner_tx, blobdata(), 1))
|
||||
if (!construct_miner_tx(height, misc_utils::median(block_sizes), already_generated_coins, current_block_size, 0, miner_acc.get_keys().m_account_address, blk.miner_tx, blobdata(), max_outs))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -220,7 +220,8 @@ public:
|
||||
bf_prev_id = 1 << 3,
|
||||
bf_miner_tx = 1 << 4,
|
||||
bf_tx_hashes = 1 << 5,
|
||||
bf_diffic = 1 << 6
|
||||
bf_diffic = 1 << 6,
|
||||
bf_max_outs = 1 << 7
|
||||
};
|
||||
|
||||
void get_block_chain(std::vector<block_info>& blockchain, const crypto::hash& head, size_t n) const;
|
||||
@ -240,7 +241,7 @@ public:
|
||||
const cryptonote::account_base& miner_acc, int actual_params = bf_none, uint8_t major_ver = 0,
|
||||
uint8_t minor_ver = 0, uint64_t timestamp = 0, const crypto::hash& prev_id = crypto::hash(),
|
||||
const cryptonote::difficulty_type& diffic = 1, const cryptonote::transaction& miner_tx = cryptonote::transaction(),
|
||||
const std::vector<crypto::hash>& tx_hashes = std::vector<crypto::hash>(), size_t txs_sizes = 0);
|
||||
const std::vector<crypto::hash>& tx_hashes = std::vector<crypto::hash>(), size_t txs_sizes = 0, size_t max_outs = 0);
|
||||
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);
|
||||
|
||||
@ -470,6 +471,14 @@ inline bool replay_events_through_core(cryptonote::core& cr, const std::vector<t
|
||||
}
|
||||
//--------------------------------------------------------------------------
|
||||
template<class t_test_class>
|
||||
struct get_test_options {
|
||||
const std::pair<uint8_t, uint64_t> hard_forks[1] = {std::make_pair(1, 0)};
|
||||
const cryptonote::test_options test_options = {
|
||||
hard_forks
|
||||
};
|
||||
};
|
||||
//--------------------------------------------------------------------------
|
||||
template<class t_test_class>
|
||||
inline bool do_replay_events(std::vector<test_event_entry>& events)
|
||||
{
|
||||
boost::program_options::options_description desc("Allowed options");
|
||||
@ -484,15 +493,12 @@ inline bool do_replay_events(std::vector<test_event_entry>& events)
|
||||
if (!r)
|
||||
return false;
|
||||
|
||||
// hardcode a --fakechain option for tests
|
||||
static const char * const fakechain[] = {"", "--fakechain"};
|
||||
boost::program_options::store(boost::program_options::parse_command_line(2, fakechain, desc), vm);
|
||||
|
||||
cryptonote::cryptonote_protocol_stub pr; //TODO: stub only for this kind of test, make real validation of relayed objects
|
||||
cryptonote::core c(&pr);
|
||||
// FIXME: make sure that vm has arg_testnet_on set to true or false if
|
||||
// this test needs for it to be so.
|
||||
if (!c.init(vm))
|
||||
const get_test_options<t_test_class> gto;
|
||||
if (!c.init(vm, >o.test_options))
|
||||
{
|
||||
std::cout << concolor::magenta << "Failed to init core" << concolor::normal << std::endl;
|
||||
return false;
|
||||
|
@ -168,6 +168,13 @@ int main(int argc, char* argv[])
|
||||
|
||||
GENERATE_AND_PLAY(gen_block_reward);
|
||||
|
||||
GENERATE_AND_PLAY(gen_v2_tx_mixable_0_mixin);
|
||||
GENERATE_AND_PLAY(gen_v2_tx_mixable_low_mixin);
|
||||
GENERATE_AND_PLAY(gen_v2_tx_unmixable_only);
|
||||
GENERATE_AND_PLAY(gen_v2_tx_unmixable_one);
|
||||
GENERATE_AND_PLAY(gen_v2_tx_unmixable_two);
|
||||
GENERATE_AND_PLAY(gen_v2_tx_dust);
|
||||
|
||||
std::cout << (failed_tests.empty() ? concolor::green : concolor::magenta);
|
||||
std::cout << "\nREPORT:\n";
|
||||
std::cout << " Test run: " << tests_count << '\n';
|
||||
|
@ -39,6 +39,7 @@
|
||||
#include "integer_overflow.h"
|
||||
#include "ring_signature_1.h"
|
||||
#include "tx_validation.h"
|
||||
#include "v2_tests.h"
|
||||
/************************************************************************/
|
||||
/* */
|
||||
/************************************************************************/
|
||||
|
@ -155,7 +155,7 @@ template <typename T>
|
||||
class BlockchainDBTest : public testing::Test
|
||||
{
|
||||
protected:
|
||||
BlockchainDBTest() : m_db(new T())
|
||||
BlockchainDBTest() : m_db(new T()), m_hardfork(*m_db, 1, 0)
|
||||
{
|
||||
for (auto& i : t_blocks)
|
||||
{
|
||||
@ -184,11 +184,18 @@ protected:
|
||||
}
|
||||
|
||||
BlockchainDB* m_db;
|
||||
HardFork m_hardfork;
|
||||
std::string m_prefix;
|
||||
std::vector<block> m_blocks;
|
||||
std::vector<std::vector<transaction> > m_txs;
|
||||
std::vector<std::string> m_filenames;
|
||||
|
||||
void init_hard_fork()
|
||||
{
|
||||
m_hardfork.init();
|
||||
m_db->set_hard_fork(&m_hardfork);
|
||||
}
|
||||
|
||||
void get_filenames()
|
||||
{
|
||||
m_filenames = m_db->get_filenames();
|
||||
@ -257,6 +264,7 @@ TYPED_TEST(BlockchainDBTest, AddBlock)
|
||||
// make sure open does not throw
|
||||
ASSERT_NO_THROW(this->m_db->open(fname));
|
||||
this->get_filenames();
|
||||
this->init_hard_fork();
|
||||
|
||||
// adding a block with no parent in the blockchain should throw.
|
||||
// note: this shouldn't be possible, but is a good (and cheap) failsafe.
|
||||
@ -300,6 +308,7 @@ TYPED_TEST(BlockchainDBTest, RetrieveBlockData)
|
||||
// make sure open does not throw
|
||||
ASSERT_NO_THROW(this->m_db->open(fname));
|
||||
this->get_filenames();
|
||||
this->init_hard_fork();
|
||||
|
||||
ASSERT_NO_THROW(this->m_db->add_block(this->m_blocks[0], t_sizes[0], t_diffs[0], t_coins[0], this->m_txs[0]));
|
||||
|
||||
|
@ -57,6 +57,10 @@ public:
|
||||
virtual void batch_start(uint64_t batch_num_blocks=0) {}
|
||||
virtual void batch_stop() {}
|
||||
virtual void set_batch_transactions(bool) {}
|
||||
virtual void block_txn_start() {}
|
||||
virtual void block_txn_stop() {}
|
||||
virtual void block_txn_abort() {}
|
||||
virtual void drop_hard_fork_info() {}
|
||||
virtual bool block_exists(const crypto::hash& h) const { return false; }
|
||||
virtual block get_block(const crypto::hash& h) const { return block(); }
|
||||
virtual uint64_t get_block_height(const crypto::hash& h) const { return 0; }
|
||||
|
Loading…
Reference in New Issue
Block a user