mirror of
https://codeberg.org/anoncontributorxmr/monero.git
synced 2024-11-23 10:37:37 -07:00
Merge pull request #139
72a80f6
fixed incorrect version reference (Riccardo Spagni)95a2701
Change testnet prefix (Zachary Michaels)120c84d
Make P2P use the testnet data dir (Zachary Michaels)2352565
Replace macro with equivalent function call (Zachary Michaels)d033087
Separate testnet address prefix (Zachary Michaels)ee1bacc
Add testnet seed nodes (Zachary Michaels)4a6eb0a
Create testnet data dir if necessary (Zachary Michaels)018e251
Separate testnet default data dir (Zachary Michaels)3ef7f33
Add descriptions for RPC command line params (Zachary Michaels)1e38a02
Add testnet genesis tx as output by CN reference (Zachary Michaels)96eed84
Pass tx and nonce to genesis block constructor (Zachary Michaels)257077a
Separate network id for testnet (Zachary Michaels)658b669
Separate rpc port for testnet (Zachary Michaels)98ed9a4
Separate p2p port for testnet (Zachary Michaels)fb4146f
Reorganize testnet constants (Zachary Michaels)79862ad
Add testnet constants (Zachary Michaels)07470fd
Add testnet flag (Zachary Michaels)32004a7
increase ABSTRACT_SERVER_SEND_QUE_MAX_COUNT to a more sane value (Riccardo Spagni)2c0a87f
additional README info on static builds and FreeBSD (Riccardo Spagni)
This commit is contained in:
commit
83276bf92d
@ -47,4 +47,5 @@ namespace command_line
|
||||
const arg_descriptor<bool> arg_help = {"help", "Produce help message"};
|
||||
const arg_descriptor<bool> arg_version = {"version", "Output version information"};
|
||||
const arg_descriptor<std::string> arg_data_dir = {"data-dir", "Specify data directory"};
|
||||
const arg_descriptor<std::string> arg_testnet_data_dir = {"testnet-data-dir", "Specify testnet data directory"};
|
||||
}
|
||||
|
@ -203,4 +203,5 @@ namespace command_line
|
||||
extern const arg_descriptor<bool> arg_help;
|
||||
extern const arg_descriptor<bool> arg_version;
|
||||
extern const arg_descriptor<std::string> arg_data_dir;
|
||||
extern const arg_descriptor<std::string> arg_testnet_data_dir;
|
||||
}
|
||||
|
@ -259,7 +259,7 @@ bool handle_request_stat(po::variables_map& vm, peerid_type peer_id)
|
||||
pot.peer_id = peer_id;
|
||||
pot.time = time(NULL);
|
||||
crypto::public_key pubk = AUTO_VAL_INIT(pubk);
|
||||
string_tools::hex_to_pod(P2P_STAT_TRUSTED_PUB_KEY, pubk);
|
||||
string_tools::hex_to_pod(::config::P2P_REMOTE_DEBUG_TRUSTED_PUB_KEY, pubk);
|
||||
crypto::hash h = tools::get_proof_of_trust_hash(pot);
|
||||
crypto::generate_signature(h, pubk, prvk, pot.sign);
|
||||
|
||||
|
@ -30,12 +30,14 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <boost/uuid/uuid.hpp>
|
||||
|
||||
#define CRYPTONOTE_MAX_BLOCK_NUMBER 500000000
|
||||
#define CRYPTONOTE_MAX_BLOCK_SIZE 500000000 // block header blob limit, never used!
|
||||
#define CRYPTONOTE_GETBLOCKTEMPLATE_MAX_BLOCK_SIZE 196608 //size of block (bytes) that is the maximum that miners will produce
|
||||
#define CRYPTONOTE_MAX_TX_SIZE 1000000000
|
||||
#define CRYPTONOTE_PUBLIC_ADDRESS_TEXTBLOB_VER 0
|
||||
#define CRYPTONOTE_PUBLIC_ADDRESS_BASE58_PREFIX 18 // addresses start with "4"
|
||||
#define CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW 60
|
||||
#define CURRENT_TRANSACTION_VERSION 1
|
||||
#define CURRENT_BLOCK_MAJOR_VERSION 1
|
||||
@ -81,8 +83,6 @@
|
||||
#define CRYPTONOTE_MEMPOOL_TX_LIVETIME 86400 //seconds, one day
|
||||
#define CRYPTONOTE_MEMPOOL_TX_FROM_ALT_BLOCK_LIVETIME 604800 //seconds, one week
|
||||
|
||||
#define P2P_DEFAULT_PORT 18080
|
||||
#define RPC_DEFAULT_PORT 18081
|
||||
#define COMMAND_RPC_GET_BLOCKS_FAST_MAX_COUNT 1000
|
||||
|
||||
#define P2P_LOCAL_WHITE_PEERLIST_LIMIT 1000
|
||||
@ -96,7 +96,6 @@
|
||||
#define P2P_DEFAULT_PING_CONNECTION_TIMEOUT 2000 //2 seconds
|
||||
#define P2P_DEFAULT_INVOKE_TIMEOUT 60*2*1000 //2 minutes
|
||||
#define P2P_DEFAULT_HANDSHAKE_INVOKE_TIMEOUT 5000 //5 seconds
|
||||
#define P2P_STAT_TRUSTED_PUB_KEY "0000000000000000000000000000000000000000000000000000000000000000"
|
||||
#define P2P_DEFAULT_WHITELIST_CONNECTIONS_PERCENT 70
|
||||
|
||||
#define ALLOW_DEBUG_COMMANDS
|
||||
@ -110,3 +109,32 @@
|
||||
|
||||
#define THREAD_STACK_SIZE 5 * 1024 * 1024
|
||||
|
||||
// New constants are intended to go here
|
||||
namespace config
|
||||
{
|
||||
uint64_t const DEFAULT_FEE_ATOMIC_XMR_PER_KB = 500; // Just a placeholder! Change me!
|
||||
uint8_t const FEE_CALCULATION_MAX_RETRIES = 10;
|
||||
uint64_t const DEFAULT_DUST_THRESHOLD = 5000000000; // 5 * 10^9
|
||||
std::string const P2P_REMOTE_DEBUG_TRUSTED_PUB_KEY = "0000000000000000000000000000000000000000000000000000000000000000";
|
||||
|
||||
uint64_t const CRYPTONOTE_PUBLIC_ADDRESS_BASE58_PREFIX = 18;
|
||||
uint16_t const P2P_DEFAULT_PORT = 18080;
|
||||
uint16_t const RPC_DEFAULT_PORT = 18081;
|
||||
boost::uuids::uuid const NETWORK_ID = { {
|
||||
0x12 ,0x30, 0xF1, 0x71 , 0x61, 0x04 , 0x41, 0x61, 0x17, 0x31, 0x00, 0x82, 0x16, 0xA1, 0xA1, 0x10
|
||||
} }; // Bender's nightmare
|
||||
std::string const GENESIS_TX = "013c01ff0001ffffffffffff03029b2e4c0281c0b02e7c53291a94d1d0cbff8883f8024f5142ee494ffbbd08807121017767aafcde9be00dcfd098715ebcf7f410daebc582fda69d24a28e9d0bc890d1";
|
||||
uint32_t const GENESIS_NONCE = 10000;
|
||||
|
||||
namespace testnet
|
||||
{
|
||||
uint64_t const CRYPTONOTE_PUBLIC_ADDRESS_BASE58_PREFIX = 53;
|
||||
uint16_t const P2P_DEFAULT_PORT = 28080;
|
||||
uint16_t const RPC_DEFAULT_PORT = 28081;
|
||||
boost::uuids::uuid const NETWORK_ID = { {
|
||||
0x12 ,0x30, 0xF1, 0x71 , 0x61, 0x04 , 0x41, 0x61, 0x17, 0x31, 0x00, 0x82, 0x16, 0xA1, 0xA1, 0x11
|
||||
} }; // Bender's daydream
|
||||
std::string const GENESIS_TX = "013c01ff0001ffffffffffff0f029b2e4c0281c0b02e7c53291a94d1d0cbff8883f8024f5142ee494ffbbd0880712101168d0c4ca86fb55a4cf6a36d31431be1c53a3bd7411bb24e8832410289fa6f3b";
|
||||
uint32_t const GENESIS_NONCE = 10001;
|
||||
}
|
||||
}
|
||||
|
@ -93,10 +93,10 @@ DISABLE_VS_WARNINGS(4244 4345)
|
||||
return m_keys;
|
||||
}
|
||||
//-----------------------------------------------------------------
|
||||
std::string account_base::get_public_address_str()
|
||||
std::string account_base::get_public_address_str(bool testnet)
|
||||
{
|
||||
//TODO: change this code into base 58
|
||||
return get_account_address_as_str(m_keys.m_account_address);
|
||||
return get_account_address_as_str(testnet, m_keys.m_account_address);
|
||||
}
|
||||
//-----------------------------------------------------------------
|
||||
}
|
||||
|
@ -59,7 +59,7 @@ namespace cryptonote
|
||||
account_base();
|
||||
crypto::secret_key generate(const crypto::secret_key& recovery_key = crypto::secret_key(), bool recover = false, bool two_random = false);
|
||||
const account_keys& get_keys() const;
|
||||
std::string get_public_address_str();
|
||||
std::string get_public_address_str(bool testnet);
|
||||
|
||||
uint64_t get_createtime() const { return m_creation_timestamp; }
|
||||
void set_createtime(uint64_t val) { m_creation_timestamp = val; }
|
||||
|
@ -82,7 +82,7 @@ uint64_t blockchain_storage::get_current_blockchain_height()
|
||||
return m_blocks.size();
|
||||
}
|
||||
//------------------------------------------------------------------
|
||||
bool blockchain_storage::init(const std::string& config_folder)
|
||||
bool blockchain_storage::init(const std::string& config_folder, bool testnet)
|
||||
{
|
||||
CRITICAL_REGION_LOCAL(m_blockchain_lock);
|
||||
m_config_folder = config_folder;
|
||||
@ -114,18 +114,42 @@ bool blockchain_storage::init(const std::string& config_folder)
|
||||
LOG_PRINT_L0("Can't load blockchain storage from file, generating genesis block.");
|
||||
block bl = boost::value_initialized<block>();
|
||||
block_verification_context bvc = boost::value_initialized<block_verification_context>();
|
||||
generate_genesis_block(bl);
|
||||
if (testnet)
|
||||
{
|
||||
generate_genesis_block(bl, config::testnet::GENESIS_TX, config::testnet::GENESIS_NONCE);
|
||||
}
|
||||
else
|
||||
{
|
||||
generate_genesis_block(bl, config::GENESIS_TX, config::GENESIS_NONCE);
|
||||
}
|
||||
add_new_block(bl, bvc);
|
||||
CHECK_AND_ASSERT_MES(!bvc.m_verifivation_failed && bvc.m_added_to_main_chain, false, "Failed to add genesis block to blockchain");
|
||||
}
|
||||
if(!m_blocks.size())
|
||||
{
|
||||
LOG_PRINT_L0("Blockchain not loaded, generating genesis block.");
|
||||
block bl = boost::value_initialized<block>();
|
||||
block_verification_context bvc = boost::value_initialized<block_verification_context>();
|
||||
generate_genesis_block(bl);
|
||||
add_new_block(bl, bvc);
|
||||
CHECK_AND_ASSERT_MES(!bvc.m_verifivation_failed, false, "Failed to add genesis block to blockchain");
|
||||
|
||||
if (!store_genesis_block(testnet)) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
cryptonote::block b;
|
||||
|
||||
if (testnet)
|
||||
{
|
||||
generate_genesis_block(b, config::testnet::GENESIS_TX, config::testnet::GENESIS_NONCE);
|
||||
}
|
||||
else
|
||||
{
|
||||
generate_genesis_block(b, config::GENESIS_TX, config::GENESIS_NONCE);
|
||||
}
|
||||
|
||||
crypto::hash genesis_hash = get_block_hash(m_blocks[0].bl);
|
||||
crypto::hash testnet_genesis_hash = get_block_hash(b);
|
||||
if (genesis_hash != testnet_genesis_hash) {
|
||||
LOG_ERROR("Failed to init: genesis block mismatch. Probably you set --testnet flag with data dir with non-test blockchain or another network.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
uint64_t timestamp_diff = time(NULL) - m_blocks.back().bl.timestamp;
|
||||
if(!m_blocks.back().bl.timestamp)
|
||||
@ -134,6 +158,24 @@ bool blockchain_storage::init(const std::string& config_folder)
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------
|
||||
bool blockchain_storage::store_genesis_block(bool testnet) {
|
||||
block bl = ::boost::value_initialized<block>();
|
||||
block_verification_context bvc = boost::value_initialized<block_verification_context>();
|
||||
|
||||
if (testnet)
|
||||
{
|
||||
generate_genesis_block(bl, config::testnet::GENESIS_TX, config::testnet::GENESIS_NONCE);
|
||||
}
|
||||
else
|
||||
{
|
||||
generate_genesis_block(bl, config::GENESIS_TX, config::GENESIS_NONCE);
|
||||
}
|
||||
|
||||
add_new_block(bl, bvc);
|
||||
CHECK_AND_ASSERT_MES(!bvc.m_verifivation_failed, false, "Failed to add genesis block to blockchain");
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------
|
||||
bool blockchain_storage::store_blockchain()
|
||||
{
|
||||
m_is_blockchain_storing = true;
|
||||
|
@ -81,8 +81,8 @@ namespace cryptonote
|
||||
blockchain_storage(tx_memory_pool& tx_pool):m_tx_pool(tx_pool), m_current_block_cumul_sz_limit(0), m_is_in_checkpoint_zone(false), m_is_blockchain_storing(false)
|
||||
{};
|
||||
|
||||
bool init() { return init(tools::get_default_data_dir()); }
|
||||
bool init(const std::string& config_folder);
|
||||
bool init() { return init(tools::get_default_data_dir(), true); }
|
||||
bool init(const std::string& config_folder, bool testnet = false);
|
||||
bool deinit();
|
||||
|
||||
void set_checkpoints(checkpoints&& chk_pts) { m_checkpoints = chk_pts; }
|
||||
@ -242,6 +242,7 @@ namespace cryptonote
|
||||
uint64_t get_adjusted_time();
|
||||
bool complete_timestamps_vector(uint64_t start_height, std::vector<uint64_t>& timestamps);
|
||||
bool update_next_comulative_size_limit();
|
||||
bool store_genesis_block(bool testnet);
|
||||
};
|
||||
|
||||
|
||||
|
@ -103,9 +103,15 @@ namespace cryptonote {
|
||||
return summ;
|
||||
}
|
||||
//-----------------------------------------------------------------------
|
||||
std::string get_account_address_as_str(const account_public_address& adr)
|
||||
std::string get_account_address_as_str(
|
||||
bool testnet
|
||||
, account_public_address const & adr
|
||||
)
|
||||
{
|
||||
return tools::base58::encode_addr(CRYPTONOTE_PUBLIC_ADDRESS_BASE58_PREFIX, t_serializable_object_to_blob(adr));
|
||||
uint64_t address_prefix = testnet ?
|
||||
config::testnet::CRYPTONOTE_PUBLIC_ADDRESS_BASE58_PREFIX : config::CRYPTONOTE_PUBLIC_ADDRESS_BASE58_PREFIX;
|
||||
|
||||
return tools::base58::encode_addr(address_prefix, t_serializable_object_to_blob(adr));
|
||||
}
|
||||
//-----------------------------------------------------------------------
|
||||
bool is_coinbase(const transaction& tx)
|
||||
@ -119,8 +125,15 @@ namespace cryptonote {
|
||||
return true;
|
||||
}
|
||||
//-----------------------------------------------------------------------
|
||||
bool get_account_address_from_str(account_public_address& adr, const std::string& str)
|
||||
bool get_account_address_from_str(
|
||||
account_public_address& adr
|
||||
, bool testnet
|
||||
, std::string const & str
|
||||
)
|
||||
{
|
||||
uint64_t address_prefix = testnet ?
|
||||
config::testnet::CRYPTONOTE_PUBLIC_ADDRESS_BASE58_PREFIX : config::CRYPTONOTE_PUBLIC_ADDRESS_BASE58_PREFIX;
|
||||
|
||||
if (2 * sizeof(public_address_outer_blob) != str.size())
|
||||
{
|
||||
blobdata data;
|
||||
@ -131,9 +144,9 @@ namespace cryptonote {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (CRYPTONOTE_PUBLIC_ADDRESS_BASE58_PREFIX != prefix)
|
||||
if (address_prefix != prefix)
|
||||
{
|
||||
LOG_PRINT_L1("Wrong address prefix: " << prefix << ", expected " << CRYPTONOTE_PUBLIC_ADDRESS_BASE58_PREFIX);
|
||||
LOG_PRINT_L1("Wrong address prefix: " << prefix << ", expected " << address_prefix);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -66,8 +66,18 @@ namespace cryptonote {
|
||||
size_t get_max_tx_size();
|
||||
bool get_block_reward(size_t median_size, size_t current_block_size, uint64_t already_generated_coins, uint64_t &reward);
|
||||
uint8_t get_account_address_checksum(const public_address_outer_blob& bl);
|
||||
std::string get_account_address_as_str(const account_public_address& adr);
|
||||
bool get_account_address_from_str(account_public_address& adr, const std::string& str);
|
||||
|
||||
std::string get_account_address_as_str(
|
||||
bool testnet
|
||||
, const account_public_address& adr
|
||||
);
|
||||
|
||||
bool get_account_address_from_str(
|
||||
account_public_address& adr
|
||||
, bool testnet
|
||||
, const std::string& str
|
||||
);
|
||||
|
||||
bool is_coinbase(const transaction& tx);
|
||||
|
||||
bool operator ==(const cryptonote::transaction& a, const cryptonote::transaction& b);
|
||||
|
@ -75,9 +75,10 @@ namespace cryptonote
|
||||
{
|
||||
}
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
bool core::handle_command_line(const boost::program_options::variables_map& vm)
|
||||
bool core::handle_command_line(const boost::program_options::variables_map& vm, bool testnet)
|
||||
{
|
||||
m_config_folder = command_line::get_arg(vm, command_line::arg_data_dir);
|
||||
auto data_dir_arg = testnet ? command_line::arg_testnet_data_dir : command_line::arg_data_dir;
|
||||
m_config_folder = command_line::get_arg(vm, data_dir_arg);
|
||||
return true;
|
||||
}
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
@ -116,17 +117,17 @@ namespace cryptonote
|
||||
return m_blockchain_storage.get_alternative_blocks_count();
|
||||
}
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
bool core::init(const boost::program_options::variables_map& vm)
|
||||
bool core::init(const boost::program_options::variables_map& vm, bool testnet)
|
||||
{
|
||||
bool r = handle_command_line(vm);
|
||||
bool r = handle_command_line(vm, testnet);
|
||||
|
||||
r = m_mempool.init(m_config_folder);
|
||||
CHECK_AND_ASSERT_MES(r, false, "Failed to initialize memory pool");
|
||||
|
||||
r = m_blockchain_storage.init(m_config_folder);
|
||||
r = m_blockchain_storage.init(m_config_folder, testnet);
|
||||
CHECK_AND_ASSERT_MES(r, false, "Failed to initialize blockchain storage");
|
||||
|
||||
r = m_miner.init(vm);
|
||||
r = m_miner.init(vm, testnet);
|
||||
CHECK_AND_ASSERT_MES(r, false, "Failed to initialize blockchain storage");
|
||||
|
||||
return load_state_data();
|
||||
|
@ -70,7 +70,7 @@ namespace cryptonote
|
||||
|
||||
miner& get_miner(){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, bool testnet);
|
||||
bool set_genesis_block(const block& b);
|
||||
bool deinit();
|
||||
uint64_t get_current_blockchain_height();
|
||||
@ -136,7 +136,7 @@ namespace cryptonote
|
||||
bool check_tx_ring_signature(const txin_to_key& tx, const crypto::hash& tx_prefix_hash, const std::vector<crypto::signature>& sig);
|
||||
bool is_tx_spendtime_unlocked(uint64_t unlock_time);
|
||||
bool update_miner_block_template();
|
||||
bool handle_command_line(const boost::program_options::variables_map& vm);
|
||||
bool handle_command_line(const boost::program_options::variables_map& vm, bool testnet);
|
||||
bool on_update_blocktemplate_interval();
|
||||
bool check_tx_inputs_keyimages_diff(const transaction& tx);
|
||||
|
||||
|
@ -660,7 +660,11 @@ namespace cryptonote
|
||||
return p;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
bool generate_genesis_block(block& bl)
|
||||
bool generate_genesis_block(
|
||||
block& bl
|
||||
, std::string const & genesis_tx
|
||||
, uint32_t nonce
|
||||
)
|
||||
{
|
||||
//genesis block
|
||||
bl = boost::value_initialized<block>();
|
||||
@ -672,8 +676,7 @@ namespace cryptonote
|
||||
blobdata txb = tx_to_blob(bl.miner_tx);
|
||||
std::string hex_tx_represent = string_tools::buff_to_hex_nodelimer(txb);
|
||||
|
||||
//hard code coinbase tx in genesis block, because "tru" generating tx use random, but genesis should be always the same
|
||||
std::string genesis_coinbase_tx_hex = "013c01ff0001ffffffffffff03029b2e4c0281c0b02e7c53291a94d1d0cbff8883f8024f5142ee494ffbbd08807121017767aafcde9be00dcfd098715ebcf7f410daebc582fda69d24a28e9d0bc890d1";
|
||||
std::string genesis_coinbase_tx_hex = config::GENESIS_TX;
|
||||
|
||||
blobdata tx_bl;
|
||||
string_tools::parse_hexstr_to_binbuff(genesis_coinbase_tx_hex, tx_bl);
|
||||
@ -682,7 +685,7 @@ namespace cryptonote
|
||||
bl.major_version = CURRENT_BLOCK_MAJOR_VERSION;
|
||||
bl.minor_version = CURRENT_BLOCK_MINOR_VERSION;
|
||||
bl.timestamp = 0;
|
||||
bl.nonce = 10000;
|
||||
bl.nonce = nonce;
|
||||
miner::find_nonce_for_given_block(bl, 1, 0);
|
||||
return true;
|
||||
}
|
||||
|
@ -105,7 +105,11 @@ namespace cryptonote
|
||||
crypto::hash get_block_hash(const block& b);
|
||||
bool get_block_longhash(const block& b, crypto::hash& res, uint64_t height);
|
||||
crypto::hash get_block_longhash(const block& b, uint64_t height);
|
||||
bool generate_genesis_block(block& bl);
|
||||
bool generate_genesis_block(
|
||||
block& bl
|
||||
, std::string const & genesis_tx
|
||||
, uint32_t nonce
|
||||
);
|
||||
bool parse_and_validate_block_from_blob(const blobdata& b_blob, block& b);
|
||||
bool get_inputs_money_amount(const transaction& tx, uint64_t& money);
|
||||
uint64_t get_outs_money_amount(const transaction& tx);
|
||||
|
@ -171,7 +171,7 @@ namespace cryptonote
|
||||
command_line::add_arg(desc, arg_mining_threads);
|
||||
}
|
||||
//-----------------------------------------------------------------------------------------------------
|
||||
bool miner::init(const boost::program_options::variables_map& vm)
|
||||
bool miner::init(const boost::program_options::variables_map& vm, bool testnet)
|
||||
{
|
||||
if(command_line::has_arg(vm, arg_extra_messages))
|
||||
{
|
||||
@ -198,7 +198,7 @@ namespace cryptonote
|
||||
|
||||
if(command_line::has_arg(vm, arg_start_mining))
|
||||
{
|
||||
if(!cryptonote::get_account_address_from_str(m_mine_address, command_line::get_arg(vm, arg_start_mining)))
|
||||
if(!cryptonote::get_account_address_from_str(m_mine_address, testnet, command_line::get_arg(vm, arg_start_mining)))
|
||||
{
|
||||
LOG_ERROR("Target account address " << command_line::get_arg(vm, arg_start_mining) << " has wrong format, starting daemon canceled");
|
||||
return false;
|
||||
|
@ -56,7 +56,7 @@ namespace cryptonote
|
||||
public:
|
||||
miner(i_miner_handler* phandler);
|
||||
~miner();
|
||||
bool init(const boost::program_options::variables_map& vm);
|
||||
bool init(const boost::program_options::variables_map& vm, bool testnet);
|
||||
static void init_options(boost::program_options::options_description& desc);
|
||||
bool set_block_template(const block& bl, const difficulty_type& diffic, uint64_t height);
|
||||
bool on_block_chain_update();
|
||||
|
@ -42,6 +42,7 @@ using namespace epee;
|
||||
#include "crypto/hash.h"
|
||||
#include "console_handler.h"
|
||||
#include "p2p/net_node.h"
|
||||
#include "cryptonote_config.h"
|
||||
#include "cryptonote_core/checkpoints_create.h"
|
||||
#include "cryptonote_core/cryptonote_core.h"
|
||||
#include "rpc/core_rpc_server.h"
|
||||
@ -62,6 +63,11 @@ namespace
|
||||
const command_line::arg_descriptor<std::string> arg_log_file = {"log-file", "", ""};
|
||||
const command_line::arg_descriptor<int> arg_log_level = {"log-level", "", LOG_LEVEL_0};
|
||||
const command_line::arg_descriptor<bool> arg_console = {"no-console", "Disable daemon console commands"};
|
||||
const command_line::arg_descriptor<bool> arg_testnet_on = {
|
||||
"testnet"
|
||||
, "Run on testnet. The wallet must be launched with --testnet flag."
|
||||
, false
|
||||
};
|
||||
}
|
||||
|
||||
bool command_line_preprocessor(const boost::program_options::variables_map& vm)
|
||||
@ -110,6 +116,9 @@ int main(int argc, char* argv[])
|
||||
|
||||
TRY_ENTRY();
|
||||
|
||||
boost::filesystem::path default_data_path {tools::get_default_data_dir()};
|
||||
boost::filesystem::path default_testnet_data_path {default_data_path / "testnet"};
|
||||
|
||||
po::options_description desc_cmd_only("Command line options");
|
||||
po::options_description desc_cmd_sett("Command line options and settings options");
|
||||
|
||||
@ -117,13 +126,14 @@ int main(int argc, char* argv[])
|
||||
command_line::add_arg(desc_cmd_only, command_line::arg_version);
|
||||
command_line::add_arg(desc_cmd_only, arg_os_version);
|
||||
// tools::get_default_data_dir() can't be called during static initialization
|
||||
command_line::add_arg(desc_cmd_only, command_line::arg_data_dir, tools::get_default_data_dir());
|
||||
command_line::add_arg(desc_cmd_only, command_line::arg_data_dir, default_data_path.string());
|
||||
command_line::add_arg(desc_cmd_only, command_line::arg_testnet_data_dir, default_testnet_data_path.string());
|
||||
command_line::add_arg(desc_cmd_only, arg_config_file);
|
||||
|
||||
command_line::add_arg(desc_cmd_sett, arg_log_file);
|
||||
command_line::add_arg(desc_cmd_sett, arg_log_level);
|
||||
command_line::add_arg(desc_cmd_sett, arg_console);
|
||||
|
||||
command_line::add_arg(desc_cmd_sett, arg_testnet_on);
|
||||
|
||||
cryptonote::core::init_options(desc_cmd_sett);
|
||||
cryptonote::core_rpc_server::init_options(desc_cmd_sett);
|
||||
@ -137,6 +147,12 @@ int main(int argc, char* argv[])
|
||||
bool r = command_line::handle_error_helper(desc_options, [&]()
|
||||
{
|
||||
po::store(po::parse_command_line(argc, argv, desc_options), vm);
|
||||
po::notify(vm);
|
||||
|
||||
return true;
|
||||
});
|
||||
if (!r)
|
||||
return 1;
|
||||
|
||||
if (command_line::get_arg(vm, command_line::arg_help))
|
||||
{
|
||||
@ -145,7 +161,12 @@ int main(int argc, char* argv[])
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string data_dir = command_line::get_arg(vm, command_line::arg_data_dir);
|
||||
bool testnet_mode = command_line::get_arg(vm, arg_testnet_on);
|
||||
|
||||
auto data_dir_arg = testnet_mode ? command_line::arg_testnet_data_dir : command_line::arg_data_dir;
|
||||
|
||||
std::string data_dir = command_line::get_arg(vm, data_dir_arg);
|
||||
tools::create_directories_if_necessary(data_dir);
|
||||
std::string config = command_line::get_arg(vm, arg_config_file);
|
||||
|
||||
boost::filesystem::path data_dir_path(data_dir);
|
||||
@ -160,12 +181,6 @@ int main(int argc, char* argv[])
|
||||
{
|
||||
po::store(po::parse_config_file<char>(config_path.string<std::string>().c_str(), desc_cmd_sett), vm);
|
||||
}
|
||||
po::notify(vm);
|
||||
|
||||
return true;
|
||||
});
|
||||
if (!r)
|
||||
return 1;
|
||||
|
||||
//set up logging options
|
||||
boost::filesystem::path log_file_path(command_line::get_arg(vm, arg_log_file));
|
||||
@ -191,17 +206,26 @@ int main(int argc, char* argv[])
|
||||
|
||||
//create objects and link them
|
||||
cryptonote::core ccore(NULL);
|
||||
|
||||
if (testnet_mode) {
|
||||
LOG_PRINT_L0("Starting in testnet mode!");
|
||||
} else {
|
||||
ccore.set_checkpoints(std::move(checkpoints));
|
||||
}
|
||||
|
||||
cryptonote::t_cryptonote_protocol_handler<cryptonote::core> cprotocol(ccore, NULL);
|
||||
nodetool::node_server<cryptonote::t_cryptonote_protocol_handler<cryptonote::core> > p2psrv(cprotocol);
|
||||
cryptonote::core_rpc_server rpc_server(ccore, p2psrv);
|
||||
nodetool::node_server<cryptonote::t_cryptonote_protocol_handler<cryptonote::core> > p2psrv {
|
||||
cprotocol
|
||||
, testnet_mode ? std::move(config::testnet::NETWORK_ID) : std::move(config::NETWORK_ID)
|
||||
};
|
||||
cryptonote::core_rpc_server rpc_server {ccore, p2psrv, testnet_mode};
|
||||
cprotocol.set_p2p_endpoint(&p2psrv);
|
||||
ccore.set_cryptonote_protocol(&cprotocol);
|
||||
daemon_cmmands_handler dch(p2psrv);
|
||||
daemon_cmmands_handler dch(p2psrv, testnet_mode);
|
||||
|
||||
//initialize objects
|
||||
LOG_PRINT_L0("Initializing P2P server...");
|
||||
res = p2psrv.init(vm);
|
||||
res = p2psrv.init(vm, testnet_mode);
|
||||
CHECK_AND_ASSERT_MES(res, 1, "Failed to initialize P2P server.");
|
||||
LOG_PRINT_L0("P2P server initialized OK");
|
||||
|
||||
@ -217,7 +241,7 @@ int main(int argc, char* argv[])
|
||||
|
||||
//initialize core here
|
||||
LOG_PRINT_L0("Initializing core...");
|
||||
res = ccore.init(vm);
|
||||
res = ccore.init(vm, testnet_mode);
|
||||
CHECK_AND_ASSERT_MES(res, 1, "Failed to initialize core");
|
||||
LOG_PRINT_L0("Core initialized OK");
|
||||
|
||||
|
@ -50,7 +50,12 @@ class daemon_cmmands_handler
|
||||
{
|
||||
nodetool::node_server<cryptonote::t_cryptonote_protocol_handler<cryptonote::core> >& m_srv;
|
||||
public:
|
||||
daemon_cmmands_handler(nodetool::node_server<cryptonote::t_cryptonote_protocol_handler<cryptonote::core> >& srv):m_srv(srv)
|
||||
daemon_cmmands_handler(
|
||||
nodetool::node_server<cryptonote::t_cryptonote_protocol_handler<cryptonote::core> >& srv
|
||||
, bool testnet
|
||||
)
|
||||
: m_srv(srv)
|
||||
, m_testnet {testnet}
|
||||
{
|
||||
m_cmd_binder.set_handler("help", boost::bind(&daemon_cmmands_handler::help, this, _1), "Show this help");
|
||||
m_cmd_binder.set_handler("print_pl", boost::bind(&daemon_cmmands_handler::print_pl, this, _1), "Print peer list");
|
||||
@ -84,6 +89,7 @@ public:
|
||||
|
||||
private:
|
||||
epee::srv_console_handlers_binder<nodetool::node_server<cryptonote::t_cryptonote_protocol_handler<cryptonote::core> > > m_cmd_binder;
|
||||
bool m_testnet;
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
std::string get_commands_str()
|
||||
@ -368,7 +374,7 @@ private:
|
||||
}
|
||||
|
||||
cryptonote::account_public_address adr;
|
||||
if(!cryptonote::get_account_address_from_str(adr, args.front()))
|
||||
if(!cryptonote::get_account_address_from_str(adr, m_testnet, args.front()))
|
||||
{
|
||||
std::cout << "target account address has wrong format" << std::endl;
|
||||
return true;
|
||||
|
@ -41,13 +41,14 @@
|
||||
#include <boost/program_options/options_description.hpp>
|
||||
#include <boost/program_options/variables_map.hpp>
|
||||
#include <boost/serialization/version.hpp>
|
||||
#include <boost/uuid/uuid.hpp>
|
||||
|
||||
#include "cryptonote_config.h"
|
||||
#include "warnings.h"
|
||||
#include "net/levin_server_cp2.h"
|
||||
#include "p2p_protocol_defs.h"
|
||||
#include "storages/levin_abstract_invoke2.h"
|
||||
#include "net_peerlist.h"
|
||||
#include "p2p_networks.h"
|
||||
#include "math_helper.h"
|
||||
#include "net_node_common.h"
|
||||
#include "common/command_line.h"
|
||||
@ -78,14 +79,21 @@ namespace nodetool
|
||||
|
||||
public:
|
||||
typedef t_payload_net_handler payload_net_handler;
|
||||
// Some code
|
||||
node_server(t_payload_net_handler& payload_handler):m_payload_handler(payload_handler), m_allow_local_ip(false), m_hide_my_port(false)
|
||||
|
||||
node_server(
|
||||
t_payload_net_handler& payload_handler
|
||||
, boost::uuids::uuid network_id
|
||||
)
|
||||
: m_payload_handler(payload_handler)
|
||||
, m_allow_local_ip(false)
|
||||
, m_hide_my_port(false)
|
||||
, m_network_id(std::move(network_id))
|
||||
{}
|
||||
|
||||
static void init_options(boost::program_options::options_description& desc);
|
||||
|
||||
bool run();
|
||||
bool init(const boost::program_options::variables_map& vm);
|
||||
bool init(const boost::program_options::variables_map& vm, bool testnet);
|
||||
bool deinit();
|
||||
bool send_stop_signal();
|
||||
uint32_t get_this_peer_port(){return m_listenning_port;}
|
||||
@ -149,7 +157,10 @@ namespace nodetool
|
||||
virtual void for_each_connection(std::function<bool(typename t_payload_net_handler::connection_context&, peerid_type)> f);
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
bool parse_peer_from_string(nodetool::net_address& pe, const std::string& node_addr);
|
||||
bool handle_command_line(const boost::program_options::variables_map& vm);
|
||||
bool handle_command_line(
|
||||
const boost::program_options::variables_map& vm
|
||||
, bool testnet
|
||||
);
|
||||
bool idle_worker();
|
||||
bool handle_remote_peerlist(const std::list<peerlist_entry>& peerlist, time_t local_time, const epee::net_utils::connection_context_base& context);
|
||||
bool get_local_node_data(basic_node_data& node_data);
|
||||
@ -229,6 +240,7 @@ namespace nodetool
|
||||
uint64_t m_peer_livetime;
|
||||
//keep connections to initiate some interactions
|
||||
net_server m_net_server;
|
||||
boost::uuids::uuid m_network_id;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -60,7 +60,16 @@ namespace nodetool
|
||||
namespace
|
||||
{
|
||||
const command_line::arg_descriptor<std::string> arg_p2p_bind_ip = {"p2p-bind-ip", "Interface for p2p network protocol", "0.0.0.0"};
|
||||
const command_line::arg_descriptor<std::string> arg_p2p_bind_port = {"p2p-bind-port", "Port for p2p network protocol", boost::to_string(P2P_DEFAULT_PORT)};
|
||||
const command_line::arg_descriptor<std::string> arg_p2p_bind_port = {
|
||||
"p2p-bind-port"
|
||||
, "Port for p2p network protocol"
|
||||
, std::to_string(config::P2P_DEFAULT_PORT)
|
||||
};
|
||||
const command_line::arg_descriptor<std::string> arg_testnet_p2p_bind_port = {
|
||||
"testnet-p2p-bind-port"
|
||||
, "Port for testnet p2p network protocol"
|
||||
, std::to_string(config::testnet::P2P_DEFAULT_PORT)
|
||||
};
|
||||
const command_line::arg_descriptor<uint32_t> arg_p2p_external_port = {"p2p-external-port", "External port for p2p network protocol (if port forwarding used with NAT)", 0};
|
||||
const command_line::arg_descriptor<bool> arg_p2p_allow_local_ip = {"allow-local-ip", "Allow local ip add to peer list, mostly in debug purposes"};
|
||||
const command_line::arg_descriptor<std::vector<std::string> > arg_p2p_add_peer = {"add-peer", "Manually add peer to local peerlist"};
|
||||
@ -77,6 +86,7 @@ namespace nodetool
|
||||
{
|
||||
command_line::add_arg(desc, arg_p2p_bind_ip);
|
||||
command_line::add_arg(desc, arg_p2p_bind_port);
|
||||
command_line::add_arg(desc, arg_testnet_p2p_bind_port);
|
||||
command_line::add_arg(desc, arg_p2p_external_port);
|
||||
command_line::add_arg(desc, arg_p2p_allow_local_ip);
|
||||
command_line::add_arg(desc, arg_p2p_add_peer);
|
||||
@ -138,10 +148,15 @@ namespace nodetool
|
||||
}
|
||||
//-----------------------------------------------------------------------------------
|
||||
template<class t_payload_net_handler>
|
||||
bool node_server<t_payload_net_handler>::handle_command_line(const boost::program_options::variables_map& vm)
|
||||
bool node_server<t_payload_net_handler>::handle_command_line(
|
||||
const boost::program_options::variables_map& vm
|
||||
, bool testnet
|
||||
)
|
||||
{
|
||||
auto p2p_bind_arg = testnet ? arg_testnet_p2p_bind_port : arg_p2p_bind_port;
|
||||
|
||||
m_bind_ip = command_line::get_arg(vm, arg_p2p_bind_ip);
|
||||
m_port = command_line::get_arg(vm, arg_p2p_bind_port);
|
||||
m_port = command_line::get_arg(vm, p2p_bind_arg);
|
||||
m_external_port = command_line::get_arg(vm, arg_p2p_external_port);
|
||||
m_allow_local_ip = command_line::get_arg(vm, arg_p2p_allow_local_ip);
|
||||
|
||||
@ -180,15 +195,15 @@ namespace nodetool
|
||||
return true;
|
||||
}
|
||||
//-----------------------------------------------------------------------------------
|
||||
namespace
|
||||
{
|
||||
template<typename T>
|
||||
bool append_net_address(T& nodes, const std::string& addr)
|
||||
inline void add_hardcoded_seed_node(
|
||||
std::vector<net_address> & seed_nodes
|
||||
, std::string const & addr
|
||||
)
|
||||
{
|
||||
using namespace boost::asio;
|
||||
|
||||
size_t pos = addr.find_last_of(':');
|
||||
CHECK_AND_ASSERT_MES(std::string::npos != pos && addr.length() - 1 != pos && 0 != pos, false, "Failed to parse seed address from string: '" << addr << '\'');
|
||||
CHECK_AND_ASSERT_MES_NO_RET(std::string::npos != pos && addr.length() - 1 != pos && 0 != pos, "Failed to parse seed address from string: '" << addr << '\'');
|
||||
std::string host = addr.substr(0, pos);
|
||||
std::string port = addr.substr(pos + 1);
|
||||
|
||||
@ -197,7 +212,7 @@ namespace nodetool
|
||||
ip::tcp::resolver::query query(host, port);
|
||||
boost::system::error_code ec;
|
||||
ip::tcp::resolver::iterator i = resolver.resolve(query, ec);
|
||||
CHECK_AND_NO_ASSERT_MES(!ec, false, "Failed to resolve host name '" << host << "': " << ec.message() << ':' << ec.value());
|
||||
CHECK_AND_ASSERT_MES_NO_RET(!ec, "Failed to resolve host name '" << host << "': " << ec.message() << ':' << ec.value());
|
||||
|
||||
ip::tcp::resolver::iterator iend;
|
||||
for (; i != iend; ++i)
|
||||
@ -208,7 +223,7 @@ namespace nodetool
|
||||
nodetool::net_address na;
|
||||
na.ip = boost::asio::detail::socket_ops::host_to_network_long(endpoint.address().to_v4().to_ulong());
|
||||
na.port = endpoint.port();
|
||||
nodes.push_back(na);
|
||||
seed_nodes.push_back(na);
|
||||
LOG_PRINT_L4("Added seed node: " << endpoint.address().to_v4().to_string(ec) << ':' << na.port);
|
||||
}
|
||||
else
|
||||
@ -216,31 +231,38 @@ namespace nodetool
|
||||
LOG_PRINT_L2("IPv6 doesn't supported, skip '" << host << "' -> " << endpoint.address().to_v6().to_string(ec));
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
#define ADD_HARDCODED_SEED_NODE(addr) append_net_address(m_seed_nodes, addr);
|
||||
//-----------------------------------------------------------------------------------
|
||||
template<class t_payload_net_handler>
|
||||
bool node_server<t_payload_net_handler>::init(const boost::program_options::variables_map& vm)
|
||||
bool node_server<t_payload_net_handler>::init(const boost::program_options::variables_map& vm, bool testnet)
|
||||
{
|
||||
ADD_HARDCODED_SEED_NODE("62.210.78.186:18080");
|
||||
ADD_HARDCODED_SEED_NODE("195.12.60.154:18080");
|
||||
ADD_HARDCODED_SEED_NODE("54.241.246.125:18080");
|
||||
ADD_HARDCODED_SEED_NODE("107.170.157.169:18080");
|
||||
ADD_HARDCODED_SEED_NODE("54.207.112.216:18080");
|
||||
ADD_HARDCODED_SEED_NODE("78.27.112.54:18080");
|
||||
ADD_HARDCODED_SEED_NODE("209.222.30.57:18080");
|
||||
ADD_HARDCODED_SEED_NODE("80.71.13.55:18080");
|
||||
ADD_HARDCODED_SEED_NODE("107.178.112.126:18080");
|
||||
ADD_HARDCODED_SEED_NODE("107.158.233.98:18080");
|
||||
ADD_HARDCODED_SEED_NODE("64.22.111.2:18080");
|
||||
if (testnet)
|
||||
{
|
||||
add_hardcoded_seed_node(m_seed_nodes, "107.152.187.202:28080");
|
||||
add_hardcoded_seed_node(m_seed_nodes, "197.242.158.240:28080");
|
||||
add_hardcoded_seed_node(m_seed_nodes, "107.152.130.98:28080");
|
||||
}
|
||||
else
|
||||
{
|
||||
add_hardcoded_seed_node(m_seed_nodes, "62.210.78.186:18080");
|
||||
add_hardcoded_seed_node(m_seed_nodes, "195.12.60.154:18080");
|
||||
add_hardcoded_seed_node(m_seed_nodes, "54.241.246.125:18080");
|
||||
add_hardcoded_seed_node(m_seed_nodes, "107.170.157.169:18080");
|
||||
add_hardcoded_seed_node(m_seed_nodes, "54.207.112.216:18080");
|
||||
add_hardcoded_seed_node(m_seed_nodes, "78.27.112.54:18080");
|
||||
add_hardcoded_seed_node(m_seed_nodes, "209.222.30.57:18080");
|
||||
add_hardcoded_seed_node(m_seed_nodes, "80.71.13.55:18080");
|
||||
add_hardcoded_seed_node(m_seed_nodes, "107.178.112.126:18080");
|
||||
add_hardcoded_seed_node(m_seed_nodes, "107.158.233.98:18080");
|
||||
add_hardcoded_seed_node(m_seed_nodes, "64.22.111.2:18080");
|
||||
}
|
||||
|
||||
bool res = handle_command_line(vm);
|
||||
bool res = handle_command_line(vm, testnet);
|
||||
CHECK_AND_ASSERT_MES(res, false, "Failed to handle command line");
|
||||
m_config_folder = command_line::get_arg(vm, command_line::arg_data_dir);
|
||||
|
||||
auto config_arg = testnet ? command_line::arg_testnet_data_dir : command_line::arg_data_dir;
|
||||
m_config_folder = command_line::get_arg(vm, config_arg);
|
||||
|
||||
res = init_config();
|
||||
CHECK_AND_ASSERT_MES(res, false, "Failed to init config.");
|
||||
@ -410,7 +432,7 @@ namespace nodetool
|
||||
return;
|
||||
}
|
||||
|
||||
if(rsp.node_data.network_id != MONERO_NETWORK)
|
||||
if(rsp.node_data.network_id != m_network_id)
|
||||
{
|
||||
LOG_ERROR_CCONTEXT("COMMAND_HANDSHAKE Failed, wrong network! (" << epee::string_tools::get_str_from_guid_a(rsp.node_data.network_id) << "), closing connection.");
|
||||
return;
|
||||
@ -818,7 +840,7 @@ namespace nodetool
|
||||
node_data.my_port = m_external_port ? m_external_port : m_listenning_port;
|
||||
else
|
||||
node_data.my_port = 0;
|
||||
node_data.network_id = MONERO_NETWORK;
|
||||
node_data.network_id = m_network_id;
|
||||
return true;
|
||||
}
|
||||
//-----------------------------------------------------------------------------------
|
||||
@ -844,7 +866,7 @@ namespace nodetool
|
||||
return false;
|
||||
}
|
||||
crypto::public_key pk = AUTO_VAL_INIT(pk);
|
||||
epee::string_tools::hex_to_pod(P2P_STAT_TRUSTED_PUB_KEY, pk);
|
||||
epee::string_tools::hex_to_pod(::config::P2P_REMOTE_DEBUG_TRUSTED_PUB_KEY, pk);
|
||||
crypto::hash h = tools::get_proof_of_trust_hash(tr);
|
||||
if(!crypto::check_signature(h, pk, tr.sign))
|
||||
{
|
||||
@ -1038,7 +1060,7 @@ namespace nodetool
|
||||
template<class t_payload_net_handler>
|
||||
int node_server<t_payload_net_handler>::handle_handshake(int command, typename COMMAND_HANDSHAKE::request& arg, typename COMMAND_HANDSHAKE::response& rsp, p2p_connection_context& context)
|
||||
{
|
||||
if(arg.node_data.network_id != MONERO_NETWORK)
|
||||
if(arg.node_data.network_id != m_network_id)
|
||||
{
|
||||
|
||||
LOG_PRINT_CCONTEXT_L1("WRONG NETWORK AGENT CONNECTED! id=" << epee::string_tools::get_str_from_guid_a(arg.node_data.network_id));
|
||||
|
@ -1,36 +0,0 @@
|
||||
// Copyright (c) 2014, 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
|
||||
|
||||
namespace nodetool
|
||||
{
|
||||
const static boost::uuids::uuid MONERO_NETWORK = { { 0x12 ,0x30, 0xF1, 0x71 , 0x61, 0x04 , 0x41, 0x61, 0x17, 0x31, 0x00, 0x82, 0x16, 0xA1, 0xA1, 0x10} }; //Bender's nightmare
|
||||
}
|
@ -45,8 +45,23 @@ namespace cryptonote
|
||||
{
|
||||
namespace
|
||||
{
|
||||
const command_line::arg_descriptor<std::string> arg_rpc_bind_ip = {"rpc-bind-ip", "", "127.0.0.1"};
|
||||
const command_line::arg_descriptor<std::string> arg_rpc_bind_port = {"rpc-bind-port", "", std::to_string(RPC_DEFAULT_PORT)};
|
||||
const command_line::arg_descriptor<std::string> arg_rpc_bind_ip = {
|
||||
"rpc-bind-ip"
|
||||
, "IP for RPC server"
|
||||
, "127.0.0.1"
|
||||
};
|
||||
|
||||
const command_line::arg_descriptor<std::string> arg_rpc_bind_port = {
|
||||
"rpc-bind-port"
|
||||
, "Port for RPC server"
|
||||
, std::to_string(config::RPC_DEFAULT_PORT)
|
||||
};
|
||||
|
||||
const command_line::arg_descriptor<std::string> arg_testnet_rpc_bind_port = {
|
||||
"testnet-rpc-bind-port"
|
||||
, "Port for testnet RPC server"
|
||||
, std::to_string(config::testnet::RPC_DEFAULT_PORT)
|
||||
};
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------
|
||||
@ -54,19 +69,33 @@ namespace cryptonote
|
||||
{
|
||||
command_line::add_arg(desc, arg_rpc_bind_ip);
|
||||
command_line::add_arg(desc, arg_rpc_bind_port);
|
||||
command_line::add_arg(desc, arg_testnet_rpc_bind_port);
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
core_rpc_server::core_rpc_server(core& cr, nodetool::node_server<cryptonote::t_cryptonote_protocol_handler<cryptonote::core> >& p2p):m_core(cr), m_p2p(p2p)
|
||||
core_rpc_server::core_rpc_server(
|
||||
core& cr
|
||||
, nodetool::node_server<cryptonote::t_cryptonote_protocol_handler<cryptonote::core> >& p2p
|
||||
, bool testnet
|
||||
)
|
||||
: m_core(cr)
|
||||
, m_p2p(p2p)
|
||||
, m_testnet {testnet}
|
||||
{}
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
bool core_rpc_server::handle_command_line(const boost::program_options::variables_map& vm)
|
||||
bool core_rpc_server::handle_command_line(
|
||||
const boost::program_options::variables_map& vm
|
||||
)
|
||||
{
|
||||
auto p2p_bind_arg = m_testnet ? arg_testnet_rpc_bind_port : arg_rpc_bind_port;
|
||||
|
||||
m_bind_ip = command_line::get_arg(vm, arg_rpc_bind_ip);
|
||||
m_port = command_line::get_arg(vm, arg_rpc_bind_port);
|
||||
m_port = command_line::get_arg(vm, p2p_bind_arg);
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
bool core_rpc_server::init(const boost::program_options::variables_map& vm)
|
||||
bool core_rpc_server::init(
|
||||
const boost::program_options::variables_map& vm
|
||||
)
|
||||
{
|
||||
m_net_server.set_threads_prefix("RPC");
|
||||
bool r = handle_command_line(vm);
|
||||
@ -278,7 +307,7 @@ namespace cryptonote
|
||||
{
|
||||
CHECK_CORE_READY();
|
||||
account_public_address adr;
|
||||
if(!get_account_address_from_str(adr, req.miner_address))
|
||||
if(!get_account_address_from_str(adr, m_testnet, req.miner_address))
|
||||
{
|
||||
res.status = "Failed, wrong address";
|
||||
return true;
|
||||
@ -318,7 +347,7 @@ namespace cryptonote
|
||||
res.speed = lMiner.get_speed();
|
||||
res.threads_count = lMiner.get_threads_count();
|
||||
const account_public_address& lMiningAdr = lMiner.get_mining_address();
|
||||
res.address = get_account_address_as_str(lMiningAdr);
|
||||
res.address = get_account_address_as_str(m_testnet, lMiningAdr);
|
||||
}
|
||||
|
||||
res.status = CORE_RPC_STATUS_OK;
|
||||
@ -402,7 +431,7 @@ namespace cryptonote
|
||||
|
||||
cryptonote::account_public_address acc = AUTO_VAL_INIT(acc);
|
||||
|
||||
if(!req.wallet_address.size() || !cryptonote::get_account_address_from_str(acc, req.wallet_address))
|
||||
if(!req.wallet_address.size() || !cryptonote::get_account_address_from_str(acc, m_testnet, req.wallet_address))
|
||||
{
|
||||
error_resp.code = CORE_RPC_ERROR_CODE_WRONG_WALLET_ADDRESS;
|
||||
error_resp.message = "Failed to parse wallet address";
|
||||
|
@ -49,10 +49,16 @@ namespace cryptonote
|
||||
public:
|
||||
typedef epee::net_utils::connection_context_base connection_context;
|
||||
|
||||
core_rpc_server(core& cr, nodetool::node_server<cryptonote::t_cryptonote_protocol_handler<cryptonote::core> >& p2p);
|
||||
core_rpc_server(
|
||||
core& cr
|
||||
, nodetool::node_server<cryptonote::t_cryptonote_protocol_handler<cryptonote::core> >& p2p
|
||||
, bool testnet
|
||||
);
|
||||
|
||||
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
|
||||
);
|
||||
private:
|
||||
|
||||
CHAIN_HTTP_TO_MAP2(connection_context); //forward http requests to uri map
|
||||
@ -105,7 +111,9 @@ namespace cryptonote
|
||||
bool on_get_connections(const COMMAND_RPC_GET_CONNECTIONS::request& req, COMMAND_RPC_GET_CONNECTIONS::response& res, epee::json_rpc::error& error_resp, connection_context& cntx);
|
||||
bool on_get_info_json(const COMMAND_RPC_GET_INFO::request& req, COMMAND_RPC_GET_INFO::response& res, epee::json_rpc::error& error_resp, connection_context& cntx);
|
||||
//-----------------------
|
||||
bool handle_command_line(const boost::program_options::variables_map& vm);
|
||||
bool handle_command_line(
|
||||
const boost::program_options::variables_map& vm
|
||||
);
|
||||
bool check_core_busy();
|
||||
bool check_core_ready();
|
||||
|
||||
@ -117,5 +125,6 @@ namespace cryptonote
|
||||
nodetool::node_server<cryptonote::t_cryptonote_protocol_handler<cryptonote::core> >& m_p2p;
|
||||
std::string m_port;
|
||||
std::string m_bind_ip;
|
||||
bool m_testnet;
|
||||
};
|
||||
}
|
||||
|
@ -72,6 +72,7 @@ namespace
|
||||
const command_line::arg_descriptor<bool> arg_non_deterministic = {"non-deterministic", "creates non-deterministic view and spend keys", false};
|
||||
const command_line::arg_descriptor<int> arg_daemon_port = {"daemon-port", "Use daemon instance at port <arg> instead of 8081", 0};
|
||||
const command_line::arg_descriptor<uint32_t> arg_log_level = {"set_log", "", 0, true};
|
||||
const command_line::arg_descriptor<bool> arg_testnet = {"testnet", "Used to deploy test nets. The daemon must be launched with --testnet flag", false};
|
||||
|
||||
const command_line::arg_descriptor< std::vector<std::string> > arg_command = {"command", ""};
|
||||
|
||||
@ -327,10 +328,16 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm)
|
||||
if(!ask_wallet_create_if_needed()) return false;
|
||||
}
|
||||
|
||||
bool testnet = command_line::get_arg(vm, arg_testnet);
|
||||
|
||||
if (m_daemon_host.empty())
|
||||
m_daemon_host = "localhost";
|
||||
|
||||
if (!m_daemon_port)
|
||||
m_daemon_port = RPC_DEFAULT_PORT;
|
||||
{
|
||||
m_daemon_port = testnet ? config::testnet::RPC_DEFAULT_PORT : config::RPC_DEFAULT_PORT;
|
||||
}
|
||||
|
||||
if (m_daemon_address.empty())
|
||||
m_daemon_address = std::string("http://") + m_daemon_host + ":" + std::to_string(m_daemon_port);
|
||||
|
||||
@ -378,12 +385,12 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
bool r = new_wallet(m_wallet_file, pwd_container.password(), m_recovery_key, m_restore_deterministic_wallet, m_non_deterministic);
|
||||
bool r = new_wallet(m_wallet_file, pwd_container.password(), m_recovery_key, m_restore_deterministic_wallet, m_non_deterministic, testnet);
|
||||
CHECK_AND_ASSERT_MES(r, false, "account creation failed");
|
||||
}
|
||||
else
|
||||
{
|
||||
bool r = open_wallet(m_wallet_file, pwd_container.password());
|
||||
bool r = open_wallet(m_wallet_file, pwd_container.password(), testnet);
|
||||
CHECK_AND_ASSERT_MES(r, false, "could not open account");
|
||||
}
|
||||
|
||||
@ -423,18 +430,20 @@ bool simple_wallet::try_connect_to_daemon()
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
bool simple_wallet::new_wallet(const string &wallet_file, const std::string& password, const crypto::secret_key& recovery_key, bool recover, bool two_random)
|
||||
bool simple_wallet::new_wallet(const string &wallet_file, const std::string& password, const crypto::secret_key& recovery_key, bool recover, bool two_random, bool testnet)
|
||||
{
|
||||
m_wallet_file = wallet_file;
|
||||
|
||||
m_wallet.reset(new tools::wallet2());
|
||||
m_wallet.reset(new tools::wallet2(testnet));
|
||||
m_wallet->callback(this);
|
||||
|
||||
crypto::secret_key recovery_val;
|
||||
try
|
||||
{
|
||||
recovery_val = m_wallet->generate(wallet_file, password, recovery_key, recover, two_random);
|
||||
message_writer(epee::log_space::console_color_white, true) << "Generated new wallet: " << m_wallet->get_account().get_public_address_str() << std::endl << "view key: " << string_tools::pod_to_hex(m_wallet->get_account().get_keys().m_view_secret_key);
|
||||
message_writer(epee::log_space::console_color_white, true) << "Generated new wallet: "
|
||||
<< m_wallet->get_account().get_public_address_str(m_wallet->testnet()) << std::endl << "view key: "
|
||||
<< string_tools::pod_to_hex(m_wallet->get_account().get_keys().m_view_secret_key);
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
@ -471,16 +480,17 @@ bool simple_wallet::new_wallet(const string &wallet_file, const std::string& pas
|
||||
return true;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
bool simple_wallet::open_wallet(const string &wallet_file, const std::string& password)
|
||||
bool simple_wallet::open_wallet(const string &wallet_file, const std::string& password, bool testnet)
|
||||
{
|
||||
m_wallet_file = wallet_file;
|
||||
m_wallet.reset(new tools::wallet2());
|
||||
m_wallet.reset(new tools::wallet2(testnet));
|
||||
m_wallet->callback(this);
|
||||
|
||||
try
|
||||
{
|
||||
m_wallet->load(m_wallet_file, password);
|
||||
message_writer(epee::log_space::console_color_white, true) << "Opened wallet: " << m_wallet->get_account().get_public_address_str();
|
||||
message_writer(epee::log_space::console_color_white, true) << "Opened wallet: "
|
||||
<< m_wallet->get_account().get_public_address_str(m_wallet->testnet());
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
@ -541,7 +551,7 @@ bool simple_wallet::start_mining(const std::vector<std::string>& args)
|
||||
return true;
|
||||
|
||||
COMMAND_RPC_START_MINING::request req;
|
||||
req.miner_address = m_wallet->get_account().get_public_address_str();
|
||||
req.miner_address = m_wallet->get_account().get_public_address_str(m_wallet->testnet());
|
||||
|
||||
bool ok = true;
|
||||
size_t max_mining_threads_count = (std::max)(std::thread::hardware_concurrency(), static_cast<unsigned>(2));
|
||||
@ -898,7 +908,7 @@ bool simple_wallet::transfer(const std::vector<std::string> &args_)
|
||||
for (size_t i = 0; i < local_args.size(); i += 2)
|
||||
{
|
||||
cryptonote::tx_destination_entry de;
|
||||
if(!get_account_address_from_str(de.addr, local_args[i]))
|
||||
if(!get_account_address_from_str(de.addr, m_wallet->testnet(), local_args[i]))
|
||||
{
|
||||
fail_msg_writer() << "wrong address: " << local_args[i];
|
||||
return true;
|
||||
@ -1028,7 +1038,7 @@ bool simple_wallet::transfer(const std::vector<std::string> &args_)
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
bool simple_wallet::run()
|
||||
{
|
||||
std::string addr_start = m_wallet->get_account().get_public_address_str().substr(0, 6);
|
||||
std::string addr_start = m_wallet->get_account().get_public_address_str(m_wallet->testnet()).substr(0, 6);
|
||||
return m_cmd_binder.run_handling("[wallet " + addr_start + "]: ", "");
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
@ -1040,7 +1050,7 @@ void simple_wallet::stop()
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
bool simple_wallet::print_address(const std::vector<std::string> &args/* = std::vector<std::string>()*/)
|
||||
{
|
||||
success_msg_writer() << m_wallet->get_account().get_public_address_str();
|
||||
success_msg_writer() << m_wallet->get_account().get_public_address_str(m_wallet->testnet());
|
||||
return true;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
@ -1075,6 +1085,7 @@ int main(int argc, char* argv[])
|
||||
command_line::add_arg(desc_params, arg_restore_deterministic_wallet );
|
||||
command_line::add_arg(desc_params, arg_non_deterministic );
|
||||
command_line::add_arg(desc_params, arg_electrum_seed );
|
||||
command_line::add_arg(desc_params, arg_testnet);
|
||||
tools::wallet_rpc_server::init_options(desc_params);
|
||||
|
||||
po::positional_options_description positional_options;
|
||||
@ -1144,6 +1155,7 @@ int main(int argc, char* argv[])
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool testnet = command_line::get_arg(vm, arg_testnet);
|
||||
std::string wallet_file = command_line::get_arg(vm, arg_wallet_file);
|
||||
std::string wallet_password = command_line::get_arg(vm, arg_password);
|
||||
std::string daemon_address = command_line::get_arg(vm, arg_daemon_address);
|
||||
@ -1152,11 +1164,11 @@ int main(int argc, char* argv[])
|
||||
if (daemon_host.empty())
|
||||
daemon_host = "localhost";
|
||||
if (!daemon_port)
|
||||
daemon_port = RPC_DEFAULT_PORT;
|
||||
daemon_port = config::RPC_DEFAULT_PORT;
|
||||
if (daemon_address.empty())
|
||||
daemon_address = std::string("http://") + daemon_host + ":" + std::to_string(daemon_port);
|
||||
|
||||
tools::wallet2 wal;
|
||||
tools::wallet2 wal(testnet);
|
||||
try
|
||||
{
|
||||
LOG_PRINT_L0("Loading wallet...");
|
||||
|
@ -66,8 +66,8 @@ namespace cryptonote
|
||||
|
||||
bool run_console_handler();
|
||||
|
||||
bool new_wallet(const std::string &wallet_file, const std::string& password, const crypto::secret_key& recovery_key = crypto::secret_key(), bool recover = false, bool two_random = false);
|
||||
bool open_wallet(const std::string &wallet_file, const std::string& password);
|
||||
bool new_wallet(const std::string &wallet_file, const std::string& password, const crypto::secret_key& recovery_key = crypto::secret_key(), bool recover = false, bool two_random = false, bool testnet = false);
|
||||
bool open_wallet(const std::string &wallet_file, const std::string& password, bool testnet);
|
||||
bool close_wallet();
|
||||
|
||||
bool viewkey(const std::vector<std::string> &args = std::vector<std::string>());
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include "include_base_utils.h"
|
||||
using namespace epee;
|
||||
|
||||
#include "cryptonote_config.h"
|
||||
#include "wallet2.h"
|
||||
#include "cryptonote_core/cryptonote_format_utils.h"
|
||||
#include "rpc/core_rpc_server_commands_defs.h"
|
||||
@ -420,9 +421,6 @@ bool wallet2::clear()
|
||||
{
|
||||
m_blockchain.clear();
|
||||
m_transfers.clear();
|
||||
cryptonote::block b;
|
||||
cryptonote::generate_genesis_block(b);
|
||||
m_blockchain.push_back(get_block_hash(b));
|
||||
m_local_bc_height = 1;
|
||||
return true;
|
||||
}
|
||||
@ -498,9 +496,13 @@ crypto::secret_key wallet2::generate(const std::string& wallet_, const std::stri
|
||||
bool r = store_keys(m_keys_file, password);
|
||||
THROW_WALLET_EXCEPTION_IF(!r, error::file_save_error, m_keys_file);
|
||||
|
||||
r = file_io_utils::save_string_to_file(m_wallet_file + ".address.txt", m_account.get_public_address_str());
|
||||
r = file_io_utils::save_string_to_file(m_wallet_file + ".address.txt", m_account.get_public_address_str(m_testnet));
|
||||
if(!r) LOG_PRINT_RED_L0("String with address text not saved");
|
||||
|
||||
cryptonote::block b;
|
||||
generate_genesis(b);
|
||||
m_blockchain.push_back(get_block_hash(b));
|
||||
|
||||
store();
|
||||
return retval;
|
||||
}
|
||||
@ -541,8 +543,12 @@ bool wallet2::check_connection()
|
||||
|
||||
net_utils::http::url_content u;
|
||||
net_utils::parse_url(m_daemon_address, u);
|
||||
|
||||
if(!u.port)
|
||||
u.port = RPC_DEFAULT_PORT;
|
||||
{
|
||||
u.port = m_testnet ? config::testnet::RPC_DEFAULT_PORT : config::RPC_DEFAULT_PORT;
|
||||
}
|
||||
|
||||
return m_http_client.connect(u.host, std::to_string(u.port), WALLET_RCP_CONNECTION_TIMEOUT);
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
@ -556,7 +562,7 @@ void wallet2::load(const std::string& wallet_, const std::string& password)
|
||||
THROW_WALLET_EXCEPTION_IF(e || !exists, error::file_not_found, m_keys_file);
|
||||
|
||||
load_keys(m_keys_file, password);
|
||||
LOG_PRINT_L0("Loaded wallet keys file, with public address: " << m_account.get_public_address_str());
|
||||
LOG_PRINT_L0("Loaded wallet keys file, with public address: " << m_account.get_public_address_str(m_testnet));
|
||||
|
||||
//keys loaded ok!
|
||||
//try to load wallet file. but even if we failed, it is not big problem
|
||||
@ -573,15 +579,28 @@ void wallet2::load(const std::string& wallet_, const std::string& password)
|
||||
m_account_public_address.m_view_public_key != m_account.get_keys().m_account_address.m_view_public_key,
|
||||
error::wallet_files_doesnt_correspond, m_keys_file, m_wallet_file);
|
||||
|
||||
if(m_blockchain.empty())
|
||||
cryptonote::block genesis;
|
||||
generate_genesis(genesis);
|
||||
crypto::hash genesis_hash = get_block_hash(genesis);
|
||||
|
||||
if (m_blockchain.empty())
|
||||
{
|
||||
cryptonote::block b;
|
||||
cryptonote::generate_genesis_block(b);
|
||||
m_blockchain.push_back(get_block_hash(b));
|
||||
m_blockchain.push_back(genesis_hash);
|
||||
}
|
||||
else
|
||||
{
|
||||
check_genesis(genesis_hash);
|
||||
}
|
||||
|
||||
m_local_bc_height = m_blockchain.size();
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
void wallet2::check_genesis(const crypto::hash& genesis_hash) {
|
||||
std::string what("Genesis block missmatch. You probably use wallet without testnet flag with blockchain from test network or vice versa");
|
||||
|
||||
THROW_WALLET_EXCEPTION_IF(genesis_hash != m_blockchain[0], error::wallet_internal_error, what);
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
void wallet2::store()
|
||||
{
|
||||
bool r = tools::serialize_obj_to_file(*this, m_wallet_file);
|
||||
@ -918,4 +937,16 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions(std::vector<crypto
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
void wallet2::generate_genesis(cryptonote::block& b) {
|
||||
if (m_testnet)
|
||||
{
|
||||
cryptonote::generate_genesis_block(b, config::testnet::GENESIS_TX, config::testnet::GENESIS_NONCE);
|
||||
}
|
||||
else
|
||||
{
|
||||
cryptonote::generate_genesis_block(b, config::GENESIS_TX, config::GENESIS_NONCE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -80,9 +80,9 @@ namespace tools
|
||||
|
||||
class wallet2
|
||||
{
|
||||
wallet2(const wallet2&) : m_run(true), m_callback(0) {};
|
||||
wallet2(const wallet2&) : m_run(true), m_callback(0), m_testnet(false) {};
|
||||
public:
|
||||
wallet2() : m_run(true), m_callback(0) {};
|
||||
wallet2(bool testnet = false) : m_run(true), m_callback(0), m_testnet(testnet) {};
|
||||
struct transfer_details
|
||||
{
|
||||
uint64_t m_block_height;
|
||||
@ -158,6 +158,8 @@ namespace tools
|
||||
void refresh(uint64_t start_height, size_t & blocks_fetched, bool& received_money);
|
||||
bool refresh(size_t & blocks_fetched, bool& received_money, bool& ok);
|
||||
|
||||
bool testnet() { return m_testnet; }
|
||||
|
||||
uint64_t balance();
|
||||
uint64_t unlocked_balance();
|
||||
template<typename T>
|
||||
@ -209,6 +211,8 @@ namespace tools
|
||||
bool prepare_file_names(const std::string& file_path);
|
||||
void process_unconfirmed(const cryptonote::transaction& tx);
|
||||
void add_unconfirmed_tx(const cryptonote::transaction& tx, uint64_t change_amount);
|
||||
void generate_genesis(cryptonote::block& b);
|
||||
void check_genesis(const crypto::hash& genesis_hash); //throws
|
||||
|
||||
cryptonote::account_base m_account;
|
||||
std::string m_daemon_address;
|
||||
@ -228,6 +232,7 @@ namespace tools
|
||||
std::atomic<bool> m_run;
|
||||
|
||||
i_wallet2_callback* m_callback;
|
||||
bool m_testnet;
|
||||
};
|
||||
}
|
||||
BOOST_CLASS_VERSION(tools::wallet2, 7)
|
||||
@ -357,7 +362,7 @@ namespace tools
|
||||
{
|
||||
THROW_WALLET_EXCEPTION_IF(0 == dt.amount, error::zero_destination);
|
||||
needed_money += dt.amount;
|
||||
THROW_WALLET_EXCEPTION_IF(needed_money < dt.amount, error::tx_sum_overflow, dsts, fee);
|
||||
THROW_WALLET_EXCEPTION_IF(needed_money < dt.amount, error::tx_sum_overflow, dsts, fee, m_testnet);
|
||||
}
|
||||
|
||||
// randomly select inputs for transaction
|
||||
@ -462,7 +467,7 @@ namespace tools
|
||||
}
|
||||
|
||||
bool r = cryptonote::construct_tx(m_account.get_keys(), sources, splitted_dsts, extra, tx, unlock_time);
|
||||
THROW_WALLET_EXCEPTION_IF(!r, error::tx_not_constructed, sources, splitted_dsts, unlock_time);
|
||||
THROW_WALLET_EXCEPTION_IF(!r, error::tx_not_constructed, sources, splitted_dsts, unlock_time, m_testnet);
|
||||
THROW_WALLET_EXCEPTION_IF(m_upper_transaction_size_limit <= get_object_blobsize(tx), error::tx_too_big, tx, m_upper_transaction_size_limit);
|
||||
|
||||
std::string key_images;
|
||||
|
@ -376,11 +376,18 @@ namespace tools
|
||||
typedef std::vector<cryptonote::tx_source_entry> sources_t;
|
||||
typedef std::vector<cryptonote::tx_destination_entry> destinations_t;
|
||||
|
||||
explicit tx_not_constructed(std::string&& loc, const sources_t& sources, const destinations_t& destinations, uint64_t unlock_time)
|
||||
: transfer_error(std::move(loc), "transaction was not constructed")
|
||||
, m_sources(sources)
|
||||
, m_destinations(destinations)
|
||||
, m_unlock_time(unlock_time)
|
||||
explicit tx_not_constructed(
|
||||
std::string && loc
|
||||
, sources_t const & sources
|
||||
, destinations_t const & destinations
|
||||
, uint64_t unlock_time
|
||||
, bool testnet
|
||||
)
|
||||
: transfer_error {std::move(loc), "transaction was not constructed"}
|
||||
, m_sources {sources}
|
||||
, m_destinations {destinations}
|
||||
, m_unlock_time {unlock_time}
|
||||
, m_testnet {testnet}
|
||||
{
|
||||
}
|
||||
|
||||
@ -414,7 +421,7 @@ namespace tools
|
||||
for (size_t i = 0; i < m_destinations.size(); ++i)
|
||||
{
|
||||
const cryptonote::tx_destination_entry& dst = m_destinations[i];
|
||||
ss << "\n " << i << ": " << cryptonote::get_account_address_as_str(dst.addr) << " " <<
|
||||
ss << "\n " << i << ": " << cryptonote::get_account_address_as_str(m_testnet, dst.addr) << " " <<
|
||||
cryptonote::print_money(dst.amount);
|
||||
}
|
||||
|
||||
@ -427,6 +434,7 @@ namespace tools
|
||||
sources_t m_sources;
|
||||
destinations_t m_destinations;
|
||||
uint64_t m_unlock_time;
|
||||
bool m_testnet;
|
||||
};
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
struct tx_rejected : public transfer_error
|
||||
@ -457,10 +465,16 @@ namespace tools
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
struct tx_sum_overflow : public transfer_error
|
||||
{
|
||||
explicit tx_sum_overflow(std::string&& loc, const std::vector<cryptonote::tx_destination_entry>& destinations, uint64_t fee)
|
||||
: transfer_error(std::move(loc), "transaction sum + fee exceeds " + cryptonote::print_money(std::numeric_limits<uint64_t>::max()))
|
||||
, m_destinations(destinations)
|
||||
, m_fee(fee)
|
||||
explicit tx_sum_overflow(
|
||||
std::string && loc
|
||||
, const std::vector<cryptonote::tx_destination_entry>& destinations
|
||||
, uint64_t fee
|
||||
, bool testnet
|
||||
)
|
||||
: transfer_error {std::move(loc), "transaction sum + fee exceeds " + cryptonote::print_money(std::numeric_limits<uint64_t>::max())}
|
||||
, m_destinations {destinations}
|
||||
, m_fee {fee}
|
||||
, m_testnet {testnet}
|
||||
{
|
||||
}
|
||||
|
||||
@ -475,7 +489,7 @@ namespace tools
|
||||
", destinations:";
|
||||
for (const auto& dst : m_destinations)
|
||||
{
|
||||
ss << '\n' << cryptonote::print_money(dst.amount) << " -> " << cryptonote::get_account_address_as_str(dst.addr);
|
||||
ss << '\n' << cryptonote::print_money(dst.amount) << " -> " << cryptonote::get_account_address_as_str(m_testnet, dst.addr);
|
||||
}
|
||||
return ss.str();
|
||||
}
|
||||
@ -483,6 +497,7 @@ namespace tools
|
||||
private:
|
||||
std::vector<cryptonote::tx_destination_entry> m_destinations;
|
||||
uint64_t m_fee;
|
||||
bool m_testnet;
|
||||
};
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
struct tx_too_big : public transfer_error
|
||||
|
@ -101,7 +101,7 @@ namespace tools
|
||||
{
|
||||
try
|
||||
{
|
||||
res.address = m_wallet.get_account().get_public_address_str();
|
||||
res.address = m_wallet.get_account().get_public_address_str(m_wallet.testnet());
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
@ -118,7 +118,7 @@ namespace tools
|
||||
for (auto it = destinations.begin(); it != destinations.end(); it++)
|
||||
{
|
||||
cryptonote::tx_destination_entry de;
|
||||
if(!get_account_address_from_str(de.addr, it->address))
|
||||
if(!get_account_address_from_str(de.addr, m_wallet.testnet(), it->address))
|
||||
{
|
||||
er.code = WALLET_RPC_ERROR_CODE_WRONG_ADDRESS;
|
||||
er.message = std::string("WALLET_RPC_ERROR_CODE_WRONG_ADDRESS: ") + it->address;
|
||||
|
@ -104,7 +104,10 @@ int main(int argc, char* argv[])
|
||||
//create objects and link them
|
||||
tests::proxy_core pr_core;
|
||||
cryptonote::t_cryptonote_protocol_handler<tests::proxy_core> cprotocol(pr_core, NULL);
|
||||
nodetool::node_server<cryptonote::t_cryptonote_protocol_handler<tests::proxy_core> > p2psrv(cprotocol);
|
||||
nodetool::node_server<cryptonote::t_cryptonote_protocol_handler<tests::proxy_core> > p2psrv {
|
||||
cprotocol
|
||||
, std::move(config::NETWORK_ID)
|
||||
};
|
||||
cprotocol.set_p2p_endpoint(&p2psrv);
|
||||
//pr_core.set_cryptonote_protocol(&cprotocol);
|
||||
//daemon_cmmands_handler dch(p2psrv);
|
||||
@ -112,7 +115,7 @@ int main(int argc, char* argv[])
|
||||
//initialize objects
|
||||
|
||||
LOG_PRINT_L0("Initializing p2p server...");
|
||||
bool res = p2psrv.init(vm);
|
||||
bool res = p2psrv.init(vm, false);
|
||||
CHECK_AND_ASSERT_MES(res, 1, "Failed to initialize p2p server.");
|
||||
LOG_PRINT_L0("P2p server initialized OK");
|
||||
|
||||
@ -224,7 +227,7 @@ bool tests::proxy_core::get_blockchain_top(uint64_t& height, crypto::hash& top_i
|
||||
}
|
||||
|
||||
bool tests::proxy_core::init(const boost::program_options::variables_map& /*vm*/) {
|
||||
generate_genesis_block(m_genesis);
|
||||
generate_genesis_block(m_genesis, config::GENESIS_TX, config::GENESIS_NONCE);
|
||||
crypto::hash h = get_block_hash(m_genesis);
|
||||
add_block(h, get_block_longhash(m_genesis, 0), m_genesis, block_to_blob(m_genesis));
|
||||
return true;
|
||||
|
@ -487,7 +487,7 @@ inline bool do_replay_events(std::vector<test_event_entry>& events)
|
||||
|
||||
cryptonote::cryptonote_protocol_stub pr; //TODO: stub only for this kind of test, make real validation of relayed objects
|
||||
cryptonote::core c(&pr);
|
||||
if (!c.init(vm))
|
||||
if (!c.init(vm, false))
|
||||
{
|
||||
std::cout << concolor::magenta << "Failed to init core" << concolor::normal << std::endl;
|
||||
return false;
|
||||
|
@ -54,7 +54,7 @@ bool test_transaction_generation_and_ring_signature()
|
||||
account_base miner_acc6;
|
||||
miner_acc6.generate();
|
||||
|
||||
std::string add_str = miner_acc3.get_public_address_str();
|
||||
std::string add_str = miner_acc3.get_public_address_str(false);
|
||||
|
||||
|
||||
account_base rv_acc;
|
||||
@ -150,7 +150,7 @@ bool test_block_creation()
|
||||
uint64_t vszs[] = {80,476,476,475,475,474,475,474,474,475,472,476,476,475,475,474,475,474,474,475,472,476,476,475,475,474,475,474,474,475,9391,476,476,475,475,474,475,8819,8301,475,472,4302,5316,14347,16620,19583,19403,19728,19442,19852,19015,19000,19016,19795,19749,18087,19787,19704,19750,19267,19006,19050,19445,19407,19522,19546,19788,19369,19486,19329,19370,18853,19600,19110,19320,19746,19474,19474,19743,19494,19755,19715,19769,19620,19368,19839,19532,23424,28287,30707};
|
||||
std::vector<uint64_t> szs(&vszs[0], &vszs[90]);
|
||||
account_public_address adr;
|
||||
bool r = get_account_address_from_str(adr, "0099be99c70ef10fd534c43c88e9d13d1c8853213df7e362afbec0e4ee6fec4948d0c190b58f4b356cd7feaf8d9d0a76e7c7e5a9a0a497a6b1faf7a765882dd08ac2");
|
||||
bool r = get_account_address_from_str(adr, false, "0099be99c70ef10fd534c43c88e9d13d1c8853213df7e362afbec0e4ee6fec4948d0c190b58f4b356cd7feaf8d9d0a76e7c7e5a9a0a497a6b1faf7a765882dd08ac2");
|
||||
CHECK_AND_ASSERT_MES(r, false, "failed to import");
|
||||
block b;
|
||||
r = construct_miner_tx(90, epee::misc_utils::median(szs), 3553616528562147, 33094, 10000000, adr, b.miner_tx, blobdata(), 11);
|
||||
|
@ -54,7 +54,7 @@ TEST(Transfers, Transfers)
|
||||
miner.generate();
|
||||
ASSERT_TRUE(miner.init());
|
||||
ASSERT_TRUE(miner.store("miner.b2wallet"));
|
||||
cout << "miner: " << miner.get_account().get_public_address_str() << endl;
|
||||
cout << "miner: " << miner.get_account().get_public_address_str(false) << endl;
|
||||
|
||||
for (int i = 0; i < ACCS; i++) {
|
||||
ostringstream s;
|
||||
@ -69,7 +69,7 @@ TEST(Transfers, Transfers)
|
||||
|
||||
{
|
||||
COMMAND_RPC_START_MINE::request req;
|
||||
req.miner_address = miner.get_account().get_public_address_str();
|
||||
req.miner_address = miner.get_account().get_public_address_str(false);
|
||||
req.threads_count = 1;
|
||||
COMMAND_RPC_START_MINE::response res;
|
||||
bool r = net_utils::http::invoke_http_json_remote_command(daemon_address + "/start_mine", req, res, http_client);
|
||||
|
@ -37,6 +37,12 @@ using namespace epee;
|
||||
#include "wallet/wallet2.h"
|
||||
using namespace cryptonote;
|
||||
|
||||
namespace
|
||||
{
|
||||
uint64_t const TEST_FEE = 5000000000; // 5 * 10^9
|
||||
uint64_t const TEST_DUST_THRESHOLD = 5000000000; // 5 * 10^9
|
||||
}
|
||||
|
||||
std::string generate_random_wallet_name()
|
||||
{
|
||||
std::stringstream ss;
|
||||
@ -79,7 +85,7 @@ bool do_send_money(tools::wallet2& w1, tools::wallet2& w2, size_t mix_in_factor,
|
||||
try
|
||||
{
|
||||
tools::wallet2::pending_tx ptx;
|
||||
w1.transfer(dsts, mix_in_factor, 0, DEFAULT_FEE, std::vector<uint8_t>(), tools::detail::null_split_strategy, tools::tx_dust_policy(DEFAULT_FEE), tx, ptx);
|
||||
w1.transfer(dsts, mix_in_factor, 0, TEST_FEE, std::vector<uint8_t>(), tools::detail::null_split_strategy, tools::tx_dust_policy(TEST_DUST_THRESHOLD), tx, ptx);
|
||||
w1.commit_tx(ptx);
|
||||
return true;
|
||||
}
|
||||
@ -145,8 +151,8 @@ bool transactions_flow_test(std::string& working_folder,
|
||||
w2.init(daemon_addr_b);
|
||||
|
||||
LOG_PRINT_GREEN("Using wallets: " << ENDL
|
||||
<< "Source: " << w1.get_account().get_public_address_str() << ENDL << "Path: " << working_folder + "/" + path_source_wallet << ENDL
|
||||
<< "Target: " << w2.get_account().get_public_address_str() << ENDL << "Path: " << working_folder + "/" + path_terget_wallet, LOG_LEVEL_1);
|
||||
<< "Source: " << w1.get_account().get_public_address_str(false) << ENDL << "Path: " << working_folder + "/" + path_source_wallet << ENDL
|
||||
<< "Target: " << w2.get_account().get_public_address_str(false) << ENDL << "Path: " << working_folder + "/" + path_terget_wallet, LOG_LEVEL_1);
|
||||
|
||||
//lets do some money
|
||||
epee::net_utils::http::http_simple_client http_client;
|
||||
@ -157,7 +163,7 @@ bool transactions_flow_test(std::string& working_folder,
|
||||
|
||||
COMMAND_RPC_START_MINING::request daemon_req = AUTO_VAL_INIT(daemon_req);
|
||||
COMMAND_RPC_START_MINING::response daemon_rsp = AUTO_VAL_INIT(daemon_rsp);
|
||||
daemon_req.miner_address = w1.get_account().get_public_address_str();
|
||||
daemon_req.miner_address = w1.get_account().get_public_address_str(false);
|
||||
daemon_req.threads_count = 9;
|
||||
r = net_utils::invoke_http_json_remote_command2(daemon_addr_a + "/start_mining", daemon_req, daemon_rsp, http_client, 10000);
|
||||
CHECK_AND_ASSERT_MES(r, false, "failed to get getrandom_outs");
|
||||
@ -185,7 +191,7 @@ bool transactions_flow_test(std::string& working_folder,
|
||||
BOOST_FOREACH(tools::wallet2::transfer_details& td, incoming_transfers)
|
||||
{
|
||||
cryptonote::transaction tx_s;
|
||||
bool r = do_send_money(w1, w1, 0, td.m_tx.vout[td.m_internal_output_index].amount - DEFAULT_FEE, tx_s, 50);
|
||||
bool r = do_send_money(w1, w1, 0, td.m_tx.vout[td.m_internal_output_index].amount - TEST_FEE, tx_s, 50);
|
||||
CHECK_AND_ASSERT_MES(r, false, "Failed to send starter tx " << get_transaction_hash(tx_s));
|
||||
LOG_PRINT_GREEN("Starter transaction sent " << get_transaction_hash(tx_s), LOG_LEVEL_0);
|
||||
if(++count >= FIRST_N_TRANSFERS)
|
||||
@ -213,7 +219,7 @@ bool transactions_flow_test(std::string& working_folder,
|
||||
for(i = 0; i != transactions_count; i++)
|
||||
{
|
||||
uint64_t amount_to_tx = (amount_to_transfer - transfered_money) > transfer_size ? transfer_size: (amount_to_transfer - transfered_money);
|
||||
while(w1.unlocked_balance() < amount_to_tx + DEFAULT_FEE)
|
||||
while(w1.unlocked_balance() < amount_to_tx + TEST_FEE)
|
||||
{
|
||||
misc_utils::sleep_no_w(1000);
|
||||
LOG_PRINT_L0("not enough money, waiting for cashback or mining");
|
||||
|
@ -473,14 +473,14 @@ TEST(get_account_address_as_str, works_correctly)
|
||||
{
|
||||
cryptonote::account_public_address addr;
|
||||
ASSERT_TRUE(serialization::parse_binary(test_serialized_keys, addr));
|
||||
std::string addr_str = cryptonote::get_account_address_as_str(addr);
|
||||
std::string addr_str = cryptonote::get_account_address_as_str(false, addr);
|
||||
ASSERT_EQ(addr_str, test_keys_addr_str);
|
||||
}
|
||||
|
||||
TEST(get_account_address_from_str, handles_valid_address)
|
||||
{
|
||||
cryptonote::account_public_address addr;
|
||||
ASSERT_TRUE(cryptonote::get_account_address_from_str(addr, test_keys_addr_str));
|
||||
ASSERT_TRUE(cryptonote::get_account_address_from_str(addr, false, test_keys_addr_str));
|
||||
|
||||
std::string blob;
|
||||
ASSERT_TRUE(serialization::dump_binary(addr, blob));
|
||||
@ -493,7 +493,7 @@ TEST(get_account_address_from_str, fails_on_invalid_address_format)
|
||||
std::string addr_str = test_keys_addr_str;
|
||||
addr_str[0] = '0';
|
||||
|
||||
ASSERT_FALSE(cryptonote::get_account_address_from_str(addr, addr_str));
|
||||
ASSERT_FALSE(cryptonote::get_account_address_from_str(addr, false, addr_str));
|
||||
}
|
||||
|
||||
TEST(get_account_address_from_str, fails_on_invalid_address_prefix)
|
||||
@ -501,39 +501,39 @@ TEST(get_account_address_from_str, fails_on_invalid_address_prefix)
|
||||
std::string addr_str = base58::encode_addr(0, test_serialized_keys);
|
||||
|
||||
cryptonote::account_public_address addr;
|
||||
ASSERT_FALSE(cryptonote::get_account_address_from_str(addr, addr_str));
|
||||
ASSERT_FALSE(cryptonote::get_account_address_from_str(addr, false, addr_str));
|
||||
}
|
||||
|
||||
TEST(get_account_address_from_str, fails_on_invalid_address_content)
|
||||
{
|
||||
std::string addr_str = base58::encode_addr(CRYPTONOTE_PUBLIC_ADDRESS_BASE58_PREFIX, test_serialized_keys.substr(1));
|
||||
std::string addr_str = base58::encode_addr(config::CRYPTONOTE_PUBLIC_ADDRESS_BASE58_PREFIX, test_serialized_keys.substr(1));
|
||||
|
||||
cryptonote::account_public_address addr;
|
||||
ASSERT_FALSE(cryptonote::get_account_address_from_str(addr, addr_str));
|
||||
ASSERT_FALSE(cryptonote::get_account_address_from_str(addr, false, addr_str));
|
||||
}
|
||||
|
||||
TEST(get_account_address_from_str, fails_on_invalid_address_spend_key)
|
||||
{
|
||||
std::string serialized_keys_copy = test_serialized_keys;
|
||||
serialized_keys_copy[0] = '\0';
|
||||
std::string addr_str = base58::encode_addr(CRYPTONOTE_PUBLIC_ADDRESS_BASE58_PREFIX, serialized_keys_copy);
|
||||
std::string addr_str = base58::encode_addr(config::CRYPTONOTE_PUBLIC_ADDRESS_BASE58_PREFIX, serialized_keys_copy);
|
||||
|
||||
cryptonote::account_public_address addr;
|
||||
ASSERT_FALSE(cryptonote::get_account_address_from_str(addr, addr_str));
|
||||
ASSERT_FALSE(cryptonote::get_account_address_from_str(addr, false, addr_str));
|
||||
}
|
||||
|
||||
TEST(get_account_address_from_str, fails_on_invalid_address_view_key)
|
||||
{
|
||||
std::string serialized_keys_copy = test_serialized_keys;
|
||||
serialized_keys_copy.back() = '\x01';
|
||||
std::string addr_str = base58::encode_addr(CRYPTONOTE_PUBLIC_ADDRESS_BASE58_PREFIX, serialized_keys_copy);
|
||||
std::string addr_str = base58::encode_addr(config::CRYPTONOTE_PUBLIC_ADDRESS_BASE58_PREFIX, serialized_keys_copy);
|
||||
|
||||
cryptonote::account_public_address addr;
|
||||
ASSERT_FALSE(cryptonote::get_account_address_from_str(addr, addr_str));
|
||||
ASSERT_FALSE(cryptonote::get_account_address_from_str(addr, false, addr_str));
|
||||
}
|
||||
|
||||
TEST(get_account_address_from_str, parses_old_address_format)
|
||||
{
|
||||
cryptonote::account_public_address addr;
|
||||
ASSERT_TRUE(cryptonote::get_account_address_from_str(addr, "002391bbbb24dea6fd95232e97594a27769d0153d053d2102b789c498f57a2b00b69cd6f2f5c529c1660f2f4a2b50178d6640c20ce71fe26373041af97c5b10236fc"));
|
||||
ASSERT_TRUE(cryptonote::get_account_address_from_str(addr, false, "002391bbbb24dea6fd95232e97594a27769d0153d053d2102b789c498f57a2b00b69cd6f2f5c529c1660f2f4a2b50178d6640c20ce71fe26373041af97c5b10236fc"));
|
||||
}
|
||||
|
@ -35,6 +35,10 @@
|
||||
#include "common/util.h"
|
||||
#include "cryptonote_core/cryptonote_format_utils.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
uint64_t const TEST_FEE = 5000000000; // 5 * 10^9
|
||||
}
|
||||
|
||||
TEST(parse_tx_extra, handles_empty_extra)
|
||||
{
|
||||
@ -135,7 +139,7 @@ TEST(parse_and_validate_tx_extra, is_valid_tx_extra_parsed)
|
||||
cryptonote::account_base acc;
|
||||
acc.generate();
|
||||
cryptonote::blobdata b = "dsdsdfsdfsf";
|
||||
ASSERT_TRUE(cryptonote::construct_miner_tx(0, 0, 10000000000000, 1000, DEFAULT_FEE, acc.get_keys().m_account_address, tx, b, 1));
|
||||
ASSERT_TRUE(cryptonote::construct_miner_tx(0, 0, 10000000000000, 1000, TEST_FEE, acc.get_keys().m_account_address, tx, b, 1));
|
||||
crypto::public_key tx_pub_key = cryptonote::get_tx_pub_key_from_extra(tx);
|
||||
ASSERT_NE(tx_pub_key, cryptonote::null_pkey);
|
||||
}
|
||||
@ -145,7 +149,7 @@ TEST(parse_and_validate_tx_extra, fails_on_big_extra_nonce)
|
||||
cryptonote::account_base acc;
|
||||
acc.generate();
|
||||
cryptonote::blobdata b(TX_EXTRA_NONCE_MAX_COUNT + 1, 0);
|
||||
ASSERT_FALSE(cryptonote::construct_miner_tx(0, 0, 10000000000000, 1000, DEFAULT_FEE, acc.get_keys().m_account_address, tx, b, 1));
|
||||
ASSERT_FALSE(cryptonote::construct_miner_tx(0, 0, 10000000000000, 1000, TEST_FEE, acc.get_keys().m_account_address, tx, b, 1));
|
||||
}
|
||||
TEST(parse_and_validate_tx_extra, fails_on_wrong_size_in_extra_nonce)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user