Add shielded_balances_match check

This commit is contained in:
Deirdre Connolly 2020-10-16 13:54:14 -07:00 committed by Deirdre Connolly
parent 612148fbdd
commit 1653aca570
2 changed files with 21 additions and 2 deletions

View File

@ -53,6 +53,8 @@ pub enum VerifyTransactionError {
WrongVersion,
/// A transaction MUST move money around.
NoTransfer,
/// The balance of money moving around doesn't compute.
BadBalance,
/// Could not verify a transparent script
Script(#[from] zebra_script::Error),
/// Could not verify a Groth16 proof of a JoinSplit/Spend/Output description
@ -180,6 +182,7 @@ where
}
if let Some(shielded_data) = shielded_data {
check::shielded_balances_match(&shielded_data, *value_balance)?;
for spend in shielded_data.spends() {
// TODO: check that spend.cv and spend.rk are NOT of small
// order.

View File

@ -1,7 +1,7 @@
use std::convert::TryFrom;
use std::convert::{TryFrom, TryInto};
use zebra_chain::{
amount::Amount,
amount::{self, Amount, NegativeAllowed},
primitives::{
ed25519,
redjubjub::{self, Binding},
@ -76,3 +76,19 @@ pub fn any_coinbase_inputs_no_transparent_outputs(
_ => return Err(VerifyTransactionError::WrongVersion),
}
}
/// Check that if there are no Spends or Outputs, that valueBalance is also 0.
///
/// https://zips.z.cash/protocol/canopy.pdf#consensusfrombitcoin
pub fn shielded_balances_match(
shielded_data: &ShieldedData,
value_balance: Amount,
) -> Result<(), VerifyTransactionError> {
if shielded_data.spends().count() + shielded_data.outputs().count() != 0 {
return Ok(());
} else if i64::from(value_balance) == 0 {
return Ok(());
} else {
return Err(VerifyTransactionError::BadBalance);
}
}