Compare commits
14 commits
dev
...
assets_tra
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
057856b953 | ||
|
|
ecbc437c0c | ||
|
|
52bab97374 | ||
|
|
cb0e2c3650 | ||
|
|
f3367b895a | ||
|
|
735a5adfde | ||
|
|
9fac4c8f49 | ||
|
|
10c0ee541a | ||
|
|
47a11bba99 | ||
|
|
0f43835f17 | ||
|
|
31857b8440 | ||
|
|
9613215a87 | ||
|
|
a39c42a1b5 | ||
|
|
922ec739dc |
11 changed files with 370 additions and 246 deletions
|
|
@ -509,6 +509,10 @@ namespace misc_utils
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UNSUBSCRIBE_ALL()
|
||||||
|
{
|
||||||
|
m_callbacks.clear();
|
||||||
|
}
|
||||||
|
|
||||||
template<typename param_t>
|
template<typename param_t>
|
||||||
void RAISE_DEBUG_EVENT(const param_t& p)
|
void RAISE_DEBUG_EVENT(const param_t& p)
|
||||||
|
|
|
||||||
|
|
@ -84,46 +84,47 @@ namespace crypto
|
||||||
scalar_t y;
|
scalar_t y;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<generator_tag gen>
|
|
||||||
|
template<typename generator_t>
|
||||||
|
inline bool generate_schnorr_sig_custom_generator(const hash& m, const point_t& A, const scalar_t& secret_a, generic_schnorr_sig& result, const generator_t& g_point_g)
|
||||||
|
{
|
||||||
|
#ifndef NDEBUG
|
||||||
|
if (A != secret_a * g_point_g)
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
scalar_t r = scalar_t::random();
|
||||||
|
point_t R = r * g_point_g;
|
||||||
|
hash_helper_t::hs_t hsc(3);
|
||||||
|
hsc.add_hash(m);
|
||||||
|
hsc.add_point(A);
|
||||||
|
hsc.add_point(R);
|
||||||
|
result.c = hsc.calc_hash();
|
||||||
|
result.y.assign_mulsub(result.c, secret_a, r); // y = r - c * secret_a
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<generator_tag gen = gt_G>
|
||||||
inline bool generate_schnorr_sig(const hash& m, const point_t& A, const scalar_t& secret_a, generic_schnorr_sig& result);
|
inline bool generate_schnorr_sig(const hash& m, const point_t& A, const scalar_t& secret_a, generic_schnorr_sig& result);
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
inline bool generate_schnorr_sig<gt_G>(const hash& m, const point_t& A, const scalar_t& secret_a, generic_schnorr_sig& result)
|
inline bool generate_schnorr_sig<gt_G>(const hash& m, const point_t& A, const scalar_t& secret_a, generic_schnorr_sig& result)
|
||||||
{
|
{
|
||||||
#ifndef NDEBUG
|
return generate_schnorr_sig_custom_generator(m, A, secret_a, result, c_point_G);
|
||||||
if (A != secret_a * c_point_G)
|
|
||||||
return false;
|
|
||||||
#endif
|
|
||||||
scalar_t r = scalar_t::random();
|
|
||||||
point_t R = r * c_point_G;
|
|
||||||
hash_helper_t::hs_t hsc(3);
|
|
||||||
hsc.add_hash(m);
|
|
||||||
hsc.add_point(A);
|
|
||||||
hsc.add_point(R);
|
|
||||||
result.c = hsc.calc_hash();
|
|
||||||
result.y.assign_mulsub(result.c, secret_a, r); // y = r - c * secret_a
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
inline bool generate_schnorr_sig<gt_X>(const hash& m, const point_t& A, const scalar_t& secret_a, generic_schnorr_sig& result)
|
inline bool generate_schnorr_sig<gt_X>(const hash& m, const point_t& A, const scalar_t& secret_a, generic_schnorr_sig& result)
|
||||||
{
|
{
|
||||||
#ifndef NDEBUG
|
return generate_schnorr_sig_custom_generator(m, A, secret_a, result, c_point_X);
|
||||||
if (A != secret_a * c_point_X)
|
|
||||||
return false;
|
|
||||||
#endif
|
|
||||||
scalar_t r = scalar_t::random();
|
|
||||||
point_t R = r * c_point_X;
|
|
||||||
hash_helper_t::hs_t hsc(3);
|
|
||||||
hsc.add_hash(m);
|
|
||||||
hsc.add_point(A);
|
|
||||||
hsc.add_point(R);
|
|
||||||
result.c = hsc.calc_hash();
|
|
||||||
result.y.assign_mulsub(result.c, secret_a, r); // y = r - c * secret_a
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<generator_tag gen>
|
inline bool generate_schnorr_sig(const hash& m, const public_key& A, const secret_key& secret_a, generic_schnorr_sig& result)
|
||||||
|
{
|
||||||
|
return generate_schnorr_sig(m, point_t(A), scalar_t(secret_a), result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<generator_tag gen = gt_G>
|
||||||
inline bool verify_schnorr_sig(const hash& m, const public_key& A, const generic_schnorr_sig& sig) noexcept;
|
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;
|
// TODO @#@# make optimized version inline bool verify_schnorr_sig(const hash& m, const point_t& A, const generic_schnorr_sig& sig) noexcept;
|
||||||
|
|
@ -291,4 +292,4 @@ namespace crypto
|
||||||
const vector_UG_aggregation_proof& sig, uint8_t* p_err = nullptr) noexcept;
|
const vector_UG_aggregation_proof& sig, uint8_t* p_err = nullptr) noexcept;
|
||||||
|
|
||||||
|
|
||||||
} // namespace crypto
|
} // namespace crypto
|
||||||
|
|
@ -4088,13 +4088,15 @@ bool blockchain_storage::validate_ado_ownership(asset_op_verification_context& a
|
||||||
{
|
{
|
||||||
// asset_id = AUTO_VAL_INIT(asset_id);
|
// asset_id = AUTO_VAL_INIT(asset_id);
|
||||||
// CHECK_AND_ASSERT_MES(validate_asset_operation_balance_proof(tx, tx_id, ado, asset_id), false, "asset operation validation failed!");
|
// CHECK_AND_ASSERT_MES(validate_asset_operation_balance_proof(tx, tx_id, ado, asset_id), false, "asset operation validation failed!");
|
||||||
CHECK_AND_ASSERT_MES(avc.ado.opt_proof.has_value(), false, "Ownership validation failed - missing signature");
|
asset_operation_ownership_proof aoop = AUTO_VAL_INIT(aoop);
|
||||||
|
bool r = get_type_in_variant_container(avc.tx.proofs, aoop);
|
||||||
|
CHECK_AND_ASSERT_MES(r, false, "Ownership validation failed - missing signature");
|
||||||
|
|
||||||
|
|
||||||
CHECK_AND_ASSERT_MES(avc.asset_op_history->size() != 0, false, "asset with id " << avc.asset_id << " has invalid history size() == 0");
|
CHECK_AND_ASSERT_MES(avc.asset_op_history->size() != 0, false, "asset with id " << avc.asset_id << " has invalid history size() == 0");
|
||||||
|
|
||||||
crypto::public_key owner_key = avc.asset_op_history->back().descriptor.owner;
|
crypto::public_key owner_key = avc.asset_op_history->back().descriptor.owner;
|
||||||
return crypto::check_signature(get_signature_hash_for_asset_operation(avc.ado), owner_key, *avc.ado.opt_proof);
|
return crypto::verify_schnorr_sig(avc.tx_id, owner_key, aoop.gss);
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
bool blockchain_storage::put_asset_info(const transaction& tx, const crypto::hash& tx_id, const asset_descriptor_operation& ado)
|
bool blockchain_storage::put_asset_info(const transaction& tx, const crypto::hash& tx_id, const asset_descriptor_operation& ado)
|
||||||
|
|
@ -4126,7 +4128,7 @@ bool blockchain_storage::put_asset_info(const transaction& tx, const crypto::has
|
||||||
|
|
||||||
CHECK_AND_ASSERT_MES(avc.asset_op_history && avc.asset_op_history->size(), false, "asset with id " << avc.asset_id << " has not been registered");
|
CHECK_AND_ASSERT_MES(avc.asset_op_history && avc.asset_op_history->size(), false, "asset with id " << avc.asset_id << " has not been registered");
|
||||||
// check ownership permission
|
// check ownership permission
|
||||||
if (ado.operation_type == ASSET_DESCRIPTOR_OPERATION_EMIT || ado.operation_type == ASSET_DESCRIPTOR_OPERATION_UPDATE || ado.operation_type == ASSET_DESCRIPTOR_OPERATION_PUBLIC_BURN)
|
if (ado.operation_type == ASSET_DESCRIPTOR_OPERATION_EMIT || ado.operation_type == ASSET_DESCRIPTOR_OPERATION_UPDATE /*|| ado.operation_type == ASSET_DESCRIPTOR_OPERATION_PUBLIC_BURN*/)
|
||||||
{
|
{
|
||||||
bool r = validate_ado_ownership(avc);
|
bool r = validate_ado_ownership(avc);
|
||||||
CHECK_AND_ASSERT_MES(r, false, "Faild to validate ownership of asset_descriptor_operation, rejecting");
|
CHECK_AND_ASSERT_MES(r, false, "Faild to validate ownership of asset_descriptor_operation, rejecting");
|
||||||
|
|
|
||||||
|
|
@ -775,7 +775,6 @@ namespace currency
|
||||||
uint8_t operation_type = ASSET_DESCRIPTOR_OPERATION_UNDEFINED;
|
uint8_t operation_type = ASSET_DESCRIPTOR_OPERATION_UNDEFINED;
|
||||||
asset_descriptor_base descriptor;
|
asset_descriptor_base descriptor;
|
||||||
crypto::public_key amount_commitment; // premultiplied by 1/8
|
crypto::public_key amount_commitment; // premultiplied by 1/8
|
||||||
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
|
boost::optional<crypto::public_key> opt_asset_id; // target asset_id - for update/emit
|
||||||
uint8_t verion = ASSET_DESCRIPTOR_OPERATION_STRUCTURE_VER;
|
uint8_t verion = ASSET_DESCRIPTOR_OPERATION_STRUCTURE_VER;
|
||||||
|
|
||||||
|
|
@ -784,7 +783,6 @@ namespace currency
|
||||||
FIELD(descriptor)
|
FIELD(descriptor)
|
||||||
FIELD(amount_commitment)
|
FIELD(amount_commitment)
|
||||||
END_VERSION_UNDER(1)
|
END_VERSION_UNDER(1)
|
||||||
FIELD(opt_proof)
|
|
||||||
FIELD(opt_asset_id)
|
FIELD(opt_asset_id)
|
||||||
END_SERIALIZE()
|
END_SERIALIZE()
|
||||||
|
|
||||||
|
|
@ -793,7 +791,6 @@ namespace currency
|
||||||
BOOST_SERIALIZE(descriptor)
|
BOOST_SERIALIZE(descriptor)
|
||||||
BOOST_SERIALIZE(amount_commitment)
|
BOOST_SERIALIZE(amount_commitment)
|
||||||
BOOST_END_VERSION_UNDER(1)
|
BOOST_END_VERSION_UNDER(1)
|
||||||
BOOST_SERIALIZE(opt_proof)
|
|
||||||
BOOST_SERIALIZE(opt_asset_id)
|
BOOST_SERIALIZE(opt_asset_id)
|
||||||
END_BOOST_SERIALIZATION()
|
END_BOOST_SERIALIZATION()
|
||||||
};
|
};
|
||||||
|
|
@ -819,6 +816,21 @@ namespace currency
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct asset_operation_ownership_proof
|
||||||
|
{
|
||||||
|
crypto::generic_schnorr_sig_s gss;
|
||||||
|
uint8_t version = 0;
|
||||||
|
|
||||||
|
BEGIN_VERSIONED_SERIALIZE(0, version)
|
||||||
|
FIELD(gss)
|
||||||
|
END_SERIALIZE()
|
||||||
|
|
||||||
|
BEGIN_BOOST_SERIALIZATION()
|
||||||
|
BOOST_SERIALIZE(gss)
|
||||||
|
BOOST_END_VERSION_UNDER(1)
|
||||||
|
BOOST_SERIALIZE(version)
|
||||||
|
END_BOOST_SERIALIZATION()
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
struct extra_padding
|
struct extra_padding
|
||||||
|
|
@ -924,7 +936,7 @@ namespace currency
|
||||||
|
|
||||||
typedef boost::variant<NLSAG_sig, void_sig, ZC_sig, zarcanum_sig> signature_v;
|
typedef boost::variant<NLSAG_sig, void_sig, ZC_sig, zarcanum_sig> signature_v;
|
||||||
|
|
||||||
typedef boost::variant<zc_asset_surjection_proof, zc_outs_range_proof, zc_balance_proof, asset_operation_proof> proof_v;
|
typedef boost::variant<zc_asset_surjection_proof, zc_outs_range_proof, zc_balance_proof, asset_operation_proof, asset_operation_ownership_proof> proof_v;
|
||||||
|
|
||||||
|
|
||||||
//include backward compatibility defintions
|
//include backward compatibility defintions
|
||||||
|
|
@ -1111,6 +1123,7 @@ BLOB_SERIALIZER(currency::txout_to_key);
|
||||||
|
|
||||||
BOOST_CLASS_VERSION(currency::asset_descriptor_operation, 1);
|
BOOST_CLASS_VERSION(currency::asset_descriptor_operation, 1);
|
||||||
BOOST_CLASS_VERSION(currency::asset_operation_proof, 1);
|
BOOST_CLASS_VERSION(currency::asset_operation_proof, 1);
|
||||||
|
BOOST_CLASS_VERSION(currency::asset_operation_ownership_proof, 1);
|
||||||
|
|
||||||
|
|
||||||
// txin_v variant currency
|
// txin_v variant currency
|
||||||
|
|
@ -1181,6 +1194,7 @@ SET_VARIANT_TAGS(currency::zc_balance_proof, 48, "zc_balance_proof");
|
||||||
|
|
||||||
SET_VARIANT_TAGS(currency::asset_descriptor_operation, 49, "asset_descriptor_base");
|
SET_VARIANT_TAGS(currency::asset_descriptor_operation, 49, "asset_descriptor_base");
|
||||||
SET_VARIANT_TAGS(currency::asset_operation_proof, 50, "asset_operation_proof");
|
SET_VARIANT_TAGS(currency::asset_operation_proof, 50, "asset_operation_proof");
|
||||||
|
SET_VARIANT_TAGS(currency::asset_operation_ownership_proof, 51, "asset_operation_ownership_proof");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -172,7 +172,16 @@ namespace currency
|
||||||
if (is_asset_emitting_transaction(tx, &ado))
|
if (is_asset_emitting_transaction(tx, &ado))
|
||||||
{
|
{
|
||||||
crypto::point_t asset_id_pt = crypto::c_point_0;
|
crypto::point_t asset_id_pt = crypto::c_point_0;
|
||||||
calculate_asset_id(ado.descriptor.owner, &asset_id_pt, nullptr); // TODO @#@# optimization: this expensive calculation should be done only once
|
if (ado.opt_asset_id)
|
||||||
|
{
|
||||||
|
//emmit on existing asset, we SHOULD not calculate asset_id, instead we use the one provided
|
||||||
|
//since the owner might have been changed since creation
|
||||||
|
asset_id_pt = crypto::point_t(*ado.opt_asset_id);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
calculate_asset_id(ado.descriptor.owner, &asset_id_pt, nullptr); // TODO @#@# optimization: this expensive calculation should be done only once
|
||||||
|
}
|
||||||
pseudo_outs_blinded_asset_ids.emplace_back(asset_id_pt); // additional ring member for asset emitting tx
|
pseudo_outs_blinded_asset_ids.emplace_back(asset_id_pt); // additional ring member for asset emitting tx
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1137,20 +1146,21 @@ namespace currency
|
||||||
return origin_blob;
|
return origin_blob;
|
||||||
}
|
}
|
||||||
//---------------------------------------------------------------
|
//---------------------------------------------------------------
|
||||||
bool validate_ado_update_allowed(const asset_descriptor_base& a, const asset_descriptor_base& b)
|
bool validate_ado_update_allowed(const asset_descriptor_base& new_ado, const asset_descriptor_base& prev_ado)
|
||||||
{
|
{
|
||||||
if (a.total_max_supply != b.total_max_supply) return false;
|
if (new_ado.total_max_supply != prev_ado.total_max_supply) return false;
|
||||||
//if (a.current_supply != b.current_supply) return false;
|
if (new_ado.current_supply > prev_ado.total_max_supply) return false;
|
||||||
if (a.decimal_point != b.decimal_point) return false;
|
if (new_ado.decimal_point != prev_ado.decimal_point) return false;
|
||||||
if (a.ticker != b.ticker) return false;
|
if (new_ado.ticker != prev_ado.ticker) return false;
|
||||||
if (a.full_name != b.full_name) return false;
|
if (new_ado.full_name != prev_ado.full_name) return false;
|
||||||
//a.meta_info;
|
//a.meta_info;
|
||||||
if (a.owner != b.owner) return false;
|
//if (a.owner != b.owner) return false;
|
||||||
if (a.hidden_supply != b.hidden_supply) return false;
|
if (new_ado.hidden_supply != prev_ado.hidden_supply) return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
//---------------------------------------------------------------
|
//---------------------------------------------------------------
|
||||||
|
/*
|
||||||
crypto::hash get_signature_hash_for_asset_operation(const asset_descriptor_operation& ado)
|
crypto::hash get_signature_hash_for_asset_operation(const asset_descriptor_operation& ado)
|
||||||
{
|
{
|
||||||
asset_descriptor_operation ado_local = ado;
|
asset_descriptor_operation ado_local = ado;
|
||||||
|
|
@ -1164,6 +1174,7 @@ namespace currency
|
||||||
{
|
{
|
||||||
op.opt_proof = boost::none;
|
op.opt_proof = boost::none;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
//---------------------------------------------------------------
|
//---------------------------------------------------------------
|
||||||
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, uint8_t tx_outs_attr /* = CURRENCY_TO_KEY_OUT_RELAXED */)
|
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, uint8_t tx_outs_attr /* = CURRENCY_TO_KEY_OUT_RELAXED */)
|
||||||
|
|
@ -2154,14 +2165,16 @@ namespace currency
|
||||||
{
|
{
|
||||||
if (ado.operation_type == ASSET_DESCRIPTOR_OPERATION_REGISTER)
|
if (ado.operation_type == ASSET_DESCRIPTOR_OPERATION_REGISTER)
|
||||||
{
|
{
|
||||||
crypto::secret_key asset_control_key{};
|
//crypto::secret_key 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);
|
//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");
|
//CHECK_AND_ASSERT_MES(r, false, "derive_key_pair_from_key_pair failed");
|
||||||
|
|
||||||
|
ado.descriptor.owner = sender_account_keys.account_address.spend_public_key;
|
||||||
|
|
||||||
calculate_asset_id(ado.descriptor.owner, &gen_context.ao_asset_id_pt, &gen_context.ao_asset_id);
|
calculate_asset_id(ado.descriptor.owner, &gen_context.ao_asset_id_pt, &gen_context.ao_asset_id);
|
||||||
|
|
||||||
// calculate amount blinding mask
|
// calculate amount blinding mask
|
||||||
gen_context.ao_amount_blinding_mask = crypto::hash_helper_t::hs(CRYPTO_HDS_ASSET_CONTROL_ABM, asset_control_key, tx_key.pub);
|
gen_context.ao_amount_blinding_mask = crypto::hash_helper_t::hs(CRYPTO_HDS_ASSET_CONTROL_ABM, tx_key.sec, tx_key.pub);
|
||||||
|
|
||||||
// set correct asset_id to the corresponding destination entries
|
// set correct asset_id to the corresponding destination entries
|
||||||
uint64_t amount_of_emitted_asset = 0;
|
uint64_t amount_of_emitted_asset = 0;
|
||||||
|
|
@ -2178,6 +2191,41 @@ 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;
|
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.amount_commitment = (crypto::c_scalar_1div8 * gen_context.ao_amount_commitment).to_public_key();
|
ado.amount_commitment = (crypto::c_scalar_1div8 * gen_context.ao_amount_commitment).to_public_key();
|
||||||
}
|
}
|
||||||
|
else if (ado.operation_type == ASSET_DESCRIPTOR_OPERATION_PUBLIC_BURN)
|
||||||
|
{
|
||||||
|
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, tx_key.sec, tx_key.pub);
|
||||||
|
gen_context.ao_commitment_in_outputs = true;
|
||||||
|
|
||||||
|
// set correct asset_id to the corresponding destination entries
|
||||||
|
uint64_t amount_of_burned_assets = 0;
|
||||||
|
for (auto& item : ftp.sources)
|
||||||
|
{
|
||||||
|
if (item.asset_id == gen_context.ao_asset_id)
|
||||||
|
{
|
||||||
|
amount_of_burned_assets += item.amount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (auto& item : ftp.prepared_destinations)
|
||||||
|
{
|
||||||
|
if (item.asset_id == gen_context.ao_asset_id)
|
||||||
|
{
|
||||||
|
CHECK_AND_ASSERT_THROW_MES(amount_of_burned_assets >= item.amount, "Failed to find burn amount, failed condition: amount_of_burned_assets(" << amount_of_burned_assets << ") >= item.amount(" << item.amount << ")");
|
||||||
|
amount_of_burned_assets -= item.amount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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.amount_commitment = (crypto::c_scalar_1div8 * gen_context.ao_amount_commitment).to_public_key();
|
||||||
|
|
||||||
|
if (ftp.pevents_dispatcher) ftp.pevents_dispatcher->RAISE_DEBUG_EVENT(wde_construct_tx_handle_asset_descriptor_operation_before_burn{ &ado });
|
||||||
|
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (ado.operation_type == ASSET_DESCRIPTOR_OPERATION_EMIT)
|
if (ado.operation_type == ASSET_DESCRIPTOR_OPERATION_EMIT)
|
||||||
|
|
@ -2187,7 +2235,7 @@ namespace currency
|
||||||
gen_context.ao_asset_id = *ado.opt_asset_id;
|
gen_context.ao_asset_id = *ado.opt_asset_id;
|
||||||
gen_context.ao_asset_id_pt.from_public_key(gen_context.ao_asset_id);
|
gen_context.ao_asset_id_pt.from_public_key(gen_context.ao_asset_id);
|
||||||
// calculate amount blinding mask
|
// calculate amount blinding mask
|
||||||
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_amount_blinding_mask = crypto::hash_helper_t::hs(CRYPTO_HDS_ASSET_CONTROL_ABM, tx_key.sec, tx_key.pub);
|
||||||
|
|
||||||
// set correct asset_id to the corresponding destination entries
|
// set correct asset_id to the corresponding destination entries
|
||||||
uint64_t amount_of_emitted_asset = 0;
|
uint64_t amount_of_emitted_asset = 0;
|
||||||
|
|
@ -2212,47 +2260,27 @@ namespace currency
|
||||||
|
|
||||||
//fields that not supposed to be changed?
|
//fields that not supposed to be changed?
|
||||||
}
|
}
|
||||||
else if (ado.operation_type == ASSET_DESCRIPTOR_OPERATION_PUBLIC_BURN)
|
|
||||||
{
|
|
||||||
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, tx_key.pub);
|
|
||||||
gen_context.ao_commitment_in_outputs = true;
|
|
||||||
|
|
||||||
// set correct asset_id to the corresponding destination entries
|
|
||||||
uint64_t amount_of_burned_assets = 0;
|
|
||||||
for (auto& item: ftp.sources)
|
|
||||||
{
|
|
||||||
if (item.asset_id == gen_context.ao_asset_id)
|
|
||||||
{
|
|
||||||
amount_of_burned_assets += item.amount;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (auto& item : ftp.prepared_destinations)
|
|
||||||
{
|
|
||||||
if (item.asset_id == gen_context.ao_asset_id )
|
|
||||||
{
|
|
||||||
CHECK_AND_ASSERT_THROW_MES(amount_of_burned_assets >= item.amount, "Failed to find burn amount, failed condition: amount_of_burned_assets(" << amount_of_burned_assets << ") >= item.amount("<< item.amount << ")");
|
|
||||||
amount_of_burned_assets -= item.amount;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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.amount_commitment = (crypto::c_scalar_1div8 * gen_context.ao_amount_commitment).to_public_key();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ftp.pevents_dispatcher) ftp.pevents_dispatcher->RAISE_DEBUG_EVENT(wde_construct_tx_handle_asset_descriptor_operation_before_seal{ &ado });
|
if (ftp.pevents_dispatcher) ftp.pevents_dispatcher->RAISE_DEBUG_EVENT(wde_construct_tx_handle_asset_descriptor_operation_before_seal{ &ado });
|
||||||
|
|
||||||
|
ftp.need_to_generate_ado_proof = true;
|
||||||
|
/*
|
||||||
//seal it with owners signature
|
//seal it with owners signature
|
||||||
crypto::signature sig = currency::null_sig;
|
crypto::signature sig = currency::null_sig;
|
||||||
crypto::public_key pub_k = currency::null_pkey;
|
crypto::hash h = get_signature_hash_for_asset_operation(ado)
|
||||||
crypto::secret_key_to_public_key(ftp.asset_control_key, pub_k);
|
if (ftp.pthirdparty_sign_handler)
|
||||||
crypto::generate_signature(get_signature_hash_for_asset_operation(ado), pub_k, ftp.asset_control_key, sig);
|
{
|
||||||
|
bool r = ftp.pthirdparty_sign_handler->sign(h, ftp.ado_current_asset_owner, sig);
|
||||||
|
CHECK_AND_ASSERT_MES(r, false, "asset thirparty sign failed");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
crypto::public_key pub_k = currency::null_pkey;
|
||||||
|
crypto::secret_key_to_public_key(sender_account_keys.spend_secret_key, pub_k);
|
||||||
|
CHECK_AND_ASSERT_MES(ftp.ado_current_asset_owner == pub_k, false, "asset owner key not matched with provided private key for asset operation signing");
|
||||||
|
crypto::generate_signature(h, pub_k, account_keys.spend_secret_key, sig);
|
||||||
|
}
|
||||||
ado.opt_proof = sig;
|
ado.opt_proof = sig;
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -2679,6 +2707,25 @@ namespace currency
|
||||||
aop.opt_amount_commitment_g_proof = aop_g_sig;
|
aop.opt_amount_commitment_g_proof = aop_g_sig;
|
||||||
tx.proofs.emplace_back(std::move(aop));
|
tx.proofs.emplace_back(std::move(aop));
|
||||||
}
|
}
|
||||||
|
if(ftp.need_to_generate_ado_proof)
|
||||||
|
{
|
||||||
|
asset_operation_ownership_proof aoop = AUTO_VAL_INIT(aoop);
|
||||||
|
|
||||||
|
if (ftp.pthirdparty_sign_handler)
|
||||||
|
{
|
||||||
|
//ask third party to generate proof
|
||||||
|
r = ftp.pthirdparty_sign_handler->sign(tx_prefix_hash, ftp.ado_current_asset_owner, aoop.gss);
|
||||||
|
CHECK_AND_ASSERT_MES(r, false, "Failed to sign ado by thirdparty");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//generate signature by wallet account
|
||||||
|
r = crypto::generate_schnorr_sig(tx_prefix_hash, ftp.ado_current_asset_owner, sender_account_keys.spend_secret_key, aoop.gss);
|
||||||
|
CHECK_AND_ASSERT_MES(r, false, "Failed to sign ado proof");
|
||||||
|
}
|
||||||
|
if (ftp.pevents_dispatcher) ftp.pevents_dispatcher->RAISE_DEBUG_EVENT(wde_construct_tx_after_asset_ownership_proof_generated{ &aoop });
|
||||||
|
tx.proofs.emplace_back(aoop);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//size_t prefix_size = get_object_blobsize(static_cast<const transaction_prefix&>(tx));
|
//size_t prefix_size = get_object_blobsize(static_cast<const transaction_prefix&>(tx));
|
||||||
|
|
|
||||||
|
|
@ -134,15 +134,18 @@ namespace currency
|
||||||
END_KV_SERIALIZE_MAP()
|
END_KV_SERIALIZE_MAP()
|
||||||
};
|
};
|
||||||
|
|
||||||
struct htlc_info
|
struct htlc_info
|
||||||
{
|
{
|
||||||
bool hltc_our_out_is_before_expiration;
|
bool hltc_our_out_is_before_expiration;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct thirdparty_sign_handler
|
||||||
|
{
|
||||||
|
virtual bool sign(const crypto::hash& h, const crypto::public_key& owner_public_key, crypto::generic_schnorr_sig& sig);
|
||||||
|
};
|
||||||
|
|
||||||
struct finalize_tx_param
|
struct finalize_tx_param
|
||||||
{
|
{
|
||||||
|
|
||||||
uint64_t unlock_time;
|
uint64_t unlock_time;
|
||||||
std::vector<currency::extra_v> extra;
|
std::vector<currency::extra_v> extra;
|
||||||
std::vector<currency::attachment_v> attachments;
|
std::vector<currency::attachment_v> attachments;
|
||||||
|
|
@ -158,10 +161,15 @@ namespace currency
|
||||||
crypto::public_key spend_pub_key; // only for validations
|
crypto::public_key spend_pub_key; // only for validations
|
||||||
uint64_t tx_version;
|
uint64_t tx_version;
|
||||||
uint64_t mode_separate_fee = 0;
|
uint64_t mode_separate_fee = 0;
|
||||||
crypto::secret_key asset_control_key = currency::null_skey;
|
|
||||||
epee::misc_utils::events_dispatcher* pevents_dispatcher;
|
epee::misc_utils::events_dispatcher* pevents_dispatcher;
|
||||||
|
|
||||||
tx_generation_context gen_context{}; // solely for consolidated txs
|
tx_generation_context gen_context{}; // solely for consolidated txs
|
||||||
|
|
||||||
|
//crypto::secret_key asset_control_key = currency::null_skey;
|
||||||
|
crypto::public_key ado_current_asset_owner = null_pkey;
|
||||||
|
thirdparty_sign_handler* pthirdparty_sign_handler = nullptr;
|
||||||
|
mutable bool need_to_generate_ado_proof = false;
|
||||||
|
|
||||||
|
|
||||||
BEGIN_SERIALIZE_OBJECT()
|
BEGIN_SERIALIZE_OBJECT()
|
||||||
FIELD(unlock_time)
|
FIELD(unlock_time)
|
||||||
|
|
@ -179,9 +187,12 @@ namespace currency
|
||||||
FIELD(spend_pub_key)
|
FIELD(spend_pub_key)
|
||||||
FIELD(tx_version)
|
FIELD(tx_version)
|
||||||
FIELD(mode_separate_fee)
|
FIELD(mode_separate_fee)
|
||||||
FIELD(asset_control_key)
|
|
||||||
if (flags & TX_FLAG_SIGNATURE_MODE_SEPARATE)
|
if (flags & TX_FLAG_SIGNATURE_MODE_SEPARATE)
|
||||||
|
{
|
||||||
FIELD(gen_context);
|
FIELD(gen_context);
|
||||||
|
}
|
||||||
|
FIELD(ado_current_asset_owner)
|
||||||
|
FIELD(need_to_generate_ado_proof)
|
||||||
END_SERIALIZE()
|
END_SERIALIZE()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -402,20 +402,8 @@ void wallet2::process_ado_in_new_transaction(const currency::asset_descriptor_op
|
||||||
{
|
{
|
||||||
if (ado.operation_type == ASSET_DESCRIPTOR_OPERATION_REGISTER)
|
if (ado.operation_type == ASSET_DESCRIPTOR_OPERATION_REGISTER)
|
||||||
{
|
{
|
||||||
crypto::public_key self_check = AUTO_VAL_INIT(self_check);
|
if (ado.descriptor.owner != m_account.get_public_address().spend_public_key)
|
||||||
crypto::secret_key asset_control_key = AUTO_VAL_INIT(asset_control_key);
|
|
||||||
bool r = derive_key_pair_from_key_pair(ptc.tx_pub_key, m_account.get_keys().spend_secret_key, asset_control_key, self_check, CRYPTO_HDS_ASSET_CONTROL_KEY);
|
|
||||||
if (!r)
|
|
||||||
{
|
{
|
||||||
//not critical error, continue to work
|
|
||||||
LOG_ERROR("Failed to derive_key_pair_from_key_pair for asset_descriptor_operation in tx " << ptc.tx_hash());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (self_check != ado.descriptor.owner)
|
|
||||||
{
|
|
||||||
//still not critical error
|
|
||||||
LOG_ERROR("Public key from asset_descriptor_operation(" << ado.descriptor.owner << ") not much with derived public key(" << self_check << "), for tx" << ptc.tx_hash());
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
crypto::public_key asset_id{};
|
crypto::public_key asset_id{};
|
||||||
|
|
@ -423,7 +411,6 @@ void wallet2::process_ado_in_new_transaction(const currency::asset_descriptor_op
|
||||||
WLT_THROW_IF_FALSE_WALLET_CMN_ERR_EX(m_own_asset_descriptors.count(asset_id) == 0, "asset with asset_id " << asset_id << " has already been registered in the wallet as own asset");
|
WLT_THROW_IF_FALSE_WALLET_CMN_ERR_EX(m_own_asset_descriptors.count(asset_id) == 0, "asset with asset_id " << asset_id << " has already been registered in the wallet as own asset");
|
||||||
wallet_own_asset_context& asset_context = m_own_asset_descriptors[asset_id];
|
wallet_own_asset_context& asset_context = m_own_asset_descriptors[asset_id];
|
||||||
asset_context.asset_descriptor = ado.descriptor;
|
asset_context.asset_descriptor = ado.descriptor;
|
||||||
asset_context.control_key = asset_control_key;
|
|
||||||
|
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << "New Asset Registered:"
|
ss << "New Asset Registered:"
|
||||||
|
|
@ -440,22 +427,80 @@ void wallet2::process_ado_in_new_transaction(const currency::asset_descriptor_op
|
||||||
if (m_wcallback)
|
if (m_wcallback)
|
||||||
m_wcallback->on_message(i_wallet2_callback::ms_yellow, ss.str());
|
m_wcallback->on_message(i_wallet2_callback::ms_yellow, ss.str());
|
||||||
}
|
}
|
||||||
else if (ado.operation_type == ASSET_DESCRIPTOR_OPERATION_UPDATE || ado.operation_type == ASSET_DESCRIPTOR_OPERATION_EMIT || ado.operation_type == ASSET_DESCRIPTOR_OPERATION_PUBLIC_BURN)
|
else if (ado.operation_type == ASSET_DESCRIPTOR_OPERATION_EMIT || ado.operation_type == ASSET_DESCRIPTOR_OPERATION_PUBLIC_BURN)
|
||||||
|
{
|
||||||
|
WLT_THROW_IF_FALSE_WALLET_CMN_ERR_EX(ado.opt_asset_id, get_asset_operation_type_string(ado.operation_type) << " failed with empty opt_asset_id");
|
||||||
|
auto it = m_own_asset_descriptors.find(*ado.opt_asset_id);
|
||||||
|
if (it == m_own_asset_descriptors.end())
|
||||||
|
break;
|
||||||
|
//asset had been updated
|
||||||
|
add_rollback_event(ptc.height, asset_update_event{ it->first, it->second });
|
||||||
|
it->second.asset_descriptor = ado.descriptor;
|
||||||
|
}
|
||||||
|
else if (ado.operation_type == ASSET_DESCRIPTOR_OPERATION_UPDATE )
|
||||||
{
|
{
|
||||||
WLT_THROW_IF_FALSE_WALLET_CMN_ERR_EX(ado.opt_asset_id, get_asset_operation_type_string(ado.operation_type) << " failed with empty opt_asset_id");
|
WLT_THROW_IF_FALSE_WALLET_CMN_ERR_EX(ado.opt_asset_id, get_asset_operation_type_string(ado.operation_type) << " failed with empty opt_asset_id");
|
||||||
auto it = m_own_asset_descriptors.find(*ado.opt_asset_id);
|
auto it = m_own_asset_descriptors.find(*ado.opt_asset_id);
|
||||||
WLT_THROW_IF_FALSE_WALLET_CMN_ERR_EX(it != m_own_asset_descriptors.end(), "asset with asset_id " << *ado.opt_asset_id << " not found during " << get_asset_operation_type_string(ado.operation_type));
|
if (it == m_own_asset_descriptors.end())
|
||||||
if (it->second.asset_descriptor.owner != ado.descriptor.owner)
|
|
||||||
{
|
{
|
||||||
//ownership of the asset had been transfered
|
if (ado.descriptor.owner == m_account.get_public_address().spend_public_key)
|
||||||
add_rollback_event(ptc.height, asset_unown_event{ it->first, it->second });
|
{
|
||||||
m_own_asset_descriptors.erase(it);
|
// ownership of the asset acquired
|
||||||
|
|
||||||
|
wallet_own_asset_context& asset_context = m_own_asset_descriptors[*ado.opt_asset_id];
|
||||||
|
asset_context.asset_descriptor = ado.descriptor;
|
||||||
|
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << "Asset ownership acquired:"
|
||||||
|
<< ENDL << "asset id: " << *ado.opt_asset_id
|
||||||
|
<< ENDL << "Name: " << ado.descriptor.full_name
|
||||||
|
<< ENDL << "Ticker: " << ado.descriptor.ticker
|
||||||
|
<< ENDL << "Total Max Supply: " << print_asset_money(ado.descriptor.total_max_supply, ado.descriptor.decimal_point)
|
||||||
|
<< ENDL << "Current Supply: " << print_asset_money(ado.descriptor.current_supply, ado.descriptor.decimal_point)
|
||||||
|
<< ENDL << "Decimal Point: " << ado.descriptor.decimal_point;
|
||||||
|
|
||||||
|
|
||||||
|
add_rollback_event(ptc.height, asset_register_event{ *ado.opt_asset_id });
|
||||||
|
WLT_LOG_MAGENTA(ss.str(), LOG_LEVEL_0);
|
||||||
|
if (m_wcallback)
|
||||||
|
m_wcallback->on_message(i_wallet2_callback::ms_yellow, ss.str());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// update event of the asset that we not control, skip
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//asset had been updated
|
//update event for asset that we control, check if ownership is still ours
|
||||||
add_rollback_event(ptc.height, asset_update_event{ it->first, it->second });
|
if (ado.descriptor.owner != m_account.get_public_address().spend_public_key && !it->second.thirdparty_custody)
|
||||||
it->second.asset_descriptor = ado.descriptor;
|
{
|
||||||
|
//ownership of the asset had been transfered
|
||||||
|
add_rollback_event(ptc.height, asset_unown_event{ it->first, it->second });
|
||||||
|
m_own_asset_descriptors.erase(it);
|
||||||
|
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << "Asset ownership lost:"
|
||||||
|
<< ENDL << "asset id: " << *ado.opt_asset_id
|
||||||
|
<< ENDL << "New owner: " << ado.descriptor.owner
|
||||||
|
<< ENDL << "Name: " << ado.descriptor.full_name
|
||||||
|
<< ENDL << "Ticker: " << ado.descriptor.ticker
|
||||||
|
<< ENDL << "Total Max Supply: " << print_asset_money(ado.descriptor.total_max_supply, ado.descriptor.decimal_point)
|
||||||
|
<< ENDL << "Current Supply: " << print_asset_money(ado.descriptor.current_supply, ado.descriptor.decimal_point)
|
||||||
|
<< ENDL << "Decimal Point: " << ado.descriptor.decimal_point;
|
||||||
|
|
||||||
|
add_rollback_event(ptc.height, asset_register_event{ *ado.opt_asset_id });
|
||||||
|
WLT_LOG_MAGENTA(ss.str(), LOG_LEVEL_0);
|
||||||
|
if (m_wcallback)
|
||||||
|
m_wcallback->on_message(i_wallet2_callback::ms_yellow, ss.str());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//just an update of the asset
|
||||||
|
add_rollback_event(ptc.height, asset_update_event{ it->first, it->second });
|
||||||
|
it->second.asset_descriptor = ado.descriptor;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while (false);
|
} while (false);
|
||||||
|
|
@ -868,15 +913,13 @@ void wallet2::process_new_transaction(const currency::transaction& tx, uint64_t
|
||||||
m_payments.emplace(payment_id, payment);
|
m_payments.emplace(payment_id, payment);
|
||||||
WLT_LOG_L2("Payment found, id (hex): " << epee::string_tools::buff_to_hex_nodelimer(payment_id) << ", tx: " << payment.m_tx_hash << ", amount: " << print_money_brief(payment.m_amount) << "subtransfers = " << payment.subtransfers.size());
|
WLT_LOG_L2("Payment found, id (hex): " << epee::string_tools::buff_to_hex_nodelimer(payment_id) << ", tx: " << payment.m_tx_hash << ", amount: " << print_money_brief(payment.m_amount) << "subtransfers = " << payment.subtransfers.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ptc.spent_own_native_inputs)
|
//check if there are asset_registration that belong to this wallet
|
||||||
|
const asset_descriptor_operation* pado = get_type_in_variant_container<const asset_descriptor_operation>(tx.extra);
|
||||||
|
if (pado && (ptc.employed_entries.receive.size() || ptc.employed_entries.spent.size() || pado->descriptor.owner == m_account.get_public_address().spend_public_key))
|
||||||
{
|
{
|
||||||
//check if there are asset_registration that belong to this wallet
|
//check if there are asset_registration that belong to this wallet
|
||||||
asset_descriptor_operation ado = AUTO_VAL_INIT(ado);
|
process_ado_in_new_transaction(*pado, ptc);
|
||||||
if (get_type_in_variant_container(tx.extra, ado))
|
|
||||||
{
|
|
||||||
process_ado_in_new_transaction(ado, ptc);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (has_in_transfers || has_out_transfers || is_derivation_used_to_encrypt(tx, derivation) || ptc.employed_entries.spent.size())
|
if (has_in_transfers || has_out_transfers || is_derivation_used_to_encrypt(tx, derivation) || ptc.employed_entries.spent.size())
|
||||||
|
|
@ -3333,7 +3376,7 @@ uint64_t wallet2::balance(uint64_t& unlocked, uint64_t& awaiting_in, uint64_t& a
|
||||||
return total;
|
return total;
|
||||||
}
|
}
|
||||||
//----------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------
|
||||||
uint64_t wallet2::balance(crypto::public_key asset_id, uint64_t& unlocked) const
|
uint64_t wallet2::balance(const crypto::public_key& asset_id, uint64_t& unlocked) const
|
||||||
{
|
{
|
||||||
std::unordered_map<crypto::public_key, wallet_public::asset_balance_entry_base> balances;
|
std::unordered_map<crypto::public_key, wallet_public::asset_balance_entry_base> balances;
|
||||||
uint64_t dummy;
|
uint64_t dummy;
|
||||||
|
|
@ -3347,6 +3390,12 @@ uint64_t wallet2::balance(crypto::public_key asset_id, uint64_t& unlocked) const
|
||||||
return it->second.total;
|
return it->second.total;
|
||||||
}
|
}
|
||||||
//----------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------
|
||||||
|
uint64_t wallet2::balance(const crypto::public_key& asset_id) const
|
||||||
|
{
|
||||||
|
uint64_t dummy = 0;
|
||||||
|
return balance(asset_id, dummy);
|
||||||
|
}
|
||||||
|
//----------------------------------------------------------------------------------------------------
|
||||||
bool wallet2::balance(std::unordered_map<crypto::public_key, wallet_public::asset_balance_entry_base>& balances, uint64_t& mined) const
|
bool wallet2::balance(std::unordered_map<crypto::public_key, wallet_public::asset_balance_entry_base>& balances, uint64_t& mined) const
|
||||||
{
|
{
|
||||||
mined = 0;
|
mined = 0;
|
||||||
|
|
@ -4882,7 +4931,8 @@ void wallet2::emmit_asset(const crypto::public_key asset_id, std::vector<currenc
|
||||||
ctp.dsts = destinations;
|
ctp.dsts = destinations;
|
||||||
ctp.extra.push_back(asset_emmit_info);
|
ctp.extra.push_back(asset_emmit_info);
|
||||||
ctp.need_at_least_1_zc = true;
|
ctp.need_at_least_1_zc = true;
|
||||||
ctp.asset_deploy_control_key = own_asset_entry_it->second.control_key;
|
ctp.ado_current_asset_owner = rsp.asset_descriptor.owner;
|
||||||
|
//ctp.asset_deploy_control_key = own_asset_entry_it->second.control_key;
|
||||||
|
|
||||||
finalized_tx ft = AUTO_VAL_INIT(ft);
|
finalized_tx ft = AUTO_VAL_INIT(ft);
|
||||||
this->transfer(ctp, ft, true, nullptr);
|
this->transfer(ctp, ft, true, nullptr);
|
||||||
|
|
@ -4901,7 +4951,33 @@ void wallet2::update_asset(const crypto::public_key asset_id, const currency::as
|
||||||
construct_tx_param ctp = get_default_construct_tx_param();
|
construct_tx_param ctp = get_default_construct_tx_param();
|
||||||
ctp.extra.push_back(asset_update_info);
|
ctp.extra.push_back(asset_update_info);
|
||||||
ctp.need_at_least_1_zc = true;
|
ctp.need_at_least_1_zc = true;
|
||||||
ctp.asset_deploy_control_key = own_asset_entry_it->second.control_key;
|
currency::asset_descriptor_base adb = AUTO_VAL_INIT(adb);
|
||||||
|
bool r = this->daemon_get_asset_info(asset_id, adb);
|
||||||
|
CHECK_AND_ASSERT_THROW_MES(r, "Failed to get asset info from daemon");
|
||||||
|
ctp.ado_current_asset_owner = adb.owner;
|
||||||
|
|
||||||
|
finalized_tx ft = AUTO_VAL_INIT(ft);
|
||||||
|
this->transfer(ctp, ft, true, nullptr);
|
||||||
|
result_tx = ft.tx;
|
||||||
|
}
|
||||||
|
//----------------------------------------------------------------------------------------------------
|
||||||
|
void wallet2::transfer_asset_ownership(const crypto::public_key asset_id, const crypto::public_key& new_owner, currency::transaction& result_tx)
|
||||||
|
{
|
||||||
|
auto own_asset_entry_it = m_own_asset_descriptors.find(asset_id);
|
||||||
|
CHECK_AND_ASSERT_THROW_MES(own_asset_entry_it != m_own_asset_descriptors.end(), "Failed find asset_id " << asset_id << " in own assets list");
|
||||||
|
|
||||||
|
currency::asset_descriptor_base adb = AUTO_VAL_INIT(adb);
|
||||||
|
bool r = this->daemon_get_asset_info(asset_id, adb);
|
||||||
|
CHECK_AND_ASSERT_THROW_MES(r, "Failed to get asset info from daemon");
|
||||||
|
|
||||||
|
asset_descriptor_operation asset_update_info = AUTO_VAL_INIT(asset_update_info);
|
||||||
|
asset_update_info.descriptor = adb;
|
||||||
|
asset_update_info.operation_type = ASSET_DESCRIPTOR_OPERATION_UPDATE;
|
||||||
|
asset_update_info.opt_asset_id = asset_id;
|
||||||
|
asset_update_info.descriptor.owner = new_owner;
|
||||||
|
construct_tx_param ctp = get_default_construct_tx_param();
|
||||||
|
ctp.ado_current_asset_owner = adb.owner;
|
||||||
|
ctp.extra.push_back(asset_update_info);
|
||||||
|
|
||||||
finalized_tx ft = AUTO_VAL_INIT(ft);
|
finalized_tx ft = AUTO_VAL_INIT(ft);
|
||||||
this->transfer(ctp, ft, true, nullptr);
|
this->transfer(ctp, ft, true, nullptr);
|
||||||
|
|
@ -4910,8 +4986,8 @@ void wallet2::update_asset(const crypto::public_key asset_id, const currency::as
|
||||||
//----------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------
|
||||||
void wallet2::burn_asset(const crypto::public_key asset_id, uint64_t amount_to_burn, currency::transaction& result_tx)
|
void wallet2::burn_asset(const crypto::public_key asset_id, uint64_t amount_to_burn, currency::transaction& result_tx)
|
||||||
{
|
{
|
||||||
auto own_asset_entry_it = m_own_asset_descriptors.find(asset_id);
|
//auto own_asset_entry_it = m_own_asset_descriptors.find(asset_id);
|
||||||
CHECK_AND_ASSERT_THROW_MES(own_asset_entry_it != m_own_asset_descriptors.end(), "Failed find asset_id " << asset_id << " in own assets list");
|
//CHECK_AND_ASSERT_THROW_MES(own_asset_entry_it != m_own_asset_descriptors.end(), "Failed find asset_id " << asset_id << " in own assets list");
|
||||||
COMMAND_RPC_GET_ASSET_INFO::request req;
|
COMMAND_RPC_GET_ASSET_INFO::request req;
|
||||||
req.asset_id = asset_id;
|
req.asset_id = asset_id;
|
||||||
COMMAND_RPC_GET_ASSET_INFO::response rsp;
|
COMMAND_RPC_GET_ASSET_INFO::response rsp;
|
||||||
|
|
@ -4934,7 +5010,7 @@ void wallet2::burn_asset(const crypto::public_key asset_id, uint64_t amount_to_b
|
||||||
construct_tx_param ctp = get_default_construct_tx_param();
|
construct_tx_param ctp = get_default_construct_tx_param();
|
||||||
ctp.extra.push_back(asset_burn_info);
|
ctp.extra.push_back(asset_burn_info);
|
||||||
ctp.need_at_least_1_zc = true;
|
ctp.need_at_least_1_zc = true;
|
||||||
ctp.asset_deploy_control_key = own_asset_entry_it->second.control_key;
|
ctp.ado_current_asset_owner = rsp.asset_descriptor.owner;
|
||||||
ctp.dsts.push_back(dst_to_burn);
|
ctp.dsts.push_back(dst_to_burn);
|
||||||
|
|
||||||
finalized_tx ft = AUTO_VAL_INIT(ft);
|
finalized_tx ft = AUTO_VAL_INIT(ft);
|
||||||
|
|
@ -6927,7 +7003,8 @@ bool wallet2::prepare_transaction(construct_tx_param& ctp, currency::finalize_tx
|
||||||
|
|
||||||
const currency::transaction& tx_for_mode_separate = msc.tx_for_mode_separate;
|
const currency::transaction& tx_for_mode_separate = msc.tx_for_mode_separate;
|
||||||
assets_selection_context needed_money_map = get_needed_money(ctp.fee, ctp.dsts);
|
assets_selection_context needed_money_map = get_needed_money(ctp.fee, ctp.dsts);
|
||||||
ftp.asset_control_key = ctp.asset_deploy_control_key;
|
ftp.ado_current_asset_owner = ctp.ado_current_asset_owner;
|
||||||
|
ftp.pthirdparty_sign_handler = ctp.pthirdparty_sign_handler;
|
||||||
//
|
//
|
||||||
// TODO @#@# need to do refactoring over this part to support hidden amounts and asset_id
|
// TODO @#@# need to do refactoring over this part to support hidden amounts and asset_id
|
||||||
//
|
//
|
||||||
|
|
|
||||||
|
|
@ -391,9 +391,10 @@ namespace tools
|
||||||
void emmit_asset(const crypto::public_key asset_id, std::vector<currency::tx_destination_entry>& destinations, currency::transaction& result_tx);
|
void emmit_asset(const crypto::public_key asset_id, std::vector<currency::tx_destination_entry>& destinations, currency::transaction& result_tx);
|
||||||
void update_asset(const crypto::public_key asset_id, const currency::asset_descriptor_base new_descriptor, currency::transaction& result_tx);
|
void update_asset(const crypto::public_key asset_id, const currency::asset_descriptor_base new_descriptor, currency::transaction& result_tx);
|
||||||
void burn_asset(const crypto::public_key asset_id, uint64_t amount_to_burn, currency::transaction& result_tx);
|
void burn_asset(const crypto::public_key asset_id, uint64_t amount_to_burn, currency::transaction& result_tx);
|
||||||
|
void transfer_asset_ownership(const crypto::public_key asset_id, const crypto::public_key& new_owner, currency::transaction& result_tx);
|
||||||
|
|
||||||
bool daemon_get_asset_info(const crypto::public_key& asset_id, currency::asset_descriptor_base& adb);
|
bool daemon_get_asset_info(const crypto::public_key& asset_id, currency::asset_descriptor_base& adb);
|
||||||
|
const std::unordered_map<crypto::public_key, wallet_own_asset_context>& get_own_assets() const { return m_own_asset_descriptors; }
|
||||||
bool set_core_proxy(const std::shared_ptr<i_core_proxy>& proxy);
|
bool set_core_proxy(const std::shared_ptr<i_core_proxy>& proxy);
|
||||||
void set_pos_utxo_count_limits_for_defragmentation_tx(uint64_t min_outs, uint64_t max_outs); // don't create UTXO defrag. tx if there are less than 'min_outs' outs; don't put more than 'max_outs' outs
|
void set_pos_utxo_count_limits_for_defragmentation_tx(uint64_t min_outs, uint64_t max_outs); // don't create UTXO defrag. tx if there are less than 'min_outs' outs; don't put more than 'max_outs' outs
|
||||||
void set_pos_decoys_count_for_defragmentation_tx(size_t decoys_count);
|
void set_pos_decoys_count_for_defragmentation_tx(size_t decoys_count);
|
||||||
|
|
@ -404,7 +405,8 @@ namespace tools
|
||||||
uint64_t balance(uint64_t& unloked, uint64_t& awaiting_in, uint64_t& awaiting_out, uint64_t& mined, const crypto::public_key& asset_id = currency::native_coin_asset_id) const;
|
uint64_t balance(uint64_t& unloked, uint64_t& awaiting_in, uint64_t& awaiting_out, uint64_t& mined, const crypto::public_key& asset_id = currency::native_coin_asset_id) const;
|
||||||
bool balance(std::unordered_map<crypto::public_key, wallet_public::asset_balance_entry_base>& balances, uint64_t& mined) const;
|
bool balance(std::unordered_map<crypto::public_key, wallet_public::asset_balance_entry_base>& balances, uint64_t& mined) const;
|
||||||
bool balance(std::list<wallet_public::asset_balance_entry>& balances, uint64_t& mined) const;
|
bool balance(std::list<wallet_public::asset_balance_entry>& balances, uint64_t& mined) const;
|
||||||
uint64_t balance(crypto::public_key asset_id, uint64_t& unloked) const;
|
uint64_t balance(const crypto::public_key& asset_id, uint64_t& unlocked) const;
|
||||||
|
uint64_t balance(const crypto::public_key& asset_id) const;
|
||||||
|
|
||||||
uint64_t balance(uint64_t& unloked) const;
|
uint64_t balance(uint64_t& unloked) const;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -199,6 +199,7 @@ namespace tools
|
||||||
END_SERIALIZE()
|
END_SERIALIZE()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct construct_tx_param
|
struct construct_tx_param
|
||||||
{
|
{
|
||||||
// preparing data for tx
|
// preparing data for tx
|
||||||
|
|
@ -223,7 +224,9 @@ namespace tools
|
||||||
bool shuffle = false;
|
bool shuffle = false;
|
||||||
bool create_utxo_defragmentation_tx = false;
|
bool create_utxo_defragmentation_tx = false;
|
||||||
bool need_at_least_1_zc = false;
|
bool need_at_least_1_zc = false;
|
||||||
crypto::secret_key asset_deploy_control_key = currency::null_skey;
|
//crypto::secret_key asset_deploy_control_key = currency::null_skey;
|
||||||
|
currency::thirdparty_sign_handler* pthirdparty_sign_handler = nullptr;
|
||||||
|
crypto::public_key ado_current_asset_owner = currency::null_pkey;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mode_separate_context
|
struct mode_separate_context
|
||||||
|
|
@ -255,13 +258,11 @@ namespace tools
|
||||||
struct wallet_own_asset_context
|
struct wallet_own_asset_context
|
||||||
{
|
{
|
||||||
currency::asset_descriptor_base asset_descriptor;
|
currency::asset_descriptor_base asset_descriptor;
|
||||||
crypto::secret_key control_key;
|
bool thirdparty_custody = false;
|
||||||
//uint64_t height = 0;
|
|
||||||
|
|
||||||
BEGIN_BOOST_SERIALIZATION()
|
BEGIN_BOOST_SERIALIZATION()
|
||||||
BOOST_SERIALIZE(asset_descriptor)
|
BOOST_SERIALIZE(asset_descriptor)
|
||||||
BOOST_SERIALIZE(control_key)
|
BOOST_SERIALIZE(thirdparty_custody)
|
||||||
//BOOST_SERIALIZE(height)
|
|
||||||
END_BOOST_SERIALIZATION()
|
END_BOOST_SERIALIZATION()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,9 +13,20 @@ struct wde_construct_tx_handle_asset_descriptor_operation
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
//Wallet Debug Events
|
|
||||||
struct wde_construct_tx_handle_asset_descriptor_operation_before_seal
|
struct wde_construct_tx_handle_asset_descriptor_operation_before_seal
|
||||||
{
|
{
|
||||||
currency::asset_descriptor_operation* pado;
|
currency::asset_descriptor_operation* pado;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct wde_construct_tx_handle_asset_descriptor_operation_before_burn
|
||||||
|
{
|
||||||
|
currency::asset_descriptor_operation* pado;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
struct wde_construct_tx_after_asset_ownership_proof_generated
|
||||||
|
{
|
||||||
|
currency::asset_operation_ownership_proof* pownership_proof;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,65 +11,6 @@
|
||||||
#include "wallet/wallet_debug_events_definitions.h"
|
#include "wallet/wallet_debug_events_definitions.h"
|
||||||
using namespace currency;
|
using namespace currency;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
|
|
||||||
struct debug_context_event_1
|
|
||||||
{
|
|
||||||
int& i;
|
|
||||||
std::string& s;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//#define RAISE_DEBUG_EVENT dw.handle_type
|
|
||||||
|
|
||||||
|
|
||||||
void test_test()
|
|
||||||
{
|
|
||||||
epee::misc_utils::events_dispatcher ed;
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------
|
|
||||||
//--------------------------------------------------------------------------------
|
|
||||||
//--------------------------------------------------------------------------------
|
|
||||||
//thus code will be called in the tests
|
|
||||||
ed.SUBSCIRBE_DEBUG_EVENT<debug_context_event_1>([&](debug_context_event_1& d)
|
|
||||||
{
|
|
||||||
//here some operations
|
|
||||||
LOG_PRINT_L0("lala: " << d.i << d.s);
|
|
||||||
//
|
|
||||||
d.i = 10;
|
|
||||||
d.s = "33333";
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------
|
|
||||||
//--------------------------------------------------------------------------------
|
|
||||||
//--------------------------------------------------------------------------------
|
|
||||||
//this code will be in the wallet and helper functions
|
|
||||||
|
|
||||||
int i = 22;
|
|
||||||
std::string sss = "11111";
|
|
||||||
|
|
||||||
ed.RAISE_DEBUG_EVENT(debug_context_event_1{i, sss });
|
|
||||||
|
|
||||||
|
|
||||||
LOG_PRINT_L0("lala: " << i << sss);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
#define AMOUNT_TO_TRANSFER_MULTIASSETS_BASIC (TESTS_DEFAULT_FEE)
|
#define AMOUNT_TO_TRANSFER_MULTIASSETS_BASIC (TESTS_DEFAULT_FEE)
|
||||||
|
|
@ -97,6 +38,7 @@ bool multiassets_basic_test::generate(std::vector<test_event_entry>& events) con
|
||||||
DO_CALLBACK(events, "configure_core"); // default configure_core callback will initialize core runtime config with m_hardforks
|
DO_CALLBACK(events, "configure_core"); // default configure_core callback will initialize core runtime config with m_hardforks
|
||||||
//TODO: Need to make sure REWIND_BLOCKS_N and other coretests codebase are capable of following hardfork4 rules
|
//TODO: Need to make sure REWIND_BLOCKS_N and other coretests codebase are capable of following hardfork4 rules
|
||||||
//in this test hardfork4 moment moved to runtime section
|
//in this test hardfork4 moment moved to runtime section
|
||||||
|
//REWIND_BLOCKS_N_WITH_TIME(events, blk_2_inital, blk_0, alice_acc, 2);
|
||||||
REWIND_BLOCKS_N_WITH_TIME(events, blk_0r, blk_0, miner_acc, CURRENCY_MINED_MONEY_UNLOCK_WINDOW + 3);
|
REWIND_BLOCKS_N_WITH_TIME(events, blk_0r, blk_0, miner_acc, CURRENCY_MINED_MONEY_UNLOCK_WINDOW + 3);
|
||||||
|
|
||||||
DO_CALLBACK(events, "c1");
|
DO_CALLBACK(events, "c1");
|
||||||
|
|
@ -115,7 +57,7 @@ bool multiassets_basic_test::c1(currency::core& c, size_t ev_index, const std::v
|
||||||
alice_wlt->get_account().set_createtime(0);
|
alice_wlt->get_account().set_createtime(0);
|
||||||
|
|
||||||
asset_descriptor_base adb = AUTO_VAL_INIT(adb);
|
asset_descriptor_base adb = AUTO_VAL_INIT(adb);
|
||||||
adb.total_max_supply = 1000000000000000000; //1M coins
|
adb.total_max_supply = 10000000000000000000; //1M coins
|
||||||
adb.full_name = "Test coins";
|
adb.full_name = "Test coins";
|
||||||
adb.ticker = "TCT";
|
adb.ticker = "TCT";
|
||||||
adb.decimal_point = 12;
|
adb.decimal_point = 12;
|
||||||
|
|
@ -141,31 +83,13 @@ bool multiassets_basic_test::c1(currency::core& c, size_t ev_index, const std::v
|
||||||
r = mine_next_pow_blocks_in_playtime(miner_wlt->get_account().get_public_address(), c, CURRENCY_MINED_MONEY_UNLOCK_WINDOW);
|
r = mine_next_pow_blocks_in_playtime(miner_wlt->get_account().get_public_address(), c, CURRENCY_MINED_MONEY_UNLOCK_WINDOW);
|
||||||
CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_blocks_in_playtime failed");
|
CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_blocks_in_playtime failed");
|
||||||
|
|
||||||
|
|
||||||
miner_wlt->refresh();
|
miner_wlt->refresh();
|
||||||
alice_wlt->refresh();
|
alice_wlt->refresh();
|
||||||
uint64_t mined = 0;
|
CHECK_AND_ASSERT_MES(miner_wlt->balance(asset_id) == AMOUNT_ASSETS_TO_TRANSFER_MULTIASSETS_BASIC, false, "Failed to find needed asset in result balances");
|
||||||
std::unordered_map<crypto::public_key, tools::wallet_public::asset_balance_entry_base> balances;
|
CHECK_AND_ASSERT_MES(miner_wlt->balance() == uint64_t(17517225990000000000), false, "Failed to find needed asset in result balances");
|
||||||
miner_wlt->balance(balances, mined);
|
|
||||||
|
|
||||||
auto it_asset = balances.find(asset_id);
|
CHECK_AND_ASSERT_MES(alice_wlt->balance() == 0, false, "Failed to find needed asset in result balances");
|
||||||
auto it_native = balances.find(currency::native_coin_asset_id);
|
CHECK_AND_ASSERT_MES(alice_wlt->balance(asset_id) == AMOUNT_ASSETS_TO_TRANSFER_MULTIASSETS_BASIC, false, "Failed to find needed asset in result balances");
|
||||||
|
|
||||||
|
|
||||||
CHECK_AND_ASSERT_MES(it_asset != balances.end() && it_native != balances.end(), false, "Failed to find needed asset in result balances");
|
|
||||||
CHECK_AND_ASSERT_MES(it_asset->second.total == AMOUNT_ASSETS_TO_TRANSFER_MULTIASSETS_BASIC, false, "Failed to find needed asset in result balances");
|
|
||||||
CHECK_AND_ASSERT_MES(it_native->second.total == uint64_t(17517225990000000000), false, "Failed to find needed asset in result balances");
|
|
||||||
|
|
||||||
|
|
||||||
balances.clear();
|
|
||||||
alice_wlt->balance(balances, mined);
|
|
||||||
|
|
||||||
it_asset = balances.find(asset_id);
|
|
||||||
it_native = balances.find(currency::native_coin_asset_id);
|
|
||||||
|
|
||||||
CHECK_AND_ASSERT_MES(it_asset != balances.end(), false, "Failed to find needed asset in result balances");
|
|
||||||
CHECK_AND_ASSERT_MES(it_native == balances.end(), false, "Failed to find needed asset in result balances");
|
|
||||||
CHECK_AND_ASSERT_MES(it_asset->second.total == AMOUNT_ASSETS_TO_TRANSFER_MULTIASSETS_BASIC, false, "Failed to find needed asset in result balances");
|
|
||||||
|
|
||||||
miner_wlt->transfer(AMOUNT_ASSETS_TO_TRANSFER_MULTIASSETS_BASIC/2, alice_wlt->get_account().get_public_address(), asset_id);
|
miner_wlt->transfer(AMOUNT_ASSETS_TO_TRANSFER_MULTIASSETS_BASIC/2, alice_wlt->get_account().get_public_address(), asset_id);
|
||||||
//pass over hardfork
|
//pass over hardfork
|
||||||
|
|
@ -173,11 +97,9 @@ bool multiassets_basic_test::c1(currency::core& c, size_t ev_index, const std::v
|
||||||
CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_blocks_in_playtime failed");
|
CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_blocks_in_playtime failed");
|
||||||
|
|
||||||
alice_wlt->refresh();
|
alice_wlt->refresh();
|
||||||
uint64_t last_alice_balances = alice_wlt->balance(asset_id, mined);
|
uint64_t last_alice_balances = alice_wlt->balance(asset_id);
|
||||||
CHECK_AND_ASSERT_MES(last_alice_balances == AMOUNT_ASSETS_TO_TRANSFER_MULTIASSETS_BASIC + AMOUNT_ASSETS_TO_TRANSFER_MULTIASSETS_BASIC/2, false, "Failed to find needed asset in result balances");
|
CHECK_AND_ASSERT_MES(last_alice_balances == AMOUNT_ASSETS_TO_TRANSFER_MULTIASSETS_BASIC + AMOUNT_ASSETS_TO_TRANSFER_MULTIASSETS_BASIC/2, false, "Failed to find needed asset in result balances");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
|
||||||
|
|
@ -193,7 +115,7 @@ bool multiassets_basic_test::c1(currency::core& c, size_t ev_index, const std::v
|
||||||
}
|
}
|
||||||
|
|
||||||
miner_wlt->refresh();
|
miner_wlt->refresh();
|
||||||
uint64_t last_miner_balance = miner_wlt->balance(asset_id, mined);
|
uint64_t last_miner_balance = miner_wlt->balance(asset_id);
|
||||||
|
|
||||||
|
|
||||||
asset_descriptor_base asset_info = AUTO_VAL_INIT(asset_info);
|
asset_descriptor_base asset_info = AUTO_VAL_INIT(asset_info);
|
||||||
|
|
@ -211,7 +133,7 @@ bool multiassets_basic_test::c1(currency::core& c, size_t ev_index, const std::v
|
||||||
//test update function
|
//test update function
|
||||||
asset_info.meta_info = "{\"some\": \"info\"}";
|
asset_info.meta_info = "{\"some\": \"info\"}";
|
||||||
miner_wlt->update_asset(asset_id, asset_info, tx);
|
miner_wlt->update_asset(asset_id, asset_info, tx);
|
||||||
r = mine_next_pow_blocks_in_playtime(miner_wlt->get_account().get_public_address(), c, 2);
|
r = mine_next_pow_blocks_in_playtime(alice_wlt->get_account().get_public_address(), c, 2);
|
||||||
CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_blocks_in_playtime failed");
|
CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_blocks_in_playtime failed");
|
||||||
|
|
||||||
asset_descriptor_base asset_info2 = AUTO_VAL_INIT(asset_info2);
|
asset_descriptor_base asset_info2 = AUTO_VAL_INIT(asset_info2);
|
||||||
|
|
@ -228,8 +150,8 @@ bool multiassets_basic_test::c1(currency::core& c, size_t ev_index, const std::v
|
||||||
|
|
||||||
miner_wlt->refresh();
|
miner_wlt->refresh();
|
||||||
alice_wlt->refresh();
|
alice_wlt->refresh();
|
||||||
CHECK_AND_ASSERT_MES(miner_wlt->balance(asset_id, mined) == last_miner_balance + destinations[0].amount, false, "Miner balance wrong");
|
CHECK_AND_ASSERT_MES(miner_wlt->balance(asset_id) == last_miner_balance + destinations[0].amount, false, "Miner balance wrong");
|
||||||
CHECK_AND_ASSERT_MES(alice_wlt->balance(asset_id, mined) == last_alice_balances + destinations[1].amount, false, "Alice balance wrong");
|
CHECK_AND_ASSERT_MES(alice_wlt->balance(asset_id) == last_alice_balances + destinations[1].amount, false, "Alice balance wrong");
|
||||||
|
|
||||||
asset_descriptor_base asset_info3 = AUTO_VAL_INIT(asset_info3);
|
asset_descriptor_base asset_info3 = AUTO_VAL_INIT(asset_info3);
|
||||||
r = c.get_blockchain_storage().get_asset_info(asset_id, asset_info3);
|
r = c.get_blockchain_storage().get_asset_info(asset_id, asset_info3);
|
||||||
|
|
@ -242,7 +164,7 @@ bool multiassets_basic_test::c1(currency::core& c, size_t ev_index, const std::v
|
||||||
r = mine_next_pow_blocks_in_playtime(miner_wlt->get_account().get_public_address(), c, 1);
|
r = mine_next_pow_blocks_in_playtime(miner_wlt->get_account().get_public_address(), c, 1);
|
||||||
|
|
||||||
miner_wlt->refresh();
|
miner_wlt->refresh();
|
||||||
CHECK_AND_ASSERT_MES(miner_wlt->balance(asset_id, mined) == destinations[0].amount, false, "Miner balance wrong");
|
CHECK_AND_ASSERT_MES(miner_wlt->balance(asset_id) == destinations[0].amount, false, "Miner balance wrong");
|
||||||
|
|
||||||
asset_descriptor_base asset_info4 = AUTO_VAL_INIT(asset_info4);
|
asset_descriptor_base asset_info4 = AUTO_VAL_INIT(asset_info4);
|
||||||
r = c.get_blockchain_storage().get_asset_info(asset_id, asset_info4);
|
r = c.get_blockchain_storage().get_asset_info(asset_id, asset_info4);
|
||||||
|
|
@ -252,10 +174,10 @@ bool multiassets_basic_test::c1(currency::core& c, size_t ev_index, const std::v
|
||||||
|
|
||||||
//------------------- tests that trying to break stuff -------------------
|
//------------------- tests that trying to break stuff -------------------
|
||||||
//tests that trying to break stuff
|
//tests that trying to break stuff
|
||||||
miner_wlt->get_debug_events_dispatcher().SUBSCIRBE_DEBUG_EVENT<wde_construct_tx_handle_asset_descriptor_operation>([&](const wde_construct_tx_handle_asset_descriptor_operation& o)
|
miner_wlt->get_debug_events_dispatcher().SUBSCIRBE_DEBUG_EVENT<wde_construct_tx_after_asset_ownership_proof_generated>([&](const wde_construct_tx_after_asset_ownership_proof_generated& o)
|
||||||
{
|
{
|
||||||
crypto::signature s = currency::null_sig;
|
//crypto::signature s = currency::null_sig;
|
||||||
o.pado->opt_proof = s;
|
o.pownership_proof->gss = crypto::generic_schnorr_sig_s{};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -270,7 +192,7 @@ bool multiassets_basic_test::c1(currency::core& c, size_t ev_index, const std::v
|
||||||
c.get_tx_pool().purge_transactions();
|
c.get_tx_pool().purge_transactions();
|
||||||
miner_wlt->refresh();
|
miner_wlt->refresh();
|
||||||
|
|
||||||
miner_wlt->get_debug_events_dispatcher().UNSUBSCRIBE_DEBUG_EVENT<wde_construct_tx_handle_asset_descriptor_operation>();
|
miner_wlt->get_debug_events_dispatcher().UNSUBSCRIBE_ALL();
|
||||||
|
|
||||||
CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Unexpected number of txs in the pool: " << c.get_pool_transactions_count());
|
CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Unexpected number of txs in the pool: " << c.get_pool_transactions_count());
|
||||||
|
|
||||||
|
|
@ -317,17 +239,17 @@ bool multiassets_basic_test::c1(currency::core& c, size_t ev_index, const std::v
|
||||||
|
|
||||||
|
|
||||||
// check update_asset() with modified 'owner'
|
// check update_asset() with modified 'owner'
|
||||||
r = c.get_blockchain_storage().get_asset_info(asset_id, asset_info);
|
//r = c.get_blockchain_storage().get_asset_info(asset_id, asset_info);
|
||||||
CHECK_AND_ASSERT_MES(r, false, "Failed to get_asset_info");
|
//CHECK_AND_ASSERT_MES(r, false, "Failed to get_asset_info");
|
||||||
|
|
||||||
asset_info.owner = currency::keypair::generate().pub;
|
//asset_info.owner = currency::keypair::generate().pub;
|
||||||
miner_wlt->update_asset(asset_id, asset_info, tx);
|
//miner_wlt->update_asset(asset_id, asset_info, tx);
|
||||||
CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "Unexpected number of txs in the pool: " << c.get_pool_transactions_count());
|
//CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "Unexpected number of txs in the pool: " << c.get_pool_transactions_count());
|
||||||
r = mine_next_pow_block_in_playtime(miner_wlt->get_account().get_public_address(), c);
|
//r = mine_next_pow_block_in_playtime(miner_wlt->get_account().get_public_address(), c);
|
||||||
CHECK_AND_ASSERT_MES(!r, false, "block with a bad tx was unexpectedly mined");
|
//CHECK_AND_ASSERT_MES(!r, false, "block with a bad tx was unexpectedly mined");
|
||||||
CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "Unexpected number of txs in the pool: " << c.get_pool_transactions_count()); // make sure tx was not confirmed
|
//CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "Unexpected number of txs in the pool: " << c.get_pool_transactions_count()); // make sure tx was not confirmed
|
||||||
c.get_tx_pool().purge_transactions();
|
//c.get_tx_pool().purge_transactions();
|
||||||
miner_wlt->refresh();
|
//miner_wlt->refresh();
|
||||||
|
|
||||||
|
|
||||||
// check emmit_asset() with modified 'current_supply'
|
// check emmit_asset() with modified 'current_supply'
|
||||||
|
|
@ -346,13 +268,14 @@ bool multiassets_basic_test::c1(currency::core& c, size_t ev_index, const std::v
|
||||||
|
|
||||||
//------------------- tests that trying to break stuff -------------------
|
//------------------- tests that trying to break stuff -------------------
|
||||||
//test burn that burns more than tx has
|
//test burn that burns more than tx has
|
||||||
miner_wlt->get_debug_events_dispatcher().UNSUBSCRIBE_DEBUG_EVENT<wde_construct_tx_handle_asset_descriptor_operation_before_seal>();
|
miner_wlt->get_debug_events_dispatcher().UNSUBSCRIBE_ALL();
|
||||||
|
|
||||||
miner_wlt->get_debug_events_dispatcher().SUBSCIRBE_DEBUG_EVENT<wde_construct_tx_handle_asset_descriptor_operation_before_seal>([&](const wde_construct_tx_handle_asset_descriptor_operation_before_seal& o)
|
miner_wlt->get_debug_events_dispatcher().SUBSCIRBE_DEBUG_EVENT<wde_construct_tx_handle_asset_descriptor_operation_before_burn>([&](const wde_construct_tx_handle_asset_descriptor_operation_before_burn& o)
|
||||||
{
|
{
|
||||||
o.pado->descriptor.current_supply -= 1000000;
|
o.pado->descriptor.current_supply -= 1000000;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
miner_wlt->burn_asset(asset_id, 10000000000000, tx);
|
miner_wlt->burn_asset(asset_id, 10000000000000, tx);
|
||||||
CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "Unexpected number of txs in the pool: " << c.get_pool_transactions_count());
|
CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "Unexpected number of txs in the pool: " << c.get_pool_transactions_count());
|
||||||
r = mine_next_pow_block_in_playtime(miner_wlt->get_account().get_public_address(), c);
|
r = mine_next_pow_block_in_playtime(miner_wlt->get_account().get_public_address(), c);
|
||||||
|
|
@ -360,8 +283,39 @@ bool multiassets_basic_test::c1(currency::core& c, size_t ev_index, const std::v
|
||||||
CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "Unexpected number of txs in the pool: " << c.get_pool_transactions_count()); // make sure tx was not confirmed
|
CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "Unexpected number of txs in the pool: " << c.get_pool_transactions_count()); // make sure tx was not confirmed
|
||||||
c.get_tx_pool().purge_transactions();
|
c.get_tx_pool().purge_transactions();
|
||||||
miner_wlt->refresh();
|
miner_wlt->refresh();
|
||||||
|
miner_wlt->get_debug_events_dispatcher().UNSUBSCRIBE_ALL();
|
||||||
|
|
||||||
//
|
//
|
||||||
|
miner_wlt->transfer_asset_ownership(asset_id, alice_wlt->get_account().get_public_address().spend_public_key, tx);
|
||||||
|
CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "Unexpected number of txs in the pool: " << c.get_pool_transactions_count());
|
||||||
|
r = mine_next_pow_block_in_playtime(miner_wlt->get_account().get_public_address(), c);
|
||||||
|
CHECK_AND_ASSERT_MES(r, false, "block with a bad tx was unexpectedly mined");
|
||||||
|
CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Unexpected number of txs in the pool: " << c.get_pool_transactions_count()); // make sure tx was not confirmed
|
||||||
|
|
||||||
|
miner_wlt->refresh();
|
||||||
|
alice_wlt->refresh();
|
||||||
|
|
||||||
|
auto miner_own_assets = miner_wlt->get_own_assets();
|
||||||
|
auto alice_own_assets = alice_wlt->get_own_assets();
|
||||||
|
CHECK_AND_ASSERT_MES(miner_own_assets.size() == 0, false, "Miner wlt still think he own asset");
|
||||||
|
CHECK_AND_ASSERT_MES(alice_own_assets.size() == 1, false, "Alice still don't know she own asset");
|
||||||
|
|
||||||
|
uint64_t balance_alice_native = alice_wlt->balance();
|
||||||
|
uint64_t balance_miner_native = miner_wlt->balance();
|
||||||
|
uint64_t balance_alice_asset = alice_wlt->balance(asset_id);
|
||||||
|
uint64_t balance_miner_asset = miner_wlt->balance(asset_id);
|
||||||
|
|
||||||
|
alice_wlt->emmit_asset(asset_id, destinations, tx);
|
||||||
|
r = mine_next_pow_blocks_in_playtime(miner_wlt->get_account().get_public_address(), c, CURRENCY_MINED_MONEY_UNLOCK_WINDOW);
|
||||||
|
CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_blocks_in_playtime failed");
|
||||||
|
|
||||||
|
miner_wlt->refresh();
|
||||||
|
alice_wlt->refresh();
|
||||||
|
|
||||||
|
CHECK_AND_ASSERT_MES(miner_wlt->balance(asset_id) == balance_miner_asset + destinations[0].amount, false, "Miner balance wrong");
|
||||||
|
CHECK_AND_ASSERT_MES(alice_wlt->balance(asset_id) == balance_alice_asset + destinations[1].amount, false, "Alice balance wrong");
|
||||||
|
|
||||||
|
//TODO: attempt to emmmit from old key, attempt to emmit from more then max supply
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -432,7 +386,7 @@ bool assets_and_explicit_native_coins_in_outs::generate(std::vector<test_event_e
|
||||||
MAKE_TX(events, tx_1, alice_acc, alice_acc, m_alice_initial_balance - TESTS_DEFAULT_FEE, blk_1r);
|
MAKE_TX(events, tx_1, alice_acc, alice_acc, m_alice_initial_balance - TESTS_DEFAULT_FEE, blk_1r);
|
||||||
CHECK_AND_ASSERT_MES(tx_1.vout.size() == 2, false, "unexpected tx_1.vout.size : " << tx_1.vout.size());
|
CHECK_AND_ASSERT_MES(tx_1.vout.size() == 2, false, "unexpected tx_1.vout.size : " << tx_1.vout.size());
|
||||||
|
|
||||||
// make sure that all tx_1 outputs have explicit hative coin asset id
|
// make sure that all tx_1 outputs have explicit native coin asset id
|
||||||
for(auto& out : tx_1.vout)
|
for(auto& out : tx_1.vout)
|
||||||
{
|
{
|
||||||
CHECK_AND_ASSERT_MES(out.type() == typeid(tx_out_zarcanum), false, "invalid out type");
|
CHECK_AND_ASSERT_MES(out.type() == typeid(tx_out_zarcanum), false, "invalid out type");
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue