Conversation
Signed-off-by: Daira Hopwood <daira@jacaranda.org>
`reddsa 0.5.1` has MSRV 1.65.
Migrate to `incrementalmerkletree 0.5`
This is currently "whatever lockfile happened to last work for str4d", but going forward will be the lockfile we use for testing our MSRV. See https://blog.rust-lang.org/2023/08/29/committing-lockfiles for rationale on this change.
Label Consensus Rules
CI: Modernise workflows
The term `recipient` is commonly used to refer to the address to which a note is sent; however, a bundle may include multiple outputs to the same recipient. This change is intended to clarify this usage. Co-authored-by: Daira Emma Hopwood <daira@jacaranda.org>
Co-authored-by: str4d <thestr4d@gmail.com>
Add a public bundle-builder function as an alternative to the mutable builder.
Ying Tong Lai. Signed-off-by: Daira Emma Hopwood <daira@jacaranda.org>
Signed-off-by: Daira Emma Hopwood <daira@jacaranda.org>
Change license from BOSL to "MIT OR Apache-2.0"
Move some changelog entries from 0.3.0 to 0.4.0
…duced. This adds a flag to `BundleType` that, when set, requires a dummy-only bundle to be produced even if no spends or outputs are added to the builder, and when unset results in standard padding.
Modify `BundleType` to exclude the anchor & allow no bundle to be produced.
Make the `MERKLE_DEPTH_ORCHARD` constant public.
In order to be able to associate requested spends and outputs with the indices of the actions that execute these operations, it is necessary to track the randomization of inputs and outputs and return the mappings that resulted from that shuffling.
Trivial update to the doc for `struct Action`
Additions needed for Orchard batch scanning
Release 0.7.1
…horchard Add a `MerkleHashOrchard::random` function under the `test-dependencies` feature.
This change removes the ability to construct a `Rho` value directly from the public API, except via deserialization from bytes (which is necessary in order to be able to serialize a `Note`). Ordinarily, `Rho` should be obtained either from an already-constructed `Note` or from an `Action` or `CompactAction`.
Add a `Rho` type, to distinguish from revealed nullifiers of spent notes.
Add `impl Distribution<MerkleHashOrchard> for Standard` for testing.
…lation errors in tests)
…uble column in the use of external zip32 crate
PaulLaux
left a comment
There was a problem hiding this comment.
Good overall, some more polish for clarity is required
src/builder.rs
Outdated
| /// builder will prevent any spends or outputs from being added. | ||
| pub const DISABLED: BundleType = BundleType::Transactional { | ||
| flags: Flags::from_parts(false, false, false), // FIXME: is this correct? | ||
| flags: Flags::from_parts(false, false, false), // FIXME: is `false` value for ZSA flag correct here? |
There was a problem hiding this comment.
Got it, removed the FIXME comment.
And there're similar questions for bundle.rs: does zsa_enabled need to be false for SPENDS_DISABLED and OUTPUTS_DISABLED?
builder.rs:106:
/// The flag set with spends disabled.
pub const SPENDS_DISABLED: Flags = Flags {
spends_enabled: false,
outputs_enabled: true,
zsa_enabled: false, // FIXME: is this correct?
};
/// The flag set with outputs disabled.
pub const OUTPUTS_DISABLED: Flags = Flags {
spends_enabled: true,
outputs_enabled: false,
zsa_enabled: false, // FIXME: is this correct?
};
There was a problem hiding this comment.
yes, both are correct, the first is used for mining zec, the second is not used.
There was a problem hiding this comment.
Got it, thanks. Fixed (removed FIXME comments).
src/builder.rs
Outdated
| let dummy_spend = SpendInfo::dummy(AssetBase::native(), rng); | ||
| hm.insert( | ||
| dummy_spend.note.asset(), | ||
| (vec![(usize::MAX, dummy_spend)], vec![]), |
There was a problem hiding this comment.
Dummy spends/outputs should not participate in BundleMetadata indexing. To manage this, we need a way to mark them as a dummy in the indexed vectors of spends/outputs, so that in further code of bundle functions the following assignments will be skipped:
bundle_meta.spend_indices[spend_idx] = action_idx;
bundle_meta.output_indices[out_idx] = action_idx;
In the previous version of the code for this PR I simply used usize::MAX instead of the indices for marking dummy spends/outputs, so the checks:
if spend_idx < num_requested_spends {
if out_idx < num_requested_outputs {
skipped such items.
I agree that it was confusing, so now, I use the Option type to mark dummy items (for dummy items the index is None, for real ones - Some(...))
There was a problem hiding this comment.
nice, lets add comment
if hm.is_empty() {
let dummy_spend = pad_spend(None, AssetBase::native(), rng);
// dummy_spend should not be included in the indexing and marked as None.
hm.insert(
dummy_spend.note.asset(),
(vec![(None, dummy_spend)], vec![]),
);
src/builder.rs
Outdated
| /// 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: Copy + Into<i64> + TryFrom<i64>>( |
There was a problem hiding this comment.
previously we worked hard to avoid it + see comment below
There was a problem hiding this comment.
The Copy + Into<i64> constraint was added to the build function's signature in PR #35 of the QED-it/orchard repository.
The reason for this, as I understand it, is that in the Zcash repository, the bvk value was calculated separately within the build function instead of using the bundle.binding_validating_key() method (this method requires the Copy + Into<i64> constraint).
PR #35 added the burn functionality, making the separate calculation of bvk in build more complicated. To avoid duplicating code, the calculation was switched to use bundle.binding_validating_key(), which required the Copy + Into<i64> constraint.
Now, to fix this and remove the Copy + Into<i64> constraint while still using bundle.binding_validating_key() (and avoiding code duplication), I suggest calculating native_value_balance as an i64 first, then converting it to V, which doesn't require Into<i64>. Also, to reuse the binding_validating_key logic for bvk, we could modify it by adding a new free function called derive_bvk in the bundle.rs module. This function would take three parameters: an actions iterator, a generic value_balance, and a burn iterator. Using iterators would avoid extra memory usage.
We can call derive_bvk from binding_validating_key, and have bundle call derive_bvk instead of directly using binding_validating_key.
I've implemented this solution in the latest version of the code for this PR.
src/builder.rs
Outdated
| let dummy_spend = SpendInfo::dummy(AssetBase::native(), rng); | ||
| hm.insert( | ||
| dummy_spend.note.asset(), | ||
| (vec![(usize::MAX, dummy_spend)], vec![]), |
There was a problem hiding this comment.
I don't like the potential duplicated logic, can we use pad_spend() for this?
There was a problem hiding this comment.
instead SpendInfo::dummy(AssetBase::native(), rng);
There was a problem hiding this comment.
Fixed it in this way:
let dummy_spend = pad_spend(None, AssetBase::native(), rng);
src/builder.rs
Outdated
| .chain(iter::repeat_with(|| { | ||
| (usize::MAX, pad_spend(first_spend.as_ref(), asset, &mut rng)) |
There was a problem hiding this comment.
usize::MAX is unintuitive, use named var / constant (everywhere)
reading the code I need to understand at this point that this is the spend index but currently it is unclear
also unclear how multiple spends can have the same index (usize:max)
There was a problem hiding this comment.
Fixed (now it uses the Option type to mark dummy spends/outputs to skip them when populating BundleMetadata, see the comment above).
…nction. 2) Refactor builder::bundle function (pre-action genetation), to split 'fold' into three parts
- Introduce `derive_bvk` function for streamlined calculation of `bvk` - Use `derive_bvk` in `bundle.binding_validating_key()` to avoid duplication - Adjust `native_value_balance` calculation to an `i64` and convert to `V` - Optimize calculations with iterators to reduce memory usage
| #[allow(clippy::type_complexity)] | ||
| fn partition_by_asset( | ||
| spends: &[SpendInfo], | ||
| recipients: &[RecipientInfo], | ||
| outputs: &[OutputInfo], | ||
| rng: &mut impl RngCore, | ||
| ) -> HashMap<AssetBase, (Vec<SpendInfo>, Vec<RecipientInfo>)> { | ||
| ) -> HashMap< | ||
| AssetBase, | ||
| ( | ||
| Vec<(Option<usize>, SpendInfo)>, | ||
| Vec<(Option<usize>, OutputInfo)>, | ||
| ), | ||
| > { |
There was a problem hiding this comment.
let's add a named type to explain the logic.
let's switch location between the content and the index SpendInfo <-> MetadataIdx
/// The index of the attached spend or output in the bundle.
/// None indicates a dummy note.
/// The index is used to track the position of the note in the bundle.
type MetadataIdx = Option<usize>;
/// Partition a list of spends and recipients by note types.
/// Method creates single dummy ZEC note if spends and recipients are both empty.
#[allow(clippy::type_complexity)]
fn partition_by_asset(
spends: &[SpendInfo],
outputs: &[OutputInfo],
rng: &mut impl RngCore,
) -> HashMap<
AssetBase,
(
Vec<(SpendInfo, MetadataIdx)>,
Vec<(OutputInfo, MetadataIdx)>,
),
> {
This PR merges the latest updates from the
zcash/orchardrepository (version 0.8.0) intozsa1branch. These updates include refactorings and enhancements which are detailed below. The integration has been completed in thezsa1-with-zcash-0.8.0branch, where conflicts were resolved and all unit tests and CI checks pass successfully.Key Changes from zcash/orchard v0.8.0
rhovalue, keeping Nullifier for nullifiers.zip32module functionality and new features, while localzsa32retains orchard-specific features now.bundlefunction, introducing BundleMetadata to track indices pre-shuffle.