Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions input/witnessgen.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ type StandardWitnessType uint16
// WitnessType interface.
var _ WitnessType = (StandardWitnessType)(0)

// NOTE: When adding a new `StandardWitnessType`, also update the `WitnessType`
// protobuf enum and the `allWitnessTypes` map in the `walletrpc` package.
const (
// CommitmentTimeLock is a witness that allows us to spend our output
// on our local commitment transaction after a relative lock-time
Expand Down
381 changes: 233 additions & 148 deletions lnrpc/walletrpc/walletkit.pb.go

Large diffs are not rendered by default.

70 changes: 70 additions & 0 deletions lnrpc/walletrpc/walletkit.proto
Original file line number Diff line number Diff line change
Expand Up @@ -863,6 +863,76 @@ enum WitnessType {
transaction.
*/
COMMITMENT_ANCHOR = 13;

/*
A witness type that is similar to the COMMITMENT_NO_DELAY type,
but it omits the tweak that randomizes the key we need to
spend with a channel peer supplied set of randomness.
*/
COMMITMENT_NO_DELAY_TWEAKLESS = 14;

/*
A witness type that allows us to spend our output on the counterparty's
commitment transaction after a confirmation.
*/
COMMITMENT_TO_REMOTE_CONFIRMED = 15;

/*
A witness type that allows us to sweep an HTLC output that we extended
to a party, but was never fulfilled. This _is_ the HTLC output directly
on our commitment transaction, and the input to the second-level HTLC
timeout transaction. It can only be spent after CLTV expiry, and
commitment confirmation.
*/
HTLC_OFFERED_TIMEOUT_SECOND_LEVEL_INPUT_CONFIRMED = 16;

/*
A witness type that allows us to sweep an HTLC output that was offered
to us, and for which we have a payment preimage. This _is_ the HTLC
output directly on our commitment transaction, and the input to the
second-level HTLC success transaction. It can only be spent after the
commitment has confirmed.
*/
HTLC_ACCEPTED_SUCCESS_SECOND_LEVEL_INPUT_CONFIRMED = 17;

/*
A witness type that allows us to spend our output on our local
commitment transaction after a relative and absolute lock-time lockout as
part of the script enforced lease commitment type.
*/
LEASE_COMMITMENT_TIME_LOCK = 18;

/*
A witness type that allows us to spend our output on the counterparty's
commitment transaction after a confirmation and absolute locktime as part
of the script enforced lease commitment type.
*/
LEASE_COMMITMENT_TO_REMOTE_CONFIRMED = 19;

/*
A witness type that allows us to sweep an HTLC output that we extended
to a party, but was never fulfilled. 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
and CLTV locktime as part of the script enforced lease commitment type.
*/
LEASE_HTLC_OFFERED_TIMEOUT_SECOND_LEVEL = 20;

/*
A witness type that allows us to sweep an HTLC output that was offered
to us, and for which we have a payment preimage. This HTLC output isn't
directly on our commitment transaction, but is the result of confirmed
second-level HTLC transaction. As a result, we can only spend this after
a CSV delay and CLTV locktime as part of the script enforced lease
commitment type.
*/
LEASE_HTLC_ACCEPTED_SUCCESS_SECOND_LEVEL = 21;

/*
A witness type that allows us to spend a regular p2tr output that's sent
to an output which is under complete control of the backing wallet.
*/
TAPROOT_PUB_KEY_SPEND = 22;
}

message PendingSweep {
Expand Down
13 changes: 11 additions & 2 deletions lnrpc/walletrpc/walletkit.swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -1998,10 +1998,19 @@
"HTLC_SECOND_LEVEL_REVOKE",
"WITNESS_KEY_HASH",
"NESTED_WITNESS_KEY_HASH",
"COMMITMENT_ANCHOR"
"COMMITMENT_ANCHOR",
"COMMITMENT_NO_DELAY_TWEAKLESS",
"COMMITMENT_TO_REMOTE_CONFIRMED",
"HTLC_OFFERED_TIMEOUT_SECOND_LEVEL_INPUT_CONFIRMED",
"HTLC_ACCEPTED_SUCCESS_SECOND_LEVEL_INPUT_CONFIRMED",
"LEASE_COMMITMENT_TIME_LOCK",
"LEASE_COMMITMENT_TO_REMOTE_CONFIRMED",
"LEASE_HTLC_OFFERED_TIMEOUT_SECOND_LEVEL",
"LEASE_HTLC_ACCEPTED_SUCCESS_SECOND_LEVEL",
"TAPROOT_PUB_KEY_SPEND"
],
"default": "UNKNOWN_WITNESS",
"description": " - COMMITMENT_TIME_LOCK: A witness that allows us to spend the output of a commitment transaction\nafter a relative lock-time lockout.\n - COMMITMENT_NO_DELAY: A witness that allows us to spend a settled no-delay output immediately on a\ncounterparty's commitment transaction.\n - COMMITMENT_REVOKE: A witness that allows us to sweep the settled output of a malicious\ncounterparty's who broadcasts a revoked commitment transaction.\n - HTLC_OFFERED_REVOKE: A witness that allows us to sweep an HTLC which we offered to the remote\nparty in the case that they broadcast a revoked commitment state.\n - HTLC_ACCEPTED_REVOKE: A witness that allows us to sweep an HTLC output sent to us in the case that\nthe remote party broadcasts a revoked commitment state.\n - HTLC_OFFERED_TIMEOUT_SECOND_LEVEL: A witness that allows us to sweep an HTLC output that we extended to a\nparty, but was never fulfilled. This HTLC output isn't directly on the\ncommitment transaction, but is the result of a confirmed second-level HTLC\ntransaction. As a result, we can only spend this after a CSV delay.\n - HTLC_ACCEPTED_SUCCESS_SECOND_LEVEL: A witness that allows us to sweep an HTLC output that was offered to us, and\nfor which we have a payment preimage. This HTLC output isn't directly on our\ncommitment transaction, but is the result of confirmed second-level HTLC\ntransaction. As a result, we can only spend this after a CSV delay.\n - HTLC_OFFERED_REMOTE_TIMEOUT: A witness that allows us to sweep an HTLC that we offered to the remote\nparty which lies in the commitment transaction of the remote party. We can\nspend this output after the absolute CLTV timeout of the HTLC as passed.\n - HTLC_ACCEPTED_REMOTE_SUCCESS: A witness that allows us to sweep an HTLC that was offered to us by the\nremote party. We use this witness in the case that the remote party goes to\nchain, and we know the pre-image to the HTLC. We can sweep this without any\nadditional timeout.\n - HTLC_SECOND_LEVEL_REVOKE: A witness that allows us to sweep an HTLC from the remote party's commitment\ntransaction in the case that the broadcast a revoked commitment, but then\nalso immediately attempt to go to the second level to claim the HTLC.\n - WITNESS_KEY_HASH: A witness type that allows us to spend a regular p2wkh output that's sent to\nan output which is under complete control of the backing wallet.\n - NESTED_WITNESS_KEY_HASH: A witness type that allows us to sweep an output that sends to a nested P2SH\nscript that pays to a key solely under our control.\n - COMMITMENT_ANCHOR: A witness type that allows us to spend our anchor on the commitment\ntransaction."
"description": " - COMMITMENT_TIME_LOCK: A witness that allows us to spend the output of a commitment transaction\nafter a relative lock-time lockout.\n - COMMITMENT_NO_DELAY: A witness that allows us to spend a settled no-delay output immediately on a\ncounterparty's commitment transaction.\n - COMMITMENT_REVOKE: A witness that allows us to sweep the settled output of a malicious\ncounterparty's who broadcasts a revoked commitment transaction.\n - HTLC_OFFERED_REVOKE: A witness that allows us to sweep an HTLC which we offered to the remote\nparty in the case that they broadcast a revoked commitment state.\n - HTLC_ACCEPTED_REVOKE: A witness that allows us to sweep an HTLC output sent to us in the case that\nthe remote party broadcasts a revoked commitment state.\n - HTLC_OFFERED_TIMEOUT_SECOND_LEVEL: A witness that allows us to sweep an HTLC output that we extended to a\nparty, but was never fulfilled. This HTLC output isn't directly on the\ncommitment transaction, but is the result of a confirmed second-level HTLC\ntransaction. As a result, we can only spend this after a CSV delay.\n - HTLC_ACCEPTED_SUCCESS_SECOND_LEVEL: A witness that allows us to sweep an HTLC output that was offered to us, and\nfor which we have a payment preimage. This HTLC output isn't directly on our\ncommitment transaction, but is the result of confirmed second-level HTLC\ntransaction. As a result, we can only spend this after a CSV delay.\n - HTLC_OFFERED_REMOTE_TIMEOUT: A witness that allows us to sweep an HTLC that we offered to the remote\nparty which lies in the commitment transaction of the remote party. We can\nspend this output after the absolute CLTV timeout of the HTLC as passed.\n - HTLC_ACCEPTED_REMOTE_SUCCESS: A witness that allows us to sweep an HTLC that was offered to us by the\nremote party. We use this witness in the case that the remote party goes to\nchain, and we know the pre-image to the HTLC. We can sweep this without any\nadditional timeout.\n - HTLC_SECOND_LEVEL_REVOKE: A witness that allows us to sweep an HTLC from the remote party's commitment\ntransaction in the case that the broadcast a revoked commitment, but then\nalso immediately attempt to go to the second level to claim the HTLC.\n - WITNESS_KEY_HASH: A witness type that allows us to spend a regular p2wkh output that's sent to\nan output which is under complete control of the backing wallet.\n - NESTED_WITNESS_KEY_HASH: A witness type that allows us to sweep an output that sends to a nested P2SH\nscript that pays to a key solely under our control.\n - COMMITMENT_ANCHOR: A witness type that allows us to spend our anchor on the commitment\ntransaction.\n - COMMITMENT_NO_DELAY_TWEAKLESS: A witness type that is similar to the COMMITMENT_NO_DELAY type,\nbut it omits the tweak that randomizes the key we need to\nspend with a channel peer supplied set of randomness.\n - COMMITMENT_TO_REMOTE_CONFIRMED: A witness type that allows us to spend our output on the counterparty's\ncommitment transaction after a confirmation.\n - HTLC_OFFERED_TIMEOUT_SECOND_LEVEL_INPUT_CONFIRMED: A witness type that allows us to sweep an HTLC output that we extended\nto a party, but was never fulfilled. This _is_ the HTLC output directly\non our commitment transaction, and the input to the second-level HTLC\ntimeout transaction. It can only be spent after CLTV expiry, and\ncommitment confirmation.\n - HTLC_ACCEPTED_SUCCESS_SECOND_LEVEL_INPUT_CONFIRMED: A witness type that allows us to sweep an HTLC output that was offered\nto us, and for which we have a payment preimage. This _is_ the HTLC\noutput directly on our commitment transaction, and the input to the\nsecond-level HTLC success transaction. It can only be spent after the\ncommitment has confirmed.\n - LEASE_COMMITMENT_TIME_LOCK: A witness type that allows us to spend our output on our local\ncommitment transaction after a relative and absolute lock-time lockout as\npart of the script enforced lease commitment type.\n - LEASE_COMMITMENT_TO_REMOTE_CONFIRMED: A witness type that allows us to spend our output on the counterparty's\ncommitment transaction after a confirmation and absolute locktime as part\nof the script enforced lease commitment type.\n - LEASE_HTLC_OFFERED_TIMEOUT_SECOND_LEVEL: A witness type that allows us to sweep an HTLC output that we extended\nto a party, but was never fulfilled. This HTLC output isn't directly on\nthe commitment transaction, but is the result of a confirmed second-level\nHTLC transaction. As a result, we can only spend this after a CSV delay\nand CLTV locktime as part of the script enforced lease commitment type.\n - LEASE_HTLC_ACCEPTED_SUCCESS_SECOND_LEVEL: A witness type that allows us to sweep an HTLC output that was offered\nto us, and for which we have a payment preimage. This HTLC output isn't\ndirectly on our commitment transaction, but is the result of confirmed\nsecond-level HTLC transaction. As a result, we can only spend this after\na CSV delay and CLTV locktime as part of the script enforced lease\ncommitment type.\n - TAPROOT_PUB_KEY_SPEND: A witness type that allows us to spend a regular p2tr output that's sent\nto an output which is under complete control of the backing wallet."
}
}
}
70 changes: 39 additions & 31 deletions lnrpc/walletrpc/walletkit_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,40 @@ var (
0x82, 0x54, 0x5d, 0x4b, 0xb4, 0xfa, 0xe0, 0x8b,
0xd5, 0x93, 0x78, 0x31, 0xb7, 0xe3, 0x8f, 0x98,
}

// allWitnessTypes is a mapping between the witness types defined in the
// `input` package, and the witness types in the protobuf definition.
// This map is necessary because the native enum and the protobuf enum
// are numbered differently. The protobuf enum cannot be renumbered
// because this would break backwards compatibility with older clients,
// and the native enum cannot be renumbered because it is stored in the
// watchtower and breacharbiter databases.
//
//nolint:lll
allWitnessTypes = map[input.WitnessType]WitnessType{
input.CommitmentTimeLock: WitnessType_COMMITMENT_TIME_LOCK,
input.CommitmentNoDelay: WitnessType_COMMITMENT_NO_DELAY,
input.CommitmentRevoke: WitnessType_COMMITMENT_REVOKE,
input.HtlcOfferedRevoke: WitnessType_HTLC_OFFERED_REVOKE,
input.HtlcAcceptedRevoke: WitnessType_HTLC_ACCEPTED_REVOKE,
input.HtlcOfferedTimeoutSecondLevel: WitnessType_HTLC_OFFERED_TIMEOUT_SECOND_LEVEL,
input.HtlcAcceptedSuccessSecondLevel: WitnessType_HTLC_ACCEPTED_SUCCESS_SECOND_LEVEL,
input.HtlcOfferedRemoteTimeout: WitnessType_HTLC_OFFERED_REMOTE_TIMEOUT,
input.HtlcAcceptedRemoteSuccess: WitnessType_HTLC_ACCEPTED_REMOTE_SUCCESS,
input.HtlcSecondLevelRevoke: WitnessType_HTLC_SECOND_LEVEL_REVOKE,
input.WitnessKeyHash: WitnessType_WITNESS_KEY_HASH,
input.NestedWitnessKeyHash: WitnessType_NESTED_WITNESS_KEY_HASH,
input.CommitmentAnchor: WitnessType_COMMITMENT_ANCHOR,
input.HtlcOfferedTimeoutSecondLevelInputConfirmed: WitnessType_HTLC_OFFERED_TIMEOUT_SECOND_LEVEL_INPUT_CONFIRMED,
input.HtlcAcceptedSuccessSecondLevelInputConfirmed: WitnessType_HTLC_ACCEPTED_SUCCESS_SECOND_LEVEL_INPUT_CONFIRMED,
input.CommitSpendNoDelayTweakless: WitnessType_COMMITMENT_NO_DELAY_TWEAKLESS,
input.CommitmentToRemoteConfirmed: WitnessType_COMMITMENT_TO_REMOTE_CONFIRMED,
input.LeaseCommitmentTimeLock: WitnessType_LEASE_COMMITMENT_TIME_LOCK,
input.LeaseCommitmentToRemoteConfirmed: WitnessType_LEASE_COMMITMENT_TO_REMOTE_CONFIRMED,
input.LeaseHtlcOfferedTimeoutSecondLevel: WitnessType_LEASE_HTLC_OFFERED_TIMEOUT_SECOND_LEVEL,
input.LeaseHtlcAcceptedSuccessSecondLevel: WitnessType_LEASE_HTLC_ACCEPTED_SUCCESS_SECOND_LEVEL,
input.TaprootPubKeySpend: WitnessType_TAPROOT_PUB_KEY_SPEND,
}
)

// ErrZeroLabel is returned when an attempt is made to label a transaction with
Expand Down Expand Up @@ -715,37 +749,11 @@ func (w *WalletKit) PendingSweeps(ctx context.Context,
// Convert them into their respective RPC format.
rpcPendingSweeps := make([]*PendingSweep, 0, len(pendingInputs))
for _, pendingInput := range pendingInputs {
var witnessType WitnessType
switch pendingInput.WitnessType {
case input.CommitmentTimeLock:
witnessType = WitnessType_COMMITMENT_TIME_LOCK
case input.CommitmentNoDelay:
witnessType = WitnessType_COMMITMENT_NO_DELAY
case input.CommitmentRevoke:
witnessType = WitnessType_COMMITMENT_REVOKE
case input.HtlcOfferedRevoke:
witnessType = WitnessType_HTLC_OFFERED_REVOKE
case input.HtlcAcceptedRevoke:
witnessType = WitnessType_HTLC_ACCEPTED_REVOKE
case input.HtlcOfferedTimeoutSecondLevel:
witnessType = WitnessType_HTLC_OFFERED_TIMEOUT_SECOND_LEVEL
case input.HtlcAcceptedSuccessSecondLevel:
witnessType = WitnessType_HTLC_ACCEPTED_SUCCESS_SECOND_LEVEL
case input.HtlcOfferedRemoteTimeout:
witnessType = WitnessType_HTLC_OFFERED_REMOTE_TIMEOUT
case input.HtlcAcceptedRemoteSuccess:
witnessType = WitnessType_HTLC_ACCEPTED_REMOTE_SUCCESS
case input.HtlcSecondLevelRevoke:
witnessType = WitnessType_HTLC_SECOND_LEVEL_REVOKE
case input.WitnessKeyHash:
witnessType = WitnessType_WITNESS_KEY_HASH
case input.NestedWitnessKeyHash:
witnessType = WitnessType_NESTED_WITNESS_KEY_HASH
case input.CommitmentAnchor:
witnessType = WitnessType_COMMITMENT_ANCHOR
default:
log.Warnf("Unhandled witness type %v for input %v",
pendingInput.WitnessType, pendingInput.OutPoint)
witnessType, ok := allWitnessTypes[pendingInput.WitnessType]
if !ok {
return nil, fmt.Errorf("unhandled witness type %v for "+
"input %v", pendingInput.WitnessType,
pendingInput.OutPoint)
}

op := &lnrpc.OutPoint{
Expand Down
50 changes: 50 additions & 0 deletions lnrpc/walletrpc/walletkit_server_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
//go:build walletrpc
// +build walletrpc

package walletrpc

import (
"strings"
"testing"

"github.com/stretchr/testify/require"
)

// TestWitnessTypeMapping tests that the two witness type enums in the `input`
// package and the `walletrpc` package remain equal.
func TestWitnessTypeMapping(t *testing.T) {
t.Parallel()

// Tests that both enum types have the same length except the
// UNKNOWN_WITNESS type which is only present in the walletrpc
// witness type enum.
require.Equal(
t, len(allWitnessTypes), len(WitnessType_name)-1,
"number of witness types should match proto definition",
)

// Tests that the string representations of both enum types are
// equivalent.
for witnessType, witnessTypeProto := range allWitnessTypes {
// Redeclare to avoid loop variables being captured
// by func literal.
witnessType := witnessType
witnessTypeProto := witnessTypeProto

t.Run(witnessType.String(), func(tt *testing.T) {
tt.Parallel()

witnessTypeName := witnessType.String()
witnessTypeName = strings.ToUpper(witnessTypeName)
witnessTypeProtoName := witnessTypeProto.String()
witnessTypeProtoName = strings.ReplaceAll(
witnessTypeProtoName, "_", "",
)

require.Equal(
t, witnessTypeName, witnessTypeProtoName,
"mapped witness types should be named the same",
)
})
}
}