Browse Source

Make sure transactions have non-empty outputs

pull/4/head
Eirik Ogilvie-Wigley 6 years ago
parent
commit
4b4662b06d
  1. 8
      src/main.cpp
  2. 13
      src/test/transaction_tests.cpp

8
src/main.cpp

@ -1039,12 +1039,14 @@ bool CheckTransactionWithoutProofVerification(const CTransaction& tx, CValidatio
}
}
// Transactions can contain empty `vin` and `vout` so long as
// either `vjoinsplit` or `vShieldedSpend` are non-empty.
// Transactions containing empty `vin` must have either non-empty
// `vjoinsplit` or non-empty `vShieldedSpend`.
if (tx.vin.empty() && tx.vjoinsplit.empty() && tx.vShieldedSpend.empty())
return state.DoS(10, error("CheckTransaction(): vin empty"),
REJECT_INVALID, "bad-txns-vin-empty");
if (tx.vout.empty() && tx.vjoinsplit.empty() && tx.vShieldedSpend.empty())
// Transactions containing empty `vout` must have either non-empty
// `vjoinsplit` or non-empty `vShieldedOutput`.
if (tx.vout.empty() && tx.vjoinsplit.empty() && tx.vShieldedOutput.empty())
return state.DoS(10, error("CheckTransaction(): vout empty"),
REJECT_INVALID, "bad-txns-vout-empty");

13
src/test/transaction_tests.cpp

@ -408,6 +408,16 @@ void test_simple_sapling_invalidity(uint32_t consensusBranchId, CMutableTransact
BOOST_CHECK(!CheckTransactionWithoutProofVerification(newTx, state));
BOOST_CHECK(state.GetRejectReason() == "bad-txns-vin-empty");
}
{
CMutableTransaction newTx(tx);
CValidationState state;
newTx.vShieldedSpend.push_back(SpendDescription());
newTx.vShieldedSpend[0].nullifier = GetRandHash();
BOOST_CHECK(!CheckTransactionWithoutProofVerification(newTx, state));
BOOST_CHECK(state.GetRejectReason() == "bad-txns-vout-empty");
}
{
// Ensure that nullifiers are never duplicated within a transaction.
CMutableTransaction newTx(tx);
@ -415,6 +425,9 @@ void test_simple_sapling_invalidity(uint32_t consensusBranchId, CMutableTransact
newTx.vShieldedSpend.push_back(SpendDescription());
newTx.vShieldedSpend[0].nullifier = GetRandHash();
newTx.vShieldedOutput.push_back(OutputDescription());
newTx.vShieldedSpend.push_back(SpendDescription());
newTx.vShieldedSpend[1].nullifier = newTx.vShieldedSpend[0].nullifier;

Loading…
Cancel
Save