forked from lthn/blockchain
some progress on implementation locked coins pos mining
This commit is contained in:
parent
d4233ff013
commit
50d55a5eec
7 changed files with 84 additions and 54 deletions
|
|
@ -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());
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue