forked from lthn/blockchain
explicit tx fee for zarcanum txs: get_tx_fee, add_tx_fee_amount_to_extra, process_type_in_variant_container
This commit is contained in:
parent
458f347e1e
commit
636fb820ea
3 changed files with 61 additions and 9 deletions
|
|
@ -418,18 +418,34 @@ namespace currency
|
|||
fee = 0;
|
||||
if (is_coinbase(tx))
|
||||
return true;
|
||||
uint64_t amount_in = 0;
|
||||
uint64_t amount_out = get_outs_money_amount(tx);
|
||||
|
||||
BOOST_FOREACH(auto& in, tx.vin)
|
||||
|
||||
if (tx.version <= TRANSACTION_VERSION_PRE_HF4)
|
||||
{
|
||||
amount_in += get_amount_from_variant(in);
|
||||
// all amounts are open: fee = sum(outputs) - sum(inputs)
|
||||
|
||||
uint64_t amount_in = 0;
|
||||
uint64_t amount_out = get_outs_money_amount(tx);
|
||||
|
||||
for(auto& in : tx.vin)
|
||||
amount_in += get_amount_from_variant(in);
|
||||
|
||||
CHECK_AND_ASSERT_MES(amount_in >= amount_out, false, "transaction spends (" << print_money_brief(amount_in) << ") more than it has (" << print_money_brief(amount_out) << ")");
|
||||
fee = amount_in - amount_out;
|
||||
return true;
|
||||
}
|
||||
|
||||
// tx.version > TRANSACTION_VERSION_PRE_HF4
|
||||
// all amounts are hidden with Pedersen commitments
|
||||
// therefore fee should be explicitly stated in the extra
|
||||
if (!process_type_in_variant_container<zarcanum_tx_data_v1>(tx.extra, [&](const zarcanum_tx_data_v1& ztd) -> bool {
|
||||
fee += ztd.fee;
|
||||
return true; // continue
|
||||
}, false))
|
||||
{
|
||||
fee = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
CHECK_AND_ASSERT_MES(amount_in >= amount_out, false, "transaction spend (" << amount_in << ") more than it has (" << amount_out << ")");
|
||||
fee = amount_in - amount_out;
|
||||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
|
|
@ -555,6 +571,22 @@ namespace currency
|
|||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
// puts explicit fee amount to tx extra, should be used only for tx.verson > TRANSACTION_VERSION_PRE_HF4
|
||||
bool add_tx_fee_amount_to_extra(transaction& tx, uint64_t fee, bool make_sure_its_unique /* = true */)
|
||||
{
|
||||
if (make_sure_its_unique)
|
||||
{
|
||||
if (count_type_in_variant_container<zarcanum_tx_data_v1>(tx.extra) != 0)
|
||||
return false;
|
||||
}
|
||||
|
||||
zarcanum_tx_data_v1 ztd = AUTO_VAL_INIT(ztd);
|
||||
ztd.fee = fee;
|
||||
|
||||
tx.extra.push_back(ztd);
|
||||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
//---------------------------------------------------------------
|
||||
|
||||
struct multisig_id_generator
|
||||
|
|
|
|||
|
|
@ -305,6 +305,7 @@ namespace currency
|
|||
bool parse_and_validate_tx_extra(const transaction& tx, crypto::public_key& tx_pub_key);
|
||||
crypto::public_key get_tx_pub_key_from_extra(const transaction& tx);
|
||||
bool add_tx_pub_key_to_extra(transaction& tx, const crypto::public_key& tx_pub_key);
|
||||
bool add_tx_fee_amount_to_extra(transaction& tx, uint64_t fee, bool make_sure_its_unique = true);
|
||||
bool add_tx_extra_userdata(transaction& tx, const blobdata& extra_nonce);
|
||||
|
||||
crypto::hash get_multisig_out_id(const transaction& tx, size_t n);
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ namespace currency
|
|||
}
|
||||
//---------------------------------------------------------------
|
||||
template<typename specific_type_t, typename variant_t_container>
|
||||
bool get_type_in_variant_container(const variant_t_container& av, specific_type_t& a)
|
||||
bool get_type_in_variant_container(variant_t_container& av, specific_type_t& a)
|
||||
{
|
||||
for (auto& ai : av)
|
||||
{
|
||||
|
|
@ -107,6 +107,25 @@ namespace currency
|
|||
return false;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
// if cb returns true, it means "continue", false -- means "stop"
|
||||
template<typename specific_type_t, typename variant_container_t, typename callback_t>
|
||||
bool process_type_in_variant_container(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))
|
||||
{
|
||||
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)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue