lnwallet: update WitnessType names to be more descriptive

In this commit, we rename several of the existing WitnessType
definitions to be more descriptive than they were previously. We also
add a number of additional types which we need to handle scripts for,
but weren’t yet added before. Finally, we modify the
receiverHtlcSpendTimeout to optionally take an additional parameter to
set the locktime of the spending transaction accordingly. This final
modification allows the caller to specify that the lock time has
already been set on the main transaction.
This commit is contained in:
Olaoluwa Osuntokun 2018-01-16 17:59:43 -08:00
parent 3fa0cde631
commit ff872b798c
No known key found for this signature in database
GPG key ID: 964EA263DD637C21
3 changed files with 71 additions and 29 deletions

View file

@ -573,17 +573,24 @@ func ReceiverHtlcSpendRevoke(signer Signer, signDesc *SignDescriptor,
// receiverHtlcSpendTimeout constructs a valid witness allowing the sender of // receiverHtlcSpendTimeout constructs a valid witness allowing the sender of
// an HTLC to recover the pending funds after an absolute timeout in the // an HTLC to recover the pending funds after an absolute timeout in the
// scenario that the receiver of the HTLC broadcasts their version of the // scenario that the receiver of the HTLC broadcasts their version of the
// commitment transaction. // commitment transaction. If the caller has already set the lock time on the
// spending transaction, than a value of -1 can be passed for the cltvExipiry
// value.
// //
// NOTE: The target input of the passed transaction MUST NOT have a final // NOTE: The target input of the passed transaction MUST NOT have a final
// sequence number. Otherwise, the OP_CHECKLOCKTIMEVERIFY check will fail. // sequence number. Otherwise, the OP_CHECKLOCKTIMEVERIFY check will fail.
func receiverHtlcSpendTimeout(signer Signer, signDesc *SignDescriptor, func receiverHtlcSpendTimeout(signer Signer, signDesc *SignDescriptor,
sweepTx *wire.MsgTx, cltvExpiry uint32) (wire.TxWitness, error) { sweepTx *wire.MsgTx, cltvExpiry int32) (wire.TxWitness, error) {
// The HTLC output has an absolute time period before we are permitted // If the caller set a proper timeout value, then we'll apply it
// to recover the pending funds. Therefore we need to set the locktime // directly to the transaction.
// on this sweeping transaction in order to pass Script verification. if cltvExpiry != -1 {
sweepTx.LockTime = cltvExpiry // The HTLC output has an absolute time period before we are
// permitted to recover the pending funds. Therefore we need to
// set the locktime on this sweeping transaction in order to
// pass Script verification.
sweepTx.LockTime = uint32(cltvExpiry)
}
// With the lock time on the transaction set, we'll not generate a // With the lock time on the transaction set, we'll not generate a
// signature for the sweep transaction. The passed sign descriptor // signature for the sweep transaction. The passed sign descriptor

View file

@ -78,6 +78,7 @@ type SignDescriptor struct {
// WriteSignDescriptor serializes a SignDescriptor struct into the passed // WriteSignDescriptor serializes a SignDescriptor struct into the passed
// io.Writer stream. // io.Writer stream.
//
// NOTE: We assume the SigHashes and InputIndex fields haven't been assigned // NOTE: We assume the SigHashes and InputIndex fields haven't been assigned
// yet, since that is usually done just before broadcast by the witness // yet, since that is usually done just before broadcast by the witness
// generator. // generator.
@ -119,7 +120,6 @@ func WriteSignDescriptor(w io.Writer, sd *SignDescriptor) error {
// ReadSignDescriptor deserializes a SignDescriptor struct from the passed // ReadSignDescriptor deserializes a SignDescriptor struct from the passed
// io.Reader stream. // io.Reader stream.
func ReadSignDescriptor(r io.Reader, sd *SignDescriptor) error { func ReadSignDescriptor(r io.Reader, sd *SignDescriptor) error {
pubKeyBytes, err := wire.ReadVarBytes(r, 0, 34, "pubkey") pubKeyBytes, err := wire.ReadVarBytes(r, 0, 34, "pubkey")
if err != nil { if err != nil {
return err return err
@ -134,11 +134,11 @@ func ReadSignDescriptor(r io.Reader, sd *SignDescriptor) error {
return err return err
} }
// Serializing a SignDescriptor with a nil-valued SingleTweak results in // Serializing a SignDescriptor with a nil-valued SingleTweak results
// deserializing a zero-length slice. Since a nil-valued SingleTweak has // in deserializing a zero-length slice. Since a nil-valued SingleTweak
// special meaning and a zero-length slice for a SingleTweak is invalid, // has special meaning and a zero-length slice for a SingleTweak is
// we can use the zero-length slice as the flag for a nil-valued // invalid, we can use the zero-length slice as the flag for a
// SingleTweak. // nil-valued SingleTweak.
if len(singleTweak) == 0 { if len(singleTweak) == 0 {
sd.SingleTweak = nil sd.SingleTweak = nil
} else { } else {
@ -150,11 +150,11 @@ func ReadSignDescriptor(r io.Reader, sd *SignDescriptor) error {
return err return err
} }
// Serializing a SignDescriptor with a nil-valued DoubleTweak results in // Serializing a SignDescriptor with a nil-valued DoubleTweak results
// deserializing a zero-length slice. Since a nil-valued DoubleTweak has // in deserializing a zero-length slice. Since a nil-valued DoubleTweak
// special meaning and a zero-length slice for a DoubleTweak is invalid, // has special meaning and a zero-length slice for a DoubleTweak is
// we can use the zero-length slice as the flag for a nil-valued // invalid, we can use the zero-length slice as the flag for a
// DoubleTweak. // nil-valued DoubleTweak.
if len(doubleTweakBytes) == 0 { if len(doubleTweakBytes) == 0 {
sd.DoubleTweak = nil sd.DoubleTweak = nil
} else { } else {

View file

@ -27,22 +27,42 @@ const (
// commitment transaction. // commitment transaction.
CommitmentRevoke WitnessType = 2 CommitmentRevoke WitnessType = 2
// HtlcOfferedRevoke is a witness that allows us to sweep an HTLC // HtlcOfferedRevoke is a witness that allows us to sweep an HTLC which
// output that we offered to the counterparty. // we offered to the remote party in the case that they broadcast a
// revoked commitmetn state.
HtlcOfferedRevoke WitnessType = 3 HtlcOfferedRevoke WitnessType = 3
// HtlcAcceptedRevoke is a witness that allows us to sweep an HTLC // HtlcAcceptedRevoke is a witness that allows us to sweep an HTLC
// output that we accepted from the counterparty. // output sent to us in the case that the remote party broadcasts a
// revoked commitment state.
HtlcAcceptedRevoke WitnessType = 4 HtlcAcceptedRevoke WitnessType = 4
// HtlcOfferedTimeout is a witness that allows us to sweep an HTLC // HtlcOfferedTimeoutSecondLevel is a witness that allows us to sweep
// output that we extended to a party, but was never fulfilled. // an HTLC output that we extended to a party, but was never fulfilled.
HtlcOfferedTimeout WitnessType = 5 // This HTLC output isn't directly on the commitment transaction, but
// is the result of a confirmed second-level HTLC transaction. As a
// result, we can only spend this after a CSV delay.
HtlcOfferedTimeoutSecondLevel WitnessType = 5
// HtlcAcceptedSuccess is a witness that allows us to sweep an HTLC // HtlcAcceptedSuccessSecondLevel is a witness that allows us to sweep
// output that was offered to us, and for which we have a payment // an HTLC output that was offered to us, and for which we have a
// preimage. // payment preimage. This HTLC output isn't diretly on our commitment
HtlcAcceptedSuccess WitnessType = 6 // transaction, but is the result of confirmed second-level HTLC
// transaction. As a result, we can only spend this after a CSV delay.
HtlcAcceptedSuccessSecondLevel WitnessType = 6
// HtlcOfferedRemoteTimeout is a witness that allows us to sweep an
// HTLC that we offered to the remote party which lies in the
// commitment transaction of the remote party. We can spend this output
// after the absolute CLTV timeout of the HTLC as passed.
HtlcOfferedRemoteTimeout WitnessType = 7
// HtlcAcceptedRemoteSuccess is a witness that allows us to sweep an
// HTLC that was offered to us by the remote party. We use this witness
// in the case that the remote party goes to chain, and we know the
// pre-image to the HTLC. We can sweep this without any additional
// timeout.
HtlcAcceptedRemoteSuccess WitnessType = 8
) )
// WitnessGenerator represents a function which is able to generate the final // WitnessGenerator represents a function which is able to generate the final
@ -66,16 +86,31 @@ func (wt WitnessType) GenWitnessFunc(signer Signer,
switch wt { switch wt {
case CommitmentTimeLock: case CommitmentTimeLock:
return CommitSpendTimeout(signer, desc, tx) return CommitSpendTimeout(signer, desc, tx)
case CommitmentNoDelay: case CommitmentNoDelay:
return CommitSpendNoDelay(signer, desc, tx) return CommitSpendNoDelay(signer, desc, tx)
case CommitmentRevoke: case CommitmentRevoke:
return CommitSpendRevoke(signer, desc, tx) return CommitSpendRevoke(signer, desc, tx)
case HtlcOfferedRevoke: case HtlcOfferedRevoke:
return ReceiverHtlcSpendRevoke(signer, desc, tx) return ReceiverHtlcSpendRevoke(signer, desc, tx)
case HtlcAcceptedRevoke: case HtlcAcceptedRevoke:
return SenderHtlcSpendRevoke(signer, desc, tx) return SenderHtlcSpendRevoke(signer, desc, tx)
case HtlcOfferedTimeout:
return HtlcSpendSuccess(signer, desc, tx) case HtlcOfferedTimeoutSecondLevel:
return HtlcSecondLevelSpend(signer, desc, tx)
case HtlcAcceptedSuccessSecondLevel:
return HtlcSecondLevelSpend(signer, desc, tx)
case HtlcOfferedRemoteTimeout:
// We pass in a value of -1 for the timeout, as we
// expect the caller to have already set the lock time
// value.
return receiverHtlcSpendTimeout(signer, desc, tx, -1)
default: default:
return nil, fmt.Errorf("unknown witness type: %v", wt) return nil, fmt.Errorf("unknown witness type: %v", wt)
} }