Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -127,4 +127,4 @@ codegen-units = 1
[patch.crates-io]
zcash_note_encryption = { version = "0.4", git = "https://github.com/QED-it/zcash_note_encryption", branch = "zsa1" }
sapling = { package = "sapling-crypto", version = "0.1.3", git = "https://github.com/QED-it/sapling-crypto", branch = "zsa1" }
orchard = { version = "0.8.0", git = "https://github.com/QED-it/orchard", rev = "190a50c31c1db7d329905bef04326445c2d87801" }
orchard = { version = "0.8.0", git = "https://github.com/QED-it/orchard", rev = "831ca109705a409bc3d3b82e76245e45dd0f0812" }
71 changes: 35 additions & 36 deletions zcash_primitives/src/transaction/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -471,7 +471,7 @@ impl<'a, P: consensus::Parameters> Builder<'a, P, ()> {
pub fn init_issuance_bundle<FE>(
&mut self,
ik: IssuanceAuthorizingKey,
asset_desc: Vec<u8>,
asset_desc_hash: [u8; 32],
issue_info: Option<IssueInfo>,
first_issuance: bool,
) -> Result<(), Error<FE>> {
Expand All @@ -484,12 +484,11 @@ impl<'a, P: consensus::Parameters> Builder<'a, P, ()> {
self.issuance_builder = Some(
IssueBundle::new(
IssuanceValidatingKey::from(&ik),
asset_desc,
asset_desc_hash,
issue_info,
first_issuance,
OsRng,
)
.map_err(Error::IssuanceBundle)?
.0,
);
self.issuance_isk = Some(ik);
Expand All @@ -501,7 +500,7 @@ impl<'a, P: consensus::Parameters> Builder<'a, P, ()> {
#[cfg(zcash_unstable = "nu6" /* TODO nu7 */ )]
pub fn add_recipient<FE>(
&mut self,
asset_desc: &[u8],
asset_desc_hash: [u8; 32],
recipient: Address,
value: orchard::value::NoteValue,
first_issuance: bool,
Expand All @@ -510,20 +509,20 @@ impl<'a, P: consensus::Parameters> Builder<'a, P, ()> {
self.issuance_builder
.as_mut()
.ok_or(Error::IssuanceBuilderNotAvailable)?
.add_recipient(asset_desc, recipient, value, first_issuance, OsRng)
.add_recipient(asset_desc_hash, recipient, value, first_issuance, OsRng)
.map_err(Error::IssuanceBundle)?;

Ok(())
}

/// Finalizes a given asset
#[cfg(zcash_unstable = "nu6" /* TODO nu7 */ )]
pub fn finalize_asset<FE>(&mut self, asset_desc: &[u8]) -> Result<(), Error<FE>> {
pub fn finalize_asset<FE>(&mut self, asset_desc_hash: &[u8; 32]) -> Result<(), Error<FE>> {
assert!(self.build_config.orchard_bundle_type()? == BundleType::DEFAULT_ZSA);
self.issuance_builder
.as_mut()
.ok_or(Error::IssuanceBuilderNotAvailable)?
.finalize_action(asset_desc)
.finalize_action(asset_desc_hash)
.map_err(Error::IssuanceBundle)?;

Ok(())
Expand Down Expand Up @@ -1161,7 +1160,7 @@ mod tests {
#[cfg(zcash_unstable = "nu6" /* TODO nu7 */ )]
use {
crate::transaction::fees::zip317::FeeError,
orchard::issuance::IssueInfo,
orchard::issuance::{compute_asset_desc_hash, IssueInfo},
orchard::keys::{
FullViewingKey, IssuanceAuthorizingKey, IssuanceValidatingKey, SpendingKey,
},
Expand Down Expand Up @@ -1467,17 +1466,17 @@ mod tests {
fn init_issuance_bundle_with_finalization() {
let (mut builder, iak, _) = prepare_zsa_test();

let asset_desc: Vec<u8> = "asset_desc".into();
let asset_desc_hash: [u8; 32] = compute_asset_desc_hash(b"asset_desc").unwrap();

builder
.init_issuance_bundle::<FeeError>(iak, asset_desc.clone(), None, false)
.init_issuance_bundle::<FeeError>(iak, asset_desc_hash, None, false)
.unwrap();

let tx = builder.mock_build_no_fee(OsRng).unwrap().into_transaction();
let bundle = tx.issue_bundle().unwrap();

assert_eq!(bundle.actions().len(), 1, "There should be only one action");
let action = bundle.get_action_by_desc(&asset_desc).unwrap();
let action = bundle.get_action_by_desc_hash(&asset_desc_hash).unwrap();
assert!(action.is_finalized(), "Action should be finalized");
assert_eq!(action.notes().len(), 0, "Action should have zero notes");
}
Expand All @@ -1487,12 +1486,12 @@ mod tests {
fn init_issuance_bundle_without_finalization() {
let (mut builder, iak, address) = prepare_zsa_test();

let asset_desc: Vec<u8> = "asset_desc".into();
let asset_desc_hash: [u8; 32] = compute_asset_desc_hash(b"asset_desc").unwrap();

builder
.init_issuance_bundle::<FeeError>(
iak,
asset_desc.clone(),
asset_desc_hash,
Some(IssueInfo {
recipient: address,
value: NoteValue::from_raw(42),
Expand All @@ -1505,7 +1504,7 @@ mod tests {
let bundle = binding.issue_bundle().unwrap();

assert_eq!(bundle.actions().len(), 1, "There should be only one action");
let action = bundle.get_action_by_desc(&asset_desc).unwrap();
let action = bundle.get_action_by_desc_hash(&asset_desc_hash).unwrap();
assert!(!action.is_finalized(), "Action should not be finalized");
assert_eq!(action.notes().len(), 1, "Action should have 1 note");
assert_eq!(
Expand All @@ -1520,12 +1519,12 @@ mod tests {
fn add_issuance_same_asset() {
let (mut builder, iak, address) = prepare_zsa_test();

let asset_desc: Vec<u8> = "asset_desc".into();
let asset_desc_hash: [u8; 32] = compute_asset_desc_hash(b"asset_desc").unwrap();

builder
.init_issuance_bundle::<FeeError>(
iak,
asset_desc.clone(),
asset_desc_hash,
Some(IssueInfo {
recipient: address,
value: NoteValue::from_raw(42),
Expand All @@ -1534,14 +1533,14 @@ mod tests {
)
.unwrap();
builder
.add_recipient::<FeeError>(&asset_desc, address, NoteValue::from_raw(21), false)
.add_recipient::<FeeError>(asset_desc_hash, address, NoteValue::from_raw(21), false)
.unwrap();

let binding = builder.mock_build_no_fee(OsRng).unwrap().into_transaction();
let bundle = binding.issue_bundle().unwrap();

assert_eq!(bundle.actions().len(), 1, "There should be only one action");
let action = bundle.get_action_by_desc(&asset_desc).unwrap();
let action = bundle.get_action_by_desc_hash(&asset_desc_hash).unwrap();
assert!(!action.is_finalized(), "Action should not be finalized");
assert_eq!(action.notes().len(), 2, "Action should have 2 notes");
assert_eq!(
Expand All @@ -1560,13 +1559,13 @@ mod tests {
fn add_issuance_different_asset() {
let (mut builder, iak, address) = prepare_zsa_test();

let asset_desc_1: Vec<u8> = "asset_desc".into();
let asset_desc_2: Vec<u8> = "asset_desc_2".into();
let asset_desc_hash_1: [u8; 32] = compute_asset_desc_hash(b"asset_desc").unwrap();
let asset_desc_hash_2: [u8; 32] = compute_asset_desc_hash(b"asset_desc_2").unwrap();

builder
.init_issuance_bundle::<FeeError>(
iak,
asset_desc_1.clone(),
asset_desc_hash_1,
Some(IssueInfo {
recipient: address,
value: NoteValue::from_raw(42),
Expand All @@ -1575,15 +1574,15 @@ mod tests {
)
.unwrap();
builder
.add_recipient::<FeeError>(&asset_desc_2, address, NoteValue::from_raw(21), false)
.add_recipient::<FeeError>(asset_desc_hash_2, address, NoteValue::from_raw(21), false)
.unwrap();

let binding = builder.mock_build_no_fee(OsRng).unwrap().into_transaction();
let bundle = binding.issue_bundle().unwrap();

assert_eq!(bundle.actions().len(), 2, "There should be 2 actions");

let action = bundle.get_action_by_desc(&asset_desc_1).unwrap();
let action = bundle.get_action_by_desc_hash(&asset_desc_hash_1).unwrap();
assert!(!action.is_finalized(), "Action should not be finalized");
assert_eq!(action.notes().len(), 1, "Action should have 1 note");
assert_eq!(
Expand All @@ -1596,7 +1595,7 @@ mod tests {
"Incorrect notes sum"
);

let action2 = bundle.get_action_by_desc(&asset_desc_2).unwrap();
let action2 = bundle.get_action_by_desc_hash(&asset_desc_hash_2).unwrap();
assert!(!action2.is_finalized(), "Action should not be finalized");
assert_eq!(action2.notes().len(), 1, "Action should have 1 note");
assert_eq!(
Expand All @@ -1615,12 +1614,12 @@ mod tests {
fn first_issuance_init_issuance_bundle() {
let (mut builder, iak, address) = prepare_zsa_test();

let asset_desc: Vec<u8> = "asset_desc".into();
let asset_desc_hash: [u8; 32] = compute_asset_desc_hash(b"asset_desc").unwrap();

builder
.init_issuance_bundle::<FeeError>(
iak,
asset_desc.clone(),
asset_desc_hash,
Some(IssueInfo {
recipient: address,
value: NoteValue::from_raw(42),
Expand All @@ -1633,7 +1632,7 @@ mod tests {
let bundle = binding.issue_bundle().unwrap();

assert_eq!(bundle.actions().len(), 1, "There should be only one action");
let action = bundle.get_action_by_desc(&asset_desc).unwrap();
let action = bundle.get_action_by_desc_hash(&asset_desc_hash).unwrap();
assert_eq!(
action.notes().len(),
2,
Expand Down Expand Up @@ -1661,21 +1660,21 @@ mod tests {
fn first_issuance_add_recipient() {
let (mut builder, iak, address) = prepare_zsa_test();

let asset_desc: Vec<u8> = "asset_desc".into();
let asset_desc_hash: [u8; 32] = compute_asset_desc_hash(b"asset_desc").unwrap();

builder
.init_issuance_bundle::<FeeError>(iak, asset_desc.clone(), None, true)
.init_issuance_bundle::<FeeError>(iak, asset_desc_hash, None, true)
.unwrap();

builder
.add_recipient::<FeeError>(&asset_desc, address, NoteValue::from_raw(42), false)
.add_recipient::<FeeError>(asset_desc_hash, address, NoteValue::from_raw(42), false)
.unwrap();

let binding = builder.mock_build_no_fee(OsRng).unwrap().into_transaction();
let bundle = binding.issue_bundle().unwrap();

assert_eq!(bundle.actions().len(), 1, "There should be only one action");
let action = bundle.get_action_by_desc(&asset_desc).unwrap();
let action = bundle.get_action_by_desc_hash(&asset_desc_hash).unwrap();
assert_eq!(
action.notes().len(),
2,
Expand Down Expand Up @@ -1703,17 +1702,17 @@ mod tests {
fn first_issuance_only_reference_note() {
let (mut builder, iak, _) = prepare_zsa_test();

let asset_desc: Vec<u8> = "asset_desc".into();
let asset_desc_hash: [u8; 32] = compute_asset_desc_hash(b"asset_desc").unwrap();

builder
.init_issuance_bundle::<FeeError>(iak, asset_desc.clone(), None, true)
.init_issuance_bundle::<FeeError>(iak, asset_desc_hash, None, true)
.unwrap();

let binding = builder.mock_build_no_fee(OsRng).unwrap().into_transaction();
let bundle = binding.issue_bundle().unwrap();

assert_eq!(bundle.actions().len(), 1, "There should be only one action");
let action = bundle.get_action_by_desc(&asset_desc).unwrap();
let action = bundle.get_action_by_desc_hash(&asset_desc_hash).unwrap();
assert_eq!(
action.notes().len(),
1,
Expand All @@ -1737,8 +1736,8 @@ mod tests {
fn fails_on_add_burn_without_input() {
let (mut builder, iak, _) = prepare_zsa_test();

let asset_desc: &[u8] = b"asset_desc";
let asset_base = AssetBase::derive(&IssuanceValidatingKey::from(&iak), asset_desc);
let asset_desc: [u8; 32] = compute_asset_desc_hash(b"asset_desc").unwrap();
let asset_base = AssetBase::derive(&IssuanceValidatingKey::from(&iak), &asset_desc);

builder.add_burn::<FeeError>(42, asset_base).unwrap();

Expand Down
12 changes: 9 additions & 3 deletions zcash_primitives/src/transaction/components/issuance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,13 @@ fn read_authorization<R: Read>(mut reader: R) -> io::Result<Signed> {
}

fn read_action<R: Read>(mut reader: R) -> io::Result<IssueAction> {
let asset_descr_bytes = Vector::read(&mut reader, |r| r.read_u8())?;
let mut asset_desc_hash = [0u8; 32];
reader.read_exact(&mut asset_desc_hash).map_err(|_| {
Error::new(
ErrorKind::InvalidData,
"Invalid Asset Description Hash in IssueAction",
)
})?;
let notes = Vector::read(&mut reader, |r| read_note(r))?;
let finalize = match reader.read_u8()? {
0 => false,
Expand All @@ -61,7 +67,7 @@ fn read_action<R: Read>(mut reader: R) -> io::Result<IssueAction> {
))
}
};
Ok(IssueAction::from_parts(asset_descr_bytes, notes, finalize))
Ok(IssueAction::from_parts(asset_desc_hash, notes, finalize))
}

pub fn read_note<R: Read>(mut reader: R) -> io::Result<Note> {
Expand Down Expand Up @@ -128,7 +134,7 @@ pub fn write_v6_bundle<W: Write>(
}

fn write_action<W: Write>(mut writer: &mut W, action: &IssueAction) -> io::Result<()> {
Vector::write(&mut writer, action.asset_desc(), |w, b| w.write_u8(*b))?;
writer.write_all(action.asset_desc_hash())?;
Vector::write(&mut writer, action.notes(), write_note)?;
writer.write_u8(action.is_finalized() as u8)?;
Ok(())
Expand Down
Loading