Skip to content
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

Implement ZIP 302 memos #177

Merged
merged 6 commits into from
Mar 24, 2021
Merged

Implement ZIP 302 memos #177

merged 6 commits into from
Mar 24, 2021

Conversation

str4d
Copy link
Contributor

@str4d str4d commented Nov 27, 2019

Memo is now an enum, which improves type safety.

Closes #175. Part of zcash/zcash#1849.

@str4d str4d requested a review from ebfull November 27, 2019 20:30
@str4d
Copy link
Contributor Author

str4d commented Nov 28, 2019

Best reviewed commit-by-commit, because one of the commits is a move-only commit.

@str4d str4d changed the title Rework note_encryption::Memo as an enum Implement ZIP 302 memos Nov 28, 2019
@str4d str4d force-pushed the 175-memo-enum branch 2 times, most recently from 1627c85 to 7d3b090 Compare February 28, 2020 23:59
@str4d
Copy link
Contributor Author

str4d commented Feb 29, 2020

I rebased on master to fix merge conflicts. I also reordered the commits so the move happens before the refactor, cleaned up the history, and removed structured memo support (for now, while we decide how to handle them in ZIP 302).

@codecov
Copy link

codecov bot commented Aug 27, 2020

Codecov Report

Merging #177 (e122c3d) into master (3a8e729) will decrease coverage by 0.25%.
The diff coverage is 40.84%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #177      +/-   ##
==========================================
- Coverage   64.64%   64.38%   -0.26%     
==========================================
  Files          69       70       +1     
  Lines        7079     7157      +78     
==========================================
+ Hits         4576     4608      +32     
- Misses       2503     2549      +46     
Impacted Files Coverage Δ
zcash_client_backend/src/data_api.rs 15.38% <0.00%> (ø)
zcash_client_backend/src/data_api/wallet.rs 90.62% <ø> (ø)
zcash_client_sqlite/src/error.rs 15.15% <0.00%> (-0.98%) ⬇️
zcash_primitives/src/transaction/builder.rs 56.21% <0.00%> (-1.36%) ⬇️
zcash_client_sqlite/src/wallet.rs 78.75% <25.00%> (ø)
zcash_primitives/src/memo.rs 37.16% <37.16%> (ø)
zcash_client_sqlite/src/lib.rs 54.40% <44.44%> (+0.35%) ⬆️
zcash_client_backend/src/welding_rig.rs 91.79% <100.00%> (ø)
zcash_primitives/src/note_encryption.rs 82.65% <100.00%> (+6.48%) ⬆️
zcash_primitives/src/transaction/mod.rs 47.72% <0.00%> (-1.52%) ⬇️
... and 16 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 3a8e729...e122c3d. Read the comment docs.

Copy link
Contributor

@nuttycom nuttycom left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One change requested: that we should remove the Default impls.

zcash_primitives/src/memo.rs Outdated Show resolved Hide resolved
The MemoBytes struct is a minimal wrapper around the memo bytes, and only
imposes the existence of null-padding for shorter memos. The only error
case is attempting to construct a memo that is too long. MemoBytes is
guaranteed to be round-trip encodable (modulo null padding).

The Memo enum implements the additional memo rules defined in ZIP 302,
interpreting the contents of a memo (for example, parsing it as text).
Memo fields have two ways to encode an empty memo:

- 0xF6 followed by all-zeroes, encoding "there is no memo".
- All-zeroes, encoding the empty UTF-8 string.

In almost all cases you want the former, but users thinking about byte
slices may expect MemoBytes::default() to result in the latter. To
ensure clarity, we now require calling either MemoBytes::default() or
MemoBytes::from_bytes(&[]) to be explicit.

No such confusion exists for the Memo enum, because the two types are
visibly separated as different enum cases, and Memo::Empty makes sense
as the default.
Copy link
Contributor

@nuttycom nuttycom left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK!

@nuttycom
Copy link
Contributor

After additional consideration, I really think that Memo should be moved to zcash_client_backend. I'd like to start drawing a hard line around zcash_primitives such that everything that's in that crate, and on crates it depends upon (once we pull out Orchard and Sapling crates) are strictly consensus-critical, and that everything else go a layer up. WDYT?

@str4d
Copy link
Contributor Author

str4d commented Mar 17, 2021

The problem is that the line is fuzzy here. For example, note encryption for non-shielded coinbase outputs is not "consensus critical" (and cannot be without the ZKPs checking the encryption inside the circuit, which we aren't going to do), but it is absolutely a core part of the protocol that everyone needs to agree on, or else users lose funds.

I'm not against moving Memo from zcash_primitives to zcash_client_backend, but I do not want to do so in the next release; it should be considered as part of the larger crate refactor. I'd prefer to land things like the Sapling protocol and note encryption logic refactor first, and then see how the crate APIs are shaping up.

@r3ld3v r3ld3v added this to the Core Sprint 2021-10 milestone Mar 17, 2021
Copy link
Contributor

@nuttycom nuttycom left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need handling of the 0xF5 case.

match bytes.0[0] {
0xF6 if bytes.0.iter().skip(1).all(|&b| b == 0) => Ok(Memo::Empty),
0xFF => Ok(Memo::Arbitrary(Box::new(bytes.0[1..].try_into().unwrap()))),
b if b <= 0xF4 => str::from_utf8(bytes.as_slice())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just noticed that this doesn't yet implement the 0xF5 case specified in ZIP 302. That specification also needs some clarification related to how to parse the length bytes (see zcash/zips#105 (comment)).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I intentionally removed 0xF5 handling from this PR last year, in an effort to make the PR mergeable, as it was the most contentious part.

Copy link
Contributor

@nuttycom nuttycom left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 to deferring implementation of 0xF5

We're removing those from the ZIP draft until they can be agreed upon.
@str4d str4d merged commit ebadc8c into zcash:master Mar 24, 2021
@str4d str4d deleted the 175-memo-enum branch March 24, 2021 21:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Rework Memo as an enum
3 participants