Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e2bc467618 | |||
| cb3f1905ed |
@@ -1,4 +1,4 @@
|
||||
# Salvium One v1.0.0
|
||||
# Salvium Zero v0.9.9
|
||||
|
||||
Copyright (c) 2023-2024, Salvium
|
||||
Portions Copyright (c) 2014-2023, The Monero Project
|
||||
@@ -172,7 +172,7 @@ invokes cmake commands as needed.
|
||||
|
||||
```bash
|
||||
cd salvium
|
||||
git checkout v1.0.0
|
||||
git checkout v0.9.9
|
||||
make
|
||||
```
|
||||
|
||||
@@ -251,7 +251,7 @@ Tested on a Raspberry Pi Zero with a clean install of minimal Raspbian Stretch (
|
||||
```bash
|
||||
git clone https://github.com/salvium/salvium
|
||||
cd salvium
|
||||
git checkout v1.0.0
|
||||
git checkout v0.9.9
|
||||
```
|
||||
|
||||
* Build:
|
||||
@@ -370,10 +370,10 @@ application.
|
||||
cd salvium
|
||||
```
|
||||
|
||||
* If you would like a specific [version/tag](https://github.com/salvium/salvium/tags), do a git checkout for that version. eg. 'v1.0.0'. If you don't care about the version and just want binaries from master, skip this step:
|
||||
* If you would like a specific [version/tag](https://github.com/salvium/salvium/tags), do a git checkout for that version. eg. 'v0.9.9'. If you don't care about the version and just want binaries from master, skip this step:
|
||||
|
||||
```bash
|
||||
git checkout v1.0.0
|
||||
git checkout v0.9.9
|
||||
```
|
||||
|
||||
* If you are on a 64-bit system, run:
|
||||
|
||||
Vendored
+1
-1
Submodule external/mx25519 updated: e808a6406b...42f36ede5f
@@ -238,7 +238,7 @@ void BlockchainDB::add_transaction(const crypto::hash& blk_hash, const std::pair
|
||||
LOG_PRINT_L1("Failed to get output unlock time, aborting transaction addition");
|
||||
throw std::runtime_error("Unexpected error getting output unlock_time, aborting");
|
||||
}
|
||||
if (miner_tx && tx.version >= 2)
|
||||
if (miner_tx && tx.version == 2)
|
||||
{
|
||||
cryptonote::tx_out vout = tx.vout[i];
|
||||
// TODO: avoid multiple expensive zeroCommitVartime call here + get_outs_by_last_locked_block + ver_non_input_consensus
|
||||
|
||||
@@ -208,8 +208,8 @@ typedef struct yield_tx_info {
|
||||
} yield_tx_info;
|
||||
|
||||
typedef struct yield_tx_info_carrot {
|
||||
uint64_t block_height;
|
||||
uint8_t version;
|
||||
uint64_t block_height;
|
||||
crypto::hash tx_hash;
|
||||
uint64_t locked_coins;
|
||||
crypto::public_key return_address;
|
||||
|
||||
@@ -315,55 +315,6 @@ crypto::secret_key carrot_and_legacy_account::generate(
|
||||
return retval;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
void carrot_and_legacy_account::set_keys(const cryptonote::account_keys& keys, bool copy_spend_secret_keys)
|
||||
{
|
||||
// CN keys
|
||||
m_keys.m_account_address = keys.m_account_address;
|
||||
if (copy_spend_secret_keys) m_keys.m_spend_secret_key = keys.m_spend_secret_key;
|
||||
m_keys.m_view_secret_key = keys.m_view_secret_key;
|
||||
if (copy_spend_secret_keys) m_keys.m_multisig_keys = keys.m_multisig_keys;
|
||||
m_keys.m_device = keys.m_device;
|
||||
m_keys.m_encryption_iv = keys.m_encryption_iv;
|
||||
|
||||
// Carrot keys
|
||||
if (copy_spend_secret_keys) m_keys.s_master = keys.s_master;
|
||||
if (copy_spend_secret_keys) m_keys.k_prove_spend = keys.k_prove_spend;
|
||||
m_keys.s_view_balance = keys.s_view_balance;
|
||||
m_keys.k_view_incoming = keys.k_view_incoming;
|
||||
m_keys.k_generate_image = keys.k_generate_image;
|
||||
m_keys.s_generate_address = keys.s_generate_address;
|
||||
m_keys.m_carrot_account_address = keys.m_carrot_account_address;
|
||||
m_keys.m_carrot_main_address = keys.m_carrot_main_address;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
void carrot_and_legacy_account::create_from_svb_key(const cryptonote::account_public_address& address, const crypto::secret_key& svb_key)
|
||||
{
|
||||
// top level keys
|
||||
m_keys.s_master = crypto::null_skey;
|
||||
make_carrot_provespend_key(m_keys.s_master, m_keys.k_prove_spend);
|
||||
m_keys.s_view_balance = svb_key;
|
||||
|
||||
// view balance keys
|
||||
make_carrot_viewincoming_key(m_keys.s_view_balance, m_keys.k_view_incoming);
|
||||
make_carrot_generateimage_key(m_keys.s_view_balance, m_keys.k_generate_image);
|
||||
make_carrot_generateaddress_secret(m_keys.s_view_balance, m_keys.s_generate_address);
|
||||
|
||||
// carrot account address - use the provided address spend pubkey
|
||||
m_keys.m_carrot_account_address = address;
|
||||
k_view_incoming_dev.view_key_scalar_mult_ed25519(m_keys.m_carrot_account_address.m_spend_public_key,
|
||||
m_keys.m_carrot_account_address.m_view_public_key
|
||||
);
|
||||
|
||||
// carrot main wallet address
|
||||
m_keys.m_carrot_main_address = address;
|
||||
k_view_incoming_dev.view_key_scalar_mult_ed25519(crypto::get_G(),
|
||||
m_keys.m_carrot_main_address.m_view_public_key
|
||||
);
|
||||
|
||||
this->default_derive_type = AddressDeriveType::Carrot;
|
||||
generate_subaddress_map();
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
void carrot_and_legacy_account::set_carrot_keys(const AddressDeriveType default_derive_type)
|
||||
{
|
||||
// top level keys
|
||||
@@ -382,7 +333,6 @@ void carrot_and_legacy_account::set_carrot_keys(const AddressDeriveType default_
|
||||
m_keys.m_carrot_account_address.m_spend_public_key,
|
||||
m_keys.m_carrot_account_address.m_view_public_key
|
||||
);
|
||||
m_keys.m_carrot_account_address.m_is_carrot = true;
|
||||
|
||||
// carrot main wallet address
|
||||
m_keys.m_carrot_main_address.m_spend_public_key = m_keys.m_carrot_account_address.m_spend_public_key;
|
||||
@@ -390,7 +340,6 @@ void carrot_and_legacy_account::set_carrot_keys(const AddressDeriveType default_
|
||||
crypto::get_G(),
|
||||
m_keys.m_carrot_main_address.m_view_public_key
|
||||
);
|
||||
m_keys.m_carrot_main_address.m_is_carrot = true;
|
||||
|
||||
this->default_derive_type = default_derive_type;
|
||||
generate_subaddress_map();
|
||||
|
||||
@@ -52,16 +52,6 @@ namespace carrot
|
||||
crypto::secret_key x;
|
||||
crypto::secret_key y;
|
||||
|
||||
return_output_info_t() {
|
||||
// Default constructor for serialization
|
||||
input_context = input_context_t();
|
||||
K_o = crypto::public_key();
|
||||
K_change = crypto::public_key();
|
||||
key_image = crypto::key_image();
|
||||
x = crypto::secret_key();
|
||||
y = crypto::secret_key();
|
||||
}
|
||||
|
||||
return_output_info_t(
|
||||
const input_context_t &input_context,
|
||||
const crypto::public_key &K_o,
|
||||
@@ -75,15 +65,6 @@ namespace carrot
|
||||
key_image(key_image),
|
||||
x(x),
|
||||
y(y) {}
|
||||
|
||||
BEGIN_SERIALIZE_OBJECT()
|
||||
FIELD(input_context)
|
||||
FIELD(K_o)
|
||||
FIELD(K_change)
|
||||
FIELD(key_image)
|
||||
FIELD(x)
|
||||
FIELD(y)
|
||||
END_SERIALIZE()
|
||||
};
|
||||
|
||||
|
||||
@@ -101,8 +82,6 @@ namespace carrot
|
||||
s_generate_address_dev(get_keys().s_generate_address)
|
||||
{}
|
||||
|
||||
void set_keys(const cryptonote::account_keys& keys, bool copy_spend_secret_keys);
|
||||
|
||||
carrot_and_legacy_account(const carrot_and_legacy_account &k) = delete;
|
||||
carrot_and_legacy_account(carrot_and_legacy_account&&) = delete;
|
||||
|
||||
@@ -153,7 +132,6 @@ namespace carrot
|
||||
const AddressDeriveType default_derive_type = AddressDeriveType::Carrot
|
||||
);
|
||||
|
||||
void create_from_svb_key(const cryptonote::account_public_address& address, const crypto::secret_key& svb_key);
|
||||
void set_carrot_keys(const AddressDeriveType default_derive_type = AddressDeriveType::Carrot);
|
||||
void insert_subaddresses(const std::unordered_map<crypto::public_key, subaddress_index_extended>& subaddress_map);
|
||||
void insert_return_output_info(
|
||||
@@ -168,35 +146,3 @@ namespace carrot
|
||||
std::unordered_map<crypto::public_key, return_output_info_t> return_output_map;
|
||||
};
|
||||
}
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace serialization
|
||||
{
|
||||
template <class Archive>
|
||||
inline typename std::enable_if<!Archive::is_loading::value, void>::type initialize_transfer_details(Archive &a, carrot::return_output_info_t &x, const boost::serialization::version_type ver)
|
||||
{
|
||||
}
|
||||
template <class Archive>
|
||||
inline typename std::enable_if<Archive::is_loading::value, void>::type initialize_transfer_details(Archive &a, carrot::return_output_info_t &x, const boost::serialization::version_type ver)
|
||||
{
|
||||
x.input_context = carrot::input_context_t();
|
||||
x.K_o = crypto::public_key();
|
||||
x.K_change = crypto::public_key();
|
||||
x.key_image = crypto::key_image();
|
||||
x.x = crypto::secret_key();
|
||||
x.y = crypto::secret_key();
|
||||
}
|
||||
|
||||
template <class Archive>
|
||||
inline void serialize(Archive &a, carrot::return_output_info_t &x, const boost::serialization::version_type ver)
|
||||
{
|
||||
a & x.input_context;
|
||||
a & x.K_o;
|
||||
a & x.K_change;
|
||||
a & x.key_image;
|
||||
a & x.x;
|
||||
a & x.y;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,10 +70,11 @@ static constexpr const unsigned char CARROT_DOMAIN_SEP_SUBADDRESS_SCALAR[] = "Ca
|
||||
static constexpr const unsigned int CARROT_MIN_TX_OUTPUTS = 2;
|
||||
static constexpr const unsigned int CARROT_MAX_TX_OUTPUTS = 8;
|
||||
static constexpr const unsigned int CARROT_MIN_TX_INPUTS = 1;
|
||||
static constexpr const unsigned int CARROT_MAX_TX_INPUTS = 64;
|
||||
static constexpr const unsigned int CARROT_MAX_TX_INPUTS = 128;
|
||||
|
||||
// SPARC addressing protocol domain separators
|
||||
static constexpr const unsigned char SPARC_DOMAIN_SEP_RETURN_PUBKEY_ENCRYPTION_MASK[] = "SPARC return pubkey encryption mask";
|
||||
static constexpr const unsigned char SPARC_DOMAIN_SEP_RETURN_ADDRESS_SCALAR[] = "SPARC return address scalar";
|
||||
static constexpr const unsigned char SPARC_DOMAIN_SEP_RETURN_INDEX_SCALAR[] = "SPARC return index scalar";
|
||||
|
||||
} //namespace carrot
|
||||
|
||||
@@ -211,6 +211,17 @@ void make_sparc_return_privkey(const unsigned char s_sender_receiver_unctx[32],
|
||||
derive_scalar(transcript.data(), transcript.size(), s_sender_receiver_unctx, &return_privkey_out);
|
||||
}
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
void make_sparc_return_index(const unsigned char s_sender_receiver_unctx[32],
|
||||
const input_context_t &input_context,
|
||||
const crypto::public_key &onetime_address,
|
||||
const uint64_t idx,
|
||||
crypto::secret_key &return_index_out)
|
||||
{
|
||||
// k_return = H_32(s_sr || input_context || Ko)
|
||||
const auto transcript = sp::make_fixed_transcript<SPARC_DOMAIN_SEP_RETURN_INDEX_SCALAR>(input_context, onetime_address, idx);
|
||||
derive_scalar(transcript.data(), transcript.size(), s_sender_receiver_unctx, &return_index_out);
|
||||
}
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
void make_sparc_return_pubkey_encryption_mask(const unsigned char s_sender_receiver_unctx[32],
|
||||
const input_context_t &input_context,
|
||||
const crypto::public_key &onetime_address,
|
||||
@@ -222,22 +233,33 @@ void make_sparc_return_pubkey_encryption_mask(const unsigned char s_sender_recei
|
||||
}
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
void make_sparc_return_pubkey(const unsigned char s_sender_receiver_unctx[32],
|
||||
const input_context_t &input_context,
|
||||
const view_balance_secret_device *s_view_balance_dev,
|
||||
const crypto::public_key &onetime_address,
|
||||
encrypted_return_pubkey_t &return_pubkey_out)
|
||||
const input_context_t &input_context,
|
||||
const view_balance_secret_device *s_view_balance_dev,
|
||||
const crypto::public_key &onetime_address,
|
||||
const uint64_t idx,
|
||||
encrypted_return_pubkey_t &return_enc_pubkey_out)
|
||||
{
|
||||
// K_return = k_return G ^ m_return
|
||||
// K_return = k_return G + k_idx T
|
||||
crypto::secret_key k_return;
|
||||
crypto::public_key return_pub;
|
||||
encrypted_return_pubkey_t K_return;
|
||||
encrypted_return_pubkey_t m_return;
|
||||
crypto::secret_key k_idx = crypto::null_skey;
|
||||
encrypted_return_pubkey_t return_pub;
|
||||
s_view_balance_dev->make_internal_return_privkey(input_context, onetime_address, k_return);
|
||||
crypto::secret_key_to_public_key(k_return, return_pub);
|
||||
static_assert(sizeof(K_return.bytes) == sizeof(return_pub.data), "Size mismatch");
|
||||
memcpy(K_return.bytes, return_pub.data, sizeof(encrypted_return_pubkey_t));
|
||||
make_sparc_return_index(to_bytes(onetime_address), input_context, onetime_address, idx, k_idx);
|
||||
rct::key K_return;
|
||||
rct::addKeys2(K_return,
|
||||
rct::sk2rct(k_return),
|
||||
rct::sk2rct(k_idx),
|
||||
rct::pk2rct(crypto::get_T()));
|
||||
//K_return = rct::scalarmult8(K_return);
|
||||
if (!rct::isInMainSubgroup(K_return))
|
||||
throw std::runtime_error("K_return is not in main subgroup");
|
||||
static_assert(sizeof(K_return.bytes) == sizeof(return_pub.bytes), "Size mismatch");
|
||||
memcpy(return_pub.bytes, K_return.bytes, sizeof(encrypted_return_pubkey_t));
|
||||
|
||||
// return_enc = return_pub ^ m_return
|
||||
encrypted_return_pubkey_t m_return;
|
||||
make_sparc_return_pubkey_encryption_mask(s_sender_receiver_unctx, input_context, onetime_address, m_return);
|
||||
return_pubkey_out = K_return ^ m_return;
|
||||
return_enc_pubkey_out = return_pub ^ m_return;
|
||||
}
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -138,6 +138,20 @@ void make_sparc_return_privkey(const unsigned char s_sender_receiver_unctx[32],
|
||||
const crypto::public_key &onetime_address,
|
||||
crypto::secret_key &return_privkey_out);
|
||||
/**
|
||||
* brief: make_sparc_return_index - return k_idx, given non-secret data
|
||||
* k_idx = H_32(s_sr || input_context || Ko || idx)
|
||||
* param: s_sender_receiver_unctx - s_sr
|
||||
* param: input_context - input_context
|
||||
* param: onetime_address - Ko
|
||||
* param: idx
|
||||
* outparam: return_index_out - k_idx
|
||||
*/
|
||||
void make_sparc_return_index(const unsigned char s_sender_receiver_unctx[32],
|
||||
const input_context_t &input_context,
|
||||
const crypto::public_key &onetime_address,
|
||||
const uint64_t idx,
|
||||
crypto::secret_key &return_index_out);
|
||||
/**
|
||||
* brief: make_sparc_return_pubkey_encryption_mask - used for hiding return pubkey
|
||||
* m_return = H_32(s_sr || input_context || Ko)
|
||||
* param: s_sender_receiver_unctx - s_sr
|
||||
@@ -156,13 +170,15 @@ void make_sparc_return_pubkey_encryption_mask(const unsigned char s_sender_recei
|
||||
* param: input_context - input_context
|
||||
* param: s_view_balance_dev - s_vb
|
||||
* param: onetime_address - Ko
|
||||
* param: idx
|
||||
* outparam: return_pubkey_mask_out - K_return
|
||||
*/
|
||||
void make_sparc_return_pubkey(const unsigned char s_sender_receiver_unctx[32],
|
||||
const input_context_t &input_context,
|
||||
const view_balance_secret_device *s_view_balance_dev,
|
||||
const crypto::public_key &onetime_address,
|
||||
encrypted_return_pubkey_t &return_pubkey_out);
|
||||
const input_context_t &input_context,
|
||||
const view_balance_secret_device *s_view_balance_dev,
|
||||
const crypto::public_key &onetime_address,
|
||||
const uint64_t idx,
|
||||
encrypted_return_pubkey_t &return_pubkey_out);
|
||||
/**
|
||||
* brief: make_carrot_input_context_coinbase - input context for a sender-receiver secret (coinbase txs)
|
||||
* input_context = "C" || IntToBytes256(block_index)
|
||||
|
||||
@@ -216,7 +216,7 @@ void get_output_enote_proposals(const std::vector<CarrotPaymentProposalV1> &norm
|
||||
// construct normal enotes
|
||||
for (size_t i = 0; i < normal_payment_proposals.size(); ++i)
|
||||
{
|
||||
auto &output_entry = sortable_data.emplace_back();
|
||||
auto &output_entry = tools::add_element(sortable_data);
|
||||
output_entry.second = {false, i};
|
||||
|
||||
encrypted_payment_id_t encrypted_payment_id;
|
||||
@@ -270,7 +270,7 @@ void get_output_enote_proposals(const std::vector<CarrotPaymentProposalV1> &norm
|
||||
{
|
||||
const CarrotPaymentProposalSelfSendV1 &selfsend_payment_proposal = selfsend_payment_proposals.at(i);
|
||||
|
||||
auto &output_entry = sortable_data.emplace_back();
|
||||
auto &output_entry = tools::add_element(sortable_data);
|
||||
output_entry.second = {true, i};
|
||||
|
||||
if (s_view_balance_dev != nullptr)
|
||||
@@ -361,11 +361,11 @@ void get_output_enote_proposals(const std::vector<CarrotPaymentProposalV1> &norm
|
||||
component_out_of_order, "this set contains duplicate onetime addresses");
|
||||
|
||||
// assert all K_o lie in prime order subgroup
|
||||
// for (const RCTOutputEnoteProposal &output_enote_proposal : output_enote_proposals_out)
|
||||
// {
|
||||
// CARROT_CHECK_AND_THROW(rct::isInMainSubgroup(rct::pk2rct(output_enote_proposal.enote.onetime_address)),
|
||||
// invalid_point, "this set contains an invalid onetime address");
|
||||
// }
|
||||
for (const RCTOutputEnoteProposal &output_enote_proposal : output_enote_proposals_out)
|
||||
{
|
||||
CARROT_CHECK_AND_THROW(rct::isInMainSubgroup(rct::pk2rct(output_enote_proposal.enote.onetime_address)),
|
||||
invalid_point, "this set contains an invalid onetime address");
|
||||
}
|
||||
|
||||
// assert unique and non-trivial k_a
|
||||
memcmp_set<crypto::secret_key> amount_blinding_factors;
|
||||
@@ -416,7 +416,7 @@ void get_coinbase_output_enotes(const std::vector<CarrotPaymentProposalV1> &norm
|
||||
{
|
||||
get_coinbase_output_proposal_v1(normal_payment_proposals[i],
|
||||
block_index,
|
||||
output_coinbase_enotes_out.emplace_back());
|
||||
tools::add_element(output_coinbase_enotes_out));
|
||||
}
|
||||
|
||||
// assert uniqueness and non-trivial-ness of D_e
|
||||
|
||||
@@ -208,10 +208,11 @@ static void get_external_output_proposal_parts(const mx25519_pubkey &s_sender_re
|
||||
// 4. construct the return pubkey
|
||||
if (s_view_balance_dev != nullptr)
|
||||
make_sparc_return_pubkey(s_sender_receiver_unctx.data,
|
||||
input_context,
|
||||
s_view_balance_dev,
|
||||
onetime_address_out,
|
||||
return_pubkey_out);
|
||||
input_context,
|
||||
s_view_balance_dev,
|
||||
onetime_address_out,
|
||||
0/*idx*/,
|
||||
return_pubkey_out);
|
||||
}
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -34,6 +34,11 @@
|
||||
//local headers
|
||||
#include "destination.h"
|
||||
#include "enote_utils.h"
|
||||
extern "C"
|
||||
{
|
||||
#include "crypto/crypto-ops.h"
|
||||
}
|
||||
#include "crypto/generators.h"
|
||||
#include "ringct/rctOps.h"
|
||||
#include "scan_unsafe.h"
|
||||
|
||||
@@ -508,20 +513,31 @@ bool try_scan_carrot_enote_internal_receiver(const CarrotEnoteV1 &enote,
|
||||
const carrot::input_context_t input_context = carrot::make_carrot_input_context(enote.tx_first_key_image);
|
||||
account.s_view_balance_dev.make_internal_return_privkey(input_context, output_key, k_return);
|
||||
|
||||
// compute K_return = k_return * G
|
||||
crypto::public_key K_return;
|
||||
crypto::secret_key_to_public_key(k_return, K_return);
|
||||
// make k_idx
|
||||
crypto::secret_key k_idx = crypto::null_skey;
|
||||
uint64_t idx = 0;
|
||||
make_sparc_return_index(to_bytes(output_key), input_context, output_key, idx, k_idx);
|
||||
|
||||
// compute K_return = k_return * G + k_idx * T
|
||||
rct::key K_return;
|
||||
rct::addKeys2(K_return,
|
||||
rct::sk2rct(k_return),
|
||||
rct::sk2rct(k_idx),
|
||||
rct::pk2rct(crypto::get_T()));
|
||||
//K_return = rct::scalarmult8(K_return);
|
||||
|
||||
// compute K_r = K_return + K_o
|
||||
crypto::public_key K_r = rct::rct2pk(rct::addKeys(rct::pk2rct(K_return), rct::pk2rct(enote.onetime_address)));
|
||||
crypto::public_key K_r = rct::rct2pk(rct::addKeys(K_return, rct::pk2rct(enote.onetime_address)));
|
||||
|
||||
// calculate the key image for the return output
|
||||
crypto::secret_key sum_g;
|
||||
sc_add(to_bytes(sum_g), to_bytes(sender_extension_g_out), to_bytes(k_return));
|
||||
crypto::secret_key sum_t;
|
||||
sc_add(to_bytes(sum_t), to_bytes(sender_extension_t_out), to_bytes(k_idx));
|
||||
crypto::key_image key_image = account.derive_key_image(
|
||||
account.get_keys().m_carrot_account_address.m_spend_public_key,
|
||||
sum_g,
|
||||
sender_extension_t_out,
|
||||
sum_t,
|
||||
K_r
|
||||
);
|
||||
|
||||
@@ -529,7 +545,7 @@ bool try_scan_carrot_enote_internal_receiver(const CarrotEnoteV1 &enote,
|
||||
account.try_searching_for_opening_for_onetime_address(
|
||||
account.get_keys().m_carrot_account_address.m_spend_public_key,
|
||||
sum_g,
|
||||
sender_extension_t_out,
|
||||
sum_t,
|
||||
x,
|
||||
y
|
||||
);
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include "carrot_core/enote_utils.h"
|
||||
#include "carrot_core/exceptions.h"
|
||||
#include "carrot_core/payment_proposal.h"
|
||||
#include "common/container_helpers.h"
|
||||
#include "cryptonote_basic/cryptonote_format_utils.h"
|
||||
#include "cryptonote_core/cryptonote_tx_utils.h"
|
||||
#include "cryptonote_config.h"
|
||||
@@ -257,7 +258,7 @@ cryptonote::transaction store_carrot_to_transaction_v1(const std::vector<CarrotE
|
||||
}});
|
||||
|
||||
//a_enc
|
||||
rct::ecdhTuple &ecdh_tuple = tx.rct_signatures.ecdhInfo.emplace_back();
|
||||
rct::ecdhTuple &ecdh_tuple = tools::add_element(tx.rct_signatures.ecdhInfo);
|
||||
memcpy(ecdh_tuple.amount.bytes, enote.amount_enc.bytes, sizeof(ecdh_tuple.amount));
|
||||
|
||||
//C_a
|
||||
@@ -420,7 +421,7 @@ cryptonote::transaction store_carrot_to_coinbase_transaction_v1(
|
||||
cryptonote::transaction tx;
|
||||
tx.type = tx_type;
|
||||
tx.pruned = false;
|
||||
tx.version = TRANSACTION_VERSION_CARROT;
|
||||
tx.version = 2;
|
||||
tx.unlock_time = CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW;
|
||||
tx.vin.reserve(1);
|
||||
tx.vout.reserve(nouts);
|
||||
|
||||
@@ -318,27 +318,33 @@ std::vector<std::size_t> get_input_counts_in_preferred_order()
|
||||
// 1 or 2 randomly, then
|
||||
// other ascending powers of 2, then
|
||||
// other ascending positive numbers
|
||||
|
||||
|
||||
//! @TODO: MRL discussion about 2 vs 1 default input count when 1 input can pay. If we default
|
||||
// to 1, then that may reveal more information about the amount, and reveals that one can't pay
|
||||
// with 1 output when using 2. Vice versa, if we default to 2, then that means that one only
|
||||
// owns 1 output when using 1. It may be the most advantageous to randomly switch between
|
||||
// preferring 1 vs 2. See: https://lavalle.pl/planning/node437.html. Con to this approach: if we
|
||||
// default to 1 over 2 always then there's scenarios where we net save tx fees and proving time.
|
||||
|
||||
//static_assert(CARROT_MAX_TX_INPUTS == FCMP_PLUS_PLUS_MAX_INPUTS, "inconsistent input count max limit");
|
||||
static_assert(CARROT_MIN_TX_INPUTS == 1 && CARROT_MAX_TX_INPUTS == 64,
|
||||
// preferring 1 vs 2. See: https://lavalle.pl/planning/node437.html. Con to this approach: if we
|
||||
// default to 1 over 2 always then there's scenarios where we net save tx fees and proving time.
|
||||
|
||||
//static_assert(CARROT_MAX_TX_INPUTS == FCMP_PLUS_PLUS_MAX_INPUTS, "inconsistent input count max limit");
|
||||
static_assert(CARROT_MIN_TX_INPUTS == 1 && CARROT_MAX_TX_INPUTS == 128,
|
||||
"refactor this function for different input count limits");
|
||||
|
||||
const bool random_bit = 0 == (crypto::rand<uint8_t>() & 0x01);
|
||||
if (random_bit)
|
||||
return {2, 1, 4, 8, 16, 32, 64, 3, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 17, 18, 19, 20, 21, 22, 23,
|
||||
24, 25, 26, 27, 28, 29, 30, 31, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
|
||||
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63};
|
||||
return {2, 1, 4, 8, 16, 32, 64, 128, 3, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 17, 18, 19, 20, 21, 22, 23,
|
||||
24, 25, 26, 27, 28, 29, 30, 31, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
|
||||
49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 65, 66, 67, 68, 69, 70, 71, 72, 73,
|
||||
74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97,
|
||||
98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116,
|
||||
117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127};
|
||||
else
|
||||
return {1, 2, 4, 8, 16, 32, 64, 3, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 17, 18, 19, 20, 21, 22, 23,
|
||||
24, 25, 26, 27, 28, 29, 30, 31, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
|
||||
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63};
|
||||
return {1, 2, 4, 8, 16, 32, 64, 128, 3, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 17, 18, 19, 20, 21, 22, 23,
|
||||
24, 25, 26, 27, 28, 29, 30, 31, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
|
||||
49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 65, 66, 67, 68, 69, 70, 71, 72, 73,
|
||||
74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97,
|
||||
98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116,
|
||||
117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127};
|
||||
}
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
select_inputs_func_t make_single_transfer_input_selector(
|
||||
|
||||
@@ -331,6 +331,15 @@ void make_carrot_transaction_proposal_v1_transfer(
|
||||
selfsend_payment_proposals.back().proposal.amount =
|
||||
boost::numeric_cast<rct::xmr_amount>(implicit_change_amount);
|
||||
|
||||
// remove the self send payment we have made to ourself now that we have our change payment.
|
||||
if (tx_type == cryptonote::transaction_type::STAKE ||
|
||||
tx_type == cryptonote::transaction_type::BURN)
|
||||
{
|
||||
selfsend_payment_proposals.back().proposal.enote_ephemeral_pubkey =
|
||||
selfsend_payment_proposals.front().proposal.enote_ephemeral_pubkey;
|
||||
selfsend_payment_proposals.erase(selfsend_payment_proposals.begin());
|
||||
}
|
||||
|
||||
// deduct an even fee amount from all subtractable outputs
|
||||
const size_t num_subtractble_normal = subtractable_normal_payment_proposals.size();
|
||||
const size_t num_subtractable_selfsend = subtractable_selfsend_payment_proposals.size();
|
||||
@@ -394,16 +403,6 @@ void make_carrot_transaction_proposal_v1_transfer(
|
||||
|
||||
CHECK_AND_ASSERT_THROW_MES(fee_remainder == 0,
|
||||
"make unsigned transaction transfer subtractable: bug: fee remainder at end of carve function");
|
||||
|
||||
// remove the self send payment we have made to ourself now that we have our change payment.
|
||||
if (tx_type == cryptonote::transaction_type::STAKE ||
|
||||
tx_type == cryptonote::transaction_type::BURN)
|
||||
{
|
||||
selfsend_payment_proposals.back().proposal.enote_ephemeral_pubkey =
|
||||
selfsend_payment_proposals.front().proposal.enote_ephemeral_pubkey;
|
||||
selfsend_payment_proposals.erase(selfsend_payment_proposals.begin());
|
||||
}
|
||||
|
||||
}; //end carve_fees_and_balance
|
||||
|
||||
// make unsigned transaction with fee carving callback
|
||||
|
||||
@@ -138,6 +138,13 @@ bool keys_match_internal_values(const std::unordered_map<KeyT, ValueT> &map, Pre
|
||||
|
||||
return true;
|
||||
}
|
||||
/// convenience wrapper for getting the last element after emplacing back
|
||||
template <typename ContainerT>
|
||||
typename ContainerT::value_type& add_element(ContainerT &container)
|
||||
{
|
||||
container.emplace_back();
|
||||
return container.back();
|
||||
}
|
||||
/// convenience erasor for unordered maps: std::erase_if(std::unordered_map) is C++20
|
||||
template <typename KeyT, typename ValueT, typename PredT>
|
||||
void for_all_in_map_erase_if(std::unordered_map<KeyT, ValueT> &map_inout, PredT predicate)
|
||||
|
||||
@@ -151,8 +151,6 @@ DISABLE_VS_WARNINGS(4244 4345)
|
||||
void account_base::forget_spend_key()
|
||||
{
|
||||
m_keys.m_spend_secret_key = crypto::secret_key();
|
||||
m_keys.s_master = m_keys.m_spend_secret_key;
|
||||
m_keys.k_prove_spend = m_keys.m_spend_secret_key;
|
||||
m_keys.m_multisig_keys.clear();
|
||||
}
|
||||
//-----------------------------------------------------------------
|
||||
@@ -165,7 +163,6 @@ DISABLE_VS_WARNINGS(4244 4345)
|
||||
"Unexpected derived public spend key");
|
||||
|
||||
m_keys.m_spend_secret_key = spend_secret_key;
|
||||
m_keys.s_master = m_keys.m_spend_secret_key;
|
||||
}
|
||||
//-----------------------------------------------------------------
|
||||
crypto::secret_key account_base::generate(const crypto::secret_key& recovery_key, bool recover, bool two_random)
|
||||
|
||||
@@ -73,11 +73,6 @@ namespace boost
|
||||
a & reinterpret_cast<char (&)[sizeof(crypto::key_image)]>(x);
|
||||
}
|
||||
template <class Archive>
|
||||
inline void serialize(Archive &a, carrot::input_context_t &x, const boost::serialization::version_type ver)
|
||||
{
|
||||
a & reinterpret_cast<char (&)[sizeof(carrot::input_context_t)]>(x);
|
||||
}
|
||||
template <class Archive>
|
||||
inline void serialize(Archive &a, crypto::view_tag &x, const boost::serialization::version_type ver)
|
||||
{
|
||||
a & reinterpret_cast<char (&)[sizeof(crypto::view_tag)]>(x);
|
||||
|
||||
@@ -1381,31 +1381,17 @@ namespace cryptonote
|
||||
|
||||
for (const auto &o: tx.vout)
|
||||
{
|
||||
if (hf_version >= HF_VERSION_ENFORCE_CARROT)
|
||||
if (hf_version >= HF_VERSION_CARROT)
|
||||
{
|
||||
// from v10, require outputs be carrot outputs
|
||||
// from v11, require outputs be carrot outputs
|
||||
CHECK_AND_ASSERT_MES(o.target.type() == typeid(txout_to_carrot_v1), false, "wrong variant type: "
|
||||
<< o.target.type().name() << ", expected txout_to_carrot_v1 in transaction id=" << get_transaction_hash(tx));
|
||||
} else if (hf_version >= HF_VERSION_CARROT) {
|
||||
if (tx.type != cryptonote::transaction_type::PROTOCOL) {
|
||||
CHECK_AND_ASSERT_MES(o.target.type() == typeid(txout_to_carrot_v1), false, "wrong variant type: "
|
||||
<< o.target.type().name() << ", expected txout_to_carrot_v1 in transaction id=" << get_transaction_hash(tx));
|
||||
} else {
|
||||
CHECK_AND_ASSERT_MES(o.target.type() == typeid(txout_to_key) ||
|
||||
o.target.type() == typeid(txout_to_tagged_key) ||
|
||||
o.target.type() == typeid(txout_to_carrot_v1), false, "wrong variant type: "
|
||||
<< o.target.type().name() << ", expected txout_to_key or txout_to_tagged_key or txout_to_carrot_v1 in protocol transaction");
|
||||
// require all outputs in a tx be of the same type
|
||||
CHECK_AND_ASSERT_MES(o.target.type() == tx.vout[0].target.type(), false, "non-matching variant types: "
|
||||
<< o.target.type().name() << " and " << tx.vout[0].target.type().name() << ", "
|
||||
<< "expected matching variant types in protocol transaction");
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// require outputs be of type txout_to_key OR txout_to_tagged_key
|
||||
// to allow grace period before requiring all to be txout_to_tagged_key
|
||||
CHECK_AND_ASSERT_MES(o.target.type() == typeid(txout_to_key) || o.target.type() == typeid(txout_to_tagged_key), false, "wrong variant type: "
|
||||
<< o.target.type().name() << ", expected txout_to_key or txout_to_tagged_key in transaction");
|
||||
|
||||
// require all outputs in a tx be of the same type
|
||||
CHECK_AND_ASSERT_MES(o.target.type() == tx.vout[0].target.type(), false, "non-matching variant types: "
|
||||
<< o.target.type().name() << " and " << tx.vout[0].target.type().name() << ", "
|
||||
|
||||
+17
-18
@@ -244,14 +244,13 @@
|
||||
#define HF_VERSION_AUDIT2 8
|
||||
#define HF_VERSION_AUDIT2_PAUSE 9
|
||||
#define HF_VERSION_CARROT 10
|
||||
#define HF_VERSION_ENFORCE_CARROT 11
|
||||
|
||||
#define HF_VERSION_REQUIRE_VIEW_TAGS 255
|
||||
#define HF_VERSION_ENABLE_CONVERT 255
|
||||
#define HF_VERSION_ENABLE_ORACLE 255
|
||||
#define HF_VERSION_SLIPPAGE_YIELD 255
|
||||
|
||||
#define TESTNET_VERSION 15
|
||||
#define TESTNET_VERSION 14
|
||||
#define STAGENET_VERSION 1
|
||||
|
||||
#define PER_KB_FEE_QUANTIZATION_DECIMALS 8
|
||||
@@ -432,22 +431,22 @@ namespace config
|
||||
|
||||
// treasury payout {tx-key, output-key, anchor_enc, vie_tag} tuples
|
||||
const std::map<uint64_t, std::tuple<std::string, std::string, std::string, std::string>> TREASURY_SAL1_MINT_OUTPUT_DATA = {
|
||||
{1100, {"0d82afb3ae9c5de25a06da49e24e64d37ba05d6144f9f6153cea325c61407106","81440913c1484891d25010986806a62d1fae1b2fe045e3ac1396413638d594f1","40864bbf80397c05516368a1397eb5c3","220bda"}},
|
||||
{1120, {"a032f2de4d3b5d880d3a636d9786a4a2f586bee360c323bc7521f987a2ada51b","cf8e5eeb5d37996d86c9c4c88fabaabc1ec77bab9cd5ce610a61b49f1e079ce2","9877a989e0216f76a8cdf0a568e57d45","017549"}},
|
||||
{1140, {"51da7a4c34aa20a800ada615a931fbba5fd1b9f7df78f0f911097ad9d99dc230","dd784a5bf1adf9c01cb44946ca094ed4d38f8d9cccf8edfdab397db3b7631dbf","97314be452f184b54f16a558ee8a7dbe","357ac3"}},
|
||||
{1160, {"a0cf49118c62cea834fabae83e12f26939ce170f308adadacf7275226e5cdf6d","7ec9cb2dfac8dfa45bab1bab2b1e31a4291a9e3d939e9c193740cc191d1b720d","4e950acc71ffd4f3835ec79202dc46fd","e7da3a"}},
|
||||
{1180, {"5193e35f6cd3ff8408a442be5eaf4aa1871419ecb0c485546e9d995c4c9c2730","39fb9792b88290b3377036a150a6681334ebe5cb201e2005d2c1d7b212b3df4d","cb458163806a277c7b3513df0d5b0028","1939b5"}},
|
||||
{1200, {"a2c71a7381bc48576f4cb4313cb6264d2a6e82cd2ddcbbd5460bce1db8d5021e","d0c46f29f4bbdd5538d64a438c0ab93cb0586e67fbfc7d1671f0c9809d6a7fac","af38cc2ddccb9229728ef704e360e15a","8a8dc1"}},
|
||||
{1220, {"8358105081510e907c98da59636eef777460513d827aba400efbb81d82aead4c","b2b8e2f9bb13e7527d0ee1bc3ebf0ca5057139ee4f9302251455b9f27dca3b16","dc226161830e952b2533fe34b1dd3c48","fb7c67"}},
|
||||
{1240, {"90b0bc153b97a93eefd59af9b47d26c0c91aadda6203de91a15f2f76fc949074","06e6a11b8742ee78beafe89f894fb9078a514ee6dd4e099182ac982ead37eacc","4fbfd0f3c2b8d514f2c675b37b9f0b6f","3308ad"}},
|
||||
{1260, {"cd10148b3175804b17e3c68a6a5556364d585dee89953904b32f005a5f6d8f14","d9d6f64119776e9c97fe2fb540cdb5f40bea0c40127fda0f1f2b831cb7fa7d2b","9c21b83d29324e2d91774a623219ae28","1d647c"}},
|
||||
{1280, {"5963697782de7db5111d12c853f3fec0dd53f597d80cc376c7945f1d4afa224b","cc5e5b1273c10016dc855ec1d9bfa0bcf4736a748125f5341717ad9d080fbba0","19dd1f9a0cac118564e2ccb9f36be53a","7ab2c2"}},
|
||||
{1300, {"cf1d4d2d21b7b3f1a54889e0688a4654687e28a302a2ac3ad046ac2ad323f97a","5b5926da5e9199f190e86073ebd09ccb867faf1e9887c9e52a47c194915b2575","5775fa47af3c7226f2ec3017470410c9","2b03b3"}},
|
||||
{1320, {"b565ec8842f3e6c22c7a23eb23f0e5684b462d2261681dff7b2ce71ab02ff170","4f94cf4d811574c9fcc27888cc972ebc6c01ae97146b9882d397b77c9232d1fd","9d142686627c918a26b6c6853b911143","685b18"}},
|
||||
{1340, {"50d1b1bcacf36ba14b23b3827e36a02a7610dd3199a9f1b9d0a23ebcbd1c2d54","38818e41cf0ce7d54391978801c58087ddd5fe517dadb5e61d840f27a7a81a52","55328f4bff5120d44c5d76fc5a9dfdbd","d17be2"}},
|
||||
{1360, {"7657bf97a9be9beac5f999a1e2c1226613849c41c12df5d7185d4d6613a27328","63d96a47f29fab0e727d13905cc843df40ccb76b14dc48857d0dd9ec0873e8c5","ab4f7ffa6431452f0fac7eec33e89e3e","5acd14"}},
|
||||
{1380, {"845e4cbe9b9d2462fae2225da698d6a4e18340f06b312545ee9cfda8127abd41","cc65f1f22f863b31f3c4a53ac3987186c2a699f387a2bf08d8dfed54037912c6","bda3aa3bdd2b42e8183c1013e4350c98","d4a418"}},
|
||||
{1400, {"4b11413fcba49df61537427ff35fdd47ee12a8467751236ff22681bbea343d2c","32d22bba59559489f422298ae653ef55ec8c87e8705daf4c89da7187c8574cbd","8868e1c1d788ce4560beb4afbe77aa5a","5a35d9"}}
|
||||
{1100, {"310fe378b82e2475a87c83eef07c57d92fa0731d5c499258e774852158276968","f17c5a62efcc96710f2a173538fe5e79b190b44ab6facc01a619f0e227ac18d1","eb613855f58d093ae9d527e8ab69b46a","6c74f9"}},
|
||||
{1120, {"adb74cea72d46ebe5a45e5886189e71c493308686f076ccfc053cb9b4f55b656","b40e958589238cc48a5a7f03f1f28406a13b2f724efe831cfec43c06bb0fcb60","77a51cc3a6c3c53d631cadad72f57c1d","e5fec0"}},
|
||||
{1140, {"c5e9a67c695ddcab05b980de0c8cc7d9d5b9c09af58047843bfd7d29a038f671","6c3253bd837b899b87aedc97114feb9c10c2d255ce59b7ba5b470817a37d16df","fcf6e1907ea30dbafd510e33a37cc2dc","fa5c45"}},
|
||||
{1160, {"e95c8b7fc3d0e7e34d544e97d3b526e94f70acb7d85cb0053b3cb830e863ac38","3a5ae93e922985ea1a126ff8fd35f6cbf39fa556525e15a049765510eb1360e1","7ea6d62add9387a28f3dbed5dbac120b","c26ac2"}},
|
||||
{1180, {"9d453235a25e470df2d7ceaa8f8d4216a8939a0a93bc0c43f1b902cb461ee82d","2e990ed2de4d745389d88aa9868634ce430f09d2c0cb5ebc2ee8b9bcc23e221a","807e07241a48b97acb537241822a97b8","eb37c0"}},
|
||||
{1200, {"92dbd7da158d4bcb4f002dcc505ed4c49ac4e4782724b506a5977119c80c4869","4505a9be31c2ac6ad5faa2ea8332b85b1a3efee84d0456740d208b8188ad842a","8870c1f88de25b5443d8323759f386d9","443c65"}},
|
||||
{1220, {"1e4d5c44a112c3ac89ab2c7065bb2c8c094779b3a5d696652198f7dd05f88b77","01f56bf134652852688e30dd9559bdb5fe2edd046bed99dbea23b655d2475b89","da088fc1e1c2f2d0e348f06f2079e8ed","d7c7bf"}},
|
||||
{1240, {"91ba144c930a65996b2d7c3b296217c692225756392b580a323838e48b357452","f2d5f4f2aaa599a52c557270cbc5cde138b753a98297d975b74a7223a9b80b13","0dc3a42cb1f36768a09c316790936356","172c22"}},
|
||||
{1260, {"1d626ede8d2e34e888384655b30942a25be272a3ea58d49835265e6933a91a52","05666de1b136236f0682e128c0c3ae84578a6a4b233a578dd676e581a582fe19","c81ccf7f93e01e7872543907de8d17d0","21dd94"}},
|
||||
{1280, {"85b10b5ae72ab59281f47be4edede17b7a017dc7ddd839813e3a12c0b2a39874","d34d259e2fee2b0c977242c473cf83997920c1e64ff7a9c364b2bf4abba4d5cc","43de6ce100ca3eeb6734fc44cc9f7dbc","574e2f"}},
|
||||
{1300, {"c699ca0dcbe538e6be9e997acb50a4c13557d1e8cf3a105ab47406cb68300656","50c5e0fa60907c2c2b66748562193b7f5bfcba269eb398c5c975c9e125933942","05aeb41f8863152a7e0e36f216ecbb12","e413dd"}},
|
||||
{1320, {"76bb126d6e0e5d3d7ee7ccabd194a248cbe006ae7d57f89c31c6826f8e7b4851","e1f2277b378630d92bc03003e3d206899404afde342fcb3a9b1790f798c8b5a4","26274ad1bbf5d483f2c747754b898873","a2df70"}},
|
||||
{1340, {"5738dc94686bfffe1789b695785f270f6f616b1a52e071e975cf915063233b1a","982b4848ed74f2a5d899f778b182c35f40535579349435b466ff98c3fce678e7","67bd9b9a434b9028564a065a30ae34fa","36ceec"}},
|
||||
{1360, {"473b6f6941d6eafaef007d3d932763b6e39c1428d3ba76dfff452ddc67f93b48","76e3b1280b959672d86c357e6f5fcd8a74e61a0a948a0541a0eb384060705bac","74b5ad8847471e3d8723ad3e101b8a13","5e5671"}},
|
||||
{1380, {"6dae9a14e24b96caf8f7acb0edad936a4ecaa194a61b3785a2b1d08cbca0a158","26ca204c10481ed2447447e3893e0c46c9f01df16c3f3a671cf9e6054176ee5d","7c04e4ed28bfac12a0050bdae44f9979","4c23ad"}},
|
||||
{1400, {"a5837480d8e17ddb9b29baaf5671545d59d18b546de0d7092768882cff94d125","dc76eb3892b3721da947fc71de8ab30ef32651f1b6bb1a45eb7b80882217a5ac","bb490940a3cdf4a17fd0bec0b578531f","84d899"}}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -1348,11 +1348,6 @@ bool Blockchain::prevalidate_miner_transaction(const block& b, uint64_t height,
|
||||
CHECK_AND_ASSERT_MES(b.miner_tx.vin[0].type() == typeid(txin_gen), false, "coinbase transaction in the block has the wrong type");
|
||||
CHECK_AND_ASSERT_MES(b.miner_tx.version > 1, false, "Invalid coinbase transaction version");
|
||||
|
||||
if (hf_version >= HF_VERSION_CARROT) {
|
||||
CHECK_AND_ASSERT_MES(b.miner_tx.version == TRANSACTION_VERSION_CARROT, false, "miner transaction has wrong version");
|
||||
CHECK_AND_ASSERT_MES(b.miner_tx.type == cryptonote::transaction_type::MINER, false, "miner transaction has wrong type");
|
||||
}
|
||||
|
||||
// for v2 txes (ringct), we only accept empty rct signatures for miner transactions,
|
||||
if (hf_version >= HF_VERSION_REJECT_SIGS_IN_COINBASE && b.miner_tx.version >= 2)
|
||||
{
|
||||
@@ -1403,16 +1398,6 @@ bool Blockchain::prevalidate_protocol_transaction(const block& b, uint64_t heigh
|
||||
CHECK_AND_ASSERT_MES(b.protocol_tx.vin[0].type() == typeid(txin_gen), false, "coinbase protocol transaction in the block has the wrong type");
|
||||
CHECK_AND_ASSERT_MES(b.protocol_tx.version > 1, false, "Invalid coinbase protocol transaction version");
|
||||
|
||||
if (hf_version >= HF_VERSION_CARROT) {
|
||||
CHECK_AND_ASSERT_MES(b.protocol_tx.version == TRANSACTION_VERSION_CARROT || 2, false, "protocol transaction has wrong version");
|
||||
CHECK_AND_ASSERT_MES(b.protocol_tx.type == cryptonote::transaction_type::PROTOCOL, false, "protocol transaction has wrong type");
|
||||
}
|
||||
|
||||
if (hf_version >= HF_VERSION_ENFORCE_CARROT) {
|
||||
CHECK_AND_ASSERT_MES(b.protocol_tx.version == TRANSACTION_VERSION_CARROT, false, "protocol transaction has wrong version");
|
||||
CHECK_AND_ASSERT_MES(b.protocol_tx.type == cryptonote::transaction_type::PROTOCOL, false, "protocol transaction has wrong type");
|
||||
}
|
||||
|
||||
// for v2 txes (ringct), we only accept empty rct signatures for protocol transactions,
|
||||
if (hf_version >= HF_VERSION_REJECT_SIGS_IN_COINBASE && b.protocol_tx.version >= 2)
|
||||
{
|
||||
@@ -1521,7 +1506,6 @@ bool Blockchain::validate_miner_transaction(const block& b, size_t cumulative_bl
|
||||
case HF_VERSION_AUDIT2:
|
||||
case HF_VERSION_AUDIT2_PAUSE:
|
||||
case HF_VERSION_CARROT:
|
||||
case HF_VERSION_ENFORCE_CARROT:
|
||||
if (b.miner_tx.amount_burnt > 0) {
|
||||
CHECK_AND_ASSERT_MES(money_in_use + b.miner_tx.amount_burnt > money_in_use, false, "miner transaction is overflowed by amount_burnt");
|
||||
money_in_use += b.miner_tx.amount_burnt;
|
||||
@@ -1589,7 +1573,7 @@ bool Blockchain::validate_protocol_transaction(const block& b, uint64_t height,
|
||||
LOG_PRINT_L1("Block at height: " << height << " - no yield payouts due - skipping");
|
||||
} else {
|
||||
// Iterate over the cached data for block yield, calculating the yield payouts due
|
||||
if (get_ideal_hard_fork_version(matured_height) >= HF_VERSION_CARROT) {
|
||||
if (hf_version >= HF_VERSION_CARROT) {
|
||||
if (!calculate_yield_payouts(matured_height, carrot_yield_payouts)) {
|
||||
LOG_ERROR("Block at height: " << height << " - Failed to obtain carrot yield payout information - aborting");
|
||||
return false;
|
||||
@@ -1637,7 +1621,7 @@ bool Blockchain::validate_protocol_transaction(const block& b, uint64_t height,
|
||||
);
|
||||
|
||||
if (hf_version >= HF_VERSION_CARROT) {
|
||||
|
||||
// TODO: add other verifications for carrot yield payouts
|
||||
size_t output_idx = 0;
|
||||
for (auto it = carrot_yield_payouts.begin(); it != carrot_yield_payouts.end(); it++, output_idx++) {
|
||||
// Verify the output key
|
||||
@@ -1645,16 +1629,6 @@ bool Blockchain::validate_protocol_transaction(const block& b, uint64_t height,
|
||||
cryptonote::get_output_public_key(b.protocol_tx.vout[output_idx], out_key);
|
||||
CHECK_AND_ASSERT_MES(out_key == it->first.return_address, false, "Incorrect output key detected in protocol_tx");
|
||||
|
||||
// Verify the return pubkey
|
||||
if (b.protocol_tx.vout.size() > 1) {
|
||||
const auto additional_pubkeys = cryptonote::get_additional_tx_pub_keys_from_extra(b.protocol_tx.extra);
|
||||
CHECK_AND_ASSERT_MES(additional_pubkeys.size() > output_idx, false, "Missing return pubkey detected in protocol_tx");
|
||||
CHECK_AND_ASSERT_MES(additional_pubkeys[output_idx] == it->first.return_pubkey, false, "Incorrect return pubkey detected in protocol_tx");
|
||||
} else {
|
||||
const auto main_pubkey = cryptonote::get_tx_pub_key_from_extra(b.protocol_tx.extra);
|
||||
CHECK_AND_ASSERT_MES(main_pubkey == it->first.return_pubkey, false, "Incorrect return pubkey detected in protocol_tx");
|
||||
}
|
||||
|
||||
// Verify the output amount
|
||||
uint64_t expected_amount = it->second;
|
||||
CHECK_AND_ASSERT_MES(b.protocol_tx.vout[output_idx].amount == expected_amount, false, "Incorrect output amount detected in protocol_tx. expected_amount: " << expected_amount);
|
||||
@@ -1662,21 +1636,11 @@ bool Blockchain::validate_protocol_transaction(const block& b, uint64_t height,
|
||||
// Verify the output asset type
|
||||
std::string out_asset_type;
|
||||
cryptonote::get_output_asset_type(b.protocol_tx.vout[output_idx], out_asset_type);
|
||||
CHECK_AND_ASSERT_MES(out_asset_type == "SAL1", false, "Incorrect output asset_type (!= SAL1) detected in protocol_tx");
|
||||
|
||||
// Verify the view tag
|
||||
CHECK_AND_ASSERT_MES(
|
||||
boost::get<cryptonote::txout_to_carrot_v1>(
|
||||
b.protocol_tx.vout[output_idx].target
|
||||
).view_tag == it->first.return_view_tag, false, "Incorrect view tag detected in protocol_tx"
|
||||
);
|
||||
|
||||
// Verify the anchor encrypted
|
||||
CHECK_AND_ASSERT_MES(
|
||||
boost::get<cryptonote::txout_to_carrot_v1>(
|
||||
b.protocol_tx.vout[output_idx].target
|
||||
).encrypted_janus_anchor == it->first.return_anchor_enc, false, "Incorrect anchor detected in protocol_tx"
|
||||
);
|
||||
uint8_t hf_yield = m_hardfork->get_ideal_version(it->first.block_height);
|
||||
if (hf_yield >= HF_VERSION_SALVIUM_ONE_PROOFS)
|
||||
CHECK_AND_ASSERT_MES(out_asset_type == "SAL1", false, "Incorrect output asset_type (!= SAL1) detected in protocol_tx");
|
||||
else
|
||||
CHECK_AND_ASSERT_MES(out_asset_type == "SAL", false, "Incorrect output asset_type (!= SAL) detected in protocol_tx");
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -1987,14 +1951,11 @@ bool Blockchain::create_block_template(block& b, const crypto::hash *from_block,
|
||||
cryptonote::yield_block_info ybi_matured;
|
||||
bool ok = get_ybi_entry(start_height, ybi_matured);
|
||||
if (ok && ybi_matured.locked_coins_this_block > 0) {
|
||||
|
||||
// Work out what the asset_type should be based on height of submission
|
||||
uint8_t hf_submitted = m_hardfork->get_ideal_version(start_height);
|
||||
|
||||
|
||||
// Iterate over the cached data for block yield, calculating the yield payouts due
|
||||
std::vector<std::pair<yield_tx_info, uint64_t>> yield_payouts;
|
||||
std::vector<std::pair<yield_tx_info_carrot, uint64_t>> carrot_yield_payouts;
|
||||
if (hf_submitted >= HF_VERSION_CARROT) {
|
||||
std::vector<std::pair<yield_tx_info_carrot, uint64_t>> carrot_yield_payouts;
|
||||
if (b.major_version >= HF_VERSION_CARROT) {
|
||||
if (!calculate_yield_payouts(start_height, carrot_yield_payouts)) {
|
||||
LOG_ERROR("Failed to obtain yield payout information - aborting");
|
||||
return false;
|
||||
@@ -2006,8 +1967,11 @@ bool Blockchain::create_block_template(block& b, const crypto::hash *from_block,
|
||||
}
|
||||
}
|
||||
|
||||
// Work out what the asset_type should be based on height of submission
|
||||
uint8_t hf_submitted = m_hardfork->get_ideal_version(start_height);
|
||||
|
||||
// Create the protocol_metadata entries here
|
||||
if (!carrot_yield_payouts.empty()) {
|
||||
if (b.major_version >= HF_VERSION_CARROT) {
|
||||
for (const auto& yield_entry: carrot_yield_payouts) {
|
||||
cryptonote::protocol_data_entry entry;
|
||||
entry.amount_burnt = yield_entry.second;
|
||||
@@ -2026,7 +1990,6 @@ bool Blockchain::create_block_template(block& b, const crypto::hash *from_block,
|
||||
entry.origin_height = start_height;
|
||||
entry.return_view_tag = yield_entry.first.return_view_tag;
|
||||
entry.return_anchor_enc = yield_entry.first.return_anchor_enc;
|
||||
entry.is_carrot = true;
|
||||
protocol_entries.push_back(entry);
|
||||
}
|
||||
} else {
|
||||
@@ -2047,7 +2010,6 @@ bool Blockchain::create_block_template(block& b, const crypto::hash *from_block,
|
||||
entry.P_change = yield_entry.first.P_change;
|
||||
entry.return_pubkey = yield_entry.first.return_pubkey;
|
||||
entry.origin_height = start_height;
|
||||
entry.is_carrot = false;
|
||||
protocol_entries.push_back(entry);
|
||||
}
|
||||
}
|
||||
@@ -3723,7 +3685,7 @@ bool Blockchain::check_tx_outputs(const transaction& tx, tx_verification_context
|
||||
*/
|
||||
|
||||
if (hf_version >= HF_VERSION_CARROT) {
|
||||
// from v10, force the new SalviumOne RCT data
|
||||
// from v11, force the new SalviumOne RCT data
|
||||
if (tx.type == cryptonote::transaction_type::TRANSFER || tx.type == cryptonote::transaction_type::STAKE || tx.type == cryptonote::transaction_type::BURN || tx.type == cryptonote::transaction_type::CONVERT || tx.type == cryptonote::transaction_type::AUDIT) {
|
||||
if (tx.rct_signatures.type != rct::RCTTypeSalviumOne) {
|
||||
MERROR_VER("SalviumOne data required after v" + std::to_string(HF_VERSION_CARROT));
|
||||
@@ -3798,7 +3760,7 @@ bool Blockchain::check_tx_type_and_version(const transaction& tx, tx_verificatio
|
||||
}
|
||||
|
||||
// Check for v1 TXs - genesis block protocol_tx exception required!
|
||||
if (tx.version == 1) {
|
||||
if (tx.version == 1 && epee::string_tools::pod_to_hex(cryptonote::get_transaction_hash(tx)) == "4f78ff511e860acd03138737a71505eb62eb78b620e180e58c8e13ed0e1e3e19") {
|
||||
MERROR("v1 TXs are not permitted");
|
||||
tvc.m_version_mismatch = true;
|
||||
return false;
|
||||
@@ -3831,32 +3793,6 @@ bool Blockchain::check_tx_type_and_version(const transaction& tx, tx_verificatio
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (tx.type == cryptonote::transaction_type::AUDIT) {
|
||||
// Make sure we are supposed to accept AUDIT txs at this point
|
||||
const std::map<uint8_t, std::pair<uint64_t, std::pair<std::string, std::string>>> audit_hard_forks = get_config(m_nettype).AUDIT_HARD_FORKS;
|
||||
CHECK_AND_ASSERT_MES(audit_hard_forks.find(hf_version) != audit_hard_forks.end(), false, "trying to audit outside an audit fork");
|
||||
std::string expected_asset_type = audit_hard_forks.at(hf_version).second.first;
|
||||
CHECK_AND_ASSERT_MES(tx.source_asset_type == expected_asset_type, false, "trying to spend " << tx.source_asset_type << " coins in an AUDIT TX");
|
||||
} else {
|
||||
if (hf_version >= HF_VERSION_SALVIUM_ONE_PROOFS) {
|
||||
CHECK_AND_ASSERT_MES(tx.source_asset_type == "SAL1", false, "trying to spend " << tx.source_asset_type << " coins in a non-AUDIT TX");
|
||||
} else {
|
||||
CHECK_AND_ASSERT_MES(tx.source_asset_type == "SAL", false, "trying to spend " << tx.source_asset_type << " coins in a non-AUDIT TX");
|
||||
}
|
||||
}
|
||||
|
||||
if (tx.type == cryptonote::transaction_type::BURN) {
|
||||
CHECK_AND_ASSERT_MES(tx.destination_asset_type == "BURN", false, "incorrect burn tx destination type:" << tx.destination_asset_type);
|
||||
} else {
|
||||
if (tx.source_asset_type != tx.destination_asset_type) {
|
||||
MERROR_VER("Tx " << get_transaction_hash(tx) << " has mismatched asset types: " << tx.source_asset_type << " != " << tx.destination_asset_type);
|
||||
tvc.m_verifivation_failed = true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Check for invalid TX types
|
||||
if (tx.type == cryptonote::transaction_type::UNSET || tx.type > cryptonote::transaction_type::MAX) {
|
||||
MERROR("TX type `" + std::to_string(tx.type) + "' is not supported");
|
||||
@@ -4120,6 +4056,20 @@ bool Blockchain::check_tx_inputs(transaction& tx, tx_verification_context &tvc,
|
||||
}
|
||||
}
|
||||
|
||||
if (tx.type == cryptonote::transaction_type::AUDIT) {
|
||||
// Make sure we are supposed to accept AUDIT txs at this point
|
||||
const std::map<uint8_t, std::pair<uint64_t, std::pair<std::string, std::string>>> audit_hard_forks = get_config(m_nettype).AUDIT_HARD_FORKS;
|
||||
CHECK_AND_ASSERT_MES(audit_hard_forks.find(hf_version) != audit_hard_forks.end(), false, "trying to audit outside an audit fork");
|
||||
std::string expected_asset_type = audit_hard_forks.at(hf_version).second.first;
|
||||
CHECK_AND_ASSERT_MES(tx.source_asset_type == expected_asset_type, false, "trying to spend " << tx.source_asset_type << " coins in an AUDIT TX");
|
||||
} else {
|
||||
if (hf_version >= HF_VERSION_SALVIUM_ONE_PROOFS) {
|
||||
CHECK_AND_ASSERT_MES(tx.source_asset_type == "SAL1", false, "trying to spend " << tx.source_asset_type << " coins in a non-AUDIT TX");
|
||||
} else {
|
||||
CHECK_AND_ASSERT_MES(tx.source_asset_type == "SAL", false, "trying to spend " << tx.source_asset_type << " coins in a non-AUDIT TX");
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::vector<rct::ctkey>> pubkeys(tx.vin.size());
|
||||
std::vector < uint64_t > results;
|
||||
results.resize(tx.vin.size(), 0);
|
||||
@@ -4723,7 +4673,7 @@ bool Blockchain::calculate_yield_payouts(const uint64_t start_height, std::vecto
|
||||
if (!yield_entries.size()) {
|
||||
|
||||
// Report error and abort
|
||||
LOG_ERROR("calculate_yield_payouts() called for carrot, but no yield TXs found at height " << start_height << " - aborting");
|
||||
LOG_ERROR("calculate_yield_payouts() called, but no yield TXs found at height " << start_height << " - aborting");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -4759,14 +4709,10 @@ bool Blockchain::calculate_yield_payouts(const uint64_t start_height, std::vecto
|
||||
|
||||
// Iterate over the yield_container, adding each proportion of the yield
|
||||
for (auto& entry: yield_container) {
|
||||
|
||||
boost::multiprecision::int128_t locked_coins_128 = entry.first.locked_coins;
|
||||
boost::multiprecision::int128_t yield_128 = (slippage_128 * locked_coins_128) / locked_total_128;
|
||||
uint64_t yield_u64 = boost::numeric_cast<uint64_t>(yield_128);
|
||||
|
||||
if (entry.second + yield_u64 < entry.second) {
|
||||
throw std::overflow_error("uint64_t addition overflow");
|
||||
}
|
||||
entry.second += yield_u64;
|
||||
entry.second += yield_128.convert_to<uint64_t>();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4825,14 +4771,10 @@ bool Blockchain::calculate_yield_payouts(const uint64_t start_height, std::vecto
|
||||
|
||||
// Iterate over the yield_container, adding each proportion of the yield
|
||||
for (auto& entry: yield_container) {
|
||||
|
||||
boost::multiprecision::int128_t locked_coins_128 = entry.first.locked_coins;
|
||||
boost::multiprecision::int128_t yield_128 = (slippage_128 * locked_coins_128) / locked_total_128;
|
||||
uint64_t yield_u64 = boost::numeric_cast<uint64_t>(yield_128);
|
||||
|
||||
if (entry.second + yield_u64 < entry.second) {
|
||||
throw std::overflow_error("uint64_t addition overflow");
|
||||
}
|
||||
entry.second += yield_u64;
|
||||
entry.second += yield_128.convert_to<uint64_t>();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1022,7 +1022,7 @@ namespace cryptonote
|
||||
}
|
||||
if (!rvv.empty())
|
||||
{
|
||||
LOG_PRINT_L1("Verifying transactions one at a time");
|
||||
LOG_PRINT_L1("One transaction among this group has bad semantics, verifying one at a time");
|
||||
ret = false;
|
||||
for (size_t n = 0; n < tx_info.size(); ++n)
|
||||
{
|
||||
|
||||
@@ -346,27 +346,14 @@ namespace cryptonote
|
||||
|
||||
// Clear the TX contents
|
||||
tx.set_null();
|
||||
tx.version = 2;
|
||||
bool carrot_found = false;
|
||||
bool noncarrot_found = false;
|
||||
tx.type = cryptonote::transaction_type::PROTOCOL;
|
||||
|
||||
// Scan the protocol_data to make sure all or none are Carrot
|
||||
for (auto const& entry: protocol_data) {
|
||||
if (entry.is_carrot) carrot_found = true;
|
||||
else noncarrot_found = true;
|
||||
}
|
||||
|
||||
if (carrot_found && noncarrot_found) {
|
||||
LOG_ERROR("Cannot mix Carrot and non-Carrot outputs in the same protocol transaction");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (carrot_found || hard_fork_version >= HF_VERSION_ENFORCE_CARROT)
|
||||
{
|
||||
// Force the TX type to 2
|
||||
tx.version = 2;
|
||||
|
||||
// Ensure the TX version is correct
|
||||
tx.version = TRANSACTION_VERSION_CARROT;
|
||||
const bool do_carrot = hard_fork_version >= HF_VERSION_CARROT;
|
||||
if (do_carrot)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Create a vector of enotes
|
||||
@@ -386,6 +373,7 @@ namespace cryptonote
|
||||
memcpy(e.enote_ephemeral_pubkey.data, entry.return_pubkey.data, sizeof(crypto::public_key));
|
||||
enotes.push_back(e);
|
||||
}
|
||||
|
||||
tx = store_carrot_to_coinbase_transaction_v1(enotes, std::string{}, cryptonote::transaction_type::PROTOCOL, height);
|
||||
tx.amount_burnt = 0;
|
||||
tx.invalidate_hashes();
|
||||
@@ -408,29 +396,14 @@ namespace cryptonote
|
||||
std::vector<crypto::public_key> additional_tx_public_keys;
|
||||
for (auto const& entry: protocol_data) {
|
||||
if (entry.type == cryptonote::transaction_type::STAKE) {
|
||||
|
||||
// PAYOUT
|
||||
LOG_PRINT_L2("Yield TX payout submitted " << entry.amount_burnt << entry.source_asset);
|
||||
|
||||
if (entry.is_carrot) {
|
||||
tx_out out;
|
||||
out.amount = entry.amount_burnt;
|
||||
out.target = txout_to_carrot_v1 {
|
||||
.key = entry.return_address,
|
||||
.asset_type = entry.destination_asset,
|
||||
.view_tag = entry.return_view_tag,
|
||||
.encrypted_janus_anchor = entry.return_anchor_enc,
|
||||
};
|
||||
|
||||
additional_tx_public_keys.push_back(entry.return_pubkey);
|
||||
tx.vout.push_back(out);
|
||||
} else {
|
||||
// Create the TX output for this refund
|
||||
tx_out out;
|
||||
cryptonote::set_tx_out(entry.amount_burnt, entry.destination_asset, CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW, entry.return_address, false, crypto::view_tag{}, out);
|
||||
additional_tx_public_keys.push_back(entry.return_pubkey);
|
||||
tx.vout.push_back(out);
|
||||
}
|
||||
// Create the TX output for this refund
|
||||
tx_out out;
|
||||
cryptonote::set_tx_out(entry.amount_burnt, entry.destination_asset, CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW, entry.return_address, false, crypto::view_tag{}, out);
|
||||
additional_tx_public_keys.push_back(entry.return_pubkey);
|
||||
tx.vout.push_back(out);
|
||||
} else if (entry.type == cryptonote::transaction_type::AUDIT) {
|
||||
// PAYOUT
|
||||
LOG_PRINT_L2("Audit TX payout submitted " << entry.amount_burnt << entry.source_asset);
|
||||
@@ -594,7 +567,6 @@ namespace cryptonote
|
||||
case HF_VERSION_AUDIT2:
|
||||
case HF_VERSION_AUDIT2_PAUSE:
|
||||
case HF_VERSION_CARROT:
|
||||
case HF_VERSION_ENFORCE_CARROT:
|
||||
// SRCG: subtract 20% that will be rewarded to staking users
|
||||
CHECK_AND_ASSERT_MES(tx.amount_burnt == 0, false, "while creating outs: amount_burnt is nonzero");
|
||||
tx.amount_burnt = amount / 5;
|
||||
|
||||
@@ -71,7 +71,6 @@ namespace cryptonote
|
||||
carrot::view_tag_t return_view_tag;
|
||||
carrot::encrypted_janus_anchor_t return_anchor_enc;
|
||||
uint64_t origin_height;
|
||||
bool is_carrot;
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------
|
||||
|
||||
@@ -92,9 +92,6 @@ const hardfork_t testnet_hard_forks[] = {
|
||||
|
||||
// version 10 Carrot - including treasury mint - starts from block 1100
|
||||
{10, 1100, 0, 1739780005 },
|
||||
|
||||
// version 11 Carrot and CryptoNote starts from block 1200
|
||||
{11, 1200, 0, 1756811153 },
|
||||
};
|
||||
const size_t num_testnet_hard_forks = sizeof(testnet_hard_forks) / sizeof(testnet_hard_forks[0]);
|
||||
const uint64_t testnet_hard_fork_version_1_till = ((uint64_t)-1);
|
||||
|
||||
@@ -733,9 +733,9 @@ namespace nodetool
|
||||
std::set<std::string> full_addrs;
|
||||
if (m_nettype == cryptonote::TESTNET)
|
||||
{
|
||||
full_addrs.insert("165.22.6.67:29080");
|
||||
full_addrs.insert("165.22.15.162:29080");
|
||||
full_addrs.insert("162.243.163.207:29080");
|
||||
full_addrs.insert("72.5.43.63:29080");
|
||||
full_addrs.insert("195.85.114.217:29080");
|
||||
full_addrs.insert("206.188.197.72:29080");
|
||||
}
|
||||
else if (m_nettype == cryptonote::STAGENET)
|
||||
{
|
||||
|
||||
@@ -38,7 +38,6 @@
|
||||
#include "crypto/crypto.h"
|
||||
#include "crypto/hash.h"
|
||||
#include "mx25519.h"
|
||||
#include "carrot_core/core_types.h"
|
||||
|
||||
// read
|
||||
template <template <bool> class Archive>
|
||||
@@ -86,7 +85,6 @@ BLOB_SERIALIZER(crypto::public_key);
|
||||
BLOB_SERIALIZER(crypto::secret_key);
|
||||
BLOB_SERIALIZER(crypto::key_derivation);
|
||||
BLOB_SERIALIZER(crypto::key_image);
|
||||
BLOB_SERIALIZER(carrot::input_context_t);
|
||||
BLOB_SERIALIZER(crypto::signature);
|
||||
BLOB_SERIALIZER(crypto::view_tag);
|
||||
BLOB_SERIALIZER(crypto::ec_point);
|
||||
@@ -97,7 +95,6 @@ VARIANT_TAG(debug_archive, crypto::public_key, "public_key");
|
||||
VARIANT_TAG(debug_archive, crypto::secret_key, "secret_key");
|
||||
VARIANT_TAG(debug_archive, crypto::key_derivation, "key_derivation");
|
||||
VARIANT_TAG(debug_archive, crypto::key_image, "key_image");
|
||||
VARIANT_TAG(debug_archive, carrot::input_context_t, "input_context");
|
||||
VARIANT_TAG(debug_archive, crypto::signature, "signature");
|
||||
VARIANT_TAG(debug_archive, crypto::view_tag, "view_tag");
|
||||
VARIANT_TAG(debug_archive, crypto::ec_point, "ec_point");
|
||||
|
||||
@@ -192,7 +192,6 @@ namespace
|
||||
const command_line::arg_descriptor<std::string> arg_generate_new_wallet = {"generate-new-wallet", sw::tr("Generate new wallet and save it to <arg>"), ""};
|
||||
const command_line::arg_descriptor<std::string> arg_generate_from_device = {"generate-from-device", sw::tr("Generate new wallet from device and save it to <arg>"), ""};
|
||||
const command_line::arg_descriptor<std::string> arg_generate_from_view_key = {"generate-from-view-key", sw::tr("Generate incoming-only wallet from view key"), ""};
|
||||
const command_line::arg_descriptor<std::string> arg_generate_from_svb_key = {"generate-from-svb-key", sw::tr("Generate full view-only wallet from view key"), ""};
|
||||
const command_line::arg_descriptor<std::string> arg_generate_from_spend_key = {"generate-from-spend-key", sw::tr("Generate deterministic wallet from spend key"), ""};
|
||||
const command_line::arg_descriptor<std::string> arg_generate_from_keys = {"generate-from-keys", sw::tr("Generate wallet from private keys"), ""};
|
||||
const command_line::arg_descriptor<std::string> arg_generate_from_multisig_keys = {"generate-from-multisig-keys", sw::tr("Generate a master wallet from multisig wallet keys"), ""};
|
||||
@@ -4425,12 +4424,12 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm)
|
||||
|
||||
bool welcome = false;
|
||||
|
||||
if((!m_generate_new.empty()) + (!m_wallet_file.empty()) + (!m_generate_from_device.empty()) + (!m_generate_from_view_key.empty()) + (!m_generate_from_svb_key.empty()) + (!m_generate_from_spend_key.empty()) + (!m_generate_from_keys.empty()) + (!m_generate_from_multisig_keys.empty()) + (!m_generate_from_json.empty()) > 1)
|
||||
if((!m_generate_new.empty()) + (!m_wallet_file.empty()) + (!m_generate_from_device.empty()) + (!m_generate_from_view_key.empty()) + (!m_generate_from_spend_key.empty()) + (!m_generate_from_keys.empty()) + (!m_generate_from_multisig_keys.empty()) + (!m_generate_from_json.empty()) > 1)
|
||||
{
|
||||
fail_msg_writer() << tr("can't specify more than one of --generate-new-wallet=\"wallet_name\", --wallet-file=\"wallet_name\", --generate-from-view-key=\"wallet_name\", --generate-from-svb-key=\"wallet_name\", --generate-from-spend-key=\"wallet_name\", --generate-from-keys=\"wallet_name\", --generate-from-multisig-keys=\"wallet_name\", --generate-from-json=\"jsonfilename\" and --generate-from-device=\"wallet_name\"");
|
||||
fail_msg_writer() << tr("can't specify more than one of --generate-new-wallet=\"wallet_name\", --wallet-file=\"wallet_name\", --generate-from-view-key=\"wallet_name\", --generate-from-spend-key=\"wallet_name\", --generate-from-keys=\"wallet_name\", --generate-from-multisig-keys=\"wallet_name\", --generate-from-json=\"jsonfilename\" and --generate-from-device=\"wallet_name\"");
|
||||
return false;
|
||||
}
|
||||
else if (m_generate_new.empty() && m_wallet_file.empty() && m_generate_from_device.empty() && m_generate_from_view_key.empty() && m_generate_from_svb_key.empty() && m_generate_from_spend_key.empty() && m_generate_from_keys.empty() && m_generate_from_multisig_keys.empty() && m_generate_from_json.empty())
|
||||
else if (m_generate_new.empty() && m_wallet_file.empty() && m_generate_from_device.empty() && m_generate_from_view_key.empty() && m_generate_from_spend_key.empty() && m_generate_from_keys.empty() && m_generate_from_multisig_keys.empty() && m_generate_from_json.empty())
|
||||
{
|
||||
if(!ask_wallet_create_if_needed()) return false;
|
||||
}
|
||||
@@ -4585,69 +4584,6 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm)
|
||||
password = *r;
|
||||
welcome = true;
|
||||
}
|
||||
else if (!m_generate_from_svb_key.empty())
|
||||
{
|
||||
m_wallet_file = m_generate_from_svb_key;
|
||||
// parse address
|
||||
std::string address_string = input_line("Standard address");
|
||||
if (std::cin.eof())
|
||||
return false;
|
||||
if (address_string.empty()) {
|
||||
fail_msg_writer() << tr("No data supplied, cancelled");
|
||||
return false;
|
||||
}
|
||||
cryptonote::address_parse_info info;
|
||||
if(!get_account_address_from_str(info, nettype, address_string))
|
||||
{
|
||||
fail_msg_writer() << tr("failed to parse address");
|
||||
return false;
|
||||
}
|
||||
if (info.is_subaddress)
|
||||
{
|
||||
fail_msg_writer() << tr("This address is a subaddress which cannot be used here.");
|
||||
return false;
|
||||
}
|
||||
if (!info.is_carrot)
|
||||
{
|
||||
fail_msg_writer() << tr("This address is not a Carrot address, and cannot be used here.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// parse view secret key
|
||||
epee::wipeable_string viewkey_string = input_secure_line("Secret view key");
|
||||
if (std::cin.eof())
|
||||
return false;
|
||||
if (viewkey_string.empty()) {
|
||||
fail_msg_writer() << tr("No data supplied, cancelled");
|
||||
return false;
|
||||
}
|
||||
crypto::secret_key viewkey;
|
||||
if (!viewkey_string.hex_to_pod(unwrap(unwrap(viewkey))))
|
||||
{
|
||||
fail_msg_writer() << tr("failed to parse view key secret key");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Create all of the necessary keys for Carrot view-only wallet
|
||||
|
||||
/*
|
||||
// check the view key matches the given address
|
||||
crypto::public_key pkey;
|
||||
if (!crypto::secret_key_to_public_key(viewkey, pkey)) {
|
||||
fail_msg_writer() << tr("failed to verify view key secret key");
|
||||
return false;
|
||||
}
|
||||
if (info.address.m_view_public_key != pkey) {
|
||||
fail_msg_writer() << tr("view key does not match standard address");
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
|
||||
auto r = new_wallet(vm, info.address, boost::none, viewkey);
|
||||
CHECK_AND_ASSERT_MES(r, false, tr("account creation failed"));
|
||||
password = *r;
|
||||
welcome = true;
|
||||
}
|
||||
else if (!m_generate_from_spend_key.empty())
|
||||
{
|
||||
m_wallet_file = m_generate_from_spend_key;
|
||||
@@ -5113,7 +5049,6 @@ bool simple_wallet::handle_command_line(const boost::program_options::variables_
|
||||
m_generate_new = command_line::get_arg(vm, arg_generate_new_wallet);
|
||||
m_generate_from_device = command_line::get_arg(vm, arg_generate_from_device);
|
||||
m_generate_from_view_key = command_line::get_arg(vm, arg_generate_from_view_key);
|
||||
m_generate_from_svb_key = command_line::get_arg(vm, arg_generate_from_svb_key);
|
||||
m_generate_from_spend_key = command_line::get_arg(vm, arg_generate_from_spend_key);
|
||||
m_generate_from_keys = command_line::get_arg(vm, arg_generate_from_keys);
|
||||
m_generate_from_multisig_keys = command_line::get_arg(vm, arg_generate_from_multisig_keys);
|
||||
@@ -5129,7 +5064,6 @@ bool simple_wallet::handle_command_line(const boost::program_options::variables_
|
||||
m_subaddress_lookahead = command_line::get_arg(vm, arg_subaddress_lookahead);
|
||||
m_use_english_language_names = command_line::get_arg(vm, arg_use_english_language_names);
|
||||
m_restoring = !m_generate_from_view_key.empty() ||
|
||||
!m_generate_from_svb_key.empty() ||
|
||||
!m_generate_from_spend_key.empty() ||
|
||||
!m_generate_from_keys.empty() ||
|
||||
!m_generate_from_multisig_keys.empty() ||
|
||||
@@ -5353,9 +5287,8 @@ boost::optional<epee::wipeable_string> simple_wallet::new_wallet(const boost::pr
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
boost::optional<epee::wipeable_string> simple_wallet::new_wallet(const boost::program_options::variables_map& vm,
|
||||
const cryptonote::account_public_address& address,
|
||||
const boost::optional<crypto::secret_key>& spendkey,
|
||||
const crypto::secret_key& viewkey)
|
||||
const cryptonote::account_public_address& address, const boost::optional<crypto::secret_key>& spendkey,
|
||||
const crypto::secret_key& viewkey)
|
||||
{
|
||||
std::pair<std::unique_ptr<tools::wallet2>, tools::password_container> rc;
|
||||
try { rc = tools::wallet2::make_new(vm, false, password_prompter); }
|
||||
@@ -7772,6 +7705,7 @@ bool simple_wallet::sweep_unmixable(const std::vector<std::string> &args_)
|
||||
bool simple_wallet::sweep_main(uint32_t account, uint64_t below, bool locked, const std::vector<std::string> &args_)
|
||||
{
|
||||
CHECK_IF_BACKGROUND_SYNCING("cannot sweep");
|
||||
std::string asset_type = (args_.size() > 1) ? args_.back() : (m_wallet->get_current_hard_fork() >= HF_VERSION_SALVIUM_ONE_PROOFS) ? "SAL1" : "SAL";
|
||||
auto print_usage = [this, account, below]()
|
||||
{
|
||||
if (below)
|
||||
@@ -7904,8 +7838,6 @@ bool simple_wallet::sweep_main(uint32_t account, uint64_t below, bool locked, co
|
||||
}
|
||||
}
|
||||
|
||||
std::string asset_type = (m_wallet->get_current_hard_fork() >= HF_VERSION_SALVIUM_ONE_PROOFS) ? "SAL1" : "SAL";
|
||||
|
||||
std::vector<uint8_t> extra;
|
||||
bool payment_id_seen = false;
|
||||
if (local_args.size() >= 2)
|
||||
@@ -7997,8 +7929,8 @@ bool simple_wallet::sweep_main(uint32_t account, uint64_t below, bool locked, co
|
||||
prompt << tr("WARNING: Outputs of multiple addresses are being used together, which might potentially compromise your privacy.\n");
|
||||
}
|
||||
|
||||
// if (!process_ring_members(ptx_vector, prompt, m_wallet->print_ring_members()))
|
||||
// return true;
|
||||
if (!process_ring_members(ptx_vector, prompt, m_wallet->print_ring_members()))
|
||||
return true;
|
||||
|
||||
if (ptx_vector.size() > 1) {
|
||||
prompt << boost::format(tr("Sweeping %s in %llu transactions for a total fee of %s. Is this okay?")) %
|
||||
@@ -11144,7 +11076,7 @@ bool simple_wallet::address_book(const std::vector<std::string> &args/* = std::v
|
||||
description += " ";
|
||||
description += args[i];
|
||||
}
|
||||
m_wallet->add_address_book_row(info.address, info.has_payment_id ? &info.payment_id : NULL, description, info.is_subaddress, info.is_carrot);
|
||||
m_wallet->add_address_book_row(info.address, info.has_payment_id ? &info.payment_id : NULL, description, info.is_subaddress);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -11168,9 +11100,9 @@ bool simple_wallet::address_book(const std::vector<std::string> &args/* = std::v
|
||||
success_msg_writer() << tr("Index: ") << i;
|
||||
std::string address;
|
||||
if (row.m_has_payment_id)
|
||||
address = cryptonote::get_account_integrated_address_as_str(m_wallet->nettype(), row.m_address, row.m_payment_id, row.m_is_carrot);
|
||||
address = cryptonote::get_account_integrated_address_as_str(m_wallet->nettype(), row.m_address, row.m_payment_id);
|
||||
else
|
||||
address = get_account_address_as_str(m_wallet->nettype(), row.m_is_subaddress, row.m_address, row.m_is_carrot);
|
||||
address = get_account_address_as_str(m_wallet->nettype(), row.m_is_subaddress, row.m_address);
|
||||
success_msg_writer() << tr("Address: ") << address;
|
||||
success_msg_writer() << tr("Description: ") << row.m_description << "\n";
|
||||
}
|
||||
@@ -11896,7 +11828,6 @@ int main(int argc, char* argv[])
|
||||
command_line::add_arg(desc_params, arg_generate_new_wallet);
|
||||
command_line::add_arg(desc_params, arg_generate_from_device);
|
||||
command_line::add_arg(desc_params, arg_generate_from_view_key);
|
||||
command_line::add_arg(desc_params, arg_generate_from_svb_key);
|
||||
command_line::add_arg(desc_params, arg_generate_from_spend_key);
|
||||
command_line::add_arg(desc_params, arg_generate_from_keys);
|
||||
command_line::add_arg(desc_params, arg_generate_from_multisig_keys);
|
||||
|
||||
@@ -101,11 +101,8 @@ namespace cryptonote
|
||||
|
||||
boost::optional<epee::wipeable_string> new_wallet(const boost::program_options::variables_map& vm, const crypto::secret_key& recovery_key,
|
||||
bool recover, bool two_random, const std::string &old_language);
|
||||
boost::optional<epee::wipeable_string> new_wallet(const boost::program_options::variables_map& vm,
|
||||
const cryptonote::account_public_address& address,
|
||||
const boost::optional<crypto::secret_key>& spendkey,
|
||||
const crypto::secret_key& viewkey
|
||||
);
|
||||
boost::optional<epee::wipeable_string> new_wallet(const boost::program_options::variables_map& vm, const cryptonote::account_public_address& address,
|
||||
const boost::optional<crypto::secret_key>& spendkey, const crypto::secret_key& viewkey);
|
||||
boost::optional<epee::wipeable_string> new_wallet(const boost::program_options::variables_map& vm,
|
||||
const epee::wipeable_string &multisig_keys, const epee::wipeable_string &seed_pass, const std::string &old_language);
|
||||
boost::optional<epee::wipeable_string> new_wallet(const boost::program_options::variables_map& vm);
|
||||
@@ -433,7 +430,6 @@ namespace cryptonote
|
||||
std::string m_generate_new;
|
||||
std::string m_generate_from_device;
|
||||
std::string m_generate_from_view_key;
|
||||
std::string m_generate_from_svb_key;
|
||||
std::string m_generate_from_spend_key;
|
||||
std::string m_generate_from_keys;
|
||||
std::string m_generate_from_multisig_keys;
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
#define DEF_SALVIUM_VERSION_TAG "@VERSIONTAG@"
|
||||
#define DEF_SALVIUM_VERSION "1.0.0-rc4"
|
||||
#define DEF_SALVIUM_VERSION "0.9.9-rc4"
|
||||
#define DEF_MONERO_VERSION_TAG "release"
|
||||
#define DEF_MONERO_VERSION "0.18.3.4"
|
||||
#define DEF_MONERO_RELEASE_NAME "One"
|
||||
|
||||
@@ -62,7 +62,7 @@ bool AddressBookImpl::addRow(const std::string &dst_addr , const std::string &pa
|
||||
return false;
|
||||
}
|
||||
|
||||
bool r = m_wallet->m_wallet->add_address_book_row(info.address, info.has_payment_id ? &info.payment_id : NULL,description,info.is_subaddress,info.is_carrot);
|
||||
bool r = m_wallet->m_wallet->add_address_book_row(info.address, info.has_payment_id ? &info.payment_id : NULL,description,info.is_subaddress);
|
||||
if (r)
|
||||
refresh();
|
||||
else
|
||||
@@ -81,7 +81,7 @@ bool AddressBookImpl::setDescription(std::size_t index, const std::string &descr
|
||||
|
||||
tools::wallet2::address_book_row entry = ab[index];
|
||||
entry.m_description = description;
|
||||
bool r = m_wallet->m_wallet->set_address_book_row(index, entry.m_address, entry.m_has_payment_id ? &entry.m_payment_id : nullptr, entry.m_description, entry.m_is_subaddress,entry.m_is_carrot);
|
||||
bool r = m_wallet->m_wallet->set_address_book_row(index, entry.m_address, entry.m_has_payment_id ? &entry.m_payment_id : nullptr, entry.m_description, entry.m_is_subaddress);
|
||||
if (r)
|
||||
refresh();
|
||||
else
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include "carrot_core/lazy_amount_commitment.h"
|
||||
#include "carrot_core/scan.h"
|
||||
#include "carrot_impl/format_utils.h"
|
||||
#include "common/container_helpers.h"
|
||||
#include "crypto/generators.h"
|
||||
#include "cryptonote_basic/cryptonote_format_utils.h"
|
||||
#include "ringct/rctOps.h"
|
||||
@@ -132,9 +133,6 @@ static bool try_load_pre_carrot_enote(const bool is_coinbase,
|
||||
enote_out.amount_commitment = rct::Z;
|
||||
}
|
||||
|
||||
// Check for protocol_tx outputs
|
||||
enote_out.is_protocol_tx_output = (tx.type == cryptonote::transaction_type::PROTOCOL);
|
||||
|
||||
return true;
|
||||
}
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
@@ -171,8 +169,8 @@ static std::optional<enote_view_incoming_scan_info_t> view_incoming_scan_pre_car
|
||||
|
||||
crypto::ec_scalar amount_key;
|
||||
if (!hwdev.derivation_to_scalar(receive_info->derivation,
|
||||
enote.is_protocol_tx_output ? 0 : enote.local_output_index,
|
||||
amount_key))
|
||||
enote.local_output_index,
|
||||
amount_key))
|
||||
return std::nullopt;
|
||||
|
||||
// a
|
||||
@@ -211,16 +209,16 @@ static std::optional<enote_view_incoming_scan_info_t> view_incoming_scan_pre_car
|
||||
// derive k^g_o
|
||||
crypto::secret_key sender_extension_g;
|
||||
if (!hwdev.derivation_to_scalar(receive_info->derivation,
|
||||
enote.is_protocol_tx_output ? 0 : enote.local_output_index,
|
||||
sender_extension_g))
|
||||
enote.local_output_index,
|
||||
sender_extension_g))
|
||||
return std::nullopt;
|
||||
|
||||
// K^j_s'
|
||||
crypto::public_key address_spend_pubkey;
|
||||
if (!hwdev.derive_subaddress_public_key(enote.onetime_address,
|
||||
receive_info->derivation,
|
||||
enote.is_protocol_tx_output ? 0 : enote.local_output_index,
|
||||
address_spend_pubkey))
|
||||
receive_info->derivation,
|
||||
enote.local_output_index,
|
||||
address_spend_pubkey))
|
||||
return std::nullopt;
|
||||
|
||||
//pid
|
||||
@@ -489,14 +487,14 @@ void perform_ecdh_derivations(const epee::span<const crypto::public_key> main_tx
|
||||
{
|
||||
hwdev.generate_key_derivation(main_tx_ephemeral_pubkey,
|
||||
k_view_incoming,
|
||||
main_derivations_out.emplace_back());
|
||||
tools::add_element(main_derivations_out));
|
||||
}
|
||||
|
||||
for (const crypto::public_key &additional_tx_ephemeral_pubkey : additional_tx_ephemeral_pubkeys)
|
||||
{
|
||||
hwdev.generate_key_derivation(additional_tx_ephemeral_pubkey,
|
||||
k_view_incoming,
|
||||
additional_derivations_out.emplace_back());
|
||||
tools::add_element(additional_derivations_out));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,8 +100,6 @@ struct PreCarrotEnote
|
||||
bool short_amount;
|
||||
rct::key amount_commitment;
|
||||
rct::ecdhTuple amount;
|
||||
|
||||
bool is_protocol_tx_output;
|
||||
};
|
||||
|
||||
using MoneroEnoteVariant = std::variant<PreCarrotEnote,
|
||||
|
||||
@@ -541,6 +541,9 @@ std::vector<carrot::CarrotTransactionProposalV1> make_carrot_transaction_proposa
|
||||
const std::set<uint32_t> &subaddr_indices,
|
||||
const wallet2::unique_index_container &subtract_fee_from_outputs)
|
||||
{
|
||||
wallet2::transfer_container transfers;
|
||||
w.get_transfers(transfers);
|
||||
|
||||
const bool use_per_byte_fee = w.use_fork_rules(HF_VERSION_PER_BYTE_FEE, 0);
|
||||
CHECK_AND_ASSERT_THROW_MES(use_per_byte_fee,
|
||||
"make_carrot_transaction_proposals_wallet2_transfer: not using per-byte base fee");
|
||||
@@ -739,7 +742,7 @@ std::vector<carrot::CarrotTransactionProposalV1> make_carrot_transaction_proposa
|
||||
subaddr_account,
|
||||
subaddr_indices,
|
||||
only_below ? only_below : MONEY_SUPPLY,
|
||||
1, // ignore_below
|
||||
0,
|
||||
top_block_index))
|
||||
continue;
|
||||
|
||||
|
||||
+42
-79
@@ -2621,7 +2621,7 @@ void wallet2::process_new_scanned_transaction(
|
||||
continue;
|
||||
|
||||
// update m_transfers view-incoming scan info, and default values
|
||||
transfer_details& td = m_transfers.emplace_back();
|
||||
transfer_details& td = tools::add_element(m_transfers);
|
||||
td.m_block_height = height;
|
||||
td.m_internal_output_index = local_output_index;
|
||||
td.m_global_output_index = o_indices.at(local_output_index);
|
||||
@@ -2704,37 +2704,6 @@ void wallet2::process_new_scanned_transaction(
|
||||
// update m_transfer_indices
|
||||
m_transfers_indices[enote_scan_info->asset_type].insert(m_transfers.size()-1);
|
||||
|
||||
// Check for STAKE / AUDIT TX payouts
|
||||
if (tx.type == cryptonote::transaction_type::PROTOCOL && td.m_td_origin_idx != std::numeric_limits<uint64_t>::max()) {
|
||||
|
||||
// Attempt to get the origin TX
|
||||
THROW_WALLET_EXCEPTION_IF(td.m_td_origin_idx >= get_num_transfer_details(),
|
||||
error::wallet_internal_error,
|
||||
"cannot locate return_payment TX origin in m_transfers");
|
||||
const transfer_details &td_origin = m_transfers[td.m_td_origin_idx];
|
||||
THROW_WALLET_EXCEPTION_IF(td_origin.m_tx.type != cryptonote::transaction_type::AUDIT && td_origin.m_tx.type != cryptonote::transaction_type::STAKE,
|
||||
error::wallet_internal_error,
|
||||
"incorrect TX type for protocol_tx origin in m_transfers");
|
||||
|
||||
// Get the output key for the change entry
|
||||
crypto::public_key pk_locked_coins = crypto::null_pkey;
|
||||
THROW_WALLET_EXCEPTION_IF(!get_output_public_key(td_origin.m_tx.vout[td_origin.m_internal_output_index], pk_locked_coins),
|
||||
error::wallet_internal_error,
|
||||
"Failed to get output public key for locked coins");
|
||||
|
||||
// At this point, we need to clear the "locked coins" count, because otherwise we will be counting yield stakes twice in our balance
|
||||
if (!m_locked_coins.erase(pk_locked_coins)) {
|
||||
LOG_ERROR("Failed to remove protocol_tx entry from m_locked_coins - possible duplicate output key detected");
|
||||
}
|
||||
}
|
||||
|
||||
// Check for STAKE / AUDIT TXs
|
||||
if (tx.type == cryptonote::transaction_type::AUDIT || tx.type == cryptonote::transaction_type::STAKE) {
|
||||
|
||||
// Add a "locked coins" entry so users don't freak out when they STAKE/AUDITOA
|
||||
m_locked_coins.insert({onetime_address, {0, tx.amount_burnt, tx.source_asset_type}});
|
||||
}
|
||||
|
||||
// update multisig info
|
||||
if (m_multisig)
|
||||
{
|
||||
@@ -2880,8 +2849,21 @@ void wallet2::process_new_scanned_transaction(
|
||||
// save the change output key in our subaddress_map, so we can receive money to it later
|
||||
// from protocol or return txs
|
||||
for (const auto &entry: tx_amounts_individual_outs[i->first]) {
|
||||
const crypto::public_key &onetime_address = std::get<1>(entry);
|
||||
carrot::AddressDeriveType derive_type;
|
||||
if (use_fork_rules(HF_VERSION_CARROT, 0)) {
|
||||
derive_type = carrot::AddressDeriveType::Carrot;
|
||||
} else {
|
||||
derive_type = carrot::AddressDeriveType::PreCarrot;
|
||||
}
|
||||
const carrot::subaddress_index_extended subaddr_ext = {i->first.major, i->first.minor, derive_type, true};
|
||||
// save to m_subaddresses as well, so that we can populate account subaddress map
|
||||
// when we open the wallet first time.
|
||||
if (derive_type == carrot::AddressDeriveType::PreCarrot)
|
||||
m_subaddresses_extended[onetime_address] = subaddr_ext;
|
||||
|
||||
// update m_salvium_txs
|
||||
m_salvium_txs.insert({std::get<1>(entry), m_transfers.size()-1});
|
||||
m_salvium_txs.insert({onetime_address, m_transfers.size()-1});
|
||||
}
|
||||
|
||||
// delete change output from amounts
|
||||
@@ -3131,7 +3113,8 @@ void wallet2::process_new_blockchain_entry(const cryptonote::block& b,
|
||||
|
||||
m_last_block_reward = cryptonote::get_outs_money_amount(b.miner_tx);
|
||||
LOG_PRINT_L2("Processed block: " << bl_id << ", height " << height << ", " << miner_tx_handle_time + txs_handle_time << "(" << miner_tx_handle_time << "/" << txs_handle_time <<")ms");
|
||||
} else {
|
||||
}else
|
||||
{
|
||||
if (!(height % 128))
|
||||
LOG_PRINT_L2( "Skipped block by timestamp, height: " << height << ", block time " << b.timestamp << ", account time " << m_account.get_createtime());
|
||||
}
|
||||
@@ -3399,6 +3382,19 @@ void wallet2::process_parsed_blocks(const uint64_t start_height, const std::vect
|
||||
size_t i = 0;
|
||||
size_t tx_output_idx = 0;
|
||||
while (i < blocks.size()) {
|
||||
/*
|
||||
if (!skip_scan_for_this_block && m_refresh_type != RefreshNoCoinbase)
|
||||
tx_scan_job(par_blk.block.miner_tx, tx_output_idx);
|
||||
tx_output_idx += par_blk.block.miner_tx.vout.size();
|
||||
if (!skip_scan_for_this_block && m_refresh_type != RefreshNoCoinbase)
|
||||
tx_scan_job(par_blk.block.protocol_tx, tx_output_idx);
|
||||
tx_output_idx += par_blk.block.protocol_tx.vout.size();
|
||||
for (const cryptonote::transaction &tx : par_blk.txes)
|
||||
{
|
||||
if (!skip_scan_for_this_block)
|
||||
tx_scan_job(tx, tx_output_idx);
|
||||
tx_output_idx += tx.vout.size();
|
||||
*/
|
||||
tools::threadpool::waiter scan_blocks_waiter(tpool);
|
||||
for (size_t j = 0; j < 10; ++j)
|
||||
{
|
||||
@@ -3472,23 +3468,6 @@ void wallet2::process_parsed_blocks(const uint64_t start_height, const std::vect
|
||||
tx_output_idx += n_block_outputs;
|
||||
++current_index;
|
||||
}
|
||||
|
||||
// save accumulated return subaddresses to m_subaddresses_extended, so that we can re-insert
|
||||
// them into account after we restart the wallet.
|
||||
m_subaddresses_extended.clear();
|
||||
for (const auto& subaddr: m_account.get_subaddress_map_ref()) {
|
||||
if (subaddr.second.derive_type == carrot::AddressDeriveType::PreCarrot &&
|
||||
subaddr.second.is_return_spend_key == true
|
||||
) {
|
||||
m_subaddresses_extended.insert({subaddr.first, subaddr.second});
|
||||
}
|
||||
}
|
||||
|
||||
// save accumulated return output info to wallet
|
||||
m_return_output_info.clear();
|
||||
for (const auto& output_info: m_account.get_return_output_map_ref()) {
|
||||
m_return_output_info.insert({output_info.first, output_info.second});
|
||||
}
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
void wallet2::refresh(bool trusted_daemon)
|
||||
@@ -4052,7 +4031,7 @@ void wallet2::fast_refresh(uint64_t stop_height, uint64_t &blocks_start_height,
|
||||
}
|
||||
|
||||
|
||||
bool wallet2::add_address_book_row(const cryptonote::account_public_address &address, const crypto::hash8 *payment_id, const std::string &description, bool is_subaddress, bool is_carrot)
|
||||
bool wallet2::add_address_book_row(const cryptonote::account_public_address &address, const crypto::hash8 *payment_id, const std::string &description, bool is_subaddress)
|
||||
{
|
||||
wallet2::address_book_row a;
|
||||
a.m_address = address;
|
||||
@@ -4060,7 +4039,6 @@ bool wallet2::add_address_book_row(const cryptonote::account_public_address &add
|
||||
a.m_payment_id = payment_id ? *payment_id : crypto::null_hash8;
|
||||
a.m_description = description;
|
||||
a.m_is_subaddress = is_subaddress;
|
||||
a.m_is_carrot = is_carrot;
|
||||
|
||||
auto old_size = m_address_book.size();
|
||||
m_address_book.push_back(a);
|
||||
@@ -4069,7 +4047,7 @@ bool wallet2::add_address_book_row(const cryptonote::account_public_address &add
|
||||
return false;
|
||||
}
|
||||
|
||||
bool wallet2::set_address_book_row(size_t row_id, const cryptonote::account_public_address &address, const crypto::hash8 *payment_id, const std::string &description, bool is_subaddress, bool is_carrot)
|
||||
bool wallet2::set_address_book_row(size_t row_id, const cryptonote::account_public_address &address, const crypto::hash8 *payment_id, const std::string &description, bool is_subaddress)
|
||||
{
|
||||
wallet2::address_book_row a;
|
||||
a.m_address = address;
|
||||
@@ -4077,7 +4055,6 @@ bool wallet2::set_address_book_row(size_t row_id, const cryptonote::account_publ
|
||||
a.m_payment_id = payment_id ? *payment_id : crypto::null_hash8;
|
||||
a.m_description = description;
|
||||
a.m_is_subaddress = is_subaddress;
|
||||
a.m_is_carrot = is_carrot;
|
||||
|
||||
const auto size = m_address_book.size();
|
||||
if (row_id >= size)
|
||||
@@ -5845,7 +5822,7 @@ crypto::secret_key wallet2::generate(const std::string& wallet_, const epee::wip
|
||||
*/
|
||||
void wallet2::generate(const std::string& wallet_, const epee::wipeable_string& password,
|
||||
const cryptonote::account_public_address &account_public_address,
|
||||
const crypto::secret_key& viewkey, bool create_address_file)
|
||||
const crypto::secret_key& viewkey, bool create_address_file)
|
||||
{
|
||||
clear();
|
||||
prepare_file_names(wallet_);
|
||||
@@ -5857,11 +5834,7 @@ void wallet2::generate(const std::string& wallet_, const epee::wipeable_string&
|
||||
THROW_WALLET_EXCEPTION_IF(boost::filesystem::exists(m_keys_file, ignored_ec), error::file_exists, m_keys_file);
|
||||
}
|
||||
|
||||
if (account_public_address.m_is_carrot) {
|
||||
m_account.create_from_svb_key(account_public_address, viewkey);
|
||||
} else {
|
||||
m_account.create_from_viewkey(account_public_address, viewkey);
|
||||
}
|
||||
m_account.create_from_viewkey(account_public_address, viewkey);
|
||||
init_type(hw::device::device_type::SOFTWARE);
|
||||
m_watch_only = true;
|
||||
m_account_public_address = account_public_address;
|
||||
@@ -6623,21 +6596,17 @@ void wallet2::load(const std::string& wallet_, const epee::wipeable_string& pass
|
||||
|
||||
if (get_num_subaddress_accounts() == 0)
|
||||
add_subaddress_account(tr("Primary account"));
|
||||
|
||||
// populate account subaddress list
|
||||
m_account.insert_subaddresses(m_subaddresses_extended);
|
||||
if (!m_subaddresses.empty())
|
||||
{
|
||||
// if we have subaddresses, we need to insert them into the account
|
||||
for (const auto &subaddress : m_subaddresses)
|
||||
m_account.insert_subaddresses(
|
||||
// we assume none of these subaddresses are return tx subaddresses
|
||||
// TODO: we assume none of these subaddresses are return tx subaddresses
|
||||
{{subaddress.first, {{subaddress.second.major, subaddress.second.minor}, carrot::AddressDeriveType::PreCarrot, false}}}
|
||||
);
|
||||
}
|
||||
m_account.insert_subaddresses(m_subaddresses_extended);
|
||||
|
||||
// populate account return output info
|
||||
m_account.insert_return_output_info(m_return_output_info);
|
||||
|
||||
try
|
||||
{
|
||||
@@ -6844,8 +6813,9 @@ void wallet2::process_background_cache_on_open()
|
||||
background_w2->m_custom_background_key = m_custom_background_key;
|
||||
|
||||
// TODO: uncommet this block
|
||||
background_w2->m_account.set_keys(m_account.get_keys(), false);
|
||||
background_w2->m_account.forget_spend_key();
|
||||
// carrot::carrot_and_legacy_account account = m_account;
|
||||
// account.forget_spend_key();
|
||||
// background_w2->m_account = account;
|
||||
|
||||
// Load background cache from file
|
||||
background_w2->clear();
|
||||
@@ -7457,14 +7427,6 @@ bool wallet2::is_transfer_unlocked(const transfer_details& td)
|
||||
uint64_t unlock_time = 0;
|
||||
if (!cryptonote::get_output_unlock_time(td.m_tx.vout[td.m_internal_output_index], unlock_time))
|
||||
return false;
|
||||
if (unlock_time == 0) {
|
||||
if (td.m_tx.type == cryptonote::transaction_type::MINER || td.m_tx.type == cryptonote::transaction_type::PROTOCOL) {
|
||||
unlock_time = CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW;
|
||||
} else {
|
||||
unlock_time = CRYPTONOTE_DEFAULT_TX_SPENDABLE_AGE;
|
||||
}
|
||||
}
|
||||
|
||||
return is_transfer_unlocked(unlock_time, td.m_block_height);
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
@@ -11614,8 +11576,9 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_all(uint64_t below
|
||||
const auto tx_proposals = tools::wallet::make_carrot_transaction_proposals_wallet2_sweep_all(*this, below, address, is_subaddress, outputs, priority, extra, tx_type, subaddr_account, subaddr_indices);
|
||||
std::vector<pending_tx> ptx_vector;
|
||||
ptx_vector.reserve(tx_proposals.size());
|
||||
for (const auto &tx_proposal : tx_proposals)
|
||||
ptx_vector.push_back(tools::wallet::finalize_all_proofs_from_transfer_details_as_pending_tx(tx_proposal, *this));
|
||||
// TODO: use CLSAGS here..
|
||||
// for (const auto &tx_proposal : tx_proposals)
|
||||
// ptx_vector.push_back(tools::wallet::finalize_all_proofs_from_transfer_details_as_pending_tx(tx_proposal, *this));
|
||||
return ptx_vector;
|
||||
}
|
||||
|
||||
|
||||
+3
-12
@@ -859,7 +859,6 @@ private:
|
||||
std::string m_description;
|
||||
bool m_is_subaddress;
|
||||
bool m_has_payment_id;
|
||||
bool m_is_carrot;
|
||||
|
||||
BEGIN_SERIALIZE_OBJECT()
|
||||
VERSION_FIELD(0)
|
||||
@@ -868,7 +867,6 @@ private:
|
||||
FIELD(m_description)
|
||||
FIELD(m_is_subaddress)
|
||||
FIELD(m_has_payment_id)
|
||||
FIELD(m_is_carrot)
|
||||
END_SERIALIZE()
|
||||
};
|
||||
|
||||
@@ -1019,7 +1017,6 @@ private:
|
||||
* \param account_public_address The account's public address
|
||||
* \param viewkey view secret key
|
||||
* \param create_address_file Whether to create an address file
|
||||
* \param is_carrot Whether viewkey is k_v (CN) or s_vb (Carrot)
|
||||
*/
|
||||
void generate(const std::string& wallet, const epee::wipeable_string& password,
|
||||
const cryptonote::account_public_address &account_public_address,
|
||||
@@ -1420,7 +1417,6 @@ private:
|
||||
return;
|
||||
a & m_subaddresses.parent();
|
||||
a & m_subaddresses_extended.parent();
|
||||
a & m_return_output_info.parent();
|
||||
std::unordered_map<cryptonote::subaddress_index, crypto::public_key> dummy_subaddresses_inv;
|
||||
a & dummy_subaddresses_inv;
|
||||
a & m_subaddress_labels;
|
||||
@@ -1488,7 +1484,6 @@ private:
|
||||
FIELD(m_scanned_pool_txs[1])
|
||||
FIELD(m_subaddresses)
|
||||
FIELD(m_subaddresses_extended)
|
||||
FIELD(m_return_output_info)
|
||||
FIELD(m_subaddress_labels)
|
||||
FIELD(m_additional_tx_keys)
|
||||
FIELD(m_attributes)
|
||||
@@ -1649,8 +1644,8 @@ private:
|
||||
* \brief GUI Address book get/store
|
||||
*/
|
||||
std::vector<address_book_row> get_address_book() const { return m_address_book; }
|
||||
bool add_address_book_row(const cryptonote::account_public_address &address, const crypto::hash8 *payment_id, const std::string &description, bool is_subaddress, bool is_carrot);
|
||||
bool set_address_book_row(size_t row_id, const cryptonote::account_public_address &address, const crypto::hash8 *payment_id, const std::string &description, bool is_subaddress, bool is_carrot);
|
||||
bool add_address_book_row(const cryptonote::account_public_address &address, const crypto::hash8 *payment_id, const std::string &description, bool is_subaddress);
|
||||
bool set_address_book_row(size_t row_id, const cryptonote::account_public_address &address, const crypto::hash8 *payment_id, const std::string &description, bool is_subaddress);
|
||||
bool delete_address_book_row(std::size_t row_id);
|
||||
|
||||
uint64_t get_num_rct_outputs();
|
||||
@@ -2152,7 +2147,6 @@ private:
|
||||
cryptonote::account_public_address m_account_public_address;
|
||||
serializable_unordered_map<crypto::public_key, cryptonote::subaddress_index> m_subaddresses;
|
||||
serializable_unordered_map<crypto::public_key, carrot::subaddress_index_extended> m_subaddresses_extended;
|
||||
serializable_unordered_map<crypto::public_key, carrot::return_output_info_t> m_return_output_info;
|
||||
std::vector<std::vector<std::string>> m_subaddress_labels;
|
||||
serializable_unordered_map<crypto::hash, std::string> m_tx_notes;
|
||||
serializable_unordered_map<std::string, std::string> m_attributes;
|
||||
@@ -2293,7 +2287,7 @@ BOOST_CLASS_VERSION(tools::wallet2::payment_details, 5)
|
||||
BOOST_CLASS_VERSION(tools::wallet2::pool_payment_details, 1)
|
||||
BOOST_CLASS_VERSION(tools::wallet2::unconfirmed_transfer_details, 8)
|
||||
BOOST_CLASS_VERSION(tools::wallet2::confirmed_transfer_details, 6)
|
||||
BOOST_CLASS_VERSION(tools::wallet2::address_book_row, 19)
|
||||
BOOST_CLASS_VERSION(tools::wallet2::address_book_row, 18)
|
||||
BOOST_CLASS_VERSION(tools::wallet2::reserve_proof_entry, 0)
|
||||
BOOST_CLASS_VERSION(tools::wallet2::unsigned_tx_set, 1)
|
||||
BOOST_CLASS_VERSION(tools::wallet2::signed_tx_set, 1)
|
||||
@@ -2671,9 +2665,6 @@ namespace boost
|
||||
a & x.m_has_payment_id;
|
||||
if (x.m_has_payment_id)
|
||||
a & x.m_payment_id;
|
||||
if (ver < 19)
|
||||
return;
|
||||
a & x.m_is_carrot;
|
||||
}
|
||||
|
||||
template <class Archive>
|
||||
|
||||
@@ -3313,9 +3313,9 @@ namespace tools
|
||||
const auto &entry = ab[idx];
|
||||
std::string address;
|
||||
if (entry.m_has_payment_id)
|
||||
address = cryptonote::get_account_integrated_address_as_str(m_wallet->nettype(), entry.m_address, entry.m_payment_id, entry.m_is_carrot);
|
||||
address = cryptonote::get_account_integrated_address_as_str(m_wallet->nettype(), entry.m_address, entry.m_payment_id);
|
||||
else
|
||||
address = get_account_address_as_str(m_wallet->nettype(), entry.m_is_subaddress, entry.m_address, entry.m_is_carrot);
|
||||
address = get_account_address_as_str(m_wallet->nettype(), entry.m_is_subaddress, entry.m_address);
|
||||
res.entries.push_back(wallet_rpc::COMMAND_RPC_GET_ADDRESS_BOOK_ENTRY::entry{idx, address, entry.m_description});
|
||||
}
|
||||
}
|
||||
@@ -3355,7 +3355,7 @@ namespace tools
|
||||
er.message = std::string("WALLET_RPC_ERROR_CODE_WRONG_ADDRESS: ") + req.address;
|
||||
return false;
|
||||
}
|
||||
if (!m_wallet->add_address_book_row(info.address, info.has_payment_id ? &info.payment_id : NULL, req.description, info.is_subaddress, info.is_carrot))
|
||||
if (!m_wallet->add_address_book_row(info.address, info.has_payment_id ? &info.payment_id : NULL, req.description, info.is_subaddress))
|
||||
{
|
||||
er.code = WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR;
|
||||
er.message = "Failed to add address book entry";
|
||||
@@ -3414,13 +3414,12 @@ namespace tools
|
||||
entry.m_is_subaddress = info.is_subaddress;
|
||||
if (info.has_payment_id)
|
||||
entry.m_payment_id = info.payment_id;
|
||||
entry.m_is_carrot = info.is_carrot;
|
||||
}
|
||||
|
||||
if (req.set_description)
|
||||
entry.m_description = req.description;
|
||||
|
||||
if (!m_wallet->set_address_book_row(req.index, entry.m_address, req.set_address && entry.m_has_payment_id ? &entry.m_payment_id : NULL, entry.m_description, entry.m_is_subaddress, entry.m_is_carrot))
|
||||
if (!m_wallet->set_address_book_row(req.index, entry.m_address, req.set_address && entry.m_has_payment_id ? &entry.m_payment_id : NULL, entry.m_description, entry.m_is_subaddress))
|
||||
{
|
||||
er.code = WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR;
|
||||
er.message = "Failed to edit address book entry";
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#include "carrot_impl/tx_proposal_utils.h"
|
||||
#include "carrot_impl/input_selection.h"
|
||||
#include "carrot_mock_helpers.h"
|
||||
#include "common/container_helpers.h"
|
||||
#include "crypto/generators.h"
|
||||
#include "cryptonote_basic/account.h"
|
||||
#include "cryptonote_basic/subaddress_index.h"
|
||||
@@ -62,7 +63,7 @@ static void unittest_scan_enote_set_multi_account(const std::vector<CarrotEnoteV
|
||||
res.reserve(accounts.size());
|
||||
|
||||
for (const auto *account : accounts)
|
||||
mock_scan_enote_set(enotes, encrypted_payment_id, *account, res.emplace_back());
|
||||
mock_scan_enote_set(enotes, encrypted_payment_id, *account, tools::add_element(res));
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
@@ -356,7 +357,7 @@ TEST(carrot_impl, multi_account_transfer_over_transaction_1)
|
||||
acc1.generate();
|
||||
|
||||
// 1 normal payment
|
||||
CarrotPaymentProposalV1 &normal_payment_proposal = tx_proposal.per_account_payments[0].second.emplace_back().first;
|
||||
CarrotPaymentProposalV1 &normal_payment_proposal = tools::add_element( tx_proposal.per_account_payments[0].second).first;
|
||||
normal_payment_proposal = CarrotPaymentProposalV1{
|
||||
.destination = acc0.cryptonote_address(),
|
||||
.amount = crypto::rand_idx((rct::xmr_amount) 1ull << 63),
|
||||
@@ -395,21 +396,21 @@ TEST(carrot_impl, multi_account_transfer_over_transaction_2)
|
||||
tx_proposal.self_sender_index = 2;
|
||||
|
||||
// 1 subaddress payment
|
||||
acc0.second.emplace_back().first = CarrotPaymentProposalV1{
|
||||
tools::add_element(acc0.second).first = CarrotPaymentProposalV1{
|
||||
.destination = acc0.first.subaddress({{2, 3}}),
|
||||
.amount = crypto::rand_idx<rct::xmr_amount>(1000000),
|
||||
.randomness = gen_janus_anchor()
|
||||
};
|
||||
|
||||
// 1 main address payment
|
||||
acc1.second.emplace_back().first = CarrotPaymentProposalV1{
|
||||
tools::add_element(acc1.second).first = CarrotPaymentProposalV1{
|
||||
.destination = acc1.first.cryptonote_address(),
|
||||
.amount = crypto::rand_idx<rct::xmr_amount>(1000000),
|
||||
.randomness = gen_janus_anchor()
|
||||
};
|
||||
|
||||
// 1 integrated address payment
|
||||
acc3.second.emplace_back().first = CarrotPaymentProposalV1{
|
||||
tools::add_element(acc3.second).first = CarrotPaymentProposalV1{
|
||||
.destination = acc3.first.cryptonote_address(gen_payment_id()),
|
||||
.amount = crypto::rand_idx<rct::xmr_amount>(1000000),
|
||||
.randomness = gen_janus_anchor()
|
||||
@@ -444,7 +445,7 @@ TEST(carrot_impl, multi_account_transfer_over_transaction_3)
|
||||
tx_proposal.self_sender_index = 2;
|
||||
|
||||
// 2 subaddress payment
|
||||
acc0.second.emplace_back().first = CarrotPaymentProposalV1{
|
||||
tools::add_element(acc0.second).first = CarrotPaymentProposalV1{
|
||||
.destination = acc0.first.subaddress({{2, 3}}),
|
||||
.amount = crypto::rand_idx<rct::xmr_amount>(1000000),
|
||||
.randomness = gen_janus_anchor()
|
||||
@@ -453,7 +454,7 @@ TEST(carrot_impl, multi_account_transfer_over_transaction_3)
|
||||
acc0.second.back().first.randomness = gen_janus_anchor(); //mangle anchor_norm
|
||||
|
||||
// 2 main address payment
|
||||
acc1.second.emplace_back().first = CarrotPaymentProposalV1{
|
||||
tools::add_element(acc1.second).first = CarrotPaymentProposalV1{
|
||||
.destination = acc1.first.cryptonote_address(),
|
||||
.amount = crypto::rand_idx<rct::xmr_amount>(1000000),
|
||||
.randomness = gen_janus_anchor()
|
||||
@@ -462,7 +463,7 @@ TEST(carrot_impl, multi_account_transfer_over_transaction_3)
|
||||
acc1.second.back().first.randomness = gen_janus_anchor(); //mangle anchor_norm
|
||||
|
||||
// 1 integrated address payment
|
||||
acc3.second.emplace_back().first = CarrotPaymentProposalV1{
|
||||
tools::add_element(acc3.second).first = CarrotPaymentProposalV1{
|
||||
.destination = acc3.first.cryptonote_address(gen_payment_id()),
|
||||
.amount = crypto::rand_idx<rct::xmr_amount>(1000000),
|
||||
.randomness = gen_janus_anchor()
|
||||
@@ -497,7 +498,7 @@ TEST(carrot_impl, multi_account_transfer_over_transaction_4)
|
||||
tx_proposal.self_sender_index = 2;
|
||||
|
||||
// 2 subaddress payment
|
||||
acc0.second.emplace_back().first = CarrotPaymentProposalV1{
|
||||
tools::add_element(acc0.second).first = CarrotPaymentProposalV1{
|
||||
.destination = acc0.first.subaddress({{2, 3}}),
|
||||
.amount = crypto::rand_idx<rct::xmr_amount>(1000000),
|
||||
.randomness = gen_janus_anchor()
|
||||
@@ -506,7 +507,7 @@ TEST(carrot_impl, multi_account_transfer_over_transaction_4)
|
||||
acc0.second.back().first.randomness = gen_janus_anchor(); //mangle anchor_norm
|
||||
|
||||
// 2 main address payment
|
||||
acc1.second.emplace_back().first = CarrotPaymentProposalV1{
|
||||
tools::add_element(acc1.second).first = CarrotPaymentProposalV1{
|
||||
.destination = acc1.first.cryptonote_address(),
|
||||
.amount = crypto::rand_idx<rct::xmr_amount>(1000000),
|
||||
.randomness = gen_janus_anchor()
|
||||
@@ -515,14 +516,14 @@ TEST(carrot_impl, multi_account_transfer_over_transaction_4)
|
||||
acc1.second.back().first.randomness = gen_janus_anchor(); //mangle anchor_norm
|
||||
|
||||
// 1 integrated address payment
|
||||
acc3.second.emplace_back().first = CarrotPaymentProposalV1{
|
||||
tools::add_element(acc3.second).first = CarrotPaymentProposalV1{
|
||||
.destination = acc3.first.cryptonote_address(gen_payment_id()),
|
||||
.amount = crypto::rand_idx<rct::xmr_amount>(1000000),
|
||||
.randomness = gen_janus_anchor()
|
||||
};
|
||||
|
||||
// 1 main address selfsend
|
||||
tx_proposal.explicit_selfsend_proposals.emplace_back().first.proposal = CarrotPaymentProposalSelfSendV1{
|
||||
tools::add_element(tx_proposal.explicit_selfsend_proposals).first.proposal = CarrotPaymentProposalSelfSendV1{
|
||||
.destination_address_spend_pubkey = acc2.first.carrot_account_spend_pubkey,
|
||||
.amount = crypto::rand_idx<rct::xmr_amount>(1000000),
|
||||
.enote_type = CarrotEnoteType::PAYMENT,
|
||||
@@ -530,7 +531,7 @@ TEST(carrot_impl, multi_account_transfer_over_transaction_4)
|
||||
};
|
||||
|
||||
// 1 subaddress selfsend
|
||||
tx_proposal.explicit_selfsend_proposals.emplace_back().first = CarrotPaymentProposalVerifiableSelfSendV1{
|
||||
tools::add_element(tx_proposal.explicit_selfsend_proposals).first = CarrotPaymentProposalVerifiableSelfSendV1{
|
||||
.proposal = CarrotPaymentProposalSelfSendV1{
|
||||
.destination_address_spend_pubkey = acc2.first.subaddress({{4, 19}}).address_spend_pubkey,
|
||||
.amount = crypto::rand_idx<rct::xmr_amount>(1000000),
|
||||
@@ -561,7 +562,7 @@ TEST(carrot_impl, multi_account_transfer_over_transaction_5)
|
||||
acc1.generate(AddressDeriveType::PreCarrot);
|
||||
|
||||
// 1 normal payment
|
||||
CarrotPaymentProposalV1 &normal_payment_proposal = tx_proposal.per_account_payments[0].second.emplace_back().first;
|
||||
CarrotPaymentProposalV1 &normal_payment_proposal = tools::add_element( tx_proposal.per_account_payments[0].second).first;
|
||||
normal_payment_proposal = CarrotPaymentProposalV1{
|
||||
.destination = acc0.cryptonote_address(),
|
||||
.amount = crypto::rand_idx((rct::xmr_amount) 1ull << 63),
|
||||
@@ -600,21 +601,21 @@ TEST(carrot_impl, multi_account_transfer_over_transaction_6)
|
||||
tx_proposal.self_sender_index = 2;
|
||||
|
||||
// 1 subaddress payment
|
||||
acc0.second.emplace_back().first = CarrotPaymentProposalV1{
|
||||
tools::add_element(acc0.second).first = CarrotPaymentProposalV1{
|
||||
.destination = acc0.first.subaddress({{2, 3}}),
|
||||
.amount = crypto::rand_idx<rct::xmr_amount>(1000000),
|
||||
.randomness = gen_janus_anchor()
|
||||
};
|
||||
|
||||
// 1 main address payment
|
||||
acc1.second.emplace_back().first = CarrotPaymentProposalV1{
|
||||
tools::add_element(acc1.second).first = CarrotPaymentProposalV1{
|
||||
.destination = acc1.first.cryptonote_address(),
|
||||
.amount = crypto::rand_idx<rct::xmr_amount>(1000000),
|
||||
.randomness = gen_janus_anchor()
|
||||
};
|
||||
|
||||
// 1 integrated address payment
|
||||
acc3.second.emplace_back().first = CarrotPaymentProposalV1{
|
||||
tools::add_element(acc3.second).first = CarrotPaymentProposalV1{
|
||||
.destination = acc3.first.cryptonote_address(gen_payment_id()),
|
||||
.amount = crypto::rand_idx<rct::xmr_amount>(1000000),
|
||||
.randomness = gen_janus_anchor()
|
||||
@@ -649,7 +650,7 @@ TEST(carrot_impl, multi_account_transfer_over_transaction_7)
|
||||
tx_proposal.self_sender_index = 2;
|
||||
|
||||
// 2 subaddress payment
|
||||
acc0.second.emplace_back().first = CarrotPaymentProposalV1{
|
||||
tools::add_element(acc0.second).first = CarrotPaymentProposalV1{
|
||||
.destination = acc0.first.subaddress({{2, 3}}),
|
||||
.amount = crypto::rand_idx<rct::xmr_amount>(1000000),
|
||||
.randomness = gen_janus_anchor()
|
||||
@@ -658,7 +659,7 @@ TEST(carrot_impl, multi_account_transfer_over_transaction_7)
|
||||
acc0.second.back().first.randomness = gen_janus_anchor(); //mangle anchor_norm
|
||||
|
||||
// 2 main address payment
|
||||
acc1.second.emplace_back().first = CarrotPaymentProposalV1{
|
||||
tools::add_element(acc1.second).first = CarrotPaymentProposalV1{
|
||||
.destination = acc1.first.cryptonote_address(),
|
||||
.amount = crypto::rand_idx<rct::xmr_amount>(1000000),
|
||||
.randomness = gen_janus_anchor()
|
||||
@@ -667,7 +668,7 @@ TEST(carrot_impl, multi_account_transfer_over_transaction_7)
|
||||
acc1.second.back().first.randomness = gen_janus_anchor(); //mangle anchor_norm
|
||||
|
||||
// 1 integrated address payment
|
||||
acc3.second.emplace_back().first = CarrotPaymentProposalV1{
|
||||
tools::add_element(acc3.second).first = CarrotPaymentProposalV1{
|
||||
.destination = acc3.first.cryptonote_address(gen_payment_id()),
|
||||
.amount = crypto::rand_idx<rct::xmr_amount>(1000000),
|
||||
.randomness = gen_janus_anchor()
|
||||
@@ -702,7 +703,7 @@ TEST(carrot_impl, multi_account_transfer_over_transaction_8)
|
||||
tx_proposal.self_sender_index = 2;
|
||||
|
||||
// 2 subaddress payment
|
||||
acc0.second.emplace_back().first = CarrotPaymentProposalV1{
|
||||
tools::add_element(acc0.second).first = CarrotPaymentProposalV1{
|
||||
.destination = acc0.first.subaddress({{2, 3}}),
|
||||
.amount = crypto::rand_idx<rct::xmr_amount>(1000000),
|
||||
.randomness = gen_janus_anchor()
|
||||
@@ -711,7 +712,7 @@ TEST(carrot_impl, multi_account_transfer_over_transaction_8)
|
||||
acc0.second.back().first.randomness = gen_janus_anchor(); //mangle anchor_norm
|
||||
|
||||
// 2 main address payment
|
||||
acc1.second.emplace_back().first = CarrotPaymentProposalV1{
|
||||
tools::add_element(acc1.second).first = CarrotPaymentProposalV1{
|
||||
.destination = acc1.first.cryptonote_address(),
|
||||
.amount = crypto::rand_idx<rct::xmr_amount>(1000000),
|
||||
.randomness = gen_janus_anchor()
|
||||
@@ -720,14 +721,14 @@ TEST(carrot_impl, multi_account_transfer_over_transaction_8)
|
||||
acc1.second.back().first.randomness = gen_janus_anchor(); //mangle anchor_norm
|
||||
|
||||
// 1 integrated address payment
|
||||
acc3.second.emplace_back().first = CarrotPaymentProposalV1{
|
||||
tools::add_element(acc3.second).first = CarrotPaymentProposalV1{
|
||||
.destination = acc3.first.cryptonote_address(gen_payment_id()),
|
||||
.amount = crypto::rand_idx<rct::xmr_amount>(1000000),
|
||||
.randomness = gen_janus_anchor()
|
||||
};
|
||||
|
||||
// 1 main address selfsend
|
||||
tx_proposal.explicit_selfsend_proposals.emplace_back().first.proposal = CarrotPaymentProposalSelfSendV1{
|
||||
tools::add_element(tx_proposal.explicit_selfsend_proposals).first.proposal = CarrotPaymentProposalSelfSendV1{
|
||||
.destination_address_spend_pubkey = acc2.first.carrot_account_spend_pubkey,
|
||||
.amount = crypto::rand_idx<rct::xmr_amount>(1000000),
|
||||
.enote_type = CarrotEnoteType::PAYMENT,
|
||||
@@ -735,7 +736,7 @@ TEST(carrot_impl, multi_account_transfer_over_transaction_8)
|
||||
};
|
||||
|
||||
// 1 subaddress selfsend
|
||||
tx_proposal.explicit_selfsend_proposals.emplace_back().first = CarrotPaymentProposalVerifiableSelfSendV1{
|
||||
tools::add_element(tx_proposal.explicit_selfsend_proposals).first = CarrotPaymentProposalVerifiableSelfSendV1{
|
||||
.proposal = CarrotPaymentProposalSelfSendV1{
|
||||
.destination_address_spend_pubkey = acc2.first.subaddress({{4, 19}}).address_spend_pubkey,
|
||||
.amount = crypto::rand_idx<rct::xmr_amount>(1000000),
|
||||
@@ -767,7 +768,7 @@ TEST(carrot_impl, multi_account_transfer_over_transaction_9)
|
||||
acc1.generate();
|
||||
|
||||
// 1 normal payment (subtractable)
|
||||
CarrotPaymentProposalV1 &normal_payment_proposal = tx_proposal.per_account_payments[0].second.emplace_back().first;
|
||||
CarrotPaymentProposalV1 &normal_payment_proposal = tools::add_element( tx_proposal.per_account_payments[0].second).first;
|
||||
normal_payment_proposal = CarrotPaymentProposalV1{
|
||||
.destination = acc0.cryptonote_address(),
|
||||
.amount = crypto::rand_idx((rct::xmr_amount) 1ull << 63),
|
||||
@@ -808,21 +809,21 @@ TEST(carrot_impl, multi_account_transfer_over_transaction_10)
|
||||
tx_proposal.self_sender_index = 2;
|
||||
|
||||
// 1 subaddress payment (subtractable)
|
||||
acc0.second.emplace_back().first = CarrotPaymentProposalV1{ = {CarrotPaymentProposalV1{
|
||||
tools::add_element(acc0.second) = {CarrotPaymentProposalV1{
|
||||
.destination = acc0.first.subaddress({{2, 3}}),
|
||||
.amount = crypto::rand_idx<rct::xmr_amount>(1000000),
|
||||
.randomness = gen_janus_anchor()
|
||||
}, true};
|
||||
|
||||
// 1 main address payment
|
||||
acc1.second.emplace_back().first = CarrotPaymentProposalV1{
|
||||
tools::add_element(acc1.second).first = CarrotPaymentProposalV1{
|
||||
.destination = acc1.first.cryptonote_address(),
|
||||
.amount = crypto::rand_idx<rct::xmr_amount>(1000000),
|
||||
.randomness = gen_janus_anchor()
|
||||
};
|
||||
|
||||
// 1 integrated address payment
|
||||
acc3.second.emplace_back().first = CarrotPaymentProposalV1{
|
||||
tools::add_element(acc3.second) = {CarrotPaymentProposalV1{
|
||||
.destination = acc3.first.cryptonote_address(gen_payment_id()),
|
||||
.amount = crypto::rand_idx<rct::xmr_amount>(1000000),
|
||||
.randomness = gen_janus_anchor()
|
||||
@@ -858,7 +859,7 @@ TEST(carrot_impl, multi_account_transfer_over_transaction_11)
|
||||
tx_proposal.self_sender_index = 2;
|
||||
|
||||
// 2 subaddress payment
|
||||
acc0.second.emplace_back().first = CarrotPaymentProposalV1{
|
||||
tools::add_element(acc0.second).first = CarrotPaymentProposalV1{
|
||||
.destination = acc0.first.subaddress({{2, 3}}),
|
||||
.amount = crypto::rand_idx<rct::xmr_amount>(1000000),
|
||||
.randomness = gen_janus_anchor()
|
||||
@@ -868,7 +869,7 @@ TEST(carrot_impl, multi_account_transfer_over_transaction_11)
|
||||
acc0.second.back().second = true; //set copy as subtractable
|
||||
|
||||
// 2 main address payment
|
||||
acc1.second.emplace_back().first = CarrotPaymentProposalV1{
|
||||
tools::add_element(acc1.second).first = CarrotPaymentProposalV1{
|
||||
.destination = acc1.first.cryptonote_address(),
|
||||
.amount = crypto::rand_idx<rct::xmr_amount>(1000000),
|
||||
.randomness = gen_janus_anchor()
|
||||
@@ -878,7 +879,7 @@ TEST(carrot_impl, multi_account_transfer_over_transaction_11)
|
||||
acc1.second.back().second = true; //set copy as subtractable
|
||||
|
||||
// 1 integrated address payment
|
||||
acc3.second.emplace_back().first = CarrotPaymentProposalV1{
|
||||
tools::add_element(acc3.second).first = CarrotPaymentProposalV1{
|
||||
.destination = acc3.first.cryptonote_address(gen_payment_id()),
|
||||
.amount = crypto::rand_idx<rct::xmr_amount>(1000000),
|
||||
.randomness = gen_janus_anchor()
|
||||
@@ -914,7 +915,7 @@ TEST(carrot_impl, multi_account_transfer_over_transaction_12)
|
||||
tx_proposal.self_sender_index = 2;
|
||||
|
||||
// 2 subaddress payment (1 subtractable)
|
||||
acc0.second.emplace_back().first = CarrotPaymentProposalV1{ = {CarrotPaymentProposalV1{
|
||||
tools::add_element(acc0.second) = {CarrotPaymentProposalV1{
|
||||
.destination = acc0.first.subaddress({{2, 3}}),
|
||||
.amount = crypto::rand_idx<rct::xmr_amount>(1000000),
|
||||
.randomness = gen_janus_anchor()
|
||||
@@ -924,7 +925,7 @@ TEST(carrot_impl, multi_account_transfer_over_transaction_12)
|
||||
acc0.second.back().second = false; //set not subtractable, first already is
|
||||
|
||||
// 2 main address payment
|
||||
acc1.second.emplace_back().first = CarrotPaymentProposalV1{
|
||||
tools::add_element(acc1.second).first = CarrotPaymentProposalV1{
|
||||
.destination = acc1.first.cryptonote_address(),
|
||||
.amount = crypto::rand_idx<rct::xmr_amount>(1000000),
|
||||
.randomness = gen_janus_anchor()
|
||||
@@ -933,14 +934,14 @@ TEST(carrot_impl, multi_account_transfer_over_transaction_12)
|
||||
acc1.second.back().first.randomness = gen_janus_anchor(); //mangle anchor_norm
|
||||
|
||||
// 1 integrated address payment (subtractable)
|
||||
acc3.second.emplace_back().first = CarrotPaymentProposalV1{
|
||||
tools::add_element(acc3.second) = {CarrotPaymentProposalV1{
|
||||
.destination = acc3.first.cryptonote_address(gen_payment_id()),
|
||||
.amount = crypto::rand_idx<rct::xmr_amount>(1000000),
|
||||
.randomness = gen_janus_anchor()
|
||||
}, true};
|
||||
|
||||
// 1 main address selfsend
|
||||
tx_proposal.explicit_selfsend_proposals.emplace_back().first.proposal = CarrotPaymentProposalSelfSendV1{
|
||||
tools::add_element(tx_proposal.explicit_selfsend_proposals).first.proposal = CarrotPaymentProposalSelfSendV1{
|
||||
.destination_address_spend_pubkey = acc2.first.carrot_account_spend_pubkey,
|
||||
.amount = crypto::rand_idx<rct::xmr_amount>(1000000),
|
||||
.enote_type = CarrotEnoteType::PAYMENT,
|
||||
@@ -948,7 +949,7 @@ TEST(carrot_impl, multi_account_transfer_over_transaction_12)
|
||||
};
|
||||
|
||||
// 1 subaddress selfsend (subtractable)
|
||||
tx_proposal.explicit_selfsend_proposals.emplace_back().first = CarrotPaymentProposalVerifiableSelfSendV1{
|
||||
tools::add_element(tx_proposal.explicit_selfsend_proposals) = {CarrotPaymentProposalVerifiableSelfSendV1{
|
||||
.proposal = CarrotPaymentProposalSelfSendV1{
|
||||
.destination_address_spend_pubkey = acc2.first.subaddress({{4, 19}}).address_spend_pubkey,
|
||||
.amount = crypto::rand_idx<rct::xmr_amount>(1000000),
|
||||
@@ -980,7 +981,7 @@ TEST(carrot_impl, multi_account_transfer_over_transaction_13)
|
||||
acc1.generate(AddressDeriveType::PreCarrot);
|
||||
|
||||
// 1 normal payment (subtractable)
|
||||
CarrotPaymentProposalV1 &normal_payment_proposal = tx_proposal.per_account_payments[0].second.emplace_back().first;
|
||||
CarrotPaymentProposalV1 &normal_payment_proposal = tools::add_element( tx_proposal.per_account_payments[0].second).first;
|
||||
normal_payment_proposal = CarrotPaymentProposalV1{
|
||||
.destination = acc0.cryptonote_address(),
|
||||
.amount = crypto::rand_idx((rct::xmr_amount) 1ull << 63),
|
||||
@@ -1021,21 +1022,21 @@ TEST(carrot_impl, multi_account_transfer_over_transaction_14)
|
||||
tx_proposal.self_sender_index = 2;
|
||||
|
||||
// 1 subaddress payment (subtractable)
|
||||
acc0.second.emplace_back().first = CarrotPaymentProposalV1{ = {CarrotPaymentProposalV1{
|
||||
tools::add_element(acc0.second) = {CarrotPaymentProposalV1{
|
||||
.destination = acc0.first.subaddress({{2, 3}}),
|
||||
.amount = crypto::rand_idx<rct::xmr_amount>(1000000),
|
||||
.randomness = gen_janus_anchor()
|
||||
}, true};
|
||||
|
||||
// 1 main address payment
|
||||
acc1.second.emplace_back().first = CarrotPaymentProposalV1{
|
||||
tools::add_element(acc1.second).first = CarrotPaymentProposalV1{
|
||||
.destination = acc1.first.cryptonote_address(),
|
||||
.amount = crypto::rand_idx<rct::xmr_amount>(1000000),
|
||||
.randomness = gen_janus_anchor()
|
||||
};
|
||||
|
||||
// 1 integrated address payment (subtractable)
|
||||
acc3.second.emplace_back().first = CarrotPaymentProposalV1{
|
||||
tools::add_element(acc3.second) = {CarrotPaymentProposalV1{
|
||||
.destination = acc3.first.cryptonote_address(gen_payment_id()),
|
||||
.amount = crypto::rand_idx<rct::xmr_amount>(1000000),
|
||||
.randomness = gen_janus_anchor()
|
||||
@@ -1071,7 +1072,7 @@ TEST(carrot_impl, multi_account_transfer_over_transaction_15)
|
||||
tx_proposal.self_sender_index = 2;
|
||||
|
||||
// 2 subaddress payment (subtractable)
|
||||
acc0.second.emplace_back().first = CarrotPaymentProposalV1{ = {CarrotPaymentProposalV1{
|
||||
tools::add_element(acc0.second) = {CarrotPaymentProposalV1{
|
||||
.destination = acc0.first.subaddress({{2, 3}}),
|
||||
.amount = crypto::rand_idx<rct::xmr_amount>(1000000),
|
||||
.randomness = gen_janus_anchor()
|
||||
@@ -1080,7 +1081,7 @@ TEST(carrot_impl, multi_account_transfer_over_transaction_15)
|
||||
acc0.second.back().first.randomness = gen_janus_anchor(); //mangle anchor_norm
|
||||
|
||||
// 2 main address payment (subtractable)
|
||||
acc1.second.emplace_back().first = CarrotPaymentProposalV1{
|
||||
tools::add_element(acc1.second) = {CarrotPaymentProposalV1{
|
||||
.destination = acc1.first.cryptonote_address(),
|
||||
.amount = crypto::rand_idx<rct::xmr_amount>(1000000),
|
||||
.randomness = gen_janus_anchor()
|
||||
@@ -1089,7 +1090,7 @@ TEST(carrot_impl, multi_account_transfer_over_transaction_15)
|
||||
acc1.second.back().first.randomness = gen_janus_anchor(); //mangle anchor_norm
|
||||
|
||||
// 1 integrated address payment (subtractable)
|
||||
acc3.second.emplace_back().first = CarrotPaymentProposalV1{
|
||||
tools::add_element(acc3.second) = {CarrotPaymentProposalV1{
|
||||
.destination = acc3.first.cryptonote_address(gen_payment_id()),
|
||||
.amount = crypto::rand_idx<rct::xmr_amount>(1000000),
|
||||
.randomness = gen_janus_anchor()
|
||||
@@ -1125,7 +1126,7 @@ TEST(carrot_impl, multi_account_transfer_over_transaction_16)
|
||||
tx_proposal.self_sender_index = 2;
|
||||
|
||||
// 2 subaddress payment (subtractable)
|
||||
acc0.second.emplace_back().first = CarrotPaymentProposalV1{ = {CarrotPaymentProposalV1{
|
||||
tools::add_element(acc0.second) = {CarrotPaymentProposalV1{
|
||||
.destination = acc0.first.subaddress({{2, 3}}),
|
||||
.amount = crypto::rand_idx<rct::xmr_amount>(1000000),
|
||||
.randomness = gen_janus_anchor()
|
||||
@@ -1134,7 +1135,7 @@ TEST(carrot_impl, multi_account_transfer_over_transaction_16)
|
||||
acc0.second.back().first.randomness = gen_janus_anchor(); //mangle anchor_norm
|
||||
|
||||
// 2 main address payment (subtractable)
|
||||
acc1.second.emplace_back().first = CarrotPaymentProposalV1{
|
||||
tools::add_element(acc1.second) = {CarrotPaymentProposalV1{
|
||||
.destination = acc1.first.cryptonote_address(),
|
||||
.amount = crypto::rand_idx<rct::xmr_amount>(1000000),
|
||||
.randomness = gen_janus_anchor()
|
||||
@@ -1143,22 +1144,22 @@ TEST(carrot_impl, multi_account_transfer_over_transaction_16)
|
||||
acc1.second.back().first.randomness = gen_janus_anchor(); //mangle anchor_norm
|
||||
|
||||
// 1 integrated address payment (subtractable)
|
||||
acc3.second.emplace_back().first = CarrotPaymentProposalV1{
|
||||
tools::add_element(acc3.second) = {CarrotPaymentProposalV1{
|
||||
.destination = acc3.first.cryptonote_address(gen_payment_id()),
|
||||
.amount = crypto::rand_idx<rct::xmr_amount>(1000000),
|
||||
.randomness = gen_janus_anchor()
|
||||
}, true};
|
||||
|
||||
// 1 main address selfsend (subtractable)
|
||||
tx_proposal.explicit_selfsend_proposals.emplace_back() = {CarrotPaymentProposalSelfSendV1{
|
||||
tools::add_element(tx_proposal.explicit_selfsend_proposals) = {{CarrotPaymentProposalSelfSendV1{
|
||||
.destination_address_spend_pubkey = acc2.first.carrot_account_spend_pubkey,
|
||||
.amount = crypto::rand_idx<rct::xmr_amount>(1000000),
|
||||
.enote_type = CarrotEnoteType::PAYMENT,
|
||||
// no internal messages for legacy self-sends
|
||||
}, true};
|
||||
}}, true};
|
||||
|
||||
// 1 subaddress selfsend (subtractable)
|
||||
tx_proposal.explicit_selfsend_proposals.emplace_back() = {CarrotPaymentProposalVerifiableSelfSendV1{
|
||||
tools::add_element(tx_proposal.explicit_selfsend_proposals) = {CarrotPaymentProposalVerifiableSelfSendV1{
|
||||
.proposal = CarrotPaymentProposalSelfSendV1{
|
||||
.destination_address_spend_pubkey = acc2.first.subaddress({{4, 19}}).address_spend_pubkey,
|
||||
.amount = crypto::rand_idx<rct::xmr_amount>(1000000),
|
||||
|
||||
@@ -157,7 +157,7 @@ TEST(x25519, scmul_key_convergence)
|
||||
for (unsigned char j = 0; j < 8; ++j)
|
||||
{
|
||||
// add 2^i + j (sometimes with duplicates, which is okay)
|
||||
mx25519_privkey &s = scalars.emplace_back();
|
||||
mx25519_privkey &s = tools::add_element(scalars);
|
||||
memset(s.data, 0, sizeof(mx25519_privkey));
|
||||
const int msb_byte_index = i >> 3;
|
||||
const int msb_bit_index = i & 7;
|
||||
@@ -169,7 +169,7 @@ TEST(x25519, scmul_key_convergence)
|
||||
scalars.push_back(hex2pod<mx25519_privkey>("ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f"));
|
||||
// add random
|
||||
const rct::key a = rct::skGen();
|
||||
memcpy(scalars.emplace_back().data, &a, sizeof(mx25519_privkey));
|
||||
memcpy(tools::add_element(scalars).data, &a, sizeof(mx25519_privkey));
|
||||
|
||||
std::vector<std::pair<rct::key, mx25519_pubkey>> points;
|
||||
// add base point
|
||||
|
||||
Reference in New Issue
Block a user