From 89d6c58c07c3bcd3ebee32bb6b9ce70e5b9045dd Mon Sep 17 00:00:00 2001 From: Oliver Gugger Date: Sun, 8 Dec 2019 11:19:10 +0100 Subject: [PATCH] Fix some stats --- entry.go | 3 +++ summary.go | 48 ++++++++++++++++++++++++++++++++++++------------ 2 files changed, 39 insertions(+), 12 deletions(-) diff --git a/entry.go b/entry.go index defe560..437c45f 100644 --- a/entry.go +++ b/entry.go @@ -51,6 +51,8 @@ type SummaryEntry struct { 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"` ClosingTX *ClosingTX `json:"closing_tx,omitempty"` ForceClose *ForceClose `json:"force_close"` } @@ -62,6 +64,7 @@ type SummaryEntryFile struct { ForceClosedChannels uint32 `json:"force_closed_channels"` CoopClosedChannels uint32 `json:"coop_closed_channels"` FullySpentChannels uint32 `json:"fully_spent_channels"` + ChannelsWithUnspent uint32 `json:"channels_with_unspent_funds"` ChannelsWithPotential uint32 `json:"channels_with_potential_funds"` FundsOpenChannels uint64 `json:"funds_open_channels"` FundsClosedChannels uint64 `json:"funds_closed_channels"` diff --git a/summary.go b/summary.go index 47a6d46..699816e 100644 --- a/summary.go +++ b/summary.go @@ -18,6 +18,7 @@ func summarizeChannels(apiUrl string, channels []*SummaryEntry) error { if err == ErrTxNotFound { log.Errorf("Funding TX %s not found. Ignoring.", channel.FundingTXID) + channel.ChanExists = false continue } if err != nil { @@ -25,6 +26,7 @@ func summarizeChannels(apiUrl string, channels []*SummaryEntry) error { idx, channel.FundingTXID, err) return err } + channel.ChanExists = true outspend := tx.Vout[channel.FundingTXIndex].outspend if outspend.Spent { summaryFile.ClosedChannels++ @@ -45,6 +47,7 @@ func summarizeChannels(apiUrl string, channels []*SummaryEntry) error { summaryFile.OpenChannels++ summaryFile.FundsOpenChannels += channel.LocalBalance channel.ClosingTX = nil + channel.HasPotential = true } if idx%50 == 0 { @@ -64,6 +67,8 @@ func summarizeChannels(apiUrl string, channels []*SummaryEntry) error { log.Infof(" --> closed channels with all outputs spent: %d", summaryFile.FullySpentChannels) log.Infof(" --> closed channels with unspent outputs: %d", + summaryFile.ChannelsWithUnspent) + log.Infof(" --> closed channels with potentially our outputs: %d", summaryFile.ChannelsWithPotential) log.Infof("Sats in closed channels: %d", summaryFile.FundsClosedChannels) log.Infof(" --> closed channel sats that have been swept/spent: %d", @@ -92,42 +97,56 @@ func reportOutspend(api *chainApi, summaryFile *SummaryEntryFile, } summaryFile.FundsClosedChannels += entry.LocalBalance + var utxo []*vout + for _, vout := range spendTx.Vout { + if !vout.outspend.Spent { + utxo = append(utxo, vout) + } + } if isCoopClose(spendTx) { summaryFile.CoopClosedChannels++ summaryFile.FundsCoopClose += entry.LocalBalance entry.ClosingTX.ForceClose = false + entry.ClosingTX.AllOutsSpent = len(utxo) == 0 + entry.HasPotential = entry.LocalBalance > 0 && len(utxo) != 0 return nil } summaryFile.ForceClosedChannels++ entry.ClosingTX.ForceClose = true - - var utxo []*vout - for _, vout := range spendTx.Vout { - if !vout.outspend.Spent { - utxo = append(utxo, vout) - } - } + entry.HasPotential = false + if len(utxo) > 0 { log.Debugf("Channel %s spent by %s:%d which has %d outputs of "+ "which %d are unspent.", entry.ChannelPoint, os.Txid, os.Vin, len(spendTx.Vout), len(utxo)) entry.ClosingTX.AllOutsSpent = false - summaryFile.ChannelsWithPotential++ + summaryFile.ChannelsWithUnspent++ if couldBeOurs(entry, utxo) { + summaryFile.ChannelsWithPotential++ summaryFile.FundsForceClose += utxo[0].Value + entry.HasPotential = true - switch { - case len(utxo) == 1 && + // Could maybe be brute forced. + if len(utxo) == 1 && utxo[0].ScriptPubkeyType == "v0_p2wpkh" && - utxo[0].outspend.Spent == false: + utxo[0].outspend.Spent == false { entry.ClosingTX.OurAddr = utxo[0].ScriptPubkeyAddr } } else { + // It's theirs, ignore. + if entry.LocalBalance == 0 || + (len(utxo) == 1 && + utxo[0].Value == entry.RemoteBalance) { + + return nil + } + + // We don't know what this output is, logging for debug. for idx, vout := range spendTx.Vout { if !vout.outspend.Spent { log.Debugf("UTXO %d of type %s with "+ @@ -142,6 +161,7 @@ func reportOutspend(api *chainApi, summaryFile *SummaryEntryFile, } } else { entry.ClosingTX.AllOutsSpent = true + entry.HasPotential = false summaryFile.FundsClosedSpent += entry.LocalBalance summaryFile.FullySpentChannels++ } @@ -150,7 +170,11 @@ func reportOutspend(api *chainApi, summaryFile *SummaryEntryFile, } func couldBeOurs(entry *SummaryEntry, utxo []*vout) bool { - return utxo[0].ScriptPubkeyType == "v0_p2wpkh" && entry.LocalBalance != 0 + if len(utxo) == 1 && utxo[0].Value == entry.RemoteBalance { + return false + } + + return entry.LocalBalance != 0 } func isCoopClose(tx *transaction) bool {