github.com/vipernet-xyz/tm@v0.34.24/tools/tm-signer-harness/main.go (about)

     1  package main
     2  
     3  import (
     4  	"flag"
     5  	"fmt"
     6  	"os"
     7  	"path/filepath"
     8  	"time"
     9  
    10  	"github.com/vipernet-xyz/tm/crypto/ed25519"
    11  	"github.com/vipernet-xyz/tm/libs/log"
    12  	"github.com/vipernet-xyz/tm/privval"
    13  	"github.com/vipernet-xyz/tm/tools/tm-signer-harness/internal"
    14  	"github.com/vipernet-xyz/tm/version"
    15  )
    16  
    17  const (
    18  	defaultAcceptRetries    = 100
    19  	defaultBindAddr         = "tcp://127.0.0.1:0"
    20  	defaultTMHome           = "~/.tendermint"
    21  	defaultAcceptDeadline   = 1
    22  	defaultConnDeadline     = 3
    23  	defaultExtractKeyOutput = "./signing.key"
    24  )
    25  
    26  var logger = log.NewTMLogger(log.NewSyncWriter(os.Stdout))
    27  
    28  // Command line flags
    29  var (
    30  	flagAcceptRetries int
    31  	flagBindAddr      string
    32  	flagTMHome        string
    33  	flagKeyOutputPath string
    34  )
    35  
    36  // Command line commands
    37  var (
    38  	rootCmd       *flag.FlagSet
    39  	runCmd        *flag.FlagSet
    40  	extractKeyCmd *flag.FlagSet
    41  	versionCmd    *flag.FlagSet
    42  )
    43  
    44  func init() {
    45  	rootCmd = flag.NewFlagSet("root", flag.ExitOnError)
    46  	rootCmd.Usage = func() {
    47  		fmt.Println(`Remote signer test harness for Tendermint.
    48  
    49  Usage:
    50    tm-signer-harness <command> [flags]
    51  
    52  Available Commands:
    53    extract_key        Extracts a signing key from a local Tendermint instance
    54    help               Help on the available commands
    55    run                Runs the test harness
    56    version            Display version information and exit
    57  
    58  Use "tm-signer-harness help <command>" for more information about that command.`)
    59  		fmt.Println("")
    60  	}
    61  
    62  	runCmd = flag.NewFlagSet("run", flag.ExitOnError)
    63  	runCmd.IntVar(&flagAcceptRetries,
    64  		"accept-retries",
    65  		defaultAcceptRetries,
    66  		"The number of attempts to listen for incoming connections")
    67  	runCmd.StringVar(&flagBindAddr, "addr", defaultBindAddr, "Bind to this address for the testing")
    68  	runCmd.StringVar(&flagTMHome, "tmhome", defaultTMHome, "Path to the Tendermint home directory")
    69  	runCmd.Usage = func() {
    70  		fmt.Println(`Runs the remote signer test harness for Tendermint.
    71  
    72  Usage:
    73    tm-signer-harness run [flags]
    74  
    75  Flags:`)
    76  		runCmd.PrintDefaults()
    77  		fmt.Println("")
    78  	}
    79  
    80  	extractKeyCmd = flag.NewFlagSet("extract_key", flag.ExitOnError)
    81  	extractKeyCmd.StringVar(&flagKeyOutputPath,
    82  		"output",
    83  		defaultExtractKeyOutput,
    84  		"Path to which signing key should be written")
    85  	extractKeyCmd.StringVar(&flagTMHome, "tmhome", defaultTMHome, "Path to the Tendermint home directory")
    86  	extractKeyCmd.Usage = func() {
    87  		fmt.Println(`Extracts a signing key from a local Tendermint instance for use in the remote
    88  signer under test.
    89  
    90  Usage:
    91    tm-signer-harness extract_key [flags]
    92  
    93  Flags:`)
    94  		extractKeyCmd.PrintDefaults()
    95  		fmt.Println("")
    96  	}
    97  
    98  	versionCmd = flag.NewFlagSet("version", flag.ExitOnError)
    99  	versionCmd.Usage = func() {
   100  		fmt.Println(`
   101  Prints the Tendermint version for which this remote signer harness was built.
   102  
   103  Usage:
   104    tm-signer-harness version`)
   105  		fmt.Println("")
   106  	}
   107  }
   108  
   109  func runTestHarness(acceptRetries int, bindAddr, tmhome string) {
   110  	tmhome = internal.ExpandPath(tmhome)
   111  	cfg := internal.TestHarnessConfig{
   112  		BindAddr:         bindAddr,
   113  		KeyFile:          filepath.Join(tmhome, "config", "priv_validator_key.json"),
   114  		StateFile:        filepath.Join(tmhome, "data", "priv_validator_state.json"),
   115  		GenesisFile:      filepath.Join(tmhome, "config", "genesis.json"),
   116  		AcceptDeadline:   time.Duration(defaultAcceptDeadline) * time.Second,
   117  		AcceptRetries:    acceptRetries,
   118  		ConnDeadline:     time.Duration(defaultConnDeadline) * time.Second,
   119  		SecretConnKey:    ed25519.GenPrivKey(),
   120  		ExitWhenComplete: true,
   121  	}
   122  	harness, err := internal.NewTestHarness(logger, cfg)
   123  	if err != nil {
   124  		logger.Error(err.Error())
   125  		if therr, ok := err.(*internal.TestHarnessError); ok {
   126  			os.Exit(therr.Code)
   127  		}
   128  		os.Exit(internal.ErrOther)
   129  	}
   130  	harness.Run()
   131  }
   132  
   133  func extractKey(tmhome, outputPath string) {
   134  	keyFile := filepath.Join(internal.ExpandPath(tmhome), "config", "priv_validator_key.json")
   135  	stateFile := filepath.Join(internal.ExpandPath(tmhome), "data", "priv_validator_state.json")
   136  	fpv := privval.LoadFilePV(keyFile, stateFile)
   137  	pkb := []byte(fpv.Key.PrivKey.(ed25519.PrivKey))
   138  	if err := os.WriteFile(internal.ExpandPath(outputPath), pkb[:32], 0o600); err != nil {
   139  		logger.Info("Failed to write private key", "output", outputPath, "err", err)
   140  		os.Exit(1)
   141  	}
   142  	logger.Info("Successfully wrote private key", "output", outputPath)
   143  }
   144  
   145  func main() {
   146  	if err := rootCmd.Parse(os.Args[1:]); err != nil {
   147  		fmt.Printf("Error parsing flags: %v\n", err)
   148  		os.Exit(1)
   149  	}
   150  	if rootCmd.NArg() == 0 || (rootCmd.NArg() == 1 && rootCmd.Arg(0) == "help") {
   151  		rootCmd.Usage()
   152  		os.Exit(0)
   153  	}
   154  
   155  	logger = log.NewFilter(logger, log.AllowInfo())
   156  
   157  	switch rootCmd.Arg(0) {
   158  	case "help":
   159  		switch rootCmd.Arg(1) {
   160  		case "run":
   161  			runCmd.Usage()
   162  		case "extract_key":
   163  			extractKeyCmd.Usage()
   164  		case "version":
   165  			versionCmd.Usage()
   166  		default:
   167  			fmt.Printf("Unrecognized command: %s\n", rootCmd.Arg(1))
   168  			os.Exit(1)
   169  		}
   170  	case "run":
   171  		if err := runCmd.Parse(os.Args[2:]); err != nil {
   172  			fmt.Printf("Error parsing flags: %v\n", err)
   173  			os.Exit(1)
   174  		}
   175  		runTestHarness(flagAcceptRetries, flagBindAddr, flagTMHome)
   176  	case "extract_key":
   177  		if err := extractKeyCmd.Parse(os.Args[2:]); err != nil {
   178  			fmt.Printf("Error parsing flags: %v\n", err)
   179  			os.Exit(1)
   180  		}
   181  		extractKey(flagTMHome, flagKeyOutputPath)
   182  	case "version":
   183  		fmt.Println(version.TMCoreSemVer)
   184  	default:
   185  		fmt.Printf("Unrecognized command: %s\n", flag.Arg(0))
   186  		os.Exit(1)
   187  	}
   188  }