diff --git a/lnwallet/reservation.go b/lnwallet/reservation.go index b7dafc76..58052321 100644 --- a/lnwallet/reservation.go +++ b/lnwallet/reservation.go @@ -10,7 +10,12 @@ import ( "github.com/btcsuite/btcutil" ) -// ChannelContribution... +// ChannelContribution is the primary constituent of the funding workflow within +// lnwallet. Each side first exchanges their respective contributions along with +// channel specific paramters like the min fee/KB. Once contributions have been +// exchanged, each side will then produce signatures for all their inputs to the +// funding transactions, and finally a signature for the other party's version +// of the commitment transaction. type ChannelContribution struct { // Amount of funds contributed to the funding transaction. FundingAmount btcutil.Amount @@ -43,8 +48,38 @@ type ChannelContribution struct { CsvDelay uint32 } -// ChannelReservation... +// ChannelReservation represents an intent to open a lightning payment channel +// a counterpaty. The funding proceses from reservation to channel opening is a +// 3-step process. In order to allow for full concurrency during the reservation +// workflow, resources consumed by a contribution are "locked" themselves. This +// prevents a number of race conditions such as two funding transactions +// double-spending the same input. A reservation can also be cancelled, which +// removes the resources from limbo, allowing another reservation to claim them. +// +// The reservation workflow consists of the following three steps: +// 1. lnwallet.InitChannelReservation +// * One requests the wallet to allocate the neccessary resources for a +// channel reservation. These resources a put in limbo for the lifetime +// of a reservation. +// * Once completed the reservation will have the wallet's contribution +// accessible via the .OurContribution() method. This contribution +// contains the neccessary items to allow the remote party to build both +// the funding, and commitment transactions. +// 2. ChannelReservation.ProcessContribution +// * The counterparty presents their contribution to the payment channel. +// This allows us to build the funding, and commitment transactions +// ourselves. +// * We're now able to sign our inputs to the funding transactions, and +// the counterparty's version of the commitment transaction. +// * All signatures crafted by us, are now available via .OurSignatures(). +// 3. ChannelReservation.CompleteReservation +// * The final step in the workflow. The counterparty presents the +// signatures for all their inputs to the funding transation, as well +// as a signature to our version of the commitment transaction. +// * We then verify the validity of all signatures before considering the +// channel "open". type ChannelReservation struct { + // TODO(roasbeef): remove this? we're only implementing the golden... fundingType FundingType // This mutex MUST be held when either reading or modifying any of the @@ -81,7 +116,10 @@ type ChannelReservation struct { wallet *LightningWallet } -// newChannelReservation... +// newChannelReservation creates a new channel reservation. This function is +// used only internally by lnwallet. In order to concurrent safety, the creation +// of all channel reservations should be carried out via the +// lnwallet.InitChannelReservation interface. func newChannelReservation(t FundingType, fundingAmt btcutil.Amount, minFeeRate btcutil.Amount, wallet *LightningWallet, id uint64) *ChannelReservation { // TODO(roasbeef): CSV here, or on delay? @@ -105,15 +143,24 @@ func newChannelReservation(t FundingType, fundingAmt btcutil.Amount, } } -// OurContribution... +// OurContribution returns the wallet's fully populated contribution to the +// pending payment channel. See 'ChannelContribution' for further details +// regarding the contents of a contribution. // NOTE: This SHOULD NOT be modified. +// TODO(roasbeef): make copy? func (r *ChannelReservation) OurContribution() *ChannelContribution { r.RLock() defer r.RUnlock() return r.ourContribution } -// ProcessContribution... +// ProcesContribution verifies the counterparty's contribution to the pending +// payment channel. As a result of this incoming message, lnwallet is able to +// build the funding transaction, and both commitment transactions. Once this +// message has been processed, all signatures to inputs to the funding +// transaction belonging to the wallet are available. Additionally, the wallet +// will generate a signature to the counterparty's version of the commitment +// transaction. func (r *ChannelReservation) ProcessContribution(theirContribution *ChannelContribution) error { errChan := make(chan error, 1) @@ -126,20 +173,42 @@ func (r *ChannelReservation) ProcessContribution(theirContribution *ChannelContr return <-errChan } +// TheirContribution returns the counterparty's pending contribution to the +// payment channel. See 'ChannelContribution' for further details regarding +// the contents of a contribution. This attribute will ONLY be available +// after a call to .ProcesContribution(). +// NOTE: This SHOULD NOT be modified. func (r *ChannelReservation) TheirContribution() *ChannelContribution { r.RLock() defer r.RUnlock() return r.theirContribution } -// OurSignatures... +// OurSignatures retrieves the wallet's signatures to all inputs to the funding +// transaction belonging to itself, and also a signature for the counterparty's +// version of the commitment transaction. The signatures for the wallet's +// inputs to the funding transaction are returned in sorted order according to +// BIP-69: https://github.com/bitcoin/bips/blob/master/bip-0069.mediawiki. +// NOTE: These signatures will only be populated after a call to +// .ProcesContribution() func (r *ChannelReservation) OurSignatures() ([][]byte, []byte) { r.RLock() defer r.RUnlock() return r.ourFundingSigs, r.ourCommitmentSig } -// CompleteFundingReservation... +// CompleteFundingReservation finalizes the pending channel reservation, +// transitioning from a pending payment channel, to an open payment +// channel. All passed signatures to the counterparty's inputs to the funding +// transaction will be fully verified. Signatures are expected to be passed in +// sorted order according to BIP-69: +// https://github.com/bitcoin/bips/blob/master/bip-0069.mediawiki. Additionally, +// verification is performed in order to ensure that the counterparty supplied +// a valid signature to our version of the commitment transaction. +// Once this method returns, caller's should then call .WaitForChannelOpen() +// which will block until the funding transaction obtains the configured number +// of confirmations. Once the method unblocks, a LightningChannel instance is +// returned, marking the channel available for updates. func (r *ChannelReservation) CompleteReservation(fundingSigs [][]byte, commitmentSig []byte) error { @@ -155,21 +224,31 @@ func (r *ChannelReservation) CompleteReservation(fundingSigs [][]byte, return <-errChan } -// OurSignatures... +// OurSignatures returns the counterparty's signatures to all inputs to the +// funding transaction belonging to them, as well as their signature for the +// wallet's version of the commitment transaction. This methods is provided for +// additional verification, such as needed by tests. +// NOTE: These attributes will be unpopulated before a call to +// .CompleteReservation(). func (r *ChannelReservation) TheirSignatures() ([][]byte, []byte) { r.RLock() defer r.RUnlock() return r.theirFundingSigs, r.theirCommitmentSig } -// FinalFundingTransaction... +// FinalFundingTx returns the finalized, fully signed funding transaction for +// this reservation. func (r *ChannelReservation) FinalFundingTx() *wire.MsgTx { r.RLock() defer r.RUnlock() return r.partialState.FundingTx } -// RequestFundingReserveCancellation... +// Cancel abandons this channel reservation. This method should be called in +// the scenario that communications with the counterparty break down. Upon +// cancellation, all resources previously reserved for this pending payment +// channel are returned to the free pool, allowing subsequent reservations to +// utilize the now freed resources. func (r *ChannelReservation) Cancel() error { errChan := make(chan error, 1) r.wallet.msgChan <- &fundingReserveCancelMsg{ @@ -180,7 +259,12 @@ func (r *ChannelReservation) Cancel() error { return <-errChan } -// WaitForChannelOpen... +// WaitForChannelOpen blocks until the funding transaction for this pending +// payment channel obtains the configured number of confirmations. Once +// confirmations have been obtained, a fully initialized LightningChannel +// instance is returned, allowing for channel updates. +// NOTE: If this method is called before .CompleteReservation(), it will block +// indefinitely. func (r *ChannelReservation) WaitForChannelOpen() *LightningChannel { return nil }