lnwallet: add ChannelContribution, finalize ChannelReservation API/workflow
* Final workflow has been greatly simplified. * Interaction is now: * init * add contribution * complete
This commit is contained in:
parent
b606804934
commit
e762d328fa
@ -8,58 +8,178 @@ import (
|
||||
"github.com/btcsuite/btcutil"
|
||||
)
|
||||
|
||||
// ChannelContribution...
|
||||
type ChannelContribution struct {
|
||||
// Amount of funds contributed to the funding transaction.
|
||||
FundingAmount btcutil.Amount
|
||||
|
||||
// Inputs to the funding transaction.
|
||||
Inputs []*wire.TxIn
|
||||
|
||||
// Outputs to be used in the case that the total value of the fund
|
||||
// ing inputs is greather than the total potential channel capacity.
|
||||
ChangeOutputs []*wire.TxOut
|
||||
|
||||
// The key to be used for the funding transaction's P2SH multi-sig
|
||||
// 2-of-2 output.
|
||||
MultiSigKey *btcec.PublicKey
|
||||
|
||||
// The key to be used for this party's version of the commitment
|
||||
// transaction.
|
||||
CommitKey *btcec.PublicKey
|
||||
|
||||
// Address to be used for delivery of cleared channel funds in the scenario
|
||||
// of a cooperative channel closure.
|
||||
DeliveryAddress btcutil.Address
|
||||
|
||||
// Hash to be used as the revocation for the initial version of this
|
||||
// party's commitment transaction.
|
||||
RevocationHash [wire.HashSize]byte
|
||||
|
||||
// The delay (in blocks) to be used for the pay-to-self output in this
|
||||
// party's version of the commitment transaction.
|
||||
CsvDelay int64
|
||||
}
|
||||
|
||||
// ChannelReservation...
|
||||
type ChannelReservation struct {
|
||||
sync.RWMutex // All fields below owned by the lnwallet.
|
||||
fundingType FundingType
|
||||
|
||||
//for CLTV it is nLockTime, for CSV it's nSequence, for segwit it's not needed
|
||||
// This mutex MUST be held when either reading or modifying any of the
|
||||
// fields below.
|
||||
sync.RWMutex
|
||||
|
||||
// For CLTV it is nLockTime, for CSV it's nSequence, for segwit it's
|
||||
// not needed
|
||||
fundingLockTime int64
|
||||
fundingAmount btcutil.Amount
|
||||
|
||||
//Current state of the channel, progesses through until complete
|
||||
//Makes sure we can't go backwards and only accept messages once
|
||||
channelState uint8
|
||||
|
||||
theirInputs []*wire.TxIn
|
||||
ourInputs []*wire.TxIn
|
||||
|
||||
// NOTE(j): FundRequest assumes there is only one change (see ChangePkScript)
|
||||
theirChange []*wire.TxOut
|
||||
ourChange []*wire.TxOut
|
||||
|
||||
theirMultiSigKey *btcec.PublicKey
|
||||
|
||||
// In order of sorted inputs. Sorting is done in accordance
|
||||
// to BIP-69: https://github.com/bitcoin/bips/blob/master/bip-0069.mediawiki.
|
||||
ourFundingSigs [][]byte
|
||||
theirFundingSigs [][]byte
|
||||
|
||||
ourRevokeHash [wire.HashSize]byte
|
||||
// Our signature for their version of the commitment transaction.
|
||||
ourCommitmentSig []byte
|
||||
|
||||
ourContribution *ChannelContribution
|
||||
theirContribution *ChannelContribution
|
||||
|
||||
partialState *OpenChannelState
|
||||
|
||||
// The ID of this reservation, used to uniquely track the reservation
|
||||
// throughout its lifetime.
|
||||
reservationID uint64
|
||||
wallet *LightningWallet
|
||||
|
||||
// A channel which will be sent on once the channel is considered
|
||||
// 'open'. A channel is open once the funding transaction has reached
|
||||
// a sufficient number of confirmations.
|
||||
chanOpen chan *LightningChannel
|
||||
|
||||
wallet *LightningWallet
|
||||
}
|
||||
|
||||
// newChannelReservation...
|
||||
func newChannelReservation(t FundingType, fundingAmt btcutil.Amount,
|
||||
minFeeRate btcutil.Amount, wallet *LightningWallet, id uint64) *ChannelReservation {
|
||||
// TODO(roasbeef): CSV here, or on delay?
|
||||
return &ChannelReservation{
|
||||
fundingAmount: fundingAmt,
|
||||
// TODO(roasbeef): assumes balanced symmetric channels.
|
||||
partialState: &OpenChannelState{
|
||||
capacity: fundingAmt * 2,
|
||||
fundingType: t,
|
||||
fundingType: t,
|
||||
ourContribution: &ChannelContribution{
|
||||
FundingAmount: fundingAmt,
|
||||
},
|
||||
theirContribution: &ChannelContribution{
|
||||
FundingAmount: fundingAmt,
|
||||
},
|
||||
partialState: &OpenChannelState{
|
||||
// TODO(roasbeef): assumes balanced symmetric channels.
|
||||
capacity: fundingAmt * 2,
|
||||
minFeePerKb: minFeeRate,
|
||||
},
|
||||
wallet: wallet,
|
||||
reservationID: id,
|
||||
wallet: wallet,
|
||||
}
|
||||
}
|
||||
|
||||
// OurContribution...
|
||||
// NOTE: This SHOULD NOT be modified.
|
||||
func (r *ChannelReservation) OurContribution() *ChannelContribution {
|
||||
r.RLock()
|
||||
defer r.RUnlock()
|
||||
return r.ourContribution
|
||||
}
|
||||
|
||||
// ProcessContribution...
|
||||
func (r *ChannelReservation) ProcessContribution(theirContribution *ChannelContribution) error {
|
||||
errChan := make(chan error, 1)
|
||||
|
||||
r.wallet.msgChan <- &addContributionMsg{
|
||||
pendingFundingID: r.reservationID,
|
||||
contribution: theirContribution,
|
||||
err: errChan,
|
||||
}
|
||||
|
||||
return <-errChan
|
||||
}
|
||||
|
||||
func (r *ChannelReservation) TheirContribution() *ChannelContribution {
|
||||
r.RLock()
|
||||
defer r.RUnlock()
|
||||
return r.theirContribution
|
||||
}
|
||||
|
||||
// OurSignatures...
|
||||
func (r *ChannelReservation) OurSignatures() ([][]byte, []byte) {
|
||||
r.RLock()
|
||||
defer r.RUnlock()
|
||||
return r.ourFundingSigs, r.ourCommitmentSig
|
||||
}
|
||||
|
||||
// CompleteFundingReservation...
|
||||
// TODO(roasbeef): add commit sig also
|
||||
func (r *ChannelReservation) CompleteReservation(fundingSigs [][]byte, commitmentSig []byte) error {
|
||||
errChan := make(chan error, 1)
|
||||
|
||||
r.wallet.msgChan <- &addCounterPartySigsMsg{
|
||||
pendingFundingID: r.reservationID,
|
||||
theirFundingSigs: fundingSigs,
|
||||
theirCommitmentSig: commitmentSig,
|
||||
err: errChan,
|
||||
}
|
||||
|
||||
return <-errChan
|
||||
}
|
||||
|
||||
// OurSignatures...
|
||||
func (r *ChannelReservation) TheirSignatures() ([][]byte, []byte) {
|
||||
r.RLock()
|
||||
defer r.RUnlock()
|
||||
return r.theirFundingSigs, r.partialState.theirCommitSig
|
||||
}
|
||||
|
||||
// FinalFundingTransaction...
|
||||
func (r *ChannelReservation) FinalFundingTx() *wire.MsgTx {
|
||||
r.RLock()
|
||||
defer r.RUnlock()
|
||||
return r.partialState.fundingTx
|
||||
}
|
||||
|
||||
// RequestFundingReserveCancellation...
|
||||
// TODO(roasbeef): also return mutated state?
|
||||
func (r *ChannelReservation) Cancel() error {
|
||||
errChan := make(chan error, 1)
|
||||
r.wallet.msgChan <- &fundingReserveCancelMsg{
|
||||
pendingFundingID: r.reservationID,
|
||||
err: errChan,
|
||||
}
|
||||
|
||||
return <-errChan
|
||||
}
|
||||
|
||||
// WaitForChannelOpen...
|
||||
func (r *ChannelReservation) WaitForChannelOpen() *LightningChannel {
|
||||
return nil
|
||||
}
|
||||
|
||||
/*//FundRequest serialize
|
||||
//(reading from ChannelReservation directly to reduce the amount of copies)
|
||||
//We can move this stuff to another file too if it's too big...
|
||||
@ -236,109 +356,6 @@ func (r *ChannelReservation) DeserializeCSVRefundRevocation() error {
|
||||
return nil
|
||||
}*/
|
||||
|
||||
// OurFunds...
|
||||
func (r *ChannelReservation) OurFunds() ([]*wire.TxIn, []*wire.TxOut) {
|
||||
r.RLock()
|
||||
defer r.RUnlock()
|
||||
return r.ourInputs, r.ourChange
|
||||
}
|
||||
|
||||
func (r *ChannelReservation) OurKeys() (*btcec.PrivateKey, *btcec.PrivateKey) {
|
||||
r.RLock()
|
||||
defer r.RUnlock()
|
||||
return r.partialState.multiSigKey, r.partialState.ourCommitKey
|
||||
}
|
||||
|
||||
// AddContribution...
|
||||
func (r *ChannelReservation) AddContribution(theirInputs []*wire.TxIn,
|
||||
theirChangeOutputs []*wire.TxOut, commitKey, multiSigKey *btcec.PublicKey,
|
||||
deliveryAddress btcutil.Address, initialRevocation [wire.HashSize]byte,
|
||||
acceptedDelayPeriod int64) error {
|
||||
|
||||
errChan := make(chan error, 1)
|
||||
|
||||
r.wallet.msgChan <- &addContributionMsg{
|
||||
pendingFundingID: r.reservationID,
|
||||
theirInputs: theirInputs,
|
||||
theirChangeOutputs: theirChangeOutputs,
|
||||
theirMultiSigKey: multiSigKey,
|
||||
theirCommitKey: commitKey,
|
||||
deliveryAddress: deliveryAddress,
|
||||
revocationHash: initialRevocation,
|
||||
csvDelay: acceptedDelayPeriod,
|
||||
err: errChan,
|
||||
}
|
||||
|
||||
return <-errChan
|
||||
}
|
||||
|
||||
// OurFundingSigs...
|
||||
func (r *ChannelReservation) OurFundingSigs() [][]byte {
|
||||
r.RLock()
|
||||
defer r.RUnlock()
|
||||
return r.ourFundingSigs
|
||||
}
|
||||
|
||||
// OurCommitmentSig
|
||||
func (r *ChannelReservation) OurCommitmentSig() []byte {
|
||||
r.RLock()
|
||||
defer r.RUnlock()
|
||||
return r.ourCommitmentSig
|
||||
}
|
||||
|
||||
// TheirFunds...
|
||||
// TODO(roasbeef): return error if accessors not yet populated?
|
||||
func (r *ChannelReservation) TheirFunds() ([]*wire.TxIn, []*wire.TxOut) {
|
||||
r.RLock()
|
||||
defer r.RUnlock()
|
||||
return r.theirInputs, r.theirChange
|
||||
}
|
||||
|
||||
func (r *ChannelReservation) TheirKeys() (*btcec.PublicKey, *btcec.PublicKey) {
|
||||
r.RLock()
|
||||
defer r.RUnlock()
|
||||
return r.theirMultiSigKey, r.partialState.theirCommitKey
|
||||
}
|
||||
|
||||
// CompleteFundingReservation...
|
||||
// TODO(roasbeef): add commit sig also
|
||||
func (r *ChannelReservation) CompleteReservation(fundingSigs [][]byte, commitmentSig []byte) error {
|
||||
errChan := make(chan error, 1)
|
||||
|
||||
r.wallet.msgChan <- &addCounterPartySigsMsg{
|
||||
pendingFundingID: r.reservationID,
|
||||
theirFundingSigs: fundingSigs,
|
||||
theirCommitmentSig: commitmentSig,
|
||||
err: errChan,
|
||||
}
|
||||
|
||||
return <-errChan
|
||||
}
|
||||
|
||||
// FinalFundingTransaction...
|
||||
func (r *ChannelReservation) FundingTx() *wire.MsgTx {
|
||||
r.RLock()
|
||||
defer r.RUnlock()
|
||||
return r.partialState.fundingTx
|
||||
}
|
||||
|
||||
// RequestFundingReserveCancellation...
|
||||
// TODO(roasbeef): also return mutated state?
|
||||
func (r *ChannelReservation) Cancel() error {
|
||||
errChan := make(chan error, 1)
|
||||
r.wallet.msgChan <- &fundingReserveCancelMsg{
|
||||
pendingFundingID: r.reservationID,
|
||||
err: errChan,
|
||||
}
|
||||
|
||||
return <-errChan
|
||||
}
|
||||
|
||||
// WaitForChannelOpen...
|
||||
func (r *ChannelReservation) WaitForChannelOpen() *LightningChannel {
|
||||
return nil
|
||||
}
|
||||
|
||||
// * finish reset of tests
|
||||
// * comment out stuff that'll need a node.
|
||||
// * start on commitment side
|
||||
|
Loading…
Reference in New Issue
Block a user