-
Notifications
You must be signed in to change notification settings - Fork 87
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
parse V5 (nu5) transactions #367
Conversation
It's easier to review this PR if you ignore whitespace: https://github.com/zcash/lightwalletd/pull/367/files?w=1 |
c6ae3df
to
4971c6e
Compare
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 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.
4971c6e
to
589f710
Compare
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 |
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 small required change, the fOverwintered
flag needs to be checked; otherwise just a nit about transaction construction that you can ignore at your discretion.
589f710
to
25949b2
Compare
Force-pushed for @nuttycom's review comments (thanks!) |
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.
utACK
Pushed a new commit to address the latest review comments (make a separate commit for easier review; will squash the commit later). |
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.
re-utACK.
parser/transaction.go
Outdated
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)) |
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.
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") | ||
} |
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.
} | |
} | |
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") | ||
} |
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.
} | |
} | |
if outputCount >= (1 << 16) { | |
return nil, errors.New(fmt.Sprintf("outputCount (%d) must be less than 2^16", outputCount)) | |
} |
parser/transaction.go
Outdated
@@ -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 |
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.
// parse version 4 | |
// parse version 4 transaction data after the nVersionGroupId field. |
6281972
to
e33780b
Compare
Force-pushed for latest review comments (enforcing |
var joinSplitCount int | ||
if !s.ReadCompactSize(&joinSplitCount) { | ||
return nil, errors.New("could not read nJoinSplit") | ||
var proofsCount int |
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.
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 |
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 know what this means.
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.
utACK modulo comments.
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.
e33780b
to
f166d2c
Compare
todo: