Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

watchtower: integrate altruist watchtower and watchtower client #3133

Merged
merged 35 commits into from Jun 14, 2019

Conversation

Projects
None yet
4 participants
@cfromknecht
Copy link
Collaborator

commented May 29, 2019

This PR finalizes the bulk of the watchtower integration, by supporting the ability to run lnd with a companion tower and also as a client to backup justice transactions to a remote tower. This PR does not expose the setting up a tower to receive rewards from the justice transaction, as there are some lingering todos to address before it can be safely enabled.

If you're interested in testing this PR, I'd suggest creating a tower listening on localhost and pointing the client towards your own daemon. This will allow you to monitor both end points at once and also delete db state on both ends if any bugs are encountered. The relevant config options are:

[Wtclient]
wtclient.private-tower-uris=<your-pubkey>@localhost:9911

[Watchtower]
watchtower.active=1
watchtower.listen=localhost:9911

For the time being, I'd suggest NOT pointing the client towards a remote tower (or listening publicly). There are a few small changes that may happen from now until final merge, having both client and tower locally makes it easy to wipe the dbs and proceed.

@cfromknecht cfromknecht force-pushed the cfromknecht:wt-polish branch from 66da94a to df7ca2c May 29, 2019

@Roasbeef
Copy link
Member

left a comment

The Eye of Sauron casts its gaze upon the Lightning Network....

First pass review completed, will need to revisit some of the existing package as well before my next pass. Stoked to set up this latest version on my nodes!

@@ -400,6 +405,13 @@ func (l *channelLink) Start() error {
l.overflowQueue.Start()
l.hodlQueue.Start()

if l.cfg.TowerClient != nil {
err := l.cfg.TowerClient.RegisterChannel(l.ChanID())

This comment has been minimized.

Copy link
@Roasbeef

Roasbeef May 29, 2019

Member

What's the impact of re-registering each time the link is created? Should this instead be done once for all active channels once the daemon starts up?

This comment has been minimized.

Copy link
@cfromknecht

cfromknecht May 29, 2019

Author Collaborator

the first execution will generate a sweep pkscript and cause a db write, after that it always hits an in-memory cache protected by a mutex.

i did consider that, but by placing it here we ensure we only generate pkscripts for usable channels and it is the most natural place from a perspective of lazily registering the channel and not make any assumptions about whether this is called before being added to the switch

Show resolved Hide resolved log.go
Show resolved Hide resolved watchtower/conf.go
Show resolved Hide resolved watchtower/conf.go
Show resolved Hide resolved lnd.go Outdated
Show resolved Hide resolved lnd_test.go Outdated
Show resolved Hide resolved lnd_test.go Outdated
lnd_test.go Outdated
// testRevokedCloseRetributionAltruistWatchtower tests that Dave is able
// carry out retribution in the event that she fails in state where the remote
// commitment output has zero-value.
func testRevokedCloseRetributionAltruistWatchtower(net *lntest.NetworkHarness,

This comment has been minimized.

Copy link
@Roasbeef

Roasbeef May 29, 2019

Member

This test has a lot of overlap with the existing revocation related itests (step, db state copy, breach). I think much of this can be consolidated, similar to the assertDLPExecuted method I added when the SCB DLP tests were introduced.

This comment has been minimized.

Copy link
@Roasbeef

Roasbeef May 29, 2019

Member

Reading it a bit more, there's a bit less overlap than I originally suspected.

This comment has been minimized.

Copy link
@wpaulino

wpaulino May 30, 2019

Collaborator

Could still refactor this slightly to not cause a large change when adding tests for private towers with rewards.

Show resolved Hide resolved lnd_test.go Outdated

@cfromknecht cfromknecht force-pushed the cfromknecht:wt-polish branch from df7ca2c to 49de27f May 29, 2019

@cfromknecht cfromknecht added this to the 0.7 milestone May 29, 2019

@cfromknecht

This comment has been minimized.

Copy link
Collaborator Author

commented May 29, 2019

@Roasbeef ptal

@wpaulino
Copy link
Collaborator

left a comment

Just a few nits from me -- excited to finally see all of the pieces working together!

Show resolved Hide resolved watchtower/blob/justice_kit.go
Show resolved Hide resolved watchtower/wtclient/session_queue.go
Show resolved Hide resolved watchtower/wtclient/session_queue.go Outdated
Show resolved Hide resolved htlcswitch/link.go
Show resolved Hide resolved lncfg/wtclient.go Outdated
Show resolved Hide resolved lncfg/wtclient.go
Show resolved Hide resolved lnd.go Outdated
Show resolved Hide resolved lnd_test.go Outdated
lnd_test.go Outdated
// testRevokedCloseRetributionAltruistWatchtower tests that Dave is able
// carry out retribution in the event that she fails in state where the remote
// commitment output has zero-value.
func testRevokedCloseRetributionAltruistWatchtower(net *lntest.NetworkHarness,

This comment has been minimized.

Copy link
@wpaulino

wpaulino May 30, 2019

Collaborator

Could still refactor this slightly to not cause a large change when adding tests for private towers with rewards.

@tyzbit

This comment has been minimized.

Copy link
Contributor

commented May 30, 2019

Worked for me on testnet!

Expand
2019-05-30 02:42:11.662 [DBG] WTWR: Fetching block for (height=1518949, hash=0000000000045417fd18738839b482b5b34b8f0f67f415bbe098b1f8a9f5d7cf)
2019-05-30 02:42:11.675 [DBG] WTWR: Scanning 269 transaction in block (height=1518949, hash=0000000000045417fd18738839b482b5b34b8f0f67f415bbe098b1f8a9f5d7cf) for breaches
2019-05-30 02:42:11.679 [INF] WTWR: Found 1 breach in (height=1518949, hash=0000000000045417fd18738839b482b5b34b8f0f67f415bbe098b1f8a9f5d7cf)
2019-05-30 02:42:11.679 [INF] WTWR: Dispatching punisher for client 03a8a114395b54298b61c9f0b6479b4f339d0bfdb8dcb6d0c1b610bd1e65140b83, breach-txid=5963ce837874099d26d400d55e4c82fdc6dab845436b2c35df2eb5bf4e0cc40b
2019-05-30 02:42:11.680 [INF] WTWR: Publishing justice transaction for client=03a8a114395b54298b61c9f0b6479b4f339d0bfdb8dcb6d0c1b610bd1e65140b83 with txid=3f708e64db0090f3d5862a4b696181d4c092445a477d5ba0ff519cf65be2b06e
2019-05-30 02:42:11.703 [INF] WTWR: Punishment for client 03a8a114395b54298b61c9f0b6479b4f339d0bfdb8dcb6d0c1b610bd1e65140b83 with breach-txid=5963ce837874099d26d400d55e4c82fdc6dab845436b2c35df2eb5bf4e0cc40b dispatched

@cfromknecht cfromknecht force-pushed the cfromknecht:wt-polish branch 3 times, most recently from 9082808 to f9eda3a May 30, 2019

Show resolved Hide resolved config.go
Show resolved Hide resolved server.go Outdated
@@ -561,6 +561,7 @@ func (c *TowerClient) backupDispatcher() {
// Wait until we receive the newly negotiated session.
// All backups sent in the meantime are queued in the
// revoke queue, as we cannot process them.
awaitSession:

This comment has been minimized.

Copy link
@wpaulino

wpaulino Jun 7, 2019

Collaborator

It's possible for the client to not gracefully shut down if it's waiting here. In the select statement for once we have an active session we seem to handle the case where the backup queue is shut down, but not here.

Relevant profile:

1 @ 0x1030e1f 0x10407f8 0x19b991d 0x105e331
#	0x19b991c	github.com/lightningnetwork/lnd/watchtower/wtclient.(*TowerClient).backupDispatcher+0xc5c	/Users/user/git/lnd/watchtower/wtclient/client.go:611

1 @ 0x1030e1f 0x10407f8 0x19bc7d5 0x105e331
#	0x19bc7d4	github.com/lightningnetwork/lnd/watchtower/wtclient.(*sessionNegotiator).negotiationDispatcher+0x134	/Users/user/git/lnd/watchtower/wtclient/session_negotiator.go:177

1 @ 0x1030e1f 0x10407f8 0x19bd102 0x105e331
#	0x19bd101	github.com/lightningnetwork/lnd/watchtower/wtclient.(*sessionNegotiator).negotiate+0x6a1	/Users/user/git/lnd/watchtower/wtclient/session_negotiator.go:236

1 @ 0x1030e1f 0x10412d9 0x10412af 0x1040f59 0x10751f5 0x19c2bc1 0x10742f3 0x19b8484 0x1aa9245 0x10742f3 0x1a85f34 0x1a4b702 0x1ab6b06 0x1030a2c 0x105e331
#	0x1040f58	sync.runtime_Semacquire+0x38								/usr/local/go/src/runtime/sema.go:56
#	0x10751f4	sync.(*WaitGroup).Wait+0x64								/usr/local/go/src/sync/waitgroup.go:130
#	0x19c2bc0	github.com/lightningnetwork/lnd/watchtower/wtclient.(*TowerClient).Stop.func1+0xa0	/Users/user/git/lnd/watchtower/wtclient/client.go:415
#	0x10742f2	sync.(*Once).Do+0xb2									/usr/local/go/src/sync/once.go:44
#	0x19b8483	github.com/lightningnetwork/lnd/watchtower/wtclient.(*TowerClient).Stop+0x53		/Users/user/git/lnd/watchtower/wtclient/client.go:387
#	0x1aa9244	github.com/lightningnetwork/lnd.(*server).Stop.func1+0x354				/Users/user/git/lnd/server.go:1312
#	0x10742f2	sync.(*Once).Do+0xb2									/usr/local/go/src/sync/once.go:44
#	0x1a85f33	github.com/lightningnetwork/lnd.(*server).Stop+0x53					/Users/user/git/lnd/server.go:1283
#	0x1a4b701	github.com/lightningnetwork/lnd.Main+0x1241						/Users/user/git/lnd/lnd.go:489
#	0x1ab6b05	main.main+0x25										/Users/user/git/lnd/cmd/lnd/main.go:14
#	0x1030a2b	runtime.main+0x20b									/usr/local/go/src/runtime/proc.go:200

This comment has been minimized.

Copy link
@cfromknecht

cfromknecht Jun 7, 2019

Author Collaborator

yep this fixed locally setting a ForceQuitDelay in the client's conf

This comment has been minimized.

Copy link
@wpaulino

wpaulino Jun 7, 2019

Collaborator

Why should it still wait for the delay if there aren't any queued tasks though?

Show resolved Hide resolved config.go

@cfromknecht cfromknecht force-pushed the cfromknecht:wt-polish branch 3 times, most recently from f4c8f19 to 108cafb Jun 14, 2019

cfromknecht added some commits Jun 14, 2019

Show resolved Hide resolved watchtower/blob/derivation.go Outdated
Show resolved Hide resolved watchtower/lookout/lookout.go Outdated
Show resolved Hide resolved lntest/itest/lnd_test.go

cfromknecht added some commits Jun 14, 2019

cfromknecht added some commits Jun 14, 2019

server+utxonursery: generate pkscript closures
This commit moves the newSweepPkScript function
previously in the nursery to be a helper function
within the server. Additionally, the function now
returns a closure that satisfies the configuration
interfaces of several other subsystems.

As a result, the configuration sites contain much
less boilerplate, as it's now encapsulated in
the newSweepPkScriptGen helper.
watchtower/wtclient/client: avoid over requesting sessions
This commit fixes a bug that would cause us to request more sessions
that needed from the session negotiator. With the current stat ticker,
we'd ask the negotiator for a new session every 30s if session
session negotiation did not return before printing the stats. Now we'll
avoid requesting to sessions by jumping back into the select loop.
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.
watchtower/wtclient/client: use existing session with same TxPolicy
This commit modifies the client's filtering when selecting from existing
sessions. The new logic compares the configured TxPolicy with the
TxPolicy of the candidate sessions, which has the effect of ignoring
operational parameters such as MaxUpdates. Prior, changing MaxUpdates
would cause the client to request a new session even if it had perfectly
good slots available in a policy with an equal TxPolicy.
watchtower/wtwire/message: bump wtwire messages outside reserved ranges
BOLT01 reserves the following ranges:
 - Setup & Control (types 0-31)
 - Channel (types 32-127)
 - Commitment (types 128-255)
 - Routing (types 256-511)

The wtwire messages now occupy 600-607.
watchtower/wtdb: only accept properly sized blobs
Modifies the bbolt and mock tower databases to only accept blobs that
are the expected size of the session's blob type. This prevents resource
exhaustion attacks where a client may provide disproportionately large
encrypted blob, even though all supported blob types are of fixed-size.

@cfromknecht cfromknecht force-pushed the cfromknecht:wt-polish branch from 108cafb to 059887b Jun 14, 2019

@Roasbeef
Copy link
Member

left a comment

LGTM 🧿

@Roasbeef Roasbeef merged commit a533232 into lightningnetwork:master Jun 14, 2019

1 of 2 checks passed

coverage/coveralls Coverage decreased (-0.09%) to 60.818%
Details
continuous-integration/travis-ci/pr The Travis CI build passed
Details

@cfromknecht cfromknecht deleted the cfromknecht:wt-polish branch Jun 14, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.