watchtower: add new TaprootCommit Type and flag

This commit adds a new FlagTaprootChannel Flag which is then used to
construct a new blob Type: TypeAltruistTaprootCommit. New watchtower
feature bits are also added (4/5).
This commit is contained in:
Elle Mouton 2023-05-19 11:18:22 +02:00
parent fde982ad78
commit 20a107600f
No known key found for this signature in database
GPG key ID: D7D916376026F177
5 changed files with 82 additions and 24 deletions

View file

@ -26,6 +26,10 @@ const (
// channel, and therefore must expect a P2WSH-style to-remote output if
// one exists.
FlagAnchorChannel Flag = 1 << 2
// FlagTaprootChannel signals that this blob is meant to spend a
// taproot channel and therefore must expect P2TR outputs.
FlagTaprootChannel Flag = 1 << 3
)
// Type returns a Type consisting solely of this flag enabled.
@ -42,6 +46,8 @@ func (f Flag) String() string {
return "FlagCommitOutputs"
case FlagAnchorChannel:
return "FlagAnchorChannel"
case FlagTaprootChannel:
return "FlagTaprootChannel"
default:
return "FlagUnknown"
}
@ -67,6 +73,11 @@ const (
// TypeRewardCommit sweeps only commitment outputs to a sweep address
// controlled by the user, and pays a negotiated reward to the tower.
TypeRewardCommit = Type(FlagCommitOutputs | FlagReward)
// TypeAltruistTaprootCommit sweeps only the commitment outputs from a
// taproot channel commitment to a sweep address controlled by the user,
// and does not give the tower a reward.
TypeAltruistTaprootCommit = Type(FlagCommitOutputs | FlagTaprootChannel)
)
// Identifier returns a unique, stable string identifier for the blob Type.
@ -78,6 +89,8 @@ func (t Type) Identifier() (string, error) {
return "anchor", nil
case TypeRewardCommit:
return "reward", nil
case TypeAltruistTaprootCommit:
return "taproot", nil
default:
return "", fmt.Errorf("unknown blob type: %v", t)
}
@ -124,14 +137,20 @@ func (t Type) IsAnchorChannel() bool {
return t.Has(FlagAnchorChannel)
}
// knownFlags maps the supported flags to their name.
var knownFlags = map[Flag]struct{}{
FlagReward: {},
FlagCommitOutputs: {},
FlagAnchorChannel: {},
// IsTaprootChannel returns true if the blob type is for a taproot channel.
func (t Type) IsTaprootChannel() bool {
return t.Has(FlagTaprootChannel)
}
// String returns a human readable description of a Type.
// knownFlags maps the supported flags to their name.
var knownFlags = map[Flag]struct{}{
FlagReward: {},
FlagCommitOutputs: {},
FlagAnchorChannel: {},
FlagTaprootChannel: {},
}
// String returns a human-readable description of a Type.
func (t Type) String() string {
var (
hrPieces []string
@ -175,9 +194,10 @@ func (t Type) String() string {
// supportedTypes is the set of all configurations known to be supported by the
// package.
var supportedTypes = map[Type]struct{}{
TypeAltruistCommit: {},
TypeRewardCommit: {},
TypeAltruistAnchorCommit: {},
TypeAltruistCommit: {},
TypeRewardCommit: {},
TypeAltruistAnchorCommit: {},
TypeAltruistTaprootCommit: {},
}
// IsSupportedType returns true if the given type is supported by the package.

View file

@ -16,19 +16,28 @@ type typeStringTest struct {
var typeStringTests = []typeStringTest{
{
name: "commit no-reward",
typ: blob.TypeAltruistCommit,
expStr: "[No-FlagAnchorChannel|FlagCommitOutputs|No-FlagReward]",
name: "commit no-reward",
typ: blob.TypeAltruistCommit,
expStr: "[No-FlagTaprootChannel|" +
"No-FlagAnchorChannel|" +
"FlagCommitOutputs|" +
"No-FlagReward]",
},
{
name: "commit reward",
typ: blob.TypeRewardCommit,
expStr: "[No-FlagAnchorChannel|FlagCommitOutputs|FlagReward]",
name: "commit reward",
typ: blob.TypeRewardCommit,
expStr: "[No-FlagTaprootChannel|" +
"No-FlagAnchorChannel|" +
"FlagCommitOutputs|" +
"FlagReward]",
},
{
name: "unknown flag",
typ: unknownFlag.Type(),
expStr: "0000000000010000[No-FlagAnchorChannel|No-FlagCommitOutputs|No-FlagReward]",
name: "unknown flag",
typ: unknownFlag.Type(),
expStr: "0000000000010000[No-FlagTaprootChannel|" +
"No-FlagAnchorChannel|" +
"No-FlagCommitOutputs|" +
"No-FlagReward]",
},
}

View file

@ -125,6 +125,12 @@ func (p Policy) IsAnchorChannel() bool {
return p.TxPolicy.BlobType.IsAnchorChannel()
}
// IsTaprootChannel returns true if the session policy requires taproot
// channels.
func (p Policy) IsTaprootChannel() bool {
return p.TxPolicy.BlobType.IsTaprootChannel()
}
// Validate ensures that the policy satisfies some minimal correctness
// constraints.
func (p Policy) Validate() error {

View file

@ -93,20 +93,32 @@ func TestPolicyValidate(t *testing.T) {
}
}
// TestPolicyIsAnchorChannel asserts that the IsAnchorChannel helper properly
// reflects the anchor bit of the policy's blob type.
func TestPolicyIsAnchorChannel(t *testing.T) {
policyNoAnchor := wtpolicy.Policy{
// TestPolicyIsChannelType asserts that the IsAnchorChannel and IsTaprootChannel
// helpers properly reflect the anchor bit of the policy's blob type.
func TestPolicyIsChannelType(t *testing.T) {
t.Parallel()
policyLegacy := wtpolicy.Policy{
TxPolicy: wtpolicy.TxPolicy{
BlobType: blob.TypeAltruistCommit,
},
}
require.Equal(t, false, policyNoAnchor.IsAnchorChannel())
require.False(t, policyLegacy.IsAnchorChannel())
require.False(t, policyLegacy.IsTaprootChannel())
policyAnchor := wtpolicy.Policy{
TxPolicy: wtpolicy.TxPolicy{
BlobType: blob.TypeAltruistAnchorCommit,
},
}
require.Equal(t, true, policyAnchor.IsAnchorChannel())
require.True(t, policyAnchor.IsAnchorChannel())
require.False(t, policyAnchor.IsTaprootChannel())
policyTaproot := wtpolicy.Policy{
TxPolicy: wtpolicy.TxPolicy{
BlobType: blob.TypeAltruistTaprootCommit,
},
}
require.True(t, policyTaproot.IsTaprootChannel())
require.False(t, policyTaproot.IsAnchorChannel())
}

View file

@ -9,6 +9,8 @@ var FeatureNames = map[lnwire.FeatureBit]string{
AltruistSessionsOptional: "altruist-sessions",
AnchorCommitRequired: "anchor-commit",
AnchorCommitOptional: "anchor-commit",
TaprootCommitRequired: "taproot-commit",
TaprootCommitOptional: "taproot-commit",
}
const (
@ -30,4 +32,13 @@ const (
// AnchorCommitOptional specifies that the advertising tower allows the
// remote party to negotiate sessions for protecting anchor channels.
AnchorCommitOptional lnwire.FeatureBit = 3
// TaprootCommitRequired specifies that the advertising tower requires
// the remote party to negotiate sessions for protecting taproot
// channels.
TaprootCommitRequired lnwire.FeatureBit = 4
// TaprootCommitOptional specifies that the advertising tower allows the
// remote party to negotiate sessions for protecting taproot channels.
TaprootCommitOptional lnwire.FeatureBit = 5
)