In this commit, we fix an issue that was recently introduced as a result of migration #10. The new TLV format ended up modifying the serialization functions called in `serializePaymentAttemptInfo`. Migration #9, also used this `serializePaymentAttemptInfo` method to serialize the _new_ (pre TLV, but new payment attempt structure) routes into the database during its migration. However, migration #10 failed to copy over the existing unmodified `serializePaymentAttemptInfo` method into the legacy serialization for migration #9. As a result, once migration #9 was run, the routes/payments were serialized using the _new_ format, rather than the format used for v0.7.1. This then lead to de-serialization either failing, or causing partial payment corruption as migration #10 was expecting the "legacy" format (no TLV info). We fix this issue by adding a new fully enclosed `serializePaymentAttemptInfoMigration9`method that will be used for migration #9. Note that our tests didn't catch this, as they test the migration in isolation, rather than in series which is how users will encounter the migrations. Fixes #3463.
This commit is contained in:
2 files changed
+49
-1
No files matched your search
@@ -7,6 +7,7 @@ import (
|
|||||||
|
|
||||||
"github.com/coreos/bbolt"
|
"github.com/coreos/bbolt"
|
||||||
"github.com/lightningnetwork/lnd/lnwire"
|
"github.com/lightningnetwork/lnd/lnwire"
|
||||||
|
"github.com/lightningnetwork/lnd/routing/route"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -253,3 +254,50 @@ func deserializeOutgoingPayment(r io.Reader) (*outgoingPayment, error) {
|
|||||||
|
|
||||||
return p, nil
|
return p, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// serializePaymentAttemptInfoMigration9 is the serializePaymentAttemptInfo
|
||||||
|
// version as existed when migration #9 was created. We keep this around, along
|
||||||
|
// with the methods below to ensure that clients that upgrade will use the
|
||||||
|
// correct version of this method.
|
||||||
|
func serializePaymentAttemptInfoMigration9(w io.Writer, a *PaymentAttemptInfo) error {
|
||||||
|
if err := WriteElements(w, a.PaymentID, a.SessionKey); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := serializeRouteMigration9(w, a.Route); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func serializeHopMigration9(w io.Writer, h *route.Hop) error {
|
||||||
|
if err := WriteElements(w,
|
||||||
|
h.PubKeyBytes[:], h.ChannelID, h.OutgoingTimeLock,
|
||||||
|
h.AmtToForward,
|
||||||
|
); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func serializeRouteMigration9(w io.Writer, r route.Route) error {
|
||||||
|
if err := WriteElements(w,
|
||||||
|
r.TotalTimeLock, r.TotalAmount, r.SourcePubKey[:],
|
||||||
|
); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := WriteElements(w, uint32(len(r.Hops))); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, h := range r.Hops {
|
||||||
|
if err := serializeHopMigration9(w, h); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -845,7 +845,7 @@ func migrateOutgoingPayments(tx *bbolt.Tx) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var attemptBuf bytes.Buffer
|
var attemptBuf bytes.Buffer
|
||||||
if err := serializePaymentAttemptInfo(&attemptBuf, s); err != nil {
|
if err := serializePaymentAttemptInfoMigration9(&attemptBuf, s); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user