In this commit, we add a series of abstractions that'll allow us to
easily do funding and also state updates for the new taproot channels. A
partial session is defined by the knowledge of a verification nonce.
Once the remote party sends a signature, we learn of their signing
nonce, and can then complete a session. By using a JIT nonce approach,
we ensure that the signer can generate their nonces randomly and also
at the very last step to avoid having to maintain state.
For our local nonces, we also have an option to use a counter based
nonce derived from the shachain instead of fully random nonces. This
allows us to not have to store ay additional state. Instead, when we
need to go to broadcast, we can just regenerate the nonce then use that
to broadcast.
In this commit, we update the set of intents and assemblers to recognize
musig2. For this change, we use a new bool, `musig2`, then use that to
determine if we need to use the new taproot funding scripts or not.
In this commit, we extract the musig2 session management into a new
module. This allows us to re-use the session logic elsewhere in unit
tests so we don't need to instantiate the entire wallet.
In this commit, we update the Sig type to support ECDSA and schnorr
signatures. We need to do this as the HTLC signatures will become
schnorr sigs for taproot channels. The current spec draft opts to
overload this field since both the sigs are actually 64 bytes in length.
The only consideration with this move is that callers need to "coerce" a
sig to the proper type if they need schnorr signatures.
Adding the ability to stop rebroadcasting a transaction. This is
useful when we want to abandon a channel and grantee that this
transaction will not confirm accidentally.
In theory, it should be only one custom account with a given name. However,
users could have created custom accounts with various key scopes. In that case,
'LookupAccount' has a non deterministic behaviour. To fix that, we browse
through all key scopes (deterministically) and return the first account we found.
In theory, it should be only one custom account with a given name. However,
due to a lack of check, users could have created custom accounts with various
key scopes. In that case, ListAccounts has to list all these accounts.
We know that onion blobs in lightning are _exactly_ 1366 bytes in
lightning, but they are currently expressed as a byte slice in
channeldb's HTLC struct. Blobs are currently serialized as var bytes,
so we can take advantage of this known length and variable length
to add additional data to the inline serialization of our HTLCs, which
are otherwise not easily extensible (without creating a new bucket).
We add a Memo field to the OpenChannel DB struct. We also persist
it using a tlv record. We then pass the Memo value from the
InitFundingReserveMsg when creating a new reservation for the channel.
Finally, we also read Memo field when fetching channel from DB.
Allows to define a maximum amount to provision a channel
opening with using a new field `FundUpToMaxAmt` on the
`Request` struct. Also adds a new coin select function
`CoinSelectUpToAmount` to select coins up to a maximum
amount respecting a minimum amount.
This commit replaces `FundingLocked` found in docs using the following
command,
```shell
find . -name "*.go" -exec sed -i '' 's/FundingLocked/ChannelReady/g' {} \;
find . -name "*.go" -exec sed -i '' 's/FundingLock/ChannelReady/g' {} \;
```
Add a new test htlc set comprised of htlc 1 from the original set and
two new htlcs, 5 and 6, that use the same preimage and have the same
output value (in sats). This htlc set is used in tests that assert the
ordering of htlcs that have the same preimage and output value.
In this commit, an assertion is added to the bolt 3 commitment tx tests
that ensures that the local and remote balances add up to the expected
funding amount. Adding this assertion uncovered a borked test vector
which is also fixed in this commit.
In this commit, we add a new Rebroadcaster interface to be used for
publishing transactions passively in the background until they've been
confirmed on chain. This is useful if a tx drops out of the mempool, but
then the pool clears down and has more space available to accept the tx
at the current fee level.
This commit adds a new build tag `integration` and removes the old tag
`rpctest` for clarity. Multiple unnecessary usages of `build !rpctest`
is also removed.
In this commit, the NewBreachRetribution function is adjusted so that a
caller can optionally set the spendTx parameter to nil. In this case,
the function will check the revocation log to see if the local and
remote amount fields are available there and use them if they are.
If the fields are not present, which they might not be given a previous
migration that removed the fields, then an error is returned.
By default, P2TR addresses are used for changes. However, some users
might encounter some problems with this change. We add the possibility
to define a custom address type in FundPsbt for default/imported accounts
(only P2TR for now). If no address type is specified for these accounts,
we will use P2WKH by default.
The SendOutputs method isn't used very often in our code so the missing
Taproot sighash type wasn't detected before.
Also, a P2TR input will never have a sigScript, so we can explicitly set
that parameter to nil instead of relying on it being nil anyway.
There is a one byte difference between the sigScript and the
witnessScript in case of a np2wkh input. The remote signer actually
needs the witness script and not the sig script to produce a valid
signature.
Fixes an issue where re-using a sign descriptor in a loop carried over
signing information from one call to the next, which caused the remote
signing issue.
With this commit we bump the github.com/btcd/btcec/v2 library to v2.3.2
which implements the MuSig2 BIP version v1.0.0rc2. With this the
github.com/btcsuite/btcd/btcec/v2/schnorr/musig2 package becomes
v1.0.0rc2 and the github.com/lightningnetwork/lnd/internal/musig2v040
stays at the old v0.4.0 version.
We put the calls that don't use musig2 package specific types as
parameters or return values behind an interface so we can easily call
those directly in the RPC without needing to know the underlying
implementation version. Some calls can't be used in the interface
because they use the specific package version's types. These calls are
implemented in helper functions in the input package instead that do the
necessary type switches.
As a preparation for making it possible to version switch calls to the
MuSig2 API, we move some of the calls to the input package where in a
future commit we'll call the corresponding code in the correct package.
Before this commitment, we'd end up failing in `schnorr.ParseSignature`
if a non-default sighash was used. To fix that, we'll slice the
signature to only pass in the sig w/o the sighash flag.
Add a new subpackage to `lnd/channeldb` to hold some of the types that
are used in the package itself and in other packages that should not
depend on `channeldb`.
This commit moves the `HeightHintCache` implementation to the
`channeldb` package and inverts the dependency relation between
`chainntnfs` and `channeldb`.
Many packages depend on channeldb for type definitions,
interfaces, etc. `chainntnfs` is an example of that. `chainntnfs`
defines the `SpendHintCache` and `ConfirmHintCache` interfaces but
it also implments them (`HeightHintCache` struct). The implementation
uses logic that should not leak from channeldb (ex: bucket paths).
This makes our code highly coupled + it would not allow us to use any
of these interfaces in a package that is imported by `channeldb`
(circular dependency).
Our OpenChannelRPC was accepting invalid values for the closing address
field. If we were able to decode the address we would use it in the
script even if the address is for another bitcoin net.
This commit makes sure that no loop variables or other temporary
variables are accessed directly in a goroutine but are instead passed
into the goroutine through a parameter. This makes sure a copy of the
value is put on the stack and is not changed while the outside loop
continues.
This commit fixes signing of Taproot inputs when some of the other
inputs of the transaction are not known to the wallet (such as a Pool
account for example).
If we want to sign for a Taproot (change) input when depositing into a
Pool account the wallet won't know the Pool account input. So we need to
make sure we pass it along inside the PrevOutputFetcher (which contains
the UTXO information extracted from the PSBT).
This commit fixes an issue with signing for mixed inputs in a remote
signing setup where the re-use of the sign descriptor would lead to the
sign method not being reset correctly if a p2wkh input is following a
p2tr input.
In this commit, we modify the way we compute the starting ideal fee for
the co-op close transaction. Before thsi commit, channel.CalcFee was
used, which'll compute the fee based on the commitment transaction
itself, rathern than the co-op close transaction. As the co-op close
transaction is potentailly bigger (two P2TR outputs) than the commitment
transaction, this can cause us to under estimate the fee, which can
result in the fee rate being too low to propagate.
To remedy this, we now compute a fee estimate from scratch, based on the
delivery fees of the two parties.
We also add a bug fix in the chancloser unit tests that wasn't caught
due to loop variable shadowing.
The wallet import itest has been updated as well, since we'll now pay
600 extra saothis to close the channel, since we're accounting for the
added weight of the P2TR outputs.
Fixes#6953
In this commit, the sanity checks in the CommitConstraints method is
moved out into a helper function called VerifyConstraints. This is done
so that the sanity checks can be performed more easily else where in the
code base. The new helper method is then called in the
handleInitFundingMsg method of the funding manager before the
OpenChannelMessage is sent.
In this commit, we catch up our logic with the latest version of the
spec that removed support for normal p2kh and p2sh addresses for co-op
closes, in order to make dust calculations more uniform.
In this commit, we remove the raw channel state machine pointer from the
chan closer and instead replace that with an interface that captures
*just* the methods we need in order to do the co-op close dance.
This is a preparatory refactoring for some upcoming unit tests.
In this commit, we stop clamping the ideal fee rate to the commitment
fee of the channel. This catches us up to this PR of the spec:
https://github.com/lightning/bolts/pull/847.
We also do away with the old 3x ideal fee "max fee", and replace that
with an explicit max fee. This new max fee will either be the default
multiplier of the ideal fee, or a new user specified max fee value.
With a change in #6379 we made sure that all default scopes are added to
the the wallet. Unfortunately this included the BIP044 key scope that
our wallet doesn't really use. This breaks the remote signing setup
because we don't export the account of the BIP044 scope and therefore
run into an issue on the watch-only side when attempting to create the
wallet.
This extends the Reservation arguments to include whether a pending
channel open has negotiated the zero-conf channel type, the scid-alias
channel type, and/or the scid-alias feature bit. The result of those
negotiates are stored in the OpenChannel's ChanType. The arguments to
NewChannelReservation have also been simplified.
Fixes#6626.
If either of the two fields FinalScriptSig or FinalScriptWitness is set
on an input of a PSBT then that results in most of the fields of that
input not to be serialized in the packet anymore, since the input is
considered to be complete.
But because a signer isn't supposed to set any of the Final* fields,
this was wrong from the beginning. Only the finalizer will set those
fields.
Because the original dcrec secp256k1 library that is used for the
Schnorr signature primitives uses different hash algorithms than the
btcd secp256k1 library. Therefore pulling in the wrong library can lead
to weird and unexpected errors. We try to make it harder to make the
mistake by not using the library directly in lnd in the first place.
Note that it is still indirectly needed by the btcd secp256k1 library,
therefore the module dependency is still expected to be there, just
moved to the indirect section.
In this commit, we add a new field `TapTweak` to be used for key path
spends. Before this commit, we'd overload the existing `WitnessScript`
field to pass this information to the signing context. This was
confusing as for tapscript spends, this was the leaf script, which
mirrors the other script based spending types.
With this new filed, users need to set this to the script root for
keypath spends where the output key commits to a real merkle root, and
nothing when bip 86 spending is being used.
To make the signing even more explicit, we also add a new field called
sign_method with an enum type that differentiates between the different
segwit v0 and v1 signing methods.
Fixes https://github.com/lightningnetwork/lnd/issues/6446.
Since we might now be given a whole list of UTXOs in the PrevOutputs
field of the SignOutputRaw RPC, the previous output fetcher might
contain the information we require for the remote signing case. So
instead of failing if our wallet doesn't know each input that's being
spent, we fall back to the UTXO information contained in the previous
outputs.
With this commit we support fee calculation in coin selection for p2tr
inputs. We assume that coins in our UTXO selection are only BIP0086
coins. Any other input types with different spend paths won't be
selected by the wallet assembler.
The inclusion proof field in the TapscriptPartialReveal function was
incorrect. An inclusion proof can be zero or more elements of 32-byte
slices. So an empty inclusion proof can be valid too for a tree that
only consists of a single leaf.
On startup, we'll check whether we have the coop close chan status
and have already broadcasted a coop close txn, and then make a
decision on whether to restart the process based on that.
This commit changes the `NewBreachRetribution` to use the new revocation
log format, while maintaining the compatibilty to use an older
revocation log format. Unit tests have been added to make sure a breach
retribution can be created in both log formats.
This also means the watch tower needs to pass the relevant commit tx at
its backup height when creating the breach retribution during backing
up. This is achieved by recording the current remote commitment state
before advancing the remote commitment chain.
This commit adds a new method, findOutputIndexesFromRemote to compute
the our/their output indexes. As we will see in the following commit,
saving these two fields(4+4=8 bytes) will end up saving us some disk
space.
If new default scopes are added to the underlying btcwallet
implementation, then they aren't automatically created for _existing_
wallets, only for new ones. So on startup we need to make sure all
scopes are present.
Fixes#6329.
This commit fixes a connection leak in the RPC wallet's health check. By
not closing the test connection the watch-only node would slowly stack
up connections and eventually hit the ulimit.
Fixes an issue with SignOutputRaw in remote signing mode where we
weren't able to sign on the remote signer if we only provided the public
key or only the family/index (and not both).
Fixes part of an issue detected in lightninglabs/loop#457.
We need to be able to query the watch-only wallet about a public key
when trying to sign with a key that we don't know the family or index
of. The easiest way to do that is to leverage the wallet's address index
to query the derivation path for a public key.
To give the RPC wallet access to that functionality, we need to expose
the method on the WalletController interface.
With `OutputDetail` now containing the destination addresses, the `DestAddresses` field can be removed from the `lnwallet.TransactionDetail`. It is already populated when needed for backwards compatibility to `lnrpc.TransactionDetail` via `OutputDetail.Addresses`.
Adds the output script and amount to the `DestOutput` field of `TransactionDetails`, as well as sets the flag `isOurAddress` if the output is controlled by the node's wallet.
A new `DestOutputs` field contains additional information on destinations of a transaction described with the `TransactionDetail` structure.
The additional information inside `DestOuputs` denote the output script and amount, as well as a flag `IsOurAddress` if the address is controlled by the node's wallet.
Before this commit, we we were trying to sweep an anchor output, and
that output was spent by someone else (not the sweeper), then we would
report this back to the original resolver (allowing it to be cleaned
up), and also remove the set of inputs spent by that transaction from
the set we need to sweep.
However, it's possible that if a user is spending unconfirmed outputs,
then the wallet is holding onto an invalid transaction, as the outputs
that were used as inputs have been double spent elsewhere.
In this commit, we fix this issue by recursively removing all descendant
transactions of our past sweeps that have an intersecting input set as
the spending transaction. In cases where a user spent an unconfirmed
output to funding a channel, and that output was a descendant of the now
swept anchor output, the funds will now properly be marked as available.
Fixes#6241
This commit was previously split into the following parts to ease
review:
- 2d746f68: replace imports
- 4008f0fd: use ecdsa.Signature
- 849e33d1: remove btcec.S256()
- b8f6ebbd: use v2 library correctly
- fa80bca9: bump go modules
In this commit, we increase the legacy fee limit threshold (the amount
below which we'll allow 100% of funds to go to fees for the non-v2 RPC
calls) from 50 sats to 1k sats.
If we're signing for an UTXO that isn't known to the wallet, then the
UTXO's pk script _must_ be set in the sign descriptor. Otherwise we run
into a generic PSBT serialization error when running in a remote signing
setup.
To enable converting an existing wallet with private key material into a
watch-only wallet on first startup with remote signing enabled, we add a
new flag. Since the conversion is a destructive process, this shouldn't
happen automatically just because remote signing is enabled.
This fixeslightninglabs/loop#437 by adding all accounts that are used
in liquidity products such as Loop or Pool. Since both of these products
use key families below 255, we can get by with that number.
The alternative to creating way too many accounts (which increases the
default wallet size by ~250kB) would be to hard code the exact accounts
used by Loop (99) and Pool (210). But that sounds like a bad idea given
that there could always be more accounts being added to those (or other)
products. By making sure the first 255 accounts exist, we have a lot
more flexibility in those products for choosing key families.
With the remote signing instance now not needing to know anything about
addresses or current derivation indices, we don't need to forward any
such calls to that instance and can simplify the RPCKeyRing
considerably.
The minimum relay fee is always ensured to be above our fee floor except
in the very first min relay fee query to bitcoind. This commit ensures
that the fee floor is respected in this first query.
This change avoids enforcing new reserved value when PSBT funding is not
finished yet as new inputs and outputs may still be added that could
change the outcome of the check.
This originally failed in the scenario when funding a channel from
external wallet *and depositing to on-chain wallet* was done
simultaneously in a single transaction. If such transaction confirms
then reserved UTXO is guaranteed to be available but the check didn't
take it into account.
The enforcement still occurs in the final step of PSBT funding flow, so
it is safe. It also occurs in case of non-PSBT funding.
This commit modifies the channel state machine to be able to derive the
proper commitment and second-level HTLC output scripts required by the
new script-enforced leased channel commitment type.
Pass htlc amount down to the channel so that we don't need to rely
on minHtlc (and pad it when the channel sets a 0 min htlc). Update
test to just check some sane values since we're no longer relying
on minHtlc amount at all.
In order to support the full range of on-chain functionality, including
importing watch-only accounts in the watch-only instance, we need to
forward some calls like creating new addresses or importing accounts to
the remote signing instance.
To simplify the message signing API even further, we refactor the
lnwallet.MessageSigner interface to use a key locator instead of the
public key to identify which key should be signed with.
This commit adds a fetchMinMempoolFee function to the BitcoindEstimator
that fetches the current min mempool fee from the bitcoind backend. The
commit then also updates the BitcoindEstimator to use a minFeeManager
for it's minFeeManager member and uses the fetchMinMempoolFee function
to initialise this.
The validateFeeRate function uses the availableBalance function to get
the current spendable balance of a channel, adds the old fee and then
ensures that the new fee is not larger than the amount we have available
to spend. This commit also removes the local reserve check in the
validateFeeRate function since the balance returned from
availableBalance already takes the local reserve into acccount.
In this commit we ensure that the max fee calculated in the MaxFeeRate
function takes the local reserve amount into account along with any
pending HTLCs. This is done by calling the avaialbeBalance function.
The FundingPsbtFinalize step is a safety measure that assures the final
signed funding transaction has the same TXID as was registered during
the funding flow and was used for the commitment transactions.
This step is cumbersome to use if the whole funding process is completed
external to lnd. We allow the finalize step to be skipped for such
cases. The API user/script will need to make sure things are verified
(and possibly cleaned up) properly.
During the final part of the channel funding negotiation we only need to
assemble the full funding TX with the witness if we are going to publish
the transaction ourselves. If the final funding TX is published
externally we don't need this information. This will make it possible to
skip the verify process for fully externally funded PSBT channels.
It over-estimates the local or remote commitment's dust sum by
counting all updates in both updateLogs that are dust using the
trimmed-to-dust mechanism if applicable. The over-estimation is done
because ensuring an accurate counting is a trade-off between code
simplicity and accuracy.
With go 1.17 a change to the build flags was implemented:
https://go.googlesource.com/proposal/+/master/design/draft-gobuild.md
The formatter now automatically adds the forward-compatible build tag
format and the linter checks for them, so we need to include them in our
code.
This is necessary and is implied by BOLT#02. Both ChannelReserve
parameters should be above both DustLimit parameters. Otherwise,
it is possible for one side to have nothing at stake.
This commit updates call-sites to use the proper dust limits for
various script types. This also updates the default dust limit used
in the funding flow to be 354 satoshis instead of 573 satoshis.
Adds a new Brontide struct method tryLinkShutdown that attempts to
fetch the target link and calls ShutdownIfChannelClean on it. This
allows the coop close process to guarantee atomicity of the underlying
channel state. Also removes the UnregisterChannel method from the
chancloser's config as the link is shut down before the chancloser
is created.
Adds a method to the LightningChannel struct called IsChannelClean
that returns a boolean telling the caller whether the channel state
is clean or not. Clean in this case means there are no lingering
updates to be signed for, no HTLC's active on either sides commitment
transaction, and no pending commitments on either side. This can be
used for dynamic commitments or during a strict cooperative close
process that ensures atomicity of the channel.
In this commit, we start to optimistically use the new private key cache
that was added to btcwallet. As is, btcwallet will cache the decrypted
account keys for each scope in memory. However, the existing methods
to derive a child key from those account keys requires a write database
transaction, and will re-derive the private key using BIP-32 each time.
The newly added `DeriveFromKeyPathCache` lets us skip all this and
directly use a cache assuming the account info is already cached. The
new logic will try to use this method, but if it fails fall back to the
existing `DeriveFromKeyPath` method. All calls after this will use this
new cached key.
Fixes https://github.com/lightningnetwork/lnd/issues/5125.
Basic benchmark before the btcwallet change and after:
```
benchmark old ns/op new ns/op delta
BenchmarkDerivePrivKey-8 22840583 125 -100.00%
benchmark old allocs new allocs delta
BenchmarkDerivePrivKey-8 89 2 -97.75%
benchmark old bytes new bytes delta
BenchmarkDerivePrivKey-8 10225 24 -99.77%
```
Depends on btcsuite/btcwallet#757.
Pulls in the updated version of btcwallet and walletdb that have the DB
interface enhanced by their own View() and Update() methods with the
reset callback/closure supported out of the box. That way the global
package-level View() and Update() functions now become pure redirects.
Improve 'ErrReservedValueInvalidated' error string to explain that the
error is triggered by a transaction that would deplete funds reserved for
potential future anchor channel closings (via CPFP)
Add hint that further details can be found in the debug log
Update strings in 'lntest/itest/log_error_whitelist.txt' correspondingly
We only want to register the bbolt DB backend ("bdb") when we're not
compiling for a JS/WASM build targets. That's why we want to have that
import in only one file that we can add a build tag to. We remove it in
two other places since only one import is enough anyway.
In this commit, in order to allow the test added in the prior commit to
pass, we'll increment the mockHTLCAmt value by 1 to ensure we never
attempt to add a zero value HTLC.
Fixes#5468
As is, if the remote party proposes a min HTLC of 0 `mSat` to us, then
we won't ever be able to _send outgoing_ in the channel as the
`MayAddOutgoingHtlc` will attempt to add a zero-value HTLC, which isn't
allowed within the protocol.
The default channels created actually already use a min HTLC value of
zero within the tests, so this test case fails as is.
This commit adds a new struct AnchorResolutions which wraps the anchor
resolutions for local/remote/pending remote commitment transactions. It
is then returned from NewAnchorResolutions. Thus the caller knows how to
retrieve a certain anchor resolution.
In this commit, we add a check inside EstimateFeePerKW for bitcoind so
that when the conf target exceeds the maxBlockTarget, we will use
maxBlockTarget instead.
This commit aims to address a flaw in our anchor reserve enforcement
logic in which an inbound "legacy" channel (i.e. a channel with a
commitment type that precedes anchors) would be rejected by the
recipient if they have at least one opened channel using the anchors
commitment type and do not have enough on-chain funds to meet the
anchors reserve.
Otherwise, we would get non-standard txn's and fail to broadcast
them when cooperatively closing a channel. This wouldn't affect
funds security as no HTLCs would be active to steal. This is just
a safety measure as we should only generate standard txn's.
Fixes#5287.
The PSBT spec is a bit vague when it comes to the WitnessUtxo field of
an input as it's not strictly required for witness inputs. Therefore
Electrum for example does not include the field.
We need to make the SegWit input check a bit more elaborate by looking
at the output script of the UTXO and also the redeem script in case it's
a nested SegWit spend.
Since private channels (most likely) won't be used for routing other
than as last hop, they bear a smaller risk that we must quickly force
close them in order to resolve a HTLC up/downstream.
In the case where it actually has to be force to resolve a payment (if
it is the first/last hop on a routed payment), we can assume that the
router will have UTXOs available from the reserved value from the
incoming public channel.
We cap the maximum value we'll reserve for anchor channel fee bumping at
10 times the per-channel amount such that nodes with a high number of
channels don't have to keep around a very large amount for the unlikely
scanario that they all close at the same time.
This commit ensures that for the neutrino implementation of
lnwallet.BlockChainIO, the neutrino GetBlock method is called directly
(since it already uses the blockcache). It also ensures that the block
cache mutex for the given hash is locked before the call to GetBlock.
The previous behavior would allow updates to be overwritten in some
scenarios. Upon restart, this would lead to a missing settle/fail in
the update logs.