lnrpc: add channel resolutions to closed channels

This commit is contained in:
carla 2020-07-07 10:32:12 +02:00
parent d8a4b37c0e
commit 1d5d616da3
No known key found for this signature in database
GPG Key ID: 4CA7FE54A6213C91
4 changed files with 1266 additions and 854 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1249,6 +1249,79 @@ message ChannelCloseSummary {
force closes, although only one party's close will be confirmed on chain.
*/
Initiator close_initiator = 12;
repeated Resolution resolutions = 13;
}
enum ResolutionType{
TYPE_UNKNOWN = 0;
// We resolved an anchor output.
ANCHOR = 1;
/*
We are resolving an incoming htlc on chain. This if this htlc is
claimed, we swept the incoming htlc with the preimage. If it is timed
out, our peer swept the timeout path.
*/
INCOMING_HTLC = 2;
/*
We are resolving an outgoing htlc on chain. If this htlc is claimed,
the remote party swept the htlc with the preimage. If it is timed out,
we swept it with the timeout path.
*/
OUTGOING_HTLC = 3;
// We force closed and need to sweep our time locked commitment output.
COMMIT = 4;
}
enum ResolutionOutcome {
// Outcome unknown.
OUTCOME_UNKNOWN = 0;
// An output was claimed on chain.
CLAIMED = 1;
// An output was left unclaimed on chain.
UNCLAIMED = 2;
/*
ResolverOutcomeAbandoned indicates that an output that we did not
claim on chain, for example an anchor that we did not sweep and a
third party claimed on chain, or a htlc that we could not decode
so left unclaimed.
*/
ABANDONED = 3;
/*
If we force closed our channel, our htlcs need to be claimed in two
stages. This outcome represents the broadcast of a timeout or success
transaction for this two stage htlc claim.
*/
FIRST_STAGE = 4;
// A htlc was timed out on chain.
TIMEOUT = 5;
}
message Resolution {
// The type of output we are resolving.
ResolutionType resolution_type = 1;
// The outcome of our on chain action that resolved the outpoint.
ResolutionOutcome outcome = 2;
// The outpoint that was spent by the resolution.
OutPoint outpoint = 3;
// The amount that was claimed by the resolution.
uint64 amount_sat = 4;
// The hex-encoded transaction ID of the sweep transaction that spent the
// output.
string sweep_txid = 5;
}
message ClosedChannelsRequest {

View File

@ -2786,6 +2786,12 @@
"close_initiator": {
"$ref": "#/definitions/lnrpcInitiator",
"description": "Close initiator indicates which party initiated the close. This value will\nbe unknown for channels that were cooperatively closed before we started\ntracking cooperative close initiators. Note that this indicates which party\ninitiated a close, and it is possible for both to initiate cooperative or\nforce closes, although only one party's close will be confirmed on chain."
},
"resolutions": {
"type": "array",
"items": {
"$ref": "#/definitions/lnrpcResolution"
}
}
}
},
@ -4849,6 +4855,57 @@
}
}
},
"lnrpcResolution": {
"type": "object",
"properties": {
"resolution_type": {
"$ref": "#/definitions/lnrpcResolutionType",
"description": "The type of output we are resolving."
},
"outcome": {
"$ref": "#/definitions/lnrpcResolutionOutcome",
"description": "The outcome of our on chain action that resolved the outpoint."
},
"outpoint": {
"$ref": "#/definitions/lnrpcOutPoint",
"description": "The outpoint that was spent by the resolution."
},
"amount_sat": {
"type": "string",
"format": "uint64",
"description": "The amount that was claimed by the resolution."
},
"sweep_txid": {
"type": "string",
"description": "The hex-encoded transaction ID of the sweep transaction that spent the\noutput."
}
}
},
"lnrpcResolutionOutcome": {
"type": "string",
"enum": [
"OUTCOME_UNKNOWN",
"CLAIMED",
"UNCLAIMED",
"ABANDONED",
"FIRST_STAGE",
"TIMEOUT"
],
"default": "OUTCOME_UNKNOWN",
"description": " - OUTCOME_UNKNOWN: Outcome unknown.\n - CLAIMED: An output was claimed on chain.\n - UNCLAIMED: An output was left unclaimed on chain.\n - ABANDONED: ResolverOutcomeAbandoned indicates that an output that we did not\nclaim on chain, for example an anchor that we did not sweep and a\nthird party claimed on chain, or a htlc that we could not decode\nso left unclaimed.\n - FIRST_STAGE: If we force closed our channel, our htlcs need to be claimed in two\nstages. This outcome represents the broadcast of a timeout or success\ntransaction for this two stage htlc claim.\n - TIMEOUT: A htlc was timed out on chain."
},
"lnrpcResolutionType": {
"type": "string",
"enum": [
"TYPE_UNKNOWN",
"ANCHOR",
"INCOMING_HTLC",
"OUTGOING_HTLC",
"COMMIT"
],
"default": "TYPE_UNKNOWN",
"description": " - ANCHOR: We resolved an anchor output.\n - INCOMING_HTLC: We are resolving an incoming htlc on chain. This if this htlc is\nclaimed, we swept the incoming htlc with the preimage. If it is timed\nout, our peer swept the timeout path.\n - OUTGOING_HTLC: We are resolving an outgoing htlc on chain. If this htlc is claimed,\nthe remote party swept the htlc with the preimage. If it is timed out,\nwe swept it with the timeout path.\n - COMMIT: We force closed and need to sweep our time locked commitment output."
},
"lnrpcRestoreBackupResponse": {
"type": "object"
},

View File

@ -3528,7 +3528,7 @@ func (r *rpcServer) createRPCClosedChannel(
closeType = lnrpc.ChannelCloseSummary_ABANDONED
}
return &lnrpc.ChannelCloseSummary{
channel := &lnrpc.ChannelCloseSummary{
Capacity: int64(dbChannel.Capacity),
RemotePubkey: nodeID,
CloseHeight: dbChannel.CloseHeight,
@ -3541,7 +3541,95 @@ func (r *rpcServer) createRPCClosedChannel(
ClosingTxHash: dbChannel.ClosingTXID.String(),
OpenInitiator: openInit,
CloseInitiator: closeInitiator,
}, nil
}
reports, err := r.server.chanDB.FetchChannelReports(
*activeNetParams.GenesisHash, &dbChannel.ChanPoint,
)
switch err {
// If the channel does not have its resolver outcomes stored,
// ignore it.
case channeldb.ErrNoChainHashBucket:
fallthrough
case channeldb.ErrNoChannelSummaries:
return channel, nil
// If there is no error, fallthrough the switch to process reports.
case nil:
// If another error occurred, return it.
default:
return nil, err
}
for _, report := range reports {
rpcResolution, err := rpcChannelResolution(report)
if err != nil {
return nil, err
}
channel.Resolutions = append(channel.Resolutions, rpcResolution)
}
return channel, nil
}
func rpcChannelResolution(report *channeldb.ResolverReport) (*lnrpc.Resolution,
error) {
res := &lnrpc.Resolution{
AmountSat: uint64(report.Amount),
Outpoint: &lnrpc.OutPoint{
OutputIndex: report.OutPoint.Index,
TxidStr: report.OutPoint.Hash.String(),
TxidBytes: report.OutPoint.Hash[:],
},
}
if report.SpendTxID != nil {
res.SweepTxid = report.SpendTxID.String()
}
switch report.ResolverType {
case channeldb.ResolverTypeAnchor:
res.ResolutionType = lnrpc.ResolutionType_ANCHOR
case channeldb.ResolverTypeIncomingHtlc:
res.ResolutionType = lnrpc.ResolutionType_INCOMING_HTLC
case channeldb.ResolverTypeOutgoingHtlc:
res.ResolutionType = lnrpc.ResolutionType_OUTGOING_HTLC
case channeldb.ResolverTypeCommit:
res.ResolutionType = lnrpc.ResolutionType_COMMIT
default:
return nil, fmt.Errorf("unknown resolver type: %v",
report.ResolverType)
}
switch report.ResolverOutcome {
case channeldb.ResolverOutcomeClaimed:
res.Outcome = lnrpc.ResolutionOutcome_CLAIMED
case channeldb.ResolverOutcomeUnclaimed:
res.Outcome = lnrpc.ResolutionOutcome_UNCLAIMED
case channeldb.ResolverOutcomeAbandoned:
res.Outcome = lnrpc.ResolutionOutcome_ABANDONED
case channeldb.ResolverOutcomeFirstStage:
res.Outcome = lnrpc.ResolutionOutcome_FIRST_STAGE
case channeldb.ResolverOutcomeTimeout:
res.Outcome = lnrpc.ResolutionOutcome_TIMEOUT
default:
return nil, fmt.Errorf("unknown outcome: %v",
report.ResolverOutcome)
}
return res, nil
}
// getInitiators returns an initiator enum that provides information about the