Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions node/cmd/guardiand/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,7 @@ var (
guardianKeyPath *string
guardianSignerUri *string

tssSecretsPath *string
tssNetworkSocketPath *string
tssSecretsPath *string

ethRPC *string
ethContract *string
Expand Down Expand Up @@ -326,7 +325,6 @@ func init() {
fogoShimContract = NodeCmd.Flags().String("fogoShimContract", "", "Address of the Fogo shim program")

tssSecretsPath = NodeCmd.Flags().String("tssSecret", "", "Path to guardian tss secrets (required)")
tssNetworkSocketPath = NodeCmd.Flags().String("tssNetworkPort", "[::]:8998", "Listen address for TSS server")

ethRPC = node.RegisterFlagWithValidationOrFail(NodeCmd, "ethRPC", "Ethereum RPC URL", "ws://eth-devnet:8545", []string{"ws", "wss"})
ethContract = NodeCmd.Flags().String("ethContract", "", "Ethereum contract address")
Expand Down Expand Up @@ -1919,7 +1917,7 @@ func runNode(cmd *cobra.Command, args []string) {
node.GuardianOptionStatusServer(*statusAddr),
node.GuardianOptionAlternatePublisher(guardianAddrAsBytes, *additionalPublishers),
node.GuardianOptionProcessor(*p2pNetworkID),
node.GuardianOptionTSSNetwork(*tssNetworkSocketPath),
node.GuardianOptionTSSNetwork(),

// Keep this last so that all of its dependencies are met.
node.GuardianOptionP2P(
Expand Down
2 changes: 1 addition & 1 deletion node/pkg/node/node_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ func mockGuardianRunnable(t testing.TB, gs []*mockGuardian, mockGuardianIndex ui
GuardianOptionAlternatePublisher([]byte{}, []string{}), // disable alternate publisher
GuardianOptionProcessor(networkID),

GuardianOptionTSSNetwork(fmt.Sprintf("[::]:%d", cfg.tssNetworkPort)),
GuardianOptionTSSNetwork(),

// Keep this last so that all of its dependencies are met.
GuardianOptionP2P(gs[mockGuardianIndex].p2pKey, networkID, bootstrapPeers, nodeName, informOnNewVAAs, false, cfg.p2pPort, "", 0, "", "", false, []string{}, []string{}, []string{}),
Expand Down
6 changes: 2 additions & 4 deletions node/pkg/node/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -662,15 +662,13 @@ func GuardianOptionProcessor(networkId string) *GuardianOption {
}}
}

func GuardianOptionTSSNetwork(
socketPath string,
) *GuardianOption {
func GuardianOptionTSSNetwork() *GuardianOption {
serviceName := "tsscomm"
return &GuardianOption{
name: serviceName,
dependencies: []string{"processor"}, // TODO: I think it is dependant on it, since the TSS passes its signatures to the processor.
f: func(_ context.Context, logger *zap.Logger, g *G) error {
srvr, err := tsscomm.NewServer(socketPath, logger.Named(serviceName), g.tssEngine)
srvr, err := tsscomm.NewServer(logger.Named(serviceName), g.tssEngine)
if err != nil {
return fmt.Errorf("failed to create tsscomm server: %w", err)
}
Expand Down
38 changes: 37 additions & 1 deletion node/pkg/tss/comm/runnable.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ import (
"context"
"crypto/tls"
"crypto/x509"
"errors"
"fmt"
"net"
"strconv"

tsscommv1 "github.com/certusone/wormhole/node/pkg/proto/tsscomm/v1"
"github.com/certusone/wormhole/node/pkg/tss"
Expand All @@ -27,7 +29,41 @@ type DirectLink interface {
WaitForConnections(ctx context.Context) error
}

func NewServer(socketPath string, logger *zap.Logger, tssMessenger tss.ReliableMessenger) (DirectLink, error) {
func NewServer(logger *zap.Logger, tssMessenger tss.ReliableMessenger) (DirectLink, error) {
cert := tssMessenger.GetCertificate()
if cert == nil {
return nil, errors.New("tssMessenger returned nil certificate")
}

selfID, err := tssMessenger.FetchIdentity(cert.Leaf)
Comment thread
jonathanMweiss marked this conversation as resolved.
if err != nil {
return nil, fmt.Errorf("failed to fetch self identity from tssMessenger: %w", err)
}

port := selfID.Port
if port == 0 {
p, err := strconv.Atoi(tss.DefaultPort)
if err != nil {
return nil, fmt.Errorf("failed to parse default port: %w", err)
}

port = p
}

return newServer(fmt.Sprintf("[::]:%d", port), logger, tssMessenger)
}

func newServer(socketPath string, logger *zap.Logger, tssMessenger tss.ReliableMessenger) (DirectLink, error) {
if socketPath == "" {
return nil, errors.New("can't create DirectLink server: socketPath is empty")
}
if logger == nil {
return nil, errors.New("can't create DirectLink server: logger is nil")
}
if tssMessenger == nil {
return nil, errors.New("can't create DirectLink server: tssMessenger is nil")
}

peers := tssMessenger.GetPeers()
partyIds := make([]*tss.Identity, len(peers))
peerToCert := make(map[string]*x509.Certificate, len(peers))
Expand Down
66 changes: 52 additions & 14 deletions node/pkg/tss/comm/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ func (m *mockTssMessageHandler) FetchIdentity(*x509.Certificate) (*tss.Identity,
func (m *mockTssMessageHandler) ProducedOutputMessages() <-chan tss.Sendable {
return m.chn
}

func (m *mockTssMessageHandler) HandleIncomingTssMessage(msg tss.Incoming) {
fmt.Println("received message from", msg.GetSource())
}
Expand Down Expand Up @@ -85,7 +86,7 @@ func TestTLSConnectAndRedial(t *testing.T) {
en, err := _loadGuardians(2)
a.NoError(err)

tmpSrvr, err := NewServer(workingServerSock, supervisor.Logger(ctx), &mockTssMessageHandler{
tmpSrvr, err := newServer(workingServerSock, supervisor.Logger(ctx), &mockTssMessageHandler{
chn: nil,
selfCert: en[0].GetCertificate(),
// connect to no one.
Expand Down Expand Up @@ -117,7 +118,7 @@ func TestTLSConnectAndRedial(t *testing.T) {
a.NoError(err)

msgChan := make(chan tss.Sendable)
srvr, err := NewServer("localhost:5930", supervisor.Logger(ctx), &mockTssMessageHandler{
srvr, err := newServer("localhost:5930", supervisor.Logger(ctx), &mockTssMessageHandler{
chn: msgChan,
selfCert: en[1].GetCertificate(),
peersToConnectTo: []*x509.Certificate{serverCert}, // will ask to fetch each peer (and return the below peerId)
Expand Down Expand Up @@ -167,7 +168,7 @@ func TestRelentlessReconnections(t *testing.T) {
a.NoError(err)

msgChan := make(chan tss.Sendable)
srvr, err := NewServer("localhost:5930", supervisor.Logger(ctx), &mockTssMessageHandler{
srvr, err := newServer("localhost:5930", supervisor.Logger(ctx), &mockTssMessageHandler{
chn: msgChan,
selfCert: en[1].GetCertificate(),
peersToConnectTo: []*x509.Certificate{serverCert}, // will ask to fetch each peer (and return the below peerId)
Expand All @@ -184,7 +185,7 @@ func TestRelentlessReconnections(t *testing.T) {
// setting up server dailer and sender
srv.run()

tmpSrvr, err := NewServer(workingServerSock, supervisor.Logger(ctx), &mockTssMessageHandler{
tmpSrvr, err := newServer(workingServerSock, supervisor.Logger(ctx), &mockTssMessageHandler{
chn: nil,
selfCert: en[0].GetCertificate(),
// connect to no one.
Expand Down Expand Up @@ -259,7 +260,7 @@ func TestNonBlockedBroadcast(t *testing.T) {
donechns := make([]chan struct{}, 2)
// set servers up.
for i := 0; i < 2; i++ {
tmpSrvr, err := NewServer(workingServers[i], supervisor.Logger(ctx), &mockTssMessageHandler{
tmpSrvr, err := newServer(workingServers[i], supervisor.Logger(ctx), &mockTssMessageHandler{
chn: nil,
selfCert: en[i].GetCertificate(),
peersToConnectTo: en[0].GetPeers(), // Give the peer a certificate.
Expand Down Expand Up @@ -309,7 +310,7 @@ func TestNonBlockedBroadcast(t *testing.T) {
en[2].GuardianStorage.SetInnerFields()

msgChan := make(chan tss.Sendable)
srvr, err := NewServer("localhost:5930", supervisor.Logger(ctx), &tssMockJustForMessageGeneration{
srvr, err := newServer("localhost:5930", supervisor.Logger(ctx), &tssMockJustForMessageGeneration{
ReliableMessenger: en[2],
chn: msgChan,
})
Expand Down Expand Up @@ -529,7 +530,7 @@ func TestNotAcceptNonCAs(t *testing.T) {
defer cancel()
ctx = testutils.MakeSupervisorContext(ctx)

tmp, err := NewServer(workingServerSock, supervisor.Logger(ctx), &mockTssMessageHandler{
tmp, err := newServer(workingServerSock, supervisor.Logger(ctx), &mockTssMessageHandler{
chn: nil,
selfCert: en[0].GetCertificate(),
// connect to no one.
Expand Down Expand Up @@ -620,7 +621,7 @@ func TestDialWithDefaultPort(t *testing.T) {

listenerServerPath := "localhost:" + tss.DefaultPort
// set up server that only listent and aren't able to connect to anyone.
listenerServer, err := NewServer(listenerServerPath, supervisor.Logger(ctx), &mockTssMessageHandler{
listenerServer, err := newServer(listenerServerPath, supervisor.Logger(ctx), &mockTssMessageHandler{
chn: nil,
selfCert: listenerEngine.GetCertificate(),
// the listening server will expect this cert to connect with.
Expand Down Expand Up @@ -665,7 +666,7 @@ func TestDialWithDefaultPort(t *testing.T) {
a.NoError(communicatingEngine.GuardianStorage.SetInnerFields())

msgChan := make(chan tss.Sendable)
communicator, err := NewServer("localhost:5930", supervisor.Logger(ctx), &tssMockJustForMessageGeneration{
communicator, err := newServer("localhost:5930", supervisor.Logger(ctx), &tssMockJustForMessageGeneration{
ReliableMessenger: communicatingEngine,
chn: msgChan,
})
Expand Down Expand Up @@ -750,7 +751,7 @@ func TestDialWithDefaultPortDeliverCorrectSrc(t *testing.T) {
senderEngine.GuardianStorage.SetInnerFields()

incomingDataChan := make(chan tss.Incoming)
listenerServer, err := NewServer(streamReceiverPath, supervisor.Logger(ctx),
listenerServer, err := newServer(streamReceiverPath, supervisor.Logger(ctx),
&mockJustHandleIncomingMessage{
ReliableMessenger: streamReceiverEngine,
receivedData: incomingDataChan,
Expand All @@ -772,7 +773,7 @@ func TestDialWithDefaultPortDeliverCorrectSrc(t *testing.T) {
go gserver.Serve(l)

msgChan := make(chan tss.Sendable)
sender, err := NewServer("nonsensePort", supervisor.Logger(ctx), &tssMockJustForMessageGeneration{
sender, err := newServer("nonsensePort", supervisor.Logger(ctx), &tssMockJustForMessageGeneration{
ReliableMessenger: senderEngine,
chn: msgChan,
})
Expand Down Expand Up @@ -844,7 +845,7 @@ func TestConnectingToServers(t *testing.T) {

e.GuardianStorage.SetInnerFields()
e.Start(ctx)
s, err := NewServer(e.GuardianStorage.Self.NetworkName(), supervisor.Logger(ctx), &mockProduceOutputMessages{
s, err := newServer(e.GuardianStorage.Self.NetworkName(), supervisor.Logger(ctx), &mockProduceOutputMessages{
mockJustHandleIncomingMessage: mockJustHandleIncomingMessage{
ReliableMessenger: e,
receivedData: incomingMsgChn[i],
Expand Down Expand Up @@ -891,7 +892,7 @@ func TestDetectConnectionsDone(t *testing.T) {
en, err := _loadGuardians(2)
a.NoError(err)

tmpSrvr, err := NewServer(workingServerSock, supervisor.Logger(ctx), &mockTssMessageHandler{
tmpSrvr, err := newServer(workingServerSock, supervisor.Logger(ctx), &mockTssMessageHandler{
chn: nil,
selfCert: en[0].GetCertificate(),
// connect to no one.
Expand Down Expand Up @@ -923,7 +924,7 @@ func TestDetectConnectionsDone(t *testing.T) {
a.NoError(err)

msgChan := make(chan tss.Sendable)
srvr, err := NewServer("localhost:5930", supervisor.Logger(ctx), &mockTssMessageHandler{
srvr, err := newServer("localhost:5930", supervisor.Logger(ctx), &mockTssMessageHandler{
chn: msgChan,
selfCert: en[1].GetCertificate(),
peersToConnectTo: []*x509.Certificate{serverCert}, // will ask to fetch each peer (and return the below peerId)
Expand Down Expand Up @@ -961,3 +962,40 @@ func TestDetectConnectionsDone(t *testing.T) {
case <-tstServer.done:
}
}

func TestSocketPathCreation(t *testing.T) {
a := require.New(t)
ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
defer cancel()
ctx = testutils.MakeSupervisorContext(ctx)

en, err := _loadGuardians(2)
a.NoError(err)

en[0].Self.Port = 1233456
en[0].GuardianStorage.Identities[en[0].Self.CommunicationIndex].Port = 1233456

tmpSrvr, err := NewServer(supervisor.Logger(ctx), en[0])
a.NoError(err)

a.Equal(fmt.Sprintf("[::]:%d", en[0].Self.Port), tmpSrvr.(*server).socketPath)

// now checking correct behavior when port is 0
en[1].Self.Port = 0
en[1].GuardianStorage.Identities[en[1].Self.CommunicationIndex].Port = 0
tmpSrvr2, err := NewServer(supervisor.Logger(ctx), en[1])
a.NoError(err)
a.Equal(fmt.Sprintf("[::]:%s", tss.DefaultPort), tmpSrvr2.(*server).socketPath)

// For coverage completness we Invoke Run and close the server.

go tmpSrvr2.Run(ctx)
time.Sleep(time.Second * 1)

cancel()
select {
case <-ctx.Done():
case <-time.After(time.Second * 2):
t.Fatal("server run did not stop after context cancel")
}
}
11 changes: 3 additions & 8 deletions node/pkg/tss/internal/cmd/dkg/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ func main() {
keygen.Start(ctx)

logger.Info("Setting up server...")
srvr := createServer(gst, keygen)
srvr := createServer(keygen)
go func() {
if err := srvr.Run(ctx); err != nil {
logger.Fatal("Server stopped", zap.Error(err))
Expand Down Expand Up @@ -149,13 +149,8 @@ func run(ctx context.Context, keygen engine.KeyGenerator, gst *engine.GuardianSt
logger.Fatal("failed to complete DKG after 10 attempts, please check the logs for more details")
}

func createServer(gst *engine.GuardianStorage, keygen engine.KeyGenerator) comm.DirectLink {
socketpath := "[::]:" + strconv.Itoa(gst.Self.Port)
if gst.Self.Port == 0 {
socketpath = "[::]:" + engine.DefaultPort
}

srvr, err := comm.NewServer(socketpath, logger, keygen)
func createServer(keygen engine.KeyGenerator) comm.DirectLink {
srvr, err := comm.NewServer(logger, keygen)
if err != nil {
logger.Fatal("failed to create a new server", zap.Error(err))
}
Expand Down
31 changes: 23 additions & 8 deletions node/pkg/tss/internal/cmd/lkg/local_key_generation.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"github.com/xlabs/multi-party-sig/pkg/math/sample"
"github.com/xlabs/multi-party-sig/pkg/party"
"github.com/xlabs/multi-party-sig/protocols/frost"
"github.com/xlabs/multi-party-sig/protocols/frost/sign"
)

var cnfgPath = flag.String("cnfg", "", "path to config file in json format used to run the protocol")
Expand Down Expand Up @@ -62,7 +63,8 @@ type dkgPlayer struct {
self *engine.Identity
ids engine.IdentitiesKeep

selfCert []byte
selfCert []byte
certKeyPEM []byte

// same for all guardians // generated here.
loadDistributionKey []byte
Expand Down Expand Up @@ -90,9 +92,8 @@ func Run(cnfg *cmd.SetupConfigs) {
// this function simulates the results of running a DKG protocol.
func simulateDKG(all []*dkgPlayer, threshold int) {
group := curve.Secp256k1{}
secret := sample.Scalar(rand.Reader, group)
f := polynomial.NewPolynomial(group, threshold, secret)
publicKey := secret.ActOnBase()

publicKey, f := makefrostKey(group, threshold)

privateShares := make(map[party.ID]curve.Scalar, len(all))
for _, p := range all {
Expand Down Expand Up @@ -135,7 +136,7 @@ func simulateDKG(all []*dkgPlayer, threshold int) {
Configurations: engine.Configurations{},
Self: p.self,
TlsX509: p.selfCert,
PrivateKey: nil, // each guardian stores this by themselves.
PrivateKey: p.certKeyPEM,
IdentitiesKeep: p.ids,
Threshold: threshold,
// SavedSecretParameters: ,
Expand All @@ -156,19 +157,32 @@ func simulateDKG(all []*dkgPlayer, threshold int) {
panic("")
}

if err := os.MkdirAll(all[i].whereToStore, 0600); err != nil {
if err := os.MkdirAll(all[i].whereToStore, 0700); err != nil {
panic("Failed to create directory: " + err.Error())
}

fname := path.Join(all[i].whereToStore, "secrets.json")

if err := os.WriteFile(fname, bts, 0777); err != nil {
if err := os.WriteFile(fname, bts, 0600); err != nil {
panic("Failed to write to disk: " + err.Error())
}
}

}

func makefrostKey(group curve.Secp256k1, threshold int) (curve.Point, *polynomial.Polynomial) {
for range 128 {
Comment thread
jonathanMweiss marked this conversation as resolved.
secret := sample.Scalar(rand.Reader, group)
f := polynomial.NewPolynomial(group, threshold, secret)
publicKey := secret.ActOnBase()
if sign.PublicKeyValidForContract(publicKey) {
return publicKey, f
}
}

panic("could not generate a valid frost key after 128 attempts")
}

func setupPlayers(cnfg *cmd.SetupConfigs) ([]*dkgPlayer, error) {
if err := cnfg.Validate(); err != nil {
return nil, err
Expand Down Expand Up @@ -203,12 +217,13 @@ func setupPlayers(cnfg *cmd.SetupConfigs) ([]*dkgPlayer, error) {

// peerContext := tss.NewPeerContext(sortedPids)

gspecific := mp[string(id.Pid.GetID())]
gspecific := mp[string(id.KeyPEM)]

p := &dkgPlayer{
self: id,
whereToStore: cnfg.SaveLocation[index],
selfCert: gspecific.TlsX509,
certKeyPEM: cnfg.Secrets[index],
loadDistributionKey: tmp,

ids: engine.IdentitiesKeep{
Expand Down
Loading
Loading