Refactor data format into package

pull/3/head
Oliver Gugger 4 years ago
parent cf119ed4e5
commit 10f14d24da
No known key found for this signature in database
GPG Key ID: 8E4256593F177720

@ -2,6 +2,7 @@ package chantools
import ( import (
"fmt" "fmt"
"github.com/btcsuite/btcutil" "github.com/btcsuite/btcutil"
"github.com/btcsuite/btcutil/hdkeychain" "github.com/btcsuite/btcutil/hdkeychain"
) )

@ -13,12 +13,14 @@ import (
"github.com/btcsuite/btcd/wire" "github.com/btcsuite/btcd/wire"
"github.com/btcsuite/btcutil/hdkeychain" "github.com/btcsuite/btcutil/hdkeychain"
"github.com/guggero/chantools/chain" "github.com/guggero/chantools/chain"
"github.com/guggero/chantools/dataformat"
"github.com/lightningnetwork/lnd/channeldb" "github.com/lightningnetwork/lnd/channeldb"
"github.com/lightningnetwork/lnd/input" "github.com/lightningnetwork/lnd/input"
) )
func forceCloseChannels(extendedKey *hdkeychain.ExtendedKey, func forceCloseChannels(extendedKey *hdkeychain.ExtendedKey,
entries []*SummaryEntry, chanDb *channeldb.DB, publish bool) error { entries []*dataformat.SummaryEntry, chanDb *channeldb.DB,
publish bool) error {
channels, err := chanDb.FetchAllChannels() channels, err := chanDb.FetchAllChannels()
if err != nil { if err != nil {
@ -31,7 +33,7 @@ func forceCloseChannels(extendedKey *hdkeychain.ExtendedKey,
// publish their local commitment TX. // publish their local commitment TX.
for _, channel := range channels { for _, channel := range channels {
channelPoint := channel.FundingOutpoint.String() channelPoint := channel.FundingOutpoint.String()
var channelEntry *SummaryEntry var channelEntry *dataformat.SummaryEntry
for _, entry := range entries { for _, entry := range entries {
if entry.ChannelPoint == channelPoint { if entry.ChannelPoint == channelPoint {
channelEntry = entry channelEntry = entry
@ -90,17 +92,17 @@ func forceCloseChannels(extendedKey *hdkeychain.ExtendedKey,
// Store all information that we collected into the channel // Store all information that we collected into the channel
// entry file so we don't need to use the channel.db file for // entry file so we don't need to use the channel.db file for
// the next step. // the next step.
channelEntry.ForceClose = &ForceClose{ channelEntry.ForceClose = &dataformat.ForceClose{
TXID: hash.String(), TXID: hash.String(),
Serialized: serialized, Serialized: serialized,
DelayBasePoint: &BasePoint{ DelayBasePoint: &dataformat.BasePoint{
Family: uint16(basepoint.Family), Family: uint16(basepoint.Family),
Index: basepoint.Index, Index: basepoint.Index,
PubKey: hex.EncodeToString( PubKey: hex.EncodeToString(
basepoint.PubKey.SerializeCompressed(), basepoint.PubKey.SerializeCompressed(),
), ),
}, },
RevocationBasePoint: &BasePoint{ RevocationBasePoint: &dataformat.BasePoint{
PubKey: hex.EncodeToString( PubKey: hex.EncodeToString(
revpoint.PubKey.SerializeCompressed(), revpoint.PubKey.SerializeCompressed(),
), ),
@ -108,7 +110,9 @@ func forceCloseChannels(extendedKey *hdkeychain.ExtendedKey,
CommitPoint: hex.EncodeToString( CommitPoint: hex.EncodeToString(
point.SerializeCompressed(), point.SerializeCompressed(),
), ),
Outs: make([]*Out, len(localCommitTx.TxOut)), Outs: make(
[]*dataformat.Out, len(localCommitTx.TxOut),
),
CSVDelay: channel.LocalChanCfg.CsvDelay, CSVDelay: channel.LocalChanCfg.CsvDelay,
} }
for idx, out := range localCommitTx.TxOut { for idx, out := range localCommitTx.TxOut {
@ -116,7 +120,7 @@ func forceCloseChannels(extendedKey *hdkeychain.ExtendedKey,
if err != nil { if err != nil {
return err return err
} }
channelEntry.ForceClose.Outs[idx] = &Out{ channelEntry.ForceClose.Outs[idx] = &dataformat.Out{
Script: hex.EncodeToString(out.PkScript), Script: hex.EncodeToString(out.PkScript),
ScriptAsm: script, ScriptAsm: script,
Value: uint64(out.Value), Value: uint64(out.Value),
@ -134,7 +138,7 @@ func forceCloseChannels(extendedKey *hdkeychain.ExtendedKey,
} }
} }
summaryBytes, err := json.MarshalIndent(&SummaryEntryFile{ summaryBytes, err := json.MarshalIndent(&dataformat.SummaryEntryFile{
Channels: entries, Channels: entries,
}, "", " ") }, "", " ")
if err != nil { if err != nil {

@ -11,6 +11,7 @@ import (
"github.com/btcsuite/btcd/btcec" "github.com/btcsuite/btcd/btcec"
"github.com/btcsuite/btcutil" "github.com/btcsuite/btcutil"
"github.com/btcsuite/btcutil/hdkeychain" "github.com/btcsuite/btcutil/hdkeychain"
"github.com/guggero/chantools/dataformat"
"github.com/lightningnetwork/lnd/channeldb" "github.com/lightningnetwork/lnd/channeldb"
"github.com/lightningnetwork/lnd/input" "github.com/lightningnetwork/lnd/input"
"github.com/lightningnetwork/lnd/keychain" "github.com/lightningnetwork/lnd/keychain"
@ -29,7 +30,7 @@ type cacheEntry struct {
} }
func rescueClosedChannels(extendedKey *hdkeychain.ExtendedKey, func rescueClosedChannels(extendedKey *hdkeychain.ExtendedKey,
entries []*SummaryEntry, chanDb *channeldb.DB) error { entries []*dataformat.SummaryEntry, chanDb *channeldb.DB) error {
err := fillCache(extendedKey) err := fillCache(extendedKey)
if err != nil { if err != nil {
@ -44,7 +45,7 @@ func rescueClosedChannels(extendedKey *hdkeychain.ExtendedKey,
// Try naive/lucky guess with information from channel DB. // Try naive/lucky guess with information from channel DB.
for _, channel := range channels { for _, channel := range channels {
channelPoint := channel.FundingOutpoint.String() channelPoint := channel.FundingOutpoint.String()
var channelEntry *SummaryEntry var channelEntry *dataformat.SummaryEntry
for _, entry := range entries { for _, entry := range entries {
if entry.ChannelPoint == channelPoint { if entry.ChannelPoint == channelPoint {
channelEntry = entry channelEntry = entry
@ -93,7 +94,7 @@ func rescueClosedChannels(extendedKey *hdkeychain.ExtendedKey,
} }
} }
summaryBytes, err := json.MarshalIndent(&SummaryEntryFile{ summaryBytes, err := json.MarshalIndent(&dataformat.SummaryEntryFile{
Channels: entries, Channels: entries,
}, "", " ") }, "", " ")
if err != nil { if err != nil {

@ -7,10 +7,13 @@ import (
"time" "time"
"github.com/guggero/chantools/chain" "github.com/guggero/chantools/chain"
"github.com/guggero/chantools/dataformat"
) )
func summarizeChannels(apiUrl string, channels []*SummaryEntry) error { func summarizeChannels(apiUrl string,
summaryFile := &SummaryEntryFile{ channels []*dataformat.SummaryEntry) error {
summaryFile := &dataformat.SummaryEntryFile{
Channels: channels, Channels: channels,
} }
chainApi := &chain.Api{BaseUrl: apiUrl} chainApi := &chain.Api{BaseUrl: apiUrl}
@ -32,7 +35,7 @@ func summarizeChannels(apiUrl string, channels []*SummaryEntry) error {
outspend := tx.Vout[channel.FundingTXIndex].Outspend outspend := tx.Vout[channel.FundingTXIndex].Outspend
if outspend.Spent { if outspend.Spent {
summaryFile.ClosedChannels++ summaryFile.ClosedChannels++
channel.ClosingTX = &ClosingTX{ channel.ClosingTX = &dataformat.ClosingTX{
TXID: outspend.Txid, TXID: outspend.Txid,
ConfHeight: uint32(outspend.Status.BlockHeight), ConfHeight: uint32(outspend.Status.BlockHeight),
} }
@ -90,8 +93,8 @@ func summarizeChannels(apiUrl string, channels []*SummaryEntry) error {
return ioutil.WriteFile(fileName, summaryBytes, 0644) return ioutil.WriteFile(fileName, summaryBytes, 0644)
} }
func reportOutspend(api *chain.Api, summaryFile *SummaryEntryFile, func reportOutspend(api *chain.Api, summaryFile *dataformat.SummaryEntryFile,
entry *SummaryEntry, os *chain.Outspend) error { entry *dataformat.SummaryEntry, os *chain.Outspend) error {
spendTx, err := api.Transaction(os.Txid) spendTx, err := api.Transaction(os.Txid)
if err != nil { if err != nil {
@ -171,7 +174,7 @@ func reportOutspend(api *chain.Api, summaryFile *SummaryEntryFile,
return nil return nil
} }
func couldBeOurs(entry *SummaryEntry, utxo []*chain.Vout) bool { func couldBeOurs(entry *dataformat.SummaryEntry, utxo []*chain.Vout) bool {
if len(utxo) == 1 && utxo[0].Value == entry.RemoteBalance { if len(utxo) == 1 && utxo[0].Value == entry.RemoteBalance {
return false return false
} }

@ -11,6 +11,7 @@ import (
"github.com/btcsuite/btcd/wire" "github.com/btcsuite/btcd/wire"
"github.com/btcsuite/btcutil/hdkeychain" "github.com/btcsuite/btcutil/hdkeychain"
"github.com/guggero/chantools/chain" "github.com/guggero/chantools/chain"
"github.com/guggero/chantools/dataformat"
"github.com/lightningnetwork/lnd/input" "github.com/lightningnetwork/lnd/input"
) )
@ -19,7 +20,7 @@ const (
) )
func sweepTimeLock(extendedKey *hdkeychain.ExtendedKey, apiUrl string, func sweepTimeLock(extendedKey *hdkeychain.ExtendedKey, apiUrl string,
entries []*SummaryEntry, sweepAddr string, maxCsvTimeout int, entries []*dataformat.SummaryEntry, sweepAddr string, maxCsvTimeout int,
publish bool) error { publish bool) error {
// Create signer and transaction template. // Create signer and transaction template.
@ -76,7 +77,7 @@ func sweepTimeLock(extendedKey *hdkeychain.ExtendedKey, apiUrl string,
if err != nil { if err != nil {
return fmt.Errorf("error parsing commit point: %v", err) return fmt.Errorf("error parsing commit point: %v", err)
} }
delayDesc := fc.DelayBasePoint.toDesc() delayDesc := fc.DelayBasePoint.Desc()
delayPrivKey, err := signer.fetchPrivKey(delayDesc) delayPrivKey, err := signer.fetchPrivKey(delayDesc)
if err != nil { if err != nil {
return fmt.Errorf("error getting private key: %v", err) return fmt.Errorf("error getting private key: %v", err)

@ -1,13 +1,10 @@
package chantools package dataformat
import ( import (
"bytes"
"encoding/hex" "encoding/hex"
"encoding/json" "encoding/json"
"fmt" "fmt"
"github.com/lightningnetwork/lnd/channeldb" "github.com/lightningnetwork/lnd/channeldb"
"io/ioutil"
"os"
"strconv" "strconv"
"strings" "strings"
) )
@ -38,62 +35,11 @@ type Input interface {
AsSummaryEntry() *SummaryEntry AsSummaryEntry() *SummaryEntry
} }
func ParseInput(cfg *config) ([]*SummaryEntry, error) { type ListChannelsFile struct {
var ( Channels []*ListChannelsChannel `json:"channels"`
content []byte
err error
target InputFile
)
switch {
case cfg.ListChannels != "":
content, err = readInput(cfg.ListChannels)
target = &listChannelsFile{}
case cfg.PendingChannels != "":
content, err = readInput(cfg.PendingChannels)
target = &pendingChannelsFile{}
case cfg.FromSummary != "":
content, err = readInput(cfg.FromSummary)
target = &SummaryEntryFile{}
case cfg.FromChannelDB != "":
db, err := channeldb.Open(cfg.FromChannelDB)
if err != nil {
return nil, fmt.Errorf("error opening channel DB: %v",
err)
}
target = &channelDBFile{db: db}
return target.AsSummaryEntries()
default:
return nil, fmt.Errorf("an input file must be specified")
}
if err != nil {
return nil, err
}
decoder := json.NewDecoder(bytes.NewReader(content))
err = decoder.Decode(&target)
if err != nil {
return nil, err
}
return target.AsSummaryEntries()
}
func readInput(input string) ([]byte, error) {
if strings.TrimSpace(input) == "-" {
return ioutil.ReadAll(os.Stdin)
}
return ioutil.ReadFile(input)
}
type listChannelsFile struct {
Channels []*listChannelsChannel `json:"channels"`
} }
func (f *listChannelsFile) AsSummaryEntries() ([]*SummaryEntry, error) { func (f *ListChannelsFile) AsSummaryEntries() ([]*SummaryEntry, error) {
result := make([]*SummaryEntry, len(f.Channels)) result := make([]*SummaryEntry, len(f.Channels))
for idx, entry := range f.Channels { for idx, entry := range f.Channels {
result[idx] = entry.AsSummaryEntry() result[idx] = entry.AsSummaryEntry()
@ -101,7 +47,7 @@ func (f *listChannelsFile) AsSummaryEntries() ([]*SummaryEntry, error) {
return result, nil return result, nil
} }
type listChannelsChannel struct { type ListChannelsChannel struct {
RemotePubkey string `json:"remote_pubkey"` RemotePubkey string `json:"remote_pubkey"`
ChannelPoint string `json:"channel_point"` ChannelPoint string `json:"channel_point"`
Capacity NumberString `json:"capacity"` Capacity NumberString `json:"capacity"`
@ -110,7 +56,7 @@ type listChannelsChannel struct {
RemoteBalance NumberString `json:"remote_balance"` RemoteBalance NumberString `json:"remote_balance"`
} }
func (c *listChannelsChannel) AsSummaryEntry() *SummaryEntry { func (c *ListChannelsChannel) AsSummaryEntry() *SummaryEntry {
return &SummaryEntry{ return &SummaryEntry{
RemotePubkey: c.RemotePubkey, RemotePubkey: c.RemotePubkey,
ChannelPoint: c.ChannelPoint, ChannelPoint: c.ChannelPoint,
@ -123,14 +69,14 @@ func (c *listChannelsChannel) AsSummaryEntry() *SummaryEntry {
} }
} }
type pendingChannelsFile struct { type PendingChannelsFile struct {
PendingOpen []*pendingChannelsChannel `json:"pending_open_channels"` PendingOpen []*PendingChannelsChannel `json:"pending_open_channels"`
PendingClosing []*pendingChannelsChannel `json:"pending_closing_channels"` PendingClosing []*PendingChannelsChannel `json:"pending_closing_channels"`
PendingForceClosing []*pendingChannelsChannel `json:"pending_force_closing_channels"` PendingForceClosing []*PendingChannelsChannel `json:"pending_force_closing_channels"`
WaitingClose []*pendingChannelsChannel `json:"waiting_close_channels"` WaitingClose []*PendingChannelsChannel `json:"waiting_close_channels"`
} }
func (f *pendingChannelsFile) AsSummaryEntries() ([]*SummaryEntry, error) { func (f *PendingChannelsFile) AsSummaryEntries() ([]*SummaryEntry, error) {
numChannels := len(f.PendingOpen) + len(f.PendingClosing) + numChannels := len(f.PendingOpen) + len(f.PendingClosing) +
len(f.PendingForceClosing) + len(f.WaitingClose) len(f.PendingForceClosing) + len(f.WaitingClose)
result := make([]*SummaryEntry, numChannels) result := make([]*SummaryEntry, numChannels)
@ -154,7 +100,7 @@ func (f *pendingChannelsFile) AsSummaryEntries() ([]*SummaryEntry, error) {
return result, nil return result, nil
} }
type pendingChannelsChannel struct { type PendingChannelsChannel struct {
Channel struct { Channel struct {
RemotePubkey string `json:"remote_node_pub"` RemotePubkey string `json:"remote_node_pub"`
ChannelPoint string `json:"channel_point"` ChannelPoint string `json:"channel_point"`
@ -164,7 +110,7 @@ type pendingChannelsChannel struct {
} `json:"channel"` } `json:"channel"`
} }
func (c *pendingChannelsChannel) AsSummaryEntry() *SummaryEntry { func (c *PendingChannelsChannel) AsSummaryEntry() *SummaryEntry {
return &SummaryEntry{ return &SummaryEntry{
RemotePubkey: c.Channel.RemotePubkey, RemotePubkey: c.Channel.RemotePubkey,
ChannelPoint: c.Channel.ChannelPoint, ChannelPoint: c.Channel.ChannelPoint,
@ -177,12 +123,12 @@ func (c *pendingChannelsChannel) AsSummaryEntry() *SummaryEntry {
} }
} }
type channelDBFile struct { type ChannelDBFile struct {
db *channeldb.DB DB *channeldb.DB
} }
func (c *channelDBFile) AsSummaryEntries() ([]*SummaryEntry, error) { func (c *ChannelDBFile) AsSummaryEntries() ([]*SummaryEntry, error) {
channels, err := c.db.FetchAllChannels() channels, err := c.DB.FetchAllChannels()
if err != nil { if err != nil {
return nil, fmt.Errorf("error fetching channels: %v", err) return nil, fmt.Errorf("error fetching channels: %v", err)
} }

@ -1,4 +1,4 @@
package chantools package dataformat
import "github.com/lightningnetwork/lnd/keychain" import "github.com/lightningnetwork/lnd/keychain"
@ -17,7 +17,7 @@ type BasePoint struct {
PubKey string `json:"pubkey"` PubKey string `json:"pubkey"`
} }
func (b *BasePoint) toDesc() *keychain.KeyDescriptor { func (b *BasePoint) Desc() *keychain.KeyDescriptor {
return &keychain.KeyDescriptor{ return &keychain.KeyDescriptor{
KeyLocator: keychain.KeyLocator{ KeyLocator: keychain.KeyLocator{
Family: keychain.KeyFamily(b.Family), Family: keychain.KeyFamily(b.Family),

@ -2,7 +2,10 @@ package chantools
import ( import (
"bufio" "bufio"
"bytes"
"encoding/json"
"fmt" "fmt"
"io/ioutil"
"os" "os"
"path" "path"
"strings" "strings"
@ -10,6 +13,7 @@ import (
"github.com/btcsuite/btcd/chaincfg" "github.com/btcsuite/btcd/chaincfg"
"github.com/btcsuite/btcutil/hdkeychain" "github.com/btcsuite/btcutil/hdkeychain"
"github.com/guggero/chantools/dataformat"
"github.com/jessevdk/go-flags" "github.com/jessevdk/go-flags"
"github.com/lightningnetwork/lnd/aezeed" "github.com/lightningnetwork/lnd/aezeed"
"github.com/lightningnetwork/lnd/build" "github.com/lightningnetwork/lnd/build"
@ -318,6 +322,57 @@ func (c *deriveKeyCommand) Execute(_ []string) error {
return deriveKey(extendedKey, c.Path, c.Neuter) return deriveKey(extendedKey, c.Path, c.Neuter)
} }
func ParseInput(cfg *config) ([]*dataformat.SummaryEntry, error) {
var (
content []byte
err error
target dataformat.InputFile
)
switch {
case cfg.ListChannels != "":
content, err = readInput(cfg.ListChannels)
target = &dataformat.ListChannelsFile{}
case cfg.PendingChannels != "":
content, err = readInput(cfg.PendingChannels)
target = &dataformat.PendingChannelsFile{}
case cfg.FromSummary != "":
content, err = readInput(cfg.FromSummary)
target = &dataformat.SummaryEntryFile{}
case cfg.FromChannelDB != "":
db, err := channeldb.Open(cfg.FromChannelDB)
if err != nil {
return nil, fmt.Errorf("error opening channel DB: %v",
err)
}
target = &dataformat.ChannelDBFile{DB: db}
return target.AsSummaryEntries()
default:
return nil, fmt.Errorf("an input file must be specified")
}
if err != nil {
return nil, err
}
decoder := json.NewDecoder(bytes.NewReader(content))
err = decoder.Decode(&target)
if err != nil {
return nil, err
}
return target.AsSummaryEntries()
}
func readInput(input string) ([]byte, error) {
if strings.TrimSpace(input) == "-" {
return ioutil.ReadAll(os.Stdin)
}
return ioutil.ReadFile(input)
}
func setupChainParams(cfg *config) { func setupChainParams(cfg *config) {
if cfg.Testnet { if cfg.Testnet {
chainParams = &chaincfg.TestNet3Params chainParams = &chaincfg.TestNet3Params

Loading…
Cancel
Save