This commit fixes a lingering bug in the way the internal channel state
machine handled fee calculation. Previously, we would count the dust
HTLC’s that were trimmed towards the fee that the initiator paid. This
is invalid as otherwise, the initiator would always benefit from dust
HTLC’s. Instead, we now simply “donate” the dust HTLC’s to the miner in
the commitment transaction. This change puts us in compliance with
BOLT-0003.
This commit modifies the CommitSpendNoDelay script witness generation
function. We must modify this function as all non-delayed outputs now
also require a key derivation. The current default
signer.ComputeInputScript implementation is unable to directly look up
the public key required as it attempt to target the pub key using the
pkScript.
This commit modifies the closeObserver code to populate the signDesc in
the case we have a non-trimmed balance. Additionally, we now also add a
*wire.OutPoint field to the struct in order to allow receivers of the
message to construct a witness that can spend the newly created output
to their wallet.
This commit modifies the methods that transition the state of the
channel into an active closing state. With the new commitment design,
the delivery scripts are no longer pre-committed to the initial funding
messages. Instead, the scripts are sent at the instant that either side
decides to shutdown within the Shutdown message.
This commit adds a new companion struct: OutgoingHtlcResolution to the
commitment state machine. The purpose of this struct is the provide the
caller with the information necessary to sweep all outgoing HTLC’s in
the case of a broadcast up-to-date commitment transaction.
The HTLC resolutions allow a caller to sweep an outgoing HTLC into
their wallet after the absolute timeout of the HTLc has passed. This is
a two step process, with the first portion consisting of broadcasting
the HTLC timeout transaction itself, and the second portion consisting
of claiming the HTLC itself after a CSV delay.
This commit adds awareness of active HTLC outputs to the
BreachRetribution struct. Previously, in the case of a breach, the
struct was only populated with enough information to sweep the two
commitment outputs. With this commit, the struct now has enough
information to sweep _all_ outputs within the commitment transaction.
This commit updates the central fetchCommitmentView method to manage
and derive the necessary easy required to create new commitments due to
the new state machine design within the specification. Each state now
requires us to derive a number of keys for each commitment state:
localDelay, remoteDelay, localKey, remoteKey, the commitment point, and
finally the revocation key itself.
This commit updates the set of functions tasked with generating HTLC’s
scripts for new commitments to now adhere to the new commitment
transaction design. With this change, the process of claiming an HTLC
now requires a second-level HTLC transaction, which solves a prior
issues due to the tight coupling of the timeout and delay clauses when
claiming an HTLC.
This commit adds a new method to the commitment struct:
populateHtlcIndexes. populateHtlcIndexes modifies the set of HTLC's
locked-into the target view to have full indexing information
populated. This information is required as we need to keep track of the
indexes of each HTLC in order to properly write the current state to
disk, and also to locate the PaymentDescriptor corresponding to HTLC
outputs in the commitment transaction.
We also modify toChannelDelta to take not of these new changes, and
access the appropriate index directly.
This commit modifies the way we account for dust HTLC’s within the
commitment state machine when creating and validating new states.
Previously, an HTLC was dust if the amount of the HTLC was below the
dustLimit of the commitment chain. Now, with the HTLC covenant
transaction, the value of the HTLC also needs to cover the required fee
of the HTLC covenant transaction at the specified fee rate of the
commitment chain.
As a result, we now determine if an HTLC is dust or not, only at the
commitment site, using the new htlcIsDust function.
This commit modifies the current core channel state machine in order to
may a step towards BOLT-0002 and BOLT-0003 compliance. In this change,
we abandon the prior revocation window, in favor of a fixed revocation
window of size two. The revocation window will be filled at the start
of the lifetime of the channel, and never extended from there until the
channel has been fully closed.
We now maintain two variables, the current un-revoked commitment point,
and the next commitment point to use when creating a new state. The
next commitment point must initially be inserted into the channel state
with the InitNextRevocation method.
A major difference between the prior revocation key handling is that
the remote party now instead sends us the _commitment point_ in
isolation, which we then use locally (with our revocation base point)
to create the next full revocation key for _their_ commitment
transaction.
This commit updates much of the state interaction within the
LightningChannel structure to account for the recent changes within the
chanenldb involving the OpenChannel struct, namely the introduction of
ChannelConfig and ChannelConstraints.
This commit introduce a new struct which acts as a companion struct to
the channel state machine struct. With the new commitment state
machine, we require a signature to be signed and validated for each
outstanding non-trimmed HTLC within the commitment state. As it’s
possible to have hundreds of HTLC’s on a given commitment transaction,
rather than perform all ECDSA operations in serial, we instead aim to
parallelize the computation with a worker pool of sign+verify workers.
The two primary methods of the sigPool are SubmitVerifyBatch and
SubmitSignBatch which allow a caller to trigger an asynchronous job
execution when creating or validating a new commitment state.
This commit updates the prior set of interface-level wallet tests to
exercise the new funding workflow, and also to switch to utilizing two
wallet instances throughout the tests. This allows us to abandon the
dependency on the bobNode struct.
This commit modifies the interface-level wallet integration tests to
spin up two distinct wallet instances, wiping them after each
successful test. This change paves the way for an upcoming change which
uses two live wallet instances, rather than mocking out most of the
other interaction.
This commit removes bobNode from the wallet’s funding interaction
tests. bobNode was originally created at a very early point in lnd’s
life time before any sort of back end chain access was hooked in. At
that time the integration tests were unable to run, but bobNode allowed
us to test a portion of the funding workflow given idealized inputs.
The tests will be modified in a later commit to eschew bobNode in favor
of just having two LightningWallet instances communicate with one
another.
This commit updates the engine that drives the reservation workflow to
utilize the new ChannelConfig and ChannelConstraint structs added in
prior commits. With this change, the internal reservation engine has
been modified to retain the prior dual funder workflow, but also be
able to properly manage and execute the new single funder workflow
defined in BOLT-0002.
This commit updates the channel reservation workflow in order to
properly implement the new funding workflow defined in BOLT-0002.
The workflow itself hasn’t changed significantly, but the contents of
the contributions of both sides have. The bulk of the fields within the
contribution of both sides has been boiled down into a pointer to the
ChannelConfig which houses all the data required to handle all states
of the channel, and commitment state machine.
For the two portions which are dictated by the other party, we now add
builder-like modifiers to allow specifying the constraints after the
initial portion of the workflow.
This commit modifies the Signer interface to reflect the new key
derivation defined within BOLT-0003. This entails removing the prior
PrivateTweak field all together in favor of two new fields: SingleTweak
and DoubleTweak.
These two fields are mutually exclusive. The SingleTweak field is now
required in order to sign all regular non-delay, and also must be used
to generate signatures for the localKey, or delayKey. The DoubleTweak
field is used to generate the private key that corresponds to the
revoked revocation key.
This commit updates the constants in size.go to include the weight of
the HTLC success and timeout transactions. These values are required in
order to properly compute the fee required for a particular HTLC
transaction. The fee will change depending on if the HTLC is incoming
or outgoing.
This commit adds a series of new functions that can be used to generate
the second level HTLC transactions, and also to claim the output
created by the transaction after a delay. The details of the scripts
and transaction format can be found in BOLT #3.
This commit updates all the pkScripts used within the commitment
transaction of the party that is on the reign side of an HTLC.
The major difference in these scripts as the prior generation’s is that
the claim action is now spared into a distinct transition. This clause
is guarded by a 2-of-2 multi-sig op code, which effecting creates an
off-chain covenant forcing the party claiming the transaction to incur
a delay before the funds can be swept.
This commit updates all the spendHtlcSpend* functions which are used to
spend each of the possible clauses within the HTLC contract placed on
the sender’s commitment transaction.
This commit updates the key derivation to match the derivation required
in order to construct and validate the commitment scheme that is used
within the draft specification of the Lightning Network. The new scheme
is very similar to the prior scheme aside from the following major
differences:
* Each key (not just the revocation key) now changes with each state.
* A commitment point (a component of the revocation key) is used to
randomize each key, and also generate new tweaked versions of the key.
* Base points are used along with the commitment point to generate
the keys for the commitment transaction.
* Before the remote party would send over the fully valid revocation
key. Now the remote party sends us a commitment point, which we then
use our local revocation base point to generate their revocation key.
This commit modifies the prior revocation root generation to a newer
version which is intended to allow for easy recovery of revocation
state. Rather than using the node’s keys (which we can’t count on NOT
to change), we instead now use the block hash as a salt. With this,
given the block hash prior to the one that funded the channel, and the
node’s identity key, we can reconstruct our revocation state.
This commit adds the possibility for the initiator of a
channel to send the update_fee message, as specified
in BOLT#2. After the message is sent and both parties
have committed to the updated fee, all new commitment
messages in the channel will use the specified fee.
If an HTLC’s value is below a node’s dust limit, the amount for that
HTLC should be applied to to the fee used for the channel’s commitment
transaction.
The btclog package has been changed to defining its own logging
interface (rather than seelog's) and provides a default implementation
for callers to use.
There are two primary advantages to the new logger implementation.
First, all log messages are created before the call returns. Compared
to seelog, this prevents data races when mutable variables are logged.
Second, the new logger does not implement any kind of artifical rate
limiting (what seelog refers to as "adaptive logging"). Log messages
are outputted as soon as possible and the application will appear to
perform much better when watching standard output.
Because log rotation is not a feature of the btclog logging
implementation, it is handled by the main package by importing a file
rotation package that provides an io.Reader interface for creating
output to a rotating file output. The rotator has been configured
with the same defaults that btcd previously used in the seelog config
(10MB file limits with maximum of 3 rolls) but now compresses newly
created roll files. Due to the high compressibility of log text, the
compressed files typically reduce to around 15-30% of the original
10MB file.
This commit fixes a race condition that would at times occur in the
htlcswitch.TestChannelLinkBidirectionalOneHopPayments test case. A race
condition would occur in the goroutine running ReceiveNewCommitment
compared with the grouting that would obtain the snapshot in order to
make a forwarding decision.
We fix this by creating a new public key for each new commitment
transaction such that we complete avoid the read/write race condition.
This commit fixes a race condition that was discovered as a result of
the new htlcswitch package. The StateSnapshot method and all of the
other methods which mutate the state of the channel state machine were
using distinct mutexes. The fix is trivial: all methods accessing the
internal channel state variable now use the same mutex.
This commit fixes a bug wherein the wallet would use the default relay
fee to craft transactions. On testnet, this might be insufficient or be
rejected all together in a mainnet setting. Therefore, we now pass in
the FeeEstimator interface and ensure that it’s consulted in order to
set the relay fee the wallet will use to craft transactions.
Note that this is a hold over until we have true dynamic fee
calculation within lnd which can then be extended to the internal
wallets.
In order to be able to use the DeriveRevocationRoot in the createChannel
function inside the htlcswicth package we need to make it public.
NOTE: The original lnwallet.CreateChannel function haven't been
sufficient as far it not takes the private keys as input.
add rhash to the payment descriptor when receiving the settle htlc in
order to be able to pass it during settle htlc packet generation and
later find the user pending payment by rhash without additional hashing.
In this commit we made state machine to be responsible for returning
proper available balance - amount of satoshi which we able to use at
current moment. This will help us in constrction channel link
abstraction.
In this commit severe bug have been fixed which allows the state of the
nodes to be desychnorinesed in the moments of high htlc flow. We limit
the number of the htlc which we can add to commitment transaction
to half of the available capcity. This change fixes the bug when
commimtment transaction on the verge of being full, in this case race
condition might occures and remote htlc will be rejected, but at the
same time they will be added on remote side, the same situiation will
happen with htlc we have added, which cause the commitment transactions
to be different.
This commit changes the cooperative channel close workflow to comply
with the latest spec. This adds steps to handle and send shutdown
messages as well as moving responsibility for sending the channel close
message from the initiator to the responder.
This commit modifies the fee calculation logic when creating or
accepting a new commitment transaction to use the set FeePerKw within
the channel rather then re-query the estimator each time. The prior
behavior was benign as we currently use a static fee estimator, but the
dynamic setting this could’ve caused a state divergence.
This commit corrects an error in the scaling as currently implemented
in the default static fee estimator. The spec draft has an error and
erroneously recommends multiplying by 4 to arrive at the fee-per-weight
from the fee-per-byte. This is incorrect as with the segwit block-size
increase, the ratio is 1/4 rather than 4.
This commit modifies the coin selection logic around selecting inputs
for a funding transaction to query the fee estimator directly (and use
fee-per-byte), rather than use the fee estimate which was passed into
the context.
We also use the value passed into the InitChannelReservation method
directly rather than make a call to the fee estimator. With this
change, the responder to a funding workflow will now properly adopt the
fee-per-kw suggested by the funder of the channel.
The remote balance in the case of a single funder workflow is simply
what ever the pushSat amount is. The capacity - fundingAmt in this
scenario would always be zero, so we simply just set it directly to
pushSat.
This commit replaces the hard-coded 5000 satoshi fees with calls to the
FeeEstimator interface. This should provide a way to cleanly plug in
additional fee calculation algorithms in the future. This change
affected quite a few tests. When possible, the tests were changed to
assert amounts sent rather than balances so that fees wouldn't need to
be taken into account. There were several tests for which this wasn't
possible, so calls to the static fee calculator were made.
This commit adds the FeeEstimator interface, which can be used for
future fee calculation implementations. Currently, there is only the
StaticFeeEstimator implementation, which returns the same fee rate for
any transaction.
In order to cleanly handle shutdowns and restarts during state machine operation, the fee for the current
commitment transaction must be persisted. This allows the fee to be
reapplied when the current state is reloaded.
In order to make the node's dust limit available to the wallet during
the initial stages of the funding process, add and set a
DustLimit field in the Contribution.
Primarily to avoid linting errors, the lnwallet.OP_CHECKSEQUENCEVERIFY
variable was removed and references to it replaced with
txscript.OP_CHECKSEQUENCEVERIFY.