aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/crypto/skein.c4
-rw-r--r--src/simplewallet/simplewallet.cpp22
-rw-r--r--src/simplewallet/simplewallet.h2
-rw-r--r--src/wallet/wallet2.cpp30
-rw-r--r--src/wallet/wallet2.h3
-rw-r--r--utils/gpg_keys/anonimal.asc64
6 files changed, 112 insertions, 13 deletions
diff --git a/src/crypto/skein.c b/src/crypto/skein.c
index 9c8ac288d..65e4525c3 100644
--- a/src/crypto/skein.c
+++ b/src/crypto/skein.c
@@ -77,7 +77,7 @@ typedef struct /* 1024-bit Skein hash context stru
} Skein1024_Ctxt_t;
/* Skein APIs for (incremental) "straight hashing" */
-#if SKEIN_256_NIST_MAX_HASH_BITS
+#if SKEIN_256_NIST_MAX_HASHBITS
static int Skein_256_Init (Skein_256_Ctxt_t *ctx, size_t hashBitLen);
#endif
static int Skein_512_Init (Skein_512_Ctxt_t *ctx, size_t hashBitLen);
@@ -1941,7 +1941,7 @@ static HashReturn Final (hashState *state, BitSequence *hashval);
/* select the context size and init the context */
static HashReturn Init(hashState *state, int hashbitlen)
{
-#if SKEIN_256_NIST_MAX_HASH_BITS
+#if SKEIN_256_NIST_MAX_HASHBITS
if (hashbitlen <= SKEIN_256_NIST_MAX_HASHBITS)
{
Skein_Assert(hashbitlen > 0,BAD_HASHLEN);
diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp
index cef1d6dcf..b1049265d 100644
--- a/src/simplewallet/simplewallet.cpp
+++ b/src/simplewallet/simplewallet.cpp
@@ -3114,16 +3114,16 @@ bool simple_wallet::sweep_all(const std::vector<std::string> &args_)
return true;
}
//----------------------------------------------------------------------------------------------------
-bool simple_wallet::accept_loaded_tx(const tools::wallet2::unsigned_tx_set &txs)
+bool simple_wallet::accept_loaded_tx(const std::function<size_t()> get_num_txes, const std::function<const tools::wallet2::tx_construction_data&(size_t)> &get_tx)
{
// gather info to ask the user
uint64_t amount = 0, amount_to_dests = 0, change = 0;
size_t min_mixin = ~0;
std::unordered_map<std::string, uint64_t> dests;
const std::string wallet_address = m_wallet->get_account().get_public_address_str(m_wallet->testnet());
- for (size_t n = 0; n < txs.txes.size(); ++n)
+ for (size_t n = 0; n < get_num_txes(); ++n)
{
- const tools::wallet2::tx_construction_data &cd = txs.txes[n];
+ const tools::wallet2::tx_construction_data &cd = get_tx(n);
for (size_t s = 0; s < cd.sources.size(); ++s)
{
amount += cd.sources[s].amount;
@@ -3157,6 +3157,8 @@ bool simple_wallet::accept_loaded_tx(const tools::wallet2::unsigned_tx_set &txs)
}
change = cd.change_dts.amount;
it->second -= cd.change_dts.amount;
+ if (it->second == 0)
+ dests.erase(get_account_address_as_str(m_wallet->testnet(), cd.change_dts.addr));
}
}
std::string dest_string;
@@ -3171,11 +3173,21 @@ bool simple_wallet::accept_loaded_tx(const tools::wallet2::unsigned_tx_set &txs)
dest_string = tr("with no destinations");
uint64_t fee = amount - amount_to_dests;
- std::string prompt_str = (boost::format(tr("Loaded %lu transactions, for %s, fee %s, change %s, %s, with min mixin %lu. Is this okay? (Y/Yes/N/No)")) % (unsigned long)txs.txes.size() % print_money(amount) % print_money(fee) % print_money(change) % dest_string % (unsigned long)min_mixin).str();
+ std::string prompt_str = (boost::format(tr("Loaded %lu transactions, for %s, fee %s, change %s, %s, with min mixin %lu. Is this okay? (Y/Yes/N/No)")) % (unsigned long)get_num_txes() % print_money(amount) % print_money(fee) % print_money(change) % dest_string % (unsigned long)min_mixin).str();
std::string accepted = command_line::input_line(prompt_str);
return is_it_true(accepted);
}
//----------------------------------------------------------------------------------------------------
+bool simple_wallet::accept_loaded_tx(const tools::wallet2::unsigned_tx_set &txs)
+{
+ return accept_loaded_tx([&txs](){return txs.txes.size();}, [&txs](size_t n)->const tools::wallet2::tx_construction_data&{return txs.txes[n];});
+}
+//----------------------------------------------------------------------------------------------------
+bool simple_wallet::accept_loaded_tx(const tools::wallet2::signed_tx_set &txs)
+{
+ return accept_loaded_tx([&txs](){return txs.ptx.size();}, [&txs](size_t n)->const tools::wallet2::tx_construction_data&{return txs.ptx[n].construction_data;});
+}
+//----------------------------------------------------------------------------------------------------
bool simple_wallet::sign_transfer(const std::vector<std::string> &args_)
{
if(m_wallet->watch_only())
@@ -3211,7 +3223,7 @@ bool simple_wallet::submit_transfer(const std::vector<std::string> &args_)
try
{
std::vector<tools::wallet2::pending_tx> ptx_vector;
- bool r = m_wallet->load_tx("signed_monero_tx", ptx_vector);
+ bool r = m_wallet->load_tx("signed_monero_tx", ptx_vector, [&](const tools::wallet2::signed_tx_set &tx){ return accept_loaded_tx(tx); });
if (!r)
{
fail_msg_writer() << tr("Failed to load transaction from file");
diff --git a/src/simplewallet/simplewallet.h b/src/simplewallet/simplewallet.h
index 92cc0ddfc..fcc77ff69 100644
--- a/src/simplewallet/simplewallet.h
+++ b/src/simplewallet/simplewallet.h
@@ -158,7 +158,9 @@ namespace cryptonote
uint64_t get_daemon_blockchain_height(std::string& err);
bool try_connect_to_daemon(bool silent = false);
bool ask_wallet_create_if_needed();
+ bool accept_loaded_tx(const std::function<size_t()> get_num_txes, const std::function<const tools::wallet2::tx_construction_data&(size_t)> &get_tx);
bool accept_loaded_tx(const tools::wallet2::unsigned_tx_set &txs);
+ bool accept_loaded_tx(const tools::wallet2::signed_tx_set &txs);
bool get_address_from_str(const std::string &str, cryptonote::account_public_address &address, bool &has_payment_id, crypto::hash8 &payment_id);
/*!
diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp
index ba8c65540..5ea8de5c7 100644
--- a/src/wallet/wallet2.cpp
+++ b/src/wallet/wallet2.cpp
@@ -246,6 +246,15 @@ static uint64_t decodeRct(const rct::rctSig & rv, const crypto::public_key pub,
}
}
//----------------------------------------------------------------------------------------------------
+bool wallet2::wallet_generate_key_image_helper(const cryptonote::account_keys& ack, const crypto::public_key& tx_public_key, size_t real_output_index, cryptonote::keypair& in_ephemeral, crypto::key_image& ki)
+{
+ if (!cryptonote::generate_key_image_helper(ack, tx_public_key, real_output_index, in_ephemeral, ki))
+ return false;
+ if (m_watch_only)
+ memset(&ki, 0, 32);
+ return true;
+}
+//----------------------------------------------------------------------------------------------------
void wallet2::process_new_transaction(const cryptonote::transaction& tx, const std::vector<uint64_t> &o_indices, uint64_t height, uint64_t ts, bool miner_tx, bool pool)
{
class lazy_txid_getter
@@ -317,7 +326,7 @@ void wallet2::process_new_transaction(const cryptonote::transaction& tx, const s
// this assumes that the miner tx pays a single address
if (received)
{
- cryptonote::generate_key_image_helper(m_account.get_keys(), tx_pub_key, 0, in_ephemeral[0], ki[0]);
+ wallet_generate_key_image_helper(m_account.get_keys(), tx_pub_key, 0, in_ephemeral[0], ki[0]);
THROW_WALLET_EXCEPTION_IF(in_ephemeral[0].pub != boost::get<cryptonote::txout_to_key>(tx.vout[0].target).key,
error::wallet_internal_error, "key_image generated ephemeral public key not matched with output_key");
@@ -360,7 +369,7 @@ void wallet2::process_new_transaction(const cryptonote::transaction& tx, const s
}
if (received[i])
{
- cryptonote::generate_key_image_helper(m_account.get_keys(), tx_pub_key, i, in_ephemeral[i], ki[i]);
+ wallet_generate_key_image_helper(m_account.get_keys(), tx_pub_key, i, in_ephemeral[i], ki[i]);
THROW_WALLET_EXCEPTION_IF(in_ephemeral[i].pub != boost::get<cryptonote::txout_to_key>(tx.vout[i].target).key,
error::wallet_internal_error, "key_image generated ephemeral public key not matched with output_key");
@@ -408,7 +417,7 @@ void wallet2::process_new_transaction(const cryptonote::transaction& tx, const s
}
if (received[i])
{
- cryptonote::generate_key_image_helper(m_account.get_keys(), tx_pub_key, i, in_ephemeral[i], ki[i]);
+ wallet_generate_key_image_helper(m_account.get_keys(), tx_pub_key, i, in_ephemeral[i], ki[i]);
THROW_WALLET_EXCEPTION_IF(in_ephemeral[i].pub != boost::get<cryptonote::txout_to_key>(tx.vout[i].target).key,
error::wallet_internal_error, "key_image generated ephemeral public key not matched with output_key");
@@ -440,7 +449,7 @@ void wallet2::process_new_transaction(const cryptonote::transaction& tx, const s
{
if (received)
{
- cryptonote::generate_key_image_helper(m_account.get_keys(), tx_pub_key, i, in_ephemeral[i], ki[i]);
+ wallet_generate_key_image_helper(m_account.get_keys(), tx_pub_key, i, in_ephemeral[i], ki[i]);
THROW_WALLET_EXCEPTION_IF(in_ephemeral[i].pub != boost::get<cryptonote::txout_to_key>(tx.vout[i].target).key,
error::wallet_internal_error, "key_image generated ephemeral public key not matched with output_key");
@@ -2138,9 +2147,14 @@ void wallet2::rescan_spent()
std::to_string(daemon_resp.spent_status.size()) + ", expected " + std::to_string(key_images.size()));
// update spent status
+ key_image zero_ki;
+ memset(&zero_ki, 0, 32);
for (size_t i = 0; i < m_transfers.size(); ++i)
{
transfer_details& td = m_transfers[i];
+ // a view wallet may not know about key images
+ if (td.m_key_image == zero_ki)
+ continue;
if (td.m_spent != (daemon_resp.spent_status[i] != COMMAND_RPC_IS_KEY_IMAGE_SPENT::UNSPENT))
{
if (td.m_spent)
@@ -2678,7 +2692,7 @@ bool wallet2::sign_tx(const std::string &unsigned_filename, const std::string &s
return epee::file_io_utils::save_string_to_file(signed_filename, std::string(SIGNED_TX_PREFIX) + s);
}
//----------------------------------------------------------------------------------------------------
-bool wallet2::load_tx(const std::string &signed_filename, std::vector<tools::wallet2::pending_tx> &ptx)
+bool wallet2::load_tx(const std::string &signed_filename, std::vector<tools::wallet2::pending_tx> &ptx, std::function<bool(const signed_tx_set&)> accept_func)
{
std::string s;
boost::system::error_code errcode;
@@ -2709,6 +2723,12 @@ bool wallet2::load_tx(const std::string &signed_filename, std::vector<tools::wal
LOG_PRINT_L0("Loaded signed tx data from binary: " << signed_txs.ptx.size() << " transactions");
for (auto &ptx: signed_txs.ptx) LOG_PRINT_L0(cryptonote::obj_to_json_str(ptx.tx));
+ if (accept_func && !accept_func(signed_txs))
+ {
+ LOG_PRINT_L1("Transactions rejected by callback");
+ return false;
+ }
+
ptx = signed_txs.ptx;
return true;
diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h
index 8afe35aca..6cd288ac1 100644
--- a/src/wallet/wallet2.h
+++ b/src/wallet/wallet2.h
@@ -357,7 +357,7 @@ namespace tools
void commit_tx(std::vector<pending_tx>& ptx_vector);
bool save_tx(const std::vector<pending_tx>& ptx_vector, const std::string &filename);
bool sign_tx(const std::string &unsigned_filename, const std::string &signed_filename, std::function<bool(const unsigned_tx_set&)> accept_func = NULL);
- bool load_tx(const std::string &signed_filename, std::vector<tools::wallet2::pending_tx> &ptx);
+ bool load_tx(const std::string &signed_filename, std::vector<tools::wallet2::pending_tx> &ptx, std::function<bool(const signed_tx_set&)> accept_func = NULL);
std::vector<pending_tx> create_transactions(std::vector<cryptonote::tx_destination_entry> dsts, const size_t fake_outs_count, const uint64_t unlock_time, uint32_t priority, const std::vector<uint8_t> extra, bool trusted_daemon);
std::vector<wallet2::pending_tx> create_transactions_2(std::vector<cryptonote::tx_destination_entry> dsts, const size_t fake_outs_count, const uint64_t unlock_time, uint32_t priority, const std::vector<uint8_t> extra, bool trusted_daemon);
std::vector<wallet2::pending_tx> create_transactions_all(const cryptonote::account_public_address &address, const size_t fake_outs_count, const uint64_t unlock_time, uint32_t priority, const std::vector<uint8_t> extra, bool trusted_daemon);
@@ -526,6 +526,7 @@ namespace tools
void set_unspent(size_t idx);
template<typename entry>
void get_outs(std::vector<std::vector<entry>> &outs, const std::list<size_t> &selected_transfers, size_t fake_outputs_count);
+ bool wallet_generate_key_image_helper(const cryptonote::account_keys& ack, const crypto::public_key& tx_public_key, size_t real_output_index, cryptonote::keypair& in_ephemeral, crypto::key_image& ki);
cryptonote::account_base m_account;
std::string m_daemon_address;
diff --git a/utils/gpg_keys/anonimal.asc b/utils/gpg_keys/anonimal.asc
new file mode 100644
index 000000000..0fb9f827e
--- /dev/null
+++ b/utils/gpg_keys/anonimal.asc
@@ -0,0 +1,64 @@
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v1
+
+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
+=EuZn
+-----END PGP PUBLIC KEY BLOCK-----