wtclinet+itest: expose anchor client via rpc + add itest

This commit is contained in:
Conner Fromknecht 2020-11-25 15:08:30 -08:00
parent 5b3a08a1cd
commit b28bbc3223
No known key found for this signature in database
GPG Key ID: E7D737B67FA592C7
2 changed files with 90 additions and 9 deletions

@ -14,6 +14,8 @@ import (
"github.com/lightningnetwork/lnd/lnwire"
"github.com/lightningnetwork/lnd/watchtower"
"github.com/lightningnetwork/lnd/watchtower/wtclient"
"github.com/lightningnetwork/lnd/watchtower/wtdb"
"github.com/lightningnetwork/lnd/watchtower/wtpolicy"
"google.golang.org/grpc"
"gopkg.in/macaroon-bakery.v2/bakery"
)
@ -176,9 +178,14 @@ func (c *WatchtowerClient) AddTower(ctx context.Context,
IdentityKey: pubKey,
Address: addr,
}
// TODO(conner): make atomic via multiplexed client
if err := c.cfg.Client.AddTower(towerAddr); err != nil {
return nil, err
}
if err := c.cfg.AnchorClient.AddTower(towerAddr); err != nil {
return nil, err
}
return &AddTowerResponse{}, nil
}
@ -211,7 +218,13 @@ func (c *WatchtowerClient) RemoveTower(ctx context.Context,
}
}
if err := c.cfg.Client.RemoveTower(pubKey, addr); err != nil {
// TODO(conner): make atomic via multiplexed client
err = c.cfg.Client.RemoveTower(pubKey, addr)
if err != nil {
return nil, err
}
err = c.cfg.AnchorClient.RemoveTower(pubKey, addr)
if err != nil {
return nil, err
}
@ -226,11 +239,25 @@ func (c *WatchtowerClient) ListTowers(ctx context.Context,
return nil, err
}
towers, err := c.cfg.Client.RegisteredTowers()
anchorTowers, err := c.cfg.AnchorClient.RegisteredTowers()
if err != nil {
return nil, err
}
legacyTowers, err := c.cfg.Client.RegisteredTowers()
if err != nil {
return nil, err
}
// Filter duplicates.
towers := make(map[wtdb.TowerID]*wtclient.RegisteredTower)
for _, tower := range anchorTowers {
towers[tower.Tower.ID] = tower
}
for _, tower := range legacyTowers {
towers[tower.Tower.ID] = tower
}
rpcTowers := make([]*Tower, 0, len(towers))
for _, tower := range towers {
rpcTower := marshallTower(tower, req.IncludeSessions)
@ -253,7 +280,11 @@ func (c *WatchtowerClient) GetTowerInfo(ctx context.Context,
return nil, err
}
tower, err := c.cfg.Client.LookupTower(pubKey)
var tower *wtclient.RegisteredTower
tower, err = c.cfg.Client.LookupTower(pubKey)
if err == wtdb.ErrTowerNotFound {
tower, err = c.cfg.AnchorClient.LookupTower(pubKey)
}
if err != nil {
return nil, err
}
@ -269,7 +300,24 @@ func (c *WatchtowerClient) Stats(ctx context.Context,
return nil, err
}
stats := c.cfg.Client.Stats()
clientStats := []wtclient.ClientStats{
c.cfg.Client.Stats(),
c.cfg.AnchorClient.Stats(),
}
var stats wtclient.ClientStats
for i := range clientStats {
// Grab a reference to the slice index rather than copying bc
// ClientStats contains a lock which cannot be copied by value.
stat := &clientStats[i]
stats.NumTasksAccepted += stat.NumTasksAccepted
stats.NumTasksIneligible += stat.NumTasksIneligible
stats.NumTasksReceived += stat.NumTasksReceived
stats.NumSessionsAcquired += stat.NumSessionsAcquired
stats.NumSessionsExhausted += stat.NumSessionsExhausted
}
return &StatsResponse{
NumBackups: uint32(stats.NumTasksAccepted),
NumFailedBackups: uint32(stats.NumTasksIneligible),
@ -287,7 +335,17 @@ func (c *WatchtowerClient) Policy(ctx context.Context,
return nil, err
}
policy := c.cfg.Client.Policy()
var policy wtpolicy.Policy
switch req.PolicyType {
case PolicyType_LEGACY:
policy = c.cfg.Client.Policy()
case PolicyType_ANCHOR:
policy = c.cfg.AnchorClient.Policy()
default:
return nil, fmt.Errorf("unknown policy type: %v",
req.PolicyType)
}
return &PolicyResponse{
MaxUpdates: uint32(policy.MaxUpdates),
SweepSatPerByte: uint32(policy.SweepFeeRate.FeePerKVByte() / 1000),

@ -9071,6 +9071,19 @@ func testRevokedCloseRetributionRemoteHodl(net *lntest.NetworkHarness,
func testRevokedCloseRetributionAltruistWatchtower(net *lntest.NetworkHarness,
t *harnessTest) {
t.t.Run("anchors", func(tt *testing.T) {
ht := newHarnessTest(tt, net)
testRevokedCloseRetributionAltruistWatchtowerCase(net, ht, true)
})
t.t.Run("legacy", func(tt *testing.T) {
ht := newHarnessTest(tt, net)
testRevokedCloseRetributionAltruistWatchtowerCase(net, ht, false)
})
}
func testRevokedCloseRetributionAltruistWatchtowerCase(
net *lntest.NetworkHarness, t *harnessTest, anchors bool) {
ctxb := context.Background()
const (
chanAmt = lnd.MaxBtcFundingAmount
@ -9081,7 +9094,11 @@ func testRevokedCloseRetributionAltruistWatchtower(net *lntest.NetworkHarness,
// Since we'd like to test some multi-hop failure scenarios, we'll
// introduce another node into our test network: Carol.
carol, err := net.NewNode("Carol", []string{"--hodl.exit-settle"})
carolArgs := []string{"--hodl.exit-settle"}
if anchors {
carolArgs = append(carolArgs, "--protocol.anchors")
}
carol, err := net.NewNode("Carol", carolArgs)
if err != nil {
t.Fatalf("unable to create new nodes: %v", err)
}
@ -9134,10 +9151,14 @@ func testRevokedCloseRetributionAltruistWatchtower(net *lntest.NetworkHarness,
// Dave will be the breached party. We set --nolisten to ensure Carol
// won't be able to connect to him and trigger the channel data
// protection logic automatically.
dave, err := net.NewNode("Dave", []string{
daveArgs := []string{
"--nolisten",
"--wtclient.active",
})
}
if anchors {
daveArgs = append(daveArgs, "--protocol.anchors")
}
dave, err := net.NewNode("Dave", daveArgs)
if err != nil {
t.Fatalf("unable to create new node: %v", err)
}
@ -9250,7 +9271,9 @@ func testRevokedCloseRetributionAltruistWatchtower(net *lntest.NetworkHarness,
err = wait.NoError(func() error {
ctxt, cancel := context.WithTimeout(ctxb, defaultTimeout)
defer cancel()
bkpStats, err := dave.WatchtowerClient.Stats(ctxt, &wtclientrpc.StatsRequest{})
bkpStats, err := dave.WatchtowerClient.Stats(ctxt,
&wtclientrpc.StatsRequest{},
)
if err != nil {
return err