utxonursery: add additional comments to new sections

This commit is contained in:
Olaoluwa Osuntokun 2017-01-07 19:59:30 -08:00
parent c9dbaa1403
commit ccb12ab0a8
No known key found for this signature in database
GPG Key ID: 9CC5B105D03521A2
1 changed files with 40 additions and 10 deletions

View File

@ -61,7 +61,8 @@ const (
// witness for a particular public key script. This function acts as an
// abstraction layer, hiding the details of the underlying script from the
// utxoNursery.
type witnessGenerator func(tx *wire.MsgTx, hc *txscript.TxSigHashes, inputIndex int) ([][]byte, error)
type witnessGenerator func(tx *wire.MsgTx, hc *txscript.TxSigHashes,
inputIndex int) ([][]byte, error)
// generateFunc will return the witnessGenerator function that a kidOutput uses
// to generate the witness for a sweep transaction. Currently there is only one
@ -71,7 +72,9 @@ func (wt witnessType) generateFunc(signer *lnwallet.Signer,
switch wt {
case commitmentTimeLock:
return func(tx *wire.MsgTx, hc *txscript.TxSigHashes, inputIndex int) ([][]byte, error) {
return func(tx *wire.MsgTx, hc *txscript.TxSigHashes,
inputIndex int) ([][]byte, error) {
desc := descriptor
desc.SigHashes = hc
desc.InputIndex = inputIndex
@ -344,8 +347,14 @@ out:
return
}
if err := u.graduateKindergarten(uint32(epoch.Height)); err != nil {
utxnLog.Errorf("error while graduating kindergarten outputs: %v", err)
// A new block has just been connected to the main
// chain which means we might be able to graduate some
// outputs out of the kindergarten bucket. Graduation
// entails successfully sweeping a time-locked output.
height := uint32(epoch.Height)
if err := u.graduateKindergarten(height); err != nil {
utxnLog.Errorf("error while graduating "+
"kindergarten outputs: %v", err)
}
case <-u.quit:
@ -430,11 +439,14 @@ func (k *kidOutput) waitForPromotion(db *channeldb.DB, confChan *chainntnfs.Conf
return err
}
maturityHeight := k.confHeight +
k.blocksToMaturity
maturityHeight := k.confHeight + k.blocksToMaturity
heightBytes := make([]byte, 4)
byteOrder.PutUint32(heightBytes, uint32(maturityHeight))
// If there're any existing outputs for this particular block
// height target, then we'll append this new output to the
// serialized list of outputs.
var existingOutputs []byte
if results := kgtnBucket.Get(heightBytes); results != nil {
existingOutputs = results
@ -444,7 +456,6 @@ func (k *kidOutput) waitForPromotion(db *channeldb.DB, confChan *chainntnfs.Conf
if err := serializeKidOutput(b, k); err != nil {
return err
}
if err := kgtnBucket.Put(heightBytes, b.Bytes()); err != nil {
return err
}
@ -467,22 +478,31 @@ func (k *kidOutput) waitForPromotion(db *channeldb.DB, confChan *chainntnfs.Conf
// startup in order to process graduations from blocks missed while the UTXO
// nursery was offline.
func (u *utxoNursery) graduateKindergarten(blockHeight uint32) error {
// First fetch the set of outputs that we can "graduate" at this
// particular block height. We can graduate an output once we've
// reached its height maturity.
kgtnOutputs, err := fetchGraduatingOutputs(u.db, u.wallet, blockHeight)
if err != nil {
return err
}
// If we're able to graduate any outputs, then create a single
// transaction which sweeps them all into the wallet.
if len(kgtnOutputs) > 0 {
if err := sweepGraduatingOutputs(u.wallet, kgtnOutputs); err != nil {
return err
}
}
// Using a re-org safety margin of 6-blocks, delete any outputs which
// have graduated 6 blocks ago.
deleteHeight := blockHeight - 6
if err := deleteGraduatedOutputs(u.db, deleteHeight); err != nil {
return err
}
// Finally, record the last height at which we graduated outputs so we
// can reconcile our state with that of the main-chain during restarts.
return putLastHeightGraduated(u.db, blockHeight)
}
@ -495,7 +515,6 @@ func fetchGraduatingOutputs(db *channeldb.DB, wallet *lnwallet.LightningWallet,
blockHeight uint32) ([]*kidOutput, error) {
var results []byte
if err := db.View(func(tx *bolt.Tx) error {
// A new block has just been connected, check to see if we have
// any new outputs that can be swept into the wallet.
@ -508,21 +527,28 @@ func fetchGraduatingOutputs(db *channeldb.DB, wallet *lnwallet.LightningWallet,
byteOrder.PutUint32(heightBytes, blockHeight)
results = kgtnBucket.Get(heightBytes)
return nil
}); err != nil {
return nil, err
}
// If no time-locked outputs can be sweeped at this point, ten we can
// exit early.
if len(results) == 0 {
return nil, nil
}
// Otherwise, we deserialize the list of kid outputs into their full
// forms.
kgtnOutputs, err := deserializeKidList(bytes.NewReader(results))
if err != nil {
utxnLog.Errorf("error while deserializing list of kidOutputs: %v", err)
}
// For each of the outputs, we also generate its proper witness
// function based on its witness type. This varies if the output is on
// our commitment transaction or theirs, and also if it's an HTLC
// output or not.
for _, kgtnOutput := range kgtnOutputs {
kgtnOutput.witnessFunc = kgtnOutput.witnessType.generateFunc(
&wallet.Signer, kgtnOutput.signDescriptor,
@ -562,6 +588,7 @@ func sweepGraduatingOutputs(wallet *lnwallet.LightningWallet, kgtnOutputs []*kid
if err := wallet.PublishTransaction(sweepTx); err != nil {
utxnLog.Errorf("unable to broadcast sweep tx: %v, %v",
err, spew.Sdump(sweepTx))
return err
}
return nil
@ -570,7 +597,9 @@ func sweepGraduatingOutputs(wallet *lnwallet.LightningWallet, kgtnOutputs []*kid
// createSweepTx creates a final sweeping transaction with all witnesses in
// place for all inputs. The created transaction has a single output sending
// all the funds back to the source wallet.
func createSweepTx(wallet *lnwallet.LightningWallet, matureOutputs []*kidOutput) (*wire.MsgTx, error) {
func createSweepTx(wallet *lnwallet.LightningWallet,
matureOutputs []*kidOutput) (*wire.MsgTx, error) {
pkScript, err := newSweepPkScript(wallet)
if err != nil {
return nil, err
@ -608,6 +637,7 @@ func createSweepTx(wallet *lnwallet.LightningWallet, matureOutputs []*kidOutput)
txIn.Witness = witness
}
return sweepTx, nil
}