Merge pull request #496
db1fb66
wallet: storing outgoing tx info now defaults to enabled (moneromooo-monero)9156ba3
wallet: rename store-tx-keys to store-tx-info (moneromooo-monero)b3d4d41
wallet: improve show_transfers (moneromooo-monero)725ae4e
wallet: use incoming blocks to keep track of payments too (moneromooo-monero)00790a8
simplewallet: lessen display flicker confusion (moneromooo-monero)
This commit is contained in:
commit
72a348e734
@ -335,7 +335,7 @@ bool simple_wallet::set_always_confirm_transfers(const std::vector<std::string>
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool simple_wallet::set_store_tx_keys(const std::vector<std::string> &args/* = std::vector<std::string>()*/)
|
bool simple_wallet::set_store_tx_info(const std::vector<std::string> &args/* = std::vector<std::string>()*/)
|
||||||
{
|
{
|
||||||
bool success = false;
|
bool success = false;
|
||||||
if (m_wallet->watch_only())
|
if (m_wallet->watch_only())
|
||||||
@ -359,7 +359,7 @@ bool simple_wallet::set_store_tx_keys(const std::vector<std::string> &args/* = s
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_wallet->store_tx_keys(is_it_true(args[1]));
|
m_wallet->store_tx_info(is_it_true(args[1]));
|
||||||
m_wallet->rewrite(m_wallet_file, pwd_container.password());
|
m_wallet->rewrite(m_wallet_file, pwd_container.password());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -449,7 +449,7 @@ simple_wallet::simple_wallet()
|
|||||||
m_cmd_binder.set_handler("viewkey", boost::bind(&simple_wallet::viewkey, this, _1), tr("Get viewkey"));
|
m_cmd_binder.set_handler("viewkey", boost::bind(&simple_wallet::viewkey, this, _1), tr("Get viewkey"));
|
||||||
m_cmd_binder.set_handler("spendkey", boost::bind(&simple_wallet::spendkey, this, _1), tr("Get spendkey"));
|
m_cmd_binder.set_handler("spendkey", boost::bind(&simple_wallet::spendkey, this, _1), tr("Get spendkey"));
|
||||||
m_cmd_binder.set_handler("seed", boost::bind(&simple_wallet::seed, this, _1), tr("Get deterministic seed"));
|
m_cmd_binder.set_handler("seed", boost::bind(&simple_wallet::seed, this, _1), tr("Get deterministic seed"));
|
||||||
m_cmd_binder.set_handler("set", boost::bind(&simple_wallet::set_variable, this, _1), tr("available options: seed language - Set wallet seed langage; always-confirm-transfers <1|0> - whether to confirm unsplit txes; store-tx-keys <1|0> - whether to store per-tx private keys for future reference; default_mixin <n> - set default mixin (default default is 4"));
|
m_cmd_binder.set_handler("set", boost::bind(&simple_wallet::set_variable, this, _1), tr("available options: seed language - Set wallet seed langage; always-confirm-transfers <1|0> - whether to confirm unsplit txes; store-tx-info <1|0> - whether to store per outgoing tx info (destination address, payment id, tx secret key) for future reference; default_mixin <n> - set default mixin (default default is 4"));
|
||||||
m_cmd_binder.set_handler("rescan_spent", boost::bind(&simple_wallet::rescan_spent, this, _1), tr("Rescan blockchain for spent outputs"));
|
m_cmd_binder.set_handler("rescan_spent", boost::bind(&simple_wallet::rescan_spent, this, _1), tr("Rescan blockchain for spent outputs"));
|
||||||
m_cmd_binder.set_handler("get_tx_key", boost::bind(&simple_wallet::get_tx_key, this, _1), tr("Get transaction key (r) for a given tx"));
|
m_cmd_binder.set_handler("get_tx_key", boost::bind(&simple_wallet::get_tx_key, this, _1), tr("Get transaction key (r) for a given tx"));
|
||||||
m_cmd_binder.set_handler("check_tx_key", boost::bind(&simple_wallet::check_tx_key, this, _1), tr("Check amount going to a given address in a partcular tx"));
|
m_cmd_binder.set_handler("check_tx_key", boost::bind(&simple_wallet::check_tx_key, this, _1), tr("Check amount going to a given address in a partcular tx"));
|
||||||
@ -496,18 +496,18 @@ bool simple_wallet::set_variable(const std::vector<std::string> &args)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (args[0] == "store-tx-keys")
|
else if (args[0] == "store-tx-info")
|
||||||
{
|
{
|
||||||
if (args.size() <= 1)
|
if (args.size() <= 1)
|
||||||
{
|
{
|
||||||
fail_msg_writer() << tr("set store-tx-keys: needs an argument (0 or 1)");
|
fail_msg_writer() << tr("set store-tx-info: needs an argument (0 or 1)");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::vector<std::string> local_args = args;
|
std::vector<std::string> local_args = args;
|
||||||
local_args.erase(local_args.begin(), local_args.begin()+2);
|
local_args.erase(local_args.begin(), local_args.begin()+2);
|
||||||
set_store_tx_keys(local_args);
|
set_store_tx_info(local_args);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1998,24 +1998,29 @@ bool simple_wallet::show_transfers(const std::vector<std::string> &args_)
|
|||||||
std::vector<std::string> local_args = args_;
|
std::vector<std::string> local_args = args_;
|
||||||
bool in = true;
|
bool in = true;
|
||||||
bool out = true;
|
bool out = true;
|
||||||
|
bool pending = true;
|
||||||
uint64_t min_height = 0;
|
uint64_t min_height = 0;
|
||||||
uint64_t max_height = (uint64_t)-1;
|
uint64_t max_height = (uint64_t)-1;
|
||||||
|
|
||||||
if(local_args.size() > 3) {
|
if(local_args.size() > 3) {
|
||||||
fail_msg_writer() << tr("Usage: show_transfers [in|out] [<min_height> [<max_height>]]");
|
fail_msg_writer() << tr("Usage: show_transfers [in|out|all|pending] [<min_height> [<max_height>]]");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// optional in/out selector
|
// optional in/out selector
|
||||||
if (local_args.size() > 0) {
|
if (local_args.size() > 0) {
|
||||||
if (local_args[0] == "in" || local_args[0] == "incoming") {
|
if (local_args[0] == "in" || local_args[0] == "incoming") {
|
||||||
out = false;
|
out = pending = false;
|
||||||
local_args.erase(local_args.begin());
|
local_args.erase(local_args.begin());
|
||||||
}
|
}
|
||||||
else if (local_args[0] == "out" || local_args[0] == "outgoing") {
|
else if (local_args[0] == "out" || local_args[0] == "outgoing") {
|
||||||
in = false;
|
in = false;
|
||||||
local_args.erase(local_args.begin());
|
local_args.erase(local_args.begin());
|
||||||
}
|
}
|
||||||
|
else if (local_args[0] == "pending") {
|
||||||
|
in = out = false;
|
||||||
|
local_args.erase(local_args.begin());
|
||||||
|
}
|
||||||
else if (local_args[0] == "all" || local_args[0] == "both") {
|
else if (local_args[0] == "all" || local_args[0] == "both") {
|
||||||
local_args.erase(local_args.begin());
|
local_args.erase(local_args.begin());
|
||||||
}
|
}
|
||||||
@ -2055,7 +2060,7 @@ bool simple_wallet::show_transfers(const std::vector<std::string> &args_)
|
|||||||
std::string payment_id = string_tools::pod_to_hex(i->first);
|
std::string payment_id = string_tools::pod_to_hex(i->first);
|
||||||
if (payment_id.substr(16).find_first_not_of('0') == std::string::npos)
|
if (payment_id.substr(16).find_first_not_of('0') == std::string::npos)
|
||||||
payment_id = payment_id.substr(0,16);
|
payment_id = payment_id.substr(0,16);
|
||||||
output.insert(std::make_pair(pd.m_block_height, std::make_pair(true, (boost::format("%18.18s %s %s") % print_money(pd.m_amount) % string_tools::pod_to_hex(pd.m_tx_hash) % payment_id).str())));
|
output.insert(std::make_pair(pd.m_block_height, std::make_pair(true, (boost::format("%20.20s %s %s %s") % print_money(pd.m_amount) % string_tools::pod_to_hex(pd.m_tx_hash) % payment_id % "-").str())));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2065,26 +2070,40 @@ bool simple_wallet::show_transfers(const std::vector<std::string> &args_)
|
|||||||
for (std::list<std::pair<crypto::hash, tools::wallet2::confirmed_transfer_details>>::const_iterator i = payments.begin(); i != payments.end(); ++i) {
|
for (std::list<std::pair<crypto::hash, tools::wallet2::confirmed_transfer_details>>::const_iterator i = payments.begin(); i != payments.end(); ++i) {
|
||||||
const tools::wallet2::confirmed_transfer_details &pd = i->second;
|
const tools::wallet2::confirmed_transfer_details &pd = i->second;
|
||||||
uint64_t fee = pd.m_amount_in - pd.m_amount_out;
|
uint64_t fee = pd.m_amount_in - pd.m_amount_out;
|
||||||
output.insert(std::make_pair(pd.m_block_height, std::make_pair(false, (boost::format("%18.18s %s") % print_money(pd.m_amount_in - pd.m_change - fee) % "-").str())));
|
uint64_t change = pd.m_change == (uint64_t)-1 ? 0 : pd.m_change; // change may not be known
|
||||||
|
std::string dests;
|
||||||
|
for (const auto &d: pd.m_dests) {
|
||||||
|
if (!dests.empty())
|
||||||
|
dests += ", ";
|
||||||
|
dests += get_account_address_as_str(m_wallet->testnet(), d.addr) + ": " + print_money(d.amount);
|
||||||
|
}
|
||||||
|
std::string payment_id = string_tools::pod_to_hex(i->second.m_payment_id);
|
||||||
|
if (payment_id.substr(16).find_first_not_of('0') == std::string::npos)
|
||||||
|
payment_id = payment_id.substr(0,16);
|
||||||
|
output.insert(std::make_pair(pd.m_block_height, std::make_pair(false, (boost::format("%20.20s %s %s %14.14s %s") % print_money(pd.m_amount_in - change - fee) % string_tools::pod_to_hex(i->first) % payment_id % print_money(fee) % dests).str())));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// print in and out sorted by height
|
// print in and out sorted by height
|
||||||
for (std::map<uint64_t, std::pair<bool, std::string>>::const_iterator i = output.begin(); i != output.end(); ++i) {
|
for (std::map<uint64_t, std::pair<bool, std::string>>::const_iterator i = output.begin(); i != output.end(); ++i) {
|
||||||
message_writer(i->second.first ? epee::log_space::console_color_magenta : epee::log_space::console_color_green, false) <<
|
message_writer(i->second.first ? epee::log_space::console_color_magenta : epee::log_space::console_color_green, false) <<
|
||||||
boost::format("[%8.8llu] %4.4s %s") %
|
boost::format("%8.8llu %6.6s %s") %
|
||||||
((unsigned long long)i->first) % (i->second.first ? tr("in") : tr("out")) % i->second.second;
|
((unsigned long long)i->first) % (i->second.first ? tr("in") : tr("out")) % i->second.second;
|
||||||
}
|
}
|
||||||
|
|
||||||
// print unconfirmed last
|
// print unconfirmed last
|
||||||
if (out) {
|
if (pending) {
|
||||||
std::list<std::pair<crypto::hash, tools::wallet2::unconfirmed_transfer_details>> upayments;
|
std::list<std::pair<crypto::hash, tools::wallet2::unconfirmed_transfer_details>> upayments;
|
||||||
m_wallet->get_unconfirmed_payments_out(upayments);
|
m_wallet->get_unconfirmed_payments_out(upayments);
|
||||||
for (std::list<std::pair<crypto::hash, tools::wallet2::unconfirmed_transfer_details>>::const_iterator i = upayments.begin(); i != upayments.end(); ++i) {
|
for (std::list<std::pair<crypto::hash, tools::wallet2::unconfirmed_transfer_details>>::const_iterator i = upayments.begin(); i != upayments.end(); ++i) {
|
||||||
const tools::wallet2::unconfirmed_transfer_details &pd = i->second;
|
const tools::wallet2::unconfirmed_transfer_details &pd = i->second;
|
||||||
uint64_t amount = 0;
|
uint64_t amount = 0;
|
||||||
cryptonote::get_inputs_money_amount(pd.m_tx, amount);
|
cryptonote::get_inputs_money_amount(pd.m_tx, amount);
|
||||||
message_writer() << (boost::format("[%8.8s] %4.4s %18.18s") % tr("pending") % tr("out") % print_money(amount - pd.m_change)).str();
|
uint64_t fee = amount - get_outs_money_amount(pd.m_tx);
|
||||||
|
std::string payment_id = string_tools::pod_to_hex(i->second.m_payment_id);
|
||||||
|
if (payment_id.substr(16).find_first_not_of('0') == std::string::npos)
|
||||||
|
payment_id = payment_id.substr(0,16);
|
||||||
|
message_writer() << (boost::format("%8.8s %6.6s %20.20s %s %s %14.14s") % tr("pending") % tr("out") % print_money(amount - pd.m_change) % string_tools::pod_to_hex(i->first) % payment_id % print_money(fee)).str();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,7 +99,7 @@ namespace cryptonote
|
|||||||
*/
|
*/
|
||||||
bool seed_set_language(const std::vector<std::string> &args = std::vector<std::string>());
|
bool seed_set_language(const std::vector<std::string> &args = std::vector<std::string>());
|
||||||
bool set_always_confirm_transfers(const std::vector<std::string> &args = std::vector<std::string>());
|
bool set_always_confirm_transfers(const std::vector<std::string> &args = std::vector<std::string>());
|
||||||
bool set_store_tx_keys(const std::vector<std::string> &args = std::vector<std::string>());
|
bool set_store_tx_info(const std::vector<std::string> &args = std::vector<std::string>());
|
||||||
bool set_default_mixin(const std::vector<std::string> &args = std::vector<std::string>());
|
bool set_default_mixin(const std::vector<std::string> &args = std::vector<std::string>());
|
||||||
bool help(const std::vector<std::string> &args = std::vector<std::string>());
|
bool help(const std::vector<std::string> &args = std::vector<std::string>());
|
||||||
bool start_mining(const std::vector<std::string> &args);
|
bool start_mining(const std::vector<std::string> &args);
|
||||||
@ -175,9 +175,9 @@ namespace cryptonote
|
|||||||
m_blockchain_height = (std::max)(m_blockchain_height, height);
|
m_blockchain_height = (std::max)(m_blockchain_height, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (std::chrono::milliseconds(1) < current_time - m_print_time || force)
|
if (std::chrono::milliseconds(20) < current_time - m_print_time || force)
|
||||||
{
|
{
|
||||||
std::cout << QT_TRANSLATE_NOOP("cryptonote::simple_wallet", "Height ") << height << " / " << m_blockchain_height << '\r';
|
std::cout << QT_TRANSLATE_NOOP("cryptonote::simple_wallet", "Height ") << height << " / " << m_blockchain_height << '\r' << std::flush;
|
||||||
m_print_time = current_time;
|
m_print_time = current_time;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -270,7 +270,14 @@ void wallet2::process_new_transaction(const cryptonote::transaction& tx, uint64_
|
|||||||
LOG_PRINT_L2("Found unencrypted payment ID: " << payment_id);
|
LOG_PRINT_L2("Found unencrypted payment ID: " << payment_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t received = (tx_money_spent_in_ins < tx_money_got_in_outs) ? tx_money_got_in_outs - tx_money_spent_in_ins : 0;
|
uint64_t received = (tx_money_spent_in_ins < tx_money_got_in_outs) ? tx_money_got_in_outs - tx_money_spent_in_ins : 0;
|
||||||
|
|
||||||
|
if (tx_money_spent_in_ins > 0)
|
||||||
|
{
|
||||||
|
process_outgoing(tx, height, tx_money_spent_in_ins, tx_money_got_in_outs);
|
||||||
|
}
|
||||||
|
|
||||||
if (0 < received)
|
if (0 < received)
|
||||||
{
|
{
|
||||||
payment_details payment;
|
payment_details payment;
|
||||||
@ -288,7 +295,7 @@ void wallet2::process_unconfirmed(const cryptonote::transaction& tx, uint64_t he
|
|||||||
crypto::hash txid = get_transaction_hash(tx);
|
crypto::hash txid = get_transaction_hash(tx);
|
||||||
auto unconf_it = m_unconfirmed_txs.find(txid);
|
auto unconf_it = m_unconfirmed_txs.find(txid);
|
||||||
if(unconf_it != m_unconfirmed_txs.end()) {
|
if(unconf_it != m_unconfirmed_txs.end()) {
|
||||||
if (store_tx_keys()) {
|
if (store_tx_info()) {
|
||||||
try {
|
try {
|
||||||
m_confirmed_txs.insert(std::make_pair(txid, confirmed_transfer_details(unconf_it->second, height)));
|
m_confirmed_txs.insert(std::make_pair(txid, confirmed_transfer_details(unconf_it->second, height)));
|
||||||
}
|
}
|
||||||
@ -301,6 +308,18 @@ void wallet2::process_unconfirmed(const cryptonote::transaction& tx, uint64_t he
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
//----------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------
|
||||||
|
void wallet2::process_outgoing(const cryptonote::transaction &tx, uint64_t height, uint64_t spent, uint64_t received)
|
||||||
|
{
|
||||||
|
crypto::hash txid = get_transaction_hash(tx);
|
||||||
|
confirmed_transfer_details &ctd = m_confirmed_txs[txid];
|
||||||
|
// operator[] creates if not found
|
||||||
|
// fill with the info we know, some info might already be there
|
||||||
|
ctd.m_amount_in = spent;
|
||||||
|
ctd.m_amount_out = get_outs_money_amount(tx);
|
||||||
|
ctd.m_change = received;
|
||||||
|
ctd.m_block_height = height;
|
||||||
|
}
|
||||||
|
//----------------------------------------------------------------------------------------------------
|
||||||
void wallet2::process_new_blockchain_entry(const cryptonote::block& b, cryptonote::block_complete_entry& bche, crypto::hash& bl_id, uint64_t height)
|
void wallet2::process_new_blockchain_entry(const cryptonote::block& b, cryptonote::block_complete_entry& bche, crypto::hash& bl_id, uint64_t height)
|
||||||
{
|
{
|
||||||
//handle transactions from new block
|
//handle transactions from new block
|
||||||
@ -551,8 +570,8 @@ bool wallet2::store_keys(const std::string& keys_file_name, const std::string& p
|
|||||||
value2.SetInt(m_always_confirm_transfers ? 1 :0);
|
value2.SetInt(m_always_confirm_transfers ? 1 :0);
|
||||||
json.AddMember("always_confirm_transfers", value2, json.GetAllocator());
|
json.AddMember("always_confirm_transfers", value2, json.GetAllocator());
|
||||||
|
|
||||||
value2.SetInt(m_store_tx_keys ? 1 :0);
|
value2.SetInt(m_store_tx_info ? 1 :0);
|
||||||
json.AddMember("store_tx_keys", value2, json.GetAllocator());
|
json.AddMember("store_tx_info", value2, json.GetAllocator());
|
||||||
|
|
||||||
value2.SetUint(m_default_mixin);
|
value2.SetUint(m_default_mixin);
|
||||||
json.AddMember("default_mixin", value2, json.GetAllocator());
|
json.AddMember("default_mixin", value2, json.GetAllocator());
|
||||||
@ -638,7 +657,8 @@ void wallet2::load_keys(const std::string& keys_file_name, const std::string& pa
|
|||||||
m_watch_only = false;
|
m_watch_only = false;
|
||||||
}
|
}
|
||||||
m_always_confirm_transfers = json.HasMember("always_confirm_transfers") && (json["always_confirm_transfers"].GetInt() != 0);
|
m_always_confirm_transfers = json.HasMember("always_confirm_transfers") && (json["always_confirm_transfers"].GetInt() != 0);
|
||||||
m_store_tx_keys = json.HasMember("store_tx_keys") && (json["store_tx_keys"].GetInt() != 0);
|
m_store_tx_info = (json.HasMember("store_tx_keys") && (json["store_tx_keys"].GetInt() != 0))
|
||||||
|
|| (json.HasMember("store_tx_info") && (json["store_tx_info"].GetInt() != 0));
|
||||||
m_default_mixin = json.HasMember("default_mixin") ? json["default_mixin"].GetUint() : 0;
|
m_default_mixin = json.HasMember("default_mixin") ? json["default_mixin"].GetUint() : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1206,12 +1226,14 @@ uint64_t wallet2::select_transfers(uint64_t needed_money, bool add_dust, uint64_
|
|||||||
return found_money;
|
return found_money;
|
||||||
}
|
}
|
||||||
//----------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------
|
||||||
void wallet2::add_unconfirmed_tx(const cryptonote::transaction& tx, uint64_t change_amount)
|
void wallet2::add_unconfirmed_tx(const cryptonote::transaction& tx, const std::vector<cryptonote::tx_destination_entry> &dests, const crypto::hash &payment_id, uint64_t change_amount)
|
||||||
{
|
{
|
||||||
unconfirmed_transfer_details& utd = m_unconfirmed_txs[cryptonote::get_transaction_hash(tx)];
|
unconfirmed_transfer_details& utd = m_unconfirmed_txs[cryptonote::get_transaction_hash(tx)];
|
||||||
utd.m_change = change_amount;
|
utd.m_change = change_amount;
|
||||||
utd.m_sent_time = time(NULL);
|
utd.m_sent_time = time(NULL);
|
||||||
utd.m_tx = tx;
|
utd.m_tx = tx;
|
||||||
|
utd.m_dests = dests;
|
||||||
|
utd.m_payment_id = payment_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------
|
||||||
@ -1345,6 +1367,30 @@ std::string wallet2::address_from_txt_record(const std::string& s)
|
|||||||
return std::string();
|
return std::string();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
crypto::hash wallet2::get_payment_id(const pending_tx &ptx) const
|
||||||
|
{
|
||||||
|
std::vector<tx_extra_field> tx_extra_fields;
|
||||||
|
if(!parse_tx_extra(ptx.tx.extra, tx_extra_fields))
|
||||||
|
return cryptonote::null_hash;
|
||||||
|
tx_extra_nonce extra_nonce;
|
||||||
|
crypto::hash payment_id = null_hash;
|
||||||
|
if (find_tx_extra_field_by_type(tx_extra_fields, extra_nonce))
|
||||||
|
{
|
||||||
|
crypto::hash8 payment_id8 = null_hash8;
|
||||||
|
if(get_encrypted_payment_id_from_tx_extra_nonce(extra_nonce.nonce, payment_id8))
|
||||||
|
{
|
||||||
|
if (decrypt_payment_id(payment_id8, ptx.dests[0].addr.m_view_public_key, ptx.tx_key))
|
||||||
|
{
|
||||||
|
memcpy(payment_id.data, payment_id8.data, 8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!get_payment_id_from_tx_extra_nonce(extra_nonce.nonce, payment_id))
|
||||||
|
{
|
||||||
|
payment_id = cryptonote::null_hash;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return payment_id;
|
||||||
|
}
|
||||||
//----------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------
|
||||||
// take a pending tx and actually send it to the daemon
|
// take a pending tx and actually send it to the daemon
|
||||||
void wallet2::commit_tx(pending_tx& ptx)
|
void wallet2::commit_tx(pending_tx& ptx)
|
||||||
@ -1361,8 +1407,15 @@ void wallet2::commit_tx(pending_tx& ptx)
|
|||||||
THROW_WALLET_EXCEPTION_IF(daemon_send_resp.status != CORE_RPC_STATUS_OK, error::tx_rejected, ptx.tx, daemon_send_resp.status);
|
THROW_WALLET_EXCEPTION_IF(daemon_send_resp.status != CORE_RPC_STATUS_OK, error::tx_rejected, ptx.tx, daemon_send_resp.status);
|
||||||
|
|
||||||
txid = get_transaction_hash(ptx.tx);
|
txid = get_transaction_hash(ptx.tx);
|
||||||
add_unconfirmed_tx(ptx.tx, ptx.change_dts.amount);
|
crypto::hash payment_id = cryptonote::null_hash;
|
||||||
if (store_tx_keys())
|
std::vector<cryptonote::tx_destination_entry> dests;
|
||||||
|
if (store_tx_info())
|
||||||
|
{
|
||||||
|
payment_id = get_payment_id(ptx);
|
||||||
|
dests = ptx.dests;
|
||||||
|
}
|
||||||
|
add_unconfirmed_tx(ptx.tx, dests, payment_id, ptx.change_dts.amount);
|
||||||
|
if (store_tx_info())
|
||||||
m_tx_keys.insert(std::make_pair(txid, ptx.tx_key));
|
m_tx_keys.insert(std::make_pair(txid, ptx.tx_key));
|
||||||
|
|
||||||
LOG_PRINT_L2("transaction " << txid << " generated ok and sent to daemon, key_images: [" << ptx.key_images << "]");
|
LOG_PRINT_L2("transaction " << txid << " generated ok and sent to daemon, key_images: [" << ptx.key_images << "]");
|
||||||
@ -1639,6 +1692,7 @@ void wallet2::transfer_selected(const std::vector<cryptonote::tx_destination_ent
|
|||||||
ptx.change_dts = change_dts;
|
ptx.change_dts = change_dts;
|
||||||
ptx.selected_transfers = selected_transfers;
|
ptx.selected_transfers = selected_transfers;
|
||||||
ptx.tx_key = tx_key;
|
ptx.tx_key = tx_key;
|
||||||
|
ptx.dests = dsts;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Another implementation of transaction creation that is hopefully better
|
// Another implementation of transaction creation that is hopefully better
|
||||||
@ -1987,6 +2041,7 @@ void wallet2::transfer_dust(size_t num_outputs, uint64_t unlock_time, uint64_t n
|
|||||||
ptx.change_dts = change_dts;
|
ptx.change_dts = change_dts;
|
||||||
ptx.selected_transfers = selected_transfers;
|
ptx.selected_transfers = selected_transfers;
|
||||||
ptx.tx_key = tx_key;
|
ptx.tx_key = tx_key;
|
||||||
|
ptx.dests = dsts;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------
|
||||||
|
@ -79,9 +79,9 @@ namespace tools
|
|||||||
|
|
||||||
class wallet2
|
class wallet2
|
||||||
{
|
{
|
||||||
wallet2(const wallet2&) : m_run(true), m_callback(0), m_testnet(false), m_always_confirm_transfers (false), m_store_tx_keys(false), m_default_mixin(0) {}
|
wallet2(const wallet2&) : m_run(true), m_callback(0), m_testnet(false), m_always_confirm_transfers (false), m_store_tx_info(true), m_default_mixin(0) {}
|
||||||
public:
|
public:
|
||||||
wallet2(bool testnet = false, bool restricted = false) : m_run(true), m_callback(0), m_testnet(testnet), m_restricted(restricted), is_old_file_format(false), m_store_tx_keys(false), m_default_mixin(0) {}
|
wallet2(bool testnet = false, bool restricted = false) : m_run(true), m_callback(0), m_testnet(testnet), m_restricted(restricted), is_old_file_format(false), m_store_tx_info(true), m_default_mixin(0) {}
|
||||||
struct transfer_details
|
struct transfer_details
|
||||||
{
|
{
|
||||||
uint64_t m_block_height;
|
uint64_t m_block_height;
|
||||||
@ -107,6 +107,8 @@ namespace tools
|
|||||||
cryptonote::transaction m_tx;
|
cryptonote::transaction m_tx;
|
||||||
uint64_t m_change;
|
uint64_t m_change;
|
||||||
time_t m_sent_time;
|
time_t m_sent_time;
|
||||||
|
std::vector<cryptonote::tx_destination_entry> m_dests;
|
||||||
|
crypto::hash m_payment_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct confirmed_transfer_details
|
struct confirmed_transfer_details
|
||||||
@ -115,9 +117,12 @@ namespace tools
|
|||||||
uint64_t m_amount_out;
|
uint64_t m_amount_out;
|
||||||
uint64_t m_change;
|
uint64_t m_change;
|
||||||
uint64_t m_block_height;
|
uint64_t m_block_height;
|
||||||
confirmed_transfer_details() {}
|
std::vector<cryptonote::tx_destination_entry> m_dests;
|
||||||
|
crypto::hash m_payment_id;
|
||||||
|
|
||||||
|
confirmed_transfer_details(): m_amount_in(0), m_amount_out(0), m_change((uint64_t)-1), m_block_height(0), m_payment_id(cryptonote::null_hash) {}
|
||||||
confirmed_transfer_details(const unconfirmed_transfer_details &utd, uint64_t height):
|
confirmed_transfer_details(const unconfirmed_transfer_details &utd, uint64_t height):
|
||||||
m_amount_out(get_outs_money_amount(utd.m_tx)), m_change(utd.m_change), m_block_height(height) { get_inputs_money_amount(utd.m_tx, m_amount_in); }
|
m_amount_out(get_outs_money_amount(utd.m_tx)), m_change(utd.m_change), m_block_height(height), m_dests(utd.m_dests), m_payment_id(utd.m_payment_id) { get_inputs_money_amount(utd.m_tx, m_amount_in); }
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::vector<transfer_details> transfer_container;
|
typedef std::vector<transfer_details> transfer_container;
|
||||||
@ -131,6 +136,7 @@ namespace tools
|
|||||||
std::list<transfer_container::iterator> selected_transfers;
|
std::list<transfer_container::iterator> selected_transfers;
|
||||||
std::string key_images;
|
std::string key_images;
|
||||||
crypto::secret_key tx_key;
|
crypto::secret_key tx_key;
|
||||||
|
std::vector<cryptonote::tx_destination_entry> dests;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct keys_file_data
|
struct keys_file_data
|
||||||
@ -308,8 +314,8 @@ namespace tools
|
|||||||
|
|
||||||
bool always_confirm_transfers() const { return m_always_confirm_transfers; }
|
bool always_confirm_transfers() const { return m_always_confirm_transfers; }
|
||||||
void always_confirm_transfers(bool always) { m_always_confirm_transfers = always; }
|
void always_confirm_transfers(bool always) { m_always_confirm_transfers = always; }
|
||||||
bool store_tx_keys() const { return m_store_tx_keys; }
|
bool store_tx_info() const { return m_store_tx_info; }
|
||||||
void store_tx_keys(bool store) { m_store_tx_keys = store; }
|
void store_tx_info(bool store) { m_store_tx_info = store; }
|
||||||
uint32_t default_mixin() const { return m_default_mixin; }
|
uint32_t default_mixin() const { return m_default_mixin; }
|
||||||
void default_mixin(uint32_t m) { m_default_mixin = m; }
|
void default_mixin(uint32_t m) { m_default_mixin = m; }
|
||||||
|
|
||||||
@ -341,10 +347,12 @@ namespace tools
|
|||||||
uint64_t select_transfers(uint64_t needed_money, bool add_dust, uint64_t dust, std::list<transfer_container::iterator>& selected_transfers);
|
uint64_t select_transfers(uint64_t needed_money, bool add_dust, uint64_t dust, std::list<transfer_container::iterator>& selected_transfers);
|
||||||
bool prepare_file_names(const std::string& file_path);
|
bool prepare_file_names(const std::string& file_path);
|
||||||
void process_unconfirmed(const cryptonote::transaction& tx, uint64_t height);
|
void process_unconfirmed(const cryptonote::transaction& tx, uint64_t height);
|
||||||
void add_unconfirmed_tx(const cryptonote::transaction& tx, uint64_t change_amount);
|
void process_outgoing(const cryptonote::transaction& tx, uint64_t height, uint64_t spent, uint64_t received);
|
||||||
|
void add_unconfirmed_tx(const cryptonote::transaction& tx, const std::vector<cryptonote::tx_destination_entry> &dests, const crypto::hash &payment_id, uint64_t change_amount);
|
||||||
void generate_genesis(cryptonote::block& b);
|
void generate_genesis(cryptonote::block& b);
|
||||||
void check_genesis(const crypto::hash& genesis_hash) const; //throws
|
void check_genesis(const crypto::hash& genesis_hash) const; //throws
|
||||||
bool generate_chacha8_key_from_secret_keys(crypto::chacha8_key &key) const;
|
bool generate_chacha8_key_from_secret_keys(crypto::chacha8_key &key) const;
|
||||||
|
crypto::hash get_payment_id(const pending_tx &ptx) const;
|
||||||
|
|
||||||
cryptonote::account_base m_account;
|
cryptonote::account_base m_account;
|
||||||
std::string m_daemon_address;
|
std::string m_daemon_address;
|
||||||
@ -372,11 +380,11 @@ namespace tools
|
|||||||
bool is_old_file_format; /*!< Whether the wallet file is of an old file format */
|
bool is_old_file_format; /*!< Whether the wallet file is of an old file format */
|
||||||
bool m_watch_only; /*!< no spend key */
|
bool m_watch_only; /*!< no spend key */
|
||||||
bool m_always_confirm_transfers;
|
bool m_always_confirm_transfers;
|
||||||
bool m_store_tx_keys; /*!< request txkey to be returned in RPC, and store in the wallet cache file */
|
bool m_store_tx_info; /*!< request txkey to be returned in RPC, and store in the wallet cache file */
|
||||||
uint32_t m_default_mixin;
|
uint32_t m_default_mixin;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
BOOST_CLASS_VERSION(tools::wallet2, 9)
|
BOOST_CLASS_VERSION(tools::wallet2, 10)
|
||||||
|
|
||||||
namespace boost
|
namespace boost
|
||||||
{
|
{
|
||||||
@ -399,6 +407,10 @@ namespace boost
|
|||||||
a & x.m_change;
|
a & x.m_change;
|
||||||
a & x.m_sent_time;
|
a & x.m_sent_time;
|
||||||
a & x.m_tx;
|
a & x.m_tx;
|
||||||
|
if (ver < 9)
|
||||||
|
return;
|
||||||
|
a & x.m_dests;
|
||||||
|
a & x.m_payment_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Archive>
|
template <class Archive>
|
||||||
@ -408,6 +420,10 @@ namespace boost
|
|||||||
a & x.m_amount_out;
|
a & x.m_amount_out;
|
||||||
a & x.m_change;
|
a & x.m_change;
|
||||||
a & x.m_block_height;
|
a & x.m_block_height;
|
||||||
|
if (ver < 9)
|
||||||
|
return;
|
||||||
|
a & x.m_dests;
|
||||||
|
a & x.m_payment_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Archive>
|
template <class Archive>
|
||||||
@ -418,6 +434,13 @@ namespace boost
|
|||||||
a & x.m_block_height;
|
a & x.m_block_height;
|
||||||
a & x.m_unlock_time;
|
a & x.m_unlock_time;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class Archive>
|
||||||
|
inline void serialize(Archive& a, cryptonote::tx_destination_entry& x, const boost::serialization::version_type ver)
|
||||||
|
{
|
||||||
|
a & x.amount;
|
||||||
|
a & x.addr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -628,6 +651,7 @@ namespace tools
|
|||||||
ptx.change_dts = change_dts;
|
ptx.change_dts = change_dts;
|
||||||
ptx.selected_transfers = selected_transfers;
|
ptx.selected_transfers = selected_transfers;
|
||||||
ptx.tx_key = tx_key;
|
ptx.tx_key = tx_key;
|
||||||
|
ptx.dests = dsts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user