Skip to content

Commit c3d5d59

Browse files
committed
tapchannel: add test to derive limits
This test attempts to find out what the maximum number of HTLC signatures we can pack into a CommitSig message is. This number depends on the number of different fungible asset pieces (asset IDs) we have, as we need to provide a signature for each piece. The resulting values are: aux_leaf_signer_test.go:111: Last valid commit sig msg size with: numAssetIDs=0, numHTLCs=966 aux_leaf_signer_test.go:103: Last valid commit sig msg size with: numAssetIDs=1, numHTLCs=373 aux_leaf_signer_test.go:103: Last valid commit sig msg size with: numAssetIDs=2, numHTLCs=231 aux_leaf_signer_test.go:103: Last valid commit sig msg size with: numAssetIDs=3, numHTLCs=166 aux_leaf_signer_test.go:103: Last valid commit sig msg size with: numAssetIDs=4, numHTLCs=130 aux_leaf_signer_test.go:103: Last valid commit sig msg size with: numAssetIDs=5, numHTLCs=107 aux_leaf_signer_test.go:103: Last valid commit sig msg size with: numAssetIDs=6, numHTLCs=91 aux_leaf_signer_test.go:103: Last valid commit sig msg size with: numAssetIDs=7, numHTLCs=79 aux_leaf_signer_test.go:103: Last valid commit sig msg size with: numAssetIDs=8, numHTLCs=70 aux_leaf_signer_test.go:103: Last valid commit sig msg size with: numAssetIDs=9, numHTLCs=63 aux_leaf_signer_test.go:103: Last valid commit sig msg size with: numAssetIDs=10, numHTLCs=57
1 parent 5f1e5b7 commit c3d5d59

File tree

1 file changed

+166
-0
lines changed

1 file changed

+166
-0
lines changed

tapchannel/aux_leaf_signer_test.go

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
package tapchannel
2+
3+
import (
4+
"bytes"
5+
"crypto/rand"
6+
"encoding/hex"
7+
"fmt"
8+
"testing"
9+
10+
"github.com/btcsuite/btcd/btcec/v2"
11+
"github.com/btcsuite/btcd/btcec/v2/ecdsa"
12+
"github.com/btcsuite/btcd/txscript"
13+
"github.com/lightninglabs/taproot-assets/asset"
14+
cmsg "github.com/lightninglabs/taproot-assets/tapchannelmsg"
15+
"github.com/lightningnetwork/lnd/input"
16+
"github.com/lightningnetwork/lnd/lnwire"
17+
"github.com/lightningnetwork/lnd/tlv"
18+
"github.com/stretchr/testify/require"
19+
)
20+
21+
// Some of these test values and functions are from lnd's lnwire/lnwire_test.go.
22+
var (
23+
testRBytes, _ = hex.DecodeString(
24+
"8ce2bc69281ce27da07e6683571319d18e949ddfa2965fb6caa1bf0314f8" +
25+
"82d7",
26+
)
27+
testSBytes, _ = hex.DecodeString(
28+
"299105481d63e0f4bc2a88121167221b6700d72a0ead154c03be696a292d" +
29+
"24ae",
30+
)
31+
testRScalar = new(btcec.ModNScalar)
32+
testSScalar = new(btcec.ModNScalar)
33+
_ = testRScalar.SetByteSlice(testRBytes)
34+
_ = testSScalar.SetByteSlice(testSBytes)
35+
testSig = ecdsa.NewSignature(testRScalar, testSScalar)
36+
37+
testSchnorrSigStr, _ = hex.DecodeString(
38+
"04e7f9037658a92afeb4f25bae5339e3ddca81a353493827d26f16d92308" +
39+
"e49e2a25e92208678a2df86970da91b03a8af8815a8a60498b35" +
40+
"8daf560b347aa557",
41+
)
42+
testSchnorrSig, _ = lnwire.NewSigFromSchnorrRawSignature(
43+
testSchnorrSigStr,
44+
)
45+
46+
minNumHTLCs = 5
47+
maxNumHTLCs = input.MaxHTLCNumber
48+
)
49+
50+
func randPartialSigWithNonce() (*lnwire.PartialSigWithNonce, error) {
51+
var sigBytes [32]byte
52+
if _, err := rand.Read(sigBytes[:]); err != nil {
53+
return nil, fmt.Errorf("unable to generate sig: %w", err)
54+
}
55+
56+
var s btcec.ModNScalar
57+
s.SetByteSlice(sigBytes[:])
58+
59+
var nonce lnwire.Musig2Nonce
60+
if _, err := rand.Read(nonce[:]); err != nil {
61+
return nil, fmt.Errorf("unable to generate nonce: %w", err)
62+
}
63+
64+
return &lnwire.PartialSigWithNonce{
65+
PartialSig: lnwire.NewPartialSig(s),
66+
Nonce: nonce,
67+
}, nil
68+
}
69+
70+
func somePartialSigWithNonce(t *testing.T) lnwire.OptPartialSigWithNonceTLV {
71+
sig, err := randPartialSigWithNonce()
72+
if err != nil {
73+
t.Fatal(err)
74+
}
75+
76+
return tlv.SomeRecordT(tlv.NewRecordT[
77+
lnwire.PartialSigWithNonceType,
78+
lnwire.PartialSigWithNonce,
79+
](*sig))
80+
}
81+
82+
// TestMaxCommitSigMsgSize attempts to find values for the max number of asset
83+
// IDs we want to allow per channel and the resulting maximum number of HTLCs
84+
// that channel can allow. The maximum number of different asset IDs that can be
85+
// committed to a channel directly impacts the number of HTLCs that can be
86+
// created on that channel, because we have a limited message size to exchange
87+
// the second-stage HTLC signatures. The goal of this test is to find the right
88+
// number of asset IDs we should allow per channel to still give us a reasonable
89+
// amount of HTLCs.
90+
func TestMaxCommitSigMsgSize(t *testing.T) {
91+
const maxNumAssetIDs = 10
92+
93+
var buf bytes.Buffer
94+
for numID := 0; numID <= maxNumAssetIDs; numID++ {
95+
for numHTLC := minNumHTLCs; numHTLC <= maxNumHTLCs; numHTLC++ {
96+
buf.Reset()
97+
98+
msg := makeCommitSig(t, numID, numHTLC)
99+
err := msg.Encode(&buf, 0)
100+
require.NoError(t, err)
101+
102+
if buf.Len() > lnwire.MaxMsgBody {
103+
t.Logf("Last valid commit sig msg size with: "+
104+
"numAssetIDs=%d, numHTLCs=%d",
105+
numID, numHTLC-1)
106+
107+
break
108+
}
109+
110+
if numHTLC == maxNumHTLCs {
111+
t.Logf("Last valid commit sig msg size with: "+
112+
"numAssetIDs=%d, numHTLCs=%d",
113+
numID, numHTLC)
114+
}
115+
}
116+
}
117+
}
118+
119+
func makeCommitSig(t *testing.T, numAssetIDs, numHTLCs int) *lnwire.CommitSig {
120+
var (
121+
msg = &lnwire.CommitSig{
122+
HtlcSigs: make([]lnwire.Sig, numHTLCs),
123+
}
124+
err error
125+
)
126+
127+
// Static values that are always set for custom channels (which are
128+
// Taproot channels, so have an all-zero legacy commit signature and a
129+
// partial MuSig2 signature).
130+
msg.PartialSig = somePartialSigWithNonce(t)
131+
msg.CommitSig, err = lnwire.NewSigFromSignature(testSig)
132+
require.NoError(t, err)
133+
134+
assetSigs := make([][]*cmsg.AssetSig, numHTLCs)
135+
for i := range numHTLCs {
136+
msg.HtlcSigs[i] = testSchnorrSig
137+
138+
assetSigs[i] = make([]*cmsg.AssetSig, numAssetIDs)
139+
for j := range numAssetIDs {
140+
var assetID asset.ID
141+
142+
_, err := rand.Read(assetID[:])
143+
require.NoError(t, err)
144+
145+
assetSigs[i][j] = cmsg.NewAssetSig(
146+
assetID, testSchnorrSig, txscript.SigHashAll,
147+
)
148+
}
149+
}
150+
151+
if numAssetIDs == 0 {
152+
return msg
153+
}
154+
155+
commitSig := cmsg.NewCommitSig(assetSigs)
156+
157+
var buf bytes.Buffer
158+
err = commitSig.Encode(&buf)
159+
require.NoError(t, err)
160+
161+
msg.CustomRecords = lnwire.CustomRecords{
162+
65543: buf.Bytes(),
163+
}
164+
165+
return msg
166+
}

0 commit comments

Comments
 (0)