lnwallet: re-introduce rpc calls during channel reservation workflow

* In preparation for regression testing once nodetest is finished.
* These sections we’re previously uncommented to allow for testing the
wallet without a full-node hooked up.
This commit is contained in:
Olaoluwa Osuntokun 2016-01-06 16:15:49 -08:00
parent 5f705be63b
commit 6e0cfaf7ec

@ -2,6 +2,7 @@ package lnwallet
import ( import (
"bytes" "bytes"
"encoding/hex"
"errors" "errors"
"fmt" "fmt"
"log" "log"
@ -11,6 +12,8 @@ import (
"sync" "sync"
"sync/atomic" "sync/atomic"
"li.lan/labs/plasma/chainntfs"
"li.lan/labs/plasma/chainntfs/btcdnotify"
"li.lan/labs/plasma/channeldb" "li.lan/labs/plasma/channeldb"
"li.lan/labs/plasma/shachain" "li.lan/labs/plasma/shachain"
@ -203,6 +206,11 @@ type LightningWallet struct {
ChannelDB *channeldb.DB ChannelDB *channeldb.DB
db walletdb.DB db walletdb.DB
// Used by in order to obtain notifications about funding transaction
// reaching a specified confirmation depth, and to catch
// counterparty's broadcasting revoked commitment states.
chainNotifier chainntnfs.ChainNotifier
// The core wallet, all non Lightning Network specific interaction is // The core wallet, all non Lightning Network specific interaction is
// proxied to the internal wallet. // proxied to the internal wallet.
// TODO(roasbeef): Why isn't this just embedded again? // TODO(roasbeef): Why isn't this just embedded again?
@ -273,7 +281,6 @@ func NewLightningWallet(config *Config) (*LightningWallet, walletdb.DB, error) {
} }
createID = true createID = true
} }
// Wallet has been created and been initialized at this point, open it // Wallet has been created and been initialized at this point, open it
@ -290,7 +297,6 @@ func NewLightningWallet(config *Config) (*LightningWallet, walletdb.DB, error) {
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
cdb := channeldb.New(wallet.Manager, lnNamespace) cdb := channeldb.New(wallet.Manager, lnNamespace)
if err := wallet.Manager.Unlock(config.PrivatePass); err != nil { if err := wallet.Manager.Unlock(config.PrivatePass); err != nil {
@ -312,13 +318,17 @@ func NewLightningWallet(config *Config) (*LightningWallet, walletdb.DB, error) {
log.Printf("stored identity key pubkey hash in channeldb\n") log.Printf("stored identity key pubkey hash in channeldb\n")
} }
// TODO(roasbeef): logging chainNotifier, err := btcdnotify.NewBtcdNotifier(wallet)
if err != nil {
return nil, nil, err
}
return &LightningWallet{ return &LightningWallet{
db: db, db: db,
Wallet: wallet, chainNotifier: chainNotifier,
ChannelDB: cdb, Wallet: wallet,
msgChan: make(chan interface{}, msgBufferSize), ChannelDB: cdb,
msgChan: make(chan interface{}, msgBufferSize),
// TODO(roasbeef): make this atomic.Uint32 instead? Which is // TODO(roasbeef): make this atomic.Uint32 instead? Which is
// faster, locks or CAS? I'm guessing CAS because assembly: // faster, locks or CAS? I'm guessing CAS because assembly:
// * https://golang.org/src/sync/atomic/asm_amd64.s // * https://golang.org/src/sync/atomic/asm_amd64.s
@ -525,32 +535,27 @@ func (l *LightningWallet) handleFundingReserveRequest(req *initFundingReserveMsg
ourContribution.ChangeOutputs = make([]*wire.TxOut, 1) ourContribution.ChangeOutputs = make([]*wire.TxOut, 1)
// Change is necessary. Query for an available change address to // Change is necessary. Query for an available change address to
// send the remainder to. // send the remainder to.
changeAmount := selectedTotalValue - req.fundingAmount changeAddr, err := l.NewChangeAddress(waddrmgr.DefaultAccountNum)
addrs, err := l.Manager.NextInternalAddresses(waddrmgr.DefaultAccountNum, 1)
if err != nil { if err != nil {
req.err <- err req.err <- err
req.resp <- nil req.resp <- nil
return return
} }
changeAddrScript, err := txscript.PayToAddrScript(addrs[0].Address())
if err != nil {
req.err <- err
req.resp <- nil
return
}
// TODO(roasbeef): re-enable after tests are connected to real node.
// * or the change to btcwallet is made to reverse the dependancy
// between chain-client and wallet.
//changeAddr, err := l.wallet.NewChangeAddress(waddrmgr.DefaultAccountNum)
changeAddrScript, err := txscript.PayToAddrScript(changeAddr)
if err != nil {
req.err <- err
req.resp <- nil
return
}
changeAmount := selectedTotalValue - req.fundingAmount
ourContribution.ChangeOutputs[0] = wire.NewTxOut(int64(changeAmount), ourContribution.ChangeOutputs[0] = wire.NewTxOut(int64(changeAmount),
changeAddrScript) changeAddrScript)
} }
// TODO(roasbeef): re-calculate fees here to minFeePerKB, may need more inputs // TODO(roasbeef): re-calculate fees here to minFeePerKB, may need more inputs
// TODO(roasbeef): use wallet.CurrentAddress() here instead? Solves the
// problem of 'wasted' unused addrtesses.
// Grab two fresh keys from out HD chain, one will be used for the // Grab two fresh keys from out HD chain, one will be used for the
// multi-sig funding transaction, and the other for the commitment // multi-sig funding transaction, and the other for the commitment
// transaction. // transaction.
@ -573,17 +578,14 @@ func (l *LightningWallet) handleFundingReserveRequest(req *initFundingReserveMsg
// Generate a fresh address to be used in the case of a cooperative // Generate a fresh address to be used in the case of a cooperative
// channel close. // channel close.
// TODO(roasbeef): same here deliveryAddress, err := l.NewAddress(waddrmgr.DefaultAccountNum)
//deliveryAddress, err := l.wallet.NewChangeAddress(waddrmgr.DefaultAccountNum)
addrs, err := l.Manager.NextInternalAddresses(waddrmgr.DefaultAccountNum, 1)
if err != nil { if err != nil {
// TODO(roasbeef): make into func sendErorr()
req.err <- err req.err <- err
req.resp <- nil req.resp <- nil
return return
} }
reservation.partialState.OurDeliveryAddress = addrs[0].Address() reservation.partialState.OurDeliveryAddress = deliveryAddress
ourContribution.DeliveryAddress = addrs[0].Address() ourContribution.DeliveryAddress = deliveryAddress
// Create a new shaChain for verifiable transaction revocations. This // Create a new shaChain for verifiable transaction revocations. This
// will be used to generate revocation hashes for our past/current // will be used to generate revocation hashes for our past/current
@ -705,8 +707,20 @@ func (l *LightningWallet) handleContributionMsg(req *addContributionMsg) {
return return
} }
// TODO(roasbeef): do Manager.ImportScript(..) here, gives us a // Register intent for notifications related to the funding output.
// ManagedScriptAddress to play around with if we need it. // This'll allow us to properly track the number of confirmations the
// funding tx has once it has been broadcasted.
lastBlock := l.Manager.SyncedTo()
scriptAddr, err := l.Manager.ImportScript(redeemScript, &lastBlock)
if err != nil {
req.err <- err
return
}
if err := l.rpc.NotifyReceived([]btcutil.Address{scriptAddr.Address()}); err != nil {
req.err <- err
return
}
pendingReservation.partialState.FundingRedeemScript = redeemScript pendingReservation.partialState.FundingRedeemScript = redeemScript
fundingTx.AddTxOut(multiSigOut) fundingTx.AddTxOut(multiSigOut)
@ -850,17 +864,14 @@ func (l *LightningWallet) handleFundingCounterPartySigs(msg *addCounterPartySigs
fundingTx := pendingReservation.partialState.FundingTx fundingTx := pendingReservation.partialState.FundingTx
for i, txin := range fundingTx.TxIn { for i, txin := range fundingTx.TxIn {
if txin.SignatureScript == nil { if txin.SignatureScript == nil {
txin.SignatureScript = pendingReservation.theirFundingSigs[i] // Fetch the alleged previous output along with the
// TODO(roasbeef): uncomment after nodetest is finished.
/*// Fetch the alleged previous output along with the
// pkscript referenced by this input. // pkscript referenced by this input.
prevOut := txin.PreviousOutPoint prevOut := txin.PreviousOutPoint
output, err := l.rpc.GetTxOut(&prevOut.Hash, prevOut.Index, false) output, err := l.rpc.GetTxOut(&prevOut.Hash, prevOut.Index, false)
if err != nil { if output == nil {
// TODO(roasbeef): do this at the start to avoid wasting out time? // TODO(roasbeef): do this at the start to avoid wasting out time?
// 8 or a set of nodes "we" run with exposed unauthenticated RPC? // 8 or a set of nodes "we" run with exposed unauthenticated RPC?
msg.err <- err msg.err <- fmt.Errorf("input to funding tx does not exist: %v", err)
return return
} }
pkscript, err := hex.DecodeString(output.ScriptPubKey.Hex) pkscript, err := hex.DecodeString(output.ScriptPubKey.Hex)
@ -880,7 +891,9 @@ func (l *LightningWallet) handleFundingCounterPartySigs(msg *addCounterPartySigs
if err = vm.Execute(); err != nil { if err = vm.Execute(); err != nil {
msg.err <- fmt.Errorf("cannot validate transaction: %s", err) msg.err <- fmt.Errorf("cannot validate transaction: %s", err)
return return
}*/ }
txin.SignatureScript = pendingReservation.theirFundingSigs[i]
} }
} }