forked from lthn/blockchain
merge from zarcanum
This commit is contained in:
commit
52b70ffb24
24 changed files with 406 additions and 515 deletions
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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; \
|
||||
} \
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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______________"
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue