-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Update to upstream (zcash/main v0.8.0) #103
Conversation
Signed-off-by: Daira Hopwood <[email protected]>
`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 <[email protected]>
Co-authored-by: str4d <[email protected]>
Add a public bundle-builder function as an alternative to the mutable builder.
Ying Tong Lai. Signed-off-by: Daira Emma Hopwood <[email protected]>
Signed-off-by: Daira Emma Hopwood <[email protected]>
Change license from BOSL to "MIT OR Apache-2.0"
The changelog changes in zcash#362 had a non-merge conflict with zcash#363, because zcash#362 was implemented as if it would be part of the 0.3.0 release but was in fact merged just afterwards. fixes zcash#391 Signed-off-by: Daira Emma Hopwood <[email protected]>
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
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good overall, some more polish for clarity is required
src/builder.rs
Outdated
bundle_required: false, | ||
}; | ||
|
||
/// The DISABLED bundle type does not permit any bundle to be produced, and when used in the | ||
/// 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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, both are correct, the first is used for mining zec, the second is not used.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why usize:MAX?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
see below
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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![]),
);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed (added the comment).
src/builder.rs
Outdated
@@ -621,7 +620,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: Copy + Into<i64> + TryFrom<i64>>( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why Copy + Into
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
previously we worked hard to avoid it + see comment below
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't like the potential duplicated logic, can we use pad_spend()
for this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
instead SpendInfo::dummy(AssetBase::native(), rng);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
one more refactor is required for clarity.
Also, see 2 answers for previous questions.
src/builder.rs
Outdated
#[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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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)>,
),
> {
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
This PR merges the latest updates from the
zcash/orchard
repository (version 0.8.0) intozsa1
branch. These updates include refactorings and enhancements which are detailed below. The integration has been completed in thezsa1-with-zcash-0.8.0
branch, where conflicts were resolved and all unit tests and CI checks pass successfully.Key Changes from zcash/orchard v0.8.0
rho
value, keeping Nullifier for nullifiers.zip32
module functionality and new features, while localzsa32
retains orchard-specific features now.bundle
function, introducing BundleMetadata to track indices pre-shuffle.