lnwallet: add documentation to ChannelReservation
* Workflow along with expected call orders have been documented. * With this, the initial iteration of ChannelReservation is mostly complete. * However, there are still some unfinished steps internally within the wallet related to processing. Such as factoring proper tx fees, splitting fees, some node interaction etc.
This commit is contained in:
parent
b4c644c99a
commit
b2cb33c3c2
@ -10,7 +10,12 @@ import (
|
|||||||
"github.com/btcsuite/btcutil"
|
"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 {
|
type ChannelContribution struct {
|
||||||
// Amount of funds contributed to the funding transaction.
|
// Amount of funds contributed to the funding transaction.
|
||||||
FundingAmount btcutil.Amount
|
FundingAmount btcutil.Amount
|
||||||
@ -43,8 +48,38 @@ type ChannelContribution struct {
|
|||||||
CsvDelay uint32
|
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 {
|
type ChannelReservation struct {
|
||||||
|
// TODO(roasbeef): remove this? we're only implementing the golden...
|
||||||
fundingType FundingType
|
fundingType FundingType
|
||||||
|
|
||||||
// This mutex MUST be held when either reading or modifying any of the
|
// This mutex MUST be held when either reading or modifying any of the
|
||||||
@ -81,7 +116,10 @@ type ChannelReservation struct {
|
|||||||
wallet *LightningWallet
|
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,
|
func newChannelReservation(t FundingType, fundingAmt btcutil.Amount,
|
||||||
minFeeRate btcutil.Amount, wallet *LightningWallet, id uint64) *ChannelReservation {
|
minFeeRate btcutil.Amount, wallet *LightningWallet, id uint64) *ChannelReservation {
|
||||||
// TODO(roasbeef): CSV here, or on delay?
|
// 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.
|
// NOTE: This SHOULD NOT be modified.
|
||||||
|
// TODO(roasbeef): make copy?
|
||||||
func (r *ChannelReservation) OurContribution() *ChannelContribution {
|
func (r *ChannelReservation) OurContribution() *ChannelContribution {
|
||||||
r.RLock()
|
r.RLock()
|
||||||
defer r.RUnlock()
|
defer r.RUnlock()
|
||||||
return r.ourContribution
|
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 {
|
func (r *ChannelReservation) ProcessContribution(theirContribution *ChannelContribution) error {
|
||||||
errChan := make(chan error, 1)
|
errChan := make(chan error, 1)
|
||||||
|
|
||||||
@ -126,20 +173,42 @@ func (r *ChannelReservation) ProcessContribution(theirContribution *ChannelContr
|
|||||||
return <-errChan
|
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 {
|
func (r *ChannelReservation) TheirContribution() *ChannelContribution {
|
||||||
r.RLock()
|
r.RLock()
|
||||||
defer r.RUnlock()
|
defer r.RUnlock()
|
||||||
return r.theirContribution
|
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) {
|
func (r *ChannelReservation) OurSignatures() ([][]byte, []byte) {
|
||||||
r.RLock()
|
r.RLock()
|
||||||
defer r.RUnlock()
|
defer r.RUnlock()
|
||||||
return r.ourFundingSigs, r.ourCommitmentSig
|
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,
|
func (r *ChannelReservation) CompleteReservation(fundingSigs [][]byte,
|
||||||
commitmentSig []byte) error {
|
commitmentSig []byte) error {
|
||||||
|
|
||||||
@ -155,21 +224,31 @@ func (r *ChannelReservation) CompleteReservation(fundingSigs [][]byte,
|
|||||||
return <-errChan
|
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) {
|
func (r *ChannelReservation) TheirSignatures() ([][]byte, []byte) {
|
||||||
r.RLock()
|
r.RLock()
|
||||||
defer r.RUnlock()
|
defer r.RUnlock()
|
||||||
return r.theirFundingSigs, r.theirCommitmentSig
|
return r.theirFundingSigs, r.theirCommitmentSig
|
||||||
}
|
}
|
||||||
|
|
||||||
// FinalFundingTransaction...
|
// FinalFundingTx returns the finalized, fully signed funding transaction for
|
||||||
|
// this reservation.
|
||||||
func (r *ChannelReservation) FinalFundingTx() *wire.MsgTx {
|
func (r *ChannelReservation) FinalFundingTx() *wire.MsgTx {
|
||||||
r.RLock()
|
r.RLock()
|
||||||
defer r.RUnlock()
|
defer r.RUnlock()
|
||||||
return r.partialState.FundingTx
|
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 {
|
func (r *ChannelReservation) Cancel() error {
|
||||||
errChan := make(chan error, 1)
|
errChan := make(chan error, 1)
|
||||||
r.wallet.msgChan <- &fundingReserveCancelMsg{
|
r.wallet.msgChan <- &fundingReserveCancelMsg{
|
||||||
@ -180,7 +259,12 @@ func (r *ChannelReservation) Cancel() error {
|
|||||||
return <-errChan
|
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 {
|
func (r *ChannelReservation) WaitForChannelOpen() *LightningChannel {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user