We no longer track HTLC’s by their r-hash within the log into the
index, as we may have multiple HTLC’s that can be redeemed by the same
pre-image. Instead we now use a separate index which is keyed by a
log-index.
Additionally, the SettleHTLC method now also returns the index of the
HTLC being settled which allows the remote party to quickly locate the
HTLC within their log.
This commit also introduces a few trace/debug log messages which will
likely be pruned in the near future
This commit finishes the initial draft of the commitment state machine.
A full re-write of the prior protocol which combines aspects of the
former ‘lnstate’ package has replaced the prior un-finished
stop-and-wait protocol.
This new protocol is designed to operate in an asynchronous environment
and to facilitate non-blocking batched and pipelined updates to the
committed channel states. The protocol is also de-synchronized meaning
that either side can propose new commitment states independent of the
actions of the other party.
The state machine implemented is very similar to that of c-lightning,
however we allow multiple unrevoked commentates in order to minimize
blocking, and also to reduce latency across several hops in a
bi-directional setting.
The current implementation consists of 3 main data structures: a
commitment chain which consist of unrevoked commitment transactions
(one for each side), and a (mostly) append-only log of HTLC updates
shared between both sides. New commitments proposed index into the log
denoting which updates they include, this allows both parties to
progress chains independent of one another. Revoked commitments, reduce
the length of the chain by one, and free up space within the revocation
window.
At this point only basic tests are in place for the state machine,
however more extensive testing infrastructure along with formal proofs
using PlusCall are planned.
This commit updates the previous HTLC and commitment scripts to their
current latest evolution.
The HTLC scripts have been optimized for space savings, the
functionality itself has remained relatively unchanged. A trade off was
made to add additional bytes into the sigScript in order to avoid
extraneous CHECKSIG’s. The rationale is that an extra 1-2 bytes in the
sigScript to guide execution, are worthwhile since they’re in the
witness, and witness data may be pruned in the near future.
The primary change is within the commitment transaction itself. Instead
of using revocation hashes, we now use signature based revocation. This
saves space in the Script, and optimizes away an extra hashing
operation. Elkrem/shachain is still used but, we now use the pre-images
to homomorphically derive a public key which the other party will be
able to sign with, once we disclose the pre-image itself.
Finally, we have switched to using SHA-256 everywhere uniformly for
both revocation hashes, and payment hashes. The rationale is that the
output of ripemd160 is too small for modern security margins, and that
other coins/chains are more likely to have SHA-256 implemented, than
ripemd160.
A set of tests has also been included which contain (mostly) exhaustive
tests of all possible redemption paths for both commitment and HTLC.
This unifies some inconstancies across the code-base with hashes being
32 vs 20 bytes. All hashes, whether payment or revocation are now
uniformly 32 bytes everywhere. As a result, only OP_SHA256 will be used
within commitment and HTLC scripts. The rationale for using sha256
instead of hash160 for the HTLC payment pre-image is that alternative
chains are more likely to have sha256 implemented, rather than
ripemd160.
A forthcoming commit will update the current commitment, and HTLC
scripts.
A cooperative closure of a LightningChannel proceeds in two steps.
First, the party who wishes to close the channel sends a signature for
the closing transaction. Next, the responder reconstructs the closing
transaction identically as the initiator did using a canonical
input/output ordering, and the currently settled balance within the
channel. At this point, the responder then broadcasts the closure
transaction. It is the responsibility of the initiator to watch for
this transaction broadcast within the network to clean up any resources
they committed to the active channel.
* Hooks into the ChainNotifier infrastructure to receive a notification
once the funding transaction gets enough notifications.
* Still need to set up the notification grouting within a
LightningChannel to watch for uncooperative closures, and broadcasts
and revoked channel states.
* Updates to the channel are made atomic, and consistent via a proxy
object: “ChannelUpdate” which encapsulates an update transaction. Only
one update transaction may be outstanding at any time.
* Update transactions are initiated via AddHTLC or SettleHTLC.
* Once a transaction has been begun, in order to complete the update
the transaction must first be presented with a signature from the
counter-party for our new version of the commitment tx
(VerifyNewCommitmentSigs), and finally to atomically commit the
transaction, the counterparty’s pre-image to their previous revocation
hash must be validate (Commit).
* moved sorting of transaction outside of createCommitTx also us to add
HTLC’s before sorting
* On the fence about the proxy object design, will re-visit once we
start to implement the p2p code.
* Initial draft of brain dump of chandler. Nothing yet set in stone.
* Will most likely move the storage of all structs to a more “column”
oriented approach. Such that, small updates like incrementing the total
satoshi sent don’t result in the entire struct being serialized and
written.
* Some skeleton structs for other possible data we might want to store
are also included.
* Seem valuable to record as much data as possible for record keeping,
visualization, debugging, etc. Will need to set up a time+space+dirty
cache to ensure performance isn’t impacted too much.