From 8b289e79f54801405f1377f9d8f2e2324fce6167 Mon Sep 17 00:00:00 2001 From: yyforyongyu Date: Sat, 16 Apr 2022 11:45:05 +0800 Subject: [PATCH] channeldb+migration: export commonly used methods This commit exports several commonly used methods that can be used by later migrations. It also adds a channel commit deserializer. --- channeldb/migration24/migration.go | 4 +- channeldb/migration24/migration_test.go | 6 +- channeldb/migration_01_to_11/channel.go | 97 ++++++++++++++++++- channeldb/migration_01_to_11/codec.go | 12 +-- channeldb/migration_01_to_11/graph.go | 2 +- .../legacy_serialization.go | 2 +- .../migration_01_to_11/migrations_test.go | 6 +- 7 files changed, 109 insertions(+), 20 deletions(-) diff --git a/channeldb/migration24/migration.go b/channeldb/migration24/migration.go index 287955dbf..8382a9ba6 100644 --- a/channeldb/migration24/migration.go +++ b/channeldb/migration24/migration.go @@ -70,7 +70,7 @@ func MigrateFwdPkgCleanup(tx kvdb.RwTx) error { // Iterate over all close channels and remove their forwarding packages. for _, summery := range chanSummaries { - sourceBytes := makeLogKey(summery.ShortChanID.ToUint64()) + sourceBytes := MakeLogKey(summery.ShortChanID.ToUint64()) // First, we will try to find the corresponding bucket. If there // is not a nested bucket matching the ShortChanID, we will skip @@ -112,7 +112,7 @@ func deserializeCloseChannelSummary( } // makeLogKey converts a uint64 into an 8 byte array. -func makeLogKey(updateNum uint64) [8]byte { +func MakeLogKey(updateNum uint64) [8]byte { var key [8]byte binary.BigEndian.PutUint64(key[:], updateNum) return key diff --git a/channeldb/migration24/migration_test.go b/channeldb/migration24/migration_test.go index ea337e198..417c3d0ed 100644 --- a/channeldb/migration24/migration_test.go +++ b/channeldb/migration24/migration_test.go @@ -187,7 +187,7 @@ func genAfterMigration(deleted, untouched []int) func(kvdb.RwTx) error { // Reading deleted buckets should return nil for _, id := range deleted { chanID := lnwire.NewShortChanIDFromInt(uint64(id)) - sourceKey := makeLogKey(chanID.ToUint64()) + sourceKey := MakeLogKey(chanID.ToUint64()) sourceBkt := fwdPkgBkt.NestedReadBucket(sourceKey[:]) if sourceBkt != nil { return fmt.Errorf( @@ -200,7 +200,7 @@ func genAfterMigration(deleted, untouched []int) func(kvdb.RwTx) error { // Reading untouched buckets should return not nil for _, id := range untouched { chanID := lnwire.NewShortChanIDFromInt(uint64(id)) - sourceKey := makeLogKey(chanID.ToUint64()) + sourceKey := MakeLogKey(chanID.ToUint64()) sourceBkt := fwdPkgBkt.NestedReadBucket(sourceKey[:]) if sourceBkt == nil { return fmt.Errorf( @@ -259,7 +259,7 @@ func createTestFwdPkgBucket(tx kvdb.RwTx, chanID lnwire.ShortChannelID) error { return err } - source := makeLogKey(chanID.ToUint64()) + source := MakeLogKey(chanID.ToUint64()) if _, err := fwdPkgBkt.CreateBucketIfNotExists(source[:]); err != nil { return err } diff --git a/channeldb/migration_01_to_11/channel.go b/channeldb/migration_01_to_11/channel.go index 333bdf05f..47cbca355 100644 --- a/channeldb/migration_01_to_11/channel.go +++ b/channeldb/migration_01_to_11/channel.go @@ -616,7 +616,7 @@ func serializeChannelCloseSummary(w io.Writer, cs *ChannelCloseSummary) error { return err } - if err := writeChanConfig(w, &cs.LocalChanConfig); err != nil { + if err := WriteChanConfig(w, &cs.LocalChanConfig); err != nil { return err } @@ -680,7 +680,7 @@ func deserializeCloseChannelSummary(r io.Reader) (*ChannelCloseSummary, error) { return nil, err } - if err := readChanConfig(r, &c.LocalChanConfig); err != nil { + if err := ReadChanConfig(r, &c.LocalChanConfig); err != nil { return nil, err } @@ -731,7 +731,7 @@ func deserializeCloseChannelSummary(r io.Reader) (*ChannelCloseSummary, error) { return c, nil } -func writeChanConfig(b io.Writer, c *ChannelConfig) error { +func WriteChanConfig(b io.Writer, c *ChannelConfig) error { return WriteElements(b, c.DustLimit, c.MaxPendingAmount, c.ChanReserve, c.MinHTLC, c.MaxAcceptedHtlcs, c.CsvDelay, c.MultiSigKey, @@ -740,7 +740,7 @@ func writeChanConfig(b io.Writer, c *ChannelConfig) error { ) } -func readChanConfig(b io.Reader, c *ChannelConfig) error { +func ReadChanConfig(b io.Reader, c *ChannelConfig) error { return ReadElements(b, &c.DustLimit, &c.MaxPendingAmount, &c.ChanReserve, &c.MinHTLC, &c.MaxAcceptedHtlcs, &c.CsvDelay, @@ -749,3 +749,92 @@ func readChanConfig(b io.Reader, c *ChannelConfig) error { &c.HtlcBasePoint, ) } + +func DeserializeChanCommit(r io.Reader) (ChannelCommitment, error) { + var c ChannelCommitment + + err := ReadElements(r, + &c.CommitHeight, &c.LocalLogIndex, &c.LocalHtlcIndex, &c.RemoteLogIndex, + &c.RemoteHtlcIndex, &c.LocalBalance, &c.RemoteBalance, + &c.CommitFee, &c.FeePerKw, &c.CommitTx, &c.CommitSig, + ) + if err != nil { + return c, err + } + + c.Htlcs, err = DeserializeHtlcs(r) + if err != nil { + return c, err + } + + return c, nil +} + +// DeserializeHtlcs attempts to read out a slice of HTLC's from the passed +// io.Reader. The bytes within the passed reader MUST have been previously +// written to using the SerializeHtlcs function. +// +// NOTE: This API is NOT stable, the on-disk format will likely change in the +// future. +func DeserializeHtlcs(r io.Reader) ([]HTLC, error) { + var numHtlcs uint16 + if err := ReadElement(r, &numHtlcs); err != nil { + return nil, err + } + + var htlcs []HTLC + if numHtlcs == 0 { + return htlcs, nil + } + + htlcs = make([]HTLC, numHtlcs) + for i := uint16(0); i < numHtlcs; i++ { + if err := ReadElements(r, + &htlcs[i].Signature, &htlcs[i].RHash, &htlcs[i].Amt, + &htlcs[i].RefundTimeout, &htlcs[i].OutputIndex, + &htlcs[i].Incoming, &htlcs[i].OnionBlob, + &htlcs[i].HtlcIndex, &htlcs[i].LogIndex, + ); err != nil { + return htlcs, err + } + } + + return htlcs, nil +} + +func SerializeChanCommit(w io.Writer, c *ChannelCommitment) error { + if err := WriteElements(w, + c.CommitHeight, c.LocalLogIndex, c.LocalHtlcIndex, + c.RemoteLogIndex, c.RemoteHtlcIndex, c.LocalBalance, + c.RemoteBalance, c.CommitFee, c.FeePerKw, c.CommitTx, + c.CommitSig, + ); err != nil { + return err + } + + return SerializeHtlcs(w, c.Htlcs...) +} + +// SerializeHtlcs writes out the passed set of HTLC's into the passed writer +// using the current default on-disk serialization format. +// +// NOTE: This API is NOT stable, the on-disk format will likely change in the +// future. +func SerializeHtlcs(b io.Writer, htlcs ...HTLC) error { + numHtlcs := uint16(len(htlcs)) + if err := WriteElement(b, numHtlcs); err != nil { + return err + } + + for _, htlc := range htlcs { + if err := WriteElements(b, + htlc.Signature, htlc.RHash, htlc.Amt, htlc.RefundTimeout, + htlc.OutputIndex, htlc.Incoming, htlc.OnionBlob[:], + htlc.HtlcIndex, htlc.LogIndex, + ); err != nil { + return err + } + } + + return nil +} diff --git a/channeldb/migration_01_to_11/codec.go b/channeldb/migration_01_to_11/codec.go index 986bf9dbc..a87f6eda7 100644 --- a/channeldb/migration_01_to_11/codec.go +++ b/channeldb/migration_01_to_11/codec.go @@ -15,9 +15,9 @@ import ( "github.com/lightningnetwork/lnd/shachain" ) -// writeOutpoint writes an outpoint to the passed writer using the minimal +// WriteOutpoint writes an outpoint to the passed writer using the minimal // amount of bytes possible. -func writeOutpoint(w io.Writer, o *wire.OutPoint) error { +func WriteOutpoint(w io.Writer, o *wire.OutPoint) error { if _, err := w.Write(o.Hash[:]); err != nil { return err } @@ -28,9 +28,9 @@ func writeOutpoint(w io.Writer, o *wire.OutPoint) error { return nil } -// readOutpoint reads an outpoint from the passed reader that was previously +// ReadOutpoint reads an outpoint from the passed reader that was previously // written using the writeOutpoint struct. -func readOutpoint(r io.Reader, o *wire.OutPoint) error { +func ReadOutpoint(r io.Reader, o *wire.OutPoint) error { if _, err := io.ReadFull(r, o.Hash[:]); err != nil { return err } @@ -88,7 +88,7 @@ func WriteElement(w io.Writer, element interface{}) error { } case wire.OutPoint: - return writeOutpoint(w, &e) + return WriteOutpoint(w, &e) case lnwire.ShortChannelID: if err := binary.Write(w, byteOrder, e.ToUint64()); err != nil { @@ -258,7 +258,7 @@ func ReadElement(r io.Reader, element interface{}) error { } case *wire.OutPoint: - return readOutpoint(r, e) + return ReadOutpoint(r, e) case *lnwire.ShortChannelID: var a uint64 diff --git a/channeldb/migration_01_to_11/graph.go b/channeldb/migration_01_to_11/graph.go index 8e9c624d3..0f36a78ed 100644 --- a/channeldb/migration_01_to_11/graph.go +++ b/channeldb/migration_01_to_11/graph.go @@ -836,7 +836,7 @@ func deserializeChanEdgeInfo(r io.Reader) (ChannelEdgeInfo, error) { } edgeInfo.ChannelPoint = wire.OutPoint{} - if err := readOutpoint(r, &edgeInfo.ChannelPoint); err != nil { + if err := ReadOutpoint(r, &edgeInfo.ChannelPoint); err != nil { return ChannelEdgeInfo{}, err } if err := binary.Read(r, byteOrder, &edgeInfo.Capacity); err != nil { diff --git a/channeldb/migration_01_to_11/legacy_serialization.go b/channeldb/migration_01_to_11/legacy_serialization.go index 5d731bff6..f154f1804 100644 --- a/channeldb/migration_01_to_11/legacy_serialization.go +++ b/channeldb/migration_01_to_11/legacy_serialization.go @@ -34,7 +34,7 @@ func deserializeCloseChannelSummaryV6(r io.Reader) (*ChannelCloseSummary, error) return nil, err } - if err := readChanConfig(r, &c.LocalChanConfig); err != nil { + if err := ReadChanConfig(r, &c.LocalChanConfig); err != nil { return nil, err } diff --git a/channeldb/migration_01_to_11/migrations_test.go b/channeldb/migration_01_to_11/migrations_test.go index 5d7f91b88..9c47bdcdf 100644 --- a/channeldb/migration_01_to_11/migrations_test.go +++ b/channeldb/migration_01_to_11/migrations_test.go @@ -203,7 +203,7 @@ func TestMigrateOptionalChannelCloseSummaryFields(t *testing.T) { } var chanPointBuf bytes.Buffer - err = writeOutpoint(&chanPointBuf, &chanState.FundingOutpoint) + err = WriteOutpoint(&chanPointBuf, &chanState.FundingOutpoint) if err != nil { t.Fatalf("unable to write outpoint: %v", err) } @@ -303,7 +303,7 @@ func TestMigrateOptionalChannelCloseSummaryFields(t *testing.T) { t.Fatal(err) } - err = writeChanConfig(&buf, &cs.LocalChanConfig) + err = WriteChanConfig(&buf, &cs.LocalChanConfig) if err != nil { t.Fatal(err) } @@ -354,7 +354,7 @@ func TestMigrateOptionalChannelCloseSummaryFields(t *testing.T) { t.Fatal(err) } - err = writeChanConfig(&buf, &cs.LocalChanConfig) + err = WriteChanConfig(&buf, &cs.LocalChanConfig) if err != nil { t.Fatal(err) }