Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
33a205b
Circleci project setup (#1)
PaulLaux Mar 30, 2022
71565ee
issuer keys implementation (#5)
daniben31 Jun 14, 2022
5ae5107
Added NoteType to Notes (#2)
PaulLaux Jun 14, 2022
ac71bc7
ZSA note encryption in Orchard crate (#3)
naure Jul 20, 2022
29808bd
Zsa builder (#4)
PaulLaux Sep 19, 2022
b90f88d
Issuance (#12)
PaulLaux Sep 29, 2022
afaad60
E2E tests for issuance (#20)
alexeykoren Oct 20, 2022
081b01b
disabled split notes (#22)
PaulLaux Oct 20, 2022
22377f2
Review fixes (#23)
PaulLaux Oct 26, 2022
4f9b589
Review fixes2 (#24)
PaulLaux Oct 27, 2022
4e23faf
verify_issue_bundle() cleanup (#25)
PaulLaux Oct 28, 2022
2ed26d2
WIP
alexeykoren Nov 11, 2022
dfa9a53
Fix bvk-bsk consistency test
Nov 14, 2022
e1d1dd7
E2E test draft
Nov 21, 2022
99789fd
PR preview
alexeykoren Nov 22, 2022
675c1da
Rust toolchain 1.61.0
alexeykoren Nov 23, 2022
fef34e8
Rust toolchain 1.61.0 EVERYWHERE
alexeykoren Nov 23, 2022
7b5c32d
Not allow to burn native assets
alexeykoren Nov 23, 2022
d282307
Fix burnt assets type
alexeykoren Nov 23, 2022
880ec64
PR comments part 1
alexeykoren Nov 23, 2022
bb4bbba
TODO added
alexeykoren Nov 23, 2022
cef9963
PR fixes
alexeykoren Nov 28, 2022
12e09da
BVK building code deduplication
alexeykoren Nov 28, 2022
c64af45
PR fixes 2
alexeykoren Dec 2, 2022
392478c
Generic addition for value sum
alexeykoren Dec 5, 2022
36d69c2
Merge branch 'zsa1' into zsa1-burn
alexeykoren Dec 7, 2022
e91596b
Clippy
alexeykoren Dec 7, 2022
e3deb03
Unify Rust version
alexeykoren Dec 7, 2022
26bfce5
Replace into with TryFrom trait bound
alexeykoren Dec 7, 2022
be8333c
1.61.0
alexeykoren Dec 7, 2022
927cf40
Revert "Replace into with TryFrom trait bound"
alexeykoren Dec 7, 2022
313e5b2
proptest-regressions/*.txt
alexeykoren Dec 7, 2022
fbb65a5
Minor type fix
alexeykoren Dec 7, 2022
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 .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
# Specify the execution environment. You can specify an image from Dockerhub or use one of our Convenience Images from CircleCI's Developer Hub.
# See: https://circleci.com/docs/2.0/configuration-reference/#docker-machine-macos-windows-executor
docker:
- image: cimg/rust:1.59.0
- image: cimg/rust:1.61.0
# Add steps to the job
# See: https://circleci.com/docs/2.0/configuration-reference/#steps
steps:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/bench.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions-rs/toolchain@v1
with:
toolchain: 1.61
toolchain: 1.61.0
override: true
- name: Run benchmark
run: cargo bench -- --output-format bencher | tee output.txt
Expand Down
10 changes: 5 additions & 5 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions-rs/toolchain@v1
with:
toolchain: 1.61
toolchain: 1.61.0
override: true
- name: Run tests
uses: actions-rs/cargo@v1
Expand All @@ -30,7 +30,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions-rs/toolchain@v1
with:
toolchain: 1.61
toolchain: 1.61.0
override: true
# Build benchmarks to prevent bitrot
- name: Build benchmarks
Expand All @@ -46,7 +46,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions-rs/toolchain@v1
with:
toolchain: 1.61
toolchain: 1.61.0
override: true
- name: Setup mdBook
uses: peaceiris/actions-mdbook@v1
Expand Down Expand Up @@ -90,7 +90,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions-rs/toolchain@v1
with:
toolchain: 1.61
toolchain: 1.61.0
override: true
- name: cargo fetch
uses: actions-rs/cargo@v1
Expand All @@ -113,7 +113,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions-rs/toolchain@v1
with:
toolchain: 1.61
toolchain: 1.61.0
override: true
- run: rustup component add rustfmt
- uses: actions-rs/cargo@v1
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/lints-stable.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,19 @@ on: pull_request

jobs:
clippy:
name: Clippy (1.61)
name: Clippy (1.61.0)
timeout-minutes: 30
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions-rs/toolchain@v1
with:
toolchain: 1.61
toolchain: 1.61.0
components: clippy
override: true
- name: Run Clippy
uses: actions-rs/clippy-check@v1
with:
name: Clippy (1.61)
name: Clippy (1.61.0)
token: ${{ secrets.GITHUB_TOKEN }}
args: --all-features --all-targets -- -D warnings
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,3 @@ Cargo.lock
.vscode
.idea
action-circuit-layout.png
proptest-regressions/*.txt
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ authors = [
"Kris Nuttycombe <kris@electriccoin.co>",
]
edition = "2021"
rust-version = "1.61"
rust-version = "1.61.0"
description = "The Orchard shielded transaction protocol"
license-file = "LICENSE-BOSL"
repository = "https://github.com/zcash/orchard"
Expand Down
2 changes: 1 addition & 1 deletion rust-toolchain
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.61
1.61.0
58 changes: 35 additions & 23 deletions src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,7 @@ impl ActionInfo {
pub struct Builder {
spends: Vec<SpendInfo>,
recipients: Vec<RecipientInfo>,
burn: HashMap<AssetId, ValueSum>,
flags: Flags,
anchor: Anchor,
}
Expand All @@ -261,6 +262,7 @@ impl Builder {
Builder {
spends: vec![],
recipients: vec![],
burn: HashMap::new(),
flags,
anchor,
}
Expand Down Expand Up @@ -337,6 +339,17 @@ impl Builder {
Ok(())
}

/// Add an instruction to burn a given amount of a specific asset.
pub fn add_burn(&mut self, asset: AssetId, value: NoteValue) -> Result<(), &'static str> {
if asset.is_native().into() {
return Err("Burning is only possible for non-native assets");
}
let cur = *self.burn.get(&asset).unwrap_or(&ValueSum::zero());
let sum = (cur + value).ok_or("Orchard ValueSum operation overflowed")?;
self.burn.insert(asset, sum);
Ok(())
}

/// The net value of the bundle to be built. The value of all spends,
/// minus the value of all outputs.
///
Expand Down Expand Up @@ -366,7 +379,7 @@ impl Builder {
///
/// The returned bundle will have no proof or signatures; these can be applied with
/// [`Bundle::create_proof`] and [`Bundle::apply_signatures`] respectively.
pub fn build<V: TryFrom<i64>>(
pub fn build<V: TryFrom<i64> + Copy + Into<i64>>(
self,
mut rng: impl RngCore,
) -> Result<Bundle<InProgress<Unproven, Unauthorized>, V>, Error> {
Expand Down Expand Up @@ -419,16 +432,14 @@ impl Builder {
let anchor = self.anchor;

// Determine the value balance for this bundle, ensuring it is valid.
let value_balance = pre_actions
let native_value_balance: V = pre_actions
.iter()
.filter(|action| action.spend.note.asset().is_native().into())
.fold(Some(ValueSum::zero()), |acc, action| {
acc? + action.value_sum()
})
.ok_or(OverflowError)?;

let result_value_balance: V = i64::try_from(value_balance)
.map_err(Error::ValueSum)
.and_then(|i| V::try_from(i).map_err(|_| Error::ValueSum(value::OverflowError)))?;
.ok_or(OverflowError)?
.into()?;

// Compute the transaction binding signing key.
let bsk = pre_actions
Expand All @@ -441,26 +452,26 @@ impl Builder {
let (actions, circuits): (Vec<_>, Vec<_>) =
pre_actions.into_iter().map(|a| a.build(&mut rng)).unzip();

// Verify that bsk and bvk are consistent.
let bvk = (actions.iter().map(|a| a.cv_net()).sum::<ValueCommitment>()
- ValueCommitment::derive(
value_balance,
ValueCommitTrapdoor::zero(),
AssetId::native(),
))
.into_bvk();
assert_eq!(redpallas::VerificationKey::from(&bsk), bvk);

Ok(Bundle::from_parts(
let bundle = Bundle::from_parts(
NonEmpty::from_vec(actions).unwrap(),
flags,
result_value_balance,
native_value_balance,
self.burn
.into_iter()
.map(|(asset, value)| Ok((asset, value.into()?)))
.collect::<Result<_, Error>>()?,
anchor,
InProgress {
proof: Unproven { circuits },
sigs: Unauthorized { bsk },
},
))
);

assert_eq!(
redpallas::VerificationKey::from(&bundle.authorization().sigs.bsk),
bundle.binding_validating_key()
);
Ok(bundle)
}
}

Expand Down Expand Up @@ -785,7 +796,7 @@ pub mod testing {

impl<R: RngCore + CryptoRng> ArbitraryBundleInputs<R> {
/// Create a bundle from the set of arbitrary bundle inputs.
fn into_bundle<V: TryFrom<i64>>(mut self) -> Bundle<Authorized, V> {
fn into_bundle<V: TryFrom<i64> + Copy + Into<i64>>(mut self) -> Bundle<Authorized, V> {
let fvk = FullViewingKey::from(&self.sk);
let flags = Flags::from_parts(true, true);
let mut builder = Builder::new(flags, self.anchor);
Expand Down Expand Up @@ -866,14 +877,15 @@ pub mod testing {
}

/// Produce an arbitrary valid Orchard bundle using a random spending key.
pub fn arb_bundle<V: TryFrom<i64> + Debug>() -> impl Strategy<Value = Bundle<Authorized, V>> {
pub fn arb_bundle<V: TryFrom<i64> + Debug + Copy + Into<i64>>(
) -> impl Strategy<Value = Bundle<Authorized, V>> {
arb_spending_key()
.prop_flat_map(arb_bundle_inputs)
.prop_map(|inputs| inputs.into_bundle::<V>())
}

/// Produce an arbitrary valid Orchard bundle using a specified spending key.
pub fn arb_bundle_with_key<V: TryFrom<i64> + Debug>(
pub fn arb_bundle_with_key<V: TryFrom<i64> + Debug + Copy + Into<i64>>(
k: SpendingKey,
) -> impl Strategy<Value = Bundle<Authorized, V>> {
arb_bundle_inputs(k).prop_map(|inputs| inputs.into_bundle::<V>())
Expand Down
52 changes: 45 additions & 7 deletions src/bundle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,9 @@ pub struct Bundle<T: Authorization, V> {
///
/// This is the sum of Orchard spends minus the sum of Orchard outputs.
value_balance: V,
/// Assets intended for burning
/// TODO We need to add a consensus check to make sure that it is impossible to burn ZEC.
burn: Vec<(AssetId, V)>,
/// The root of the Orchard commitment tree that this bundle commits to.
anchor: Anchor,
/// The authorization for this bundle.
Expand Down Expand Up @@ -172,13 +175,15 @@ impl<T: Authorization, V> Bundle<T, V> {
actions: NonEmpty<Action<T::SpendAuth>>,
flags: Flags,
value_balance: V,
burn: Vec<(AssetId, V)>,
anchor: Anchor,
authorization: T,
) -> Self {
Bundle {
actions,
flags,
value_balance,
burn,
anchor,
authorization,
}
Expand Down Expand Up @@ -214,15 +219,20 @@ impl<T: Authorization, V> Bundle<T, V> {
}

/// Construct a new bundle by applying a transformation that might fail
/// to the value balance.
pub fn try_map_value_balance<V0, E, F: FnOnce(V) -> Result<V0, E>>(
/// to the value balance and balances of assets to burn.
pub fn try_map_value_balance<V0, E, F: Fn(V) -> Result<V0, E>>(
self,
f: F,
) -> Result<Bundle<T, V0>, E> {
Ok(Bundle {
actions: self.actions,
flags: self.flags,
value_balance: f(self.value_balance)?,
burn: self
.burn
.into_iter()
.map(|(asset, value)| Ok((asset, f(value)?)))
.collect::<Result<Vec<(AssetId, V0)>, E>>()?,
anchor: self.anchor,
authorization: self.authorization,
})
Expand All @@ -244,6 +254,7 @@ impl<T: Authorization, V> Bundle<T, V> {
value_balance: self.value_balance,
anchor: self.anchor,
authorization: step(context, authorization),
burn: self.burn,
}
}

Expand All @@ -267,6 +278,7 @@ impl<T: Authorization, V> Bundle<T, V> {
value_balance: self.value_balance,
anchor: self.anchor,
authorization: step(context, authorization)?,
burn: self.burn,
})
}

Expand Down Expand Up @@ -386,7 +398,19 @@ impl<T: Authorization, V: Copy + Into<i64>> Bundle<T, V> {
ValueSum::from_raw(self.value_balance.into()),
ValueCommitTrapdoor::zero(),
AssetId::native(),
))
)
- self
.burn
.clone()
.into_iter()
.map(|(asset, value)| {
ValueCommitment::derive(
ValueSum::from_raw(value.into()),
ValueCommitTrapdoor::zero(),
asset,
)
})
.sum::<ValueCommitment>())
.into_bvk()
}
}
Expand Down Expand Up @@ -503,6 +527,9 @@ pub mod testing {
use super::{Action, Authorization, Authorized, Bundle, Flags};

pub use crate::action::testing::{arb_action, arb_unauthorized_action};
use crate::note::asset_id::testing::zsa_asset_id;
use crate::note::AssetId;
use crate::value::testing::arb_value_sum;

/// Marker for an unauthorized bundle with no proofs or signatures.
#[derive(Debug)]
Expand Down Expand Up @@ -562,6 +589,13 @@ pub mod testing {
})
}

prop_compose! {
/// Create an arbitrary vector of assets to burn.
pub fn arb_asset_to_burn()(asset_id in zsa_asset_id(), value in arb_value_sum()) -> (AssetId, ValueSum) {
(asset_id, value)
}
}

prop_compose! {
/// Create an arbitrary set of flags.
pub fn arb_flags()(spends_enabled in prop::bool::ANY, outputs_enabled in prop::bool::ANY) -> Flags {
Expand Down Expand Up @@ -589,16 +623,18 @@ pub mod testing {
(
acts in vec(arb_unauthorized_action_n(n_actions, flags), n_actions),
anchor in arb_base().prop_map(Anchor::from),
flags in Just(flags)
flags in Just(flags),
burn in vec(arb_asset_to_burn(), 1usize..10)
) -> Bundle<Unauthorized, ValueSum> {
let (balances, actions): (Vec<ValueSum>, Vec<Action<_>>) = acts.into_iter().unzip();

Bundle::from_parts(
NonEmpty::from_vec(actions).unwrap(),
flags,
balances.into_iter().sum::<Result<ValueSum, _>>().unwrap(),
burn,
anchor,
Unauthorized
Unauthorized,
)
}
}
Expand All @@ -618,7 +654,8 @@ pub mod testing {
rng_seed in prop::array::uniform32(prop::num::u8::ANY),
fake_proof in vec(prop::num::u8::ANY, 1973),
fake_sighash in prop::array::uniform32(prop::num::u8::ANY),
flags in Just(flags)
flags in Just(flags),
burn in vec(arb_asset_to_burn(), 1usize..10)
) -> Bundle<Authorized, ValueSum> {
let (balances, actions): (Vec<ValueSum>, Vec<Action<_>>) = acts.into_iter().unzip();
let rng = StdRng::from_seed(rng_seed);
Expand All @@ -627,11 +664,12 @@ pub mod testing {
NonEmpty::from_vec(actions).unwrap(),
flags,
balances.into_iter().sum::<Result<ValueSum, _>>().unwrap(),
burn,
anchor,
Authorized {
proof: Proof::new(fake_proof),
binding_signature: sk.sign(rng, &fake_sighash),
}
},
)
}
}
Expand Down
Loading