forked from lthn/blockchain
tx pool: asset operations basic validation on tx add
This commit is contained in:
parent
3eb711fbf8
commit
709d16eb75
4 changed files with 71 additions and 36 deletions
|
|
@ -4012,7 +4012,7 @@ bool blockchain_storage::pop_asset_info(const crypto::public_key& asset_id)
|
|||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------
|
||||
bool blockchain_storage::validate_ado_ownership(asset_op_verification_context& avc)
|
||||
bool validate_ado_ownership(asset_op_verification_context& avc)
|
||||
{
|
||||
asset_operation_ownership_proof aoop = AUTO_VAL_INIT(aoop);
|
||||
bool r = get_type_in_variant_container(avc.tx.proofs, aoop);
|
||||
|
|
@ -4024,32 +4024,23 @@ bool blockchain_storage::validate_ado_ownership(asset_op_verification_context& a
|
|||
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::validate_asset_operation_against_current_blochain_state(asset_op_verification_context& avc) const
|
||||
{
|
||||
CRITICAL_REGION_LOCAL(m_read_lock);
|
||||
|
||||
asset_op_verification_context avc = { tx, tx_id, ado };
|
||||
CHECK_AND_ASSERT_MES(get_or_calculate_asset_id(avc.ado, &avc.asset_id_pt, &avc.asset_id), false, "get_or_calculate_asset_id failed");
|
||||
avc.asset_op_history = m_db_assets.find(avc.asset_id);
|
||||
|
||||
const asset_descriptor_operation& ado = avc.ado;
|
||||
|
||||
if (ado.operation_type == ASSET_DESCRIPTOR_OPERATION_REGISTER)
|
||||
{
|
||||
CHECK_AND_ASSERT_MES(get_or_calculate_asset_id(avc.ado, &avc.asset_id_pt, &avc.asset_id), false, "get_or_calculate_asset_id failed");
|
||||
|
||||
avc.asset_op_history = m_db_assets.find(avc.asset_id);
|
||||
CHECK_AND_ASSERT_MES(!avc.asset_op_history, false, "asset with id " << avc.asset_id << " has already been registered");
|
||||
|
||||
avc.amount_to_validate = ado.descriptor.current_supply;
|
||||
CHECK_AND_ASSERT_MES(validate_asset_operation_amount_commitment(avc), false, "asset operation validation failed!");
|
||||
|
||||
assets_container::t_value_type local_asset_history = AUTO_VAL_INIT(local_asset_history);
|
||||
local_asset_history.push_back(ado);
|
||||
m_db_assets.set(avc.asset_id, local_asset_history);
|
||||
LOG_PRINT_MAGENTA("[ASSET_REGISTERED]: " << print_money_brief(ado.descriptor.current_supply, ado.descriptor.decimal_point) << ", " << avc.asset_id << ": " << ado.descriptor.ticker << ", \"" << ado.descriptor.full_name << "\"", LOG_LEVEL_1);
|
||||
CHECK_AND_ASSERT_MES(validate_asset_operation_amount_commitment(avc), false, "validate_asset_operation_amount_commitment failed!");
|
||||
}
|
||||
else
|
||||
{
|
||||
CHECK_AND_ASSERT_MES(get_or_calculate_asset_id(avc.ado, &avc.asset_id_pt, &avc.asset_id), false, "get_or_calculate_asset_id failed");
|
||||
avc.asset_op_history = m_db_assets.find(avc.asset_id);
|
||||
|
||||
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
|
||||
if (ado.operation_type == ASSET_DESCRIPTOR_OPERATION_EMIT || ado.operation_type == ASSET_DESCRIPTOR_OPERATION_UPDATE /*|| ado.operation_type == ASSET_DESCRIPTOR_OPERATION_PUBLIC_BURN*/)
|
||||
|
|
@ -4092,25 +4083,40 @@ bool blockchain_storage::put_asset_info(const transaction& tx, const crypto::has
|
|||
bool r = validate_asset_operation_amount_commitment(avc);
|
||||
CHECK_AND_ASSERT_MES(r, false, "Balance proof validation failed for asset_descriptor_operation");
|
||||
}
|
||||
}
|
||||
|
||||
assets_container::t_value_type local_asset_history = *avc.asset_op_history;
|
||||
local_asset_history.push_back(ado);
|
||||
m_db_assets.set(avc.asset_id, local_asset_history);
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------
|
||||
bool blockchain_storage::put_asset_info(const transaction& tx, const crypto::hash& tx_id, const asset_descriptor_operation& ado)
|
||||
{
|
||||
CRITICAL_REGION_LOCAL(m_read_lock);
|
||||
|
||||
switch(ado.operation_type)
|
||||
{
|
||||
case ASSET_DESCRIPTOR_OPERATION_UPDATE:
|
||||
LOG_PRINT_MAGENTA("[ASSET_UPDATED]: " << avc.asset_id << ": " << ado.descriptor.ticker << ", \"" << ado.descriptor.full_name << "\"", LOG_LEVEL_1);
|
||||
break;
|
||||
case ASSET_DESCRIPTOR_OPERATION_EMIT:
|
||||
LOG_PRINT_MAGENTA("[ASSET_EMITTED]: " << print_money_brief(avc.amount_to_validate, ado.descriptor.decimal_point) << ", " << avc.asset_id << ": " << ado.descriptor.ticker << ", \"" << ado.descriptor.full_name << "\"", LOG_LEVEL_1);
|
||||
break;
|
||||
case ASSET_DESCRIPTOR_OPERATION_PUBLIC_BURN:
|
||||
LOG_PRINT_MAGENTA("[ASSET_BURNT]: " << print_money_brief(avc.amount_to_validate, ado.descriptor.decimal_point) << ", " << avc.asset_id << ": " << ado.descriptor.ticker << ", \"" << ado.descriptor.full_name << "\"", LOG_LEVEL_1);
|
||||
break;
|
||||
default:
|
||||
LOG_ERROR("Unknown operation type: " << (int)ado.operation_type);
|
||||
}
|
||||
asset_op_verification_context avc = { tx, tx_id, ado };
|
||||
CHECK_AND_ASSERT_MES(validate_asset_operation_against_current_blochain_state(avc), false, "asset operation validation failed");
|
||||
|
||||
assets_container::t_value_type local_asset_history{};
|
||||
if (avc.asset_op_history)
|
||||
local_asset_history = *avc.asset_op_history;
|
||||
local_asset_history.push_back(ado);
|
||||
m_db_assets.set(avc.asset_id, local_asset_history);
|
||||
|
||||
switch(ado.operation_type)
|
||||
{
|
||||
case ASSET_DESCRIPTOR_OPERATION_REGISTER:
|
||||
LOG_PRINT_MAGENTA("[ASSET_REGISTERED]: " << print_money_brief(ado.descriptor.current_supply, ado.descriptor.decimal_point) << ", " << avc.asset_id << ": " << ado.descriptor.ticker << ", \"" << ado.descriptor.full_name << "\"", LOG_LEVEL_1);
|
||||
break;
|
||||
case ASSET_DESCRIPTOR_OPERATION_UPDATE:
|
||||
LOG_PRINT_MAGENTA("[ASSET_UPDATED]: " << avc.asset_id << ": " << ado.descriptor.ticker << ", \"" << ado.descriptor.full_name << "\"", LOG_LEVEL_1);
|
||||
break;
|
||||
case ASSET_DESCRIPTOR_OPERATION_EMIT:
|
||||
LOG_PRINT_MAGENTA("[ASSET_EMITTED]: " << print_money_brief(avc.amount_to_validate, ado.descriptor.decimal_point) << ", " << avc.asset_id << ": " << ado.descriptor.ticker << ", \"" << ado.descriptor.full_name << "\"", LOG_LEVEL_1);
|
||||
break;
|
||||
case ASSET_DESCRIPTOR_OPERATION_PUBLIC_BURN:
|
||||
LOG_PRINT_MAGENTA("[ASSET_BURNT]: " << print_money_brief(avc.amount_to_validate, ado.descriptor.decimal_point) << ", " << avc.asset_id << ": " << ado.descriptor.ticker << ", \"" << ado.descriptor.full_name << "\"", LOG_LEVEL_1);
|
||||
break;
|
||||
default:
|
||||
LOG_ERROR("Unknown operation type: " << (int)ado.operation_type);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -375,6 +375,8 @@ namespace currency
|
|||
bool for_altchain,
|
||||
const alt_chain_type& alt_chain = alt_chain_type(),
|
||||
uint64_t split_height = 0)const;
|
||||
bool validate_asset_operation_against_current_blochain_state(asset_op_verification_context& avc) const;
|
||||
|
||||
void set_core_runtime_config(const core_runtime_config& pc) const;
|
||||
const core_runtime_config& get_core_runtime_config()const;
|
||||
size_t get_current_sequence_factor(bool pos)const;
|
||||
|
|
@ -494,6 +496,7 @@ namespace currency
|
|||
bool print_tx_outputs_lookup(const crypto::hash& tx_id) const;
|
||||
uint64_t get_last_x_block_height(bool pos)const;
|
||||
bool is_tx_spendtime_unlocked(uint64_t unlock_time)const;
|
||||
|
||||
private:
|
||||
|
||||
//-------------- DB containers --------------
|
||||
|
|
@ -670,7 +673,6 @@ namespace currency
|
|||
bool unprocess_blockchain_tx_extra(const transaction& tx);
|
||||
bool process_blockchain_tx_attachments(const transaction& tx, uint64_t h, const crypto::hash& bl_id, uint64_t timestamp);
|
||||
bool unprocess_blockchain_tx_attachments(const transaction& tx, uint64_t h, uint64_t timestamp);
|
||||
bool validate_ado_ownership(asset_op_verification_context& avc);
|
||||
bool pop_alias_info(const extra_alias_entry& ai);
|
||||
bool put_alias_info(const transaction& tx, extra_alias_entry& ai);
|
||||
bool pop_asset_info(const crypto::public_key& asset_id);
|
||||
|
|
|
|||
|
|
@ -151,6 +151,27 @@ namespace currency
|
|||
return return_value_if_none_found;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
// if cb returns false, stop immediately and return false
|
||||
template<typename specific_type_t, typename variant_container_t, typename callback_t>
|
||||
bool process_type_in_variant_container_and_make_sure_its_unique(const variant_container_t& av, callback_t& cb, bool return_value_if_none_found = true)
|
||||
{
|
||||
bool found = false;
|
||||
for (auto& ai : av)
|
||||
{
|
||||
if (ai.type() == typeid(specific_type_t))
|
||||
{
|
||||
if (found)
|
||||
return false; // already have it, type in not unique
|
||||
found = true;
|
||||
if (!cb(boost::get<specific_type_t>(ai)))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (found)
|
||||
return true;
|
||||
return return_value_if_none_found;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
// callback should return true to continue iterating through the container
|
||||
template <typename A, typename B, typename container_t, typename callback_t>
|
||||
bool handle_2_alternative_types_in_variant_container(const container_t& container, callback_t cb)
|
||||
|
|
|
|||
|
|
@ -224,13 +224,19 @@ namespace currency
|
|||
}
|
||||
TIME_MEASURE_FINISH_PD(check_inputs_time);
|
||||
|
||||
TIME_MEASURE_START_PD(check_post_hf4_balance);
|
||||
if (tx.version > TRANSACTION_VERSION_PRE_HF4)
|
||||
{
|
||||
TIME_MEASURE_START_PD(check_post_hf4_balance);
|
||||
r = check_tx_balance(tx, id);
|
||||
CHECK_AND_ASSERT_MES_CUSTOM(r, false, { tvc.m_verification_failed = true; }, "post-HF4 tx: balance proof is invalid");
|
||||
TIME_MEASURE_FINISH_PD(check_post_hf4_balance);
|
||||
|
||||
r = process_type_in_variant_container_and_make_sure_its_unique<asset_descriptor_operation>(tx.extra, [&](const asset_descriptor_operation& ado){
|
||||
asset_op_verification_context avc = { tx, id, ado };
|
||||
return m_blockchain.validate_asset_operation_against_current_blochain_state(avc);
|
||||
}, true);
|
||||
CHECK_AND_ASSERT_MES_CUSTOM(r, false, { tvc.m_verification_failed = true; }, "post-HF4 tx: asset operation is invalid");
|
||||
}
|
||||
TIME_MEASURE_FINISH_PD(check_post_hf4_balance);
|
||||
|
||||
do_insert_transaction(tx, id, blob_size, kept_by_block, tx_fee, ch_inp_res ? max_used_block_id : null_hash, ch_inp_res ? max_used_block_height : 0);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue