mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-03-13 11:09:23 +01:00
cnct+lnrpc: report anchor resolution
This commit is contained in:
parent
ea397c9d6e
commit
ab451f634e
6 changed files with 826 additions and 708 deletions
|
@ -3,8 +3,10 @@ package contractcourt
|
|||
import (
|
||||
"errors"
|
||||
"io"
|
||||
"sync"
|
||||
|
||||
"github.com/btcsuite/btcd/wire"
|
||||
"github.com/btcsuite/btcutil"
|
||||
"github.com/lightningnetwork/lnd/input"
|
||||
"github.com/lightningnetwork/lnd/lnwallet"
|
||||
"github.com/lightningnetwork/lnd/sweep"
|
||||
|
@ -30,6 +32,13 @@ type anchorResolver struct {
|
|||
// chanPoint is the channel point of the original contract.
|
||||
chanPoint wire.OutPoint
|
||||
|
||||
// currentReport stores the current state of the resolver for reporting
|
||||
// over the rpc interface.
|
||||
currentReport ContractReport
|
||||
|
||||
// reportLock prevents concurrent access to the resolver report.
|
||||
reportLock sync.Mutex
|
||||
|
||||
contractResolverKit
|
||||
}
|
||||
|
||||
|
@ -38,12 +47,23 @@ func newAnchorResolver(anchorSignDescriptor input.SignDescriptor,
|
|||
anchor wire.OutPoint, broadcastHeight uint32,
|
||||
chanPoint wire.OutPoint, resCfg ResolverConfig) *anchorResolver {
|
||||
|
||||
amt := btcutil.Amount(anchorSignDescriptor.Output.Value)
|
||||
|
||||
report := ContractReport{
|
||||
Outpoint: anchor,
|
||||
Type: ReportOutputAnchor,
|
||||
Amount: amt,
|
||||
LimboBalance: amt,
|
||||
RecoveredBalance: 0,
|
||||
}
|
||||
|
||||
r := &anchorResolver{
|
||||
contractResolverKit: *newContractResolverKit(resCfg),
|
||||
anchorSignDescriptor: anchorSignDescriptor,
|
||||
anchor: anchor,
|
||||
broadcastHeight: broadcastHeight,
|
||||
chanPoint: chanPoint,
|
||||
currentReport: report,
|
||||
}
|
||||
|
||||
r.initLogger(r)
|
||||
|
@ -101,6 +121,7 @@ func (c *anchorResolver) Resolve() (ContractResolver, error) {
|
|||
}
|
||||
}
|
||||
|
||||
var anchorRecovered bool
|
||||
select {
|
||||
case sweepRes := <-resultChan:
|
||||
switch sweepRes.Err {
|
||||
|
@ -110,6 +131,8 @@ func (c *anchorResolver) Resolve() (ContractResolver, error) {
|
|||
c.log.Debugf("anchor swept by tx %v",
|
||||
sweepRes.Tx.TxHash())
|
||||
|
||||
anchorRecovered = true
|
||||
|
||||
// Anchor was swept by someone else. This is possible after the
|
||||
// 16 block csv lock.
|
||||
case sweep.ErrRemoteSpend:
|
||||
|
@ -136,6 +159,14 @@ func (c *anchorResolver) Resolve() (ContractResolver, error) {
|
|||
return nil, errResolverShuttingDown
|
||||
}
|
||||
|
||||
// Update report to reflect that funds are no longer in limbo.
|
||||
c.reportLock.Lock()
|
||||
if anchorRecovered {
|
||||
c.currentReport.RecoveredBalance = c.currentReport.LimboBalance
|
||||
}
|
||||
c.currentReport.LimboBalance = 0
|
||||
c.reportLock.Unlock()
|
||||
|
||||
c.resolved = true
|
||||
return nil, nil
|
||||
}
|
||||
|
@ -156,6 +187,15 @@ func (c *anchorResolver) IsResolved() bool {
|
|||
return c.resolved
|
||||
}
|
||||
|
||||
// report returns a report on the resolution state of the contract.
|
||||
func (c *anchorResolver) report() *ContractReport {
|
||||
c.reportLock.Lock()
|
||||
defer c.reportLock.Unlock()
|
||||
|
||||
reportCopy := c.currentReport
|
||||
return &reportCopy
|
||||
}
|
||||
|
||||
func (c *anchorResolver) Encode(w io.Writer) error {
|
||||
return errors.New("serialization not supported")
|
||||
}
|
||||
|
|
|
@ -162,6 +162,9 @@ const (
|
|||
// ReportOutputUnencumbered is an uncontested output on the commitment
|
||||
// transaction paying to us directly.
|
||||
ReportOutputUnencumbered
|
||||
|
||||
// ReportOutputAnchor is an anchor output on the commitment tx.
|
||||
ReportOutputAnchor
|
||||
)
|
||||
|
||||
// ContractReport provides a summary of a commitment tx output.
|
||||
|
|
1454
lnrpc/rpc.pb.go
1454
lnrpc/rpc.pb.go
File diff suppressed because it is too large
Load diff
|
@ -2016,6 +2016,14 @@ message PendingChannelsResponse {
|
|||
int64 recovered_balance = 6;
|
||||
|
||||
repeated PendingHTLC pending_htlcs = 8;
|
||||
|
||||
enum AnchorState {
|
||||
LIMBO = 0;
|
||||
RECOVERED = 1;
|
||||
LOST = 2;
|
||||
}
|
||||
|
||||
AnchorState anchor = 9;
|
||||
}
|
||||
|
||||
/// The balance in satoshis encumbered in pending channels
|
||||
|
|
|
@ -1534,6 +1534,15 @@
|
|||
"default": "RESERVED",
|
||||
"description": " - RESERVED: *\nThe numbers assigned in this enumeration match the failure codes as\ndefined in BOLT #4. Because protobuf 3 requires enums to start with 0,\na RESERVED value is added.\n - INTERNAL_FAILURE: *\nAn internal error occurred.\n - UNKNOWN_FAILURE: *\nThe error source is known, but the failure itself couldn't be decoded.\n - UNREADABLE_FAILURE: *\nAn unreadable failure result is returned if the received failure message\ncannot be decrypted. In that case the error source is unknown."
|
||||
},
|
||||
"ForceClosedChannelAnchorState": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"LIMBO",
|
||||
"RECOVERED",
|
||||
"LOST"
|
||||
],
|
||||
"default": "LIMBO"
|
||||
},
|
||||
"HTLCAttemptHTLCStatus": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
|
@ -1630,6 +1639,9 @@
|
|||
"items": {
|
||||
"$ref": "#/definitions/lnrpcPendingHTLC"
|
||||
}
|
||||
},
|
||||
"anchor": {
|
||||
"$ref": "#/definitions/ForceClosedChannelAnchorState"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
17
rpcserver.go
17
rpcserver.go
|
@ -2839,6 +2839,22 @@ func (r *rpcServer) arbitratorPopulateForceCloseResp(chanPoint *wire.OutPoint,
|
|||
|
||||
forceClose.PendingHtlcs = append(forceClose.PendingHtlcs, htlc)
|
||||
|
||||
case contractcourt.ReportOutputAnchor:
|
||||
// There are three resolution states for the anchor:
|
||||
// limbo, lost and recovered. Derive the current state
|
||||
// from the limbo and recovered balances.
|
||||
switch {
|
||||
|
||||
case report.RecoveredBalance != 0:
|
||||
forceClose.Anchor = lnrpc.PendingChannelsResponse_ForceClosedChannel_RECOVERED
|
||||
|
||||
case report.LimboBalance != 0:
|
||||
forceClose.Anchor = lnrpc.PendingChannelsResponse_ForceClosedChannel_LIMBO
|
||||
|
||||
default:
|
||||
forceClose.Anchor = lnrpc.PendingChannelsResponse_ForceClosedChannel_LOST
|
||||
}
|
||||
|
||||
default:
|
||||
return fmt.Errorf("unknown report output type: %v",
|
||||
report.Type)
|
||||
|
@ -2846,7 +2862,6 @@ func (r *rpcServer) arbitratorPopulateForceCloseResp(chanPoint *wire.OutPoint,
|
|||
|
||||
forceClose.LimboBalance += int64(report.LimboBalance)
|
||||
forceClose.RecoveredBalance += int64(report.RecoveredBalance)
|
||||
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
Loading…
Add table
Reference in a new issue