chantools/dataformat/summary.go

141 lines
4.6 KiB
Go
Raw Permalink Normal View History

2020-01-04 22:44:43 +01:00
package dataformat
2019-11-24 12:32:59 +01:00
2020-01-04 23:10:26 +01:00
import (
"encoding/hex"
"fmt"
"regexp"
"strconv"
"strings"
2022-07-18 08:52:40 +02:00
"github.com/btcsuite/btcd/btcec/v2"
"github.com/btcsuite/btcd/wire"
2020-01-04 23:10:26 +01:00
"github.com/lightningnetwork/lnd/keychain"
)
2019-12-07 15:21:08 +01:00
2019-11-24 12:32:59 +01:00
type ClosingTX struct {
TXID string `json:"txid"`
ForceClose bool `json:"force_close"`
AllOutsSpent bool `json:"all_outputs_spent"`
OurAddr string `json:"our_addr"`
ToRemoteAddr string `json:"to_remote_addr"`
2019-11-24 12:32:59 +01:00
SweepPrivkey string `json:"sweep_privkey"`
2019-12-05 16:47:24 +01:00
ConfHeight uint32 `json:"conf_height"`
2019-11-24 12:32:59 +01:00
}
2019-12-07 15:21:08 +01:00
type BasePoint struct {
2019-12-05 16:47:24 +01:00
Family uint16 `json:"family,omitempty"`
Index uint32 `json:"index,omitempty"`
2019-12-07 15:21:08 +01:00
PubKey string `json:"pubkey"`
}
func (b *BasePoint) Desc() (*keychain.KeyDescriptor, error) {
pubKeyHex, err := hex.DecodeString(b.PubKey)
if err != nil {
2022-07-18 09:50:27 +02:00
return nil, fmt.Errorf("error decoding base point pubkey: %w",
err)
}
2022-07-18 08:52:40 +02:00
pubKey, err := btcec.ParsePubKey(pubKeyHex)
if err != nil {
2022-07-18 09:50:27 +02:00
return nil, fmt.Errorf("error parsing base point pubkey: %w",
err)
}
2019-12-07 15:21:08 +01:00
return &keychain.KeyDescriptor{
KeyLocator: keychain.KeyLocator{
Family: keychain.KeyFamily(b.Family),
Index: b.Index,
},
PubKey: pubKey,
}, nil
2019-11-24 15:59:24 +01:00
}
type Out struct {
Script string `json:"script"`
ScriptAsm string `json:"script_asm"`
Value uint64 `json:"value"`
}
type ForceClose struct {
2019-12-05 16:47:24 +01:00
TXID string `json:"txid"`
Serialized string `json:"serialized"`
CSVDelay uint16 `json:"csv_delay"`
2019-12-07 15:21:08 +01:00
DelayBasePoint *BasePoint `json:"delay_basepoint"`
RevocationBasePoint *BasePoint `json:"revocation_basepoint"`
2019-12-05 16:47:24 +01:00
CommitPoint string `json:"commit_point"`
Outs []*Out `json:"outs"`
2019-11-24 15:59:24 +01:00
}
2019-11-24 12:32:59 +01:00
type SummaryEntry struct {
RemotePubkey string `json:"remote_pubkey"`
ChannelPoint string `json:"channel_point"`
FundingTXID string `json:"funding_txid"`
FundingTXIndex uint32 `json:"funding_tx_index"`
Capacity uint64 `json:"capacity"`
Initiator bool `json:"initiator"`
LocalBalance uint64 `json:"local_balance"`
RemoteBalance uint64 `json:"remote_balance"`
ChanExists bool `json:"chan_exists_onchain"`
HasPotential bool `json:"has_potential_funds"`
LocalUnrevokedCommitPoint string `json:"local_unrevoked_commit_point"`
ClosingTX *ClosingTX `json:"closing_tx,omitempty"`
ForceClose *ForceClose `json:"force_close"`
2019-11-24 12:32:59 +01:00
}
type SummaryEntryFile struct {
Channels []*SummaryEntry `json:"channels"`
OpenChannels uint32 `json:"open_channels"`
ClosedChannels uint32 `json:"closed_channels"`
ForceClosedChannels uint32 `json:"force_closed_channels"`
CoopClosedChannels uint32 `json:"coop_closed_channels"`
FullySpentChannels uint32 `json:"fully_spent_channels"`
2019-12-08 11:19:10 +01:00
ChannelsWithUnspent uint32 `json:"channels_with_unspent_funds"`
2019-11-24 12:32:59 +01:00
ChannelsWithPotential uint32 `json:"channels_with_potential_funds"`
FundsOpenChannels uint64 `json:"funds_open_channels"`
FundsClosedChannels uint64 `json:"funds_closed_channels"`
FundsClosedSpent uint64 `json:"funds_closed_channels_spent"`
FundsForceClose uint64 `json:"funds_force_closed_maybe_ours"`
FundsCoopClose uint64 `json:"funds_coop_closed_maybe_ours"`
OpenChannelList []*SummaryEntry `json:"open_channel_list"`
2019-11-24 12:32:59 +01:00
}
func ExtractSummaryFromDump(data string) ([]*SummaryEntry, error) {
// Regex to match the data pattern.
pattern := `(?ms) ChanPoint: \(string\) \(len=\d+\) "(.*?)",.*? ` +
2025-02-21 15:00:29 +01:00
`RemotePub: \(string\) \(len=66\) "(.*?)",.*? ` +
`Capacity: \(btcutil\.Amount\) ([\d\.]+) BTC,.*? ` +
`LocalUnrevokedCommitPoint: \(string\) \(len=66\) "(.*?)"`
re := regexp.MustCompile(pattern)
var results []*SummaryEntry
matches := re.FindAllStringSubmatch(data, -1)
for _, match := range matches {
2025-02-21 15:00:29 +01:00
if len(match) == 5 {
chanPoint := strings.TrimSpace(match[1])
parsedOP, err := wire.NewOutPointFromString(chanPoint)
if err != nil {
return nil, fmt.Errorf("unable to parse "+
"outpoint: %w", err)
}
2025-02-21 15:00:29 +01:00
capacity, err := strconv.ParseFloat(match[3], 64)
if err != nil {
return nil, fmt.Errorf("unable to parse "+
"capacity: %w", err)
}
results = append(results, &SummaryEntry{
2025-02-21 15:00:29 +01:00
RemotePubkey: match[2],
ChannelPoint: chanPoint,
FundingTXID: parsedOP.Hash.String(),
FundingTXIndex: parsedOP.Index,
Capacity: uint64(
capacity * 1e8,
),
2025-02-21 15:00:29 +01:00
LocalUnrevokedCommitPoint: match[4],
})
}
}
return results, nil
}