|
|
@ -124,6 +124,40 @@ namespace cryptonote
|
|
|
|
return h;
|
|
|
|
return h;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//---------------------------------------------------------------
|
|
|
|
//---------------------------------------------------------------
|
|
|
|
|
|
|
|
bool expand_transaction_1(transaction &tx, bool base_only)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (tx.version >= 2 && !is_coinbase(tx))
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
rct::rctSig &rv = tx.rct_signatures;
|
|
|
|
|
|
|
|
if (rv.outPk.size() != tx.vout.size())
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
LOG_PRINT_L1("Failed to parse transaction from blob, bad outPk size in tx " << get_transaction_hash(tx));
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
for (size_t n = 0; n < tx.rct_signatures.outPk.size(); ++n)
|
|
|
|
|
|
|
|
rv.outPk[n].dest = rct::pk2rct(boost::get<txout_to_key>(tx.vout[n].target).key);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!base_only)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
const bool bulletproof = rv.type == rct::RCTTypeFullBulletproof || rv.type == rct::RCTTypeSimpleBulletproof;
|
|
|
|
|
|
|
|
if (bulletproof)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (rv.p.bulletproofs.size() != tx.vout.size())
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
LOG_PRINT_L1("Failed to parse transaction from blob, bad bulletproofs size in tx " << get_transaction_hash(tx));
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
for (size_t n = 0; n < rv.outPk.size(); ++n)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
rv.p.bulletproofs[n].V.resize(1);
|
|
|
|
|
|
|
|
rv.p.bulletproofs[n].V[0] = rv.outPk[n].mask;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------------
|
|
|
|
bool parse_and_validate_tx_from_blob(const blobdata& tx_blob, transaction& tx)
|
|
|
|
bool parse_and_validate_tx_from_blob(const blobdata& tx_blob, transaction& tx)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
std::stringstream ss;
|
|
|
|
std::stringstream ss;
|
|
|
@ -131,6 +165,7 @@ namespace cryptonote
|
|
|
|
binary_archive<false> ba(ss);
|
|
|
|
binary_archive<false> ba(ss);
|
|
|
|
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(expand_transaction_1(tx, false), false, "Failed to expand transaction data");
|
|
|
|
tx.invalidate_hashes();
|
|
|
|
tx.invalidate_hashes();
|
|
|
|
return true;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -142,6 +177,7 @@ namespace cryptonote
|
|
|
|
binary_archive<false> ba(ss);
|
|
|
|
binary_archive<false> ba(ss);
|
|
|
|
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(expand_transaction_1(tx, true), false, "Failed to expand transaction data");
|
|
|
|
return true;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//---------------------------------------------------------------
|
|
|
|
//---------------------------------------------------------------
|
|
|
@ -152,6 +188,7 @@ namespace cryptonote
|
|
|
|
binary_archive<false> ba(ss);
|
|
|
|
binary_archive<false> ba(ss);
|
|
|
|
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(expand_transaction_1(tx, false), false, "Failed to expand transaction data");
|
|
|
|
tx.invalidate_hashes();
|
|
|
|
tx.invalidate_hashes();
|
|
|
|
//TODO: validate tx
|
|
|
|
//TODO: validate tx
|
|
|
|
|
|
|
|
|
|
|
|