This commit is contained in:
stoffu 2018-02-16 20:04:04 +09:00
parent cc9a0bee04
commit af773211cb
No known key found for this signature in database
GPG key ID: 41DAB8343A9EC012
58 changed files with 566 additions and 357 deletions

View file

@ -132,6 +132,16 @@ static const struct {
};
static const uint64_t testnet_hard_fork_version_1_till = 624633;
static const struct {
uint8_t version;
uint64_t height;
uint8_t threshold;
time_t time;
} stagenet_hard_forks[] = {
// version 1 from the start of the blockchain
{ 1, 1, 0, 1341378000 },
};
//------------------------------------------------------------------
Blockchain::Blockchain(tx_memory_pool& tx_pool) :
m_db(), m_tx_pool(tx_pool), m_hardfork(NULL), m_timestamps_and_difficulties_height(0), m_current_block_cumul_sz_limit(0), m_current_block_cumul_sz_median(0),
@ -306,14 +316,12 @@ 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, bool offline, const cryptonote::test_options *test_options)
bool Blockchain::init(BlockchainDB* db, const network_type nettype, bool offline, const cryptonote::test_options *test_options)
{
LOG_PRINT_L3("Blockchain::" << __func__);
CRITICAL_REGION_LOCAL(m_tx_pool);
CRITICAL_REGION_LOCAL1(m_blockchain_lock);
bool fakechain = test_options != NULL;
if (db == nullptr)
{
LOG_ERROR("Attempted to init Blockchain with null DB");
@ -328,27 +336,32 @@ bool Blockchain::init(BlockchainDB* db, const bool testnet, bool offline, const
m_db = db;
m_testnet = testnet;
m_nettype = test_options != NULL ? FAKECHAIN : nettype;
m_offline = offline;
if (m_hardfork == nullptr)
{
if (fakechain)
if (m_nettype == FAKECHAIN || m_nettype == STAGENET)
m_hardfork = new HardFork(*db, 1, 0);
else if (m_testnet)
else if (m_nettype == 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 (fakechain)
if (m_nettype == 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)
else if (m_nettype == 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);
}
else if (m_nettype == STAGENET)
{
for (size_t n = 0; n < sizeof(stagenet_hard_forks) / sizeof(stagenet_hard_forks[0]); ++n)
m_hardfork->add_fork(stagenet_hard_forks[n].version, stagenet_hard_forks[n].height, stagenet_hard_forks[n].threshold, stagenet_hard_forks[n].time);
}
else
{
for (size_t n = 0; n < sizeof(mainnet_hard_forks) / sizeof(mainnet_hard_forks[0]); ++n)
@ -367,10 +380,14 @@ bool Blockchain::init(BlockchainDB* db, const bool testnet, bool offline, const
MINFO("Blockchain not loaded, generating genesis block.");
block bl = boost::value_initialized<block>();
block_verification_context bvc = boost::value_initialized<block_verification_context>();
if (m_testnet)
if (m_nettype == TESTNET)
{
generate_genesis_block(bl, config::testnet::GENESIS_TX, config::testnet::GENESIS_NONCE);
}
else if (m_nettype == STAGENET)
{
generate_genesis_block(bl, config::stagenet::GENESIS_TX, config::stagenet::GENESIS_NONCE);
}
else
{
generate_genesis_block(bl, config::GENESIS_TX, config::GENESIS_NONCE);
@ -384,7 +401,7 @@ bool Blockchain::init(BlockchainDB* db, const bool testnet, bool offline, const
{
}
if (!fakechain)
if (m_nettype != FAKECHAIN)
{
// ensure we fixup anything we found and fix in the future
m_db->fixup();
@ -406,7 +423,7 @@ bool Blockchain::init(BlockchainDB* db, const bool testnet, bool offline, const
m_async_pool.create_thread(boost::bind(&boost::asio::io_service::run, &m_async_service));
#if defined(PER_BLOCK_CHECKPOINT)
if (!fakechain)
if (m_nettype != FAKECHAIN)
load_compiled_in_block_hashes();
#endif
@ -417,11 +434,11 @@ bool Blockchain::init(BlockchainDB* db, const bool testnet, bool offline, const
return true;
}
//------------------------------------------------------------------
bool Blockchain::init(BlockchainDB* db, HardFork*& hf, const bool testnet, bool offline)
bool Blockchain::init(BlockchainDB* db, HardFork*& hf, const network_type nettype, bool offline)
{
if (hf != nullptr)
m_hardfork = hf;
bool res = init(db, testnet, offline, NULL);
bool res = init(db, nettype, offline, NULL);
if (hf == nullptr)
hf = m_hardfork;
return res;
@ -4316,15 +4333,17 @@ void Blockchain::cancel()
static const char expected_block_hashes_hash[] = "4b553162ee4e7af3c53666506591489c68560b9175e6e941dc96c89f96f0e35c";
void Blockchain::load_compiled_in_block_hashes()
{
if (m_fast_sync && get_blocks_dat_start(m_testnet) != nullptr && get_blocks_dat_size(m_testnet) > 0)
const bool testnet = m_nettype == TESTNET;
const bool stagenet = m_nettype == STAGENET;
if (m_fast_sync && get_blocks_dat_start(testnet, stagenet) != nullptr && get_blocks_dat_size(testnet, stagenet) > 0)
{
MINFO("Loading precomputed blocks (" << get_blocks_dat_size(m_testnet) << " bytes)");
MINFO("Loading precomputed blocks (" << get_blocks_dat_size(testnet, stagenet) << " bytes)");
if (!m_testnet)
if (m_nettype == MAINNET)
{
// first check hash
crypto::hash hash;
if (!tools::sha256sum(get_blocks_dat_start(m_testnet), get_blocks_dat_size(m_testnet), hash))
if (!tools::sha256sum(get_blocks_dat_start(testnet, stagenet), get_blocks_dat_size(testnet, stagenet), hash))
{
MERROR("Failed to hash precomputed blocks data");
return;
@ -4344,9 +4363,9 @@ void Blockchain::load_compiled_in_block_hashes()
}
}
if (get_blocks_dat_size(m_testnet) > 4)
if (get_blocks_dat_size(testnet, stagenet) > 4)
{
const unsigned char *p = get_blocks_dat_start(m_testnet);
const unsigned char *p = get_blocks_dat_start(testnet, stagenet);
const uint32_t nblocks = *p | ((*(p+1))<<8) | ((*(p+2))<<16) | ((*(p+3))<<24);
if (nblocks > (std::numeric_limits<uint32_t>::max() - 4) / sizeof(hash))
{
@ -4354,7 +4373,7 @@ void Blockchain::load_compiled_in_block_hashes()
return;
}
const size_t size_needed = 4 + nblocks * sizeof(crypto::hash);
if(nblocks > 0 && nblocks > (m_db->height() + HASH_OF_HASHES_STEP - 1) / HASH_OF_HASHES_STEP && get_blocks_dat_size(m_testnet) >= size_needed)
if(nblocks > 0 && nblocks > (m_db->height() + HASH_OF_HASHES_STEP - 1) / HASH_OF_HASHES_STEP && get_blocks_dat_size(testnet, stagenet) >= size_needed)
{
p += sizeof(uint32_t);
m_blocks_hash_of_hashes.reserve(nblocks);

View file

@ -111,25 +111,25 @@ namespace cryptonote
* @brief Initialize the Blockchain state
*
* @param db a pointer to the backing store to use for the blockchain
* @param testnet true if on testnet, else false
* @param nettype network type
* @param offline true if running offline, else false
* @param test_options test parameters
*
* @return true on success, false if any initialization steps fail
*/
bool init(BlockchainDB* db, const bool testnet = false, bool offline = false, const cryptonote::test_options *test_options = NULL);
bool init(BlockchainDB* db, const network_type nettype = MAINNET, bool offline = false, const cryptonote::test_options *test_options = NULL);
/**
* @brief Initialize the Blockchain state
*
* @param db a pointer to the backing store to use for the blockchain
* @param hf a structure containing hardfork information
* @param testnet true if on testnet, else false
* @param nettype network type
* @param offline true if running offline, else false
*
* @return true on success, false if any initialization steps fail
*/
bool init(BlockchainDB* db, HardFork*& hf, const bool testnet = false, bool offline = false);
bool init(BlockchainDB* db, HardFork*& hf, const network_type nettype = MAINNET, bool offline = false);
/**
* @brief Uninitializes the blockchain state
@ -1010,7 +1010,7 @@ namespace cryptonote
HardFork *m_hardfork;
bool m_testnet;
network_type m_nettype;
bool m_offline;
std::atomic<bool> m_cancel;

View file

@ -71,14 +71,21 @@ namespace cryptonote
, "Run on testnet. The wallet must be launched with --testnet flag."
, false
};
const command_line::arg_descriptor<std::string, false, true> arg_data_dir = {
const command_line::arg_descriptor<bool, false> arg_stagenet_on = {
"stagenet"
, "Run on stagenet. The wallet must be launched with --stagenet flag."
, false
};
const command_line::arg_descriptor<std::string, false, true, 2> arg_data_dir = {
"data-dir"
, "Specify data directory"
, tools::get_default_data_dir()
, arg_testnet_on
, [](bool testnet, bool defaulted, std::string val) {
if (testnet)
, {{ &arg_testnet_on, &arg_stagenet_on }}
, [](std::array<bool, 2> testnet_stagenet, bool defaulted, std::string val) {
if (testnet_stagenet[0])
return (boost::filesystem::path(val) / "testnet").string();
else if (testnet_stagenet[1])
return (boost::filesystem::path(val) / "stagenet").string();
return val;
}
};
@ -194,7 +201,7 @@ namespace cryptonote
//-----------------------------------------------------------------------------------------------
bool core::update_checkpoints()
{
if (m_testnet || m_fakechain || m_disable_dns_checkpoints) return true;
if (m_nettype != MAINNET || m_disable_dns_checkpoints) return true;
if (m_checkpoints_updating.test_and_set()) return true;
@ -243,6 +250,7 @@ namespace cryptonote
command_line::add_arg(desc, arg_test_drop_download_height);
command_line::add_arg(desc, arg_testnet_on);
command_line::add_arg(desc, arg_stagenet_on);
command_line::add_arg(desc, arg_dns_checkpoints);
command_line::add_arg(desc, arg_prep_blocks_threads);
command_line::add_arg(desc, arg_fast_block_sync);
@ -262,16 +270,21 @@ namespace cryptonote
//-----------------------------------------------------------------------------------------------
bool core::handle_command_line(const boost::program_options::variables_map& vm)
{
m_testnet = command_line::get_arg(vm, arg_testnet_on);
if (m_nettype != FAKECHAIN)
{
const bool testnet = command_line::get_arg(vm, arg_testnet_on);
const bool stagenet = command_line::get_arg(vm, arg_stagenet_on);
m_nettype = testnet ? TESTNET : stagenet ? STAGENET : MAINNET;
}
m_config_folder = command_line::get_arg(vm, arg_data_dir);
auto data_dir = boost::filesystem::path(m_config_folder);
if (!m_testnet && !m_fakechain)
if (m_nettype == MAINNET)
{
cryptonote::checkpoints checkpoints;
if (!checkpoints.init_default_checkpoints(m_testnet))
if (!checkpoints.init_default_checkpoints(m_nettype))
{
throw std::runtime_error("Failed to initialize checkpoints");
}
@ -360,9 +373,11 @@ namespace cryptonote
{
start_time = std::time(nullptr);
m_fakechain = test_options != NULL;
if (test_options != NULL)
{
m_nettype = FAKECHAIN;
}
bool r = handle_command_line(vm);
bool testnet = command_line::get_arg(vm, arg_testnet_on);
std::string m_config_folder_mempool = m_config_folder;
if (config_subdir)
@ -377,7 +392,7 @@ namespace cryptonote
size_t max_txpool_size = command_line::get_arg(vm, arg_max_txpool_size);
boost::filesystem::path folder(m_config_folder);
if (m_fakechain)
if (m_nettype == FAKECHAIN)
folder /= "fake";
// make sure the data directory exists, and try to lock it
@ -491,7 +506,7 @@ namespace cryptonote
m_blockchain_storage.set_user_options(blocks_threads,
blocks_per_sync, sync_mode, fast_sync);
r = m_blockchain_storage.init(db.release(), m_testnet, m_offline, test_options);
r = m_blockchain_storage.init(db.release(), m_nettype, m_offline, test_options);
r = m_mempool.init(max_txpool_size);
CHECK_AND_ASSERT_MES(r, false, "Failed to initialize memory pool");
@ -526,7 +541,7 @@ namespace cryptonote
return false;
}
r = m_miner.init(vm, m_testnet);
r = m_miner.init(vm, m_nettype);
CHECK_AND_ASSERT_MES(r, false, "Failed to initialize miner instance");
return load_state_data();
@ -909,7 +924,7 @@ namespace cryptonote
//-----------------------------------------------------------------------------------------------
size_t core::get_block_sync_size(uint64_t height) const
{
static const uint64_t quick_height = m_testnet ? 801219 : 1220516;
static const uint64_t quick_height = m_nettype == TESTNET ? 801219 : m_nettype == MAINNET ? 1220516 : 0;
if (block_sync_size > 0)
return block_sync_size;
if (height >= quick_height)

View file

@ -58,8 +58,9 @@ namespace cryptonote
const std::pair<uint8_t, uint64_t> *hard_forks;
};
extern const command_line::arg_descriptor<std::string, false, true> arg_data_dir;
extern const command_line::arg_descriptor<std::string, false, true, 2> arg_data_dir;
extern const command_line::arg_descriptor<bool, false> arg_testnet_on;
extern const command_line::arg_descriptor<bool, false> arg_stagenet_on;
extern const command_line::arg_descriptor<bool> arg_offline;
/************************************************************************/
@ -725,11 +726,11 @@ namespace cryptonote
std::pair<uint64_t, uint64_t> get_coinbase_tx_sum(const uint64_t start_offset, const size_t count);
/**
* @brief get whether we're on testnet or not
* @brief get the network type we're on
*
* @return are we on testnet?
* @return which network are we on?
*/
bool get_testnet() const { return m_testnet; };
network_type get_nettype() const { return m_nettype; };
/**
* @brief get whether fluffy blocks are enabled
@ -954,9 +955,7 @@ namespace cryptonote
uint64_t m_target_blockchain_height; //!< blockchain height target
bool m_testnet; //!< are we on testnet?
bool m_fakechain; //!< are we using a fake chain (for testing purposes)?
network_type m_nettype; //!< which network are we on?
std::string m_checkpoints_path; //!< path to json checkpoints file
time_t m_last_dns_checkpoints_update; //!< time when dns checkpoints were last updated