mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-07-27 21:32:34 +02:00
cnct: persist anchor resolutions
This commit is contained in:
@@ -29,6 +29,11 @@ type ContractResolutions struct {
|
|||||||
// HtlcResolutions contains all data required to fully resolve any
|
// HtlcResolutions contains all data required to fully resolve any
|
||||||
// incoming+outgoing HTLC's present within the commitment transaction.
|
// incoming+outgoing HTLC's present within the commitment transaction.
|
||||||
HtlcResolutions lnwallet.HtlcResolutions
|
HtlcResolutions lnwallet.HtlcResolutions
|
||||||
|
|
||||||
|
// AnchorResolution contains the data required to sweep the anchor
|
||||||
|
// output. If the channel type doesn't include anchors, the value of
|
||||||
|
// this field will be nil.
|
||||||
|
AnchorResolution *lnwallet.AnchorResolution
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsEmpty returns true if the set of resolutions is "empty". A resolution is
|
// IsEmpty returns true if the set of resolutions is "empty". A resolution is
|
||||||
@@ -37,7 +42,8 @@ type ContractResolutions struct {
|
|||||||
func (c *ContractResolutions) IsEmpty() bool {
|
func (c *ContractResolutions) IsEmpty() bool {
|
||||||
return c.CommitResolution == nil &&
|
return c.CommitResolution == nil &&
|
||||||
len(c.HtlcResolutions.IncomingHTLCs) == 0 &&
|
len(c.HtlcResolutions.IncomingHTLCs) == 0 &&
|
||||||
len(c.HtlcResolutions.OutgoingHTLCs) == 0
|
len(c.HtlcResolutions.OutgoingHTLCs) == 0 &&
|
||||||
|
c.AnchorResolution == nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ArbitratorLog is the primary source of persistent storage for the
|
// ArbitratorLog is the primary source of persistent storage for the
|
||||||
@@ -263,6 +269,10 @@ var (
|
|||||||
// the full set of resolutions for a channel.
|
// the full set of resolutions for a channel.
|
||||||
resolutionsKey = []byte("resolutions")
|
resolutionsKey = []byte("resolutions")
|
||||||
|
|
||||||
|
// anchorResolutionKey is the key under the logScope that we'll use to
|
||||||
|
// store the anchor resolution, if any.
|
||||||
|
anchorResolutionKey = []byte("anchor-resolution")
|
||||||
|
|
||||||
// actionsBucketKey is the key under the logScope that we'll use to
|
// actionsBucketKey is the key under the logScope that we'll use to
|
||||||
// store all chain actions once they're determined.
|
// store all chain actions once they're determined.
|
||||||
actionsBucketKey = []byte("chain-actions")
|
actionsBucketKey = []byte("chain-actions")
|
||||||
@@ -630,7 +640,26 @@ func (b *boltArbitratorLog) LogContractResolutions(c *ContractResolutions) error
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return scopeBucket.Put(resolutionsKey, b.Bytes())
|
err = scopeBucket.Put(resolutionsKey, b.Bytes())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write out the anchor resolution if present.
|
||||||
|
if c.AnchorResolution != nil {
|
||||||
|
var b bytes.Buffer
|
||||||
|
err := encodeAnchorResolution(&b, c.AnchorResolution)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = scopeBucket.Put(anchorResolutionKey, b.Bytes())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -710,6 +739,18 @@ func (b *boltArbitratorLog) FetchContractResolutions() (*ContractResolutions, er
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
anchorResBytes := scopeBucket.Get(anchorResolutionKey)
|
||||||
|
if anchorResBytes != nil {
|
||||||
|
c.AnchorResolution = &lnwallet.AnchorResolution{}
|
||||||
|
resReader := bytes.NewReader(anchorResBytes)
|
||||||
|
err := decodeAnchorResolution(
|
||||||
|
resReader, c.AnchorResolution,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -1045,6 +1086,35 @@ func decodeCommitResolution(r io.Reader,
|
|||||||
return binary.Read(r, endian, &c.MaturityDelay)
|
return binary.Read(r, endian, &c.MaturityDelay)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func encodeAnchorResolution(w io.Writer,
|
||||||
|
a *lnwallet.AnchorResolution) error {
|
||||||
|
|
||||||
|
if _, err := w.Write(a.CommitAnchor.Hash[:]); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err := binary.Write(w, endian, a.CommitAnchor.Index)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return input.WriteSignDescriptor(w, &a.AnchorSignDescriptor)
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeAnchorResolution(r io.Reader,
|
||||||
|
a *lnwallet.AnchorResolution) error {
|
||||||
|
|
||||||
|
_, err := io.ReadFull(r, a.CommitAnchor.Hash[:])
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = binary.Read(r, endian, &a.CommitAnchor.Index)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return input.ReadSignDescriptor(r, &a.AnchorSignDescriptor)
|
||||||
|
}
|
||||||
|
|
||||||
func encodeHtlcSetKey(w io.Writer, h *HtlcSetKey) error {
|
func encodeHtlcSetKey(w io.Writer, h *HtlcSetKey) error {
|
||||||
err := binary.Write(w, endian, h.IsRemote)
|
err := binary.Write(w, endian, h.IsRemote)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@@ -46,6 +46,15 @@ var (
|
|||||||
Index: 2,
|
Index: 2,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
testChanPoint3 = wire.OutPoint{
|
||||||
|
Hash: chainhash.Hash{
|
||||||
|
0x48, 0x59, 0xe6, 0x96, 0x31, 0x13, 0xa1, 0x17,
|
||||||
|
0x51, 0xb6, 0x37, 0xd8, 0xfc, 0xd2, 0xc6, 0xda,
|
||||||
|
0x2d, 0xe7, 0x93, 0xe4,
|
||||||
|
},
|
||||||
|
Index: 3,
|
||||||
|
}
|
||||||
|
|
||||||
testPreimage = [32]byte{
|
testPreimage = [32]byte{
|
||||||
0x52, 0xb6, 0x37, 0xd8, 0xfc, 0xd2, 0xc6, 0xda,
|
0x52, 0xb6, 0x37, 0xd8, 0xfc, 0xd2, 0xc6, 0xda,
|
||||||
0x48, 0x59, 0xe6, 0x96, 0x31, 0x13, 0xa1, 0x17,
|
0x48, 0x59, 0xe6, 0x96, 0x31, 0x13, 0xa1, 0x17,
|
||||||
@@ -540,6 +549,10 @@ func TestContractResolutionsStorage(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
AnchorResolution: &lnwallet.AnchorResolution{
|
||||||
|
CommitAnchor: testChanPoint3,
|
||||||
|
AnchorSignDescriptor: testSignDesc,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
// First make sure that fetching unlogged contract resolutions will
|
// First make sure that fetching unlogged contract resolutions will
|
||||||
|
@@ -2090,6 +2090,7 @@ func (c *ChannelArbitrator) channelAttendant(bestHeight int32) {
|
|||||||
CommitHash: closeTx.TxHash(),
|
CommitHash: closeTx.TxHash(),
|
||||||
CommitResolution: closeInfo.CommitResolution,
|
CommitResolution: closeInfo.CommitResolution,
|
||||||
HtlcResolutions: *closeInfo.HtlcResolutions,
|
HtlcResolutions: *closeInfo.HtlcResolutions,
|
||||||
|
AnchorResolution: closeInfo.AnchorResolution,
|
||||||
}
|
}
|
||||||
|
|
||||||
// When processing a unilateral close event, we'll
|
// When processing a unilateral close event, we'll
|
||||||
@@ -2156,6 +2157,7 @@ func (c *ChannelArbitrator) channelAttendant(bestHeight int32) {
|
|||||||
CommitHash: *uniClosure.SpenderTxHash,
|
CommitHash: *uniClosure.SpenderTxHash,
|
||||||
CommitResolution: uniClosure.CommitResolution,
|
CommitResolution: uniClosure.CommitResolution,
|
||||||
HtlcResolutions: *uniClosure.HtlcResolutions,
|
HtlcResolutions: *uniClosure.HtlcResolutions,
|
||||||
|
AnchorResolution: uniClosure.AnchorResolution,
|
||||||
}
|
}
|
||||||
|
|
||||||
// When processing a unilateral close event, we'll
|
// When processing a unilateral close event, we'll
|
||||||
|
Reference in New Issue
Block a user