These race conditions originate from the mock database storing and
returning pointers, rather than returning a copy.
Observed on Travis:
WARNING: DATA RACE
Read at 0x00c0003222b8 by goroutine 149:
github.com/lightningnetwork/lnd/watchtower/wtclient.(*sessionQueue).drainBackups()
/home/runner/work/lnd/lnd/watchtower/wtclient/session_queue.go:288 +0xed
github.com/lightningnetwork/lnd/watchtower/wtclient.(*sessionQueue).sessionManager()
/home/runner/work/lnd/lnd/watchtower/wtclient/session_queue.go:281 +0x450
Previous write at 0x00c0003222b8 by goroutine 93:
github.com/lightningnetwork/lnd/watchtower/wtclient.getClientSessions()
/home/runner/work/lnd/lnd/watchtower/wtclient/client.go:365 +0x24f
github.com/lightningnetwork/lnd/watchtower/wtclient.(*TowerClient).handleNewTower()
/home/runner/work/lnd/lnd/watchtower/wtclient/client.go:1063 +0x23e
github.com/lightningnetwork/lnd/watchtower/wtclient.(*TowerClient).backupDispatcher()
/home/runner/work/lnd/lnd/watchtower/wtclient/client.go:784 +0x10b9
These operations are currently unused, but will be integrated into the
TowerClient at a later point as future preparation for the
WatchtowerClient RPC subserver, which will allow users to add, remove,
and list the watchtowers currntly in use.
This currently takes O(N) time as there does not exist an index of
active client sessions for each watchtower within the client's database.
This index is likely to be added in the future.
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.
In advance of the upcoming wtdb.ClientDB, we'll modify the behavior
of the mockdb to be more like the final bbolt backed one, and assert
that all or our tests are still passing.
This commit replaces the map-based CommittedUpdates field with a slice.
When reading from disk, these will already be sorted by bbolt, so the
client restore the updates as presented without needing to sort them
first.
Since the key in the map variant was the sequence number, we refactor
the CommittedUpdate struct to have a sequence number and an embedded
CommittedUpdateBody (which is equivalent to the old CommittedUpdate).
The database is then expected to populate the sequence number from the
key on disk.
Since the sequence number is now directly integrated in the
CommittedUpdate struct, this allow allows us to remove the now redundant
seqNum argument from CommitUpdate.