wallet: do not store signatures in the wallet cache

Saves some substantial space.
Also avoid calculating tx hashes we don't need.
This commit is contained in:
moneromooo-monero 2016-08-06 19:19:25 +01:00
parent 0263dd2d23
commit a47ceee83b
No known key found for this signature in database
GPG key ID: 686F07454D6CEFC3
11 changed files with 95 additions and 31 deletions

View file

@ -180,7 +180,7 @@ namespace cryptonote
FIELD(extra) FIELD(extra)
END_SERIALIZE() END_SERIALIZE()
protected: public:
transaction_prefix(){} transaction_prefix(){}
}; };

View file

@ -143,6 +143,16 @@ namespace boost
} }
template <class Archive>
inline void serialize(Archive &a, cryptonote::transaction_prefix &x, const boost::serialization::version_type ver)
{
a & x.version;
a & x.unlock_time;
a & x.vin;
a & x.vout;
a & x.extra;
}
template <class Archive> template <class Archive>
inline void serialize(Archive &a, cryptonote::transaction &x, const boost::serialization::version_type ver) inline void serialize(Archive &a, cryptonote::transaction &x, const boost::serialization::version_type ver)
{ {

View file

@ -321,6 +321,11 @@ namespace cryptonote
return pub_key_field.pub_key; return pub_key_field.pub_key;
} }
//--------------------------------------------------------------- //---------------------------------------------------------------
crypto::public_key get_tx_pub_key_from_extra(const transaction_prefix& tx_prefix)
{
return get_tx_pub_key_from_extra(tx_prefix.extra);
}
//---------------------------------------------------------------
crypto::public_key get_tx_pub_key_from_extra(const transaction& tx) crypto::public_key get_tx_pub_key_from_extra(const transaction& tx)
{ {
return get_tx_pub_key_from_extra(tx.extra); return get_tx_pub_key_from_extra(tx.extra);

View file

@ -89,6 +89,7 @@ namespace cryptonote
bool parse_tx_extra(const std::vector<uint8_t>& tx_extra, std::vector<tx_extra_field>& tx_extra_fields); bool parse_tx_extra(const std::vector<uint8_t>& tx_extra, std::vector<tx_extra_field>& tx_extra_fields);
crypto::public_key get_tx_pub_key_from_extra(const std::vector<uint8_t>& tx_extra); crypto::public_key get_tx_pub_key_from_extra(const std::vector<uint8_t>& tx_extra);
crypto::public_key get_tx_pub_key_from_extra(const transaction_prefix& tx);
crypto::public_key get_tx_pub_key_from_extra(const transaction& tx); crypto::public_key get_tx_pub_key_from_extra(const transaction& tx);
bool add_tx_pub_key_to_extra(transaction& tx, const crypto::public_key& tx_pub_key); bool add_tx_pub_key_to_extra(transaction& tx, const crypto::public_key& tx_pub_key);
bool add_extra_nonce_to_tx_extra(std::vector<uint8_t>& tx_extra, const blobdata& extra_nonce); bool add_extra_nonce_to_tx_extra(std::vector<uint8_t>& tx_extra, const blobdata& extra_nonce);

View file

@ -2068,7 +2068,7 @@ bool simple_wallet::show_incoming_transfers(const std::vector<std::string>& args
(m_wallet->is_transfer_unlocked(td) ? tr("unlocked") : tr("locked")) % (m_wallet->is_transfer_unlocked(td) ? tr("unlocked") : tr("locked")) %
(td.is_rct() ? tr("RingCT") : tr("-")) % (td.is_rct() ? tr("RingCT") : tr("-")) %
td.m_global_output_index % td.m_global_output_index %
get_transaction_hash (td.m_tx); td.m_txid;
} }
} }

View file

@ -165,9 +165,8 @@ void TransactionHistoryImpl::refresh()
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;
const crypto::hash &hash = i->first; const crypto::hash &hash = i->first;
uint64_t amount = 0; uint64_t amount = pd.m_amount_in;
cryptonote::get_inputs_money_amount(pd.m_tx, amount); uint64_t fee = amount - pd.m_amount_out;
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); 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) 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);

View file

@ -225,6 +225,24 @@ static uint64_t decodeRct(const rct::rctSig & rv, const rct::key & sk, unsigned
//---------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------------
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) 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
{
const cryptonote::transaction &tx;
crypto::hash lazy_txid;
bool computed;
public:
lazy_txid_getter(const transaction &tx): tx(tx), computed(false) {}
const crypto::hash &operator()()
{
if (!computed)
{
lazy_txid = cryptonote::get_transaction_hash(tx);
computed = true;
}
return lazy_txid;
}
} txid(tx);
if (!miner_tx) if (!miner_tx)
process_unconfirmed(tx, height); process_unconfirmed(tx, height);
std::vector<size_t> outs; std::vector<size_t> outs;
@ -235,7 +253,7 @@ void wallet2::process_new_transaction(const cryptonote::transaction& tx, const s
if(!parse_tx_extra(tx.extra, tx_extra_fields)) if(!parse_tx_extra(tx.extra, tx_extra_fields))
{ {
// Extra may only be partially parsed, it's OK if tx_extra_fields contains public key // Extra may only be partially parsed, it's OK if tx_extra_fields contains public key
LOG_PRINT_L0("Transaction extra has unsupported format: " << get_transaction_hash(tx)); LOG_PRINT_L0("Transaction extra has unsupported format: " << txid());
} }
// Don't try to extract tx public key if tx has no ouputs // Don't try to extract tx public key if tx has no ouputs
@ -244,7 +262,7 @@ void wallet2::process_new_transaction(const cryptonote::transaction& tx, const s
tx_extra_pub_key pub_key_field; tx_extra_pub_key pub_key_field;
if(!find_tx_extra_field_by_type(tx_extra_fields, pub_key_field)) if(!find_tx_extra_field_by_type(tx_extra_fields, pub_key_field))
{ {
LOG_PRINT_L0("Public key wasn't found in the transaction extra. Skipping transaction " << get_transaction_hash(tx)); LOG_PRINT_L0("Public key wasn't found in the transaction extra. Skipping transaction " << txid());
if(0 != m_callback) if(0 != m_callback)
m_callback->on_skip_transaction(height, tx); m_callback->on_skip_transaction(height, tx);
return; return;
@ -452,7 +470,8 @@ void wallet2::process_new_transaction(const cryptonote::transaction& tx, const s
td.m_block_height = height; td.m_block_height = height;
td.m_internal_output_index = o; td.m_internal_output_index = o;
td.m_global_output_index = o_indices[o]; td.m_global_output_index = o_indices[o];
td.m_tx = tx; td.m_tx = (const cryptonote::transaction_prefix&)tx;
td.m_txid = txid();
td.m_key_image = ki[o]; td.m_key_image = ki[o];
td.m_amount = tx.vout[o].amount; td.m_amount = tx.vout[o].amount;
if (td.m_amount == 0) if (td.m_amount == 0)
@ -466,9 +485,9 @@ void wallet2::process_new_transaction(const cryptonote::transaction& tx, const s
} }
set_unspent(td); set_unspent(td);
m_key_images[td.m_key_image] = m_transfers.size()-1; m_key_images[td.m_key_image] = m_transfers.size()-1;
LOG_PRINT_L0("Received money: " << print_money(td.amount()) << ", with tx: " << get_transaction_hash(tx)); LOG_PRINT_L0("Received money: " << print_money(td.amount()) << ", with tx: " << txid());
if (0 != m_callback) if (0 != m_callback)
m_callback->on_money_received(height, td.m_tx, td.m_amount); m_callback->on_money_received(height, tx, td.m_amount);
} }
} }
else if (m_transfers[kit->second].m_spent || m_transfers[kit->second].amount() >= tx.vout[o].amount) else if (m_transfers[kit->second].m_spent || m_transfers[kit->second].amount() >= tx.vout[o].amount)
@ -492,7 +511,8 @@ void wallet2::process_new_transaction(const cryptonote::transaction& tx, const s
td.m_block_height = height; td.m_block_height = height;
td.m_internal_output_index = o; td.m_internal_output_index = o;
td.m_global_output_index = o_indices[o]; td.m_global_output_index = o_indices[o];
td.m_tx = tx; td.m_tx = (const cryptonote::transaction_prefix&)tx;
td.m_txid = txid();
td.m_amount = tx.vout[o].amount; td.m_amount = tx.vout[o].amount;
if (td.m_amount == 0) if (td.m_amount == 0)
{ {
@ -506,9 +526,9 @@ void wallet2::process_new_transaction(const cryptonote::transaction& tx, const s
THROW_WALLET_EXCEPTION_IF(td.m_key_image != ki[o], error::wallet_internal_error, "Inconsistent key images"); THROW_WALLET_EXCEPTION_IF(td.m_key_image != ki[o], error::wallet_internal_error, "Inconsistent key images");
THROW_WALLET_EXCEPTION_IF(td.m_spent, error::wallet_internal_error, "Inconsistent spent status"); THROW_WALLET_EXCEPTION_IF(td.m_spent, error::wallet_internal_error, "Inconsistent spent status");
LOG_PRINT_L0("Received money: " << print_money(td.amount()) << ", with tx: " << get_transaction_hash(tx)); LOG_PRINT_L0("Received money: " << print_money(td.amount()) << ", with tx: " << txid());
if (0 != m_callback) if (0 != m_callback)
m_callback->on_money_received(height, td.m_tx, td.m_amount); m_callback->on_money_received(height, tx, td.m_amount);
} }
} }
} }
@ -533,11 +553,11 @@ void wallet2::process_new_transaction(const cryptonote::transaction& tx, const s
std::string(", expected ") + print_money(td.amount())); std::string(", expected ") + print_money(td.amount()));
} }
amount = td.amount(); amount = td.amount();
LOG_PRINT_L0("Spent money: " << print_money(amount) << ", with tx: " << get_transaction_hash(tx)); LOG_PRINT_L0("Spent money: " << print_money(amount) << ", with tx: " << txid());
tx_money_spent_in_ins += amount; tx_money_spent_in_ins += amount;
set_spent(td, height); set_spent(td, height);
if (0 != m_callback) if (0 != m_callback)
m_callback->on_money_spent(height, td.m_tx, amount, tx); m_callback->on_money_spent(height, tx, amount, tx);
} }
} }
@ -589,7 +609,7 @@ void wallet2::process_new_transaction(const cryptonote::transaction& tx, const s
} }
payment_details payment; payment_details payment;
payment.m_tx_hash = cryptonote::get_transaction_hash(tx); payment.m_tx_hash = txid();
payment.m_amount = received; payment.m_amount = received;
payment.m_block_height = height; payment.m_block_height = height;
payment.m_unlock_time = tx.unlock_time; payment.m_unlock_time = tx.unlock_time;
@ -604,6 +624,9 @@ void wallet2::process_new_transaction(const cryptonote::transaction& tx, const s
//---------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------------
void wallet2::process_unconfirmed(const cryptonote::transaction& tx, uint64_t height) void wallet2::process_unconfirmed(const cryptonote::transaction& tx, uint64_t height)
{ {
if (m_unconfirmed_txs.empty())
return;
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()) {
@ -915,7 +938,7 @@ void wallet2::update_pool_state()
std::unordered_map<crypto::hash, wallet2::unconfirmed_transfer_details>::iterator it = m_unconfirmed_txs.begin(); std::unordered_map<crypto::hash, wallet2::unconfirmed_transfer_details>::iterator it = m_unconfirmed_txs.begin();
while (it != m_unconfirmed_txs.end()) while (it != m_unconfirmed_txs.end())
{ {
const std::string txid = epee::string_tools::pod_to_hex(cryptonote::get_transaction_hash(it->second.m_tx)); const std::string txid = epee::string_tools::pod_to_hex(it->first);
bool found = false; bool found = false;
for (auto it2: res.transactions) for (auto it2: res.transactions)
{ {
@ -1141,7 +1164,7 @@ void wallet2::refresh(uint64_t start_height, uint64_t & blocks_fetched, bool& re
blocks_fetched = 0; blocks_fetched = 0;
uint64_t added_blocks = 0; uint64_t added_blocks = 0;
size_t try_count = 0; size_t try_count = 0;
crypto::hash last_tx_hash_id = m_transfers.size() ? get_transaction_hash(m_transfers.back().m_tx) : null_hash; crypto::hash last_tx_hash_id = m_transfers.size() ? m_transfers.back().m_txid : null_hash;
std::list<crypto::hash> short_chain_history; std::list<crypto::hash> short_chain_history;
boost::thread pull_thread; boost::thread pull_thread;
uint64_t blocks_start_height; uint64_t blocks_start_height;
@ -1213,7 +1236,7 @@ void wallet2::refresh(uint64_t start_height, uint64_t & blocks_fetched, bool& re
} }
} }
} }
if(last_tx_hash_id != (m_transfers.size() ? get_transaction_hash(m_transfers.back().m_tx) : null_hash)) if(last_tx_hash_id != (m_transfers.size() ? m_transfers.back().m_txid : null_hash))
received_money = true; received_money = true;
try try
@ -2179,11 +2202,9 @@ float wallet2::get_output_relatedness(const transfer_details &td0, const transfe
{ {
int dh; int dh;
#if 0
// expensive test, and same tx will fall onto the same block height below // expensive test, and same tx will fall onto the same block height below
if (get_transaction_hash(td0.m_tx) == get_transaction_hash(td1.m_tx)) if (td0.m_txid == td1.m_txid)
return 1.0f; return 1.0f;
#endif
// same block height -> possibly tx burst, or same tx (since above is disabled) // same block height -> possibly tx burst, or same tx (since above is disabled)
dh = td0.m_block_height > td1.m_block_height ? td0.m_block_height - td1.m_block_height : td1.m_block_height - td0.m_block_height; dh = td0.m_block_height > td1.m_block_height ? td0.m_block_height - td1.m_block_height : td1.m_block_height - td0.m_block_height;
@ -2269,7 +2290,7 @@ void wallet2::add_unconfirmed_tx(const cryptonote::transaction& tx, uint64_t amo
utd.m_amount_out += d.amount; utd.m_amount_out += d.amount;
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 = (const cryptonote::transaction_prefix&)tx;
utd.m_dests = dests; utd.m_dests = dests;
utd.m_payment_id = payment_id; utd.m_payment_id = payment_id;
utd.m_state = wallet2::unconfirmed_transfer_details::pending; utd.m_state = wallet2::unconfirmed_transfer_details::pending;

View file

@ -99,7 +99,8 @@ namespace tools
struct transfer_details struct transfer_details
{ {
uint64_t m_block_height; uint64_t m_block_height;
cryptonote::transaction m_tx; cryptonote::transaction_prefix m_tx;
crypto::hash m_txid;
size_t m_internal_output_index; size_t m_internal_output_index;
uint64_t m_global_output_index; uint64_t m_global_output_index;
bool m_spent; bool m_spent;
@ -123,7 +124,7 @@ namespace tools
struct unconfirmed_transfer_details struct unconfirmed_transfer_details
{ {
cryptonote::transaction m_tx; cryptonote::transaction_prefix m_tx;
uint64_t m_amount_in; uint64_t m_amount_in;
uint64_t m_amount_out; uint64_t m_amount_out;
uint64_t m_change; uint64_t m_change;
@ -502,9 +503,9 @@ namespace tools
}; };
} }
BOOST_CLASS_VERSION(tools::wallet2, 14) BOOST_CLASS_VERSION(tools::wallet2, 14)
BOOST_CLASS_VERSION(tools::wallet2::transfer_details, 2) BOOST_CLASS_VERSION(tools::wallet2::transfer_details, 3)
BOOST_CLASS_VERSION(tools::wallet2::payment_details, 1) BOOST_CLASS_VERSION(tools::wallet2::payment_details, 1)
BOOST_CLASS_VERSION(tools::wallet2::unconfirmed_transfer_details, 4) BOOST_CLASS_VERSION(tools::wallet2::unconfirmed_transfer_details, 5)
BOOST_CLASS_VERSION(tools::wallet2::confirmed_transfer_details, 2) BOOST_CLASS_VERSION(tools::wallet2::confirmed_transfer_details, 2)
namespace boost namespace boost
@ -535,7 +536,17 @@ namespace boost
a & x.m_block_height; a & x.m_block_height;
a & x.m_global_output_index; a & x.m_global_output_index;
a & x.m_internal_output_index; a & x.m_internal_output_index;
a & x.m_tx; if (ver < 3)
{
cryptonote::transaction tx;
a & tx;
x.m_tx = (const cryptonote::transaction_prefix&)tx;
x.m_txid = cryptonote::get_transaction_hash(tx);
}
else
{
a & x.m_tx;
}
a & x.m_spent; a & x.m_spent;
a & x.m_key_image; a & x.m_key_image;
if (ver < 1) if (ver < 1)
@ -552,6 +563,9 @@ namespace boost
return; return;
} }
a & x.m_spent_height; a & x.m_spent_height;
if (ver < 3)
return;
a & x.m_txid;
} }
template <class Archive> template <class Archive>
@ -559,7 +573,16 @@ namespace boost
{ {
a & x.m_change; a & x.m_change;
a & x.m_sent_time; a & x.m_sent_time;
a & x.m_tx; if (ver < 5)
{
cryptonote::transaction tx;
a & tx;
x.m_tx = (const cryptonote::transaction_prefix&)tx;
}
else
{
a & x.m_tx;
}
if (ver < 1) if (ver < 1)
return; return;
a & x.m_dests; a & x.m_dests;

View file

@ -729,7 +729,7 @@ namespace tools
rpc_transfers.amount = td.amount(); rpc_transfers.amount = td.amount();
rpc_transfers.spent = td.m_spent; rpc_transfers.spent = td.m_spent;
rpc_transfers.global_index = td.m_global_output_index; rpc_transfers.global_index = td.m_global_output_index;
rpc_transfers.tx_hash = epee::string_tools::pod_to_hex(cryptonote::get_transaction_hash(td.m_tx)); rpc_transfers.tx_hash = epee::string_tools::pod_to_hex(td.m_txid);
rpc_transfers.tx_size = txBlob.size(); rpc_transfers.tx_size = txBlob.size();
res.transfers.push_back(rpc_transfers); res.transfers.push_back(rpc_transfers);
} }

View file

@ -281,7 +281,7 @@ bool transactions_flow_test(std::string& working_folder,
w2.get_transfers(tc); w2.get_transfers(tc);
BOOST_FOREACH(tools::wallet2::transfer_details& td, tc) BOOST_FOREACH(tools::wallet2::transfer_details& td, tc)
{ {
auto it = txs.find(get_transaction_hash(td.m_tx)); auto it = txs.find(td.m_txid);
CHECK_AND_ASSERT_MES(it != txs.end(), false, "transaction not found in local cache"); CHECK_AND_ASSERT_MES(it != txs.end(), false, "transaction not found in local cache");
it->second.m_received_count += 1; it->second.m_received_count += 1;
} }

View file

@ -42,6 +42,11 @@ static tools::wallet2::transfer_container make_transfers_container(size_t N)
tools::wallet2::transfer_details &td = transfers.back(); tools::wallet2::transfer_details &td = transfers.back();
td.m_block_height = 1000; td.m_block_height = 1000;
td.m_spent = false; td.m_spent = false;
td.m_txid = cryptonote::null_hash;
td.m_txid.data[0] = n & 0xff;
td.m_txid.data[1] = (n >> 8) & 0xff;
td.m_txid.data[2] = (n >> 16) & 0xff;
td.m_txid.data[3] = (n >> 24) & 0xff;
} }
return transfers; return transfers;
} }