diff --git a/cmd/horcrux/cmd/address.go b/cmd/horcrux/cmd/address.go index dad3f031..fc69f870 100644 --- a/cmd/horcrux/cmd/address.go +++ b/cmd/horcrux/cmd/address.go @@ -10,7 +10,8 @@ import ( cometprivval "github.com/cometbft/cometbft/privval" "github.com/cosmos/cosmos-sdk/types/bech32" "github.com/spf13/cobra" - "github.com/strangelove-ventures/horcrux/signer" + cconfig "github.com/strangelove-ventures/horcrux/pkg/config" + "github.com/strangelove-ventures/horcrux/pkg/thresholdTemP" ) type AddressCmdOutput struct { @@ -34,7 +35,7 @@ func addressCmd() *cobra.Command { chainID := args[0] switch config.Config.SignMode { - case signer.SignModeThreshold: + case cconfig.SignModeThreshold: err := config.Config.ValidateThresholdModeConfig() if err != nil { return err @@ -45,13 +46,13 @@ func addressCmd() *cobra.Command { return err } - key, err := signer.LoadThresholdSignerEd25519Key(keyFile) + key, err := thresholdTemP.LoadThresholdSignerEd25519Key(keyFile) if err != nil { return fmt.Errorf("error reading threshold key: %w, check that key is present for chain id: %s", err, chainID) } pubKey = key.PubKey - case signer.SignModeSingle: + case cconfig.SignModeSingle: err := config.Config.ValidateSingleSignerConfig() if err != nil { return err @@ -70,7 +71,7 @@ func addressCmd() *cobra.Command { pubKeyAddress := pubKey.Address() - pubKeyJSON, err := signer.PubKey("", pubKey) + pubKeyJSON, err := cconfig.PubKey("", pubKey) if err != nil { return err } @@ -86,7 +87,7 @@ func addressCmd() *cobra.Command { return err } output.ValConsAddress = bech32ValConsAddress - pubKeyBech32, err := signer.PubKey(args[1], pubKey) + pubKeyBech32, err := cconfig.PubKey(args[1], pubKey) if err != nil { return err } diff --git a/cmd/horcrux/cmd/config.go b/cmd/horcrux/cmd/config.go index 047c04c5..6504e875 100644 --- a/cmd/horcrux/cmd/config.go +++ b/cmd/horcrux/cmd/config.go @@ -5,7 +5,7 @@ import ( "os" "github.com/spf13/cobra" - "github.com/strangelove-ventures/horcrux/signer" + cconfig "github.com/strangelove-ventures/horcrux/pkg/config" ) const ( @@ -48,7 +48,7 @@ for threshold signer mode, --cosigner flags and --threshold flag are required. bare, _ := cmdFlags.GetBool(flagBare) nodes, _ := cmdFlags.GetStringSlice(flagNode) - cn, err := signer.ChainNodesFromFlag(nodes) + cn, err := cconfig.ChainNodesFromFlag(nodes) if err != nil { return err } @@ -60,7 +60,7 @@ for threshold signer mode, --cosigner flags and --threshold flag are required. config.ConfigFile) } - var cfg signer.Config + var cfg cconfig.Config signMode, _ := cmdFlags.GetString(flagSignMode) keyDirFlag, _ := cmdFlags.GetString(flagKeyDir) @@ -70,21 +70,21 @@ for threshold signer mode, --cosigner flags and --threshold flag are required. } debugAddr, _ := cmdFlags.GetString(flagDebugAddr) grpcAddr, _ := cmdFlags.GetString(flagGRPCAddress) - if signMode == string(signer.SignModeThreshold) { + if signMode == string(cconfig.SignModeThreshold) { // Threshold Mode Config cosignersFlag, _ := cmdFlags.GetStringSlice(flagCosigner) threshold, _ := cmdFlags.GetInt(flagThreshold) raftTimeout, _ := cmdFlags.GetString(flagRaftTimeout) grpcTimeout, _ := cmdFlags.GetString(flagGRPCTimeout) - cosigners, err := signer.CosignersFromFlag(cosignersFlag) + cosigners, err := cconfig.CosignersFromFlag(cosignersFlag) if err != nil { return err } - cfg = signer.Config{ - SignMode: signer.SignModeThreshold, + cfg = cconfig.Config{ + SignMode: cconfig.SignModeThreshold, PrivValKeyDir: keyDir, - ThresholdModeConfig: &signer.ThresholdModeConfig{ + ThresholdModeConfig: &cconfig.ThresholdModeConfig{ Threshold: threshold, Cosigners: cosigners, GRPCTimeout: grpcTimeout, @@ -102,8 +102,8 @@ for threshold signer mode, --cosigner flags and --threshold flag are required. } } else { // Single Signer Config - cfg = signer.Config{ - SignMode: signer.SignModeSingle, + cfg = cconfig.Config{ + SignMode: cconfig.SignModeSingle, PrivValKeyDir: keyDir, ChainNodes: cn, DebugAddr: debugAddr, @@ -134,8 +134,8 @@ for threshold signer mode, --cosigner flags and --threshold flag are required. } f := cmd.Flags() - f.StringP(flagSignMode, "m", string(signer.SignModeThreshold), - `sign mode, "threshold" (recommended) or "single" (unsupported). threshold mode requires --cosigner (multiple) and --threshold`, //nolint + f.StringP(flagSignMode, "m", string(cconfig.SignModeThreshold), + `sign mode, "threshold" (recommended) or "single" (unsupported). threshold mode requires --cosigner (multiple) and --threshold`, // nolint ) f.StringSliceP(flagNode, "n", []string{}, "chain nodes in format tcp://{node-addr}:{privval-port} \n"+ "(e.g. --node tcp://sentry-1:1234 --node tcp://sentry-2:1234 --node tcp://sentry-3:1234 )") diff --git a/cmd/horcrux/cmd/leader_election.go b/cmd/horcrux/cmd/leader_election.go index 8dba6858..b0bf35e1 100644 --- a/cmd/horcrux/cmd/leader_election.go +++ b/cmd/horcrux/cmd/leader_election.go @@ -5,10 +5,11 @@ import ( "fmt" "time" + "github.com/strangelove-ventures/horcrux/pkg/nodes/nodesecurity" + grpcretry "github.com/grpc-ecosystem/go-grpc-middleware/retry" "github.com/spf13/cobra" "github.com/strangelove-ventures/horcrux/client" - "github.com/strangelove-ventures/horcrux/signer" "github.com/strangelove-ventures/horcrux/signer/multiresolver" "github.com/strangelove-ventures/horcrux/signer/proto" "google.golang.org/grpc" @@ -116,14 +117,14 @@ func getLeaderCmd() *cobra.Command { return fmt.Errorf("cosigner encryption keys not found (%s) - (%s): %w", keyFileECIES, keyFileRSA, err) } - key, err := signer.LoadCosignerRSAKey(keyFileRSA) + key, err := nodesecurity.LoadCosignerRSAKey(keyFileRSA) if err != nil { return fmt.Errorf("error reading cosigner key (%s): %w", keyFileRSA, err) } id = key.ID } else { - key, err := signer.LoadCosignerECIESKey(keyFileECIES) + key, err := nodesecurity.LoadCosignerECIESKey(keyFileECIES) if err != nil { return fmt.Errorf("error reading cosigner key (%s): %w", keyFileECIES, err) } diff --git a/cmd/horcrux/cmd/migrate.go b/cmd/horcrux/cmd/migrate.go index af083e3a..4dc0afda 100644 --- a/cmd/horcrux/cmd/migrate.go +++ b/cmd/horcrux/cmd/migrate.go @@ -8,12 +8,15 @@ import ( "os" "path/filepath" + cconfig "github.com/strangelove-ventures/horcrux/pkg/config" + "github.com/strangelove-ventures/horcrux/pkg/nodes/nodesecurity" + "github.com/strangelove-ventures/horcrux/pkg/thresholdTemP" + cometcrypto "github.com/cometbft/cometbft/crypto" cometcryptoed25519 "github.com/cometbft/cometbft/crypto/ed25519" cometcryptoencoding "github.com/cometbft/cometbft/crypto/encoding" cometprotocrypto "github.com/cometbft/cometbft/proto/tendermint/crypto" "github.com/spf13/cobra" - "github.com/strangelove-ventures/horcrux/signer" amino "github.com/tendermint/go-amino" "gopkg.in/yaml.v2" ) @@ -218,7 +221,7 @@ func migrateCmd() *cobra.Command { return err } - newEd25519Key := signer.CosignerEd25519Key{ + newEd25519Key := thresholdTemP.CosignerEd25519Key{ PubKey: legacyCosignerKey.PubKey, PrivateShard: legacyCosignerKey.ShareKey, ID: legacyCosignerKey.ID, @@ -234,7 +237,7 @@ func migrateCmd() *cobra.Command { return fmt.Errorf("failed to write new Ed25519 key to %s: %w", newEd25519Path, err) } - newRSAKey := signer.CosignerRSAKey{ + newRSAKey := nodesecurity.CosignerRSAKey{ RSAKey: legacyCosignerKey.RSAKey, ID: legacyCosignerKey.ID, RSAPubs: legacyCosignerKey.RSAPubs, @@ -252,10 +255,10 @@ func migrateCmd() *cobra.Command { // only attempt config migration if legacy config exists if legacyCfgErr == nil { - var migratedNodes signer.ChainNodes + var migratedNodes cconfig.ChainNodes for _, n := range legacyCfg.ChainNodes { - migratedNodes = append(migratedNodes, signer.ChainNode{ + migratedNodes = append(migratedNodes, cconfig.ChainNode{ PrivValAddr: n.PrivValAddr, }) } @@ -263,17 +266,17 @@ func migrateCmd() *cobra.Command { config.Config.ChainNodes = migratedNodes config.Config.DebugAddr = legacyCfg.DebugAddr - signMode := signer.SignModeSingle + signMode := cconfig.SignModeSingle if legacyCfg.Cosigner != nil { - signMode = signer.SignModeThreshold + signMode = cconfig.SignModeThreshold - var migratedCosigners signer.CosignersConfig + var migratedCosigners cconfig.CosignersConfig if legacyCfg.Cosigner.P2PListen != "" { migratedCosigners = append( migratedCosigners, - signer.CosignerConfig{ + cconfig.CosignerConfig{ ShardID: legacyCosignerKey.ID, P2PAddr: legacyCfg.Cosigner.P2PListen, }, @@ -281,13 +284,13 @@ func migrateCmd() *cobra.Command { } for _, c := range legacyCfg.Cosigner.Peers { - migratedCosigners = append(migratedCosigners, signer.CosignerConfig{ + migratedCosigners = append(migratedCosigners, cconfig.CosignerConfig{ ShardID: c.ShareID, P2PAddr: c.P2PAddr, }) } - config.Config.ThresholdModeConfig = &signer.ThresholdModeConfig{ + config.Config.ThresholdModeConfig = &cconfig.ThresholdModeConfig{ Threshold: legacyCfg.Cosigner.Threshold, Cosigners: migratedCosigners, GRPCTimeout: legacyCfg.Cosigner.Timeout, diff --git a/cmd/horcrux/cmd/root.go b/cmd/horcrux/cmd/root.go index ff506a7e..dd943f83 100644 --- a/cmd/horcrux/cmd/root.go +++ b/cmd/horcrux/cmd/root.go @@ -8,11 +8,11 @@ import ( homedir "github.com/mitchellh/go-homedir" "github.com/spf13/cobra" "github.com/spf13/viper" - "github.com/strangelove-ventures/horcrux/signer" + cconfig "github.com/strangelove-ventures/horcrux/pkg/config" "gopkg.in/yaml.v2" ) -var config signer.RuntimeConfig +var config cconfig.RuntimeConfig func rootCmd() *cobra.Command { cmd := &cobra.Command{ @@ -74,7 +74,7 @@ func initConfig() { } else { home = config.HomeDir } - config = signer.RuntimeConfig{ + config = cconfig.RuntimeConfig{ HomeDir: home, ConfigFile: filepath.Join(home, "config.yaml"), StateDir: filepath.Join(home, "state"), diff --git a/cmd/horcrux/cmd/shards.go b/cmd/horcrux/cmd/shards.go index 57906db8..12551e62 100644 --- a/cmd/horcrux/cmd/shards.go +++ b/cmd/horcrux/cmd/shards.go @@ -20,8 +20,10 @@ import ( "os" "path/filepath" + "github.com/strangelove-ventures/horcrux/pkg/nodes/nodesecurity" + "github.com/strangelove-ventures/horcrux/pkg/thresholdTemP" + "github.com/spf13/cobra" - "github.com/strangelove-ventures/horcrux/signer" ) func createCosignerDirectoryIfNecessary(out string, id int) (string, error) { @@ -112,7 +114,7 @@ func createCosignerEd25519ShardsCmd() *cobra.Command { return nil } - csKeys, err := signer.CreateEd25519ThresholdSignShardsFromFile(keyFile, threshold, shards) + csKeys, err := thresholdTemP.CreateEd25519ThresholdSignShardsFromFile(keyFile, threshold, shards) if err != nil { return err } @@ -133,7 +135,7 @@ func createCosignerEd25519ShardsCmd() *cobra.Command { return err } filename := filepath.Join(dir, fmt.Sprintf("%s_shard.json", chainID)) - if err = signer.WriteCosignerEd25519ShardFile(c, filename); err != nil { + if err = thresholdTemP.WriteCosignerEd25519ShardFile(c, filename); err != nil { return err } fmt.Fprintf(cmd.OutOrStdout(), "Created Ed25519 Shard %s\n", filename) @@ -170,7 +172,7 @@ func createCosignerECIESShardsCmd() *cobra.Command { return fmt.Errorf("shards must be greater than zero (%d): %w", shards, err) } - csKeys, err := signer.CreateCosignerECIESShards(int(shards)) + csKeys, err := nodesecurity.CreateCosignerECIESShards(int(shards)) if err != nil { return err } @@ -191,7 +193,7 @@ func createCosignerECIESShardsCmd() *cobra.Command { return err } filename := filepath.Join(dir, "ecies_keys.json") - if err = signer.WriteCosignerECIESShardFile(c, filename); err != nil { + if err = nodesecurity.WriteCosignerECIESShardFile(c, filename); err != nil { return err } fmt.Fprintf(cmd.OutOrStdout(), "Created ECIES Shard %s\n", filename) @@ -218,7 +220,7 @@ func createCosignerRSAShardsCmd() *cobra.Command { return fmt.Errorf("shards must be greater than zero (%d): %w", shards, err) } - csKeys, err := signer.CreateCosignerRSAShards(int(shards)) + csKeys, err := nodesecurity.CreateCosignerRSAShards(int(shards)) if err != nil { return err } @@ -239,7 +241,7 @@ func createCosignerRSAShardsCmd() *cobra.Command { return err } filename := filepath.Join(dir, "rsa_keys.json") - if err = signer.WriteCosignerRSAShardFile(c, filename); err != nil { + if err = nodesecurity.WriteCosignerRSAShardFile(c, filename); err != nil { return err } fmt.Fprintf(cmd.OutOrStdout(), "Created RSA Shard %s\n", filename) diff --git a/cmd/horcrux/cmd/start.go b/cmd/horcrux/cmd/start.go index 8f207b1e..ffa06a97 100644 --- a/cmd/horcrux/cmd/start.go +++ b/cmd/horcrux/cmd/start.go @@ -9,6 +9,7 @@ import ( cometlog "github.com/cometbft/cometbft/libs/log" "github.com/cometbft/cometbft/libs/service" "github.com/spf13/cobra" + cconfig "github.com/strangelove-ventures/horcrux/pkg/config" "github.com/strangelove-ventures/horcrux/signer" ) @@ -48,12 +49,12 @@ func startCmd() *cobra.Command { var services []service.Service switch config.Config.SignMode { - case signer.SignModeThreshold: + case cconfig.SignModeThreshold: services, val, err = NewThresholdValidator(cmd.Context(), logger) if err != nil { return err } - case signer.SignModeSingle: + case cconfig.SignModeSingle: val, err = NewSingleSignerValidator(out, acceptRisk) if err != nil { return err diff --git a/cmd/horcrux/cmd/threshold.go b/cmd/horcrux/cmd/threshold.go index 5831b3ed..a8b44e8e 100644 --- a/cmd/horcrux/cmd/threshold.go +++ b/cmd/horcrux/cmd/threshold.go @@ -9,6 +9,7 @@ import ( cometlog "github.com/cometbft/cometbft/libs/log" cometservice "github.com/cometbft/cometbft/libs/service" + "github.com/strangelove-ventures/horcrux/pkg/nodes" "github.com/strangelove-ventures/horcrux/signer" ) @@ -24,11 +25,11 @@ func NewThresholdValidator( thresholdCfg := config.Config.ThresholdModeConfig - remoteCosigners := make([]signer.Cosigner, 0, len(thresholdCfg.Cosigners)-1) + remoteCosigners := make([]nodes.Cosigner, 0, len(thresholdCfg.Cosigners)-1) var p2pListen string - var security signer.CosignerSecurity + var security nodes.ICosignerSecurity var eciesErr error security, eciesErr = config.CosignerSecurityECIES() if eciesErr != nil { @@ -41,7 +42,7 @@ func NewThresholdValidator( for _, c := range thresholdCfg.Cosigners { if c.ShardID != security.GetID() { - rc, err := signer.NewRemoteCosigner(c.ShardID, c.P2PAddr) + rc, err := nodes.NewRemoteCosigner(c.ShardID, c.P2PAddr) if err != nil { return nil, nil, fmt.Errorf("failed to initialize remote cosigner: %w", err) } @@ -58,7 +59,7 @@ func NewThresholdValidator( return nil, nil, fmt.Errorf("cosigner config does not exist for our shard Index %d", security.GetID()) } - localCosigner := signer.NewLocalCosigner( + localCosigner := nodes.NewLocalCosigner( logger, &config, security, diff --git a/signer/config.go b/pkg/config/config.go similarity index 92% rename from signer/config.go rename to pkg/config/config.go index edf9bfb2..50eebb57 100644 --- a/signer/config.go +++ b/pkg/config/config.go @@ -1,4 +1,4 @@ -package signer +package config import ( "fmt" @@ -8,6 +8,8 @@ import ( "path/filepath" "time" + "github.com/strangelove-ventures/horcrux/pkg/nodes/nodesecurity" + "github.com/cometbft/cometbft/crypto" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/codec/legacy" @@ -25,6 +27,13 @@ type SignMode string const ( SignModeThreshold SignMode = "threshold" SignModeSingle SignMode = "single" + + // Default values for the nouncecahce + // TODO: Is this the best way to do this? + DefaultGetNoncesInterval = 3 * time.Second + DefaultGetNoncesTimeout = 4 * time.Second + DefaultNonceExpiration = 10 * time.Second // half of the local cosigner cache expiration + ) // Config maps to the on-disk yaml format @@ -101,32 +110,32 @@ type RuntimeConfig struct { Config Config } -func (c RuntimeConfig) CosignerSecurityECIES() (*CosignerSecurityECIES, error) { +func (c RuntimeConfig) CosignerSecurityECIES() (*nodesecurity.CosignerSecurityECIES, error) { keyFile, err := c.KeyFileExistsCosignerECIES() if err != nil { return nil, err } - key, err := LoadCosignerECIESKey(keyFile) + key, err := nodesecurity.LoadCosignerECIESKey(keyFile) if err != nil { return nil, fmt.Errorf("error reading cosigner key (%s): %w", keyFile, err) } - return NewCosignerSecurityECIES(key), nil + return nodesecurity.NewCosignerSecurityECIES(key), nil } -func (c RuntimeConfig) CosignerSecurityRSA() (*CosignerSecurityRSA, error) { +func (c RuntimeConfig) CosignerSecurityRSA() (*nodesecurity.CosignerSecurityRSA, error) { keyFile, err := c.KeyFileExistsCosignerRSA() if err != nil { return nil, err } - key, err := LoadCosignerRSAKey(keyFile) + key, err := nodesecurity.LoadCosignerRSAKey(keyFile) if err != nil { return nil, fmt.Errorf("error reading cosigner key (%s): %w", keyFile, err) } - return NewCosignerSecurityRSA(key), nil + return nodesecurity.NewCosignerSecurityRSA(key), nil } func (c RuntimeConfig) cachedKeyDirectory() string { diff --git a/signer/config_test.go b/pkg/config/config_test.go similarity index 84% rename from signer/config_test.go rename to pkg/config/config_test.go index 649eb40a..fb419ab8 100644 --- a/signer/config_test.go +++ b/pkg/config/config_test.go @@ -1,4 +1,4 @@ -package signer_test +package config_test import ( "fmt" @@ -8,15 +8,15 @@ import ( "path/filepath" "testing" - "github.com/strangelove-ventures/horcrux/signer" + "github.com/strangelove-ventures/horcrux/pkg/config" "github.com/stretchr/testify/require" ) const testChainID = "test" func TestNodes(t *testing.T) { - c := signer.Config{ - ChainNodes: signer.ChainNodes{ + c := config.Config{ + ChainNodes: config.ChainNodes{ { PrivValAddr: "tcp://0.0.0.0:1234", }, @@ -32,15 +32,15 @@ func TestNodes(t *testing.T) { func TestValidateSingleSignerConfig(t *testing.T) { type testCase struct { name string - config signer.Config + config config.Config expectErr error } testCases := []testCase{ { name: "valid config", - config: signer.Config{ - ChainNodes: []signer.ChainNode{ + config: config.Config{ + ChainNodes: []config.ChainNode{ { PrivValAddr: "tcp://127.0.0.1:1234", }, @@ -50,8 +50,8 @@ func TestValidateSingleSignerConfig(t *testing.T) { }, { name: "invalid node address", - config: signer.Config{ - ChainNodes: []signer.ChainNode{ + config: config.Config{ + ChainNodes: []config.ChainNode{ { PrivValAddr: "abc://\\invalid_addr", }, @@ -75,19 +75,19 @@ func TestValidateSingleSignerConfig(t *testing.T) { func TestValidateThresholdModeConfig(t *testing.T) { type testCase struct { name string - config signer.Config + config config.Config expectErr error } testCases := []testCase{ { name: "valid config", - config: signer.Config{ - ThresholdModeConfig: &signer.ThresholdModeConfig{ + config: config.Config{ + ThresholdModeConfig: &config.ThresholdModeConfig{ Threshold: 2, RaftTimeout: "1000ms", GRPCTimeout: "1000ms", - Cosigners: signer.CosignersConfig{ + Cosigners: config.CosignersConfig{ { ShardID: 1, P2PAddr: "tcp://127.0.0.1:2223", @@ -102,7 +102,7 @@ func TestValidateThresholdModeConfig(t *testing.T) { }, }, }, - ChainNodes: []signer.ChainNode{ + ChainNodes: []config.ChainNode{ { PrivValAddr: "tcp://127.0.0.1:1234", }, @@ -118,8 +118,8 @@ func TestValidateThresholdModeConfig(t *testing.T) { }, { name: "no cosigner config", - config: signer.Config{ - ChainNodes: []signer.ChainNode{ + config: config.Config{ + ChainNodes: []config.ChainNode{ { PrivValAddr: "tcp://127.0.0.1:1234", }, @@ -135,12 +135,12 @@ func TestValidateThresholdModeConfig(t *testing.T) { }, { name: "invalid p2p listen", - config: signer.Config{ - ThresholdModeConfig: &signer.ThresholdModeConfig{ + config: config.Config{ + ThresholdModeConfig: &config.ThresholdModeConfig{ Threshold: 2, RaftTimeout: "1000ms", GRPCTimeout: "1000ms", - Cosigners: signer.CosignersConfig{ + Cosigners: config.CosignersConfig{ { ShardID: 1, P2PAddr: ":2222", @@ -155,7 +155,7 @@ func TestValidateThresholdModeConfig(t *testing.T) { }, }, }, - ChainNodes: []signer.ChainNode{ + ChainNodes: []config.ChainNode{ { PrivValAddr: "tcp://127.0.0.1:1234", }, @@ -175,12 +175,12 @@ func TestValidateThresholdModeConfig(t *testing.T) { }, { name: "not enough cosigners", - config: signer.Config{ - ThresholdModeConfig: &signer.ThresholdModeConfig{ + config: config.Config{ + ThresholdModeConfig: &config.ThresholdModeConfig{ Threshold: 3, RaftTimeout: "1000ms", GRPCTimeout: "1000ms", - Cosigners: signer.CosignersConfig{ + Cosigners: config.CosignersConfig{ { ShardID: 1, P2PAddr: "tcp://127.0.0.1:2222", @@ -191,7 +191,7 @@ func TestValidateThresholdModeConfig(t *testing.T) { }, }, }, - ChainNodes: []signer.ChainNode{ + ChainNodes: []config.ChainNode{ { PrivValAddr: "tcp://127.0.0.1:1234", }, @@ -207,12 +207,12 @@ func TestValidateThresholdModeConfig(t *testing.T) { }, { name: "invalid raft timeout", - config: signer.Config{ - ThresholdModeConfig: &signer.ThresholdModeConfig{ + config: config.Config{ + ThresholdModeConfig: &config.ThresholdModeConfig{ Threshold: 2, GRPCTimeout: "1000ms", RaftTimeout: "1000", - Cosigners: signer.CosignersConfig{ + Cosigners: config.CosignersConfig{ { ShardID: 1, P2PAddr: "tcp://127.0.0.1:2222", @@ -227,7 +227,7 @@ func TestValidateThresholdModeConfig(t *testing.T) { }, }, }, - ChainNodes: []signer.ChainNode{ + ChainNodes: []config.ChainNode{ { PrivValAddr: "tcp://127.0.0.1:1234", }, @@ -243,12 +243,12 @@ func TestValidateThresholdModeConfig(t *testing.T) { }, { name: "invalid grpc timeout", - config: signer.Config{ - ThresholdModeConfig: &signer.ThresholdModeConfig{ + config: config.Config{ + ThresholdModeConfig: &config.ThresholdModeConfig{ Threshold: 2, GRPCTimeout: "1000", RaftTimeout: "1000ms", - Cosigners: signer.CosignersConfig{ + Cosigners: config.CosignersConfig{ { ShardID: 1, P2PAddr: "tcp://127.0.0.1:2222", @@ -263,7 +263,7 @@ func TestValidateThresholdModeConfig(t *testing.T) { }, }, }, - ChainNodes: []signer.ChainNode{ + ChainNodes: []config.ChainNode{ { PrivValAddr: "tcp://127.0.0.1:1234", }, @@ -279,12 +279,12 @@ func TestValidateThresholdModeConfig(t *testing.T) { }, { name: "invalid node address", - config: signer.Config{ - ThresholdModeConfig: &signer.ThresholdModeConfig{ + config: config.Config{ + ThresholdModeConfig: &config.ThresholdModeConfig{ Threshold: 2, RaftTimeout: "1000ms", GRPCTimeout: "1000ms", - Cosigners: signer.CosignersConfig{ + Cosigners: config.CosignersConfig{ { ShardID: 1, P2PAddr: "tcp://127.0.0.1:2222", @@ -299,7 +299,7 @@ func TestValidateThresholdModeConfig(t *testing.T) { }, }, }, - ChainNodes: []signer.ChainNode{ + ChainNodes: []config.ChainNode{ { PrivValAddr: "abc://\\invalid_addr", }, @@ -322,7 +322,7 @@ func TestValidateThresholdModeConfig(t *testing.T) { func TestRuntimeConfigKeyFilePath(t *testing.T) { dir := t.TempDir() - c := signer.RuntimeConfig{ + c := config.RuntimeConfig{ HomeDir: dir, } @@ -336,7 +336,7 @@ func TestRuntimeConfigKeyFilePath(t *testing.T) { func TestRuntimeConfigPrivValStateFile(t *testing.T) { dir := t.TempDir() - c := signer.RuntimeConfig{ + c := config.RuntimeConfig{ StateDir: dir, } @@ -346,15 +346,15 @@ func TestRuntimeConfigPrivValStateFile(t *testing.T) { func TestRuntimeConfigWriteConfigFile(t *testing.T) { dir := t.TempDir() configFile := filepath.Join(dir, "config.yaml") - c := signer.RuntimeConfig{ + c := config.RuntimeConfig{ ConfigFile: configFile, - Config: signer.Config{ - SignMode: signer.SignModeThreshold, - ThresholdModeConfig: &signer.ThresholdModeConfig{ + Config: config.Config{ + SignMode: config.SignModeThreshold, + ThresholdModeConfig: &config.ThresholdModeConfig{ Threshold: 2, RaftTimeout: "1000ms", GRPCTimeout: "1000ms", - Cosigners: signer.CosignersConfig{ + Cosigners: config.CosignersConfig{ { ShardID: 1, P2PAddr: "tcp://127.0.0.1:2222", @@ -369,7 +369,7 @@ func TestRuntimeConfigWriteConfigFile(t *testing.T) { }, }, }, - ChainNodes: []signer.ChainNode{ + ChainNodes: []config.ChainNode{ { PrivValAddr: "tcp://127.0.0.1:1234", }, @@ -409,7 +409,7 @@ grpcAddr: "" func TestRuntimeConfigKeyFileExists(t *testing.T) { dir := t.TempDir() - c := signer.RuntimeConfig{ + c := config.RuntimeConfig{ HomeDir: dir, } @@ -455,11 +455,11 @@ func TestRuntimeConfigKeyFileExists(t *testing.T) { } func TestThresholdModeConfigLeaderElectMultiAddress(t *testing.T) { - c := &signer.ThresholdModeConfig{ + c := &config.ThresholdModeConfig{ Threshold: 2, RaftTimeout: "1000ms", GRPCTimeout: "1000ms", - Cosigners: signer.CosignersConfig{ + Cosigners: config.CosignersConfig{ { ShardID: 1, P2PAddr: "tcp://127.0.0.1:2222", @@ -483,13 +483,13 @@ func TestThresholdModeConfigLeaderElectMultiAddress(t *testing.T) { func TestCosignerRSAPubKeysConfigValidate(t *testing.T) { type testCase struct { name string - cosigners signer.CosignersConfig + cosigners config.CosignersConfig expectErr error } testCases := []testCase{ { name: "valid config", - cosigners: signer.CosignersConfig{ + cosigners: config.CosignersConfig{ { ShardID: 1, P2PAddr: "tcp://127.0.0.1:2222", @@ -507,7 +507,7 @@ func TestCosignerRSAPubKeysConfigValidate(t *testing.T) { }, { name: "too many cosigners", - cosigners: signer.CosignersConfig{ + cosigners: config.CosignersConfig{ { ShardID: 2, P2PAddr: "tcp://127.0.0.1:2223", @@ -521,7 +521,7 @@ func TestCosignerRSAPubKeysConfigValidate(t *testing.T) { }, { name: "duplicate cosigner", - cosigners: signer.CosignersConfig{ + cosigners: config.CosignersConfig{ { ShardID: 2, P2PAddr: "tcp://127.0.0.1:2223", @@ -564,7 +564,7 @@ func TestCosignersFromFlag(t *testing.T) { } for _, tc := range testCases { - _, err := signer.CosignersFromFlag(tc.cosigners) + _, err := config.CosignersFromFlag(tc.cosigners) if tc.expectErr == nil { require.NoError(t, err, tc.name) } else { diff --git a/signer/cosigner.go b/pkg/nodes/cosigner.go similarity index 97% rename from signer/cosigner.go rename to pkg/nodes/cosigner.go index 9ce3e15a..8ef20256 100644 --- a/signer/cosigner.go +++ b/pkg/nodes/cosigner.go @@ -1,8 +1,8 @@ +package nodes + /* Package signer: Cosinger is responsible for the network communication between the cosigners */ -package signer - import ( "context" "time" @@ -139,7 +139,7 @@ func (n *CosignerUUIDNonces) For(id int) *CosignerUUIDNonces { type CosignerUUIDNoncesMultiple []*CosignerUUIDNonces -func (n CosignerUUIDNoncesMultiple) toProto() []*proto.UUIDNonce { +func (n CosignerUUIDNoncesMultiple) ToProto() []*proto.UUIDNonce { out := make([]*proto.UUIDNonce, len(n)) for i, nonces := range n { out[i] = &proto.UUIDNonce{ diff --git a/signer/cosigner_security.go b/pkg/nodes/cosigner_security.go similarity index 92% rename from signer/cosigner_security.go rename to pkg/nodes/cosigner_security.go index 996a52a2..7c94797a 100644 --- a/signer/cosigner_security.go +++ b/pkg/nodes/cosigner_security.go @@ -1,7 +1,7 @@ -package signer +package nodes // CosignerSecurity is an interface for the security layer of the cosigner. -type CosignerSecurity interface { +type ICosignerSecurity interface { // GetID returns the Index of the cosigner. GetID() int diff --git a/signer/local_cosigner.go b/pkg/nodes/local_cosigner.go similarity index 94% rename from signer/local_cosigner.go rename to pkg/nodes/local_cosigner.go index f9ab6ee2..d1faf109 100644 --- a/signer/local_cosigner.go +++ b/pkg/nodes/local_cosigner.go @@ -1,4 +1,4 @@ -package signer +package nodes import ( "context" @@ -7,7 +7,9 @@ import ( "sync" "time" + "github.com/strangelove-ventures/horcrux/pkg/config" "github.com/strangelove-ventures/horcrux/pkg/metrics" + "github.com/strangelove-ventures/horcrux/pkg/thresholdTemP" "github.com/strangelove-ventures/horcrux/pkg/types" @@ -29,8 +31,8 @@ const nonceExpiration = 20 * time.Second // Signing is thread safe. type LocalCosigner struct { logger cometlog.Logger - config *RuntimeConfig - security CosignerSecurity + config *config.RuntimeConfig + security ICosignerSecurity chainState sync.Map // TODO: Add type so its not any? address string pendingDiskWG sync.WaitGroup @@ -42,8 +44,8 @@ type LocalCosigner struct { func NewLocalCosigner( logger cometlog.Logger, - config *RuntimeConfig, - security CosignerSecurity, + config *config.RuntimeConfig, + security ICosignerSecurity, address string, ) *LocalCosigner { return &LocalCosigner{ @@ -61,7 +63,7 @@ type ChainState struct { // incremented whenever we are asked to sign an HRS lastSignState *types.SignState // signer generates nonces, combines nonces, signs, and verifies signatures. - signer ThresholdSigner + signer thresholdTemP.ThresholdSigner } // StartNoncePruner periodically prunes nonces that have expired. @@ -131,9 +133,9 @@ func (cosigner *LocalCosigner) SaveLastSignedState(chainID string, signState typ ) } -// waitForSignStatesToFlushToDisk waits for all state file writes queued +// WaitForSignStatesToFlushToDisk waits for all state file writes queued // in SaveLastSignedState to complete before termination. -func (cosigner *LocalCosigner) waitForSignStatesToFlushToDisk() { +func (cosigner *LocalCosigner) WaitForSignStatesToFlushToDisk() { cosigner.pendingDiskWG.Wait() } @@ -281,7 +283,7 @@ func (cosigner *LocalCosigner) generateNonces() ([]types.Nonces, error) { total := len(cosigner.config.Config.ThresholdModeConfig.Cosigners) meta := make([]types.Nonces, total) - nonces, err := GenerateNonces( + nonces, err := thresholdTemP.GenerateNonces( uint8(cosigner.config.Config.ThresholdModeConfig.Threshold), uint8(total), ) @@ -308,9 +310,9 @@ func (cosigner *LocalCosigner) LoadSignStateIfNecessary(chainID string) error { return err } - var signer ThresholdSigner + var signer thresholdTemP.ThresholdSigner - signer, err = NewThresholdSignerSoft(cosigner.config, cosigner.GetIndex(), chainID) + signer, err = thresholdTemP.NewThresholdSignerSoft(cosigner.config, cosigner.GetIndex(), chainID) if err != nil { return err } @@ -440,7 +442,7 @@ func (cosigner *LocalCosigner) getNonce( return nonce, nil } -const errUnexpectedState = "unexpected state, metadata does not exist for U:" +const ErrUnexpectedState = "unexpected state, metadata does not exist for U:" // setNonce stores a nonce provided by another cosigner func (cosigner *LocalCosigner) setNonce(uuid uuid.UUID, nonce CosignerNonce) error { @@ -464,7 +466,7 @@ func (cosigner *LocalCosigner) setNonce(uuid uuid.UUID, nonce CosignerNonce) err if !ok { return fmt.Errorf( "%s %s", - errUnexpectedState, + ErrUnexpectedState, uuid, ) } diff --git a/signer/local_cosigner_test.go b/pkg/nodes/local_cosigner_test.go similarity index 79% rename from signer/local_cosigner_test.go rename to pkg/nodes/local_cosigner_test.go index 0dc690a8..4331a422 100644 --- a/signer/local_cosigner_test.go +++ b/pkg/nodes/local_cosigner_test.go @@ -1,4 +1,4 @@ -package signer +package nodes_test import ( "context" @@ -10,6 +10,10 @@ import ( "testing" "time" + "github.com/strangelove-ventures/horcrux/pkg/config" + "github.com/strangelove-ventures/horcrux/pkg/nodes" + "github.com/strangelove-ventures/horcrux/pkg/nodes/nodesecurity" + "github.com/strangelove-ventures/horcrux/pkg/thresholdTemP" "github.com/strangelove-ventures/horcrux/pkg/types" cometcryptoed25519 "github.com/cometbft/cometbft/crypto/ed25519" @@ -40,7 +44,7 @@ func TestLocalCosignerSignRSA3of5(t *testing.T) { func testLocalCosignerSignRSA(t *testing.T, threshold, total uint8) { t.Parallel() - security := make([]CosignerSecurity, total) + security := make([]*nodesecurity.CosignerSecurityRSA, total) keys := make([]*rsa.PrivateKey, total) pubKeys := make([]*rsa.PublicKey, total) @@ -53,8 +57,8 @@ func testLocalCosignerSignRSA(t *testing.T, threshold, total uint8) { } for i, k := range keys { - security[i] = NewCosignerSecurityRSA( - CosignerRSAKey{ + security[i] = nodesecurity.NewCosignerSecurityRSA( + nodesecurity.CosignerRSAKey{ ID: i + 1, RSAKey: *k, RSAPubs: pubKeys, @@ -76,7 +80,7 @@ func TestLocalCosignerSignECIES3of5(t *testing.T) { func testLocalCosignerSignECIES(t *testing.T, threshold, total uint8) { t.Parallel() - security := make([]CosignerSecurity, total) + security := make([]nodes.ICosignerSecurity, total) keys := make([]*ecies.PrivateKey, total) pubKeys := make([]*ecies.PublicKey, total) @@ -89,8 +93,8 @@ func testLocalCosignerSignECIES(t *testing.T, threshold, total uint8) { } for i, k := range keys { - security[i] = NewCosignerSecurityECIES( - CosignerECIESKey{ + security[i] = nodesecurity.NewCosignerSecurityECIES( + nodesecurity.CosignerECIESKey{ ID: i + 1, ECIESKey: k, ECIESPubs: pubKeys, @@ -101,7 +105,7 @@ func testLocalCosignerSignECIES(t *testing.T, threshold, total uint8) { testLocalCosignerSign(t, threshold, total, security) } -func testLocalCosignerSign(t *testing.T, threshold, total uint8, security []CosignerSecurity) { +func testLocalCosignerSign(t *testing.T, threshold, total uint8, security []*nodes.ICosignerSecurity) { privateKey := cometcryptoed25519.GenPrivKey() privKeyBytes := [64]byte{} @@ -109,10 +113,10 @@ func testLocalCosignerSign(t *testing.T, threshold, total uint8, security []Cosi privShards := tsed25519.DealShares(tsed25519.ExpandSecret(privKeyBytes[:32]), threshold, total) pubKey := privateKey.PubKey() - cfg := Config{ - ThresholdModeConfig: &ThresholdModeConfig{ + cfg := config.Config{ + ThresholdModeConfig: &config.ThresholdModeConfig{ Threshold: int(threshold), - Cosigners: make(CosignersConfig, total), + Cosigners: make(config.CosignersConfig, total), }, } @@ -120,8 +124,8 @@ func testLocalCosignerSign(t *testing.T, threshold, total uint8, security []Cosi tmpDir := t.TempDir() - thresholdCosigners := make([]*LocalCosigner, threshold) - nonces := make([][]CosignerNonce, threshold) + thresholdCosigners := make([]*nodes.LocalCosigner, threshold) + nonces := make([][]nodes.CosignerNonce, threshold) now := time.Now() @@ -138,13 +142,13 @@ func testLocalCosignerSign(t *testing.T, threshold, total uint8, security []Cosi for i := 0; i < int(total); i++ { id := i + 1 - key := CosignerEd25519Key{ + key := thresholdTemP.CosignerEd25519Key{ PubKey: pubKey, PrivateShard: privShards[i], ID: id, } - cfg.ThresholdModeConfig.Cosigners[i] = CosignerConfig{ + cfg.ThresholdModeConfig.Cosigners[i] = config.CosignerConfig{ ShardID: id, } @@ -152,9 +156,9 @@ func testLocalCosignerSign(t *testing.T, threshold, total uint8, security []Cosi err := os.Mkdir(cosignerDir, 0700) require.NoError(t, err) - cosigner := NewLocalCosigner( + cosigner := nodes.NewLocalCosigner( log.NewNopLogger(), - &RuntimeConfig{ + &config.RuntimeConfig{ HomeDir: cosignerDir, StateDir: cosignerDir, Config: cfg, @@ -197,7 +201,7 @@ func testLocalCosignerSign(t *testing.T, threshold, total uint8, security []Cosi sigs := make([]types.PartialSignature, threshold) for i, cosigner := range thresholdCosigners { - cosignerNonces := make([]CosignerNonce, 0, threshold-1) + cosignerNonces := make([]nodes.CosignerNonce, 0, threshold-1) for j, nonce := range nonces { if i == j { @@ -211,8 +215,8 @@ func testLocalCosignerSign(t *testing.T, threshold, total uint8, security []Cosi } } - sigRes, err := cosigner.SetNoncesAndSign(ctx, CosignerSetNoncesAndSignRequest{ - Nonces: &CosignerUUIDNonces{ + sigRes, err := cosigner.SetNoncesAndSign(ctx, nodes.CosignerSetNoncesAndSignRequest{ + Nonces: &nodes.CosignerUUIDNonces{ UUID: u, Nonces: cosignerNonces, }, diff --git a/signer/cosigner_key_shares.go b/pkg/nodes/nodesecurity/cosigner_key_shares.go similarity index 78% rename from signer/cosigner_key_shares.go rename to pkg/nodes/nodesecurity/cosigner_key_shares.go index 5f4f6248..c6f168ef 100644 --- a/signer/cosigner_key_shares.go +++ b/pkg/nodes/nodesecurity/cosigner_key_shares.go @@ -1,4 +1,4 @@ -package signer +package nodesecurity import ( "crypto/rand" @@ -6,8 +6,6 @@ import ( "encoding/json" "os" - cometjson "github.com/cometbft/cometbft/libs/json" - "github.com/cometbft/cometbft/privval" "github.com/ethereum/go-ethereum/crypto/ecies" "github.com/ethereum/go-ethereum/crypto/secp256k1" "golang.org/x/sync/errgroup" @@ -30,27 +28,6 @@ func CreateCosignerRSAShards(shards int) ([]CosignerRSAKey, error) { return out, nil } -// ReadPrivValidatorFile reads in a privval.FilePVKey from a given file. -func ReadPrivValidatorFile(priv string) (out privval.FilePVKey, err error) { - var bz []byte - if bz, err = os.ReadFile(priv); err != nil { - return - } - if err = cometjson.Unmarshal(bz, &out); err != nil { - return - } - return -} - -// WriteCosignerEd25519ShardFile writes a cosigner Ed25519 key to a given file name. -func WriteCosignerEd25519ShardFile(cosigner CosignerEd25519Key, file string) error { - jsonBytes, err := json.Marshal(&cosigner) - if err != nil { - return err - } - return os.WriteFile(file, jsonBytes, 0600) -} - // WriteCosignerRSAShardFile writes a cosigner RSA key to a given file name. func WriteCosignerRSAShardFile(cosigner CosignerRSAKey, file string) error { jsonBytes, err := json.Marshal(&cosigner) diff --git a/signer/cosigner_security_ecies.go b/pkg/nodes/nodesecurity/cosigner_security_ecies.go similarity index 95% rename from signer/cosigner_security_ecies.go rename to pkg/nodes/nodesecurity/cosigner_security_ecies.go index c5af8857..39decfb1 100644 --- a/signer/cosigner_security_ecies.go +++ b/pkg/nodes/nodesecurity/cosigner_security_ecies.go @@ -1,4 +1,4 @@ -package signer +package nodesecurity import ( "crypto/ecdsa" @@ -12,10 +12,11 @@ import ( cometjson "github.com/cometbft/cometbft/libs/json" "github.com/ethereum/go-ethereum/crypto/ecies" "github.com/ethereum/go-ethereum/crypto/secp256k1" + "github.com/strangelove-ventures/horcrux/pkg/nodes" "golang.org/x/sync/errgroup" ) -var _ CosignerSecurity = &CosignerSecurityECIES{} +var _ nodes.ICosignerSecurity = &CosignerSecurityECIES{} // CosignerSecurityECIES is an implementation of CosignerSecurity // using ECIES for encryption and ECDSA for digital signature. @@ -136,8 +137,8 @@ func (c *CosignerSecurityECIES) GetID() int { } // EncryptAndSign encrypts the nonce and signs it for authentication. -func (c *CosignerSecurityECIES) EncryptAndSign(id int, noncePub []byte, nonceShare []byte) (CosignerNonce, error) { - nonce := CosignerNonce{ +func (c *CosignerSecurityECIES) EncryptAndSign(id int, noncePub []byte, nonceShare []byte) (nodes.CosignerNonce, error) { + nonce := nodes.CosignerNonce{ SourceID: c.key.ID, } @@ -206,7 +207,7 @@ func (c *CosignerSecurityECIES) DecryptAndVerify( return nil, nil, fmt.Errorf("unknown cosigner: %d", id) } - digestMsg := CosignerNonce{ + digestMsg := nodes.CosignerNonce{ SourceID: id, PubKey: encryptedNoncePub, Share: encryptedNonceShare, diff --git a/signer/cosigner_security_ecies_test.go b/pkg/nodes/nodesecurity/cosigner_security_ecies_test.go similarity index 81% rename from signer/cosigner_security_ecies_test.go rename to pkg/nodes/nodesecurity/cosigner_security_ecies_test.go index aa7d04d8..e2f7e515 100644 --- a/signer/cosigner_security_ecies_test.go +++ b/pkg/nodes/nodesecurity/cosigner_security_ecies_test.go @@ -1,4 +1,4 @@ -package signer +package nodesecurity_test import ( "crypto/rand" @@ -7,6 +7,8 @@ import ( "github.com/ethereum/go-ethereum/crypto/ecies" "github.com/ethereum/go-ethereum/crypto/secp256k1" + "github.com/strangelove-ventures/horcrux/pkg/nodes/nodesecurity" + "github.com/stretchr/testify/require" "golang.org/x/sync/errgroup" ) @@ -25,20 +27,20 @@ func TestCosignerECIES(t *testing.T) { pubs[i] = &key.PublicKey } - securities := make([]CosignerSecurity, 3) + securities := make([]nodesecurity.CosignerSecurityECIES, 3) for i := 0; i < 3; i++ { - key := CosignerECIESKey{ + key := nodesecurity.CosignerECIESKey{ ID: i + 1, ECIESKey: keys[i], ECIESPubs: pubs, } - securities[i] = NewCosignerSecurityECIES(key) + securities[i] = *nodesecurity.NewCosignerSecurityECIES(key) bz, err := json.Marshal(&key) require.NoError(t, err) - var key2 CosignerECIESKey + var key2 nodesecurity.CosignerECIESKey require.NoError(t, json.Unmarshal(bz, &key2)) require.Equal(t, key, key2) @@ -55,7 +57,7 @@ func TestCosignerECIES(t *testing.T) { require.ErrorContains(t, err, "failed to decrypt") } -func testCosignerSecurity(t *testing.T, securities []CosignerSecurity) error { +func testCosignerSecurity(t *testing.T, securities []nodesecurity.CosignerSecurityECIES) error { var ( mockPub = []byte("mock_pub") mockShare = []byte("mock_share") @@ -91,14 +93,15 @@ func TestConcurrentIterateCosignerECIES(t *testing.T) { pubs[i] = &key.PublicKey } - securities := make([]CosignerSecurity, 3) + securities := make([]*nodesecurity.CosignerSecurityECIES, 3) for i := 0; i < 3; i++ { - securities[i] = NewCosignerSecurityECIES(CosignerECIESKey{ - ID: i + 1, - ECIESKey: keys[i], - ECIESPubs: pubs, - }) + securities[i] = nodesecurity.NewCosignerSecurityECIES( + nodesecurity.CosignerECIESKey{ + ID: i + 1, + ECIESKey: keys[i], + ECIESPubs: pubs, + }) } for i := 0; i < 5000; i++ { diff --git a/signer/cosigner_security_rsa.go b/pkg/nodes/nodesecurity/cosigner_security_rsa.go similarity index 94% rename from signer/cosigner_security_rsa.go rename to pkg/nodes/nodesecurity/cosigner_security_rsa.go index a2d02675..95a36fb9 100644 --- a/signer/cosigner_security_rsa.go +++ b/pkg/nodes/nodesecurity/cosigner_security_rsa.go @@ -1,4 +1,4 @@ -package signer +package nodesecurity import ( "crypto" @@ -11,10 +11,11 @@ import ( "os" cometjson "github.com/cometbft/cometbft/libs/json" + "github.com/strangelove-ventures/horcrux/pkg/nodes" "golang.org/x/sync/errgroup" ) -var _ CosignerSecurity = &CosignerSecurityRSA{} +var _ nodes.ICosignerSecurity = &CosignerSecurityRSA{} // CosignerSecurityRSA is an implementation of CosignerSecurity using RSA for encryption and P5S for digital signature. type CosignerSecurityRSA struct { @@ -22,7 +23,7 @@ type CosignerSecurityRSA struct { rsaPubKeys map[int]CosignerRSAPubKey } -// CosignerRSAKey is a cosigner's RSA public key. +// CosignerRSAPubKey is a cosigner's RSA public key. type CosignerRSAPubKey struct { ID int PublicKey rsa.PublicKey @@ -128,8 +129,8 @@ func (c *CosignerSecurityRSA) GetID() int { } // EncryptAndSign encrypts the nonce and signs it for authentication. -func (c *CosignerSecurityRSA) EncryptAndSign(id int, noncePub []byte, nonceShare []byte) (CosignerNonce, error) { - nonce := CosignerNonce{ +func (c *CosignerSecurityRSA) EncryptAndSign(id int, noncePub []byte, nonceShare []byte) (nodes.CosignerNonce, error) { + nonce := nodes.CosignerNonce{ SourceID: c.key.ID, } @@ -194,7 +195,7 @@ func (c *CosignerSecurityRSA) DecryptAndVerify( return nil, nil, fmt.Errorf("unknown cosigner: %d", id) } - digestMsg := CosignerNonce{ + digestMsg := nodes.CosignerNonce{ SourceID: id, PubKey: encryptedNoncePub, Share: encryptedNonceShare, diff --git a/signer/cosigner_security_rsa_test.go b/pkg/nodes/nodesecurity/cosigner_security_rsa_test.go similarity index 81% rename from signer/cosigner_security_rsa_test.go rename to pkg/nodes/nodesecurity/cosigner_security_rsa_test.go index 7830d9af..8dbc73cf 100644 --- a/signer/cosigner_security_rsa_test.go +++ b/pkg/nodes/nodesecurity/cosigner_security_rsa_test.go @@ -1,4 +1,4 @@ -package signer +package nodesecurity_test import ( "crypto/rand" @@ -6,10 +6,17 @@ import ( "encoding/json" "testing" + "github.com/strangelove-ventures/horcrux/pkg/nodes" + "github.com/strangelove-ventures/horcrux/pkg/nodes/nodesecurity" + "github.com/stretchr/testify/require" "golang.org/x/sync/errgroup" ) +const ( + bitSize = 2048 +) + func TestCosignerRSA(t *testing.T) { t.Parallel() @@ -24,20 +31,20 @@ func TestCosignerRSA(t *testing.T) { pubKeys[i] = &key.PublicKey } - securities := make([]CosignerSecurity, 3) + securities := make([]nodes.ICosignerSecurity, 3) for i := 0; i < 3; i++ { - key := CosignerRSAKey{ + key := nodesecurity.CosignerRSAKey{ ID: i + 1, RSAKey: *keys[i], RSAPubs: pubKeys, } - securities[i] = NewCosignerSecurityRSA(key) + securities[i] = nodesecurity.NewCosignerSecurityRSA(key) bz, err := json.Marshal(&key) require.NoError(t, err) - var key2 CosignerRSAKey + var key2 nodesecurity.CosignerRSAKey require.NoError(t, json.Unmarshal(bz, &key2)) require.Equal(t, key, key2) @@ -67,10 +74,10 @@ func TestConcurrentIterateCosignerRSA(t *testing.T) { pubKeys[i] = &key.PublicKey } - securities := make([]CosignerSecurity, 3) + securities := make([]nodes.ICosignerSecurity, 3) for i := 0; i < 3; i++ { - securities[i] = NewCosignerSecurityRSA(CosignerRSAKey{ + securities[i] = nodesecurity.NewCosignerSecurityRSA(nodesecurity.CosignerRSAKey{ ID: i + 1, RSAKey: *keys[i], RSAPubs: pubKeys, diff --git a/signer/remote_cosigner.go b/pkg/nodes/remote_cosigner.go similarity index 92% rename from signer/remote_cosigner.go rename to pkg/nodes/remote_cosigner.go index 62f9df48..55054e24 100644 --- a/signer/remote_cosigner.go +++ b/pkg/nodes/remote_cosigner.go @@ -1,4 +1,4 @@ -package signer +package nodes import ( "context" @@ -20,7 +20,7 @@ type RemoteCosigner struct { id int address string - client proto.CosignerClient + Client proto.CosignerClient } // NewRemoteCosigner returns a newly initialized RemoteCosigner @@ -33,7 +33,7 @@ func NewRemoteCosigner(id int, address string) (*RemoteCosigner, error) { cosigner := &RemoteCosigner{ id: id, address: address, - client: client, + Client: client, } return cosigner, nil @@ -88,7 +88,7 @@ func (cosigner *RemoteCosigner) GetNonces( us[i] = make([]byte, 16) copy(us[i], u[:]) } - res, err := cosigner.client.GetNonces(ctx, &proto.GetNoncesRequest{ + res, err := cosigner.Client.GetNonces(ctx, &proto.GetNoncesRequest{ Uuids: us, }) if err != nil { @@ -108,7 +108,7 @@ func (cosigner *RemoteCosigner) GetNonces( func (cosigner *RemoteCosigner) SetNoncesAndSign( ctx context.Context, req CosignerSetNoncesAndSignRequest) (*CosignerSignResponse, error) { - res, err := cosigner.client.SetNoncesAndSign(ctx, &proto.SetNoncesAndSignRequest{ + res, err := cosigner.Client.SetNoncesAndSign(ctx, &proto.SetNoncesAndSignRequest{ Uuid: req.Nonces.UUID[:], ChainID: req.ChainID, Nonces: req.Nonces.Nonces.toProto(), @@ -129,7 +129,7 @@ func (cosigner *RemoteCosigner) Sign( ctx context.Context, req CosignerSignBlockRequest, ) (*CosignerSignBlockResponse, error) { - res, err := cosigner.client.SignBlock(ctx, &proto.SignBlockRequest{ + res, err := cosigner.Client.SignBlock(ctx, &proto.SignBlockRequest{ ChainID: req.ChainID, Block: req.Block.ToProto(), }) diff --git a/signer/cosigner_key.go b/pkg/thresholdTemP/cosigner_key.go similarity index 73% rename from signer/cosigner_key.go rename to pkg/thresholdTemP/cosigner_key.go index 63c6ced7..9afc75b3 100644 --- a/signer/cosigner_key.go +++ b/pkg/thresholdTemP/cosigner_key.go @@ -1,15 +1,25 @@ -package signer +package thresholdTemP import ( "encoding/json" + "os" cometcrypto "github.com/cometbft/cometbft/crypto" cometcryptoed25519 "github.com/cometbft/cometbft/crypto/ed25519" cometcryptoencoding "github.com/cometbft/cometbft/crypto/encoding" + cometjson "github.com/cometbft/cometbft/libs/json" + "github.com/cometbft/cometbft/privval" cometprotocrypto "github.com/cometbft/cometbft/proto/tendermint/crypto" amino "github.com/tendermint/go-amino" ) +/* +type ISignerKey interface { + MarshalJSON() ([]byte, error) + UnmarshalJSON(data []byte) error +} +*/ + // CosignerEd25519Key is a single Ed255219 key shard for an m-of-n threshold signer. type CosignerEd25519Key struct { PubKey cometcrypto.PubKey `json:"pubKey"` @@ -82,3 +92,24 @@ func (key *CosignerEd25519Key) UnmarshalJSON(data []byte) error { key.PubKey = pubkey return nil } + +// ReadPrivValidatorFile reads in a privval.FilePVKey from a given file. +func ReadPrivValidatorFile(priv string) (out privval.FilePVKey, err error) { + var bz []byte + if bz, err = os.ReadFile(priv); err != nil { + return + } + if err = cometjson.Unmarshal(bz, &out); err != nil { + return + } + return +} + +// WriteCosignerEd25519ShardFile writes a cosigner Ed25519 key to a given file name. +func WriteCosignerEd25519ShardFile(cosigner CosignerEd25519Key, file string) error { + jsonBytes, err := json.Marshal(&cosigner) + if err != nil { + return err + } + return os.WriteFile(file, jsonBytes, 0600) +} diff --git a/signer/threshold_signer.go b/pkg/thresholdTemP/threshold_signer.go similarity index 98% rename from signer/threshold_signer.go rename to pkg/thresholdTemP/threshold_signer.go index 676e15c4..e87a4f03 100644 --- a/signer/threshold_signer.go +++ b/pkg/thresholdTemP/threshold_signer.go @@ -1,4 +1,4 @@ -package signer +package thresholdTemP import ( "encoding/json" diff --git a/signer/threshold_signer_soft.go b/pkg/thresholdTemP/threshold_signer_soft.go similarity index 94% rename from signer/threshold_signer_soft.go rename to pkg/thresholdTemP/threshold_signer_soft.go index 38c7a471..96b3dc93 100644 --- a/signer/threshold_signer_soft.go +++ b/pkg/thresholdTemP/threshold_signer_soft.go @@ -1,4 +1,4 @@ -package signer +package thresholdTemP import ( "bytes" @@ -6,6 +6,7 @@ import ( "errors" "fmt" + "github.com/strangelove-ventures/horcrux/pkg/config" "github.com/strangelove-ventures/horcrux/pkg/types" "gitlab.com/unit410/edwards25519" @@ -21,7 +22,7 @@ type ThresholdSignerSoft struct { total uint8 } -func NewThresholdSignerSoft(config *RuntimeConfig, id int, chainID string) (*ThresholdSignerSoft, error) { +func NewThresholdSignerSoft(config *config.RuntimeConfig, id int, chainID string) (*ThresholdSignerSoft, error) { keyFile, err := config.KeyFileExistsCosigner(chainID) if err != nil { return nil, err diff --git a/signer/cosigner_grpc_server.go b/signer/cosigner_grpc_server.go index f0e8262f..f7c060c6 100644 --- a/signer/cosigner_grpc_server.go +++ b/signer/cosigner_grpc_server.go @@ -4,6 +4,8 @@ import ( "context" "fmt" + "github.com/strangelove-ventures/horcrux/pkg/nodes" + "github.com/strangelove-ventures/horcrux/pkg/types" "github.com/google/uuid" @@ -14,7 +16,7 @@ import ( var _ proto.CosignerServer = &CosignerGRPCServer{} type CosignerGRPCServer struct { - cosigner *LocalCosigner + cosigner *nodes.LocalCosigner thresholdValidator *ThresholdValidator raftStore *RaftStore // TODO: add logger and not rely on raftStore.logger @@ -22,7 +24,7 @@ type CosignerGRPCServer struct { } func NewCosignerGRPCServer( - cosigner *LocalCosigner, + cosigner *nodes.LocalCosigner, thresholdValidator *ThresholdValidator, raftStore *RaftStore, ) *CosignerGRPCServer { @@ -50,11 +52,11 @@ func (rpc *CosignerGRPCServer) SetNoncesAndSign( ctx context.Context, req *proto.SetNoncesAndSignRequest, ) (*proto.SetNoncesAndSignResponse, error) { - res, err := rpc.cosigner.SetNoncesAndSign(ctx, CosignerSetNoncesAndSignRequest{ + res, err := rpc.cosigner.SetNoncesAndSign(ctx, nodes.CosignerSetNoncesAndSignRequest{ ChainID: req.ChainID, - Nonces: &CosignerUUIDNonces{ + Nonces: &nodes.CosignerUUIDNonces{ UUID: uuid.UUID(req.Uuid), - Nonces: CosignerNoncesFromProto(req.GetNonces()), + Nonces: nodes.CosignerNoncesFromProto(req.GetNonces()), }, HRST: types.HRSTKeyFromProto(req.GetHrst()), SignBytes: req.GetSignBytes(), @@ -101,7 +103,7 @@ func (rpc *CosignerGRPCServer) GetNonces( } return &proto.GetNoncesResponse{ - Nonces: res.toProto(), + Nonces: res.ToProto(), }, nil } diff --git a/signer/cosigner_health.go b/signer/cosigner_health.go index 3c50e09b..90760b08 100644 --- a/signer/cosigner_health.go +++ b/signer/cosigner_health.go @@ -2,6 +2,7 @@ package signer import ( "context" + "github.com/strangelove-ventures/horcrux/pkg/nodes" "sort" "sync" "time" @@ -16,14 +17,14 @@ const ( type CosignerHealth struct { logger cometlog.Logger - cosigners []Cosigner + cosigners []nodes.Cosigner rtt map[int]int64 mu sync.RWMutex leader Leader } -func NewCosignerHealth(logger cometlog.Logger, cosigners []Cosigner, leader Leader) *CosignerHealth { +func NewCosignerHealth(logger cometlog.Logger, cosigners []nodes.Cosigner, leader Leader) *CosignerHealth { return &CosignerHealth{ logger: logger, cosigners: cosigners, @@ -39,7 +40,7 @@ func (ch *CosignerHealth) Reconcile(ctx context.Context) { var wg sync.WaitGroup wg.Add(len(ch.cosigners)) for _, cosigner := range ch.cosigners { - if rc, ok := cosigner.(*RemoteCosigner); ok { + if rc, ok := cosigner.(*nodes.RemoteCosigner); ok { go ch.updateRTT(ctx, rc, &wg) } } @@ -59,13 +60,13 @@ func (ch *CosignerHealth) Start(ctx context.Context) { } } -func (ch *CosignerHealth) MarkUnhealthy(cosigner Cosigner) { +func (ch *CosignerHealth) MarkUnhealthy(cosigner nodes.Cosigner) { ch.mu.Lock() defer ch.mu.Unlock() ch.rtt[cosigner.GetIndex()] = -1 } -func (ch *CosignerHealth) updateRTT(ctx context.Context, cosigner *RemoteCosigner, wg *sync.WaitGroup) { +func (ch *CosignerHealth) updateRTT(ctx context.Context, cosigner *nodes.RemoteCosigner, wg *sync.WaitGroup) { defer wg.Done() rtt := int64(-1) @@ -78,7 +79,7 @@ func (ch *CosignerHealth) updateRTT(ctx context.Context, cosigner *RemoteCosigne ctx, cancel := context.WithTimeout(ctx, 1*time.Second) defer cancel() - _, err := cosigner.client.Ping(ctx, &proto.PingRequest{}) + _, err := cosigner.Client.Ping(ctx, &proto.PingRequest{}) if err != nil { ch.logger.Error("Failed to ping", "cosigner", cosigner.GetIndex(), "error", err) return @@ -86,11 +87,11 @@ func (ch *CosignerHealth) updateRTT(ctx context.Context, cosigner *RemoteCosigne rtt = time.Since(start).Nanoseconds() } -func (ch *CosignerHealth) GetFastest() []Cosigner { +func (ch *CosignerHealth) GetFastest() []nodes.Cosigner { ch.mu.RLock() defer ch.mu.RUnlock() - fastest := make([]Cosigner, len(ch.cosigners)) + fastest := make([]nodes.Cosigner, len(ch.cosigners)) copy(fastest, ch.cosigners) sort.Slice(fastest, func(i, j int) bool { diff --git a/signer/cosigner_health_test.go b/signer/cosigner_health_test.go index 67dad1f1..7412603a 100644 --- a/signer/cosigner_health_test.go +++ b/signer/cosigner_health_test.go @@ -1,21 +1,24 @@ -package signer +package signer_test import ( "os" "testing" + "github.com/strangelove-ventures/horcrux/pkg/nodes" + "github.com/strangelove-ventures/horcrux/signer" + cometlog "github.com/cometbft/cometbft/libs/log" "github.com/stretchr/testify/require" ) func TestCosignerHealth(t *testing.T) { - ch := NewCosignerHealth( + ch := signer.NewCosignerHealth( cometlog.NewTMLogger(cometlog.NewSyncWriter(os.Stdout)), - []Cosigner{ - &RemoteCosigner{id: 2}, - &RemoteCosigner{id: 3}, - &RemoteCosigner{id: 4}, - &RemoteCosigner{id: 5}, + []nodes.Cosigner{ + &nodes.RemoteCosigner{id: 2}, + &nodes.RemoteCosigner{id: 3}, + &nodes.RemoteCosigner{id: 4}, + &nodes.RemoteCosigner{id: 5}, }, &MockLeader{id: 1}, ) diff --git a/signer/cosigner_nonce_cache.go b/signer/cosigner_nonce_cache.go index 865e7572..6c8021ef 100644 --- a/signer/cosigner_nonce_cache.go +++ b/signer/cosigner_nonce_cache.go @@ -7,6 +7,8 @@ import ( "sync/atomic" "time" + "github.com/strangelove-ventures/horcrux/pkg/nodes" + "github.com/strangelove-ventures/horcrux/pkg/metrics" cometlog "github.com/cometbft/cometbft/libs/log" @@ -21,7 +23,7 @@ const ( type CosignerNonceCache struct { logger cometlog.Logger - cosigners []Cosigner + cosigners []nodes.Cosigner leader Leader @@ -139,13 +141,13 @@ func (nc *NonceCache) PruneNonces() int { } type CosignerNoncesRel struct { - Cosigner Cosigner - Nonces CosignerNonces + Cosigner nodes.Cosigner + Nonces nodes.CosignerNonces } type CachedNonceSingle struct { - Cosigner Cosigner - Nonces CosignerUUIDNoncesMultiple + Cosigner nodes.Cosigner + Nonces nodes.CosignerUUIDNoncesMultiple } type CachedNonce struct { @@ -161,7 +163,7 @@ type CachedNonce struct { func NewCosignerNonceCache( logger cometlog.Logger, - cosigners []Cosigner, + cosigners []nodes.Cosigner, leader Leader, getNoncesInterval time.Duration, getNoncesTimeout time.Duration, @@ -351,12 +353,12 @@ func (cnc *CosignerNonceCache) Start(ctx context.Context) { } } -func (cnc *CosignerNonceCache) GetNonces(fastestPeers []Cosigner) (*CosignerUUIDNonces, error) { +func (cnc *CosignerNonceCache) GetNonces(fastestPeers []nodes.Cosigner) (*nodes.CosignerUUIDNonces, error) { cnc.cache.mu.Lock() defer cnc.cache.mu.Unlock() CheckNoncesLoop: for i, cn := range cnc.cache.cache { - var nonces CosignerNonces + var nonces nodes.CosignerNonces for _, p := range fastestPeers { found := false for _, n := range cn.Nonces { @@ -381,7 +383,7 @@ CheckNoncesLoop: } // all peers found - return &CosignerUUIDNonces{ + return &nodes.CosignerUUIDNonces{ UUID: cn.UUID, Nonces: nonces, }, nil @@ -398,7 +400,7 @@ CheckNoncesLoop: return nil, fmt.Errorf("no nonces found involving cosigners %+v", cosignerInts) } -func (cnc *CosignerNonceCache) ClearNonces(cosigner Cosigner) { +func (cnc *CosignerNonceCache) ClearNonces(cosigner nodes.Cosigner) { cnc.cache.mu.Lock() defer cnc.cache.mu.Unlock() for i := 0; i < len(cnc.cache.cache); i++ { diff --git a/signer/cosigner_nonce_cache_test.go b/signer/cosigner_nonce_cache_test.go index 2c65f175..6ad9defb 100644 --- a/signer/cosigner_nonce_cache_test.go +++ b/signer/cosigner_nonce_cache_test.go @@ -1,4 +1,4 @@ -package signer +package signer_test import ( "context" @@ -9,6 +9,7 @@ import ( cometlog "github.com/cometbft/cometbft/libs/log" "github.com/google/uuid" + "github.com/strangelove-ventures/horcrux/pkg/nodes" "github.com/stretchr/testify/require" ) @@ -57,7 +58,7 @@ func TestMovingAverage(t *testing.T) { func TestClearNonces(t *testing.T) { lcs, _ := getTestLocalCosigners(t, 2, 3) - cosigners := make([]Cosigner, len(lcs)) + cosigners := make([]nodes.Cosigner, len(lcs)) for i, lc := range lcs { cosigners[i] = lc } @@ -142,7 +143,7 @@ func (mp *mockPruner) Result() (int, int) { func TestNonceCacheDemand(t *testing.T) { lcs, _ := getTestLocalCosigners(t, 2, 3) - cosigners := make([]Cosigner, len(lcs)) + cosigners := make([]nodes.Cosigner, len(lcs)) for i, lc := range lcs { cosigners[i] = lc } @@ -169,7 +170,7 @@ func TestNonceCacheDemand(t *testing.T) { go nonceCache.Start(ctx) for i := 0; i < 3000; i++ { - _, err := nonceCache.GetNonces([]Cosigner{cosigners[0], cosigners[1]}) + _, err := nonceCache.GetNonces([]nodes.Cosigner{cosigners[0], cosigners[1]}) require.NoError(t, err) time.Sleep(10 * time.Millisecond) require.Greater(t, nonceCache.cache.Size(), 0) @@ -191,7 +192,7 @@ func TestNonceCacheDemand(t *testing.T) { func TestNonceCacheExpiration(t *testing.T) { lcs, _ := getTestLocalCosigners(t, 2, 3) - cosigners := make([]Cosigner, len(lcs)) + cosigners := make([]nodes.Cosigner, len(lcs)) for i, lc := range lcs { cosigners[i] = lc } @@ -402,7 +403,7 @@ func TestNonceCachePrune(t *testing.T) { func TestNonceCacheDemandSlow(t *testing.T) { lcs, _ := getTestLocalCosigners(t, 2, 3) - cosigners := make([]Cosigner, len(lcs)) + cosigners := make([]nodes.Cosigner, len(lcs)) for i, lc := range lcs { cosigners[i] = lc } @@ -425,7 +426,7 @@ func TestNonceCacheDemandSlow(t *testing.T) { for i := 0; i < 10; i++ { time.Sleep(200 * time.Millisecond) require.Greater(t, nonceCache.cache.Size(), 0) - _, err := nonceCache.GetNonces([]Cosigner{cosigners[0], cosigners[1]}) + _, err := nonceCache.GetNonces([]nodes.Cosigner{cosigners[0], cosigners[1]}) require.NoError(t, err) } @@ -439,7 +440,7 @@ func TestNonceCacheDemandSlowDefault(t *testing.T) { t.Skip() } lcs, _ := getTestLocalCosigners(t, 2, 3) - cosigners := make([]Cosigner, len(lcs)) + cosigners := make([]nodes.Cosigner, len(lcs)) for i, lc := range lcs { cosigners[i] = lc } @@ -462,7 +463,7 @@ func TestNonceCacheDemandSlowDefault(t *testing.T) { for i := 0; i < 10; i++ { time.Sleep(7 * time.Second) require.Greater(t, nonceCache.cache.Size(), 0) - _, err := nonceCache.GetNonces([]Cosigner{cosigners[0], cosigners[1]}) + _, err := nonceCache.GetNonces([]nodes.Cosigner{cosigners[0], cosigners[1]}) require.NoError(t, err) } diff --git a/signer/leader_mock.go b/signer/leader_mock_test.go similarity index 58% rename from signer/leader_mock.go rename to signer/leader_mock_test.go index daef26d9..fb54d42d 100644 --- a/signer/leader_mock.go +++ b/signer/leader_mock_test.go @@ -1,18 +1,24 @@ -package signer +package signer_test import ( "sync" + "github.com/strangelove-ventures/horcrux/pkg/nodes" "github.com/strangelove-ventures/horcrux/pkg/types" + "github.com/strangelove-ventures/horcrux/signer" ) -var _ Leader = (*MockLeader)(nil) +var _ signer.Leader = (*MockLeader)(nil) + +type MockThresholdValidator struct { + myCosigner *nodes.LocalCosigner +} type MockLeader struct { id int mu sync.Mutex - leader *ThresholdValidator + leader *MockThresholdValidator } func (m *MockLeader) IsLeader() bool { @@ -21,7 +27,7 @@ func (m *MockLeader) IsLeader() bool { return m.leader != nil && m.leader.myCosigner.GetIndex() == m.id } -func (m *MockLeader) SetLeader(tv *ThresholdValidator) { +func (m *MockLeader) SetLeader(tv *MockThresholdValidator) { m.mu.Lock() defer m.mu.Unlock() m.leader = tv diff --git a/signer/raft_store.go b/signer/raft_store.go index 27e2271a..963b0d70 100644 --- a/signer/raft_store.go +++ b/signer/raft_store.go @@ -10,6 +10,7 @@ package signer import ( "encoding/json" "fmt" + "github.com/strangelove-ventures/horcrux/pkg/nodes" "io" "net" "net/url" @@ -54,7 +55,7 @@ type RaftStore struct { RaftDir string RaftBind string RaftTimeout time.Duration - Cosigners []Cosigner + Cosigners []nodes.Cosigner mu sync.Mutex m map[string]string // The key-value store for the system. @@ -62,14 +63,14 @@ type RaftStore struct { raft *raft.Raft // The consensus mechanism logger log.Logger - cosigner *LocalCosigner + cosigner *nodes.LocalCosigner thresholdValidator *ThresholdValidator } // New returns a new Store. func NewRaftStore( nodeID string, directory string, bindAddress string, timeout time.Duration, - logger log.Logger, cosigner *LocalCosigner, cosigners []Cosigner) *RaftStore { + logger log.Logger, cosigner *nodes.LocalCosigner, cosigners []nodes.Cosigner) *RaftStore { cosignerRaftStore := &RaftStore{ NodeID: nodeID, RaftDir: directory, diff --git a/signer/raft_store_test.go b/signer/raft_store_test.go index c7b051e8..769f5136 100644 --- a/signer/raft_store_test.go +++ b/signer/raft_store_test.go @@ -1,4 +1,4 @@ -package signer +package signer_test import ( "crypto/rand" @@ -6,6 +6,8 @@ import ( "testing" "time" + "github.com/strangelove-ventures/horcrux/pkg/nodes" + cometcryptoed25519 "github.com/cometbft/cometbft/crypto/ed25519" "github.com/cometbft/cometbft/libs/log" "github.com/ethereum/go-ethereum/crypto/ecies" @@ -30,11 +32,11 @@ func Test_StoreInMemOpenSingleNode(t *testing.T) { ID: 1, } - cosigner := NewLocalCosigner( + cosigner := nodes.NewLocalCosigner( log.NewNopLogger(), &RuntimeConfig{}, - NewCosignerSecurityECIES( - CosignerECIESKey{ + nodes.NewCosignerSecurityECIES( + nodes.CosignerECIESKey{ ID: key.ID, ECIESKey: eciesKey, ECIESPubs: []*ecies.PublicKey{&eciesKey.PublicKey}, diff --git a/signer/single_signer_validator.go b/signer/single_signer_validator.go index 9d110d0b..9e9e286d 100644 --- a/signer/single_signer_validator.go +++ b/signer/single_signer_validator.go @@ -7,6 +7,7 @@ import ( "sync" "time" + "github.com/strangelove-ventures/horcrux/pkg/config" "github.com/strangelove-ventures/horcrux/pkg/connector" "github.com/strangelove-ventures/horcrux/pkg/types" @@ -17,7 +18,7 @@ var _ connector.PrivValidator = &SingleSignerValidator{} // SingleSignerValidator guards access to an underlying PrivValidator by using mutexes // for each of the PrivValidator interface functions type SingleSignerValidator struct { - config *RuntimeConfig + config *config.RuntimeConfig chainState sync.Map } @@ -33,7 +34,7 @@ type SingleSignerChainState struct { // NewSingleSignerValidator constructs a validator for single-sign mode (not recommended). // NewThresholdValidator is recommended, but single-sign mode can be used for convenience. -func NewSingleSignerValidator(config *RuntimeConfig) *SingleSignerValidator { +func NewSingleSignerValidator(config *config.RuntimeConfig) *SingleSignerValidator { return &SingleSignerValidator{ config: config, } diff --git a/signer/single_signer_validator_test.go b/signer/single_signer_validator_test.go index 81341e28..d896334c 100644 --- a/signer/single_signer_validator_test.go +++ b/signer/single_signer_validator_test.go @@ -1,11 +1,13 @@ -package signer +package signer_test import ( "context" "path/filepath" "time" + "github.com/strangelove-ventures/horcrux/pkg/config" "github.com/strangelove-ventures/horcrux/pkg/types" + "github.com/strangelove-ventures/horcrux/signer" "os" "testing" @@ -19,6 +21,12 @@ import ( "github.com/stretchr/testify/require" ) +const ( + testChainID = "chain-1" + testChainID2 = "chain-2" + BitSize = 4096 +) + func TestSingleSignerValidator(t *testing.T) { t.Skip("TODO: fix this test when run with 'make test'") @@ -28,7 +36,7 @@ func TestSingleSignerValidator(t *testing.T) { err := os.MkdirAll(stateDir, 0700) require.NoError(t, err) - runtimeConfig := &RuntimeConfig{ + runtimeConfig := &config.RuntimeConfig{ HomeDir: tmpDir, StateDir: filepath.Join(tmpDir, "state"), } @@ -48,7 +56,7 @@ func TestSingleSignerValidator(t *testing.T) { err = os.WriteFile(runtimeConfig.KeyFilePathSingleSigner("different"), marshaled, 0600) require.NoError(t, err) - validator := NewSingleSignerValidator(runtimeConfig) + validator := signer.NewSingleSignerValidator(runtimeConfig) proposal := cometproto.Proposal{ Height: 1, @@ -98,7 +106,7 @@ func TestSingleSignerValidator(t *testing.T) { require.NoError(t, err) // reinitialize validator to make sure new runtime will not allow double sign - validator = NewSingleSignerValidator(runtimeConfig) + validator = signer.NewSingleSignerValidator(runtimeConfig) _, _, err = validator.Sign(ctx, testChainID, types.ProposalToBlock(testChainID, &proposal)) require.Error(t, err, "double sign!") diff --git a/signer/threshold_signer_bls.go b/signer/threshold_signer_bls.go deleted file mode 100644 index bc8c9e15..00000000 --- a/signer/threshold_signer_bls.go +++ /dev/null @@ -1,106 +0,0 @@ -package signer - -import ( - "bytes" - "errors" - "fmt" - - "github.com/strangelove-ventures/horcrux/pkg/types" - - "gitlab.com/unit410/edwards25519" - tsed25519 "gitlab.com/unit410/threshold-ed25519/pkg" -) - -var _ ThresholdSigner = &ThresholdSignerSoftBLS{} - -type ThresholdSignerSoftBLS struct { - privateKeyShard []byte - pubKey []byte - threshold uint8 - total uint8 -} - -func NewThresholdSignerSoftBLS(config *RuntimeConfig, id int, chainID string) (*ThresholdSignerSoftBLS, error) { - keyFile, err := config.KeyFileExistsCosigner(chainID) - if err != nil { - return nil, err - } - - key, err := LoadThresholdSignerEd25519Key(keyFile) - if err != nil { - return nil, fmt.Errorf("error reading cosigner key: %s", err) - } - - if key.ID != id { - return nil, fmt.Errorf("key shard Index (%d) in (%s) does not match cosigner Index (%d)", key.ID, keyFile, id) - } - - s := ThresholdSignerSoftBLS{ - privateKeyShard: key.PrivateShard, - pubKey: key.PubKey.Bytes(), - threshold: uint8(config.Config.ThresholdModeConfig.Threshold), - total: uint8(len(config.Config.ThresholdModeConfig.Cosigners)), - } - - return &s, nil -} - -func (s *ThresholdSignerSoftBLS) GetPubKey() []byte { - return s.pubKey -} - -func (s *ThresholdSignerSoftBLS) Sign(nonces []types.Nonce, payload []byte) ([]byte, error) { - nonceShare, noncePub, err := s.sumNonces(nonces) - if err != nil { - return nil, fmt.Errorf("failed to combine nonces: %w", err) - } - - sig := tsed25519.SignWithShare( - payload, s.privateKeyShard, nonceShare, s.pubKey, noncePub) - return append(noncePub, sig...), nil -} - -func (s *ThresholdSignerSoftBLS) sumNonces(nonces []types.Nonce) (tsed25519.Scalar, tsed25519.Element, error) { - shareParts := make([]tsed25519.Scalar, len(nonces)) - publicKeys := make([]tsed25519.Element, len(nonces)) - - for i, n := range nonces { - shareParts[i] = n.Share - publicKeys[i] = n.PubKey - } - - nonceShare := tsed25519.AddScalars(shareParts) - noncePub := tsed25519.AddElements(publicKeys) - - // check bounds for ephemeral share to avoid passing out of bounds valids to SignWithShare - if len(nonceShare) != 32 { - return nil, nil, errors.New("ephemeral share is out of bounds") - } - - var scalarBytes [32]byte - copy(scalarBytes[:], nonceShare) - if !edwards25519.ScMinimal(&scalarBytes) { - return nil, nil, errors.New("ephemeral share is out of bounds") - } - - return nonceShare, noncePub, nil -} - -func (s *ThresholdSignerSoftBLS) CombineSignatures(signatures []types.PartialSignature) ([]byte, error) { - sigIds := make([]int, len(signatures)) - shareSigs := make([][]byte, len(signatures)) - var ephPub []byte - - for i, sig := range signatures { - sigIds[i] = sig.Index - if i == 0 { - ephPub = sig.Signature[:32] - } else if !bytes.Equal(sig.Signature[:32], ephPub) { - return nil, fmt.Errorf("ephemeral public keys do not match") - } - shareSigs[i] = sig.Signature[32:] - } - combinedSig := tsed25519.CombineShares(s.total, sigIds, shareSigs) - - return append(ephPub, combinedSig...), nil -} diff --git a/signer/threshold_validator.go b/signer/threshold_validator.go index 6572c67f..a52515fa 100644 --- a/signer/threshold_validator.go +++ b/signer/threshold_validator.go @@ -10,6 +10,9 @@ import ( "sync" "time" + "github.com/strangelove-ventures/horcrux/pkg/nodes" + + "github.com/strangelove-ventures/horcrux/pkg/config" "github.com/strangelove-ventures/horcrux/pkg/connector" "github.com/strangelove-ventures/horcrux/pkg/metrics" @@ -25,8 +28,23 @@ import ( var _ connector.PrivValidator = &ThresholdValidator{} +// TODO: Must be a better way to do this? +type nodecacheconfigs struct { + defaultGetNoncesInterval time.Duration + defaultGetNoncesTimeout time.Duration + defaultNonceExpiration time.Duration +} + +func nodecacheconfig() nodecacheconfigs { + return nodecacheconfigs{ + defaultGetNoncesInterval: config.DefaultGetNoncesInterval, + defaultGetNoncesTimeout: config.DefaultGetNoncesTimeout, + defaultNonceExpiration: config.DefaultNonceExpiration, + } +} + type ThresholdValidator struct { - config *RuntimeConfig + config *config.RuntimeConfig threshold int @@ -35,10 +53,10 @@ type ThresholdValidator struct { chainState sync.Map // map[string]SignState, chainState["chainid"] -> types.SignState // our own cosigner - myCosigner *LocalCosigner + myCosigner *nodes.LocalCosigner // peer cosigners - peerCosigners Cosigners + peerCosigners nodes.Cosigners leader Leader @@ -50,9 +68,37 @@ type ThresholdValidator struct { cosignerHealth *CosignerHealth + // FIX: This f-up a lot. Now its like 3-4 places that + // spaggettio leaders, cosigners etc etc nonceCache *CosignerNonceCache } +type StillWaitingForBlockError struct { + msg string +} + +func (e *StillWaitingForBlockError) Error() string { return e.msg } + +func newStillWaitingForBlockError(chainID string, hrs types.HRSKey) *StillWaitingForBlockError { + return &StillWaitingForBlockError{ + msg: fmt.Sprintf("[%s] Still waiting for block %d.%d.%d", + chainID, hrs.Height, hrs.Round, hrs.Step), + } +} + +type SameBlockError struct { + msg string +} + +func (e *SameBlockError) Error() string { return e.msg } + +func newSameBlockError(chainID string, hrs types.HRSKey) *SameBlockError { + return &SameBlockError{ + msg: fmt.Sprintf("[%s] Same block: %d.%d.%d", + chainID, hrs.Height, hrs.Round, hrs.Step), + } +} + type ChainSignState struct { // stores the last sign state for a block we have fully signed // Cached to respond to SignVote requests if we already have a signature @@ -64,18 +110,37 @@ type ChainSignState struct { lastSignStateInitiatedMutex *sync.Mutex } +type BeyondBlockError struct { + msg string +} + +func (e *BeyondBlockError) Error() string { return e.msg } + +func (pv *ThresholdValidator) newBeyondBlockError(chainID string, hrs types.HRSKey) *BeyondBlockError { + css := pv.mustLoadChainState(chainID) + + lss := css.lastSignStateInitiated + return &BeyondBlockError{ + msg: fmt.Sprintf("[%s] Progress already started on block %d.%d.%d, skipping %d.%d.%d", + chainID, + lss.Height, lss.Round, lss.Step, + hrs.Height, hrs.Round, hrs.Step, + ), + } +} + // NewThresholdValidator creates and returns a new ThresholdValidator func NewThresholdValidator( logger log.Logger, - config *RuntimeConfig, + config *config.RuntimeConfig, threshold int, grpcTimeout time.Duration, maxWaitForSameBlockAttempts int, - myCosigner *LocalCosigner, - peerCosigners []Cosigner, + myCosigner *nodes.LocalCosigner, + peerCosigners []nodes.Cosigner, leader Leader, ) *ThresholdValidator { - allCosigners := make([]Cosigner, len(peerCosigners)+1) + allCosigners := make([]nodes.Cosigner, len(peerCosigners)+1) allCosigners[0] = myCosigner copy(allCosigners[1:], peerCosigners) @@ -83,13 +148,14 @@ func NewThresholdValidator( logger.Debug("Peer cosigner", "id", cosigner.GetIndex()) } + nodecacheconfig := nodecacheconfig() nc := NewCosignerNonceCache( logger, allCosigners, leader, - defaultGetNoncesInterval, - defaultGetNoncesTimeout, - defaultNonceExpiration, + nodecacheconfig.defaultGetNoncesInterval, + nodecacheconfig.defaultGetNoncesTimeout, + nodecacheconfig.defaultNonceExpiration, uint8(threshold), nil, ) @@ -272,7 +338,7 @@ func (pv *ThresholdValidator) Stop() { func (pv *ThresholdValidator) waitForSignStatesToFlushToDisk() { pv.pendingDiskWG.Wait() - pv.myCosigner.waitForSignStatesToFlushToDisk() + pv.myCosigner.WaitForSignStatesToFlushToDisk() } // GetPubKey returns the public key of the validator. @@ -285,39 +351,6 @@ func (pv *ThresholdValidator) GetPubKey(_ context.Context, chainID string) ([]by return pubKey.Bytes(), nil } -func (pv *ThresholdValidator) newBeyondBlockError(chainID string, hrs types.HRSKey) *metrics.BeyondBlockError { - css := pv.mustLoadChainState(chainID) - - lss := css.lastSignStateInitiated - return &metrics.BeyondBlockError{ - Msg: fmt.Sprintf("[%s] Progress already started on block %d.%d.%d, skipping %d.%d.%d", - chainID, - lss.Height, lss.Round, lss.Step, - hrs.Height, hrs.Round, hrs.Step, - ), - } -} - -type StillWaitingForBlockError struct { - msg string -} - -func (e *StillWaitingForBlockError) Error() string { return e.msg } - -func newStillWaitingForBlockError(chainID string, hrs types.HRSKey) *StillWaitingForBlockError { - return &StillWaitingForBlockError{ - msg: fmt.Sprintf("[%s] Still waiting for block %d.%d.%d", - chainID, hrs.Height, hrs.Round, hrs.Step), - } -} - -func newSameBlockError(chainID string, hrs types.HRSKey) *metrics.SameBlockError { - return &metrics.SameBlockError{ - Msg: fmt.Sprintf("[%s] Same block: %d.%d.%d", - chainID, hrs.Height, hrs.Round, hrs.Step), - } -} - func (pv *ThresholdValidator) LoadSignStateIfNecessary(chainID string) error { if _, ok := pv.chainState.Load(chainID); ok { return nil @@ -418,8 +451,8 @@ func (pv *ThresholdValidator) compareBlockSignatureAgainstHRS( func (pv *ThresholdValidator) getNoncesFallback( ctx context.Context, -) (*CosignerUUIDNonces, []Cosigner, error) { - nonces := make(map[Cosigner]CosignerNonces) +) (*nodes.CosignerUUIDNonces, []nodes.Cosigner, error) { + nonces := make(map[nodes.Cosigner]nodes.CosignerNonces) metrics.DrainedNonceCache.Inc() metrics.TotalDrainedNonceCache.Inc() @@ -431,7 +464,7 @@ func (pv *ThresholdValidator) getNoncesFallback( u := uuid.New() - allCosigners := make([]Cosigner, len(pv.peerCosigners)+1) + allCosigners := make([]nodes.Cosigner, len(pv.peerCosigners)+1) allCosigners[0] = pv.myCosigner copy(allCosigners[1:], pv.peerCosigners) @@ -445,8 +478,8 @@ func (pv *ThresholdValidator) getNoncesFallback( return nil, nil, errors.New("timed out waiting for ephemeral shares") } - var thresholdNonces CosignerNonces - thresholdCosigners := make([]Cosigner, len(nonces)) + var thresholdNonces nodes.CosignerNonces + thresholdCosigners := make([]nodes.Cosigner, len(nonces)) i := 0 for c, n := range nonces { thresholdCosigners[i] = c @@ -455,7 +488,7 @@ func (pv *ThresholdValidator) getNoncesFallback( thresholdNonces = append(thresholdNonces, n...) } - return &CosignerUUIDNonces{ + return &nodes.CosignerUUIDNonces{ UUID: u, Nonces: thresholdNonces, }, thresholdCosigners, nil @@ -478,9 +511,9 @@ func waitUntilCompleteOrTimeout(wg *sync.WaitGroup, timeout time.Duration) bool func (pv *ThresholdValidator) waitForPeerNonces( ctx context.Context, u uuid.UUID, - peer Cosigner, + peer nodes.Cosigner, wg *sync.WaitGroup, - nonces map[Cosigner]CosignerNonces, + nonces map[nodes.Cosigner]nodes.CosignerNonces, mu sync.Locker, ) { peerStartTime := time.Now() @@ -546,7 +579,7 @@ func (pv *ThresholdValidator) proxyIfNecessary( return true, nil, stamp, fmt.Errorf("failed to find cosigner with id %d", leader) } - signRes, err := cosignerLeader.(*RemoteCosigner).Sign(ctx, CosignerSignBlockRequest{ + signRes, err := cosignerLeader.(*nodes.RemoteCosigner).Sign(ctx, nodes.CosignerSignBlockRequest{ ChainID: chainID, Block: &block, }) @@ -613,7 +646,7 @@ func (pv *ThresholdValidator) Sign(ctx context.Context, chainID string, block ty peerStartTime := time.Now() cosignersOrderedByFastest := pv.cosignerHealth.GetFastest() - cosignersForThisBlock := make([]Cosigner, pv.threshold) + cosignersForThisBlock := make([]nodes.Cosigner, pv.threshold) cosignersForThisBlock[0] = pv.myCosigner copy(cosignersForThisBlock[1:], cosignersOrderedByFastest[:pv.threshold-1]) @@ -635,7 +668,7 @@ func (pv *ThresholdValidator) Sign(ctx context.Context, chainID string, block ty nextFastestCosignerIndex := pv.threshold - 1 var nextFastestCosignerIndexMu sync.Mutex - getNextFastestCosigner := func() Cosigner { + getNextFastestCosigner := func() nodes.Cosigner { nextFastestCosignerIndexMu.Lock() defer nextFastestCosignerIndexMu.Unlock() if nextFastestCosignerIndex >= len(cosignersOrderedByFastest) { @@ -673,7 +706,7 @@ func (pv *ThresholdValidator) Sign(ctx context.Context, chainID string, block ty peerStartTime := time.Now() // set peerNonces and sign in single rpc call. - sigRes, err := cosigner.SetNoncesAndSign(signCtx, CosignerSetNoncesAndSignRequest{ + sigRes, err := cosigner.SetNoncesAndSign(signCtx, nodes.CosignerSetNoncesAndSignRequest{ ChainID: chainID, Nonces: nonces.For(cosigner.GetIndex()), HRST: hrst, @@ -686,7 +719,7 @@ func (pv *ThresholdValidator) Sign(ctx context.Context, chainID string, block ty "err", err.Error(), ) - if strings.Contains(err.Error(), errUnexpectedState) { + if strings.Contains(err.Error(), nodes.ErrUnexpectedState) { pv.nonceCache.ClearNonces(cosigner) } diff --git a/signer/threshold_validator_test.go b/signer/threshold_validator_test.go index 95aca51d..762aa9d2 100644 --- a/signer/threshold_validator_test.go +++ b/signer/threshold_validator_test.go @@ -1,4 +1,4 @@ -package signer +package signer_test import ( "bytes" @@ -10,6 +10,9 @@ import ( "sync" "time" + "github.com/strangelove-ventures/horcrux/pkg/nodes" + "github.com/strangelove-ventures/horcrux/pkg/thresholdTemP" + "github.com/strangelove-ventures/horcrux/pkg/types" "os" @@ -46,12 +49,12 @@ func TestThresholdValidator3of5(t *testing.T) { } func loadKeyForLocalCosigner( - cosigner *LocalCosigner, + cosigner *nodes.LocalCosigner, pubKey cometcrypto.PubKey, chainID string, privateShard []byte, ) error { - key := CosignerEd25519Key{ + key := thresholdTemP.CosignerEd25519Key{ PubKey: pubKey, PrivateShard: privateShard, ID: cosigner.GetIndex(), @@ -68,7 +71,7 @@ func loadKeyForLocalCosigner( func testThresholdValidator(t *testing.T, threshold, total uint8) { cosigners, pubKey := getTestLocalCosigners(t, threshold, total) - thresholdCosigners := make([]Cosigner, 0, threshold-1) + thresholdCosigners := make([]nodes.Cosigner, 0, threshold-1) for i, cosigner := range cosigners { require.Equal(t, i+1, cosigner.GetIndex()) @@ -96,7 +99,7 @@ func testThresholdValidator(t *testing.T, threshold, total uint8) { ctx := context.Background() - err := validator.LoadSignStateIfNecessary(testChainID) + err := validator.LoadSignStateIfNecessary(nodes.testChainID) require.NoError(t, err) proposal := cometproto.Proposal{ @@ -105,9 +108,9 @@ func testThresholdValidator(t *testing.T, threshold, total uint8) { Type: cometproto.ProposalType, } - block := types.ProposalToBlock(testChainID, &proposal) + block := types.ProposalToBlock(nodes.testChainID, &proposal) - signature, _, err := validator.Sign(ctx, testChainID, block) + signature, _, err := validator.Sign(ctx, nodes.testChainID, block) require.NoError(t, err) require.True(t, pubKey.VerifySignature(block.SignBytes, signature)) @@ -123,12 +126,12 @@ func testThresholdValidator(t *testing.T, threshold, total uint8) { Timestamp: time.Now(), } - block = types.ProposalToBlock(testChainID, &proposal) + block = types.ProposalToBlock(nodes.testChainID, &proposal) validator.nonceCache.LoadN(ctx, 1) // should be able to sign same proposal with only differing timestamp - _, _, err = validator.Sign(ctx, testChainID, block) + _, _, err = validator.Sign(ctx, nodes.testChainID, block) require.NoError(t, err) // construct different block Index for proposal at same height as highest signed @@ -147,7 +150,7 @@ func testThresholdValidator(t *testing.T, threshold, total uint8) { // different than single-signer mode, threshold mode will be successful for this, // but it will return the same signature as before. - signature, _, err = validator.Sign(ctx, testChainID, types.ProposalToBlock(testChainID, &proposal)) + signature, _, err = validator.Sign(ctx, nodes.testChainID, types.ProposalToBlock(nodes.testChainID, &proposal)) require.NoError(t, err) require.True(t, bytes.Equal(firstSignature, signature)) @@ -157,13 +160,13 @@ func testThresholdValidator(t *testing.T, threshold, total uint8) { validator.nonceCache.LoadN(ctx, 1) // should not be able to sign lower than highest signed - _, _, err = validator.Sign(ctx, testChainID, types.ProposalToBlock(testChainID, &proposal)) + _, _, err = validator.Sign(ctx, nodes.testChainID, types.ProposalToBlock(nodes.testChainID, &proposal)) require.Error(t, err, "double sign!") validator.nonceCache.LoadN(ctx, 1) // lower LSS should sign for different chain Index - _, _, err = validator.Sign(ctx, testChainID2, types.ProposalToBlock(testChainID2, &proposal)) + _, _, err = validator.Sign(ctx, nodes.testChainID2, types.ProposalToBlock(nodes.testChainID2, &proposal)) require.NoError(t, err) // reinitialize validator to make sure new runtime will not allow double sign @@ -181,7 +184,7 @@ func testThresholdValidator(t *testing.T, threshold, total uint8) { newValidator.nonceCache.LoadN(ctx, 1) - _, _, err = newValidator.Sign(ctx, testChainID, types.ProposalToBlock(testChainID, &proposal)) + _, _, err = newValidator.Sign(ctx, nodes.testChainID, types.ProposalToBlock(nodes.testChainID, &proposal)) require.Error(t, err, "double sign!") proposal = cometproto.Proposal{ @@ -202,15 +205,15 @@ func testThresholdValidator(t *testing.T, threshold, total uint8) { newValidator.nonceCache.LoadN(ctx, 3) eg.Go(func() error { - _, _, err := newValidator.Sign(ctx, testChainID, types.ProposalToBlock(testChainID, &proposal)) + _, _, err := newValidator.Sign(ctx, nodes.testChainID, types.ProposalToBlock(nodes.testChainID, &proposal)) return err }) eg.Go(func() error { - _, _, err := newValidator.Sign(ctx, testChainID, types.ProposalToBlock(testChainID, &proposalClone)) + _, _, err := newValidator.Sign(ctx, nodes.testChainID, types.ProposalToBlock(nodes.testChainID, &proposalClone)) return err }) eg.Go(func() error { - _, _, err := newValidator.Sign(ctx, testChainID, types.ProposalToBlock(testChainID, &proposalClone2)) + _, _, err := newValidator.Sign(ctx, nodes.testChainID, types.ProposalToBlock(nodes.testChainID, &proposalClone2)) return err }) // signing higher block now should succeed @@ -236,19 +239,19 @@ func testThresholdValidator(t *testing.T, threshold, total uint8) { eg.Go(func() error { start := time.Now() - _, _, err := newValidator.Sign(ctx, testChainID, types.VoteToBlock(testChainID, &prevote)) + _, _, err := newValidator.Sign(ctx, nodes.testChainID, types.VoteToBlock(nodes.testChainID, &prevote)) t.Log("Sign time", "duration", time.Since(start)) return err }) eg.Go(func() error { start := time.Now() - _, _, err := newValidator.Sign(ctx, testChainID, types.VoteToBlock(testChainID, &prevoteClone)) + _, _, err := newValidator.Sign(ctx, nodes.testChainID, types.VoteToBlock(nodes.testChainID, &prevoteClone)) t.Log("Sign time", "duration", time.Since(start)) return err }) eg.Go(func() error { start := time.Now() - _, _, err := newValidator.Sign(ctx, testChainID, types.VoteToBlock(testChainID, &prevoteClone2)) + _, _, err := newValidator.Sign(ctx, nodes.testChainID, types.VoteToBlock(nodes.testChainID, &prevoteClone2)) t.Log("Sign time", "duration", time.Since(start)) return err }) @@ -274,18 +277,18 @@ func testThresholdValidator(t *testing.T, threshold, total uint8) { eg.Go(func() error { start := time.Now() t.Log("Sign time", "duration", time.Since(start)) - _, _, err := newValidator.Sign(ctx, testChainID, types.VoteToBlock(testChainID, &precommit)) + _, _, err := newValidator.Sign(ctx, nodes.testChainID, types.VoteToBlock(nodes.testChainID, &precommit)) return err }) eg.Go(func() error { start := time.Now() t.Log("Sign time", "duration", time.Since(start)) - _, _, err := newValidator.Sign(ctx, testChainID, types.VoteToBlock(testChainID, &precommitClone)) + _, _, err := newValidator.Sign(ctx, nodes.testChainID, types.VoteToBlock(nodes.testChainID, &precommitClone)) return err }) eg.Go(func() error { start := time.Now() - _, _, err := newValidator.Sign(ctx, testChainID, types.VoteToBlock(testChainID, &precommitClone2)) + _, _, err := newValidator.Sign(ctx, nodes.testChainID, types.VoteToBlock(nodes.testChainID, &precommitClone2)) t.Log("Sign time", "duration", time.Since(start)) return err }) @@ -295,10 +298,10 @@ func testThresholdValidator(t *testing.T, threshold, total uint8) { } } -func getTestLocalCosigners(t *testing.T, threshold, total uint8) ([]*LocalCosigner, cometcrypto.PubKey) { +func getTestLocalCosigners(t *testing.T, threshold, total uint8) ([]*nodes.LocalCosigner, cometcrypto.PubKey) { eciesKeys := make([]*ecies.PrivateKey, total) pubKeys := make([]*ecies.PublicKey, total) - cosigners := make([]*LocalCosigner, total) + cosigners := make([]*nodes.LocalCosigner, total) for i := uint8(0); i < total; i++ { eciesKey, err := ecies.GenerateKey(rand.Reader, secp256k1.S256(), nil) @@ -333,17 +336,17 @@ func getTestLocalCosigners(t *testing.T, threshold, total uint8) ([]*LocalCosign StateDir: cosignerDir, Config: Config{ ThresholdModeConfig: &ThresholdModeConfig{ - Threshold: int(threshold), - Cosigners: cosignersConfig, + Threshold: int(threshold), + nodes.Cosigners: cosignersConfig, }, }, } - cosigner := NewLocalCosigner( + cosigner := nodes.NewLocalCosigner( cometlog.NewNopLogger(), cosignerConfig, - NewCosignerSecurityECIES( - CosignerECIESKey{ + nodes.NewCosignerSecurityECIES( + nodes.CosignerECIESKey{ ID: i + 1, ECIESKey: eciesKeys[i], ECIESPubs: pubKeys, @@ -355,10 +358,10 @@ func getTestLocalCosigners(t *testing.T, threshold, total uint8) ([]*LocalCosign cosigners[i] = cosigner - err = loadKeyForLocalCosigner(cosigner, privateKey.PubKey(), testChainID, privShards[i]) + err = loadKeyForLocalCosigner(cosigner, privateKey.PubKey(), nodes.testChainID, privShards[i]) require.NoError(t, err) - err = loadKeyForLocalCosigner(cosigner, privateKey.PubKey(), testChainID2, privShards[i]) + err = loadKeyForLocalCosigner(cosigner, privateKey.PubKey(), nodes.testChainID2, privShards[i]) require.NoError(t, err) } @@ -375,7 +378,7 @@ func testThresholdValidatorLeaderElection(t *testing.T, threshold, total uint8) ctx := context.Background() for i, cosigner := range cosigners { - peers := make([]Cosigner, 0, len(cosigners)-1) + peers := make([]nodes.Cosigner, 0, len(cosigners)-1) for j, otherCosigner := range cosigners { if i != j { peers = append(peers, otherCosigner) @@ -400,7 +403,7 @@ func testThresholdValidatorLeaderElection(t *testing.T, threshold, total uint8) thresholdValidators = append(thresholdValidators, tv) defer tv.Stop() - err := tv.LoadSignStateIfNecessary(testChainID) + err := tv.LoadSignStateIfNecessary(nodes.testChainID) require.NoError(t, err) require.NoError(t, tv.Start(ctx)) @@ -459,13 +462,13 @@ func testThresholdValidatorLeaderElection(t *testing.T, threshold, total uint8) Type: cometproto.ProposalType, } - signature, _, err := tv.Sign(ctx, testChainID, types.ProposalToBlock(testChainID, &proposal)) + signature, _, err := tv.Sign(ctx, nodes.testChainID, types.ProposalToBlock(nodes.testChainID, &proposal)) if err != nil { t.Log("Proposal sign failed", "error", err) return } - signBytes := comet.ProposalSignBytes(testChainID, &proposal) + signBytes := comet.ProposalSignBytes(nodes.testChainID, &proposal) sig := make([]byte, len(signature)) copy(sig, signature) @@ -501,13 +504,13 @@ func testThresholdValidatorLeaderElection(t *testing.T, threshold, total uint8) Type: cometproto.PrevoteType, } - signature, _, err := tv.Sign(ctx, testChainID, types.VoteToBlock(testChainID, &preVote)) + signature, _, err := tv.Sign(ctx, nodes.testChainID, types.VoteToBlock(nodes.testChainID, &preVote)) if err != nil { t.Log("PreVote sign failed", "error", err) return } - signBytes := comet.VoteSignBytes(testChainID, &preVote) + signBytes := comet.VoteSignBytes(nodes.testChainID, &preVote) sig := make([]byte, len(signature)) copy(sig, signature) @@ -543,13 +546,13 @@ func testThresholdValidatorLeaderElection(t *testing.T, threshold, total uint8) Type: cometproto.PrecommitType, } - signature, _, err := tv.Sign(ctx, testChainID, types.VoteToBlock(testChainID, &preCommit)) + signature, _, err := tv.Sign(ctx, nodes.testChainID, types.VoteToBlock(nodes.testChainID, &preCommit)) if err != nil { t.Log("PreCommit sign failed", "error", err) return } - signBytes := comet.VoteSignBytes(testChainID, &preCommit) + signBytes := comet.VoteSignBytes(nodes.testChainID, &preCommit) sig := make([]byte, len(signature)) copy(sig, signature) diff --git a/test/go.sum b/test/go.sum index c5533b23..5b5c08b5 100644 --- a/test/go.sum +++ b/test/go.sum @@ -172,6 +172,7 @@ cloud.google.com/go/storage v1.22.1/go.mod h1:S8N1cAStu7BOeFfE8KAQzmyyLkK8p/vmRq cloud.google.com/go/storage v1.23.0/go.mod h1:vOEEDNFnciUMhBeT6hsJIn3ieU5cFRmzeLgDvXzfIXc= cloud.google.com/go/storage v1.27.0/go.mod h1:x9DOL8TK/ygDUMieqwfhdpQryTeEkhGKMi80i/iqR2s= cloud.google.com/go/storage v1.35.1 h1:B59ahL//eDfx2IIKFBeT5Atm9wnNmj3+8xG/W4WB//w= +cloud.google.com/go/storage v1.35.1/go.mod h1:M6M/3V/D3KpzMTJyPOR/HU6n2Si5QdaXYEsng2xgOs8= cloud.google.com/go/talent v1.1.0/go.mod h1:Vl4pt9jiHKvOgF9KoZo6Kob9oV4lwd/ZD5Cto54zDRw= cloud.google.com/go/talent v1.2.0/go.mod h1:MoNF9bhFQbiJ6eFD3uSsg0uBALw4n4gaCaEjBw9zo8g= cloud.google.com/go/videointelligence v1.6.0/go.mod h1:w0DIDlVRKtwPCn/C4iwZIJdvC69yInhW0cfi+p546uU= @@ -418,6 +419,7 @@ github.com/danieljoos/wincred v1.1.2/go.mod h1:GijpziifJoIBfYh+S7BbkdUTU4LfM+QnG github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/deckarep/golang-set v1.8.0 h1:sk9/l/KqpunDwP7pSjUg0keiOOLEnOBHzykLrsPppp4= github.com/deckarep/golang-set v1.8.0/go.mod h1:5nI87KwE7wgsBU1F4GKAw2Qod7p5kyS383rP6+o6qqo= github.com/deckarep/golang-set/v2 v2.1.0 h1:g47V4Or+DUdzbs8FxCCmgb6VYd+ptPAngjM6dtGktsI= @@ -483,6 +485,7 @@ github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5Kwzbycv github.com/fatih/color v1.12.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= +github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= @@ -490,10 +493,12 @@ github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHqu github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= +github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= +github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/getsentry/sentry-go v0.25.0 h1:q6Eo+hS+yoJlTO3uu/azhQadsD8V+jQn2D8VvX1eOyI= github.com/getsentry/sentry-go v0.25.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= @@ -725,6 +730,7 @@ github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdv github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= +github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek= github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= @@ -950,6 +956,7 @@ github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1y github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= github.com/onsi/gomega v1.28.1 h1:MijcGUbfYuznzK/5R4CPNoUP/9Xvuo20sXfEm6XxoTA= +github.com/onsi/gomega v1.28.1/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= @@ -1056,7 +1063,9 @@ github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQD github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ= +github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4= github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= +github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= github.com/sasha-s/go-deadlock v0.3.1 h1:sqv7fDNShgjcaxkO0JNcOAlr8B9+cV5Ey/OB71efZx0= github.com/sasha-s/go-deadlock v0.3.1/go.mod h1:F73l+cr82YSh10GxyRI6qZiCgK64VaZjwesgfQ1/iLM= @@ -1075,13 +1084,16 @@ github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9 github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= +github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= +github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= +github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= @@ -1093,6 +1105,7 @@ github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/spf13/viper v1.17.0 h1:I5txKw7MJasPL/BrfkbA0Jyo/oELqVmux4pR/UxOMfI= +github.com/spf13/viper v1.17.0/go.mod h1:BmMMMLQXSbcHK6KAOiFLz0l5JHrU89OdIRHvsk0+yVI= github.com/strangelove-ventures/interchaintest/v8 v8.0.0 h1:z6hz23NJEhRJxZUH1vuDNTVscRwnUii+K4En9lfyndc= github.com/strangelove-ventures/interchaintest/v8 v8.0.0/go.mod h1:0LEZ1dXKlAYOm18X6s8AC4y5e6uAjJ0L69A6JpUkjDc= github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= @@ -1117,6 +1130,7 @@ github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= +github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d h1:vfofYNRScrDdvS342BElfbETmL1Aiz3i2t0zfRj16Hs= github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d/go.mod h1:RRCYJbIwD5jmqPI9XoAFR0OcDxqUctll6zUj/+B4S48= github.com/tendermint/go-amino v0.16.0 h1:GyhmgQKvqF82e2oZeuMSp9JTN0N09emoSZlb2lyGa2E= @@ -1207,6 +1221,7 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.16.0 h1:mMMrFzRSCF0GvB7Ne27XVtVAaXLrPmgPC7/v0tkwHaY= +golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1219,6 +1234,7 @@ golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EH golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= golang.org/x/exp v0.0.0-20231127185646-65229373498e h1:Gvh4YaCaXNs6dKTlfgismwWZKyjVZXwOPfIyUaqU3No= +golang.org/x/exp v0.0.0-20231127185646-65229373498e/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1308,6 +1324,7 @@ golang.org/x/net v0.0.0-20220909164309-bea034e7d591/go.mod h1:YDH+HFinaLZZlnHAfS golang.org/x/net v0.0.0-20221014081412-f15817d10f9b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= +golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1334,6 +1351,7 @@ golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1/go.mod h1:h4gKUeWbJ4rQPri golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= golang.org/x/oauth2 v0.1.0/go.mod h1:G9FE4dLTsbXUu90h/Pf85g4w1D+SSAgR+q46nJZ8M4A= golang.org/x/oauth2 v0.15.0 h1:s8pnnxNVzjWyrvYdFUQq5llS1PX2zhPXmccZv99h7uQ= +golang.org/x/oauth2 v0.15.0/go.mod h1:q48ptWNTY5XWf+JNten23lcvHpLJ0ZSxF5ttTHKVCAM= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1453,10 +1471,12 @@ golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= +golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4= +golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1475,6 +1495,7 @@ golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= +golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -1538,6 +1559,7 @@ golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.16.0 h1:GO788SKMRunPIBCXiQyo2AaexLstOrVhuAL5YwsckQM= +golang.org/x/tools v0.16.0/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1598,6 +1620,7 @@ google.golang.org/api v0.97.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ google.golang.org/api v0.98.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= google.golang.org/api v0.100.0/go.mod h1:ZE3Z2+ZOr87Rx7dqFsdRQkRBk36kDtp/h+QpHbB7a70= google.golang.org/api v0.152.0 h1:t0r1vPnfMc260S2Ci+en7kfCZaLOPs5KI0sVV/6jZrY= +google.golang.org/api v0.152.0/go.mod h1:3qNJX5eOmhiWYc67jRA/3GsDw97UFb5ivv7Y2PrriAY= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -1720,6 +1743,7 @@ google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17/go.mod h1:J7XzRzVy google.golang.org/genproto/googleapis/api v0.0.0-20231106174013-bbf56f31fb17 h1:JpwMPBpFN3uKhdaekDpiNlImDdkUAyiJ6ez/uxGaUSo= google.golang.org/genproto/googleapis/api v0.0.0-20231106174013-bbf56f31fb17/go.mod h1:0xJLfVdJqpAPl8tDg1ujOCGzx6LFLttXT5NhllGOXY4= google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f h1:ultW7fxlIvee4HYrtnaRPon9HpEgFk5zYpmfMgtKB5I= +google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f/go.mod h1:L9KNLi232K1/xB6f7AlSX692koaRnKaWSR0stBki0Yc= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= diff --git a/test/horcrux_test.go b/test/horcrux_test.go index 4f15bf4a..00b9a0f1 100644 --- a/test/horcrux_test.go +++ b/test/horcrux_test.go @@ -6,9 +6,12 @@ import ( "sync" "testing" + "github.com/strangelove-ventures/horcrux/pkg/nodes/nodesecurity" + "github.com/cometbft/cometbft/crypto" dockertypes "github.com/docker/docker/api/types" - "github.com/strangelove-ventures/horcrux/signer" + "github.com/strangelove-ventures/horcrux/pkg/config" + "github.com/strangelove-ventures/horcrux/pkg/thresholdTemP" interchaintest "github.com/strangelove-ventures/interchaintest/v8" "github.com/strangelove-ventures/interchaintest/v8/chain/cosmos" "github.com/strangelove-ventures/interchaintest/v8/ibc" @@ -356,13 +359,13 @@ func TestMultipleChainHorcrux(t *testing.T) { for i := 0; i < totalChains; i++ { chainConfigs[i] = &cosignerChainConfig{ sentries: make([]cosmos.ChainNodes, sentriesPerSigner), - shards: make([]signer.CosignerEd25519Key, totalSigners), + shards: make([]thresholdTemP.CosignerEd25519Key, totalSigners), } } cosignerSidecars := make(horcruxSidecars, totalSigners) - eciesShards, err := signer.CreateCosignerECIESShards(totalSigners) + eciesShards, err := nodesecurity.CreateCosignerECIESShards(totalSigners) require.NoError(t, err) var wg sync.WaitGroup @@ -450,7 +453,7 @@ func TestMultipleChainHorcrux(t *testing.T) { type cosignerChainConfig struct { chainID string - shards []signer.CosignerEd25519Key + shards []thresholdTemP.CosignerEd25519Key sentries []cosmos.ChainNodes } @@ -464,7 +467,7 @@ type horcruxSidecars []horcruxSidecarProcess func configureAndStartSidecars( ctx context.Context, t *testing.T, - eciesShards []signer.CosignerECIESKey, + eciesShards []nodesecurity.CosignerECIESKey, sidecars horcruxSidecars, threshold int, wg *sync.WaitGroup, @@ -476,9 +479,9 @@ func configureAndStartSidecars( totalSigners := len(sidecars) - cosignersConfig := make(signer.CosignersConfig, totalSigners) + cosignersConfig := make(config.CosignersConfig, totalSigners) for i, s := range sidecars { - cosignersConfig[i] = signer.CosignerConfig{ + cosignersConfig[i] = config.CosignerConfig{ ShardID: i + 1, P2PAddr: fmt.Sprintf("tcp://%s:%s", s.cosigner.HostName(), signerPort), } @@ -492,14 +495,14 @@ func configureAndStartSidecars( numSentries += len(chainConfig.sentries[i]) } - chainNodes := make(signer.ChainNodes, 0, numSentries) + chainNodes := make(config.ChainNodes, 0, numSentries) ed25519Shards := make([]chainEd25519Shard, len(chainConfigs)) for j, chainConfig := range chainConfigs { if s.proxy == nil { for _, sentry := range chainConfig.sentries[i] { - chainNodes = append(chainNodes, signer.ChainNode{ + chainNodes = append(chainNodes, config.ChainNode{ PrivValAddr: fmt.Sprintf("tcp://%s:1234", sentry.HostName()), }) } @@ -516,9 +519,9 @@ func configureAndStartSidecars( grpcAddr = ":5555" } - config := signer.Config{ - SignMode: signer.SignModeThreshold, - ThresholdModeConfig: &signer.ThresholdModeConfig{ + config := config.Config{ + SignMode: config.SignModeThreshold, + ThresholdModeConfig: &config.ThresholdModeConfig{ Threshold: threshold, Cosigners: cosignersConfig, GRPCTimeout: "200ms", @@ -591,13 +594,13 @@ func TestHorcruxProxyGRPC(t *testing.T) { for i := 0; i < totalChains; i++ { chainConfigs[i] = &cosignerChainConfig{ sentries: make([]cosmos.ChainNodes, sentriesPerSigner), - shards: make([]signer.CosignerEd25519Key, totalSigners), + shards: make([]thresholdTemP.CosignerEd25519Key, totalSigners), } } cosignerSidecars := make(horcruxSidecars, totalSigners) - eciesShards, err := signer.CreateCosignerECIESShards(totalSigners) + eciesShards, err := nodesecurity.CreateCosignerECIESShards(totalSigners) require.NoError(t, err) var wg sync.WaitGroup diff --git a/test/validator_single.go b/test/validator_single.go index c7919ab8..0ddb82ea 100644 --- a/test/validator_single.go +++ b/test/validator_single.go @@ -10,7 +10,7 @@ import ( cometjson "github.com/cometbft/cometbft/libs/json" "github.com/cometbft/cometbft/privval" "github.com/docker/docker/client" - "github.com/strangelove-ventures/horcrux/signer" + "github.com/strangelove-ventures/horcrux/pkg/config" interchaintest "github.com/strangelove-ventures/interchaintest/v8" "github.com/strangelove-ventures/interchaintest/v8/chain/cosmos" "github.com/strangelove-ventures/interchaintest/v8/ibc" @@ -84,15 +84,15 @@ func preGenesisSingleNodeAndHorcruxSingle( return err } - chainNodes := make(signer.ChainNodes, len(sentries)) + chainNodes := make(config.ChainNodes, len(sentries)) for i, sentry := range sentries { - chainNodes[i] = signer.ChainNode{ + chainNodes[i] = config.ChainNode{ PrivValAddr: fmt.Sprintf("tcp://%s:1234", sentry.HostName()), } } - config := signer.Config{ - SignMode: signer.SignModeSingle, + config := config.Config{ + SignMode: config.SignModeSingle, ChainNodes: chainNodes, } @@ -118,7 +118,7 @@ func writeConfigAndKeysSingle( ctx context.Context, chainID string, singleSigner *cosmos.SidecarProcess, - config signer.Config, + config config.Config, pvKey privval.FilePVKey, ) error { configBz, err := json.Marshal(config) diff --git a/test/validator_threshold.go b/test/validator_threshold.go index b74d2482..efd31eca 100644 --- a/test/validator_threshold.go +++ b/test/validator_threshold.go @@ -12,7 +12,9 @@ import ( "github.com/docker/docker/client" dto "github.com/prometheus/client_model/go" "github.com/prometheus/common/expfmt" - "github.com/strangelove-ventures/horcrux/signer" + "github.com/strangelove-ventures/horcrux/pkg/config" + "github.com/strangelove-ventures/horcrux/pkg/nodes/nodesecurity" + "github.com/strangelove-ventures/horcrux/pkg/thresholdTemP" interchaintest "github.com/strangelove-ventures/interchaintest/v8" "github.com/strangelove-ventures/interchaintest/v8/chain/cosmos" "github.com/strangelove-ventures/interchaintest/v8/ibc" @@ -182,12 +184,12 @@ func convertValidatorToHorcrux( return nil, err } - eciesShards, err := signer.CreateCosignerECIESShards(totalSigners) + eciesShards, err := nodesecurity.CreateCosignerECIESShards(totalSigners) if err != nil { return nil, err } - cosigners := make(signer.CosignersConfig, totalSigners) + cosigners := make(config.CosignersConfig, totalSigners) for i := 0; i < totalSigners; i++ { _, err := horcruxSidecar(ctx, validator, fmt.Sprintf("cosigner-%d", i+1), client, network) @@ -195,7 +197,7 @@ func convertValidatorToHorcrux( return nil, err } - cosigners[i] = signer.CosignerConfig{ + cosigners[i] = config.CosignerConfig{ ShardID: i + 1, P2PAddr: fmt.Sprintf("tcp://%s:%s", validator.Sidecars[i].HostName(), signerPort), } @@ -206,16 +208,16 @@ func convertValidatorToHorcrux( cosigner := validator.Sidecars[i] sentriesForCosigner := sentriesForCosigners[i] - chainNodes := make(signer.ChainNodes, len(sentriesForCosigner)) + chainNodes := make(config.ChainNodes, len(sentriesForCosigner)) for i, sentry := range sentriesForCosigner { - chainNodes[i] = signer.ChainNode{ + chainNodes[i] = config.ChainNode{ PrivValAddr: fmt.Sprintf("tcp://%s:1234", sentry.HostName()), } } - config := signer.Config{ - SignMode: signer.SignModeThreshold, - ThresholdModeConfig: &signer.ThresholdModeConfig{ + config := config.Config{ + SignMode: config.SignModeThreshold, + ThresholdModeConfig: &config.ThresholdModeConfig{ Threshold: int(threshold), Cosigners: cosigners, GRPCTimeout: "200ms", @@ -251,13 +253,13 @@ func convertValidatorToHorcrux( } // getPrivvalKey gets the privval key from the validator and creates threshold shards from it. -func getShardedPrivvalKey(ctx context.Context, node *cosmos.ChainNode, threshold uint8, shards uint8) ([]signer.CosignerEd25519Key, crypto.PubKey, error) { +func getShardedPrivvalKey(ctx context.Context, node *cosmos.ChainNode, threshold uint8, shards uint8) ([]thresholdTemP.CosignerEd25519Key, crypto.PubKey, error) { pvKey, err := getPrivvalKey(ctx, node) if err != nil { return nil, nil, err } - ed25519Shards := signer.CreateEd25519ThresholdSignShards(pvKey, threshold, shards) + ed25519Shards := thresholdTemP.CreateEd25519ThresholdSignShards(pvKey, threshold, shards) return ed25519Shards, pvKey.PubKey, nil } @@ -265,15 +267,15 @@ func getShardedPrivvalKey(ctx context.Context, node *cosmos.ChainNode, threshold // chainEd25519Shard is a wrapper for a chain Index and a shard of an ed25519 consensus key. type chainEd25519Shard struct { chainID string - key signer.CosignerEd25519Key + key thresholdTemP.CosignerEd25519Key } // writeConfigAndKeysThreshold writes the config and keys for a horcrux cosigner to the sidecar's docker volume. func writeConfigAndKeysThreshold( ctx context.Context, cosigner *cosmos.SidecarProcess, - config signer.Config, - eciesKey signer.CosignerECIESKey, + config config.Config, + eciesKey nodesecurity.CosignerECIESKey, ed25519Shards ...chainEd25519Shard, ) error { configBz, err := yaml.Marshal(config)