mirror of
https://github.com/luxfi/threshold.git
synced 2026-10-30 15:15:53 +00:00
225 lines
5.2 KiB
Go
225 lines
5.2 KiB
Go
package keygen_test
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
"time"
|
|
|
|
log "github.com/luxfi/log"
|
|
"github.com/luxfi/metric"
|
|
"github.com/luxfi/threshold/internal/test"
|
|
"github.com/luxfi/threshold/pkg/math/curve"
|
|
"github.com/luxfi/threshold/pkg/party"
|
|
"github.com/luxfi/threshold/pkg/pool"
|
|
"github.com/luxfi/threshold/pkg/protocol"
|
|
"github.com/luxfi/threshold/protocols/lss"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestLSSKeygenSpecificWithTimeout(t *testing.T) {
|
|
// Test LSS keygen specifically with timeout
|
|
n := 3
|
|
threshold := 2
|
|
partyIDs := test.PartyIDs(n)
|
|
group := curve.Secp256k1{}
|
|
pl := pool.NewPool(0)
|
|
defer pl.TearDown()
|
|
|
|
// Test with controlled timeout
|
|
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
|
|
defer cancel()
|
|
|
|
logger := log.NewTestLogger(log.InfoLevel)
|
|
sessionID := []byte("test-lss-keygen-specific")
|
|
config := protocol.DefaultConfig()
|
|
|
|
// Create handlers for each party
|
|
handlers := make([]*protocol.Handler, n)
|
|
for i, id := range partyIDs {
|
|
h, err := protocol.NewHandler(ctx, logger, metric.NewRegistry(),
|
|
lss.Keygen(group, id, partyIDs, threshold, pl), sessionID, config)
|
|
if err != nil {
|
|
t.Logf("Error creating handler for party %s: %v", id, err)
|
|
continue
|
|
}
|
|
handlers[i] = h
|
|
}
|
|
|
|
// Count successful handlers
|
|
successCount := 0
|
|
for _, h := range handlers {
|
|
if h != nil {
|
|
successCount++
|
|
}
|
|
}
|
|
|
|
t.Logf("Successfully created %d/%d handlers", successCount, n)
|
|
assert.True(t, successCount > 0, "At least one handler should be created")
|
|
|
|
// Run a simple message exchange test
|
|
done := make(chan bool, 1)
|
|
go func() {
|
|
defer func() {
|
|
if r := recover(); r != nil {
|
|
t.Logf("Protocol execution panicked: %v", r)
|
|
}
|
|
done <- true
|
|
}()
|
|
|
|
// Just check that handlers can start
|
|
for _, h := range handlers {
|
|
if h != nil {
|
|
// Try to get a message
|
|
select {
|
|
case msg := <-h.Listen():
|
|
if msg != nil {
|
|
t.Logf("Got message from handler")
|
|
}
|
|
case <-time.After(100 * time.Millisecond):
|
|
// Timeout is ok
|
|
}
|
|
}
|
|
}
|
|
}()
|
|
|
|
select {
|
|
case <-done:
|
|
t.Log("Message exchange test completed")
|
|
case <-ctx.Done():
|
|
t.Log("Test timed out (expected)")
|
|
}
|
|
}
|
|
|
|
func TestLSSKeygenInitOnly(t *testing.T) {
|
|
// Test just initialization without protocol execution
|
|
testCases := []struct {
|
|
n int
|
|
threshold int
|
|
name string
|
|
}{
|
|
{3, 2, "3-party"},
|
|
{5, 3, "5-party"},
|
|
{7, 4, "7-party"},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
partyIDs := test.PartyIDs(tc.n)
|
|
group := curve.Secp256k1{}
|
|
pl := pool.NewPool(0)
|
|
defer pl.TearDown()
|
|
|
|
// Just test that we can create the protocol
|
|
for _, id := range partyIDs {
|
|
keygen := lss.Keygen(group, id, partyIDs, tc.threshold, pl)
|
|
require.NotNil(t, keygen, "Keygen should be created for party %s", id)
|
|
}
|
|
|
|
t.Logf("Successfully initialized %d-of-%d keygen", tc.threshold, tc.n)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestLSSKeygenRoundProgression(t *testing.T) {
|
|
// Test round progression without full execution
|
|
n := 3
|
|
threshold := 2
|
|
partyIDs := test.PartyIDs(n)
|
|
group := curve.Secp256k1{}
|
|
pl := pool.NewPool(0)
|
|
defer pl.TearDown()
|
|
|
|
// Create a single handler to test
|
|
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
|
|
defer cancel()
|
|
|
|
logger := log.NewTestLogger(log.InfoLevel)
|
|
sessionID := []byte("test-round-progression")
|
|
config := protocol.DefaultConfig()
|
|
|
|
h, err := protocol.NewHandler(ctx, logger, metric.NewRegistry(),
|
|
lss.Keygen(group, partyIDs[0], partyIDs, threshold, pl), sessionID, config)
|
|
|
|
require.NoError(t, err, "Handler should be created")
|
|
require.NotNil(t, h, "Handler should not be nil")
|
|
|
|
// Check that handler is ready
|
|
done := make(chan bool, 1)
|
|
|
|
go func() {
|
|
defer func() {
|
|
if r := recover(); r != nil {
|
|
t.Logf("Handler test panicked: %v", r)
|
|
}
|
|
done <- true
|
|
}()
|
|
|
|
// Try to get initial messages
|
|
select {
|
|
case msg := <-h.Listen():
|
|
if msg != nil {
|
|
t.Logf("Handler produced initial message for round %d", msg.RoundNumber)
|
|
}
|
|
case <-time.After(500 * time.Millisecond):
|
|
t.Log("No initial message (may be waiting for input)")
|
|
}
|
|
}()
|
|
|
|
select {
|
|
case <-done:
|
|
t.Log("Round progression test completed")
|
|
case <-ctx.Done():
|
|
t.Log("Round progression test timed out (expected)")
|
|
}
|
|
}
|
|
|
|
func TestLSSKeygenConcurrentInit(t *testing.T) {
|
|
// Test concurrent initialization
|
|
n := 5
|
|
threshold := 3
|
|
partyIDs := test.PartyIDs(n)
|
|
group := curve.Secp256k1{}
|
|
pl := pool.NewPool(0)
|
|
defer pl.TearDown()
|
|
|
|
// Initialize concurrently
|
|
done := make(chan bool, n)
|
|
errors := make(chan error, n)
|
|
|
|
for _, id := range partyIDs {
|
|
go func(partyID party.ID) {
|
|
defer func() {
|
|
if r := recover(); r != nil {
|
|
errors <- assert.AnError
|
|
}
|
|
done <- true
|
|
}()
|
|
|
|
keygen := lss.Keygen(group, partyID, partyIDs, threshold, pl)
|
|
if keygen == nil {
|
|
errors <- assert.AnError
|
|
}
|
|
}(id)
|
|
}
|
|
|
|
// Wait for all goroutines
|
|
successCount := 0
|
|
errorCount := 0
|
|
|
|
for i := 0; i < n; i++ {
|
|
select {
|
|
case <-done:
|
|
successCount++
|
|
case <-errors:
|
|
errorCount++
|
|
case <-time.After(2 * time.Second):
|
|
t.Log("Concurrent init timed out")
|
|
return
|
|
}
|
|
}
|
|
|
|
t.Logf("Concurrent init: %d succeeded, %d failed", successCount, errorCount)
|
|
assert.True(t, successCount > 0, "At least one concurrent init should succeed")
|
|
}
|