multi: store loop out htlc confirmations on disk

To allow users to specify differing confirmation targets, we store the
swap conf target per-swap. This makes us restart safe, so we do not
forget confirmation values for swaps that are in flight when we restart.
This commit is contained in:
carla 2020-08-04 20:28:06 +02:00
parent e15549e9af
commit 1877b7f08b
No known key found for this signature in database
GPG key ID: 4CA7FE54A6213C91
7 changed files with 70 additions and 12 deletions

View file

@ -36,6 +36,10 @@ type LoopOutContract struct {
// client sweep tx.
SweepConfTarget int32
// HtlcConfirmations is the number of confirmations we require the on
// chain htlc to have before proceeding with the swap.
HtlcConfirmations uint32
// OutgoingChanSet is the set of short ids of channels that may be used.
// If empty, any channel may be used.
OutgoingChanSet ChannelSet

View file

@ -77,11 +77,23 @@ var (
// value: concatenation of uint64 channel ids
outgoingChanSetKey = []byte("outgoing-chan-set")
// confirmationsKey is the key that stores the number of confirmations
// that were requested for a loop out swap.
//
// path: loopOutBucket -> swapBucket[hash] -> confirmationsKey
//
// value: uint32 confirmation value
confirmationsKey = []byte("confirmations")
byteOrder = binary.BigEndian
keyLength = 33
)
// DefaultLoopOutHtlcConfirmations is the default number of confirmations we
// set for a loop out htlc.
const DefaultLoopOutHtlcConfirmations uint32 = 1
// fileExists returns true if the file exists, and false otherwise.
func fileExists(path string) bool {
if _, err := os.Stat(path); err != nil {
@ -242,6 +254,23 @@ func (s *boltSwapStore) FetchLoopOutSwaps() ([]*LoopOut, error) {
}
}
// Set our default number of confirmations for the swap.
contract.HtlcConfirmations = DefaultLoopOutHtlcConfirmations
// If we have the number of confirmations stored for
// this swap, we overwrite our default with the stored
// value.
confBytes := swapBucket.Get(confirmationsKey)
if confBytes != nil {
r := bytes.NewReader(confBytes)
err := binary.Read(
r, byteOrder, &contract.HtlcConfirmations,
)
if err != nil {
return err
}
}
updates, err := deserializeUpdates(swapBucket)
if err != nil {
return err
@ -471,6 +500,18 @@ func (s *boltSwapStore) CreateLoopOut(hash lntypes.Hash,
return err
}
// Write our confirmation target under its own key.
var buf bytes.Buffer
err = binary.Write(&buf, byteOrder, swap.HtlcConfirmations)
if err != nil {
return err
}
err = swapBucket.Put(confirmationsKey, buf.Bytes())
if err != nil {
return err
}
// Finally, we'll create an empty updates bucket for this swap
// to track any future updates to the swap itself.
_, err = swapBucket.CreateBucket(updatesBucketKey)

View file

@ -70,6 +70,7 @@ func TestLoopOutStore(t *testing.T) {
SwapInvoice: "swapinvoice",
MaxSwapRoutingFee: 30,
SweepConfTarget: 2,
HtlcConfirmations: 2,
SwapPublicationDeadline: time.Unix(0, initiationTime.UnixNano()),
}