You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
chantools/dump/dump.go

224 lines
6.7 KiB
Go

package dump
import (
"bytes"
"encoding/hex"
"fmt"
"github.com/lightningnetwork/lnd/input"
"net"
"github.com/btcsuite/btcd/btcec"
"github.com/btcsuite/btcd/chaincfg"
"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/btcsuite/btcutil"
"github.com/lightningnetwork/lnd/chanbackup"
"github.com/lightningnetwork/lnd/channeldb"
"github.com/lightningnetwork/lnd/keychain"
"github.com/lightningnetwork/lnd/lnwire"
)
const (
lndInternalDerivationPath = "m/1017'/%d'/%d'/0/%d"
)
// BackupSingle is the information we want to dump from an lnd channel backup
// multi file. See `chanbackup.Multi` for information about the fields.
type BackupMulti struct {
Version chanbackup.MultiBackupVersion
StaticBackups []BackupSingle
}
// BackupSingle is the information we want to dump from an lnd channel backup.
// See `chanbackup.Single` for information about the fields.
type BackupSingle struct {
Version chanbackup.SingleBackupVersion
IsInitiator bool
ChainHash string
FundingOutpoint string
ShortChannelID lnwire.ShortChannelID
RemoteNodePub string
Addresses []net.Addr
Capacity btcutil.Amount
LocalChanCfg ChannelConfig
RemoteChanCfg ChannelConfig
ShaChainRootDesc KeyDescriptor
}
// OpenChannel is the information we want to dump from an open channel in lnd's
// channel DB. See `channeldb.OpenChannel` for information about the fields.
type OpenChannel struct {
ChanType channeldb.ChannelType
ChainHash chainhash.Hash
FundingOutpoint string
ShortChannelID lnwire.ShortChannelID
IsPending bool
IsInitiator bool
ChanStatus channeldb.ChannelStatus
FundingBroadcastHeight uint32
NumConfsRequired uint16
ChannelFlags lnwire.FundingFlag
IdentityPub string
Capacity btcutil.Amount
TotalMSatSent lnwire.MilliSatoshi
TotalMSatReceived lnwire.MilliSatoshi
PerCommitPoint string
LocalChanCfg ChannelConfig
RemoteChanCfg ChannelConfig
LocalCommitment channeldb.ChannelCommitment
RemoteCommitment channeldb.ChannelCommitment
RemoteCurrentRevocation string
RemoteNextRevocation string
FundingTxn string
LocalShutdownScript lnwire.DeliveryAddress
RemoteShutdownScript lnwire.DeliveryAddress
}
// ChannelConfig is the information we want to dump from a channel
// configuration. See `channeldb.ChannelConfig` for more information about the
// fields.
type ChannelConfig struct {
channeldb.ChannelConstraints
MultiSigKey KeyDescriptor
RevocationBasePoint KeyDescriptor
PaymentBasePoint KeyDescriptor
DelayBasePoint KeyDescriptor
HtlcBasePoint KeyDescriptor
}
// KeyDescriptor is the information we want to dump from a key descriptor. See
// `keychain.KeyDescriptor` for more information about the fields.
type KeyDescriptor struct {
Path string
PubKey string
}
// ChannelDump converts the channels in the given channel DB into a dumpable
// format.
func ChannelDump(channels []*channeldb.OpenChannel, params *chaincfg.Params) (
[]OpenChannel, error) {
dumpChannels := make([]OpenChannel, len(channels))
for idx, channel := range channels {
var buf bytes.Buffer
if channel.FundingTxn != nil {
err := channel.FundingTxn.Serialize(&buf)
if err != nil {
return nil, err
}
}
revPreimage, err := channel.RevocationProducer.AtIndex(
channel.LocalCommitment.CommitHeight,
)
if err != nil {
return nil, err
}
perCommitPoint := input.ComputeCommitmentPoint(revPreimage[:])
dumpChannels[idx] = OpenChannel{
ChanType: channel.ChanType,
ChainHash: channel.ChainHash,
FundingOutpoint: channel.FundingOutpoint.String(),
ShortChannelID: channel.ShortChannelID,
IsPending: channel.IsPending,
IsInitiator: channel.IsInitiator,
ChanStatus: channel.ChanStatus(),
FundingBroadcastHeight: channel.FundingBroadcastHeight,
NumConfsRequired: channel.NumConfsRequired,
ChannelFlags: channel.ChannelFlags,
IdentityPub: PubKeyToString(
channel.IdentityPub,
),
Capacity: channel.Capacity,
TotalMSatSent: channel.TotalMSatSent,
TotalMSatReceived: channel.TotalMSatReceived,
PerCommitPoint: PubKeyToString(perCommitPoint),
LocalChanCfg: ToChannelConfig(
params, channel.LocalChanCfg,
),
RemoteChanCfg: ToChannelConfig(
params, channel.RemoteChanCfg,
),
LocalCommitment: channel.LocalCommitment,
RemoteCommitment: channel.RemoteCommitment,
RemoteCurrentRevocation: PubKeyToString(
channel.RemoteCurrentRevocation,
),
RemoteNextRevocation: PubKeyToString(
channel.RemoteNextRevocation,
),
FundingTxn: hex.EncodeToString(buf.Bytes()),
LocalShutdownScript: channel.LocalShutdownScript,
RemoteShutdownScript: channel.RemoteShutdownScript,
}
}
return dumpChannels, nil
}
// BackupDump converts the given multi backup into a dumpable format.
func BackupDump(multi *chanbackup.Multi, params *chaincfg.Params) []BackupSingle {
dumpSingles := make([]BackupSingle, len(multi.StaticBackups))
for idx, single := range multi.StaticBackups {
dumpSingles[idx] = BackupSingle{
Version: single.Version,
IsInitiator: single.IsInitiator,
ChainHash: single.ChainHash.String(),
FundingOutpoint: single.FundingOutpoint.String(),
ShortChannelID: single.ShortChannelID,
RemoteNodePub: PubKeyToString(
single.RemoteNodePub,
),
Addresses: single.Addresses,
Capacity: single.Capacity,
LocalChanCfg: ToChannelConfig(
params, single.LocalChanCfg,
),
RemoteChanCfg: ToChannelConfig(
params, single.RemoteChanCfg,
),
ShaChainRootDesc: ToKeyDescriptor(
params, single.ShaChainRootDesc,
),
}
}
return dumpSingles
}
func ToChannelConfig(params *chaincfg.Params,
cfg channeldb.ChannelConfig) ChannelConfig {
return ChannelConfig{
ChannelConstraints: cfg.ChannelConstraints,
MultiSigKey: ToKeyDescriptor(params, cfg.MultiSigKey),
RevocationBasePoint: ToKeyDescriptor(
params, cfg.RevocationBasePoint,
),
PaymentBasePoint: ToKeyDescriptor(
params, cfg.PaymentBasePoint,
),
DelayBasePoint: ToKeyDescriptor(
params, cfg.DelayBasePoint,
),
HtlcBasePoint: ToKeyDescriptor(params, cfg.HtlcBasePoint),
}
}
func ToKeyDescriptor(params *chaincfg.Params,
desc keychain.KeyDescriptor) KeyDescriptor {
return KeyDescriptor{
Path: fmt.Sprintf(
lndInternalDerivationPath, params.HDCoinType,
desc.Family, desc.Index,
),
PubKey: PubKeyToString(desc.PubKey),
}
}
func PubKeyToString(pubkey *btcec.PublicKey) string {
if pubkey == nil {
return "<nil>"
}
return hex.EncodeToString(pubkey.SerializeCompressed())
}