Skip to content

Commit ccefbea

Browse files
committed
rfqmsg: generate ID for 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 make sure we derive a random ID that can be successfully transformed into a valid SCID alias.
1 parent cb7520e commit ccefbea

File tree

4 files changed

+61
-8
lines changed

4 files changed

+61
-8
lines changed

rfqmsg/buy_request.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package rfqmsg
22

33
import (
4-
"crypto/rand"
54
"fmt"
65

76
"github.com/btcsuite/btcd/btcec/v2"
@@ -49,8 +48,7 @@ func NewBuyRequest(peer route.Vertex, assetID *asset.ID,
4948
assetGroupKey *btcec.PublicKey, assetAmount uint64,
5049
bidPrice lnwire.MilliSatoshi) (*BuyRequest, error) {
5150

52-
var id [32]byte
53-
_, err := rand.Read(id[:])
51+
id, err := NewID()
5452
if err != nil {
5553
return nil, fmt.Errorf("unable to generate random "+
5654
"quote request id: %w", err)

rfqmsg/messages.go

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
package rfqmsg
22

33
import (
4+
"crypto/rand"
45
"crypto/sha256"
56
"encoding/binary"
67
"encoding/hex"
78
"errors"
89
"io"
910
"math"
1011

12+
"github.com/lightningnetwork/lnd/aliasmgr"
1113
"github.com/lightningnetwork/lnd/lnwire"
1214
"github.com/lightningnetwork/lnd/routing/route"
1315
"github.com/lightningnetwork/lnd/tlv"
@@ -16,9 +18,45 @@ import (
1618
// SerialisedScid is a serialised short channel id (SCID).
1719
type SerialisedScid uint64
1820

19-
// ID is the identifier for a RFQ message.
21+
// ID is the identifier for a RFQ message. A new ID _MUST_ be created using the
22+
// NewID constructor to make sure it can be transformed into a valid SCID alias.
2023
type ID [32]byte
2124

25+
// NewID generates a new random ID that can be transformed into a valid SCID
26+
// alias that is in the allowed range for lnd.
27+
func NewID() (ID, error) {
28+
// We make sure we don't loop endlessly in case we can't find a valid
29+
// ID. We should never reach this limit in practice, the chances for
30+
// finding a valid ID are very high.
31+
const maxNumTries = 10e6
32+
var (
33+
id ID
34+
numTries int
35+
)
36+
37+
for {
38+
_, err := rand.Read(id[:])
39+
if err != nil {
40+
return id, err
41+
}
42+
43+
// We make sure that when deriving the SCID alias from the ID,
44+
// we get a valid alias. If not, we try again.
45+
scid := lnwire.NewShortChanIDFromInt(uint64(id.Scid()))
46+
if aliasmgr.IsAlias(scid) {
47+
break
48+
}
49+
50+
numTries++
51+
52+
if numTries >= maxNumTries {
53+
return id, errors.New("unable to find valid ID")
54+
}
55+
}
56+
57+
return id, nil
58+
}
59+
2260
// String returns the string representation of the ID.
2361
func (id ID) String() string {
2462
return hex.EncodeToString(id[:])
@@ -32,7 +70,9 @@ func (id ID) Scid() SerialisedScid {
3270
scidBytes := id[24:]
3371

3472
scidInteger := binary.BigEndian.Uint64(scidBytes)
35-
return SerialisedScid(scidInteger)
73+
scid := lnwire.NewShortChanIDFromInt(scidInteger)
74+
75+
return SerialisedScid(scid.ToUint64())
3676
}
3777

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

rfqmsg/messages_test.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package rfqmsg
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/require"
7+
)
8+
9+
// TestNewID tests that we can easily derive 1000 new IDs without any errors.
10+
func TestNewID(t *testing.T) {
11+
const numIDs = 1000
12+
13+
for range numIDs {
14+
_, err := NewID()
15+
require.NoError(t, err)
16+
}
17+
}

rfqmsg/sell_request.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package rfqmsg
22

33
import (
4-
"crypto/rand"
54
"fmt"
65

76
"github.com/btcsuite/btcd/btcec/v2"
@@ -53,8 +52,7 @@ func NewSellRequest(peer route.Vertex, assetID *asset.ID,
5352
assetGroupKey *btcec.PublicKey, assetAmount uint64,
5453
askPrice lnwire.MilliSatoshi) (*SellRequest, error) {
5554

56-
var id [32]byte
57-
_, err := rand.Read(id[:])
55+
id, err := NewID()
5856
if err != nil {
5957
return nil, fmt.Errorf("unable to generate random id: %w", err)
6058
}

0 commit comments

Comments
 (0)