watchtower/multi: embed TxPolicy in wtpolicy.Policy

This commit splits out the parameters that shape the justice transaction
into their own struct, which then embedded within the overarching
wtpolicy.Policy which may have additional parameters describing
operation of the session.

This is done as a preliminary step to support comparison of sessions
based on matching TxPolicy configurations. This prevents otherwise
identical Policies from being counted as different if operational
parameters like MaxUpdates differ, even if it has no material difference
to the justice transaction.
This commit is contained in:
Conner Fromknecht 2019-06-13 17:33:06 -07:00
parent 9b365567b6
commit 98c2d329e5
No known key found for this signature in database
GPG Key ID: E7D737B67FA592C7
6 changed files with 104 additions and 60 deletions

@ -156,9 +156,11 @@ func testJusticeDescriptor(t *testing.T, blobType blob.Type) {
// parameters that should be used in constructing the justice // parameters that should be used in constructing the justice
// transaction. // transaction.
policy := wtpolicy.Policy{ policy := wtpolicy.Policy{
TxPolicy: wtpolicy.TxPolicy{
BlobType: blobType, BlobType: blobType,
SweepFeeRate: 2000, SweepFeeRate: 2000,
RewardRate: 900000, RewardRate: 900000,
},
} }
sessionInfo := &wtdb.SessionInfo{ sessionInfo := &wtdb.SessionInfo{
Policy: policy, Policy: policy,

@ -96,7 +96,9 @@ func TestLookoutBreachMatching(t *testing.T) {
sessionInfo1 := &wtdb.SessionInfo{ sessionInfo1 := &wtdb.SessionInfo{
ID: makeArray33(1), ID: makeArray33(1),
Policy: wtpolicy.Policy{ Policy: wtpolicy.Policy{
TxPolicy: wtpolicy.TxPolicy{
BlobType: rewardAndCommitType, BlobType: rewardAndCommitType,
},
MaxUpdates: 10, MaxUpdates: 10,
}, },
RewardAddress: makeAddrSlice(22), RewardAddress: makeAddrSlice(22),
@ -104,7 +106,9 @@ func TestLookoutBreachMatching(t *testing.T) {
sessionInfo2 := &wtdb.SessionInfo{ sessionInfo2 := &wtdb.SessionInfo{
ID: makeArray33(2), ID: makeArray33(2),
Policy: wtpolicy.Policy{ Policy: wtpolicy.Policy{
TxPolicy: wtpolicy.TxPolicy{
BlobType: rewardAndCommitType, BlobType: rewardAndCommitType,
},
MaxUpdates: 10, MaxUpdates: 10,
}, },
RewardAddress: makeAddrSlice(22), RewardAddress: makeAddrSlice(22),

@ -207,10 +207,12 @@ func genTaskTest(
expRewardScript: rewardScript, expRewardScript: rewardScript,
session: &wtdb.ClientSessionBody{ session: &wtdb.ClientSessionBody{
Policy: wtpolicy.Policy{ Policy: wtpolicy.Policy{
TxPolicy: wtpolicy.TxPolicy{
BlobType: blobType, BlobType: blobType,
SweepFeeRate: sweepFeeRate, SweepFeeRate: sweepFeeRate,
RewardRate: 10000, RewardRate: 10000,
}, },
},
RewardPkScript: rewardScript, RewardPkScript: rewardScript,
}, },
bindErr: bindErr, bindErr: bindErr,

@ -785,10 +785,12 @@ var clientTests = []clientTest{
localBalance: localBalance, localBalance: localBalance,
remoteBalance: remoteBalance, remoteBalance: remoteBalance,
policy: wtpolicy.Policy{ policy: wtpolicy.Policy{
TxPolicy: wtpolicy.TxPolicy{
BlobType: blob.TypeDefault, BlobType: blob.TypeDefault,
MaxUpdates: 20000,
SweepFeeRate: 1, SweepFeeRate: 1,
}, },
MaxUpdates: 20000,
},
noRegisterChan0: true, noRegisterChan0: true,
}, },
fn: func(h *testHarness) { fn: func(h *testHarness) {
@ -817,10 +819,12 @@ var clientTests = []clientTest{
localBalance: localBalance, localBalance: localBalance,
remoteBalance: remoteBalance, remoteBalance: remoteBalance,
policy: wtpolicy.Policy{ policy: wtpolicy.Policy{
TxPolicy: wtpolicy.TxPolicy{
BlobType: blob.TypeDefault, BlobType: blob.TypeDefault,
MaxUpdates: 20000,
SweepFeeRate: 1, SweepFeeRate: 1,
}, },
MaxUpdates: 20000,
},
}, },
fn: func(h *testHarness) { fn: func(h *testHarness) {
const ( const (
@ -850,10 +854,12 @@ var clientTests = []clientTest{
localBalance: localBalance, localBalance: localBalance,
remoteBalance: remoteBalance, remoteBalance: remoteBalance,
policy: wtpolicy.Policy{ policy: wtpolicy.Policy{
TxPolicy: wtpolicy.TxPolicy{
BlobType: blob.TypeDefault, BlobType: blob.TypeDefault,
MaxUpdates: 5,
SweepFeeRate: 1, SweepFeeRate: 1,
}, },
MaxUpdates: 5,
},
}, },
fn: func(h *testHarness) { fn: func(h *testHarness) {
const ( const (
@ -884,10 +890,12 @@ var clientTests = []clientTest{
localBalance: localBalance, localBalance: localBalance,
remoteBalance: remoteBalance, remoteBalance: remoteBalance,
policy: wtpolicy.Policy{ policy: wtpolicy.Policy{
TxPolicy: wtpolicy.TxPolicy{
BlobType: blob.TypeDefault, BlobType: blob.TypeDefault,
MaxUpdates: 20000,
SweepFeeRate: 1000000, // high sweep fee creates dust SweepFeeRate: 1000000, // high sweep fee creates dust
}, },
MaxUpdates: 20000,
},
}, },
fn: func(h *testHarness) { fn: func(h *testHarness) {
const ( const (
@ -913,10 +921,12 @@ var clientTests = []clientTest{
localBalance: localBalance, localBalance: localBalance,
remoteBalance: remoteBalance, remoteBalance: remoteBalance,
policy: wtpolicy.Policy{ policy: wtpolicy.Policy{
TxPolicy: wtpolicy.TxPolicy{
BlobType: blob.TypeDefault, BlobType: blob.TypeDefault,
MaxUpdates: 20000,
SweepFeeRate: 1, SweepFeeRate: 1,
}, },
MaxUpdates: 20000,
},
}, },
fn: func(h *testHarness) { fn: func(h *testHarness) {
const ( const (
@ -993,10 +1003,12 @@ var clientTests = []clientTest{
localBalance: localBalance, localBalance: localBalance,
remoteBalance: remoteBalance, remoteBalance: remoteBalance,
policy: wtpolicy.Policy{ policy: wtpolicy.Policy{
TxPolicy: wtpolicy.TxPolicy{
BlobType: blob.TypeDefault, BlobType: blob.TypeDefault,
MaxUpdates: 5,
SweepFeeRate: 1, SweepFeeRate: 1,
}, },
MaxUpdates: 5,
},
}, },
fn: func(h *testHarness) { fn: func(h *testHarness) {
const ( const (
@ -1049,10 +1061,12 @@ var clientTests = []clientTest{
localBalance: 10000001, // ensure (% amt != 0) localBalance: 10000001, // ensure (% amt != 0)
remoteBalance: 20000001, // ensure (% amt != 0) remoteBalance: 20000001, // ensure (% amt != 0)
policy: wtpolicy.Policy{ policy: wtpolicy.Policy{
TxPolicy: wtpolicy.TxPolicy{
BlobType: blob.TypeDefault, BlobType: blob.TypeDefault,
MaxUpdates: 1000,
SweepFeeRate: 1, SweepFeeRate: 1,
}, },
MaxUpdates: 1000,
},
}, },
fn: func(h *testHarness) { fn: func(h *testHarness) {
var ( var (
@ -1091,10 +1105,12 @@ var clientTests = []clientTest{
localBalance: localBalance, localBalance: localBalance,
remoteBalance: remoteBalance, remoteBalance: remoteBalance,
policy: wtpolicy.Policy{ policy: wtpolicy.Policy{
TxPolicy: wtpolicy.TxPolicy{
BlobType: blob.TypeDefault, BlobType: blob.TypeDefault,
MaxUpdates: 5,
SweepFeeRate: 1, SweepFeeRate: 1,
}, },
MaxUpdates: 5,
},
}, },
fn: func(h *testHarness) { fn: func(h *testHarness) {
const ( const (
@ -1139,10 +1155,12 @@ var clientTests = []clientTest{
localBalance: localBalance, localBalance: localBalance,
remoteBalance: remoteBalance, remoteBalance: remoteBalance,
policy: wtpolicy.Policy{ policy: wtpolicy.Policy{
TxPolicy: wtpolicy.TxPolicy{
BlobType: blob.TypeDefault, BlobType: blob.TypeDefault,
MaxUpdates: 5,
SweepFeeRate: 1, SweepFeeRate: 1,
}, },
MaxUpdates: 5,
},
noAckCreateSession: true, noAckCreateSession: true,
}, },
fn: func(h *testHarness) { fn: func(h *testHarness) {
@ -1195,10 +1213,12 @@ var clientTests = []clientTest{
localBalance: localBalance, localBalance: localBalance,
remoteBalance: remoteBalance, remoteBalance: remoteBalance,
policy: wtpolicy.Policy{ policy: wtpolicy.Policy{
TxPolicy: wtpolicy.TxPolicy{
BlobType: blob.TypeDefault, BlobType: blob.TypeDefault,
MaxUpdates: 5,
SweepFeeRate: 1, SweepFeeRate: 1,
}, },
MaxUpdates: 5,
},
noAckCreateSession: true, noAckCreateSession: true,
}, },
fn: func(h *testHarness) { fn: func(h *testHarness) {
@ -1256,10 +1276,12 @@ var clientTests = []clientTest{
localBalance: localBalance, localBalance: localBalance,
remoteBalance: remoteBalance, remoteBalance: remoteBalance,
policy: wtpolicy.Policy{ policy: wtpolicy.Policy{
TxPolicy: wtpolicy.TxPolicy{
BlobType: blob.TypeDefault, BlobType: blob.TypeDefault,
MaxUpdates: 5,
SweepFeeRate: 1, SweepFeeRate: 1,
}, },
MaxUpdates: 5,
},
}, },
fn: func(h *testHarness) { fn: func(h *testHarness) {
const ( const (

@ -49,28 +49,28 @@ var (
// used by clients or servers. // used by clients or servers.
func DefaultPolicy() Policy { func DefaultPolicy() Policy {
return Policy{ return Policy{
TxPolicy: TxPolicy{
BlobType: blob.TypeDefault, BlobType: blob.TypeDefault,
MaxUpdates: DefaultMaxUpdates,
RewardRate: DefaultRewardRate, RewardRate: DefaultRewardRate,
SweepFeeRate: lnwallet.SatPerKWeight( SweepFeeRate: lnwallet.SatPerKWeight(
DefaultSweepFeeRate, DefaultSweepFeeRate,
), ),
},
MaxUpdates: DefaultMaxUpdates,
} }
} }
// Policy defines the negotiated parameters for a session between a client and // TxPolicy defines the negotiate parameters that determine the form of the
// server. The parameters specify the format of encrypted blobs sent to the // justice transaction for a given breached state. Thus, for any given revoked
// tower, the reward schedule for the tower, and the number of encrypted blobs a // state, an identical key will result in an identical justice transaction
// client can send in one session. // (barring signatures). The parameters specify the format of encrypted blobs
type Policy struct { // sent to the tower, the reward schedule for the tower, and the number of
// encrypted blobs a client can send in one session.
type TxPolicy struct {
// BlobType specifies the blob format that must be used by all updates sent // BlobType specifies the blob format that must be used by all updates sent
// under the session key used to negotiate this session. // under the session key used to negotiate this session.
BlobType blob.Type BlobType blob.Type
// MaxUpdates is the maximum number of updates the watchtower will honor
// for this session.
MaxUpdates uint16
// RewardBase is the fixed amount allocated to the tower when the // RewardBase is the fixed amount allocated to the tower when the
// policy's blob type specifies a reward for the tower. This is taken // policy's blob type specifies a reward for the tower. This is taken
// before adding the proportional reward. // before adding the proportional reward.
@ -88,6 +88,18 @@ type Policy struct {
SweepFeeRate lnwallet.SatPerKWeight SweepFeeRate lnwallet.SatPerKWeight
} }
// Policy defines the negotiated parameters for a session between a client and
// server. In addition to the TxPolicy that governs the shape of the justice
// transaction, the Policy also includes features which only affect the
// operation of the session.
type Policy struct {
TxPolicy
// MaxUpdates is the maximum number of updates the watchtower will honor
// for this session.
MaxUpdates uint16
}
// String returns a human-readable description of the current policy. // String returns a human-readable description of the current policy.
func (p Policy) String() string { func (p Policy) String() string {
return fmt.Sprintf("(blob-type=%b max-updates=%d reward-rate=%d "+ return fmt.Sprintf("(blob-type=%b max-updates=%d reward-rate=%d "+

@ -89,12 +89,14 @@ func (s *Server) handleCreateSession(peer Peer, id *wtdb.SessionID,
info := wtdb.SessionInfo{ info := wtdb.SessionInfo{
ID: *id, ID: *id,
Policy: wtpolicy.Policy{ Policy: wtpolicy.Policy{
TxPolicy: wtpolicy.TxPolicy{
BlobType: req.BlobType, BlobType: req.BlobType,
MaxUpdates: req.MaxUpdates,
RewardBase: req.RewardBase, RewardBase: req.RewardBase,
RewardRate: req.RewardRate, RewardRate: req.RewardRate,
SweepFeeRate: req.SweepFeeRate, SweepFeeRate: req.SweepFeeRate,
}, },
MaxUpdates: req.MaxUpdates,
},
RewardAddress: rewardScript, RewardAddress: rewardScript,
} }