In this commit, we update the project and relevant sub-modules to sqldb
v1.0.2. The next step is to tag a new version of kvdb, then update the
main module to use that.
In this commit, we fix a race in the `TestPackager` series on channeldb.
A few tests were sharing the same global variable of the set of log
updates, which includes a pointer to an HTLC. The `ExtraData` value of
the HTLC would then be mutated once we go to encode the message on disk.
To fix this, we the global with a function that returns a new instance
of all the test data.
```
==================
WARNING: DATA RACE
Write at 0x0000021b0a48 by goroutine 2896:
github.com/lightningnetwork/lnd/lnwire.(*ExtraOpaqueData).PackRecords()
/home/runner/work/lnd/lnd/lnwire/extra_bytes.go:74 +0x546
github.com/lightningnetwork/lnd/lnwire.EncodeMessageExtraData()
/home/runner/work/lnd/lnd/lnwire/extra_bytes.go:121 +0x4d
github.com/lightningnetwork/lnd/lnwire.(*UpdateAddHTLC).Encode()
/home/runner/work/lnd/lnd/lnwire/update_add_htlc.go:164 +0x5af
github.com/lightningnetwork/lnd/lnwire.WriteMessage()
/home/runner/work/lnd/lnd/lnwire/message.go:330 +0x351
github.com/lightningnetwork/lnd/channeldb.WriteElement()
/home/runner/work/lnd/lnd/channeldb/codec.go:186 +0x1975
github.com/lightningnetwork/lnd/channeldb.WriteElements()
/home/runner/work/lnd/lnd/channeldb/codec.go:247 +0x14f
github.com/lightningnetwork/lnd/channeldb.serializeLogUpdate()
/home/runner/work/lnd/lnd/channeldb/channel.go:2529 +0x3c
github.com/lightningnetwork/lnd/channeldb.putLogUpdate()
/home/runner/work/lnd/lnd/channeldb/forwarding_package.go:525 +0xae
github.com/lightningnetwork/lnd/channeldb.(*ChannelPackager).AddFwdPkg()
/home/runner/work/lnd/lnd/channeldb/forwarding_package.go:489 +0x684
github.com/lightningnetwork/lnd/channeldb_test.TestPackagerOnlyAdds.func1()
/home/runner/work/lnd/lnd/channeldb/forwarding_package_test.go:283 +0x4c
github.com/btcsuite/btcwallet/walletdb/bdb.(*db).Update()
/home/runner/go/pkg/mod/github.com/btcsuite/btcwallet/walletdb@v1.4.2/bdb/db.go:429 +0xe5
github.com/lightningnetwork/lnd/kvdb.Update()
/home/runner/go/pkg/mod/github.com/lightningnetwork/lnd/kvdb@v1.4.6/interface.go:16 +0x258
github.com/lightningnetwork/lnd/channeldb_test.TestPackagerOnlyAdds()
/home/runner/work/lnd/lnd/channeldb/forwarding_package_test.go:282 +0x17b
testing.tRunner()
/home/runner/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.21.4.linux-amd64/src/testing/testing.go:1595 +0x238
testing.(*T).Run.func1()
/home/runner/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.21.4.linux-amd64/src/testing/testing.go:1648 +0x44
Previous write at 0x0000021b0a48 by goroutine 2898:
github.com/lightningnetwork/lnd/lnwire.(*ExtraOpaqueData).PackRecords()
/home/runner/work/lnd/lnd/lnwire/extra_bytes.go:74 +0x546
github.com/lightningnetwork/lnd/lnwire.EncodeMessageExtraData()
/home/runner/work/lnd/lnd/lnwire/extra_bytes.go:121 +0x4d
github.com/lightningnetwork/lnd/lnwire.(*UpdateAddHTLC).Encode()
/home/runner/work/lnd/lnd/lnwire/update_add_htlc.go:164 +0x5af
github.com/lightningnetwork/lnd/lnwire.WriteMessage()
/home/runner/work/lnd/lnd/lnwire/message.go:330 +0x351
github.com/lightningnetwork/lnd/channeldb.WriteElement()
/home/runner/work/lnd/lnd/channeldb/codec.go:186 +0x1975
github.com/lightningnetwork/lnd/channeldb.WriteElements()
/home/runner/work/lnd/lnd/channeldb/codec.go:247 +0x14f
github.com/lightningnetwork/lnd/channeldb.serializeLogUpdate()
/home/runner/work/lnd/lnd/channeldb/channel.go:2529 +0x3c
github.com/lightningnetwork/lnd/channeldb.putLogUpdate()
/home/runner/work/lnd/lnd/channeldb/forwarding_package.go:525 +0xae
github.com/lightningnetwork/lnd/channeldb.(*ChannelPackager).AddFwdPkg()
/home/runner/work/lnd/lnd/channeldb/forwarding_package.go:489 +0x684
github.com/lightningnetwork/lnd/channeldb_test.TestPackagerAddsThenSettleFails.func1()
/home/runner/work/lnd/lnd/channeldb/forwarding_package_test.go:490 +0x4c
github.com/btcsuite/btcwallet/walletdb/bdb.(*db).Update()
/home/runner/go/pkg/mod/github.com/btcsuite/btcwallet/walletdb@v1.4.2/bdb/db.go:429 +0xe5
github.com/lightningnetwork/lnd/kvdb.Update()
/home/runner/go/pkg/mod/github.com/lightningnetwork/lnd/kvdb@v1.4.6/interface.go:16 +0x2cd
github.com/lightningnetwork/lnd/channeldb_test.TestPackagerAddsThenSettleFails()
/home/runner/work/lnd/lnd/channeldb/forwarding_package_test.go:489 +0x1e7
testing.tRunner()
/home/runner/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.21.4.linux-amd64/src/testing/testing.go:1595 +0x238
testing.(*T).Run.func1()
/home/runner/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.21.4.linux-amd64/src/testing/testing.go:1648 +0x44
Goroutine 2896 (running) created at:
testing.(*T).Run()
/home/runner/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.21.4.linux-amd64/src/testing/testing.go:1648 +0x82a
testing.runTests.func1()
/home/runner/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.21.4.linux-amd64/src/testing/testing.go:2054 +0x84
testing.tRunner()
/home/runner/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.21.4.linux-amd64/src/testing/testing.go:1595 +0x238
testing.runTests()
/home/runner/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.21.4.linux-amd64/src/testing/testing.go:2052 +0x896
testing.(*M).Run()
/home/runner/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.21.4.linux-amd64/src/testing/testing.go:1925 +0xb57
github.com/lightningnetwork/lnd/kvdb.RunTests()
/home/runner/go/pkg/mod/github.com/lightningnetwork/lnd/kvdb@v1.4.6/test_utils.go:23 +0x26
github.com/lightningnetwork/lnd/channeldb.TestMain()
/home/runner/work/lnd/lnd/channeldb/setup_test.go:10 +0x308
main.main()
_testmain.go:321 +0x303
Goroutine 2898 (running) created at:
testing.(*T).Run()
/home/runner/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.21.4.linux-amd64/src/testing/testing.go:1648 +0x82a
testing.runTests.func1()
/home/runner/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.21.4.linux-amd64/src/testing/testing.go:2054 +0x84
testing.tRunner()
/home/runner/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.21.4.linux-amd64/src/testing/testing.go:1595 +0x238
testing.runTests()
/home/runner/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.21.4.linux-amd64/src/testing/testing.go:2052 +0x896
testing.(*M).Run()
/home/runner/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.21.4.linux-amd64/src/testing/testing.go:1925 +0xb57
github.com/lightningnetwork/lnd/kvdb.RunTests()
/home/runner/go/pkg/mod/github.com/lightningnetwork/lnd/kvdb@v1.4.6/test_utils.go:23 +0x26
github.com/lightningnetwork/lnd/channeldb.TestMain()
/home/runner/work/lnd/lnd/channeldb/setup_test.go:10 +0x308
main.main()
_testmain.go:321 +0x303
==================
```
This itest adds a test that we still propagate blinded errors back
properly after a restart with an on-chain resolution. The test also
updates our sendpayment timeout to longer so that there's time to
resolve the on chain claim.
In this commit, we fix an inconsistent in the API related to AMP
payments. When a payment request isn't specified, we require the `--amp`
flag on the CLI to make an AMP payment. However, for payment requests,
we don't require this flag. To fix this inconsistency, we now require
the `--amp` flag to _also_ be set for payment requests.
This type is useful when one wants to encode an integer as an underlying BigSize record. It wraps any integer, then handles the transformation into and out of the BigSize encoding on disk.
In this commit, we add a new type alias for a blob type. This type can be used in areas where a byte slice is used to store a TLV value, which may be a fully opaque nested TLV.
Create our error encrypter with a wrapped type if we have a blinding
point present. Doing this in the iterator allows us to track this
information when we have both pieces of information available to us,
compared to trying to handle this later down the line:
- Downstream link on failure: we know that we've set a blinding point
for out outgoing HTLC, but not whether we're introduction or not
- Upstream link on failure: once the failure packet has been sent
through the switch, we no longer know whether we were the introduction
point (without looking it up / examining our payload again /
propagating this information through the switch).
Introduce two wrapper types for our existing SphinxErrorEncrypter
that are used to represent error encrypters where we're a part of a
blinded route. These encrypters are functionally the same as a sphinx
encrypter, and are just used as "markers" so that we know that we
need to handle our error differently due to our different role.
We need to persist this information to account for restart cases where
we've resovled the outgoing HTLC, then restart and need to handle the
error for the incoming link. Specifically, this is relevant for:
- On chain resolution messages received after restart
- Forwarding packages that are re-forwarded after restart
This is also generally helpful, because we can store this information
in one place (the circuit) rather than trying to reconstruct it in
various places when forwarding the failure back over the switch.
We need to know what role we're playing to be able to handle errors
correctly, but the information that we need for this is held by our
iterator:
- Whether we had a blinding point in update add (blinding kit)
- Whether we had a blinding point in payload
As we're now going to use the route role return value even when our
err!=nil, we rename the error to signal that we're using less
canonical golang here.
An alternative to this approach is to attach a RouteRole to our
ErrInvalidPayload. The downside of that approach is:
- Propagate context through parsing (whether we had updateAddHtlc)
- Clumsy handling for errors that are not of type ErrInvalidPayload
When handling blinded errors, we need to know whether there was a
blinding key in our payload when we successfully parsed our payload
but then found an invalid set of fields. The combination of
parsing and validation in NewPayloadFromReader means that we don't know
whether a blinding point was available to us by the time the error is
returned.
This commit splits parsing and validation into two functions so that
we can take a look at what we actually pulled of the payload in between
parsing and TLV validation.
This commit moves all our validation related to the presence of fields
into ValidateParsedPayloadTypes so that we can handle them in a single
place. We draw the distinction between:
- Validation of the payload (and the context within it's being parsed,
final hop / blinded hop etc)
- Processing and validation of encrypted data, where we perform
additional cryptographic operations and validate that the fields
contained in the blob are valid.
This helps draw the line more clearly between the two validation types,
rather than splitting some payload-releated blinded hop processing
into the encrypted data processing part. The downside of this approach
(vs doing the blinded path payload check _after_ payload validation)
is that we have to pass additional context into payload validation
(ie, whether we got a blinding point in our UpdateAddHtlc - as we
already do for isFinalHop).
This commit adds handling for malformed HTLC errors related to blinded
paths. We expect to receive these errors _within_ a blinded path,
because all non-introduction nodes are instructed to return malformed
errors for failures.
Note that we may actually switch back to a malformed error later on if
we too are a relaying node in the route, but we handle that case the
incoming link.