2015-11-05 21:36:33 +01:00
|
|
|
package wallet
|
2015-11-13 03:43:32 +01:00
|
|
|
|
|
|
|
import (
|
2015-11-14 20:52:07 +01:00
|
|
|
"sync"
|
|
|
|
|
2015-11-13 03:43:32 +01:00
|
|
|
"github.com/btcsuite/btcd/btcec"
|
|
|
|
"github.com/btcsuite/btcd/wire"
|
|
|
|
"github.com/btcsuite/btcutil"
|
|
|
|
)
|
|
|
|
|
|
|
|
// ChannelReservation...
|
|
|
|
type ChannelReservation struct {
|
|
|
|
FundingType FundingType
|
|
|
|
|
|
|
|
FundingAmount btcutil.Amount
|
|
|
|
ReserveAmount btcutil.Amount
|
|
|
|
MinFeePerKb btcutil.Amount
|
|
|
|
|
2015-11-29 01:20:57 +01:00
|
|
|
sync.RWMutex // All fields below owned by the lnwallet.
|
2015-11-14 20:52:07 +01:00
|
|
|
|
|
|
|
theirInputs []*wire.TxIn
|
|
|
|
ourInputs []*wire.TxIn
|
2015-11-13 03:43:32 +01:00
|
|
|
|
2015-11-14 20:52:07 +01:00
|
|
|
theirChange []*wire.TxOut
|
|
|
|
ourChange []*wire.TxOut
|
2015-11-13 03:43:32 +01:00
|
|
|
|
2015-11-14 20:52:07 +01:00
|
|
|
ourKey *btcec.PrivateKey
|
|
|
|
theirKey *btcec.PublicKey
|
2015-11-13 03:43:32 +01:00
|
|
|
|
|
|
|
// In order of sorted inputs. Sorting is done in accordance
|
|
|
|
// to BIP-69: https://github.com/bitcoin/bips/blob/master/bip-0069.mediawiki.
|
2015-11-14 20:52:07 +01:00
|
|
|
theirSigs [][]byte
|
|
|
|
ourSigs [][]byte
|
2015-11-13 03:43:32 +01:00
|
|
|
|
2015-11-14 20:52:07 +01:00
|
|
|
normalizedTxID wire.ShaHash
|
2015-11-13 03:43:32 +01:00
|
|
|
|
2015-11-14 20:52:07 +01:00
|
|
|
fundingTx *wire.MsgTx
|
2015-11-13 03:43:32 +01:00
|
|
|
// TODO(roasbef): time locks, who pays fee etc.
|
|
|
|
// TODO(roasbeef): record Bob's ln-ID?
|
|
|
|
|
2015-11-14 20:52:07 +01:00
|
|
|
completedFundingTx *btcutil.Tx
|
2015-11-13 03:43:32 +01:00
|
|
|
|
|
|
|
reservationID uint64
|
|
|
|
wallet *LightningWallet
|
|
|
|
}
|
|
|
|
|
|
|
|
// newChannelReservation...
|
|
|
|
func newChannelReservation(t FundingType, fundingAmt btcutil.Amount,
|
|
|
|
minFeeRate btcutil.Amount, wallet *LightningWallet, id uint64) *ChannelReservation {
|
|
|
|
return &ChannelReservation{
|
|
|
|
FundingType: t,
|
|
|
|
FundingAmount: fundingAmt,
|
|
|
|
MinFeePerKb: minFeeRate,
|
|
|
|
wallet: wallet,
|
|
|
|
reservationID: id,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-11-14 20:52:07 +01:00
|
|
|
// OurFunds...
|
|
|
|
func (r *ChannelReservation) OurFunds() ([]*wire.TxIn, []*wire.TxOut, *btcec.PublicKey) {
|
|
|
|
r.RLock()
|
2015-11-29 01:20:57 +01:00
|
|
|
defer r.RUnlock()
|
2015-11-14 20:52:07 +01:00
|
|
|
return r.ourInputs, r.ourChange, r.ourKey.PubKey()
|
|
|
|
}
|
|
|
|
|
2015-11-13 03:43:32 +01:00
|
|
|
// AddCounterPartyFunds...
|
|
|
|
func (r *ChannelReservation) AddFunds(theirInputs []*wire.TxIn, theirChangeOutputs []*wire.TxOut, multiSigKey *btcec.PublicKey) error {
|
|
|
|
errChan := make(chan error, 1)
|
|
|
|
|
|
|
|
r.wallet.msgChan <- &addCounterPartyFundsMsg{
|
|
|
|
pendingFundingID: r.reservationID,
|
|
|
|
theirInputs: theirInputs,
|
|
|
|
theirChangeOutputs: theirChangeOutputs,
|
|
|
|
theirKey: multiSigKey,
|
2015-11-29 21:19:13 +01:00
|
|
|
err: errChan,
|
2015-11-13 03:43:32 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return <-errChan
|
|
|
|
}
|
|
|
|
|
2015-11-14 20:52:07 +01:00
|
|
|
// OurSigs...
|
|
|
|
func (r *ChannelReservation) OurSigs() [][]byte {
|
|
|
|
r.RLock()
|
2015-11-29 01:20:57 +01:00
|
|
|
defer r.RUnlock()
|
2015-11-14 20:52:07 +01:00
|
|
|
return r.ourSigs
|
|
|
|
}
|
|
|
|
|
|
|
|
// TheirFunds...
|
2015-11-29 01:20:57 +01:00
|
|
|
// TODO(roasbeef): return error if accessors not yet populated?
|
2015-11-14 20:52:07 +01:00
|
|
|
func (r *ChannelReservation) TheirFunds() ([]*wire.TxIn, []*wire.TxOut, *btcec.PublicKey) {
|
|
|
|
r.RLock()
|
2015-11-29 01:20:57 +01:00
|
|
|
defer r.RUnlock()
|
2015-11-14 20:52:07 +01:00
|
|
|
return r.theirInputs, r.theirChange, r.theirKey
|
|
|
|
}
|
|
|
|
|
2015-11-13 03:43:32 +01:00
|
|
|
// CompleteFundingReservation...
|
2015-11-27 07:52:14 +01:00
|
|
|
func (r *ChannelReservation) CompleteReservation(theirSigs [][]byte) error {
|
2015-11-13 03:43:32 +01:00
|
|
|
errChan := make(chan error, 1)
|
|
|
|
|
|
|
|
r.wallet.msgChan <- &addCounterPartySigsMsg{
|
2015-11-27 07:52:14 +01:00
|
|
|
pendingFundingID: r.reservationID,
|
2015-11-13 03:43:32 +01:00
|
|
|
theirSigs: theirSigs,
|
|
|
|
err: errChan,
|
|
|
|
}
|
|
|
|
|
|
|
|
return <-errChan
|
|
|
|
}
|
|
|
|
|
2015-11-14 20:52:07 +01:00
|
|
|
// FinalFundingTransaction...
|
|
|
|
func (r *ChannelReservation) FinalFundingTx() *btcutil.Tx {
|
|
|
|
r.RLock()
|
2015-11-29 01:20:57 +01:00
|
|
|
defer r.RUnlock()
|
2015-11-14 20:52:07 +01:00
|
|
|
return r.completedFundingTx
|
|
|
|
}
|
|
|
|
|
2015-11-13 03:43:32 +01:00
|
|
|
// RequestFundingReserveCancellation...
|
2015-11-14 20:52:07 +01:00
|
|
|
// TODO(roasbeef): also return mutated state?
|
2015-11-27 07:52:14 +01:00
|
|
|
func (r *ChannelReservation) Cancel() {
|
2015-11-13 03:43:32 +01:00
|
|
|
doneChan := make(chan struct{}, 1)
|
|
|
|
r.wallet.msgChan <- &fundingReserveCancelMsg{
|
2015-11-27 07:52:14 +01:00
|
|
|
pendingFundingID: r.reservationID,
|
2015-11-13 03:43:32 +01:00
|
|
|
done: doneChan,
|
|
|
|
}
|
|
|
|
|
|
|
|
<-doneChan
|
|
|
|
}
|
2015-12-03 01:49:41 +01:00
|
|
|
|
|
|
|
// WaitForChannelOpen...
|
|
|
|
func (r *ChannelReservation) WaitForChannelOpen() *LightningChannel {
|
|
|
|
return nil
|
|
|
|
}
|