2015-12-20 07:00:50 +01:00
|
|
|
package lnwallet
|
2015-11-13 03:43:32 +01:00
|
|
|
|
|
|
|
import (
|
2015-11-14 20:52:07 +01:00
|
|
|
"sync"
|
|
|
|
|
2015-12-26 19:35:15 +01:00
|
|
|
"li.lan/labs/plasma/channeldb"
|
|
|
|
|
2015-11-13 03:43:32 +01:00
|
|
|
"github.com/btcsuite/btcd/btcec"
|
|
|
|
"github.com/btcsuite/btcd/wire"
|
|
|
|
"github.com/btcsuite/btcutil"
|
|
|
|
)
|
|
|
|
|
2015-12-23 05:30:11 +01:00
|
|
|
// ChannelContribution...
|
|
|
|
type ChannelContribution struct {
|
|
|
|
// Amount of funds contributed to the funding transaction.
|
|
|
|
FundingAmount btcutil.Amount
|
2015-12-18 20:29:35 +01:00
|
|
|
|
2015-12-23 05:30:11 +01:00
|
|
|
// 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
|
2015-11-14 20:52:07 +01:00
|
|
|
|
2015-12-23 05:30:11 +01:00
|
|
|
// The key to be used for this party's version of the commitment
|
|
|
|
// transaction.
|
|
|
|
CommitKey *btcec.PublicKey
|
2015-12-18 20:29:35 +01:00
|
|
|
|
2015-12-23 05:30:11 +01:00
|
|
|
// 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.
|
2015-12-31 07:30:52 +01:00
|
|
|
RevocationHash [20]byte
|
2015-12-23 05:30:11 +01:00
|
|
|
|
|
|
|
// The delay (in blocks) to be used for the pay-to-self output in this
|
|
|
|
// party's version of the commitment transaction.
|
2015-12-26 07:07:30 +01:00
|
|
|
CsvDelay uint32
|
2015-12-23 05:30:11 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// ChannelReservation...
|
|
|
|
type ChannelReservation struct {
|
|
|
|
fundingType FundingType
|
2015-11-13 03:43:32 +01:00
|
|
|
|
2015-12-23 05:30:11 +01:00
|
|
|
// This mutex MUST be held when either reading or modifying any of the
|
|
|
|
// fields below.
|
|
|
|
sync.RWMutex
|
2015-11-13 03:43:32 +01:00
|
|
|
|
2015-12-23 05:30:11 +01:00
|
|
|
// For CLTV it is nLockTime, for CSV it's nSequence, for segwit it's
|
|
|
|
// not needed
|
2015-12-26 07:07:30 +01:00
|
|
|
fundingLockTime uint32
|
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-12-19 04:39:51 +01:00
|
|
|
ourFundingSigs [][]byte
|
|
|
|
theirFundingSigs [][]byte
|
2015-11-13 03:43:32 +01:00
|
|
|
|
2015-12-23 05:30:11 +01:00
|
|
|
// Our signature for their version of the commitment transaction.
|
2015-12-29 06:38:50 +01:00
|
|
|
ourCommitmentSig []byte
|
|
|
|
theirCommitmentSig []byte
|
2015-11-13 03:43:32 +01:00
|
|
|
|
2015-12-23 05:30:11 +01:00
|
|
|
ourContribution *ChannelContribution
|
|
|
|
theirContribution *ChannelContribution
|
|
|
|
|
2015-12-26 19:35:15 +01:00
|
|
|
partialState *channeldb.OpenChannel
|
2015-11-13 03:43:32 +01:00
|
|
|
|
2015-12-23 05:30:11 +01:00
|
|
|
// The ID of this reservation, used to uniquely track the reservation
|
|
|
|
// throughout its lifetime.
|
2015-11-13 03:43:32 +01:00
|
|
|
reservationID uint64
|
2015-12-15 22:22:18 +01:00
|
|
|
|
2015-12-23 05:30:11 +01:00
|
|
|
// 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.
|
2015-12-15 22:22:18 +01:00
|
|
|
chanOpen chan *LightningChannel
|
2015-12-23 05:30:11 +01:00
|
|
|
|
|
|
|
wallet *LightningWallet
|
2015-11-13 03:43:32 +01:00
|
|
|
}
|
|
|
|
|
2015-12-19 04:42:49 +01:00
|
|
|
// newChannelReservation...
|
|
|
|
func newChannelReservation(t FundingType, fundingAmt btcutil.Amount,
|
|
|
|
minFeeRate btcutil.Amount, wallet *LightningWallet, id uint64) *ChannelReservation {
|
2015-12-23 05:30:11 +01:00
|
|
|
// TODO(roasbeef): CSV here, or on delay?
|
2015-12-19 04:42:49 +01:00
|
|
|
return &ChannelReservation{
|
2015-12-23 05:30:11 +01:00
|
|
|
fundingType: t,
|
|
|
|
ourContribution: &ChannelContribution{
|
|
|
|
FundingAmount: fundingAmt,
|
|
|
|
},
|
|
|
|
theirContribution: &ChannelContribution{
|
|
|
|
FundingAmount: fundingAmt,
|
|
|
|
},
|
2015-12-26 19:35:15 +01:00
|
|
|
partialState: &channeldb.OpenChannel{
|
2015-12-23 05:30:11 +01:00
|
|
|
// TODO(roasbeef): assumes balanced symmetric channels.
|
2015-12-26 07:07:30 +01:00
|
|
|
Capacity: fundingAmt * 2,
|
|
|
|
OurBalance: fundingAmt,
|
|
|
|
TheirBalance: fundingAmt,
|
|
|
|
MinFeePerKb: minFeeRate,
|
2015-12-19 04:42:49 +01:00
|
|
|
},
|
|
|
|
reservationID: id,
|
2015-12-23 05:30:11 +01:00
|
|
|
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...
|
2015-12-29 06:58:06 +01:00
|
|
|
func (r *ChannelReservation) CompleteReservation(fundingSigs [][]byte,
|
|
|
|
commitmentSig []byte) error {
|
|
|
|
|
2015-12-23 05:30:11 +01:00
|
|
|
errChan := make(chan error, 1)
|
|
|
|
|
|
|
|
r.wallet.msgChan <- &addCounterPartySigsMsg{
|
|
|
|
pendingFundingID: r.reservationID,
|
|
|
|
theirFundingSigs: fundingSigs,
|
|
|
|
theirCommitmentSig: commitmentSig,
|
|
|
|
err: errChan,
|
2015-12-19 04:42:49 +01:00
|
|
|
}
|
2015-12-23 05:30:11 +01:00
|
|
|
|
|
|
|
return <-errChan
|
|
|
|
}
|
|
|
|
|
|
|
|
// OurSignatures...
|
|
|
|
func (r *ChannelReservation) TheirSignatures() ([][]byte, []byte) {
|
|
|
|
r.RLock()
|
|
|
|
defer r.RUnlock()
|
2015-12-29 06:38:50 +01:00
|
|
|
return r.theirFundingSigs, r.theirCommitmentSig
|
2015-12-23 05:30:11 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// FinalFundingTransaction...
|
|
|
|
func (r *ChannelReservation) FinalFundingTx() *wire.MsgTx {
|
|
|
|
r.RLock()
|
|
|
|
defer r.RUnlock()
|
2015-12-24 19:41:15 +01:00
|
|
|
return r.partialState.FundingTx
|
2015-12-23 05:30:11 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// RequestFundingReserveCancellation...
|
|
|
|
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
|
2015-12-19 04:42:49 +01:00
|
|
|
}
|
|
|
|
|
2015-12-15 22:22:33 +01:00
|
|
|
// * finish reset of tests
|
|
|
|
// * comment out stuff that'll need a node.
|
|
|
|
// * start on commitment side
|
|
|
|
// * implement rusty's shachain
|
|
|
|
// * set up logic to get notification from node when funding tx gets 6 deep.
|
|
|
|
// * prob spawn into ChainNotifier struct
|
|
|
|
// * create builder for initial funding transaction
|
|
|
|
// * fascade through the wallet, for signing and such.
|
|
|
|
// * channel should have active namespace to it's bucket, query at that point fo past commits etc
|