Skip to content

Commit 741b081

Browse files
committed
rfqmsg: shift SCID alias into custom range
A recent change to the lnd SCID alias RPCs requires us to generate SCID aliases in a certain range. Because we derive the alias from the randomly generated RFQ ID, we need to do some shifting arithmetic to arrive at an acceptable alias.
1 parent 4da20cd commit 741b081

File tree

2 files changed

+151
-1
lines changed

2 files changed

+151
-1
lines changed

rfqmsg/messages.go

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"io"
99
"math"
1010

11+
"github.com/lightningnetwork/lnd/aliasmgr"
1112
"github.com/lightningnetwork/lnd/lnwire"
1213
"github.com/lightningnetwork/lnd/routing/route"
1314
"github.com/lightningnetwork/lnd/tlv"
@@ -32,7 +33,27 @@ func (id ID) Scid() SerialisedScid {
3233
scidBytes := id[24:]
3334

3435
scidInteger := binary.BigEndian.Uint64(scidBytes)
35-
return SerialisedScid(scidInteger)
36+
37+
// We need to make sure the block height is within the range of valid
38+
// SCID block heights.
39+
scid := lnwire.NewShortChanIDFromInt(scidInteger)
40+
41+
minBlock := uint32(aliasmgr.AliasStartBlockHeight)
42+
maxBlock := uint32(aliasmgr.AliasEndBlockHeight)
43+
44+
// If we're within the valid range, we can return the SCID as is.
45+
if aliasmgr.IsAlias(scid) {
46+
return SerialisedScid(scid.ToUint64())
47+
}
48+
49+
// Normalize the value relative to min, then wrap within blockRange, and
50+
// finally shift back by min. Generated by ChatGPT and I couldn't find a
51+
// better way to do this.
52+
blockRange := maxBlock - minBlock + 1
53+
scid.BlockHeight = ((scid.BlockHeight-minBlock)%blockRange+blockRange)%
54+
blockRange + minBlock
55+
56+
return SerialisedScid(scid.ToUint64())
3657
}
3758

3859
// Record returns a TLV record that can be used to encode/decode an ID to/from a

rfqmsg/messages_test.go

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
package rfqmsg
2+
3+
import (
4+
"encoding/binary"
5+
"testing"
6+
7+
"github.com/lightningnetwork/lnd/aliasmgr"
8+
"github.com/lightningnetwork/lnd/lnwire"
9+
"github.com/stretchr/testify/require"
10+
)
11+
12+
func intToID(scid uint64) ID {
13+
var id ID
14+
binary.BigEndian.PutUint64(id[24:], scid)
15+
return id
16+
}
17+
18+
func shortChannelIDToID(scid lnwire.ShortChannelID) ID {
19+
return intToID(scid.ToUint64())
20+
}
21+
22+
// TestIDSerializedScid tests that an RFQ ID can be correctly converted into a
23+
// custom SCID alias that lies within the valid SCID block height range.
24+
func TestIDSerializedScid(t *testing.T) {
25+
tests := []struct {
26+
id ID
27+
expected lnwire.ShortChannelID
28+
}{
29+
{
30+
id: intToID(123456),
31+
expected: lnwire.ShortChannelID{
32+
BlockHeight: 16200181,
33+
TxIndex: 1,
34+
TxPosition: 57920,
35+
},
36+
},
37+
{
38+
id: intToID(0),
39+
expected: lnwire.ShortChannelID{
40+
BlockHeight: 16200181,
41+
},
42+
},
43+
{
44+
id: shortChannelIDToID(lnwire.ShortChannelID{
45+
BlockHeight: uint32(
46+
aliasmgr.AliasStartBlockHeight,
47+
),
48+
}),
49+
expected: lnwire.ShortChannelID{
50+
BlockHeight: uint32(
51+
aliasmgr.AliasStartBlockHeight,
52+
),
53+
},
54+
},
55+
{
56+
id: intToID(1),
57+
expected: lnwire.ShortChannelID{
58+
BlockHeight: 16200181,
59+
TxPosition: 1,
60+
},
61+
},
62+
{
63+
id: intToID(123456789),
64+
expected: lnwire.ShortChannelID{
65+
BlockHeight: 16200181,
66+
TxIndex: 1883,
67+
TxPosition: 52501,
68+
},
69+
},
70+
{
71+
id: shortChannelIDToID(lnwire.ShortChannelID{
72+
BlockHeight: uint32(
73+
aliasmgr.AliasEndBlockHeight + 1,
74+
),
75+
TxIndex: 123,
76+
TxPosition: 123,
77+
}),
78+
expected: lnwire.ShortChannelID{
79+
BlockHeight: uint32(
80+
aliasmgr.AliasStartBlockHeight,
81+
),
82+
TxIndex: 123,
83+
TxPosition: 123,
84+
},
85+
},
86+
{
87+
id: shortChannelIDToID(lnwire.ShortChannelID{
88+
BlockHeight: 10561306,
89+
TxIndex: 5698083,
90+
TxPosition: 53702,
91+
}),
92+
expected: lnwire.ShortChannelID{
93+
BlockHeight: 16011444,
94+
TxIndex: 5698083,
95+
TxPosition: 53702,
96+
},
97+
},
98+
{
99+
id: ID{
100+
0xd3, 0x62, 0x2a, 0xa3, 0x9b, 0x51, 0x53, 0x88,
101+
0x84, 0x2a, 0xa9, 0x78, 0x40, 0x65, 0xb3, 0x15,
102+
0x80, 0x56, 0xb3, 0x09, 0x80, 0xeb, 0xbb, 0x50,
103+
0xb8, 0xdf, 0x1a, 0x56, 0xf2, 0x23, 0xd1, 0xc6,
104+
},
105+
expected: lnwire.ShortChannelID{
106+
BlockHeight: 16065870,
107+
TxIndex: 5698083,
108+
TxPosition: 53702,
109+
},
110+
},
111+
}
112+
113+
for idx, test := range tests {
114+
t.Logf("Running test #%d", idx)
115+
scid := test.id.Scid()
116+
shortChanID := lnwire.NewShortChanIDFromInt(uint64(scid))
117+
require.Equal(t, test.expected, shortChanID)
118+
119+
require.GreaterOrEqual(
120+
t, shortChanID.BlockHeight,
121+
uint32(aliasmgr.AliasStartBlockHeight),
122+
)
123+
require.Less(
124+
t, shortChanID.BlockHeight,
125+
uint32(aliasmgr.AliasEndBlockHeight),
126+
)
127+
require.True(t, aliasmgr.IsAlias(shortChanID))
128+
}
129+
}

0 commit comments

Comments
 (0)