mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-01-19 05:45:21 +01:00
contractcourt: handle writing BreachResolution in arbitrator log
This commit is contained in:
parent
f99933fa69
commit
af03c8cb46
@ -36,16 +36,21 @@ type ContractResolutions struct {
|
||||
// output. If the channel type doesn't include anchors, the value of
|
||||
// this field will be nil.
|
||||
AnchorResolution *lnwallet.AnchorResolution
|
||||
|
||||
// BreachResolution contains the data required to manage the lifecycle
|
||||
// of a breach in the ChannelArbitrator.
|
||||
BreachResolution *BreachResolution
|
||||
}
|
||||
|
||||
// IsEmpty returns true if the set of resolutions is "empty". A resolution is
|
||||
// empty if: our commitment output has been trimmed, and we don't have any
|
||||
// incoming or outgoing HTLC's active.
|
||||
// empty if: our commitment output has been trimmed, we don't have any
|
||||
// incoming or outgoing HTLC's active, there is no anchor output to sweep, or
|
||||
// there are no breached outputs to resolve.
|
||||
func (c *ContractResolutions) IsEmpty() bool {
|
||||
return c.CommitResolution == nil &&
|
||||
len(c.HtlcResolutions.IncomingHTLCs) == 0 &&
|
||||
len(c.HtlcResolutions.OutgoingHTLCs) == 0 &&
|
||||
c.AnchorResolution == nil
|
||||
c.AnchorResolution == nil && c.BreachResolution == nil
|
||||
}
|
||||
|
||||
// ArbitratorLog is the primary source of persistent storage for the
|
||||
@ -269,6 +274,10 @@ const (
|
||||
// sweeping out direct commitment output form the remote party's
|
||||
// commitment transaction.
|
||||
resolverUnilateralSweep resolverType = 4
|
||||
|
||||
// resolverBreach is the type of resolver that manages a contract
|
||||
// breach on-chain.
|
||||
resolverBreach resolverType = 5
|
||||
)
|
||||
|
||||
// resolverIDLen is the size of the resolver ID key. This is 36 bytes as we get
|
||||
@ -341,6 +350,11 @@ var (
|
||||
// store the anchor resolution, if any.
|
||||
anchorResolutionKey = []byte("anchor-resolution")
|
||||
|
||||
// breachResolutionKey is the key under the logScope that we'll use to
|
||||
// store the breach resolution, if any. This is used rather than the
|
||||
// resolutionsKey.
|
||||
breachResolutionKey = []byte("breach-resolution")
|
||||
|
||||
// actionsBucketKey is the key under the logScope that we'll use to
|
||||
// store all chain actions once they're determined.
|
||||
actionsBucketKey = []byte("chain-actions")
|
||||
@ -464,6 +478,8 @@ func (b *boltArbitratorLog) writeResolver(contractBucket kvdb.RwBucket,
|
||||
rType = resolverIncomingContest
|
||||
case *commitSweepResolver:
|
||||
rType = resolverUnilateralSweep
|
||||
case *breachResolver:
|
||||
rType = resolverBreach
|
||||
}
|
||||
if _, err := buf.Write([]byte{byte(rType)}); err != nil {
|
||||
return err
|
||||
@ -593,6 +609,11 @@ func (b *boltArbitratorLog) FetchUnresolvedContracts() ([]ContractResolver, erro
|
||||
resReader, resolverCfg,
|
||||
)
|
||||
|
||||
case resolverBreach:
|
||||
res, err = newBreachResolverFromReader(
|
||||
resReader, resolverCfg,
|
||||
)
|
||||
|
||||
default:
|
||||
return fmt.Errorf("unknown resolver type: %v", resType)
|
||||
}
|
||||
@ -785,6 +806,20 @@ func (b *boltArbitratorLog) LogContractResolutions(c *ContractResolutions) error
|
||||
}
|
||||
}
|
||||
|
||||
// Write out the breach resolution if present.
|
||||
if c.BreachResolution != nil {
|
||||
var b bytes.Buffer
|
||||
err := encodeBreachResolution(&b, c.BreachResolution)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = scopeBucket.Put(breachResolutionKey, b.Bytes())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
@ -904,6 +939,18 @@ func (b *boltArbitratorLog) FetchContractResolutions() (*ContractResolutions, er
|
||||
}
|
||||
}
|
||||
|
||||
breachResBytes := scopeBucket.Get(breachResolutionKey)
|
||||
if breachResBytes != nil {
|
||||
c.BreachResolution = &BreachResolution{}
|
||||
resReader := bytes.NewReader(breachResBytes)
|
||||
err := decodeBreachResolution(
|
||||
resReader, c.BreachResolution,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}, func() {
|
||||
c = &ContractResolutions{}
|
||||
@ -1372,6 +1419,21 @@ func decodeAnchorResolution(r io.Reader,
|
||||
return input.ReadSignDescriptor(r, &a.AnchorSignDescriptor)
|
||||
}
|
||||
|
||||
func encodeBreachResolution(w io.Writer, b *BreachResolution) error {
|
||||
if _, err := w.Write(b.FundingOutPoint.Hash[:]); err != nil {
|
||||
return err
|
||||
}
|
||||
return binary.Write(w, endian, b.FundingOutPoint.Index)
|
||||
}
|
||||
|
||||
func decodeBreachResolution(r io.Reader, b *BreachResolution) error {
|
||||
_, err := io.ReadFull(r, b.FundingOutPoint.Hash[:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return binary.Read(r, endian, &b.FundingOutPoint.Index)
|
||||
}
|
||||
|
||||
func encodeHtlcSetKey(w io.Writer, h *HtlcSetKey) error {
|
||||
err := binary.Write(w, endian, h.IsRemote)
|
||||
if err != nil {
|
||||
|
@ -57,6 +57,11 @@ type RemoteUnilateralCloseInfo struct {
|
||||
CommitSet CommitSet
|
||||
}
|
||||
|
||||
// BreachResolution wraps the outpoint of the breached channel.
|
||||
type BreachResolution struct {
|
||||
FundingOutPoint wire.OutPoint
|
||||
}
|
||||
|
||||
// CommitSet is a collection of the set of known valid commitments at a given
|
||||
// instant. If ConfCommitKey is set, then the commitment identified by the
|
||||
// HtlcSetKey has hit the chain. This struct will be used to examine all live
|
||||
|
Loading…
Reference in New Issue
Block a user