mirror of
https://github.com/lightningnetwork/lnd.git
synced 2024-11-19 01:43:16 +01:00
multi: update channel db HTLC OnionBlob to array
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).
This commit is contained in:
parent
f9d4600ff8
commit
2fc8e9d617
@ -2001,7 +2001,7 @@ func (c *OpenChannel) ActiveHtlcs() []HTLC {
|
|||||||
// which ones are present on their commitment.
|
// which ones are present on their commitment.
|
||||||
remoteHtlcs := make(map[[32]byte]struct{})
|
remoteHtlcs := make(map[[32]byte]struct{})
|
||||||
for _, htlc := range c.RemoteCommitment.Htlcs {
|
for _, htlc := range c.RemoteCommitment.Htlcs {
|
||||||
onionHash := sha256.Sum256(htlc.OnionBlob)
|
onionHash := sha256.Sum256(htlc.OnionBlob[:])
|
||||||
remoteHtlcs[onionHash] = struct{}{}
|
remoteHtlcs[onionHash] = struct{}{}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2009,7 +2009,7 @@ func (c *OpenChannel) ActiveHtlcs() []HTLC {
|
|||||||
// as active if *we* know them as well.
|
// as active if *we* know them as well.
|
||||||
activeHtlcs := make([]HTLC, 0, len(remoteHtlcs))
|
activeHtlcs := make([]HTLC, 0, len(remoteHtlcs))
|
||||||
for _, htlc := range c.LocalCommitment.Htlcs {
|
for _, htlc := range c.LocalCommitment.Htlcs {
|
||||||
onionHash := sha256.Sum256(htlc.OnionBlob)
|
onionHash := sha256.Sum256(htlc.OnionBlob[:])
|
||||||
if _, ok := remoteHtlcs[onionHash]; !ok {
|
if _, ok := remoteHtlcs[onionHash]; !ok {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -2056,7 +2056,7 @@ type HTLC struct {
|
|||||||
|
|
||||||
// OnionBlob is an opaque blob which is used to complete multi-hop
|
// OnionBlob is an opaque blob which is used to complete multi-hop
|
||||||
// routing.
|
// routing.
|
||||||
OnionBlob []byte
|
OnionBlob [lnwire.OnionPacketSize]byte
|
||||||
|
|
||||||
// HtlcIndex is the HTLC counter index of this active, outstanding
|
// HtlcIndex is the HTLC counter index of this active, outstanding
|
||||||
// HTLC. This differs from the LogIndex, as the HtlcIndex is only
|
// HTLC. This differs from the LogIndex, as the HtlcIndex is only
|
||||||
@ -2113,14 +2113,17 @@ func DeserializeHtlcs(r io.Reader) ([]HTLC, error) {
|
|||||||
|
|
||||||
htlcs = make([]HTLC, numHtlcs)
|
htlcs = make([]HTLC, numHtlcs)
|
||||||
for i := uint16(0); i < numHtlcs; i++ {
|
for i := uint16(0); i < numHtlcs; i++ {
|
||||||
|
var onionBlob []byte
|
||||||
if err := ReadElements(r,
|
if err := ReadElements(r,
|
||||||
&htlcs[i].Signature, &htlcs[i].RHash, &htlcs[i].Amt,
|
&htlcs[i].Signature, &htlcs[i].RHash, &htlcs[i].Amt,
|
||||||
&htlcs[i].RefundTimeout, &htlcs[i].OutputIndex,
|
&htlcs[i].RefundTimeout, &htlcs[i].OutputIndex,
|
||||||
&htlcs[i].Incoming, &htlcs[i].OnionBlob,
|
&htlcs[i].Incoming, &onionBlob,
|
||||||
&htlcs[i].HtlcIndex, &htlcs[i].LogIndex,
|
&htlcs[i].HtlcIndex, &htlcs[i].LogIndex,
|
||||||
); err != nil {
|
); err != nil {
|
||||||
return htlcs, err
|
return htlcs, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
copy(htlcs[i].OnionBlob[:], onionBlob)
|
||||||
}
|
}
|
||||||
|
|
||||||
return htlcs, nil
|
return htlcs, nil
|
||||||
|
@ -19,6 +19,7 @@ import (
|
|||||||
"github.com/lightningnetwork/lnd/clock"
|
"github.com/lightningnetwork/lnd/clock"
|
||||||
"github.com/lightningnetwork/lnd/keychain"
|
"github.com/lightningnetwork/lnd/keychain"
|
||||||
"github.com/lightningnetwork/lnd/kvdb"
|
"github.com/lightningnetwork/lnd/kvdb"
|
||||||
|
"github.com/lightningnetwork/lnd/lnmock"
|
||||||
"github.com/lightningnetwork/lnd/lntest/channels"
|
"github.com/lightningnetwork/lnd/lntest/channels"
|
||||||
"github.com/lightningnetwork/lnd/lnwire"
|
"github.com/lightningnetwork/lnd/lnwire"
|
||||||
"github.com/lightningnetwork/lnd/shachain"
|
"github.com/lightningnetwork/lnd/shachain"
|
||||||
@ -366,12 +367,13 @@ func TestOpenChannelPutGetDelete(t *testing.T) {
|
|||||||
// Create the test channel state, with additional htlcs on the local
|
// Create the test channel state, with additional htlcs on the local
|
||||||
// and remote commitment.
|
// and remote commitment.
|
||||||
localHtlcs := []HTLC{
|
localHtlcs := []HTLC{
|
||||||
{Signature: testSig.Serialize(),
|
{
|
||||||
|
Signature: testSig.Serialize(),
|
||||||
Incoming: true,
|
Incoming: true,
|
||||||
Amt: 10,
|
Amt: 10,
|
||||||
RHash: key,
|
RHash: key,
|
||||||
RefundTimeout: 1,
|
RefundTimeout: 1,
|
||||||
OnionBlob: []byte("onionblob"),
|
OnionBlob: lnmock.MockOnion(),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -382,7 +384,7 @@ func TestOpenChannelPutGetDelete(t *testing.T) {
|
|||||||
Amt: 10,
|
Amt: 10,
|
||||||
RHash: key,
|
RHash: key,
|
||||||
RefundTimeout: 1,
|
RefundTimeout: 1,
|
||||||
OnionBlob: []byte("onionblob"),
|
OnionBlob: lnmock.MockOnion(),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -612,8 +614,10 @@ func TestChannelStateTransition(t *testing.T) {
|
|||||||
LogIndex: uint64(i * 2),
|
LogIndex: uint64(i * 2),
|
||||||
HtlcIndex: uint64(i),
|
HtlcIndex: uint64(i),
|
||||||
}
|
}
|
||||||
htlc.OnionBlob = make([]byte, 10)
|
copy(
|
||||||
copy(htlc.OnionBlob[:], bytes.Repeat([]byte{2}, 10))
|
htlc.OnionBlob[:],
|
||||||
|
bytes.Repeat([]byte{2}, lnwire.OnionPacketSize),
|
||||||
|
)
|
||||||
htlcs = append(htlcs, htlc)
|
htlcs = append(htlcs, htlc)
|
||||||
htlcAmt += htlc.Amt
|
htlcAmt += htlc.Amt
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@ import (
|
|||||||
"github.com/lightningnetwork/lnd/channeldb"
|
"github.com/lightningnetwork/lnd/channeldb"
|
||||||
"github.com/lightningnetwork/lnd/input"
|
"github.com/lightningnetwork/lnd/input"
|
||||||
"github.com/lightningnetwork/lnd/kvdb"
|
"github.com/lightningnetwork/lnd/kvdb"
|
||||||
|
"github.com/lightningnetwork/lnd/lnmock"
|
||||||
"github.com/lightningnetwork/lnd/lntest/channels"
|
"github.com/lightningnetwork/lnd/lntest/channels"
|
||||||
"github.com/lightningnetwork/lnd/lnwallet"
|
"github.com/lightningnetwork/lnd/lnwallet"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
@ -745,7 +746,7 @@ func TestCommitSetStorage(t *testing.T) {
|
|||||||
activeHTLCs := []channeldb.HTLC{
|
activeHTLCs := []channeldb.HTLC{
|
||||||
{
|
{
|
||||||
Amt: 1000,
|
Amt: 1000,
|
||||||
OnionBlob: make([]byte, 0),
|
OnionBlob: lnmock.MockOnion(),
|
||||||
Signature: make([]byte, 0),
|
Signature: make([]byte, 0),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -487,7 +487,7 @@ func (h *htlcIncomingContestResolver) Supplement(htlc channeldb.HTLC) {
|
|||||||
func (h *htlcIncomingContestResolver) decodePayload() (*hop.Payload,
|
func (h *htlcIncomingContestResolver) decodePayload() (*hop.Payload,
|
||||||
[]byte, error) {
|
[]byte, error) {
|
||||||
|
|
||||||
onionReader := bytes.NewReader(h.htlc.OnionBlob)
|
onionReader := bytes.NewReader(h.htlc.OnionBlob[:])
|
||||||
iterator, err := h.OnionProcessor.ReconstructHopIterator(
|
iterator, err := h.OnionProcessor.ReconstructHopIterator(
|
||||||
onionReader, h.htlc.RHash[:],
|
onionReader, h.htlc.RHash[:],
|
||||||
)
|
)
|
||||||
|
@ -13,6 +13,7 @@ import (
|
|||||||
"github.com/lightningnetwork/lnd/htlcswitch/hop"
|
"github.com/lightningnetwork/lnd/htlcswitch/hop"
|
||||||
"github.com/lightningnetwork/lnd/invoices"
|
"github.com/lightningnetwork/lnd/invoices"
|
||||||
"github.com/lightningnetwork/lnd/kvdb"
|
"github.com/lightningnetwork/lnd/kvdb"
|
||||||
|
"github.com/lightningnetwork/lnd/lnmock"
|
||||||
"github.com/lightningnetwork/lnd/lntest/mock"
|
"github.com/lightningnetwork/lnd/lntest/mock"
|
||||||
"github.com/lightningnetwork/lnd/lntypes"
|
"github.com/lightningnetwork/lnd/lntypes"
|
||||||
"github.com/lightningnetwork/lnd/lnwallet"
|
"github.com/lightningnetwork/lnd/lnwallet"
|
||||||
@ -29,7 +30,6 @@ var (
|
|||||||
testResPreimage = lntypes.Preimage{1, 2, 3}
|
testResPreimage = lntypes.Preimage{1, 2, 3}
|
||||||
testResHash = testResPreimage.Hash()
|
testResHash = testResPreimage.Hash()
|
||||||
testResCircuitKey = models.CircuitKey{}
|
testResCircuitKey = models.CircuitKey{}
|
||||||
testOnionBlob = []byte{4, 5, 6}
|
|
||||||
testAcceptHeight int32 = 1234
|
testAcceptHeight int32 = 1234
|
||||||
testHtlcAmount = 2300
|
testHtlcAmount = 2300
|
||||||
)
|
)
|
||||||
@ -139,8 +139,9 @@ func TestHtlcIncomingResolverExitSettle(t *testing.T) {
|
|||||||
|
|
||||||
ctx.waitForResult(true)
|
ctx.waitForResult(true)
|
||||||
|
|
||||||
|
expetedOnion := lnmock.MockOnion()
|
||||||
if !bytes.Equal(
|
if !bytes.Equal(
|
||||||
ctx.onionProcessor.offeredOnionBlob, testOnionBlob,
|
ctx.onionProcessor.offeredOnionBlob, expetedOnion[:],
|
||||||
) {
|
) {
|
||||||
|
|
||||||
t.Fatal("unexpected onion blob")
|
t.Fatal("unexpected onion blob")
|
||||||
@ -375,7 +376,7 @@ func newIncomingResolverTestContext(t *testing.T, isExit bool) *incomingResolver
|
|||||||
htlc: channeldb.HTLC{
|
htlc: channeldb.HTLC{
|
||||||
Amt: lnwire.MilliSatoshi(testHtlcAmount),
|
Amt: lnwire.MilliSatoshi(testHtlcAmount),
|
||||||
RHash: testResHash,
|
RHash: testResHash,
|
||||||
OnionBlob: testOnionBlob,
|
OnionBlob: lnmock.MockOnion(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
htlcExpiry: testHtlcExpiry,
|
htlcExpiry: testHtlcExpiry,
|
||||||
|
@ -9,6 +9,7 @@ import (
|
|||||||
"github.com/lightningnetwork/lnd/channeldb"
|
"github.com/lightningnetwork/lnd/channeldb"
|
||||||
"github.com/lightningnetwork/lnd/input"
|
"github.com/lightningnetwork/lnd/input"
|
||||||
"github.com/lightningnetwork/lnd/kvdb"
|
"github.com/lightningnetwork/lnd/kvdb"
|
||||||
|
"github.com/lightningnetwork/lnd/lnmock"
|
||||||
"github.com/lightningnetwork/lnd/lntest/mock"
|
"github.com/lightningnetwork/lnd/lntest/mock"
|
||||||
"github.com/lightningnetwork/lnd/lntypes"
|
"github.com/lightningnetwork/lnd/lntypes"
|
||||||
"github.com/lightningnetwork/lnd/lnwallet"
|
"github.com/lightningnetwork/lnd/lnwallet"
|
||||||
@ -183,7 +184,7 @@ func newOutgoingResolverTestContext(t *testing.T) *outgoingResolverTestContext {
|
|||||||
htlc: channeldb.HTLC{
|
htlc: channeldb.HTLC{
|
||||||
Amt: lnwire.MilliSatoshi(testHtlcAmount),
|
Amt: lnwire.MilliSatoshi(testHtlcAmount),
|
||||||
RHash: testResHash,
|
RHash: testResHash,
|
||||||
OnionBlob: testOnionBlob,
|
OnionBlob: lnmock.MockOnion(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,7 @@ import (
|
|||||||
"github.com/lightningnetwork/lnd/channeldb"
|
"github.com/lightningnetwork/lnd/channeldb"
|
||||||
"github.com/lightningnetwork/lnd/input"
|
"github.com/lightningnetwork/lnd/input"
|
||||||
"github.com/lightningnetwork/lnd/kvdb"
|
"github.com/lightningnetwork/lnd/kvdb"
|
||||||
|
"github.com/lightningnetwork/lnd/lnmock"
|
||||||
"github.com/lightningnetwork/lnd/lntest/mock"
|
"github.com/lightningnetwork/lnd/lntest/mock"
|
||||||
"github.com/lightningnetwork/lnd/lnwallet"
|
"github.com/lightningnetwork/lnd/lnwallet"
|
||||||
"github.com/lightningnetwork/lnd/lnwire"
|
"github.com/lightningnetwork/lnd/lnwire"
|
||||||
@ -110,7 +111,7 @@ func newHtlcResolverTestContext(t *testing.T,
|
|||||||
|
|
||||||
htlc := channeldb.HTLC{
|
htlc := channeldb.HTLC{
|
||||||
RHash: testResHash,
|
RHash: testResHash,
|
||||||
OnionBlob: testOnionBlob,
|
OnionBlob: lnmock.MockOnion(),
|
||||||
Amt: testHtlcAmt,
|
Amt: testHtlcAmt,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
16
lnmock/routing.go
Normal file
16
lnmock/routing.go
Normal file
@ -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
|
||||||
|
}
|
@ -745,7 +745,6 @@ func (c *commitment) toDiskCommit(ourCommit bool) *channeldb.ChannelCommitment {
|
|||||||
LogIndex: htlc.LogIndex,
|
LogIndex: htlc.LogIndex,
|
||||||
Incoming: false,
|
Incoming: false,
|
||||||
}
|
}
|
||||||
h.OnionBlob = make([]byte, len(htlc.OnionBlob))
|
|
||||||
copy(h.OnionBlob[:], htlc.OnionBlob)
|
copy(h.OnionBlob[:], htlc.OnionBlob)
|
||||||
|
|
||||||
if ourCommit && htlc.sig != nil {
|
if ourCommit && htlc.sig != nil {
|
||||||
@ -770,7 +769,6 @@ func (c *commitment) toDiskCommit(ourCommit bool) *channeldb.ChannelCommitment {
|
|||||||
LogIndex: htlc.LogIndex,
|
LogIndex: htlc.LogIndex,
|
||||||
Incoming: true,
|
Incoming: true,
|
||||||
}
|
}
|
||||||
h.OnionBlob = make([]byte, len(htlc.OnionBlob))
|
|
||||||
copy(h.OnionBlob[:], htlc.OnionBlob)
|
copy(h.OnionBlob[:], htlc.OnionBlob)
|
||||||
|
|
||||||
if ourCommit && htlc.sig != nil {
|
if ourCommit && htlc.sig != nil {
|
||||||
@ -859,7 +857,7 @@ func (lc *LightningChannel) diskHtlcToPayDesc(feeRate chainfee.SatPerKWeight,
|
|||||||
EntryType: Add,
|
EntryType: Add,
|
||||||
HtlcIndex: htlc.HtlcIndex,
|
HtlcIndex: htlc.HtlcIndex,
|
||||||
LogIndex: htlc.LogIndex,
|
LogIndex: htlc.LogIndex,
|
||||||
OnionBlob: htlc.OnionBlob,
|
OnionBlob: htlc.OnionBlob[:],
|
||||||
localOutputIndex: localOutputIndex,
|
localOutputIndex: localOutputIndex,
|
||||||
remoteOutputIndex: remoteOutputIndex,
|
remoteOutputIndex: remoteOutputIndex,
|
||||||
ourPkScript: ourP2WSH,
|
ourPkScript: ourP2WSH,
|
||||||
|
Loading…
Reference in New Issue
Block a user