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.
This commit changes t.Fatal to t.Fatalf in TestCheckDustLimit so as to
provide more information. This commit also makes some column width
adjustments and minor spelling/formatting changes.
This commit modifies the GetUtxo method of the BlockChainIO interface
to be more light client friendly by introducing a height hint which
gives light clients that don’t have UTXO set commitments a way in which
they can restrict their search space. Light clients will now be able to
have a concrete cut off point in the chain as they scan backwards for
spentness of an output.
This commit modifies the actions of the closeObserver goroutine to
utilize a _new_ channel to send channel close details over. The
original close signal channel is still used to notify observers that a
channel _has_ been closed, but this new channel will provide a single
observer with details w.r.t _how_ a channel was closed.
This commit adds an additional field to the ForceCloseSummary that
allows observers of the channel that sends this struct to track _which_
channel the force close came from.
Previously, if an error was returned during handleSingleFunderSigs or
handleFundingCounterPartySigs, the wallet would hang waiting for
the completeChan channel to be populated. This commit adds nil returns for
the completeChan when errors are propagated.
This commit modifies the way we go about unlocking the wallet. With the
latest changes to the API of btcwallet, we can on longer directly
access the waddrmgr struct. As a result, we’re now forced to go
_directly_ via the wallet to unlock the waddrmgr. The root
LightingWallet has been modified to not request the root key until we
finish starting the underlying wallet, so we can unlock the wallet in
the Start() method.
This commit modifies the initialization logic of the LightningWallet to
fetch the root key during startup rather than during creation. We make
this change in order to give enough time for the underlying
WalletController to properly boot up before we ask it to do any work.
This commit removes the now deprecated FundingSigner struct as part of
the btcwallet package, and instead replaces it within an implementation
of the MessageSigner interface.
This commit introduces the MessageSigner interface which is an abstract
object capable of signing arbitrary messages with a target public key.
This interface will be used within the daemon for: signing channel
authentication proofs, signing node/channel announcements, and also to
possibly sign arbitrary messages in the future.
This commit improves the channel state machine by converting the
objective PendingUpdates method to a subjective FullySynced method
which is to be used in place of PendingUpdates. The new FullySynced
method is fully encompassing and replaces any upper state required by
the state machine which wraps this one.
The new FullySynced method is identical to PendingUpdates aside from
the fact that: it now also factors in the log message index of the
remote commitment chain, and also introduces a concept of an “owed
commitment”. A commitment chain owes a commitment if the height of the
local commitment chain is higher than that of the remote chain.
This commit removes the theirPrevPkScript field from the
LightningChannel struct all together. It’s no longer needed as the more
fundamental mutation bug has been fixed within the channel state
machine.
This commit fixes a class of bug that can arise in the channel state
machine when a very high throughput workflow is attempted. Since the
PaymentDescriptor’s within a commitment pointed directly into the log,
any changes to a payment descriptor would also be reflected in all
other ones. Due to this mutation possibility, at times, the
locateOutputIndex method would fail since the HTLC’s pkScript was
modified, causing the channel to fail.
We fix this class of bug by simply ensure that once an HTLC has been
associated with a particular commitment, then it becomes immutable.
This commit fixes a build issue that appears when attempting to
cross-compile binaries to a 32-bit system from a 64-bit system. The
issue was that the defined max-state hint overflows a 32-bit integer. To
fix this issue, we now proeprly specify a type of a uint64 for the typed
constant.
This commit bolsters the logging available within the lnwallet package
by include the logging from both web sockets connections, and the
wtxmgr as part of the exposed package level logging. With this, users
will gain additional avenues for obtaining debug logs from various
parts of the system.
This commit implements some minor coding style, commenting and naming
clean up after the recent major discovery service was merged into the
codebase.
Highlights of the naming changes:
* fundingManager.SendToDiscovery -> SendAnnouncement
* discovery.Discovery -> discovery.AuthenticatedGossiper
The rest of the changes consist primary of grammar fixes and proper
column wrapping.
Added the signer which will be needed in the funding manager to sign
the lnwaire announcement message before sending them to discovery
package. Also in the future the message signer will be used to sign
the users data.
This commit fixes a slight oversight in the current state machine which
assumes that both commitment chains are always at the same height. In a
future where we move back to allowing nodes to pipeline commitment
updates, this will not always be the case.
This commit fixes a lingering TODO within the wallet portion of the
codebase by properly adhering to the set dust limits when closing a
channel. With this new commit if a party’s current settled balance is
below their current dust-limit, then it will be omitted from the
commitment transaction.
The prior test that asserted negative outputs are rejected has been
removed as they’ll now be avoided by ensuring we omit dust outputs from
the commitment transaction.
This commit does some minor shuffling around and also adds some
additional comments to the restoreStateLogs method within the channel
state machine. After the latest merge in this area, the code has
diverged slightly from what’s considered typical within the rest of the
codebase.
It is possible that that there are multiple HTLCs with different values,
but the same public key script. As such, a check against the value should
be performed when looking for HTLC outputs in a commitment transaction.
Create a new helper method called genHtlcScript which will
generate the public key scripts for a supplied HTLC. This functionality
from addHTLC is removed, and addHTLC will instead call this new
method.
In restoreStateLogs we will regenerate the public key scripts for the
HTLCs with genHtlcScript and restore the proper values.
When an HTLC is either cancelled or settled we must properly set the
pkScript for the HTLC on the remote commitment, such that we can
generate a valid ChannelDelta.
Description of bug:
When calling ReceiveNewCommitment() we will progress through methods
fetchCommitmentView and addHTLC which will add HTLC outputs to the
commitment transaction in the local commitment chain and save the
pkScript to the relevant PaymentDescriptor which resides in the
corresponding updateLog. Finally the local commitment will be added
to the local commitment chain.
When the same user next calls SignNextCommitment we will again
progress through fetchCommitmentView and addHTLC. In addHTLC we will
now overwrite the pkScripts in the PaymentDescriptors with the
pkScript from the context of the remote commitment. When we later
call RevokeCurrentCommitment and proceed into toChannelDelta, we
will not be able to find the correct pkScript in the PaymentDescriptor
to match it against the outputs in the commitment transaction.
This will lead to the nested function locateOutputIndex returning
incorrect values.
Fixing the bug:
We introduce three new fields in PaymentDescriptor:
* ourPkScript
* theirPkScript
* theirPrevPkScript
ourPkScript will include the pkScript for the HTLC from the context
of the local commitment.
theirPkScript will take the value of the latest pkScript for the HTLC
from the context of the remote commitment.
theirPrevPkScript will take the second-latest pkScript for the HTLC
from the context of the remote commitment. This is the value we use
in toChannelDelta when we save a revoked commitment from our peer.
The appropriate value of these fields are set in the addHTLC method.
Additionally we pass a boolean value to toChannelDelta so we know
whether we are operating on a local or remote commitment and grab
the correct pkScript in locateUpdateIndex.
This commit removes all instances of the fastsha256 library and
replaces it with the sha256 library in the standard library. This
change should see a number of performance improvements as the standard
library has highly optimized assembly instructions with use vectorized
instructions as the platform supports.
If the value of the to-local output is below the dust limit, the
ForceCloseSummary should not include a sign descriptor for this output.
We also find the proper to-self output by looking for the expected public
key script and not assume that no HTLC outputs exist.
Currently non-HTLC outputs will be accepted in the commitment
transaction as long as it is non-zero. We change this by not allowing
outputs with a value lower than the dust limit. The value of such
an output will go towards transaction fees.
This commit fixes a class of bug that currently exists within the
cooperative closure methods for the channel state machine. As an
example, due to the current hard coded fees, if one of the outputs
generated within the generated closure transaction has a negative
output, then the initiating node would gladly forward this to the
remote node. The remote node would then reject the closure as the
transaction is invalid. However, the act of completing the closure
would cause the remote node’s state machine to shift into a “closed”
state. As a result, any further closure attempts by the first node
(force or regular) would go unnoticed by the remote node.
We fix this issue by ensuring the transaction is “sane” before
initiating of completing a cooperative channel closure.
At test case has been added exercising the particular erroneous case
reported by “moli” on IRC.
This commit avoids a class of bug wherein the state of the channel
would be marked as closing enough though an error occurred somewhere in
the function. The bug was due to the fact that the channel `status` was
shifted before any actual logic within the function(s) were executed.
We fix this bug by _only_ shifting the channel status once the function
has completed without any error.
This commit adds a new method to the channel’s state machine:
NextRevocationKey. This method is being added in preparation for the
upcoming change to switch to the commitment transaction format outlined
in the spec. When this comes to pass, the ExtendRevocationWindow method
will be removed, as it will no longer be needed.
The NextRevocationKey method will be needed as to conform to the spec,
we’ll need to send the next revocation key within the `fundingLocked`
message.
This commit adds the FundingManagerPersistence test to ensure that the
funding process completes as expected when nodes shutdown after the the
funding transaction has been broadcast. Note that the final parts of
several wallet tests have been removed, as functionality has been moved
to the Funding Manager and should now be tested there.
Once a channel funding process has advanced to the point of broadcasting
the funding transaction, the state of the channel should be persisted
so that the nodes can disconnect or go down without having to wait for the
funding transaction to be confirmed on the blockchain.
Previously, the finalization of the funding process was handled by a
combination of the funding manager, the peer and the wallet, but if
the remote peer is no longer online or no longer connected, this flow
will no longer work. This commit moves all funding steps following
the transaction broadcast into the funding manager, which is available
as long as the daemon is running.
When a pending channel is persisted and then reloaded upon system startup
it's necessary to also persist the number of confirmations that will be required
before the pending channel can be opened.
In order to facilitate persistence during the funding process, added
the isPending flag to channels so that when the daemon restarts, we can
properly re-initialize the chain notifier and update the state of
channels that were going through the funding process.
In this commit the initial implementation of revocation hash
generation 'elkrem' was replaced with 'shachain' Rusty Russel
implementation which currently enshrined in the spec. This alghoritm has
the same asymptotic characteristics but has more complex scheme
to determine wish hash we can drop and what needs to be stored
in order to be able to achive full compression.
Introduce TimelockShift which is used to make sure the commitment
transaction is spendable by setting the locktime with it so that
it is larger than 500,000,000, thus interpreting it as Unix epoch
timestamp and not a block height. It is also smaller than the current
timestamp which has bit (1 << 30) set, so there is no risk of having
the commitment transaction be rejected. This way we can safely use
the lower 24 bits of the locktime field for part of the obscured
commitment transaction number.
Add tests to assert maximum state can be used. Also test
that more than one input in the commitment transaction
will fail and that having state number larger than
maxStateHint will fail.
Fix SetStateNumHint and GetStateNumHint to properly
set and get the stateNumHints using the lower 24 bits
of the locktime of the commitment transaction as the
lower 24 bits of the obfuscated state number and the
lower 24 bits of the sequence field as the higher 24
bits.
This commit fixes a bug in the wallet’s internal reservation manager
that prevented it from cleaning up the resources used by a reservation
after it was finished running through the workflow.
We fix this issue by ensuring the reservations context is deleted from
the funding limbo.
It is the callers responsibility to properly .Cancel() a reservation in
the case of an error during the funding workflow.
This commit adds an additional case of the closeObserver that will
properly handle the case of a channel being closed by a de-sync’d
commitment transaction from the PoV of the local node. In the case of a
minor 1-state divergence, the commitment transaction broadcast by the
remote node will be 1 state ahead of the commitment transaction we have
locally. This should be seen as a regular unilateral close as they
remote peer didn’t violate the channel contract in any way.
We address this case by changing the `==` to a `>=`.
This commit updates the set of channel state machine tests to properly
compile and execute with the latest set of changes to the state
machine.
Most of the changes within this commit are just renaming and field
changes as a result of the new wire messages.
The more substantial change is due to the change in semantics of the
new state machine w.r.t what has and has not been ACK’d when a new
state transition is implemented. In the case of a concurrent update
(both sides add to the log before a state transition), both sides need
to trigger a state update in order to ensure their updates have been
included.
This commit updates the internal channel state machine to the one as
described within the spec and currently implemented within the rest of
the other Lightning implementations.
At a high level the following modifications have been made:
* When signing we no loner include the index of the remote party’s
log
that our signature covers. Instead we include ALL of our current
updates, but only the updates of the remote party that we’ve
ACK’d.
* A pending change is considered ACK’d once a revocation message
has been received, locking in the changes in the remote party’s
commitment transaction.
* When sending a new commitment, we remember the index of our
log at that point so we can mark that portion of the log as ACK’d
once we receive a revocation message from the remote party.
* When receiving a new commitment signature, we include ALL of
the remote party’s changes that we’ve received but only our set
of changes that’ve been ACK’d by the remote party.
* Implicitly a revocation message now also implicitly serves to ACK
all the changes that were included in the CommitSig message
received before it.
The resulting change is a rather minor diff. However, with this state
machine it’s important to note that the order to sig/revoke messages
has been swapped. A proper exchange now looks like the following:
* Alice -> Add, Add, Add
* Alice -> Sig
* Revoke <- Bob
* Sig <- Bob
* Alice -> Revoke
One other thing that’s worth noting is that with this state machine,
since what’s included in an update is implicit, both side may need to
at times send a new commitment update in the case of a concurrent state
transition initiated by both sides.
Finally, all counters/indexes have been made 64-bit integers in order
to properly match the spec.
This commit adds a new struct to the channel state machine: updateLog.
updateLog encapsulates the update log linked list itself, a series of
new counters we’ll need in order to switch to the spec’s state machine
and also the index into the log itself. This new struct serves to
simplify much of the logic surrounding the update log and also
elminates a bit of code duplication within the current state machine.
This commit only adds the new struct. The rest of the state machine
will be updated in a later commit to use the new log and its new
counters.
This commit fixes a bug in the LightingChannel commitment state machine
which could occasionally result in the total number of satoshis sent or
received being counted twice if a redundant state transition were
initiated.
To fix this bug, we now only increment the number of satoshi
sent/recv’d iff it’s the first time the HTLC has been processed.
This commit ensures that when a channel’s closeObserver is signaled to
exit before a channel closure has been detected, then the resources
dedicated to the pending spend notification can be freed up.
rHashMap is used to store the PaymentDescriptor belonging to a received
HTLC's revocation hash. This improves the efficiency of looking up
PaymentDescriptors from their RHash whenever we want to settle or cancel
that HTLC.
This commit fixes a bug which would cause the node on the _receiving_
side of a channel force close to be blind of their immediately funds
on-chain. The root of the issue was that within the btcwallet
implementation of the WalletController method ‘NewRawKey’, the wallet
wouldn’t request notifications for the new address, as the direct
function from the waddrmgr was used which skips registration of the new
address.
To fix, this, we now ensure that btcwallet will receive notifications
for keys used within the raw p2wkh commitment output. This ensures that
the wallet is aware of funds that are made available as a result of a
channel force closure by the channel counter party.