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

parse V5 (nu5) transactions #367

Merged
merged 1 commit into from
Oct 24, 2021

Conversation

LarryRuane
Copy link
Collaborator

todo:

  • add relevant V5 fields to CompactBlock (instead of skipping over)
  • add V5 test vectors to unit tests

@LarryRuane LarryRuane requested review from nuttycom and daira October 7, 2021 21:01
@LarryRuane LarryRuane self-assigned this Oct 7, 2021
parser/transaction.go Outdated Show resolved Hide resolved
parser/transaction.go Outdated Show resolved Hide resolved
@LarryRuane
Copy link
Collaborator Author

LarryRuane commented Oct 8, 2021

It's easier to review this PR if you ignore whitespace: https://github.com/zcash/lightwalletd/pull/367/files?w=1
(The whitespace changes are necessary because when working with Go, the convention is to keep the code always formatted (gofmt).)

@LarryRuane LarryRuane force-pushed the 2021-10-v5-transaction-parsing branch from c6ae3df to 4971c6e Compare October 8, 2021 14:04
@LarryRuane
Copy link
Collaborator Author

Force-pushed to incorporate @daira's comment. @nuttycom, on further thought, let's just leave this as-is for now, we should merge this quickly, I could possibly break it by reorganizing the code, and I can clean it up separately.

@LarryRuane LarryRuane requested a review from str4d October 8, 2021 14:09
@r3ld3v r3ld3v added this to the Core Sprint 2021-40 milestone Oct 11, 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.

I would prefer for the V4 and V5 parsers to be separate functions, which may delegate to functions that perform parsing of the common parts of the format. It's hard to check against the spec with the two formats interleaved, and this is the same reason that we wrote an entirely separate section in the protocol for the V5 format rather than trying to write it interleaved.

parser/transaction.go Outdated Show resolved Hide resolved
@LarryRuane LarryRuane force-pushed the 2021-10-v5-transaction-parsing branch from 4971c6e to 589f710 Compare October 13, 2021 14:33
@LarryRuane
Copy link
Collaborator Author

Force-pushed to incorporate @nuttycom's suggestions (thanks!). There are now separate functions to parse pre-V5 transactions and V5 transactions. In order to not duplicate too much code, I refactored the transparent parsing into a separate function (called by both top-level transaction parsers). This didn't work out so nicely for the Sapling spends and outputs, so I didn't do the same there.

It's easiest to review this code with whitespace ignored: https://github.com/zcash/lightwalletd/pull/367/files?w=1

@LarryRuane LarryRuane requested a review from nuttycom October 13, 2021 15:32
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 more small required change, the fOverwintered flag needs to be checked; otherwise just a nit about transaction construction that you can ignore at your discretion.

parser/transaction.go Show resolved Hide resolved
parser/transaction.go Show resolved Hide resolved
parser/transaction.go Show resolved Hide resolved
parser/transaction.go Outdated Show resolved Hide resolved
@LarryRuane LarryRuane force-pushed the 2021-10-v5-transaction-parsing branch from 589f710 to 25949b2 Compare October 14, 2021 19:34
@LarryRuane
Copy link
Collaborator Author

Force-pushed for @nuttycom's review comments (thanks!)

parser/transaction.go Outdated Show resolved Hide resolved
@LarryRuane
Copy link
Collaborator Author

New commit 6f019a3 to address @nuttycom's suggestions, will squash before merging. I tested these changes by running testnet, although the orchard actions still haven't been tested (testnet has v5 transactions, but none of them contain orchard actions yet).

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.

utACK

parser/transaction.go Outdated Show resolved Hide resolved
parser/transaction.go Outdated Show resolved Hide resolved
@LarryRuane
Copy link
Collaborator Author

Pushed a new commit to address the latest review comments (make a separate commit for easier review; will squash the commit later).

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.

re-utACK.

return nil, errors.New("could not read nVersionGroupId")
}
if tx.nVersionGroupID != 0x26A7270A {
return nil, errors.New(fmt.Sprintf("version number %d must be 0x26A7270A", tx.nVersionGroupID))
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
return nil, errors.New(fmt.Sprintf("version number %d must be 0x26A7270A", tx.nVersionGroupID))
return nil, errors.New(fmt.Sprintf("version group ID %d must be 0x26A7270A", tx.nVersionGroupID))

}
if !s.ReadCompactSize(&spendCount) {
return nil, errors.New("could not read nShieldedSpend")
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
}
}
if spendCount >= (1 << 16) {
return nil, errors.New(fmt.Sprintf("spendCount (%d) must be less than 2^16", spendCount))
}

Although the consensus rule restricting the maximum number of spends and outputs to 216 - 1 each was only added for NU5, they were already restricted to lower limits by the block size, so it is correct to check them unconditionally for both v4 and v5 transactions, as zcashd does.

if !s.ReadCompactSize(&txInCount) {
return nil, errors.New("could not read tx_in_count")
if !s.ReadCompactSize(&outputCount) {
return nil, errors.New("could not read nShieldedOutput")
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
}
}
if outputCount >= (1 << 16) {
return nil, errors.New(fmt.Sprintf("outputCount (%d) must be less than 2^16", outputCount))
}

@@ -325,148 +352,221 @@ func (tx *Transaction) ToCompact(index int) *walletrpc.CompactTx {
return ctx
}

// ParseFromSlice deserializes a single transaction from the given data.
func (tx *Transaction) ParseFromSlice(data []byte) ([]byte, error) {
// parse version 4
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
// parse version 4
// parse version 4 transaction data after the nVersionGroupId field.

@LarryRuane LarryRuane force-pushed the 2021-10-v5-transaction-parsing branch from 6281972 to e33780b Compare October 21, 2021 14:54
@LarryRuane
Copy link
Collaborator Author

Force-pushed for latest review comments (enforcing spendCount and outputCount limits, fix version group ID error string, improve 2 comments), thank you, @daira.

var joinSplitCount int
if !s.ReadCompactSize(&joinSplitCount) {
return nil, errors.New("could not read nJoinSplit")
var proofsCount int
Copy link
Contributor

Choose a reason for hiding this comment

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

This is not a count of proofs, it's a size in bytes. Rename it to something like proofsSize.

if !s.ReadBytes(&tx.joinSplitPubKey, 32) {
return nil, errors.New("could not read joinSplitPubKey")
}
// declare here to prevent shadowing problems in cryptobyte assignments
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't know what this means.

Copy link
Contributor

@daira daira left a comment

Choose a reason for hiding this comment

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

utACK modulo comments.

@r3ld3v r3ld3v removed this from the Core Sprint 2021-40 milestone Oct 22, 2021
TODO:
- store, instead of just skip over, nu5 transaction fields
- add relevant nu5 fields to CompactBlock
- restore disabled V4 unit tests
- add V5 test vectors to unit tests

The reason most of the V4 transaction and block unit tests are removed
is that they used V3 transactions, which lightwalletd never sees in
production, since lightwalletd starts at Sapling activation (which has
V4 transactions). So these tests were always wrong, in a way. This
commit simplifies the parsing code by removing support for V3 (since it
was never needed). The tests need to be updated to V4, but we'll do
that in a later PR.
@LarryRuane LarryRuane force-pushed the 2021-10-v5-transaction-parsing branch from e33780b to f166d2c Compare October 24, 2021 19:29
@LarryRuane LarryRuane merged commit ddf3781 into zcash:master Oct 24, 2021
@LarryRuane LarryRuane deleted the 2021-10-v5-transaction-parsing branch October 26, 2021 14:47
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.

4 participants