channeldb: add customized encoding for HtlcIndex
This commit is contained in:
2 files changed
+130
-3
No files matched your search
@@ -2,6 +2,7 @@ package channeldb
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"io"
|
||||
"math"
|
||||
@@ -512,13 +513,22 @@ func deserializeRevocationLog(r io.Reader) (RevocationLog, error) {
|
||||
// deserializeHTLCEntries deserializes a list of HTLC entries based on tlv
|
||||
// format.
|
||||
func deserializeHTLCEntries(r io.Reader) ([]*HTLCEntry, error) {
|
||||
var htlcs []*HTLCEntry
|
||||
var (
|
||||
htlcs []*HTLCEntry
|
||||
|
||||
// htlcIndexBlob defines the tlv record type to be used when
|
||||
// decoding from the disk. We use it instead of the one defined
|
||||
// in `HTLCEntry.HtlcIndex` as previously this field was encoded
|
||||
// using `uint16`, thus we will read it as raw bytes and
|
||||
// deserialize it further below.
|
||||
htlcIndexBlob tlv.OptionalRecordT[tlv.TlvType6, tlv.Blob]
|
||||
)
|
||||
|
||||
for {
|
||||
var htlc HTLCEntry
|
||||
|
||||
customBlob := htlc.CustomBlob.Zero()
|
||||
htlcIndex := htlc.HtlcIndex.Zero()
|
||||
htlcIndex := htlcIndexBlob.Zero()
|
||||
|
||||
// Create the tlv stream.
|
||||
records := []tlv.Record{
|
||||
@@ -551,7 +561,14 @@ func deserializeHTLCEntries(r io.Reader) ([]*HTLCEntry, error) {
|
||||
}
|
||||
|
||||
if t, ok := parsedTypes[htlcIndex.TlvType()]; ok && t == nil {
|
||||
htlc.HtlcIndex = tlv.SomeRecordT(htlcIndex)
|
||||
record, err := deserializeHtlcIndexCompatible(
|
||||
htlcIndex.Val,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
htlc.HtlcIndex = record
|
||||
}
|
||||
|
||||
// Append the entry.
|
||||
@@ -561,6 +578,55 @@ func deserializeHTLCEntries(r io.Reader) ([]*HTLCEntry, error) {
|
||||
return htlcs, nil
|
||||
}
|
||||
|
||||
// deserializeHtlcIndexCompatible takes raw bytes and decodes it into an
|
||||
// optional record that's assigned to the entry's HtlcIndex.
|
||||
//
|
||||
// NOTE: previously this `HtlcIndex` was a tlv record that used `uint16` to
|
||||
// encode its value. Given now its value is encoded using BigSizeT, and for any
|
||||
// BigSizeT, its possible length values are 1, 3, 5, and 8. This means if the
|
||||
// tlv record has a length of 2, we know for sure it must be an old record
|
||||
// whose value was encoded using uint16.
|
||||
func deserializeHtlcIndexCompatible(rawBytes []byte) (
|
||||
tlv.OptionalRecordT[tlv.TlvType6, tlv.BigSizeT[uint64]], error) {
|
||||
|
||||
var (
|
||||
// record defines the record that's used by the HtlcIndex in the
|
||||
// entry.
|
||||
record tlv.OptionalRecordT[
|
||||
tlv.TlvType6, tlv.BigSizeT[uint64],
|
||||
]
|
||||
|
||||
// htlcIndexVal is the decoded uint64 value.
|
||||
htlcIndexVal uint64
|
||||
)
|
||||
|
||||
// If the length of the tlv record is 2, it must be encoded using uint16
|
||||
// as the BigSizeT encoding cannot have this length.
|
||||
if len(rawBytes) == 2 {
|
||||
// Decode the raw bytes into uint16 and convert it into uint64.
|
||||
htlcIndexVal = uint64(binary.BigEndian.Uint16(rawBytes))
|
||||
} else {
|
||||
// This value is encoded using BigSizeT, we now use the decoder
|
||||
// to deserialize the raw bytes.
|
||||
r := bytes.NewBuffer(rawBytes)
|
||||
|
||||
// Create a buffer to be used in the decoding process.
|
||||
buf := [8]byte{}
|
||||
|
||||
// Use the BigSizeT's decoder.
|
||||
err := tlv.DBigSize(r, &htlcIndexVal, &buf, 8)
|
||||
if err != nil {
|
||||
return record, err
|
||||
}
|
||||
}
|
||||
|
||||
record = tlv.SomeRecordT(tlv.NewRecordT[tlv.TlvType6](
|
||||
tlv.NewBigSizeT(htlcIndexVal),
|
||||
))
|
||||
|
||||
return record, nil
|
||||
}
|
||||
|
||||
// writeTlvStream is a helper function that encodes the tlv stream into the
|
||||
// writer.
|
||||
func writeTlvStream(w io.Writer, s *tlv.Stream) error {
|
||||
|
||||
Reference in new issue
Block a user