Skip to content

Commit

Permalink
multi: update channel db HTLC OnionBlob to array
Browse files Browse the repository at this point in the history
We know that onion blobs in lightning are _exactly_ 1366 bytes in
lightning, but they are currently expressed as a byte slice in
channeldb's HTLC struct. Blobs are currently serialized as var bytes,
so we can take advantage of this known length and variable length
to add additional data to the inline serialization of our HTLCs, which
are otherwise not easily extensible (without creating a new bucket).
  • Loading branch information
carlaKC committed Jun 2, 2023
1 parent f9d4600 commit 2fc8e9d
Show file tree
Hide file tree
Showing 9 changed files with 44 additions and 19 deletions.
11 changes: 7 additions & 4 deletions channeldb/channel.go
Original file line number Diff line number Diff line change
Expand Up @@ -2001,15 +2001,15 @@ func (c *OpenChannel) ActiveHtlcs() []HTLC {
// which ones are present on their commitment.
remoteHtlcs := make(map[[32]byte]struct{})
for _, htlc := range c.RemoteCommitment.Htlcs {
onionHash := sha256.Sum256(htlc.OnionBlob)
onionHash := sha256.Sum256(htlc.OnionBlob[:])
remoteHtlcs[onionHash] = struct{}{}
}

// Now that we know which HTLC's they have, we'll only mark the HTLC's
// as active if *we* know them as well.
activeHtlcs := make([]HTLC, 0, len(remoteHtlcs))
for _, htlc := range c.LocalCommitment.Htlcs {
onionHash := sha256.Sum256(htlc.OnionBlob)
onionHash := sha256.Sum256(htlc.OnionBlob[:])
if _, ok := remoteHtlcs[onionHash]; !ok {
continue
}
Expand Down Expand Up @@ -2056,7 +2056,7 @@ type HTLC struct {

// OnionBlob is an opaque blob which is used to complete multi-hop
// routing.
OnionBlob []byte
OnionBlob [lnwire.OnionPacketSize]byte

// HtlcIndex is the HTLC counter index of this active, outstanding
// HTLC. This differs from the LogIndex, as the HtlcIndex is only
Expand Down Expand Up @@ -2113,14 +2113,17 @@ func DeserializeHtlcs(r io.Reader) ([]HTLC, error) {

htlcs = make([]HTLC, numHtlcs)
for i := uint16(0); i < numHtlcs; i++ {
var onionBlob []byte
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].Incoming, &onionBlob,
&htlcs[i].HtlcIndex, &htlcs[i].LogIndex,
); err != nil {
return htlcs, err
}

copy(htlcs[i].OnionBlob[:], onionBlob)
}

return htlcs, nil
Expand Down
14 changes: 9 additions & 5 deletions channeldb/channel_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"github.com/lightningnetwork/lnd/clock"
"github.com/lightningnetwork/lnd/keychain"
"github.com/lightningnetwork/lnd/kvdb"
"github.com/lightningnetwork/lnd/lnmock"
"github.com/lightningnetwork/lnd/lntest/channels"
"github.com/lightningnetwork/lnd/lnwire"
"github.com/lightningnetwork/lnd/shachain"
Expand Down Expand Up @@ -366,12 +367,13 @@ func TestOpenChannelPutGetDelete(t *testing.T) {
// Create the test channel state, with additional htlcs on the local
// and remote commitment.
localHtlcs := []HTLC{
{Signature: testSig.Serialize(),
{
Signature: testSig.Serialize(),
Incoming: true,
Amt: 10,
RHash: key,
RefundTimeout: 1,
OnionBlob: []byte("onionblob"),
OnionBlob: lnmock.MockOnion(),
},
}

Expand All @@ -382,7 +384,7 @@ func TestOpenChannelPutGetDelete(t *testing.T) {
Amt: 10,
RHash: key,
RefundTimeout: 1,
OnionBlob: []byte("onionblob"),
OnionBlob: lnmock.MockOnion(),
},
}

Expand Down Expand Up @@ -612,8 +614,10 @@ func TestChannelStateTransition(t *testing.T) {
LogIndex: uint64(i * 2),
HtlcIndex: uint64(i),
}
htlc.OnionBlob = make([]byte, 10)
copy(htlc.OnionBlob[:], bytes.Repeat([]byte{2}, 10))
copy(
htlc.OnionBlob[:],
bytes.Repeat([]byte{2}, lnwire.OnionPacketSize),
)
htlcs = append(htlcs, htlc)
htlcAmt += htlc.Amt
}
Expand Down
3 changes: 2 additions & 1 deletion contractcourt/briefcase_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"github.com/lightningnetwork/lnd/channeldb"
"github.com/lightningnetwork/lnd/input"
"github.com/lightningnetwork/lnd/kvdb"
"github.com/lightningnetwork/lnd/lnmock"
"github.com/lightningnetwork/lnd/lntest/channels"
"github.com/lightningnetwork/lnd/lnwallet"
"github.com/stretchr/testify/require"
Expand Down Expand Up @@ -745,7 +746,7 @@ func TestCommitSetStorage(t *testing.T) {
activeHTLCs := []channeldb.HTLC{
{
Amt: 1000,
OnionBlob: make([]byte, 0),
OnionBlob: lnmock.MockOnion(),
Signature: make([]byte, 0),
},
}
Expand Down
2 changes: 1 addition & 1 deletion contractcourt/htlc_incoming_contest_resolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -487,7 +487,7 @@ func (h *htlcIncomingContestResolver) Supplement(htlc channeldb.HTLC) {
func (h *htlcIncomingContestResolver) decodePayload() (*hop.Payload,
[]byte, error) {

onionReader := bytes.NewReader(h.htlc.OnionBlob)
onionReader := bytes.NewReader(h.htlc.OnionBlob[:])
iterator, err := h.OnionProcessor.ReconstructHopIterator(
onionReader, h.htlc.RHash[:],
)
Expand Down
7 changes: 4 additions & 3 deletions contractcourt/htlc_incoming_resolver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"github.com/lightningnetwork/lnd/htlcswitch/hop"
"github.com/lightningnetwork/lnd/invoices"
"github.com/lightningnetwork/lnd/kvdb"
"github.com/lightningnetwork/lnd/lnmock"
"github.com/lightningnetwork/lnd/lntest/mock"
"github.com/lightningnetwork/lnd/lntypes"
"github.com/lightningnetwork/lnd/lnwallet"
Expand All @@ -29,7 +30,6 @@ var (
testResPreimage = lntypes.Preimage{1, 2, 3}
testResHash = testResPreimage.Hash()
testResCircuitKey = models.CircuitKey{}
testOnionBlob = []byte{4, 5, 6}
testAcceptHeight int32 = 1234
testHtlcAmount = 2300
)
Expand Down Expand Up @@ -139,8 +139,9 @@ func TestHtlcIncomingResolverExitSettle(t *testing.T) {

ctx.waitForResult(true)

expetedOnion := lnmock.MockOnion()
if !bytes.Equal(
ctx.onionProcessor.offeredOnionBlob, testOnionBlob,
ctx.onionProcessor.offeredOnionBlob, expetedOnion[:],
) {

t.Fatal("unexpected onion blob")
Expand Down Expand Up @@ -375,7 +376,7 @@ func newIncomingResolverTestContext(t *testing.T, isExit bool) *incomingResolver
htlc: channeldb.HTLC{
Amt: lnwire.MilliSatoshi(testHtlcAmount),
RHash: testResHash,
OnionBlob: testOnionBlob,
OnionBlob: lnmock.MockOnion(),
},
},
htlcExpiry: testHtlcExpiry,
Expand Down
3 changes: 2 additions & 1 deletion contractcourt/htlc_outgoing_contest_resolver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"github.com/lightningnetwork/lnd/channeldb"
"github.com/lightningnetwork/lnd/input"
"github.com/lightningnetwork/lnd/kvdb"
"github.com/lightningnetwork/lnd/lnmock"
"github.com/lightningnetwork/lnd/lntest/mock"
"github.com/lightningnetwork/lnd/lntypes"
"github.com/lightningnetwork/lnd/lnwallet"
Expand Down Expand Up @@ -183,7 +184,7 @@ func newOutgoingResolverTestContext(t *testing.T) *outgoingResolverTestContext {
htlc: channeldb.HTLC{
Amt: lnwire.MilliSatoshi(testHtlcAmount),
RHash: testResHash,
OnionBlob: testOnionBlob,
OnionBlob: lnmock.MockOnion(),
},
},
}
Expand Down
3 changes: 2 additions & 1 deletion contractcourt/htlc_success_resolver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"github.com/lightningnetwork/lnd/channeldb"
"github.com/lightningnetwork/lnd/input"
"github.com/lightningnetwork/lnd/kvdb"
"github.com/lightningnetwork/lnd/lnmock"
"github.com/lightningnetwork/lnd/lntest/mock"
"github.com/lightningnetwork/lnd/lnwallet"
"github.com/lightningnetwork/lnd/lnwire"
Expand Down Expand Up @@ -110,7 +111,7 @@ func newHtlcResolverTestContext(t *testing.T,

htlc := channeldb.HTLC{
RHash: testResHash,
OnionBlob: testOnionBlob,
OnionBlob: lnmock.MockOnion(),
Amt: testHtlcAmt,
}

Expand Down
16 changes: 16 additions & 0 deletions lnmock/routing.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package lnmock

import (
"bytes"

"github.com/lightningnetwork/lnd/lnwire"
)

// MockOnion returns a mock onion payload.
func MockOnion() [lnwire.OnionPacketSize]byte {
var onion [lnwire.OnionPacketSize]byte
onionBlob := bytes.Repeat([]byte{1}, lnwire.OnionPacketSize)
copy(onion[:], onionBlob)

return onion
}
4 changes: 1 addition & 3 deletions lnwallet/channel.go
Original file line number Diff line number Diff line change
Expand Up @@ -745,7 +745,6 @@ func (c *commitment) toDiskCommit(ourCommit bool) *channeldb.ChannelCommitment {
LogIndex: htlc.LogIndex,
Incoming: false,
}
h.OnionBlob = make([]byte, len(htlc.OnionBlob))
copy(h.OnionBlob[:], htlc.OnionBlob)

if ourCommit && htlc.sig != nil {
Expand All @@ -770,7 +769,6 @@ func (c *commitment) toDiskCommit(ourCommit bool) *channeldb.ChannelCommitment {
LogIndex: htlc.LogIndex,
Incoming: true,
}
h.OnionBlob = make([]byte, len(htlc.OnionBlob))
copy(h.OnionBlob[:], htlc.OnionBlob)

if ourCommit && htlc.sig != nil {
Expand Down Expand Up @@ -859,7 +857,7 @@ func (lc *LightningChannel) diskHtlcToPayDesc(feeRate chainfee.SatPerKWeight,
EntryType: Add,
HtlcIndex: htlc.HtlcIndex,
LogIndex: htlc.LogIndex,
OnionBlob: htlc.OnionBlob,
OnionBlob: htlc.OnionBlob[:],
localOutputIndex: localOutputIndex,
remoteOutputIndex: remoteOutputIndex,
ourPkScript: ourP2WSH,
Expand Down

0 comments on commit 2fc8e9d

Please sign in to comment.