-
Notifications
You must be signed in to change notification settings - Fork 123
swap: HTLCV3 added #473
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
swap: HTLCV3 added #473
Conversation
|
The Used something like the below to attempt to accomplish this but some feedback would be appreciated. increment := func(seedPhrase []byte, i int) []byte {
// Increment the origin of the hash using the mapping candidateSed :=
// h(i || seedPhrase).
shaStream := sha256.New()
var iterationBytes [8]byte
binary.BigEndian.PutUint64(iterationBytes[:], uint64(i))
shaStream.Write(iterationBytes[:])
shaStream.Write(seedPhrase)
seedHash := shaStream.Sum(nil)
return seedHash[:]
}
var i int
for {
// At the start of the iteration, we'll try with a counter
// offset of 0, each time we fail to find a proper point, we'll
// increment this by one.
candidateSeed := increment(randomPub, i)
fmt.Printf("iteration_num=%v, candidate=%x\n", i, candidateSeed[:])
var pubBytes [33]byte
pubBytes[0] = 0x02
copy(pubBytes[1:], candidateSeed[:])
// Try to see if this point when intercepted as an x coordinate
// is actually found on the curve.
candidatePoint, err := btcec.ParsePubKey(pubBytes[:])
if err == nil {
fmt.Printf("Global param generated: %x\n",
candidatePoint.SerializeCompressed())
break
}
fmt.Printf("not a quadratic residue: %v\n", err)
i++
} |
8765ba2 to
83f8a76
Compare
swap/htlc.go
Outdated
| // - witness_script_length: 1 byte | ||
| // - witness_script: len(script) bytes | ||
| // - control_block_length: 1 byte | ||
| // - control_block: 4129 bytes |
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.
How do you get 4129 for control block?
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.
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 think this should be based on the worst-case size of our control block so that we can get as close to accurate as possible.
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 agree with Carla, since our taptree is shallow, our control block is also small compared to the worst theoretical case, so we should calculate the max for our case imo. (Even though we don't use this function).
Edit: we should actually also use these functions in our test cases as a sanity check (once the control block sizes are adjusted)
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.
Set to our worst case, which is 65 bytes - please confirm
swap/htlc.go
Outdated
| TaprootKey *secp.PublicKey | ||
| InternalPubKey *secp.PublicKey |
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.
[32] byte?
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.
Storing as byte slice adds a lot of conversions all over the place, but better here than throughout the codebase. Storing as array will only add another conversion without reason imo.
(also, I think secp.PublicKey are 33 bytes when compressed)
3b3df7b to
5a31825
Compare
swap/htlc.go
Outdated
| func newHTLCScriptV3(cltvExpiry int32, receiverHtlcKey, senderHtlcKey [33]byte, | ||
| swapHash lntypes.Hash) (*HtlcScriptV3, error) { | ||
|
|
||
| _, receiverPubKey := btcec.PrivKeyFromBytes( |
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.
Pubkey from privkeyfrombytes?
receiverPubkey, err:= btcec.ParsePubkey(receiverHtlcKey[:])
copy(schnorrReceiverKey, schnorr.SerializePubkey(receiverPubkey)
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.
From NewHtlc:
// NewHtlc returns a new instance. For V1 and V2 scripts, receiver and sender
// keys are expected to be in ecdsa compressed format. For V3 scripts, keys are
// expected to be raw private key bytes.
This was feedback I received from laolu and oli in regards to dealing with the serializeLoopContract issue which requires the keys stored to be 33 bytes (which ecdsa compressed are), however schnorr keys are 32 bytes, which throws the serializer off. To mitigate this issue, we store raw private key bytes in the LoopContract in memory and feed those raw bytes to NewHtlc only in the htlcv3 case.
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 can't we just store [33]byte then schnorr.SerializePubkey when we need to use the key in a HtlcV3 context?
Do you have a link to that convo so I can understand the context of that discussion?
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.
Took that approach, addressed
5a31825 to
3d4ba17
Compare
swap/htlc.go
Outdated
| // - witness_script_length: 1 byte | ||
| // - witness_script: len(script) bytes | ||
| // - control_block_length: 1 byte | ||
| // - control_block: 4129 bytes |
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 think this should be based on the worst-case size of our control block so that we can get as close to accurate as possible.
swap/htlc.go
Outdated
| func newHTLCScriptV3(cltvExpiry int32, receiverHtlcKey, senderHtlcKey [33]byte, | ||
| swapHash lntypes.Hash) (*HtlcScriptV3, error) { | ||
|
|
||
| _, receiverPubKey := btcec.PrivKeyFromBytes( |
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 can't we just store [33]byte then schnorr.SerializePubkey when we need to use the key in a HtlcV3 context?
Do you have a link to that convo so I can understand the context of that discussion?
bhandras
left a comment
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.
Great PR, almost there just a few comments remain.
swap/htlc.go
Outdated
| // - witness_script_length: 1 byte | ||
| // - witness_script: len(script) bytes | ||
| // - control_block_length: 1 byte | ||
| // - control_block: 4129 bytes |
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 agree with Carla, since our taptree is shallow, our control block is also small compared to the worst theoretical case, so we should calculate the max for our case imo. (Even though we don't use this function).
Edit: we should actually also use these functions in our test cases as a sanity check (once the control block sizes are adjusted)
swap/htlc_test.go
Outdated
| ) | ||
|
|
||
| sig := signTx( | ||
| tx, senderPrivKey, txscript.NewBaseTapLeaf(trHtlc.ClaimScript), |
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 testcase descriptions and the actual testcases are inverted.
2a2d675 to
06fd791
Compare
arshbot
left a comment
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.
Made the requested changes! Ready for another pass
swap/htlc.go
Outdated
| func newHTLCScriptV3(cltvExpiry int32, receiverHtlcKey, senderHtlcKey [33]byte, | ||
| swapHash lntypes.Hash) (*HtlcScriptV3, error) { | ||
|
|
||
| _, receiverPubKey := btcec.PrivKeyFromBytes( |
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.
Took that approach, addressed
swap/htlc.go
Outdated
| // - witness_script_length: 1 byte | ||
| // - witness_script: len(script) bytes | ||
| // - control_block_length: 1 byte | ||
| // - control_block: 4129 bytes |
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.
Set to our worst case, which is 65 bytes - please confirm
guggero
left a comment
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.
Looks way better now, but still a lot of nits. We want to be extra careful, explicit and verbose with anything that touches on-chain scripts.
swap/htlc_test.go
Outdated
| preimage := [32]byte{1, 2, 3} | ||
| p := lntypes.Preimage(preimage) | ||
| hashedPreimage := sha256.Sum256(p[:]) | ||
| value := int64(800_000 - 500) // TODO(guggero): Calculate actual fee. |
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.
Fee calculation is now available in lnd master.
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.
Removed fee because previous tests don't include and it's a distraction from what this is testing
06fd791 to
fcc1c35
Compare
b8dff91 to
abce7d1
Compare
bhandras
left a comment
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.
Tried to find everything, hopefully we're now just one round away from being ready.
swap/htlc.go
Outdated
|
|
||
| switch outputType { | ||
| case HtlcNP2WSH: | ||
| pkScript, err := input.WitnessScriptHash(htlc.Script()) |
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.
pkScript inside the case will shadow the pkScript declared outside. A way to fix it is to declare the error as well. Example: https://go.dev/play/p/3RXcMVh162P
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 catch, done. Since err is already declared earlier, the redeclaration shouldn't be necessary
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.
It's still wrong?
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.
edit: I see you fixed it in the other commit. Please fix it in this commit.
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
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 still wrong in the first commit.
bcfb001 to
b3e4f68
Compare
|
@bhandras PTAL! |
|
@guggero I think is ready for another pass from you as well! PTAL! |
b3e4f68 to
2135bcd
Compare
bhandras
left a comment
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.
Almost ready :)
swap/htlc.go
Outdated
|
|
||
| switch outputType { | ||
| case HtlcNP2WSH: | ||
| pkScript, err := input.WitnessScriptHash(htlc.Script()) |
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.
edit: I see you fixed it in the other commit. Please fix it in this commit.
2135bcd to
0f75c9b
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.
Please fix the aliasing issue (#473 (review)) in the first commit, other than that LGTM 🎉
In this commit we add the version 3 htlc, which is implemented with taproot script spending the two payment paths: the claim path case, and the timeout case.
0f75c9b to
173c213
Compare
|
Uhm, these PRs need two approvals.. |
In this commit we add the version 3 htlc, which is implemented with
taproot script spending the two payment paths: the claim path case, and
the timeout case.
Pull Request Checklist
release_notes.mdif your PR contains major features, breaking changes or bugfixes