lnwallet: once the reservation workflow is complete, wait then open the payment channel
* Hooks into the ChainNotifier infrastructure to receive a notification once the funding transaction gets enough notifications. * Still need to set up the notification grouting within a LightningChannel to watch for uncooperative closures, and broadcasts and revoked channel states.
This commit is contained in:
parent
6e0cfaf7ec
commit
07b0d5ca3e
@ -29,7 +29,7 @@ type PaymentHash [20]byte
|
|||||||
// TODO(roasbeef): future peer struct should embed this struct
|
// TODO(roasbeef): future peer struct should embed this struct
|
||||||
type LightningChannel struct {
|
type LightningChannel struct {
|
||||||
lnwallet *LightningWallet
|
lnwallet *LightningWallet
|
||||||
channelEvents *chainntnfs.ChainNotifier
|
channelEvents chainntnfs.ChainNotifier
|
||||||
|
|
||||||
// TODO(roasbeef): Stores all previous R values + timeouts for each
|
// TODO(roasbeef): Stores all previous R values + timeouts for each
|
||||||
// commitment update, plus some other meta-data...Or just use OP_RETURN
|
// commitment update, plus some other meta-data...Or just use OP_RETURN
|
||||||
@ -39,7 +39,7 @@ type LightningChannel struct {
|
|||||||
|
|
||||||
// stateMtx protects concurrent access to the state struct.
|
// stateMtx protects concurrent access to the state struct.
|
||||||
stateMtx sync.RWMutex
|
stateMtx sync.RWMutex
|
||||||
channelState channeldb.OpenChannel
|
channelState *channeldb.OpenChannel
|
||||||
|
|
||||||
updateTotem chan struct{}
|
updateTotem chan struct{}
|
||||||
|
|
||||||
@ -61,8 +61,8 @@ type LightningChannel struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// newLightningChannel...
|
// newLightningChannel...
|
||||||
func newLightningChannel(wallet *LightningWallet, events *chainntnfs.ChainNotifier,
|
func newLightningChannel(wallet *LightningWallet, events chainntnfs.ChainNotifier,
|
||||||
chanDB *channeldb.DB, state channeldb.OpenChannel) (*LightningChannel, error) {
|
chanDB *channeldb.DB, state *channeldb.OpenChannel) (*LightningChannel, error) {
|
||||||
|
|
||||||
lc := &LightningChannel{
|
lc := &LightningChannel{
|
||||||
lnwallet: wallet,
|
lnwallet: wallet,
|
||||||
@ -74,6 +74,9 @@ func newLightningChannel(wallet *LightningWallet, events *chainntnfs.ChainNotifi
|
|||||||
unfufilledPayments: make(map[PaymentHash]*PaymentRequest),
|
unfufilledPayments: make(map[PaymentHash]*PaymentRequest),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO(roasbeef): do a NotifySpent for the funding input, and
|
||||||
|
// NotifyReceived for all commitment outputs.
|
||||||
|
|
||||||
// Populate the totem.
|
// Populate the totem.
|
||||||
lc.updateTotem <- struct{}{}
|
lc.updateTotem <- struct{}{}
|
||||||
|
|
||||||
@ -318,7 +321,7 @@ func (lc *LightningChannel) AddHTLC(timeout uint32, value btcutil.Amount,
|
|||||||
|
|
||||||
// Re-create copies of the current commitment transactions to be updated.
|
// Re-create copies of the current commitment transactions to be updated.
|
||||||
ourNewCommitTx, theirNewCommitTx, err := createNewCommitmentTxns(
|
ourNewCommitTx, theirNewCommitTx, err := createNewCommitmentTxns(
|
||||||
lc.fundingTxIn, &lc.channelState, chanUpdate, amountToUs, amountToThem,
|
lc.fundingTxIn, lc.channelState, chanUpdate, amountToUs, amountToThem,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -463,7 +466,7 @@ func (lc *LightningChannel) SettleHTLC(rValue [20]byte, newRevocation [20]byte)
|
|||||||
// Create new commitment transactions that reflect the settlement of
|
// Create new commitment transactions that reflect the settlement of
|
||||||
// this pending HTLC.
|
// this pending HTLC.
|
||||||
ourNewCommitTx, theirNewCommitTx, err := createNewCommitmentTxns(
|
ourNewCommitTx, theirNewCommitTx, err := createNewCommitmentTxns(
|
||||||
lc.fundingTxIn, &lc.channelState, chanUpdate, amountToUs, amountToThem,
|
lc.fundingTxIn, lc.channelState, chanUpdate, amountToUs, amountToThem,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -266,7 +266,7 @@ func (r *ChannelReservation) Cancel() error {
|
|||||||
// NOTE: If this method is called before .CompleteReservation(), it will block
|
// NOTE: If this method is called before .CompleteReservation(), it will block
|
||||||
// indefinitely.
|
// indefinitely.
|
||||||
func (r *ChannelReservation) WaitForChannelOpen() *LightningChannel {
|
func (r *ChannelReservation) WaitForChannelOpen() *LightningChannel {
|
||||||
return nil
|
return <-r.chanOpen
|
||||||
}
|
}
|
||||||
|
|
||||||
// * finish reset of tests
|
// * finish reset of tests
|
||||||
|
@ -323,6 +323,7 @@ func NewLightningWallet(config *Config) (*LightningWallet, walletdb.DB, error) {
|
|||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO(roasbeef): logging
|
||||||
return &LightningWallet{
|
return &LightningWallet{
|
||||||
db: db,
|
db: db,
|
||||||
chainNotifier: chainNotifier,
|
chainNotifier: chainNotifier,
|
||||||
@ -967,19 +968,36 @@ func (l *LightningWallet) handleFundingCounterPartySigs(msg *addCounterPartySigs
|
|||||||
// which will be used for the lifetime of this channel.
|
// which will be used for the lifetime of this channel.
|
||||||
err = l.ChannelDB.PutOpenChannel(pendingReservation.partialState)
|
err = l.ChannelDB.PutOpenChannel(pendingReservation.partialState)
|
||||||
|
|
||||||
// TODO(roasbeef): broadcast now?
|
// Create a goroutine to watch the chain so we can open the channel once
|
||||||
// * create goroutine, listens on blockconnected+blockdisconnected channels
|
// the funding tx has enough confirmations.
|
||||||
// * after six blocks, then will create an LightningChannel struct and
|
// TODO(roasbeef): add number of confs to the confi
|
||||||
// send over reservation.
|
go l.openChannelAfterConfirmations(pendingReservation, 3)
|
||||||
// * will need a multi-plexer to fan out, to listen on ListenConnectedBlocks
|
|
||||||
// * should prob be a separate struct/modele
|
|
||||||
// * use NotifySpent in order to catch non-cooperative spends of revoked
|
|
||||||
// * NotifySpent(outpoints []*wire.OutPoint)
|
|
||||||
// commitment txns. Hmm using p2sh or bare multi-sig?
|
|
||||||
// * record partialState.CreationTime once tx is 'open'
|
|
||||||
msg.err <- err
|
msg.err <- err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// openChannelAfterConfirmations creates, and opens a payment channel after
|
||||||
|
// the funding transaction created within the passed channel reservation
|
||||||
|
// obtains the specified number of confirmations.
|
||||||
|
func (l *LightningWallet) openChannelAfterConfirmations(res *ChannelReservation, numConfs uint32) {
|
||||||
|
// Register with the ChainNotifier for a notification once the funding
|
||||||
|
// transaction reaches `numConfs` confirmations.
|
||||||
|
trigger := &chainntnfs.NotificationTrigger{
|
||||||
|
TriggerChan: make(chan struct{}, 1),
|
||||||
|
}
|
||||||
|
txid := res.partialState.FundingTx.TxSha()
|
||||||
|
l.chainNotifier.RegisterConfirmationsNotification(&txid, numConfs, trigger)
|
||||||
|
|
||||||
|
// Wait until the specified number of confirmations has been reached.
|
||||||
|
<-trigger.TriggerChan
|
||||||
|
|
||||||
|
// Finally, create and officially open the payment channel!
|
||||||
|
// TODO(roasbeef): CreationTime once tx is 'open'
|
||||||
|
channel, _ := newLightningChannel(l, l.chainNotifier, l.ChannelDB,
|
||||||
|
res.partialState)
|
||||||
|
res.chanOpen <- channel
|
||||||
|
}
|
||||||
|
|
||||||
// getNextRawKey retrieves the next key within our HD key-chain for use within
|
// getNextRawKey retrieves the next key within our HD key-chain for use within
|
||||||
// as a multi-sig key within the funding transaction, or within the commitment
|
// as a multi-sig key within the funding transaction, or within the commitment
|
||||||
// transaction's outputs.
|
// transaction's outputs.
|
||||||
|
Loading…
Reference in New Issue
Block a user