moved all stuff to github

This commit is contained in:
Antonio Juarez 2014-03-03 22:07:58 +00:00
parent 095fbeeb67
commit 296ae46ed8
388 changed files with 95937 additions and 469 deletions

View file

@ -0,0 +1,112 @@
// Copyright (c) 2012-2013 The Cryptonote developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <boost/program_options.hpp>
#include "include_base_utils.h"
using namespace epee;
#include "common/command_line.h"
#include "transactions_flow_test.h"
namespace po = boost::program_options;
namespace
{
const command_line::arg_descriptor<bool> arg_test_transactions_flow = {"test_transactions_flow", ""};
const command_line::arg_descriptor<std::string> arg_working_folder = {"working-folder", "", "."};
const command_line::arg_descriptor<std::string> arg_source_wallet = {"source-wallet", "", "", true};
const command_line::arg_descriptor<std::string> arg_dest_wallet = {"dest-wallet", "", "", true};
const command_line::arg_descriptor<std::string> arg_daemon_addr_a = {"daemon-addr-a", "", "127.0.0.1:8080"};
const command_line::arg_descriptor<std::string> arg_daemon_addr_b = {"daemon-addr-b", "", "127.0.0.1:8082"};
const command_line::arg_descriptor<uint64_t> arg_transfer_amount = {"transfer_amount", "", 60000000000000};
const command_line::arg_descriptor<size_t> arg_mix_in_factor = {"mix-in-factor", "", 10};
const command_line::arg_descriptor<size_t> arg_tx_count = {"tx-count", "", 100};
const command_line::arg_descriptor<size_t> arg_tx_per_second = {"tx-per-second", "", 20};
const command_line::arg_descriptor<size_t> arg_test_repeat_count = {"test_repeat_count", "", 1};
}
int main(int argc, char* argv[])
{
TRY_ENTRY();
string_tools::set_module_name_and_folder(argv[0]);
//set up logging options
log_space::get_set_log_detalisation_level(true, LOG_LEVEL_3);
log_space::log_singletone::add_logger(LOGGER_CONSOLE, NULL, NULL, LOG_LEVEL_2);
log_space::log_singletone::add_logger(LOGGER_FILE,
log_space::log_singletone::get_default_log_file().c_str(),
log_space::log_singletone::get_default_log_folder().c_str());
po::options_description desc_options("Allowed options");
command_line::add_arg(desc_options, command_line::arg_help);
command_line::add_arg(desc_options, arg_test_transactions_flow);
command_line::add_arg(desc_options, arg_working_folder);
command_line::add_arg(desc_options, arg_source_wallet);
command_line::add_arg(desc_options, arg_dest_wallet);
command_line::add_arg(desc_options, arg_daemon_addr_a);
command_line::add_arg(desc_options, arg_daemon_addr_b);
command_line::add_arg(desc_options, arg_transfer_amount);
command_line::add_arg(desc_options, arg_mix_in_factor);
command_line::add_arg(desc_options, arg_tx_count);
command_line::add_arg(desc_options, arg_tx_per_second);
command_line::add_arg(desc_options, arg_test_repeat_count);
po::variables_map vm;
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))
{
std::cout << desc_options << std::endl;
return 0;
}
if (command_line::get_arg(vm, arg_test_transactions_flow))
{
std::string working_folder = command_line::get_arg(vm, arg_working_folder);
std::string path_source_wallet, path_target_wallet;
if(command_line::has_arg(vm, arg_source_wallet))
path_source_wallet = command_line::get_arg(vm, arg_source_wallet);
if(command_line::has_arg(vm, arg_dest_wallet))
path_target_wallet = command_line::get_arg(vm, arg_dest_wallet);
std::string daemon_addr_a = command_line::get_arg(vm, arg_daemon_addr_a);
std::string daemon_addr_b = command_line::get_arg(vm, arg_daemon_addr_b);
uint64_t amount_to_transfer = command_line::get_arg(vm, arg_transfer_amount);
size_t mix_in_factor = command_line::get_arg(vm, arg_mix_in_factor);
size_t transactions_count = command_line::get_arg(vm, arg_tx_count);
size_t transactions_per_second = command_line::get_arg(vm, arg_tx_per_second);
size_t repeat_count = command_line::get_arg(vm, arg_test_repeat_count);
for(size_t i = 0; i != repeat_count; i++)
if(!transactions_flow_test(working_folder, path_source_wallet, path_target_wallet, daemon_addr_a, daemon_addr_b, amount_to_transfer, mix_in_factor, transactions_count, transactions_per_second))
break;
std::string s;
std::cin >> s;
return 1;
}
else
{
std::cout << desc_options << std::endl;
return 1;
}
CATCH_ENTRY_L0("main", 1);
return 0;
}

View file

@ -0,0 +1,269 @@
// Copyright (c) 2012-2013 The Cryptonote developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <boost/uuid/uuid.hpp>
#include <boost/uuid/random_generator.hpp>
#include <unordered_map>
#include "include_base_utils.h"
using namespace epee;
#include "wallet/wallet2.h"
using namespace cryptonote;
std::string generate_random_wallet_name()
{
std::stringstream ss;
ss << boost::uuids::random_generator()();
return ss.str();
}
inline uint64_t random(const uint64_t max_value) {
return (uint64_t(rand()) ^
(uint64_t(rand())<<16) ^
(uint64_t(rand())<<32) ^
(uint64_t(rand())<<48)) % max_value;
}
bool do_send_money(tools::wallet2& w1, tools::wallet2& w2, size_t mix_in_factor, uint64_t amount_to_transfer, transaction& tx, size_t parts=1)
{
CHECK_AND_ASSERT_MES(parts > 0, false, "parts must be > 0");
std::vector<cryptonote::tx_destination_entry> dsts;
dsts.reserve(parts);
uint64_t amount_used = 0;
uint64_t max_part = amount_to_transfer / parts;
for (size_t i = 0; i < parts; ++i)
{
cryptonote::tx_destination_entry de;
de.addr = w2.get_account().get_keys().m_account_address;
if (i < parts - 1)
de.amount = random(max_part);
else
de.amount = amount_to_transfer - amount_used;
amount_used += de.amount;
//std::cout << "PARTS (" << amount_to_transfer << ") " << amount_used << " " << de.amount << std::endl;
dsts.push_back(de);
}
return w1.transfer(dsts, mix_in_factor, 0, DEFAULT_FEE, tools::detail::null_split_strategy, tools::wallet2::tx_dust_policy(DEFAULT_FEE), tx);
}
uint64_t get_money_in_first_transfers(const tools::wallet2::transfer_container& incoming_transfers, size_t n_transfers)
{
uint64_t summ = 0;
size_t count = 0;
BOOST_FOREACH(const tools::wallet2::transfer_details& td, incoming_transfers)
{
summ += td.m_tx.vout[td.m_internal_output_index].amount;
if(++count >= n_transfers)
return summ;
}
return summ;
}
#define FIRST_N_TRANSFERS 10*10
bool transactions_flow_test(std::string& working_folder,
std::string path_source_wallet,
std::string path_terget_wallet,
std::string& daemon_addr_a,
std::string& daemon_addr_b,
uint64_t amount_to_transfer, size_t mix_in_factor, size_t transactions_count, size_t transactions_per_second)
{
LOG_PRINT_L0("-----------------------STARTING TRANSACTIONS FLOW TEST-----------------------");
tools::wallet2 w1, w2;
if(path_source_wallet.empty())
path_source_wallet = generate_random_wallet_name();
if(path_terget_wallet.empty())
path_terget_wallet = generate_random_wallet_name();
if(!w1.generate(working_folder + "/" + path_source_wallet, ""))
{
LOG_ERROR("failed to load source wallet from " << path_source_wallet);
return false;
}
if(!w2.generate(working_folder + "/" + path_terget_wallet, ""))
{
LOG_ERROR( "failed to generate target load wallet from " << path_source_wallet );
return false;
}
if(!w1.init(daemon_addr_a))
{
LOG_ERROR("failed to init source wallet from " << daemon_addr_a );
return false;
}
size_t blocks_fetched = 0;
if(!w1.refresh(blocks_fetched))
{
LOG_ERROR( "failed to refresh source wallet from " << daemon_addr_a );
return false;
}
if(!w2.init(daemon_addr_b))
{
LOG_ERROR( "failed to init target wallet from " << daemon_addr_b );
return false;
}
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);
//lets do some money
epee::net_utils::http::http_simple_client http_client;
COMMAND_RPC_STOP_MINING::request daemon1_req = AUTO_VAL_INIT(daemon1_req);
COMMAND_RPC_STOP_MINING::response daemon1_rsp = AUTO_VAL_INIT(daemon1_rsp);
bool r = net_utils::invoke_http_json_remote_command2(daemon_addr_a + "/stop_mine", daemon1_req, daemon1_rsp, http_client, 10000);
CHECK_AND_ASSERT_MES(r, false, "failed to stop mining");
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.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");
CHECK_AND_ASSERT_MES(daemon_rsp.status == CORE_RPC_STATUS_OK, false, "failed to getrandom_outs.bin");
//wait for money, until balance will have enough money
w1.refresh(blocks_fetched);
while(w1.unlocked_balance() < amount_to_transfer)
{
misc_utils::sleep_no_w(1000);
w1.refresh(blocks_fetched);
}
//lets make a lot of small outs to ourselves
//since it is not possible to start from transaction that bigger than 20Kb, we gonna make transactions
//with 500 outs (about 18kb), and we have to wait appropriate count blocks, mined for test wallet
while(true)
{
tools::wallet2::transfer_container incoming_transfers;
w1.get_transfers(incoming_transfers);
if(incoming_transfers.size() > FIRST_N_TRANSFERS && get_money_in_first_transfers(incoming_transfers, FIRST_N_TRANSFERS) < w1.unlocked_balance() )
{
//lets go!
size_t count = 0;
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);
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)
break;
}
break;
}else
{
misc_utils::sleep_no_w(1000);
w1.refresh();
}
}
//do actual transfer
uint64_t transfered_money = 0;
uint64_t transfer_size = amount_to_transfer/transactions_count;
size_t i = 0;
struct tx_test_entry
{
transaction tx;
size_t m_received_count;
uint64_t amount_transfered;
};
crypto::key_image lst_sent_ki = AUTO_VAL_INIT(lst_sent_ki);
std::unordered_map<crypto::hash, tx_test_entry> txs;
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)
{
misc_utils::sleep_no_w(1000);
LOG_PRINT_L0("not enough money, waiting for cashback or mining");
w1.refresh(blocks_fetched);
}
transaction tx;
/*size_t n_attempts = 0;
while (!do_send_money(w1, w2, mix_in_factor, amount_to_tx, tx)) {
n_attempts++;
std::cout << "failed to transfer money, refresh and try again (attempts=" << n_attempts << ")" << std::endl;
w1.refresh();
}*/
if(!do_send_money(w1, w2, mix_in_factor, amount_to_tx, tx))
{
LOG_PRINT_L0("failed to transfer money, tx: " << get_transaction_hash(tx) << ", refresh and try again" );
w1.refresh(blocks_fetched);
if(!do_send_money(w1, w2, mix_in_factor, amount_to_tx, tx))
{
LOG_PRINT_L0( "failed to transfer money, second chance. tx: " << get_transaction_hash(tx) << ", exit" );
LOCAL_ASSERT(false);
return false;
}
}
lst_sent_ki = boost::get<txin_to_key>(tx.vin[0]).k_image;
transfered_money += amount_to_tx;
LOG_PRINT_L0("transferred " << amount_to_tx << ", i=" << i );
tx_test_entry& ent = txs[get_transaction_hash(tx)] = boost::value_initialized<tx_test_entry>();
ent.amount_transfered = amount_to_tx;
ent.tx = tx;
//if(i % transactions_per_second)
// misc_utils::sleep_no_w(1000);
}
LOG_PRINT_L0( "waiting some new blocks...");
misc_utils::sleep_no_w(DIFFICULTY_BLOCKS_ESTIMATE_TIMESPAN*20*1000);//wait two blocks before sync on another wallet on another daemon
LOG_PRINT_L0( "refreshing...");
bool recvd_money = false;
while(w2.refresh(blocks_fetched, recvd_money) && ( (blocks_fetched && recvd_money) || !blocks_fetched ) )
{
misc_utils::sleep_no_w(DIFFICULTY_BLOCKS_ESTIMATE_TIMESPAN*1000);//wait two blocks before sync on another wallet on another daemon
}
uint64_t money_2 = w2.balance();
if(money_2 == transfered_money)
{
LOG_PRINT_GREEN("-----------------------FINISHING TRANSACTIONS FLOW TEST OK-----------------------", LOG_LEVEL_0);
LOG_PRINT_GREEN("transferred " << print_money(transfered_money) << " via " << i << " transactions" , LOG_LEVEL_0);
return true;
}else
{
tools::wallet2::transfer_container tc;
w2.get_transfers(tc);
BOOST_FOREACH(tools::wallet2::transfer_details& td, tc)
{
auto it = txs.find(get_transaction_hash(td.m_tx));
CHECK_AND_ASSERT_MES(it != txs.end(), false, "transaction not found in local cache");
it->second.m_received_count += 1;
}
BOOST_FOREACH(auto& tx_pair, txs)
{
if(tx_pair.second.m_received_count != 1)
{
LOG_PRINT_RED_L0("Transaction lost: " << get_transaction_hash(tx_pair.second.tx));
}
}
LOG_PRINT_RED_L0("-----------------------FINISHING TRANSACTIONS FLOW TEST FAILED-----------------------" );
LOG_PRINT_RED_L0("income " << print_money(money_2) << " via " << i << " transactions, expected money = " << print_money(transfered_money) );
LOCAL_ASSERT(false);
return false;
}
return true;
}

View file

@ -0,0 +1,12 @@
// Copyright (c) 2012-2013 The Cryptonote developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
bool transactions_flow_test(std::string& working_folder,
std::string path_source_wallet,
std::string path_terget_wallet,
std::string& daemon_addr_a,
std::string& daemon_addr_b,
uint64_t amount_to_transfer, size_t mix_in_factor, size_t transactions_count, size_t transactions_per_second);

View file

@ -0,0 +1,128 @@
// Copyright (c) 2012-2013 The Cryptonote developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "include_base_utils.h"
using namespace epee;
#include "wallet/wallet2.h"
#include "cryptonote_core/blockchain_storage.h"
using namespace cryptonote;
/*
bool transactions_generation_from_blockchain(std::string& blockchain_folder_path)
{
string_tools::parse_hexstr_to_binbuff()
tx_memory_pool pool;
blockchain_storage bchs(pool);
bool r = bchs.init(blockchain_folder_path);
CHECK_AND_ASSERT_MES(r, false, "failed to load blockchain");
//amount = 3000000000000
//key_offsets = 1,2,3,4,5,10,12,27,31,33,34
//
}
tx_source_entry::output_entry make_outptu_entr_for_gindex(size_t i, std::map<crypto::hash, transaction>& txs, std::vector<std::pair<crypto::hash, size_t> >& v)
{
tx_source_entry::output_entry oe;
oe = i;
oe.second = txs[v[i].first].boost::get<txout_to_key>(vout[v[i].second].target).key;
return oe;
}
bool make_tx(blockchain_storage& bch)
{
std::map<crypto::hash, transaction> txs;
std::vector<std::pair<crypto::hash, size_t> > v;
bch.get_outs_for_amounts(3000000000000, v);
std::vector<tx_source_entry> sources(11);
sources[0].amount = 3000000000000;
sources[0].outputs.push_back(make_outptu_entr_for_gindex(1, txs, v));
sources[0].outputs.push_back(make_outptu_entr_for_gindex(2, txs, v));
sources[0].outputs.push_back(make_outptu_entr_for_gindex(3, txs, v));
sources[0].outputs.push_back(make_outptu_entr_for_gindex(4, txs, v));
sources[0].outputs.push_back(make_outptu_entr_for_gindex(5, txs, v));
sources[0].outputs.push_back(make_outptu_entr_for_gindex(10, txs, v));
sources[0].outputs.push_back(make_outptu_entr_for_gindex(12, txs, v));
sources[0].outputs.push_back(make_outptu_entr_for_gindex(27, txs, v));
sources[0].outputs.push_back(make_outptu_entr_for_gindex(31, txs, v));
sources[0].outputs.push_back(make_outptu_entr_for_gindex(33, txs, v));
sources[0].outputs.push_back(make_outptu_entr_for_gindex(34, txs, v));
sources[0].real_out_tx_key =
BOOST_FOREACH(transfer_container::iterator it, selected_transfers)
{
sources.resize(sources.size()+1);
cryptonote::tx_source_entry& src = sources.back();
transfer_details& td = *it;
src.amount = td.m_tx.vout[td.m_internal_output_index].amount;
//paste mixin transaction
if(daemon_resp.outs.size())
{
daemon_resp.outs[i].outs.sort([](const out_entry& a, const out_entry& b){return a.global_amount_index < b.global_amount_index;});
BOOST_FOREACH(out_entry& daemon_oe, daemon_resp.outs[i].outs)
{
if(td.m_global_output_index == daemon_oe.global_amount_index)
continue;
tx_output_entry oe;
oe.first = daemon_oe.global_amount_index;
oe.second = daemon_oe.out_key;
src.outputs.push_back(oe);
if(src.outputs.size() >= fake_outputs_count)
break;
}
}
//paste real transaction to the random index
auto it_to_insert = std::find_if(src.outputs.begin(), src.outputs.end(), [&](const tx_output_entry& a)
{
return a.first >= td.m_global_output_index;
});
//size_t real_index = src.outputs.size() ? (rand() % src.outputs.size() ):0;
tx_output_entry real_oe;
real_oe.first = td.m_global_output_index;
real_oe.second = boost::get<txout_to_key>(td.m_tx.vout[td.m_internal_output_index].target).key;
auto interted_it = src.outputs.insert(it_to_insert, real_oe);
src.real_out_tx_key = td.m_tx.tx_pub_key;
src.real_output = interted_it - src.outputs.begin();
src.real_output_in_tx_index = td.m_internal_output_index;
++i;
}
if(found_money != needed_money)
{
//lets make last output to odd money
dsts.resize(dsts.size()+1);
cryptonote::tx_destination_entry& destination = dsts.back();
CHECK_AND_ASSERT_MES(found_money > needed_money, false, "internal error found_money=" << found_money << " !> needed_money=" << needed_money);
destination.amount = found_money - needed_money;
}
transaction tx;
bool r = cryptonote::construct_tx(m_account.get_keys(), sources, dsts, tx, unlock_time);
if(!r)
{
std::cout << "transaction construction failed" << std::endl;
}
COMMAND_RPC_SEND_RAW_TX::request req;
req.tx_as_hex = epee::string_tools::buff_to_hex_nodelimer(tx_to_blob(tx));
COMMAND_RPC_SEND_RAW_TX::response daemon_send_resp;
r = net_utils::http::invoke_http_json_remote_command(m_daemon_address + "/sendrawtransaction", req, daemon_send_resp, m_http_client);
CHECK_AND_ASSERT_MES(r, false, "failed to send transaction");
if(daemon_send_resp.status != CORE_RPC_STATUS_OK)
{
std::cout << "daemon failed to accept generated transaction" << ENDL;
return false;
}
std::cout << "transaction generated ok and sent to daemon" << std::endl;
BOOST_FOREACH(transfer_container::iterator it, selected_transfers)
it->m_spent = true;
return true;
}*/

View file

@ -0,0 +1,7 @@
// Copyright (c) 2012-2013 The Cryptonote developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
bool transactions_generation_from_blockchain(std::string& blockchain_path);