diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index 0436c667..309b171f 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -27,8 +27,8 @@ jobs:
uses: actions/checkout@v3
# make sure proto files are up to date
- - name: generate fresh signer proto .go files
- run: make signer-proto
+ - name: generate fresh pkg proto .go files
+ run: make pkg-proto
# run tests
- name: run horcrux tests
@@ -60,8 +60,8 @@ jobs:
uses: actions/checkout@v3
# make sure proto files are up to date
- - name: generate fresh signer proto .go files
- run: make signer-proto
+ - name: generate fresh pkg proto .go files
+ run: make pkg-proto
# run test matrix
- name: run test
diff --git a/Makefile b/Makefile
index bae93bb9..b7341788 100644
--- a/Makefile
+++ b/Makefile
@@ -38,11 +38,11 @@ build-horcrux-docker:
mkfile_path := $(abspath $(lastword $(MAKEFILE_LIST)))
mkfile_dir := $(dir $(mkfile_path))
-signer-proto:
+pkg-proto:
docker run \
--rm \
-u $(shell id -u ${USER}):$(shell id -g ${USER}) \
- --mount type=bind,source=$(mkfile_dir)/signer/proto,target=/horcrux/signer/proto \
+ --mount type=bind,source=$(mkfile_dir)/pkg/proto,target=/horcrux/pkg/proto \
--entrypoint protoc \
namely/protoc-all \
--go_out=/horcrux \
diff --git a/cmd/horcrux/cmd/address.go b/cmd/horcrux/cmd/address.go
index d0baf136..f327c615 100644
--- a/cmd/horcrux/cmd/address.go
+++ b/cmd/horcrux/cmd/address.go
@@ -6,11 +6,12 @@ import (
"fmt"
"strings"
+ "github.com/strangelove-ventures/horcrux/pkg/cosigner"
+
"github.com/cometbft/cometbft/crypto"
cometprivval "github.com/cometbft/cometbft/privval"
"github.com/cosmos/cosmos-sdk/types/bech32"
"github.com/spf13/cobra"
- "github.com/strangelove-ventures/horcrux/signer"
)
type AddressCmdOutput struct {
@@ -34,24 +35,24 @@ func addressCmd() *cobra.Command {
chainID := args[0]
switch config.Config.SignMode {
- case signer.SignModeThreshold:
+ case cosigner.SignModeThreshold:
err := config.Config.ValidateThresholdModeConfig()
if err != nil {
return err
}
- keyFile, err := config.KeyFileExistsCosigner(chainID)
+ keyFile, err := config.KeyFileExistsCosign(chainID)
if err != nil {
return err
}
- key, err := signer.LoadCosignerEd25519Key(keyFile)
+ key, err := cosigner.LoadCosignerEd25519Key(keyFile)
if err != nil {
return fmt.Errorf("error reading cosigner key: %w, check that key is present for chain ID: %s", err, chainID)
}
pubKey = key.PubKey
- case signer.SignModeSingle:
+ case cosigner.SignModeSingle:
err := config.Config.ValidateSingleSignerConfig()
if err != nil {
return err
@@ -69,7 +70,7 @@ func addressCmd() *cobra.Command {
pubKeyAddress := pubKey.Address()
- pubKeyJSON, err := signer.PubKey("", pubKey)
+ pubKeyJSON, err := cosigner.PubKey("", pubKey)
if err != nil {
return err
}
@@ -85,7 +86,7 @@ func addressCmd() *cobra.Command {
return err
}
output.ValConsAddress = bech32ValConsAddress
- pubKeyBech32, err := signer.PubKey(args[1], pubKey)
+ pubKeyBech32, err := cosigner.PubKey(args[1], pubKey)
if err != nil {
return err
}
diff --git a/cmd/horcrux/cmd/config.go b/cmd/horcrux/cmd/config.go
index 4c93ffb2..0c0e6036 100644
--- a/cmd/horcrux/cmd/config.go
+++ b/cmd/horcrux/cmd/config.go
@@ -4,8 +4,9 @@ import (
"fmt"
"os"
+ "github.com/strangelove-ventures/horcrux/pkg/cosigner"
+
"github.com/spf13/cobra"
- "github.com/strangelove-ventures/horcrux/signer"
)
const (
@@ -23,7 +24,7 @@ const (
func configCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "config",
- Short: "Commands to configure the horcrux signer",
+ Short: "Commands to configure the horcrux pkg",
}
cmd.AddCommand(initCmd())
@@ -38,7 +39,7 @@ func initCmd() *cobra.Command {
Aliases: []string{"i"},
Short: "initialize configuration file and home directory if one doesn't already exist",
Long: `initialize configuration file.
-for threshold signer mode, --cosigner flags and --threshold flag are required.
+for threshold pkg mode, --cosigner flags and --threshold flag are required.
`,
Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, args []string) (err error) {
@@ -47,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 := cosigner.ChainNodesFromFlag(nodes)
if err != nil {
return err
}
@@ -59,7 +60,7 @@ for threshold signer mode, --cosigner flags and --threshold flag are required.
config.ConfigFile)
}
- var cfg signer.Config
+ var cfg cosigner.Config
signMode, _ := cmdFlags.GetString(flagSignMode)
keyDirFlag, _ := cmdFlags.GetString(flagKeyDir)
@@ -68,21 +69,21 @@ for threshold signer mode, --cosigner flags and --threshold flag are required.
keyDir = &keyDirFlag
}
debugAddr, _ := cmdFlags.GetString("debug-addr")
- if signMode == string(signer.SignModeThreshold) {
+ if signMode == string(cosigner.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 := cosigner.CosignersFromFlag(cosignersFlag)
if err != nil {
return err
}
- cfg = signer.Config{
- SignMode: signer.SignModeThreshold,
+ cfg = cosigner.Config{
+ SignMode: cosigner.SignModeThreshold,
PrivValKeyDir: keyDir,
- ThresholdModeConfig: &signer.ThresholdModeConfig{
+ ThresholdModeConfig: &cosigner.ThresholdModeConfig{
Threshold: threshold,
Cosigners: cosigners,
GRPCTimeout: grpcTimeout,
@@ -99,8 +100,8 @@ for threshold signer mode, --cosigner flags and --threshold flag are required.
}
} else {
// Single Signer Config
- cfg = signer.Config{
- SignMode: signer.SignModeSingle,
+ cfg = cosigner.Config{
+ SignMode: cosigner.SignModeSingle,
PrivValKeyDir: keyDir,
ChainNodes: cn,
DebugAddr: debugAddr,
@@ -131,7 +132,7 @@ for threshold signer mode, --cosigner flags and --threshold flag are required.
}
f := cmd.Flags()
- f.StringP(flagSignMode, "m", string(signer.SignModeThreshold),
+ f.StringP(flagSignMode, "m", string(cosigner.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"+
diff --git a/cmd/horcrux/cmd/leader_election.go b/cmd/horcrux/cmd/leader_election.go
index 127f58ec..2d0f42bf 100644
--- a/cmd/horcrux/cmd/leader_election.go
+++ b/cmd/horcrux/cmd/leader_election.go
@@ -5,12 +5,13 @@ import (
"fmt"
"time"
+ "github.com/strangelove-ventures/horcrux/pkg/cosigner"
+
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"
+ "github.com/strangelove-ventures/horcrux/pkg/multiresolver"
+ "github.com/strangelove-ventures/horcrux/pkg/proto"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
)
@@ -69,7 +70,7 @@ horcrux elect 2 # elect specific leader`,
ctx, cancelFunc := context.WithTimeout(context.Background(), 30*time.Second)
defer cancelFunc()
- grpcClient := proto.NewCosignerGRPCClient(conn)
+ grpcClient := proto.NewICosignerGRPCClient(conn)
_, err = grpcClient.TransferLeadership(
ctx,
&proto.CosignerGRPCTransferLeadershipRequest{LeaderID: leaderID},
@@ -109,21 +110,21 @@ func getLeaderCmd() *cobra.Command {
var id int
- keyFileECIES, err := config.KeyFileExistsCosignerECIES()
+ keyFileECIES, err := config.KeyFileExistsCosignECIES()
if err != nil {
- keyFileRSA, err := config.KeyFileExistsCosignerRSA()
+ keyFileRSA, err := config.KeyFileExistsCosignRSA()
if err != nil {
return fmt.Errorf("cosigner encryption keys not found (%s) - (%s): %w", keyFileECIES, keyFileRSA, err)
}
- key, err := signer.LoadCosignerRSAKey(keyFileRSA)
+ key, err := cosigner.LoadCosignRSAKey(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 := cosigner.LoadCosignerECIESKey(keyFileECIES)
if err != nil {
return fmt.Errorf("error reading cosigner key (%s): %w", keyFileECIES, err)
}
@@ -166,7 +167,7 @@ func getLeaderCmd() *cobra.Command {
ctx, cancelFunc := context.WithTimeout(context.Background(), 30*time.Second)
defer cancelFunc()
- grpcClient := proto.NewCosignerGRPCClient(conn)
+ grpcClient := proto.NewICosignerGRPCClient(conn)
res, err := grpcClient.GetLeader(ctx, &proto.CosignerGRPCGetLeaderRequest{})
if err != nil {
diff --git a/cmd/horcrux/cmd/migrate.go b/cmd/horcrux/cmd/migrate.go
index af083e3a..28e2f257 100644
--- a/cmd/horcrux/cmd/migrate.go
+++ b/cmd/horcrux/cmd/migrate.go
@@ -8,12 +8,13 @@ import (
"os"
"path/filepath"
+ "github.com/strangelove-ventures/horcrux/pkg/cosigner"
+
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"
)
@@ -103,7 +104,7 @@ func (key *v2CosignerKey) UnmarshalJSON(data []byte) error {
// Prior to the tendermint protobuf migration, the public key bytes in key files
// were encoded using the go-amino libraries via
- // cdc.MarshalBinaryBare(CosignerEd25519Key.PubKey)
+ // cdc.MarshalBinaryBare(CosignEd25519Key.PubKey)
//
// To support reading the public key bytes from these key files, we fallback to
// amino unmarshalling if the protobuf unmarshalling fails
@@ -218,7 +219,7 @@ func migrateCmd() *cobra.Command {
return err
}
- newEd25519Key := signer.CosignerEd25519Key{
+ newEd25519Key := cosigner.CosignEd25519Key{
PubKey: legacyCosignerKey.PubKey,
PrivateShard: legacyCosignerKey.ShareKey,
ID: legacyCosignerKey.ID,
@@ -234,7 +235,7 @@ func migrateCmd() *cobra.Command {
return fmt.Errorf("failed to write new Ed25519 key to %s: %w", newEd25519Path, err)
}
- newRSAKey := signer.CosignerRSAKey{
+ newRSAKey := cosigner.CosignRSAKey{
RSAKey: legacyCosignerKey.RSAKey,
ID: legacyCosignerKey.ID,
RSAPubs: legacyCosignerKey.RSAPubs,
@@ -252,10 +253,10 @@ func migrateCmd() *cobra.Command {
// only attempt config migration if legacy config exists
if legacyCfgErr == nil {
- var migratedNodes signer.ChainNodes
+ var migratedNodes cosigner.ChainNodes
for _, n := range legacyCfg.ChainNodes {
- migratedNodes = append(migratedNodes, signer.ChainNode{
+ migratedNodes = append(migratedNodes, cosigner.ChainNode{
PrivValAddr: n.PrivValAddr,
})
}
@@ -263,17 +264,17 @@ func migrateCmd() *cobra.Command {
config.Config.ChainNodes = migratedNodes
config.Config.DebugAddr = legacyCfg.DebugAddr
- signMode := signer.SignModeSingle
+ signMode := cosigner.SignModeSingle
if legacyCfg.Cosigner != nil {
- signMode = signer.SignModeThreshold
+ signMode = cosigner.SignModeThreshold
- var migratedCosigners signer.CosignersConfig
+ var migratedCosigners cosigner.CosignersConfig
if legacyCfg.Cosigner.P2PListen != "" {
migratedCosigners = append(
migratedCosigners,
- signer.CosignerConfig{
+ cosigner.CosignConfig{
ShardID: legacyCosignerKey.ID,
P2PAddr: legacyCfg.Cosigner.P2PListen,
},
@@ -281,13 +282,13 @@ func migrateCmd() *cobra.Command {
}
for _, c := range legacyCfg.Cosigner.Peers {
- migratedCosigners = append(migratedCosigners, signer.CosignerConfig{
+ migratedCosigners = append(migratedCosigners, cosigner.CosignConfig{
ShardID: c.ShareID,
P2PAddr: c.P2PAddr,
})
}
- config.Config.ThresholdModeConfig = &signer.ThresholdModeConfig{
+ config.Config.ThresholdModeConfig = &cosigner.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..9ce6ca00 100644
--- a/cmd/horcrux/cmd/root.go
+++ b/cmd/horcrux/cmd/root.go
@@ -5,14 +5,15 @@ import (
"os"
"path/filepath"
+ "github.com/strangelove-ventures/horcrux/pkg/cosigner"
+
homedir "github.com/mitchellh/go-homedir"
"github.com/spf13/cobra"
"github.com/spf13/viper"
- "github.com/strangelove-ventures/horcrux/signer"
"gopkg.in/yaml.v2"
)
-var config signer.RuntimeConfig
+var config cosigner.RuntimeConfig
func rootCmd() *cobra.Command {
cmd := &cobra.Command{
@@ -74,7 +75,7 @@ func initConfig() {
} else {
home = config.HomeDir
}
- config = signer.RuntimeConfig{
+ config = cosigner.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 5dbcb95b..ddca071d 100644
--- a/cmd/horcrux/cmd/shards.go
+++ b/cmd/horcrux/cmd/shards.go
@@ -20,8 +20,9 @@ import (
"os"
"path/filepath"
+ "github.com/strangelove-ventures/horcrux/pkg/cosigner"
+
"github.com/spf13/cobra"
- "github.com/strangelove-ventures/horcrux/signer"
)
func createCosignerDirectoryIfNecessary(out string, id int) (string, error) {
@@ -112,7 +113,7 @@ func createCosignerEd25519ShardsCmd() *cobra.Command {
return nil
}
- csKeys, err := signer.CreateCosignerEd25519ShardsFromFile(keyFile, threshold, shards)
+ csKeys, err := cosigner.CreateCosignerEd25519ShardsFromFile(keyFile, threshold, shards)
if err != nil {
return err
}
@@ -133,7 +134,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 = cosigner.WriteCosignerEd25519ShardFile(c, filename); err != nil {
return err
}
fmt.Fprintf(cmd.OutOrStdout(), "Created Ed25519 Shard %s\n", filename)
@@ -170,7 +171,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 := cosigner.CreateCosignerECIESShards(int(shards))
if err != nil {
return err
}
@@ -191,7 +192,7 @@ func createCosignerECIESShardsCmd() *cobra.Command {
return err
}
filename := filepath.Join(dir, "ecies_keys.json")
- if err = signer.WriteCosignerECIESShardFile(c, filename); err != nil {
+ if err = cosigner.WriteCosignECIESShardFile(c, filename); err != nil {
return err
}
fmt.Fprintf(cmd.OutOrStdout(), "Created ECIES Shard %s\n", filename)
@@ -218,7 +219,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 := cosigner.CreateCosignerRSAShards(int(shards))
if err != nil {
return err
}
@@ -239,7 +240,7 @@ func createCosignerRSAShardsCmd() *cobra.Command {
return err
}
filename := filepath.Join(dir, "rsa_keys.json")
- if err = signer.WriteCosignerRSAShardFile(c, filename); err != nil {
+ if err = cosigner.WriteCosignerRSAShardFile(c, filename); err != nil {
return err
}
fmt.Fprintf(cmd.OutOrStdout(), "Created RSA Shard %s\n", filename)
diff --git a/cmd/horcrux/cmd/single_signer.go b/cmd/horcrux/cmd/single_signer.go
index 18b4ba1e..afaefb94 100644
--- a/cmd/horcrux/cmd/single_signer.go
+++ b/cmd/horcrux/cmd/single_signer.go
@@ -4,7 +4,7 @@ import (
"fmt"
"io"
- "github.com/strangelove-ventures/horcrux/signer"
+ "github.com/strangelove-ventures/horcrux/pkg/node"
)
const (
@@ -23,7 +23,7 @@ as it is not officially supported by Strangelove.`
func NewSingleSignerValidator(
out io.Writer,
acceptRisk bool,
-) (*signer.SingleSignerValidator, error) {
+) (*node.SingleSignerValidator, error) {
fmt.Fprintln(out, singleSignerWarning)
if !acceptRisk {
@@ -34,5 +34,5 @@ func NewSingleSignerValidator(
return nil, err
}
- return signer.NewSingleSignerValidator(&config), nil
+ return node.NewSingleSignerValidator(&config), nil
}
diff --git a/cmd/horcrux/cmd/start.go b/cmd/horcrux/cmd/start.go
index 630bc390..0fe5d708 100644
--- a/cmd/horcrux/cmd/start.go
+++ b/cmd/horcrux/cmd/start.go
@@ -4,10 +4,13 @@ import (
"fmt"
"os"
+ "github.com/strangelove-ventures/horcrux/pkg/cosigner"
+
+ "github.com/strangelove-ventures/horcrux/pkg/node"
+
cometlog "github.com/cometbft/cometbft/libs/log"
"github.com/cometbft/cometbft/libs/service"
"github.com/spf13/cobra"
- "github.com/strangelove-ventures/horcrux/signer"
)
func startCmd() *cobra.Command {
@@ -17,7 +20,7 @@ func startCmd() *cobra.Command {
Args: cobra.NoArgs,
SilenceUsage: true,
RunE: func(cmd *cobra.Command, args []string) error {
- err := signer.RequireNotRunning(config.PidFile)
+ err := node.RequireNotRunning(config.PidFile)
if err != nil {
return err
}
@@ -43,16 +46,16 @@ func startCmd() *cobra.Command {
acceptRisk, _ := cmd.Flags().GetBool(flagAcceptRisk)
- var val signer.PrivValidator
+ var val node.IPrivValidator
var services []service.Service
switch config.Config.SignMode {
- case signer.SignModeThreshold:
+ case cosigner.SignModeThreshold:
services, val, err = NewThresholdValidator(logger)
if err != nil {
return err
}
- case signer.SignModeSingle:
+ case cosigner.SignModeSingle:
val, err = NewSingleSignerValidator(out, acceptRisk)
if err != nil {
return err
@@ -63,12 +66,12 @@ func startCmd() *cobra.Command {
go EnableDebugAndMetrics(cmd.Context(), out)
- services, err = signer.StartRemoteSigners(services, logger, val, config.Config.Nodes())
+ services, err = node.StartRemoteSigners(services, logger, val, config.Config.Nodes())
if err != nil {
return fmt.Errorf("failed to start remote signer(s): %w", err)
}
- signer.WaitAndTerminate(logger, services, config.PidFile)
+ node.WaitAndTerminate(logger, services, config.PidFile)
return nil
},
diff --git a/cmd/horcrux/cmd/state.go b/cmd/horcrux/cmd/state.go
index 5380da16..3fba2a1e 100644
--- a/cmd/horcrux/cmd/state.go
+++ b/cmd/horcrux/cmd/state.go
@@ -10,10 +10,12 @@ import (
"strings"
"time"
- "github.com/spf13/cobra"
- "github.com/strangelove-ventures/horcrux/signer"
+ "github.com/strangelove-ventures/horcrux/pkg/types"
+
+ "github.com/strangelove-ventures/horcrux/pkg/node"
cometjson "github.com/cometbft/cometbft/libs/json"
+ "github.com/spf13/cobra"
)
// Snippet Taken from https://raw.githubusercontent.com/cometbft/cometbft/main/privval/file.go
@@ -52,12 +54,12 @@ func showStateCmd() *cobra.Command {
return fmt.Errorf("%s does not exist, initialize config with horcrux config init and try again", config.HomeDir)
}
- pv, err := signer.LoadSignState(config.PrivValStateFile(chainID))
+ pv, err := types.LoadSignState(config.PrivValStateFile(chainID))
if err != nil {
return err
}
- cs, err := signer.LoadSignState(config.CosignerStateFile(chainID))
+ cs, err := types.LoadSignState(config.CosignStateFile(chainID))
if err != nil {
return err
}
@@ -89,16 +91,16 @@ func setStateCmd() *cobra.Command {
// Resetting the priv_validator_state.json should only be allowed if the
// signer is not running.
- if err := signer.RequireNotRunning(config.PidFile); err != nil {
+ if err := node.RequireNotRunning(config.PidFile); err != nil {
return err
}
- pv, err := signer.LoadOrCreateSignState(config.PrivValStateFile(chainID))
+ pv, err := types.LoadOrCreateSignState(config.PrivValStateFile(chainID))
if err != nil {
return err
}
- cs, err := signer.LoadOrCreateSignState(config.CosignerStateFile(chainID))
+ cs, err := types.LoadOrCreateSignState(config.CosignStateFile(chainID))
if err != nil {
return err
}
@@ -112,7 +114,7 @@ func setStateCmd() *cobra.Command {
fmt.Fprintf(cmd.OutOrStdout(), "Setting height %d\n", height)
pv.NoncePublic, cs.NoncePublic = nil, nil
- signState := signer.SignStateConsensus{
+ signState := types.SignStateConsensus{
Height: height,
Round: 0,
Step: 0,
@@ -152,18 +154,18 @@ func importStateCmd() *cobra.Command {
// Resetting the priv_validator_state.json should only be allowed if the
// signer is not running.
- if err := signer.RequireNotRunning(config.PidFile); err != nil {
+ if err := node.RequireNotRunning(config.PidFile); err != nil {
return err
}
// Recreate privValStateFile if necessary
- pv, err := signer.LoadOrCreateSignState(config.PrivValStateFile(chainID))
+ pv, err := types.LoadOrCreateSignState(config.PrivValStateFile(chainID))
if err != nil {
return err
}
// shareStateFile does not exist during default config init, so create if necessary
- cs, err := signer.LoadOrCreateSignState(config.CosignerStateFile(chainID))
+ cs, err := types.LoadOrCreateSignState(config.CosignStateFile(chainID))
if err != nil {
return err
}
@@ -196,7 +198,7 @@ func importStateCmd() *cobra.Command {
}
pv.NoncePublic = nil
- signState := signer.SignStateConsensus{
+ signState := types.SignStateConsensus{
Height: pvState.Height,
Round: int64(pvState.Round),
Step: pvState.Step,
@@ -225,7 +227,7 @@ func importStateCmd() *cobra.Command {
}
}
-func printSignState(out io.Writer, ss *signer.SignState) {
+func printSignState(out io.Writer, ss *types.SignState) {
fmt.Fprintf(out, " Height: %v\n"+
" Round: %v\n"+
" Step: %v\n",
diff --git a/cmd/horcrux/cmd/state_test.go b/cmd/horcrux/cmd/state_test.go
index baa74e89..fdb8c769 100644
--- a/cmd/horcrux/cmd/state_test.go
+++ b/cmd/horcrux/cmd/state_test.go
@@ -7,7 +7,8 @@ import (
"testing"
"time"
- "github.com/strangelove-ventures/horcrux/signer"
+ "github.com/strangelove-ventures/horcrux/pkg/types"
+
"github.com/stretchr/testify/require"
)
@@ -64,7 +65,7 @@ func TestStateSetCmd(t *testing.T) {
height, err := strconv.ParseInt(tc.args[1], 10, 64)
require.NoError(t, err)
- ss, err := signer.LoadSignState(filepath.Join(stateDir, chainID+"_priv_validator_state.json"))
+ ss, err := types.LoadSignState(filepath.Join(stateDir, chainID+"_priv_validator_state.json"))
require.NoError(t, err)
require.Equal(t, height, ss.Height)
require.Equal(t, int64(0), ss.Round)
@@ -73,7 +74,7 @@ func TestStateSetCmd(t *testing.T) {
require.Nil(t, ss.Signature)
require.Nil(t, ss.SignBytes)
- ss, err = signer.LoadSignState(filepath.Join(stateDir, chainID+"_share_sign_state.json"))
+ ss, err = types.LoadSignState(filepath.Join(stateDir, chainID+"_share_sign_state.json"))
require.NoError(t, err)
require.Equal(t, height, ss.Height)
require.Equal(t, int64(0), ss.Round)
diff --git a/cmd/horcrux/cmd/threshold.go b/cmd/horcrux/cmd/threshold.go
index 3f8e4050..d33597aa 100644
--- a/cmd/horcrux/cmd/threshold.go
+++ b/cmd/horcrux/cmd/threshold.go
@@ -6,32 +6,34 @@ import (
"path/filepath"
"time"
+ "github.com/strangelove-ventures/horcrux/pkg/cosigner"
+
+ "github.com/strangelove-ventures/horcrux/pkg/node"
+
cometlog "github.com/cometbft/cometbft/libs/log"
cometservice "github.com/cometbft/cometbft/libs/service"
- "github.com/strangelove-ventures/horcrux/signer"
)
const maxWaitForSameBlockAttempts = 3
func NewThresholdValidator(
logger cometlog.Logger,
-) ([]cometservice.Service, *signer.ThresholdValidator, error) {
+) ([]cometservice.Service, *node.ThresholdValidator, error) {
if err := config.Config.ValidateThresholdModeConfig(); err != nil {
return nil, nil, err
}
thresholdCfg := config.Config.ThresholdModeConfig
-
- remoteCosigners := make([]signer.Cosigner, 0, len(thresholdCfg.Cosigners)-1)
+ remoteCosigners := make([]node.ICosigner, 0, len(thresholdCfg.Cosigners)-1)
var p2pListen string
- var security signer.CosignerSecurity
+ var security cosigner.ICosignerSecurity
var eciesErr error
- security, eciesErr = config.CosignerSecurityECIES()
+ security, eciesErr = config.SecurityECIES()
if eciesErr != nil {
var rsaErr error
- security, rsaErr = config.CosignerSecurityRSA()
+ security, rsaErr = config.SecurityRSA()
if rsaErr != nil {
return nil, nil, fmt.Errorf("failed to initialize cosigner ECIES / RSA security : %w / %w", eciesErr, rsaErr)
}
@@ -41,7 +43,7 @@ func NewThresholdValidator(
if c.ShardID != security.GetID() {
remoteCosigners = append(
remoteCosigners,
- signer.NewRemoteCosigner(c.ShardID, c.P2PAddr),
+ cosigner.NewRemoteCosigner(c.ShardID, c.P2PAddr),
)
} else {
p2pListen = c.P2PAddr
@@ -52,7 +54,7 @@ func NewThresholdValidator(
return nil, nil, fmt.Errorf("cosigner config does not exist for our shard ID %d", security.GetID())
}
- localCosigner := signer.NewLocalCosigner(
+ localCosigner := cosigner.NewLocalCosigner(
logger,
&config,
security,
@@ -72,14 +74,14 @@ func NewThresholdValidator(
nodeID := fmt.Sprint(security.GetID())
// Start RAFT store listener
- raftStore := signer.NewRaftStore(nodeID,
- raftDir, p2pListen, raftTimeout, logger, localCosigner, remoteCosigners)
+ raftStore := node.NewRaftStore(nodeID,
+ raftDir, p2pListen, raftTimeout, logger)
if err := raftStore.Start(); err != nil {
return nil, nil, fmt.Errorf("error starting raft store: %w", err)
}
services := []cometservice.Service{raftStore}
- val := signer.NewThresholdValidator(
+ val := node.NewThresholdValidator(
logger,
&config,
thresholdCfg.Threshold,
@@ -87,7 +89,7 @@ func NewThresholdValidator(
maxWaitForSameBlockAttempts,
localCosigner,
remoteCosigners,
- raftStore,
+ raftStore, // raftStore implements the ILeader interface
)
raftStore.SetThresholdValidator(val)
diff --git a/docs/metrics.md b/docs/metrics.md
index a4c398a6..1bce4f4b 100644
--- a/docs/metrics.md
+++ b/docs/metrics.md
@@ -15,7 +15,7 @@ Resulting in a configuration like the following:
```
thresholdMode:
threshold: 2
- cosigners:
+ cosigner:
- shardID: 1
p2pAddr: tcp://localhost:5001
- shardID: 2
@@ -97,7 +97,7 @@ signer_sign_block_threshold_lag_seconds{quantile="0.9"} 0.028546635
signer_sign_block_threshold_lag_seconds{quantile="0.99"} 0.029730841
```
-After reaching the threshold, all cosigners should sign quickly
+After reaching the threshold, all cosigner should sign quickly
```
signer_sign_block_cosigner_lag_seconds{quantile="0.5"} 0.031424561
signer_sign_block_cosigner_lag_seconds{quantile="0.9"} 0.0407505
diff --git a/docs/migrating.md b/docs/migrating.md
index a11c1602..24ee5de6 100644
--- a/docs/migrating.md
+++ b/docs/migrating.md
@@ -50,7 +50,7 @@ When installing `horcrux` we recommend using either the [container image](https:
The image or binary will be used on each cosigner (bare virtual machine, docker container, kubernetes pod, etc.)
The binary should also be installed on your local machine for working with the config and key files before distributing to the cosigner nodes.
-Run the following on your local machine. If you are using the binary on the cosigners rather than container image, run this on each cosigner node VM also.
+Run the following on your local machine. If you are using the binary on the cosigner rather than container image, run this on each cosigner node VM also.
```bash
TAG=v3.0.0
$ wget https://github.com/strangelove-ventures/horcrux/releases/download/${TAG}/horcrux_${TAG}_linux_amd64.tar.gz
@@ -67,18 +67,18 @@ $ sudo nano /etc/systemd/system/horcrux.service
$ sudo systemctl daemon-reload
```
-After that is done, initialize the shared configuration for the cosigners on your local machine using the `horcrux` cli. If you would like different cosigners to connect to different sentry node(s): repeat this command and modify the `--node` flag values for each cosigner, or modify the config after the initial generation.
+After that is done, initialize the shared configuration for the cosigner on your local machine using the `horcrux` cli. If you would like different cosigner to connect to different sentry node(s): repeat this command and modify the `--node` flag values for each cosigner, or modify the config after the initial generation.
```bash
$ horcrux config init --node "tcp://10.168.0.1:1234" --node "tcp://10.168.0.2:1234" --node "tcp://10.168.0.3:1234" --cosigner "tcp://10.168.1.1:2222" --cosigner "tcp://10.168.1.2:2222" --cosigner "tcp://10.168.1.3:2222" --threshold 2 --grpc-timeout 1000ms --raft-timeout 1000ms
```
> **Note**
-> Note the use of multiple `--node` and `--cosigner` flags. In this example, there are 3 sentry (chain) nodes that each horcrux cosigner will connect to. There are 3 horcrux cosigners, with a threshold of 2 cosigners required to sign a valid block signature.
+> Note the use of multiple `--node` and `--cosigner` flags. In this example, there are 3 sentry (chain) nodes that each horcrux cosigner will connect to. There are 3 horcrux cosigner, with a threshold of 2 cosigner required to sign a valid block signature.
#### Flags
-- `-c`/`--cosigner`: configures the P2P address and shard ID for cosigner nodes. Keeping the node names and the IDs the same helps avoid errors. The DNS/IP used for all of these must be reachable by the other cosigners, i.e. do not use 0.0.0.0 for the hostname.
+- `-c`/`--cosigner`: configures the P2P address and shard ID for cosigner nodes. Keeping the node names and the IDs the same helps avoid errors. The DNS/IP used for all of these must be reachable by the other cosigner, i.e. do not use 0.0.0.0 for the hostname.
- `-n`/`--node`: configures the priv-val interface listen address for the chain sentry nodes.
- `-k`/`--key-dir`: configures the directory for the RSA and Ed25519 private key files if you would like to use a different path than the default, `~/.horcrux`.
- `--grpc-timeout`: configures the timeout for cosigner-to-cosigner GRPC communication. This value defaults to `1000ms`.
@@ -91,7 +91,7 @@ $ horcrux config init --node "tcp://10.168.0.1:1234" --node "tcp://10.168.0.2:12
### 3. Generate cosigner communication encryption keys
-Horcrux uses secp256k1 keys to encrypt (ECIES) and sign (ECDSA) cosigner-to-cosigner p2p communication. This is done by encrypting the payloads that are sent over GRPC between cosigners. Open your shell to a working directory and generate the ECIES keys that will be used on each cosigner using the `horcrux` CLI on your local machine.
+Horcrux uses secp256k1 keys to encrypt (ECIES) and sign (ECDSA) cosigner-to-cosigner p2p communication. This is done by encrypting the payloads that are sent over GRPC between cosigner. Open your shell to a working directory and generate the ECIES keys that will be used on each cosigner using the `horcrux` CLI on your local machine.
```bash
$ horcrux create-ecies-shards --shards 3
@@ -117,7 +117,7 @@ ecies_keys.json
> **CAUTION:** **The security of any key material is outside the scope of this guide. The suggested procedure here is not necessarily the one you will use. We aim to make this guide easy to understand, not necessarily the most secure. This guide assumes that your local machine is a trusted computer. The tooling here is all written in go and can be compiled and used in an airgapped setup if needed. Please open issues if you have questions about how to fit `horcrux` into your infra.**
-Horcrux uses threshold Ed25519 cryptography to sign a block payload on the cosigners and combine the resulting signatures to produce a signature that can be validated against your validator's Ed25519 public key. On your local machine which contains your full `priv_validator_key.json` key file(s), shard the key using the `horcrux` CLI in the same working directory as the previous command.
+Horcrux uses threshold Ed25519 cryptography to sign a block payload on the cosigner and combine the resulting signatures to produce a signature that can be validated against your validator's Ed25519 public key. On your local machine which contains your full `priv_validator_key.json` key file(s), shard the key using the `horcrux` CLI in the same working directory as the previous command.
```bash
$ horcrux create-ed25519-shards --chain-id cosmoshub-4 --key-file /path/to/cosmoshub/priv_validator_key.json --threshold 2 --shards 3
diff --git a/docs/misc.md b/docs/misc.md
new file mode 100644
index 00000000..e9fcc963
--- /dev/null
+++ b/docs/misc.md
@@ -0,0 +1,37 @@
+# Misc
+
+| | Num. Rounds | Robust | Num. Signers | Parallel Secure |
+|--------------------|:--------------------:|:------:|:------------:|:---------------:|
+| **Stinson Strobl [^1]** | 4 | Yes | t | Yes |
+| **Gennaro et al. [^2]** | 1 with preprocessing | No | n | No |
+| **FROST** [^3] | 1 with preprocessing | No | t | Yes |
+| **ROAST** [^TBD] | TBD | TBD | TBD | TBD |
+**Stinson Strobl** threshold signature scheme is the **only** implemented Threshold Scheme in Horcrux so far. However, its important to note that the key generation in Horcrux is not fully the same as proposed in the paper. Instead of using Pedersen´s Verifiable Secret Sharing (PVSS) Horxruc uses "classic" shamir secret sharing with a fully trusted dealer.
+
+
+### Overview
+
+#### Stinson and Strobl
+**Stinson and Strobl**[^1] is a threshold signature scheme producing Schnorr signatures. It uses a modification of Pedersen’s DKG presented by Gennaro et al.[^4] to generate both the *secret key s* during key generation as well as the *random nonce k* for each signing operation.
+
+This construction requires at minimum four rounds for each signing operation (assuming no participant misbehaves):
+- three rounds to perform the DKG to obtain k (the random nonce),
+- and one round to distribute signature shares and compute the group signature.
+
+Each round requires participants to send values to every other participant.
+
+
+[^1]: Stinson, D.R., Strobl, R. (2001). Provably Secure Distributed Schnorr Signatures and a (t, n) Threshold Scheme for Implicit Certificates. In: Varadharajan, V., Mu, Y. (eds) Information Security and Privacy. ACISP 2001. Lecture Notes in Computer Science, vol 2119. Springer, Berlin, Heidelberg. [](https://doi.org/10.1007/3-540-47719-5_33)https://doi.org/10.1007/3-540-47719-5_33
+[^2]: Gennaro, R., Goldfeder, S. (2020). One Round Threshold ECDSA with Identifiable Abort. In: Cryptology ePrint Archive, Paper 2020/540. [](https://eprint.iacr.org/2020/540)https://eprint.iacr.org/2020/540
+[^3]: Komlo, C., Goldberg, I. (2021). FROST: Flexible Round-Optimized Schnorr Threshold Signatures. In: Dunkelman, O., Jacobson, Jr., M.J., O'Flynn, C. (eds) Selected Areas in Cryptography. SAC 2020. Lecture Notes in Computer Science(), vol 12804. Springer, Cham. [](https://eprint.iacr.org/2020/852.pdf)https://eprint.iacr.org/2020/852.pdf
+[^4]: Rosario Gennaro, Stanislaw Jarecki, Hugo Krawczyk, and Tal Rabin. Secure Distributed Key Generation for Discrete-Log Based Cryptosystems. Journal of Cryptology, 20:51–83, 2007.
+
+### Glossary - WORK IN PROGRESS
+
+- In cryptography, a **nonce** (number once) is an arbitrary number that can be used just once in a cryptographic communication.
+
+- A cryptographic key is called **ephemeral** if it is generated for each execution of a key establishment process.
+
+- **Threshold signatures** allow for splitting a private key into n secret shares. To sign a message, at least some threshold of the shareholders need to coordinate and provide their individual signatures using their share. These individual signatures combine to form a single valid signature.
+
+- **Robust schemes** ensure that so long as t participants correctly follow the protocol, the protocol is guaranteed to complete successfully, even if a subset of participants (at most n − t) contribute malformed shares.
diff --git a/signer/cond/cond.go b/pkg/cond/cond.go
similarity index 92%
rename from signer/cond/cond.go
rename to pkg/cond/cond.go
index 74b0b3bd..c7fe7c55 100644
--- a/signer/cond/cond.go
+++ b/pkg/cond/cond.go
@@ -17,6 +17,8 @@ type Cond struct {
p atomic.Pointer[chan struct{}]
}
+// New creates a new Cond instance. It requires a Locker instance to lock/unlock
+// before/after each Wait() call.
func New(l sync.Locker) *Cond {
c := &Cond{
L: l,
diff --git a/signer/cond/cond_test.go b/pkg/cond/cond_test.go
similarity index 93%
rename from signer/cond/cond_test.go
rename to pkg/cond/cond_test.go
index 21b35077..41fc683e 100644
--- a/signer/cond/cond_test.go
+++ b/pkg/cond/cond_test.go
@@ -5,7 +5,8 @@ import (
"sync"
"testing"
- "github.com/strangelove-ventures/horcrux/signer/cond"
+ "github.com/strangelove-ventures/horcrux/pkg/cond"
+
"github.com/stretchr/testify/require"
)
diff --git a/signer/config.go b/pkg/cosigner/config.go
similarity index 89%
rename from signer/config.go
rename to pkg/cosigner/config.go
index d78582a9..f61bc446 100644
--- a/signer/config.go
+++ b/pkg/cosigner/config.go
@@ -1,4 +1,4 @@
-package signer
+package cosigner
import (
"fmt"
@@ -43,7 +43,7 @@ func (c *Config) Nodes() (out []string) {
return out
}
-func (c *Config) MustMarshalYaml() []byte {
+func (c *Config) mustMarshalYaml() []byte {
out, err := yaml.Marshal(c)
if err != nil {
panic(err)
@@ -106,8 +106,8 @@ type RuntimeConfig struct {
Config Config
}
-func (c RuntimeConfig) CosignerSecurityECIES() (*CosignerSecurityECIES, error) {
- keyFile, err := c.KeyFileExistsCosignerECIES()
+func (c RuntimeConfig) SecurityECIES() (*CosignSecurityECIES, error) {
+ keyFile, err := c.KeyFileExistsCosignECIES()
if err != nil {
return nil, err
}
@@ -120,13 +120,13 @@ func (c RuntimeConfig) CosignerSecurityECIES() (*CosignerSecurityECIES, error) {
return NewCosignerSecurityECIES(key), nil
}
-func (c RuntimeConfig) CosignerSecurityRSA() (*CosignerSecurityRSA, error) {
- keyFile, err := c.KeyFileExistsCosignerRSA()
+func (c RuntimeConfig) SecurityRSA() (*SecurityRSA, error) {
+ keyFile, err := c.KeyFileExistsCosignRSA()
if err != nil {
return nil, err
}
- key, err := LoadCosignerRSAKey(keyFile)
+ key, err := LoadCosignRSAKey(keyFile)
if err != nil {
return nil, fmt.Errorf("error reading cosigner key (%s): %w", keyFile, err)
}
@@ -177,12 +177,12 @@ func (c RuntimeConfig) PrivValStateFile(chainID string) string {
return filepath.Join(c.StateDir, fmt.Sprintf("%s_priv_validator_state.json", chainID))
}
-func (c RuntimeConfig) CosignerStateFile(chainID string) string {
+func (c RuntimeConfig) CosignStateFile(chainID string) string {
return filepath.Join(c.StateDir, fmt.Sprintf("%s_share_sign_state.json", chainID))
}
func (c RuntimeConfig) WriteConfigFile() error {
- return os.WriteFile(c.ConfigFile, c.Config.MustMarshalYaml(), 0600)
+ return os.WriteFile(c.ConfigFile, c.Config.mustMarshalYaml(), 0600)
}
func fileExists(file string) error {
@@ -205,17 +205,17 @@ func (c RuntimeConfig) KeyFileExistsSingleSigner(chainID string) (string, error)
return keyFile, fileExists(keyFile)
}
-func (c RuntimeConfig) KeyFileExistsCosigner(chainID string) (string, error) {
+func (c RuntimeConfig) KeyFileExistsCosign(chainID string) (string, error) {
keyFile := c.KeyFilePathCosigner(chainID)
return keyFile, fileExists(keyFile)
}
-func (c RuntimeConfig) KeyFileExistsCosignerRSA() (string, error) {
+func (c RuntimeConfig) KeyFileExistsCosignRSA() (string, error) {
keyFile := c.KeyFilePathCosignerRSA()
return keyFile, fileExists(keyFile)
}
-func (c RuntimeConfig) KeyFileExistsCosignerECIES() (string, error) {
+func (c RuntimeConfig) KeyFileExistsCosignECIES() (string, error) {
keyFile := c.KeyFilePathCosignerECIES()
return keyFile, fileExists(keyFile)
}
@@ -236,13 +236,13 @@ func (cfg *ThresholdModeConfig) LeaderElectMultiAddress() (string, error) {
return client.MultiAddress(addresses)
}
-// CosignerConfig is the on disk format representing a cosigner for threshold sign mode.
-type CosignerConfig struct {
+// CosignConfig is the on disk format representing a cosigner for threshold sign mode.
+type CosignConfig struct {
ShardID int `yaml:"shardID"`
P2PAddr string `yaml:"p2pAddr"`
}
-type CosignersConfig []CosignerConfig
+type CosignersConfig []CosignConfig
func (cosigners CosignersConfig) Validate() error {
// Check IDs to make sure none are duplicated
@@ -283,7 +283,7 @@ func (cosigners CosignersConfig) Validate() error {
return nil
}
-func duplicateCosigners(cosigners []CosignerConfig) (duplicates map[int][]string) {
+func duplicateCosigners(cosigners []CosignConfig) (duplicates map[int][]string) {
idAddrs := make(map[int][]string)
for _, cosigner := range cosigners {
// Collect all addresses assigned to each cosigner.
@@ -306,10 +306,10 @@ func duplicateCosigners(cosigners []CosignerConfig) (duplicates map[int][]string
return idAddrs
}
-func CosignersFromFlag(cosigners []string) (out []CosignerConfig, err error) {
+func CosignersFromFlag(cosigners []string) (out []CosignConfig, err error) {
var errs []error
for i, c := range cosigners {
- out = append(out, CosignerConfig{ShardID: i + 1, P2PAddr: c})
+ out = append(out, CosignConfig{ShardID: i + 1, P2PAddr: c})
}
if len(errs) > 0 {
return nil, nil
diff --git a/signer/config_test.go b/pkg/cosigner/config_test.go
similarity index 82%
rename from signer/config_test.go
rename to pkg/cosigner/config_test.go
index 456ea541..83b8b6e9 100644
--- a/signer/config_test.go
+++ b/pkg/cosigner/config_test.go
@@ -1,4 +1,4 @@
-package signer_test
+package cosigner_test
import (
"fmt"
@@ -8,15 +8,16 @@ import (
"path/filepath"
"testing"
- "github.com/strangelove-ventures/horcrux/signer"
+ "github.com/strangelove-ventures/horcrux/pkg/cosigner"
+
"github.com/stretchr/testify/require"
)
const testChainID = "test"
func TestNodes(t *testing.T) {
- c := signer.Config{
- ChainNodes: signer.ChainNodes{
+ c := cosigner.Config{
+ ChainNodes: cosigner.ChainNodes{
{
PrivValAddr: "tcp://0.0.0.0:1234",
},
@@ -32,15 +33,15 @@ func TestNodes(t *testing.T) {
func TestValidateSingleSignerConfig(t *testing.T) {
type testCase struct {
name string
- config signer.Config
+ config cosigner.Config
expectErr error
}
testCases := []testCase{
{
name: "valid config",
- config: signer.Config{
- ChainNodes: []signer.ChainNode{
+ config: cosigner.Config{
+ ChainNodes: []cosigner.ChainNode{
{
PrivValAddr: "tcp://127.0.0.1:1234",
},
@@ -50,15 +51,15 @@ func TestValidateSingleSignerConfig(t *testing.T) {
},
{
name: "no nodes configured",
- config: signer.Config{
+ config: cosigner.Config{
ChainNodes: nil,
},
expectErr: fmt.Errorf("need to have chainNodes configured for priv-val connection"),
},
{
name: "invalid node address",
- config: signer.Config{
- ChainNodes: []signer.ChainNode{
+ config: cosigner.Config{
+ ChainNodes: []cosigner.ChainNode{
{
PrivValAddr: "abc://\\invalid_addr",
},
@@ -82,19 +83,19 @@ func TestValidateSingleSignerConfig(t *testing.T) {
func TestValidateThresholdModeConfig(t *testing.T) {
type testCase struct {
name string
- config signer.Config
+ config cosigner.Config
expectErr error
}
testCases := []testCase{
{
name: "valid config",
- config: signer.Config{
- ThresholdModeConfig: &signer.ThresholdModeConfig{
+ config: cosigner.Config{
+ ThresholdModeConfig: &cosigner.ThresholdModeConfig{
Threshold: 2,
RaftTimeout: "1000ms",
GRPCTimeout: "1000ms",
- Cosigners: signer.CosignersConfig{
+ Cosigners: cosigner.CosignersConfig{
{
ShardID: 1,
P2PAddr: "tcp://127.0.0.1:2223",
@@ -109,7 +110,7 @@ func TestValidateThresholdModeConfig(t *testing.T) {
},
},
},
- ChainNodes: []signer.ChainNode{
+ ChainNodes: []cosigner.ChainNode{
{
PrivValAddr: "tcp://127.0.0.1:1234",
},
@@ -125,8 +126,8 @@ func TestValidateThresholdModeConfig(t *testing.T) {
},
{
name: "no cosigner config",
- config: signer.Config{
- ChainNodes: []signer.ChainNode{
+ config: cosigner.Config{
+ ChainNodes: []cosigner.ChainNode{
{
PrivValAddr: "tcp://127.0.0.1:1234",
},
@@ -142,12 +143,12 @@ func TestValidateThresholdModeConfig(t *testing.T) {
},
{
name: "invalid p2p listen",
- config: signer.Config{
- ThresholdModeConfig: &signer.ThresholdModeConfig{
+ config: cosigner.Config{
+ ThresholdModeConfig: &cosigner.ThresholdModeConfig{
Threshold: 2,
RaftTimeout: "1000ms",
GRPCTimeout: "1000ms",
- Cosigners: signer.CosignersConfig{
+ Cosigners: cosigner.CosignersConfig{
{
ShardID: 1,
P2PAddr: ":2222",
@@ -162,7 +163,7 @@ func TestValidateThresholdModeConfig(t *testing.T) {
},
},
},
- ChainNodes: []signer.ChainNode{
+ ChainNodes: []cosigner.ChainNode{
{
PrivValAddr: "tcp://127.0.0.1:1234",
},
@@ -182,12 +183,12 @@ func TestValidateThresholdModeConfig(t *testing.T) {
},
{
name: "not enough cosigners",
- config: signer.Config{
- ThresholdModeConfig: &signer.ThresholdModeConfig{
+ config: cosigner.Config{
+ ThresholdModeConfig: &cosigner.ThresholdModeConfig{
Threshold: 3,
RaftTimeout: "1000ms",
GRPCTimeout: "1000ms",
- Cosigners: signer.CosignersConfig{
+ Cosigners: cosigner.CosignersConfig{
{
ShardID: 1,
P2PAddr: "tcp://127.0.0.1:2222",
@@ -198,7 +199,7 @@ func TestValidateThresholdModeConfig(t *testing.T) {
},
},
},
- ChainNodes: []signer.ChainNode{
+ ChainNodes: []cosigner.ChainNode{
{
PrivValAddr: "tcp://127.0.0.1:1234",
},
@@ -214,12 +215,12 @@ func TestValidateThresholdModeConfig(t *testing.T) {
},
{
name: "invalid raft timeout",
- config: signer.Config{
- ThresholdModeConfig: &signer.ThresholdModeConfig{
+ config: cosigner.Config{
+ ThresholdModeConfig: &cosigner.ThresholdModeConfig{
Threshold: 2,
GRPCTimeout: "1000ms",
RaftTimeout: "1000",
- Cosigners: signer.CosignersConfig{
+ Cosigners: cosigner.CosignersConfig{
{
ShardID: 1,
P2PAddr: "tcp://127.0.0.1:2222",
@@ -234,7 +235,7 @@ func TestValidateThresholdModeConfig(t *testing.T) {
},
},
},
- ChainNodes: []signer.ChainNode{
+ ChainNodes: []cosigner.ChainNode{
{
PrivValAddr: "tcp://127.0.0.1:1234",
},
@@ -250,12 +251,12 @@ func TestValidateThresholdModeConfig(t *testing.T) {
},
{
name: "invalid grpc timeout",
- config: signer.Config{
- ThresholdModeConfig: &signer.ThresholdModeConfig{
+ config: cosigner.Config{
+ ThresholdModeConfig: &cosigner.ThresholdModeConfig{
Threshold: 2,
GRPCTimeout: "1000",
RaftTimeout: "1000ms",
- Cosigners: signer.CosignersConfig{
+ Cosigners: cosigner.CosignersConfig{
{
ShardID: 1,
P2PAddr: "tcp://127.0.0.1:2222",
@@ -270,7 +271,7 @@ func TestValidateThresholdModeConfig(t *testing.T) {
},
},
},
- ChainNodes: []signer.ChainNode{
+ ChainNodes: []cosigner.ChainNode{
{
PrivValAddr: "tcp://127.0.0.1:1234",
},
@@ -286,12 +287,12 @@ func TestValidateThresholdModeConfig(t *testing.T) {
},
{
name: "no nodes configured",
- config: signer.Config{
- ThresholdModeConfig: &signer.ThresholdModeConfig{
+ config: cosigner.Config{
+ ThresholdModeConfig: &cosigner.ThresholdModeConfig{
Threshold: 2,
RaftTimeout: "1000ms",
GRPCTimeout: "1000ms",
- Cosigners: signer.CosignersConfig{
+ Cosigners: cosigner.CosignersConfig{
{
ShardID: 1,
P2PAddr: "tcp://127.0.0.1:2222",
@@ -312,12 +313,12 @@ func TestValidateThresholdModeConfig(t *testing.T) {
},
{
name: "invalid node address",
- config: signer.Config{
- ThresholdModeConfig: &signer.ThresholdModeConfig{
+ config: cosigner.Config{
+ ThresholdModeConfig: &cosigner.ThresholdModeConfig{
Threshold: 2,
RaftTimeout: "1000ms",
GRPCTimeout: "1000ms",
- Cosigners: signer.CosignersConfig{
+ Cosigners: cosigner.CosignersConfig{
{
ShardID: 1,
P2PAddr: "tcp://127.0.0.1:2222",
@@ -332,7 +333,7 @@ func TestValidateThresholdModeConfig(t *testing.T) {
},
},
},
- ChainNodes: []signer.ChainNode{
+ ChainNodes: []cosigner.ChainNode{
{
PrivValAddr: "abc://\\invalid_addr",
},
@@ -355,7 +356,7 @@ func TestValidateThresholdModeConfig(t *testing.T) {
func TestRuntimeConfigKeyFilePath(t *testing.T) {
dir := t.TempDir()
- c := signer.RuntimeConfig{
+ c := cosigner.RuntimeConfig{
HomeDir: dir,
}
@@ -369,7 +370,7 @@ func TestRuntimeConfigKeyFilePath(t *testing.T) {
func TestRuntimeConfigPrivValStateFile(t *testing.T) {
dir := t.TempDir()
- c := signer.RuntimeConfig{
+ c := cosigner.RuntimeConfig{
StateDir: dir,
}
@@ -379,15 +380,15 @@ func TestRuntimeConfigPrivValStateFile(t *testing.T) {
func TestRuntimeConfigWriteConfigFile(t *testing.T) {
dir := t.TempDir()
configFile := filepath.Join(dir, "config.yaml")
- c := signer.RuntimeConfig{
+ c := cosigner.RuntimeConfig{
ConfigFile: configFile,
- Config: signer.Config{
- SignMode: signer.SignModeThreshold,
- ThresholdModeConfig: &signer.ThresholdModeConfig{
+ Config: cosigner.Config{
+ SignMode: cosigner.SignModeThreshold,
+ ThresholdModeConfig: &cosigner.ThresholdModeConfig{
Threshold: 2,
RaftTimeout: "1000ms",
GRPCTimeout: "1000ms",
- Cosigners: signer.CosignersConfig{
+ Cosigners: cosigner.CosignersConfig{
{
ShardID: 1,
P2PAddr: "tcp://127.0.0.1:2222",
@@ -402,7 +403,7 @@ func TestRuntimeConfigWriteConfigFile(t *testing.T) {
},
},
},
- ChainNodes: []signer.ChainNode{
+ ChainNodes: []cosigner.ChainNode{
{
PrivValAddr: "tcp://127.0.0.1:1234",
},
@@ -441,12 +442,12 @@ debugAddr: ""
func TestRuntimeConfigKeyFileExists(t *testing.T) {
dir := t.TempDir()
- c := signer.RuntimeConfig{
+ c := cosigner.RuntimeConfig{
HomeDir: dir,
}
// Test cosigner
- keyFile, err := c.KeyFileExistsCosigner(testChainID)
+ keyFile, err := c.KeyFileExistsCosign(testChainID)
require.Error(t, err)
require.Equal(t, fmt.Errorf(
@@ -462,10 +463,10 @@ func TestRuntimeConfigKeyFileExists(t *testing.T) {
err = os.WriteFile(keyFile, []byte{}, 0600)
require.NoError(t, err)
- _, err = c.KeyFileExistsCosigner(testChainID)
+ _, err = c.KeyFileExistsCosign(testChainID)
require.NoError(t, err)
- // Test single signer
+ // Test single pcosigner
keyFile, err = c.KeyFileExistsSingleSigner(testChainID)
require.Error(t, err)
@@ -487,11 +488,11 @@ func TestRuntimeConfigKeyFileExists(t *testing.T) {
}
func TestThresholdModeConfigLeaderElectMultiAddress(t *testing.T) {
- c := &signer.ThresholdModeConfig{
+ c := &cosigner.ThresholdModeConfig{
Threshold: 2,
RaftTimeout: "1000ms",
GRPCTimeout: "1000ms",
- Cosigners: signer.CosignersConfig{
+ Cosigners: cosigner.CosignersConfig{
{
ShardID: 1,
P2PAddr: "tcp://127.0.0.1:2222",
@@ -515,13 +516,13 @@ func TestThresholdModeConfigLeaderElectMultiAddress(t *testing.T) {
func TestCosignerRSAPubKeysConfigValidate(t *testing.T) {
type testCase struct {
name string
- cosigners signer.CosignersConfig
+ cosigners cosigner.CosignersConfig
expectErr error
}
testCases := []testCase{
{
name: "valid config",
- cosigners: signer.CosignersConfig{
+ cosigners: cosigner.CosignersConfig{
{
ShardID: 1,
P2PAddr: "tcp://127.0.0.1:2222",
@@ -539,7 +540,7 @@ func TestCosignerRSAPubKeysConfigValidate(t *testing.T) {
},
{
name: "too many cosigners",
- cosigners: signer.CosignersConfig{
+ cosigners: cosigner.CosignersConfig{
{
ShardID: 2,
P2PAddr: "tcp://127.0.0.1:2223",
@@ -553,7 +554,7 @@ func TestCosignerRSAPubKeysConfigValidate(t *testing.T) {
},
{
name: "duplicate cosigner",
- cosigners: signer.CosignersConfig{
+ cosigners: cosigner.CosignersConfig{
{
ShardID: 2,
P2PAddr: "tcp://127.0.0.1:2223",
@@ -596,7 +597,7 @@ func TestCosignersFromFlag(t *testing.T) {
}
for _, tc := range testCases {
- _, err := signer.CosignersFromFlag(tc.cosigners)
+ _, err := cosigner.CosignersFromFlag(tc.cosigners)
if tc.expectErr == nil {
require.NoError(t, err, tc.name)
} else {
diff --git a/pkg/cosigner/cosigner.go b/pkg/cosigner/cosigner.go
new file mode 100644
index 00000000..4732ccfa
--- /dev/null
+++ b/pkg/cosigner/cosigner.go
@@ -0,0 +1,84 @@
+package cosigner
+
+import (
+ "time"
+
+ "github.com/strangelove-ventures/horcrux/pkg/types"
+
+ "github.com/strangelove-ventures/horcrux/pkg/proto"
+)
+
+type SignBlockResponse struct {
+ Signature []byte
+}
+
+// SignRequest is sent to a co-signer to obtain their signature for the SignBytes
+// The SignBytes should be a serialized block
+type SignRequest struct {
+ ChainID string
+ SignBytes []byte
+}
+
+type SignResponse struct {
+ NoncePublic []byte
+ Timestamp time.Time
+ Signature []byte
+}
+
+// WrappedNonce is wrapping the Nonce to be used in communication between cosigners
+type WrappedNonce struct {
+ SourceID int
+ DestinationID int
+ PubKey []byte
+ Share []byte
+ Signature []byte
+}
+
+func (secretPart *WrappedNonce) toProto() *proto.Nonce {
+ return &proto.Nonce{
+ SourceID: int32(secretPart.SourceID),
+ DestinationID: int32(secretPart.DestinationID),
+ PubKey: secretPart.PubKey,
+ Share: secretPart.Share,
+ Signature: secretPart.Signature,
+ }
+}
+
+// WrappedNonces is a list of WrappedNonce
+type WrappedNonces []WrappedNonce
+
+func (secretParts WrappedNonces) ToProto() (out []*proto.Nonce) {
+ for _, secretPart := range secretParts {
+ out = append(out, secretPart.toProto())
+ }
+ return
+}
+
+func NonceFromProto(secretPart *proto.Nonce) WrappedNonce {
+ return WrappedNonce{
+ SourceID: int(secretPart.SourceID),
+ DestinationID: int(secretPart.DestinationID),
+ PubKey: secretPart.PubKey,
+ Share: secretPart.Share,
+ Signature: secretPart.Signature,
+ }
+}
+
+func NoncesFromProto(secretParts []*proto.Nonce) []WrappedNonce {
+ out := make([]WrappedNonce, len(secretParts))
+ for i, secretPart := range secretParts {
+ out[i] = NonceFromProto(secretPart)
+ }
+ return out
+}
+
+type NoncesResponse struct {
+ Nonces []WrappedNonce
+}
+
+type SetNoncesAndSignRequest struct {
+ ChainID string
+ Nonces []WrappedNonce
+ HRST types.HRSTKey
+ SignBytes []byte
+}
diff --git a/signer/cosigner_key.go b/pkg/cosigner/cosigner_key.go
similarity index 76%
rename from signer/cosigner_key.go
rename to pkg/cosigner/cosigner_key.go
index 8aaa396d..3190ce19 100644
--- a/signer/cosigner_key.go
+++ b/pkg/cosigner/cosigner_key.go
@@ -1,4 +1,4 @@
-package signer
+package cosigner
import (
"encoding/json"
@@ -11,15 +11,15 @@ import (
amino "github.com/tendermint/go-amino"
)
-// CosignerEd25519Key is a single Ed255219 key shard for an m-of-n threshold signer.
-type CosignerEd25519Key struct {
+// CosignEd25519Key is a single Ed255219 key shard for an m-of-n threshold signer.
+type CosignEd25519Key struct {
PubKey cometcrypto.PubKey `json:"pubKey"`
PrivateShard []byte `json:"privateShard"`
ID int `json:"id"`
}
-func (key *CosignerEd25519Key) MarshalJSON() ([]byte, error) {
- type Alias CosignerEd25519Key
+func (key *CosignEd25519Key) MarshalJSON() ([]byte, error) {
+ type Alias CosignEd25519Key
protoPubkey, err := cometcryptoencoding.PubKeyToProto(key.PubKey)
if err != nil {
@@ -31,17 +31,18 @@ func (key *CosignerEd25519Key) MarshalJSON() ([]byte, error) {
return nil, err
}
- return json.Marshal(&struct {
- PubKey []byte `json:"pubKey"`
- *Alias
- }{
- PubKey: protoBytes,
- Alias: (*Alias)(key),
- })
+ return json.Marshal(
+ &struct {
+ PubKey []byte `json:"pubKey"`
+ *Alias
+ }{
+ PubKey: protoBytes,
+ Alias: (*Alias)(key),
+ })
}
-func (key *CosignerEd25519Key) UnmarshalJSON(data []byte) error {
- type Alias CosignerEd25519Key
+func (key *CosignEd25519Key) UnmarshalJSON(data []byte) error {
+ type Alias CosignEd25519Key
aux := &struct {
PubkeyBytes []byte `json:"pubKey"`
@@ -84,9 +85,9 @@ func (key *CosignerEd25519Key) UnmarshalJSON(data []byte) error {
return nil
}
-// LoadCosignerEd25519Key loads a CosignerEd25519Key from file.
-func LoadCosignerEd25519Key(file string) (CosignerEd25519Key, error) {
- pvKey := CosignerEd25519Key{}
+// LoadCosignerEd25519Key loads a CosignEd25519Key from file.
+func LoadCosignerEd25519Key(file string) (CosignEd25519Key, error) {
+ pvKey := CosignEd25519Key{}
keyJSONBytes, err := os.ReadFile(file)
if err != nil {
return pvKey, err
diff --git a/signer/cosigner_key_shares.go b/pkg/cosigner/cosigner_key_shares.go
similarity index 71%
rename from signer/cosigner_key_shares.go
rename to pkg/cosigner/cosigner_key_shares.go
index 0aee38a5..68459989 100644
--- a/signer/cosigner_key_shares.go
+++ b/pkg/cosigner/cosigner_key_shares.go
@@ -1,4 +1,4 @@
-package signer
+package cosigner
import (
"crypto/rand"
@@ -14,8 +14,8 @@ import (
"golang.org/x/sync/errgroup"
)
-// CreateCosignerEd25519ShardsFromFile creates CosignerEd25519Key objects from a priv_validator_key.json file
-func CreateCosignerEd25519ShardsFromFile(priv string, threshold, shards uint8) ([]CosignerEd25519Key, error) {
+// CreateCosignerEd25519ShardsFromFile creates CosignEd25519Key objects from a priv_validator_key.json file
+func CreateCosignerEd25519ShardsFromFile(priv string, threshold, shards uint8) ([]CosignEd25519Key, error) {
pv, err := ReadPrivValidatorFile(priv)
if err != nil {
return nil, err
@@ -23,12 +23,15 @@ func CreateCosignerEd25519ShardsFromFile(priv string, threshold, shards uint8) (
return CreateCosignerEd25519Shards(pv, threshold, shards), nil
}
-// CreateCosignerEd25519Shards creates CosignerEd25519Key objects from a privval.FilePVKey
-func CreateCosignerEd25519Shards(pv privval.FilePVKey, threshold, shards uint8) []CosignerEd25519Key {
+// CreateCosignerEd25519Shards creates CosignEd25519Key objects from a privval.FilePVKey
+// by splitting the secret using Shamir secret sharing.
+func CreateCosignerEd25519Shards(pv privval.FilePVKey, threshold, shards uint8) []CosignEd25519Key {
+ // tsed25519.DealShares splits the secret using Shamir Secret Sharing (Note its: no verifiable secret sharing)
+ // privshards is shamir shares
privShards := tsed25519.DealShares(tsed25519.ExpandSecret(pv.PrivKey.Bytes()[:32]), threshold, shards)
- out := make([]CosignerEd25519Key, shards)
+ out := make([]CosignEd25519Key, shards)
for i, shard := range privShards {
- out[i] = CosignerEd25519Key{
+ out[i] = CosignEd25519Key{
PubKey: pv.PubKey,
PrivateShard: shard,
ID: i + 1,
@@ -37,15 +40,15 @@ func CreateCosignerEd25519Shards(pv privval.FilePVKey, threshold, shards uint8)
return out
}
-// CreateCosignerRSAShards generate CosignerRSAKey objects.
-func CreateCosignerRSAShards(shards int) ([]CosignerRSAKey, error) {
+// CreateCosignerRSAShards generate CosignRSAKey objects.
+func CreateCosignerRSAShards(shards int) ([]CosignRSAKey, error) {
rsaKeys, pubKeys, err := makeRSAKeys(shards)
if err != nil {
return nil, err
}
- out := make([]CosignerRSAKey, shards)
+ out := make([]CosignRSAKey, shards)
for i, key := range rsaKeys {
- out[i] = CosignerRSAKey{
+ out[i] = CosignRSAKey{
ID: i + 1,
RSAKey: *key,
RSAPubs: pubKeys,
@@ -67,7 +70,7 @@ func ReadPrivValidatorFile(priv string) (out privval.FilePVKey, err error) {
}
// WriteCosignerEd25519ShardFile writes a cosigner Ed25519 key to a given file name.
-func WriteCosignerEd25519ShardFile(cosigner CosignerEd25519Key, file string) error {
+func WriteCosignerEd25519ShardFile(cosigner CosignEd25519Key, file string) error {
jsonBytes, err := json.Marshal(&cosigner)
if err != nil {
return err
@@ -76,7 +79,7 @@ func WriteCosignerEd25519ShardFile(cosigner CosignerEd25519Key, file string) err
}
// WriteCosignerRSAShardFile writes a cosigner RSA key to a given file name.
-func WriteCosignerRSAShardFile(cosigner CosignerRSAKey, file string) error {
+func WriteCosignerRSAShardFile(cosigner CosignRSAKey, file string) error {
jsonBytes, err := json.Marshal(&cosigner)
if err != nil {
return err
@@ -84,15 +87,15 @@ func WriteCosignerRSAShardFile(cosigner CosignerRSAKey, file string) error {
return os.WriteFile(file, jsonBytes, 0600)
}
-// CreateCosignerECIESShards generates CosignerECIESKey objects.
-func CreateCosignerECIESShards(shards int) ([]CosignerECIESKey, error) {
+// CreateCosignerECIESShards generates CosignEciesKey objects.
+func CreateCosignerECIESShards(shards int) ([]CosignEciesKey, error) {
eciesKeys, pubKeys, err := makeECIESKeys(shards)
if err != nil {
return nil, err
}
- out := make([]CosignerECIESKey, shards)
+ out := make([]CosignEciesKey, shards)
for i, key := range eciesKeys {
- out[i] = CosignerECIESKey{
+ out[i] = CosignEciesKey{
ID: i + 1,
ECIESKey: key,
ECIESPubs: pubKeys,
@@ -101,8 +104,8 @@ func CreateCosignerECIESShards(shards int) ([]CosignerECIESKey, error) {
return out, nil
}
-// WriteCosignerECIESShardFile writes a cosigner ECIES key to a given file name.
-func WriteCosignerECIESShardFile(cosigner CosignerECIESKey, file string) error {
+// WriteCosignECIESShardFile writes a cosigner ECIES key to a given file name.
+func WriteCosignECIESShardFile(cosigner CosignEciesKey, file string) error {
jsonBytes, err := json.Marshal(&cosigner)
if err != nil {
return err
diff --git a/signer/cosigner_security.go b/pkg/cosigner/cosigner_security.go
similarity index 74%
rename from signer/cosigner_security.go
rename to pkg/cosigner/cosigner_security.go
index dc22254a..eed21764 100644
--- a/signer/cosigner_security.go
+++ b/pkg/cosigner/cosigner_security.go
@@ -1,7 +1,7 @@
-package signer
+package cosigner
-// CosignerSecurity is an interface for the security layer of the cosigner.
-type CosignerSecurity interface {
+// ICosignerSecurity is an interface for the security layer of the cosigner.
+type ICosignerSecurity interface {
// GetID returns the ID of the cosigner.
GetID() int
@@ -10,7 +10,7 @@ type CosignerSecurity interface {
id int,
noncePub []byte,
nonceShare []byte,
- ) (CosignerNonce, error)
+ ) (WrappedNonce, error)
// DecryptAndVerify decrypts the nonce and verifies the signature to authenticate the source cosigner.
DecryptAndVerify(
diff --git a/signer/cosigner_security_ecies.go b/pkg/cosigner/cosigner_security_ecies.go
similarity index 77%
rename from signer/cosigner_security_ecies.go
rename to pkg/cosigner/cosigner_security_ecies.go
index cde12d12..4f530cad 100644
--- a/signer/cosigner_security_ecies.go
+++ b/pkg/cosigner/cosigner_security_ecies.go
@@ -1,4 +1,4 @@
-package signer
+package cosigner
import (
"crypto/ecdsa"
@@ -15,30 +15,30 @@ import (
"golang.org/x/sync/errgroup"
)
-var _ CosignerSecurity = &CosignerSecurityECIES{}
+var _ ICosignerSecurity = &CosignSecurityECIES{}
-// CosignerSecurityECIES is an implementation of CosignerSecurity
+// CosignSecurityECIES is an implementation of CosignerSecurity
// using ECIES for encryption and ECDSA for digital signature.
-type CosignerSecurityECIES struct {
- key CosignerECIESKey
- eciesPubKeys map[int]CosignerECIESPubKey
+type CosignSecurityECIES struct {
+ key CosignEciesKey
+ eciesPubKeys map[int]CosignECIESPubKey
}
-// CosignerECIESKey is a cosigner's ECIES public key.
-type CosignerECIESPubKey struct {
+// CosignEciesKey is a cosigner's ECIES public key.
+type CosignECIESPubKey struct {
ID int
PublicKey *ecies.PublicKey
}
-// CosignerECIESKey is an ECIES key for an m-of-n threshold signer, composed of a private key and n public keys.
-type CosignerECIESKey struct {
+// CosignEciesKey is an ECIES key for an m-of-n threshold signer, composed of a private key and n public keys.
+type CosignEciesKey struct {
ECIESKey *ecies.PrivateKey `json:"eciesKey"`
ID int `json:"id"`
ECIESPubs []*ecies.PublicKey `json:"eciesPubs"`
}
-func (key *CosignerECIESKey) MarshalJSON() ([]byte, error) {
- type Alias CosignerECIESKey
+func (key *CosignEciesKey) MarshalJSON() ([]byte, error) {
+ type Alias CosignEciesKey
// marshal our private key and all public keys
privateBytes := key.ECIESKey.D.Bytes()
@@ -62,8 +62,8 @@ func (key *CosignerECIESKey) MarshalJSON() ([]byte, error) {
})
}
-func (key *CosignerECIESKey) UnmarshalJSON(data []byte) error {
- type Alias CosignerECIESKey
+func (key *CosignEciesKey) UnmarshalJSON(data []byte) error {
+ type Alias CosignEciesKey
aux := &struct {
ECIESKey []byte `json:"eciesKey"`
@@ -97,9 +97,9 @@ func (key *CosignerECIESKey) UnmarshalJSON(data []byte) error {
return nil
}
-// LoadCosignerECIESKey loads a CosignerECIESKey from file.
-func LoadCosignerECIESKey(file string) (CosignerECIESKey, error) {
- pvKey := CosignerECIESKey{}
+// LoadCosignerECIESKey loads a CosignEciesKey from file.
+func LoadCosignerECIESKey(file string) (CosignEciesKey, error) {
+ pvKey := CosignEciesKey{}
keyJSONBytes, err := os.ReadFile(file)
if err != nil {
return pvKey, err
@@ -113,15 +113,15 @@ func LoadCosignerECIESKey(file string) (CosignerECIESKey, error) {
return pvKey, nil
}
-// NewCosignerSecurityECIES creates a new CosignerSecurityECIES.
-func NewCosignerSecurityECIES(key CosignerECIESKey) *CosignerSecurityECIES {
- c := &CosignerSecurityECIES{
+// NewCosignerSecurityECIES creates a new CosignSecurityECIES.
+func NewCosignerSecurityECIES(key CosignEciesKey) *CosignSecurityECIES {
+ c := &CosignSecurityECIES{
key: key,
- eciesPubKeys: make(map[int]CosignerECIESPubKey, len(key.ECIESPubs)),
+ eciesPubKeys: make(map[int]CosignECIESPubKey, len(key.ECIESPubs)),
}
for i, pubKey := range key.ECIESPubs {
- c.eciesPubKeys[i+1] = CosignerECIESPubKey{
+ c.eciesPubKeys[i+1] = CosignECIESPubKey{
ID: i + 1,
PublicKey: pubKey,
}
@@ -131,13 +131,13 @@ func NewCosignerSecurityECIES(key CosignerECIESKey) *CosignerSecurityECIES {
}
// GetID returns the ID of the cosigner.
-func (c *CosignerSecurityECIES) GetID() int {
+func (c *CosignSecurityECIES) GetID() int {
return c.key.ID
}
// 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 *CosignSecurityECIES) EncryptAndSign(id int, noncePub []byte, nonceShare []byte) (WrappedNonce, error) {
+ nonce := WrappedNonce{
SourceID: c.key.ID,
}
@@ -195,7 +195,7 @@ func (c *CosignerSecurityECIES) EncryptAndSign(id int, noncePub []byte, nonceSha
// DecryptAndVerify decrypts the nonce and verifies
// the signature to authenticate the source cosigner.
-func (c *CosignerSecurityECIES) DecryptAndVerify(
+func (c *CosignSecurityECIES) DecryptAndVerify(
id int,
encryptedNoncePub []byte,
encryptedNonceShare []byte,
@@ -206,7 +206,7 @@ func (c *CosignerSecurityECIES) DecryptAndVerify(
return nil, nil, fmt.Errorf("unknown cosigner: %d", id)
}
- digestMsg := CosignerNonce{
+ digestMsg := WrappedNonce{
SourceID: id,
PubKey: encryptedNoncePub,
Share: encryptedNonceShare,
diff --git a/signer/cosigner_security_ecies_test.go b/pkg/cosigner/cosigner_security_ecies_test.go
similarity index 90%
rename from signer/cosigner_security_ecies_test.go
rename to pkg/cosigner/cosigner_security_ecies_test.go
index aa7d04d8..ae17ee3d 100644
--- a/signer/cosigner_security_ecies_test.go
+++ b/pkg/cosigner/cosigner_security_ecies_test.go
@@ -1,4 +1,4 @@
-package signer
+package cosigner
import (
"crypto/rand"
@@ -25,10 +25,10 @@ func TestCosignerECIES(t *testing.T) {
pubs[i] = &key.PublicKey
}
- securities := make([]CosignerSecurity, 3)
+ securities := make([]ICosignerSecurity, 3)
for i := 0; i < 3; i++ {
- key := CosignerECIESKey{
+ key := CosignEciesKey{
ID: i + 1,
ECIESKey: keys[i],
ECIESPubs: pubs,
@@ -38,7 +38,7 @@ func TestCosignerECIES(t *testing.T) {
bz, err := json.Marshal(&key)
require.NoError(t, err)
- var key2 CosignerECIESKey
+ var key2 CosignEciesKey
require.NoError(t, json.Unmarshal(bz, &key2))
require.Equal(t, key, key2)
@@ -55,7 +55,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 []ICosignerSecurity) error {
var (
mockPub = []byte("mock_pub")
mockShare = []byte("mock_share")
@@ -91,10 +91,10 @@ func TestConcurrentIterateCosignerECIES(t *testing.T) {
pubs[i] = &key.PublicKey
}
- securities := make([]CosignerSecurity, 3)
+ securities := make([]ICosignerSecurity, 3)
for i := 0; i < 3; i++ {
- securities[i] = NewCosignerSecurityECIES(CosignerECIESKey{
+ securities[i] = NewCosignerSecurityECIES(CosignEciesKey{
ID: i + 1,
ECIESKey: keys[i],
ECIESPubs: pubs,
diff --git a/signer/cosigner_security_rsa.go b/pkg/cosigner/cosigner_security_rsa.go
similarity index 76%
rename from signer/cosigner_security_rsa.go
rename to pkg/cosigner/cosigner_security_rsa.go
index eb46b442..e22757b6 100644
--- a/signer/cosigner_security_rsa.go
+++ b/pkg/cosigner/cosigner_security_rsa.go
@@ -1,4 +1,4 @@
-package signer
+package cosigner
import (
"crypto"
@@ -14,29 +14,29 @@ import (
"golang.org/x/sync/errgroup"
)
-var _ CosignerSecurity = &CosignerSecurityRSA{}
+var _ ICosignerSecurity = &SecurityRSA{}
-// CosignerSecurityRSA is an implementation of CosignerSecurity using RSA for encryption and P5S for digital signature.
-type CosignerSecurityRSA struct {
- key CosignerRSAKey
- rsaPubKeys map[int]CosignerRSAPubKey
+// SecurityRSA is an implementation of CosignerSecurity using RSA for encryption and P5S for digital signature.
+type SecurityRSA struct {
+ key CosignRSAKey
+ rsaPubKeys map[int]CosignRSAPubKey
}
-// CosignerRSAKey is a cosigner's RSA public key.
-type CosignerRSAPubKey struct {
+// CosignRSAKey is a cosigner's RSA public key.
+type CosignRSAPubKey struct {
ID int
PublicKey rsa.PublicKey
}
-// CosignerRSAKey is an RSA key for an m-of-n threshold signer, composed of a private key and n public keys.
-type CosignerRSAKey struct {
+// CosignRSAKey is an RSA key for an m-of-n threshold signer, composed of a private key and n public keys.
+type CosignRSAKey struct {
RSAKey rsa.PrivateKey `json:"rsaKey"`
ID int `json:"id"`
RSAPubs []*rsa.PublicKey `json:"rsaPubs"`
}
-func (key *CosignerRSAKey) MarshalJSON() ([]byte, error) {
- type Alias CosignerRSAKey
+func (key *CosignRSAKey) MarshalJSON() ([]byte, error) {
+ type Alias CosignRSAKey
// marshal our private key and all public keys
privateBytes := x509.MarshalPKCS1PrivateKey(&key.RSAKey)
@@ -57,8 +57,8 @@ func (key *CosignerRSAKey) MarshalJSON() ([]byte, error) {
})
}
-func (key *CosignerRSAKey) UnmarshalJSON(data []byte) error {
- type Alias CosignerRSAKey
+func (key *CosignRSAKey) UnmarshalJSON(data []byte) error {
+ type Alias CosignRSAKey
aux := &struct {
RSAKey []byte `json:"rsaKey"`
@@ -89,9 +89,9 @@ func (key *CosignerRSAKey) UnmarshalJSON(data []byte) error {
return nil
}
-// LoadCosignerRSAKey loads a CosignerRSAKey from file.
-func LoadCosignerRSAKey(file string) (CosignerRSAKey, error) {
- pvKey := CosignerRSAKey{}
+// LoadCosignRSAKey loads a CosignRSAKey from file.
+func LoadCosignRSAKey(file string) (CosignRSAKey, error) {
+ pvKey := CosignRSAKey{}
keyJSONBytes, err := os.ReadFile(file)
if err != nil {
return pvKey, err
@@ -106,14 +106,14 @@ func LoadCosignerRSAKey(file string) (CosignerRSAKey, error) {
}
// NewCosignerSecurityRSA creates a new CosignerSecurityRSA.
-func NewCosignerSecurityRSA(key CosignerRSAKey) *CosignerSecurityRSA {
- c := &CosignerSecurityRSA{
+func NewCosignerSecurityRSA(key CosignRSAKey) *SecurityRSA {
+ c := &SecurityRSA{
key: key,
- rsaPubKeys: make(map[int]CosignerRSAPubKey),
+ rsaPubKeys: make(map[int]CosignRSAPubKey),
}
for i, pubKey := range key.RSAPubs {
- c.rsaPubKeys[i+1] = CosignerRSAPubKey{
+ c.rsaPubKeys[i+1] = CosignRSAPubKey{
ID: i + 1,
PublicKey: *pubKey,
}
@@ -123,13 +123,13 @@ func NewCosignerSecurityRSA(key CosignerRSAKey) *CosignerSecurityRSA {
}
// GetID returns the ID of the cosigner.
-func (c *CosignerSecurityRSA) GetID() int {
+func (c *SecurityRSA) GetID() int {
return c.key.ID
}
// 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 *SecurityRSA) EncryptAndSign(id int, noncePub []byte, nonceShare []byte) (WrappedNonce, error) {
+ nonce := WrappedNonce{
SourceID: c.key.ID,
}
@@ -183,7 +183,7 @@ func (c *CosignerSecurityRSA) EncryptAndSign(id int, noncePub []byte, nonceShare
// DecryptAndVerify decrypts the nonce and verifies
// the signature to authenticate the source cosigner.
-func (c *CosignerSecurityRSA) DecryptAndVerify(
+func (c *SecurityRSA) DecryptAndVerify(
id int,
encryptedNoncePub []byte,
encryptedNonceShare []byte,
@@ -194,7 +194,7 @@ func (c *CosignerSecurityRSA) DecryptAndVerify(
return nil, nil, fmt.Errorf("unknown cosigner: %d", id)
}
- digestMsg := CosignerNonce{
+ digestMsg := WrappedNonce{
SourceID: id,
PubKey: encryptedNoncePub,
Share: encryptedNonceShare,
diff --git a/signer/cosigner_security_rsa_test.go b/pkg/cosigner/cosigner_security_rsa_test.go
similarity index 91%
rename from signer/cosigner_security_rsa_test.go
rename to pkg/cosigner/cosigner_security_rsa_test.go
index 7830d9af..00b97090 100644
--- a/signer/cosigner_security_rsa_test.go
+++ b/pkg/cosigner/cosigner_security_rsa_test.go
@@ -1,4 +1,4 @@
-package signer
+package cosigner
import (
"crypto/rand"
@@ -24,10 +24,10 @@ func TestCosignerRSA(t *testing.T) {
pubKeys[i] = &key.PublicKey
}
- securities := make([]CosignerSecurity, 3)
+ securities := make([]ICosignerSecurity, 3)
for i := 0; i < 3; i++ {
- key := CosignerRSAKey{
+ key := CosignRSAKey{
ID: i + 1,
RSAKey: *keys[i],
RSAPubs: pubKeys,
@@ -37,7 +37,7 @@ func TestCosignerRSA(t *testing.T) {
bz, err := json.Marshal(&key)
require.NoError(t, err)
- var key2 CosignerRSAKey
+ var key2 CosignRSAKey
require.NoError(t, json.Unmarshal(bz, &key2))
require.Equal(t, key, key2)
@@ -67,10 +67,10 @@ func TestConcurrentIterateCosignerRSA(t *testing.T) {
pubKeys[i] = &key.PublicKey
}
- securities := make([]CosignerSecurity, 3)
+ securities := make([]ICosignerSecurity, 3)
for i := 0; i < 3; i++ {
- securities[i] = NewCosignerSecurityRSA(CosignerRSAKey{
+ securities[i] = NewCosignerSecurityRSA(CosignRSAKey{
ID: i + 1,
RSAKey: *keys[i],
RSAPubs: pubKeys,
diff --git a/signer/threshold_signer.go b/pkg/cosigner/cosigner_signer.go
similarity index 52%
rename from signer/threshold_signer.go
rename to pkg/cosigner/cosigner_signer.go
index f4ebbd37..d5021dd8 100644
--- a/signer/threshold_signer.go
+++ b/pkg/cosigner/cosigner_signer.go
@@ -1,14 +1,15 @@
-package signer
+package cosigner
-// Interface for the local signer whether it's a soft sign or HSM
-type ThresholdSigner interface {
- // PubKey returns the public key bytes for the combination of all cosigners.
- PubKey() []byte
+// IThresholdSigner is interface for the cosigner_signer whether it's a soft sign or HSM
+type IThresholdSigner interface {
+ // GetPubKey returns the persistent public key
+ GetPubKey() []byte
// GenerateNonces deals nonces for all cosigners.
GenerateNonces() (Nonces, error)
- // Sign signs a byte payload with the provided nonces.
+ // Sign signs a byte payload using the a list of nonces.
+ // Sign returns the partial signature and an error if any.
Sign(nonces []Nonce, payload []byte) ([]byte, error)
// CombineSignatures combines multiple partial signatures to a full signature.
@@ -17,7 +18,11 @@ type ThresholdSigner interface {
// Nonces contains the ephemeral information generated by one cosigner for all other cosigners.
type Nonces struct {
+ // PubKey is the public key for the generated nounces by cosigner
PubKey []byte
+
+ // Shares is the list nonces of size n generated by the cosigner.
+ // Shares[i] is the nonce for cosigner i.
Shares [][]byte
}
@@ -28,7 +33,7 @@ type Nonce struct {
PubKey []byte
}
-// PartialSignature contains the signature and identifier for a piece of the combined signature.
+// PartialSignature contains the partial signature and identifier (shamir id) of the signer.
type PartialSignature struct {
ID int
Signature []byte
diff --git a/signer/threshold_signer_soft.go b/pkg/cosigner/cosigner_signer_soft.go
similarity index 79%
rename from signer/threshold_signer_soft.go
rename to pkg/cosigner/cosigner_signer_soft.go
index b3715737..7a95b9a7 100644
--- a/signer/threshold_signer_soft.go
+++ b/pkg/cosigner/cosigner_signer_soft.go
@@ -1,4 +1,4 @@
-package signer
+package cosigner
import (
"bytes"
@@ -10,17 +10,19 @@ import (
tsed25519 "gitlab.com/unit410/threshold-ed25519/pkg"
)
-var _ ThresholdSigner = &ThresholdSignerSoft{}
+var _ IThresholdSigner = &ThresholdSignerSoft{}
+// ThresholdSignerSoft is a soft implementation of the IThresholdSigner interface.
type ThresholdSignerSoft struct {
- privateKeyShard []byte
- pubKey []byte
- threshold uint8
- total uint8
+ privateKeyShard []byte // privateKeyShard is our persistent private key shard
+ pubKey []byte // pubKey is our persistent public key
+ threshold uint8 // threshold is the number of t cosigners required to sign, t
+ total uint8 // total is the total number n of cosigners
+
}
func NewThresholdSignerSoft(config *RuntimeConfig, id int, chainID string) (*ThresholdSignerSoft, error) {
- keyFile, err := config.KeyFileExistsCosigner(chainID)
+ keyFile, err := config.KeyFileExistsCosign(chainID)
if err != nil {
return nil, err
}
@@ -44,7 +46,8 @@ func NewThresholdSignerSoft(config *RuntimeConfig, id int, chainID string) (*Thr
return &s, nil
}
-func (s *ThresholdSignerSoft) PubKey() []byte {
+// GetPubkey implements the IThresholdSigner interface
+func (s *ThresholdSignerSoft) GetPubKey() []byte {
return s.pubKey
}
@@ -59,6 +62,7 @@ func (s *ThresholdSignerSoft) Sign(nonces []Nonce, payload []byte) ([]byte, erro
return append(noncePub, sig...), nil
}
+// Note: sumNonces sums the "working secret"
func (s *ThresholdSignerSoft) sumNonces(nonces []Nonce) (tsed25519.Scalar, tsed25519.Element, error) {
shareParts := make([]tsed25519.Scalar, len(nonces))
publicKeys := make([]tsed25519.Element, len(nonces))
@@ -85,6 +89,7 @@ func (s *ThresholdSignerSoft) sumNonces(nonces []Nonce) (tsed25519.Scalar, tsed2
return nonceShare, noncePub, nil
}
+// GenerateNonces deals "nonces" (A Pubkey and t of n shares) for all the cosigners.
func (s *ThresholdSignerSoft) GenerateNonces() (Nonces, error) {
secret := make([]byte, 32)
if _, err := rand.Read(secret); err != nil {
@@ -96,6 +101,7 @@ func (s *ThresholdSignerSoft) GenerateNonces() (Nonces, error) {
Shares: make([][]byte, s.total),
}
+ // Splits the secret with Shamir secret sharing
shares := tsed25519.DealShares(secret, s.threshold, s.total)
for i, s := range shares {
diff --git a/pkg/cosigner/cosigner_signer_soft_test.go b/pkg/cosigner/cosigner_signer_soft_test.go
new file mode 100644
index 00000000..f2d3b886
--- /dev/null
+++ b/pkg/cosigner/cosigner_signer_soft_test.go
@@ -0,0 +1,143 @@
+package cosigner
+
+import (
+ "crypto/ed25519"
+ "crypto/rand"
+ "encoding/hex"
+ "fmt"
+ "reflect"
+ "testing"
+ "time"
+
+ cometproto "github.com/cometbft/cometbft/proto/tendermint/types"
+ comet "github.com/cometbft/cometbft/types"
+ "github.com/stretchr/testify/require"
+ tsed25519 "gitlab.com/unit410/threshold-ed25519/pkg"
+)
+
+func TestThresholdSignerSoft_GenerateNonces(t *testing.T) {
+ type fields struct {
+ privateKeyShard []byte
+ pubKey []byte
+ threshold uint8
+ total uint8
+ }
+ tests := []struct {
+ name string
+ fields fields
+ want Nonces
+ wantErr bool
+ }{
+ // TODO: Add test cases.
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ s := &ThresholdSignerSoft{
+ privateKeyShard: tt.fields.privateKeyShard,
+ pubKey: tt.fields.pubKey,
+ threshold: tt.fields.threshold,
+ total: tt.fields.total,
+ }
+ got, err := s.GenerateNonces()
+ if (err != nil) != tt.wantErr {
+ t.Errorf("ThresholdSignerSoft.GenerateNonces() error = %v, wantErr %v", err, tt.wantErr)
+ return
+ }
+ if !reflect.DeepEqual(got, tt.want) {
+ t.Errorf("ThresholdSignerSoft.GenerateNonces() = %v, want %v", got, tt.want)
+ }
+ })
+ }
+}
+
+func TestSignthreshold25519(test *testing.T) {
+ // pack a vote into sign bytes
+ var vote cometproto.Vote
+ vote.Height = 1
+ vote.Round = 0
+ vote.Type = cometproto.PrevoteType
+ vote.Timestamp = time.Now()
+
+ message := comet.VoteSignBytes("chain-id", &vote)
+
+ publicKey, privateKey, err := ed25519.GenerateKey(rand.Reader)
+ require.NoError(test, err)
+
+ // persistentshares is the privateKey split into 3 shamir parts
+ persistentshares := tsed25519.DealShares(tsed25519.ExpandSecret(privateKey.Seed()), 2, 3)
+
+ // each player generates secret Ri
+ r1 := make([]byte, 32)
+ _, err = rand.Read(r1)
+ require.NoError(test, err)
+
+ r2 := make([]byte, 32)
+ _, err = rand.Read(r2)
+ require.NoError(test, err)
+
+ r3 := make([]byte, 32)
+ _, err = rand.Read(r3)
+ require.NoError(test, err)
+
+ // each player split secret per t,n, Rij by Shamir secret sharing
+ shares1 := tsed25519.DealShares(r1, 2, 3)
+ shares2 := tsed25519.DealShares(r2, 2, 3)
+ shares3 := tsed25519.DealShares(r3, 2, 3)
+
+ pub1 := tsed25519.ScalarMultiplyBase(r1)
+ pub2 := tsed25519.ScalarMultiplyBase(r2)
+ pub3 := tsed25519.ScalarMultiplyBase(r3)
+
+ // B=B1+B2+...Bn
+ ephPublicKey := tsed25519.AddElements([]tsed25519.Element{pub1, pub2, pub3})
+
+ // Double check Pubkey
+ persistentSharesPub1 := tsed25519.ScalarMultiplyBase(persistentshares[0])
+ persistentSharesPub2 := tsed25519.ScalarMultiplyBase(persistentshares[1])
+ persistentSharesPub3 := tsed25519.ScalarMultiplyBase(persistentshares[2])
+
+ // A=A1+A2+...An = A=s1⋅B+s2⋅B+...sn⋅B
+ publicKey2 := tsed25519.AddElements(
+ []tsed25519.Element{persistentSharesPub1, persistentSharesPub2, persistentSharesPub3})
+ // require.Equal(test, publicKey, publicKey_2)
+
+ // each player sends s(i)_{j} to corresponding other player j (i.e. s(1)_{2} to player 2)
+ // each player sums all s(i)_{j}, i=1 ... n, j= self id to form their working secret
+ s1 := tsed25519.AddScalars([]tsed25519.Scalar{shares1[0], shares2[0], shares3[0]})
+ s2 := tsed25519.AddScalars([]tsed25519.Scalar{shares1[1], shares2[1], shares3[1]})
+ s3 := tsed25519.AddScalars([]tsed25519.Scalar{shares1[2], shares2[2], shares3[2]})
+
+ _, _ = fmt.Printf("public keys: %x\n", publicKey)
+ _, _ = fmt.Printf("public keys: %x\n", publicKey2)
+ _, err = fmt.Printf("eph pub: %x\n", ephPublicKey)
+ if err != nil {
+ panic(err)
+ }
+ // fmt.Printf("eph secret: %x\n", ephemeralPublic)
+
+ shareSig1 := tsed25519.SignWithShare(message, persistentshares[0], s1, publicKey, ephPublicKey)
+ shareSig2 := tsed25519.SignWithShare(message, persistentshares[1], s2, publicKey, ephPublicKey)
+ shareSig3 := tsed25519.SignWithShare(message, persistentshares[2], s3, publicKey, ephPublicKey)
+
+ {
+ combinedSig := tsed25519.CombineShares(3, []int{1, 2, 3}, [][]byte{shareSig1, shareSig2, shareSig3})
+ var signature []byte
+ signature = append(signature, ephPublicKey...)
+ signature = append(signature, combinedSig...)
+ fmt.Println(hex.EncodeToString(signature))
+ fmt.Println(ed25519.Verify(publicKey, message, signature))
+
+ if !ed25519.Verify(publicKey, message, signature) {
+ test.Error("Invalid Signature for signer [1,2,3]")
+ }
+ }
+ {
+ combinedSig := tsed25519.CombineShares(3, []int{1, 2}, [][]byte{shareSig1, shareSig2})
+ var signature []byte
+ signature = append(signature, ephPublicKey...)
+ signature = append(signature, combinedSig...)
+ if !ed25519.Verify(publicKey, message, signature) {
+ test.Error("Invalid Signature for signer [1,2]")
+ }
+ }
+}
diff --git a/signer/local_cosigner.go b/pkg/cosigner/local_cosigner.go
similarity index 58%
rename from signer/local_cosigner.go
rename to pkg/cosigner/local_cosigner.go
index ad8f6a5b..56070e47 100644
--- a/signer/local_cosigner.go
+++ b/pkg/cosigner/local_cosigner.go
@@ -1,60 +1,86 @@
-package signer
+package cosigner
import (
"errors"
"fmt"
+
+ "github.com/strangelove-ventures/horcrux/pkg/types"
+
"sync"
"time"
+ "github.com/strangelove-ventures/horcrux/pkg/metrics"
+
cometcrypto "github.com/cometbft/cometbft/crypto"
cometcryptoed25519 "github.com/cometbft/cometbft/crypto/ed25519"
cometlog "github.com/cometbft/cometbft/libs/log"
"golang.org/x/sync/errgroup"
)
-var _ Cosigner = &LocalCosigner{}
+type SetNonceRequest struct {
+ ChainID string
+ SourceID int
+ PubKey []byte
+ Share []byte
+ Signature []byte
+ Height int64
+ Round int64
+ Step int8
+ Timestamp time.Time
+}
-// LocalCosigner responds to sign requests.
-// It maintains a high watermark to avoid double-signing.
-// Signing is thread safe.
+type GetNonceRequest struct {
+ ChainID string
+ ID int
+ Height int64
+ Round int64
+ Step int8
+ Timestamp time.Time
+}
+
+// LocalCosigner "responds" to sign requests from RemoteCosigner
+// - LocalCosigner maintains a high watermark to avoid double-signing.
+// - Signing is thread safe.
+// - LocalCosigner implements the ICosigner interface
type LocalCosigner struct {
logger cometlog.Logger
- config *RuntimeConfig
- security CosignerSecurity
- chainState sync.Map
- address string
+ Config *RuntimeConfig
+ security ICosignerSecurity
+ chainStateMap sync.Map // chainstate is a used for map[ChainID] -> *ChainState
+ address string // ip address of the cosigner
pendingDiskWG sync.WaitGroup
}
func NewLocalCosigner(
logger cometlog.Logger,
config *RuntimeConfig,
- security CosignerSecurity,
+ security ICosignerSecurity,
address string,
) *LocalCosigner {
return &LocalCosigner{
logger: logger,
- config: config,
+ Config: config,
security: security,
address: address,
}
}
+// ChainState
type ChainState struct {
// lastSignState stores the last sign state for an HRS we have fully signed
// incremented whenever we are asked to sign an HRS
- lastSignState *SignState
+ lastSignState *types.SignState
- // Signing is thread safe - mutex is used for putting locks so only one goroutine can r/w to the function
+ // Signing is thread safe - mutex is used for putting locks so only one goroutine can r/w to the ChainState
mu sync.RWMutex
// signer generates nonces, combines nonces, signs, and verifies signatures.
- signer ThresholdSigner
+ signer IThresholdSigner
// Height, Round, Step -> metadata
- nonces map[HRSTKey][]Nonces
+ nonces map[types.HRSTKey][]Nonces
}
-func (ccs *ChainState) combinedNonces(myID int, threshold uint8, hrst HRSTKey) ([]Nonce, error) {
+func (ccs *ChainState) combinedNonces(myID int, threshold uint8, hrst types.HRSTKey) ([]Nonce, error) {
ccs.mu.RLock()
defer ccs.mu.RUnlock()
@@ -80,51 +106,47 @@ func (ccs *ChainState) combinedNonces(myID int, threshold uint8, hrst HRSTKey) (
return combinedNonces, nil
}
-type CosignerGetNonceRequest struct {
- ChainID string
- ID int
- Height int64
- Round int64
- Step int8
- Timestamp time.Time
-}
-
-// Save updates the high watermark height/round/step (HRS) if it is greater
+// SaveLastSignedState updates the high watermark height/round/step (HRS) if it is greater
// than the current high watermark. A mutex is used to avoid concurrent state updates.
// The disk write is scheduled in a separate goroutine which will perform an atomic write.
// pendingDiskWG is used upon termination in pendingDiskWG to ensure all writes have completed.
-func (cosigner *LocalCosigner) SaveLastSignedState(chainID string, signState SignStateConsensus) error {
- ccs, err := cosigner.getChainState(chainID)
+func (c *LocalCosigner) SaveLastSignedState(chainID string, signState types.SignStateConsensus) error {
+ ccs, err := c.getChainState(chainID)
if err != nil {
return err
}
return ccs.lastSignState.Save(
signState,
- &cosigner.pendingDiskWG,
+ &c.pendingDiskWG,
)
}
-// 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() {
- cosigner.pendingDiskWG.Wait()
+
+func (c *LocalCosigner) waitForSignStatesToFlushToDisk() {
+ c.pendingDiskWG.Wait()
+}
+
+func (c *LocalCosigner) WaitForSignStatesToFlushToDisk() {
+ c.waitForSignStatesToFlushToDisk()
}
// GetID returns the id of the cosigner
// Implements Cosigner interface
-func (cosigner *LocalCosigner) GetID() int {
- return cosigner.security.GetID()
+func (c *LocalCosigner) GetID() int {
+ return c.security.GetID()
}
// GetAddress returns the RPC URL of the cosigner
// Implements Cosigner interface
-func (cosigner *LocalCosigner) GetAddress() string {
- return cosigner.address
+func (c *LocalCosigner) GetAddress() string {
+ return c.address
}
-func (cosigner *LocalCosigner) getChainState(chainID string) (*ChainState, error) {
- cs, ok := cosigner.chainState.Load(chainID)
+func (c *LocalCosigner) getChainState(chainID string) (*ChainState, error) {
+ cs, ok := c.chainStateMap.Load(chainID)
if !ok {
return nil, fmt.Errorf("failed to load chain state for %s", chainID)
}
@@ -139,22 +161,22 @@ func (cosigner *LocalCosigner) getChainState(chainID string) (*ChainState, error
// GetPubKey returns public key of the validator.
// Implements Cosigner interface
-func (cosigner *LocalCosigner) GetPubKey(chainID string) (cometcrypto.PubKey, error) {
- if err := cosigner.LoadSignStateIfNecessary(chainID); err != nil {
+func (c *LocalCosigner) GetPubKey(chainID string) (cometcrypto.PubKey, error) {
+ if err := c.LoadSignStateIfNecessary(chainID); err != nil {
return nil, err
}
- ccs, err := cosigner.getChainState(chainID)
+ ccs, err := c.getChainState(chainID)
if err != nil {
return nil, err
}
- return cometcryptoed25519.PubKey(ccs.signer.PubKey()), nil
+ return cometcryptoed25519.PubKey(ccs.signer.GetPubKey()), nil
}
// CombineSignatures combines partial signatures into a full signature.
-func (cosigner *LocalCosigner) CombineSignatures(chainID string, signatures []PartialSignature) ([]byte, error) {
- ccs, err := cosigner.getChainState(chainID)
+func (c *LocalCosigner) CombineSignatures(chainID string, signatures []PartialSignature) ([]byte, error) {
+ ccs, err := c.getChainState(chainID)
if err != nil {
return nil, err
}
@@ -162,43 +184,42 @@ func (cosigner *LocalCosigner) CombineSignatures(chainID string, signatures []Pa
return ccs.signer.CombineSignatures(signatures)
}
-// VerifySignature validates a signed payload against the public key.
+// VerifySignature validates a signed payload against the (persistent) public key.
// Implements Cosigner interface
-func (cosigner *LocalCosigner) VerifySignature(chainID string, payload, signature []byte) bool {
- if err := cosigner.LoadSignStateIfNecessary(chainID); err != nil {
+func (c *LocalCosigner) VerifySignature(chainID string, payload, signature []byte) bool {
+ if err := c.LoadSignStateIfNecessary(chainID); err != nil {
return false
}
- ccs, err := cosigner.getChainState(chainID)
+ ccs, err := c.getChainState(chainID)
if err != nil {
return false
}
- return cometcryptoed25519.PubKey(ccs.signer.PubKey()).VerifySignature(payload, signature)
+ return cometcryptoed25519.PubKey(ccs.signer.GetPubKey()).VerifySignature(payload, signature)
}
// Sign the sign request using the cosigner's shard
// Return the signed bytes or an error
-// Implements Cosigner interface
-func (cosigner *LocalCosigner) sign(req CosignerSignRequest) (CosignerSignResponse, error) {
+func (c *LocalCosigner) sign(req SignRequest) (SignResponse, error) {
chainID := req.ChainID
- res := CosignerSignResponse{}
+ res := SignResponse{}
- ccs, err := cosigner.getChainState(chainID)
+ ccs, err := c.getChainState(chainID)
if err != nil {
return res, err
}
// This function has multiple exit points. Only start time can be guaranteed
- metricsTimeKeeper.SetPreviousLocalSignStart(time.Now())
+ metrics.MetricsTimeKeeper.SetPreviousLocalSignStart(time.Now())
- hrst, err := UnpackHRST(req.SignBytes)
+ hrst, err := types.UnpackHRST(req.SignBytes)
if err != nil {
return res, err
}
- existingSignature, err := ccs.lastSignState.existingSignatureOrErrorIfRegression(hrst, req.SignBytes)
+ existingSignature, err := ccs.lastSignState.ExistingSignatureOrErrorIfRegression(hrst, req.SignBytes)
if err != nil {
return res, err
}
@@ -208,7 +229,7 @@ func (cosigner *LocalCosigner) sign(req CosignerSignRequest) (CosignerSignRespon
return res, nil
}
- nonces, err := ccs.combinedNonces(cosigner.GetID(), uint8(cosigner.config.Config.ThresholdModeConfig.Threshold), hrst)
+ nonces, err := ccs.combinedNonces(c.GetID(), uint8(c.Config.Config.ThresholdModeConfig.Threshold), hrst)
if err != nil {
return res, err
}
@@ -218,16 +239,16 @@ func (cosigner *LocalCosigner) sign(req CosignerSignRequest) (CosignerSignRespon
return res, err
}
- err = ccs.lastSignState.Save(SignStateConsensus{
+ err = ccs.lastSignState.Save(types.SignStateConsensus{
Height: hrst.Height,
Round: hrst.Round,
Step: hrst.Step,
Signature: sig,
SignBytes: req.SignBytes,
- }, &cosigner.pendingDiskWG)
+ }, &c.pendingDiskWG)
if err != nil {
- if _, isSameHRSError := err.(*SameHRSError); !isSameHRSError {
+ if _, isSameHRSError := err.(*types.SameHRSError); !isSameHRSError {
return res, err
}
}
@@ -245,78 +266,81 @@ func (cosigner *LocalCosigner) sign(req CosignerSignRequest) (CosignerSignRespon
res.Signature = sig
// Note - Function may return before this line so elapsed time for Finish may be multiple block times
- metricsTimeKeeper.SetPreviousLocalSignFinish(time.Now())
+ metrics.MetricsTimeKeeper.SetPreviousLocalSignFinish(time.Now())
return res, nil
}
-func (cosigner *LocalCosigner) dealShares(req CosignerGetNonceRequest) ([]Nonces, error) {
+func (c *LocalCosigner) dealShares(req GetNonceRequest) ([]Nonces, error) {
chainID := req.ChainID
- ccs, err := cosigner.getChainState(chainID)
+ ccs, err := c.getChainState(chainID)
if err != nil {
return nil, err
}
- meta := make([]Nonces, len(cosigner.config.Config.ThresholdModeConfig.Cosigners))
+ meta := make([]Nonces, len(c.Config.Config.ThresholdModeConfig.Cosigners))
nonces, err := ccs.signer.GenerateNonces()
if err != nil {
return nil, err
}
- meta[cosigner.GetID()-1] = nonces
+ meta[c.GetID()-1] = nonces
return meta, nil
}
-func (cosigner *LocalCosigner) LoadSignStateIfNecessary(chainID string) error {
+func (c *LocalCosigner) LoadSignStateIfNecessary(chainID string) error {
if chainID == "" {
return fmt.Errorf("chain id cannot be empty")
}
- if _, ok := cosigner.chainState.Load(chainID); ok {
+ if _, ok := c.chainStateMap.Load(chainID); ok {
return nil
}
- signState, err := LoadOrCreateSignState(cosigner.config.CosignerStateFile(chainID))
+ signState, err := types.LoadOrCreateSignState(c.Config.CosignStateFile(chainID))
if err != nil {
return err
}
- var signer ThresholdSigner
+ var signer IThresholdSigner
- signer, err = NewThresholdSignerSoft(cosigner.config, cosigner.GetID(), chainID)
+ signer, err = NewThresholdSignerSoft(c.Config, c.GetID(), chainID)
if err != nil {
return err
}
- cosigner.chainState.Store(chainID, &ChainState{
+ c.chainStateMap.Store(chainID, &ChainState{
lastSignState: signState,
- nonces: make(map[HRSTKey][]Nonces),
+ nonces: make(map[types.HRSTKey][]Nonces),
signer: signer,
})
return nil
}
-func (cosigner *LocalCosigner) GetNonces(
+// GetNonces implements the ICosigner interface.
+//
+// GetNonces returns the nonces for the given HRS
+func (c *LocalCosigner) GetNonces(
chainID string,
- hrst HRSTKey,
-) (*CosignerNoncesResponse, error) {
- metricsTimeKeeper.SetPreviousLocalNonce(time.Now())
+ hrst types.HRSTKey,
+) (*NoncesResponse, error) {
+ metrics.MetricsTimeKeeper.SetPreviousLocalNonce(time.Now())
- if err := cosigner.LoadSignStateIfNecessary(chainID); err != nil {
+ if err := c.LoadSignStateIfNecessary(chainID); err != nil {
return nil, err
}
- total := len(cosigner.config.Config.ThresholdModeConfig.Cosigners)
+ total := len(c.Config.Config.ThresholdModeConfig.Cosigners)
- res := &CosignerNoncesResponse{
- Nonces: make([]CosignerNonce, total-1),
+ res := &NoncesResponse{
+ Nonces: make([]WrappedNonce, total-1), // an empty list of nonces for each c except for ourselves
}
- id := cosigner.GetID()
+ id := c.GetID()
var eg errgroup.Group
// getting nonces requires encrypting and signing for each cosigner,
@@ -331,7 +355,7 @@ func (cosigner *LocalCosigner) GetNonces(
i := i
eg.Go(func() error {
- secretPart, err := cosigner.getNonce(CosignerGetNonceRequest{
+ secretPart, err := c.getNonce(GetNonceRequest{
ChainID: chainID,
ID: peerID,
Height: hrst.Height,
@@ -354,7 +378,7 @@ func (cosigner *LocalCosigner) GetNonces(
return nil, err
}
- cosigner.logger.Debug(
+ c.logger.Debug(
"Generated nonces",
"chain_id", chainID,
"height", hrst.Height,
@@ -365,8 +389,8 @@ func (cosigner *LocalCosigner) GetNonces(
return res, nil
}
-func (cosigner *LocalCosigner) dealSharesIfNecessary(chainID string, hrst HRSTKey) ([]Nonces, error) {
- ccs, err := cosigner.getChainState(chainID)
+func (c *LocalCosigner) dealSharesIfNecessary(chainID string, hrst types.HRSTKey) ([]Nonces, error) {
+ ccs, err := c.getChainState(chainID)
if err != nil {
return nil, err
}
@@ -380,7 +404,7 @@ func (cosigner *LocalCosigner) dealSharesIfNecessary(chainID string, hrst HRSTKe
return nonces, nil
}
- newNonces, err := cosigner.dealShares(CosignerGetNonceRequest{
+ newNonces, err := c.dealShares(GetNonceRequest{
ChainID: chainID,
Height: hrst.Height,
Round: hrst.Round,
@@ -398,28 +422,28 @@ func (cosigner *LocalCosigner) dealSharesIfNecessary(chainID string, hrst HRSTKe
// Get the ephemeral secret part for an ephemeral share
// The ephemeral secret part is encrypted for the receiver
-func (cosigner *LocalCosigner) getNonce(
- req CosignerGetNonceRequest,
-) (CosignerNonce, error) {
- chainID := req.ChainID
- zero := CosignerNonce{}
+func (c *LocalCosigner) getNonce(
+ req GetNonceRequest,
+) (WrappedNonce, error) {
- hrst := HRSTKey{
+ chainID := req.ChainID
+ zero := WrappedNonce{}
+ hrst := types.HRSTKey{
Height: req.Height,
Round: req.Round,
Step: req.Step,
Timestamp: req.Timestamp.UnixNano(),
}
- id := cosigner.GetID()
+ id := c.GetID()
- meta, err := cosigner.dealSharesIfNecessary(chainID, hrst)
+ meta, err := c.dealSharesIfNecessary(chainID, hrst)
if err != nil {
return zero, err
}
ourCosignerMeta := meta[id-1]
- nonce, err := cosigner.security.EncryptAndSign(req.ID, ourCosignerMeta.PubKey, ourCosignerMeta.Shares[req.ID-1])
+ nonce, err := c.security.EncryptAndSign(req.ID, ourCosignerMeta.PubKey, ourCosignerMeta.Shares[req.ID-1])
if err != nil {
return zero, err
}
@@ -428,10 +452,10 @@ func (cosigner *LocalCosigner) getNonce(
}
// setNonce stores a nonce provided by another cosigner
-func (cosigner *LocalCosigner) setNonce(req CosignerSetNonceRequest) error {
+func (c *LocalCosigner) setNonce(req SetNonceRequest) error {
chainID := req.ChainID
- ccs, err := cosigner.getChainState(chainID)
+ ccs, err := c.getChainState(chainID)
if err != nil {
return err
}
@@ -441,13 +465,13 @@ func (cosigner *LocalCosigner) setNonce(req CosignerSetNonceRequest) error {
return errors.New("signature field is required")
}
- noncePub, nonceShare, err := cosigner.security.DecryptAndVerify(
+ noncePub, nonceShare, err := c.security.DecryptAndVerify(
req.SourceID, req.PubKey, req.Share, req.Signature)
if err != nil {
return err
}
- hrst := HRSTKey{
+ hrst := types.HRSTKey{
Height: req.Height,
Round: req.Round,
Step: req.Step,
@@ -472,19 +496,19 @@ func (cosigner *LocalCosigner) setNonce(req CosignerSetNonceRequest) error {
// set slot
if nonces[req.SourceID-1].Shares == nil {
- nonces[req.SourceID-1].Shares = make([][]byte, len(cosigner.config.Config.ThresholdModeConfig.Cosigners))
+ nonces[req.SourceID-1].Shares = make([][]byte, len(c.Config.Config.ThresholdModeConfig.Cosigners))
}
- nonces[req.SourceID-1].Shares[cosigner.GetID()-1] = nonceShare
+ nonces[req.SourceID-1].Shares[c.GetID()-1] = nonceShare
nonces[req.SourceID-1].PubKey = noncePub
return nil
}
-func (cosigner *LocalCosigner) SetNoncesAndSign(
- req CosignerSetNoncesAndSignRequest) (*CosignerSignResponse, error) {
+func (c *LocalCosigner) SetNoncesAndSign(
+ req SetNoncesAndSignRequest) (*SignResponse, error) {
chainID := req.ChainID
- if err := cosigner.LoadSignStateIfNecessary(chainID); err != nil {
+ if err := c.LoadSignStateIfNecessary(chainID); err != nil {
return nil, err
}
@@ -497,7 +521,7 @@ func (cosigner *LocalCosigner) SetNoncesAndSign(
secretPart := secretPart
eg.Go(func() error {
- return cosigner.setNonce(CosignerSetNonceRequest{
+ return c.setNonce(SetNonceRequest{
ChainID: chainID,
SourceID: secretPart.SourceID,
PubKey: secretPart.PubKey,
@@ -515,7 +539,7 @@ func (cosigner *LocalCosigner) SetNoncesAndSign(
return nil, err
}
- res, err := cosigner.sign(CosignerSignRequest{
+ res, err := c.sign(SignRequest{
ChainID: chainID,
SignBytes: req.SignBytes,
})
diff --git a/signer/local_cosigner_test.go b/pkg/cosigner/local_cosigner_test.go
similarity index 87%
rename from signer/local_cosigner_test.go
rename to pkg/cosigner/local_cosigner_test.go
index da4e907f..e83d02dd 100644
--- a/signer/local_cosigner_test.go
+++ b/pkg/cosigner/local_cosigner_test.go
@@ -1,4 +1,4 @@
-package signer
+package cosigner
import (
"crypto/rand"
@@ -9,6 +9,8 @@ import (
"testing"
"time"
+ "github.com/strangelove-ventures/horcrux/pkg/types"
+
cometcryptoed25519 "github.com/cometbft/cometbft/crypto/ed25519"
"github.com/cometbft/cometbft/libs/log"
cometproto "github.com/cometbft/cometbft/proto/tendermint/types"
@@ -36,7 +38,7 @@ func TestLocalCosignerSignRSA3of5(t *testing.T) {
func testLocalCosignerSignRSA(t *testing.T, threshold, total uint8) {
t.Parallel()
- security := make([]CosignerSecurity, total)
+ security := make([]ICosignerSecurity, total)
keys := make([]*rsa.PrivateKey, total)
pubKeys := make([]*rsa.PublicKey, total)
@@ -50,7 +52,7 @@ func testLocalCosignerSignRSA(t *testing.T, threshold, total uint8) {
for i, k := range keys {
security[i] = NewCosignerSecurityRSA(
- CosignerRSAKey{
+ CosignRSAKey{
ID: i + 1,
RSAKey: *k,
RSAPubs: pubKeys,
@@ -72,7 +74,7 @@ func TestLocalCosignerSignECIES3of5(t *testing.T) {
func testLocalCosignerSignECIES(t *testing.T, threshold, total uint8) {
t.Parallel()
- security := make([]CosignerSecurity, total)
+ security := make([]ICosignerSecurity, total)
keys := make([]*ecies.PrivateKey, total)
pubKeys := make([]*ecies.PublicKey, total)
@@ -86,7 +88,7 @@ func testLocalCosignerSignECIES(t *testing.T, threshold, total uint8) {
for i, k := range keys {
security[i] = NewCosignerSecurityECIES(
- CosignerECIESKey{
+ CosignEciesKey{
ID: i + 1,
ECIESKey: k,
ECIESPubs: pubKeys,
@@ -97,7 +99,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 []ICosignerSecurity) {
privateKey := cometcryptoed25519.GenPrivKey()
privKeyBytes := [64]byte{}
@@ -115,11 +117,11 @@ func testLocalCosignerSign(t *testing.T, threshold, total uint8, security []Cosi
tmpDir := t.TempDir()
thresholdCosigners := make([]*LocalCosigner, threshold)
- nonces := make([][]CosignerNonce, threshold)
+ nonces := make([][]WrappedNonce, threshold)
now := time.Now()
- hrst := HRSTKey{
+ hrst := types.HRSTKey{
Height: 1,
Round: 0,
Step: 2,
@@ -129,13 +131,13 @@ func testLocalCosignerSign(t *testing.T, threshold, total uint8, security []Cosi
for i := 0; i < int(total); i++ {
id := i + 1
- key := CosignerEd25519Key{
+ key := CosignEd25519Key{
PubKey: pubKey,
PrivateShard: privShards[i],
ID: id,
}
- cfg.ThresholdModeConfig.Cosigners[i] = CosignerConfig{
+ cfg.ThresholdModeConfig.Cosigners[i] = CosignConfig{
ShardID: id,
}
@@ -156,10 +158,10 @@ func testLocalCosignerSign(t *testing.T, threshold, total uint8, security []Cosi
keyBz, err := key.MarshalJSON()
require.NoError(t, err)
- err = os.WriteFile(cosigner.config.KeyFilePathCosigner(testChainID), keyBz, 0600)
+ err = os.WriteFile(cosigner.Config.KeyFilePathCosigner(testChainID), keyBz, 0600)
require.NoError(t, err)
- defer cosigner.waitForSignStatesToFlushToDisk()
+ defer cosigner.WaitForSignStatesToFlushToDisk()
err = cosigner.LoadSignStateIfNecessary(testChainID)
require.NoError(t, err)
@@ -188,7 +190,7 @@ func testLocalCosignerSign(t *testing.T, threshold, total uint8, security []Cosi
sigs := make([]PartialSignature, threshold)
for i, cosigner := range thresholdCosigners {
- cosignerNonces := make([]CosignerNonce, 0, threshold-1)
+ cosignerNonces := make([]WrappedNonce, 0, threshold-1)
for j, nonce := range nonces {
if i == j {
@@ -202,7 +204,7 @@ func testLocalCosignerSign(t *testing.T, threshold, total uint8, security []Cosi
}
}
- sigRes, err := cosigner.SetNoncesAndSign(CosignerSetNoncesAndSignRequest{
+ sigRes, err := cosigner.SetNoncesAndSign(SetNoncesAndSignRequest{
ChainID: testChainID,
Nonces: cosignerNonces,
HRST: hrst,
diff --git a/signer/remote_cosigner.go b/pkg/cosigner/remote_cosigner.go
similarity index 54%
rename from signer/remote_cosigner.go
rename to pkg/cosigner/remote_cosigner.go
index ad4247c2..277d16e2 100644
--- a/signer/remote_cosigner.go
+++ b/pkg/cosigner/remote_cosigner.go
@@ -1,18 +1,26 @@
-package signer
+package cosigner
+// RemoteCosigner is a Cosigner implementation that uses gRPC make to request from other Cosigners
import (
"context"
"fmt"
"net/url"
"time"
+ "github.com/strangelove-ventures/horcrux/pkg/types"
+
cometcrypto "github.com/cometbft/cometbft/crypto"
- "github.com/strangelove-ventures/horcrux/signer/proto"
+ "github.com/strangelove-ventures/horcrux/pkg/proto"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
)
-// RemoteCosigner uses CosignerGRPC to request signing from a remote cosigner
+// RemoteCosigner uses CosignerGRPC to request/query a signing process from a LocalCosigner
+//
+// - RemoteCosigner acts as a client(!) and requests via gRPC the other
+// "node's" LocalCosigner to set the nonces and sign the payload and respons.
+// - RemoteCosigner --> gRPC --> LocalCosigner
+// - RemoteCosigner implements the Cosigner interface
type RemoteCosigner struct {
id int
address string
@@ -32,7 +40,7 @@ const (
rpcTimeout = 4 * time.Second
)
-func getContext() (context.Context, context.CancelFunc) {
+func GetContext() (context.Context, context.CancelFunc) {
return context.WithTimeout(context.Background(), rpcTimeout)
}
@@ -43,7 +51,7 @@ func (cosigner *RemoteCosigner) GetID() int {
}
// GetAddress returns the P2P URL of the remote cosigner
-// Implements the cosigner interface
+// Implements the ICosigner interface
func (cosigner *RemoteCosigner) GetAddress() string {
return cosigner.address
}
@@ -55,12 +63,12 @@ func (cosigner *RemoteCosigner) GetPubKey(_ string) (cometcrypto.PubKey, error)
}
// VerifySignature validates a signed payload against the public key.
-// Implements Cosigner interface
+// Implements ICosigner interface
func (cosigner *RemoteCosigner) VerifySignature(_ string, _, _ []byte) bool {
return false
}
-func (cosigner *RemoteCosigner) getGRPCClient() (proto.CosignerGRPCClient, *grpc.ClientConn, error) {
+func (cosigner *RemoteCosigner) getGRPCClient() (proto.ICosignerGRPCClient, *grpc.ClientConn, error) {
var grpcAddress string
url, err := url.Parse(cosigner.address)
if err != nil {
@@ -72,53 +80,61 @@ func (cosigner *RemoteCosigner) getGRPCClient() (proto.CosignerGRPCClient, *grpc
if err != nil {
return nil, nil, err
}
- return proto.NewCosignerGRPCClient(conn), conn, nil
+ return proto.NewICosignerGRPCClient(conn), conn, nil
}
-// Implements the cosigner interface
+// GetNonces implements the Cosigner interface
+// It uses the gRPC client to request the nonces from the other
func (cosigner *RemoteCosigner) GetNonces(
chainID string,
- req HRSTKey,
-) (*CosignerNoncesResponse, error) {
+ req types.HRSTKey,
+) (*NoncesResponse, error) {
+
client, conn, err := cosigner.getGRPCClient()
if err != nil {
return nil, err
}
defer conn.Close()
- context, cancelFunc := getContext()
+ context, cancelFunc := GetContext()
defer cancelFunc()
- res, err := client.GetNonces(context, &proto.CosignerGRPCGetNoncesRequest{
- ChainID: chainID,
- Hrst: req.toProto(),
- })
+ res, err := client.GetNonces(
+ context,
+ &proto.CosignerGRPCGetNoncesRequest{
+ ChainID: chainID,
+ Hrst: req.ToProto(),
+ },
+ )
if err != nil {
return nil, err
}
- return &CosignerNoncesResponse{
- Nonces: CosignerNoncesFromProto(res.GetNonces()),
+ return &NoncesResponse{
+ Nonces: NoncesFromProto(res.GetNonces()),
}, nil
}
-// Implements the cosigner interface
+// SetNoncesAndSign implements the Cosigner interface
+// It acts as a client(!) and requests via gRPC the other
+// "node's" LocalCosigner to set the nonces and sign the payload.
func (cosigner *RemoteCosigner) SetNoncesAndSign(
- req CosignerSetNoncesAndSignRequest) (*CosignerSignResponse, error) {
+ req SetNoncesAndSignRequest) (*SignResponse, error) {
client, conn, err := cosigner.getGRPCClient()
if err != nil {
return nil, err
}
defer conn.Close()
- context, cancelFunc := getContext()
+ context, cancelFunc := GetContext()
defer cancelFunc()
- res, err := client.SetNoncesAndSign(context, &proto.CosignerGRPCSetNoncesAndSignRequest{
- ChainID: req.ChainID,
- Nonces: CosignerNonces(req.Nonces).toProto(),
- Hrst: req.HRST.toProto(),
- SignBytes: req.SignBytes,
- })
+ res, err := client.SetNoncesAndSign(context,
+ &proto.CosignerGRPCSetNoncesAndSignRequest{
+ ChainID: req.ChainID,
+ Nonces: WrappedNonces(req.Nonces).ToProto(),
+ Hrst: req.HRST.ToProto(),
+ SignBytes: req.SignBytes,
+ })
if err != nil {
return nil, err
}
- return &CosignerSignResponse{
+ return &SignResponse{
NoncePublic: res.GetNoncePublic(),
Timestamp: time.Unix(0, res.GetTimestamp()),
Signature: res.GetSignature(),
diff --git a/signer/metrics.go b/pkg/metrics/metrics.go
similarity index 71%
rename from signer/metrics.go
rename to pkg/metrics/metrics.go
index 24415783..2834da97 100644
--- a/signer/metrics.go
+++ b/pkg/metrics/metrics.go
@@ -1,4 +1,4 @@
-package signer
+package metrics
import (
"sync"
@@ -60,111 +60,111 @@ func (mt *metricsTimer) UpdatePrometheusMetrics() {
defer mt.mu.Unlock()
// Update Prometheus Gauges
- secondsSinceLastPrecommit.Set(time.Since(mt.previousPrecommit).Seconds())
- secondsSinceLastPrevote.Set(time.Since(mt.previousPrevote).Seconds())
- secondsSinceLastLocalSignStart.Set(time.Since(mt.previousLocalSignStart).Seconds())
- secondsSinceLastLocalSignFinish.Set(time.Since(mt.previousLocalSignFinish).Seconds())
- secondsSinceLastLocalNonceTime.Set(time.Since(mt.previousLocalNonce).Seconds())
+ SecondsSinceLastPrecommit.Set(time.Since(mt.previousPrecommit).Seconds())
+ SecondsSinceLastPrevote.Set(time.Since(mt.previousPrevote).Seconds())
+ SecondsSinceLastLocalSignStart.Set(time.Since(mt.previousLocalSignStart).Seconds())
+ SecondsSinceLastLocalSignFinish.Set(time.Since(mt.previousLocalSignFinish).Seconds())
+ SecondsSinceLastLocalNonceTime.Set(time.Since(mt.previousLocalNonce).Seconds())
}
var (
// Variables to calculate Prometheus Metrics
- previousPrecommitHeight = int64(0)
- previousPrevoteHeight = int64(0)
- metricsTimeKeeper = newMetricsTimer()
+ PreviousPrecommitHeight = int64(0)
+ PreviousPrevoteHeight = int64(0)
+ MetricsTimeKeeper = newMetricsTimer()
// Prometheus Metrics
- totalPubKeyRequests = promauto.NewCounter(prometheus.CounterOpts{
+ TotalPubKeyRequests = promauto.NewCounter(prometheus.CounterOpts{
Name: "signer_total_pubkey_requests",
Help: "Total times public key requested (High count may indicate validator restarts)",
})
- lastPrecommitHeight = promauto.NewGauge(prometheus.GaugeOpts{
+ LastPrecommitHeight = promauto.NewGauge(prometheus.GaugeOpts{
Name: "signer_last_precommit_height",
Help: "Last Height Precommit Signed",
})
- lastPrevoteHeight = promauto.NewGauge(prometheus.GaugeOpts{
+ LastPrevoteHeight = promauto.NewGauge(prometheus.GaugeOpts{
Name: "signer_last_prevote_height",
Help: "Last Height Prevote Signed",
})
- lastProposalHeight = promauto.NewGauge(prometheus.GaugeOpts{
+ LastProposalHeight = promauto.NewGauge(prometheus.GaugeOpts{
Name: "signer_last_proposal_height",
Help: "Last Height Proposal Signed",
})
- lastPrecommitRound = promauto.NewGauge(prometheus.GaugeOpts{
+ LastPrecommitRound = promauto.NewGauge(prometheus.GaugeOpts{
Name: "signer_last_precommit_round",
Help: "Last Round Precommit Signed",
})
- lastPrevoteRound = promauto.NewGauge(prometheus.GaugeOpts{
+ LastPrevoteRound = promauto.NewGauge(prometheus.GaugeOpts{
Name: "signer_last_prevote_round",
Help: "Last Round Prevote Signed",
})
- lastProposalRound = promauto.NewGauge(prometheus.GaugeOpts{
+ LastProposalRound = promauto.NewGauge(prometheus.GaugeOpts{
Name: "signer_last_proposal_round",
Help: "Last Round Proposal Signed",
})
- totalPrecommitsSigned = promauto.NewCounter(prometheus.CounterOpts{
+ TotalPrecommitsSigned = promauto.NewCounter(prometheus.CounterOpts{
Name: "signer_total_precommits_signed",
Help: "Total Precommit Signed",
})
- totalPrevotesSigned = promauto.NewCounter(prometheus.CounterOpts{
+ TotalPrevotesSigned = promauto.NewCounter(prometheus.CounterOpts{
Name: "signer_total_prevotes_signed",
Help: "Total Prevote Signed",
})
- totalProposalsSigned = promauto.NewCounter(prometheus.CounterOpts{
+ TotalProposalsSigned = promauto.NewCounter(prometheus.CounterOpts{
Name: "signer_total_proposals_signed",
Help: "Total Proposal Signed",
})
- secondsSinceLastPrecommit = promauto.NewGauge(prometheus.GaugeOpts{
+ SecondsSinceLastPrecommit = promauto.NewGauge(prometheus.GaugeOpts{
Name: "signer_seconds_since_last_precommit",
Help: "Seconds Since Last Precommit (Useful for Signing Co-Signer Node, Single Signer)",
})
- secondsSinceLastPrevote = promauto.NewGauge(prometheus.GaugeOpts{
+ SecondsSinceLastPrevote = promauto.NewGauge(prometheus.GaugeOpts{
Name: "signer_seconds_since_last_prevote",
Help: "Seconds Since Last Prevote (Useful for Signing Co-Signer Node, Single Signer)",
})
- secondsSinceLastLocalSignStart = promauto.NewGauge(prometheus.GaugeOpts{
+ SecondsSinceLastLocalSignStart = promauto.NewGauge(prometheus.GaugeOpts{
Name: "signer_seconds_since_last_local_sign_start_time",
Help: "Seconds Since Last Local Start Sign (May increase beyond block time, Rarely important) ",
})
- secondsSinceLastLocalSignFinish = promauto.NewGauge(prometheus.GaugeOpts{
+ SecondsSinceLastLocalSignFinish = promauto.NewGauge(prometheus.GaugeOpts{
Name: "signer_seconds_since_last_local_sign_finish_time",
Help: "Seconds Since Last Local Finish Sign (Should stay below 2 * Block Time)",
})
- secondsSinceLastLocalNonceTime = promauto.NewGauge(prometheus.GaugeOpts{
+ SecondsSinceLastLocalNonceTime = promauto.NewGauge(prometheus.GaugeOpts{
Name: "signer_seconds_since_last_local_ephemeral_share_time",
Help: "Seconds Since Last Local Ephemeral Share Sign " +
"(Should not increase beyond block time; If high, may indicate raft joining issue for CoSigner) ",
})
- missedPrecommits = promauto.NewGauge(prometheus.GaugeOpts{
+ MissedPrecommits = promauto.NewGauge(prometheus.GaugeOpts{
Name: "signer_missed_precommits",
Help: "Consecutive Precommit Missed",
})
- missedPrevotes = promauto.NewGauge(prometheus.GaugeOpts{
+ MissedPrevotes = promauto.NewGauge(prometheus.GaugeOpts{
Name: "signer_missed_prevotes",
Help: "Consecutive Prevote Missed",
})
- totalMissedPrecommits = promauto.NewCounter(prometheus.CounterOpts{
+ TotalMissedPrecommits = promauto.NewCounter(prometheus.CounterOpts{
Name: "signer_total_missed_precommits",
Help: "Total Precommit Missed",
})
- totalMissedPrevotes = promauto.NewCounter(prometheus.CounterOpts{
+ TotalMissedPrevotes = promauto.NewCounter(prometheus.CounterOpts{
Name: "signer_total_missed_prevotes",
Help: "Total Prevote Missed",
})
- missedNonces = promauto.NewGaugeVec(
+ MissedNonces = promauto.NewGaugeVec(
prometheus.GaugeOpts{
Name: "signer_missed_ephemeral_shares",
Help: "Consecutive Threshold Signature Parts Missed",
},
[]string{"peerid"},
)
- totalMissedNonces = promauto.NewCounterVec(
+ TotalMissedNonces = promauto.NewCounterVec(
prometheus.CounterOpts{
Name: "signer_total_missed_ephemeral_shares",
Help: "Total Threshold Signature Parts Missed",
@@ -172,66 +172,66 @@ var (
[]string{"peerid"},
)
- sentryConnectTries = promauto.NewGauge(prometheus.GaugeOpts{
+ SentryConnectTries = promauto.NewGauge(prometheus.GaugeOpts{
Name: "signer_sentry_connect_tries",
Help: "Consecutive Number of times sentry TCP connect has been tried (High count may indicate validator restarts)",
})
- totalSentryConnectTries = promauto.NewCounter(prometheus.CounterOpts{
+ TotalSentryConnectTries = promauto.NewCounter(prometheus.CounterOpts{
Name: "signer_total_sentry_connect_tries",
Help: "Total Number of times sentry TCP connect has been tried (High count may indicate validator restarts)",
})
- beyondBlockErrors = promauto.NewCounter(prometheus.CounterOpts{
+ BeyondBlockErrors = promauto.NewCounter(prometheus.CounterOpts{
Name: "signer_total_beyond_block_errors",
Help: "Total Times Signing Started but duplicate height/round request arrives",
})
- failedSignVote = promauto.NewCounter(prometheus.CounterOpts{
+ FailedSignVote = promauto.NewCounter(prometheus.CounterOpts{
Name: "signer_total_failed_sign_vote",
Help: "Total Times Signer Failed to sign block - Unstarted and Unexepcted Height",
})
- totalRaftLeader = promauto.NewCounter(prometheus.CounterOpts{
+ TotalRaftLeader = promauto.NewCounter(prometheus.CounterOpts{
Name: "signer_total_raft_leader",
Help: "Total Times Signer is Raft Leader",
})
- totalNotRaftLeader = promauto.NewCounter(prometheus.CounterOpts{
+ TotalNotRaftLeader = promauto.NewCounter(prometheus.CounterOpts{
Name: "signer_total_raft_not_leader",
Help: "Total Times Signer is NOT Raft Leader (Proxy signing to Raft Leader)",
})
- totalRaftLeaderElectiontimeout = promauto.NewCounter(prometheus.CounterOpts{
+ TotalRaftLeaderElectiontimeout = promauto.NewCounter(prometheus.CounterOpts{
Name: "signer_total_raft_leader_election_timeout",
Help: "Total Times Raft Leader Failed Election (Lacking Peers)",
})
- totalInvalidSignature = promauto.NewCounter(prometheus.CounterOpts{
+ TotalInvalidSignature = promauto.NewCounter(prometheus.CounterOpts{
Name: "signer_error_total_invalid_signatures",
Help: "Total Times Combined Signature is Invalid",
})
- totalInsufficientCosigners = promauto.NewCounter(prometheus.CounterOpts{
+ TotalInsufficientCosigners = promauto.NewCounter(prometheus.CounterOpts{
Name: "signer_error_total_insufficient_cosigners",
Help: "Total Times Cosigners doesn't reach threshold",
})
- timedSignBlockThresholdLag = promauto.NewSummary(prometheus.SummaryOpts{
+ TimedSignBlockThresholdLag = promauto.NewSummary(prometheus.SummaryOpts{
Name: "signer_sign_block_threshold_lag_seconds",
Help: "Seconds taken to get threshold of cosigners available",
Objectives: map[float64]float64{0.5: 0.05, 0.9: 0.01, 0.99: 0.001},
})
- timedSignBlockCosignerLag = promauto.NewSummary(prometheus.SummaryOpts{
+ TimedSignBlockCosignerLag = promauto.NewSummary(prometheus.SummaryOpts{
Name: "signer_sign_block_cosigner_lag_seconds",
Help: "Seconds taken to get all cosigner signatures",
Objectives: map[float64]float64{0.5: 0.05, 0.9: 0.01, 0.99: 0.001},
})
- timedSignBlockLag = promauto.NewSummary(prometheus.SummaryOpts{
+ TimedSignBlockLag = promauto.NewSummary(prometheus.SummaryOpts{
Name: "signer_sign_block_lag_seconds",
Help: "Seconds taken to sign block",
Objectives: map[float64]float64{0.5: 0.05, 0.9: 0.01, 0.99: 0.001},
})
- timedCosignerNonceLag = promauto.NewSummaryVec(
+ TimedCosignerNonceLag = promauto.NewSummaryVec(
prometheus.SummaryOpts{
Name: "signer_cosigner_ephemeral_share_lag_seconds",
Help: "Time taken to get cosigner ephemeral share",
@@ -239,7 +239,7 @@ var (
},
[]string{"peerid"},
)
- timedCosignerSignLag = promauto.NewSummaryVec(
+ TimedCosignerSignLag = promauto.NewSummaryVec(
prometheus.SummaryOpts{
Name: "signer_cosigner_sign_lag_seconds",
Help: "Time taken to get cosigner signature",
@@ -252,7 +252,7 @@ var (
func StartMetrics() {
// Update elapsed times on an interval basis
for {
- metricsTimeKeeper.UpdatePrometheusMetrics()
+ MetricsTimeKeeper.UpdatePrometheusMetrics()
// Prometheus often only polls every 1 to every few seconds
// Frequent updates minimize reporting error.
diff --git a/signer/multiresolver/multi.go b/pkg/multiresolver/multi.go
similarity index 100%
rename from signer/multiresolver/multi.go
rename to pkg/multiresolver/multi.go
diff --git a/signer/multiresolver/multi_test.go b/pkg/multiresolver/multi_test.go
similarity index 79%
rename from signer/multiresolver/multi_test.go
rename to pkg/multiresolver/multi_test.go
index 5652b0c1..895be347 100644
--- a/signer/multiresolver/multi_test.go
+++ b/pkg/multiresolver/multi_test.go
@@ -9,10 +9,11 @@ import (
"testing"
"time"
+ "github.com/strangelove-ventures/horcrux/pkg/node"
+
grpcretry "github.com/grpc-ecosystem/go-grpc-middleware/retry"
- "github.com/strangelove-ventures/horcrux/signer"
- "github.com/strangelove-ventures/horcrux/signer/multiresolver"
- "github.com/strangelove-ventures/horcrux/signer/proto"
+ "github.com/strangelove-ventures/horcrux/pkg/multiresolver"
+ "github.com/strangelove-ventures/horcrux/pkg/proto"
"github.com/stretchr/testify/require"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
@@ -26,12 +27,18 @@ func createListener(nodeID string, homedir string) (string, func(), error) {
port := strconv.Itoa(sock.Addr().(*net.TCPAddr).Port)
- s := signer.NewRaftStore(
+ s := node.NewRaftStore(
nodeID,
homedir,
"127.0.0.1:"+port,
500*time.Millisecond,
- nil, nil, nil)
+ nil)
+
+ // Need to set pointers to avoid nil pointers.
+ var cosigners []node.ICosigner
+ var timeDuration time.Duration
+ thresholdvalidator := node.NewThresholdValidator(nil, nil, 0, timeDuration, 0, nil, cosigners, nil)
+ s.SetThresholdValidator(thresholdvalidator)
transportManager, err := s.Open()
if err != nil {
@@ -39,7 +46,7 @@ func createListener(nodeID string, homedir string) (string, func(), error) {
}
grpcServer := grpc.NewServer()
- proto.RegisterCosignerGRPCServer(grpcServer, signer.NewGRPCServer(nil, nil, s))
+ proto.RegisterICosignerGRPCServer(grpcServer, node.NewGRPCServer(nil, nil, s))
transportManager.Register(grpcServer)
go func() {
@@ -90,7 +97,7 @@ func TestMultiResolver(t *testing.T) {
ctx, cancelFunc := context.WithTimeout(context.Background(), 30*time.Second)
defer cancelFunc()
- grpcClient := proto.NewCosignerGRPCClient(connDNS)
+ grpcClient := proto.NewICosignerGRPCClient(connDNS)
_, err = grpcClient.GetLeader(ctx, &proto.CosignerGRPCGetLeaderRequest{})
require.NoError(t, err)
@@ -103,7 +110,7 @@ func TestMultiResolver(t *testing.T) {
require.NoError(t, err)
defer connIP.Close()
- grpcClient = proto.NewCosignerGRPCClient(connIP)
+ grpcClient = proto.NewICosignerGRPCClient(connIP)
_, err = grpcClient.GetLeader(ctx, &proto.CosignerGRPCGetLeaderRequest{})
require.NoError(t, err)
}
diff --git a/signer/grpc_server.go b/pkg/node/grpc_server.go
similarity index 65%
rename from signer/grpc_server.go
rename to pkg/node/grpc_server.go
index 61d98b27..6ff38540 100644
--- a/signer/grpc_server.go
+++ b/pkg/node/grpc_server.go
@@ -1,25 +1,31 @@
-package signer
+package node
import (
"context"
"fmt"
"time"
+ "github.com/strangelove-ventures/horcrux/pkg/cosigner"
+ "github.com/strangelove-ventures/horcrux/pkg/types"
+
"github.com/hashicorp/raft"
- "github.com/strangelove-ventures/horcrux/signer/proto"
+ "github.com/strangelove-ventures/horcrux/pkg/proto"
)
-var _ proto.CosignerGRPCServer = &GRPCServer{}
+// Enures that GRPCServer implements the proto.CosignerGRPCServer interface.
+var _ proto.ICosignerGRPCServer = &GRPCServer{}
type GRPCServer struct {
- cosigner *LocalCosigner
- thresholdValidator *ThresholdValidator
- raftStore *RaftStore
- proto.UnimplementedCosignerGRPCServer
+ cosigner *cosigner.LocalCosigner // The "node's" LocalCosigner
+ thresholdValidator *ThresholdValidator // The "node's" ThresholdValidator
+ raftStore *RaftStore // The "node's" RaftStore
+ // Promoted Fields is embedded to have forward compatiblitity
+ proto.UnimplementedICosignerGRPCServer
}
+// NewGRPCServer returns a new GRPCServer.
func NewGRPCServer(
- cosigner *LocalCosigner,
+ cosigner *cosigner.LocalCosigner,
thresholdValidator *ThresholdValidator,
raftStore *RaftStore,
) *GRPCServer {
@@ -30,6 +36,7 @@ func NewGRPCServer(
}
}
+// SignBlock "pseudo-implements" the ICosignerGRPCServer interface in pkg/proto/cosigner_grpc_server_grpc.pb.go
func (rpc *GRPCServer) SignBlock(
_ context.Context,
req *proto.CosignerGRPCSignBlockRequest,
@@ -41,6 +48,7 @@ func (rpc *GRPCServer) SignBlock(
SignBytes: req.Block.GetSignBytes(),
Timestamp: time.Unix(0, req.Block.GetTimestamp()),
}
+ // this
res, _, err := rpc.thresholdValidator.SignBlock(req.ChainID, block)
if err != nil {
return nil, err
@@ -54,12 +62,13 @@ func (rpc *GRPCServer) SetNoncesAndSign(
_ context.Context,
req *proto.CosignerGRPCSetNoncesAndSignRequest,
) (*proto.CosignerGRPCSetNoncesAndSignResponse, error) {
- res, err := rpc.cosigner.SetNoncesAndSign(CosignerSetNoncesAndSignRequest{
- ChainID: req.ChainID,
- Nonces: CosignerNoncesFromProto(req.GetNonces()),
- HRST: HRSTKeyFromProto(req.GetHrst()),
- SignBytes: req.GetSignBytes(),
- })
+ res, err := rpc.cosigner.SetNoncesAndSign(
+ cosigner.SetNoncesAndSignRequest{
+ ChainID: req.ChainID,
+ Nonces: cosigner.NoncesFromProto(req.GetNonces()),
+ HRST: types.HRSTKeyFromProto(req.GetHrst()),
+ SignBytes: req.GetSignBytes(),
+ })
if err != nil {
rpc.raftStore.logger.Error(
"Failed to sign with shard",
@@ -85,22 +94,24 @@ func (rpc *GRPCServer) SetNoncesAndSign(
}, nil
}
+// GetNonces implements the ICosignerGRPCServer interface.
func (rpc *GRPCServer) GetNonces(
_ context.Context,
req *proto.CosignerGRPCGetNoncesRequest,
) (*proto.CosignerGRPCGetNoncesResponse, error) {
res, err := rpc.cosigner.GetNonces(
req.ChainID,
- HRSTKeyFromProto(req.GetHrst()),
+ types.HRSTKeyFromProto(req.GetHrst()),
)
if err != nil {
return nil, err
}
return &proto.CosignerGRPCGetNoncesResponse{
- Nonces: CosignerNonces(res.Nonces).toProto(),
+ Nonces: cosigner.WrappedNonces(res.Nonces).ToProto(),
}, nil
}
+// TransferLeadership pseudo-implements the ICosignerGRPCServer interface in pkg/proto/cosigner_grpc_server_grpc.pb.go
func (rpc *GRPCServer) TransferLeadership(
_ context.Context,
req *proto.CosignerGRPCTransferLeadershipRequest,
@@ -110,7 +121,7 @@ func (rpc *GRPCServer) TransferLeadership(
}
leaderID := req.GetLeaderID()
if leaderID != "" {
- for _, c := range rpc.raftStore.Cosigners {
+ for _, c := range rpc.raftStore.thresholdValidator.peerCosigners {
shardID := fmt.Sprint(c.GetID())
if shardID == leaderID {
raftAddress := p2pURLToRaftAddress(c.GetAddress())
@@ -125,6 +136,8 @@ func (rpc *GRPCServer) TransferLeadership(
return &proto.CosignerGRPCTransferLeadershipResponse{}, nil
}
+// GetLeader pseudo-implements the ICosignerGRPCServer interface in pkg/proto/cosigner_grpc_server_grpc.pb.go
+// GetLeader gets the current raft cluster leader and send it as respons.
func (rpc *GRPCServer) GetLeader(
context.Context,
*proto.CosignerGRPCGetLeaderRequest,
diff --git a/pkg/node/icosigner.go b/pkg/node/icosigner.go
new file mode 100644
index 00000000..4c7dc4b5
--- /dev/null
+++ b/pkg/node/icosigner.go
@@ -0,0 +1,30 @@
+package node
+
+import (
+ cometcrypto "github.com/cometbft/cometbft/crypto"
+ "github.com/strangelove-ventures/horcrux/pkg/cosigner"
+ "github.com/strangelove-ventures/horcrux/pkg/types"
+)
+
+// ICosigner interface is a set of methods for an m-of-n threshold signature.
+// This interface abstracts the underlying key storage and management
+type ICosigner interface {
+ // GetID should return the id number of the cosigner
+ // The ID is the shamir index: 1, 2, etc...
+ GetID() int
+
+ // GetAddress gets the P2P URL (GRPC and Raft)
+ GetAddress() string
+
+ // GetPubKey gets the combined public key (permament)
+ // Not used by Remote Cosigner
+ GetPubKey(chainID string) (cometcrypto.PubKey, error)
+
+ VerifySignature(chainID string, payload, signature []byte) bool
+
+ // GetNonces requests nonce frpm the peer cosigners
+ GetNonces(chainID string, hrst types.HRSTKey) (*cosigner.NoncesResponse, error)
+
+ // Sign the requested bytes
+ SetNoncesAndSign(req cosigner.SetNoncesAndSignRequest) (*cosigner.SignResponse, error)
+}
diff --git a/pkg/node/leader.go b/pkg/node/leader.go
new file mode 100644
index 00000000..e91d4b80
--- /dev/null
+++ b/pkg/node/leader.go
@@ -0,0 +1,18 @@
+package node
+
+import (
+ "github.com/strangelove-ventures/horcrux/pkg/types"
+)
+
+// ILeader is an interface for the detecting if the current node/validator/cosigner is
+// the leader and performing leader actions.
+type ILeader interface {
+ // IsLeader returns true if the cosigner is the leader.
+ IsLeader() bool
+
+ // SignBlock asks the leader to manage the signing of a block.
+ SignBlock(ValidatorSignBlockRequest) (*ValidatorSignBlockResponse, error)
+
+ // ShareSigned shares the last signed state with the other cosigners.
+ ShareSigned(lss types.ChainSignStateConsensus) error
+}
diff --git a/signer/leader_mock.go b/pkg/node/leader_mock.go
similarity index 71%
rename from signer/leader_mock.go
rename to pkg/node/leader_mock.go
index 21b866cb..40863e1e 100644
--- a/signer/leader_mock.go
+++ b/pkg/node/leader_mock.go
@@ -1,12 +1,15 @@
-package signer
+package node
+// MockLeader is a "helper" mathod for use with testing.
import (
"errors"
"sync"
"time"
+
+ "github.com/strangelove-ventures/horcrux/pkg/types"
)
-var _ Leader = (*MockLeader)(nil)
+var _ ILeader = (*MockLeader)(nil)
type MockLeader struct {
id int
@@ -27,7 +30,7 @@ func (m *MockLeader) SetLeader(tv *ThresholdValidator) {
m.leader = tv
}
-func (m *MockLeader) SignBlock(req CosignerSignBlockRequest) (*CosignerSignBlockResponse, error) {
+func (m *MockLeader) SignBlock(req ValidatorSignBlockRequest) (*ValidatorSignBlockResponse, error) {
var l *ThresholdValidator
for i := 0; i < 30; i++ {
m.mu.Lock()
@@ -54,11 +57,11 @@ func (m *MockLeader) SignBlock(req CosignerSignBlockRequest) (*CosignerSignBlock
if err != nil {
return nil, err
}
- return &CosignerSignBlockResponse{
+ return &ValidatorSignBlockResponse{
Signature: res,
}, nil
}
-func (m *MockLeader) ShareSigned(_ ChainSignStateConsensus) error {
+func (m *MockLeader) ShareSigned(_ types.ChainSignStateConsensus) error {
return nil
}
diff --git a/signer/raft_events.go b/pkg/node/raft_events.go
similarity index 68%
rename from signer/raft_events.go
rename to pkg/node/raft_events.go
index 450d7538..1efc4b9d 100644
--- a/signer/raft_events.go
+++ b/pkg/node/raft_events.go
@@ -1,11 +1,15 @@
-package signer
+package node
import (
"encoding/json"
"errors"
"time"
- "github.com/strangelove-ventures/horcrux/signer/proto"
+ "github.com/strangelove-ventures/horcrux/pkg/cosigner"
+ "github.com/strangelove-ventures/horcrux/pkg/types"
+
+ "github.com/strangelove-ventures/horcrux/pkg/metrics"
+ "github.com/strangelove-ventures/horcrux/pkg/proto"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
)
@@ -26,7 +30,7 @@ func (f *fsm) shouldRetain(key string) bool {
}
func (f *fsm) handleLSSEvent(value string) {
- lss := &ChainSignStateConsensus{}
+ lss := &types.ChainSignStateConsensus{}
err := json.Unmarshal([]byte(value), lss)
if err != nil {
f.logger.Error(
@@ -44,10 +48,10 @@ func (f *fsm) handleLSSEvent(value string) {
return
}
_ = f.thresholdValidator.SaveLastSignedState(lss.ChainID, lss.SignStateConsensus)
- _ = f.cosigner.SaveLastSignedState(lss.ChainID, lss.SignStateConsensus)
+ _ = f.thresholdValidator.myCosigner.SaveLastSignedState(lss.ChainID, lss.SignStateConsensus)
}
-func (s *RaftStore) getLeaderGRPCClient() (proto.CosignerGRPCClient, *grpc.ClientConn, error) {
+func (s *RaftStore) getLeaderGRPCClient() (proto.ICosignerGRPCClient, *grpc.ClientConn, error) {
var leader string
for i := 0; i < 30; i++ {
leader = string(s.GetLeader())
@@ -57,23 +61,23 @@ func (s *RaftStore) getLeaderGRPCClient() (proto.CosignerGRPCClient, *grpc.Clien
time.Sleep(100 * time.Millisecond)
}
if leader == "" {
- totalRaftLeaderElectiontimeout.Inc()
+ metrics.TotalRaftLeaderElectiontimeout.Inc()
return nil, nil, errors.New("timed out waiting for leader election to complete")
}
conn, err := grpc.Dial(leader, grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil {
return nil, nil, err
}
- return proto.NewCosignerGRPCClient(conn), conn, nil
+ return proto.NewICosignerGRPCClient(conn), conn, nil
}
-func (s *RaftStore) SignBlock(req CosignerSignBlockRequest) (*CosignerSignBlockResponse, error) {
+func (s *RaftStore) SignBlock(req ValidatorSignBlockRequest) (*ValidatorSignBlockResponse, error) {
client, conn, err := s.getLeaderGRPCClient()
if err != nil {
return nil, err
}
defer conn.Close()
- context, cancelFunc := getContext()
+ context, cancelFunc := cosigner.GetContext()
defer cancelFunc()
res, err := client.SignBlock(context, &proto.CosignerGRPCSignBlockRequest{
ChainID: req.ChainID,
@@ -82,7 +86,7 @@ func (s *RaftStore) SignBlock(req CosignerSignBlockRequest) (*CosignerSignBlockR
if err != nil {
return nil, err
}
- return &CosignerSignBlockResponse{
+ return &ValidatorSignBlockResponse{
Signature: res.GetSignature(),
}, nil
}
diff --git a/signer/raft_store.go b/pkg/node/raft_store.go
similarity index 92%
rename from signer/raft_store.go
rename to pkg/node/raft_store.go
index b920b8fb..0aafe85b 100644
--- a/signer/raft_store.go
+++ b/pkg/node/raft_store.go
@@ -5,7 +5,7 @@
//
// Distributed consensus is provided via the Raft algorithm, specifically the
// Hashicorp implementation.
-package signer
+package node
import (
"encoding/json"
@@ -18,6 +18,8 @@ import (
"sync"
"time"
+ "github.com/strangelove-ventures/horcrux/pkg/types"
+
"github.com/Jille/raft-grpc-leader-rpc/leaderhealth"
raftgrpctransport "github.com/Jille/raft-grpc-transport"
"github.com/Jille/raftadmin"
@@ -25,13 +27,13 @@ import (
"github.com/cometbft/cometbft/libs/service"
"github.com/hashicorp/raft"
boltdb "github.com/hashicorp/raft-boltdb/v2"
- "github.com/strangelove-ventures/horcrux/signer/proto"
+ "github.com/strangelove-ventures/horcrux/pkg/proto"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
"google.golang.org/grpc/reflection"
)
-var _ Leader = (*RaftStore)(nil)
+var _ ILeader = (*RaftStore)(nil) // Ensure RaftStore implements ILeader
const (
retainSnapshotCount = 2
@@ -43,7 +45,7 @@ type command struct {
Value string `json:"value,omitempty"`
}
-// Store is a simple key-value store, where all changes are made via Raft consensus.
+// RaftStore is a simple key-value store, where all changes are made via Raft consensus.
type RaftStore struct {
service.BaseService
@@ -51,22 +53,21 @@ type RaftStore struct {
RaftDir string
RaftBind string
RaftTimeout time.Duration
- Cosigners []Cosigner
mu sync.Mutex
m map[string]string // The key-value store for the system.
raft *raft.Raft // The consensus mechanism
- logger log.Logger
- cosigner *LocalCosigner
+ logger log.Logger
+
thresholdValidator *ThresholdValidator
}
-// New returns a new Store.
+// NewRaftStore returns a new RaftStore.
func NewRaftStore(
nodeID string, directory string, bindAddress string, timeout time.Duration,
- logger log.Logger, cosigner *LocalCosigner, cosigners []Cosigner) *RaftStore {
+ logger log.Logger) *RaftStore {
cosignerRaftStore := &RaftStore{
NodeID: nodeID,
RaftDir: directory,
@@ -74,8 +75,6 @@ func NewRaftStore(
RaftTimeout: timeout,
m: make(map[string]string),
logger: logger,
- cosigner: cosigner,
- Cosigners: cosigners,
}
cosignerRaftStore.BaseService = *service.NewBaseService(logger, "CosignerRaftStore", cosignerRaftStore)
@@ -101,8 +100,10 @@ func (s *RaftStore) init() error {
if err != nil {
return err
}
+ // Create a new gRPC server which is used by both the Raft, the threshold validator and the cosigner
grpcServer := grpc.NewServer()
- proto.RegisterCosignerGRPCServer(grpcServer, NewGRPCServer(s.cosigner, s.thresholdValidator, s))
+ proto.RegisterICosignerGRPCServer(grpcServer,
+ NewGRPCServer(s.thresholdValidator.myCosigner, s.thresholdValidator, s))
transportManager.Register(grpcServer)
leaderhealth.Setup(s.raft, grpcServer, []string{"Leader"})
raftadmin.Register(grpcServer, s.raft)
@@ -115,6 +116,7 @@ func (s *RaftStore) OnStart() error {
go func() {
err := s.init()
if err != nil {
+ s.logger.Error("OnStart %v", err)
panic(err)
}
}()
@@ -180,7 +182,8 @@ func (s *RaftStore) Open() (*raftgrpctransport.Manager, error) {
},
},
}
- for _, c := range s.Cosigners {
+
+ for _, c := range s.thresholdValidator.peerCosigners {
configuration.Servers = append(configuration.Servers, raft.Server{
ID: raft.ServerID(fmt.Sprint(c.GetID())),
Address: raft.ServerAddress(p2pURLToRaftAddress(c.GetAddress())),
@@ -294,7 +297,7 @@ func (s *RaftStore) GetLeader() raft.ServerAddress {
return s.raft.Leader()
}
-func (s *RaftStore) ShareSigned(lss ChainSignStateConsensus) error {
+func (s *RaftStore) ShareSigned(lss types.ChainSignStateConsensus) error {
return s.Emit(raftEventLSS, lss)
}
diff --git a/signer/raft_store_test.go b/pkg/node/raft_store_test.go
similarity index 76%
rename from signer/raft_store_test.go
rename to pkg/node/raft_store_test.go
index c7b051e8..b31f6cb0 100644
--- a/signer/raft_store_test.go
+++ b/pkg/node/raft_store_test.go
@@ -1,4 +1,4 @@
-package signer
+package node
import (
"crypto/rand"
@@ -7,9 +7,11 @@ import (
"time"
cometcryptoed25519 "github.com/cometbft/cometbft/crypto/ed25519"
+
"github.com/cometbft/cometbft/libs/log"
"github.com/ethereum/go-ethereum/crypto/ecies"
"github.com/ethereum/go-ethereum/crypto/secp256k1"
+ "github.com/strangelove-ventures/horcrux/pkg/cosigner"
"github.com/stretchr/testify/require"
)
@@ -24,17 +26,17 @@ func Test_StoreInMemOpenSingleNode(t *testing.T) {
eciesKey, err := ecies.GenerateKey(rand.Reader, secp256k1.S256(), nil)
require.NoError(t, err)
- key := CosignerEd25519Key{
+ key := cosigner.CosignEd25519Key{
PubKey: dummyPub,
PrivateShard: []byte{},
ID: 1,
}
- cosigner := NewLocalCosigner(
+ cosigner := cosigner.NewLocalCosigner(
log.NewNopLogger(),
- &RuntimeConfig{},
- NewCosignerSecurityECIES(
- CosignerECIESKey{
+ &cosigner.RuntimeConfig{},
+ cosigner.NewCosignerSecurityECIES(
+ cosigner.CosignEciesKey{
ID: key.ID,
ECIESKey: eciesKey,
ECIESPubs: []*ecies.PublicKey{&eciesKey.PublicKey},
@@ -42,14 +44,17 @@ func Test_StoreInMemOpenSingleNode(t *testing.T) {
"",
)
+ validator := &ThresholdValidator{
+ myCosigner: cosigner}
+
s := &RaftStore{
- NodeID: "1",
- RaftDir: tmpDir,
- RaftBind: "127.0.0.1:0",
- RaftTimeout: 1 * time.Second,
- m: make(map[string]string),
- logger: nil,
- cosigner: cosigner,
+ NodeID: "1",
+ RaftDir: tmpDir,
+ RaftBind: "127.0.0.1:0",
+ RaftTimeout: 1 * time.Second,
+ m: make(map[string]string),
+ logger: nil,
+ thresholdValidator: validator,
}
if _, err := s.Open(); err != nil {
diff --git a/signer/services.go b/pkg/node/services.go
similarity index 99%
rename from signer/services.go
rename to pkg/node/services.go
index 62ff93ba..5ed81685 100644
--- a/signer/services.go
+++ b/pkg/node/services.go
@@ -1,4 +1,4 @@
-package signer
+package node
import (
"errors"
diff --git a/signer/services_test.go b/pkg/node/services_test.go
similarity index 92%
rename from signer/services_test.go
rename to pkg/node/services_test.go
index fe8acb8b..b91ab595 100644
--- a/signer/services_test.go
+++ b/pkg/node/services_test.go
@@ -1,4 +1,4 @@
-package signer_test
+package node_test
import (
"errors"
@@ -13,10 +13,10 @@ import (
"testing"
"time"
+ "github.com/strangelove-ventures/horcrux/pkg/node"
+
cometlog "github.com/cometbft/cometbft/libs/log"
cometservice "github.com/cometbft/cometbft/libs/service"
- "github.com/strangelove-ventures/horcrux/signer"
-
fork "github.com/kraken-hpc/go-fork"
"github.com/stretchr/testify/require"
)
@@ -72,7 +72,7 @@ func TestIsRunning(t *testing.T) {
pidBz, err := os.ReadFile(pidFilePath)
require.NoError(t, err)
- err = signer.RequireNotRunning(pidFilePath)
+ err = node.RequireNotRunning(pidFilePath)
expectedErrorMsg := fmt.Sprintf("horcrux is already running on PID: %s", strings.TrimSpace(string(pidBz)))
require.EqualError(t, err, expectedErrorMsg)
}
@@ -81,7 +81,7 @@ func TestIsNotRunning(t *testing.T) {
homeDir := t.TempDir()
pidFilePath := filepath.Join(homeDir, "horcrux.pid")
- err := signer.RequireNotRunning(pidFilePath)
+ err := node.RequireNotRunning(pidFilePath)
require.NoError(t, err)
}
@@ -135,7 +135,7 @@ func TestIsRunningNonExistentPid(t *testing.T) {
)
require.NoError(t, err, "error writing pid file")
- err = signer.RequireNotRunning(pidFilePath)
+ err = node.RequireNotRunning(pidFilePath)
expectedErrorMsg := fmt.Sprintf(`unclean shutdown detected. PID file exists at %s but PID %d is not running.
manual deletion of PID file required`, pidFilePath, pid)
require.EqualError(t, err, expectedErrorMsg)
@@ -172,7 +172,7 @@ func TestConcurrentStart(t *testing.T) {
for i := 0; i < concurrentAttempts; i++ {
go func() {
defer recoverFromPanic()
- signer.WaitAndTerminate(logger, services, pidFilePath)
+ node.WaitAndTerminate(logger, services, pidFilePath)
doneCount++
wg.Done()
}()
@@ -191,7 +191,7 @@ func TestIsRunningAndWaitForService(t *testing.T) {
var logger cometlog.Logger
var services []cometservice.Service
- go func() { signer.WaitAndTerminate(logger, services, pidFilePath) }()
+ go func() { node.WaitAndTerminate(logger, services, pidFilePath) }()
// Wait for signer.WaitAndTerminate to create pidFile
var err error
@@ -216,7 +216,7 @@ func TestIsRunningAndWaitForService(t *testing.T) {
}
panicFunction := func() {
defer recoverFromPanic()
- err = signer.RequireNotRunning(pidFilePath)
+ err = node.RequireNotRunning(pidFilePath)
}
go panicFunction()
wg.Wait()
diff --git a/signer/single_signer_validator.go b/pkg/node/single_signer_validator.go
similarity index 92%
rename from signer/single_signer_validator.go
rename to pkg/node/single_signer_validator.go
index b3a6ebb4..e1eb40a2 100644
--- a/signer/single_signer_validator.go
+++ b/pkg/node/single_signer_validator.go
@@ -1,21 +1,23 @@
-package signer
+package node
import (
"fmt"
"os"
"sync"
+ "github.com/strangelove-ventures/horcrux/pkg/cosigner"
+
cometcrypto "github.com/cometbft/cometbft/crypto"
cometprivval "github.com/cometbft/cometbft/privval"
cometproto "github.com/cometbft/cometbft/proto/tendermint/types"
)
-var _ PrivValidator = &SingleSignerValidator{}
+var _ IPrivValidator = &SingleSignerValidator{}
// SingleSignerValidator guards access to an underlying PrivValidator by using mutexes
// for each of the PrivValidator interface functions
type SingleSignerValidator struct {
- config *RuntimeConfig
+ config *cosigner.RuntimeConfig
chainState sync.Map
}
@@ -31,7 +33,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 *cosigner.RuntimeConfig) *SingleSignerValidator {
return &SingleSignerValidator{
config: config,
}
@@ -73,7 +75,6 @@ func (pv *SingleSignerValidator) loadChainStateIfNecessary(chainID string) (*Sin
if ok {
return cachedChainState.(*SingleSignerChainState), nil
}
-
keyFile := pv.config.KeyFilePathSingleSigner(chainID)
if _, err := os.Stat(keyFile); err != nil {
return nil, fmt.Errorf("failed to load key file (%s) - %w", keyFile, err)
diff --git a/signer/single_signer_validator_test.go b/pkg/node/single_signer_validator_test.go
similarity index 96%
rename from signer/single_signer_validator_test.go
rename to pkg/node/single_signer_validator_test.go
index c1aa8bc2..126cd801 100644
--- a/signer/single_signer_validator_test.go
+++ b/pkg/node/single_signer_validator_test.go
@@ -1,9 +1,11 @@
-package signer
+package node
import (
"path/filepath"
"time"
+ "github.com/strangelove-ventures/horcrux/pkg/cosigner"
+
"os"
"testing"
@@ -25,7 +27,7 @@ func TestSingleSignerValidator(t *testing.T) {
err := os.MkdirAll(stateDir, 0700)
require.NoError(t, err)
- runtimeConfig := &RuntimeConfig{
+ runtimeConfig := &cosigner.RuntimeConfig{
HomeDir: tmpDir,
StateDir: filepath.Join(tmpDir, "state"),
}
diff --git a/signer/remote_signer.go b/pkg/node/threshold_remote_signer.go
similarity index 84%
rename from signer/remote_signer.go
rename to pkg/node/threshold_remote_signer.go
index f9c2d661..507e8aeb 100644
--- a/signer/remote_signer.go
+++ b/pkg/node/threshold_remote_signer.go
@@ -1,4 +1,4 @@
-package signer
+package node
import (
"context"
@@ -6,6 +6,8 @@ import (
"net"
"time"
+ "github.com/strangelove-ventures/horcrux/pkg/types"
+
cometcrypto "github.com/cometbft/cometbft/crypto"
cometcryptoed25519 "github.com/cometbft/cometbft/crypto/ed25519"
cometcryptoencoding "github.com/cometbft/cometbft/crypto/encoding"
@@ -16,13 +18,14 @@ import (
cometprotocrypto "github.com/cometbft/cometbft/proto/tendermint/crypto"
cometprotoprivval "github.com/cometbft/cometbft/proto/tendermint/privval"
cometproto "github.com/cometbft/cometbft/proto/tendermint/types"
+ "github.com/strangelove-ventures/horcrux/pkg/metrics"
)
const connRetrySec = 2
-// PrivValidator is a wrapper for tendermint PrivValidator,
+// IPrivValidator is a wrapper for tendermint PrivValidator,
// with additional Stop method for safe shutdown.
-type PrivValidator interface {
+type IPrivValidator interface {
SignVote(chainID string, vote *cometproto.Vote) error
SignProposal(chainID string, proposal *cometproto.Proposal) error
GetPubKey(chainID string) (cometcrypto.PubKey, error)
@@ -36,7 +39,7 @@ type ReconnRemoteSigner struct {
address string
privKey cometcryptoed25519.PrivKey
- privVal PrivValidator
+ privVal IPrivValidator
dialer net.Dialer
}
@@ -49,7 +52,7 @@ type ReconnRemoteSigner struct {
func NewReconnRemoteSigner(
address string,
logger cometlog.Logger,
- privVal PrivValidator,
+ privVal IPrivValidator,
dialer net.Dialer,
) *ReconnRemoteSigner {
rs := &ReconnRemoteSigner{
@@ -108,14 +111,14 @@ func (rs *ReconnRemoteSigner) loop(ctx context.Context) {
timer := time.NewTimer(connRetrySec * time.Second)
conn, err = rs.establishConnection(ctx)
if err == nil {
- sentryConnectTries.Set(0)
+ metrics.SentryConnectTries.Set(0)
timer.Stop()
rs.Logger.Info("Connected to Sentry", "address", rs.address)
break
}
- sentryConnectTries.Add(1)
- totalSentryConnectTries.Inc()
+ metrics.SentryConnectTries.Add(1)
+ metrics.TotalSentryConnectTries.Inc()
retries++
rs.Logger.Error(
"Error establishing connection, will retry",
@@ -138,7 +141,7 @@ func (rs *ReconnRemoteSigner) loop(ctx context.Context) {
return
}
- req, err := ReadMsg(conn)
+ req, err := types.ReadMsg(conn)
if err != nil {
rs.Logger.Error(
"Failed to read message from connection",
@@ -153,7 +156,7 @@ func (rs *ReconnRemoteSigner) loop(ctx context.Context) {
// handleRequest handles request errors. We always send back a response
res := rs.handleRequest(req)
- err = WriteMsg(conn, res)
+ err = types.WriteMsg(conn, res)
if err != nil {
rs.Logger.Error(
"Failed to write message to connection",
@@ -201,7 +204,7 @@ func (rs *ReconnRemoteSigner) handleSignVoteRequest(chainID string, vote *cometp
"validator", fmt.Sprintf("%X", vote.ValidatorAddress),
"reason", typedErr.msg,
)
- beyondBlockErrors.Inc()
+ metrics.BeyondBlockErrors.Inc()
default:
rs.Logger.Error(
"Failed to sign vote",
@@ -213,7 +216,7 @@ func (rs *ReconnRemoteSigner) handleSignVoteRequest(chainID string, vote *cometp
"validator", fmt.Sprintf("%X", vote.ValidatorAddress),
"error", err,
)
- failedSignVote.Inc()
+ metrics.FailedSignVote.Inc()
}
msgSum.SignedVoteResponse.Error = getRemoteSignerError(err)
return cometprotoprivval.Message{Sum: msgSum}
@@ -235,38 +238,38 @@ func (rs *ReconnRemoteSigner) handleSignVoteRequest(chainID string, vote *cometp
)
if vote.Type == cometproto.PrecommitType {
- stepSize := vote.Height - previousPrecommitHeight
- if previousPrecommitHeight != 0 && stepSize > 1 {
- missedPrecommits.Add(float64(stepSize))
- totalMissedPrecommits.Add(float64(stepSize))
+ stepSize := vote.Height - metrics.PreviousPrecommitHeight
+ if metrics.PreviousPrecommitHeight != 0 && stepSize > 1 {
+ metrics.MissedPrecommits.Add(float64(stepSize))
+ metrics.TotalMissedPrecommits.Add(float64(stepSize))
} else {
- missedPrecommits.Set(0)
+ metrics.MissedPrecommits.Set(0)
}
- previousPrecommitHeight = vote.Height // remember last PrecommitHeight
+ metrics.PreviousPrecommitHeight = vote.Height // remember last PrecommitHeight
- metricsTimeKeeper.SetPreviousPrecommit(time.Now())
+ metrics.MetricsTimeKeeper.SetPreviousPrecommit(time.Now())
- lastPrecommitHeight.Set(float64(vote.Height))
- lastPrecommitRound.Set(float64(vote.Round))
- totalPrecommitsSigned.Inc()
+ metrics.LastPrecommitHeight.Set(float64(vote.Height))
+ metrics.LastPrecommitRound.Set(float64(vote.Round))
+ metrics.TotalPrecommitsSigned.Inc()
}
if vote.Type == cometproto.PrevoteType {
// Determine number of heights since the last Prevote
- stepSize := vote.Height - previousPrevoteHeight
- if previousPrevoteHeight != 0 && stepSize > 1 {
- missedPrevotes.Add(float64(stepSize))
- totalMissedPrevotes.Add(float64(stepSize))
+ stepSize := vote.Height - metrics.PreviousPrevoteHeight
+ if metrics.PreviousPrevoteHeight != 0 && stepSize > 1 {
+ metrics.MissedPrevotes.Add(float64(stepSize))
+ metrics.TotalMissedPrevotes.Add(float64(stepSize))
} else {
- missedPrevotes.Set(0)
+ metrics.MissedPrevotes.Set(0)
}
- previousPrevoteHeight = vote.Height // remember last PrevoteHeight
+ metrics.PreviousPrevoteHeight = vote.Height // remember last PrevoteHeight
- metricsTimeKeeper.SetPreviousPrevote(time.Now())
+ metrics.MetricsTimeKeeper.SetPreviousPrevote(time.Now())
- lastPrevoteHeight.Set(float64(vote.Height))
- lastPrevoteRound.Set(float64(vote.Round))
- totalPrevotesSigned.Inc()
+ metrics.LastPrevoteHeight.Set(float64(vote.Height))
+ metrics.LastPrevoteRound.Set(float64(vote.Round))
+ metrics.TotalPrevotesSigned.Inc()
}
msgSum.SignedVoteResponse.Vote = *vote
@@ -295,7 +298,7 @@ func (rs *ReconnRemoteSigner) handleSignProposalRequest(
"node", rs.address,
"reason", typedErr.msg,
)
- beyondBlockErrors.Inc()
+ metrics.BeyondBlockErrors.Inc()
default:
rs.Logger.Error(
"Failed to sign proposal",
@@ -325,15 +328,15 @@ func (rs *ReconnRemoteSigner) handleSignProposalRequest(
"ts", proposal.Timestamp.Unix(),
"node", rs.address,
)
- lastProposalHeight.Set(float64(proposal.Height))
- lastProposalRound.Set(float64(proposal.Round))
- totalProposalsSigned.Inc()
+ metrics.LastProposalHeight.Set(float64(proposal.Height))
+ metrics.LastProposalRound.Set(float64(proposal.Round))
+ metrics.TotalProposalsSigned.Inc()
msgSum.SignedProposalResponse.Proposal = *proposal
return cometprotoprivval.Message{Sum: msgSum}
}
func (rs *ReconnRemoteSigner) handlePubKeyRequest(chainID string) cometprotoprivval.Message {
- totalPubKeyRequests.Inc()
+ metrics.TotalPubKeyRequests.Inc()
msgSum := &cometprotoprivval.Message_PubKeyResponse{PubKeyResponse: &cometprotoprivval.PubKeyResponse{
PubKey: cometprotocrypto.PublicKey{},
Error: nil,
@@ -386,11 +389,11 @@ func getRemoteSignerError(err error) *cometprotoprivval.RemoteSignerError {
func StartRemoteSigners(
services []cometservice.Service,
logger cometlog.Logger,
- privVal PrivValidator,
+ privVal IPrivValidator,
nodes []string,
) ([]cometservice.Service, error) {
var err error
- go StartMetrics()
+ go metrics.StartMetrics()
for _, node := range nodes {
// CometBFT requires a connection within 3 seconds of start or crashes
// A long timeout such as 30 seconds would cause the sentry to fail in loops
diff --git a/signer/threshold_validator.go b/pkg/node/threshold_validator.go
similarity index 81%
rename from signer/threshold_validator.go
rename to pkg/node/threshold_validator.go
index 0a6d7b63..cad72378 100644
--- a/signer/threshold_validator.go
+++ b/pkg/node/threshold_validator.go
@@ -1,4 +1,4 @@
-package signer
+package node
import (
"bytes"
@@ -8,18 +8,30 @@ import (
"sync"
"time"
+ "github.com/strangelove-ventures/horcrux/pkg/cosigner"
+ "github.com/strangelove-ventures/horcrux/pkg/types"
+
"github.com/cometbft/cometbft/crypto"
"github.com/cometbft/cometbft/libs/log"
cometproto "github.com/cometbft/cometbft/proto/tendermint/types"
cometrpcjsontypes "github.com/cometbft/cometbft/rpc/jsonrpc/types"
comet "github.com/cometbft/cometbft/types"
- "github.com/strangelove-ventures/horcrux/signer/proto"
+ "github.com/strangelove-ventures/horcrux/pkg/metrics"
+ "github.com/strangelove-ventures/horcrux/pkg/proto"
)
-var _ PrivValidator = &ThresholdValidator{}
+var _ IPrivValidator = &ThresholdValidator{}
+
+type ValidatorSignBlockRequest struct {
+ ChainID string
+ Block *Block
+}
+type ValidatorSignBlockResponse struct {
+ Signature []byte
+}
type ThresholdValidator struct {
- config *RuntimeConfig
+ config *cosigner.RuntimeConfig
threshold int
@@ -28,12 +40,12 @@ type ThresholdValidator struct {
chainState sync.Map
// our own cosigner
- myCosigner *LocalCosigner
+ myCosigner *cosigner.LocalCosigner
// peer cosigners
- peerCosigners []Cosigner
+ peerCosigners []ICosigner
- leader Leader
+ leader ILeader
logger log.Logger
@@ -45,24 +57,24 @@ type ThresholdValidator struct {
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
- lastSignState *SignState
+ lastSignState *types.SignState
lastSignStateMutex *sync.Mutex
// stores the last sign state that we've started progress on
- lastSignStateInitiated *SignState
+ lastSignStateInitiated *types.SignState
lastSignStateInitiatedMutex *sync.Mutex
}
// NewThresholdValidator creates and returns a new ThresholdValidator
func NewThresholdValidator(
logger log.Logger,
- config *RuntimeConfig,
+ config *cosigner.RuntimeConfig,
threshold int,
grpcTimeout time.Duration,
maxWaitForSameBlockAttempts int,
- myCosigner *LocalCosigner,
- peerCosigners []Cosigner,
- leader Leader,
+ myCosigner *cosigner.LocalCosigner,
+ peerCosigners []ICosigner,
+ leader ILeader,
) *ThresholdValidator {
return &ThresholdValidator{
logger: logger,
@@ -76,11 +88,11 @@ func NewThresholdValidator(
}
}
-// SaveLastSignedState updates the high watermark height/round/step (HRS) for a completed
+// SaveLastSignedState updates the high watermark height/round/step (HRS) for a completed(!)
// sign process if it is greater than the current high watermark. A mutex is used to avoid concurrent
// state updates. The disk write is scheduled in a separate goroutine which will perform an atomic write.
// pendingDiskWG is used upon termination in pendingDiskWG to ensure all writes have completed.
-func (pv *ThresholdValidator) SaveLastSignedState(chainID string, signState SignStateConsensus) error {
+func (pv *ThresholdValidator) SaveLastSignedState(chainID string, signState types.SignStateConsensus) error {
css := pv.mustLoadChainState(chainID)
css.lastSignStateMutex.Lock()
@@ -111,7 +123,7 @@ func (pv *ThresholdValidator) SaveLastSignedStateInitiated(chainID string, block
height, round, step := block.Height, block.Round, block.Step
- err := css.lastSignStateInitiated.Save(NewSignStateConsensus(height, round, step), &pv.pendingDiskWG)
+ err := css.lastSignStateInitiated.Save(types.NewSignStateConsensus(height, round, step), &pv.pendingDiskWG)
if err == nil {
// good to sign
return nil, time.Time{}, nil
@@ -120,7 +132,7 @@ func (pv *ThresholdValidator) SaveLastSignedStateInitiated(chainID string, block
// There was an error saving the last sign state, so check if there is an existing signature for this block.
existingSignature, existingTimestamp, sameBlockErr := pv.getExistingBlockSignature(chainID, block)
- if _, ok := err.(*SameHRSError); !ok {
+ if _, ok := err.(*types.SameHRSError); !ok {
if sameBlockErr == nil {
return existingSignature, block.Timestamp, nil
}
@@ -150,14 +162,14 @@ func (pv *ThresholdValidator) SaveLastSignedStateInitiated(chainID string, block
// intended usage of cond lock prior to cond.Wait().
// cond.Wait() will unlock cond.L while it blocks waiting, then re-lock when unblocking from
// the cond.Broadcast().
- css.lastSignState.cond.L.Lock()
- defer css.lastSignState.cond.L.Unlock()
+ css.lastSignState.CondLlock()
+ defer css.lastSignState.CondLunlock()
for i := 0; i < pv.maxWaitForSameBlockAttempts; i++ {
// block until sign state is saved. It will notify and unblock when block is next signed.
- css.lastSignState.cond.WaitWithTimeout(pv.grpcTimeout)
+ css.lastSignState.WaitWithTimeout(pv.grpcTimeout)
// check if HRS exists in cache now
- ssc, ok := css.lastSignState.cache[block.HRSKey()]
+ ssc, ok := css.lastSignState.GetCache(block.HRSKey())
if !ok {
pv.logger.Debug(
"Block does not yet exist in cache while waiting for signature",
@@ -200,45 +212,49 @@ func (pv *ThresholdValidator) SaveLastSignedStateInitiated(chainID string, block
// notifyBlockSignError will alert any waiting goroutines that an error
// has occurred during signing and a retry can be attempted.
-func (pv *ThresholdValidator) notifyBlockSignError(chainID string, hrs HRSKey) {
+func (pv *ThresholdValidator) notifyBlockSignError(chainID string, hrs types.HRSKey) {
css := pv.mustLoadChainState(chainID)
- css.lastSignState.mu.Lock()
- css.lastSignState.cache[hrs] = SignStateConsensus{
- Height: hrs.Height,
- Round: hrs.Round,
- Step: hrs.Step,
- // empty signature to indicate error
- }
- css.lastSignState.mu.Unlock()
- css.lastSignState.cond.Broadcast()
-}
+ css.lastSignState.MuLock()
+ css.lastSignState.SetCache(hrs,
+ types.SignStateConsensus{
+ Height: hrs.Height,
+ Round: hrs.Round,
+ Step: hrs.Step,
+ // empty signature to indicate error
+ })
-// Stop safely shuts down the ThresholdValidator.
-func (pv *ThresholdValidator) Stop() {
- pv.waitForSignStatesToFlushToDisk()
+ css.lastSignState.MuUnlock()
+ css.lastSignState.CondBroadcast()
}
// waitForSignStatesToFlushToDisk waits for any sign states to finish writing to disk.
func (pv *ThresholdValidator) waitForSignStatesToFlushToDisk() {
pv.pendingDiskWG.Wait()
- pv.myCosigner.waitForSignStatesToFlushToDisk()
+ pv.myCosigner.WaitForSignStatesToFlushToDisk()
+}
+
+// Stop safely shuts down the ThresholdValidator.
+// Stop implements IPrivValidator from threshold_remote_signer.go
+func (pv *ThresholdValidator) Stop() {
+ pv.waitForSignStatesToFlushToDisk()
}
// GetPubKey returns the public key of the validator.
-// Implements PrivValidator.
+// Implements IPrivValidator fromt threshold_remote_signer.go
func (pv *ThresholdValidator) GetPubKey(chainID string) (crypto.PubKey, error) {
return pv.myCosigner.GetPubKey(chainID)
}
// SignVote signs a canonical representation of the vote, along with the
-// chainID. Implements PrivValidator.
+// chainID.
+// SignVote implements IPrivValidator fromt threshold_remote_signer.go
func (pv *ThresholdValidator) SignVote(chainID string, vote *cometproto.Vote) error {
block := &Block{
Height: vote.Height,
Round: int64(vote.Round),
- Step: VoteToStep(vote),
+ Step: types.VoteToStep(vote),
Timestamp: vote.Timestamp,
SignBytes: comet.VoteSignBytes(chainID, vote),
}
@@ -252,12 +268,13 @@ func (pv *ThresholdValidator) SignVote(chainID string, vote *cometproto.Vote) er
}
// SignProposal signs a canonical representation of the proposal, along with
-// the chainID. Implements PrivValidator.
+// the chainID.
+// SignProposal implements IPrivValidator fromt threshold_remote_signer.go
func (pv *ThresholdValidator) SignProposal(chainID string, proposal *cometproto.Proposal) error {
block := &Block{
Height: proposal.Height,
Round: int64(proposal.Round),
- Step: ProposalToStep(proposal),
+ Step: types.ProposalToStep(proposal),
Timestamp: proposal.Timestamp,
SignBytes: comet.ProposalSignBytes(chainID, proposal),
}
@@ -278,16 +295,16 @@ type Block struct {
Timestamp time.Time
}
-func (block Block) HRSKey() HRSKey {
- return HRSKey{
+func (block Block) HRSKey() types.HRSKey {
+ return types.HRSKey{
Height: block.Height,
Round: block.Round,
Step: block.Step,
}
}
-func (block Block) HRSTKey() HRSTKey {
- return HRSTKey{
+func (block Block) HRSTKey() types.HRSTKey {
+ return types.HRSTKey{
Height: block.Height,
Round: block.Round,
Step: block.Step,
@@ -311,7 +328,7 @@ type BeyondBlockError struct {
func (e *BeyondBlockError) Error() string { return e.msg }
-func (pv *ThresholdValidator) newBeyondBlockError(chainID string, hrs HRSKey) *BeyondBlockError {
+func (pv *ThresholdValidator) newBeyondBlockError(chainID string, hrs types.HRSKey) *BeyondBlockError {
css := pv.mustLoadChainState(chainID)
lss := css.lastSignStateInitiated
@@ -330,7 +347,7 @@ type StillWaitingForBlockError struct {
func (e *StillWaitingForBlockError) Error() string { return e.msg }
-func newStillWaitingForBlockError(chainID string, hrs HRSKey) *StillWaitingForBlockError {
+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),
@@ -343,7 +360,7 @@ type SameBlockError struct {
func (e *SameBlockError) Error() string { return e.msg }
-func newSameBlockError(chainID string, hrs HRSKey) *SameBlockError {
+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),
@@ -352,24 +369,24 @@ func newSameBlockError(chainID string, hrs HRSKey) *SameBlockError {
func (pv *ThresholdValidator) waitForPeerNonces(
chainID string,
- peer Cosigner,
- hrst HRSTKey,
+ peer ICosigner,
+ hrst types.HRSTKey,
wg *sync.WaitGroup,
- nonces map[Cosigner][]CosignerNonce,
+ nonces map[ICosigner][]cosigner.WrappedNonce,
thresholdPeersMutex *sync.Mutex,
) {
peerStartTime := time.Now()
peerNonces, err := peer.GetNonces(chainID, hrst)
if err != nil {
// Significant missing shares may lead to signature failure
- missedNonces.WithLabelValues(peer.GetAddress()).Add(float64(1))
- totalMissedNonces.WithLabelValues(peer.GetAddress()).Inc()
+ metrics.MissedNonces.WithLabelValues(peer.GetAddress()).Add(float64(1))
+ metrics.TotalMissedNonces.WithLabelValues(peer.GetAddress()).Inc()
pv.logger.Error("Error getting nonces", "cosigner", peer.GetID(), "err", err)
return
}
// Significant missing shares may lead to signature failure
- missedNonces.WithLabelValues(peer.GetAddress()).Set(0)
- timedCosignerNonceLag.WithLabelValues(peer.GetAddress()).Observe(time.Since(peerStartTime).Seconds())
+ metrics.MissedNonces.WithLabelValues(peer.GetAddress()).Set(0)
+ metrics.TimedCosignerNonceLag.WithLabelValues(peer.GetAddress()).Observe(time.Since(peerStartTime).Seconds())
// Check so that wg.Done is not called more than (threshold - 1) times which causes hardlock
thresholdPeersMutex.Lock()
@@ -381,9 +398,9 @@ func (pv *ThresholdValidator) waitForPeerNonces(
}
func (pv *ThresholdValidator) waitForPeerSetNoncesAndSign(
chainID string,
- peer Cosigner,
- hrst HRSTKey,
- noncesMap map[Cosigner][]CosignerNonce,
+ peer ICosigner,
+ hrst types.HRSTKey,
+ noncesMap map[ICosigner][]cosigner.WrappedNonce,
signBytes []byte,
shareSignatures *[][]byte,
shareSignaturesMutex *sync.Mutex,
@@ -391,7 +408,7 @@ func (pv *ThresholdValidator) waitForPeerSetNoncesAndSign(
) {
peerStartTime := time.Now()
defer wg.Done()
- peerNonces := make([]CosignerNonce, 0, pv.threshold-1)
+ peerNonces := make([]cosigner.WrappedNonce, 0, pv.threshold-1)
peerID := peer.GetID()
@@ -413,7 +430,7 @@ func (pv *ThresholdValidator) waitForPeerSetNoncesAndSign(
}
}
- sigRes, err := peer.SetNoncesAndSign(CosignerSetNoncesAndSignRequest{
+ sigRes, err := peer.SetNoncesAndSign(cosigner.SetNoncesAndSignRequest{
ChainID: chainID,
Nonces: peerNonces,
HRST: hrst,
@@ -429,7 +446,7 @@ func (pv *ThresholdValidator) waitForPeerSetNoncesAndSign(
return
}
- timedCosignerSignLag.WithLabelValues(peer.GetAddress()).Observe(time.Since(peerStartTime).Seconds())
+ metrics.TimedCosignerSignLag.WithLabelValues(peer.GetAddress()).Observe(time.Since(peerStartTime).Seconds())
pv.logger.Debug(
"Received signature part",
"cosigner", peerID,
@@ -466,13 +483,13 @@ func (pv *ThresholdValidator) LoadSignStateIfNecessary(chainID string) error {
return nil
}
- signState, err := LoadOrCreateSignState(pv.config.PrivValStateFile(chainID))
+ signState, err := types.LoadOrCreateSignState(pv.config.PrivValStateFile(chainID))
if err != nil {
return err
}
lastSignStateInitiated := signState.FreshCache()
- lastSignStateInitiated.filePath = os.DevNull
+ lastSignStateInitiated.FilePath = os.DevNull
pv.chainState.Store(chainID, ChainSignState{
lastSignState: signState,
@@ -514,7 +531,7 @@ func (pv *ThresholdValidator) getExistingBlockSignature(chainID string, block *B
func (pv *ThresholdValidator) compareBlockSignatureAgainstSSC(
chainID string,
block *Block,
- existingSignature *SignStateConsensus,
+ existingSignature *types.SignStateConsensus,
) ([]byte, time.Time, error) {
stamp, signBytes := block.Timestamp, block.SignBytes
@@ -525,7 +542,7 @@ func (pv *ThresholdValidator) compareBlockSignatureAgainstSSC(
}
// If a proposal has already been signed for this HRS, or the sign payload is identical, return the existing signature.
- if block.Step == stepPropose || bytes.Equal(signBytes, existingSignature.SignBytes) {
+ if block.Step == types.StepPropose() || bytes.Equal(signBytes, existingSignature.SignBytes) {
return existingSignature.Signature, block.Timestamp, nil
}
@@ -544,7 +561,7 @@ func (pv *ThresholdValidator) compareBlockSignatureAgainstSSC(
func (pv *ThresholdValidator) compareBlockSignatureAgainstHRS(
chainID string,
block *Block,
- hrs HRSKey,
+ hrs types.HRSKey,
) error {
blockHRS := block.HRSKey()
@@ -559,6 +576,7 @@ func (pv *ThresholdValidator) compareBlockSignatureAgainstHRS(
return newStillWaitingForBlockError(chainID, blockHRS)
}
+// SignBlock is the arranger of the whole signature/signing process.
func (pv *ThresholdValidator) SignBlock(chainID string, block *Block) ([]byte, time.Time, error) {
height, round, step, stamp, signBytes := block.Height, block.Round, block.Step, block.Timestamp, block.SignBytes
@@ -577,8 +595,9 @@ func (pv *ThresholdValidator) SignBlock(chainID string, block *Block) ([]byte, t
"round", round,
"step", step,
)
- totalNotRaftLeader.Inc()
- signRes, err := pv.leader.SignBlock(CosignerSignBlockRequest{
+ metrics.TotalNotRaftLeader.Inc()
+ // Ask the (RAFT) leader to manage the signing of the block
+ signRes, err := pv.leader.SignBlock(ValidatorSignBlockRequest{
ChainID: chainID,
Block: block,
})
@@ -595,7 +614,7 @@ func (pv *ThresholdValidator) SignBlock(chainID string, block *Block) ([]byte, t
return signRes.Signature, stamp, nil
}
- totalRaftLeader.Inc()
+ metrics.TotalRaftLeader.Inc()
pv.logger.Debug(
"I am the raft leader. Managing the sign process for this block",
"chain_id", chainID,
@@ -604,7 +623,7 @@ func (pv *ThresholdValidator) SignBlock(chainID string, block *Block) ([]byte, t
"step", step,
)
- hrst := HRSTKey{
+ hrst := types.HRSTKey{
Height: height,
Round: round,
Step: step,
@@ -625,18 +644,23 @@ func (pv *ThresholdValidator) SignBlock(chainID string, block *Block) ([]byte, t
total := uint8(numPeers + 1)
getEphemeralWaitGroup := sync.WaitGroup{}
- // Only wait until we have threshold sigs
+ // Only wait until we have enough threshold signatures
getEphemeralWaitGroup.Add(pv.threshold - 1)
// Used to track how close we are to threshold
- nonces := make(map[Cosigner][]CosignerNonce)
+ // Here the actual signing process starts from a cryptological perspective
+ nonces := make(map[ICosigner][]cosigner.WrappedNonce)
thresholdPeersMutex := sync.Mutex{}
+ // From each cosigner peer we are requesting the nonce.
+ // This is done asynchronously.
+ // pv.waitForPeersNonces uses GRPC to get the nonce from the peer.
for _, c := range pv.peerCosigners {
go pv.waitForPeerNonces(chainID, c, hrst, &getEphemeralWaitGroup,
nonces, &thresholdPeersMutex)
}
+ // Requesting a nonce from our own cosigner (a.k.a. the local cosigner)
myNonces, err := pv.myCosigner.GetNonces(chainID, hrst)
if err != nil {
pv.notifyBlockSignError(chainID, block.HRSKey())
@@ -644,7 +668,7 @@ func (pv *ThresholdValidator) SignBlock(chainID string, block *Block) ([]byte, t
return nil, stamp, err
}
- // Wait for threshold cosigners to be complete
+ // Wait for cosigners to be complete
// A Cosigner will either respond in time, or be cancelled with timeout
if waitUntilCompleteOrTimeout(&getEphemeralWaitGroup, pv.grpcTimeout) {
pv.notifyBlockSignError(chainID, block.HRSKey())
@@ -655,7 +679,7 @@ func (pv *ThresholdValidator) SignBlock(chainID string, block *Block) ([]byte, t
nonces[pv.myCosigner] = myNonces.Nonces
thresholdPeersMutex.Unlock()
- timedSignBlockThresholdLag.Observe(time.Since(timeStartSignBlock).Seconds())
+ metrics.TimedSignBlockThresholdLag.Observe(time.Since(timeStartSignBlock).Seconds())
pv.logger.Debug(
"Have threshold peers",
"chain_id", chainID,
@@ -688,7 +712,7 @@ func (pv *ThresholdValidator) SignBlock(chainID string, block *Block) ([]byte, t
return nil, stamp, errors.New("timed out waiting for peers to sign")
}
- timedSignBlockCosignerLag.Observe(time.Since(timeStartSignBlock).Seconds())
+ metrics.TimedSignBlockCosignerLag.Observe(time.Since(timeStartSignBlock).Seconds())
pv.logger.Debug(
"Done waiting for cosigners, assembling signatures",
"chain_id", chainID,
@@ -698,7 +722,7 @@ func (pv *ThresholdValidator) SignBlock(chainID string, block *Block) ([]byte, t
)
// collect all valid responses into array of partial signatures
- shareSigs := make([]PartialSignature, 0, pv.threshold)
+ shareSigs := make([]cosigner.PartialSignature, 0, pv.threshold)
for idx, shareSig := range shareSignatures {
if len(shareSig) == 0 {
continue
@@ -706,19 +730,19 @@ func (pv *ThresholdValidator) SignBlock(chainID string, block *Block) ([]byte, t
// we are ok to use the share signatures - complete boolean
// prevents future concurrent access
- shareSigs = append(shareSigs, PartialSignature{
+ shareSigs = append(shareSigs, cosigner.PartialSignature{
ID: idx + 1,
Signature: shareSig,
})
}
if len(shareSigs) < pv.threshold {
- totalInsufficientCosigners.Inc()
+ metrics.TotalInsufficientCosigners.Inc()
pv.notifyBlockSignError(chainID, block.HRSKey())
return nil, stamp, errors.New("not enough co-signers")
}
- // assemble into final signature
+ // assemble the partial signatures into a valid signature
signature, err := pv.myCosigner.CombineSignatures(chainID, shareSigs)
if err != nil {
pv.notifyBlockSignError(chainID, block.HRSKey())
@@ -735,14 +759,14 @@ func (pv *ThresholdValidator) SignBlock(chainID string, block *Block) ([]byte, t
// verify the combined signature before saving to watermark
if !pv.myCosigner.VerifySignature(chainID, signBytes, signature) {
- totalInvalidSignature.Inc()
+ metrics.TotalInvalidSignature.Inc()
pv.notifyBlockSignError(chainID, block.HRSKey())
return nil, stamp, errors.New("combined signature is not valid")
}
- newLss := ChainSignStateConsensus{
+ newLss := types.ChainSignStateConsensus{
ChainID: chainID,
- SignStateConsensus: SignStateConsensus{
+ SignStateConsensus: types.SignStateConsensus{
Height: height,
Round: round,
Step: step,
@@ -758,7 +782,7 @@ func (pv *ThresholdValidator) SignBlock(chainID string, block *Block) ([]byte, t
err = css.lastSignState.Save(newLss.SignStateConsensus, &pv.pendingDiskWG)
css.lastSignStateMutex.Unlock()
if err != nil {
- if _, isSameHRSError := err.(*SameHRSError); !isSameHRSError {
+ if _, isSameHRSError := err.(*types.SameHRSError); !isSameHRSError {
pv.notifyBlockSignError(chainID, block.HRSKey())
return nil, stamp, err
}
@@ -771,7 +795,7 @@ func (pv *ThresholdValidator) SignBlock(chainID string, block *Block) ([]byte, t
}
timeSignBlock := time.Since(timeStartSignBlock).Seconds()
- timedSignBlockLag.Observe(timeSignBlock)
+ metrics.TimedSignBlockLag.Observe(timeSignBlock)
return signature, stamp, nil
}
diff --git a/signer/threshold_validator_test.go b/pkg/node/threshold_validator_test.go
similarity index 84%
rename from signer/threshold_validator_test.go
rename to pkg/node/threshold_validator_test.go
index 92718bab..a49fb285 100644
--- a/signer/threshold_validator_test.go
+++ b/pkg/node/threshold_validator_test.go
@@ -1,14 +1,16 @@
-package signer
+package node
import (
"bytes"
"crypto/rand"
"fmt"
- mrand "math/rand"
+ "math/big"
"path/filepath"
"sync"
"time"
+ "github.com/strangelove-ventures/horcrux/pkg/cosigner"
+
"os"
"testing"
@@ -26,6 +28,12 @@ import (
"golang.org/x/sync/errgroup"
)
+const (
+ testChainID = "chain-1"
+ testChainID2 = "chain-2"
+ bitSize = 4096
+)
+
func TestThresholdValidator2of2(t *testing.T) {
testThresholdValidator(t, 2, 2)
}
@@ -43,15 +51,15 @@ func TestThresholdValidator3of5(t *testing.T) {
}
func loadKeyForLocalCosigner(
- cosigner *LocalCosigner,
+ localcosigner *cosigner.LocalCosigner,
pubKey cometcrypto.PubKey,
chainID string,
privateShard []byte,
) error {
- key := CosignerEd25519Key{
+ key := cosigner.CosignEd25519Key{
PubKey: pubKey,
PrivateShard: privateShard,
- ID: cosigner.GetID(),
+ ID: localcosigner.GetID(),
}
keyBz, err := key.MarshalJSON()
@@ -59,13 +67,13 @@ func loadKeyForLocalCosigner(
return err
}
- return os.WriteFile(cosigner.config.KeyFilePathCosigner(chainID), keyBz, 0600)
+ return os.WriteFile(localcosigner.Config.KeyFilePathCosigner(chainID), keyBz, 0600)
}
func testThresholdValidator(t *testing.T, threshold, total uint8) {
cosigners, pubKey := getTestLocalCosigners(t, threshold, total)
- thresholdCosigners := make([]Cosigner, 0, threshold-1)
+ thresholdCosigners := make([]ICosigner, 0, threshold-1)
for i, cosigner := range cosigners {
require.Equal(t, i+1, cosigner.GetID())
@@ -79,7 +87,7 @@ func testThresholdValidator(t *testing.T, threshold, total uint8) {
validator := NewThresholdValidator(
cometlog.NewTMLogger(cometlog.NewSyncWriter(os.Stdout)).With("module", "validator"),
- cosigners[0].config,
+ cosigners[0].Config,
int(threshold),
time.Second,
1,
@@ -158,7 +166,7 @@ func testThresholdValidator(t *testing.T, threshold, total uint8) {
// reinitialize validator to make sure new runtime will not allow double sign
newValidator := NewThresholdValidator(
cometlog.NewTMLogger(cometlog.NewSyncWriter(os.Stdout)).With("module", "validator"),
- cosigners[0].config,
+ cosigners[0].Config,
int(threshold),
time.Second,
1,
@@ -255,10 +263,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) ([]*cosigner.LocalCosigner, cometcrypto.PubKey) {
eciesKeys := make([]*ecies.PrivateKey, total)
pubKeys := make([]*ecies.PublicKey, total)
- cosigners := make([]*LocalCosigner, total)
+ cosigners := make([]*cosigner.LocalCosigner, total)
for i := uint8(0); i < total; i++ {
eciesKey, err := ecies.GenerateKey(rand.Reader, secp256k1.S256(), nil)
@@ -271,14 +279,15 @@ func getTestLocalCosigners(t *testing.T, threshold, total uint8) ([]*LocalCosign
privateKey := cometcryptoed25519.GenPrivKey()
privKeyBytes := privateKey[:]
+ // DealShares splits the secret by using Shamir Secret Sharing (Note its not verifiable secret sharing)
privShards := tsed25519.DealShares(tsed25519.ExpandSecret(privKeyBytes[:32]), threshold, total)
tmpDir := t.TempDir()
- cosignersConfig := make(CosignersConfig, total)
+ cosignersConfig := make(cosigner.CosignersConfig, total)
for i := range pubKeys {
- cosignersConfig[i] = CosignerConfig{
+ cosignersConfig[i] = cosigner.CosignConfig{
ShardID: i + 1,
}
}
@@ -288,22 +297,22 @@ func getTestLocalCosigners(t *testing.T, threshold, total uint8) ([]*LocalCosign
err := os.MkdirAll(cosignerDir, 0777)
require.NoError(t, err)
- cosignerConfig := &RuntimeConfig{
+ cosignerConfig := &cosigner.RuntimeConfig{
HomeDir: cosignerDir,
StateDir: cosignerDir,
- Config: Config{
- ThresholdModeConfig: &ThresholdModeConfig{
+ Config: cosigner.Config{
+ ThresholdModeConfig: &cosigner.ThresholdModeConfig{
Threshold: int(threshold),
Cosigners: cosignersConfig,
},
},
}
- cosigner := NewLocalCosigner(
+ cosign := cosigner.NewLocalCosigner(
cometlog.NewNopLogger(),
cosignerConfig,
- NewCosignerSecurityECIES(
- CosignerECIESKey{
+ cosigner.NewCosignerSecurityECIES(
+ cosigner.CosignEciesKey{
ID: i + 1,
ECIESKey: eciesKeys[i],
ECIESPubs: pubKeys,
@@ -313,12 +322,12 @@ func getTestLocalCosigners(t *testing.T, threshold, total uint8) ([]*LocalCosign
)
require.NoError(t, err)
- cosigners[i] = cosigner
+ cosigners[i] = cosign
- err = loadKeyForLocalCosigner(cosigner, privateKey.PubKey(), testChainID, privShards[i])
+ err = loadKeyForLocalCosigner(cosign, privateKey.PubKey(), testChainID, privShards[i])
require.NoError(t, err)
- err = loadKeyForLocalCosigner(cosigner, privateKey.PubKey(), testChainID2, privShards[i])
+ err = loadKeyForLocalCosigner(cosign, privateKey.PubKey(), testChainID2, privShards[i])
require.NoError(t, err)
}
@@ -332,7 +341,7 @@ func testThresholdValidatorLeaderElection(t *testing.T, threshold, total uint8)
var leader *ThresholdValidator
leaders := make([]*MockLeader, total)
for i, cosigner := range cosigners {
- peers := make([]Cosigner, 0, len(cosigners)-1)
+ peers := make([]ICosigner, 0, len(cosigners)-1)
for j, otherCosigner := range cosigners {
if i != j {
peers = append(peers, otherCosigner)
@@ -341,7 +350,7 @@ func testThresholdValidatorLeaderElection(t *testing.T, threshold, total uint8)
leaders[i] = &MockLeader{id: cosigner.GetID(), leader: leader}
tv := NewThresholdValidator(
cometlog.NewTMLogger(cometlog.NewSyncWriter(os.Stdout)).With("module", "validator"),
- cosigner.config,
+ cosigner.Config,
int(threshold),
time.Second,
1,
@@ -368,8 +377,10 @@ func testThresholdValidatorLeaderElection(t *testing.T, threshold, total uint8)
}
t.Log("No leader")
+ rnd, err := rand.Int(rand.Reader, big.NewInt(50))
+ require.NoError(t, err)
// time without a leader
- time.Sleep(time.Duration(mrand.Intn(50)+100) * time.Millisecond) //nolint:gosec
+ time.Sleep(time.Duration(int(rnd.Int64())+100) * time.Millisecond)
newLeader := thresholdValidators[i%len(thresholdValidators)]
for _, l := range leaders {
@@ -378,7 +389,9 @@ func testThresholdValidatorLeaderElection(t *testing.T, threshold, total uint8)
t.Logf("New leader: %d", newLeader.myCosigner.GetID())
// time with new leader
- time.Sleep(time.Duration(mrand.Intn(50)+100) * time.Millisecond) //nolint:gosec
+ rnd, err = rand.Int(rand.Reader, big.NewInt(50))
+ require.NoError(t, err)
+ time.Sleep(time.Duration(int(rnd.Int64())+100) * time.Millisecond)
}
}()
@@ -394,7 +407,10 @@ func testThresholdValidatorLeaderElection(t *testing.T, threshold, total uint8)
go func() {
defer wg.Done()
// stagger signing requests with random sleep
- time.Sleep(time.Duration(mrand.Intn(50)+100) * time.Millisecond) //nolint:gosec
+ rnd, err := rand.Int(rand.Reader, big.NewInt(50))
+ require.NoError(t, err)
+ // ime without a leader
+ time.Sleep(time.Duration(int(rnd.Int64())+100) * time.Millisecond)
proposal := cometproto.Proposal{
Height: 1 + int64(i),
@@ -430,7 +446,10 @@ func testThresholdValidatorLeaderElection(t *testing.T, threshold, total uint8)
go func() {
defer wg.Done()
// stagger signing requests with random sleep
- time.Sleep(time.Duration(mrand.Intn(50)+100) * time.Millisecond) //nolint:gosec
+ rnd, err := rand.Int(rand.Reader, big.NewInt(50))
+ require.NoError(t, err)
+ // time without a leader
+ time.Sleep(time.Duration(int(rnd.Int64())+100) * time.Millisecond)
preVote := cometproto.Vote{
Height: 1 + int64(i),
@@ -466,7 +485,10 @@ func testThresholdValidatorLeaderElection(t *testing.T, threshold, total uint8)
go func() {
defer wg.Done()
// stagger signing requests with random sleep
- time.Sleep(time.Duration(mrand.Intn(50)+100) * time.Millisecond) //nolint:gosec
+ rnd, err := rand.Int(rand.Reader, big.NewInt(50))
+ require.NoError(t, err)
+ // time without a leader
+ time.Sleep(time.Duration(int(rnd.Int64())+100) * time.Millisecond)
preCommit := cometproto.Vote{
Height: 1 + int64(i),
diff --git a/signer/proto/cosigner_grpc_server.pb.go b/pkg/proto/cosigner_grpc_server.pb.go
similarity index 58%
rename from signer/proto/cosigner_grpc_server.pb.go
rename to pkg/proto/cosigner_grpc_server.pb.go
index 6dd3f203..7a517121 100644
--- a/signer/proto/cosigner_grpc_server.pb.go
+++ b/pkg/proto/cosigner_grpc_server.pb.go
@@ -1,8 +1,8 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.28.1
-// protoc v3.21.6
-// source: signer/proto/cosigner_grpc_server.proto
+// protoc v3.13.0
+// source: cosigner_grpc_server.proto
package proto
@@ -35,7 +35,7 @@ type Block struct {
func (x *Block) Reset() {
*x = Block{}
if protoimpl.UnsafeEnabled {
- mi := &file_signer_proto_cosigner_grpc_server_proto_msgTypes[0]
+ mi := &file_cosigner_grpc_server_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -48,7 +48,7 @@ func (x *Block) String() string {
func (*Block) ProtoMessage() {}
func (x *Block) ProtoReflect() protoreflect.Message {
- mi := &file_signer_proto_cosigner_grpc_server_proto_msgTypes[0]
+ mi := &file_cosigner_grpc_server_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -61,7 +61,7 @@ func (x *Block) ProtoReflect() protoreflect.Message {
// Deprecated: Use Block.ProtoReflect.Descriptor instead.
func (*Block) Descriptor() ([]byte, []int) {
- return file_signer_proto_cosigner_grpc_server_proto_rawDescGZIP(), []int{0}
+ return file_cosigner_grpc_server_proto_rawDescGZIP(), []int{0}
}
func (x *Block) GetHeight() int64 {
@@ -111,7 +111,7 @@ type CosignerGRPCSignBlockRequest struct {
func (x *CosignerGRPCSignBlockRequest) Reset() {
*x = CosignerGRPCSignBlockRequest{}
if protoimpl.UnsafeEnabled {
- mi := &file_signer_proto_cosigner_grpc_server_proto_msgTypes[1]
+ mi := &file_cosigner_grpc_server_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -124,7 +124,7 @@ func (x *CosignerGRPCSignBlockRequest) String() string {
func (*CosignerGRPCSignBlockRequest) ProtoMessage() {}
func (x *CosignerGRPCSignBlockRequest) ProtoReflect() protoreflect.Message {
- mi := &file_signer_proto_cosigner_grpc_server_proto_msgTypes[1]
+ mi := &file_cosigner_grpc_server_proto_msgTypes[1]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -137,7 +137,7 @@ func (x *CosignerGRPCSignBlockRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use CosignerGRPCSignBlockRequest.ProtoReflect.Descriptor instead.
func (*CosignerGRPCSignBlockRequest) Descriptor() ([]byte, []int) {
- return file_signer_proto_cosigner_grpc_server_proto_rawDescGZIP(), []int{1}
+ return file_cosigner_grpc_server_proto_rawDescGZIP(), []int{1}
}
func (x *CosignerGRPCSignBlockRequest) GetChainID() string {
@@ -165,7 +165,7 @@ type CosignerGRPCSignBlockResponse struct {
func (x *CosignerGRPCSignBlockResponse) Reset() {
*x = CosignerGRPCSignBlockResponse{}
if protoimpl.UnsafeEnabled {
- mi := &file_signer_proto_cosigner_grpc_server_proto_msgTypes[2]
+ mi := &file_cosigner_grpc_server_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -178,7 +178,7 @@ func (x *CosignerGRPCSignBlockResponse) String() string {
func (*CosignerGRPCSignBlockResponse) ProtoMessage() {}
func (x *CosignerGRPCSignBlockResponse) ProtoReflect() protoreflect.Message {
- mi := &file_signer_proto_cosigner_grpc_server_proto_msgTypes[2]
+ mi := &file_cosigner_grpc_server_proto_msgTypes[2]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -191,7 +191,7 @@ func (x *CosignerGRPCSignBlockResponse) ProtoReflect() protoreflect.Message {
// Deprecated: Use CosignerGRPCSignBlockResponse.ProtoReflect.Descriptor instead.
func (*CosignerGRPCSignBlockResponse) Descriptor() ([]byte, []int) {
- return file_signer_proto_cosigner_grpc_server_proto_rawDescGZIP(), []int{2}
+ return file_cosigner_grpc_server_proto_rawDescGZIP(), []int{2}
}
func (x *CosignerGRPCSignBlockResponse) GetSignature() []byte {
@@ -216,7 +216,7 @@ type Nonce struct {
func (x *Nonce) Reset() {
*x = Nonce{}
if protoimpl.UnsafeEnabled {
- mi := &file_signer_proto_cosigner_grpc_server_proto_msgTypes[3]
+ mi := &file_cosigner_grpc_server_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -229,7 +229,7 @@ func (x *Nonce) String() string {
func (*Nonce) ProtoMessage() {}
func (x *Nonce) ProtoReflect() protoreflect.Message {
- mi := &file_signer_proto_cosigner_grpc_server_proto_msgTypes[3]
+ mi := &file_cosigner_grpc_server_proto_msgTypes[3]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -242,7 +242,7 @@ func (x *Nonce) ProtoReflect() protoreflect.Message {
// Deprecated: Use Nonce.ProtoReflect.Descriptor instead.
func (*Nonce) Descriptor() ([]byte, []int) {
- return file_signer_proto_cosigner_grpc_server_proto_rawDescGZIP(), []int{3}
+ return file_cosigner_grpc_server_proto_rawDescGZIP(), []int{3}
}
func (x *Nonce) GetSourceID() int32 {
@@ -294,7 +294,7 @@ type HRST struct {
func (x *HRST) Reset() {
*x = HRST{}
if protoimpl.UnsafeEnabled {
- mi := &file_signer_proto_cosigner_grpc_server_proto_msgTypes[4]
+ mi := &file_cosigner_grpc_server_proto_msgTypes[4]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -307,7 +307,7 @@ func (x *HRST) String() string {
func (*HRST) ProtoMessage() {}
func (x *HRST) ProtoReflect() protoreflect.Message {
- mi := &file_signer_proto_cosigner_grpc_server_proto_msgTypes[4]
+ mi := &file_cosigner_grpc_server_proto_msgTypes[4]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -320,7 +320,7 @@ func (x *HRST) ProtoReflect() protoreflect.Message {
// Deprecated: Use HRST.ProtoReflect.Descriptor instead.
func (*HRST) Descriptor() ([]byte, []int) {
- return file_signer_proto_cosigner_grpc_server_proto_rawDescGZIP(), []int{4}
+ return file_cosigner_grpc_server_proto_rawDescGZIP(), []int{4}
}
func (x *HRST) GetHeight() int64 {
@@ -365,7 +365,7 @@ type CosignerGRPCSetNoncesAndSignRequest struct {
func (x *CosignerGRPCSetNoncesAndSignRequest) Reset() {
*x = CosignerGRPCSetNoncesAndSignRequest{}
if protoimpl.UnsafeEnabled {
- mi := &file_signer_proto_cosigner_grpc_server_proto_msgTypes[5]
+ mi := &file_cosigner_grpc_server_proto_msgTypes[5]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -378,7 +378,7 @@ func (x *CosignerGRPCSetNoncesAndSignRequest) String() string {
func (*CosignerGRPCSetNoncesAndSignRequest) ProtoMessage() {}
func (x *CosignerGRPCSetNoncesAndSignRequest) ProtoReflect() protoreflect.Message {
- mi := &file_signer_proto_cosigner_grpc_server_proto_msgTypes[5]
+ mi := &file_cosigner_grpc_server_proto_msgTypes[5]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -391,7 +391,7 @@ func (x *CosignerGRPCSetNoncesAndSignRequest) ProtoReflect() protoreflect.Messag
// Deprecated: Use CosignerGRPCSetNoncesAndSignRequest.ProtoReflect.Descriptor instead.
func (*CosignerGRPCSetNoncesAndSignRequest) Descriptor() ([]byte, []int) {
- return file_signer_proto_cosigner_grpc_server_proto_rawDescGZIP(), []int{5}
+ return file_cosigner_grpc_server_proto_rawDescGZIP(), []int{5}
}
func (x *CosignerGRPCSetNoncesAndSignRequest) GetNonces() []*Nonce {
@@ -435,7 +435,7 @@ type CosignerGRPCSetNoncesAndSignResponse struct {
func (x *CosignerGRPCSetNoncesAndSignResponse) Reset() {
*x = CosignerGRPCSetNoncesAndSignResponse{}
if protoimpl.UnsafeEnabled {
- mi := &file_signer_proto_cosigner_grpc_server_proto_msgTypes[6]
+ mi := &file_cosigner_grpc_server_proto_msgTypes[6]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -448,7 +448,7 @@ func (x *CosignerGRPCSetNoncesAndSignResponse) String() string {
func (*CosignerGRPCSetNoncesAndSignResponse) ProtoMessage() {}
func (x *CosignerGRPCSetNoncesAndSignResponse) ProtoReflect() protoreflect.Message {
- mi := &file_signer_proto_cosigner_grpc_server_proto_msgTypes[6]
+ mi := &file_cosigner_grpc_server_proto_msgTypes[6]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -461,7 +461,7 @@ func (x *CosignerGRPCSetNoncesAndSignResponse) ProtoReflect() protoreflect.Messa
// Deprecated: Use CosignerGRPCSetNoncesAndSignResponse.ProtoReflect.Descriptor instead.
func (*CosignerGRPCSetNoncesAndSignResponse) Descriptor() ([]byte, []int) {
- return file_signer_proto_cosigner_grpc_server_proto_rawDescGZIP(), []int{6}
+ return file_cosigner_grpc_server_proto_rawDescGZIP(), []int{6}
}
func (x *CosignerGRPCSetNoncesAndSignResponse) GetNoncePublic() []byte {
@@ -497,7 +497,7 @@ type CosignerGRPCGetNoncesRequest struct {
func (x *CosignerGRPCGetNoncesRequest) Reset() {
*x = CosignerGRPCGetNoncesRequest{}
if protoimpl.UnsafeEnabled {
- mi := &file_signer_proto_cosigner_grpc_server_proto_msgTypes[7]
+ mi := &file_cosigner_grpc_server_proto_msgTypes[7]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -510,7 +510,7 @@ func (x *CosignerGRPCGetNoncesRequest) String() string {
func (*CosignerGRPCGetNoncesRequest) ProtoMessage() {}
func (x *CosignerGRPCGetNoncesRequest) ProtoReflect() protoreflect.Message {
- mi := &file_signer_proto_cosigner_grpc_server_proto_msgTypes[7]
+ mi := &file_cosigner_grpc_server_proto_msgTypes[7]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -523,7 +523,7 @@ func (x *CosignerGRPCGetNoncesRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use CosignerGRPCGetNoncesRequest.ProtoReflect.Descriptor instead.
func (*CosignerGRPCGetNoncesRequest) Descriptor() ([]byte, []int) {
- return file_signer_proto_cosigner_grpc_server_proto_rawDescGZIP(), []int{7}
+ return file_cosigner_grpc_server_proto_rawDescGZIP(), []int{7}
}
func (x *CosignerGRPCGetNoncesRequest) GetHrst() *HRST {
@@ -551,7 +551,7 @@ type CosignerGRPCGetNoncesResponse struct {
func (x *CosignerGRPCGetNoncesResponse) Reset() {
*x = CosignerGRPCGetNoncesResponse{}
if protoimpl.UnsafeEnabled {
- mi := &file_signer_proto_cosigner_grpc_server_proto_msgTypes[8]
+ mi := &file_cosigner_grpc_server_proto_msgTypes[8]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -564,7 +564,7 @@ func (x *CosignerGRPCGetNoncesResponse) String() string {
func (*CosignerGRPCGetNoncesResponse) ProtoMessage() {}
func (x *CosignerGRPCGetNoncesResponse) ProtoReflect() protoreflect.Message {
- mi := &file_signer_proto_cosigner_grpc_server_proto_msgTypes[8]
+ mi := &file_cosigner_grpc_server_proto_msgTypes[8]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -577,7 +577,7 @@ func (x *CosignerGRPCGetNoncesResponse) ProtoReflect() protoreflect.Message {
// Deprecated: Use CosignerGRPCGetNoncesResponse.ProtoReflect.Descriptor instead.
func (*CosignerGRPCGetNoncesResponse) Descriptor() ([]byte, []int) {
- return file_signer_proto_cosigner_grpc_server_proto_rawDescGZIP(), []int{8}
+ return file_cosigner_grpc_server_proto_rawDescGZIP(), []int{8}
}
func (x *CosignerGRPCGetNoncesResponse) GetNonces() []*Nonce {
@@ -598,7 +598,7 @@ type CosignerGRPCTransferLeadershipRequest struct {
func (x *CosignerGRPCTransferLeadershipRequest) Reset() {
*x = CosignerGRPCTransferLeadershipRequest{}
if protoimpl.UnsafeEnabled {
- mi := &file_signer_proto_cosigner_grpc_server_proto_msgTypes[9]
+ mi := &file_cosigner_grpc_server_proto_msgTypes[9]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -611,7 +611,7 @@ func (x *CosignerGRPCTransferLeadershipRequest) String() string {
func (*CosignerGRPCTransferLeadershipRequest) ProtoMessage() {}
func (x *CosignerGRPCTransferLeadershipRequest) ProtoReflect() protoreflect.Message {
- mi := &file_signer_proto_cosigner_grpc_server_proto_msgTypes[9]
+ mi := &file_cosigner_grpc_server_proto_msgTypes[9]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -624,7 +624,7 @@ func (x *CosignerGRPCTransferLeadershipRequest) ProtoReflect() protoreflect.Mess
// Deprecated: Use CosignerGRPCTransferLeadershipRequest.ProtoReflect.Descriptor instead.
func (*CosignerGRPCTransferLeadershipRequest) Descriptor() ([]byte, []int) {
- return file_signer_proto_cosigner_grpc_server_proto_rawDescGZIP(), []int{9}
+ return file_cosigner_grpc_server_proto_rawDescGZIP(), []int{9}
}
func (x *CosignerGRPCTransferLeadershipRequest) GetLeaderID() string {
@@ -646,7 +646,7 @@ type CosignerGRPCTransferLeadershipResponse struct {
func (x *CosignerGRPCTransferLeadershipResponse) Reset() {
*x = CosignerGRPCTransferLeadershipResponse{}
if protoimpl.UnsafeEnabled {
- mi := &file_signer_proto_cosigner_grpc_server_proto_msgTypes[10]
+ mi := &file_cosigner_grpc_server_proto_msgTypes[10]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -659,7 +659,7 @@ func (x *CosignerGRPCTransferLeadershipResponse) String() string {
func (*CosignerGRPCTransferLeadershipResponse) ProtoMessage() {}
func (x *CosignerGRPCTransferLeadershipResponse) ProtoReflect() protoreflect.Message {
- mi := &file_signer_proto_cosigner_grpc_server_proto_msgTypes[10]
+ mi := &file_cosigner_grpc_server_proto_msgTypes[10]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -672,7 +672,7 @@ func (x *CosignerGRPCTransferLeadershipResponse) ProtoReflect() protoreflect.Mes
// Deprecated: Use CosignerGRPCTransferLeadershipResponse.ProtoReflect.Descriptor instead.
func (*CosignerGRPCTransferLeadershipResponse) Descriptor() ([]byte, []int) {
- return file_signer_proto_cosigner_grpc_server_proto_rawDescGZIP(), []int{10}
+ return file_cosigner_grpc_server_proto_rawDescGZIP(), []int{10}
}
func (x *CosignerGRPCTransferLeadershipResponse) GetLeaderID() string {
@@ -698,7 +698,7 @@ type CosignerGRPCGetLeaderRequest struct {
func (x *CosignerGRPCGetLeaderRequest) Reset() {
*x = CosignerGRPCGetLeaderRequest{}
if protoimpl.UnsafeEnabled {
- mi := &file_signer_proto_cosigner_grpc_server_proto_msgTypes[11]
+ mi := &file_cosigner_grpc_server_proto_msgTypes[11]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -711,7 +711,7 @@ func (x *CosignerGRPCGetLeaderRequest) String() string {
func (*CosignerGRPCGetLeaderRequest) ProtoMessage() {}
func (x *CosignerGRPCGetLeaderRequest) ProtoReflect() protoreflect.Message {
- mi := &file_signer_proto_cosigner_grpc_server_proto_msgTypes[11]
+ mi := &file_cosigner_grpc_server_proto_msgTypes[11]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -724,7 +724,7 @@ func (x *CosignerGRPCGetLeaderRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use CosignerGRPCGetLeaderRequest.ProtoReflect.Descriptor instead.
func (*CosignerGRPCGetLeaderRequest) Descriptor() ([]byte, []int) {
- return file_signer_proto_cosigner_grpc_server_proto_rawDescGZIP(), []int{11}
+ return file_cosigner_grpc_server_proto_rawDescGZIP(), []int{11}
}
type CosignerGRPCGetLeaderResponse struct {
@@ -738,7 +738,7 @@ type CosignerGRPCGetLeaderResponse struct {
func (x *CosignerGRPCGetLeaderResponse) Reset() {
*x = CosignerGRPCGetLeaderResponse{}
if protoimpl.UnsafeEnabled {
- mi := &file_signer_proto_cosigner_grpc_server_proto_msgTypes[12]
+ mi := &file_cosigner_grpc_server_proto_msgTypes[12]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -751,7 +751,7 @@ func (x *CosignerGRPCGetLeaderResponse) String() string {
func (*CosignerGRPCGetLeaderResponse) ProtoMessage() {}
func (x *CosignerGRPCGetLeaderResponse) ProtoReflect() protoreflect.Message {
- mi := &file_signer_proto_cosigner_grpc_server_proto_msgTypes[12]
+ mi := &file_cosigner_grpc_server_proto_msgTypes[12]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -764,7 +764,7 @@ func (x *CosignerGRPCGetLeaderResponse) ProtoReflect() protoreflect.Message {
// Deprecated: Use CosignerGRPCGetLeaderResponse.ProtoReflect.Descriptor instead.
func (*CosignerGRPCGetLeaderResponse) Descriptor() ([]byte, []int) {
- return file_signer_proto_cosigner_grpc_server_proto_rawDescGZIP(), []int{12}
+ return file_cosigner_grpc_server_proto_rawDescGZIP(), []int{12}
}
func (x *CosignerGRPCGetLeaderResponse) GetLeader() string {
@@ -774,145 +774,144 @@ func (x *CosignerGRPCGetLeaderResponse) GetLeader() string {
return ""
}
-var File_signer_proto_cosigner_grpc_server_proto protoreflect.FileDescriptor
-
-var file_signer_proto_cosigner_grpc_server_proto_rawDesc = []byte{
- 0x0a, 0x27, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x63,
- 0x6f, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x5f, 0x67, 0x72, 0x70, 0x63, 0x5f, 0x73, 0x65, 0x72,
- 0x76, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x05, 0x70, 0x72, 0x6f, 0x74, 0x6f,
- 0x22, 0x85, 0x01, 0x0a, 0x05, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x16, 0x0a, 0x06, 0x68, 0x65,
- 0x69, 0x67, 0x68, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x68, 0x65, 0x69, 0x67,
- 0x68, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28,
- 0x03, 0x52, 0x05, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x74, 0x65, 0x70,
- 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x73, 0x74, 0x65, 0x70, 0x12, 0x1c, 0x0a, 0x09,
- 0x73, 0x69, 0x67, 0x6e, 0x42, 0x79, 0x74, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52,
- 0x09, 0x73, 0x69, 0x67, 0x6e, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69,
- 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74,
- 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0x5c, 0x0a, 0x1c, 0x43, 0x6f, 0x73, 0x69,
- 0x67, 0x6e, 0x65, 0x72, 0x47, 0x52, 0x50, 0x43, 0x53, 0x69, 0x67, 0x6e, 0x42, 0x6c, 0x6f, 0x63,
- 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x68, 0x61, 0x69,
- 0x6e, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e,
- 0x49, 0x44, 0x12, 0x22, 0x0a, 0x05, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28,
- 0x0b, 0x32, 0x0c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52,
- 0x05, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x22, 0x3d, 0x0a, 0x1d, 0x43, 0x6f, 0x73, 0x69, 0x67, 0x6e,
+var File_cosigner_grpc_server_proto protoreflect.FileDescriptor
+
+var file_cosigner_grpc_server_proto_rawDesc = []byte{
+ 0x0a, 0x1a, 0x63, 0x6f, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x5f, 0x67, 0x72, 0x70, 0x63, 0x5f,
+ 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x05, 0x70, 0x72,
+ 0x6f, 0x74, 0x6f, 0x22, 0x85, 0x01, 0x0a, 0x05, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x16, 0x0a,
+ 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x68,
+ 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x18, 0x02,
+ 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x73,
+ 0x74, 0x65, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x73, 0x74, 0x65, 0x70, 0x12,
+ 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x42, 0x79, 0x74, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01,
+ 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x1c, 0x0a,
+ 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03,
+ 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0x5c, 0x0a, 0x1c, 0x43,
+ 0x6f, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x47, 0x52, 0x50, 0x43, 0x53, 0x69, 0x67, 0x6e, 0x42,
+ 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x63,
+ 0x68, 0x61, 0x69, 0x6e, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x68,
+ 0x61, 0x69, 0x6e, 0x49, 0x44, 0x12, 0x22, 0x0a, 0x05, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x18, 0x02,
+ 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x42, 0x6c, 0x6f,
+ 0x63, 0x6b, 0x52, 0x05, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x22, 0x3d, 0x0a, 0x1d, 0x43, 0x6f, 0x73,
+ 0x69, 0x67, 0x6e, 0x65, 0x72, 0x47, 0x52, 0x50, 0x43, 0x53, 0x69, 0x67, 0x6e, 0x42, 0x6c, 0x6f,
+ 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69,
+ 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73,
+ 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0x95, 0x01, 0x0a, 0x05, 0x4e, 0x6f, 0x6e,
+ 0x63, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x44, 0x18, 0x01,
+ 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x44, 0x12, 0x24,
+ 0x0a, 0x0d, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x44, 0x18,
+ 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69,
+ 0x6f, 0x6e, 0x49, 0x44, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x75, 0x62, 0x4b, 0x65, 0x79, 0x18, 0x03,
+ 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x70, 0x75, 0x62, 0x4b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05,
+ 0x73, 0x68, 0x61, 0x72, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x73, 0x68, 0x61,
+ 0x72, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18,
+ 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65,
+ 0x22, 0x66, 0x0a, 0x04, 0x48, 0x52, 0x53, 0x54, 0x12, 0x16, 0x0a, 0x06, 0x68, 0x65, 0x69, 0x67,
+ 0x68, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74,
+ 0x12, 0x14, 0x0a, 0x05, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52,
+ 0x05, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x74, 0x65, 0x70, 0x18, 0x03,
+ 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x73, 0x74, 0x65, 0x70, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69,
+ 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74,
+ 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0xa4, 0x01, 0x0a, 0x23, 0x43, 0x6f, 0x73,
+ 0x69, 0x67, 0x6e, 0x65, 0x72, 0x47, 0x52, 0x50, 0x43, 0x53, 0x65, 0x74, 0x4e, 0x6f, 0x6e, 0x63,
+ 0x65, 0x73, 0x41, 0x6e, 0x64, 0x53, 0x69, 0x67, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
+ 0x12, 0x24, 0x0a, 0x06, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b,
+ 0x32, 0x0c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x52, 0x06,
+ 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x1f, 0x0a, 0x04, 0x68, 0x72, 0x73, 0x74, 0x18, 0x02,
+ 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x48, 0x52, 0x53,
+ 0x54, 0x52, 0x04, 0x68, 0x72, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x42,
+ 0x79, 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e,
+ 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x44,
+ 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x44, 0x22,
+ 0x84, 0x01, 0x0a, 0x24, 0x43, 0x6f, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x47, 0x52, 0x50, 0x43,
+ 0x53, 0x65, 0x74, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x73, 0x41, 0x6e, 0x64, 0x53, 0x69, 0x67, 0x6e,
+ 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x6e, 0x6f, 0x6e, 0x63,
+ 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x6e,
+ 0x6f, 0x6e, 0x63, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69,
+ 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74,
+ 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e,
+ 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67,
+ 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0x59, 0x0a, 0x1c, 0x43, 0x6f, 0x73, 0x69, 0x67, 0x6e,
+ 0x65, 0x72, 0x47, 0x52, 0x50, 0x43, 0x47, 0x65, 0x74, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x73, 0x52,
+ 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x04, 0x68, 0x72, 0x73, 0x74, 0x18, 0x01,
+ 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x48, 0x52, 0x53,
+ 0x54, 0x52, 0x04, 0x68, 0x72, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e,
+ 0x49, 0x44, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49,
+ 0x44, 0x22, 0x45, 0x0a, 0x1d, 0x43, 0x6f, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x47, 0x52, 0x50,
+ 0x43, 0x47, 0x65, 0x74, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
+ 0x73, 0x65, 0x12, 0x24, 0x0a, 0x06, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03,
+ 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4e, 0x6f, 0x6e, 0x63, 0x65,
+ 0x52, 0x06, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x73, 0x22, 0x43, 0x0a, 0x25, 0x43, 0x6f, 0x73, 0x69,
+ 0x67, 0x6e, 0x65, 0x72, 0x47, 0x52, 0x50, 0x43, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72,
+ 0x4c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
+ 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x49, 0x44, 0x18, 0x01, 0x20,
+ 0x01, 0x28, 0x09, 0x52, 0x08, 0x6c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x49, 0x44, 0x22, 0x6a, 0x0a,
+ 0x26, 0x43, 0x6f, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x47, 0x52, 0x50, 0x43, 0x54, 0x72, 0x61,
+ 0x6e, 0x73, 0x66, 0x65, 0x72, 0x4c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x52,
+ 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x6c, 0x65, 0x61, 0x64, 0x65,
+ 0x72, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6c, 0x65, 0x61, 0x64, 0x65,
+ 0x72, 0x49, 0x44, 0x12, 0x24, 0x0a, 0x0d, 0x6c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x41, 0x64, 0x64,
+ 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6c, 0x65, 0x61, 0x64,
+ 0x65, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x22, 0x1e, 0x0a, 0x1c, 0x43, 0x6f, 0x73,
+ 0x69, 0x67, 0x6e, 0x65, 0x72, 0x47, 0x52, 0x50, 0x43, 0x47, 0x65, 0x74, 0x4c, 0x65, 0x61, 0x64,
+ 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x37, 0x0a, 0x1d, 0x43, 0x6f, 0x73,
+ 0x69, 0x67, 0x6e, 0x65, 0x72, 0x47, 0x52, 0x50, 0x43, 0x47, 0x65, 0x74, 0x4c, 0x65, 0x61, 0x64,
+ 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x6c, 0x65,
+ 0x61, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6c, 0x65, 0x61, 0x64,
+ 0x65, 0x72, 0x32, 0x81, 0x04, 0x0a, 0x0d, 0x49, 0x43, 0x6f, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72,
+ 0x47, 0x52, 0x50, 0x43, 0x12, 0x58, 0x0a, 0x09, 0x53, 0x69, 0x67, 0x6e, 0x42, 0x6c, 0x6f, 0x63,
+ 0x6b, 0x12, 0x23, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x6f, 0x73, 0x69, 0x67, 0x6e,
0x65, 0x72, 0x47, 0x52, 0x50, 0x43, 0x53, 0x69, 0x67, 0x6e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52,
- 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61,
- 0x74, 0x75, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e,
- 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0x95, 0x01, 0x0a, 0x05, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x12,
- 0x1a, 0x0a, 0x08, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28,
- 0x05, 0x52, 0x08, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x44, 0x12, 0x24, 0x0a, 0x0d, 0x64,
- 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x44, 0x18, 0x02, 0x20, 0x01,
- 0x28, 0x05, 0x52, 0x0d, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49,
- 0x44, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x75, 0x62, 0x4b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28,
- 0x0c, 0x52, 0x06, 0x70, 0x75, 0x62, 0x4b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61,
- 0x72, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x65, 0x12,
- 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x05, 0x20, 0x01,
- 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0x66, 0x0a,
- 0x04, 0x48, 0x52, 0x53, 0x54, 0x12, 0x16, 0x0a, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18,
- 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x14, 0x0a,
- 0x05, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x72, 0x6f,
- 0x75, 0x6e, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x74, 0x65, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28,
- 0x05, 0x52, 0x04, 0x73, 0x74, 0x65, 0x70, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73,
- 0x74, 0x61, 0x6d, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65,
- 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0xa4, 0x01, 0x0a, 0x23, 0x43, 0x6f, 0x73, 0x69, 0x67, 0x6e,
- 0x65, 0x72, 0x47, 0x52, 0x50, 0x43, 0x53, 0x65, 0x74, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x73, 0x41,
- 0x6e, 0x64, 0x53, 0x69, 0x67, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x24, 0x0a,
- 0x06, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e,
- 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x52, 0x06, 0x6e, 0x6f, 0x6e,
- 0x63, 0x65, 0x73, 0x12, 0x1f, 0x0a, 0x04, 0x68, 0x72, 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28,
- 0x0b, 0x32, 0x0b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x48, 0x52, 0x53, 0x54, 0x52, 0x04,
- 0x68, 0x72, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x42, 0x79, 0x74, 0x65,
- 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x42, 0x79, 0x74,
- 0x65, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x44, 0x18, 0x04, 0x20,
- 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x44, 0x22, 0x84, 0x01, 0x0a,
- 0x24, 0x43, 0x6f, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x47, 0x52, 0x50, 0x43, 0x53, 0x65, 0x74,
- 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x73, 0x41, 0x6e, 0x64, 0x53, 0x69, 0x67, 0x6e, 0x52, 0x65, 0x73,
- 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x50, 0x75,
- 0x62, 0x6c, 0x69, 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x6e, 0x6f, 0x6e, 0x63,
- 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73,
- 0x74, 0x61, 0x6d, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65,
- 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75,
- 0x72, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74,
- 0x75, 0x72, 0x65, 0x22, 0x59, 0x0a, 0x1c, 0x43, 0x6f, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x47,
- 0x52, 0x50, 0x43, 0x47, 0x65, 0x74, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75,
- 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x04, 0x68, 0x72, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28,
- 0x0b, 0x32, 0x0b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x48, 0x52, 0x53, 0x54, 0x52, 0x04,
- 0x68, 0x72, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x44, 0x18,
- 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x44, 0x22, 0x45,
- 0x0a, 0x1d, 0x43, 0x6f, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x47, 0x52, 0x50, 0x43, 0x47, 0x65,
- 0x74, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
- 0x24, 0x0a, 0x06, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32,
- 0x0c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x52, 0x06, 0x6e,
- 0x6f, 0x6e, 0x63, 0x65, 0x73, 0x22, 0x43, 0x0a, 0x25, 0x43, 0x6f, 0x73, 0x69, 0x67, 0x6e, 0x65,
- 0x72, 0x47, 0x52, 0x50, 0x43, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x4c, 0x65, 0x61,
- 0x64, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a,
- 0x0a, 0x08, 0x6c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
- 0x52, 0x08, 0x6c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x49, 0x44, 0x22, 0x6a, 0x0a, 0x26, 0x43, 0x6f,
- 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x47, 0x52, 0x50, 0x43, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66,
- 0x65, 0x72, 0x4c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x52, 0x65, 0x73, 0x70,
- 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x6c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x49, 0x44,
- 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x49, 0x44,
- 0x12, 0x24, 0x0a, 0x0d, 0x6c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73,
- 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x41,
- 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x22, 0x1e, 0x0a, 0x1c, 0x43, 0x6f, 0x73, 0x69, 0x67, 0x6e,
- 0x65, 0x72, 0x47, 0x52, 0x50, 0x43, 0x47, 0x65, 0x74, 0x4c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x52,
- 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x37, 0x0a, 0x1d, 0x43, 0x6f, 0x73, 0x69, 0x67, 0x6e,
- 0x65, 0x72, 0x47, 0x52, 0x50, 0x43, 0x47, 0x65, 0x74, 0x4c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x52,
- 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x6c, 0x65, 0x61, 0x64, 0x65,
- 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x32,
- 0x80, 0x04, 0x0a, 0x0c, 0x43, 0x6f, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x47, 0x52, 0x50, 0x43,
- 0x12, 0x58, 0x0a, 0x09, 0x53, 0x69, 0x67, 0x6e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x23, 0x2e,
- 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x6f, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x47, 0x52,
- 0x50, 0x43, 0x53, 0x69, 0x67, 0x6e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65,
- 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x6f, 0x73, 0x69, 0x67,
- 0x6e, 0x65, 0x72, 0x47, 0x52, 0x50, 0x43, 0x53, 0x69, 0x67, 0x6e, 0x42, 0x6c, 0x6f, 0x63, 0x6b,
- 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x6d, 0x0a, 0x10, 0x53, 0x65,
- 0x74, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x73, 0x41, 0x6e, 0x64, 0x53, 0x69, 0x67, 0x6e, 0x12, 0x2a,
+ 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43,
+ 0x6f, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x47, 0x52, 0x50, 0x43, 0x53, 0x69, 0x67, 0x6e, 0x42,
+ 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x6d,
+ 0x0a, 0x10, 0x53, 0x65, 0x74, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x73, 0x41, 0x6e, 0x64, 0x53, 0x69,
+ 0x67, 0x6e, 0x12, 0x2a, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x6f, 0x73, 0x69, 0x67,
+ 0x6e, 0x65, 0x72, 0x47, 0x52, 0x50, 0x43, 0x53, 0x65, 0x74, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x73,
+ 0x41, 0x6e, 0x64, 0x53, 0x69, 0x67, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b,
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x6f, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x47,
0x52, 0x50, 0x43, 0x53, 0x65, 0x74, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x73, 0x41, 0x6e, 0x64, 0x53,
- 0x69, 0x67, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x70, 0x72, 0x6f,
- 0x74, 0x6f, 0x2e, 0x43, 0x6f, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x47, 0x52, 0x50, 0x43, 0x53,
- 0x65, 0x74, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x73, 0x41, 0x6e, 0x64, 0x53, 0x69, 0x67, 0x6e, 0x52,
- 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x58, 0x0a, 0x09, 0x47, 0x65, 0x74,
- 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x23, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43,
- 0x6f, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x47, 0x52, 0x50, 0x43, 0x47, 0x65, 0x74, 0x4e, 0x6f,
- 0x6e, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x70, 0x72,
- 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x6f, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x47, 0x52, 0x50, 0x43,
- 0x47, 0x65, 0x74, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
- 0x65, 0x22, 0x00, 0x12, 0x73, 0x0a, 0x12, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x4c,
- 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x12, 0x2c, 0x2e, 0x70, 0x72, 0x6f, 0x74,
- 0x6f, 0x2e, 0x43, 0x6f, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x47, 0x52, 0x50, 0x43, 0x54, 0x72,
- 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x4c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70,
- 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e,
- 0x43, 0x6f, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x47, 0x52, 0x50, 0x43, 0x54, 0x72, 0x61, 0x6e,
- 0x73, 0x66, 0x65, 0x72, 0x4c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x52, 0x65,
- 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x58, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x4c,
- 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x23, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x6f,
- 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x47, 0x52, 0x50, 0x43, 0x47, 0x65, 0x74, 0x4c, 0x65, 0x61,
- 0x64, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x70, 0x72, 0x6f,
+ 0x69, 0x67, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x58, 0x0a,
+ 0x09, 0x47, 0x65, 0x74, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x23, 0x2e, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x2e, 0x43, 0x6f, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x47, 0x52, 0x50, 0x43, 0x47,
- 0x65, 0x74, 0x4c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
- 0x22, 0x00, 0x42, 0x36, 0x5a, 0x34, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d,
- 0x2f, 0x73, 0x74, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x6c, 0x6f, 0x76, 0x65, 0x2d, 0x76, 0x65, 0x6e,
- 0x74, 0x75, 0x72, 0x65, 0x73, 0x2f, 0x68, 0x6f, 0x72, 0x63, 0x72, 0x75, 0x78, 0x2f, 0x73, 0x69,
- 0x67, 0x6e, 0x65, 0x72, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74,
- 0x6f, 0x33,
+ 0x65, 0x74, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
+ 0x24, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x6f, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72,
+ 0x47, 0x52, 0x50, 0x43, 0x47, 0x65, 0x74, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73,
+ 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x73, 0x0a, 0x12, 0x54, 0x72, 0x61, 0x6e, 0x73,
+ 0x66, 0x65, 0x72, 0x4c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x12, 0x2c, 0x2e,
+ 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x6f, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x47, 0x52,
+ 0x50, 0x43, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x4c, 0x65, 0x61, 0x64, 0x65, 0x72,
+ 0x73, 0x68, 0x69, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x70, 0x72,
+ 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x6f, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x47, 0x52, 0x50, 0x43,
+ 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x4c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x68,
+ 0x69, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x58, 0x0a, 0x09,
+ 0x47, 0x65, 0x74, 0x4c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x23, 0x2e, 0x70, 0x72, 0x6f, 0x74,
+ 0x6f, 0x2e, 0x43, 0x6f, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x47, 0x52, 0x50, 0x43, 0x47, 0x65,
+ 0x74, 0x4c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24,
+ 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x6f, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x47,
+ 0x52, 0x50, 0x43, 0x47, 0x65, 0x74, 0x4c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70,
+ 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x33, 0x5a, 0x31, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62,
+ 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x74, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x6c, 0x6f, 0x76, 0x65,
+ 0x2d, 0x76, 0x65, 0x6e, 0x74, 0x75, 0x72, 0x65, 0x73, 0x2f, 0x68, 0x6f, 0x72, 0x63, 0x72, 0x75,
+ 0x78, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f,
+ 0x74, 0x6f, 0x33,
}
var (
- file_signer_proto_cosigner_grpc_server_proto_rawDescOnce sync.Once
- file_signer_proto_cosigner_grpc_server_proto_rawDescData = file_signer_proto_cosigner_grpc_server_proto_rawDesc
+ file_cosigner_grpc_server_proto_rawDescOnce sync.Once
+ file_cosigner_grpc_server_proto_rawDescData = file_cosigner_grpc_server_proto_rawDesc
)
-func file_signer_proto_cosigner_grpc_server_proto_rawDescGZIP() []byte {
- file_signer_proto_cosigner_grpc_server_proto_rawDescOnce.Do(func() {
- file_signer_proto_cosigner_grpc_server_proto_rawDescData = protoimpl.X.CompressGZIP(file_signer_proto_cosigner_grpc_server_proto_rawDescData)
+func file_cosigner_grpc_server_proto_rawDescGZIP() []byte {
+ file_cosigner_grpc_server_proto_rawDescOnce.Do(func() {
+ file_cosigner_grpc_server_proto_rawDescData = protoimpl.X.CompressGZIP(file_cosigner_grpc_server_proto_rawDescData)
})
- return file_signer_proto_cosigner_grpc_server_proto_rawDescData
+ return file_cosigner_grpc_server_proto_rawDescData
}
-var file_signer_proto_cosigner_grpc_server_proto_msgTypes = make([]protoimpl.MessageInfo, 13)
-var file_signer_proto_cosigner_grpc_server_proto_goTypes = []interface{}{
+var file_cosigner_grpc_server_proto_msgTypes = make([]protoimpl.MessageInfo, 13)
+var file_cosigner_grpc_server_proto_goTypes = []interface{}{
(*Block)(nil), // 0: proto.Block
(*CosignerGRPCSignBlockRequest)(nil), // 1: proto.CosignerGRPCSignBlockRequest
(*CosignerGRPCSignBlockResponse)(nil), // 2: proto.CosignerGRPCSignBlockResponse
@@ -927,22 +926,22 @@ var file_signer_proto_cosigner_grpc_server_proto_goTypes = []interface{}{
(*CosignerGRPCGetLeaderRequest)(nil), // 11: proto.CosignerGRPCGetLeaderRequest
(*CosignerGRPCGetLeaderResponse)(nil), // 12: proto.CosignerGRPCGetLeaderResponse
}
-var file_signer_proto_cosigner_grpc_server_proto_depIdxs = []int32{
+var file_cosigner_grpc_server_proto_depIdxs = []int32{
0, // 0: proto.CosignerGRPCSignBlockRequest.block:type_name -> proto.Block
3, // 1: proto.CosignerGRPCSetNoncesAndSignRequest.nonces:type_name -> proto.Nonce
4, // 2: proto.CosignerGRPCSetNoncesAndSignRequest.hrst:type_name -> proto.HRST
4, // 3: proto.CosignerGRPCGetNoncesRequest.hrst:type_name -> proto.HRST
3, // 4: proto.CosignerGRPCGetNoncesResponse.nonces:type_name -> proto.Nonce
- 1, // 5: proto.CosignerGRPC.SignBlock:input_type -> proto.CosignerGRPCSignBlockRequest
- 5, // 6: proto.CosignerGRPC.SetNoncesAndSign:input_type -> proto.CosignerGRPCSetNoncesAndSignRequest
- 7, // 7: proto.CosignerGRPC.GetNonces:input_type -> proto.CosignerGRPCGetNoncesRequest
- 9, // 8: proto.CosignerGRPC.TransferLeadership:input_type -> proto.CosignerGRPCTransferLeadershipRequest
- 11, // 9: proto.CosignerGRPC.GetLeader:input_type -> proto.CosignerGRPCGetLeaderRequest
- 2, // 10: proto.CosignerGRPC.SignBlock:output_type -> proto.CosignerGRPCSignBlockResponse
- 6, // 11: proto.CosignerGRPC.SetNoncesAndSign:output_type -> proto.CosignerGRPCSetNoncesAndSignResponse
- 8, // 12: proto.CosignerGRPC.GetNonces:output_type -> proto.CosignerGRPCGetNoncesResponse
- 10, // 13: proto.CosignerGRPC.TransferLeadership:output_type -> proto.CosignerGRPCTransferLeadershipResponse
- 12, // 14: proto.CosignerGRPC.GetLeader:output_type -> proto.CosignerGRPCGetLeaderResponse
+ 1, // 5: proto.ICosignerGRPC.SignBlock:input_type -> proto.CosignerGRPCSignBlockRequest
+ 5, // 6: proto.ICosignerGRPC.SetNoncesAndSign:input_type -> proto.CosignerGRPCSetNoncesAndSignRequest
+ 7, // 7: proto.ICosignerGRPC.GetNonces:input_type -> proto.CosignerGRPCGetNoncesRequest
+ 9, // 8: proto.ICosignerGRPC.TransferLeadership:input_type -> proto.CosignerGRPCTransferLeadershipRequest
+ 11, // 9: proto.ICosignerGRPC.GetLeader:input_type -> proto.CosignerGRPCGetLeaderRequest
+ 2, // 10: proto.ICosignerGRPC.SignBlock:output_type -> proto.CosignerGRPCSignBlockResponse
+ 6, // 11: proto.ICosignerGRPC.SetNoncesAndSign:output_type -> proto.CosignerGRPCSetNoncesAndSignResponse
+ 8, // 12: proto.ICosignerGRPC.GetNonces:output_type -> proto.CosignerGRPCGetNoncesResponse
+ 10, // 13: proto.ICosignerGRPC.TransferLeadership:output_type -> proto.CosignerGRPCTransferLeadershipResponse
+ 12, // 14: proto.ICosignerGRPC.GetLeader:output_type -> proto.CosignerGRPCGetLeaderResponse
10, // [10:15] is the sub-list for method output_type
5, // [5:10] is the sub-list for method input_type
5, // [5:5] is the sub-list for extension type_name
@@ -950,13 +949,13 @@ var file_signer_proto_cosigner_grpc_server_proto_depIdxs = []int32{
0, // [0:5] is the sub-list for field type_name
}
-func init() { file_signer_proto_cosigner_grpc_server_proto_init() }
-func file_signer_proto_cosigner_grpc_server_proto_init() {
- if File_signer_proto_cosigner_grpc_server_proto != nil {
+func init() { file_cosigner_grpc_server_proto_init() }
+func file_cosigner_grpc_server_proto_init() {
+ if File_cosigner_grpc_server_proto != nil {
return
}
if !protoimpl.UnsafeEnabled {
- file_signer_proto_cosigner_grpc_server_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+ file_cosigner_grpc_server_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Block); i {
case 0:
return &v.state
@@ -968,7 +967,7 @@ func file_signer_proto_cosigner_grpc_server_proto_init() {
return nil
}
}
- file_signer_proto_cosigner_grpc_server_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
+ file_cosigner_grpc_server_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*CosignerGRPCSignBlockRequest); i {
case 0:
return &v.state
@@ -980,7 +979,7 @@ func file_signer_proto_cosigner_grpc_server_proto_init() {
return nil
}
}
- file_signer_proto_cosigner_grpc_server_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
+ file_cosigner_grpc_server_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*CosignerGRPCSignBlockResponse); i {
case 0:
return &v.state
@@ -992,7 +991,7 @@ func file_signer_proto_cosigner_grpc_server_proto_init() {
return nil
}
}
- file_signer_proto_cosigner_grpc_server_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
+ file_cosigner_grpc_server_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Nonce); i {
case 0:
return &v.state
@@ -1004,7 +1003,7 @@ func file_signer_proto_cosigner_grpc_server_proto_init() {
return nil
}
}
- file_signer_proto_cosigner_grpc_server_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
+ file_cosigner_grpc_server_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*HRST); i {
case 0:
return &v.state
@@ -1016,7 +1015,7 @@ func file_signer_proto_cosigner_grpc_server_proto_init() {
return nil
}
}
- file_signer_proto_cosigner_grpc_server_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
+ file_cosigner_grpc_server_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*CosignerGRPCSetNoncesAndSignRequest); i {
case 0:
return &v.state
@@ -1028,7 +1027,7 @@ func file_signer_proto_cosigner_grpc_server_proto_init() {
return nil
}
}
- file_signer_proto_cosigner_grpc_server_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
+ file_cosigner_grpc_server_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*CosignerGRPCSetNoncesAndSignResponse); i {
case 0:
return &v.state
@@ -1040,7 +1039,7 @@ func file_signer_proto_cosigner_grpc_server_proto_init() {
return nil
}
}
- file_signer_proto_cosigner_grpc_server_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
+ file_cosigner_grpc_server_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*CosignerGRPCGetNoncesRequest); i {
case 0:
return &v.state
@@ -1052,7 +1051,7 @@ func file_signer_proto_cosigner_grpc_server_proto_init() {
return nil
}
}
- file_signer_proto_cosigner_grpc_server_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
+ file_cosigner_grpc_server_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*CosignerGRPCGetNoncesResponse); i {
case 0:
return &v.state
@@ -1064,7 +1063,7 @@ func file_signer_proto_cosigner_grpc_server_proto_init() {
return nil
}
}
- file_signer_proto_cosigner_grpc_server_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} {
+ file_cosigner_grpc_server_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*CosignerGRPCTransferLeadershipRequest); i {
case 0:
return &v.state
@@ -1076,7 +1075,7 @@ func file_signer_proto_cosigner_grpc_server_proto_init() {
return nil
}
}
- file_signer_proto_cosigner_grpc_server_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} {
+ file_cosigner_grpc_server_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*CosignerGRPCTransferLeadershipResponse); i {
case 0:
return &v.state
@@ -1088,7 +1087,7 @@ func file_signer_proto_cosigner_grpc_server_proto_init() {
return nil
}
}
- file_signer_proto_cosigner_grpc_server_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} {
+ file_cosigner_grpc_server_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*CosignerGRPCGetLeaderRequest); i {
case 0:
return &v.state
@@ -1100,7 +1099,7 @@ func file_signer_proto_cosigner_grpc_server_proto_init() {
return nil
}
}
- file_signer_proto_cosigner_grpc_server_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} {
+ file_cosigner_grpc_server_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*CosignerGRPCGetLeaderResponse); i {
case 0:
return &v.state
@@ -1117,18 +1116,18 @@ func file_signer_proto_cosigner_grpc_server_proto_init() {
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
- RawDescriptor: file_signer_proto_cosigner_grpc_server_proto_rawDesc,
+ RawDescriptor: file_cosigner_grpc_server_proto_rawDesc,
NumEnums: 0,
NumMessages: 13,
NumExtensions: 0,
NumServices: 1,
},
- GoTypes: file_signer_proto_cosigner_grpc_server_proto_goTypes,
- DependencyIndexes: file_signer_proto_cosigner_grpc_server_proto_depIdxs,
- MessageInfos: file_signer_proto_cosigner_grpc_server_proto_msgTypes,
+ GoTypes: file_cosigner_grpc_server_proto_goTypes,
+ DependencyIndexes: file_cosigner_grpc_server_proto_depIdxs,
+ MessageInfos: file_cosigner_grpc_server_proto_msgTypes,
}.Build()
- File_signer_proto_cosigner_grpc_server_proto = out.File
- file_signer_proto_cosigner_grpc_server_proto_rawDesc = nil
- file_signer_proto_cosigner_grpc_server_proto_goTypes = nil
- file_signer_proto_cosigner_grpc_server_proto_depIdxs = nil
+ File_cosigner_grpc_server_proto = out.File
+ file_cosigner_grpc_server_proto_rawDesc = nil
+ file_cosigner_grpc_server_proto_goTypes = nil
+ file_cosigner_grpc_server_proto_depIdxs = nil
}
diff --git a/signer/proto/cosigner_grpc_server.proto b/pkg/proto/cosigner_grpc_server.proto
similarity index 91%
rename from signer/proto/cosigner_grpc_server.proto
rename to pkg/proto/cosigner_grpc_server.proto
index f8429cad..9987e3e9 100644
--- a/signer/proto/cosigner_grpc_server.proto
+++ b/pkg/proto/cosigner_grpc_server.proto
@@ -1,10 +1,10 @@
syntax = "proto3";
-option go_package = "github.com/strangelove-ventures/horcrux/signer/proto";
+option go_package = "github.com/strangelove-ventures/horcrux/pkg/proto";
package proto;
-
-service CosignerGRPC {
+// CosignerGRPC handles all the services (the server)
+service ICosignerGRPC {
rpc SignBlock (CosignerGRPCSignBlockRequest) returns (CosignerGRPCSignBlockResponse) {}
rpc SetNoncesAndSign (CosignerGRPCSetNoncesAndSignRequest) returns (CosignerGRPCSetNoncesAndSignResponse) {}
rpc GetNonces (CosignerGRPCGetNoncesRequest) returns (CosignerGRPCGetNoncesResponse) {}
diff --git a/pkg/proto/cosigner_grpc_server_grpc.pb.go b/pkg/proto/cosigner_grpc_server_grpc.pb.go
new file mode 100644
index 00000000..c532ed00
--- /dev/null
+++ b/pkg/proto/cosigner_grpc_server_grpc.pb.go
@@ -0,0 +1,249 @@
+// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
+// versions:
+// - protoc-gen-go-grpc v1.2.0
+// - protoc v3.13.0
+// source: cosigner_grpc_server.proto
+
+package proto
+
+import (
+ context "context"
+ grpc "google.golang.org/grpc"
+ codes "google.golang.org/grpc/codes"
+ status "google.golang.org/grpc/status"
+)
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the grpc package it is being compiled against.
+// Requires gRPC-Go v1.32.0 or later.
+const _ = grpc.SupportPackageIsVersion7
+
+// ICosignerGRPCClient is the client API for ICosignerGRPC service.
+//
+// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
+type ICosignerGRPCClient interface {
+ SignBlock(ctx context.Context, in *CosignerGRPCSignBlockRequest, opts ...grpc.CallOption) (*CosignerGRPCSignBlockResponse, error)
+ SetNoncesAndSign(ctx context.Context, in *CosignerGRPCSetNoncesAndSignRequest, opts ...grpc.CallOption) (*CosignerGRPCSetNoncesAndSignResponse, error)
+ GetNonces(ctx context.Context, in *CosignerGRPCGetNoncesRequest, opts ...grpc.CallOption) (*CosignerGRPCGetNoncesResponse, error)
+ TransferLeadership(ctx context.Context, in *CosignerGRPCTransferLeadershipRequest, opts ...grpc.CallOption) (*CosignerGRPCTransferLeadershipResponse, error)
+ GetLeader(ctx context.Context, in *CosignerGRPCGetLeaderRequest, opts ...grpc.CallOption) (*CosignerGRPCGetLeaderResponse, error)
+}
+
+type iCosignerGRPCClient struct {
+ cc grpc.ClientConnInterface
+}
+
+func NewICosignerGRPCClient(cc grpc.ClientConnInterface) ICosignerGRPCClient {
+ return &iCosignerGRPCClient{cc}
+}
+
+func (c *iCosignerGRPCClient) SignBlock(ctx context.Context, in *CosignerGRPCSignBlockRequest, opts ...grpc.CallOption) (*CosignerGRPCSignBlockResponse, error) {
+ out := new(CosignerGRPCSignBlockResponse)
+ err := c.cc.Invoke(ctx, "/proto.ICosignerGRPC/SignBlock", in, out, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+func (c *iCosignerGRPCClient) SetNoncesAndSign(ctx context.Context, in *CosignerGRPCSetNoncesAndSignRequest, opts ...grpc.CallOption) (*CosignerGRPCSetNoncesAndSignResponse, error) {
+ out := new(CosignerGRPCSetNoncesAndSignResponse)
+ err := c.cc.Invoke(ctx, "/proto.ICosignerGRPC/SetNoncesAndSign", in, out, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+func (c *iCosignerGRPCClient) GetNonces(ctx context.Context, in *CosignerGRPCGetNoncesRequest, opts ...grpc.CallOption) (*CosignerGRPCGetNoncesResponse, error) {
+ out := new(CosignerGRPCGetNoncesResponse)
+ err := c.cc.Invoke(ctx, "/proto.ICosignerGRPC/GetNonces", in, out, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+func (c *iCosignerGRPCClient) TransferLeadership(ctx context.Context, in *CosignerGRPCTransferLeadershipRequest, opts ...grpc.CallOption) (*CosignerGRPCTransferLeadershipResponse, error) {
+ out := new(CosignerGRPCTransferLeadershipResponse)
+ err := c.cc.Invoke(ctx, "/proto.ICosignerGRPC/TransferLeadership", in, out, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+func (c *iCosignerGRPCClient) GetLeader(ctx context.Context, in *CosignerGRPCGetLeaderRequest, opts ...grpc.CallOption) (*CosignerGRPCGetLeaderResponse, error) {
+ out := new(CosignerGRPCGetLeaderResponse)
+ err := c.cc.Invoke(ctx, "/proto.ICosignerGRPC/GetLeader", in, out, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+// ICosignerGRPCServer is the server API for ICosignerGRPC service.
+// All implementations must embed UnimplementedICosignerGRPCServer
+// for forward compatibility
+type ICosignerGRPCServer interface {
+ SignBlock(context.Context, *CosignerGRPCSignBlockRequest) (*CosignerGRPCSignBlockResponse, error)
+ SetNoncesAndSign(context.Context, *CosignerGRPCSetNoncesAndSignRequest) (*CosignerGRPCSetNoncesAndSignResponse, error)
+ GetNonces(context.Context, *CosignerGRPCGetNoncesRequest) (*CosignerGRPCGetNoncesResponse, error)
+ TransferLeadership(context.Context, *CosignerGRPCTransferLeadershipRequest) (*CosignerGRPCTransferLeadershipResponse, error)
+ GetLeader(context.Context, *CosignerGRPCGetLeaderRequest) (*CosignerGRPCGetLeaderResponse, error)
+ mustEmbedUnimplementedICosignerGRPCServer()
+}
+
+// UnimplementedICosignerGRPCServer must be embedded to have forward compatible implementations.
+type UnimplementedICosignerGRPCServer struct {
+}
+
+func (UnimplementedICosignerGRPCServer) SignBlock(context.Context, *CosignerGRPCSignBlockRequest) (*CosignerGRPCSignBlockResponse, error) {
+ return nil, status.Errorf(codes.Unimplemented, "method SignBlock not implemented")
+}
+func (UnimplementedICosignerGRPCServer) SetNoncesAndSign(context.Context, *CosignerGRPCSetNoncesAndSignRequest) (*CosignerGRPCSetNoncesAndSignResponse, error) {
+ return nil, status.Errorf(codes.Unimplemented, "method SetNoncesAndSign not implemented")
+}
+func (UnimplementedICosignerGRPCServer) GetNonces(context.Context, *CosignerGRPCGetNoncesRequest) (*CosignerGRPCGetNoncesResponse, error) {
+ return nil, status.Errorf(codes.Unimplemented, "method GetNonces not implemented")
+}
+func (UnimplementedICosignerGRPCServer) TransferLeadership(context.Context, *CosignerGRPCTransferLeadershipRequest) (*CosignerGRPCTransferLeadershipResponse, error) {
+ return nil, status.Errorf(codes.Unimplemented, "method TransferLeadership not implemented")
+}
+func (UnimplementedICosignerGRPCServer) GetLeader(context.Context, *CosignerGRPCGetLeaderRequest) (*CosignerGRPCGetLeaderResponse, error) {
+ return nil, status.Errorf(codes.Unimplemented, "method GetLeader not implemented")
+}
+func (UnimplementedICosignerGRPCServer) mustEmbedUnimplementedICosignerGRPCServer() {}
+
+// UnsafeICosignerGRPCServer may be embedded to opt out of forward compatibility for this service.
+// Use of this interface is not recommended, as added methods to ICosignerGRPCServer will
+// result in compilation errors.
+type UnsafeICosignerGRPCServer interface {
+ mustEmbedUnimplementedICosignerGRPCServer()
+}
+
+func RegisterICosignerGRPCServer(s grpc.ServiceRegistrar, srv ICosignerGRPCServer) {
+ s.RegisterService(&ICosignerGRPC_ServiceDesc, srv)
+}
+
+func _ICosignerGRPC_SignBlock_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+ in := new(CosignerGRPCSignBlockRequest)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(ICosignerGRPCServer).SignBlock(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: "/proto.ICosignerGRPC/SignBlock",
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(ICosignerGRPCServer).SignBlock(ctx, req.(*CosignerGRPCSignBlockRequest))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
+func _ICosignerGRPC_SetNoncesAndSign_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+ in := new(CosignerGRPCSetNoncesAndSignRequest)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(ICosignerGRPCServer).SetNoncesAndSign(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: "/proto.ICosignerGRPC/SetNoncesAndSign",
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(ICosignerGRPCServer).SetNoncesAndSign(ctx, req.(*CosignerGRPCSetNoncesAndSignRequest))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
+func _ICosignerGRPC_GetNonces_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+ in := new(CosignerGRPCGetNoncesRequest)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(ICosignerGRPCServer).GetNonces(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: "/proto.ICosignerGRPC/GetNonces",
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(ICosignerGRPCServer).GetNonces(ctx, req.(*CosignerGRPCGetNoncesRequest))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
+func _ICosignerGRPC_TransferLeadership_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+ in := new(CosignerGRPCTransferLeadershipRequest)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(ICosignerGRPCServer).TransferLeadership(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: "/proto.ICosignerGRPC/TransferLeadership",
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(ICosignerGRPCServer).TransferLeadership(ctx, req.(*CosignerGRPCTransferLeadershipRequest))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
+func _ICosignerGRPC_GetLeader_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+ in := new(CosignerGRPCGetLeaderRequest)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(ICosignerGRPCServer).GetLeader(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: "/proto.ICosignerGRPC/GetLeader",
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(ICosignerGRPCServer).GetLeader(ctx, req.(*CosignerGRPCGetLeaderRequest))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
+// ICosignerGRPC_ServiceDesc is the grpc.ServiceDesc for ICosignerGRPC service.
+// It's only intended for direct use with grpc.RegisterService,
+// and not to be introspected or modified (even as a copy)
+var ICosignerGRPC_ServiceDesc = grpc.ServiceDesc{
+ ServiceName: "proto.ICosignerGRPC",
+ HandlerType: (*ICosignerGRPCServer)(nil),
+ Methods: []grpc.MethodDesc{
+ {
+ MethodName: "SignBlock",
+ Handler: _ICosignerGRPC_SignBlock_Handler,
+ },
+ {
+ MethodName: "SetNoncesAndSign",
+ Handler: _ICosignerGRPC_SetNoncesAndSign_Handler,
+ },
+ {
+ MethodName: "GetNonces",
+ Handler: _ICosignerGRPC_GetNonces_Handler,
+ },
+ {
+ MethodName: "TransferLeadership",
+ Handler: _ICosignerGRPC_TransferLeadership_Handler,
+ },
+ {
+ MethodName: "GetLeader",
+ Handler: _ICosignerGRPC_GetLeader_Handler,
+ },
+ },
+ Streams: []grpc.StreamDesc{},
+ Metadata: "cosigner_grpc_server.proto",
+}
diff --git a/signer/testdata/testdata.go b/pkg/testdata/testdata.go
similarity index 100%
rename from signer/testdata/testdata.go
rename to pkg/testdata/testdata.go
diff --git a/signer/hrs.go b/pkg/types/hrs.go
similarity index 90%
rename from signer/hrs.go
rename to pkg/types/hrs.go
index acd24a8d..ebd159bb 100644
--- a/signer/hrs.go
+++ b/pkg/types/hrs.go
@@ -1,10 +1,11 @@
-package signer
+package types
import (
- "github.com/strangelove-ventures/horcrux/signer/proto"
+ "github.com/strangelove-ventures/horcrux/pkg/proto"
)
// HRSKey represents the key for the HRS metadata map.
+// Height is the block height.
type HRSKey struct {
Height int64
Round int64
@@ -60,7 +61,7 @@ func HRSTKeyFromProto(hrs *proto.HRST) HRSTKey {
}
}
-func (hrst HRSTKey) toProto() *proto.HRST {
+func (hrst HRSTKey) ToProto() *proto.HRST {
return &proto.HRST{
Height: hrst.Height,
Round: hrst.Round,
diff --git a/signer/serialization.go b/pkg/types/serialization.go
similarity index 98%
rename from signer/serialization.go
rename to pkg/types/serialization.go
index ee6b5ab4..d6a9dcbe 100644
--- a/signer/serialization.go
+++ b/pkg/types/serialization.go
@@ -1,4 +1,4 @@
-package signer
+package types
import (
"errors"
diff --git a/signer/serialization_test.go b/pkg/types/serialization_test.go
similarity index 98%
rename from signer/serialization_test.go
rename to pkg/types/serialization_test.go
index d51a678c..078dfd4d 100644
--- a/signer/serialization_test.go
+++ b/pkg/types/serialization_test.go
@@ -1,4 +1,4 @@
-package signer
+package types
import (
"testing"
diff --git a/signer/sign_state.go b/pkg/types/sign_state.go
similarity index 86%
rename from signer/sign_state.go
rename to pkg/types/sign_state.go
index 86ac6387..17019751 100644
--- a/signer/sign_state.go
+++ b/pkg/types/sign_state.go
@@ -1,4 +1,4 @@
-package signer
+package types
import (
"bytes"
@@ -7,6 +7,9 @@ import (
"fmt"
"os"
"sync"
+ "time"
+
+ "github.com/strangelove-ventures/horcrux/pkg/cond"
cometbytes "github.com/cometbft/cometbft/libs/bytes"
cometjson "github.com/cometbft/cometbft/libs/json"
@@ -14,7 +17,6 @@ import (
"github.com/cometbft/cometbft/libs/tempfile"
cometproto "github.com/cometbft/cometbft/proto/tendermint/types"
"github.com/gogo/protobuf/proto"
- "github.com/strangelove-ventures/horcrux/signer/cond"
)
const (
@@ -24,6 +26,10 @@ const (
blocksToCache = 3
)
+func StepPropose() int8 {
+ return stepPropose
+}
+
func CanonicalVoteToStep(vote *cometproto.CanonicalVote) int8 {
switch vote.Type {
case cometproto.PrevoteType:
@@ -59,14 +65,49 @@ type SignState struct {
Signature []byte `json:"signature,omitempty"`
SignBytes cometbytes.HexBytes `json:"signbytes,omitempty"`
- filePath string
+ FilePath string
// mu protects the cache and is used for signaling with cond.
- mu sync.RWMutex
- cache map[HRSKey]SignStateConsensus
- cond *cond.Cond
+ mu sync.RWMutex // private to avoid marshal issues
+ cache map[HRSKey]SignStateConsensus // private to avoid marshal issues
+ cond *cond.Cond // private to avoid marshal issues
+}
+
+func (signState *SignState) WaitWithTimeout(timeout time.Duration) {
+ signState.cond.WaitWithTimeout(timeout)
+}
+
+func (signState *SignState) CondBroadcast() {
+ signState.cond.Broadcast()
+}
+
+func (signState *SignState) CondLlock() {
+ signState.cond.L.Lock()
+}
+
+func (signState *SignState) CondLunlock() {
+ signState.cond.L.Unlock()
}
+func (signState *SignState) MuLock() {
+ signState.mu.Lock()
+}
+
+func (signState *SignState) MuUnlock() {
+ signState.mu.Unlock()
+}
+
+func (signState *SignState) GetCache(hrs HRSKey) (SignStateConsensus, bool) {
+ ssc, err := signState.cache[hrs]
+ return ssc, err
+}
+func (signState *SignState) SetCache(hrs HRSKey, signStateConsensus SignStateConsensus) {
+ signState.cache[hrs] = signStateConsensus
+}
+
+func (signState *SignState) ExistingSignatureOrErrorIfRegression(hrst HRSTKey, signBytes []byte) ([]byte, error) {
+ return signState.existingSignatureOrErrorIfRegression(hrst, signBytes)
+}
func (signState *SignState) existingSignatureOrErrorIfRegression(hrst HRSTKey, signBytes []byte) ([]byte, error) {
signState.mu.RLock()
defer signState.mu.RUnlock()
@@ -119,6 +160,8 @@ type SignStateConsensus struct {
SignBytes cometbytes.HexBytes
}
+// TODO: this should maybe be a copy function instead of the pointer,
+// so it is a pointer method receiver?
func (signState SignStateConsensus) HRSKey() HRSKey {
return HRSKey{
Height: signState.Height,
@@ -165,7 +208,7 @@ func (signState *SignState) GetFromCache(hrs HRSKey) (HRSKey, *SignStateConsensu
return latestBlock, nil
}
-// cacheAndMarshal will cache a SignStateConsensus for it's HRS and return the marshalled bytes.
+// cacheAndMarshal will Cache a SignStateConsensus for it's HRS and return the marshalled bytes.
func (signState *SignState) cacheAndMarshal(ssc SignStateConsensus) []byte {
signState.mu.Lock()
defer signState.mu.Unlock()
@@ -186,6 +229,7 @@ func (signState *SignState) cacheAndMarshal(ssc SignStateConsensus) []byte {
jsonBytes, err := cometjson.MarshalIndent(signState, "", " ")
if err != nil {
+ fmt.Print("jsonBytes")
panic(err)
}
@@ -226,9 +270,9 @@ func (signState *SignState) Save(
return nil
}
-// Save persists the FilePvLastSignState to its filePath.
+// Save persists the FilePvLastSignState to its FilePath.
func (signState *SignState) save(jsonBytes []byte) {
- outFile := signState.filePath
+ outFile := signState.FilePath
if outFile == os.DevNull {
return
}
@@ -316,7 +360,7 @@ func (signState *SignState) FreshCache() *SignState {
SignBytes: signState.SignBytes,
cache: make(map[HRSKey]SignStateConsensus),
- filePath: signState.filePath,
+ FilePath: signState.FilePath,
}
newSignState.cond = cond.New(&newSignState.mu)
@@ -347,10 +391,11 @@ func LoadSignState(filepath string) (*SignState, error) {
err = cometjson.Unmarshal(stateJSONBytes, &state)
if err != nil {
+ // fmt.Println("Func LoadSignState Error unmarshalling sign state: ", err)
return nil, err
}
- state.filePath = filepath
+ state.FilePath = filepath
return state.FreshCache(), nil
}
@@ -363,19 +408,23 @@ func LoadOrCreateSignState(filepath string) (*SignState, error) {
if !os.IsNotExist(err) {
return nil, fmt.Errorf("unexpected error checking file existence (%s): %w", filepath, err)
}
+
+ // print that the file does not exist to the console
+ fmt.Printf("\n\tNo filepath for Signstate exist for:\n\t\t%s.", filepath)
+
// the only scenario where we want to create a new sign state file is when the file does not exist.
// Make an empty sign state and save it.
state := &SignState{
- filePath: filepath,
+ FilePath: filepath,
cache: make(map[HRSKey]SignStateConsensus),
}
state.cond = cond.New(&state.mu)
jsonBytes, err := cometjson.MarshalIndent(state, "", " ")
if err != nil {
+ fmt.Printf("cometjson.MarshalIndent: %s", err)
panic(err)
}
-
state.save(jsonBytes)
return state, nil
}
diff --git a/pkg/types/sign_state_test.go b/pkg/types/sign_state_test.go
new file mode 100644
index 00000000..00665c8b
--- /dev/null
+++ b/pkg/types/sign_state_test.go
@@ -0,0 +1,52 @@
+package types
+
+import (
+ "fmt"
+ "os"
+ "path/filepath"
+ "testing"
+
+ "github.com/strangelove-ventures/horcrux/pkg/cond"
+
+ cometjson "github.com/cometbft/cometbft/libs/json"
+ "github.com/stretchr/testify/require"
+)
+
+func TestCreateLoadSignState(t *testing.T) {
+ tmpDir := t.TempDir()
+ path := filepath.Join(tmpDir, "state.json")
+
+ // Make an empty sign state and save it.
+ state := &SignState{
+ FilePath: path,
+ cache: make(map[HRSKey]SignStateConsensus),
+ }
+ state.cond = cond.New(&state.mu)
+
+ // Set state Height to one so we can test if reading and writing is correct.
+ state.Height = 1
+
+ jsonBytes, err := cometjson.MarshalIndent(state, "", " ")
+ if err != nil {
+ fmt.Printf("cometjson.MarshalIndent: %s", err)
+ panic(err)
+ }
+ state.save(jsonBytes)
+
+ stateJSONBytes, err := os.ReadFile(path)
+ require.NoError(t, err)
+
+ newstate := new(SignState)
+ err = cometjson.Unmarshal(stateJSONBytes, &newstate)
+ require.NoError(t, err)
+
+ // Check cond is not equal
+ require.NotEqual(t, state.cond, newstate.cond)
+
+ // Check height is equal
+ require.Equal(t, state.Height, newstate.Height)
+
+ // Why this would ever happen I dont know.
+ newstate.cond = cond.New(&newstate.mu)
+ require.NotEqual(t, state.cond, newstate.cond)
+}
diff --git a/signer/cosigner.go b/signer/cosigner.go
deleted file mode 100644
index 2c39fb12..00000000
--- a/signer/cosigner.go
+++ /dev/null
@@ -1,120 +0,0 @@
-package signer
-
-import (
- "time"
-
- cometcrypto "github.com/cometbft/cometbft/crypto"
- "github.com/strangelove-ventures/horcrux/signer/proto"
-)
-
-// Cosigner interface is a set of methods for an m-of-n threshold signature.
-// This interface abstracts the underlying key storage and management
-type Cosigner interface {
- // Get the ID of the cosigner
- // The ID is the shamir index: 1, 2, etc...
- GetID() int
-
- // Get the P2P URL (GRPC and Raft)
- GetAddress() string
-
- // Get the combined public key
- GetPubKey(chainID string) (cometcrypto.PubKey, error)
-
- VerifySignature(chainID string, payload, signature []byte) bool
-
- // Get nonces for all cosigner shards
- GetNonces(chainID string, hrst HRSTKey) (*CosignerNoncesResponse, error)
-
- // Sign the requested bytes
- SetNoncesAndSign(req CosignerSetNoncesAndSignRequest) (*CosignerSignResponse, error)
-}
-
-// CosignerSignRequest is sent to a co-signer to obtain their signature for the SignBytes
-// The SignBytes should be a serialized block
-type CosignerSignRequest struct {
- ChainID string
- SignBytes []byte
-}
-
-type CosignerSignResponse struct {
- NoncePublic []byte
- Timestamp time.Time
- Signature []byte
-}
-
-type CosignerNonce struct {
- SourceID int
- DestinationID int
- PubKey []byte
- Share []byte
- Signature []byte
-}
-
-func (secretPart *CosignerNonce) toProto() *proto.Nonce {
- return &proto.Nonce{
- SourceID: int32(secretPart.SourceID),
- DestinationID: int32(secretPart.DestinationID),
- PubKey: secretPart.PubKey,
- Share: secretPart.Share,
- Signature: secretPart.Signature,
- }
-}
-
-type CosignerNonces []CosignerNonce
-
-func (secretParts CosignerNonces) toProto() (out []*proto.Nonce) {
- for _, secretPart := range secretParts {
- out = append(out, secretPart.toProto())
- }
- return
-}
-
-func CosignerNonceFromProto(secretPart *proto.Nonce) CosignerNonce {
- return CosignerNonce{
- SourceID: int(secretPart.SourceID),
- DestinationID: int(secretPart.DestinationID),
- PubKey: secretPart.PubKey,
- Share: secretPart.Share,
- Signature: secretPart.Signature,
- }
-}
-
-func CosignerNoncesFromProto(secretParts []*proto.Nonce) []CosignerNonce {
- out := make([]CosignerNonce, len(secretParts))
- for i, secretPart := range secretParts {
- out[i] = CosignerNonceFromProto(secretPart)
- }
- return out
-}
-
-type CosignerSetNonceRequest struct {
- ChainID string
- SourceID int
- PubKey []byte
- Share []byte
- Signature []byte
- Height int64
- Round int64
- Step int8
- Timestamp time.Time
-}
-
-type CosignerSignBlockRequest struct {
- ChainID string
- Block *Block
-}
-
-type CosignerSignBlockResponse struct {
- Signature []byte
-}
-
-type CosignerNoncesResponse struct {
- Nonces []CosignerNonce
-}
-
-type CosignerSetNoncesAndSignRequest struct {
- ChainID string
- Nonces []CosignerNonce
- HRST HRSTKey
- SignBytes []byte
-}
diff --git a/signer/leader.go b/signer/leader.go
deleted file mode 100644
index 3f796a2d..00000000
--- a/signer/leader.go
+++ /dev/null
@@ -1,13 +0,0 @@
-package signer
-
-// Leader is an interface for the detecting if the current cosigner is the leader and performing leader actions.
-type Leader interface {
- // IsLeader returns true if the cosigner is the leader.
- IsLeader() bool
-
- // SignBlock asks the leader to manage the signing of a block.
- SignBlock(CosignerSignBlockRequest) (*CosignerSignBlockResponse, error)
-
- // ShareSigned shares the last signed state with the other cosigners.
- ShareSigned(lss ChainSignStateConsensus) error
-}
diff --git a/signer/proto/cosigner_grpc_server_grpc.pb.go b/signer/proto/cosigner_grpc_server_grpc.pb.go
deleted file mode 100644
index 444fd22c..00000000
--- a/signer/proto/cosigner_grpc_server_grpc.pb.go
+++ /dev/null
@@ -1,249 +0,0 @@
-// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
-// versions:
-// - protoc-gen-go-grpc v1.2.0
-// - protoc v3.21.6
-// source: signer/proto/cosigner_grpc_server.proto
-
-package proto
-
-import (
- context "context"
- grpc "google.golang.org/grpc"
- codes "google.golang.org/grpc/codes"
- status "google.golang.org/grpc/status"
-)
-
-// This is a compile-time assertion to ensure that this generated file
-// is compatible with the grpc package it is being compiled against.
-// Requires gRPC-Go v1.32.0 or later.
-const _ = grpc.SupportPackageIsVersion7
-
-// CosignerGRPCClient is the client API for CosignerGRPC service.
-//
-// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
-type CosignerGRPCClient interface {
- SignBlock(ctx context.Context, in *CosignerGRPCSignBlockRequest, opts ...grpc.CallOption) (*CosignerGRPCSignBlockResponse, error)
- SetNoncesAndSign(ctx context.Context, in *CosignerGRPCSetNoncesAndSignRequest, opts ...grpc.CallOption) (*CosignerGRPCSetNoncesAndSignResponse, error)
- GetNonces(ctx context.Context, in *CosignerGRPCGetNoncesRequest, opts ...grpc.CallOption) (*CosignerGRPCGetNoncesResponse, error)
- TransferLeadership(ctx context.Context, in *CosignerGRPCTransferLeadershipRequest, opts ...grpc.CallOption) (*CosignerGRPCTransferLeadershipResponse, error)
- GetLeader(ctx context.Context, in *CosignerGRPCGetLeaderRequest, opts ...grpc.CallOption) (*CosignerGRPCGetLeaderResponse, error)
-}
-
-type cosignerGRPCClient struct {
- cc grpc.ClientConnInterface
-}
-
-func NewCosignerGRPCClient(cc grpc.ClientConnInterface) CosignerGRPCClient {
- return &cosignerGRPCClient{cc}
-}
-
-func (c *cosignerGRPCClient) SignBlock(ctx context.Context, in *CosignerGRPCSignBlockRequest, opts ...grpc.CallOption) (*CosignerGRPCSignBlockResponse, error) {
- out := new(CosignerGRPCSignBlockResponse)
- err := c.cc.Invoke(ctx, "/proto.CosignerGRPC/SignBlock", in, out, opts...)
- if err != nil {
- return nil, err
- }
- return out, nil
-}
-
-func (c *cosignerGRPCClient) SetNoncesAndSign(ctx context.Context, in *CosignerGRPCSetNoncesAndSignRequest, opts ...grpc.CallOption) (*CosignerGRPCSetNoncesAndSignResponse, error) {
- out := new(CosignerGRPCSetNoncesAndSignResponse)
- err := c.cc.Invoke(ctx, "/proto.CosignerGRPC/SetNoncesAndSign", in, out, opts...)
- if err != nil {
- return nil, err
- }
- return out, nil
-}
-
-func (c *cosignerGRPCClient) GetNonces(ctx context.Context, in *CosignerGRPCGetNoncesRequest, opts ...grpc.CallOption) (*CosignerGRPCGetNoncesResponse, error) {
- out := new(CosignerGRPCGetNoncesResponse)
- err := c.cc.Invoke(ctx, "/proto.CosignerGRPC/GetNonces", in, out, opts...)
- if err != nil {
- return nil, err
- }
- return out, nil
-}
-
-func (c *cosignerGRPCClient) TransferLeadership(ctx context.Context, in *CosignerGRPCTransferLeadershipRequest, opts ...grpc.CallOption) (*CosignerGRPCTransferLeadershipResponse, error) {
- out := new(CosignerGRPCTransferLeadershipResponse)
- err := c.cc.Invoke(ctx, "/proto.CosignerGRPC/TransferLeadership", in, out, opts...)
- if err != nil {
- return nil, err
- }
- return out, nil
-}
-
-func (c *cosignerGRPCClient) GetLeader(ctx context.Context, in *CosignerGRPCGetLeaderRequest, opts ...grpc.CallOption) (*CosignerGRPCGetLeaderResponse, error) {
- out := new(CosignerGRPCGetLeaderResponse)
- err := c.cc.Invoke(ctx, "/proto.CosignerGRPC/GetLeader", in, out, opts...)
- if err != nil {
- return nil, err
- }
- return out, nil
-}
-
-// CosignerGRPCServer is the server API for CosignerGRPC service.
-// All implementations must embed UnimplementedCosignerGRPCServer
-// for forward compatibility
-type CosignerGRPCServer interface {
- SignBlock(context.Context, *CosignerGRPCSignBlockRequest) (*CosignerGRPCSignBlockResponse, error)
- SetNoncesAndSign(context.Context, *CosignerGRPCSetNoncesAndSignRequest) (*CosignerGRPCSetNoncesAndSignResponse, error)
- GetNonces(context.Context, *CosignerGRPCGetNoncesRequest) (*CosignerGRPCGetNoncesResponse, error)
- TransferLeadership(context.Context, *CosignerGRPCTransferLeadershipRequest) (*CosignerGRPCTransferLeadershipResponse, error)
- GetLeader(context.Context, *CosignerGRPCGetLeaderRequest) (*CosignerGRPCGetLeaderResponse, error)
- mustEmbedUnimplementedCosignerGRPCServer()
-}
-
-// UnimplementedCosignerGRPCServer must be embedded to have forward compatible implementations.
-type UnimplementedCosignerGRPCServer struct {
-}
-
-func (UnimplementedCosignerGRPCServer) SignBlock(context.Context, *CosignerGRPCSignBlockRequest) (*CosignerGRPCSignBlockResponse, error) {
- return nil, status.Errorf(codes.Unimplemented, "method SignBlock not implemented")
-}
-func (UnimplementedCosignerGRPCServer) SetNoncesAndSign(context.Context, *CosignerGRPCSetNoncesAndSignRequest) (*CosignerGRPCSetNoncesAndSignResponse, error) {
- return nil, status.Errorf(codes.Unimplemented, "method SetNoncesAndSign not implemented")
-}
-func (UnimplementedCosignerGRPCServer) GetNonces(context.Context, *CosignerGRPCGetNoncesRequest) (*CosignerGRPCGetNoncesResponse, error) {
- return nil, status.Errorf(codes.Unimplemented, "method GetNonces not implemented")
-}
-func (UnimplementedCosignerGRPCServer) TransferLeadership(context.Context, *CosignerGRPCTransferLeadershipRequest) (*CosignerGRPCTransferLeadershipResponse, error) {
- return nil, status.Errorf(codes.Unimplemented, "method TransferLeadership not implemented")
-}
-func (UnimplementedCosignerGRPCServer) GetLeader(context.Context, *CosignerGRPCGetLeaderRequest) (*CosignerGRPCGetLeaderResponse, error) {
- return nil, status.Errorf(codes.Unimplemented, "method GetLeader not implemented")
-}
-func (UnimplementedCosignerGRPCServer) mustEmbedUnimplementedCosignerGRPCServer() {}
-
-// UnsafeCosignerGRPCServer may be embedded to opt out of forward compatibility for this service.
-// Use of this interface is not recommended, as added methods to CosignerGRPCServer will
-// result in compilation errors.
-type UnsafeCosignerGRPCServer interface {
- mustEmbedUnimplementedCosignerGRPCServer()
-}
-
-func RegisterCosignerGRPCServer(s grpc.ServiceRegistrar, srv CosignerGRPCServer) {
- s.RegisterService(&CosignerGRPC_ServiceDesc, srv)
-}
-
-func _CosignerGRPC_SignBlock_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
- in := new(CosignerGRPCSignBlockRequest)
- if err := dec(in); err != nil {
- return nil, err
- }
- if interceptor == nil {
- return srv.(CosignerGRPCServer).SignBlock(ctx, in)
- }
- info := &grpc.UnaryServerInfo{
- Server: srv,
- FullMethod: "/proto.CosignerGRPC/SignBlock",
- }
- handler := func(ctx context.Context, req interface{}) (interface{}, error) {
- return srv.(CosignerGRPCServer).SignBlock(ctx, req.(*CosignerGRPCSignBlockRequest))
- }
- return interceptor(ctx, in, info, handler)
-}
-
-func _CosignerGRPC_SetNoncesAndSign_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
- in := new(CosignerGRPCSetNoncesAndSignRequest)
- if err := dec(in); err != nil {
- return nil, err
- }
- if interceptor == nil {
- return srv.(CosignerGRPCServer).SetNoncesAndSign(ctx, in)
- }
- info := &grpc.UnaryServerInfo{
- Server: srv,
- FullMethod: "/proto.CosignerGRPC/SetNoncesAndSign",
- }
- handler := func(ctx context.Context, req interface{}) (interface{}, error) {
- return srv.(CosignerGRPCServer).SetNoncesAndSign(ctx, req.(*CosignerGRPCSetNoncesAndSignRequest))
- }
- return interceptor(ctx, in, info, handler)
-}
-
-func _CosignerGRPC_GetNonces_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
- in := new(CosignerGRPCGetNoncesRequest)
- if err := dec(in); err != nil {
- return nil, err
- }
- if interceptor == nil {
- return srv.(CosignerGRPCServer).GetNonces(ctx, in)
- }
- info := &grpc.UnaryServerInfo{
- Server: srv,
- FullMethod: "/proto.CosignerGRPC/GetNonces",
- }
- handler := func(ctx context.Context, req interface{}) (interface{}, error) {
- return srv.(CosignerGRPCServer).GetNonces(ctx, req.(*CosignerGRPCGetNoncesRequest))
- }
- return interceptor(ctx, in, info, handler)
-}
-
-func _CosignerGRPC_TransferLeadership_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
- in := new(CosignerGRPCTransferLeadershipRequest)
- if err := dec(in); err != nil {
- return nil, err
- }
- if interceptor == nil {
- return srv.(CosignerGRPCServer).TransferLeadership(ctx, in)
- }
- info := &grpc.UnaryServerInfo{
- Server: srv,
- FullMethod: "/proto.CosignerGRPC/TransferLeadership",
- }
- handler := func(ctx context.Context, req interface{}) (interface{}, error) {
- return srv.(CosignerGRPCServer).TransferLeadership(ctx, req.(*CosignerGRPCTransferLeadershipRequest))
- }
- return interceptor(ctx, in, info, handler)
-}
-
-func _CosignerGRPC_GetLeader_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
- in := new(CosignerGRPCGetLeaderRequest)
- if err := dec(in); err != nil {
- return nil, err
- }
- if interceptor == nil {
- return srv.(CosignerGRPCServer).GetLeader(ctx, in)
- }
- info := &grpc.UnaryServerInfo{
- Server: srv,
- FullMethod: "/proto.CosignerGRPC/GetLeader",
- }
- handler := func(ctx context.Context, req interface{}) (interface{}, error) {
- return srv.(CosignerGRPCServer).GetLeader(ctx, req.(*CosignerGRPCGetLeaderRequest))
- }
- return interceptor(ctx, in, info, handler)
-}
-
-// CosignerGRPC_ServiceDesc is the grpc.ServiceDesc for CosignerGRPC service.
-// It's only intended for direct use with grpc.RegisterService,
-// and not to be introspected or modified (even as a copy)
-var CosignerGRPC_ServiceDesc = grpc.ServiceDesc{
- ServiceName: "proto.CosignerGRPC",
- HandlerType: (*CosignerGRPCServer)(nil),
- Methods: []grpc.MethodDesc{
- {
- MethodName: "SignBlock",
- Handler: _CosignerGRPC_SignBlock_Handler,
- },
- {
- MethodName: "SetNoncesAndSign",
- Handler: _CosignerGRPC_SetNoncesAndSign_Handler,
- },
- {
- MethodName: "GetNonces",
- Handler: _CosignerGRPC_GetNonces_Handler,
- },
- {
- MethodName: "TransferLeadership",
- Handler: _CosignerGRPC_TransferLeadership_Handler,
- },
- {
- MethodName: "GetLeader",
- Handler: _CosignerGRPC_GetLeader_Handler,
- },
- },
- Streams: []grpc.StreamDesc{},
- Metadata: "signer/proto/cosigner_grpc_server.proto",
-}
diff --git a/signer/testdata/rsa_keys.json b/signer/testdata/rsa_keys.json
deleted file mode 100644
index cd1b60c1..00000000
--- a/signer/testdata/rsa_keys.json
+++ /dev/null
@@ -1,9 +0,0 @@
-{
- "rsaKey": "MIIJKAIBAAKCAgEAy3RB4zdFhlpmZQ1Xus+Tp/d7SmVFi8XXxLQJdBB57WV2i78EmtNUZfJHiyril1Mbc4Wzd1634peXNgMCzwKGgzB7hGzoG7BU9ql9cgnQnqHVgnEVX7BFesbOiiiR13ivoI6CsoGPAeOj+z03W18R1XSGpMPy+xeJctOHPEz3gswnkHofCQ8RATpzm/l3fKxBAe3Dtn4rh3p41Hl70tbAOqss9lz48EXvOAfWA16/SJRE39E7hVBI+x3y3PcJ356OjkUfBmt5k2S8zV5Rd8Iy1P9w+bcxFpsu2BkczQQPXElU6VFiZZoAPcpv0d5Xnynd82dmLtohFbqSTPnM/bsexlyMZjf9YfYRTb2rfNWf5R7fHseE7gp8dHAy2fQT2KcNKSYAMkGjgNcWZu8tflvikzoHz8iAlYL6q2bt/plowdJ9TJlOL/G7+Kyuw/+al4EMmmwoH52VXQ7S0k2fbHtek71aDeH8YGKgHhXonXSUzlbVZCkXXXkuzE4J7V5KKqpV1JPiS5ibxNuxGtc8v9joYA1d3w2gslzbzRBbKg4XkLQ9ZA/n7utObOeOI8hgFApBYOqaULHv6nsL+nksziJu02+FGm6o30Fq4PywSeWkVCk7Z0NDfauynFuuKX9cV9ELOrxXIDeUwIGrUNzJLrkF8tL6VlKZpKWQKksnPeDidn0CAwEAAQKCAgAZ/xLkK43QqwBmbRwGnLtrPO4eBW6re24kjjSfBfPuZ4aMOK4n8lTYaerGV4Z4e4AIdM8Hs6yfYWtK1XuoY9Q4Mxu1Qg0ubIuOsP18ctCbVGZpsnVesrFODNUbRi/MbnlSdKMyl+dkAGhVk+7c1/r5YVhK+Va0yr8fUvP2uobtyZRMm64XhDtSAtv+1BN2dLQhwPW+/cQmHXoO/C7cM+CAHpsyJ5MPcIAukqG/8H1Uks1yI9QNJsMMgzkjDtXOIv5oI2Dhex4fvUF6pFCYktHX8YPIBKZbEx0bM6pAcAJecmhNH78I6HKbcqBzGovrpHfdwBqIZgrQMfS7rTeKPDykNZ2aHb3xc2Tv1FOcAx+sVg58eEwyTzhTSriBJVWBlGfHbey09eojRhDMlrMgqTVArT25okKwUF+xl0eKqJlFvspSDN3XV6Yb0D35MXS8qQEFoTyM5b40mUIlgabR7cWu+jPB1sFU3P28NPHRG40fwnr89yYX3gevRPSrigewfVnkb3qMBa/fJ7Khuet7XxWYVCXwLDzRSSgHkEgkY3llc8J0Yg2HHdnNOSLqpRmnRED9li7Ol04Ps6sFB6nVszpEa6D6B7ADg7nVxsHbwrvKZ47Ut8dbGBm9Cpp4hFg9oGcvRdogz2bsjCU4Y90X3nfvR1YIkwoEkj/n5ZbuX1PPKQKCAQEA37ZzyFozo/Y2//heRxWgFPwVzBK27+DYc16WLtZxs+shaiXJ4Zn0DOI5x1VdC50sxHvlERcTQeQhSO+jnXQOkF6YQgylxLuYoFdo2l5jojn2vsHa4Klw9UatpFStCwz+PhD0wK7WhDoEKvwbvQ2wTa/wvDpnAuhhAEh2hMMuDkRpiVulYe40ywQW/NOrfUklAw1D/5NflDGPCYBYreP7pNtYbMRt9zLhOgQSvn9GqbpnnMj88gZDFxNO7jDiUsYO7yFsi01ALJ+T6AfVtKRyOEbjhpOBBpvlpwbUAMHuARjgcTWmvyWPbafIGpiaSX8ThtG8h78n/ITX6+NPF6fIfwKCAQEA6NFO9qLmYJWj8IaJaPKYBB1JdnFXOJvmPiJ4DS8BhLsSoEYsYE83ECXJwTI2F2l6MVyBXq+PPrQKm2vsUEWzzn/Fi+b7jEbjTv379yLylD1fjsMT0NHtN3vq09Yp3kNgTrd1IfCNxZ5A92Vh0f67PjHB3aMXeYd+ydBeIIlLVAgR6nUtkvGmFtuPunUlZiuB6UpMXDjPRN1VrddvQVTgSkPl9WB8wPcShxOz+wL4Hi5DII+ThFdAAh9pnIFaBF1Et/xMl2ss/7hcxqcIItQSBLotU0brPHMvoiSEjHWLuekw/b5noabkrfm8NOhB6Gjrq58oODe9ZrDjiaweh55jAwKCAQEApTqIgW29vlfXf27dkvrx5Q3au4MHAly7AVrW6XkROaVsZI3McYfXrLxZmFQACNfpfKVVJi441u27d7cmzOAu8YosQnw84vT7YVGt67rTM7pD99gN5OjAuSeekETKGeNa1FSJsNZxMe/3rBfQFO3LTVWpJByugINJQYBDqQLPPVJh8EVz/MSG0XsPz2Q2wK4JXBusIVOjwDxqPMZCuQwtjDFFOfBKl81IdCUWAwTWF/3JEQ+RYuAlJSHpphsMzb3iwdOZ67j+sPabs0A2ItliUxZobbj8DvmNwLNWWcjiFIVfH75UjdEcAg1tydbz/VyR+31lFY2l5ufm4h5dCEev2QKCAQAX543NAxLWbebkRlwLe4UiPwOQ9rg25sLwNEfRSrdEMpUKAcqCpP+JV+fsP0SQiNL0CIR7/Vie3ouMQ7uCznVUyYe2AqRnVcv3C1r4mA0CLX8HQH5jXXqWzNFiqMWpvY9A5dNQBcv4s3QGMtGlZxtAmolGQX2ii8f33r4bZx1l5mI4iYmBYfBkvmx2f5q0b9kp4+gNPAQEFRm7/Le+pIFW/ru4wwxsH7I2Tk6XgkmJh8R6rmM+HltDHIiSejGM6yqoHW6byXRYWUylVPcf5FhpRdhriYeTsFv+sPMvHM6Y6xmNpCQt0939AvxRDlveCg/Qkknl48s9pQHn29VSpW+TAoIBAE862157emwegrRYu66ENMMNLbF6YxBpL47iWC1NQ4/8aM5i58edv1VWUw5R441uvAGXk7uzsYkrxmp0nj6UANkjq6n06mayN90kbg4FvjAzEtbbAu8byap+B5xLSuetIc+dVqACKihQ09zwm3d/LFtbrgZ2KGiw/RfvMxxT0HYp9A7NdYT4nf2Aqa3UR4SuxWm4bWWLHHMGeS4N9MuwFP64jLgLrXzyB851Avuz9LJCpNAflE9SQUvTqGwpFvsgEwQcGH+5vcvcBENCYbAwq5hmMnzrAXsA1NnJNqn+oqXG8GIogG7DOa4965QL60TwDu9s/opzV2bMVhVtxDqKSfo=",
- "rsaPubs": [
- "MIICCgKCAgEAzo2bGRRrwn1/TFlkJ9yqvOcx0BYvmay+rPQFnDFsKxb+WHHLtwn/juxY0Ub+ABwCgJgBUr4k3G9piFYwtL0R3ton6UulwYMgNQ6cnn8/zmAx/STP/WGYKXRtTR80csC+u8g/kzUK/lX2pGz77BLNxflKf/yfnm3wkCcJecnv2PLW84J3/s6b3TUkS+ygUQL3SB+IN7dI/i1pls7my6pCTOJxIu7TJ+PPahyDkRhE0OapjH0OQIbHXNeCqe71uQwALdf1dwTDl2JeIL7jhGWB8xb2PfeLX+VZsOWUR0NPfs83viS+Pjtz6ndYX1+3+BQxOIutnkUC6IwSBqsG+M2cqElETIgUHpxqRl0QtReq18+GTX9CfFB5hmWgLlGICij9Lnz0zpwtyIQJXn2Cny8XeWi8E9uKpi+4MNkDqwPd2U+wIXBPVBgqPjTByLeish+VaxKV2bHzqManB5WHa0g7WDK9p8OdZ7To8miJF+hdqOZMHnxThY/hr0102ffOq8XCDIfm873Ie2Cn/+KBHwCc6e7XO5ohWKm9WQbsxpmpn3+ru1ekWTkqC8YC7FFpljMCpl9NiGz4edVzSnnL8OU12M1pofEwpbMtlNCzaVJkMzfo9jDRoWxDyKffRYbdp93V1Oio0ab2ou9uZ0Jx0mXIpLyvznRNmDEsj5nrWmbW5jcCAwEAAQ==",
- "MIICCgKCAgEA83UMSAbKSL4/W9VAzn+XjqCmhl8og6BoZvukS1pQI0JFrox63hJYavHTQB0DO2iXomfpm9d+J8NHsBsWf7DD/9aNaByGRJ0k5Lde64FfTj6LP9I5yRoKuGGQ0Heuvuisz9DMWRyhkO9hJiyedX7VdPx3VdUW4AX+FWyJ1pKpj0g/s8eYrUFyzISdoq/pRwkVkzHpXqFh3L5ASUjf9eQXGYsQsDI0UDuzZdYD4nitQ5Q0POM7jCgSQQ8d/b0eaF2hCzbZ1UWKx8LzCU7j4NRqrYJluRqkxeEtBeZsq7QX6Hs13tg+wKKCkOI+wt/1tifLE8IA3es0pXm0UstVduaTMeFtLTvIYE9E/0yFC23aFydz1Fny6HBjpfNo6BgzNCurMziOdpiuLy+7luPM+SBJ3YV0D9TVU8Lo0vawPccj3tcKmozeJdBhuedXWAm00mlCw+LueKBUVxti2kwHiDjBDbLDymZYZHR8HYI0KsrycsvemTotZzYXgDjyRful7mPLGecJhRye7xNX9lVUse81C94gmdZXVL2GKY1PquWJvgazg99gta62GrRj127vDcS2UI+6/4aTJwQFvRqWRLvS/MIJyq5eiq1WyDLOT8dOyBlb7+BV55cB7JUTiO7MsMNaX0h/C3iGrTOnh8rmC/20ygHqZC3E1Lw0SezI2r1NzzcCAwEAAQ==",
- "MIICCgKCAgEAy3RB4zdFhlpmZQ1Xus+Tp/d7SmVFi8XXxLQJdBB57WV2i78EmtNUZfJHiyril1Mbc4Wzd1634peXNgMCzwKGgzB7hGzoG7BU9ql9cgnQnqHVgnEVX7BFesbOiiiR13ivoI6CsoGPAeOj+z03W18R1XSGpMPy+xeJctOHPEz3gswnkHofCQ8RATpzm/l3fKxBAe3Dtn4rh3p41Hl70tbAOqss9lz48EXvOAfWA16/SJRE39E7hVBI+x3y3PcJ356OjkUfBmt5k2S8zV5Rd8Iy1P9w+bcxFpsu2BkczQQPXElU6VFiZZoAPcpv0d5Xnynd82dmLtohFbqSTPnM/bsexlyMZjf9YfYRTb2rfNWf5R7fHseE7gp8dHAy2fQT2KcNKSYAMkGjgNcWZu8tflvikzoHz8iAlYL6q2bt/plowdJ9TJlOL/G7+Kyuw/+al4EMmmwoH52VXQ7S0k2fbHtek71aDeH8YGKgHhXonXSUzlbVZCkXXXkuzE4J7V5KKqpV1JPiS5ibxNuxGtc8v9joYA1d3w2gslzbzRBbKg4XkLQ9ZA/n7utObOeOI8hgFApBYOqaULHv6nsL+nksziJu02+FGm6o30Fq4PywSeWkVCk7Z0NDfauynFuuKX9cV9ELOrxXIDeUwIGrUNzJLrkF8tL6VlKZpKWQKksnPeDidn0CAwEAAQ=="
- ],
- "id": 3
-}
\ No newline at end of file
diff --git a/test/go.mod b/test/go.mod
index 5c8df641..7dac3024 100644
--- a/test/go.mod
+++ b/test/go.mod
@@ -38,9 +38,6 @@ require (
github.com/ComposableFi/go-subkey/v2 v2.0.0-tm03420 // indirect
github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e // indirect
github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec // indirect
- github.com/Jille/raft-grpc-leader-rpc v1.1.0 // indirect
- github.com/Jille/raft-grpc-transport v1.4.0 // indirect
- github.com/Jille/raftadmin v1.2.0 // indirect
github.com/Microsoft/go-winio v0.6.0 // indirect
github.com/StirlingMarketingGroup/go-namecase v1.0.0 // indirect
github.com/armon/go-metrics v0.4.1 // indirect
@@ -50,7 +47,6 @@ require (
github.com/beorn7/perks v1.0.1 // indirect
github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect
github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816 // indirect
- github.com/boltdb/bolt v1.3.1 // indirect
github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect
github.com/cenkalti/backoff/v4 v4.1.3 // indirect
github.com/cespare/xxhash v1.1.0 // indirect
@@ -88,7 +84,6 @@ require (
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/dvsekhvalnov/jose2go v1.5.0 // indirect
github.com/ethereum/go-ethereum v1.12.0 // indirect
- github.com/fatih/color v1.13.0 // indirect
github.com/felixge/httpsnoop v1.0.2 // indirect
github.com/fsnotify/fsnotify v1.6.0 // indirect
github.com/gin-gonic/gin v1.9.1 // indirect
@@ -120,19 +115,13 @@ require (
github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect
github.com/gtank/merlin v0.1.1 // indirect
github.com/gtank/ristretto255 v0.1.2 // indirect
- github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-getter v1.7.1 // indirect
- github.com/hashicorp/go-hclog v1.5.0 // indirect
github.com/hashicorp/go-immutable-radix v1.3.1 // indirect
- github.com/hashicorp/go-msgpack v1.1.5 // indirect
- github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/hashicorp/go-safetemp v1.0.0 // indirect
github.com/hashicorp/go-version v1.6.0 // indirect
github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
- github.com/hashicorp/raft v1.5.0 // indirect
- github.com/hashicorp/raft-boltdb/v2 v2.2.2 // indirect
github.com/hdevalence/ed25519consensus v0.1.0 // indirect
github.com/holiman/uint256 v1.2.2-0.20230321075855-87b91420868c // indirect
github.com/huandu/skiplist v1.2.0 // indirect
diff --git a/test/go.sum b/test/go.sum
index 185f8691..ac749a30 100644
--- a/test/go.sum
+++ b/test/go.sum
@@ -221,18 +221,11 @@ github.com/ChainSafe/go-schnorrkel v1.0.0 h1:3aDA67lAykLaG1y3AOjs88dMxC88PgUuHRr
github.com/ChainSafe/go-schnorrkel v1.0.0/go.mod h1:dpzHYVxLZcp8pjlV+O+UR8K0Hp/z7vcchBSbMBEhCw4=
github.com/ComposableFi/go-subkey/v2 v2.0.0-tm03420 h1:oknQF/iIhf5lVjbwjsVDzDByupRhga8nhA3NAmwyHDA=
github.com/ComposableFi/go-subkey/v2 v2.0.0-tm03420/go.mod h1:KYkiMX5AbOlXXYfxkrYPrRPV6EbVUALTQh5ptUOJzu8=
-github.com/DataDog/datadog-go v2.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e h1:ahyvB3q25YnZWly5Gq1ekg6jcmWaGj/vG/MhF4aisoc=
github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:kGUqhHd//musdITWjFvNTHn90WG9bMLBEPQZ17Cmlpw=
github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec h1:1Qb69mGp/UtRPn422BH4/Y4Q3SLUrD9KHuDkm8iodFc=
github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec/go.mod h1:CD8UlnlLDiqb36L110uqiP2iSflVjx9g/3U9hCI4q2U=
-github.com/Jille/raft-grpc-leader-rpc v1.1.0 h1:u36rmA4tjp+4FSdZ17jg/1sfSCYNQIe5bzzwvW0iVTM=
-github.com/Jille/raft-grpc-leader-rpc v1.1.0/go.mod h1:l+pK+uPuqpFDFcPmyUPSng4257UXrST0Vc3Lo4XwVB0=
-github.com/Jille/raft-grpc-transport v1.4.0 h1:Kwk+IceQD8MpLKOulBu2ignX+aZAEjOhffEhN44sdzQ=
-github.com/Jille/raft-grpc-transport v1.4.0/go.mod h1:afVUd8LQKUUo3V/ToLBH3mbSyvivRlMYCDK0eJRGTfQ=
-github.com/Jille/raftadmin v1.2.0 h1:hMLFUK7iKpeXP+CoIhNMWj+F53XOLSjMDSia0C60cps=
-github.com/Jille/raftadmin v1.2.0/go.mod h1:vtVEpToPGTUPVwwunypWDpi69JpdnHMhWRUlc/65U+Y=
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
github.com/Microsoft/go-winio v0.6.0 h1:slsWYD/zyx7lCXoZVlvQrj0hPTM1HI4+v1sIda2yDvg=
github.com/Microsoft/go-winio v0.6.0/go.mod h1:cTAf44im0RAYeL23bpB+fzCyDH2MJiz2BO69KH/soAE=
@@ -261,8 +254,6 @@ github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
-github.com/armon/go-metrics v0.0.0-20190430140413-ec5e00d3c878/go.mod h1:3AMJUQhVx52RsWOnlkpikZr01T/yAVN2gn0861vByNg=
-github.com/armon/go-metrics v0.3.9/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc=
github.com/armon/go-metrics v0.4.1 h1:hR91U9KYmb6bLBYLQjyM+3j+rcd/UhE+G78SFnF8gJA=
github.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4=
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
@@ -286,8 +277,6 @@ github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d/go.mod h1:6QX/PXZ
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816 h1:41iFGWnSlI2gVpmOtVTJZNodLdLQLn/KsJqFvXwnd/s=
github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
-github.com/boltdb/bolt v1.3.1 h1:JQmyP4ZBrce+ZQu0dY660FMfatumYDLun9hBCUVIkF4=
-github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps=
github.com/btcsuite/btcd/btcec/v2 v2.3.2 h1:5n0X6hX0Zk+6omWcihdYvdAlGf2DfasC0GMf7DClJ3U=
github.com/btcsuite/btcd/btcec/v2 v2.3.2/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04=
github.com/btcsuite/btcd/btcutil v1.1.2 h1:XLMbX8JQEiwMcYft2EGi8zPUkoa0abKIU6/BJSRsjzQ=
@@ -454,9 +443,6 @@ github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7
github.com/ethereum/go-ethereum v1.12.0 h1:bdnhLPtqETd4m3mS8BGMNvBTf36bO5bx/hxE2zljOa0=
github.com/ethereum/go-ethereum v1.12.0/go.mod h1:/oo2X/dZLJjf2mJ6YT9wcWxa4nNJDBKDBU6sFIpx1Gs=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
-github.com/fatih/color v1.12.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM=
-github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w=
-github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/felixge/httpsnoop v1.0.2 h1:+nS9g82KMXccJ/wp0zyRW9ZBHFETmMGtkk+2CTTrW4o=
github.com/felixge/httpsnoop v1.0.2/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
@@ -591,7 +577,6 @@ github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN
github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
-github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
@@ -672,28 +657,17 @@ github.com/gtank/ristretto255 v0.1.2/go.mod h1:Ph5OpO6c7xKUGROZfWVLiJf9icMDwUeIv
github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE=
github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
-github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
-github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ=
github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=
github.com/hashicorp/go-getter v1.7.1 h1:SWiSWN/42qdpR0MdhaOc/bLR48PLuP1ZQtYLRlM69uY=
github.com/hashicorp/go-getter v1.7.1/go.mod h1:W7TalhMmbPmsSMdNjD0ZskARur/9GJ17cfHTRtXV744=
-github.com/hashicorp/go-hclog v0.9.1/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ=
-github.com/hashicorp/go-hclog v0.16.2/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
-github.com/hashicorp/go-hclog v1.5.0 h1:bI2ocEMgcVlz55Oj1xZNBsVi900c7II+fWDyV9o+13c=
-github.com/hashicorp/go-hclog v1.5.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc=
github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
-github.com/hashicorp/go-msgpack v0.5.5/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
-github.com/hashicorp/go-msgpack v1.1.5 h1:9byZdVjKTe5mce63pRVNP1L7UAmdHOTEMGehn6KvJWs=
-github.com/hashicorp/go-msgpack v1.1.5/go.mod h1:gWVc3sv/wbDmR3rQsj1CAktEZzoz1YNK9NfGLXJ69/4=
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
-github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
-github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs=
github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
github.com/hashicorp/go-safetemp v1.0.0 h1:2HR189eFNrjHQyENnQMMpCiBAsRxzbTMIgBhEyExpmo=
@@ -709,7 +683,6 @@ github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09
github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
-github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d h1:dg1dEPuWpEqDnvIw251EVy4zlP8gWbsGj4BsUKCRpYs=
github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
@@ -717,16 +690,6 @@ github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
-github.com/hashicorp/raft v1.1.0/go.mod h1:4Ak7FSPnuvmb0GV6vgIAJ4vYT4bek9bb6Q+7HVbyzqM=
-github.com/hashicorp/raft v1.1.2/go.mod h1:vPAJM8Asw6u8LxC3eJCUZmRP/E4QmUGE1R7g7k8sG/8=
-github.com/hashicorp/raft v1.3.7/go.mod h1:4Ak7FSPnuvmb0GV6vgIAJ4vYT4bek9bb6Q+7HVbyzqM=
-github.com/hashicorp/raft v1.5.0 h1:uNs9EfJ4FwiArZRxxfd/dQ5d33nV31/CdCHArH89hT8=
-github.com/hashicorp/raft v1.5.0/go.mod h1:pKHB2mf/Y25u3AHNSXVRv+yT+WAnmeTX0BwVppVQV+M=
-github.com/hashicorp/raft-boltdb v0.0.0-20171010151810-6e5ba93211ea/go.mod h1:pNv7Wc3ycL6F5oOWn+tPGo2gWD4a5X+yp/ntwdKLjRk=
-github.com/hashicorp/raft-boltdb v0.0.0-20210409134258-03c10cc3d4ea h1:RxcPJuutPRM8PUOyiweMmkuNO+RJyfy2jds2gfvgNmU=
-github.com/hashicorp/raft-boltdb v0.0.0-20210409134258-03c10cc3d4ea/go.mod h1:qRd6nFJYYS6Iqnc/8HcUmko2/2Gw8qTFEmxDLii6W5I=
-github.com/hashicorp/raft-boltdb/v2 v2.2.2 h1:rlkPtOllgIcKLxVT4nutqlTH2NRFn+tO1wwZk/4Dxqw=
-github.com/hashicorp/raft-boltdb/v2 v2.2.2/go.mod h1:N8YgaZgNJLpZC+h+by7vDu5rzsRgONThTEeUS3zWbfY=
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
github.com/hdevalence/ed25519consensus v0.1.0 h1:jtBwzzcHuTmFrQN6xQZn6CQEO/V9f7HsjsjeEZ6auqU=
github.com/hdevalence/ed25519consensus v0.1.0/go.mod h1:w3BHWjwJbFU29IRHL1Iqkw3sus+7FctEyM4RqDxYNzo=
@@ -795,7 +758,6 @@ github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
-github.com/kraken-hpc/go-fork v0.1.1 h1:O3X/ynoNy/eS7UIcZYef8ndFq2RXEIOue9kZqyzF0Sk=
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q=
github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw=
@@ -815,16 +777,11 @@ github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3v
github.com/manifoldco/promptui v0.9.0 h1:3V4HzJk1TtXW1MTZMP7mdlwbBpIinw3HztaIlYthEiA=
github.com/manifoldco/promptui v0.9.0/go.mod h1:ka04sppxSGFAtxX0qhlYQjISsg9mR4GWtQEhdbn6Pgg=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
-github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
-github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
-github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
-github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
-github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
@@ -969,7 +926,6 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
-github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM=
github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs=
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og=
@@ -985,7 +941,6 @@ github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6T
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4=
github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w=
-github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA=
@@ -995,7 +950,6 @@ github.com/prometheus/common v0.15.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16
github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM=
github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
-github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
@@ -1141,7 +1095,6 @@ gitlab.com/unit410/edwards25519 v0.0.0-20220725154547-61980033348e/go.mod h1:lTS
gitlab.com/unit410/threshold-ed25519 v0.0.0-20220725172740-6ee731f539ac h1:SUxQNWwBUVFdvRP72Wi1wZ8K2iD7+SXFfMUMJyMCJjc=
gitlab.com/unit410/threshold-ed25519 v0.0.0-20220725172740-6ee731f539ac/go.mod h1:2TURxKmaBFbTDxXQa+B2nGuKSRWD0Jlcc3LETTAnSS0=
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
-go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
go.etcd.io/bbolt v1.3.7 h1:j+zJOnnEjF/kyHlDDgGnVL/AIqIJPq8UoB2GSNfkUfQ=
go.etcd.io/bbolt v1.3.7/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw=
go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg=
@@ -1163,7 +1116,6 @@ go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ=
go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
go.uber.org/goleak v1.1.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA=
-go.uber.org/goleak v1.1.12/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
@@ -1281,7 +1233,6 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
-golang.org/x/net v0.0.0-20210907225631-ff17edfbf26d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
@@ -1351,13 +1302,11 @@ golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5h
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190130150945-aca44879d564/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190523142557-0e01d883c5c5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -1367,7 +1316,6 @@ golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -1482,7 +1430,6 @@ golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
-golang.org/x/tools v0.0.0-20190424220101-1e8e1cfdf96b/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
diff --git a/test/horcrux_test.go b/test/horcrux_test.go
index 3ccc9a1c..d8375f73 100644
--- a/test/horcrux_test.go
+++ b/test/horcrux_test.go
@@ -3,11 +3,13 @@ package test
import (
"context"
"fmt"
+
+ "github.com/strangelove-ventures/horcrux/pkg/cosigner"
+
"sync"
"testing"
"github.com/cometbft/cometbft/crypto"
- "github.com/strangelove-ventures/horcrux/signer"
interchaintest "github.com/strangelove-ventures/interchaintest/v7"
"github.com/strangelove-ventures/interchaintest/v7/chain/cosmos"
"github.com/strangelove-ventures/interchaintest/v7/ibc"
@@ -23,62 +25,64 @@ const (
)
// Test2Of3SignerOneSentry will spin up a chain with one single-node validator and one horcrux validator
-// the horcrux validator will have three cosigner nodes with a threshold of two, and one sentry node
+// the horcrux validator will have three pcosigners nodes with a threshold of two, and one sentry node
func Test2Of3SignerOneSentry(t *testing.T) {
testChainSingleNodeAndHorcruxThreshold(t, 2, 3, 2, 1, 1)
}
// Test2Of3SignerTwoSentries will spin up a chain with one single-node validator and one horcrux validator
-// the horcrux validator will have three cosigner nodes with a threshold of two, and two sentry nodes
+// the horcrux validator will have three pcosigners nodes with a threshold of two, and two sentry nodes
// checks that no slashing occurs
func Test2Of3SignerTwoSentries(t *testing.T) {
testChainSingleNodeAndHorcruxThreshold(t, 2, 3, 2, 2, 2)
}
// Test2Of3SignerThreeSentries will spin up a chain with one single-node validator and one horcrux validator
-// the horcrux validator will have three cosigner nodes with a threshold of two, and three sentry nodes
-// where each cosigner connects to all sentries
+// the horcrux validator will have three pcosigners nodes with a threshold of two, and three sentry nodes
+// where each pcosigners connects to all sentries
func Test2Of3SignerThreeSentries(t *testing.T) {
testChainSingleNodeAndHorcruxThreshold(t, 2, 3, 2, 3, 3)
}
-// Test2Of3SignerThreeSentriesUniqueConnection will spin up a chain with one single-node validator and one horcrux validator
-// the horcrux validator will have three cosigner nodes with a threshold of two, and three sentry nodes
-// where each cosigner only connects to one sentry
+// Test2Of3SignerThreeSentriesUniqueConnection will spin up a chain with one single-node validator
+// and one horcrux validator.
+// The horcrux validator will have three pcosigners nodes with a threshold of two, and three sentry nodes
+// where each pcosigners only connects to one sentry
func Test2Of3SignerThreeSentriesUniqueConnection(t *testing.T) {
testChainSingleNodeAndHorcruxThreshold(t, 2, 3, 2, 3, 1)
}
// Test2Of3SignerOneSentry will spin up a chain with one single-node validator and one horcrux validator
-// the horcrux validator will have three cosigner nodes with a threshold of two, and one sentry node
+// the horcrux validator will have three pcosigners nodes with a threshold of two, and one sentry node
func Test3Of5SignerOneSentry(t *testing.T) {
testChainSingleNodeAndHorcruxThreshold(t, 2, 5, 3, 1, 1)
}
// Test3Of5SignerTwoSentries will spin up a chain with one single-node validator and one horcrux validator
-// the horcrux validator will have five cosigner nodes with a threshold of three, and two sentry nodes
-// where each cosigner connects to all sentries.
+// the horcrux validator will have five pcosigners nodes with a threshold of three, and two sentry nodes
+// where each pcosigners connects to all sentries.
func Test3Of5SignerTwoSentries(t *testing.T) {
testChainSingleNodeAndHorcruxThreshold(t, 2, 5, 3, 2, 2)
}
// Test3Of5SignerFiveSentries will spin up a chain with one single-node validator and one horcrux validator
-// the horcrux validator will have five cosigner nodes with a threshold of three, and five sentry nodes
-// where each cosigner connects to all sentries.
+// the horcrux validator will have five pcosigners nodes with a threshold of three, and five sentry nodes
+// where each cosign connects to all sentries.
func Test3Of5SignerFiveSentries(t *testing.T) {
testChainSingleNodeAndHorcruxThreshold(t, 2, 5, 3, 5, 5)
}
-// Test3Of5SignerFiveSentriesUniqueConnection will spin up a chain with one single-node validator and one horcrux validator
-// the horcrux validator will have three cosigner nodes with a threshold of two, and three sentry nodes
-// where each cosigner only connects to one sentry.
+// Test3Of5SignerFiveSentriesUniqueConnection will spin up a chain
+// with one single-node validator and one horcrux validator.
+// The horcrux validator will have three cosign nodes with a threshold of two, and three sentry nodes
+// where each cosign only connects to one sentry.
func Test3Of5SignerFiveSentriesUniqueConnection(t *testing.T) {
testChainSingleNodeAndHorcruxThreshold(t, 2, 5, 3, 5, 1)
}
// Test4Of7SignerTwoSentries will spin up a chain with one single-node validator and one horcrux validator
-// the horcrux validator will have seven cosigner nodes with a threshold of four, and two sentry nodes
-// where each cosigner connects to all sentries.
+// the horcrux validator will have seven cosign nodes with a threshold of four, and two sentry nodes
+// where each cosign connects to all sentries.
func Test4Of7SignerTwoSentries(t *testing.T) {
testChainSingleNodeAndHorcruxThreshold(t, 2, 7, 4, 2, 2)
}
@@ -124,7 +128,8 @@ func TestUpgradeValidatorToHorcrux(t *testing.T) {
err := v.StopContainer(ctx)
require.NoError(t, err)
- pubKey, err := convertValidatorToHorcrux(ctx, logger, client, network, v, totalSigners, threshold, cosmos.ChainNodes{v}, sentriesPerSigner)
+ pubKey, err := convertValidatorToHorcrux(
+ ctx, logger, client, network, v, totalSigners, threshold, cosmos.ChainNodes{v}, sentriesPerSigner)
require.NoError(t, err)
err = v.StartContainer(ctx)
@@ -163,7 +168,7 @@ func TestDownedSigners2of3(t *testing.T) {
t.Logf("{%s} -> Stopping signer...", cosigner.Name())
require.NoError(t, cosigner.StopContainer(ctx))
- t.Logf("{%s} -> Waiting for blocks after stopping cosigner {%s}", ourValidator.Name(), cosigner.Name())
+ t.Logf("{%s} -> Waiting for blocks after stopping pcosigners {%s}", ourValidator.Name(), cosigner.Name())
require.NoError(t, testutil.WaitForBlocks(ctx, 5, cw.chain))
requireHealthyValidator(t, ourValidator, pubKey.Address())
@@ -171,7 +176,7 @@ func TestDownedSigners2of3(t *testing.T) {
t.Logf("{%s} -> Restarting signer...", cosigner.Name())
require.NoError(t, cosigner.StartContainer(ctx))
- t.Logf("{%s} -> Waiting for blocks after restarting cosigner {%s}", ourValidator.Name(), cosigner.Name())
+ t.Logf("{%s} -> Waiting for blocks after restarting pcosigners {%s}", ourValidator.Name(), cosigner.Name())
require.NoError(t, testutil.WaitForBlocks(ctx, 5, cw.chain))
requireHealthyValidator(t, ourValidator, pubKey.Address())
@@ -213,18 +218,18 @@ func TestDownedSigners3of5(t *testing.T) {
require.NoError(t, cosigner1.StopContainer(ctx))
t.Logf("{%s} -> Stopping signer...", cosigner2.Name())
require.NoError(t, cosigner2.StopContainer(ctx))
- t.Logf("{%s} -> Waiting for blocks after stopping cosigner {%s}", ourValidator.Name(), cosigner1.Name())
+ t.Logf("{%s} -> Waiting for blocks after stopping pcosigners {%s}", ourValidator.Name(), cosigner1.Name())
} else {
t.Logf("{%s} -> Stopping signer...", cosigner2.Name())
require.NoError(t, cosigner2.StopContainer(ctx))
}
- t.Logf("{%s} -> Waiting for blocks after stopping cosigner {%s}", ourValidator.Name(), cosigner2.Name())
+ t.Logf("{%s} -> Waiting for blocks after stopping pcosigners {%s}", ourValidator.Name(), cosigner2.Name())
require.NoError(t, testutil.WaitForBlocks(ctx, 5, cw.chain))
requireHealthyValidator(t, ourValidator, pubKey.Address())
- t.Logf("{%s} -> Restarting cosigner...", cosigner1.Name())
+ t.Logf("{%s} -> Restarting pcosigners...", cosigner1.Name())
require.NoError(t, cosigner1.StartContainer(ctx))
require.NoError(t, testutil.WaitForBlocks(ctx, 5, cw.chain))
@@ -264,7 +269,7 @@ func TestLeaderElection2of3(t *testing.T) {
t.Logf("{%s} -> Waiting for signed blocks with signer as leader {%s}", ourValidator.Name(), cosigner.Name())
- // Make sure all cosigners have the same leader
+ // Make sure all pcosigners have the same leader
for _, s := range cosigners {
s := s
eg.Go(func() error {
@@ -314,7 +319,8 @@ func TestChainPureHorcrux(t *testing.T) {
totalValidators: totalValidators,
totalSentries: 1 + totalValidators*(sentriesPerValidator-1),
modifyGenesis: modifyGenesisStrictUptime,
- preGenesis: preGenesisAllHorcruxThreshold(ctx, logger, client, network, signersPerValidator, threshold, sentriesPerValidator, sentriesPerSigner, pubKeys),
+ preGenesis: preGenesisAllHorcruxThreshold(
+ ctx, logger, client, network, signersPerValidator, threshold, sentriesPerValidator, sentriesPerSigner, pubKeys),
}
startChains(
@@ -352,13 +358,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([]cosigner.CosignEd25519Key, totalSigners),
}
}
cosignerSidecars := make(cosmos.SidecarProcesses, totalSigners)
- eciesShards, err := signer.CreateCosignerECIESShards(totalSigners)
+ eciesShards, err := cosigner.CreateCosignerECIESShards(totalSigners)
require.NoError(t, err)
var wg sync.WaitGroup
@@ -392,7 +398,7 @@ func TestMultipleChainHorcrux(t *testing.T) {
if i == 0 {
for j := 0; j < totalSigners; j++ {
- cosigner, err := horcruxSidecar(ctx, firstSentry, fmt.Sprintf("cosigner-%d", j+1), client, network)
+ cosigner, err := horcruxSidecar(ctx, firstSentry, fmt.Sprintf("pcosigners-%d", j+1), client, network)
if err != nil {
wg.Done()
return err
@@ -409,7 +415,7 @@ func TestMultipleChainHorcrux(t *testing.T) {
wg.Done()
- // wait for all cosigners to be started before continuing to start the chain.
+ // wait for all pcosigners to be started before continuing to start the chain.
<-cosignersStarted
return nil
@@ -435,7 +441,10 @@ func TestMultipleChainHorcrux(t *testing.T) {
chains[i] = cw.chain
}
- testutil.WaitForBlocks(ctx, 20, chains...)
+ err = testutil.WaitForBlocks(ctx, 20, chains...)
+ if err != nil {
+ t.Logf("Error {WaitForBlocks} -> {%v}", err)
+ }
for i, p := range pubKeys {
requireHealthyValidator(t, chainWrappers[i].chain.Validators[0], p.Address())
@@ -444,14 +453,14 @@ func TestMultipleChainHorcrux(t *testing.T) {
type cosignerChainConfig struct {
chainID string
- shards []signer.CosignerEd25519Key
+ shards []cosigner.CosignEd25519Key
sentries []cosmos.ChainNodes
}
func configureAndStartSidecars(
ctx context.Context,
t *testing.T,
- eciesShards []signer.CosignerECIESKey,
+ eciesShards []cosigner.CosignEciesKey,
cosignerSidecars cosmos.SidecarProcesses,
threshold int,
wg *sync.WaitGroup,
@@ -463,29 +472,29 @@ func configureAndStartSidecars(
totalSigners := len(cosignerSidecars)
- cosignersConfig := make(signer.CosignersConfig, totalSigners)
- for i, cosigner := range cosignerSidecars {
- cosignersConfig[i] = signer.CosignerConfig{
+ cosignersConfig := make(cosigner.CosignersConfig, totalSigners)
+ for i, cosign := range cosignerSidecars {
+ cosignersConfig[i] = cosigner.CosignConfig{
ShardID: i + 1,
- P2PAddr: fmt.Sprintf("tcp://%s:%s", cosigner.HostName(), signerPort),
+ P2PAddr: fmt.Sprintf("tcp://%s:%s", cosign.HostName(), signerPort),
}
}
var eg errgroup.Group
- for i, cosigner := range cosignerSidecars {
+ for i, cosign := range cosignerSidecars {
numSentries := 0
for _, chainConfig := range chainConfigs {
numSentries += len(chainConfig.sentries[i])
}
- chainNodes := make(signer.ChainNodes, 0, numSentries)
+ chainNodes := make(cosigner.ChainNodes, 0, numSentries)
ed25519Shards := make([]chainEd25519Shard, len(chainConfigs))
for j, chainConfig := range chainConfigs {
for _, sentry := range chainConfig.sentries[i] {
- chainNodes = append(chainNodes, signer.ChainNode{
+ chainNodes = append(chainNodes, cosigner.ChainNode{
PrivValAddr: fmt.Sprintf("tcp://%s:1234", sentry.HostName()),
})
}
@@ -496,9 +505,9 @@ func configureAndStartSidecars(
}
}
- config := signer.Config{
- SignMode: signer.SignModeThreshold,
- ThresholdModeConfig: &signer.ThresholdModeConfig{
+ config := cosigner.Config{
+ SignMode: cosigner.SignModeThreshold,
+ ThresholdModeConfig: &cosigner.ThresholdModeConfig{
Threshold: threshold,
Cosigners: cosignersConfig,
GRPCTimeout: "1500ms",
@@ -507,25 +516,25 @@ func configureAndStartSidecars(
ChainNodes: chainNodes,
}
- cosigner := cosigner
+ cosign := cosign
i := i
- // configure and start cosigner in parallel
+ // configure and start cosigners in parallel
eg.Go(func() error {
- if err := writeConfigAndKeysThreshold(ctx, cosigner, config, eciesShards[i], ed25519Shards...); err != nil {
+ if err := writeConfigAndKeysThreshold(ctx, cosign, config, eciesShards[i], ed25519Shards...); err != nil {
return err
}
- if err := cosigner.CreateContainer(ctx); err != nil {
+ if err := cosign.CreateContainer(ctx); err != nil {
return err
}
- return cosigner.StartContainer(ctx)
+ return cosign.StartContainer(ctx)
})
}
require.NoError(t, eg.Wait())
- // signal to pre-genesis that all cosigners have been started and chain start can proceed.
+ // signal to pre-genesis that all pcosigners have been started and chain start can proceed.
close(cosignersStarted)
}
diff --git a/test/validator.go b/test/validator.go
index f26b3e00..28cf4d6f 100644
--- a/test/validator.go
+++ b/test/validator.go
@@ -14,7 +14,7 @@ import (
"github.com/cosmos/cosmos-sdk/types/bech32"
slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types"
"github.com/docker/docker/client"
- "github.com/strangelove-ventures/horcrux/signer/proto"
+ "github.com/strangelove-ventures/horcrux/pkg/proto"
interchaintest "github.com/strangelove-ventures/interchaintest/v7"
"github.com/strangelove-ventures/interchaintest/v7/chain/cosmos"
"github.com/strangelove-ventures/interchaintest/v7/ibc"
@@ -268,7 +268,7 @@ func getLeader(ctx context.Context, cosigner *cosmos.SidecarProcess) (string, er
ctx, cancelFunc := context.WithTimeout(ctx, 10*time.Second)
defer cancelFunc()
- grpcClient := proto.NewCosignerGRPCClient(conn)
+ grpcClient := proto.NewICosignerGRPCClient(conn)
res, err := grpcClient.GetLeader(ctx, &proto.CosignerGRPCGetLeaderRequest{})
if err != nil {
diff --git a/test/validator_single.go b/test/validator_single.go
index 11c85067..1561afa5 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/cosigner"
interchaintest "github.com/strangelove-ventures/interchaintest/v7"
"github.com/strangelove-ventures/interchaintest/v7/chain/cosmos"
"github.com/strangelove-ventures/interchaintest/v7/ibc"
@@ -20,7 +20,8 @@ import (
"go.uber.org/zap/zaptest"
)
-// testChainSingleNodeAndHorcruxSingle tests a single chain with a single horcrux (single-sign mode) validator and single node validators for the rest.
+// testChainSingleNodeAndHorcruxSingle tests a single chain with a single horcrux (single-sign mode) validator and
+// single node validators for the rest.
func testChainSingleNodeAndHorcruxSingle(
t *testing.T,
totalValidators int, // total number of validators on chain (one horcrux + single node for the rest)
@@ -84,15 +85,15 @@ func preGenesisSingleNodeAndHorcruxSingle(
return err
}
- chainNodes := make(signer.ChainNodes, len(sentries))
+ chainNodes := make(cosigner.ChainNodes, len(sentries))
for i, sentry := range sentries {
- chainNodes[i] = signer.ChainNode{
+ chainNodes[i] = cosigner.ChainNode{
PrivValAddr: fmt.Sprintf("tcp://%s:1234", sentry.HostName()),
}
}
- config := signer.Config{
- SignMode: signer.SignModeSingle,
+ config := cosigner.Config{
+ SignMode: cosigner.SignModeSingle,
ChainNodes: chainNodes,
}
@@ -118,7 +119,7 @@ func writeConfigAndKeysSingle(
ctx context.Context,
chainID string,
singleSigner *cosmos.SidecarProcess,
- config signer.Config,
+ config cosigner.Config,
pvKey privval.FilePVKey,
) error {
configBz, err := json.Marshal(config)
diff --git a/test/validator_threshold.go b/test/validator_threshold.go
index 6da7fece..ff97e9ac 100644
--- a/test/validator_threshold.go
+++ b/test/validator_threshold.go
@@ -8,11 +8,12 @@ import (
"testing"
"time"
+ pcosigner "github.com/strangelove-ventures/horcrux/pkg/cosigner"
+
"github.com/cometbft/cometbft/crypto"
"github.com/docker/docker/client"
dto "github.com/prometheus/client_model/go"
"github.com/prometheus/common/expfmt"
- "github.com/strangelove-ventures/horcrux/signer"
interchaintest "github.com/strangelove-ventures/interchaintest/v7"
"github.com/strangelove-ventures/interchaintest/v7/chain/cosmos"
"github.com/strangelove-ventures/interchaintest/v7/ibc"
@@ -181,12 +182,12 @@ func convertValidatorToHorcrux(
return nil, err
}
- eciesShards, err := signer.CreateCosignerECIESShards(totalSigners)
+ eciesShards, err := pcosigner.CreateCosignerECIESShards(totalSigners)
if err != nil {
return nil, err
}
- cosigners := make(signer.CosignersConfig, totalSigners)
+ cosigners := make(pcosigner.CosignersConfig, totalSigners)
for i := 0; i < totalSigners; i++ {
_, err := horcruxSidecar(ctx, validator, fmt.Sprintf("cosigner-%d", i+1), client, network)
@@ -194,7 +195,7 @@ func convertValidatorToHorcrux(
return nil, err
}
- cosigners[i] = signer.CosignerConfig{
+ cosigners[i] = pcosigner.CosignConfig{
ShardID: i + 1,
P2PAddr: fmt.Sprintf("tcp://%s:%s", validator.Sidecars[i].HostName(), signerPort),
}
@@ -205,16 +206,16 @@ func convertValidatorToHorcrux(
cosigner := validator.Sidecars[i]
sentriesForCosigner := sentriesForCosigners[i]
- chainNodes := make(signer.ChainNodes, len(sentriesForCosigner))
+ chainNodes := make(pcosigner.ChainNodes, len(sentriesForCosigner))
for i, sentry := range sentriesForCosigner {
- chainNodes[i] = signer.ChainNode{
+ chainNodes[i] = pcosigner.ChainNode{
PrivValAddr: fmt.Sprintf("tcp://%s:1234", sentry.HostName()),
}
}
- config := signer.Config{
- SignMode: signer.SignModeThreshold,
- ThresholdModeConfig: &signer.ThresholdModeConfig{
+ config := pcosigner.Config{
+ SignMode: pcosigner.SignModeThreshold,
+ ThresholdModeConfig: &pcosigner.ThresholdModeConfig{
Threshold: int(threshold),
Cosigners: cosigners,
GRPCTimeout: "1500ms",
@@ -250,13 +251,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) ([]pcosigner.CosignEd25519Key, crypto.PubKey, error) {
pvKey, err := getPrivvalKey(ctx, node)
if err != nil {
return nil, nil, err
}
- ed25519Shards := signer.CreateCosignerEd25519Shards(pvKey, threshold, shards)
+ ed25519Shards := pcosigner.CreateCosignerEd25519Shards(pvKey, threshold, shards)
return ed25519Shards, pvKey.PubKey, nil
}
@@ -264,15 +265,15 @@ func getShardedPrivvalKey(ctx context.Context, node *cosmos.ChainNode, threshold
// chainEd25519Shard is a wrapper for a chain ID and a shard of an ed25519 consensus key.
type chainEd25519Shard struct {
chainID string
- key signer.CosignerEd25519Key
+ key pcosigner.CosignEd25519Key
}
// 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 pcosigner.Config,
+ eciesKey pcosigner.CosignEciesKey,
ed25519Shards ...chainEd25519Shard,
) error {
configBz, err := json.Marshal(config)