forked from lthn/blockchain
Merge branch 'develop' into cryptoassets
This commit is contained in:
commit
e163c5f691
23 changed files with 241 additions and 126 deletions
|
|
@ -407,8 +407,11 @@ bool generate_genesis(const std::string& path_config, uint64_t premine_split_amo
|
|||
|
||||
ss.str("");
|
||||
ss.clear();
|
||||
const account_public_address dummy_address = AUTO_VAL_INIT(dummy_address);
|
||||
|
||||
std::cout << ENDL << "PROOF PHRASE: " << gcp.proof_string << ENDL;
|
||||
// construct_miner_tx(0, 0, 0, 0, 0, destinations, bl.miner_tx, TRANSACTION_VERSION_PRE_HF4, gcp.proof_string, CURRENCY_MINER_TX_MAX_OUTS); <-- temporarily commented out; this overload needs to be re-implemented -- sowle
|
||||
uint64_t block_reward_without_fee = 0;
|
||||
construct_miner_tx(0, 0, 0, 0, 0, dummy_address, dummy_address, bl.miner_tx, block_reward_without_fee, TRANSACTION_VERSION_PRE_HF4, gcp.proof_string, CURRENCY_MINER_TX_MAX_OUTS, false, pos_entry(), nullptr, nullptr, destinations);
|
||||
currency::blobdata txb = tx_to_blob(bl.miner_tx);
|
||||
|
||||
//self validate block
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// Copyright (c) 2020-2023 Zano Project
|
||||
// Copyright (c) 2020-2023 sowle (val@zano.org, crypto.sowle@gmail.com)
|
||||
// Copyright (c) 2020-2024 Zano Project
|
||||
// Copyright (c) 2020-2024 sowle (val@zano.org, crypto.sowle@gmail.com)
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
//
|
||||
|
|
@ -1342,6 +1342,15 @@ namespace crypto
|
|||
return hs_calculator.calc_hash();
|
||||
}
|
||||
|
||||
static scalar_t hs(const char(&str32)[32], const scalar_t& s, const crypto::public_key& pk)
|
||||
{
|
||||
hs_t hs_calculator(2);
|
||||
hs_calculator.add_32_chars(str32);
|
||||
hs_calculator.add_scalar(s);
|
||||
hs_calculator.add_pub_key(pk);
|
||||
return hs_calculator.calc_hash();
|
||||
}
|
||||
|
||||
static scalar_t hs(const crypto::public_key& pk, const uint64_t i)
|
||||
{
|
||||
hs_t hs_calculator(2);
|
||||
|
|
|
|||
|
|
@ -126,6 +126,9 @@ namespace crypto
|
|||
template<generator_tag gen>
|
||||
inline bool verify_schnorr_sig(const hash& m, const public_key& A, const generic_schnorr_sig& sig) noexcept;
|
||||
|
||||
// TODO @#@# make optimized version inline bool verify_schnorr_sig(const hash& m, const point_t& A, const generic_schnorr_sig& sig) noexcept;
|
||||
// and change check_tx_balance() accordingly
|
||||
|
||||
template<>
|
||||
inline bool verify_schnorr_sig<gt_G>(const hash& m, const public_key& A, const generic_schnorr_sig& sig) noexcept
|
||||
{
|
||||
|
|
|
|||
|
|
@ -771,7 +771,7 @@ namespace currency
|
|||
{
|
||||
uint8_t operation_type = ASSET_DESCRIPTOR_OPERATION_UNDEFINED;
|
||||
asset_descriptor_base descriptor;
|
||||
boost::optional<crypto::public_key> opt_amount_commitment; // premultiplied by 1/8
|
||||
boost::optional<crypto::public_key> opt_amount_commitment; // premultiplied by 1/8 TODO: make it non-optional, as it must always be present -- sowle
|
||||
boost::optional<crypto::signature> opt_proof; // operation proof - for update/emit
|
||||
boost::optional<crypto::public_key> opt_asset_id; // target asset_id - for update/emit
|
||||
uint8_t verion = ASSET_DESCRIPTOR_OPERATION_STRUCTURE_VER;
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
#ifndef TESTNET
|
||||
#define CURRENCY_FORMATION_VERSION 84
|
||||
#else
|
||||
#define CURRENCY_FORMATION_VERSION 90
|
||||
#define CURRENCY_FORMATION_VERSION 93
|
||||
#endif
|
||||
|
||||
#define CURRENCY_GENESIS_NONCE (CURRENCY_FORMATION_VERSION + 101011010121) //bender's nightmare
|
||||
|
|
@ -273,7 +273,7 @@
|
|||
#define ZANO_HARDFORK_01_AFTER_HEIGHT 0
|
||||
#define ZANO_HARDFORK_02_AFTER_HEIGHT 0
|
||||
#define ZANO_HARDFORK_03_AFTER_HEIGHT 0
|
||||
#define ZANO_HARDFORK_04_AFTER_HEIGHT 1440
|
||||
#define ZANO_HARDFORK_04_AFTER_HEIGHT 4440
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -367,9 +367,12 @@ namespace currency
|
|||
bool pos /* = false */,
|
||||
const pos_entry& pe /* = pos_entry() */, // only pe.stake_unlock_time and pe.stake_amount are used now, TODO: consider refactoring -- sowle
|
||||
tx_generation_context* ogc_ptr /* = nullptr */,
|
||||
const keypair* tx_one_time_key_to_use /* = nullptr */
|
||||
const keypair* tx_one_time_key_to_use /* = nullptr */,
|
||||
const std::vector<tx_destination_entry>& destinations_ /* = std::vector<tx_destination_entry>() */
|
||||
)
|
||||
{
|
||||
std::vector<tx_destination_entry> destinations = destinations_;
|
||||
|
||||
bool r = false;
|
||||
|
||||
if (!get_block_reward(pos, median_size, current_block_size, already_generated_coins, block_reward_without_fee, height))
|
||||
|
|
@ -379,45 +382,48 @@ namespace currency
|
|||
}
|
||||
uint64_t block_reward = block_reward_without_fee + fee;
|
||||
|
||||
//
|
||||
// prepare destinations
|
||||
//
|
||||
// 1. split block_reward into out_amounts
|
||||
std::vector<uint64_t> out_amounts;
|
||||
if (tx_version > TRANSACTION_VERSION_PRE_HF4)
|
||||
if (!destinations.size())
|
||||
{
|
||||
// randomly split into CURRENCY_TX_MIN_ALLOWED_OUTS outputs for PoW block, or for PoS block only if the stakeholder address differs
|
||||
// (otherwise for PoS miner tx there will be ONE output with amount = stake_amount + reward)
|
||||
if (!pos || miner_address != stakeholder_address)
|
||||
decompose_amount_randomly(block_reward, [&](uint64_t a){ out_amounts.push_back(a); }, CURRENCY_TX_MIN_ALLOWED_OUTS);
|
||||
}
|
||||
else
|
||||
{
|
||||
// non-hidden outs: split into digits
|
||||
decompose_amount_into_digits(block_reward, DEFAULT_DUST_THRESHOLD,
|
||||
[&out_amounts](uint64_t a_chunk) { out_amounts.push_back(a_chunk); },
|
||||
[&out_amounts](uint64_t a_dust) { out_amounts.push_back(a_dust); });
|
||||
CHECK_AND_ASSERT_MES(1 <= max_outs, false, "max_out must be non-zero");
|
||||
while (max_outs < out_amounts.size())
|
||||
//
|
||||
// prepare destinations
|
||||
//
|
||||
// 1. split block_reward into out_amounts
|
||||
std::vector<uint64_t> out_amounts;
|
||||
if (tx_version > TRANSACTION_VERSION_PRE_HF4)
|
||||
{
|
||||
out_amounts[out_amounts.size() - 2] += out_amounts.back();
|
||||
out_amounts.resize(out_amounts.size() - 1);
|
||||
// randomly split into CURRENCY_TX_MIN_ALLOWED_OUTS outputs for PoW block, or for PoS block only if the stakeholder address differs
|
||||
// (otherwise for PoS miner tx there will be ONE output with amount = stake_amount + reward)
|
||||
if (!pos || miner_address != stakeholder_address)
|
||||
decompose_amount_randomly(block_reward, [&](uint64_t a) { out_amounts.push_back(a); }, CURRENCY_TX_MIN_ALLOWED_OUTS);
|
||||
}
|
||||
}
|
||||
// 2. construct destinations using out_amounts
|
||||
std::vector<tx_destination_entry> destinations;
|
||||
for (auto a : out_amounts)
|
||||
{
|
||||
tx_destination_entry de = AUTO_VAL_INIT(de);
|
||||
de.addr.push_back(miner_address);
|
||||
de.amount = a;
|
||||
de.flags |= tx_destination_entry_flags::tdef_explicit_native_asset_id; // don't use asset id blinding as it's obvious which asset it is
|
||||
if (pe.stake_unlock_time && pe.stake_unlock_time > height + CURRENCY_MINED_MONEY_UNLOCK_WINDOW)
|
||||
else
|
||||
{
|
||||
//this means that block is creating after hardfork_1 and unlock_time is needed to set for every destination separately
|
||||
de.unlock_time = height + CURRENCY_MINED_MONEY_UNLOCK_WINDOW;
|
||||
// non-hidden outs: split into digits
|
||||
decompose_amount_into_digits(block_reward, DEFAULT_DUST_THRESHOLD,
|
||||
[&out_amounts](uint64_t a_chunk) { out_amounts.push_back(a_chunk); },
|
||||
[&out_amounts](uint64_t a_dust) { out_amounts.push_back(a_dust); });
|
||||
CHECK_AND_ASSERT_MES(1 <= max_outs, false, "max_out must be non-zero");
|
||||
while (max_outs < out_amounts.size())
|
||||
{
|
||||
out_amounts[out_amounts.size() - 2] += out_amounts.back();
|
||||
out_amounts.resize(out_amounts.size() - 1);
|
||||
}
|
||||
}
|
||||
// 2. construct destinations using out_amounts
|
||||
|
||||
for (auto a : out_amounts)
|
||||
{
|
||||
tx_destination_entry de = AUTO_VAL_INIT(de);
|
||||
de.addr.push_back(miner_address);
|
||||
de.amount = a;
|
||||
de.flags |= tx_destination_entry_flags::tdef_explicit_native_asset_id; // don't use asset id blinding as it's obvious which asset it is
|
||||
if (pe.stake_unlock_time && pe.stake_unlock_time > height + CURRENCY_MINED_MONEY_UNLOCK_WINDOW)
|
||||
{
|
||||
//this means that block is creating after hardfork_1 and unlock_time is needed to set for every destination separately
|
||||
de.unlock_time = height + CURRENCY_MINED_MONEY_UNLOCK_WINDOW;
|
||||
}
|
||||
destinations.push_back(de);
|
||||
}
|
||||
destinations.push_back(de);
|
||||
}
|
||||
|
||||
if (pos)
|
||||
|
|
@ -2105,7 +2111,7 @@ namespace currency
|
|||
{
|
||||
crypto::hash h = get_hash_from_POD_objects(CRYPTO_HDS_ASSET_ID, asset_owner);
|
||||
|
||||
// this hash function needs to be computationally expensive (s.e. the whitepaper)
|
||||
// this hash function needs to be computationally expensive (s.a. the whitepaper)
|
||||
for(uint64_t i = 0; i < CRYPTO_HASH_ASSET_ID_ITERATIONS; ++i)
|
||||
h = get_hash_from_POD_objects(CRYPTO_HDS_ASSET_ID, h, i);
|
||||
|
||||
|
|
@ -2139,21 +2145,20 @@ namespace currency
|
|||
bool construct_tx_handle_ado(const account_keys& sender_account_keys,
|
||||
const finalize_tx_param& ftp,
|
||||
asset_descriptor_operation& ado,
|
||||
tx_generation_context& gen_context,
|
||||
const crypto::secret_key& one_time_tx_secret_key,
|
||||
tx_generation_context& gen_context,
|
||||
const keypair& tx_key,
|
||||
std::vector<tx_destination_entry>& shuffled_dsts)
|
||||
{
|
||||
if (ado.operation_type == ASSET_DESCRIPTOR_OPERATION_REGISTER)
|
||||
{
|
||||
//CHECK_AND_ASSERT_MES(ado.operation_type == ASSET_DESCRIPTOR_OPERATION_REGISTER, false, "unsupported asset operation: " << (int)ado.operation_type);
|
||||
crypto::secret_key asset_control_key{};
|
||||
bool r = derive_key_pair_from_key_pair(sender_account_keys.account_address.spend_public_key, one_time_tx_secret_key, asset_control_key, ado.descriptor.owner, CRYPTO_HDS_ASSET_CONTROL_KEY);
|
||||
bool r = derive_key_pair_from_key_pair(sender_account_keys.account_address.spend_public_key, tx_key.sec, asset_control_key, ado.descriptor.owner, CRYPTO_HDS_ASSET_CONTROL_KEY);
|
||||
CHECK_AND_ASSERT_MES(r, false, "derive_key_pair_from_key_pair failed");
|
||||
|
||||
calculate_asset_id(ado.descriptor.owner, &gen_context.ao_asset_id_pt, &gen_context.ao_asset_id);
|
||||
|
||||
// calculate amount blinding mask
|
||||
gen_context.ao_amount_blinding_mask = crypto::hash_helper_t::hs(CRYPTO_HDS_ASSET_CONTROL_ABM, asset_control_key);
|
||||
gen_context.ao_amount_blinding_mask = crypto::hash_helper_t::hs(CRYPTO_HDS_ASSET_CONTROL_ABM, asset_control_key, tx_key.pub);
|
||||
|
||||
// set correct asset_id to the corresponding destination entries
|
||||
uint64_t amount_of_emitted_asset = 0;
|
||||
|
|
@ -2169,22 +2174,17 @@ namespace currency
|
|||
|
||||
gen_context.ao_amount_commitment = amount_of_emitted_asset * gen_context.ao_asset_id_pt + gen_context.ao_amount_blinding_mask * crypto::c_point_G;
|
||||
ado.opt_amount_commitment = (crypto::c_scalar_1div8 * gen_context.ao_amount_commitment).to_public_key();
|
||||
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
if (ado.operation_type == ASSET_DESCRIPTOR_OPERATION_EMIT)
|
||||
{
|
||||
|
||||
//bool r = derive_key_pair_from_key_pair(sender_account_keys.account_address.spend_public_key, one_time_tx_secret_key, asset_control_key, ado.descriptor.owner, CRYPTO_HDS_ASSET_CONTROL_KEY);
|
||||
//CHECK_AND_ASSERT_MES(r, false, "derive_key_pair_from_key_pair failed");
|
||||
|
||||
//calculate_asset_id(ado.descriptor.owner, &gen_context.ao_asset_id_pt, &gen_context.ao_asset_id);
|
||||
CHECK_AND_ASSERT_MES(ado.opt_asset_id, false, "ado.opt_asset_id is not found at ado.operation_type == ASSET_DESCRIPTOR_OPERATION_EMIT/UPDATE");
|
||||
CHECK_AND_ASSERT_MES(ado.opt_asset_id, false, "ado.opt_asset_id is not found at ado.operation_type == ASSET_DESCRIPTOR_OPERATION_EMIT");
|
||||
|
||||
gen_context.ao_asset_id = *ado.opt_asset_id;
|
||||
gen_context.ao_asset_id_pt.from_public_key(gen_context.ao_asset_id);
|
||||
// calculate amount blinding mask
|
||||
gen_context.ao_amount_blinding_mask = crypto::hash_helper_t::hs(CRYPTO_HDS_ASSET_CONTROL_ABM, ftp.asset_control_key);
|
||||
gen_context.ao_amount_blinding_mask = crypto::hash_helper_t::hs(CRYPTO_HDS_ASSET_CONTROL_ABM, ftp.asset_control_key, tx_key.pub);
|
||||
|
||||
// set correct asset_id to the corresponding destination entries
|
||||
uint64_t amount_of_emitted_asset = 0;
|
||||
|
|
@ -2196,7 +2196,7 @@ namespace currency
|
|||
item.asset_id = gen_context.ao_asset_id;
|
||||
}
|
||||
}
|
||||
ado.descriptor.current_supply += amount_of_emitted_asset; // TODO: consider setting current_supply beforehand, not setting it hear in ad-hoc manner -- sowle
|
||||
ado.descriptor.current_supply += amount_of_emitted_asset;
|
||||
|
||||
gen_context.ao_amount_commitment = amount_of_emitted_asset * gen_context.ao_asset_id_pt + gen_context.ao_amount_blinding_mask * crypto::c_point_G;
|
||||
ado.opt_amount_commitment = (crypto::c_scalar_1div8 * gen_context.ao_amount_commitment).to_public_key();
|
||||
|
|
@ -2204,22 +2204,20 @@ namespace currency
|
|||
}
|
||||
else if (ado.operation_type == ASSET_DESCRIPTOR_OPERATION_UPDATE)
|
||||
{
|
||||
CHECK_AND_ASSERT_MES(ado.opt_asset_id, false, "ado.opt_asset_id is not found at ado.operation_type == ASSET_DESCRIPTOR_OPERATION_EMIT/UPDATE");
|
||||
//CHECK_AND_ASSERT_MES(ado.opt_proof, false, "ado.opt_asset_id is not found at ado.operation_type == ASSET_DESCRIPTOR_OPERATION_EMMIT/UPDATE");
|
||||
CHECK_AND_ASSERT_MES(!ado.opt_amount_commitment, false, "ado.opt_asset_id is not found at ado.operation_type == ASSET_DESCRIPTOR_OPERATION_EMIT/UPDATE");
|
||||
CHECK_AND_ASSERT_MES(ado.opt_asset_id, false, "ado.opt_asset_id is not found at ado.operation_type == ASSET_DESCRIPTOR_OPERATION_UPDATE");
|
||||
//CHECK_AND_ASSERT_MES(ado.opt_proof, false, "ado.opt_asset_id is not found at ado.operation_type == ASSET_DESCRIPTOR_OPERATION_UPDATE");
|
||||
CHECK_AND_ASSERT_MES(!ado.opt_amount_commitment, false, "ado.opt_asset_id is not found at ado.operation_type == ASSET_DESCRIPTOR_OPERATION_UPDATE");
|
||||
|
||||
//fields that not supposed to be changed?
|
||||
}
|
||||
else if (ado.operation_type == ASSET_DESCRIPTOR_OPERATION_PUBLIC_BURN)
|
||||
{
|
||||
|
||||
//calculate_asset_id(ado.descriptor.owner, &gen_context.ao_asset_id_pt, &gen_context.ao_asset_id);
|
||||
CHECK_AND_ASSERT_MES(ado.opt_asset_id, false, "ado.opt_asset_id is not found at ado.operation_type == ASSET_DESCRIPTOR_OPERATION_EMIT/UPDATE");
|
||||
CHECK_AND_ASSERT_MES(ado.opt_asset_id, false, "ado.opt_asset_id is not found at ado.operation_type == ASSET_DESCRIPTOR_OPERATION_PUBLIC_BURN");
|
||||
|
||||
gen_context.ao_asset_id = *ado.opt_asset_id;
|
||||
gen_context.ao_asset_id_pt.from_public_key(gen_context.ao_asset_id);
|
||||
// calculate amount blinding mask
|
||||
gen_context.ao_amount_blinding_mask = crypto::hash_helper_t::hs(CRYPTO_HDS_ASSET_CONTROL_ABM, ftp.asset_control_key);
|
||||
gen_context.ao_amount_blinding_mask = crypto::hash_helper_t::hs(CRYPTO_HDS_ASSET_CONTROL_ABM, ftp.asset_control_key, tx_key.pub);
|
||||
gen_context.ao_commitment_in_outputs = true;
|
||||
|
||||
// set correct asset_id to the corresponding destination entries
|
||||
|
|
@ -2239,7 +2237,7 @@ namespace currency
|
|||
amount_of_burned_assets -= item.amount;
|
||||
}
|
||||
}
|
||||
ado.descriptor.current_supply -= amount_of_burned_assets; // TODO: consider setting current_supply beforehand, not setting it hear in ad-hoc manner -- sowle
|
||||
ado.descriptor.current_supply -= amount_of_burned_assets;
|
||||
|
||||
gen_context.ao_amount_commitment = amount_of_burned_assets * gen_context.ao_asset_id_pt + gen_context.ao_amount_blinding_mask * crypto::c_point_G;
|
||||
ado.opt_amount_commitment = (crypto::c_scalar_1div8 * gen_context.ao_amount_commitment).to_public_key();
|
||||
|
|
@ -2509,7 +2507,7 @@ namespace currency
|
|||
pado = get_type_in_variant_container<asset_descriptor_operation>(tx.extra);
|
||||
if (pado)
|
||||
{
|
||||
bool r = construct_tx_handle_ado(sender_account_keys, ftp, *pado, gen_context, one_time_tx_secret_key, shuffled_dsts);
|
||||
bool r = construct_tx_handle_ado(sender_account_keys, ftp, *pado, gen_context, txkey, shuffled_dsts);
|
||||
CHECK_AND_ASSERT_MES(r, false, "Failed to construct_tx_handle_ado()");
|
||||
if (ftp.pevents_dispatcher) ftp.pevents_dispatcher->RAISE_DEBUG_EVENT(wde_construct_tx_handle_asset_descriptor_operation{ pado });
|
||||
}
|
||||
|
|
|
|||
|
|
@ -280,7 +280,9 @@ namespace currency
|
|||
bool pos = false,
|
||||
const pos_entry& pe = pos_entry(),
|
||||
tx_generation_context* ogc_ptr = nullptr,
|
||||
const keypair* tx_one_time_key_to_use = nullptr);
|
||||
const keypair* tx_one_time_key_to_use = nullptr,
|
||||
const std::vector<tx_destination_entry>& destinations = std::vector<tx_destination_entry>()
|
||||
);
|
||||
//---------------------------------------------------------------
|
||||
uint64_t get_string_uint64_hash(const std::string& str);
|
||||
bool construct_tx_out(const tx_destination_entry& de, const crypto::secret_key& tx_sec_key, size_t output_index, transaction& tx, std::set<uint16_t>& deriv_cache, const account_keys& self, crypto::scalar_t& asset_blinding_mask, crypto::scalar_t& amount_blinding_mask, crypto::point_t& blinded_asset_id, crypto::point_t& amount_commitment, finalized_tx& result, uint8_t tx_outs_attr = CURRENCY_TO_KEY_OUT_RELAXED);
|
||||
|
|
|
|||
|
|
@ -404,7 +404,7 @@ namespace currency
|
|||
#ifdef TESTNET
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit 5a8320e580f5510e64e967a8a4f7fb2cbc76194a
|
||||
Subproject commit 18cb69f348bae38186f3a8da8bc9fc9991d38cd1
|
||||
|
|
@ -117,6 +117,13 @@ namespace currency
|
|||
res.default_fee = m_core.get_blockchain_storage().get_core_runtime_config().tx_default_fee;
|
||||
res.minimum_fee = m_core.get_blockchain_storage().get_core_runtime_config().tx_pool_min_fee;
|
||||
|
||||
auto & hf = m_core.get_blockchain_storage().get_core_runtime_config().hard_forks.m_height_the_hardfork_n_active_after;
|
||||
res.is_hardfok_active.resize(hf.size());
|
||||
for (size_t i = 0; i != hf.size(); i++)
|
||||
{
|
||||
res.is_hardfok_active[i] = m_core.get_blockchain_storage().is_hardfork_active(i);
|
||||
}
|
||||
|
||||
//conditional values
|
||||
if (req.flags&COMMAND_RPC_GET_INFO_FLAG_NET_TIME_DELTA_MEDIAN)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -793,6 +793,7 @@ namespace currency
|
|||
uint64_t minimum_fee;
|
||||
uint64_t last_block_timestamp;
|
||||
std::string last_block_hash;
|
||||
std::vector<bool> is_hardfok_active;
|
||||
//market
|
||||
uint64_t offers_count;
|
||||
|
||||
|
|
@ -843,6 +844,7 @@ namespace currency
|
|||
KV_SERIALIZE(minimum_fee)
|
||||
KV_SERIALIZE(last_block_timestamp)
|
||||
KV_SERIALIZE(last_block_hash)
|
||||
KV_SERIALIZE(is_hardfok_active)
|
||||
KV_SERIALIZE(offers_count)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
|
|
|
|||
|
|
@ -8,6 +8,6 @@
|
|||
#define PROJECT_REVISION "0"
|
||||
#define PROJECT_VERSION PROJECT_MAJOR_VERSION "." PROJECT_MINOR_VERSION "." PROJECT_REVISION
|
||||
|
||||
#define PROJECT_VERSION_BUILD_NO 250
|
||||
#define PROJECT_VERSION_BUILD_NO 252
|
||||
#define PROJECT_VERSION_BUILD_NO_STR STRINGIFY_EXPAND(PROJECT_VERSION_BUILD_NO)
|
||||
#define PROJECT_VERSION_LONG PROJECT_VERSION "." PROJECT_VERSION_BUILD_NO_STR "[" BUILD_COMMIT_ID "]"
|
||||
|
|
|
|||
|
|
@ -5881,14 +5881,17 @@ void wallet2::prefetch_global_indicies_if_needed(const std::vector<uint64_t>& se
|
|||
}
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
bool wallet2::prepare_tx_sources(size_t fake_outputs_count, std::vector<currency::tx_source_entry>& sources, const std::vector<uint64_t>& selected_indicies)
|
||||
bool wallet2::prepare_tx_sources(size_t fake_outputs_count_, std::vector<currency::tx_source_entry>& sources, const std::vector<uint64_t>& selected_indicies)
|
||||
{
|
||||
typedef COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::out_entry out_entry;
|
||||
typedef currency::tx_source_entry::output_entry tx_output_entry;
|
||||
|
||||
COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::response daemon_resp = AUTO_VAL_INIT(daemon_resp);
|
||||
if (fake_outputs_count)
|
||||
//we should request even of fake_outputs_count == 0, since for for postzarcanum this era this param is redefined
|
||||
//todo: remove if(true) block later if this code will be settled
|
||||
if (true)
|
||||
{
|
||||
size_t fake_outputs_count = fake_outputs_count_;
|
||||
uint64_t zarcanum_start_from = m_core_runtime_config.hard_forks.m_height_the_hardfork_n_active_after[ZANO_HARDFORK_04_ZARCANUM];
|
||||
uint64_t current_size = m_chain.get_blockchain_current_size();
|
||||
decoy_selection_generator zarcanum_decoy_set_generator;
|
||||
|
|
@ -5899,8 +5902,7 @@ bool wallet2::prepare_tx_sources(size_t fake_outputs_count, std::vector<currency
|
|||
zarcanum_decoy_set_generator.init(test_scale_size - 1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool need_to_request = fake_outputs_count != 0;
|
||||
COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS2::request req = AUTO_VAL_INIT(req);
|
||||
req.height_upper_limit = m_last_pow_block_h; // request decoys to be either older than, or the same age as stake output's height
|
||||
req.use_forced_mix_outs = false; // TODO: add this feature to UI later
|
||||
|
|
@ -5919,11 +5921,14 @@ bool wallet2::prepare_tx_sources(size_t fake_outputs_count, std::vector<currency
|
|||
//check if we have Zarcanum era output of pre-Zarcanum
|
||||
if (it->is_zc())
|
||||
{
|
||||
if(this->is_auditable())
|
||||
continue;
|
||||
//Zarcanum era
|
||||
rdisttib.amount = 0;
|
||||
//generate distribution in Zarcanum hardfork
|
||||
THROW_IF_FALSE_WALLET_INT_ERR_EX(zarcanum_decoy_set_generator.is_initialized(), "zarcanum_decoy_set_generator are not initialized");
|
||||
rdisttib.offsets = zarcanum_decoy_set_generator.generate_distribution(fake_outputs_count);
|
||||
rdisttib.offsets = zarcanum_decoy_set_generator.generate_distribution(m_core_runtime_config.hf4_minimum_mixins);
|
||||
need_to_request = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -5932,42 +5937,46 @@ bool wallet2::prepare_tx_sources(size_t fake_outputs_count, std::vector<currency
|
|||
rdisttib.offsets.resize(fake_outputs_count, 0);
|
||||
}
|
||||
}
|
||||
|
||||
size_t attempt_count = 0;
|
||||
while (true)
|
||||
if (need_to_request)
|
||||
{
|
||||
daemon_resp = COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::response();
|
||||
bool r = m_core_proxy->call_COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS2(req, daemon_resp);
|
||||
THROW_IF_FALSE_WALLET_EX(r, error::no_connection_to_daemon, "getrandom_outs2.bin");
|
||||
if(daemon_resp.status == API_RETURN_CODE_FAIL)
|
||||
size_t attempt_count = 0;
|
||||
while (true)
|
||||
{
|
||||
if (attempt_count < 10)
|
||||
daemon_resp = COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::response();
|
||||
bool r = m_core_proxy->call_COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS2(req, daemon_resp);
|
||||
THROW_IF_FALSE_WALLET_EX(r, error::no_connection_to_daemon, "getrandom_outs2.bin");
|
||||
if (daemon_resp.status == API_RETURN_CODE_FAIL)
|
||||
{
|
||||
attempt_count++;
|
||||
continue;
|
||||
if (attempt_count < 10)
|
||||
{
|
||||
attempt_count++;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(daemon_resp.outs.size() == selected_indicies.size(),
|
||||
"unable to exacute getrandom_outs.bin after 10 attempts with code API_RETURN_CODE_FAIL, there must be problems with mixins");
|
||||
}
|
||||
}
|
||||
else
|
||||
THROW_IF_FALSE_WALLET_EX(daemon_resp.status != API_RETURN_CODE_BUSY, error::daemon_busy, "getrandom_outs.bin");
|
||||
THROW_IF_FALSE_WALLET_EX(daemon_resp.status == API_RETURN_CODE_OK, error::get_random_outs_error, daemon_resp.status);
|
||||
WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(daemon_resp.outs.size() == selected_indicies.size(),
|
||||
"daemon returned wrong response for getrandom_outs.bin, wrong amounts count = " << daemon_resp.outs.size() << ", expected: " << selected_indicies.size());
|
||||
break;
|
||||
}
|
||||
|
||||
std::vector<COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::outs_for_amount> scanty_outs;
|
||||
THROW_IF_FALSE_WALLET_EX(daemon_resp.outs.size() == req.amounts.size(), error::not_enough_outs_to_mix, scanty_outs, fake_outputs_count);
|
||||
//for (COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::outs_for_amount& amount_outs : daemon_resp.outs)
|
||||
for(size_t i = 0; i != daemon_resp.outs.size(); i++)
|
||||
{
|
||||
if (daemon_resp.outs[i].outs.size() != req.amounts[i].offsets.size())
|
||||
{
|
||||
WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(daemon_resp.outs.size() == selected_indicies.size(),
|
||||
"unable to exacute getrandom_outs.bin after 10 attempts with code API_RETURN_CODE_FAIL, there must be problems with mixins");
|
||||
scanty_outs.push_back(daemon_resp.outs[i]);
|
||||
}
|
||||
}
|
||||
THROW_IF_FALSE_WALLET_EX(daemon_resp.status != API_RETURN_CODE_BUSY, error::daemon_busy, "getrandom_outs.bin");
|
||||
THROW_IF_FALSE_WALLET_EX(daemon_resp.status == API_RETURN_CODE_OK, error::get_random_outs_error, daemon_resp.status);
|
||||
WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(daemon_resp.outs.size() == selected_indicies.size(),
|
||||
"daemon returned wrong response for getrandom_outs.bin, wrong amounts count = " << daemon_resp.outs.size() << ", expected: " << selected_indicies.size());
|
||||
break;
|
||||
THROW_IF_FALSE_WALLET_EX(scanty_outs.empty(), error::not_enough_outs_to_mix, scanty_outs, fake_outputs_count);
|
||||
}
|
||||
|
||||
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() < fake_outputs_count)
|
||||
{
|
||||
scanty_outs.push_back(amount_outs);
|
||||
}
|
||||
}
|
||||
THROW_IF_FALSE_WALLET_EX(scanty_outs.empty(), error::not_enough_outs_to_mix, scanty_outs, fake_outputs_count);
|
||||
}
|
||||
|
||||
//lets prefetch m_global_output_index for selected_indicies
|
||||
|
|
@ -5985,6 +5994,12 @@ bool wallet2::prepare_tx_sources(size_t fake_outputs_count, std::vector<currency
|
|||
src.transfer_index = it - m_transfers.begin();
|
||||
src.amount = td.amount();
|
||||
src.asset_id = td.get_asset_id();
|
||||
size_t fake_outputs_count = fake_outputs_count_;
|
||||
//redefine for hardfork
|
||||
if (td.is_zc() && !this->is_auditable())
|
||||
fake_outputs_count = m_core_runtime_config.hf4_minimum_mixins;
|
||||
|
||||
|
||||
//paste mixin transaction
|
||||
if (daemon_resp.outs.size())
|
||||
{
|
||||
|
|
@ -6506,9 +6521,9 @@ bool wallet2::select_indices_for_transfer(assets_selection_context& needed_money
|
|||
return res;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
uint64_t wallet2::select_indices_for_transfer(std::vector<uint64_t>& selected_indexes, free_amounts_cache_type& found_free_amounts, uint64_t needed_money, uint64_t fake_outputs_count)
|
||||
uint64_t wallet2::select_indices_for_transfer(std::vector<uint64_t>& selected_indexes, free_amounts_cache_type& found_free_amounts, uint64_t needed_money, uint64_t fake_outputs_count_)
|
||||
{
|
||||
WLT_LOG_GREEN("Selecting indices for transfer of " << print_money_brief(needed_money) << " with " << fake_outputs_count << " fake outs, found_free_amounts.size()=" << found_free_amounts.size() << "...", LOG_LEVEL_0);
|
||||
WLT_LOG_GREEN("Selecting indices for transfer of " << print_money_brief(needed_money) << " with " << fake_outputs_count_ << " fake outs, found_free_amounts.size()=" << found_free_amounts.size() << "...", LOG_LEVEL_0);
|
||||
uint64_t found_money = 0;
|
||||
//uint64_t found_zc_input = false;
|
||||
std::string selected_amounts_str;
|
||||
|
|
@ -6520,6 +6535,11 @@ uint64_t wallet2::select_indices_for_transfer(std::vector<uint64_t>& selected_in
|
|||
it = --found_free_amounts.end();
|
||||
WLT_CHECK_AND_ASSERT_MES(it->second.size(), 0, "internal error: empty found_free_amounts map");
|
||||
}
|
||||
uint64_t fake_outputs_count = fake_outputs_count_;
|
||||
if (!this->is_auditable() && m_transfers[*it->second.begin()].is_zc())
|
||||
{
|
||||
fake_outputs_count = m_core_runtime_config.hf4_minimum_mixins;
|
||||
}
|
||||
if (is_transfer_ready_to_go(m_transfers[*it->second.begin()], fake_outputs_count))
|
||||
{
|
||||
found_money += it->first;
|
||||
|
|
@ -6582,7 +6602,13 @@ bool wallet2::prepare_free_transfers_cache(uint64_t fake_outputs_count)
|
|||
for (size_t i = 0; i < m_transfers.size(); ++i)
|
||||
{
|
||||
const transfer_details& td = m_transfers[i];
|
||||
if (is_transfer_able_to_go(td, fake_outputs_count))
|
||||
uint64_t fake_outputs_count_local = fake_outputs_count;
|
||||
if (td.m_zc_info_ptr)
|
||||
{
|
||||
//zarcanum out, redefine fake_outputs_count
|
||||
fake_outputs_count_local = this->is_auditable() ? 0 : CURRENCY_HF4_MANDATORY_DECOY_SET_SIZE;
|
||||
}
|
||||
if (is_transfer_able_to_go(td, fake_outputs_count_local))
|
||||
{
|
||||
//@#@
|
||||
m_found_free_amounts[td.get_asset_id()][td.amount()].insert(i);
|
||||
|
|
@ -6978,7 +7004,7 @@ bool wallet2::prepare_transaction(construct_tx_param& ctp, currency::finalize_tx
|
|||
return true;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
void wallet2::finalize_transaction(const currency::finalize_tx_param& ftp, currency::transaction& tx, crypto::secret_key& tx_key, bool broadcast_tx, bool store_tx_secret_key /* = true */)
|
||||
void wallet2::finalize_transaction(currency::finalize_tx_param& ftp, currency::transaction& tx, crypto::secret_key& tx_key, bool broadcast_tx, bool store_tx_secret_key /* = true */)
|
||||
{
|
||||
currency::finalized_tx result = AUTO_VAL_INIT(result);
|
||||
result.tx = tx;
|
||||
|
|
@ -6988,7 +7014,7 @@ void wallet2::finalize_transaction(const currency::finalize_tx_param& ftp, curre
|
|||
tx_key = result.one_time_key;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
void wallet2::finalize_transaction(const currency::finalize_tx_param& ftp, currency::finalized_tx& result, bool broadcast_tx, bool store_tx_secret_key /* = true */)
|
||||
void wallet2::finalize_transaction(currency::finalize_tx_param& ftp, currency::finalized_tx& result, bool broadcast_tx, bool store_tx_secret_key /* = true */)
|
||||
{
|
||||
// NOTE: if broadcast_tx == true callback rise_on_transfer2() may be called at the end of this function.
|
||||
// That callback may call balance(), so it's important to have all used/spending transfers
|
||||
|
|
@ -6997,7 +7023,10 @@ void wallet2::finalize_transaction(const currency::finalize_tx_param& ftp, curre
|
|||
// broadcasting tx without secret key storing is forbidden to avoid lost key issues
|
||||
WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(!broadcast_tx || store_tx_secret_key, "finalize_tx is requested to broadcast a tx without storing the key");
|
||||
|
||||
//TIME_MEASURE_START_MS(construct_tx_time);
|
||||
//overide mixins count for hardfork 4 outputs
|
||||
if (is_in_hardfork_zone(ZANO_HARDFORK_04_ZARCANUM))
|
||||
ftp.tx_outs_attr = m_core_runtime_config.hf4_minimum_mixins;
|
||||
|
||||
bool r = currency::construct_tx(m_account.get_keys(),
|
||||
ftp, result);
|
||||
//TIME_MEASURE_FINISH_MS(construct_tx_time);
|
||||
|
|
|
|||
|
|
@ -635,8 +635,8 @@ namespace tools
|
|||
|
||||
bool prepare_transaction(construct_tx_param& ctp, currency::finalize_tx_param& ftp, const mode_separate_context& emode_separate = mode_separate_context());
|
||||
|
||||
void finalize_transaction(const currency::finalize_tx_param& ftp, currency::transaction& tx, crypto::secret_key& tx_key, bool broadcast_tx, bool store_tx_secret_key = true);
|
||||
void finalize_transaction(const currency::finalize_tx_param& ftp, currency::finalized_tx& result, bool broadcast_tx, bool store_tx_secret_key = true );
|
||||
void finalize_transaction(currency::finalize_tx_param& ftp, currency::transaction& tx, crypto::secret_key& tx_key, bool broadcast_tx, bool store_tx_secret_key = true);
|
||||
void finalize_transaction(currency::finalize_tx_param& ftp, currency::finalized_tx& result, bool broadcast_tx, bool store_tx_secret_key = true );
|
||||
|
||||
std::string get_log_prefix() const { return m_log_prefix; }
|
||||
static uint64_t get_max_unlock_time_from_receive_indices(const currency::transaction& tx, const wallet_public::employed_tx_entries& td);
|
||||
|
|
|
|||
|
|
@ -548,8 +548,10 @@ bool wallets_manager::init_local_daemon()
|
|||
|
||||
//chain calls to rpc server
|
||||
m_prpc_chain_handler = &m_wallet_rpc_server;
|
||||
//disable this until we get full support of authentication with network
|
||||
//m_rpc_server.set_rpc_chain_handler(this);
|
||||
//disable this for main net until we get full support of authentication with network
|
||||
#ifdef TESTNET
|
||||
m_rpc_server.set_rpc_chain_handler(this);
|
||||
#endif
|
||||
|
||||
|
||||
LOG_PRINT_L0("Starting core rpc server...");
|
||||
|
|
|
|||
|
|
@ -585,6 +585,9 @@ public:
|
|||
void set_hardforks(const currency::hard_forks_descriptor& hardforks);
|
||||
const currency::hard_forks_descriptor& get_hardforks() const { return m_hardforks; }
|
||||
|
||||
void load_hardforks_from(const test_chain_unit_base* pthis) { m_hardforks = pthis->get_hardforks(); }
|
||||
template<typename t_type>
|
||||
void load_hardforks_from(const t_type* pthis) {}
|
||||
|
||||
private:
|
||||
bool m_ignore_last_pow_in_wallets;
|
||||
|
|
|
|||
|
|
@ -1079,7 +1079,7 @@ int main(int argc, char* argv[])
|
|||
GENERATE_AND_PLAY(wallet_outputs_with_same_key_image);
|
||||
GENERATE_AND_PLAY(wallet_unconfirmed_tx_expiration);
|
||||
GENERATE_AND_PLAY(wallet_unconfimed_tx_balance);
|
||||
GENERATE_AND_PLAY_HF(packing_outputs_on_pos_minting_wallet, "3-*");
|
||||
GENERATE_AND_PLAY_HF(packing_outputs_on_pos_minting_wallet, "3");
|
||||
GENERATE_AND_PLAY(wallet_watch_only_and_chain_switch);
|
||||
|
||||
GENERATE_AND_PLAY(wallet_rpc_integrated_address);
|
||||
|
|
|
|||
|
|
@ -681,6 +681,7 @@ gen_no_attchments_in_coinbase::gen_no_attchments_in_coinbase()
|
|||
|
||||
bool gen_no_attchments_in_coinbase::generate(std::vector<test_event_entry>& events) const
|
||||
{
|
||||
this->on_test_generator_created(generator);
|
||||
uint64_t ts = 1450000000;
|
||||
test_core_time::adjust(ts);
|
||||
|
||||
|
|
@ -704,7 +705,16 @@ bool gen_no_attchments_in_coinbase::init_config_set_cp(currency::core& c, size_t
|
|||
crc.pos_minimum_heigh = 1;
|
||||
c.get_blockchain_storage().set_core_runtime_config(crc);
|
||||
|
||||
m_checkpoints.add_checkpoint(12, "475331fb4a325e722ddbc2d087d32687a58392e5a9314001120de0f2ce7737f2");
|
||||
// different checkpoints due to different block versions for different hardforks -> different hashes
|
||||
if (crc.is_hardfork_active_for_height(ZANO_HARDFORK_03, 11) && !crc.is_hardfork_active_for_height(ZANO_HARDFORK_04_ZARCANUM, 11))
|
||||
{
|
||||
m_checkpoints.add_checkpoint(12, "4e6055dda442e04b2feb70bc7245584742604e8515b8d2e1c3d46c26f758d59f");
|
||||
}
|
||||
else
|
||||
{
|
||||
m_checkpoints.add_checkpoint(12, "475331fb4a325e722ddbc2d087d32687a58392e5a9314001120de0f2ce7737f2");
|
||||
}
|
||||
|
||||
c.set_checkpoints(currency::checkpoints(m_checkpoints));
|
||||
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -178,7 +178,7 @@ bool ionic_swap_basic_test::c1(currency::core& c, size_t ev_index, const std::ve
|
|||
// Alice wants to trade with Bob, to exchange 10.0 TCT to 0.5 ZANO
|
||||
view::ionic_swap_proposal_info proposal_details = AUTO_VAL_INIT(proposal_details);
|
||||
proposal_details.fee_paid_by_a = TESTS_DEFAULT_FEE;
|
||||
proposal_details.mixins = 10;
|
||||
proposal_details.mixins = c.get_blockchain_storage().get_core_runtime_config().hf4_minimum_mixins;
|
||||
proposal_details.to_finalizer.push_back(view::asset_funds{ asset_id , assets_to_exchange });
|
||||
proposal_details.to_initiator.push_back(view::asset_funds{ currency::native_coin_asset_id , native_coins_to_exchange });
|
||||
|
||||
|
|
@ -233,7 +233,7 @@ bool ionic_swap_basic_test::c1(currency::core& c, size_t ev_index, const std::ve
|
|||
//now Alice want to trade with Bob, to send 0.5 ZANO and get 10.0 TCT in exchange
|
||||
view::ionic_swap_proposal_info proposal_details = AUTO_VAL_INIT(proposal_details);
|
||||
proposal_details.fee_paid_by_a = TESTS_DEFAULT_FEE;
|
||||
proposal_details.mixins = 10;
|
||||
proposal_details.mixins = c.get_blockchain_storage().get_core_runtime_config().hf4_minimum_mixins;
|
||||
proposal_details.to_finalizer.push_back(view::asset_funds{ currency::native_coin_asset_id , native_coins_to_exchange });
|
||||
proposal_details.to_initiator.push_back(view::asset_funds{ asset_id , assets_to_exchange });
|
||||
|
||||
|
|
@ -387,7 +387,7 @@ bool ionic_swap_exact_amounts_test::c1(currency::core& c, size_t ev_index, const
|
|||
proposal_details.to_initiator.push_back(view::asset_funds{ asset_id, adb.total_max_supply });
|
||||
proposal_details.to_finalizer.push_back(view::asset_funds{ native_coin_asset_id, MK_TEST_COINS(20) });
|
||||
proposal_details.fee_paid_by_a = MK_TEST_COINS(1);
|
||||
proposal_details.mixins = 2;
|
||||
proposal_details.mixins = c.get_blockchain_storage().get_core_runtime_config().hf4_minimum_mixins;
|
||||
|
||||
tools::wallet_public::ionic_swap_proposal proposal{};
|
||||
alice_wlt->create_ionic_swap_proposal(proposal_details, m_accounts[BOB_ACC_IDX].get_public_address(), proposal);
|
||||
|
|
@ -429,7 +429,7 @@ bool ionic_swap_exact_amounts_test::c1(currency::core& c, size_t ev_index, const
|
|||
proposal_details.to_initiator.push_back(view::asset_funds{ asset_id, adb.total_max_supply });
|
||||
proposal_details.to_finalizer.push_back(view::asset_funds{ native_coin_asset_id, MK_TEST_COINS(20) });
|
||||
proposal_details.fee_paid_by_a = MK_TEST_COINS(1);
|
||||
proposal_details.mixins = 2;
|
||||
proposal_details.mixins = c.get_blockchain_storage().get_core_runtime_config().hf4_minimum_mixins;
|
||||
|
||||
proposal = tools::wallet_public::ionic_swap_proposal{};
|
||||
carol_wlt->create_ionic_swap_proposal(proposal_details, m_accounts[ALICE_ACC_IDX].get_public_address(), proposal);
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ bool isolate_auditable_and_proof::generate(std::vector<test_event_entry>& events
|
|||
generator.construct_genesis_block(blk_0, genesis_acc, test_core_time::get_time());
|
||||
events.push_back(blk_0);
|
||||
DO_CALLBACK(events, "configure_core");
|
||||
REWIND_BLOCKS_N(events, blk_0r, blk_0, m_mining_accunt, CURRENCY_MINED_MONEY_UNLOCK_WINDOW + 5);
|
||||
REWIND_BLOCKS_N(events, blk_0r, blk_0, m_mining_accunt, CURRENCY_MINED_MONEY_UNLOCK_WINDOW + 15);
|
||||
|
||||
DO_CALLBACK(events, "c1");
|
||||
epee::debug::get_set_enable_assert(true, false);
|
||||
|
|
|
|||
|
|
@ -1778,9 +1778,6 @@ bool gen_wallet_alias_and_unconfirmed_txs::c3(currency::core& c, size_t ev_index
|
|||
|
||||
gen_wallet_alias_via_special_wallet_funcs::gen_wallet_alias_via_special_wallet_funcs()
|
||||
{
|
||||
// start hardfork from block 0 in order to use extra_alias_entry (allowed only since HF2)
|
||||
m_hardforks.set_hardfork_height(1, 0);
|
||||
m_hardforks.set_hardfork_height(2, 0);
|
||||
REGISTER_CALLBACK_METHOD(gen_wallet_alias_via_special_wallet_funcs, c1);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,35 @@
|
|||
|
||||
#include "misc_language.h"
|
||||
|
||||
namespace epee::misc_utils
|
||||
{
|
||||
// old impelementation that uses std::sort
|
||||
template<class type_vec_type>
|
||||
type_vec_type old_median(std::vector<type_vec_type> &v)
|
||||
{
|
||||
//CRITICAL_REGION_LOCAL(m_lock);
|
||||
if(v.empty())
|
||||
return boost::value_initialized<type_vec_type>();
|
||||
if(v.size() == 1)
|
||||
return v[0];
|
||||
|
||||
size_t n = (v.size()) / 2;
|
||||
std::sort(v.begin(), v.end());
|
||||
//nth_element(v.begin(), v.begin()+n-1, v.end());
|
||||
if(v.size()%2)
|
||||
{//1, 3, 5...
|
||||
return v[n];
|
||||
}else
|
||||
{//2, 4, 6...
|
||||
return (v[n-1] + v[n])/2;
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace epee::misc_utils
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
bool test_median(const std::vector<uint64_t>& v_)
|
||||
{
|
||||
std::vector<uint64_t> v(v_);
|
||||
|
|
@ -21,8 +50,9 @@ bool test_median(const std::vector<uint64_t>& v_)
|
|||
}
|
||||
uint64_t m1 = epee::misc_utils::median(v);
|
||||
uint64_t m2 = mh.get_median();
|
||||
if (m1 != m2)
|
||||
return false;
|
||||
uint64_t m3 = epee::misc_utils::old_median(v);
|
||||
CHECK_AND_ASSERT_MES(m1 == m2, false, "m1 != m2");
|
||||
CHECK_AND_ASSERT_MES(m2 == m3, false, "m2 != m3");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -100,4 +130,4 @@ TEST(median_helper_test, median_helper_test)
|
|||
|
||||
mh.scan_items(cb, cb_finalizer);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
20
utils/test_api_files/transfer.json
Normal file
20
utils/test_api_files/transfer.json
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"jsonrpc": "2.0",
|
||||
"id": 0,
|
||||
"method": "transfer",
|
||||
"params": {
|
||||
"destinations": [
|
||||
{
|
||||
"amount": 1000000000,
|
||||
"address": "ZxCkEgHf3ci8hgBfboZeCENaYrHBYZ1bLFi5cgWvn4WJLaxfgs4kqG6cJi9ai2zrXWSCpsvRXit14gKjeijx6YPC1zT8rneEf"
|
||||
}
|
||||
],
|
||||
"push_payer": true,
|
||||
"hide_receiver": false,
|
||||
"service_entries_permanent": false,
|
||||
"fee": 1000000000000,
|
||||
"mixin": 10,
|
||||
"comment": "",
|
||||
"service_entries": []
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue