1
0
Fork 0
forked from lthn/blockchain

some progress on implementation locked coins pos mining

This commit is contained in:
cryptozoidberg 2019-07-22 13:04:01 +02:00
parent d4233ff013
commit 50d55a5eec
No known key found for this signature in database
GPG key ID: 22DEB97A54C6FDEC
7 changed files with 84 additions and 54 deletions

View file

@ -2215,7 +2215,7 @@ bool blockchain_storage::add_out_to_get_random_outs(COMMAND_RPC_GET_RANDOM_OUTPU
return false;
//check if transaction is unlocked
if (!is_tx_spendtime_unlocked(get_tx_unlock_time(tx)))
if (!is_tx_spendtime_unlocked(get_tx_unlock_time(tx, out_ptr->out_no)))
return false;
//use appropriate mix_attr out
@ -3833,12 +3833,12 @@ bool blockchain_storage::get_output_keys_for_input_with_checks(const txin_to_key
outputs_visitor(std::vector<crypto::public_key>& results_collector,
const blockchain_storage& bch) :m_results_collector(results_collector), m_bch(bch)
{}
bool handle_output(const transaction& tx, const tx_out& out)
bool handle_output(const transaction& tx, const tx_out& out, uint64_t out_i)
{
//check tx unlock time
if (!m_bch.is_tx_spendtime_unlocked(get_tx_unlock_time(tx)))
if (!m_bch.is_tx_spendtime_unlocked(get_tx_unlock_time(tx, out_i)))
{
LOG_PRINT_L0("One of outputs for one of inputs have wrong tx.unlock_time = " << get_tx_unlock_time(tx));
LOG_PRINT_L0("One of outputs for one of inputs have wrong tx.unlock_time = " << get_tx_unlock_time(tx, out_i));
return false;
}
@ -3927,7 +3927,7 @@ bool blockchain_storage::check_ms_input(const transaction& tx, size_t in_index,
#define LOC_CHK(cond, msg) CHECK_AND_ASSERT_MES(cond, false, "ms input check failed: ms_id: " << txin.multisig_out_id << ", input #" << in_index << " in tx " << tx_prefix_hash << ", refers to ms output #" << out_n << " in source tx " << get_transaction_hash(source_tx) << ENDL << msg)
CRITICAL_REGION_LOCAL(m_read_lock);
uint64_t unlock_time = get_tx_unlock_time(source_tx);
uint64_t unlock_time = get_tx_unlock_time(source_tx, out_n);
LOC_CHK(is_tx_spendtime_unlocked(unlock_time), "Source transaction is LOCKED! unlock_time: " << unlock_time << ", now is " << m_core_runtime_config.get_core_time() << ", blockchain size is " << get_current_blockchain_size());
LOC_CHK(source_tx.vout.size() > out_n, "internal error: out_n==" << out_n << " is out-of-bounds of source_tx.vout, size=" << source_tx.vout.size());

View file

@ -707,7 +707,7 @@ namespace currency
CHECK_AND_ASSERT_MES(mixattr_ok, false, "tx output #" << output_index << " violates mixin restrictions: mix_attr = " << static_cast<uint32_t>(outtk.mix_attr) << ", key_offsets.size = " << tx_in_to_key.key_offsets.size());
TIME_MEASURE_START_PD(tx_check_inputs_loop_scan_outputkeys_loop_handle_output);
if (!vis.handle_output(tx_ptr->tx, tx_ptr->tx.vout[n]))
if (!vis.handle_output(tx_ptr->tx, tx_ptr->tx.vout[n], output_index))
{
LOG_PRINT_L0("Failed to handle_output for output id = " << tx_id << ", no " << n);
return false;

View file

@ -336,7 +336,7 @@ namespace currency
};
//number of block (or time), used as a limitation: spend this tx not early then block/time
//number of block (or timestamp if v bigger then CURRENCY_MAX_BLOCK_NUMBER), used as a limitation: spend this tx not early then block/time
struct etc_tx_details_unlock_time
{
uint64_t v;
@ -345,6 +345,16 @@ namespace currency
END_SERIALIZE()
};
//number of block (or timestamp if unlock_time_array[i] bigger then CURRENCY_MAX_BLOCK_NUMBER), used as a limitation: spend this tx not early then block/time
//unlock_time_array[i], i - index of output, unlock_time_array.size() == vout.size()
struct etc_tx_details_unlock_time2
{
std::vector<uint64_t> unlock_time_array;
BEGIN_SERIALIZE()
VARINT_FIELD(unlock_time_array)
END_SERIALIZE()
};
struct etc_tx_details_expiration_time
{
uint64_t v;
@ -380,7 +390,7 @@ namespace currency
END_SERIALIZE()
};
typedef boost::mpl::vector<tx_service_attachment, tx_comment, tx_payer, tx_receiver, tx_message, std::string, tx_crypto_checksum, etc_tx_time, etc_tx_details_unlock_time, etc_tx_details_expiration_time, etc_tx_details_flags, crypto::public_key, extra_attachment_info, extra_alias_entry, extra_user_data, extra_padding, etc_tx_derivation_hint> all_payload_types;
typedef boost::mpl::vector<tx_service_attachment, tx_comment, tx_payer, tx_receiver, tx_message, std::string, tx_crypto_checksum, etc_tx_time, etc_tx_details_unlock_time, etc_tx_details_unlock_time2, etc_tx_details_expiration_time, etc_tx_details_flags, crypto::public_key, extra_attachment_info, extra_alias_entry, extra_user_data, extra_padding, etc_tx_derivation_hint> all_payload_types;
typedef boost::make_variant_over<all_payload_types>::type attachment_v;
typedef boost::make_variant_over<all_payload_types>::type extra_v;
typedef boost::make_variant_over<all_payload_types>::type payload_items_v;
@ -613,5 +623,6 @@ SET_VARIANT_TAGS(uint64_t, 26, "uint64_t");
SET_VARIANT_TAGS(currency::etc_tx_time, 27, "etc_tx_time");
SET_VARIANT_TAGS(uint32_t, 28, "uint32_t");
SET_VARIANT_TAGS(currency::tx_receiver, 29, "payer");
SET_VARIANT_TAGS(currency::etc_tx_details_unlock_time2, 30, "unlock_time2");
#undef SET_VARIANT_TAGS

View file

@ -891,16 +891,7 @@ namespace currency
}
return n;
}
//---------------------------------------------------------------
account_public_address get_crypt_address_from_destinations(const account_keys& sender_account_keys, const std::vector<tx_destination_entry>& destinations)
{
for (const auto& de : destinations)
{
if (de.addr.size() == 1 && sender_account_keys.m_account_address != de.addr.back())
return de.addr.back(); // return the first destination address that is non-multisig and not equal to the sender's address
}
return sender_account_keys.m_account_address; // otherwise, fallback to sender's address
}
//---------------------------------------------------------------
bool construct_tx(const account_keys& sender_account_keys,
const std::vector<tx_source_entry>& sources,
@ -2524,16 +2515,6 @@ namespace currency
{
return epee::string_tools::parse_hexstr_to_binbuff(payment_id_str, payment_id);
}
//------------------------------------------------------------------
bool is_tx_expired(const transaction& tx, uint64_t expiration_ts_median)
{
/// tx expiration condition (tx is ok if the following is true)
/// tx_expiration_time - TX_EXPIRATION_MEDIAN_SHIFT > get_last_n_blocks_timestamps_median(TX_EXPIRATION_TIMESTAMP_CHECK_WINDOW)
uint64_t expiration_time = get_tx_expiration_time(tx);
if (expiration_time == 0)
return false; // 0 means it never expires
return expiration_time <= expiration_ts_median + TX_EXPIRATION_MEDIAN_SHIFT;
}
//--------------------------------------------------------------------------------
crypto::hash prepare_prefix_hash_for_sign(const transaction& tx, uint64_t in_index, const crypto::hash& tx_id)
{

View file

@ -208,32 +208,6 @@ namespace currency
//---------------------------------------------------------------
template<class extra_type_t>
uint64_t get_tx_x_detail(const transaction& tx)
{
extra_type_t e = AUTO_VAL_INIT(e);
get_type_in_variant_container(tx.extra, e);
return e.v;
}
template<class extra_type_t>
void set_tx_x_detail(transaction& tx, uint64_t v)
{
extra_type_t e = AUTO_VAL_INIT(e);
e.v = v;
update_or_add_field_to_extra(tx.extra, e);
}
inline uint64_t get_tx_unlock_time(const transaction& tx){ return get_tx_x_detail<etc_tx_details_unlock_time>(tx);}
inline uint64_t get_tx_flags(const transaction& tx){ return get_tx_x_detail<etc_tx_details_flags>(tx); }
inline uint64_t get_tx_expiration_time(const transaction& tx){ return get_tx_x_detail<etc_tx_details_expiration_time>(tx); }
inline void set_tx_unlock_time(transaction& tx, uint64_t v){ set_tx_x_detail<etc_tx_details_unlock_time>(tx, v); }
inline void set_tx_flags(transaction& tx, uint64_t v){ set_tx_x_detail<etc_tx_details_flags>(tx, v); }
inline void set_tx_expiration_time(transaction& tx, uint64_t v){ set_tx_x_detail<etc_tx_details_expiration_time>(tx, v); }
account_public_address get_crypt_address_from_destinations(const account_keys& sender_account_keys, const std::vector<tx_destination_entry>& destinations);
bool is_tx_expired(const transaction& tx, uint64_t expiration_ts_median);
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, uint8_t tx_outs_attr = CURRENCY_TO_KEY_OUT_RELAXED);
bool validate_alias_name(const std::string& al);

View file

@ -11,6 +11,44 @@
namespace currency
{
//---------------------------------------------------------------
account_public_address get_crypt_address_from_destinations(const account_keys& sender_account_keys, const std::vector<tx_destination_entry>& destinations)
{
for (const auto& de : destinations)
{
if (de.addr.size() == 1 && sender_account_keys.m_account_address != de.addr.back())
return de.addr.back(); // return the first destination address that is non-multisig and not equal to the sender's address
}
return sender_account_keys.m_account_address; // otherwise, fallback to sender's address
}
//------------------------------------------------------------------
bool is_tx_expired(const transaction& tx, uint64_t expiration_ts_median)
{
/// tx expiration condition (tx is ok if the following is true)
/// tx_expiration_time - TX_EXPIRATION_MEDIAN_SHIFT > get_last_n_blocks_timestamps_median(TX_EXPIRATION_TIMESTAMP_CHECK_WINDOW)
uint64_t expiration_time = get_tx_expiration_time(tx);
if (expiration_time == 0)
return false; // 0 means it never expires
return expiration_time <= expiration_ts_median + TX_EXPIRATION_MEDIAN_SHIFT;
}
//---------------------------------------------------------------
inline uint64_t get_tx_unlock_time(const transaction& tx, uint64_t o_i)
{
// etc_tx_details_expiration_time have priority over etc_tx_details_expiration_time2
uint64_t v = get_tx_x_detail<etc_tx_details_unlock_time>(tx);
if (v)
return v;
etc_tx_details_unlock_time2 ut2 = AUTO_VAL_INIT(ut2);
get_type_in_variant_container(tx.extra, ut2);
if (!ut2.unlock_time_array.size())
return 0;
CHECK_AND_ASSERT_THROW_MES(ut2.unlock_time_array.size() > o_i, "unlock_time_array.size=" << ut2.unlock_time_array.size()
<< " is less then o_i=" << o_i << " in tx: " << get_transaction_hash(tx));
return ut2.unlock_time_array[o_i];
}
//---------------------------------------------------------------
void get_transaction_prefix_hash(const transaction_prefix& tx, crypto::hash& h)
{

View file

@ -13,6 +13,32 @@
namespace currency
{
template<class extra_type_t>
uint64_t get_tx_x_detail(const transaction& tx)
{
extra_type_t e = AUTO_VAL_INIT(e);
get_type_in_variant_container(tx.extra, e);
return e.v;
}
template<class extra_type_t>
void set_tx_x_detail(transaction& tx, uint64_t v)
{
extra_type_t e = AUTO_VAL_INIT(e);
e.v = v;
update_or_add_field_to_extra(tx.extra, e);
}
inline uint64_t get_tx_unlock_time(const transaction& tx, uint64_t o_i);
inline uint64_t get_tx_flags(const transaction& tx) { return get_tx_x_detail<etc_tx_details_flags>(tx); }
inline uint64_t get_tx_expiration_time(const transaction& tx) return get_tx_x_detail<etc_tx_details_expiration_time>(tx); }
inline void set_tx_unlock_time(transaction& tx, uint64_t v) { set_tx_x_detail<etc_tx_details_unlock_time>(tx, v); }
inline void set_tx_flags(transaction& tx, uint64_t v) { set_tx_x_detail<etc_tx_details_flags>(tx, v); }
inline void set_tx_expiration_time(transaction& tx, uint64_t v) { set_tx_x_detail<etc_tx_details_expiration_time>(tx, v); }
account_public_address get_crypt_address_from_destinations(const account_keys& sender_account_keys, const std::vector<tx_destination_entry>& destinations);
bool is_tx_expired(const transaction& tx, uint64_t expiration_ts_median);
void get_transaction_prefix_hash(const transaction_prefix& tx, crypto::hash& h);
crypto::hash get_transaction_prefix_hash(const transaction_prefix& tx);
bool parse_and_validate_tx_from_blob(const blobdata& tx_blob, transaction& tx, crypto::hash& tx_hash);