chanbackup: set funding broadcast height on restore

This commit is contained in:
Oliver Gugger 2019-11-18 10:26:36 +01:00
parent d4f836ecb3
commit fb683f74a4
No known key found for this signature in database
GPG Key ID: 8E4256593F177720

@ -2,9 +2,11 @@ package lnd
import ( import (
"fmt" "fmt"
"math"
"net" "net"
"github.com/btcsuite/btcd/btcec" "github.com/btcsuite/btcd/btcec"
"github.com/btcsuite/btcd/chaincfg"
"github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/lightningnetwork/lnd/chanbackup" "github.com/lightningnetwork/lnd/chanbackup"
"github.com/lightningnetwork/lnd/channeldb" "github.com/lightningnetwork/lnd/channeldb"
@ -14,6 +16,18 @@ import (
"github.com/lightningnetwork/lnd/shachain" "github.com/lightningnetwork/lnd/shachain"
) )
const (
// mainnetSCBLaunchBlock is the approximate block height of the bitcoin
// mainnet chain of the date when SCBs first were released in lnd
// (v0.6.0-beta). The block date is 4/15/2019, 10:54 PM UTC.
mainnetSCBLaunchBlock = 571800
// testnetSCBLaunchBlock is the approximate block height of the bitcoin
// testnet3 chain of the date when SCBs first were released in lnd
// (v0.6.0-beta). The block date is 4/16/2019, 08:04 AM UTC.
testnetSCBLaunchBlock = 1489300
)
// chanDBRestorer is an implementation of the chanbackup.ChannelRestorer // chanDBRestorer is an implementation of the chanbackup.ChannelRestorer
// interface that is able to properly map a Single backup, into a // interface that is able to properly map a Single backup, into a
// channeldb.ChannelShell which is required to fully restore a channel. We also // channeldb.ChannelShell which is required to fully restore a channel. We also
@ -126,15 +140,72 @@ func (c *chanDBRestorer) openChannelShell(backup chanbackup.Single) (
// NOTE: Part of the chanbackup.ChannelRestorer interface. // NOTE: Part of the chanbackup.ChannelRestorer interface.
func (c *chanDBRestorer) RestoreChansFromSingles(backups ...chanbackup.Single) error { func (c *chanDBRestorer) RestoreChansFromSingles(backups ...chanbackup.Single) error {
channelShells := make([]*channeldb.ChannelShell, 0, len(backups)) channelShells := make([]*channeldb.ChannelShell, 0, len(backups))
firstChanHeight := uint32(math.MaxUint32)
for _, backup := range backups { for _, backup := range backups {
chanShell, err := c.openChannelShell(backup) chanShell, err := c.openChannelShell(backup)
if err != nil { if err != nil {
return err return err
} }
// Find the block height of the earliest channel in this backup.
chanHeight := chanShell.Chan.ShortChanID().BlockHeight
if chanHeight != 0 && chanHeight < firstChanHeight {
firstChanHeight = chanHeight
}
channelShells = append(channelShells, chanShell) channelShells = append(channelShells, chanShell)
} }
// In case there were only unconfirmed channels, we will have to scan
// the chain beginning from the launch date of SCBs.
if firstChanHeight == math.MaxUint32 {
chainHash := channelShells[0].Chan.ChainHash
switch {
case chainHash.IsEqual(chaincfg.MainNetParams.GenesisHash):
firstChanHeight = mainnetSCBLaunchBlock
case chainHash.IsEqual(chaincfg.TestNet3Params.GenesisHash):
firstChanHeight = testnetSCBLaunchBlock
default:
// Worst case: We have no height hint and start at
// block 1. Should only happen for SCBs in regtest,
// simnet and litecoin.
firstChanHeight = 1
}
}
// If there were channels in the backup that were not confirmed at the
// time of the backup creation, they won't have a block height in the
// ShortChanID which would lead to an error in the chain watcher.
// We want to at least set the funding broadcast height that the chain
// watcher can use instead. We have two possible fallback values for
// the broadcast height that we are going to try here.
for _, chanShell := range channelShells {
channel := chanShell.Chan
switch {
// Fallback case 1: It is extremely unlikely at this point that
// a channel we are trying to restore has a coinbase funding TX.
// Therefore we can be quite certain that if the TxIndex is
// zero, it was an unconfirmed channel where we used the
// BlockHeight to encode the funding TX broadcast height. To not
// end up with an invalid short channel ID that looks valid, we
// restore the "original" unconfirmed one here.
case channel.ShortChannelID.TxIndex == 0:
broadcastHeight := channel.ShortChannelID.BlockHeight
channel.FundingBroadcastHeight = broadcastHeight
channel.ShortChannelID.BlockHeight = 0
// Fallback case 2: This is an unconfirmed channel from an old
// backup file where we didn't have any workaround in place.
// Best we can do here is set the funding broadcast height to a
// reasonable value that we determined earlier.
case channel.ShortChanID().BlockHeight == 0:
channel.FundingBroadcastHeight = firstChanHeight
}
}
ltndLog.Infof("Inserting %v SCB channel shells into DB", ltndLog.Infof("Inserting %v SCB channel shells into DB",
len(channelShells)) len(channelShells))