1
0
Fork 0
forked from lthn/blockchain

merge from zarcanum

This commit is contained in:
cryptozoidberg 2022-10-12 23:51:09 +02:00
commit 52b70ffb24
No known key found for this signature in database
GPG key ID: 22DEB97A54C6FDEC
24 changed files with 406 additions and 515 deletions

View file

@ -54,14 +54,14 @@
catch(const std::exception& ex) \
{ \
(void)(ex); \
LOG_ERROR("Exception at [" << location << "], what=" << ex.what()); \
custom_code; \
LOG_ERROR("Exception at [" << location << "], what=" << ex.what()); \
return return_val; \
} \
catch(...) \
{ \
LOG_ERROR("Exception at [" << location << "], generic exception \"...\""); \
custom_code; \
LOG_ERROR("Exception at [" << location << "], generic exception \"...\""); \
return return_val; \
}
#define CATCH_ENTRY(location, return_val) CATCH_ENTRY_CUSTOM(location, (void)0, return_val)

View file

@ -47,7 +47,7 @@ namespace epee \
bool r = kv_unserialize(s, stg, hparent_section, pname); \
if (r) \
{ \
d = epee::transform_str_to_t_pod<decltype(d)>(s); \
d = epee::transform_str_to_t_pod<type_name>(s); \
} \
return r; \
} \

View file

@ -28,6 +28,9 @@ namespace crypto
const point_t c_point_0 = point_t(point_t::tag_zero());
const point_t c_point_H_plus_G = c_point_H + c_point_G; // checked in crypto_constants
const point_t c_point_H_minus_G = c_point_H - c_point_G; // checked in crypto_constants
static_assert(sizeof(scalar_t::m_sk) == sizeof(scalar_t::m_u64) && sizeof(scalar_t::m_u64) == sizeof(scalar_t::m_s), "size missmatch");
} // namespace crypto

View file

@ -919,6 +919,8 @@ namespace crypto
extern const point_t c_point_H2;
extern const point_t c_point_X;
extern const point_t c_point_0;
extern const point_t c_point_H_plus_G;
extern const point_t c_point_H_minus_G;
//
// hash functions' helper

View file

@ -27,15 +27,17 @@ namespace crypto
#define DBG_VAL_PRINT(x) (void(0)) // std::cout << #x ": " << x << ENDL
#define DBG_PRINT(x) (void(0)) // std::cout << x << ENDL
template<typename CT>
bool bppe_gen(const scalar_vec_t& values, const scalar_vec_t& masks, const scalar_vec_t& masks2, bppe_signature& sig, std::vector<point_t>& commitments, uint8_t* p_err = nullptr)
{
#define CHECK_AND_FAIL_WITH_ERROR_IF_FALSE(cond, err_code) \
if (!(cond)) { LOG_PRINT_RED("bppe_gen: \"" << #cond << "\" is false at " << LOCATION_SS << ENDL << "error code = " << err_code, LOG_LEVEL_3); \
if (p_err) { *p_err = err_code; } return false; }
template<typename CT>
bool bppe_gen(const scalar_vec_t& values, const scalar_vec_t& masks, const scalar_vec_t& masks2, const std::vector<const crypto::public_key*>& commitments_1div8, bppe_signature& sig, uint8_t* p_err = nullptr)
{
// Note: commitments_1div8 are supposed to be already calculated
static_assert(CT::c_bpp_n <= 255, "too big N");
CHECK_AND_FAIL_WITH_ERROR_IF_FALSE(values.size() > 0 && values.size() <= CT::c_bpp_values_max && values.size() == masks.size() && masks.size() == masks2.size(), 1);
CHECK_AND_FAIL_WITH_ERROR_IF_FALSE(values.size() > 0 && values.size() <= CT::c_bpp_values_max && values.size() == masks.size() && masks.size() == masks2.size() && values.size() == commitments_1div8.size(), 1);
CHECK_AND_FAIL_WITH_ERROR_IF_FALSE(masks.is_reduced() && masks2.is_reduced(), 3);
const size_t c_bpp_log2_m = constexpr_ceil_log2(values.size());
@ -43,15 +45,6 @@ namespace crypto
const size_t c_bpp_mn = c_bpp_m * CT::c_bpp_n;
const size_t c_bpp_log2_mn = c_bpp_log2_m + CT::c_bpp_log2_n;
// pre-multiply all output points by c_scalar_1div8
// in order to enforce these points to be in the prime-order subgroup (after mul by 8 in bpp_verify())
// calc commitments vector as commitments[i] = 1/8 * values[i] * G + 1/8 * masks[i] * H + 1/8 * masks2[i] * H2
commitments.resize(values.size());
for (size_t i = 0; i < values.size(); ++i)
CT::calc_pedersen_commitment_2(values[i] * c_scalar_1div8, masks[i] * c_scalar_1div8, masks2[i] * c_scalar_1div8, commitments[i]);
// s.a. BP+ paper, page 15, eq. 11
// decompose v into aL and aR:
// v = aL o (1, 2, 2^2, ..., 2^n-1), o - component-wise product aka Hadamard product
@ -86,7 +79,7 @@ namespace crypto
DBG_PRINT("initial transcript: " << e);
hash_helper_t::hs_t hsc;
CT::update_transcript(hsc, e, commitments);
CT::update_transcript(hsc, e, commitments_1div8);
// Zarcanum paper, page 33, Fig. D.3: The prover chooses alpha_1, alpha_2 and computes A = g^aL h^aR h_1^alpha_1 h_2^alpha_2
// so we calculate A0 = alpha_1 * H + alpha_2 * H_2 + SUM(aL_i * G_i) + SUM(aR_i * H_i)
@ -336,10 +329,28 @@ namespace crypto
DBG_VAL_PRINT(sig.delta_2);
return true;
#undef CHECK_AND_FAIL_WITH_ERROR_IF_FALSE
} // bppe_gen()
// convenient overload for tests
template<typename CT>
bool bppe_gen(const scalar_vec_t& values, const scalar_vec_t& masks, const scalar_vec_t& masks2, bppe_signature& sig, std::vector<point_t>& commitments_1div8_to_be_generated, uint8_t* p_err = nullptr)
{
// calc commitments vector as commitments[i] = 1/8 * values[i] * G + 1/8 * masks[i] * H + 1/8 * masks2[i] * H2
commitments_1div8_to_be_generated.resize(values.size());
std::vector<crypto::public_key> commitments_1div8(values.size());
std::vector<const crypto::public_key*> commitments_1div8_pointers(values.size());
for (size_t i = 0; i < values.size(); ++i)
{
CT::calc_pedersen_commitment_2(values[i] * c_scalar_1div8, masks[i] * c_scalar_1div8, masks2[i] * c_scalar_1div8, commitments_1div8_to_be_generated[i]);
commitments_1div8[i] = (commitments_1div8_to_be_generated[i]).to_public_key();
commitments_1div8_pointers[i] = &commitments_1div8[i];
}
return bppe_gen<CT>(values, masks, masks2, commitments_1div8_pointers, sig, p_err);
}
#undef CHECK_AND_FAIL_WITH_ERROR_IF_FALSE
struct bppe_sig_commit_ref_t
{
bppe_sig_commit_ref_t(const bppe_signature& sig, const std::vector<point_t>& commitments)
@ -347,7 +358,7 @@ namespace crypto
, commitments(commitments)
{}
const bppe_signature& sig;
const std::vector<point_t>& commitments;
const std::vector<point_t>& commitments; // assumed to be premultiplied by 1/8
};

View file

@ -4,30 +4,156 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
//
// Note: This file originates from tests/functional_tests/crypto_tests.cpp
#include "epee/include/misc_log_ex.h"
#include "zarcanum.h"
#include "crypto/range_proofs.h"
#include "../currency_core/crypto_config.h" // TODO: move it to the crypto
namespace crypto
{
const scalar_t c_zarcanum_z_coeff_s = c_scalar_2p64;
const scalar_t c_zarcanum_z_coeff_s = { 0, 1, 0, 0 }; // c_scalar_2p64
const mp::uint256_t c_zarcanum_z_coeff_mp = c_zarcanum_z_coeff_s.as_boost_mp_type<mp::uint256_t>();
mp::uint256_t zarcanum_precalculate_l_div_z_D(const mp::uint128_t& pos_difficulty)
{
//LOG_PRINT_GREEN_L0(ENDL << "floor( l / (z * D) ) = " << c_scalar_L.as_boost_mp_type<mp::uint256_t>() / (c_zarcanum_z_coeff_mp * pos_difficulty));
return c_scalar_L.as_boost_mp_type<mp::uint256_t>() / (c_zarcanum_z_coeff_mp * pos_difficulty); // == floor( l / (z * D) )
}
mp::uint256_t zarcanum_precalculate_z_l_div_z_D(const mp::uint128_t& pos_difficulty)
{
//LOG_PRINT_GREEN_L0(ENDL << "z * floor( l / (z * D) ) = " << c_zarcanum_z_coeff_mp * (c_scalar_L.as_boost_mp_type<mp::uint256_t>() / (c_zarcanum_z_coeff_mp * pos_difficulty)));
return c_zarcanum_z_coeff_mp * (c_scalar_L.as_boost_mp_type<mp::uint256_t>() / (c_zarcanum_z_coeff_mp * pos_difficulty)); // == z * floor( l / (z * D) )
}
bool zarcanum_check_main_pos_inequality(const hash& kernel_hash, const scalar_t& blinding_mask, const scalar_t& secret_q,
const scalar_t& last_pow_block_id_hashed, const mp::uint256_t& z_l_div_z_D, uint64_t stake_amount, mp::uint256_t& lhs, mp::uint256_t& rhs)
const scalar_t& last_pow_block_id_hashed, const mp::uint256_t& z_l_div_z_D, uint64_t stake_amount, mp::uint256_t& lhs, mp::uint512_t& rhs)
{
scalar_t lhs_s = scalar_t(kernel_hash) * (blinding_mask + secret_q + last_pow_block_id_hashed); // == h * (f + q + f') mod l
lhs = lhs_s.as_boost_mp_type<mp::uint256_t>();
rhs = z_l_div_z_D * stake_amount; // == floor( l / (z * D) ) * z * a
rhs = static_cast<mp::uint512_t>(z_l_div_z_D) * stake_amount; // == floor( l / (z * D) ) * z * a
//LOG_PRINT_GREEN_L0(ENDL <<
// "z_l_div_z_D = " << z_l_div_z_D << ENDL <<
// "stake_amount = " << stake_amount << ENDL <<
// "lhs = " << lhs << ENDL <<
// "rhs = " << rhs);
return lhs < rhs; // h * (f + q + f') mod l < floor( l / (z * D) ) * z * a
}
#define CHECK_AND_FAIL_WITH_ERROR_IF_FALSE(cond, err_code) \
if (!(cond)) { LOG_PRINT_RED("zarcanum_generate_proof: \"" << #cond << "\" is false at " << LOCATION_SS << ENDL << "error code = " << err_code, LOG_LEVEL_3); \
if (p_err) { *p_err = err_code; } return false; }
bool zarcanum_generate_proof(const hash& kernel_hash, const public_key& commitment_1div8, const scalar_t& blinding_mask, const scalar_t& secret_q,
const scalar_t& last_pow_block_id_hashed, uint64_t stake_amount, zarcanum_proof& result, uint8_t* p_err)
{
const scalar_t a = stake_amount;
const scalar_t h = scalar_t(kernel_hash);
const scalar_t f_plus_q = blinding_mask + secret_q;
const scalar_t f_plus_q_plus_fp = f_plus_q + last_pow_block_id_hashed;
const scalar_t lhs = h * f_plus_q_plus_fp; // == h * (f + q + f') mod l
const mp::uint256_t d_mp = lhs.as_boost_mp_type<mp::uint256_t>() / (c_zarcanum_z_coeff_mp * stake_amount) + 1;
result.d = scalar_t(d_mp);
const scalar_t dz = result.d * c_zarcanum_z_coeff_s;
const scalar_t ba = dz * a - lhs; // b_a = dza - h(f + q + f')
const scalar_t bf = dz * f_plus_q - h * a; // b_f = dz(f + q) - ha
const scalar_t x0 = scalar_t::random(), x1 = scalar_t::random(), x2 = scalar_t::random();
const scalar_t bx = x2 - h * x1 + dz * x0; // b_x = x'' - hx' + dzx
point_t C = x0 * c_point_X + a * c_point_H + f_plus_q * c_point_G;
point_t C_prime = x1 * c_point_X + f_plus_q * c_point_H + a * c_point_G;
point_t E = bx * c_point_X + ba * c_point_H + bf * c_point_G;
result.C = C.to_public_key();
result.C_prime = C_prime.to_public_key();
result.E = E.to_public_key();
// three proofs with a shared Fiat-Shamir challenge c
// 1) linear composition proof for the fact, that C + C' = lin(X, H + G) = (x + x') X + (a + f + q) (H + G)
// 2) linear composition proof for the fact, that C - C' = lin(X, H - G) = (x - x') X + (a - f - q) (H - G)
// 3) Schnorr proof for the fact, that hC' - dzC + E + f'hH = lin(X) = x'' X
point_t F = h * C_prime - dz * C + E + last_pow_block_id_hashed * h * c_point_H;
scalar_t r0 = scalar_t::random();
scalar_t r1 = scalar_t::random();
scalar_t r2 = scalar_t::random();
scalar_t r3 = scalar_t::random();
scalar_t r4 = scalar_t::random();
point_t R_01 = r0 * c_point_X + r1 * c_point_H_plus_G;
point_t R_23 = r2 * c_point_X + r3 * c_point_H_minus_G;
point_t R_4 = r4 * c_point_G;
hash_helper_t::hs_t hash_calc(3);
hash_calc.add_32_chars(CRYPTO_HDS_ZARCANUM_PROOF_HASH);
hash_calc.add_point(R_01);
hash_calc.add_point(R_23);
hash_calc.add_point(R_4);
hash_calc.add_point(C + C_prime);
hash_calc.add_point(C - C_prime);
hash_calc.add_point(F);
result.c = hash_calc.calc_hash();
result.y0 = r0 + result.c * (x0 + x1); // y_0 = r_0 + c (x + x')
result.y1 = r1 + result.c * (a + f_plus_q); // y_1 = r_1 + c (a + f + q)
result.y2 = r2 + result.c * (x0 - x1); // y_2 = r_2 + c (x - x')
result.y3 = r3 + result.c * (a - f_plus_q); // y_3 = r_3 + c (a - f - q)
result.y4 = r4 + result.c * x2; // y_4 = r_4 + c x''
// range proof for E
const scalar_vec_t values = { a }; // H component
const scalar_vec_t masks = { bf }; // G component
const scalar_vec_t masks2 = { bx }; // X component
const std::vector<const public_key*> commitments_1div8 = { &commitment_1div8 };
if (!bppe_gen<bpp_crypto_trait_zano<>>(values, masks, masks2, commitments_1div8, result.E_range_proof, p_err))
{
return false;
}
// = four-layers ring signature data outline =
// (j in [0, ring_size-1])
// layer 0 ring
// se.outputs[j].stealth_address;
// layer 0 secret (with respect to G)
// in_contexts[i].in_ephemeral.sec;
// layer 0 linkability
// in.k_image;
//
// layer 1 ring
// crypto::point_t(se.outputs[j].amount_commitment) - pseudo_out_amount_commitment;
// layer 1 secret (with respect to G)
// se.real_out_amount_blinding_mask - blinding_mask;
//
// additional layers for Zarcanum:
//
// layer 2 ring
// C - A[j] - Q[j]
// layer 2 secret (with respect to X)
// x0
//
// layer 3 ring
// Q[j]
// layer 3 secret (with respect to G)
// secret_q
return true;
}
bool zarcanum_verify_proof(const hash& kernel_hash, const public_key& commitment_1div8, const scalar_t& last_pow_block_id_hashed, const zarcanum_proof& proof, uint8_t* p_err /* = nullptr */)
{
return false;
}
} // namespace crypto

View file

@ -6,6 +6,8 @@
// Note: This file originates from tests/functional_tests/crypto_tests.cpp
#pragma once
#include "crypto-sugar.h"
#include "crypto/range_proofs.h"
#include "crypto/clsag.h"
#include <boost/multiprecision/cpp_int.hpp>
namespace crypto
@ -19,7 +21,34 @@ namespace crypto
mp::uint256_t zarcanum_precalculate_z_l_div_z_D(const mp::uint128_t& pos_difficulty);
bool zarcanum_check_main_pos_inequality(const hash& kernel_hash, const scalar_t& blinding_mask, const scalar_t& secret_q,
const scalar_t& last_pow_block_id_hashed, const mp::uint256_t& z_l_div_z_D_, uint64_t stake_amount, mp::uint256_t& lhs, mp::uint256_t& rhs);
const scalar_t& last_pow_block_id_hashed, const mp::uint256_t& z_l_div_z_D_, uint64_t stake_amount, mp::uint256_t& lhs, mp::uint512_t& rhs);
struct zarcanum_proof
{
scalar_t d = 0;
public_key C;
public_key C_prime;
public_key E;
scalar_t c; // shared Fiat-Shamir challenge for the following three proofs
scalar_t y0; // 1st linear composition proof
scalar_t y1; // ( C + C' = lin(X, H + G) )
scalar_t y2; // 2nd linear composition proof
scalar_t y3; // ( C - C' = lin(X, H - G) )
scalar_t y4; // Schnorr proof (F = lin(X))
bppe_signature E_range_proof;
CLSAG_GGXG_signature ring_sig;
};
bool zarcanum_generate_proof(const hash& kernel_hash, const public_key& stake_commitment_1div8, const scalar_t& last_pow_block_id_hashed,
const scalar_t& blinding_mask, const scalar_t& secret_q, uint64_t stake_amount,
uint64_t secret_index,
zarcanum_proof& result, uint8_t* p_err = nullptr);
bool zarcanum_verify_proof(const hash& kernel_hash, const public_key& commitment_1div8, const scalar_t& last_pow_block_id_hashed, const zarcanum_proof& proof, uint8_t* p_err = nullptr);
} // namespace crypto

View file

@ -2483,15 +2483,21 @@ size_t blockchain_storage::get_alternative_blocks_count() const
return m_alternative_chains.size();
}
//------------------------------------------------------------------
bool blockchain_storage::add_out_to_get_random_outs(COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::outs_for_amount& result_outs, uint64_t amount, size_t i, uint64_t mix_count, bool use_only_forced_to_mix) const
bool blockchain_storage::add_out_to_get_random_outs(COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::outs_for_amount& result_outs, uint64_t amount, size_t g_index, uint64_t mix_count,
bool use_only_forced_to_mix, uint64_t height_upper_limit) const
{
CRITICAL_REGION_LOCAL(m_read_lock);
auto out_ptr = m_db_outputs.get_subitem(amount, i);
auto out_ptr = m_db_outputs.get_subitem(amount, g_index);
auto tx_ptr = m_db_transactions.find(out_ptr->tx_id);
CHECK_AND_ASSERT_MES(tx_ptr, false, "internal error: transaction with id " << out_ptr->tx_id << ENDL <<
", used in mounts global index for amount=" << amount << ": i=" << i << "not found in transactions index");
", used in mounts global index for amount=" << amount << ": g_index=" << g_index << "not found in transactions index");
CHECK_AND_ASSERT_MES(tx_ptr->tx.vout.size() > out_ptr->out_no, false, "internal error: in global outs index, transaction out index="
<< out_ptr->out_no << " more than transaction outputs = " << tx_ptr->tx.vout.size() << ", for tx id = " << out_ptr->tx_id);
CHECK_AND_ASSERT_MES(amount != 0 || height_upper_limit != 0, false, "height_upper_limit must be nonzero for hidden amounts (amount = 0)");
if (height_upper_limit != 0 && tx_ptr->m_keeper_block_height > height_upper_limit)
return false;
const transaction& tx = tx_ptr->tx;
CHECK_AND_ASSERT_MES(tx_ptr->m_spent_flags.size() == tx.vout.size(), false, "internal error: spent_flag.size()=" << tx_ptr->m_spent_flags.size() << ", tx.vout.size()=" << tx.vout.size());
@ -2503,12 +2509,25 @@ bool blockchain_storage::add_out_to_get_random_outs(COMMAND_RPC_GET_RANDOM_OUTPU
//check if transaction is unlocked
if (!is_tx_spendtime_unlocked(get_tx_unlock_time(tx, out_ptr->out_no)))
return false;
const tx_out_v& out_v = tx.vout[out_ptr->out_no];
// do not use burned coins
if (is_out_burned(tx.vout[out_ptr->out_no]))
if (is_out_burned(out_v))
return false;
VARIANT_SWITCH_BEGIN(tx.vout[out_ptr->out_no]);
// check mix_attr
uint8_t mix_attr = CURRENCY_TO_KEY_OUT_RELAXED;
if (!get_mix_attr_from_tx_out_v(out_v, mix_attr))
return false; // output has no mix_attr, skip it
if (mix_attr == CURRENCY_TO_KEY_OUT_FORCED_NO_MIX)
return false; //COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS call means that ring signature will have more than one entry.
else if (use_only_forced_to_mix && mix_attr == CURRENCY_TO_KEY_OUT_RELAXED)
return false; //relaxed not allowed
else if (mix_attr != CURRENCY_TO_KEY_OUT_RELAXED && mix_attr > mix_count)
return false; //mix_attr set to specific minimum, and mix_count is less then desired count
VARIANT_SWITCH_BEGIN(out_v);
VARIANT_CASE_CONST(tx_out_bare, o)
{
if (o.target.type() == typeid(txout_htlc))
@ -2516,41 +2535,20 @@ bool blockchain_storage::add_out_to_get_random_outs(COMMAND_RPC_GET_RANDOM_OUTPU
//silently return false, it's ok
return false;
}
CHECK_AND_ASSERT_MES(o.target.type() == typeid(txout_to_key), false, "unknown tx out type");
CHECK_AND_ASSERT_MES(o.target.type() == typeid(txout_to_key), false, "unexpected out target type: " << o.target.type().name());
const txout_to_key& otk = boost::get<txout_to_key>(o.target);
// TODO #@#@ remove code duplication, make extracting mix_attr in a more generalized way
//use appropriate mix_attr out
uint8_t mix_attr = otk.mix_attr;
if (mix_attr == CURRENCY_TO_KEY_OUT_FORCED_NO_MIX)
return false; //COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS call means that ring signature will have more than one entry.
else if (use_only_forced_to_mix && mix_attr == CURRENCY_TO_KEY_OUT_RELAXED)
return false; //relaxed not allowed
else if (mix_attr != CURRENCY_TO_KEY_OUT_RELAXED && mix_attr > mix_count)
return false;//mix_attr set to specific minimum, and mix_count is less then desired count
COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::out_entry& oen = *result_outs.outs.insert(result_outs.outs.end(), COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::out_entry());
oen.global_amount_index = i;
oen.out_key = otk.key;
oen.global_amount_index = g_index;
oen.stealth_address = otk.key;
}
VARIANT_CASE_CONST(tx_out_zarcanum, toz)
{
//use appropriate mix_attr out
uint8_t mix_attr = toz.mix_attr;
if (mix_attr == CURRENCY_TO_KEY_OUT_FORCED_NO_MIX)
return false; //COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS call means that ring signature will have more than one entry.
else if (use_only_forced_to_mix && mix_attr == CURRENCY_TO_KEY_OUT_RELAXED)
return false; //relaxed not allowed
else if (mix_attr != CURRENCY_TO_KEY_OUT_RELAXED && mix_attr > mix_count)
return false;//mix_attr set to specific minimum, and mix_count is less then desired count
COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::out_entry& oen = *result_outs.outs.insert(result_outs.outs.end(), COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::out_entry());
oen.global_amount_index = i;
oen.out_key = toz.amount_commitment;
// TODO @#@# this is certainly not enough
oen.amount_commitment = toz.amount_commitment;
oen.concealing_point = toz.concealing_point;
oen.global_amount_index = g_index;
oen.stealth_address = toz.stealth_address;
}
VARIANT_SWITCH_END();
@ -2580,7 +2578,7 @@ size_t blockchain_storage::find_end_of_allowed_index(uint64_t amount) const
bool blockchain_storage::get_random_outs_for_amounts(const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::request& req, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::response& res)const
{
CRITICAL_REGION_LOCAL(m_read_lock);
BOOST_FOREACH(uint64_t amount, req.amounts)
for(uint64_t amount : req.amounts)
{
COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::outs_for_amount& result_outs = *res.outs.insert(res.outs.end(), COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::outs_for_amount());
result_outs.amount = amount;
@ -2594,31 +2592,32 @@ bool blockchain_storage::get_random_outs_for_amounts(const COMMAND_RPC_GET_RANDO
//lets find upper bound of not fresh outs
size_t up_index_limit = find_end_of_allowed_index(amount);
CHECK_AND_ASSERT_MES(up_index_limit <= outs_container_size, false, "internal error: find_end_of_allowed_index returned wrong index=" << up_index_limit << ", with amount_outs.size = " << outs_container_size);
if (up_index_limit >= req.outs_count)
if (up_index_limit >= req.decoys_count)
{
std::set<size_t> used;
size_t try_count = 0;
for(uint64_t j = 0; j != req.outs_count && try_count < up_index_limit;)
for(uint64_t j = 0; j != req.decoys_count && try_count < up_index_limit;)
{
size_t i = crypto::rand<size_t>()%up_index_limit;
if(used.count(i))
size_t g_index = crypto::rand<size_t>() % up_index_limit;
if(used.count(g_index))
continue;
bool added = add_out_to_get_random_outs(result_outs, amount, i, req.outs_count, req.use_forced_mix_outs);
used.insert(i);
bool added = add_out_to_get_random_outs(result_outs, amount, g_index, req.decoys_count, req.use_forced_mix_outs, req.height_upper_limit);
used.insert(g_index);
if(added)
++j;
++try_count;
}
if (result_outs.outs.size() < req.outs_count)
if (result_outs.outs.size() < req.decoys_count)
{
LOG_PRINT_RED_L0("Not enough inputs for amount " << print_money_brief(amount) << ", needed " << req.outs_count << ", added " << result_outs.outs.size() << " good outs from " << up_index_limit << " unlocked of " << outs_container_size << " total");
LOG_PRINT_RED_L0("Not enough inputs for amount " << print_money_brief(amount) << ", needed " << req.decoys_count << ", added " << result_outs.outs.size() << " good outs from " << up_index_limit << " unlocked of " << outs_container_size << " total");
}
}else
}
else
{
size_t added = 0;
for (size_t i = 0; i != up_index_limit; i++)
added += add_out_to_get_random_outs(result_outs, amount, i, req.outs_count, req.use_forced_mix_outs) ? 1 : 0;
LOG_PRINT_RED_L0("Not enough inputs for amount " << print_money_brief(amount) << ", needed " << req.outs_count << ", added " << added << " good outs from " << up_index_limit << " unlocked of " << outs_container_size << " total - respond with all good outs");
added += add_out_to_get_random_outs(result_outs, amount, i, req.decoys_count, req.use_forced_mix_outs, req.height_upper_limit) ? 1 : 0;
LOG_PRINT_RED_L0("Not enough inputs for amount " << print_money_brief(amount) << ", needed " << req.decoys_count << ", added " << added << " good outs from " << up_index_limit << " unlocked of " << outs_container_size << " total - respond with all good outs");
}
}
return true;

View file

@ -624,7 +624,7 @@ namespace currency
bool add_transaction_from_block(const transaction& tx, const crypto::hash& tx_id, const crypto::hash& bl_id, uint64_t bl_height, uint64_t timestamp);
bool push_transaction_to_global_outs_index(const transaction& tx, const crypto::hash& tx_id, std::vector<uint64_t>& global_indexes);
bool pop_transaction_from_global_index(const transaction& tx, const crypto::hash& tx_id);
bool add_out_to_get_random_outs(COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::outs_for_amount& result_outs, uint64_t amount, size_t i, uint64_t mix_count, bool use_only_forced_to_mix = false) const;
bool add_out_to_get_random_outs(COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::outs_for_amount& result_outs, uint64_t amount, size_t i, uint64_t mix_count, bool use_only_forced_to_mix = false, uint64_t height_upper_limit = 0) const;
bool add_block_as_invalid(const block& bl, const crypto::hash& h);
bool add_block_as_invalid(const block_extended_info& bei, const crypto::hash& h);
size_t find_end_of_allowed_index(uint64_t amount)const;

View file

@ -23,6 +23,7 @@
#define CRYPTO_HDS_ZARCANUM_LAST_POW_HASH "ZANO_HDS_ZARCANUM_LAST_POW_HASH"
#define CRYPTO_HDS_ZARCANUM_SECRET_Q "ZANO_HDS_ZARCANUM_SECRET_Q_____"
#define CRYPTO_HDS_ZARCANUM_PROOF_HASH "ZANO_HDS_ZARCANUM_PROOF_HASH___"
#define CRYPTO_HDS_ASSET_CONTROL_KEY "ZANO_HDS_ASSET_CONTROL_KEY_____"
#define CRYPTO_HDS_ASSET_ID "ZANO_HDS_ASSET_ID______________"

View file

@ -38,6 +38,7 @@
#include "crypto/crypto.h"
#include "crypto/hash.h"
#include "crypto/range_proofs.h"
#include "crypto/zarcanum.h"
#include "misc_language.h"
#include "block_flags.h"
#include "etc_custom_serialization.h"
@ -486,6 +487,22 @@ namespace currency
END_BOOST_SERIALIZATION()
};
struct zarcanum_sig : public crypto::zarcanum_proof
{
BEGIN_SERIALIZE_OBJECT()
FIELD(d)
FIELD(C)
// TODO
END_SERIALIZE()
BEGIN_BOOST_SERIALIZATION()
BOOST_SERIALIZE(d)
BOOST_SERIALIZE(C)
// TODO
END_BOOST_SERIALIZATION()
};
//#pragma pack(pop)
typedef boost::variant<txin_gen, txin_to_key, txin_multisig, txin_htlc, txin_zc_input> txin_v;
@ -869,8 +886,7 @@ namespace currency
END_BOOST_SERIALIZATION()
};
typedef boost::variant<NLSAG_sig, void_sig, ZC_sig> signature_v;
typedef boost::variant<NLSAG_sig, void_sig, ZC_sig, zarcanum_sig> signature_v;
@ -1143,10 +1159,11 @@ SET_VARIANT_TAGS(crypto::bppe_signature_serialized, 41, "bppe_signature_serializ
SET_VARIANT_TAGS(currency::NLSAG_sig, 42, "NLSAG_sig");
SET_VARIANT_TAGS(currency::ZC_sig, 43, "ZC_sig");
SET_VARIANT_TAGS(currency::void_sig, 44, "void_sig");
SET_VARIANT_TAGS(currency::zc_outs_range_proof, 45, "zc_outs_range_proof");
SET_VARIANT_TAGS(currency::zc_balance_proof, 46, "zc_balance_proof");
SET_VARIANT_TAGS(currency::zarcanum_sig, 45, "zarcanum_sig");
SET_VARIANT_TAGS(currency::zc_outs_range_proof, 46, "zc_outs_range_proof");
SET_VARIANT_TAGS(currency::zc_balance_proof, 47, "zc_balance_proof");
SET_VARIANT_TAGS(currency::open_asset_id, 47, "asset_id");
SET_VARIANT_TAGS(currency::open_asset_id, 48, "asset_id");
SET_VARIANT_TAGS(currency::asset_descriptor_operation, 48, "asset_descriptor_base");

View file

@ -246,10 +246,8 @@ namespace currency
}
CHECK_AND_ASSERT_MES(destinations.size() <= CURRENCY_TX_MAX_ALLOWED_OUTS || height == 0, false, "Too many outs (" << destinations.size() << ")! Miner tx can't be constructed.");
tx = AUTO_VAL_INIT_T(transaction);
tx.version = tx_version;
tx.vin.clear();
tx.vout.clear();
tx.extra.clear();
keypair txkey = keypair::generate();
add_tx_pub_key_to_extra(tx, txkey.pub);
@ -3968,7 +3966,12 @@ namespace currency
//@#@ TODO
return false;
}
//--------------------------------------------------------------------------------
bool operator ==(const currency::zarcanum_sig& a, const currency::zarcanum_sig& b)
{
//@#@ TODO
return false;
}
//--------------------------------------------------------------------------------
bool verify_multiple_zc_outs_range_proofs(const std::vector<zc_outs_range_proofs_with_commitments>& range_proofs)
{

View file

@ -59,6 +59,7 @@ namespace currency
bool operator ==(const currency::NLSAG_sig& a, const currency::NLSAG_sig& b);
bool operator ==(const currency::void_sig& a, const currency::void_sig& b);
bool operator ==(const currency::ZC_sig& a, const currency::ZC_sig& b);
bool operator ==(const currency::zarcanum_sig& a, const currency::zarcanum_sig& b);
typedef boost::multiprecision::uint128_t uint128_tl;

View file

@ -254,6 +254,35 @@ namespace currency
CHECK_AND_ASSERT_THROW_MES(false, "[get_key_offsets_from_txin_v] Wrong type: " << in_v.type().name());
}
//---------------------------------------------------------------
inline
bool get_mix_attr_from_tx_out_v(const tx_out_v& out_v, uint8_t& result) noexcept
{
try
{
if (out_v.type() == typeid(tx_out_bare))
{
const tx_out_bare& ob = boost::get<tx_out_bare>(out_v);
if (ob.target.type() == typeid(txout_to_key))
{
result = boost::get<txout_to_key>(ob.target).mix_attr;
return true;
}
}
if (out_v.type() == typeid(tx_out_zarcanum))
{
result = boost::get<tx_out_zarcanum>(out_v).mix_attr;
return true;
}
}
catch(...)
{
// should never go here, just precaution
}
return false;
}
//---------------------------------------------------------------
//, txin_htlc, txin_zc_input
inline bool compare_variant_by_types(const txin_multisig& left, const txin_multisig& right)
{

View file

@ -1,4 +1,4 @@
// Copyright (c) 2014-2018 Zano Project
// Copyright (c) 2014-2022 Zano Project
// Copyright (c) 2014-2018 The Louisdor Project
// Copyright (c) 2012-2013 The Cryptonote developers
// Distributed under the MIT/X11 software license, see the accompanying
@ -35,8 +35,11 @@ namespace currency
}
//------------------------------------------------------------------------------------------------------------------------------
core_rpc_server::core_rpc_server(core& cr, nodetool::node_server<currency::t_currency_protocol_handler<currency::core> >& p2p,
bc_services::bc_offers_service& of
) :m_core(cr), m_p2p(p2p), m_of(of), m_session_counter(0), m_ignore_status(false)
bc_services::bc_offers_service& of)
: m_core(cr)
, m_p2p(p2p)
, m_of(of)
, m_ignore_status(false)
{}
//------------------------------------------------------------------------------------------------------------------------------
bool core_rpc_server::handle_command_line(const boost::program_options::variables_map& vm)
@ -830,11 +833,7 @@ namespace currency
params.stakeholder_address = stakeholder_address;
params.ex_nonce = req.extra_text;
params.pos = req.pos_block;
params.pe.amount = req.pos_amount;
params.pe.g_index = req.pos_g_index;
params.pe.tx_id = req.tx_id;
params.pe.tx_out_index = req.tx_out_index;
params.pe.stake_unlock_time = req.stake_unlock_time;
params.pe = req.pe;
//params.pe.keyimage key image will be set in the wallet
//params.pe.wallet_index is not included in serialization map, TODO: refactoring here
params.pcustom_fill_block_template_func = nullptr;
@ -1156,109 +1155,6 @@ namespace currency
return true;
}
//------------------------------------------------------------------------------------------------------------------------------
bool core_rpc_server::get_current_hi(mining::height_info& hi)
{
block prev_block = AUTO_VAL_INIT(prev_block);
m_core.get_blockchain_storage().get_top_block(prev_block);
hi.block_id = string_tools::pod_to_hex(currency::get_block_hash(prev_block));
hi.height = get_block_height(prev_block);
return true;
}
//------------------------------------------------------------------------------------------------------------------------------
void core_rpc_server::set_session_blob(const std::string& session_id, const currency::block& blob)
{
CRITICAL_REGION_LOCAL(m_session_jobs_lock);
m_session_jobs[session_id] = blob;
}
//------------------------------------------------------------------------------------------------------------------------------
bool core_rpc_server::get_session_blob(const std::string& session_id, currency::block& blob)
{
CRITICAL_REGION_LOCAL(m_session_jobs_lock);
auto it = m_session_jobs.find(session_id);
if(it == m_session_jobs.end())
return false;
blob = it->second;
return true;
}
//------------------------------------------------------------------------------------------------------------------------------
bool core_rpc_server::get_job(const std::string& job_id, mining::job_details& job, epee::json_rpc::error& err, connection_context& cntx)
{
COMMAND_RPC_GETBLOCKTEMPLATE::request bt_req = AUTO_VAL_INIT(bt_req);
COMMAND_RPC_GETBLOCKTEMPLATE::response bt_res = AUTO_VAL_INIT(bt_res);
// !!!!!!!! SET YOUR WALLET ADDRESS HERE !!!!!!!!
bt_req.wallet_address = "1HNJjUsofq5LYLoXem119dd491yFAb5g4bCHkecV4sPqigmuxw57Ci9am71fEN4CRmA9jgnvo5PDNfaq8QnprWmS5uLqnbq";
if(!on_getblocktemplate(bt_req, bt_res, err, cntx))
return false;
//patch block blob if you need(bt_res.blocktemplate_blob), and than load block from blob template
//important: you can't change block size, since it could touch reward and block became invalid
block b = AUTO_VAL_INIT(b);
std::string bin_buff;
bool r = string_tools::parse_hexstr_to_binbuff(bt_res.blocktemplate_blob, bin_buff);
CHECK_AND_ASSERT_MES(r, false, "internal error, failed to parse hex block");
r = currency::parse_and_validate_block_from_blob(bin_buff, b);
CHECK_AND_ASSERT_MES(r, false, "internal error, failed to parse block");
set_session_blob(job_id, b);
job.blob = string_tools::buff_to_hex_nodelimer(currency::get_block_hashing_blob(b));
//TODO: set up share difficulty here!
job.difficulty = bt_res.difficulty; //difficulty leaved as string field since it will be refactored into 128 bit format
job.job_id = "SOME_JOB_ID";
get_current_hi(job.prev_hi);
return true;
}
//------------------------------------------------------------------------------------------------------------------------------
bool core_rpc_server::on_login(const mining::COMMAND_RPC_LOGIN::request& req, mining::COMMAND_RPC_LOGIN::response& res, connection_context& cntx)
{
if(!check_core_ready())
{
res.status = API_RETURN_CODE_BUSY;
return true;
}
//TODO: add login information here
res.id = std::to_string(m_session_counter++); //session id
if(req.hi.height)
{
epee::json_rpc::error err = AUTO_VAL_INIT(err);
if(!get_job(res.id, res.job, err, cntx))
{
res.status = err.message;
return true;
}
}
res.status = API_RETURN_CODE_OK;
return true;
}
//------------------------------------------------------------------------------------------------------------------------------
bool core_rpc_server::on_getjob(const mining::COMMAND_RPC_GETJOB::request& req, mining::COMMAND_RPC_GETJOB::response& res, connection_context& cntx)
{
if(!check_core_ready())
{
res.status = API_RETURN_CODE_BUSY;
return true;
}
/*epee::json_rpc::error err = AUTO_VAL_INIT(err);
if(!get_job(req.id, res.jd, err, cntx))
{
res.status = err.message;
return true;
}*/
return true;
}
//------------------------------------------------------------------------------------------------------------------------------
bool core_rpc_server::on_get_alias_reward(const COMMAND_RPC_GET_ALIAS_REWARD::request& req, COMMAND_RPC_GET_ALIAS_REWARD::response& res, epee::json_rpc::error& error_resp, connection_context& cntx)
{
@ -1324,45 +1220,6 @@ namespace currency
return true;
}
//------------------------------------------------------------------------------------------------------------------------------
bool core_rpc_server::on_submit(const mining::COMMAND_RPC_SUBMITSHARE::request& req, mining::COMMAND_RPC_SUBMITSHARE::response& res, connection_context& cntx)
{
if(!check_core_ready())
{
res.status = API_RETURN_CODE_BUSY;
return true;
}
block b = AUTO_VAL_INIT(b);
if(!get_session_blob(req.id, b))
{
res.status = "Wrong session id";
return true;
}
b.nonce = req.nonce;
if(!m_core.handle_block_found(b))
{
res.status = "Block not accepted";
LOG_ERROR("Submited block not accepted");
return true;
}
res.status = API_RETURN_CODE_OK;
return true;
}
//------------------------------------------------------------------------------------------------------------------------------
bool core_rpc_server::on_get_addendums(const COMMAND_RPC_GET_ADDENDUMS::request& req, COMMAND_RPC_GET_ADDENDUMS::response& res, epee::json_rpc::error& error_resp, connection_context& cntx)
{
if (!check_core_ready())
{
res.status = API_RETURN_CODE_BUSY;
return true;
}
res.status = API_RETURN_CODE_OK;
return true;
}
//------------------------------------------------------------------------------------------------------------------------------
bool core_rpc_server::on_reset_transaction_pool(const COMMAND_RPC_RESET_TX_POOL::request& req, COMMAND_RPC_RESET_TX_POOL::response& res, connection_context& cntx)
{
m_core.get_tx_pool().purge_transactions();

View file

@ -14,7 +14,6 @@
#include "currency_core/currency_core.h"
#include "p2p/net_node.h"
#include "currency_protocol/currency_protocol_handler.h"
#include "mining_protocol_defs.h"
#include "currency_core/bc_offers_service.h"
@ -72,7 +71,6 @@ namespace currency
bool on_get_aliases(const COMMAND_RPC_GET_ALIASES::request& req, COMMAND_RPC_GET_ALIASES::response& res, epee::json_rpc::error& error_resp, connection_context& cntx);
bool on_aliases_by_address(const COMMAND_RPC_GET_ALIASES_BY_ADDRESS::request& req, COMMAND_RPC_GET_ALIASES_BY_ADDRESS::response& res, epee::json_rpc::error& error_resp, connection_context& cntx);
bool on_get_alias_reward(const COMMAND_RPC_GET_ALIAS_REWARD::request& req, COMMAND_RPC_GET_ALIAS_REWARD::response& res, epee::json_rpc::error& error_resp, connection_context& cntx);
bool on_get_addendums(const COMMAND_RPC_GET_ADDENDUMS::request& req, COMMAND_RPC_GET_ADDENDUMS::response& res, epee::json_rpc::error& error_resp, connection_context& cntx);
bool on_reset_transaction_pool(const COMMAND_RPC_RESET_TX_POOL::request& req, COMMAND_RPC_RESET_TX_POOL::response& res, connection_context& cntx);
bool on_get_pos_mining_details(const COMMAND_RPC_GET_POS_MINING_DETAILS::request& req, COMMAND_RPC_GET_POS_MINING_DETAILS::response& res, connection_context& cntx);
bool on_get_current_core_tx_expiration_median(const COMMAND_RPC_GET_CURRENT_CORE_TX_EXPIRATION_MEDIAN::request& req, COMMAND_RPC_GET_CURRENT_CORE_TX_EXPIRATION_MEDIAN::response& res, connection_context& cntx);
@ -93,15 +91,6 @@ namespace currency
//mining rpc
bool on_login(const mining::COMMAND_RPC_LOGIN::request& req, mining::COMMAND_RPC_LOGIN::response& res, connection_context& cntx);
bool on_getjob(const mining::COMMAND_RPC_GETJOB::request& req, mining::COMMAND_RPC_GETJOB::response& res, connection_context& cntx);
bool on_submit(const mining::COMMAND_RPC_SUBMITSHARE::request& req, mining::COMMAND_RPC_SUBMITSHARE::response& res, connection_context& cntx);
CHAIN_HTTP_TO_MAP2(connection_context); //forward http requests to uri map
BEGIN_URI_MAP2()
@ -157,10 +146,6 @@ namespace currency
MAP_JON_RPC ("get_current_core_tx_expiration_median", on_get_current_core_tx_expiration_median, COMMAND_RPC_GET_CURRENT_CORE_TX_EXPIRATION_MEDIAN)
//
MAP_JON_RPC_WE("marketplace_global_get_offers_ex", on_get_offers_ex, COMMAND_RPC_GET_OFFERS_EX)
//remote miner rpc
MAP_JON_RPC_N(on_login, mining::COMMAND_RPC_LOGIN)
MAP_JON_RPC_N(on_getjob, mining::COMMAND_RPC_GETJOB)
MAP_JON_RPC_N(on_submit, mining::COMMAND_RPC_SUBMITSHARE)
END_JSON_RPC_MAP()
END_URI_MAP2()
@ -169,8 +154,6 @@ namespace currency
//-----------------------
bool handle_command_line(const boost::program_options::variables_map& vm);
bool check_core_ready_(const std::string& calling_method);
bool get_job(const std::string& job_id, mining::job_details& job, epee::json_rpc::error& err, connection_context& cntx);
bool get_current_hi(mining::height_info& hi);
//utils
uint64_t get_block_reward(const block& blk);
@ -184,10 +167,6 @@ namespace currency
std::string m_port;
std::string m_bind_ip;
bool m_ignore_status;
//mining stuff
epee::critical_section m_session_jobs_lock;
std::map<std::string, currency::block> m_session_jobs; //session id -> blob
std::atomic<size_t> m_session_counter;
};
}

View file

@ -11,7 +11,6 @@
#include "currency_core/difficulty.h"
#include "crypto/hash.h"
#include "p2p/p2p_protocol_defs.h"
#include "rpc/mining_protocol_defs.h"
#include "storages/portable_storage_base.h"
#include "currency_core/offers_service_basics.h"
#include "currency_core/basic_api_response_codes.h"
@ -319,11 +318,13 @@ namespace currency
struct request
{
std::list<uint64_t> amounts;
uint64_t outs_count;
uint64_t decoys_count; // how many decoy outputs needed (per amount)
uint64_t height_upper_limit; // all the decoy outputs must be either older than, or the same age as this height
bool use_forced_mix_outs;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(amounts)
KV_SERIALIZE(outs_count)
KV_SERIALIZE(decoys_count)
KV_SERIALIZE(height_upper_limit)
KV_SERIALIZE(use_forced_mix_outs)
END_KV_SERIALIZE_MAP()
};
@ -332,7 +333,9 @@ namespace currency
struct out_entry
{
uint64_t global_amount_index;
crypto::public_key out_key;
crypto::public_key stealth_address;
crypto::public_key concealing_point;
crypto::public_key amount_commitment;
};
#pragma pack(pop)
@ -804,11 +807,13 @@ namespace currency
std::string wallet_address;
std::string stakeholder_address;
bool pos_block; //is pos block
uint64_t pos_amount; //do we still need it?
uint64_t pos_g_index; //
crypto::hash tx_id;
uint64_t tx_out_index;
uint64_t stake_unlock_time;
//uint64_t pos_amount; //do we still need it?
//uint64_t pos_g_index; //
//crypto::hash tx_id;
//uint64_t tx_out_index;
//uint64_t stake_unlock_time;
pos_entry pe; // for making PoS blocks
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE_BLOB_AS_HEX_STRING(explicit_transaction)
@ -816,11 +821,12 @@ namespace currency
KV_SERIALIZE(wallet_address)
KV_SERIALIZE(stakeholder_address);
KV_SERIALIZE(pos_block)
KV_SERIALIZE(pos_amount)
KV_SERIALIZE(pos_g_index)
KV_SERIALIZE_POD_AS_HEX_STRING(tx_id)
KV_SERIALIZE(tx_out_index)
KV_SERIALIZE(stake_unlock_time)
//KV_SERIALIZE(pos_amount)
//KV_SERIALIZE(pos_g_index)
//KV_SERIALIZE_POD_AS_HEX_STRING(tx_id)
//KV_SERIALIZE(tx_out_index)
//KV_SERIALIZE(stake_unlock_time)
KV_SERIALIZE(pe)
END_KV_SERIALIZE_MAP()
};
@ -1084,25 +1090,6 @@ namespace currency
};
struct COMMAND_RPC_GET_ADDENDUMS
{
typedef mining::height_info request;
struct response
{
std::string status;
std::list<mining::addendum> addms;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(status)
KV_SERIALIZE(addms)
END_KV_SERIALIZE_MAP()
};
};
struct COMMAND_RPC_RESET_TX_POOL
{

View file

@ -1,153 +0,0 @@
// Copyright (c) 2014-2018 Zano Project
// Copyright (c) 2014-2018 The Louisdor Project
// Copyright (c) 2012-2013 The Cryptonote developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#pragma once
#include "currency_protocol/currency_protocol_defs.h"
#include "currency_core/currency_basic.h"
#include "crypto/hash.h"
#include "net/rpc_method_name.h"
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Seems to be obsolete. Consider removing due to stratum support.
//
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
namespace mining
{
struct height_info
{
uint64_t height;
std::string block_id;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(height)
KV_SERIALIZE(block_id)
END_KV_SERIALIZE_MAP()
};
struct addendum
{
height_info hi;
std::string prev_id;
std::string addm;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(hi)
KV_SERIALIZE(prev_id)
KV_SERIALIZE(addm)
END_KV_SERIALIZE_MAP()
};
struct job_details
{
std::string blob;
std::string difficulty;
std::string job_id;
height_info prev_hi;
std::list<addendum> addms;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(blob)
KV_SERIALIZE(difficulty)
KV_SERIALIZE(job_id)
KV_SERIALIZE(prev_hi)
KV_SERIALIZE(addms)
END_KV_SERIALIZE_MAP()
};
struct COMMAND_RPC_LOGIN
{
RPC_METHOD_NAME("login");
struct request
{
std::string login;
std::string pass;
std::string agent;
height_info hi;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(login)
KV_SERIALIZE(pass)
KV_SERIALIZE(agent)
KV_SERIALIZE(hi)
END_KV_SERIALIZE_MAP()
};
struct response
{
std::string status;
std::string id;
job_details job;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(status)
KV_SERIALIZE(id)
KV_SERIALIZE(job)
END_KV_SERIALIZE_MAP()
};
};
struct COMMAND_RPC_GETJOB
{
RPC_METHOD_NAME("getjob");
struct request
{
std::string id;
height_info hi;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(id)
KV_SERIALIZE(hi)
END_KV_SERIALIZE_MAP()
};
struct response
{
std::string status;
job_details jd;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(status)
KV_CHAIN_MAP(jd)
END_KV_SERIALIZE_MAP()
};
};
struct COMMAND_RPC_SUBMITSHARE
{
RPC_METHOD_NAME("submit");
struct request
{
std::string id;
uint64_t nonce;
std::string job_id;
std::string result;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(id)
KV_SERIALIZE(nonce)
KV_SERIALIZE(job_id)
KV_SERIALIZE(result)
END_KV_SERIALIZE_MAP()
};
struct response
{
std::string status;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(status)
END_KV_SERIALIZE_MAP()
};
};
}

View file

@ -3642,51 +3642,55 @@ bool wallet2::get_pos_entries(std::vector<currency::pos_entry>& entries)
return true;
}
//----------------------------------------------------------------------------------------------------
bool wallet2::is_in_hardfork_zone(uint64_t hardfork_index)
bool wallet2::is_in_hardfork_zone(uint64_t hardfork_index) const
{
const currency::core_runtime_config& rtc = get_core_runtime_config();
return rtc.is_hardfork_active_for_height(hardfork_index, get_blockchain_current_size());
return m_core_runtime_config.is_hardfork_active_for_height(hardfork_index, get_blockchain_current_size());
}
//----------------------------------------------------------------------------------------------------
bool wallet2::prepare_and_sign_pos_block(currency::block& b,
const pos_entry& pos_info,
const crypto::public_key& source_tx_pub_key,
uint64_t in_tx_output_index,
const std::vector<const crypto::public_key*>& keys_ptrs)
bool wallet2::prepare_and_sign_pos_block(currency::block& b, const pos_entry& pe) const
{
WLT_CHECK_AND_ASSERT_MES(pe.wallet_index < m_transfers.size(), false, "invalid pe.wallet_index: " << pe.wallet_index);
const transaction& source_tx = m_transfers[pe.wallet_index].m_ptx_wallet_info->m_tx;
if (!is_in_hardfork_zone(ZANO_HARDFORK_04_ZARCANUM))
{
// old PoS with non-hidden amounts
WLT_CHECK_AND_ASSERT_MES(b.miner_tx.vin[0].type() == typeid(currency::txin_gen), false, "Wrong input 0 type in transaction: " << b.miner_tx.vin[0].type().name());
WLT_CHECK_AND_ASSERT_MES(b.miner_tx.vin[1].type() == typeid(currency::txin_to_key), false, "Wrong input 1 type in transaction: " << b.miner_tx.vin[1].type().name());
auto& txin = boost::get<currency::txin_to_key>(b.miner_tx.vin[1]);
txin.k_image = pos_info.keyimage;
txin.k_image = pe.keyimage;
WLT_CHECK_AND_ASSERT_MES(b.miner_tx.signatures.size() == 1 &&
b.miner_tx.signatures[0].type() == typeid(NLSAG_sig) &&
boost::get<NLSAG_sig>(b.miner_tx.signatures[0]).s.size() == txin.key_offsets.size(),
false, "Wrong signatures amount in coinbase transacton");
//derive secret key
crypto::key_derivation pos_coin_derivation = AUTO_VAL_INIT(pos_coin_derivation);
bool r = crypto::generate_key_derivation(source_tx_pub_key,
bool r = crypto::generate_key_derivation(get_tx_pub_key_from_extra(source_tx),
m_account.get_keys().view_secret_key,
pos_coin_derivation);
WLT_CHECK_AND_ASSERT_MES(r, false, "internal error: pos coin base generator: failed to generate_key_derivation("
<< source_tx_pub_key
<< pe.tx_id
<< ", view secret key: " << m_account.get_keys().view_secret_key << ")");
crypto::secret_key derived_secret_ephemeral_key = AUTO_VAL_INIT(derived_secret_ephemeral_key);
crypto::derive_secret_key(pos_coin_derivation,
in_tx_output_index,
pe.tx_out_index,
m_account.get_keys().spend_secret_key,
derived_secret_ephemeral_key);
// sign block actually in coinbase transaction
crypto::hash block_hash = currency::get_block_hash(b);
// get stake output pub key (stealth address) for ring signature generation
std::vector<const crypto::public_key*> keys_ptrs;
TRY_ENTRY()
const currency::tx_out_v& stake_out_v = source_tx.vout[pe.tx_out_index];
keys_ptrs.push_back(&boost::get<currency::txout_to_key>(boost::get<tx_out_bare>(stake_out_v).target).key);
CATCH_ENTRY_CUSTOM("wallet2::prepare_and_sign_pos_block", { LOG_PRINT_RED_L0("unable to get output's pub key because of the exception"); }, false);
crypto::generate_ring_signature(block_hash,
txin.k_image,
keys_ptrs,
@ -3806,7 +3810,8 @@ bool wallet2::do_pos_mining_iteration(mining_context& context, size_t transfer_i
if (context.zarcanum && td.is_zc())
{
crypto::mp::uint256_t lhs, rhs;
crypto::mp::uint256_t lhs;
crypto::mp::uint512_t rhs;
{
PROFILE_FUNC("check_zarcanum");
found = crypto::zarcanum_check_main_pos_inequality(kernel_hash, *td.m_opt_blinding_mask, context.secret_q, context.last_pow_block_id_hashed, context.z_l_div_z_D, stake_amount, lhs, rhs);
@ -3818,7 +3823,7 @@ bool wallet2::do_pos_mining_iteration(mining_context& context, size_t transfer_i
LOG_PRINT_GREEN("Found Zarcanum kernel: amount: " << currency::print_money_brief(stake_amount) << ", gindex: " << td.m_global_output_index << ENDL
<< "difficulty: " << context.basic_diff << ENDL
<< "kernel info: " << ENDL
<< print_stake_kernel_info(context.sk) << ENDL
<< print_stake_kernel_info(context.sk)
<< "kernel_hash: " << kernel_hash << ENDL
<< "lhs: " << lhs << ENDL
<< "rhs: " << rhs
@ -3840,7 +3845,7 @@ bool wallet2::do_pos_mining_iteration(mining_context& context, size_t transfer_i
LOG_PRINT_GREEN("Found kernel: amount: " << currency::print_money_brief(stake_amount)<< ", gindex: " << td.m_global_output_index << ENDL
<< "difficulty: " << context.basic_diff << ", final_diff: " << final_diff << ENDL
<< "kernel info: " << ENDL
<< print_stake_kernel_info(context.sk) << ENDL
<< print_stake_kernel_info(context.sk)
<< "kernel_hash(proof): " << kernel_hash,
LOG_LEVEL_0);
}
@ -3861,15 +3866,12 @@ bool wallet2::reset_history()
return true;
}
//-------------------------------
bool wallet2::build_minted_block(const mining_context& cxt,
uint64_t new_block_expected_height /* = UINT64_MAX */)
bool wallet2::build_minted_block(const mining_context& cxt)
{
return build_minted_block(cxt, m_account.get_public_address(), new_block_expected_height);
return build_minted_block(cxt, m_account.get_public_address());
}
bool wallet2::build_minted_block(const mining_context& cxt,
const currency::account_public_address& miner_address,
uint64_t new_block_expected_height /* UINT64_MAX */)
bool wallet2::build_minted_block(const mining_context& cxt, const currency::account_public_address& miner_address)
{
//found a block, construct it, sign and push to daemon
WLT_LOG_GREEN("Found kernel, constructing block", LOG_LEVEL_0);
@ -3877,21 +3879,30 @@ bool wallet2::build_minted_block(const mining_context& cxt,
WLT_CHECK_AND_ASSERT_MES(cxt.index < m_transfers.size(), false, "cxt.index = " << cxt.index << " is out of bounds");
const transfer_details& td = m_transfers[cxt.index];
pos_entry pe = AUTO_VAL_INIT(pe);
currency::COMMAND_RPC_GETBLOCKTEMPLATE::request tmpl_req = AUTO_VAL_INIT(tmpl_req);
currency::COMMAND_RPC_GETBLOCKTEMPLATE::response tmpl_rsp = AUTO_VAL_INIT(tmpl_rsp);
tmpl_req.wallet_address = get_account_address_as_str(miner_address);
tmpl_req.stakeholder_address = get_account_address_as_str(m_account.get_public_address());
tmpl_req.pos_block = true;
pe.g_index = tmpl_req.pos_g_index = td.m_global_output_index;
pe.amount = tmpl_req.pos_amount = td.amount();// pe.amount;
pe.keyimage = td.m_key_image;
pe.block_timestamp = td.m_ptx_wallet_info->m_block_timestamp;
pe.stake_unlock_time = tmpl_req.stake_unlock_time = cxt.stake_unlock_time;
pe.tx_id = tmpl_req.tx_id = td.tx_hash();
pe.tx_out_index = tmpl_req.tx_out_index = td.m_internal_output_index;
pe.wallet_index = cxt.index;
tmpl_req.pe = AUTO_VAL_INIT(tmpl_req.pe);
tmpl_req.pe.amount = td.amount();
tmpl_req.pe.block_timestamp = td.m_ptx_wallet_info->m_block_timestamp;
tmpl_req.pe.g_index = td.m_global_output_index;
tmpl_req.pe.keyimage = td.m_key_image;
tmpl_req.pe.stake_unlock_time = cxt.stake_unlock_time;
tmpl_req.pe.tx_id = td.tx_hash();
tmpl_req.pe.tx_out_index = td.m_internal_output_index;
tmpl_req.pe.wallet_index = cxt.index;
//pe.g_index = tmpl_req.pos_g_index = td.m_global_output_index;
//pe.amount = tmpl_req.pos_amount = td.amount();// pe.amount;
//pe.keyimage = td.m_key_image;
//pe.block_timestamp = td.m_ptx_wallet_info->m_block_timestamp;
//pe.stake_unlock_time = tmpl_req.stake_unlock_time = cxt.stake_unlock_time;
//pe.tx_id = tmpl_req.tx_id = td.tx_hash();
//pe.tx_out_index = tmpl_req.tx_out_index = td.m_internal_output_index;
//pe.wallet_index = cxt.index;
//tmpl_req.pos_index = pe.index; // gindex <--- this should be removed as soon as pos_entry::index is replaced with tx_id and tx_out_index
// TODO: also fill out tx_id and tx_out_index for mining tx creation
@ -3909,9 +3920,9 @@ bool wallet2::build_minted_block(const mining_context& cxt,
currency::block b = AUTO_VAL_INIT(b);
currency::blobdata block_blob;
bool res = epee::string_tools::parse_hexstr_to_binbuff(tmpl_rsp.blocktemplate_blob, block_blob);
WLT_CHECK_AND_ASSERT_MES(res, false, "Failed to create block template after kernel hash found!");
WLT_CHECK_AND_ASSERT_MES(res, false, "parse_hexstr_to_binbuff() failed after kernel hash found!");
res = parse_and_validate_block_from_blob(block_blob, b);
WLT_CHECK_AND_ASSERT_MES(res, false, "Failed to create block template after kernel hash found!");
WLT_CHECK_AND_ASSERT_MES(res, false, "parse_and_validate_block_from_blob() failed after kernel hash found!");
if (cxt.last_block_hash != b.prev_id)
{
@ -3936,19 +3947,7 @@ bool wallet2::build_minted_block(const mining_context& cxt,
else
{
// old fashioned non-hidden amount PoS scheme
const auto& target = boost::get<tx_out_bare>(stake_out_v).target;
WLT_CHECK_AND_ASSERT_MES(target.type() == typeid(currency::txout_to_key), false, "wrong type_id in source transaction in coinbase tx");
const currency::txout_to_key& stake_out_to_key = boost::get<currency::txout_to_key>(target);
std::vector<const crypto::public_key*> keys_ptrs;
keys_ptrs.push_back(&stake_out_to_key.key);
//sign block
res = prepare_and_sign_pos_block(b,
pe,
get_tx_pub_key_from_extra(m_transfers[pe.wallet_index].m_ptx_wallet_info->m_tx),
td.m_internal_output_index,
keys_ptrs);
res = prepare_and_sign_pos_block(b, tmpl_req.pe);
WLT_CHECK_AND_ASSERT_MES(res, false, "Failed to prepare_and_sign_pos_block");
}
@ -4804,7 +4803,7 @@ bool wallet2::prepare_tx_sources(size_t fake_outputs_count, std::vector<currency
{
COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::request req = AUTO_VAL_INIT(req);
req.use_forced_mix_outs = false; //add this feature to UI later
req.outs_count = fake_outputs_count + 1;// add one to make possible (if need) to skip real output key
req.decoys_count = fake_outputs_count + 1;// add one to make possible (if need) to skip real output key
for (uint64_t i: selected_indicies)
{
auto it = m_transfers.begin() + i;
@ -4824,7 +4823,7 @@ bool wallet2::prepare_tx_sources(size_t fake_outputs_count, std::vector<currency
std::vector<COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::outs_for_amount> scanty_outs;
for(COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::outs_for_amount& amount_outs : daemon_resp.outs)
{
if (amount_outs.outs.size() < req.outs_count)
if (amount_outs.outs.size() < req.decoys_count)
{
scanty_outs.push_back(amount_outs);
}
@ -4856,8 +4855,10 @@ bool wallet2::prepare_tx_sources(size_t fake_outputs_count, std::vector<currency
if (td.m_global_output_index == daemon_oe.global_amount_index)
continue;
tx_output_entry oe = AUTO_VAL_INIT(oe);
oe.out_reference = daemon_oe.global_amount_index;
oe.stealth_address = daemon_oe.out_key;
oe.amount_commitment = daemon_oe.amount_commitment;
oe.concealing_point = daemon_oe.concealing_point;
oe.out_reference = daemon_oe.global_amount_index;
oe.stealth_address = daemon_oe.stealth_address;
src.outputs.push_back(oe);
if (src.outputs.size() >= fake_outputs_count)
break;
@ -6053,7 +6054,7 @@ void wallet2::sweep_below(size_t fake_outs_count, const currency::account_public
{
COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::request req = AUTO_VAL_INIT(req);
req.use_forced_mix_outs = false;
req.outs_count = fake_outs_count + 1;
req.decoys_count = fake_outs_count + 1;
for (uint64_t i : selected_transfers)
req.amounts.push_back(m_transfers[i].amount());
@ -6124,7 +6125,7 @@ void wallet2::sweep_below(size_t fake_outs_count, const currency::account_public
continue;
tx_output_entry oe = AUTO_VAL_INIT(oe);
oe.out_reference = daemon_oe.global_amount_index;
oe.stealth_address = daemon_oe.out_key;
oe.stealth_address = daemon_oe.stealth_address;
src.outputs.push_back(oe);
if (src.outputs.size() >= fake_outs_count)
break;

View file

@ -842,11 +842,7 @@ namespace tools
//next functions in public area only becausce of test_generator
//TODO: Need refactoring - remove it back to private zone
void set_genesis(const crypto::hash& genesis_hash);
bool prepare_and_sign_pos_block(currency::block& b,
const currency::pos_entry& pos_info,
const crypto::public_key& source_tx_pub_key,
uint64_t in_tx_output_index,
const std::vector<const crypto::public_key*>& keys_ptrs);
bool prepare_and_sign_pos_block(currency::block& b, const currency::pos_entry& pe) const;
void process_new_blockchain_entry(const currency::block& b,
const currency::block_direct_data_entry& bche,
const crypto::hash& bl_id,
@ -857,8 +853,8 @@ namespace tools
bool get_pos_entries(std::vector<currency::pos_entry>& entries); // TODO: make it const
size_t get_pos_entries_count();
bool build_minted_block(const mining_context& cxt, uint64_t new_block_expected_height = UINT64_MAX);
bool build_minted_block(const mining_context& cxt, const currency::account_public_address& miner_address, uint64_t new_block_expected_height = UINT64_MAX);
bool build_minted_block(const mining_context& cxt);
bool build_minted_block(const mining_context& cxt, const currency::account_public_address& miner_address);
bool reset_history();
bool is_transfer_unlocked(const transfer_details& td) const;
bool is_transfer_unlocked(const transfer_details& td, bool for_pos_mining, uint64_t& stake_lock_time) const;
@ -1064,7 +1060,7 @@ private:
uint64_t get_directly_spent_transfer_index_by_input_in_tracking_wallet(uint64_t amount, const std::vector<currency::txout_ref_v> & key_offsets);
uint64_t get_directly_spent_transfer_index_by_input_in_tracking_wallet(const currency::txin_to_key& intk);
uint64_t get_directly_spent_transfer_index_by_input_in_tracking_wallet(const currency::txin_zc_input& inzc);
bool is_in_hardfork_zone(uint64_t hardfork_index);
bool is_in_hardfork_zone(uint64_t hardfork_index) const;
uint8_t out_get_mixin_attr(const currency::tx_out_v& out_t);
const crypto::public_key& out_get_pub_key(const currency::tx_out_v& out_t, std::list<currency::htlc_info>& htlc_info_list);

View file

@ -353,7 +353,7 @@ bool test_generator::sign_block(currency::block& b,
const std::vector<const block_info*>& blocks,
const outputs_index& oi)
{
uint64_t h = 0;
/*uint64_t h = 0;
uint64_t out_i = 0;
const transaction * pts = nullptr;
crypto::public_key source_tx_pub_key = null_pkey;
@ -368,11 +368,9 @@ bool test_generator::sign_block(currency::block& b,
out_i,
source_tx_pub_key,
out_key);
CHECK_AND_ASSERT_THROW_MES(r, "Failed to get_output_details_by_global_index()");
CHECK_AND_ASSERT_THROW_MES(r, "Failed to get_output_details_by_global_index()");*/
std::vector<const crypto::public_key*> keys_ptrs;
keys_ptrs.push_back(&out_key);
r = w.prepare_and_sign_pos_block(b, pe, source_tx_pub_key, out_i, keys_ptrs);
bool r = w.prepare_and_sign_pos_block(b, pe);
CHECK_AND_ASSERT_THROW_MES(r,"Failed to prepare_and_sign_pos_block()");
return true;

View file

@ -52,7 +52,7 @@ bool get_random_outs_test::check_get_rand_outs(currency::core& c, size_t ev_inde
{
currency::COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::request req = AUTO_VAL_INIT(req);
req.amounts.push_back(m_amount);
req.outs_count = 4;
req.decoys_count = 4;
req.use_forced_mix_outs = false;
currency::COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::response res = AUTO_VAL_INIT(res);
c.get_blockchain_storage().get_random_outs_for_amounts(req, res);

View file

@ -119,20 +119,17 @@ bool zarcanum_basic_test::c1(currency::core& c, size_t ev_index, const std::vect
miner_benefeciary_acc.generate();
std::shared_ptr<tools::wallet2> miner_benefeciary_acc_wlt = init_playtime_test_wallet(events, c, miner_benefeciary_acc);
alice_wlt->refresh();
size_t pos_entries_count = 0;
//do staking
for(size_t i = 0; i!= CURRENCY_MINED_MONEY_UNLOCK_WINDOW+4; i++)
for(size_t i = 0; i != CURRENCY_MINED_MONEY_UNLOCK_WINDOW + 4; i++)
{
if (!mine_next_pos_block_in_playtime_with_wallet(*alice_wlt.get(), staker_benefeciary_acc_wlt->get_account().get_public_address(), pos_entries_count))
{
CHECK_AND_ASSERT_MES(false, false, "Couldn't generate staking");
return false;
}
if (!mine_next_pow_block_in_playtime(miner_benefeciary_acc.get_public_address(), c))
{
CHECK_AND_ASSERT_MES(false, false, "Couldn't generate pow");
return false;
}
r = mine_next_pos_block_in_playtime_with_wallet(*alice_wlt.get(), staker_benefeciary_acc_wlt->get_account().get_public_address(), pos_entries_count);
CHECK_AND_ASSERT_MES(r, false, "mine_next_pos_block_in_playtime_with_wallet failed");
r = mine_next_pow_block_in_playtime(miner_benefeciary_acc.get_public_address(), c);
CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime failed");
}
//attempt to spend staked and mined coinbase outs
@ -140,10 +137,10 @@ bool zarcanum_basic_test::c1(currency::core& c, size_t ev_index, const std::vect
miner_benefeciary_acc_wlt->refresh();
staker_benefeciary_acc_wlt->transfer(transfer_amount2, bob_acc.get_public_address());
LOG_PRINT_MAGENTA("Zarcanum(pos-coinbase)-2-zarcanum transaction sent from Staker to Bob " << transfer_amount2, LOG_LEVEL_0);
LOG_PRINT_MAGENTA("Zarcanum(pos-coinbase)-2-zarcanum transaction sent from Staker to Bob " << print_money_brief(transfer_amount2), LOG_LEVEL_0);
miner_benefeciary_acc_wlt->transfer(transfer_amount2, bob_acc.get_public_address());
LOG_PRINT_MAGENTA("Zarcanum(pow-coinbase)-2-zarcanum transaction sent from Staker to Bob " << transfer_amount2, LOG_LEVEL_0);
LOG_PRINT_MAGENTA("Zarcanum(pow-coinbase)-2-zarcanum transaction sent from Staker to Bob " << print_money_brief(transfer_amount2), LOG_LEVEL_0);
CHECK_AND_FORCE_ASSERT_MES(c.get_pool_transactions_count() == 2, false, "Incorrect txs count in the pool");

View file

@ -1118,6 +1118,14 @@ TEST(crypto, scalar_arithmetic_assignment)
return true;
}
TEST(crypto, constants)
{
ASSERT_EQ(c_point_H_plus_G, c_point_H + c_point_G);
ASSERT_EQ(c_point_H_minus_G, c_point_H - c_point_G);
return true;
}
TEST(crypto, point_basics)
{
scalar_t s = 4;