mirror of
https://github.com/wownero/wownero.git
synced 2026-10-24 02:48:34 +02:00
cryptonote_basic: sanity check on key offsets
Nice early check on allowed n key offsets per tx based on the guaranteed ceiling for the entire chain.
This commit is contained in:
@@ -99,6 +99,27 @@ namespace cryptonote
|
|||||||
const uint64_t bp_clawback = (bp_base * n_padded_outputs - bp_size) * 4 / 5;
|
const uint64_t bp_clawback = (bp_base * n_padded_outputs - bp_size) * 4 / 5;
|
||||||
return bp_clawback;
|
return bp_clawback;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::size_t max_total_key_offsets()
|
||||||
|
{
|
||||||
|
// This is a 100% guaranteed ceiling for the entire chain
|
||||||
|
return get_max_tx_size() / sizeof(crypto::public_key);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool n_key_offsets_exceeds_max(const transaction_prefix& tx)
|
||||||
|
{
|
||||||
|
const std::size_t max_allowed = max_total_key_offsets();
|
||||||
|
std::size_t total_key_offsets = 0;
|
||||||
|
for (const auto &vin : tx.vin)
|
||||||
|
{
|
||||||
|
if (vin.type() != typeid(cryptonote::txin_to_key))
|
||||||
|
continue;
|
||||||
|
const std::size_t n_key_offsets = boost::get<cryptonote::txin_to_key>(vin).key_offsets.size();
|
||||||
|
CHECK_AND_ASSERT_MES((n_key_offsets + total_key_offsets) >= total_key_offsets, true, "key offsets overflow");
|
||||||
|
total_key_offsets += n_key_offsets;
|
||||||
|
}
|
||||||
|
return total_key_offsets >= max_allowed;
|
||||||
|
}
|
||||||
//---------------------------------------------------------------
|
//---------------------------------------------------------------
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -203,6 +224,7 @@ namespace cryptonote
|
|||||||
binary_archive<false> ba{epee::strspan<std::uint8_t>(tx_blob)};
|
binary_archive<false> ba{epee::strspan<std::uint8_t>(tx_blob)};
|
||||||
bool r = ::serialization::serialize(ba, tx);
|
bool r = ::serialization::serialize(ba, tx);
|
||||||
CHECK_AND_ASSERT_MES(r, false, "Failed to parse transaction from blob");
|
CHECK_AND_ASSERT_MES(r, false, "Failed to parse transaction from blob");
|
||||||
|
CHECK_AND_ASSERT_MES(!n_key_offsets_exceeds_max(tx), false, "Transaction contains too many ring members");
|
||||||
CHECK_AND_ASSERT_MES(expand_transaction_1(tx, false), false, "Failed to expand transaction data");
|
CHECK_AND_ASSERT_MES(expand_transaction_1(tx, false), false, "Failed to expand transaction data");
|
||||||
tx.invalidate_hashes();
|
tx.invalidate_hashes();
|
||||||
tx.set_blob_size(tx_blob.size());
|
tx.set_blob_size(tx_blob.size());
|
||||||
@@ -214,6 +236,7 @@ namespace cryptonote
|
|||||||
binary_archive<false> ba{epee::strspan<std::uint8_t>(tx_blob)};
|
binary_archive<false> ba{epee::strspan<std::uint8_t>(tx_blob)};
|
||||||
bool r = tx.serialize_base(ba);
|
bool r = tx.serialize_base(ba);
|
||||||
CHECK_AND_ASSERT_MES(r, false, "Failed to parse transaction from blob");
|
CHECK_AND_ASSERT_MES(r, false, "Failed to parse transaction from blob");
|
||||||
|
CHECK_AND_ASSERT_MES(!n_key_offsets_exceeds_max(tx), false, "Transaction contains too many ring members");
|
||||||
CHECK_AND_ASSERT_MES(expand_transaction_1(tx, true), false, "Failed to expand transaction data");
|
CHECK_AND_ASSERT_MES(expand_transaction_1(tx, true), false, "Failed to expand transaction data");
|
||||||
tx.invalidate_hashes();
|
tx.invalidate_hashes();
|
||||||
return true;
|
return true;
|
||||||
@@ -224,6 +247,7 @@ namespace cryptonote
|
|||||||
binary_archive<false> ba{epee::strspan<std::uint8_t>(tx_blob)};
|
binary_archive<false> ba{epee::strspan<std::uint8_t>(tx_blob)};
|
||||||
bool r = ::serialization::serialize_noeof(ba, tx);
|
bool r = ::serialization::serialize_noeof(ba, tx);
|
||||||
CHECK_AND_ASSERT_MES(r, false, "Failed to parse transaction prefix from blob");
|
CHECK_AND_ASSERT_MES(r, false, "Failed to parse transaction prefix from blob");
|
||||||
|
CHECK_AND_ASSERT_MES(!n_key_offsets_exceeds_max(tx), false, "Transaction contains too many ring members");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
//---------------------------------------------------------------
|
//---------------------------------------------------------------
|
||||||
@@ -232,6 +256,7 @@ namespace cryptonote
|
|||||||
binary_archive<false> ba{epee::strspan<std::uint8_t>(tx_blob)};
|
binary_archive<false> ba{epee::strspan<std::uint8_t>(tx_blob)};
|
||||||
bool r = ::serialization::serialize(ba, tx);
|
bool r = ::serialization::serialize(ba, tx);
|
||||||
CHECK_AND_ASSERT_MES(r, false, "Failed to parse transaction from blob");
|
CHECK_AND_ASSERT_MES(r, false, "Failed to parse transaction from blob");
|
||||||
|
CHECK_AND_ASSERT_MES(!n_key_offsets_exceeds_max(tx), false, "Transaction contains too many ring members");
|
||||||
CHECK_AND_ASSERT_MES(expand_transaction_1(tx, false), false, "Failed to expand transaction data");
|
CHECK_AND_ASSERT_MES(expand_transaction_1(tx, false), false, "Failed to expand transaction data");
|
||||||
tx.invalidate_hashes();
|
tx.invalidate_hashes();
|
||||||
tx.set_blob_size(tx_blob.size());
|
tx.set_blob_size(tx_blob.size());
|
||||||
|
|||||||
Reference in New Issue
Block a user