1
0
Fork 0
forked from lthn/blockchain

Merge branch 'zarcanum_tx' into zarcanum

# Conflicts solved in:
#	src/currency_core/blockchain_storage.cpp
#	src/currency_core/blockchain_storage.h
#	src/currency_core/core_runtime_config.h
This commit is contained in:
sowle 2022-05-26 17:59:15 +02:00
commit f24b1350ab
No known key found for this signature in database
GPG key ID: C07A24B2D89D49FC
49 changed files with 1652 additions and 1051 deletions

View file

@ -0,0 +1,57 @@
// Copyright (c) 2014-2018 Zano Project
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#pragma once
#define VARIANT_SWITCH_BEGIN(v_type_obj) {auto & local_reference_eokcmeokmeokcm = v_type_obj; if(false) {;
#define VARIANT_CASE_CONST(v_type, typed_name) } else if(local_reference_eokcmeokmeokcm.type() == typeid(v_type)) { const v_type& typed_name = boost::get<v_type>(local_reference_eokcmeokmeokcm);
#define VARIANT_CASE(v_type, typed_name) } else if(local_reference_eokcmeokmeokcm.type() == typeid(v_type)) { v_type& typed_name = boost::get<v_type>(local_reference_eokcmeokmeokcm);
#define VARIANT_CASE_TV(v_type) VARIANT_CASE(v_type, tv)
#define VARIANT_CASE_OTHER() } else {
#define VARIANT_CASE_THROW_ON_OTHER() } else { ASSERT_MES_AND_THROW("Unknown type in switch statemet: " << local_reference_eokcmeokmeokcm.type().name());
#define VARIANT_SWITCH_END() } }
/*
usage:
VARIANT_SWITCH_BEGIN(o);
VARIANT_CASE(tx_out_bare, o);
VARIANT_CASE_TV(tx_out_zarcanum);
//@#@
VARIANT_SWITCH_END();
VARIANT_SWITCH_BEGIN(o);
VARIANT_CASE_CONST(txout_to_key, o);
VARIANT_CASE_CONST(txout_multisig, ms);
VARIANT_CASE_CONST(txout_htlc, htlc);
VARIANT_CASE_THROW_ON_OTHER();
VARIANT_SWITCH_END();
VARIANT_SWITCH_BEGIN(s);
VARIANT_CASE(void_sig, v);
VARIANT_CASE(NLSAG_sig, signatures);
VARIANT_CASE(zarcanum_sig, s);
//@#@
VARIANT_CASE_THROW_ON_OTHER();
VARIANT_SWITCH_END();
VARIANT_SWITCH_BEGIN(o);
VARIANT_CASE(tx_out_bare, o)
VARIANT_CASE_TV(tx_out_zarcanum)
//@#@
VARIANT_CASE_THROW_ON_OTHER();
VARIANT_SWITCH_END();
*/

File diff suppressed because it is too large Load diff

View file

@ -39,7 +39,7 @@
#include "dispatch_core_events.h"
#include "bc_attachments_service_manager.h"
#include "common/median_db_cache.h"
#include "common/variant_helper.h"
MARK_AS_POD_C11(crypto::key_image);
@ -286,25 +286,24 @@ namespace currency
uint64_t get_aliases_count()const;
uint64_t get_block_h_older_then(uint64_t timestamp) const;
bool validate_tx_service_attachmens_in_services(const tx_service_attachment& a, size_t i, const transaction& tx)const;
bool check_tx_input(const transaction& tx, size_t in_index, const txin_to_key& txin, const crypto::hash& tx_prefix_hash, const std::vector<crypto::signature>& sig, uint64_t& max_related_block_height, uint64_t& source_max_unlock_time_for_pos_coinbase)const;
bool check_tx_input(const transaction& tx, size_t in_index, const txin_multisig& txin, const crypto::hash& tx_prefix_hash, const std::vector<crypto::signature>& sig, uint64_t& max_related_block_height)const;
bool check_tx_input(const transaction& tx, size_t in_index, const txin_htlc& txin, const crypto::hash& tx_prefix_hash, const std::vector<crypto::signature>& sig, uint64_t& max_related_block_height)const;
bool check_tx_input(const transaction& tx, size_t in_index, const txin_to_key& txin, const crypto::hash& tx_prefix_hash, uint64_t& max_related_block_height, uint64_t& source_max_unlock_time_for_pos_coinbase)const;
bool check_tx_input(const transaction& tx, size_t in_index, const txin_multisig& txin, const crypto::hash& tx_prefix_hash, uint64_t& max_related_block_height)const;
bool check_tx_input(const transaction& tx, size_t in_index, const txin_htlc& txin, const crypto::hash& tx_prefix_hash, uint64_t& max_related_block_height)const;
bool check_tx_inputs(const transaction& tx, const crypto::hash& tx_prefix_hash, uint64_t& max_used_block_height)const;
bool check_tx_inputs(const transaction& tx, const crypto::hash& tx_prefix_hash) const;
bool check_tx_inputs(const transaction& tx, const crypto::hash& tx_prefix_hash, uint64_t& max_used_block_height, crypto::hash& max_used_block_id)const;
bool check_ms_input(const transaction& tx, size_t in_index, const txin_multisig& txin, const crypto::hash& tx_prefix_hash, const std::vector<crypto::signature>& sig, const transaction& source_tx, size_t out_n) const;
bool check_ms_input(const transaction& tx, size_t in_index, const txin_multisig& txin, const crypto::hash& tx_prefix_hash, const transaction& source_tx, size_t out_n) const;
bool validate_tx_for_hardfork_specific_terms(const transaction& tx, const crypto::hash& tx_id, uint64_t block_height) const;
bool validate_tx_for_hardfork_specific_terms(const transaction& tx, const crypto::hash& tx_id) const;
bool get_output_keys_for_input_with_checks(const transaction& tx, const txin_v& verified_input, std::vector<crypto::public_key>& output_keys, uint64_t& max_related_block_height, uint64_t& source_max_unlock_time_for_pos_coinbase, scan_for_keys_context& scan_context) const;
bool get_output_keys_for_input_with_checks(const transaction& tx, const txin_v& verified_input, std::vector<crypto::public_key>& output_keys, uint64_t& max_related_block_height, uint64_t& source_max_unlock_time_for_pos_coinbase) const;
bool check_input_signature(const transaction& tx, size_t in_index, const txin_to_key& txin, const crypto::hash& tx_prefix_hash, const std::vector<crypto::signature>& sig, const std::vector<const crypto::public_key*>& output_keys_ptrs) const;
bool check_input_signature(const transaction& tx, size_t in_index, const txin_to_key& txin, const crypto::hash& tx_prefix_hash, const std::vector<const crypto::public_key*>& output_keys_ptrs) const;
bool check_input_signature(const transaction& tx,
size_t in_index,
uint64_t in_amount,
const crypto::key_image& k_image,
const std::vector<txin_etc_details_v>& in_etc_details,
const crypto::hash& tx_prefix_hash,
const std::vector<crypto::signature>& sig,
const std::vector<const crypto::public_key*>& output_keys_ptrs) const;
uint64_t get_current_comulative_blocksize_limit()const;
@ -597,13 +596,17 @@ namespace currency
const crypto::hash& bl_id,
const crypto::hash& input_tx_hash,
size_t input_index,
const std::vector<crypto::signature>& input_sigs,
uint64_t split_height,
const alt_chain_type& alt_chain,
const std::unordered_set<crypto::hash>& alt_chain_block_ids,
uint64_t& ki_lookuptime,
uint64_t* p_max_related_block_height = nullptr) const;
bool validate_alt_block_ms_input(const transaction& input_tx, const crypto::hash& input_tx_hash, size_t input_index, const std::vector<crypto::signature>& input_sigs, uint64_t split_height, const alt_chain_type& alt_chain) const;
bool validate_alt_block_ms_input(const transaction& input_tx,
const crypto::hash& input_tx_hash,
size_t input_index,
const signature_v& input_sigs,//const std::vector<crypto::signature>& input_sigs,
uint64_t split_height,
const alt_chain_type& alt_chain) const;
bool validate_alt_block_txs(const block& b, const crypto::hash& id, std::unordered_set<crypto::key_image>& collected_keyimages, alt_block_extended_info& abei, const alt_chain_type& alt_chain, uint64_t split_height, uint64_t& ki_lookup_time_total) const;
bool update_alt_out_indexes_for_tx_in_block(const transaction& tx, alt_block_extended_info& abei)const;
bool get_transaction_from_pool_or_db(const crypto::hash& tx_id, std::shared_ptr<transaction>& tx_ptr, uint64_t min_allowed_block_height = 0) const;
@ -771,55 +774,66 @@ namespace currency
TO_KEY | TO_KEY | YES
*/
bool r = is_output_allowed_for_input(tx_ptr->tx.vout[n].target, verified_input, get_current_blockchain_size() - tx_ptr->m_keeper_block_height);
CHECK_AND_ASSERT_MES(r, false, "Input and output incompatible type");
if (tx_ptr->tx.vout[n].target.type() == typeid(txout_to_key))
VARIANT_SWITCH_BEGIN(tx_ptr->tx.vout[n]);
VARIANT_CASE_CONST(tx_out_bare, o)
{
CHECKED_GET_SPECIFIC_VARIANT(tx_ptr->tx.vout[n].target, const txout_to_key, outtk, false);
//fix for burned money
patch_out_if_needed(const_cast<txout_to_key&>(outtk), tx_id, n);
bool r = is_output_allowed_for_input(o.target, verified_input, get_current_blockchain_size() - tx_ptr->m_keeper_block_height);
CHECK_AND_ASSERT_MES(r, false, "Input and output incompatible type");
bool mixattr_ok = is_mixattr_applicable_for_fake_outs_counter(outtk.mix_attr, key_offsets.size() - 1);
CHECK_AND_ASSERT_MES(mixattr_ok, false, "tx output #" << output_index << " violates mixin restrictions: mix_attr = " << static_cast<uint32_t>(outtk.mix_attr) << ", key_offsets.size = " << key_offsets.size());
}
else if (tx_ptr->tx.vout[n].target.type() == typeid(txout_htlc))
{
//check for spend flags
CHECK_AND_ASSERT_MES(tx_ptr->m_spent_flags.size() > n, false,
"Internal error: tx_ptr->m_spent_flags.size(){" << tx_ptr->m_spent_flags.size() << "} > n{" << n << "}");
CHECK_AND_ASSERT_MES(tx_ptr->m_spent_flags[n] == false, false, "HTLC out already spent, double spent attempt detected");
const txout_htlc& htlc_out = boost::get<txout_htlc>(tx_ptr->tx.vout[n].target);
if (htlc_out.expiration > get_current_blockchain_size() - tx_ptr->m_keeper_block_height)
if (o.target.type() == typeid(txout_to_key))
{
//HTLC IS NOT expired, can be used ONLY by pkey_before_expiration and ONLY by HTLC input
scan_context.htlc_is_expired = false;
CHECKED_GET_SPECIFIC_VARIANT(o.target, const txout_to_key, outtk, false);
//fix for burned money
patch_out_if_needed(const_cast<txout_to_key&>(outtk), tx_id, n);
bool mixattr_ok = is_mixattr_applicable_for_fake_outs_counter(outtk.mix_attr, key_offsets.size() - 1);
CHECK_AND_ASSERT_MES(mixattr_ok, false, "tx output #" << output_index << " violates mixin restrictions: mix_attr = " << static_cast<uint32_t>(outtk.mix_attr) << ", key_offsets.size = " << key_offsets.size());
}
else
else if (o.target.type() == typeid(txout_htlc))
{
//HTLC IS expired, can be used ONLY by pkey_after_expiration and ONLY by to_key input
scan_context.htlc_is_expired = true;
//check for spend flags
CHECK_AND_ASSERT_MES(tx_ptr->m_spent_flags.size() > n, false,
"Internal error: tx_ptr->m_spent_flags.size(){" << tx_ptr->m_spent_flags.size() << "} > n{" << n << "}");
CHECK_AND_ASSERT_MES(tx_ptr->m_spent_flags[n] == false, false, "HTLC out already spent, double spent attempt detected");
const txout_htlc& htlc_out = boost::get<txout_htlc>(o.target);
if (htlc_out.expiration > get_current_blockchain_size() - tx_ptr->m_keeper_block_height)
{
//HTLC IS NOT expired, can be used ONLY by pkey_before_expiration and ONLY by HTLC input
scan_context.htlc_is_expired = false;
}
else
{
//HTLC IS expired, can be used ONLY by pkey_after_expiration and ONLY by to_key input
scan_context.htlc_is_expired = true;
}
}
}else
{
LOG_ERROR("[scan_outputkeys_for_indexes]: Wrong output type in : " << tx_ptr->tx.vout[n].target.type().name());
return false;
else
{
LOG_ERROR("[scan_outputkeys_for_indexes]: Wrong output type in : " << o.target.type().name());
return false;
}
TIME_MEASURE_START_PD(tx_check_inputs_loop_scan_outputkeys_loop_handle_output);
if (!vis.handle_output(tx_ptr->tx, validated_tx, o, n))
{
LOG_PRINT_L0("Failed to handle_output for output id = " << tx_id << ", no " << n);
return false;
}
TIME_MEASURE_FINISH_PD(tx_check_inputs_loop_scan_outputkeys_loop_handle_output);
}
TIME_MEASURE_START_PD(tx_check_inputs_loop_scan_outputkeys_loop_handle_output);
if (!vis.handle_output(tx_ptr->tx, validated_tx, tx_ptr->tx.vout[n], n))
{
LOG_PRINT_L0("Failed to handle_output for output id = " << tx_id << ", no " << n);
VARIANT_CASE_CONST(tx_out_zarcanum, oz)
//@#@
return false;
}
TIME_MEASURE_FINISH_PD(tx_check_inputs_loop_scan_outputkeys_loop_handle_output);
VARIANT_CASE_THROW_ON_OTHER();
VARIANT_SWITCH_END();
if (max_related_block_height < tx_ptr->m_keeper_block_height)
max_related_block_height = tx_ptr->m_keeper_block_height;
if (max_related_block_height < tx_ptr->m_keeper_block_height)
max_related_block_height = tx_ptr->m_keeper_block_height;
++output_index;
}
TIME_MEASURE_FINISH_PD(tx_check_inputs_loop_scan_outputkeys_loop);

View file

@ -541,8 +541,7 @@ namespace currency
extra_alias_entry(const extra_alias_entry_old& old)
: extra_alias_entry_base(old)
, m_alias(old.m_alias)
{
}
{}
std::string m_alias;
@ -656,6 +655,44 @@ namespace currency
END_BOOST_SERIALIZATION()
};
//classic CryptoNote signature by Nicolas Van Saberhagen
struct NLSAG_sig
{
std::vector<std::vector<crypto::signature> > s;
BEGIN_SERIALIZE_OBJECT()
FIELD(s)
END_SERIALIZE()
BEGIN_BOOST_SERIALIZATION()
BOOST_SERIALIZE(s)
END_BOOST_SERIALIZATION()
};
struct zarcanum_sig
{
//TODO:
BEGIN_SERIALIZE_OBJECT()
END_SERIALIZE()
BEGIN_BOOST_SERIALIZATION()
END_BOOST_SERIALIZATION()
};
struct void_sig
{
//TODO:
BEGIN_SERIALIZE_OBJECT()
END_SERIALIZE()
BEGIN_BOOST_SERIALIZATION()
END_BOOST_SERIALIZATION()
};
typedef boost::variant<NLSAG_sig, void_sig, zarcanum_sig> signature_v;
//include backward compatibility defintions
#include "currency_basic_backward_comp.inl"
@ -668,7 +705,7 @@ namespace currency
//extra
std::vector<extra_v> extra;
std::vector<txin_v> vin;
std::vector<tx_out_bare> vout;//std::vector<tx_out> vout;
std::vector<tx_out_v> vout;
BEGIN_SERIALIZE()
VARINT_FIELD(version)
@ -697,14 +734,16 @@ namespace currency
class transaction: public transaction_prefix
{
public:
std::vector<std::vector<crypto::signature> > signatures; //count signatures always the same as inputs count
signature_v signature;
std::vector<attachment_v> attachment;
transaction();
BEGIN_SERIALIZE_OBJECT()
FIELDS(*static_cast<transaction_prefix *>(this))
FIELD(signatures)
CHAIN_TRANSITION_VER(TRANSACTION_VERSION_INITAL, transaction_v1)
CHAIN_TRANSITION_VER(TRANSACTION_VERSION_PRE_HF4, transaction_v1)
FIELD(signature)
FIELD(attachment)
END_SERIALIZE()
};
@ -719,7 +758,7 @@ namespace currency
vin.clear();
vout.clear();
extra.clear();
signatures.clear();
signature = NLSAG_sig();
attachment.clear();
}
@ -913,6 +952,9 @@ SET_VARIANT_TAGS(currency::tx_out_zarcanum, 38, "tx_out_zarcanum");
SET_VARIANT_TAGS(currency::zarcanum_tx_data_v1, 39, "zarcanum_tx_data_v1");
SET_VARIANT_TAGS(crypto::bpp_signature_serialized, 40, "bpp_signature_serialized");
SET_VARIANT_TAGS(crypto::bppe_signature_serialized, 41, "bppe_signature_serialized");
SET_VARIANT_TAGS(currency::NLSAG_sig, 42, "NLSAG_sig");
SET_VARIANT_TAGS(currency::zarcanum_sig, 43, "zarcanum_sig");
SET_VARIANT_TAGS(currency::void_sig, 43, "void_sig");

View file

@ -48,7 +48,16 @@ bool transition_convert(const transaction_prefix_current_t& from, transaction_pr
{
to.extra = from.extra;
to.vin = from.vin;
to.vout = from.vout;
for (const auto& v : from.vout)
{
if (v.type() == typeid(tx_out_bare))
{
to.vout.push_back(boost::get<tx_out_bare>(v));
}
else {
throw std::runtime_error("Unexpected type in tx_out_v");
}
}
return true;
}
template<typename transaction_prefix_current_t>
@ -56,8 +65,46 @@ bool transition_convert(const transaction_prefix_v1& from, transaction_prefix_cu
{
to.extra = from.extra;
to.vin = from.vin;
to.vout = from.vout;
for (const auto& v : from.vout)
{
to.vout.push_back(v);
}
return true;
}
class transaction_v1
{
public:
std::vector<std::vector<crypto::signature> > signatures; //count signatures always the same as inputs count
std::vector<attachment_v> attachment;
BEGIN_SERIALIZE_OBJECT()
FIELD(signatures)
FIELD(attachment)
END_SERIALIZE()
};
template<typename transaction_current_t>
bool transition_convert(const transaction_current_t& from, transaction_v1& to)
{
to.attachment = from.attachment;
if (from.signature.type() == typeid(NLSAG_sig))
{
to.signatures = boost::get<NLSAG_sig>(from.signature).s;
}
else
{
throw std::runtime_error("Unexpected type in signature_v");
}
return true;
}
template<typename transaction_current_t>
bool transition_convert(const transaction_v1& from, transaction_current_t& to)
{
to.attachment = from.attachment;
to.signature = NLSAG_sig();
boost::get<NLSAG_sig>(to.signature).s = from.signatures;
return true;
}

View file

@ -227,7 +227,7 @@ namespace boost
a & x.vin;
a & x.vout;
a & x.extra;
a & x.signatures;
a & x.signature;
a & x.attachment;
}

View file

@ -253,6 +253,13 @@
#endif
#define ZANO_HARDFORK_00_INITAL 0
#define ZANO_HARDFORK_01 1
#define ZANO_HARDFORK_02 2
#define ZANO_HARDFORK_03 3
#define ZANO_HARDFORK_04_ZARCANUM 4
static_assert(CURRENCY_MINER_TX_MAX_OUTS <= CURRENCY_TX_MAX_ALLOWED_OUTS, "Miner tx must obey normal tx max outs limit");

View file

@ -196,8 +196,9 @@ namespace currency
posin.k_image = pe.keyimage;
tx.vin.push_back(posin);
//reserve place for ring signature
tx.signatures.resize(1);
tx.signatures[0].resize(posin.key_offsets.size());
tx.signature = NLSAG_sig();
boost::get<NLSAG_sig>(tx.signature).s.resize(1);
boost::get<NLSAG_sig>(tx.signature).s[0].resize(posin.key_offsets.size());
}
uint64_t no = 0;
@ -525,8 +526,9 @@ namespace currency
//msg.vin = tx.vin;
msg.onetime_key = get_tx_pub_key_from_extra(tx);
CHECK_AND_ASSERT_MES(tx.vout.size() > n, null_hash, "tx.vout.size() > n condition failed ");
CHECK_AND_ASSERT_MES(tx.vout[n].target.type() == typeid(txout_multisig), null_hash, "tx.vout[n].target.type() == typeid(txout_multisig) condition failed");
msg.vout.push_back(tx.vout[n]);
CHECK_AND_ASSERT_MES(tx.vout[n].type() == typeid(tx_out_bare), null_hash, "Unexpected type of out:" << tx.vout[n].type().name());
CHECK_AND_ASSERT_MES(boost::get<tx_out_bare>(tx.vout[n]).target.type() == typeid(txout_multisig), null_hash, "tx.vout[n].target.type() == typeid(txout_multisig) condition failed");
msg.vout.push_back(boost::get<tx_out_bare>(tx.vout[n]));
return get_object_hash(msg);
}
//---------------------------------------------------------------
@ -1127,13 +1129,17 @@ namespace currency
if (bc_services::get_first_service_attachment_by_id(tx, BC_ESCROW_SERVICE_ID, BC_ESCROW_SERVICE_INSTRUCTION_CANCEL_PROPOSAL, tsa))
return GUI_TX_TYPE_ESCROW_CANCEL_PROPOSAL;
for (auto o : tx.vout)
for (auto ov : tx.vout)
{
if (o.target.type() == typeid(txout_htlc))
{
htlc_out = o;
return GUI_TX_TYPE_HTLC_DEPOSIT;
}
VARIANT_SWITCH_BEGIN(ov);
VARIANT_CASE_CONST(tx_out_bare, o)
if (o.target.type() == typeid(txout_htlc))
{
htlc_out = o;
return GUI_TX_TYPE_HTLC_DEPOSIT;
}
VARIANT_SWITCH_END();
}
if (get_type_in_variant_container(tx.vin, htlc_in))
@ -1152,13 +1158,18 @@ namespace currency
return get_tx_type_ex(tx, htlc_out, htlc_in);
}
//---------------------------------------------------------------
size_t get_multisig_out_index(const std::vector<tx_out_bare>& outs)
size_t get_multisig_out_index(const std::vector<tx_out_v>& outs)
{
size_t n = 0;
for (; n != outs.size(); n++)
{
if (outs[n].target.type() == typeid(txout_multisig))
break;
VARIANT_SWITCH_BEGIN(outs[n]);
VARIANT_CASE_CONST(tx_out_bare, o)
if (o.target.type() == typeid(txout_multisig))
break;
VARIANT_CASE_CONST(tx_out_zarcanum, o)
//@#@
VARIANT_SWITCH_END();
}
return n;
}
@ -1272,7 +1283,7 @@ namespace currency
{
tx.vin.clear();
tx.vout.clear();
tx.signatures.clear();
tx.signature = NLSAG_sig();
tx.extra = extra;
tx.version = ftp.tx_version;
@ -1525,8 +1536,8 @@ namespace currency
crypto::hash tx_hash_for_signature = prepare_prefix_hash_for_sign(tx, input_index, tx_prefix_hash);
CHECK_AND_ASSERT_MES(tx_hash_for_signature != null_hash, false, "failed to prepare_prefix_hash_for_sign");
tx.signatures.push_back(std::vector<crypto::signature>());
std::vector<crypto::signature>& sigs = tx.signatures.back();
boost::get<NLSAG_sig>(tx.signature).s.push_back(std::vector<crypto::signature>());
std::vector<crypto::signature>& sigs = boost::get<NLSAG_sig>(tx.signature).s.back();
if(src_entr.is_multisig())
{
@ -1597,7 +1608,12 @@ namespace currency
uint64_t reward = 0;
for (auto& out : tx.vout)
{
reward += out.amount;
VARIANT_SWITCH_BEGIN(out);
VARIANT_CASE_CONST(tx_out_bare, o)
reward += o.amount;
VARIANT_CASE_CONST(tx_out_zarcanum, o)
//@#@
VARIANT_SWITCH_END();
}
reward -= income;
return reward;
@ -1648,14 +1664,20 @@ namespace currency
size_t ms_out_index = SIZE_MAX;
for (size_t i = 0; i < source_tx.vout.size(); ++i)
{
if (source_tx.vout[i].target.type() == typeid(txout_multisig) && ms_in.multisig_out_id == get_multisig_out_id(source_tx, i))
{
ms_out_index = i;
break;
}
VARIANT_SWITCH_BEGIN(source_tx.vout[i]);
VARIANT_CASE_CONST(tx_out_bare, o)
if (o.target.type() == typeid(txout_multisig) && ms_in.multisig_out_id == get_multisig_out_id(source_tx, i))
{
ms_out_index = i;
break;
}
VARIANT_CASE_CONST(tx_out_zarcanum, o)
//@#@
VARIANT_SWITCH_END();
}
LOC_CHK(ms_out_index != SIZE_MAX, "failed to find ms output in source tx " << get_transaction_hash(source_tx) << " by ms id " << ms_in.multisig_out_id);
const txout_multisig& out_ms = boost::get<txout_multisig>(source_tx.vout[ms_out_index].target);
const txout_multisig& out_ms = boost::get<txout_multisig>( boost::get<tx_out_bare>(source_tx.vout[ms_out_index]).target);
crypto::public_key source_tx_pub_key = get_tx_pub_key_from_extra(source_tx);
@ -1665,9 +1687,13 @@ namespace currency
size_t participant_index = std::find(out_ms.keys.begin(), out_ms.keys.end(), ms_in_ephemeral_key.pub) - out_ms.keys.begin();
LOC_CHK(participant_index < out_ms.keys.size(), "Can't find given participant's ms key in ms output keys list");
LOC_CHK(ms_input_index < tx.signatures.size(), "transaction does not have signatures vectory entry for ms input #" << ms_input_index);
//@#@
LOC_CHK(tx.signature.type() == typeid(NLSAG_sig), "Wrong type of signature");
auto& sigs = tx.signatures[ms_input_index];
LOC_CHK(ms_input_index < boost::get<NLSAG_sig>(tx.signature).s.size(), "transaction does not have signatures vector entry for ms input #" << ms_input_index);
auto& sigs = boost::get<NLSAG_sig>(tx.signature).s[ms_input_index];
LOC_CHK(!sigs.empty(), "empty signatures container");
bool extra_signature_expected = (get_tx_flags(tx) & TX_FLAG_SIGNATURE_MODE_SEPARATE) && ms_input_index == tx.vin.size() - 1;
@ -1801,36 +1827,37 @@ namespace currency
//-----------------------------------------------------------------------------------------------
bool check_outs_valid(const transaction& tx)
{
for(const tx_out_bare& out : tx.vout)
for(const auto& vo : tx.vout)
{
CHECK_AND_NO_ASSERT_MES(0 < out.amount, false, "zero amount output in transaction id=" << get_transaction_hash(tx));
if (out.target.type() == typeid(txout_to_key))
VARIANT_SWITCH_BEGIN(vo);
VARIANT_CASE_CONST(tx_out_bare, out)
{
if (!check_key(boost::get<txout_to_key>(out.target).key))
return false;
}
else if (out.target.type() == typeid(txout_htlc))
{
const txout_htlc& htlc = boost::get<txout_htlc>(out.target);
if (!check_key(htlc.pkey_redeem))
return false;
if (!check_key(htlc.pkey_refund))
return false;
}
else if (out.target.type() == typeid(txout_multisig))
{
const txout_multisig& ms = boost::get<txout_multisig>(out.target);
if (!(ms.keys.size() > 0 && ms.minimum_sigs > 0 && ms.minimum_sigs <= ms.keys.size()))
{
LOG_ERROR("wrong multisig in transaction id=" << get_transaction_hash(tx));
return false;
}
}
else
{
LOG_ERROR("wrong variant type: " << out.target.type().name() << ", expected " << typeid(txout_to_key).name()
<< ", in transaction id=" << get_transaction_hash(tx));
CHECK_AND_NO_ASSERT_MES(0 < out.amount, false, "zero amount output in transaction id=" << get_transaction_hash(tx));
VARIANT_SWITCH_BEGIN(out.target);
VARIANT_CASE_CONST(txout_to_key, tk)
if (!check_key(tk.key))
return false;
VARIANT_CASE_CONST(txout_htlc, htlc)
if (!check_key(htlc.pkey_redeem))
return false;
if (!check_key(htlc.pkey_refund))
return false;
VARIANT_CASE_CONST(txout_multisig, ms)
if (!(ms.keys.size() > 0 && ms.minimum_sigs > 0 && ms.minimum_sigs <= ms.keys.size()))
{
LOG_ERROR("wrong multisig in transaction id=" << get_transaction_hash(tx));
return false;
}
VARIANT_CASE_OTHER()
LOG_ERROR("wrong variant type: " << out.target.type().name() << ", expected " << typeid(txout_to_key).name()
<< ", in transaction id=" << get_transaction_hash(tx));
VARIANT_SWITCH_END();
}
VARIANT_CASE_CONST(tx_out_zarcanum, o)
//@#@
VARIANT_SWITCH_END();
}
return true;
}
@ -1878,9 +1905,14 @@ namespace currency
uint64_t money = 0;
BOOST_FOREACH(const auto& o, tx.vout)
{
if (money > o.amount + money)
return false;
money += o.amount;
VARIANT_SWITCH_BEGIN(o);
VARIANT_CASE_CONST(tx_out_bare, o)
if (money > o.amount + money)
return false;
money += o.amount;
VARIANT_CASE_CONST(tx_out_zarcanum, o)
//@#@
VARIANT_SWITCH_END();
}
return true;
}
@ -1888,8 +1920,15 @@ namespace currency
uint64_t get_outs_money_amount(const transaction& tx)
{
uint64_t outputs_amount = 0;
for(const auto& o : tx.vout)
outputs_amount += o.amount;
for (const auto& o : tx.vout)
{
VARIANT_SWITCH_BEGIN(o);
VARIANT_CASE_CONST(tx_out_bare, o)
outputs_amount += o.amount;
VARIANT_CASE_CONST(tx_out_zarcanum, o)
//@#@
VARIANT_SWITCH_END();
}
return outputs_amount;
}
//---------------------------------------------------------------
@ -1962,7 +2001,10 @@ namespace currency
return true;
CHECK_AND_ASSERT_MES(offset < tx.vout.size(), false, "condition failed: offset(" << offset << ") < tx.vout.size() (" << tx.vout.size() << ")");
auto& o = tx.vout[offset];
auto& ov = tx.vout[offset];
CHECK_AND_ASSERT_MES(ov.type() == typeid(tx_out_bare), false, "unexpected type id in lookup_acc_outs_genesis:" << ov.type().name());
const tx_out_bare& o = boost::get<tx_out_bare>(ov);
CHECK_AND_ASSERT_MES(o.target.type() == typeid(txout_to_key), false, "condition failed: o.target.type() == typeid(txout_to_key)");
if (is_out_to_acc(acc, boost::get<txout_to_key>(o.target), derivation, offset))
{
@ -1994,46 +2036,46 @@ namespace currency
return true;
size_t i = 0;
for(const tx_out_bare& o : tx.vout)
for(const auto& ov : tx.vout)
{
if (o.target.type() == typeid(txout_to_key))
VARIANT_SWITCH_BEGIN(ov);
VARIANT_CASE_CONST(tx_out_bare, o)
{
if (is_out_to_acc(acc, boost::get<txout_to_key>(o.target), derivation, i))
{
outs.push_back(i);
money_transfered += o.amount;
}
}
else if (o.target.type() == typeid(txout_multisig))
{
if (is_out_to_acc(acc, boost::get<txout_multisig>(o.target), derivation, i))
{
outs.push_back(i);
//don't count this money
}
}
else if (o.target.type() == typeid(txout_htlc))
{
htlc_info hi = AUTO_VAL_INIT(hi);
const txout_htlc& htlc = boost::get<txout_htlc>(o.target);
if (is_out_to_acc(acc, htlc.pkey_redeem, derivation, i))
{
hi.hltc_our_out_is_before_expiration = true;
htlc_info_list.push_back(hi);
outs.push_back(i);
}
else if (is_out_to_acc(acc, htlc.pkey_refund, derivation, i))
{
hi.hltc_our_out_is_before_expiration = false;
htlc_info_list.push_back(hi);
outs.push_back(i);
}
}
else
{
LOG_ERROR("Wrong type at lookup_acc_outs, unexpected type is: " << o.target.type().name());
return false;
VARIANT_SWITCH_BEGIN(o.target);
VARIANT_CASE_CONST(txout_to_key, t)
if (is_out_to_acc(acc, t, derivation, i))
{
outs.push_back(i);
money_transfered += o.amount;
}
VARIANT_CASE_CONST(txout_multisig, t)
if (is_out_to_acc(acc, t, derivation, i))
{
outs.push_back(i);
//don't count this money
}
VARIANT_CASE_CONST(txout_htlc, htlc)
htlc_info hi = AUTO_VAL_INIT(hi);
if (is_out_to_acc(acc, htlc.pkey_redeem, derivation, i))
{
hi.hltc_our_out_is_before_expiration = true;
htlc_info_list.push_back(hi);
outs.push_back(i);
}
else if (is_out_to_acc(acc, htlc.pkey_refund, derivation, i))
{
hi.hltc_our_out_is_before_expiration = false;
htlc_info_list.push_back(hi);
outs.push_back(i);
}
VARIANT_CASE_OTHER()
LOG_ERROR("Wrong type at lookup_acc_outs, unexpected type is: " << o.target.type().name());
return false;
VARIANT_SWITCH_END();
}
VARIANT_CASE_CONST(tx_out_zarcanum, o)
//@#@
VARIANT_SWITCH_END();
i++;
}
return true;
@ -2504,12 +2546,18 @@ namespace currency
uint64_t found_alias_reward = 0;
for (const auto& out : tx.vout)
{
if (out.target.type() != typeid(txout_to_key))
continue;
VARIANT_SWITCH_BEGIN(out);
VARIANT_CASE_CONST(tx_out_bare, out)
if (out.target.type() != typeid(txout_to_key))
continue;
const txout_to_key& o = boost::get<txout_to_key>(out.target);
if (o.key == null_pkey)
found_alias_reward += out.amount;
VARIANT_CASE_CONST(tx_out_zarcanum, o)
//@#@
VARIANT_SWITCH_END();
const txout_to_key& o = boost::get<txout_to_key>(out.target);
if (o.key == null_pkey)
found_alias_reward += out.amount;
}
return found_alias_reward;
}
@ -2744,35 +2792,34 @@ namespace currency
for (auto& out : tx.vout)
{
tei.outs.push_back(tx_out_rpc_entry());
tei.outs.back().amount = out.amount;
tei.outs.back().is_spent = ptce ? ptce->m_spent_flags[i] : false;
tei.outs.back().global_index = ptce ? ptce->m_global_output_indexes[i] : 0;
VARIANT_SWITCH_BEGIN(out);
VARIANT_CASE_CONST(tx_out_bare, out)
{
tei.outs.back().amount = out.amount;
if (out.target.type() == typeid(txout_to_key))
{
const txout_to_key& otk = boost::get<txout_to_key>(out.target);
tei.outs.back().pub_keys.push_back(epee::string_tools::pod_to_hex(otk.key));
if (otk.mix_attr == CURRENCY_TO_KEY_OUT_FORCED_NO_MIX)
tei.outs.back().pub_keys.back() += "(FORCED_NO_MIX)";
if (otk.mix_attr >= CURRENCY_TO_KEY_OUT_FORCED_MIX_LOWER_BOUND)
tei.outs.back().pub_keys.back() += std::string("(FORCED_MIX_LOWER_BOUND: ") + std::to_string(otk.mix_attr) + ")";
VARIANT_SWITCH_BEGIN(out.target);
VARIANT_CASE_CONST(txout_to_key, otk)
tei.outs.back().pub_keys.push_back(epee::string_tools::pod_to_hex(otk.key));
if (otk.mix_attr == CURRENCY_TO_KEY_OUT_FORCED_NO_MIX)
tei.outs.back().pub_keys.back() += "(FORCED_NO_MIX)";
if (otk.mix_attr >= CURRENCY_TO_KEY_OUT_FORCED_MIX_LOWER_BOUND)
tei.outs.back().pub_keys.back() += std::string("(FORCED_MIX_LOWER_BOUND: ") + std::to_string(otk.mix_attr) + ")";
VARIANT_CASE_CONST(txout_multisig, otm)
for (auto& k : otm.keys)
{
tei.outs.back().pub_keys.push_back(epee::string_tools::pod_to_hex(k));
}
tei.outs.back().minimum_sigs = otm.minimum_sigs;
VARIANT_CASE_CONST(txout_htlc, otk)
tei.outs.back().pub_keys.push_back(epee::string_tools::pod_to_hex(otk.pkey_redeem) + "(htlc_pkey_redeem)");
tei.outs.back().pub_keys.push_back(epee::string_tools::pod_to_hex(otk.pkey_refund) + "(htlc_pkey_refund)");
VARIANT_SWITCH_END();
}
else if (out.target.type() == typeid(txout_multisig))
{
const txout_multisig& otm = boost::get<txout_multisig>(out.target);
for (auto& k : otm.keys)
{
tei.outs.back().pub_keys.push_back(epee::string_tools::pod_to_hex(k));
}
tei.outs.back().minimum_sigs = otm.minimum_sigs;
}
else if (out.target.type() == typeid(txout_htlc))
{
const txout_htlc& otk = boost::get<txout_htlc>(out.target);
tei.outs.back().pub_keys.push_back(epee::string_tools::pod_to_hex(otk.pkey_redeem) + "(htlc_pkey_redeem)");
tei.outs.back().pub_keys.push_back(epee::string_tools::pod_to_hex(otk.pkey_refund) + "(htlc_pkey_refund)");
}
VARIANT_CASE_CONST(tx_out_zarcanum, o)
//@#@
VARIANT_SWITCH_END();
++i;
}
return true;
@ -2819,8 +2866,8 @@ namespace currency
txin_multisig& tms = boost::get<txin_multisig>(in);
tei.ins.back().amount = tms.amount;
tei.ins.back().kimage_or_ms_id = epee::string_tools::pod_to_hex(tms.multisig_out_id);
if (tx.signatures.size() >= tei.ins.size())
tei.ins.back().multisig_count = tx.signatures[tei.ins.size() - 1].size();
if (tx.signature.type() == typeid(NLSAG_sig) && boost::get<NLSAG_sig>(tx.signature).s.size() >= tei.ins.size())
tei.ins.back().multisig_count = boost::get<NLSAG_sig>(tx.signature).s[tei.ins.size() - 1].size();
}
}
return true;
@ -2880,11 +2927,16 @@ namespace currency
{
for (size_t n = 0; n < tx.vout.size(); ++n)
{
if (tx.vout[n].target.type() == typeid(txout_to_key) || tx.vout[n].target.type() == typeid(txout_htlc))
{
uint64_t amount = tx.vout[n].amount;
gindices[amount] += 1;
}
VARIANT_SWITCH_BEGIN(tx.vout[n]);
VARIANT_CASE_CONST(tx_out_bare, o)
if (o.target.type() == typeid(txout_to_key) || o.target.type() == typeid(txout_htlc))
{
uint64_t amount = o.amount;
gindices[amount] += 1;
}
VARIANT_CASE_CONST(tx_out_zarcanum, o)
//@#@
VARIANT_SWITCH_END();
}
}
//---------------------------------------------------------------
@ -2977,6 +3029,15 @@ namespace currency
return true;
}
//-----------------------------------------------------------------------
bool is_pos_coinbase(const transaction& tx)
{
bool pos = false;
if (!is_coinbase(tx, pos) || !pos)
return false;
return true;
}
//-----------------------------------------------------------------------
bool is_coinbase(const transaction& tx, bool& pos_coinbase)
{
if (!is_coinbase(tx))

View file

@ -301,7 +301,7 @@ namespace currency
void load_wallet_transfer_info_flags(tools::wallet_public::wallet_transfer_info& x);
uint64_t get_tx_type(const transaction& tx);
uint64_t get_tx_type_ex(const transaction& tx, tx_out_bare& htlc_out, txin_htlc& htlc_in);
size_t get_multisig_out_index(const std::vector<tx_out_bare>& outs);
size_t get_multisig_out_index(const std::vector<tx_out_v>& outs);
size_t get_multisig_in_index(const std::vector<txin_v>& inputs);
uint64_t get_reward_from_miner_tx(const transaction& tx);
@ -418,6 +418,7 @@ namespace currency
bool parse_payment_id_from_hex_str(const std::string& payment_id_str, payment_id_t& payment_id);
bool is_coinbase(const transaction& tx);
bool is_coinbase(const transaction& tx, bool& pos_coinbase);
bool is_pos_coinbase(const transaction& tx);
bool have_attachment_service_in_container(const std::vector<attachment_v>& av, const std::string& service_id, const std::string& instruction);
crypto::hash prepare_prefix_hash_for_sign(const transaction& tx, uint64_t in_index, const crypto::hash& tx_id);
@ -698,7 +699,13 @@ namespace currency
uint64_t operator()(const t_input& i) const{return i.amount;}
uint64_t operator()(const txin_gen& i) const {return 0;}
};
//---------------------------------------------------------------
inline const tx_out_bare& get_tx_out_bare_from_out_v(const tx_out_v& o)
{
//this function will throw if type is not matching
return boost::get<tx_out_bare>(o);
}
//---------------------------------------------------------------
inline uint64_t get_amount_from_variant(const txin_v& v)
{
return boost::apply_visitor(input_amount_getter(), v);

View file

@ -8,6 +8,7 @@
#include "serialization/serialization.h"
#include "currency_format_utils.h"
#include "currency_format_utils_abstract.h"
#include "common/variant_helper.h"
namespace currency
{
@ -32,16 +33,27 @@ namespace currency
return expiration_time <= expiration_ts_median + TX_EXPIRATION_MEDIAN_SHIFT;
}
//---------------------------------------------------------------
uint64_t get_burned_amount(const transaction& tx)
{
uint64_t res = 0;
for (auto& o : tx.vout)
{
if (o.target.type() == typeid(txout_to_key))
{
if (boost::get<txout_to_key>(o.target).key == null_pkey)
res += o.amount;
}
VARIANT_SWITCH_BEGIN(o);
VARIANT_CASE_CONST(tx_out_bare, o)
if (o.target.type() == typeid(txout_to_key))
{
if (boost::get<txout_to_key>(o.target).key == null_pkey)
res += o.amount;
}
VARIANT_CASE_CONST(tx_out_zarcanum, o)
//@#@
VARIANT_CASE_THROW_ON_OTHER();
VARIANT_SWITCH_END();
}
return res;
}

View file

@ -1330,8 +1330,15 @@ namespace currency
idx = 0;
for (const auto& out : tx.vout)
{
if (out.target.type() == typeid(txout_multisig))
result.push_back(ms_out_info({ get_multisig_out_id(tx, idx), idx, false }));
VARIANT_SWITCH_BEGIN(out);
VARIANT_CASE_CONST(tx_out_bare, o)
if (o.target.type() == typeid(txout_multisig))
result.push_back(ms_out_info({ get_multisig_out_id(tx, idx), idx, false }));
VARIANT_CASE_CONST(tx_out_zarcanum, o)
//@#@
VARIANT_CASE_THROW_ON_OTHER();
VARIANT_SWITCH_END();
++idx;
}
}
@ -1347,8 +1354,13 @@ namespace currency
size_t idx = 0;
for (const auto& out : tx.vout)
{
if (out.target.type() == typeid(txout_multisig) && get_multisig_out_id(tx, idx) == multisig_id)
return true;
VARIANT_SWITCH_BEGIN(out);
VARIANT_CASE_CONST(tx_out_bare, o)
if (o.target.type() == typeid(txout_multisig) && get_multisig_out_id(tx, idx) == multisig_id)
return true;
VARIANT_CASE_CONST(tx_out_zarcanum, o)
//@#@
VARIANT_SWITCH_END();
++idx;
}

View file

@ -970,9 +970,14 @@ namespace currency
uint64_t core_rpc_server::get_block_reward(const block& blk)
{
uint64_t reward = 0;
BOOST_FOREACH(const tx_out_bare& out, blk.miner_tx.vout)
BOOST_FOREACH(const auto& out, blk.miner_tx.vout)
{
reward += out.amount;
VARIANT_SWITCH_BEGIN(out);
VARIANT_CASE_CONST(tx_out_bare, out)
reward += out.amount;
VARIANT_CASE_CONST(tx_out_zarcanum, out)
//@#@
VARIANT_SWITCH_END();
}
return reward;
}

View file

@ -36,6 +36,7 @@ using namespace epee;
#endif
#include "storages/levin_abstract_invoke2.h"
#include "common/variant_helper.h"
using namespace currency;
@ -86,12 +87,17 @@ namespace tools
for (auto ri : td.receive_indices)
{
CHECK_AND_ASSERT_THROW_MES(ri < tx.vout.size(), "Internal error: wrong tx transfer details: reciev index=" << ri << " is greater than transaction outputs vector " << tx.vout.size());
if (tx.vout[ri].target.type() == typeid(currency::txout_to_key))
{
//update unlock_time if needed
if (ut2.unlock_time_array[ri] > max_unlock_time)
max_unlock_time = ut2.unlock_time_array[ri];
}
VARIANT_SWITCH_BEGIN(tx.vout[ri]);
VARIANT_CASE_CONST(tx_out_bare, o)
if (o.target.type() == typeid(currency::txout_to_key))
{
//update unlock_time if needed
if (ut2.unlock_time_array[ri] > max_unlock_time)
max_unlock_time = ut2.unlock_time_array[ri];
}
VARIANT_CASE_CONST(tx_out_zarcanum, o);
VARIANT_SWITCH_END();
}
return max_unlock_time;
}
@ -109,10 +115,16 @@ void wallet2::fill_transfer_details(const currency::transaction& tx, const tools
for (auto ri : td.receive_indices)
{
WLT_CHECK_AND_ASSERT_MES(ri < tx.vout.size(), void(), "Internal error: wrong tx transfer details: reciev index=" << ri << " is greater than transaction outputs vector " << tx.vout.size());
if (tx.vout[ri].target.type() == typeid(currency::txout_to_key))
{
res_td.rcv.push_back(tx.vout[ri].amount);
}
VARIANT_SWITCH_BEGIN(tx.vout[ri]);
VARIANT_CASE_CONST(tx_out_bare, o)
if (o.target.type() == typeid(currency::txout_to_key))
{
res_td.rcv.push_back(o.amount);
}
VARIANT_CASE_CONST(tx_out_zarcanum, o);
//@#@
VARIANT_SWITCH_END();
}
}
//----------------------------------------------------------------------------------------------------
@ -405,7 +417,8 @@ void wallet2::process_new_transaction(const currency::transaction& tx, uint64_t
{
transfer_details& td = m_transfers[it->second];
WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(td.m_ptx_wallet_info->m_tx.vout.size() > td.m_internal_output_index, "Internal error: wrong td.m_internal_output_index: " << td.m_internal_output_index);
const boost::typeindex::type_info& ti = td.m_ptx_wallet_info->m_tx.vout[td.m_internal_output_index].target.type();
WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(td.m_ptx_wallet_info->m_tx.vout[td.m_internal_output_index].type() == typeid(tx_out_bare), "Internal error: wrong output type: " << td.m_ptx_wallet_info->m_tx.vout[td.m_internal_output_index].type().name());
const boost::typeindex::type_info& ti = boost::get<tx_out_bare>(td.m_ptx_wallet_info->m_tx.vout[td.m_internal_output_index]).target.type();
WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(ti == typeid(txout_htlc), "Internal error: wrong type of output's target: " << ti.name());
//input spend active htlc
m_transfers[it->second].m_spent_height = height;
@ -465,199 +478,206 @@ void wallet2::process_new_transaction(const currency::transaction& tx, uint64_t
{
size_t o = outs[i_in_outs];
WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(o < tx.vout.size(), "wrong out in transaction: internal index=" << o << ", total_outs=" << tx.vout.size());
if (tx.vout[o].target.type() == typeid(txout_to_key) || tx.vout[o].target.type() == typeid(txout_htlc))
VARIANT_SWITCH_BEGIN(tx.vout[o]);
VARIANT_CASE_CONST(tx_out_bare, out)
{
bool hltc_our_out_is_before_expiration = false;
crypto::public_key out_key = null_pkey;
if (tx.vout[o].target.type() == typeid(txout_to_key))
if (out.target.type() == typeid(txout_to_key) || out.target.type() == typeid(txout_htlc))
{
out_key = boost::get<currency::txout_to_key>(tx.vout[o].target).key;
}
else if (tx.vout[o].target.type() == typeid(txout_htlc))
{
THROW_IF_FALSE_WALLET_INT_ERR_EX(htlc_info_list.size() > 0, "Found txout_htlc out but htlc_info_list is empty");
if (htlc_info_list.front().hltc_our_out_is_before_expiration)
bool hltc_our_out_is_before_expiration = false;
crypto::public_key out_key = null_pkey;
if (out.target.type() == typeid(txout_to_key))
{
out_key = boost::get<currency::txout_htlc>(tx.vout[o].target).pkey_redeem;
out_key = boost::get<currency::txout_to_key>(out.target).key;
}
else
else if (out.target.type() == typeid(txout_htlc))
{
out_key = boost::get<currency::txout_htlc>(tx.vout[o].target).pkey_refund;
}
htlc_info_list.pop_front();
}
else
{
THROW_IF_TRUE_WALLET_INT_ERR_EX(false, "Unexpected out type im wallet: " << tx.vout[o].target.type().name());
}
//const currency::txout_to_key& otk = boost::get<currency::txout_to_key>(tx.vout[o].target);
// obtain key image for this output
crypto::key_image ki = currency::null_ki;
if (m_watch_only)
{
if (!is_auditable())
{
// don't have spend secret key, so we unable to calculate key image for an output
// look it up in special container instead
auto it = m_pending_key_images.find(out_key);
if (it != m_pending_key_images.end())
THROW_IF_FALSE_WALLET_INT_ERR_EX(htlc_info_list.size() > 0, "Found txout_htlc out but htlc_info_list is empty");
if (htlc_info_list.front().hltc_our_out_is_before_expiration)
{
ki = it->second;
WLT_LOG_L1("pending key image " << ki << " was found by out pub key " << out_key);
out_key = boost::get<currency::txout_htlc>(out.target).pkey_redeem;
}
else
{
ki = currency::null_ki;
WLT_LOG_L1("can't find pending key image by out pub key: " << out_key << ", key image temporarily set to null");
out_key = boost::get<currency::txout_htlc>(out.target).pkey_refund;
}
htlc_info_list.pop_front();
}
else
{
THROW_IF_TRUE_WALLET_INT_ERR_EX(false, "Unexpected out type im wallet: " << out.target.type().name());
}
//const currency::txout_to_key& otk = boost::get<currency::txout_to_key>(out.target);
// obtain key image for this output
crypto::key_image ki = currency::null_ki;
if (m_watch_only)
{
if (!is_auditable())
{
// don't have spend secret key, so we unable to calculate key image for an output
// look it up in special container instead
auto it = m_pending_key_images.find(out_key);
if (it != m_pending_key_images.end())
{
ki = it->second;
WLT_LOG_L1("pending key image " << ki << " was found by out pub key " << out_key);
}
else
{
ki = currency::null_ki;
WLT_LOG_L1("can't find pending key image by out pub key: " << out_key << ", key image temporarily set to null");
}
}
}
}
else
{
// normal wallet, calculate and store key images for own outs
currency::keypair in_ephemeral = AUTO_VAL_INIT(in_ephemeral);
currency::generate_key_image_helper(m_account.get_keys(), tx_pub_key, o, in_ephemeral, ki);
WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(in_ephemeral.pub == out_key, "key_image generated ephemeral public key that does not match with output_key");
}
if (ki != currency::null_ki)
{
// make sure calculated key image for this own output has not been seen before
auto it = m_key_images.find(ki);
if (it != m_key_images.end())
else
{
// normal wallet, calculate and store key images for own outs
currency::keypair in_ephemeral = AUTO_VAL_INIT(in_ephemeral);
currency::generate_key_image_helper(m_account.get_keys(), tx_pub_key, o, in_ephemeral, ki);
WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(in_ephemeral.pub == out_key, "key_image generated ephemeral public key that does not match with output_key");
}
if (ki != currency::null_ki)
{
// make sure calculated key image for this own output has not been seen before
auto it = m_key_images.find(ki);
if (it != m_key_images.end())
{
WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(it->second < m_transfers.size(), "m_key_images entry has wrong m_transfers index, it->second: " << it->second << ", m_transfers.size(): " << m_transfers.size());
const transfer_details& local_td = m_transfers[it->second];
std::stringstream ss;
ss << "tx " << get_transaction_hash(tx) << " @ block " << height << " has output #" << o << " with key image " << ki << " that has already been seen in output #" <<
local_td.m_internal_output_index << " in tx " << get_transaction_hash(local_td.m_ptx_wallet_info->m_tx) << " @ block " << local_td.m_spent_height <<
". This output can't ever be spent and will be skipped.";
WLT_LOG_YELLOW(ss.str(), LOG_LEVEL_0);
if (m_wcallback)
m_wcallback->on_message(i_wallet2_callback::ms_yellow, ss.str());
WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(tx_money_got_in_outs >= out.amount, "tx_money_got_in_outs: " << tx_money_got_in_outs << ", out.amount:" << out.amount);
tx_money_got_in_outs -= out.amount;
continue; // skip the output
}
}
if (is_auditable() && out.target.type() == typeid(txout_to_key) &&
boost::get<txout_to_key>(out.target).mix_attr != CURRENCY_TO_KEY_OUT_FORCED_NO_MIX)
{
WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(it->second < m_transfers.size(), "m_key_images entry has wrong m_transfers index, it->second: " << it->second << ", m_transfers.size(): " << m_transfers.size());
const transfer_details& local_td = m_transfers[it->second];
std::stringstream ss;
ss << "tx " << get_transaction_hash(tx) << " @ block " << height << " has output #" << o << " with key image " << ki << " that has already been seen in output #" <<
local_td.m_internal_output_index << " in tx " << get_transaction_hash(local_td.m_ptx_wallet_info->m_tx) << " @ block " << local_td.m_spent_height <<
". This output can't ever be spent and will be skipped.";
WLT_LOG_YELLOW(ss.str(), LOG_LEVEL_0);
ss << "output #" << o << " from tx " << get_transaction_hash(tx) << " with amount " << print_money_brief(out.amount)
<< " is targeted to this auditable wallet and has INCORRECT mix_attr = " << (uint64_t)boost::get<txout_to_key>(out.target).mix_attr << ". Output IGNORED.";
WLT_LOG_RED(ss.str(), LOG_LEVEL_0);
if (m_wcallback)
m_wcallback->on_message(i_wallet2_callback::ms_yellow, ss.str());
WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(tx_money_got_in_outs >= tx.vout[o].amount, "tx_money_got_in_outs: " << tx_money_got_in_outs << ", tx.vout[o].amount:" << tx.vout[o].amount);
tx_money_got_in_outs -= tx.vout[o].amount;
m_wcallback->on_message(i_wallet2_callback::ms_red, ss.str());
tx_money_got_in_outs -= out.amount;
continue; // skip the output
}
}
if (is_auditable() && tx.vout[o].target.type() == typeid(txout_to_key) &&
boost::get<txout_to_key>(tx.vout[o].target).mix_attr != CURRENCY_TO_KEY_OUT_FORCED_NO_MIX)
{
std::stringstream ss;
ss << "output #" << o << " from tx " << get_transaction_hash(tx) << " with amount " << print_money_brief(tx.vout[o].amount)
<< " is targeted to this auditable wallet and has INCORRECT mix_attr = " << (uint64_t)boost::get<txout_to_key>(tx.vout[o].target).mix_attr << ". Output IGNORED.";
WLT_LOG_RED(ss.str(), LOG_LEVEL_0);
if (m_wcallback)
m_wcallback->on_message(i_wallet2_callback::ms_red, ss.str());
tx_money_got_in_outs -= tx.vout[o].amount;
continue; // skip the output
}
mtd.receive_indices.push_back(o);
mtd.receive_indices.push_back(o);
m_transfers.push_back(boost::value_initialized<transfer_details>());
transfer_details& td = m_transfers.back();
td.m_ptx_wallet_info = pwallet_info;
td.m_internal_output_index = o;
td.m_key_image = ki;
if (m_use_deffered_global_outputs)
{
if (pglobal_indexes && pglobal_indexes->size() > o)
td.m_global_output_index = (*pglobal_indexes)[o];
else
td.m_global_output_index = WALLET_GLOBAL_OUTPUT_INDEX_UNDEFINED;
}
else
{
WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(pglobal_indexes, "pglobal_indexes IS NULL in non mobile wallet");
WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(pglobal_indexes->size() > o, "pglobal_indexes size()(" << pglobal_indexes->size() << ") <= o " << o );
td.m_global_output_index = (*pglobal_indexes)[o];
}
if (coin_base_tx)
{
//last out in coinbase tx supposed to be change from coinstake
if (!(o == tx.vout.size() - 1 && !is_derived_from_coinbase))
m_transfers.push_back(boost::value_initialized<transfer_details>());
transfer_details& td = m_transfers.back();
td.m_ptx_wallet_info = pwallet_info;
td.m_internal_output_index = o;
td.m_key_image = ki;
if (m_use_deffered_global_outputs)
{
td.m_flags |= WALLET_TRANSFER_DETAIL_FLAG_MINED_TRANSFER;
if (pglobal_indexes && pglobal_indexes->size() > o)
td.m_global_output_index = (*pglobal_indexes)[o];
else
td.m_global_output_index = WALLET_GLOBAL_OUTPUT_INDEX_UNDEFINED;
}
}
uint64_t amount = tx.vout[o].amount;
size_t transfer_index = m_transfers.size() - 1;
if (tx.vout[o].target.type() == typeid(txout_htlc))
{
const txout_htlc& hltc = boost::get<currency::txout_htlc>(tx.vout[o].target);
//mark this as spent
td.m_flags |= WALLET_TRANSFER_DETAIL_FLAG_SPENT;
//create entry for htlc input
htlc_expiration_trigger het = AUTO_VAL_INIT(het);
het.is_wallet_owns_redeem = (out_key == hltc.pkey_redeem) ? true:false;
het.transfer_index = transfer_index;
uint64_t expired_if_more_then = td.m_ptx_wallet_info->m_block_height + hltc.expiration;
m_htlcs.insert(std::make_pair(expired_if_more_then, het));
if (het.is_wallet_owns_redeem)
else
{
td.m_flags |= WALLET_TRANSFER_DETAIL_FLAG_HTLC_REDEEM;
}
//active htlc
auto amount_gindex_pair = std::make_pair(amount, td.m_global_output_index);
m_active_htlcs[amount_gindex_pair] = transfer_index;
m_active_htlcs_txid[get_transaction_hash(tx)] = transfer_index;
//add payer to extra options
currency::tx_payer payer = AUTO_VAL_INIT(payer);
if (het.is_wallet_owns_redeem)
WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(pglobal_indexes, "pglobal_indexes IS NULL in non mobile wallet");
WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(pglobal_indexes->size() > o, "pglobal_indexes size()(" << pglobal_indexes->size() << ") <= o " << o);
td.m_global_output_index = (*pglobal_indexes)[o];
}
if (coin_base_tx)
{
if (currency::get_type_in_variant_container(tx.extra, payer))
//last out in coinbase tx supposed to be change from coinstake
if (!(o == tx.vout.size() - 1 && !is_derived_from_coinbase))
{
crypto::chacha_crypt(payer.acc_addr, derivation);
td.varian_options.push_back(payer);
td.m_flags |= WALLET_TRANSFER_DETAIL_FLAG_MINED_TRANSFER;
}
}
else
uint64_t amount = out.amount;
size_t transfer_index = m_transfers.size() - 1;
if (out.target.type() == typeid(txout_htlc))
{
//since this is refund-mode htlc out, then sender is this wallet itself
payer.acc_addr = m_account.get_public_address();
td.varian_options.push_back(payer);
const txout_htlc& hltc = boost::get<currency::txout_htlc>(out.target);
//mark this as spent
td.m_flags |= WALLET_TRANSFER_DETAIL_FLAG_SPENT;
//create entry for htlc input
htlc_expiration_trigger het = AUTO_VAL_INIT(het);
het.is_wallet_owns_redeem = (out_key == hltc.pkey_redeem) ? true : false;
het.transfer_index = transfer_index;
uint64_t expired_if_more_then = td.m_ptx_wallet_info->m_block_height + hltc.expiration;
m_htlcs.insert(std::make_pair(expired_if_more_then, het));
if (het.is_wallet_owns_redeem)
{
td.m_flags |= WALLET_TRANSFER_DETAIL_FLAG_HTLC_REDEEM;
}
//active htlc
auto amount_gindex_pair = std::make_pair(amount, td.m_global_output_index);
m_active_htlcs[amount_gindex_pair] = transfer_index;
m_active_htlcs_txid[get_transaction_hash(tx)] = transfer_index;
//add payer to extra options
currency::tx_payer payer = AUTO_VAL_INIT(payer);
if (het.is_wallet_owns_redeem)
{
if (currency::get_type_in_variant_container(tx.extra, payer))
{
crypto::chacha_crypt(payer.acc_addr, derivation);
td.varian_options.push_back(payer);
}
}
else
{
//since this is refund-mode htlc out, then sender is this wallet itself
payer.acc_addr = m_account.get_public_address();
td.varian_options.push_back(payer);
}
}
if (td.m_key_image != currency::null_ki)
m_key_images[td.m_key_image] = transfer_index;
add_transfer_to_transfers_cache(amount, transfer_index);
if (is_watch_only() && is_auditable())
{
WLT_CHECK_AND_ASSERT_MES_NO_RET(td.m_global_output_index != WALLET_GLOBAL_OUTPUT_INDEX_UNDEFINED, "td.m_global_output_index != WALLET_GLOBAL_OUTPUT_INDEX_UNDEFINED validation failed");
auto amount_gindex_pair = std::make_pair(amount, td.m_global_output_index);
WLT_CHECK_AND_ASSERT_MES_NO_RET(m_amount_gindex_to_transfer_id.count(amount_gindex_pair) == 0, "update m_amount_gindex_to_transfer_id: amount " << amount << ", gindex " << td.m_global_output_index << " already exists");
m_amount_gindex_to_transfer_id[amount_gindex_pair] = transfer_index;
}
if (max_out_unlock_time < get_tx_unlock_time(tx, o))
max_out_unlock_time = get_tx_unlock_time(tx, o);
if (out.target.type() == typeid(txout_to_key))
{
WLT_LOG_L0("Received money, transfer #" << transfer_index << ", amount: " << print_money(td.amount()) << ", with tx: " << get_transaction_hash(tx) << ", at height " << height);
}
else if (out.target.type() == typeid(txout_htlc))
{
WLT_LOG_L0("Detected HTLC[" << (td.m_flags&WALLET_TRANSFER_DETAIL_FLAG_HTLC_REDEEM ? "REDEEM" : "REFUND") << "], transfer #" << transfer_index << ", amount: " << print_money(td.amount()) << ", with tx: " << get_transaction_hash(tx) << ", at height " << height);
}
}
if (td.m_key_image != currency::null_ki)
m_key_images[td.m_key_image] = transfer_index;
add_transfer_to_transfers_cache(amount, transfer_index);
if (is_watch_only() && is_auditable())
else if (out.target.type() == typeid(txout_multisig))
{
WLT_CHECK_AND_ASSERT_MES_NO_RET(td.m_global_output_index != WALLET_GLOBAL_OUTPUT_INDEX_UNDEFINED, "td.m_global_output_index != WALLET_GLOBAL_OUTPUT_INDEX_UNDEFINED validation failed");
auto amount_gindex_pair = std::make_pair(amount, td.m_global_output_index);
WLT_CHECK_AND_ASSERT_MES_NO_RET(m_amount_gindex_to_transfer_id.count(amount_gindex_pair) == 0, "update m_amount_gindex_to_transfer_id: amount " << amount << ", gindex " << td.m_global_output_index << " already exists");
m_amount_gindex_to_transfer_id[amount_gindex_pair] = transfer_index;
}
if (max_out_unlock_time < get_tx_unlock_time(tx, o))
max_out_unlock_time = get_tx_unlock_time(tx, o);
if (tx.vout[o].target.type() == typeid(txout_to_key))
{
WLT_LOG_L0("Received money, transfer #" << transfer_index << ", amount: " << print_money(td.amount()) << ", with tx: " << get_transaction_hash(tx) << ", at height " << height);
}
else if (tx.vout[o].target.type() == typeid(txout_htlc))
{
WLT_LOG_L0("Detected HTLC[" << (td.m_flags&WALLET_TRANSFER_DETAIL_FLAG_HTLC_REDEEM ? "REDEEM":"REFUND") << "], transfer #" << transfer_index << ", amount: " << print_money(td.amount()) << ", with tx: " << get_transaction_hash(tx) << ", at height " << height);
crypto::hash multisig_id = currency::get_multisig_out_id(tx, o);
WLT_CHECK_AND_ASSERT_MES_NO_RET(m_multisig_transfers.count(multisig_id) == 0, "multisig_id = " << multisig_id << " already in multisig container");
transfer_details_base& tdb = m_multisig_transfers[multisig_id];
tdb.m_ptx_wallet_info = pwallet_info;
tdb.m_internal_output_index = o;
WLT_LOG_L0("Received multisig, multisig out id: " << multisig_id << ", amount: " << tdb.amount() << ", with tx: " << get_transaction_hash(tx));
}
}
else if (tx.vout[o].target.type() == typeid(txout_multisig))
{
crypto::hash multisig_id = currency::get_multisig_out_id(tx, o);
WLT_CHECK_AND_ASSERT_MES_NO_RET(m_multisig_transfers.count(multisig_id) == 0, "multisig_id = " << multisig_id << " already in multisig container");
transfer_details_base& tdb = m_multisig_transfers[multisig_id];
tdb.m_ptx_wallet_info = pwallet_info;
tdb.m_internal_output_index = o;
WLT_LOG_L0("Received multisig, multisig out id: " << multisig_id << ", amount: " << tdb.amount() << ", with tx: " << get_transaction_hash(tx));
}
VARIANT_CASE_CONST(tx_out_zarcanum, o);
//@#@
VARIANT_SWITCH_END();
}
}
@ -813,10 +833,11 @@ void wallet2::accept_proposal(const crypto::hash& contract_id, uint64_t b_accept
tdb.m_flags &= ~(WALLET_TRANSFER_DETAIL_FLAG_SPENT);
//---------------------------------
//figure out fee that was left for release contract
THROW_IF_FALSE_WALLET_INT_ERR_EX(tx.vout[n].amount > (contr_it->second.private_detailes.amount_to_pay +
THROW_IF_FALSE_WALLET_INT_ERR_EX(tx.vout[n].type() == typeid(tx_out_bare), "Unexpected output type in accept proposal");
THROW_IF_FALSE_WALLET_INT_ERR_EX(boost::get<tx_out_bare>(tx.vout[n]).amount > (contr_it->second.private_detailes.amount_to_pay +
contr_it->second.private_detailes.amount_b_pledge +
contr_it->second.private_detailes.amount_a_pledge), "THere is no left money for fee, contract_id: " << contract_id);
uint64_t left_for_fee_in_multisig = tx.vout[n].amount - (contr_it->second.private_detailes.amount_to_pay +
uint64_t left_for_fee_in_multisig = boost::get<tx_out_bare>(tx.vout[n]).amount - (contr_it->second.private_detailes.amount_to_pay +
contr_it->second.private_detailes.amount_b_pledge +
contr_it->second.private_detailes.amount_a_pledge);
@ -1381,7 +1402,8 @@ void wallet2::unprocess_htlc_triggers_on_block_removed(uint64_t height)
tr.m_spent_height = 0;
}
//re-add to active contracts
auto pair_key = std::make_pair(tr.m_ptx_wallet_info->m_tx.vout[tr.m_internal_output_index].amount, tr.m_global_output_index);
WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(tr.m_ptx_wallet_info->m_tx.vout[tr.m_internal_output_index].type() == typeid(tx_out_bare), std::string("Unexprected type of out in unprocess_htlc_triggers_on_block_removed : ") + tr.m_ptx_wallet_info->m_tx.vout[tr.m_internal_output_index].type().name());
auto pair_key = std::make_pair(boost::get<tx_out_bare>(tr.m_ptx_wallet_info->m_tx.vout[tr.m_internal_output_index]).amount, tr.m_global_output_index);
auto it_active_htlc = m_active_htlcs.find(pair_key);
if (it_active_htlc != m_active_htlcs.end())
{
@ -1443,7 +1465,10 @@ void wallet2::process_htlc_triggers_on_block_added(uint64_t height)
m_found_free_amounts.clear();
//remove it from active contracts
auto it_active_htlc = m_active_htlcs.find(std::make_pair(tr.m_ptx_wallet_info->m_tx.vout[tr.m_internal_output_index].amount, tr.m_global_output_index));
CHECK_AND_ASSERT_MES(tr.m_ptx_wallet_info->m_tx.vout[tr.m_internal_output_index].type() == typeid(tx_out_bare), void(), "Unexpected type out in process_htlc_triggers_on_block_added: " << tr.m_ptx_wallet_info->m_tx.vout[tr.m_internal_output_index].type().name());
uint64_t amount = boost::get<tx_out_bare>(tr.m_ptx_wallet_info->m_tx.vout[tr.m_internal_output_index]).amount;
auto it_active_htlc = m_active_htlcs.find(std::make_pair(amount, tr.m_global_output_index));
if (it_active_htlc == m_active_htlcs.end())
{
LOG_ERROR("Erasing active htlc(m_active_htlcs), but it seems to be already erased");
@ -2139,7 +2164,8 @@ bool wallet2::scan_unconfirmed_outdate_tx()
if (t.m_flags&WALLET_TRANSFER_DETAIL_FLAG_SPENT
&& !t.m_spent_height
&& !static_cast<bool>(t.m_flags&WALLET_TRANSFER_DETAIL_FLAG_ESCROW_PROPOSAL_RESERVATION)
&& t.m_ptx_wallet_info->m_tx.vout[t.m_internal_output_index].target.type() != typeid(txout_htlc)
&& t.m_ptx_wallet_info->m_tx.vout[t.m_internal_output_index].type() == typeid(tx_out_bare)
&& boost::get<tx_out_bare>(t.m_ptx_wallet_info->m_tx.vout[t.m_internal_output_index]).target.type() != typeid(txout_htlc)
)
{
//check if there is unconfirmed for this transfer is no longer exist?
@ -2312,10 +2338,11 @@ void wallet2::detach_blockchain(uint64_t including_height)
for (size_t i = i_start; i != m_transfers.size(); i++)
{
//check for htlc
if (m_transfers[i].m_ptx_wallet_info->m_tx.vout[m_transfers[i].m_internal_output_index].target.type() == typeid(txout_htlc))
if (m_transfers[i].m_ptx_wallet_info->m_tx.vout[m_transfers[i].m_internal_output_index].type() == typeid(tx_out_bare) &&
boost::get<tx_out_bare>(m_transfers[i].m_ptx_wallet_info->m_tx.vout[m_transfers[i].m_internal_output_index]).target.type() == typeid(txout_htlc))
{
//need to find an entry in m_htlc and remove it
const txout_htlc& hltc = boost::get<txout_htlc>(m_transfers[i].m_ptx_wallet_info->m_tx.vout[m_transfers[i].m_internal_output_index].target);
const txout_htlc& hltc = boost::get<txout_htlc>(boost::get<tx_out_bare>(m_transfers[i].m_ptx_wallet_info->m_tx.vout[m_transfers[i].m_internal_output_index]).target);
uint64_t expiration_height = m_transfers[i].m_ptx_wallet_info->m_block_height + hltc.expiration;
auto pair_of_it = m_htlcs.equal_range(expiration_height);
bool found = false;
@ -2881,7 +2908,9 @@ void wallet2::store_watch_only(const std::wstring& path_to_save, const std::stri
if (!td.is_spent())
continue; // only spent transfers really need to be stored, because watch-only wallet will not be able to figure out they were spent otherwise
WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(td.m_internal_output_index < td.m_ptx_wallet_info->m_tx.vout.size(), "invalid transfer #" << ti);
const currency::txout_target_v& out_t = td.m_ptx_wallet_info->m_tx.vout[td.m_internal_output_index].target;
if(td.m_ptx_wallet_info->m_tx.vout[td.m_internal_output_index].type() != typeid(tx_out_bare))
continue;
const currency::txout_target_v& out_t = boost::get<tx_out_bare>(td.m_ptx_wallet_info->m_tx.vout[td.m_internal_output_index]).target;
if (out_t.type() != typeid(currency::txout_to_key))
continue;
const crypto::public_key& out_key = boost::get<txout_to_key>(out_t).key;
@ -3064,28 +3093,34 @@ void wallet2::sign_transfer(const std::string& tx_sources_blob, std::string& sig
for (size_t i = 0; i < ft.tx.vout.size(); ++i)
{
const auto& out = ft.tx.vout[i];
if (out.target.type() != typeid(txout_to_key))
continue;
const txout_to_key& otk = boost::get<txout_to_key>(out.target);
crypto::public_key ephemeral_pub = AUTO_VAL_INIT(ephemeral_pub);
if (!crypto::derive_public_key(derivation, i, m_account.get_keys().account_address.spend_public_key, ephemeral_pub))
VARIANT_SWITCH_BEGIN(ft.tx.vout[i]);
VARIANT_CASE_CONST(tx_out_bare, out)
{
WLT_LOG_ERROR("derive_public_key failed for tx " << get_transaction_hash(ft.tx) << ", out # " << i);
}
if (out.target.type() != typeid(txout_to_key))
continue;
const txout_to_key& otk = boost::get<txout_to_key>(out.target);
if (otk.key == ephemeral_pub)
{
// this is the output to the given keys
// derive secret key and calculate key image
crypto::secret_key ephemeral_sec = AUTO_VAL_INIT(ephemeral_sec);
crypto::derive_secret_key(derivation, i, m_account.get_keys().spend_secret_key, ephemeral_sec);
crypto::key_image ki = AUTO_VAL_INIT(ki);
crypto::generate_key_image(ephemeral_pub, ephemeral_sec, ki);
crypto::public_key ephemeral_pub = AUTO_VAL_INIT(ephemeral_pub);
if (!crypto::derive_public_key(derivation, i, m_account.get_keys().account_address.spend_public_key, ephemeral_pub))
{
WLT_LOG_ERROR("derive_public_key failed for tx " << get_transaction_hash(ft.tx) << ", out # " << i);
}
ft.outs_key_images.push_back(make_serializable_pair(static_cast<uint64_t>(i), ki));
if (otk.key == ephemeral_pub)
{
// this is the output to the given keys
// derive secret key and calculate key image
crypto::secret_key ephemeral_sec = AUTO_VAL_INIT(ephemeral_sec);
crypto::derive_secret_key(derivation, i, m_account.get_keys().spend_secret_key, ephemeral_sec);
crypto::key_image ki = AUTO_VAL_INIT(ki);
crypto::generate_key_image(ephemeral_pub, ephemeral_sec, ki);
ft.outs_key_images.push_back(make_serializable_pair(static_cast<uint64_t>(i), ki));
}
}
VARIANT_CASE_CONST(tx_out_zarcanum, o);
//@#@
VARIANT_SWITCH_END();
}
// serialize and encrypt the result
@ -3156,7 +3191,8 @@ void wallet2::submit_transfer(const std::string& signed_tx_blob, currency::trans
for (auto& p : ft.outs_key_images)
{
THROW_IF_FALSE_WALLET_INT_ERR_EX(p.first < tx.vout.size(), "outs_key_images has invalid out index: " << p.first << ", tx.vout.size() = " << tx.vout.size());
auto& out = tx.vout[p.first];
THROW_IF_FALSE_WALLET_INT_ERR_EX(tx.vout[p.first].type() == typeid(tx_out_bare), "Unexpected type in submit_transfer: " << tx.vout[p.first].type().name());
auto& out = boost::get<tx_out_bare>(tx.vout[p.first]);
THROW_IF_FALSE_WALLET_INT_ERR_EX(out.target.type() == typeid(txout_to_key), "outs_key_images has invalid out type, index: " << p.first);
const txout_to_key& otk = boost::get<txout_to_key>(out.target);
pk_ki_to_be_added.push_back(std::make_pair(otk.key, p.second));
@ -3380,11 +3416,11 @@ bool wallet2::is_transfer_okay_for_pos(const transfer_details& tr, uint64_t& sta
return true;
}
//----------------------------------------------------------------------------------------------------
void wallet2::get_mining_history(wallet_public::mining_history& hist)
void wallet2::get_mining_history(wallet_public::mining_history& hist, uint64_t timestamp_from)
{
for (auto& tr : m_transfer_history)
{
if (currency::is_coinbase(tr.tx) && tr.tx.vin.size() == 2)
if (currency::is_coinbase(tr.tx) && tr.tx.vin.size() == 2 && tr.timestamp > timestamp_from)
{
tools::wallet_public::mining_history_entry mhe = AUTO_VAL_INIT(mhe);
mhe.a = tr.amount;
@ -3427,6 +3463,12 @@ bool wallet2::get_pos_entries(currency::COMMAND_RPC_SCAN_POS::request& req)
return true;
}
//----------------------------------------------------------------------------------------------------
bool wallet2::is_in_hardfork_zone(uint64_t hardfork_index)
{
const currency::core_runtime_config& rtc = get_core_runtime_config();
return rtc.is_hardfork_active_for_height(hardfork_index, get_blockchain_current_size());
}
//----------------------------------------------------------------------------------------------------
bool wallet2::prepare_and_sign_pos_block(currency::block& b,
const currency::pos_entry& pos_info,
const crypto::public_key& source_tx_pub_key,
@ -3438,43 +3480,52 @@ bool wallet2::prepare_and_sign_pos_block(currency::block& b,
WLT_CHECK_AND_ASSERT_MES(b.miner_tx.vin[1].type() == typeid(currency::txin_to_key), false, "Wrong output input in transaction");
auto& txin = boost::get<currency::txin_to_key>(b.miner_tx.vin[1]);
txin.k_image = pos_info.keyimage;
WLT_CHECK_AND_ASSERT_MES(b.miner_tx.signatures.size() == 1 && b.miner_tx.signatures[0].size() == txin.key_offsets.size(),
false, "Wrong signatures amount in coinbase transacton");
if (is_in_hardfork_zone(ZANO_HARDFORK_04_ZARCANUM))
{
//@#@ TODO: add proper support of Zarcanum
WLT_THROW_IF_FALSE_WALLET_CMN_ERR_EX(false, "ZRCANUM BLOCKS NOT IMPLEMENTED YET");
return false; // to get rid of warning
}else
{
NLSAG_sig& signatures = boost::get<NLSAG_sig>(b.miner_tx.signature);
WLT_CHECK_AND_ASSERT_MES(signatures.s.size() == 1 && signatures.s[0].size() == txin.key_offsets.size(),
false, "Wrong signatures amount in coinbase transacton");
//derive secret key
crypto::key_derivation pos_coin_derivation = AUTO_VAL_INIT(pos_coin_derivation);
bool r = crypto::generate_key_derivation(source_tx_pub_key,
m_account.get_keys().view_secret_key,
pos_coin_derivation);
//derive secret key
crypto::key_derivation pos_coin_derivation = AUTO_VAL_INIT(pos_coin_derivation);
bool r = crypto::generate_key_derivation(source_tx_pub_key,
m_account.get_keys().view_secret_key,
pos_coin_derivation);
WLT_CHECK_AND_ASSERT_MES(r, false, "internal error: pos coin base generator: failed to generate_key_derivation("
<< source_tx_pub_key
<< ", view secret key: " << m_account.get_keys().view_secret_key << ")");
WLT_CHECK_AND_ASSERT_MES(r, false, "internal error: pos coin base generator: failed to generate_key_derivation("
<< source_tx_pub_key
<< ", view secret key: " << m_account.get_keys().view_secret_key << ")");
crypto::secret_key derived_secret_ephemeral_key = AUTO_VAL_INIT(derived_secret_ephemeral_key);
crypto::derive_secret_key(pos_coin_derivation,
in_tx_output_index,
m_account.get_keys().spend_secret_key,
derived_secret_ephemeral_key);
crypto::secret_key derived_secret_ephemeral_key = AUTO_VAL_INIT(derived_secret_ephemeral_key);
crypto::derive_secret_key(pos_coin_derivation,
in_tx_output_index,
m_account.get_keys().spend_secret_key,
derived_secret_ephemeral_key);
// sign block actually in coinbase transaction
crypto::hash block_hash = currency::get_block_hash(b);
// sign block actually in coinbase transaction
crypto::hash block_hash = currency::get_block_hash(b);
crypto::generate_ring_signature(block_hash,
txin.k_image,
keys_ptrs,
derived_secret_ephemeral_key,
0,
&signatures.s[0][0]);
crypto::generate_ring_signature(block_hash,
txin.k_image,
keys_ptrs,
derived_secret_ephemeral_key,
0,
&b.miner_tx.signatures[0][0]);
WLT_LOG_L4("GENERATED RING SIGNATURE: block_id " << block_hash
<< "txin.k_image" << txin.k_image
<< "key_ptr:" << *keys_ptrs[0]
<< "signature:" << signatures.s[0][0]);
WLT_LOG_L4("GENERATED RING SIGNATURE: block_id " << block_hash
<< "txin.k_image" << txin.k_image
<< "key_ptr:" << *keys_ptrs[0]
<< "signature:" << b.miner_tx.signatures[0][0]);
return true;
return true;
}
}
//------------------------------------------------------------------
bool wallet2::build_kernel(const pos_entry& pe, const stake_modifier_type& stake_modifier, const uint64_t timestamp, stake_kernel& kernel)
@ -3624,7 +3675,12 @@ bool wallet2::build_minted_block(const currency::COMMAND_RPC_SCAN_POS::request&
WLT_CHECK_AND_ASSERT_MES(req.pos_entries[rsp.index].wallet_index < m_transfers.size(),
false, "Wrong wallet_index at generating coinbase transacton");
const auto& target = m_transfers[req.pos_entries[rsp.index].wallet_index].m_ptx_wallet_info->m_tx.vout[m_transfers[req.pos_entries[rsp.index].wallet_index].m_internal_output_index].target;
if (m_transfers[req.pos_entries[rsp.index].wallet_index].m_ptx_wallet_info->m_tx.vout[m_transfers[req.pos_entries[rsp.index].wallet_index].m_internal_output_index].type() != typeid(tx_out_bare))
{
//@#@ review zarcanum here
return false;
}
const auto& target = boost::get<tx_out_bare>(m_transfers[req.pos_entries[rsp.index].wallet_index].m_ptx_wallet_info->m_tx.vout[m_transfers[req.pos_entries[rsp.index].wallet_index].m_internal_output_index]).target;
WLT_CHECK_AND_ASSERT_MES(target.type() == typeid(currency::txout_to_key), false, "wrong type_id in source transaction in coinbase tx");
const currency::txout_to_key& txtokey = boost::get<currency::txout_to_key>(target);
@ -4293,10 +4349,17 @@ void wallet2::get_list_of_active_htlc(std::list<wallet_public::htlc_entry_info>&
}
wallet_public::htlc_entry_info entry = AUTO_VAL_INIT(entry);
entry.tx_id = htlc_entry.first;
entry.amount = td.m_ptx_wallet_info->m_tx.vout[td.m_internal_output_index].amount;
WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(td.m_ptx_wallet_info->m_tx.vout[td.m_internal_output_index].target.type() == typeid(txout_htlc),
if (td.m_ptx_wallet_info->m_tx.vout[td.m_internal_output_index].type() != typeid(tx_out_bare))
{
//@#@
LOG_ERROR("Unexpected output type in get_list_of_active_htlc:" << td.m_ptx_wallet_info->m_tx.vout[td.m_internal_output_index].type().name());
continue;
}
const tx_out_bare out_b = boost::get<tx_out_bare>(td.m_ptx_wallet_info->m_tx.vout[td.m_internal_output_index]);
entry.amount = out_b.amount;
WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(out_b.target.type() == typeid(txout_htlc),
"[get_list_of_active_htlc]Internal error: unexpected type of out");
const txout_htlc& htlc = boost::get<txout_htlc>(td.m_ptx_wallet_info->m_tx.vout[td.m_internal_output_index].target);
const txout_htlc& htlc = boost::get<txout_htlc>(out_b.target);
entry.sha256_hash = htlc.htlc_hash;
currency::tx_payer payer = AUTO_VAL_INIT(payer);
@ -4491,26 +4554,33 @@ bool wallet2::prepare_tx_sources(size_t fake_outputs_count, std::vector<currency
//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; // TODO: use ref_by_id when neccessary
if (td.m_ptx_wallet_info->m_tx.vout[td.m_internal_output_index].target.type() == typeid(txout_to_key))
//@#@
VARIANT_SWITCH_BEGIN(td.m_ptx_wallet_info->m_tx.vout[td.m_internal_output_index]);
VARIANT_CASE_CONST(tx_out_bare, o)
{
real_oe.second = boost::get<txout_to_key>(td.m_ptx_wallet_info->m_tx.vout[td.m_internal_output_index].target).key;
}
else if (td.m_ptx_wallet_info->m_tx.vout[td.m_internal_output_index].target.type() == typeid(txout_htlc))
{
real_oe.second = boost::get<txout_htlc>(td.m_ptx_wallet_info->m_tx.vout[td.m_internal_output_index].target).pkey_refund;
}
else
{
WLT_THROW_IF_FALSE_WITH_CODE(false,
"Internal error: unexpected type of target: " << td.m_ptx_wallet_info->m_tx.vout[td.m_internal_output_index].target.type().name(),
API_RETURN_CODE_INTERNAL_ERROR);
}
VARIANT_SWITCH_BEGIN(o.target);
VARIANT_CASE_CONST(txout_to_key, o)
real_oe.second = o.key;
VARIANT_CASE_CONST(txout_htlc, htlc)
real_oe.second = htlc.pkey_refund;
VARIANT_CASE_OTHER()
{
WLT_THROW_IF_FALSE_WITH_CODE(false,
"Internal error: unexpected type of target: " << o.target.type().name(),
API_RETURN_CODE_INTERNAL_ERROR);
}
VARIANT_SWITCH_END();
auto interted_it = src.outputs.insert(it_to_insert, real_oe);
src.real_out_tx_key = get_tx_pub_key_from_extra(td.m_ptx_wallet_info->m_tx);
src.real_output = interted_it - src.outputs.begin();
src.real_output_in_tx_index = td.m_internal_output_index;
print_source_entry(src);
auto interted_it = src.outputs.insert(it_to_insert, real_oe);
src.real_out_tx_key = get_tx_pub_key_from_extra(td.m_ptx_wallet_info->m_tx);
src.real_output = interted_it - src.outputs.begin();
src.real_output_in_tx_index = td.m_internal_output_index;
print_source_entry(src);
}
VARIANT_CASE_CONST(tx_out_zarcanum, o);
//@#@
VARIANT_SWITCH_END();
++i;
}
return true;
@ -4523,7 +4593,9 @@ bool wallet2::prepare_tx_sources(crypto::hash multisig_id, std::vector<currency:
THROW_IF_FALSE_WALLET_INT_ERR_EX(!it->second.is_spent(), "output with multisig_id: " + epee::string_tools::pod_to_hex(multisig_id) + " has already been spent by other party at height " + epee::string_tools::num_to_string_fast(it->second.m_spent_height));
THROW_IF_FALSE_WALLET_INT_ERR_EX(it->second.m_internal_output_index < it->second.m_ptx_wallet_info->m_tx.vout.size(), "it->second.m_internal_output_index < it->second.m_tx.vout.size()");
const tx_out_bare& out = it->second.m_ptx_wallet_info->m_tx.vout[it->second.m_internal_output_index];
//@#@
THROW_IF_FALSE_WALLET_INT_ERR_EX(it->second.m_ptx_wallet_info->m_tx.vout[it->second.m_internal_output_index].type() == typeid(tx_out_bare), "Unknown type id in prepare_tx_sources: " << it->second.m_ptx_wallet_info->m_tx.vout[it->second.m_internal_output_index].type().name());
const tx_out_bare& out = boost::get<tx_out_bare>(it->second.m_ptx_wallet_info->m_tx.vout[it->second.m_internal_output_index]);
THROW_IF_FALSE_WALLET_INT_ERR_EX(out.target.type() == typeid(txout_multisig), "ms out target type is " << out.target.type().name() << ", expected: txout_multisig");
const txout_multisig& ms_out = boost::get<txout_multisig>(out.target);
@ -4553,10 +4625,15 @@ bool wallet2::prepare_tx_sources_htlc(crypto::hash htlc_tx_id, const std::string
"Internal error: index in m_active_htlcs_txid <" << it->second << "> is bigger then size of m_transfers <" << m_transfers.size() << ">", API_RETURN_CODE_INTERNAL_ERROR);
const transfer_details& td = m_transfers[it->second];
WLT_THROW_IF_FALSE_WITH_CODE(td.m_ptx_wallet_info->m_tx.vout[td.m_internal_output_index].target.type() == typeid(txout_htlc),
//@#@
WLT_THROW_IF_FALSE_WITH_CODE(td.m_ptx_wallet_info->m_tx.vout[td.m_internal_output_index].type() == typeid(tx_out_bare),
"Unexpected out type in prepare_tx_sources_htlc:" << td.m_ptx_wallet_info->m_tx.vout[td.m_internal_output_index].type().name(), API_RETURN_CODE_INTERNAL_ERROR);
const tx_out_bare& out_bare = boost::get<tx_out_bare>(td.m_ptx_wallet_info->m_tx.vout[td.m_internal_output_index]);
WLT_THROW_IF_FALSE_WITH_CODE(out_bare.target.type() == typeid(txout_htlc),
"Unexpected type in active htlc", API_RETURN_CODE_INTERNAL_ERROR);
const txout_htlc& htlc_out = boost::get<txout_htlc>(td.m_ptx_wallet_info->m_tx.vout[td.m_internal_output_index].target);
const txout_htlc& htlc_out = boost::get<txout_htlc>(out_bare.target);
bool use_sha256 = !(htlc_out.flags&CURRENCY_TXOUT_HTLC_FLAGS_HASH_TYPE_MASK);
//check origin
@ -4939,18 +5016,23 @@ bool wallet2::is_transfer_able_to_go(const transfer_details& td, uint64_t fake_o
{
if (!td.is_spendable())
return false;
if (td.m_ptx_wallet_info->m_tx.vout[td.m_internal_output_index].target.type() == typeid(txout_htlc))
VARIANT_SWITCH_BEGIN(td.m_ptx_wallet_info->m_tx.vout[td.m_internal_output_index]);
VARIANT_CASE_CONST(tx_out_bare, o);
{
if (fake_outputs_count != 0)
return false;
if (o.target.type() == typeid(txout_htlc))
{
if (fake_outputs_count != 0)
return false;
}
else
{
if (!currency::is_mixattr_applicable_for_fake_outs_counter(boost::get<currency::txout_to_key>(o.target).mix_attr, fake_outputs_count))
return false;
}
}
else
{
if (!currency::is_mixattr_applicable_for_fake_outs_counter(boost::get<currency::txout_to_key>(td.m_ptx_wallet_info->m_tx.vout[td.m_internal_output_index].target).mix_attr, fake_outputs_count))
return false;
}
VARIANT_CASE_CONST(tx_out_zarcanum, o);
//@#@
VARIANT_SWITCH_END();
return true;
}
//----------------------------------------------------------------------------------------------------
@ -4966,7 +5048,8 @@ bool wallet2::prepare_free_transfers_cache(uint64_t fake_outputs_count)
const transfer_details& td = m_transfers[i];
if (is_transfer_able_to_go(td, fake_outputs_count))
{
m_found_free_amounts[td.m_ptx_wallet_info->m_tx.vout[td.m_internal_output_index].amount].insert(i);
//@#@
m_found_free_amounts[boost::get<tx_out_bare>(td.m_ptx_wallet_info->m_tx.vout[td.m_internal_output_index]).amount].insert(i);
count++;
}
}
@ -4979,8 +5062,9 @@ bool wallet2::prepare_free_transfers_cache(uint64_t fake_outputs_count)
//----------------------------------------------------------------------------------------------------
void wallet2::add_transfers_to_transfers_cache(const std::vector<uint64_t>& indexs)
{
//@#@
for (auto i : indexs)
add_transfer_to_transfers_cache(m_transfers[i].m_ptx_wallet_info->m_tx.vout[m_transfers[i].m_internal_output_index].amount , i);
add_transfer_to_transfers_cache(boost::get<tx_out_bare>(m_transfers[i].m_ptx_wallet_info->m_tx.vout[m_transfers[i].m_internal_output_index]).amount , i);
}
//----------------------------------------------------------------------------------------------------
void wallet2::add_transfer_to_transfers_cache(uint64_t amount, uint64_t index)
@ -5649,7 +5733,11 @@ void wallet2::sweep_below(size_t fake_outs_count, const currency::account_public
});
tx_output_entry real_oe;
real_oe.first = td.m_global_output_index;
real_oe.second = boost::get<txout_to_key>(td.m_ptx_wallet_info->m_tx.vout[td.m_internal_output_index].target).key;
//@#@
if(td.m_ptx_wallet_info->m_tx.vout[td.m_internal_output_index].type() != typeid(tx_out_bare))
continue;
const tx_out_bare& out_b = boost::get<tx_out_bare>(td.m_ptx_wallet_info->m_tx.vout[td.m_internal_output_index]);
real_oe.second = boost::get<txout_to_key>(out_b.target).key;
auto inserted_it = src.outputs.insert(it_to_insert, real_oe);
src.real_out_tx_key = get_tx_pub_key_from_extra(td.m_ptx_wallet_info->m_tx);
src.real_output = inserted_it - src.outputs.begin();

View file

@ -379,8 +379,10 @@ namespace tools
uint64_t m_spent_height;
uint32_t m_flags;
uint64_t amount() const { return m_ptx_wallet_info->m_tx.vout[m_internal_output_index].amount; }
const currency::tx_out_bare& output() const { return m_ptx_wallet_info->m_tx.vout[m_internal_output_index]; }
// @#@ will throw if type is not tx_out_bare, TODO: change according to new model,
// need to replace all get_tx_out_bare_from_out_v() to proper code
uint64_t amount() const { return currency::get_tx_out_bare_from_out_v(m_ptx_wallet_info->m_tx.vout[m_internal_output_index]).amount; }
const currency::tx_out_bare& output() const { return currency::get_tx_out_bare_from_out_v(m_ptx_wallet_info->m_tx.vout[m_internal_output_index]); }
uint8_t mix_attr() const { return output().target.type() == typeid(currency::txout_to_key) ? boost::get<const currency::txout_to_key&>(output().target).mix_attr : UINT8_MAX; }
crypto::hash tx_hash() const { return get_transaction_hash(m_ptx_wallet_info->m_tx); }
bool is_spent() const { return m_flags & WALLET_TRANSFER_DETAIL_FLAG_SPENT; }
@ -820,7 +822,7 @@ namespace tools
bool reset_history();
bool is_transfer_unlocked(const transfer_details& td) const;
bool is_transfer_unlocked(const transfer_details& td, bool for_pos_mining, uint64_t& stake_lock_time) const;
void get_mining_history(wallet_public::mining_history& hist);
void get_mining_history(wallet_public::mining_history& hist, uint64_t timestamp_from = 0);
void set_core_runtime_config(const currency::core_runtime_config& pc);
currency::core_runtime_config& get_core_runtime_config();
bool backup_keys(const std::string& path);
@ -1012,6 +1014,7 @@ private:
uint64_t detach_from_block_ids(uint64_t height);
uint64_t get_wallet_minimum_height();
uint64_t get_directly_spent_transfer_id_by_input_in_tracking_wallet(const currency::txin_to_key& intk);
bool is_in_hardfork_zone(uint64_t hardfork_index);
void push_alias_info_to_extra_according_to_hf_status(const currency::extra_alias_entry& ai, std::vector<currency::extra_v>& extra);
void remove_transfer_from_amount_gindex_map(uint64_t tid);

View file

@ -7,6 +7,7 @@
#define KEEP_WALLET_LOG_MACROS
#include "wallet2.h"
#include "currency_core/currency_format_utils.h"
#include "common/variant_helper.h"
#undef LOG_DEFAULT_CHANNEL
#define LOG_DEFAULT_CHANNEL "wallet"
@ -74,20 +75,28 @@ bool wallet2::validate_escrow_proposal(const wallet_public::wallet_transfer_info
size_t ms_out_index = SIZE_MAX;
for (size_t i = 0; i != prop.tx_template.vout.size(); ++i)
{
if (prop.tx_template.vout[i].target.type() == typeid(txout_multisig))
VARIANT_SWITCH_BEGIN(prop.tx_template.vout[i]);
VARIANT_CASE_CONST(tx_out_bare, o)
{
LOC_CHK(ms_out_index == SIZE_MAX, "template has more than one multisig output");
ms_out_index = i;
if (o.target.type() == typeid(txout_multisig))
{
LOC_CHK(ms_out_index == SIZE_MAX, "template has more than one multisig output");
ms_out_index = i;
}
else if (o.target.type() == typeid(txout_to_key))
to_key_outputs_amount += o.amount;
else
LOC_CHK(false, "Invalid output type: " << o.target.type().name());
}
else if (prop.tx_template.vout[i].target.type() == typeid(txout_to_key))
to_key_outputs_amount += prop.tx_template.vout[i].amount;
else
LOC_CHK(false, "Invalid output type: " << prop.tx_template.vout[i].target.type().name());
VARIANT_CASE_CONST(tx_out_zarcanum, o);
//@#@
VARIANT_SWITCH_END();
}
LOC_CHK(ms_out_index != SIZE_MAX, "template has no multisig outputs");
ms_id = currency::get_multisig_out_id(prop.tx_template, ms_out_index);
uint64_t ms_amount = prop.tx_template.vout[ms_out_index].amount;
const txout_multisig& ms = boost::get<txout_multisig>(prop.tx_template.vout[ms_out_index].target);
// @#@ using of get_tx_out_bare_from_out_v might be not safe, TODO: review this code
uint64_t ms_amount = currency::get_tx_out_bare_from_out_v(prop.tx_template.vout[ms_out_index]).amount;
const txout_multisig& ms = boost::get<txout_multisig>(currency::get_tx_out_bare_from_out_v(prop.tx_template.vout[ms_out_index]).target);
LOC_CHK(ms.minimum_sigs == 2, "template has multisig output with wrong minimum_sigs==" << ms.minimum_sigs);
LOC_CHK(ms.keys.size() == 2, "template has multisig output with wrong keys size: " << ms.keys.size());
@ -138,7 +147,8 @@ bool wallet2::validate_escrow_release(const transaction& tx, bool release_type_n
LOC_CHK(ms.multisig_out_id == ms_id, "multisig input references to wrong ms output: " << ms.multisig_out_id << ", expected: " << ms_id);
LOC_CHK(source_ms_out.minimum_sigs == 2, "multisig output has wrong minimim_sigs: " <<source_ms_out.minimum_sigs << ", expected: 2");
LOC_CHK(ms.sigs_count == source_ms_out.minimum_sigs, "multisig input has wrong sig_count: " << ms.sigs_count << ", expected: " << source_ms_out.minimum_sigs);
LOC_CHK(ms.amount == source_tx.vout[source_ms_out_index].amount, "multisig input amount: " << ms.amount << " does not match with source tx out amount: " << source_tx.vout[source_ms_out_index].amount);
LOC_CHK(source_tx.vout[source_ms_out_index].type() == typeid(tx_out_bare), "multisig input has wrong output type:");
LOC_CHK(ms.amount == currency::get_tx_out_bare_from_out_v(source_tx.vout[source_ms_out_index]).amount, "multisig input amount: " << ms.amount << " does not match with source tx out amount: " << currency::get_tx_out_bare_from_out_v(source_tx.vout[source_ms_out_index]).amount);
uint64_t min_ms_amount = cpd.amount_a_pledge + cpd.amount_b_pledge + cpd.amount_to_pay + TX_DEFAULT_FEE;
LOC_CHK(ms.amount >= min_ms_amount, "multisig input amount " << ms.amount << " is less than contract expected value: " << min_ms_amount << ", a_pledge=" << cpd.amount_a_pledge << ", b_pledge=" << cpd.amount_b_pledge << ", amount_to_pay=" << cpd.amount_to_pay);
@ -181,20 +191,27 @@ bool wallet2::validate_escrow_release(const transaction& tx, bool release_type_n
uint64_t total_outputs_amount = 0, outputs_to_A_amount = 0, outputs_to_null_addr_amount = 0;
for (size_t i = 0; i != tx.vout.size(); ++i)
{
if (tx.vout[i].target.type() == typeid(txout_to_key))
VARIANT_SWITCH_BEGIN(tx.vout[i]);
VARIANT_CASE_CONST(tx_out_bare, o);
{
total_outputs_amount += tx.vout[i].amount;
const txout_to_key& otk = boost::get<txout_to_key>(tx.vout[i].target);
crypto::public_key ephemeral_pub_key = AUTO_VAL_INIT(ephemeral_pub_key);
r = crypto::derive_public_key(der, i, cpd.a_addr.spend_public_key, ephemeral_pub_key);
LOC_CHK(r, "derive_public_key failed for output #" << i);
if (otk.key == ephemeral_pub_key)
outputs_to_A_amount += tx.vout[i].amount;
else if (otk.key == null_pkey)
outputs_to_null_addr_amount += tx.vout[i].amount;
if (o.target.type() == typeid(txout_to_key))
{
total_outputs_amount += o.amount;
const txout_to_key& otk = boost::get<txout_to_key>(o.target);
crypto::public_key ephemeral_pub_key = AUTO_VAL_INIT(ephemeral_pub_key);
r = crypto::derive_public_key(der, i, cpd.a_addr.spend_public_key, ephemeral_pub_key);
LOC_CHK(r, "derive_public_key failed for output #" << i);
if (otk.key == ephemeral_pub_key)
outputs_to_A_amount += o.amount;
else if (otk.key == null_pkey)
outputs_to_null_addr_amount += o.amount;
}
else
LOC_CHK(false, "Invalid output type: " << o.target.type().name());
}
else
LOC_CHK(false, "Invalid output type: " << tx.vout[i].target.type().name());
VARIANT_CASE_CONST(tx_out_zarcanum, o)
LOC_CHK(false, "Invalid output type: " << typeid(o).name());
VARIANT_SWITCH_END();
}
if (release_type_normal)
@ -217,28 +234,36 @@ bool wallet2::validate_escrow_release(const transaction& tx, bool release_type_n
// (5/5) signatures
LOC_CHK(tx.signatures.size() == 1, "invalid singatures size: " << tx.signatures.size()); // only 1 input means only 1 signature vector
VARIANT_SWITCH_BEGIN(tx.signature);
VARIANT_CASE_CONST(NLSAG_sig, signatures)
{
LOC_CHK(signatures.s.size() == 1, "invalid singatures size: " << signatures.s.size()); // only 1 input means only 1 signature vector
// As we don't have b_keys we can't be sure which signature is B's and which is reserved for A (should be a null-placeholder, if present).
// Having a_keys, we determine index of A key in multisig output keys array.
// Thus it's possible to determine the order of signatures (A, B or B, A), and, eventually, validate B signature.
crypto::public_key source_tx_pub_key = get_tx_pub_key_from_extra(source_tx);
r = crypto::generate_key_derivation(source_tx_pub_key, a_keys.view_secret_key, der);
LOC_CHK(r, "generate_key_derivation failed");
crypto::public_key ephemeral_pub_key = AUTO_VAL_INIT(ephemeral_pub_key);
r = crypto::derive_public_key(der, source_ms_out_index, a_keys.account_address.spend_public_key, ephemeral_pub_key);
LOC_CHK(r, "derive_public_key failed");
// As we don't have b_keys we can't be sure which signature is B's and which is reserved for A (should be a null-placeholder, if present).
// Having a_keys, we determine index of A key in multisig output keys array.
// Thus it's possible to determine the order of signatures (A, B or B, A), and, eventually, validate B signature.
crypto::public_key source_tx_pub_key = get_tx_pub_key_from_extra(source_tx);
r = crypto::generate_key_derivation(source_tx_pub_key, a_keys.view_secret_key, der);
LOC_CHK(r, "generate_key_derivation failed");
crypto::public_key ephemeral_pub_key = AUTO_VAL_INIT(ephemeral_pub_key);
r = crypto::derive_public_key(der, source_ms_out_index, a_keys.account_address.spend_public_key, ephemeral_pub_key);
LOC_CHK(r, "derive_public_key failed");
LOC_CHK(source_ms_out.keys.size() == 2, "internal error: invalid ms output keys array, size: " << source_ms_out.keys.size());
LOC_CHK(tx.signatures[0].size() == 2, "internal error: invalid signature size for input #0: " << tx.signatures[0].size())
size_t ms_out_key_a_index = std::find(source_ms_out.keys.begin(), source_ms_out.keys.end(), ephemeral_pub_key) - source_ms_out.keys.begin();
LOC_CHK(ms_out_key_a_index < source_ms_out.keys.size(), "internal error: can't find A ephemeral pub key within ms output keys");
size_t ms_out_key_b_index = 1 - ms_out_key_a_index;
LOC_CHK(source_ms_out.keys.size() == 2, "internal error: invalid ms output keys array, size: " << source_ms_out.keys.size());
LOC_CHK(signatures.s[0].size() == 2, "internal error: invalid signature size for input #0: " << signatures.s[0].size())
size_t ms_out_key_a_index = std::find(source_ms_out.keys.begin(), source_ms_out.keys.end(), ephemeral_pub_key) - source_ms_out.keys.begin();
LOC_CHK(ms_out_key_a_index < source_ms_out.keys.size(), "internal error: can't find A ephemeral pub key within ms output keys");
size_t ms_out_key_b_index = 1 - ms_out_key_a_index;
// in this particular case (source_ms_out.minimum_sigs == source_ms_out.keys.size() == 2) index in 'keys' is the same as index in tx.signatures[0]
crypto::hash tx_hash_for_signature = prepare_prefix_hash_for_sign(tx, 0, get_transaction_hash(tx));
r = crypto::check_signature(tx_hash_for_signature, source_ms_out.keys[ms_out_key_b_index], tx.signatures[0][ms_out_key_b_index]);
LOC_CHK(r, "B signature for multisig input is invalid");
// in this particular case (source_ms_out.minimum_sigs == source_ms_out.keys.size() == 2) index in 'keys' is the same as index in signatures.s[0]
crypto::hash tx_hash_for_signature = prepare_prefix_hash_for_sign(tx, 0, get_transaction_hash(tx));
r = crypto::check_signature(tx_hash_for_signature, source_ms_out.keys[ms_out_key_b_index], signatures.s[0][ms_out_key_b_index]);
LOC_CHK(r, "B signature for multisig input is invalid");
}
VARIANT_CASE_CONST(zarcanum_sig, s);
//@#@
VARIANT_CASE_THROW_ON_OTHER();
VARIANT_SWITCH_END();
return true;
#undef LOC_CHK
@ -258,7 +283,7 @@ bool wallet2::validate_escrow_contract(const wallet_public::wallet_transfer_info
LOC_CHK(n < wti.tx.vout.size(), "multisig output was not found");
ms_id = currency::get_multisig_out_id(wti.tx, n);
LOC_CHK(ms_id != null_hash, "failed to obtain ms output id");
const txout_multisig& ms = boost::get<txout_multisig>(wti.tx.vout[n].target);
const txout_multisig& ms = boost::get<txout_multisig>( boost::get<tx_out_bare>(wti.tx.vout[n]).target);
tx_service_attachment tsa = AUTO_VAL_INIT(tsa);
r = bc_services::get_first_service_attachment_by_id(decrypted_items, BC_ESCROW_SERVICE_ID, BC_ESCROW_SERVICE_INSTRUCTION_RELEASE_TEMPLATES, tsa);
@ -318,11 +343,11 @@ bool wallet2::validate_escrow_cancel_release(const currency::transaction& tx, co
LOC_CHK(tx.vin.back().type() == typeid(txin_multisig), "input 0 is not txin_multisig");
const txin_multisig& ms = boost::get<txin_multisig>(tx.vin.back());
LOC_CHK(source_ms_out_index < source_tx.vout.size(), "internal invariant failed: source_ms_out_index is out of bounds: " << source_ms_out_index);
const txout_multisig& source_ms_out = boost::get<txout_multisig>(source_tx.vout[source_ms_out_index].target);
const txout_multisig& source_ms_out = boost::get<txout_multisig>(currency::get_tx_out_bare_from_out_v(source_tx.vout[source_ms_out_index]).target);
LOC_CHK(ms.multisig_out_id == ms_id, "multisig input references to wrong ms output: " << ms.multisig_out_id << ", expected: " << ms_id);
LOC_CHK(source_ms_out.minimum_sigs == 2, "source multisig output has wrong minimim_sigs: " <<source_ms_out.minimum_sigs << ", expected: 2");
LOC_CHK(ms.sigs_count == source_ms_out.minimum_sigs, "multisig input has wrong sig_count: " << ms.sigs_count << ", expected: " << source_ms_out.minimum_sigs);
LOC_CHK(ms.amount == source_tx.vout[source_ms_out_index].amount, "multisig input amount: " << ms.amount << " does not match with source tx out amount: " << source_tx.vout[source_ms_out_index].amount);
LOC_CHK(ms.amount == currency::get_tx_out_bare_from_out_v(source_tx.vout[source_ms_out_index]).amount, "multisig input amount: " << ms.amount << " does not match with source tx out amount: " << currency::get_tx_out_bare_from_out_v(source_tx.vout[source_ms_out_index]).amount);
uint64_t min_ms_amount = cpd.amount_a_pledge + cpd.amount_b_pledge + cpd.amount_to_pay + minimum_release_fee;
@ -363,18 +388,23 @@ bool wallet2::validate_escrow_cancel_release(const currency::transaction& tx, co
uint64_t total_outputs_amount = 0, outputs_to_B_amount = 0;
for (size_t i = 0; i != tx.vout.size(); ++i)
{
if (tx.vout[i].target.type() == typeid(txout_to_key))
{
total_outputs_amount += tx.vout[i].amount;
const txout_to_key& otk = boost::get<txout_to_key>(tx.vout[i].target);
crypto::public_key ephemeral_pub_key = AUTO_VAL_INIT(ephemeral_pub_key);
r = crypto::derive_public_key(der, i, cpd.b_addr.spend_public_key, ephemeral_pub_key);
LOC_CHK(r, "derive_public_key failed for output #" << i);
if (otk.key == ephemeral_pub_key)
outputs_to_B_amount += tx.vout[i].amount;
}
else
LOC_CHK(false, "Invalid output type: " << tx.vout[i].target.type().name());
VARIANT_SWITCH_BEGIN(tx.vout[i]);
VARIANT_CASE_CONST(tx_out_bare, o)
if (o.target.type() == typeid(txout_to_key))
{
total_outputs_amount += o.amount;
const txout_to_key& otk = boost::get<txout_to_key>(o.target);
crypto::public_key ephemeral_pub_key = AUTO_VAL_INIT(ephemeral_pub_key);
r = crypto::derive_public_key(der, i, cpd.b_addr.spend_public_key, ephemeral_pub_key);
LOC_CHK(r, "derive_public_key failed for output #" << i);
if (otk.key == ephemeral_pub_key)
outputs_to_B_amount += o.amount;
}
else
LOC_CHK(false, "Invalid output type: " << o.target.type().name());
VARIANT_CASE_CONST(tx_out_zarcanum, o)
LOC_CHK(false, "Invalid output type: " << typeid(o).name());
VARIANT_SWITCH_END();
}
LOC_CHK(outputs_to_B_amount >= cpd.amount_b_pledge, "B-addressed outs total amount: " << print_money(outputs_to_B_amount) << " is less than b_pledge: " << print_money(cpd.amount_b_pledge));
@ -388,15 +418,24 @@ bool wallet2::validate_escrow_cancel_release(const currency::transaction& tx, co
// (5/5) signatures
LOC_CHK(tx.signatures.size() == 1, "invalid singatures size: " << tx.signatures.size()); // only 1 input means only 1 signature vector
LOC_CHK(tx.signatures[0].size() == 2, "invalid signature[0] size: " << tx.signatures[0].size()); // it's expected to contain A-party signature and null-sig placeholder
LOC_CHK(source_ms_out.keys.size() == 2, "internal error: invalid source ms output keys array, size: " << source_ms_out.keys.size());
VARIANT_SWITCH_BEGIN(tx.signature);
VARIANT_CASE_CONST(NLSAG_sig, signatures)
{
LOC_CHK(signatures.s.size() == 1, "invalid singatures size: " << signatures.s.size()); // only 1 input means only 1 signature vector
LOC_CHK(signatures.s[0].size() == 2, "invalid signature[0] size: " << signatures.s[0].size()); // it's expected to contain A-party signature and null-sig placeholder
LOC_CHK(source_ms_out.keys.size() == 2, "internal error: invalid source ms output keys array, size: " << source_ms_out.keys.size());
size_t a_sign_index = (tx.signatures[0][0] != null_sig) ? 0 : 1;
size_t a_sign_index = (signatures.s[0][0] != null_sig) ? 0 : 1;
crypto::hash tx_hash_for_signature = prepare_prefix_hash_for_sign(tx, 0, get_transaction_hash(tx));
r = crypto::check_signature(tx_hash_for_signature, source_ms_out.keys[a_sign_index], signatures.s[0][a_sign_index]);
LOC_CHK(r, "A signature for multisig input is invalid");
}
VARIANT_CASE_CONST(zarcanum_sig, s);
//@#@
VARIANT_CASE_THROW_ON_OTHER();
VARIANT_SWITCH_END();
crypto::hash tx_hash_for_signature = prepare_prefix_hash_for_sign(tx, 0, get_transaction_hash(tx));
r = crypto::check_signature(tx_hash_for_signature, source_ms_out.keys[a_sign_index], tx.signatures[0][a_sign_index]);
LOC_CHK(r, "A signature for multisig input is invalid");
return true;
#undef LOC_CHK

View file

@ -318,6 +318,12 @@ namespace wallet_public
END_KV_SERIALIZE_MAP()
};
struct COMMAND_RPC_GET_MINING_HISTORY
{
typedef currency::struct_with_one_t_type<uint64_t> request;
typedef wallet_public::mining_history response;
};
#define ORDER_FROM_BEGIN_TO_END "FROM_BEGIN_TO_END"
#define ORDER_FROM_FROM_END_TO_BEGIN "FROM_END_TO_BEGIN"

View file

@ -741,6 +741,11 @@ namespace tools
return true;
}
bool wallet_rpc_server::on_get_mining_history(const wallet_public::COMMAND_RPC_GET_MINING_HISTORY::request& req, wallet_public::COMMAND_RPC_GET_MINING_HISTORY::response& res, epee::json_rpc::error& er, connection_context& cntx)
{
m_wallet.get_mining_history(res, req.v);
return true;
}
//------------------------------------------------------------------------------------------------------------------------------
bool wallet_rpc_server::on_contracts_send_proposal(const wallet_public::COMMAND_CONTRACTS_SEND_PROPOSAL::request& req, wallet_public::COMMAND_CONTRACTS_SEND_PROPOSAL::response& res, epee::json_rpc::error& er, connection_context& cntx)
{

View file

@ -53,6 +53,7 @@ namespace tools
MAP_JON_RPC_WE("search_for_transactions", on_search_for_transactions, wallet_public::COMMAND_RPC_SEARCH_FOR_TRANSACTIONS)
MAP_JON_RPC_WE("get_restore_info", on_getwallet_restore_info, wallet_public::COMMAND_RPC_GET_WALLET_RESTORE_INFO)
MAP_JON_RPC_WE("get_seed_phrase_info", on_get_seed_phrase_info, wallet_public::COMMAND_RPC_GET_SEED_PHRASE_INFO)
MAP_JON_RPC_WE("get_mining_history", on_get_mining_history, wallet_public::COMMAND_RPC_GET_MINING_HISTORY)
//contracts API
MAP_JON_RPC_WE("contracts_send_proposal", on_contracts_send_proposal, wallet_public::COMMAND_CONTRACTS_SEND_PROPOSAL)
MAP_JON_RPC_WE("contracts_accept_proposal", on_contracts_accept_proposal, wallet_public::COMMAND_CONTRACTS_ACCEPT_PROPOSAL)
@ -91,6 +92,7 @@ namespace tools
bool on_sign_transfer(const wallet_public::COMMAND_SIGN_TRANSFER::request& req, wallet_public::COMMAND_SIGN_TRANSFER::response& res, epee::json_rpc::error& er, connection_context& cntx);
bool on_submit_transfer(const wallet_public::COMMAND_SUBMIT_TRANSFER::request& req, wallet_public::COMMAND_SUBMIT_TRANSFER::response& res, epee::json_rpc::error& er, connection_context& cntx);
bool on_search_for_transactions(const wallet_public::COMMAND_RPC_SEARCH_FOR_TRANSACTIONS::request& req, wallet_public::COMMAND_RPC_SEARCH_FOR_TRANSACTIONS::response& res, epee::json_rpc::error& er, connection_context& cntx);
bool on_get_mining_history(const wallet_public::COMMAND_RPC_GET_MINING_HISTORY::request& req, wallet_public::COMMAND_RPC_GET_MINING_HISTORY::response& res, epee::json_rpc::error& er, connection_context& cntx);
bool on_contracts_send_proposal(const wallet_public::COMMAND_CONTRACTS_SEND_PROPOSAL::request& req, wallet_public::COMMAND_CONTRACTS_SEND_PROPOSAL::response& res, epee::json_rpc::error& er, connection_context& cntx);
bool on_contracts_accept_proposal(const wallet_public::COMMAND_CONTRACTS_ACCEPT_PROPOSAL::request& req, wallet_public::COMMAND_CONTRACTS_ACCEPT_PROPOSAL::response& res, epee::json_rpc::error& er, connection_context& cntx);

View file

@ -884,8 +884,8 @@ bool gen_alias_reg_with_locked_money::generate(std::vector<test_event_entry>& ev
ai.m_address = miner_acc.get_public_address();
currency::tx_source_entry se = AUTO_VAL_INIT(se);
se.amount = blk_0.miner_tx.vout[0].amount;
se.outputs.push_back(make_serializable_pair<txout_ref_v, crypto::public_key>(0, boost::get<currency::txout_to_key>(blk_0.miner_tx.vout[0].target).key));
se.amount = boost::get<currency::tx_out_bare>(blk_0.miner_tx.vout[0]).amount;
se.outputs.push_back(make_serializable_pair<txout_ref_v, crypto::public_key>(0, boost::get<currency::txout_to_key>(boost::get<currency::tx_out_bare>(blk_0.miner_tx.vout[0]).target).key));
se.real_output = 0;
se.real_output_in_tx_index = 0;
se.real_out_tx_key = currency::get_tx_pub_key_from_extra(blk_0.miner_tx);
@ -1159,8 +1159,8 @@ bool gen_alias_tx_no_outs::generate(std::vector<test_event_entry>& events) const
ai.m_address = miner_acc.get_public_address();
currency::tx_source_entry se = AUTO_VAL_INIT(se);
se.amount = blk_0.miner_tx.vout[0].amount;
se.outputs.push_back(make_serializable_pair<txout_ref_v, crypto::public_key>(0, boost::get<currency::txout_to_key>(blk_0.miner_tx.vout[0].target).key));
se.amount = boost::get<currency::tx_out_bare>(blk_0.miner_tx.vout[0]).amount;
se.outputs.push_back(make_serializable_pair<txout_ref_v, crypto::public_key>(0, boost::get<currency::txout_to_key>(boost::get<currency::tx_out_bare>(blk_0.miner_tx.vout[0]).target).key));
se.real_output = 0;
se.real_output_in_tx_index = 0;
se.real_out_tx_key = currency::get_tx_pub_key_from_extra(blk_0.miner_tx);

View file

@ -59,9 +59,9 @@ bool block_template_against_txs_size::c1(currency::core& c, size_t ev_index, con
keypair ephemeral = AUTO_VAL_INIT(ephemeral);
r = generate_key_image_helper(miner_acc.get_keys(), get_tx_pub_key_from_extra(blk_0.miner_tx), 0, ephemeral, ki);
CHECK_AND_ASSERT_MES(r, false, "generate_key_image_helper failed");
CHECK_AND_ASSERT_MES(boost::get<txout_to_key>(blk_0.miner_tx.vout[0].target).key == ephemeral.pub, false, "ephemeral.pub doesn't match with output key");
CHECK_AND_ASSERT_MES(boost::get<txout_to_key>(boost::get<currency::tx_out_bare>(blk_0.miner_tx.vout[0]).target).key == ephemeral.pub, false, "ephemeral.pub doesn't match with output key");
pos_entry pe = AUTO_VAL_INIT(pe);
pe.amount = blk_0.miner_tx.vout[0].amount;
pe.amount = boost::get<currency::tx_out_bare>(blk_0.miner_tx.vout[0]).amount;
pe.block_timestamp = UINT64_MAX; // doesn't matter
pe.index = 0; // global index
pe.keyimage = ki;
@ -100,7 +100,7 @@ bool block_template_against_txs_size::c1(currency::core& c, size_t ev_index, con
r = bcs.validate_miner_transaction(b, cumulative_block_size, g_block_txs_fee, base_reward, bcs.total_coins());
CHECK_AND_ASSERT_MES(r, false, "validate_miner_transaction failed, txs_total_size = " << txs_total_size);
uint64_t generated_coins = get_outs_money_amount(b.miner_tx) - (is_pos != 0 ? b.miner_tx.vout.back().amount : 0) - g_block_txs_fee / 2;
uint64_t generated_coins = get_outs_money_amount(b.miner_tx) - (is_pos != 0 ? boost::get<tx_out_bare>(b.miner_tx.vout.back()).amount : 0) - g_block_txs_fee / 2;
uint64_t base_block_reward = is_pos != 0 ? base_block_reward_pos : base_block_reward_pow;
if (txs_total_size % 1000 == 0)

View file

@ -311,8 +311,8 @@ bool gen_block_miner_tx_has_2_in::generate(std::vector<test_event_entry>& events
GENERATE_ACCOUNT(alice);
tx_source_entry se = AUTO_VAL_INIT(se);
se.amount = blk_0.miner_tx.vout[0].amount;
se.outputs.push_back(make_serializable_pair<txout_ref_v, crypto::public_key>(0, boost::get<txout_to_key>(blk_0.miner_tx.vout[0].target).key));
se.amount = boost::get<currency::tx_out_bare>(blk_0.miner_tx.vout[0]).amount;
se.outputs.push_back(make_serializable_pair<txout_ref_v, crypto::public_key>(0, boost::get<txout_to_key>(boost::get<currency::tx_out_bare>(blk_0.miner_tx.vout[0]).target).key));
se.real_output = 0;
se.real_out_tx_key = get_tx_pub_key_from_extra(blk_0.miner_tx);
se.real_output_in_tx_index = 0;
@ -356,8 +356,8 @@ bool gen_block_miner_tx_with_txin_to_key::generate(std::vector<test_event_entry>
REWIND_BLOCKS(events, blk_1r, blk_1, miner_account);
tx_source_entry se = AUTO_VAL_INIT(se);
se.amount = blk_1.miner_tx.vout[0].amount;
se.outputs.push_back(make_serializable_pair<txout_ref_v, crypto::public_key>(0, boost::get<txout_to_key>(blk_1.miner_tx.vout[0].target).key));
se.amount = boost::get<currency::tx_out_bare>(blk_1.miner_tx.vout[0]).amount;
se.outputs.push_back(make_serializable_pair<txout_ref_v, crypto::public_key>(0, boost::get<txout_to_key>(boost::get<currency::tx_out_bare>(blk_1.miner_tx.vout[0]).target).key));
se.real_output = 0;
se.real_out_tx_key = get_tx_pub_key_from_extra(blk_1.miner_tx);
se.real_output_in_tx_index = 0;
@ -393,7 +393,7 @@ bool gen_block_miner_tx_out_is_small::generate(std::vector<test_event_entry>& ev
BLOCK_VALIDATION_INIT_GENERATE();
MAKE_MINER_TX_MANUALLY(miner_tx, blk_0);
miner_tx.vout[0].amount /= 2;
boost::get<currency::tx_out_bare>( miner_tx.vout[0]).amount /= 2;
block blk_1;
generator.construct_block_manually(blk_1, blk_0, miner_account, test_generator::bf_miner_tx, 0, 0, 0, crypto::hash(), 0, miner_tx);
@ -409,7 +409,7 @@ bool gen_block_miner_tx_out_is_big::generate(std::vector<test_event_entry>& even
BLOCK_VALIDATION_INIT_GENERATE();
MAKE_MINER_TX_MANUALLY(miner_tx, blk_0);
miner_tx.vout[0].amount *= 2;
boost::get<currency::tx_out_bare>( miner_tx.vout[0]).amount *= 2;
block blk_1;
generator.construct_block_manually(blk_1, blk_0, miner_account, test_generator::bf_miner_tx, 0, 0, 0, crypto::hash(), 0, miner_tx);
@ -451,8 +451,8 @@ bool gen_block_miner_tx_has_out_to_alice::generate(std::vector<test_event_entry>
crypto::derive_public_key(derivation, 1, alice.get_keys().account_address.spend_public_key, out_eph_public_key);
tx_out_bare out_to_alice;
out_to_alice.amount = miner_tx.vout[0].amount / 2;
miner_tx.vout[0].amount -= out_to_alice.amount;
out_to_alice.amount =boost::get<currency::tx_out_bare>( miner_tx.vout[0]).amount / 2;
boost::get<currency::tx_out_bare>( miner_tx.vout[0]).amount -= out_to_alice.amount;
out_to_alice.target = txout_to_key(out_eph_public_key);
miner_tx.vout.push_back(out_to_alice);
@ -491,7 +491,7 @@ bool gen_block_is_too_big::generate(std::vector<test_event_entry>& events) const
uint64_t amount = get_outs_money_amount(miner_tx);
uint64_t portion = amount / tx_out_count;
uint64_t remainder = amount % tx_out_count;
txout_target_v target = miner_tx.vout[0].target;
txout_target_v target =boost::get<currency::tx_out_bare>( miner_tx.vout[0]).target;
miner_tx.vout.clear();
for (size_t i = 0; i < tx_out_count; ++i)
{

View file

@ -119,12 +119,21 @@ bool gen_chain_switch_pow_pos::generate(std::vector<test_event_entry>& events) c
crypto::public_key stake_tx_pub_key = get_tx_pub_key_from_extra(stake);
size_t stake_output_idx = 0, i = 0;
uint64_t stake_output_amount = 0;
std::for_each(stake.vout.begin(), stake.vout.end(), [&stake_output_amount, &stake_output_idx, &i](const tx_out_bare& o){ if (o.amount > stake_output_amount) { stake_output_amount = o.amount; stake_output_idx = i; } ++i; });
std::for_each(stake.vout.begin(), stake.vout.end(), [&stake_output_amount, &stake_output_idx, &i](const tx_out_v& o_)
{
auto& o = boost::get<currency::tx_out_bare>(o_);
if (o.amount > stake_output_amount)
{
stake_output_amount = o.amount;
stake_output_idx = i;
}
++i;
});
size_t stake_output_gidx = generator.get_tx_out_gindex(prev_id, currency::get_transaction_hash(stake), stake_output_idx);
crypto::key_image stake_output_key_image;
keypair kp;
generate_key_image_helper(alice.get_keys(), stake_tx_pub_key, stake_output_idx, kp, stake_output_key_image);
crypto::public_key stake_output_pubkey = boost::get<txout_to_key>(stake.vout[stake_output_idx].target).key;
crypto::public_key stake_output_pubkey = boost::get<txout_to_key>(boost::get<currency::tx_out_bare>(stake.vout[stake_output_idx]).target).key;
pos_block_builder pb;
pb.step1_init_header(height, prev_id);

View file

@ -610,8 +610,8 @@ bool test_generator::build_outputs_indext_for_chain(const blockchain_vector& blo
std::vector<uint64_t>& coinbase_outs = txs_outs[currency::get_transaction_hash(blocks[h]->b.miner_tx)];
for (size_t out_i = 0; out_i != blocks[h]->b.miner_tx.vout.size(); out_i++)
{
coinbase_outs.push_back(index[blocks[h]->b.miner_tx.vout[out_i].amount].size());
index[blocks[h]->b.miner_tx.vout[out_i].amount].push_back(std::tuple<size_t, size_t, size_t>(h, 0, out_i));
coinbase_outs.push_back(index[boost::get<currency::tx_out_bare>(blocks[h]->b.miner_tx.vout[out_i]).amount].size());
index[boost::get<currency::tx_out_bare>(blocks[h]->b.miner_tx.vout[out_i]).amount].push_back(std::tuple<size_t, size_t, size_t>(h, 0, out_i));
}
for (size_t tx_index = 0; tx_index != blocks[h]->m_transactions.size(); tx_index++)
@ -619,8 +619,8 @@ bool test_generator::build_outputs_indext_for_chain(const blockchain_vector& blo
std::vector<uint64_t>& tx_outs_indx = txs_outs[currency::get_transaction_hash(blocks[h]->m_transactions[tx_index])];
for (size_t out_i = 0; out_i != blocks[h]->m_transactions[tx_index].vout.size(); out_i++)
{
tx_outs_indx.push_back(index[blocks[h]->m_transactions[tx_index].vout[out_i].amount].size());
index[blocks[h]->m_transactions[tx_index].vout[out_i].amount].push_back(std::tuple<size_t, size_t, size_t>(h, tx_index + 1, out_i));
tx_outs_indx.push_back(index[boost::get<currency::tx_out_bare>(blocks[h]->m_transactions[tx_index].vout[out_i]).amount].size());
index[boost::get<currency::tx_out_bare>(blocks[h]->m_transactions[tx_index].vout[out_i]).amount].push_back(std::tuple<size_t, size_t, size_t>(h, tx_index + 1, out_i));
}
}
}
@ -653,13 +653,13 @@ bool test_generator::get_output_details_by_global_index(const test_generator::bl
CHECK_AND_ASSERT_THROW_MES(tx_out_index < tx->vout.size(), "tx_index < blck_chain[h].m_transactions.size()");
tx_pub_key = get_tx_pub_key_from_extra(*tx);
CHECK_AND_ASSERT_THROW_MES(tx->vout[tx_out_index].target.type() == typeid(currency::txout_to_key),
"blck_chain[h]->m_transactions[tx_index].vout[tx_out_index].target.type() == typeid(currency::txout_to_key)");
CHECK_AND_ASSERT_THROW_MES(boost::get<tx_out_bare>(tx->vout[tx_out_index]).target.type() == typeid(currency::txout_to_key),
"blck_chain[h]->m_transactions[tx_index]boost::get<currency::tx_out_bare>(.vout[tx_out_index]).target.type() == typeid(currency::txout_to_key)");
CHECK_AND_ASSERT_THROW_MES(tx->vout[tx_out_index].amount == amount,
"blck_chain[h]->m_transactions[tx_index].vout[tx_out_index].amount == amount");
CHECK_AND_ASSERT_THROW_MES(boost::get<tx_out_bare>(tx->vout[tx_out_index]).amount == amount,
"blck_chain[h]->m_transactions[tx_index]boost::get<currency::tx_out_bare>(.vout[tx_out_index]).amount == amount");
output_key = boost::get<currency::txout_to_key>(tx->vout[tx_out_index].target).key;
output_key = boost::get<currency::txout_to_key>(boost::get<tx_out_bare>(tx->vout[tx_out_index]).target).key;
return true;
}
//------------------------------------------------------------------
@ -1083,7 +1083,7 @@ bool init_output_indices(map_output_idx_t& outs, map_output_t& outs_mine, const
for (size_t j = 0; j < tx.vout.size(); ++j)
{
const tx_out_bare &out = tx.vout[j];
const tx_out_bare &out = boost::get<tx_out_bare>(tx.vout[j]);
output_index oi(out.target, out.amount, boost::get<txin_gen>(*blk.miner_tx.vin.begin()).height, i, j, &blk, vtx[i]);
if (out.target.type() == typeid(txout_to_key))
@ -1766,7 +1766,7 @@ bool find_global_index_for_output(const std::vector<test_event_entry>& events, c
auto process_tx = [&reference_tx, &reference_tx_out_index, &global_outputs](const currency::transaction& tx) -> uint64_t
{
for (size_t tx_out_index = 0; tx_out_index < tx.vout.size(); ++tx_out_index) {
const tx_out_bare &out = tx.vout[tx_out_index];
const tx_out_bare &out = boost::get<tx_out_bare>(tx.vout[tx_out_index]);
if (out.target.type() == typeid(txout_to_key)) {
uint64_t global_out_index = global_outputs[out.amount]++;
@ -1799,7 +1799,7 @@ bool find_global_index_for_output(const std::vector<test_event_entry>& events, c
size_t get_tx_out_index_by_amount(const currency::transaction& tx, const uint64_t amount)
{
for (size_t i = 0; i < tx.vout.size(); ++i)
if (tx.vout[i].amount == amount)
if (boost::get<currency::tx_out_bare>(tx.vout[i]).amount == amount)
return i;
return SIZE_MAX;
@ -1820,14 +1820,14 @@ bool sign_multisig_input_in_tx_custom(currency::transaction& tx, size_t ms_input
size_t ms_out_index = SIZE_MAX;
for (size_t i = 0; i < source_tx.vout.size(); ++i)
{
if (source_tx.vout[i].target.type() == typeid(txout_multisig) && ms_in.multisig_out_id == get_multisig_out_id(source_tx, i))
if (boost::get<currency::tx_out_bare>(source_tx.vout[i]).target.type() == typeid(txout_multisig) && ms_in.multisig_out_id == get_multisig_out_id(source_tx, i))
{
ms_out_index = i;
break;
}
}
LOC_CHK(ms_out_index != SIZE_MAX, "failed to find ms output in source tx " << get_transaction_hash(source_tx) << " by ms id " << ms_in.multisig_out_id);
const txout_multisig& out_ms = boost::get<txout_multisig>(source_tx.vout[ms_out_index].target);
const txout_multisig& out_ms = boost::get<txout_multisig>(boost::get<currency::tx_out_bare>(source_tx.vout[ms_out_index]).target);
crypto::public_key source_tx_pub_key = get_tx_pub_key_from_extra(source_tx);
@ -1835,9 +1835,9 @@ bool sign_multisig_input_in_tx_custom(currency::transaction& tx, size_t ms_input
bool r = currency::derive_ephemeral_key_helper(keys, source_tx_pub_key, ms_out_index, ms_in_ephemeral_key);
LOC_CHK(r, "derive_ephemeral_key_helper failed");
LOC_CHK(ms_input_index < tx.signatures.size(), "transaction does not have signatures vectory entry for ms input #" << ms_input_index);
LOC_CHK(ms_input_index < boost::get<currency::NLSAG_sig>(tx.signature).s.size(), "transaction does not have signatures vectory entry for ms input #" << ms_input_index);
auto& sigs = tx.signatures[ms_input_index];
auto& sigs = boost::get<currency::NLSAG_sig>(tx.signature).s[ms_input_index];
LOC_CHK(!sigs.empty(), "empty signatures container");
bool extra_signature_expected = (get_tx_flags(tx) & TX_FLAG_SIGNATURE_MODE_SEPARATE) && ms_input_index == tx.vin.size() - 1;
size_t allocated_sigs_for_participants = extra_signature_expected ? sigs.size() - 1 : sigs.size();
@ -1897,11 +1897,11 @@ bool make_tx_multisig_to_key(const currency::transaction& source_tx,
CHECK_AND_ASSERT_MES(source_tx_out_idx < source_tx.vout.size(), false, "tx " << se.real_output << " has " << source_tx.vout.size() << " outputs, #" << source_tx_out_idx << " specified");
se.real_output_in_tx_index = source_tx_out_idx;
se.multisig_id = get_multisig_out_id(source_tx, se.real_output_in_tx_index);
CHECK_AND_ASSERT_MES(source_tx.vout[se.real_output_in_tx_index].target.type() == typeid(txout_multisig), false, "tx " << se.real_output << " output #" << source_tx_out_idx << " is not a txout_multisig");
const txout_multisig& ms_out = boost::get<txout_multisig>(source_tx.vout[se.real_output_in_tx_index].target);
CHECK_AND_ASSERT_MES(boost::get<currency::tx_out_bare>(source_tx.vout[se.real_output_in_tx_index]).target.type() == typeid(txout_multisig), false, "tx " << se.real_output << " output #" << source_tx_out_idx << " is not a txout_multisig");
const txout_multisig& ms_out = boost::get<txout_multisig>(boost::get<currency::tx_out_bare>(source_tx.vout[se.real_output_in_tx_index]).target);
se.ms_keys_count = ms_out.keys.size();
se.ms_sigs_count = ms_out.minimum_sigs;
se.amount = source_tx.vout[se.real_output_in_tx_index].amount;
se.amount =boost::get<currency::tx_out_bare>( source_tx.vout[se.real_output_in_tx_index]).amount;
tx_destination_entry de(se.amount - fee, target_address);
@ -1995,11 +1995,11 @@ bool generate_pos_block_with_given_coinstake(test_generator& generator, const st
bool r = find_global_index_for_output(events, prev_id, stake_tx, stake_output_idx, stake_output_gidx);
CHECK_AND_ASSERT_MES(r, false, "find_global_index_for_output failed");
}
uint64_t stake_output_amount = stake_tx.vout[stake_output_idx].amount;
uint64_t stake_output_amount =boost::get<currency::tx_out_bare>( stake_tx.vout[stake_output_idx]).amount;
crypto::key_image stake_output_key_image;
keypair kp;
generate_key_image_helper(miner.get_keys(), stake_tx_pub_key, stake_output_idx, kp, stake_output_key_image);
crypto::public_key stake_output_pubkey = boost::get<txout_to_key>(stake_tx.vout[stake_output_idx].target).key;
crypto::public_key stake_output_pubkey = boost::get<txout_to_key>(boost::get<currency::tx_out_bare>(stake_tx.vout[stake_output_idx]).target).key;
pos_block_builder pb;
pb.step1_init_header(height, prev_id);
@ -2046,7 +2046,7 @@ bool check_ring_signature_at_gen_time(const std::vector<test_event_entry>& event
auto it = mtx.find(rbi.tx_id);
CHECK_AND_ASSERT_MES(it != mtx.end(), false, "it == end");
CHECK_AND_ASSERT_MES(rbi.n < it->second->vout.size(), false, "FAIL: rbi.n < it->second->vout.size()");
auto& pub_key = boost::get<txout_to_key>(it->second->vout[rbi.n].target).key;
auto& pub_key = boost::get<txout_to_key>(boost::get<tx_out_bare>(it->second->vout[rbi.n]).target).key;
pub_keys.push_back(pub_key);
pub_keys_ptrs.push_back(&pub_keys.back());

View file

@ -744,7 +744,7 @@ bool construct_broken_tx(const currency::account_keys& sender_account_keys, cons
{
tx.vin.clear();
tx.vout.clear();
tx.signatures.clear();
boost::get<currency::NLSAG_sig>(tx.signature).s.clear();
tx.extra = extra;
tx.version = TRANSACTION_VERSION_PRE_HF4;
@ -846,8 +846,8 @@ bool construct_broken_tx(const currency::account_keys& sender_account_keys, cons
ss_ring_s << o.second << ENDL;
}
tx.signatures.push_back(std::vector<crypto::signature>());
std::vector<crypto::signature>& sigs = tx.signatures.back();
boost::get<currency::NLSAG_sig>(tx.signature).s.push_back(std::vector<crypto::signature>());
std::vector<crypto::signature>& sigs = boost::get<currency::NLSAG_sig>(tx.signature).s.back();
sigs.resize(src_entr.outputs.size());
crypto::generate_ring_signature(tx_prefix_hash, boost::get<currency::txin_to_key>(tx.vin[i]).k_image, keys_ptrs, in_contexts[i].in_ephemeral.sec, src_entr.real_output, sigs.data());
ss_ring_s << "signatures:" << ENDL;

View file

@ -218,7 +218,7 @@ inline bool resign_tx(const currency::account_keys& sender_keys, const std::vect
if (sources.size() != tx.vin.size())
return false;
tx.signatures.clear();
boost::get<currency::NLSAG_sig>(tx.signature).s.clear();
crypto::hash tx_prefix_hash = get_transaction_hash(tx);
size_t i = 0;
@ -234,8 +234,8 @@ inline bool resign_tx(const currency::account_keys& sender_keys, const std::vect
return false;
crypto::derive_secret_key(recv_derivation, se.real_output_in_tx_index, sender_keys.spend_secret_key, in_ephemeral_sec);
tx.signatures.push_back(std::vector<crypto::signature>());
std::vector<crypto::signature>& sigs = tx.signatures.back();
boost::get<currency::NLSAG_sig>(tx.signature).s.push_back(std::vector<crypto::signature>());
std::vector<crypto::signature>& sigs = boost::get<currency::NLSAG_sig>(tx.signature).s.back();
if (se.is_multisig())
{

View file

@ -308,7 +308,7 @@ public:
return; // skip certainly invalid txs
bool b_cp = c.get_blockchain_storage().is_in_checkpoint_zone();
if (b_cp && tx.signatures.empty() && tx.attachment.empty())
if (b_cp && boost::get<currency::NLSAG_sig>(tx.signature).s.empty() && tx.attachment.empty())
return; // skip pruned txs in CP zone
size_t tx_expected_blob_size = get_object_blobsize(tx);
@ -328,7 +328,7 @@ public:
{
// tx seems to be correct ( tx_expected_blob_size == blob.size() ) or BCS is in CP zone, prune sigs and attachments and check again
currency::transaction pruned_tx = tx;
pruned_tx.signatures.clear();
boost::get<currency::NLSAG_sig>(pruned_tx.signature).s.clear();
pruned_tx.attachment.clear();
size_t pruned_tx_expected_blob_size = get_object_blobsize(pruned_tx);

View file

@ -121,7 +121,7 @@ bool gen_checkpoints_attachments_basic::check_tx(currency::core& c, size_t ev_in
bool r = c.get_transaction(m_tx_hash, tx);
CHECK_AND_ASSERT_MES(r, false, "can't get transaction");
CHECK_AND_ASSERT_MES(tx.signatures.empty(), false, "tx has non-empty sig");
CHECK_AND_ASSERT_MES(boost::get<currency::NLSAG_sig>(tx.signature).s.empty(), false, "tx has non-empty sig");
CHECK_AND_ASSERT_MES(tx.attachment.empty(), false, "tx has non-empty attachments");
return true;
}
@ -443,12 +443,12 @@ bool gen_checkpoints_prun_txs_after_blockchain_load::check_txs(currency::core& c
transaction tx_0, tx_1;
bool r = c.get_transaction(m_tx0_id, tx_0);
CHECK_AND_ASSERT_MES(r, false, "can't get transaction tx_0");
CHECK_AND_ASSERT_MES(tx_0.signatures.empty(), false, "tx_0 has non-empty sig");
CHECK_AND_ASSERT_MES(boost::get<currency::NLSAG_sig>(tx_0.signature).s.empty(), false, "tx_0 has non-empty sig");
CHECK_AND_ASSERT_MES(tx_0.attachment.empty(), false, "tx_0 has non-empty attachments");
r = c.get_transaction(m_tx1_id, tx_1);
CHECK_AND_ASSERT_MES(r, false, "can't get transaction tx_1");
CHECK_AND_ASSERT_MES(!tx_1.signatures.empty(), false, "tx_1 has empty sig");
CHECK_AND_ASSERT_MES(!boost::get<currency::NLSAG_sig>(tx_1.signature).s.empty(), false, "tx_1 has empty sig");
CHECK_AND_ASSERT_MES(!tx_1.attachment.empty(), false, "tx_1 has empty attachments");
return true;
@ -552,11 +552,11 @@ bool gen_checkpoints_pos_validation_on_altchain::generate(std::vector<test_event
crypto::public_key stake_tx_pub_key = get_tx_pub_key_from_extra(stake);
size_t stake_output_idx = 0;
size_t stake_output_gidx = 0;
uint64_t stake_output_amount = stake.vout[stake_output_idx].amount;
uint64_t stake_output_amount =boost::get<currency::tx_out_bare>( stake.vout[stake_output_idx]).amount;
crypto::key_image stake_output_key_image;
keypair kp;
generate_key_image_helper(miner_acc.get_keys(), stake_tx_pub_key, stake_output_idx, kp, stake_output_key_image);
crypto::public_key stake_output_pubkey = boost::get<txout_to_key>(stake.vout[stake_output_idx].target).key;
crypto::public_key stake_output_pubkey = boost::get<txout_to_key>(boost::get<currency::tx_out_bare>(stake.vout[stake_output_idx]).target).key;
pos_block_builder pb;
pb.step1_init_header(height, prev_id);
@ -581,11 +581,11 @@ bool gen_checkpoints_pos_validation_on_altchain::generate(std::vector<test_event
crypto::public_key stake_tx_pub_key = get_tx_pub_key_from_extra(stake);
size_t stake_output_idx = 0;
size_t stake_output_gidx = 0;
uint64_t stake_output_amount = stake.vout[stake_output_idx].amount;
uint64_t stake_output_amount =boost::get<currency::tx_out_bare>( stake.vout[stake_output_idx]).amount;
crypto::key_image stake_output_key_image;
keypair kp;
generate_key_image_helper(miner_acc.get_keys(), stake_tx_pub_key, stake_output_idx, kp, stake_output_key_image);
//crypto::public_key stake_output_pubkey = boost::get<txout_to_key>(stake.vout[stake_output_idx].target).key;
//crypto::public_key stake_output_pubkey = boost::get<txout_to_key>(boost::get<currency::tx_out_bare>(stake.vout[stake_output_idx]).target).key;
pos_block_builder pb;
pb.step1_init_header(height, prev_id);
@ -595,7 +595,7 @@ bool gen_checkpoints_pos_validation_on_altchain::generate(std::vector<test_event
// don't sign at all
//pb.step5_sign(stake_tx_pub_key, stake_output_idx, stake_output_pubkey, miner_acc);
pb.m_block.miner_tx.signatures[0].clear(); // just to make sure
boost::get<currency::NLSAG_sig>(pb.m_block.miner_tx.signature).s[0].clear(); // just to make sure
blk_2 = pb.m_block;
}
@ -875,7 +875,7 @@ bool gen_checkpoints_and_invalid_tx_to_pool::generate(std::vector<test_event_ent
CHECK_AND_ASSERT_MES(r, false, "construct_tx failed");
// invalidate tx_0 signature
tx_0.signatures.clear();
boost::get<currency::NLSAG_sig>(tx_0.signature).s.clear();
DO_CALLBACK(events, "mark_unverifiable_tx");
events.push_back(tx_0);

View file

@ -71,7 +71,7 @@ bool gen_double_spend_in_tx<txs_kept_by_block>::generate(std::vector<test_event_
// find correct output by amount (selecting random or fixed one can be possibly mistaken with changeback)
for (auto out : tx_0.vout)
{
se.amount = out.amount;
se.amount = boost::get<currency::tx_out_bare>(out).amount;
if (se.amount == send_amount)
break;
++se.real_output_in_tx_index;
@ -80,7 +80,7 @@ bool gen_double_spend_in_tx<txs_kept_by_block>::generate(std::vector<test_event_
uint64_t global_out_index = 0;
bool r = find_global_index_for_output(events, get_block_hash(blk_1r), tx_0, se.real_output_in_tx_index, global_out_index);
CHECK_AND_ASSERT_MES(r, false, "find_global_index_for_output failed");
se.outputs.push_back(make_serializable_pair<currency::txout_ref_v, crypto::public_key>(global_out_index, boost::get<currency::txout_to_key>(tx_0.vout[se.real_output_in_tx_index].target).key));
se.outputs.push_back(make_serializable_pair<currency::txout_ref_v, crypto::public_key>(global_out_index, boost::get<currency::txout_to_key>(boost::get<currency::tx_out_bare>(tx_0.vout[se.real_output_in_tx_index]).target).key));
se.real_output = 0;
se.real_out_tx_key = get_tx_pub_key_from_extra(tx_0);
sources.push_back(se);

View file

@ -98,11 +98,11 @@ bool emission_test::c1(currency::core& c, size_t ev_index, const std::vector<tes
const transaction& stake = tce_ptr->tx;
crypto::public_key stake_tx_pub_key = get_tx_pub_key_from_extra(stake);
size_t stake_output_gidx = tce_ptr->m_global_output_indexes[stake_output_idx];
uint64_t stake_output_amount = stake.vout[stake_output_idx].amount;
uint64_t stake_output_amount =boost::get<currency::tx_out_bare>( stake.vout[stake_output_idx]).amount;
crypto::key_image stake_output_key_image;
keypair kp;
generate_key_image_helper(m_miner_acc.get_keys(), stake_tx_pub_key, stake_output_idx, kp, stake_output_key_image);
crypto::public_key stake_output_pubkey = boost::get<txout_to_key>(stake.vout[stake_output_idx].target).key;
crypto::public_key stake_output_pubkey = boost::get<txout_to_key>(boost::get<currency::tx_out_bare>(stake.vout[stake_output_idx]).target).key;
difficulty = c.get_blockchain_storage().get_next_diff_conditional(true);
//size_t median_size = 0; // little hack: we're using small blocks (only coinbase tx), so we're in CURRENCY_BLOCK_GRANTED_FULL_REWARD_ZONE - don't need to calc median size
@ -124,7 +124,12 @@ bool emission_test::c1(currency::core& c, size_t ev_index, const std::vector<tes
pos_coins += gen_coins;
// update stakes queue: pop used one from the front and push output of this PoS block to the back
size_t biggest_output_idx = std::max_element(pb.m_block.miner_tx.vout.begin(), pb.m_block.miner_tx.vout.end(), [](const currency::tx_out_bare& l, const currency::tx_out_bare& r){ return l.amount < r.amount;}) - pb.m_block.miner_tx.vout.begin();
size_t biggest_output_idx = std::max_element(pb.m_block.miner_tx.vout.begin(), pb.m_block.miner_tx.vout.end(),
[](const currency::tx_out_v& l, const currency::tx_out_v& r)
{
return boost::get<tx_out_bare>(l).amount < boost::get<tx_out_bare>(r).amount;
}) - pb.m_block.miner_tx.vout.begin();
stake_tx_outs.pop_front();
stake_tx_outs.push_back(std::make_pair(get_transaction_hash(pb.m_block.miner_tx), biggest_output_idx));

View file

@ -253,8 +253,8 @@ inline bool build_custom_escrow_template(const std::vector<test_event_entry>& ev
if (custom_config_mask & eccf_template_no_a_sigs)
{
escrow_template_tx.signatures.clear();
escrow_template_tx.signatures.push_back(std::vector<crypto::signature>());
boost::get<currency::NLSAG_sig>(escrow_template_tx.signature).s.clear();
boost::get<currency::NLSAG_sig>(escrow_template_tx.signature).s.push_back(std::vector<crypto::signature>());
}
append_vector_by_another_vector(used_sources, sources);
@ -338,11 +338,11 @@ inline bool build_custom_escrow_release_template(
// inputs
// create multisig (A-B) source, add keys from B
tx_source_entry se = AUTO_VAL_INIT(se);
se.amount = (~custom_config_mask & eccf_rel_template_inv_ms_amount) ? escrow_template_tx.vout[ms_idx].amount : escrow_template_tx.vout[ms_idx].amount + 10 * TESTS_DEFAULT_FEE;
se.amount = (~custom_config_mask & eccf_rel_template_inv_ms_amount) ?boost::get<currency::tx_out_bare>( escrow_template_tx.vout[ms_idx]).amount :boost::get<currency::tx_out_bare>( escrow_template_tx.vout[ms_idx]).amount + 10 * TESTS_DEFAULT_FEE;
se.multisig_id = ms_id;
se.real_output_in_tx_index = ms_idx;
se.real_out_tx_key = get_tx_pub_key_from_extra(escrow_template_tx);
se.ms_keys_count = boost::get<txout_multisig>(escrow_template_tx.vout[ms_idx].target).keys.size();
se.ms_keys_count = boost::get<txout_multisig>(boost::get<currency::tx_out_bare>(escrow_template_tx.vout[ms_idx]).target).keys.size();
se.ms_sigs_count = (~custom_config_mask & eccf_rel_template_inv_sigs_count) ? 2 : 1;
std::vector<tx_source_entry> sources({ se });

View file

@ -108,8 +108,8 @@ bool escrow_wallet_test::prepare_proposal_accepted_test(currency::core& c, const
cpd.title = "Afterlife? If I thought I had to live another life, I'd kill myself right now!";
wallet_buyer->send_escrow_proposal(cpd, 0, 0, 3600, TESTS_DEFAULT_FEE, TESTS_DEFAULT_FEE, "", escrow_proposal_tx, escrow_template_tx);
auto it = std::find_if(escrow_template_tx.vout.begin(), escrow_template_tx.vout.end(), [](const tx_out_bare& o){
if (o.target.type() == typeid(txout_multisig))
auto it = std::find_if(escrow_template_tx.vout.begin(), escrow_template_tx.vout.end(), [](const tx_out_v& o){
if (boost::get<tx_out_bare>(o).target.type() == typeid(txout_multisig))
return true;
return false;
});

View file

@ -390,11 +390,11 @@ bool hard_fork_1_checkpoint_basic_test::generate(std::vector<test_event_entry>&
crypto::public_key stake_tx_pub_key = get_tx_pub_key_from_extra(stake);
size_t stake_output_idx = 0;
size_t stake_output_gidx = 0;
uint64_t stake_output_amount = stake.vout[stake_output_idx].amount;
uint64_t stake_output_amount =boost::get<currency::tx_out_bare>( stake.vout[stake_output_idx]).amount;
crypto::key_image stake_output_key_image;
keypair kp;
generate_key_image_helper(stakeholder.get_keys(), stake_tx_pub_key, stake_output_idx, kp, stake_output_key_image);
crypto::public_key stake_output_pubkey = boost::get<txout_to_key>(stake.vout[stake_output_idx].target).key;
crypto::public_key stake_output_pubkey = boost::get<txout_to_key>(boost::get<currency::tx_out_bare>(stake.vout[stake_output_idx]).target).key;
pos_block_builder pb;
pb.step1_init_header(height, prev_id);
@ -566,11 +566,11 @@ bool hard_fork_1_pos_and_locked_coins::generate(std::vector<test_event_entry>& e
crypto::public_key stake_tx_pub_key = get_tx_pub_key_from_extra(stake);
size_t stake_output_idx = 0;
size_t stake_output_gidx = 0;
uint64_t stake_output_amount = stake.vout[stake_output_idx].amount;
uint64_t stake_output_amount =boost::get<currency::tx_out_bare>( stake.vout[stake_output_idx]).amount;
crypto::key_image stake_output_key_image;
keypair kp;
generate_key_image_helper(alice_acc.get_keys(), stake_tx_pub_key, stake_output_idx, kp, stake_output_key_image);
crypto::public_key stake_output_pubkey = boost::get<txout_to_key>(stake.vout[stake_output_idx].target).key;
crypto::public_key stake_output_pubkey = boost::get<txout_to_key>(boost::get<currency::tx_out_bare>(stake.vout[stake_output_idx]).target).key;
pos_block_builder pb;
pb.step1_init_header(height, prev_id);
@ -605,11 +605,11 @@ bool hard_fork_1_pos_and_locked_coins::generate(std::vector<test_event_entry>& e
crypto::public_key stake_tx_pub_key = get_tx_pub_key_from_extra(stake);
size_t stake_output_idx = 0;
size_t stake_output_gidx = 0;
uint64_t stake_output_amount = stake.vout[stake_output_idx].amount;
uint64_t stake_output_amount =boost::get<currency::tx_out_bare>( stake.vout[stake_output_idx]).amount;
crypto::key_image stake_output_key_image;
keypair kp;
generate_key_image_helper(alice_acc.get_keys(), stake_tx_pub_key, stake_output_idx, kp, stake_output_key_image);
crypto::public_key stake_output_pubkey = boost::get<txout_to_key>(stake.vout[stake_output_idx].target).key;
crypto::public_key stake_output_pubkey = boost::get<txout_to_key>(boost::get<currency::tx_out_bare>(stake.vout[stake_output_idx]).target).key;
pos_block_builder pb;
pb.step1_init_header(height, prev_id);
@ -653,11 +653,11 @@ bool hard_fork_1_pos_and_locked_coins::generate(std::vector<test_event_entry>& e
crypto::public_key stake_tx_pub_key = get_tx_pub_key_from_extra(stake);
size_t stake_output_idx = 0;
size_t stake_output_gidx = 0;
uint64_t stake_output_amount = stake.vout[stake_output_idx].amount;
uint64_t stake_output_amount =boost::get<currency::tx_out_bare>( stake.vout[stake_output_idx]).amount;
crypto::key_image stake_output_key_image;
keypair kp;
generate_key_image_helper(bob_acc.get_keys(), stake_tx_pub_key, stake_output_idx, kp, stake_output_key_image);
crypto::public_key stake_output_pubkey = boost::get<txout_to_key>(stake.vout[stake_output_idx].target).key;
crypto::public_key stake_output_pubkey = boost::get<txout_to_key>(boost::get<currency::tx_out_bare>(stake.vout[stake_output_idx]).target).key;
pos_block_builder pb;
pb.step1_init_header(height, prev_id);
@ -750,11 +750,11 @@ bool hard_fork_1_pos_locked_height_vs_time::generate(std::vector<test_event_entr
crypto::public_key stake_tx_pub_key = get_tx_pub_key_from_extra(stake);
size_t stake_output_idx = 0;
size_t stake_output_gidx = 0;
uint64_t stake_output_amount = stake.vout[stake_output_idx].amount;
uint64_t stake_output_amount =boost::get<currency::tx_out_bare>( stake.vout[stake_output_idx]).amount;
crypto::key_image stake_output_key_image;
keypair kp;
generate_key_image_helper(stakeholder.get_keys(), stake_tx_pub_key, stake_output_idx, kp, stake_output_key_image);
crypto::public_key stake_output_pubkey = boost::get<txout_to_key>(stake.vout[stake_output_idx].target).key;
crypto::public_key stake_output_pubkey = boost::get<txout_to_key>(boost::get<currency::tx_out_bare>(stake.vout[stake_output_idx]).target).key;
pos_block_builder pb;
pb.step1_init_header(height, prev_id);
@ -795,11 +795,11 @@ bool hard_fork_1_pos_locked_height_vs_time::generate(std::vector<test_event_entr
crypto::public_key stake_tx_pub_key = get_tx_pub_key_from_extra(stake);
size_t stake_output_idx = 0;
size_t stake_output_gidx = 0;
uint64_t stake_output_amount = stake.vout[stake_output_idx].amount;
uint64_t stake_output_amount =boost::get<currency::tx_out_bare>( stake.vout[stake_output_idx]).amount;
crypto::key_image stake_output_key_image;
keypair kp;
generate_key_image_helper(stakeholder.get_keys(), stake_tx_pub_key, stake_output_idx, kp, stake_output_key_image);
crypto::public_key stake_output_pubkey = boost::get<txout_to_key>(stake.vout[stake_output_idx].target).key;
crypto::public_key stake_output_pubkey = boost::get<txout_to_key>(boost::get<currency::tx_out_bare>(stake.vout[stake_output_idx]).target).key;
pos_block_builder pb;
pb.step1_init_header(height, prev_id);
@ -839,11 +839,11 @@ bool hard_fork_1_pos_locked_height_vs_time::generate(std::vector<test_event_entr
crypto::public_key stake_tx_pub_key = get_tx_pub_key_from_extra(stake);
size_t stake_output_idx = 0;
size_t stake_output_gidx = 0;
uint64_t stake_output_amount = stake.vout[stake_output_idx].amount;
uint64_t stake_output_amount =boost::get<currency::tx_out_bare>( stake.vout[stake_output_idx]).amount;
crypto::key_image stake_output_key_image;
keypair kp;
generate_key_image_helper(stakeholder.get_keys(), stake_tx_pub_key, stake_output_idx, kp, stake_output_key_image);
crypto::public_key stake_output_pubkey = boost::get<txout_to_key>(stake.vout[stake_output_idx].target).key;
crypto::public_key stake_output_pubkey = boost::get<txout_to_key>(boost::get<currency::tx_out_bare>(stake.vout[stake_output_idx]).target).key;
pos_block_builder pb;
pb.step1_init_header(height, prev_id);

View file

@ -653,9 +653,9 @@ bool hard_fork_2_auditable_addresses_basics::generate(std::vector<test_event_ent
// make sure all Bob's outputs has mix_attr = 1
for (auto& out : tx_1.vout)
{
if (out.amount != MK_TEST_COINS(5))
if (boost::get<tx_out_bare>(out).amount != MK_TEST_COINS(5))
continue; // skip change
uint8_t mix_attr = boost::get<txout_to_key>(out.target).mix_attr;
uint8_t mix_attr = boost::get<txout_to_key>(boost::get<tx_out_bare>(out).target).mix_attr;
CHECK_AND_ASSERT_MES(mix_attr == CURRENCY_TO_KEY_OUT_FORCED_NO_MIX, false, "Incorrect mix_attr in tx_1: " << mix_attr);
}
@ -686,9 +686,9 @@ bool hard_fork_2_auditable_addresses_basics::c1(currency::core& c, size_t ev_ind
// make sure all Bob's outputs has mix_attr = 1
for (auto& out : tx.vout)
{
if (out.amount != MK_TEST_COINS(1))
if (boost::get<tx_out_bare>(out).amount != MK_TEST_COINS(1))
continue; // skip change
uint8_t mix_attr = boost::get<txout_to_key>(out.target).mix_attr;
uint8_t mix_attr = boost::get<txout_to_key>(boost::get<tx_out_bare>(out).target).mix_attr;
CHECK_AND_ASSERT_MES(mix_attr == CURRENCY_TO_KEY_OUT_FORCED_NO_MIX, false, "Incorrect mix_attr in tx: " << mix_attr);
}
@ -711,9 +711,9 @@ bool hard_fork_2_auditable_addresses_basics::c1(currency::core& c, size_t ev_ind
// make sure all Bob's outputs has mix_attr = 1
for (auto& out : tx.vout)
{
if (out.amount != MK_TEST_COINS(1))
if (boost::get<tx_out_bare>(out).amount != MK_TEST_COINS(1))
continue; // skip change
uint8_t mix_attr = boost::get<txout_to_key>(out.target).mix_attr;
uint8_t mix_attr = boost::get<txout_to_key>(boost::get<tx_out_bare>(out).target).mix_attr;
CHECK_AND_ASSERT_MES(mix_attr == CURRENCY_TO_KEY_OUT_FORCED_NO_MIX, false, "Incorrect mix_attr in tx: " << mix_attr);
}

View file

@ -21,7 +21,7 @@ namespace
{
uint64_t total_amount = get_outs_money_amount(miner_tx);
uint64_t amount_2 = total_amount - amount_1;
txout_target_v target = miner_tx.vout[0].target;
txout_target_v target =boost::get<currency::tx_out_bare>( miner_tx.vout[0]).target;
miner_tx.vout.clear();
@ -39,8 +39,8 @@ namespace
void append_tx_source_entry(std::vector<currency::tx_source_entry>& sources, const transaction& tx, size_t out_idx)
{
currency::tx_source_entry se = AUTO_VAL_INIT(se);
se.amount = tx.vout[out_idx].amount;
se.outputs.push_back(make_serializable_pair<txout_ref_v, crypto::public_key>(0, boost::get<currency::txout_to_key>(tx.vout[out_idx].target).key));
se.amount =boost::get<currency::tx_out_bare>( tx.vout[out_idx]).amount;
se.outputs.push_back(make_serializable_pair<txout_ref_v, crypto::public_key>(0, boost::get<currency::txout_to_key>(boost::get<currency::tx_out_bare>(tx.vout[out_idx]).target).key));
se.real_output = 0;
se.real_out_tx_key = get_tx_pub_key_from_extra(tx);
se.real_output_in_tx_index = out_idx;
@ -134,7 +134,7 @@ bool gen_uint_overflow_2::generate(std::vector<test_event_entry>& events) const
std::vector<currency::tx_source_entry> sources;
for (size_t i = 0; i < blk_0.miner_tx.vout.size(); ++i)
{
if (TESTS_DEFAULT_FEE < blk_0.miner_tx.vout[i].amount)
if (TESTS_DEFAULT_FEE < boost::get<currency::tx_out_bare>(blk_0.miner_tx.vout[i]).amount)
{
append_tx_source_entry(sources, blk_0.miner_tx, i);
break;
@ -165,7 +165,7 @@ bool gen_uint_overflow_2::generate(std::vector<test_event_entry>& events) const
sources.clear();
for (size_t i = 0; i < tx_1.vout.size(); ++i)
{
auto& tx_1_out = tx_1.vout[i];
auto& tx_1_out = boost::get<tx_out_bare>(tx_1.vout[i]);
if (tx_1_out.amount < TX_MAX_TRANSFER_AMOUNT - 1)
continue;

View file

@ -267,7 +267,7 @@ bool block_template_vs_invalid_txs_from_pool::generate(std::vector<test_event_en
se.multisig_id = get_multisig_out_id(tx_1m, 0);
se.real_output_in_tx_index = 0;
se.real_out_tx_key = get_tx_pub_key_from_extra(tx_1m);
se.ms_keys_count = boost::get<txout_multisig>(tx_1m.vout[se.real_output_in_tx_index].target).keys.size();
se.ms_keys_count = boost::get<txout_multisig>(boost::get<currency::tx_out_bare>(tx_1m.vout[se.real_output_in_tx_index]).target).keys.size();
se.ms_sigs_count = 1;
transaction tx_2m = AUTO_VAL_INIT(tx_2m);
r = construct_tx(bob_acc.get_keys(), std::vector<tx_source_entry>({ se }), std::vector<tx_destination_entry>({ tx_destination_entry(se.amount - TESTS_DEFAULT_FEE, miner_acc.get_public_address()) }),
@ -447,8 +447,8 @@ bool test_blockchain_vs_spent_multisig_outs::generate(std::vector<test_event_ent
// tx_1: txin_multisig -> txout_to_key
size_t ms_out_idx = 0;
tx_source_entry se = AUTO_VAL_INIT(se);
se.amount = tx_0.vout[ms_out_idx].amount;
se.ms_keys_count = boost::get<txout_multisig>(tx_0.vout[ms_out_idx].target).keys.size();
se.amount =boost::get<currency::tx_out_bare>( tx_0.vout[ms_out_idx]).amount;
se.ms_keys_count = boost::get<txout_multisig>(boost::get<currency::tx_out_bare>(tx_0.vout[ms_out_idx]).target).keys.size();
se.ms_sigs_count = 1;
se.multisig_id = get_multisig_out_id(tx_0, ms_out_idx);
se.real_output_in_tx_index = ms_out_idx;

View file

@ -209,7 +209,7 @@ bool mix_in_spent_outs::generate(std::vector<test_event_entry>& events) const
m_test_amount = MK_TEST_COINS(6);
for(auto& o : blk_0.miner_tx.vout)
{
CHECK_AND_ASSERT_MES(o.amount != m_test_amount, false, "Premine surprisingly has test amount output, change m_test_amount");
CHECK_AND_ASSERT_MES(boost::get<tx_out_bare>(o).amount != m_test_amount, false, "Premine surprisingly has test amount output, change m_test_amount");
}
MAKE_TX_LIST_START(events, txs, miner_acc, alice_acc, m_test_amount, blk_0r);

View file

@ -168,7 +168,7 @@ bool multisig_wallet_test::c1(currency::core& c, size_t ev_index, const std::vec
size_t i = 0;
for (; i != result_tx.vout.size(); i++)
{
if (result_tx.vout[i].target.type() == typeid(txout_multisig))
if (boost::get<currency::tx_out_bare>(result_tx.vout[i]).target.type() == typeid(txout_multisig))
break;
}
CHECK_AND_ASSERT_MES(i != result_tx.vout.size(), false, "Incorrect txs outs");
@ -299,7 +299,10 @@ bool multisig_wallet_test_many_dst::c1(currency::core& c, size_t ev_index, const
miner_wlt->transfer(std::vector<tx_destination_entry>({ de }), 0, 0, TESTS_DEFAULT_FEE, std::vector<currency::extra_v>(), std::vector<currency::attachment_v>(), tools::detail::ssi_digit, tools::tx_dust_policy(DEFAULT_DUST_THRESHOLD), result_tx);
TMP_LOG_RESTORE;
auto it = std::find_if(result_tx.vout.begin(), result_tx.vout.end(), [](tx_out_bare& o) { return o.target.type() == typeid(txout_multisig); });
auto it = std::find_if(result_tx.vout.begin(), result_tx.vout.end(), [](tx_out_v& o)
{
return boost::get<tx_out_bare>(o).target.type() == typeid(txout_multisig);
});
CHECK_AND_ASSERT_MES(it != result_tx.vout.end(), false, "Can't find output txout_multisig");
size_t multisig_index = it - result_tx.vout.begin();
@ -906,7 +909,7 @@ bool multisig_minimum_sigs::generate(std::vector<test_event_entry>& events) cons
se.multisig_id = ms_id;
se.real_output_in_tx_index = ms_out_idx;
se.real_out_tx_key = get_tx_pub_key_from_extra(tx_1);
se.ms_keys_count = boost::get<txout_multisig>(tx_1.vout[se.real_output_in_tx_index].target).keys.size();
se.ms_keys_count = boost::get<txout_multisig>(boost::get<currency::tx_out_bare>(tx_1.vout[se.real_output_in_tx_index]).target).keys.size();
se.ms_sigs_count = 2;
tx_destination_entry de(se.amount - TESTS_DEFAULT_FEE, bob_acc.get_public_address());
@ -939,7 +942,7 @@ bool multisig_minimum_sigs::generate(std::vector<test_event_entry>& events) cons
se.multisig_id = ms_id;
se.real_output_in_tx_index = ms_out_idx;
se.real_out_tx_key = get_tx_pub_key_from_extra(tx_1);
se.ms_keys_count = boost::get<txout_multisig>(tx_1.vout[se.real_output_in_tx_index].target).keys.size();
se.ms_keys_count = boost::get<txout_multisig>(boost::get<currency::tx_out_bare>(tx_1.vout[se.real_output_in_tx_index]).target).keys.size();
se.ms_sigs_count = 2;
transaction tx_3 = AUTO_VAL_INIT(tx_3);
@ -976,7 +979,7 @@ bool multisig_minimum_sigs::generate(std::vector<test_event_entry>& events) cons
se.multisig_id = ms_4_id;
se.real_output_in_tx_index = ms_4_out_idx;
se.real_out_tx_key = get_tx_pub_key_from_extra(tx_4);
se.ms_keys_count = boost::get<txout_multisig>(tx_4.vout[se.real_output_in_tx_index].target).keys.size();
se.ms_keys_count = boost::get<txout_multisig>(boost::get<currency::tx_out_bare>(tx_4.vout[se.real_output_in_tx_index]).target).keys.size();
se.ms_sigs_count = 3;
transaction tx_5 = AUTO_VAL_INIT(tx_5);
@ -1020,7 +1023,7 @@ bool multisig_minimum_sigs::generate(std::vector<test_event_entry>& events) cons
se.multisig_id = ms_6_id;
se.real_output_in_tx_index = ms_6_out_idx;
se.real_out_tx_key = get_tx_pub_key_from_extra(tx_6);
se.ms_keys_count = boost::get<txout_multisig>(tx_6.vout[se.real_output_in_tx_index].target).keys.size();
se.ms_keys_count = boost::get<txout_multisig>(boost::get<currency::tx_out_bare>(tx_6.vout[se.real_output_in_tx_index]).target).keys.size();
se.ms_sigs_count = 4;
transaction tx_7 = AUTO_VAL_INIT(tx_7);
@ -1034,7 +1037,7 @@ bool multisig_minimum_sigs::generate(std::vector<test_event_entry>& events) cons
CHECK_AND_ASSERT_MES(r && !tx_fully_signed, false, "sign_multisig_input_in_tx failed, tx_fully_signed : " << tx_fully_signed);
r = sign_multisig_input_in_tx_custom(tx_7, ms_6_out_idx, miner_acc.get_keys(), tx_6, &tx_fully_signed, false);
CHECK_AND_ASSERT_MES(r && !tx_fully_signed, false, "sign_multisig_input_in_tx failed, tx_fully_signed : " << tx_fully_signed);
tx_7.signatures[0].push_back(invalid_signature); // instead of 4th sig just add invalid sig
boost::get<currency::NLSAG_sig>(tx_7.signature).s[0].push_back(invalid_signature); // instead of 4th sig just add invalid sig
DO_CALLBACK(events, "mark_invalid_tx");
events.push_back(tx_7);
@ -1062,7 +1065,7 @@ bool multisig_minimum_sigs::generate(std::vector<test_event_entry>& events) cons
se.multisig_id = ms_8_id;
se.real_output_in_tx_index = ms_8_out_idx;
se.real_out_tx_key = get_tx_pub_key_from_extra(tx_8);
se.ms_keys_count = boost::get<txout_multisig>(tx_8.vout[se.real_output_in_tx_index].target).keys.size();
se.ms_keys_count = boost::get<txout_multisig>(boost::get<currency::tx_out_bare>(tx_8.vout[se.real_output_in_tx_index]).target).keys.size();
static const size_t redundant_keys_count = 7000;
se.ms_sigs_count = redundant_keys_count;
@ -1070,7 +1073,7 @@ bool multisig_minimum_sigs::generate(std::vector<test_event_entry>& events) cons
r = construct_tx(miner_acc.get_keys(), std::vector<tx_source_entry>({ se }), std::vector<tx_destination_entry>({ tx_destination_entry(se.amount - TESTS_DEFAULT_FEE, alice_acc.get_public_address()) }), empty_attachment, tx_9, get_tx_version_from_events(events), 0);
CHECK_AND_ASSERT_MES(r, false, "construct_tx failed");
tx_9.signatures[0].resize(redundant_keys_count, invalid_signature);
boost::get<currency::NLSAG_sig>(tx_9.signature).s[0].resize(redundant_keys_count, invalid_signature);
r = sign_multisig_input_in_tx_custom(tx_9, ms_8_out_idx, bob_acc.get_keys(), tx_8, &tx_fully_signed, false);
CHECK_AND_ASSERT_MES(r && !tx_fully_signed, false, "sign_multisig_input_in_tx failed, tx_fully_signed : " << tx_fully_signed);
@ -1138,7 +1141,7 @@ bool multisig_and_fake_outputs::generate(std::vector<test_event_entry>& events)
// Second, correctly set up multisig part
tx_source_entry& se = sources.back();
se.multisig_id = tx_1_ms_out_id;
se.ms_keys_count = boost::get<txout_multisig>(tx_1.vout[tx_1_ms_out_idx].target).keys.size();
se.ms_keys_count = boost::get<txout_multisig>(boost::get<currency::tx_out_bare>(tx_1.vout[tx_1_ms_out_idx]).target).keys.size();
se.ms_sigs_count = 1;
se.real_output_in_tx_index = tx_1_ms_out_idx;
se.real_out_tx_key = get_tx_pub_key_from_extra(tx_1);
@ -1217,7 +1220,7 @@ bool multisig_and_unlock_time::generate(std::vector<test_event_entry>& events) c
se.multisig_id = tx_1_ms_out_id;
se.real_output_in_tx_index = tx_1_ms_out_idx;
se.real_out_tx_key = get_tx_pub_key_from_extra(tx_1);
se.ms_keys_count = boost::get<txout_multisig>(tx_1.vout[tx_1_ms_out_idx].target).keys.size();
se.ms_keys_count = boost::get<txout_multisig>(boost::get<currency::tx_out_bare>(tx_1.vout[tx_1_ms_out_idx]).target).keys.size();
se.ms_sigs_count = 1;
sources.assign({ se });
@ -1295,7 +1298,7 @@ bool multisig_and_unlock_time::generate(std::vector<test_event_entry>& events) c
se.multisig_id = tx_5_ms_out_id;
se.real_output_in_tx_index = tx_5_ms_out_idx;
se.real_out_tx_key = get_tx_pub_key_from_extra(tx_5);
se.ms_keys_count = boost::get<txout_multisig>(tx_5.vout[tx_5_ms_out_idx].target).keys.size();
se.ms_keys_count = boost::get<txout_multisig>(boost::get<currency::tx_out_bare>(tx_5.vout[tx_5_ms_out_idx]).target).keys.size();
se.ms_sigs_count = 1;
sources.assign({ se });
@ -1351,11 +1354,11 @@ bool multisig_and_coinbase::generate(std::vector<test_event_entry>& events) cons
crypto::public_key stake_tx_pub_key = get_tx_pub_key_from_extra(stake);
size_t stake_output_idx = 0;
size_t stake_output_gidx = 0;
uint64_t stake_output_amount = stake.vout[stake_output_idx].amount;
uint64_t stake_output_amount =boost::get<currency::tx_out_bare>( stake.vout[stake_output_idx]).amount;
crypto::key_image stake_output_key_image;
keypair kp;
generate_key_image_helper(miner_acc.get_keys(), stake_tx_pub_key, stake_output_idx, kp, stake_output_key_image);
crypto::public_key stake_output_pubkey = boost::get<txout_to_key>(stake.vout[stake_output_idx].target).key;
crypto::public_key stake_output_pubkey = boost::get<txout_to_key>(boost::get<currency::tx_out_bare>(stake.vout[stake_output_idx]).target).key;
keypair tx_key = keypair::generate();
pos_block_builder pb;
@ -1411,7 +1414,7 @@ bool multisig_and_coinbase::generate(std::vector<test_event_entry>& events) cons
se.multisig_id = get_multisig_out_id(blk_1.miner_tx, se.real_output_in_tx_index);
//se.participants.push_back(alice_acc.get_keys());
se.real_out_tx_key = get_tx_pub_key_from_extra(blk_1.miner_tx);
se.ms_keys_count = boost::get<txout_multisig>(blk_1.miner_tx.vout[se.real_output_in_tx_index].target).keys.size();
se.ms_keys_count = boost::get<txout_multisig>(boost::get<currency::tx_out_bare>(blk_1.miner_tx.vout[se.real_output_in_tx_index]).target).keys.size();
se.ms_sigs_count = 1;
sources.assign({ se });
@ -1457,9 +1460,9 @@ bool multisig_and_coinbase::generate(std::vector<test_event_entry>& events) cons
miner_tx.vin.assign({ in_gen });
// remove all outputs except the multisig
auto it = std::find_if(miner_tx.vout.begin(), miner_tx.vout.end(), [](const tx_out_bare& o) {return o.target.type() == typeid(txout_multisig); });
auto it = std::find_if(miner_tx.vout.begin(), miner_tx.vout.end(), [](const tx_out_v& o) {return boost::get<tx_out_bare>(o).target.type() == typeid(txout_multisig); });
CHECK_AND_ASSERT_MES(it != miner_tx.vout.end(), false, "construct_tx didn't create multisig output as expected");
tx_out_bare ms_out = *it;
tx_out_bare ms_out = boost::get<tx_out_bare>(*it);
miner_tx.vout.assign({ ms_out });
CHECK_AND_ASSERT_MES(ms_out.amount == blk_2_reward, false, "unexpected amount for found ms output");
@ -1477,7 +1480,7 @@ bool multisig_and_coinbase::generate(std::vector<test_event_entry>& events) cons
se.multisig_id = get_multisig_out_id(blk_3.miner_tx, 0);
se.real_output_in_tx_index = 0;
se.real_out_tx_key = get_tx_pub_key_from_extra(blk_3.miner_tx);
se.ms_keys_count= boost::get<txout_multisig>(blk_3.miner_tx.vout[se.real_output_in_tx_index].target).keys.size();
se.ms_keys_count= boost::get<txout_multisig>(boost::get<currency::tx_out_bare>(blk_3.miner_tx.vout[se.real_output_in_tx_index]).target).keys.size();
se.ms_sigs_count = 1;
transaction tx_2 = AUTO_VAL_INIT(tx_2);
@ -1582,7 +1585,7 @@ bool multisig_with_same_id_in_pool::generate(std::vector<test_event_entry>& even
se.multisig_id = tx_1_ms_id;
se.real_output_in_tx_index = get_tx_out_index_by_amount(tx_1, amount);
se.real_out_tx_key = get_tx_pub_key_from_extra(tx_1);
se.ms_keys_count = boost::get<txout_multisig>(tx_1.vout[se.real_output_in_tx_index].target).keys.size();
se.ms_keys_count = boost::get<txout_multisig>(boost::get<currency::tx_out_bare>(tx_1.vout[se.real_output_in_tx_index]).target).keys.size();
se.ms_sigs_count = 1;
tx_destination_entry de(amount - TESTS_DEFAULT_FEE, bob_acc.get_public_address());
@ -1693,7 +1696,7 @@ bool multisig_and_checkpoints::generate(std::vector<test_event_entry>& events) c
se.real_output_in_tx_index = get_tx_out_index_by_amount(tx_1, amount);
se.multisig_id = get_multisig_out_id(tx_1, se.real_output_in_tx_index);
se.real_out_tx_key = get_tx_pub_key_from_extra(tx_1);
se.ms_keys_count = boost::get<txout_multisig>(tx_1.vout[se.real_output_in_tx_index].target).keys.size();
se.ms_keys_count = boost::get<txout_multisig>(boost::get<currency::tx_out_bare>(tx_1.vout[se.real_output_in_tx_index]).target).keys.size();
se.ms_sigs_count = 1;
tx_destination_entry de(amount - TESTS_DEFAULT_FEE, bob_acc.get_public_address());
@ -1736,7 +1739,7 @@ bool multisig_and_checkpoints::generate(std::vector<test_event_entry>& events) c
se.real_output_in_tx_index = get_tx_out_index_by_amount(tx_3, amount);
se.multisig_id = get_multisig_out_id(tx_3, se.real_output_in_tx_index);
se.real_out_tx_key = get_tx_pub_key_from_extra(tx_3);
se.ms_keys_count = boost::get<txout_multisig>(tx_3.vout[se.real_output_in_tx_index].target).keys.size();
se.ms_keys_count = boost::get<txout_multisig>(boost::get<currency::tx_out_bare>(tx_3.vout[se.real_output_in_tx_index]).target).keys.size();
se.ms_sigs_count = 1;
de = tx_destination_entry(amount - TESTS_DEFAULT_FEE, bob_acc.get_public_address());
@ -1767,7 +1770,7 @@ bool multisig_and_checkpoints::generate(std::vector<test_event_entry>& events) c
se.real_output_in_tx_index = get_tx_out_index_by_amount(tx_5, amount);
se.multisig_id = get_multisig_out_id(tx_5, se.real_output_in_tx_index);
se.real_out_tx_key = get_tx_pub_key_from_extra(tx_5);
se.ms_keys_count = boost::get<txout_multisig>(tx_5.vout[se.real_output_in_tx_index].target).keys.size();
se.ms_keys_count = boost::get<txout_multisig>(boost::get<currency::tx_out_bare>(tx_5.vout[se.real_output_in_tx_index]).target).keys.size();
se.ms_sigs_count = 1;
de = tx_destination_entry(amount - TESTS_DEFAULT_FEE, bob_acc.get_public_address());
@ -1844,7 +1847,7 @@ bool multisig_and_checkpoints_bad_txs::generate(std::vector<test_event_entry>& e
transaction tx_2 = AUTO_VAL_INIT(tx_2);
r = make_tx_multisig_to_key(tx_1, get_tx_out_index_by_amount(tx_1, amount), std::list<account_keys>({ alice_acc.get_keys() }), bob_acc.get_public_address(), tx_2);
CHECK_AND_ASSERT_MES(r, false, "make_tx_multisig_to_key failed");
tx_2.signatures.resize(10);
boost::get<currency::NLSAG_sig>(tx_2.signature).s.resize(10);
boost::get<txin_multisig>(tx_2.vin[0]).sigs_count = 10;
DO_CALLBACK(events, "mark_invalid_tx");
@ -1860,7 +1863,7 @@ bool multisig_and_checkpoints_bad_txs::generate(std::vector<test_event_entry>& e
transaction tx_3 = AUTO_VAL_INIT(tx_3);
r = make_tx_multisig_to_key(tx_1, get_tx_out_index_by_amount(tx_1, amount), std::list<account_keys>({ alice_acc.get_keys() }), bob_acc.get_public_address(), tx_3);
CHECK_AND_ASSERT_MES(r, false, "make_tx_multisig_to_key failed");
tx_3.signatures.clear();
boost::get<currency::NLSAG_sig>(tx_3.signature).s.clear();
boost::get<txin_multisig>(tx_3.vin[0]).sigs_count = 0;
events.push_back(event_visitor_settings(event_visitor_settings::set_txs_kept_by_block, true));
@ -1874,7 +1877,7 @@ bool multisig_and_checkpoints_bad_txs::generate(std::vector<test_event_entry>& e
txb.step1_init();
txb.step2_fill_inputs(miner_acc.get_keys(), sources);
txb.step3_fill_outputs(destinations, 0, 1);
boost::get<txout_multisig>(txb.m_tx.vout[0].target).keys.clear(); // zero keys
boost::get<txout_multisig>(boost::get<currency::tx_out_bare>(txb.m_tx.vout[0]).target).keys.clear(); // zero keys
txb.step4_calc_hash();
txb.step5_sign(sources);
transaction tx_4 = txb.m_tx;
@ -1888,11 +1891,11 @@ bool multisig_and_checkpoints_bad_txs::generate(std::vector<test_event_entry>& e
txb.step1_init();
txb.step2_fill_inputs(miner_acc.get_keys(), sources);
txb.step3_fill_outputs(destinations, 0, 1);
crypto::public_key k = boost::get<txout_multisig>(txb.m_tx.vout[0].target).keys[0];
boost::get<txout_multisig>(txb.m_tx.vout[0].target).keys.resize(1500, k);
crypto::public_key k = boost::get<txout_multisig>(boost::get<currency::tx_out_bare>(txb.m_tx.vout[0]).target).keys[0];
boost::get<txout_multisig>(boost::get<currency::tx_out_bare>(txb.m_tx.vout[0]).target).keys.resize(1500, k);
txb.step4_calc_hash();
txb.step5_sign(sources);
txb.m_tx.signatures.clear();
boost::get<currency::NLSAG_sig>(txb.m_tx.signature).s.clear();
transaction tx_6 = txb.m_tx;
events.push_back(event_visitor_settings(event_visitor_settings::set_txs_kept_by_block, true));
events.push_back(tx_6);
@ -2113,7 +2116,7 @@ bool ref_by_id_basics::generate(std::vector<test_event_entry>& events) const
r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx_1, 0, CURRENCY_TO_KEY_OUT_RELAXED, true);
CHECK_AND_ASSERT_MES(r, false, "construct_tx");
r = check_ring_signature_at_gen_time(events, get_block_hash(blk_0r), boost::get<txin_to_key>(tx_1.vin[0]), get_transaction_hash(tx_1), tx_1.signatures[0]);
r = check_ring_signature_at_gen_time(events, get_block_hash(blk_0r), boost::get<txin_to_key>(tx_1.vin[0]), get_transaction_hash(tx_1), boost::get<currency::NLSAG_sig>(tx_1.signature).s[0]);
CHECK_AND_ASSERT_MES(r, false, "check_ring_signature_at_gen_time failed");
events.push_back(tx_1);
@ -2262,7 +2265,7 @@ bool multisig_n_participants_seq_signing::generate(std::vector<test_event_entry>
size_t ms_out_index = get_multisig_out_index(tx_1.vout);
CHECK_AND_ASSERT_MES(ms_out_index != tx_1.vout.size(), false, "Can't find ms out index in tx_1");
tx_source_entry se = AUTO_VAL_INIT(se);
se.amount = tx_1.vout[ms_out_index].amount;
se.amount =boost::get<currency::tx_out_bare>( tx_1.vout[ms_out_index]).amount;
se.multisig_id = get_multisig_out_id(tx_1, ms_out_index);
se.ms_sigs_count = m_minimum_signs_to_spend;
// se.outputs -- not used for ms-outs
@ -2270,7 +2273,7 @@ bool multisig_n_participants_seq_signing::generate(std::vector<test_event_entry>
se.real_output_in_tx_index = ms_out_index;
se.real_out_tx_key = get_tx_pub_key_from_extra(tx_1);
// se.separately_signed_tx_complete -- not a separately-signed tx
se.ms_keys_count = boost::get<txout_multisig>(tx_1.vout[ms_out_index].target).keys.size();
se.ms_keys_count = boost::get<txout_multisig>(boost::get<currency::tx_out_bare>(tx_1.vout[ms_out_index]).target).keys.size();
sources.push_back(se);
tx_destination_entry de(ms_amount - TESTS_DEFAULT_FEE, alice_acc.get_public_address());

View file

@ -173,7 +173,7 @@ void pos_block_builder::step5_sign(const crypto::public_key& stake_tx_pub_key, s
// sign block actually in coinbase transaction
crypto::hash block_hash = currency::get_block_hash(m_block);
std::vector<const crypto::public_key*> keys_ptrs(1, &stake_tx_out_pub_key);
crypto::generate_ring_signature(block_hash, m_stake_kernel.kimage, keys_ptrs, derived_secret_ephemeral_key, 0, &m_block.miner_tx.signatures[0][0]);
crypto::generate_ring_signature(block_hash, m_stake_kernel.kimage, keys_ptrs, derived_secret_ephemeral_key, 0, &boost::get<currency::NLSAG_sig>(m_block.miner_tx.signature).s[0][0]);
m_step = 5;
}
@ -272,8 +272,8 @@ bool construct_homemade_pos_miner_tx(size_t height, size_t median_size, const bo
posin.k_image = pos_stake_keyimage;
tx.vin.push_back(posin);
//reserve place for ring signature
tx.signatures.resize(1);
tx.signatures[0].resize(posin.key_offsets.size());
boost::get<currency::NLSAG_sig>(tx.signature).s.resize(1);
boost::get<currency::NLSAG_sig>(tx.signature).s[0].resize(posin.key_offsets.size());
return true;
}
@ -298,11 +298,11 @@ bool mine_next_pos_block_in_playtime_sign_cb(currency::core& c, const currency::
crypto::public_key stake_tx_pub_key = get_tx_pub_key_from_extra(stake);
size_t stake_output_idx = 0;
size_t stake_output_gidx = 0;
uint64_t stake_output_amount = stake.vout[stake_output_idx].amount;
uint64_t stake_output_amount =boost::get<currency::tx_out_bare>( stake.vout[stake_output_idx]).amount;
crypto::key_image stake_output_key_image;
keypair kp;
generate_key_image_helper(acc.get_keys(), stake_tx_pub_key, stake_output_idx, kp, stake_output_key_image);
crypto::public_key stake_output_pubkey = boost::get<txout_to_key>(stake.vout[stake_output_idx].target).key;
crypto::public_key stake_output_pubkey = boost::get<txout_to_key>(boost::get<currency::tx_out_bare>(stake.vout[stake_output_idx]).target).key;
pos_block_builder pb;
pb.step1_init_header(height, prev_id);

View file

@ -71,11 +71,11 @@ bool gen_pos_coinstake_already_spent::generate(std::vector<test_event_entry>& ev
uint64_t stake_output_gidx = 0;
bool r = find_global_index_for_output(events, prev_id, stake, stake_output_idx, stake_output_gidx);
CHECK_AND_ASSERT_MES(r, false, "find_global_index_for_output failed");
uint64_t stake_output_amount = stake.vout[stake_output_idx].amount;
uint64_t stake_output_amount =boost::get<currency::tx_out_bare>( stake.vout[stake_output_idx]).amount;
crypto::key_image stake_output_key_image;
keypair kp;
generate_key_image_helper(miner.get_keys(), stake_tx_pub_key, stake_output_idx, kp, stake_output_key_image);
crypto::public_key stake_output_pubkey = boost::get<txout_to_key>(stake.vout[stake_output_idx].target).key;
crypto::public_key stake_output_pubkey = boost::get<txout_to_key>(boost::get<currency::tx_out_bare>(stake.vout[stake_output_idx]).target).key;
pos_block_builder pb;
pb.step1_init_header(height, prev_id);
@ -122,11 +122,11 @@ bool gen_pos_incorrect_timestamp::generate(std::vector<test_event_entry>& events
crypto::public_key stake_tx_pub_key = get_tx_pub_key_from_extra(stake);
size_t stake_output_idx = 0;
size_t stake_output_gidx = 0;
uint64_t stake_output_amount = stake.vout[stake_output_idx].amount;
uint64_t stake_output_amount =boost::get<currency::tx_out_bare>( stake.vout[stake_output_idx]).amount;
crypto::key_image stake_output_key_image;
keypair kp;
generate_key_image_helper(miner.get_keys(), stake_tx_pub_key, stake_output_idx, kp, stake_output_key_image);
crypto::public_key stake_output_pubkey = boost::get<txout_to_key>(stake.vout[stake_output_idx].target).key;
crypto::public_key stake_output_pubkey = boost::get<txout_to_key>(boost::get<currency::tx_out_bare>(stake.vout[stake_output_idx]).target).key;
pos_block_builder pb;
pb.step1_init_header(height, prev_id);
@ -239,11 +239,11 @@ bool gen_pos_extra_nonce::generate(std::vector<test_event_entry>& events) const
crypto::public_key stake_tx_pub_key = get_tx_pub_key_from_extra(stake);
size_t stake_output_idx = 0;
size_t stake_output_gidx = 0;
uint64_t stake_output_amount = stake.vout[stake_output_idx].amount;
uint64_t stake_output_amount =boost::get<currency::tx_out_bare>( stake.vout[stake_output_idx]).amount;
crypto::key_image stake_output_key_image;
keypair kp;
generate_key_image_helper(miner.get_keys(), stake_tx_pub_key, stake_output_idx, kp, stake_output_key_image);
crypto::public_key stake_output_pubkey = boost::get<txout_to_key>(stake.vout[stake_output_idx].target).key;
crypto::public_key stake_output_pubkey = boost::get<txout_to_key>(boost::get<currency::tx_out_bare>(stake.vout[stake_output_idx]).target).key;
pos_block_builder pb;
pb.step1_init_header(height, prev_id);
@ -293,11 +293,11 @@ bool gen_pos_min_allowed_height::generate(std::vector<test_event_entry>& events)
crypto::public_key stake_tx_pub_key = get_tx_pub_key_from_extra(stake);
size_t stake_output_idx = 0;
size_t stake_output_gidx = 0;
uint64_t stake_output_amount = stake.vout[stake_output_idx].amount;
uint64_t stake_output_amount =boost::get<currency::tx_out_bare>( stake.vout[stake_output_idx]).amount;
crypto::key_image stake_output_key_image;
keypair kp;
generate_key_image_helper(miner.get_keys(), stake_tx_pub_key, stake_output_idx, kp, stake_output_key_image);
crypto::public_key stake_output_pubkey = boost::get<txout_to_key>(stake.vout[stake_output_idx].target).key;
crypto::public_key stake_output_pubkey = boost::get<txout_to_key>(boost::get<currency::tx_out_bare>(stake.vout[stake_output_idx]).target).key;
pos_block_builder pb;
pb.step1_init_header(height, prev_id);
@ -345,11 +345,11 @@ bool gen_pos_invalid_coinbase::generate(std::vector<test_event_entry>& events) c
crypto::public_key stake_tx_pub_key = get_tx_pub_key_from_extra(stake);
size_t stake_output_idx = 0;
size_t stake_output_gidx = 0;
uint64_t stake_output_amount = stake.vout[stake_output_idx].amount;
uint64_t stake_output_amount =boost::get<currency::tx_out_bare>( stake.vout[stake_output_idx]).amount;
crypto::key_image stake_output_key_image;
keypair kp;
generate_key_image_helper(miner_acc.get_keys(), stake_tx_pub_key, stake_output_idx, kp, stake_output_key_image);
crypto::public_key stake_output_pubkey = boost::get<txout_to_key>(stake.vout[stake_output_idx].target).key;
crypto::public_key stake_output_pubkey = boost::get<txout_to_key>(boost::get<currency::tx_out_bare>(stake.vout[stake_output_idx]).target).key;
pos_block_builder pb;
pb.step1_init_header(height, prev_id);
@ -358,7 +358,7 @@ bool gen_pos_invalid_coinbase::generate(std::vector<test_event_entry>& events) c
pb.step4_generate_coinbase_tx(generator.get_timestamps_median(prev_id), generator.get_already_generated_coins(prev_block), alice_acc.get_public_address());
pb.step5_sign(stake_tx_pub_key, stake_output_idx, stake_output_pubkey, miner_acc);
pb.m_block.miner_tx.signatures.clear(); // remove signatures
boost::get<currency::NLSAG_sig>(pb.m_block.miner_tx.signature).s.clear(); // remove signatures
block blk_1 = pb.m_block;
@ -881,7 +881,7 @@ bool pos_altblocks_validation::generate(std::vector<test_event_entry>& events) c
// select stake_tx_out_id as an output with the biggest amount
for (size_t i = 1; i < stake_tx.vout.size(); ++i)
{
if (stake_tx.vout[i].amount > stake_tx.vout[stake_tx_out_id].amount)
if (boost::get<currency::tx_out_bare>(stake_tx.vout[i]).amount >boost::get<currency::tx_out_bare>( stake_tx.vout[stake_tx_out_id]).amount)
stake_tx_out_id = i;
}

View file

@ -25,8 +25,8 @@ struct ev_visitor : public boost::static_visitor<bool>
{
size_t real_bloc_size = t_serializable_object_to_blob(t).size();
std::cout << "prunging sigs: " << t.signatures.size() << ENDL;
t.signatures.clear();
std::cout << "prunging sigs: " << boost::get<currency::NLSAG_sig>(t.signature).s.size() << ENDL;
boost::get<currency::NLSAG_sig>(t.signature).s.clear();
//check tx pruning correctnes
if (real_bloc_size != get_object_blobsize(t))

View file

@ -61,27 +61,27 @@ bool test_transaction_generation_and_ring_signature()
{
tx_output_entry oe;
oe.first = 0;
oe.second = boost::get<txout_to_key>(tx_mine_1.vout[0].target).key;
oe.second = boost::get<txout_to_key>(boost::get<currency::tx_out_bare>(tx_mine_1.vout[0]).target).key;
src.outputs.push_back(oe);
oe.first = 1;
oe.second = boost::get<txout_to_key>(tx_mine_2.vout[0].target).key;
oe.second = boost::get<txout_to_key>(boost::get<currency::tx_out_bare>(tx_mine_2.vout[0]).target).key;
src.outputs.push_back(oe);
oe.first = 2;
oe.second = boost::get<txout_to_key>(tx_mine_3.vout[0].target).key;
oe.second = boost::get<txout_to_key>(boost::get<currency::tx_out_bare>(tx_mine_3.vout[0]).target).key;
src.outputs.push_back(oe);
oe.first = 3;
oe.second = boost::get<txout_to_key>(tx_mine_4.vout[0].target).key;
oe.second = boost::get<txout_to_key>(boost::get<currency::tx_out_bare>(tx_mine_4.vout[0]).target).key;
src.outputs.push_back(oe);
oe.first = 4;
oe.second = boost::get<txout_to_key>(tx_mine_5.vout[0].target).key;
oe.second = boost::get<txout_to_key>(boost::get<currency::tx_out_bare>(tx_mine_5.vout[0]).target).key;
src.outputs.push_back(oe);
oe.first = 5;
oe.second = boost::get<txout_to_key>(tx_mine_6.vout[0].target).key;
oe.second = boost::get<txout_to_key>(boost::get<currency::tx_out_bare>(tx_mine_6.vout[0]).target).key;
src.outputs.push_back(oe);
crypto::public_key tx_pub_key = null_pkey;
@ -104,13 +104,13 @@ bool test_transaction_generation_and_ring_signature()
crypto::hash pref_hash = get_transaction_prefix_hash(tx_rc1);
std::vector<const crypto::public_key *> output_keys;
output_keys.push_back(&boost::get<txout_to_key>(tx_mine_1.vout[0].target).key);
output_keys.push_back(&boost::get<txout_to_key>(tx_mine_2.vout[0].target).key);
output_keys.push_back(&boost::get<txout_to_key>(tx_mine_3.vout[0].target).key);
output_keys.push_back(&boost::get<txout_to_key>(tx_mine_4.vout[0].target).key);
output_keys.push_back(&boost::get<txout_to_key>(tx_mine_5.vout[0].target).key);
output_keys.push_back(&boost::get<txout_to_key>(tx_mine_6.vout[0].target).key);
r = crypto::check_ring_signature(pref_hash, boost::get<txin_to_key>(tx_rc1.vin[0]).k_image, output_keys, &tx_rc1.signatures[0][0]);
output_keys.push_back(&boost::get<txout_to_key>(boost::get<currency::tx_out_bare>(tx_mine_1.vout[0]).target).key);
output_keys.push_back(&boost::get<txout_to_key>(boost::get<currency::tx_out_bare>(tx_mine_2.vout[0]).target).key);
output_keys.push_back(&boost::get<txout_to_key>(boost::get<currency::tx_out_bare>(tx_mine_3.vout[0]).target).key);
output_keys.push_back(&boost::get<txout_to_key>(boost::get<currency::tx_out_bare>(tx_mine_4.vout[0]).target).key);
output_keys.push_back(&boost::get<txout_to_key>(boost::get<currency::tx_out_bare>(tx_mine_5.vout[0]).target).key);
output_keys.push_back(&boost::get<txout_to_key>(boost::get<currency::tx_out_bare>(tx_mine_6.vout[0]).target).key);
r = crypto::check_ring_signature(pref_hash, boost::get<txin_to_key>(tx_rc1.vin[0]).k_image, output_keys, &boost::get<currency::NLSAG_sig>(tx_rc1.signature).s[0][0]);
CHECK_AND_ASSERT_MES(r, false, "failed to check ring signature");
std::vector<size_t> outs;

View file

@ -98,7 +98,7 @@ struct tx_builder
void step5_sign(const std::vector<currency::tx_source_entry>& sources)
{
m_tx.signatures.clear();
boost::get<currency::NLSAG_sig>(m_tx.signature).s.clear();
size_t i = 0;
for(const currency::tx_source_entry& src_entr : sources)
@ -109,8 +109,8 @@ struct tx_builder
keys_ptrs.push_back(&o.second);
}
m_tx.signatures.push_back(std::vector<crypto::signature>());
std::vector<crypto::signature>& sigs = m_tx.signatures.back();
boost::get<currency::NLSAG_sig>(m_tx.signature).s.push_back(std::vector<crypto::signature>());
std::vector<crypto::signature>& sigs = boost::get<currency::NLSAG_sig>(m_tx.signature).s.back();
sigs.resize(src_entr.outputs.size());
generate_ring_signature(m_tx_prefix_hash, boost::get<currency::txin_to_key>(m_tx.vin[i]).k_image, keys_ptrs, m_in_contexts[i].sec, src_entr.real_output, sigs.data());
i++;

View file

@ -370,9 +370,9 @@ bool gen_tx_key_image_not_derive_from_tx_key::generate(std::vector<test_event_en
builder.step4_calc_hash();
// Tx with invalid key image can't be subscribed, so create empty signature
builder.m_tx.signatures.resize(1);
builder.m_tx.signatures[0].resize(1);
builder.m_tx.signatures[0][0] = boost::value_initialized<crypto::signature>();
boost::get<currency::NLSAG_sig>(builder.m_tx.signature).s.resize(1);
boost::get<currency::NLSAG_sig>(builder.m_tx.signature).s[0].resize(1);
boost::get<currency::NLSAG_sig>(builder.m_tx.signature).s[0][0] = boost::value_initialized<crypto::signature>();
DO_CALLBACK(events, "mark_invalid_tx");
events.push_back(builder.m_tx);
@ -404,9 +404,9 @@ bool gen_tx_key_image_is_invalid::generate(std::vector<test_event_entry>& events
builder.step4_calc_hash();
// Tx with invalid key image can't be subscribed, so create empty signature
builder.m_tx.signatures.resize(1);
builder.m_tx.signatures[0].resize(1);
builder.m_tx.signatures[0][0] = boost::value_initialized<crypto::signature>();
boost::get<currency::NLSAG_sig>(builder.m_tx.signature).s.resize(1);
boost::get<currency::NLSAG_sig>(builder.m_tx.signature).s[0].resize(1);
boost::get<currency::NLSAG_sig>(builder.m_tx.signature).s[0][0] = boost::value_initialized<crypto::signature>();
DO_CALLBACK(events, "mark_invalid_tx");
events.push_back(builder.m_tx);
@ -494,7 +494,7 @@ bool gen_tx_txout_to_key_has_invalid_key::generate(std::vector<test_event_entry>
builder.step2_fill_inputs(miner_account.get_keys(), sources);
builder.step3_fill_outputs(destinations);
txout_to_key& out_to_key = boost::get<txout_to_key>(builder.m_tx.vout.front().target);
txout_to_key& out_to_key = boost::get<txout_to_key>(boost::get<tx_out_bare>(builder.m_tx.vout.front()).target);
out_to_key.key = tx_builder::generate_invalid_pub_key();
builder.step4_calc_hash();
@ -523,7 +523,7 @@ bool gen_tx_output_with_zero_amount::generate(std::vector<test_event_entry>& eve
builder.step2_fill_inputs(miner_account.get_keys(), sources);
builder.step3_fill_outputs(destinations);
builder.m_tx.vout.front().amount = 0;
boost::get<tx_out_bare>(builder.m_tx.vout.front()).amount = 0;
builder.step4_calc_hash();
builder.step5_sign(sources);
@ -633,62 +633,62 @@ bool gen_tx_signatures_are_invalid::generate(std::vector<test_event_entry>& even
// create reference transaction tx_0, Carol->Alice, nmix=0
MAKE_TX(events, tx_0, carol_account, alice_account, amount, blk_1r_f);
events.pop_back();
CHECK_AND_ASSERT_MES(tx_0.vin.size() > 1 && tx_0.vout.size() > 1 && tx_0.signatures.size() > 1, false, "tx_0 is incorrect"); // need > 1 for this test
CHECK_AND_ASSERT_MES(tx_0.vin.size() > 1 && tx_0.vout.size() > 1 && boost::get<currency::NLSAG_sig>(tx_0.signature).s.size() > 1, false, "tx_0 is incorrect"); // need > 1 for this test
// create reference transaction tx_1, Dan->Alice, nmix=1
MAKE_TX_MIX(events, tx_1, dan_account, alice_account, amount, 1, blk_1r_f);
events.pop_back();
CHECK_AND_ASSERT_MES(tx_1.vin.size() > 1 && tx_1.vout.size() > 1 && tx_1.signatures.size() > 1, false, "tx_1 is incorrect"); // need > 1 for this test
CHECK_AND_ASSERT_MES(tx_1.vin.size() > 1 && tx_1.vout.size() > 1 && boost::get<currency::NLSAG_sig>(tx_1.signature).s.size() > 1, false, "tx_1 is incorrect"); // need > 1 for this test
const block& prev_block = blk_1r_f;
transaction broken_tx;
// Tx with nmix = 0 without signatures
broken_tx = tx_0;
broken_tx.signatures.clear();
boost::get<currency::NLSAG_sig>(broken_tx.signature).s.clear();
check_broken_tx(events, broken_tx, prev_block, miner_account, generator);
// Tx with nmix = 0 have a few inputs, and not enough signatures
broken_tx = tx_0;
broken_tx.signatures.resize(broken_tx.signatures.size() - 1);
boost::get<currency::NLSAG_sig>(broken_tx.signature).s.resize(boost::get<currency::NLSAG_sig>(broken_tx.signature).s.size() - 1);
check_broken_tx(events, broken_tx, prev_block, miner_account, generator);
// Tx with nmix = 0 have a few inputs, and too many signatures (1/2)
broken_tx = tx_0;
broken_tx.signatures.back().push_back(invalid_signature);
boost::get<currency::NLSAG_sig>(broken_tx.signature).s.back().push_back(invalid_signature);
check_broken_tx(events, broken_tx, prev_block, miner_account, generator);
// Tx with nmix = 0 have a few inputs, and too many signatures (2/2)
broken_tx = tx_0;
broken_tx.signatures.push_back(std::vector<crypto::signature>());
broken_tx.signatures.back().push_back(invalid_signature);
boost::get<currency::NLSAG_sig>(broken_tx.signature).s.push_back(std::vector<crypto::signature>());
boost::get<currency::NLSAG_sig>(broken_tx.signature).s.back().push_back(invalid_signature);
check_broken_tx(events, broken_tx, prev_block, miner_account, generator);
// Tx with nmix = 1 without signatures
broken_tx = tx_1;
broken_tx.signatures.clear();
boost::get<currency::NLSAG_sig>(broken_tx.signature).s.clear();
check_broken_tx(events, broken_tx, prev_block, miner_account, generator);
// Tx with nmix = 1 have not enough signatures (1/2)
broken_tx = tx_1;
broken_tx.signatures.resize(broken_tx.signatures.size() - 1);
boost::get<currency::NLSAG_sig>(broken_tx.signature).s.resize(boost::get<currency::NLSAG_sig>(broken_tx.signature).s.size() - 1);
check_broken_tx(events, broken_tx, prev_block, miner_account, generator);
// Tx with nmix = 1 have not enough signatures (2/2)
broken_tx = tx_1;
broken_tx.signatures.back().resize(broken_tx.signatures.back().size() - 1);
boost::get<currency::NLSAG_sig>(broken_tx.signature).s.back().resize(boost::get<currency::NLSAG_sig>(broken_tx.signature).s.back().size() - 1);
check_broken_tx(events, broken_tx, prev_block, miner_account, generator);
// Tx with nmix = 1 have too many signatures (1/2)
broken_tx = tx_1;
broken_tx.signatures.back().push_back(invalid_signature);
boost::get<currency::NLSAG_sig>(broken_tx.signature).s.back().push_back(invalid_signature);
check_broken_tx(events, broken_tx, prev_block, miner_account, generator);
// Tx with nmix = 1 have too many signatures (2/2)
broken_tx = tx_1;
broken_tx.signatures.push_back(std::vector<crypto::signature>());
broken_tx.signatures.back().push_back(invalid_signature);
boost::get<currency::NLSAG_sig>(broken_tx.signature).s.push_back(std::vector<crypto::signature>());
boost::get<currency::NLSAG_sig>(broken_tx.signature).s.back().push_back(invalid_signature);
check_broken_tx(events, broken_tx, prev_block, miner_account, generator);

View file

@ -21,7 +21,7 @@ const std::wstring g_wallet_filename = L"~coretests.wallet.file.tmp";
const std::string g_wallet_password = "dofatibmzibeziyekigo";
const currency::account_base null_account = AUTO_VAL_INIT(null_account);
//@#@: TODO: need refactoring, unsafe operations
POD_MAKE_COMPARABLE(currency, tx_out_bare);
// Determines which output is real and actually spent in tx inputs, when there are fake outputs.
@ -39,7 +39,8 @@ bool determine_tx_real_inputs(currency::core& c, const currency::transaction& tx
bool handle_output(const transaction& source_tx, const transaction& validated_tx, const tx_out_bare& out, uint64_t out_i)
{
CHECK_AND_ASSERT_MES(!m_found, false, "Internal error: m_found is true but the visitor is still being applied");
auto it = std::find(validated_tx.vout.begin(), validated_tx.vout.end(), out);
auto is_even = [&](const tx_out_v& v) { return boost::get<tx_out_bare>(v) == out; };
auto it = std::find_if(validated_tx.vout.begin(), validated_tx.vout.end(), is_even);
if (it == validated_tx.vout.end())
return false;
size_t output_tx_index = it - validated_tx.vout.begin();

View file

@ -196,7 +196,7 @@ uint64_t got_money_in_first_transfers(const tools::wallet2::transfer_container&
size_t count = 0;
BOOST_FOREACH(const tools::wallet2::transfer_details& td, incoming_transfers)
{
summ += td.m_ptx_wallet_info->m_tx.vout[td.m_internal_output_index].amount;
summ += boost::get<tx_out_bare>(td.m_ptx_wallet_info->m_tx.vout[td.m_internal_output_index]).amount;
if(++count >= n_transfers)
return summ;
}
@ -459,9 +459,9 @@ bool transactions_flow_test(
++count;
currency::transaction tx_s;
if (w1.unlocked_balance() >= td.m_ptx_wallet_info->m_tx.vout[td.m_internal_output_index].amount)
if (w1.unlocked_balance() >= boost::get<tx_out_bare>(td.m_ptx_wallet_info->m_tx.vout[td.m_internal_output_index]).amount)
{
bool r = do_send_money_by_fractions(w1, w1, 0, td.m_ptx_wallet_info->m_tx.vout[td.m_internal_output_index].amount - TX_DEFAULT_FEE, tx_s, transfer_size);
bool r = do_send_money_by_fractions(w1, w1, 0, boost::get<tx_out_bare>(td.m_ptx_wallet_info->m_tx.vout[td.m_internal_output_index]).amount - TX_DEFAULT_FEE, tx_s, transfer_size);
CHECK_AND_ASSERT_MES(r, false, "Failed to send starter tx " << get_transaction_hash(tx_s));
}
else

View file

@ -47,7 +47,7 @@ public:
bool test()
{
const currency::txin_to_key& txin = boost::get<currency::txin_to_key>(m_tx.vin[0]);
return crypto::check_ring_signature(m_tx_prefix_hash, txin.k_image, this->m_public_key_ptrs, ring_size, m_tx.signatures[0].data());
return crypto::check_ring_signature(m_tx_prefix_hash, txin.k_image, this->m_public_key_ptrs, ring_size, boost::get<NLSAG_sig>(m_tx.signature)[0].data());
}
private:

View file

@ -17,7 +17,7 @@ public:
bool test()
{
const currency::txout_to_key& tx_out = boost::get<currency::txout_to_key>(m_tx.vout[0].target);
const currency::txout_to_key& tx_out = boost::get<currency::txout_to_key>(boost::get<tx_out_bare>(m_tx.vout[0]).target);
return currency::is_out_to_acc(m_bob.get_keys(), tx_out, m_tx_pub_key, 0);
}
};

View file

@ -32,13 +32,13 @@ public:
if (!construct_miner_tx(0, 0, 0, 2, 0, m_miners[i].get_keys().m_account_address, m_miner_txs[i], TRANSACTION_VERSION_PRE_HF4))
return false;
txout_to_key tx_out = boost::get<txout_to_key>(m_miner_txs[i].vout[0].target);
txout_to_key tx_out = boost::get<txout_to_key>(boost::get<tx_out_bare>(m_miner_txs[i].vout[0]).target);
output_entries.push_back(make_serializable_pair<txout_ref_v, crypto::public_key>(i, tx_out.key));
m_public_keys[i] = tx_out.key;
m_public_key_ptrs[i] = &m_public_keys[i];
}
m_source_amount = m_miner_txs[0].vout[0].amount;
m_source_amount = boost::get<tx_out_bare>(m_miner_txs[0].vout[0]).amount;
tx_source_entry source_entry;
source_entry.amount = m_source_amount;

View file

@ -330,7 +330,7 @@ TEST(Serialization, serializes_transacion_signatures_correctly)
ASSERT_TRUE(false);
}
ASSERT_EQ(linearize_vector2(tx.signatures), linearize_vector2(tx1.signatures));
ASSERT_EQ(linearize_vector2(boost::get<currency::NLSAG_sig>(tx.signature).s), linearize_vector2(boost::get<currency::NLSAG_sig>(tx1.signature).s));
// Miner tx without signatures
txin_gen txin_gen1;
@ -344,10 +344,10 @@ TEST(Serialization, serializes_transacion_signatures_correctly)
{
ASSERT_TRUE(false);
}
ASSERT_EQ(linearize_vector2(tx.signatures), linearize_vector2(tx1.signatures));
ASSERT_EQ(linearize_vector2(boost::get<currency::NLSAG_sig>(tx.signature).s), linearize_vector2(boost::get<currency::NLSAG_sig>(tx1.signature).s));
// Miner tx with empty signatures 2nd vector
tx.signatures.resize(1);
boost::get<currency::NLSAG_sig>(tx.signature).s.resize(1);
ASSERT_TRUE(serialization::dump_binary(tx, blob));
ASSERT_EQ(9, blob.size()); // 5 bytes + 2 bytes vin[0] + 0 bytes extra + 0 bytes signatures + counter
ASSERT_TRUE(serialization::parse_binary(blob, tx1));
@ -355,29 +355,29 @@ TEST(Serialization, serializes_transacion_signatures_correctly)
{
ASSERT_TRUE(false);
}
ASSERT_EQ(linearize_vector2(tx.signatures), linearize_vector2(tx1.signatures));
ASSERT_EQ(linearize_vector2(boost::get<currency::NLSAG_sig>(tx.signature).s), linearize_vector2(boost::get<currency::NLSAG_sig>(tx1.signature).s));
//TX VALIDATION REMOVED FROM SERIALIZATION
/*
// Miner tx with one signature
tx.signatures[0].resize(1);
boost::get<currency::NLSAG_sig>(tx.signature).s[0].resize(1);
ASSERT_FALSE(serialization::dump_binary(tx, blob));
// Miner tx with 2 empty vectors
tx.signatures.resize(2);
tx.signatures[0].resize(0);
tx.signatures[1].resize(0);
boost::get<currency::NLSAG_sig>(tx.signature).s.resize(2);
boost::get<currency::NLSAG_sig>(tx.signature).s[0].resize(0);
boost::get<currency::NLSAG_sig>(tx.signature).s[1].resize(0);
ASSERT_FALSE(serialization::dump_binary(tx, blob));
// Miner tx with 2 signatures
tx.signatures[0].resize(1);
tx.signatures[1].resize(1);
boost::get<currency::NLSAG_sig>(tx.signature).s[0].resize(1);
boost::get<currency::NLSAG_sig>(tx.signature).s[1].resize(1);
ASSERT_FALSE(serialization::dump_binary(tx, blob));
*/
// Two txin_gen, no signatures
tx.vin.push_back(txin_gen1);
tx.signatures.resize(0);
boost::get<currency::NLSAG_sig>(tx.signature).s.resize(0);
ASSERT_TRUE(serialization::dump_binary(tx, blob));
ASSERT_EQ(10, blob.size()); // 5 bytes + 2 * 2 bytes vins + 0 bytes extra + 0 bytes signatures
ASSERT_TRUE(serialization::parse_binary(blob, tx1));
@ -385,14 +385,14 @@ TEST(Serialization, serializes_transacion_signatures_correctly)
{
ASSERT_TRUE(false);
}
ASSERT_EQ(linearize_vector2(tx.signatures), linearize_vector2(tx1.signatures));
ASSERT_EQ(linearize_vector2(boost::get<currency::NLSAG_sig>(tx.signature).s), linearize_vector2(boost::get<currency::NLSAG_sig>(tx1.signature).s));
// Two txin_gen, signatures vector contains only one empty element
//tx.signatures.resize(1);
//signatures.resize(1);
//ASSERT_FALSE(serialization::dump_binary(tx, blob));
// Two txin_gen, signatures vector contains two empty elements
tx.signatures.resize(2);
boost::get<currency::NLSAG_sig>(tx.signature).s.resize(2);
ASSERT_TRUE(serialization::dump_binary(tx, blob));
ASSERT_EQ(12, blob.size()); // 5 bytes + 2 * 2 bytes vins + 0 bytes extra + 0 bytes signatures
ASSERT_TRUE(serialization::parse_binary(blob, tx1));
@ -400,22 +400,22 @@ TEST(Serialization, serializes_transacion_signatures_correctly)
{
ASSERT_TRUE(false);
}
ASSERT_EQ(linearize_vector2(tx.signatures), linearize_vector2(tx1.signatures));
ASSERT_EQ(linearize_vector2(boost::get<currency::NLSAG_sig>(tx.signature).s), linearize_vector2(boost::get<currency::NLSAG_sig>(tx1.signature).s));
// Two txin_gen, signatures vector contains three empty elements
//tx.signatures.resize(3);
//signatures.resize(3);
//ASSERT_FALSE(serialization::dump_binary(tx, blob));
// Two txin_gen, signatures vector contains two non empty elements
//tx.signatures.resize(2);
//tx.signatures[0].resize(1);
//tx.signatures[1].resize(1);
//signatures.resize(2);
//signatures[0].resize(1);
//signatures[1].resize(1);
//ASSERT_FALSE(serialization::dump_binary(tx, blob));
// A few bytes instead of signature
tx.vin.clear();
tx.vin.push_back(txin_gen1);
tx.signatures.clear();
boost::get<currency::NLSAG_sig>(tx.signature).s.clear();
ASSERT_TRUE(serialization::dump_binary(tx, blob));
blob.append(std::string(sizeof(crypto::signature) / 2, 'x'));
ASSERT_FALSE(serialization::parse_binary(blob, tx1));
@ -430,40 +430,40 @@ TEST(Serialization, serializes_transacion_signatures_correctly)
//tx.vin.clear();
//tx.vin.push_back(txin_to_key1);
//tx.vin.push_back(txin_to_key1);
//tx.signatures.resize(1);
//tx.signatures[0].resize(2);
//signatures.resize(1);
//signatures[0].resize(2);
//ASSERT_FALSE(serialization::dump_binary(tx, blob));
/*
// Too much signatures for two inputs
tx.signatures.resize(3);
tx.signatures[0].resize(2);
tx.signatures[1].resize(2);
tx.signatures[2].resize(2);
boost::get<currency::NLSAG_sig>(tx.signature).s.resize(3);
boost::get<currency::NLSAG_sig>(tx.signature).s[0].resize(2);
boost::get<currency::NLSAG_sig>(tx.signature).s[1].resize(2);
boost::get<currency::NLSAG_sig>(tx.signature).s[2].resize(2);
ASSERT_FALSE(serialization::dump_binary(tx, blob));
// First signatures vector contains too little elements
tx.signatures.resize(2);
tx.signatures[0].resize(1);
tx.signatures[1].resize(2);
boost::get<currency::NLSAG_sig>(tx.signature).s.resize(2);
boost::get<currency::NLSAG_sig>(tx.signature).s[0].resize(1);
boost::get<currency::NLSAG_sig>(tx.signature).s[1].resize(2);
ASSERT_FALSE(serialization::dump_binary(tx, blob));
// First signatures vector contains too much elements
tx.signatures.resize(2);
tx.signatures[0].resize(3);
tx.signatures[1].resize(2);
boost::get<currency::NLSAG_sig>(tx.signature).s.resize(2);
boost::get<currency::NLSAG_sig>(tx.signature).s[0].resize(3);
boost::get<currency::NLSAG_sig>(tx.signature).s[1].resize(2);
ASSERT_FALSE(serialization::dump_binary(tx, blob));
// There are signatures for each input
tx.signatures.resize(2);
tx.signatures[0].resize(2);
tx.signatures[1].resize(2);
boost::get<currency::NLSAG_sig>(tx.signature).s.resize(2);
boost::get<currency::NLSAG_sig>(tx.signature).s[0].resize(2);
boost::get<currency::NLSAG_sig>(tx.signature).s[1].resize(2);
ASSERT_TRUE(serialization::dump_binary(tx, blob));
ASSERT_TRUE(serialization::parse_binary(blob, tx1));
ASSERT_EQ(tx, tx1);
ASSERT_EQ(linearize_vector2(tx.signatures), linearize_vector2(tx1.signatures));
ASSERT_EQ(linearize_vector2(boost::get<currency::NLSAG_sig>(tx.signature).s), linearize_vector2(boost::get<currency::NLSAG_sig>(tx1.signature).s));
// Blob doesn't contain enough data
blob.resize(blob.size() - sizeof(crypto::signature) / 2);
@ -622,7 +622,7 @@ bool operator ==(const transaction_new_tests& a, const transaction_new_tests& b)
a.extra.size() == b.extra.size() &&
a.vin.size() == b.vin.size() &&
a.vout.size() == b.vout.size() &&
a.signatures.size() == b.signatures.size();
boost::get<currency::NLSAG_sig>(a.signature).s.size() == boost::get<currency::NLSAG_sig>(b.signature).s.size();
}
bool operator ==(const transaction_new_tests& a, const transaction_old_tests& b) {
@ -630,7 +630,7 @@ bool operator ==(const transaction_new_tests& a, const transaction_old_tests& b)
a.extra.size() == b.extra.size() &&
a.vin.size() == b.vin.size() &&
a.vout.size() == b.vout.size() &&
a.signatures.size() == b.signatures.size();
boost::get<currency::NLSAG_sig>(a.signature).s.size() == boost::get<currency::NLSAG_sig>(b.signature).s.size();
}
void validate_tx_serialisation(transaction_new_tests& tx)
@ -670,7 +670,7 @@ TEST(Serialization, serializes_transacion_versions)
{
ASSERT_TRUE(false);
}
ASSERT_EQ(linearize_vector2(tx.signatures), linearize_vector2(tx1.signatures));
ASSERT_EQ(linearize_vector2(boost::get<currency::NLSAG_sig>(tx.signature).s), linearize_vector2(boost::get<currency::NLSAG_sig>(tx1.signature).s));
*/
txin_gen txin_gen1;
@ -705,12 +705,12 @@ TEST(Serialization, serializes_transacion_versions)
eae.m_alias = "eokcmeockme";
eae.m_text_comment = "sdssccsc";
tx.extra.push_back(eae);
tx.signatures.resize(2);
boost::get<currency::NLSAG_sig>(tx.signature).s.resize(2);
crypto::signature sig = epee::string_tools::parse_tpod_from_hex_string<crypto::signature>("22608f59f8080e2fbfe3c8c80eb6e6a953d47cf2d6aebd345bada3a1cab9985222608f59f8080e2fbfe3c8c80eb6e6a953d47cf2d6aebd345bada3a1cab99852");
tx.signatures[0].push_back(sig);
tx.signatures[0].push_back(sig);
tx.signatures[1].push_back(sig);
tx.signatures[1].push_back(sig);
boost::get<currency::NLSAG_sig>(tx.signature).s[0].push_back(sig);
boost::get<currency::NLSAG_sig>(tx.signature).s[0].push_back(sig);
boost::get<currency::NLSAG_sig>(tx.signature).s[1].push_back(sig);
boost::get<currency::NLSAG_sig>(tx.signature).s[1].push_back(sig);
tx.version = TRANSACTION_VERSION_INITAL;