channedb/mp_payment: add Hash to individual HTLCs

For AMP payments the hash used for each HTLC will differ, and we will
need to retrive it after a restart. We therefore persist it with each
attempt.
This commit is contained in:
Johan T. Halseth 2021-03-30 14:53:29 +02:00
parent 41ae3530a3
commit 06f045fca3
No known key found for this signature in database
GPG Key ID: 15BAADA29DA20D26
4 changed files with 45 additions and 2 deletions

@ -29,6 +29,13 @@ type HTLCAttemptInfo struct {
// AttemptTime is the time at which this HTLC was attempted.
AttemptTime time.Time
// Hash is the hash used for this single HTLC attempt. For AMP payments
// this will differ across attempts, for non-AMP payments each attempt
// will use the same hash. This can be nil for older payment attempts,
// in which the payment's PaymentHash in the PaymentCreationInfo should
// be used.
Hash *lntypes.Hash
}
// HTLCAttempt contains information about a specific HTLC attempt for a given

@ -926,7 +926,20 @@ func serializeHTLCAttemptInfo(w io.Writer, a *HTLCAttemptInfo) error {
return err
}
return serializeTime(w, a.AttemptTime)
if err := serializeTime(w, a.AttemptTime); err != nil {
return err
}
// If the hash is nil we can just return.
if a.Hash == nil {
return nil
}
if _, err := w.Write(a.Hash[:]); err != nil {
return err
}
return nil
}
func deserializeHTLCAttemptInfo(r io.Reader) (*HTLCAttemptInfo, error) {
@ -935,6 +948,7 @@ func deserializeHTLCAttemptInfo(r io.Reader) (*HTLCAttemptInfo, error) {
if err != nil {
return nil, err
}
a.Route, err = DeserializeRoute(r)
if err != nil {
return nil, err
@ -945,6 +959,24 @@ func deserializeHTLCAttemptInfo(r io.Reader) (*HTLCAttemptInfo, error) {
return nil, err
}
hash := lntypes.Hash{}
_, err = io.ReadFull(r, hash[:])
switch {
// Older payment attempts wouldn't have the hash set, in which case we
// can just return.
case err == io.EOF, err == io.ErrUnexpectedEOF:
return a, nil
case err != nil:
return nil, err
default:
}
a.Hash = &hash
return a, nil
}

@ -57,8 +57,10 @@ func makeFakeInfo() (*PaymentCreationInfo, *HTLCAttemptInfo) {
var preimg lntypes.Preimage
copy(preimg[:], rev[:])
hash := preimg.Hash()
c := &PaymentCreationInfo{
PaymentHash: preimg.Hash(),
PaymentHash: hash,
Value: 1000,
// Use single second precision to avoid false positive test
// failures due to the monotonic time component.
@ -71,6 +73,7 @@ func makeFakeInfo() (*PaymentCreationInfo, *HTLCAttemptInfo) {
SessionKey: priv,
Route: testRoute,
AttemptTime: time.Unix(100, 0),
Hash: &hash,
}
return c, a
}

@ -684,6 +684,7 @@ func (p *shardHandler) createNewPaymentAttempt(rt *route.Route, lastShard bool)
AttemptTime: p.router.cfg.Clock.Now(),
SessionKey: sessionKey,
Route: *rt,
Hash: &hash,
}
return firstHop, htlcAdd, attempt, nil