cnct: persist anchor resolutions
This commit is contained in:
parent
7f3d4e7d49
commit
dd77d9263e
@ -29,6 +29,11 @@ type ContractResolutions struct {
|
||||
// HtlcResolutions contains all data required to fully resolve any
|
||||
// incoming+outgoing HTLC's present within the commitment transaction.
|
||||
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
|
||||
@ -37,7 +42,8 @@ type ContractResolutions struct {
|
||||
func (c *ContractResolutions) IsEmpty() bool {
|
||||
return c.CommitResolution == nil &&
|
||||
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
|
||||
@ -263,6 +269,10 @@ var (
|
||||
// the full set of resolutions for a channel.
|
||||
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
|
||||
// store all chain actions once they're determined.
|
||||
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
|
||||
})
|
||||
if err != nil {
|
||||
@ -1045,6 +1086,35 @@ func decodeCommitResolution(r io.Reader,
|
||||
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 {
|
||||
err := binary.Write(w, endian, h.IsRemote)
|
||||
if err != nil {
|
||||
|
@ -46,6 +46,15 @@ var (
|
||||
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{
|
||||
0x52, 0xb6, 0x37, 0xd8, 0xfc, 0xd2, 0xc6, 0xda,
|
||||
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
|
||||
|
@ -2090,6 +2090,7 @@ func (c *ChannelArbitrator) channelAttendant(bestHeight int32) {
|
||||
CommitHash: closeTx.TxHash(),
|
||||
CommitResolution: closeInfo.CommitResolution,
|
||||
HtlcResolutions: *closeInfo.HtlcResolutions,
|
||||
AnchorResolution: closeInfo.AnchorResolution,
|
||||
}
|
||||
|
||||
// When processing a unilateral close event, we'll
|
||||
@ -2156,6 +2157,7 @@ func (c *ChannelArbitrator) channelAttendant(bestHeight int32) {
|
||||
CommitHash: *uniClosure.SpenderTxHash,
|
||||
CommitResolution: uniClosure.CommitResolution,
|
||||
HtlcResolutions: *uniClosure.HtlcResolutions,
|
||||
AnchorResolution: uniClosure.AnchorResolution,
|
||||
}
|
||||
|
||||
// When processing a unilateral close event, we'll
|
||||
|
Loading…
Reference in New Issue
Block a user