From 7dd3c007c7c965987b7e5a635ff5345400b5dad5 Mon Sep 17 00:00:00 2001 From: Adrian Brink Date: Wed, 13 Sep 2017 00:18:07 +0200 Subject: [PATCH] Refactor priv_validator Users can now just pass an object that implements the Signer interface. --- cmd/hsm/main.go | 47 ------- cmd/tendermint/commands/gen_validator.go | 2 + cmd/tendermint/commands/init.go | 1 + cmd/tendermint/commands/probe_upnp.go | 1 + cmd/tendermint/commands/replay.go | 3 + .../commands/reset_priv_validator.go | 18 ++- cmd/tendermint/commands/root.go | 1 + cmd/tendermint/commands/run_node.go | 75 ++++++----- cmd/tendermint/commands/show_validator.go | 3 +- cmd/tendermint/commands/testnet.go | 14 +- cmd/tendermint/commands/version.go | 1 + cmd/tendermint/main.go | 22 +++- consensus/common_test.go | 2 +- node/node.go | 2 +- rpc/test/helpers.go | 2 +- types/priv_validator.go | 123 +++++++++--------- 16 files changed, 152 insertions(+), 165 deletions(-) delete mode 100644 cmd/hsm/main.go diff --git a/cmd/hsm/main.go b/cmd/hsm/main.go deleted file mode 100644 index 7c12f03c8..000000000 --- a/cmd/hsm/main.go +++ /dev/null @@ -1,47 +0,0 @@ -package main - -import ( - tcrypto "github.com/tendermint/go-crypto" - tc "github.com/tendermint/tendermint/cmd/tendermint/commands" - cfg "github.com/tendermint/tendermint/config" - "github.com/tendermint/tendermint/types" - "github.com/tendermint/tmlibs/cli" - "github.com/tendermint/tmlibs/log" - "os" -) - -var ( - config = cfg.DefaultConfig() - logger = log.NewTMLogger(log.NewSyncWriter(os.Stdout)).With("module", "main") -) - -func main() { - // TODO: Make it easier to build a tendermint instance from scratch. - // All commands should be exported and it should be easy to override - // certain aspects of a single command. - // Probably every command should have a constructor that allows a user - // to vary the configuration. This is at least true for run_node.go - - rootCmd := tc.RootCmd - rootCmd.AddCommand(tc.GenValidatorCmd) - rootCmd.AddCommand(tc.InitFilesCmd) - rootCmd.AddCommand(tc.ProbeUpnpCmd) - rootCmd.AddCommand(tc.ReplayCmd) - rootCmd.AddCommand(tc.ReplayConsoleCmd) - rootCmd.AddCommand(tc.ResetAllCmd) - rootCmd.AddCommand(tc.ResetPrivValidatorCmd) - rootCmd.AddCommand(tc.ShowValidatorCmd) - rootCmd.AddCommand(tc.TestnetFilesCmd) - rootCmd.AddCommand(tc.VersionCmd) - - signerGenerator := func(pk tcrypto.PrivKey) types.Signer { - // Return your own signer implementation here - return types.NewDefaultSigner(pk) - } - - privValidator := types.LoadPrivValidatorWithSigner(config.PrivValidatorFile(), signerGenerator) - rootCmd.AddCommand(tc.NewRunNodeCmd(privValidator)) - - cmd := cli.PrepareBaseCmd(rootCmd, "TM", os.ExpandEnv("$HOME/.tendermint")) - cmd.Execute() -} diff --git a/cmd/tendermint/commands/gen_validator.go b/cmd/tendermint/commands/gen_validator.go index df82554d8..e4dfb0bd1 100644 --- a/cmd/tendermint/commands/gen_validator.go +++ b/cmd/tendermint/commands/gen_validator.go @@ -9,6 +9,8 @@ import ( "github.com/tendermint/tendermint/types" ) +// GenValidatorCmd allows the generation of a keypair for a +// validator. var GenValidatorCmd = &cobra.Command{ Use: "gen_validator", Short: "Generate new validator keypair", diff --git a/cmd/tendermint/commands/init.go b/cmd/tendermint/commands/init.go index b844386c5..5e973335d 100644 --- a/cmd/tendermint/commands/init.go +++ b/cmd/tendermint/commands/init.go @@ -9,6 +9,7 @@ import ( cmn "github.com/tendermint/tmlibs/common" ) +// InitFilesCmd initialises a fresh Tendermint Core instance. var InitFilesCmd = &cobra.Command{ Use: "init", Short: "Initialize Tendermint", diff --git a/cmd/tendermint/commands/probe_upnp.go b/cmd/tendermint/commands/probe_upnp.go index a4c71d59e..643b7713f 100644 --- a/cmd/tendermint/commands/probe_upnp.go +++ b/cmd/tendermint/commands/probe_upnp.go @@ -9,6 +9,7 @@ import ( "github.com/tendermint/tendermint/p2p/upnp" ) +// ProbeUpnpCmd adds capabilities to test the UPnP functionality. var ProbeUpnpCmd = &cobra.Command{ Use: "probe_upnp", Short: "Test UPnP functionality", diff --git a/cmd/tendermint/commands/replay.go b/cmd/tendermint/commands/replay.go index 422d44159..303ccba6b 100644 --- a/cmd/tendermint/commands/replay.go +++ b/cmd/tendermint/commands/replay.go @@ -6,6 +6,7 @@ import ( "github.com/tendermint/tendermint/consensus" ) +// ReplayCmd allows replaying of messages from the WAL. var ReplayCmd = &cobra.Command{ Use: "replay", Short: "Replay messages from WAL", @@ -14,6 +15,8 @@ var ReplayCmd = &cobra.Command{ }, } +// ReplayConsoleCmd allows replaying of messages from the WAL in a +// console. var ReplayConsoleCmd = &cobra.Command{ Use: "replay_console", Short: "Replay messages from WAL in a console", diff --git a/cmd/tendermint/commands/reset_priv_validator.go b/cmd/tendermint/commands/reset_priv_validator.go index 389e5b79b..7f01c2313 100644 --- a/cmd/tendermint/commands/reset_priv_validator.go +++ b/cmd/tendermint/commands/reset_priv_validator.go @@ -9,18 +9,29 @@ import ( "github.com/tendermint/tmlibs/log" ) +// ResetAllCmd removes the database of this Tendermint core +// instance. var ResetAllCmd = &cobra.Command{ Use: "unsafe_reset_all", Short: "(unsafe) Remove all the data and WAL, reset this node's validator", Run: resetAll, } +// ResetPrivValidatorCmd resets the private validator files. var ResetPrivValidatorCmd = &cobra.Command{ Use: "unsafe_reset_priv_validator", Short: "(unsafe) Reset this node's validator", Run: resetPrivValidator, } +// ResetAll removes the privValidator files. +// Exported so other CLI tools can use it +func ResetAll(dbDir, privValFile string, logger log.Logger) { + resetPrivValidatorLocal(privValFile, logger) + os.RemoveAll(dbDir) + logger.Info("Removed all data", "dir", dbDir) +} + // XXX: this is totally unsafe. // it's only suitable for testnets. func resetAll(cmd *cobra.Command, args []string) { @@ -33,13 +44,6 @@ func resetPrivValidator(cmd *cobra.Command, args []string) { resetPrivValidatorLocal(config.PrivValidatorFile(), logger) } -// Exported so other CLI tools can use it -func ResetAll(dbDir, privValFile string, logger log.Logger) { - resetPrivValidatorLocal(privValFile, logger) - os.RemoveAll(dbDir) - logger.Info("Removed all data", "dir", dbDir) -} - func resetPrivValidatorLocal(privValFile string, logger log.Logger) { // Get PrivValidator var privValidator *types.PrivValidator diff --git a/cmd/tendermint/commands/root.go b/cmd/tendermint/commands/root.go index 4488eae61..a54b50069 100644 --- a/cmd/tendermint/commands/root.go +++ b/cmd/tendermint/commands/root.go @@ -34,6 +34,7 @@ func ParseConfig() (*cfg.Config, error) { return conf, err } +// RootCmd is the root command for Tendermint core. var RootCmd = &cobra.Command{ Use: "tendermint", Short: "Tendermint Core (BFT Consensus) in Go", diff --git a/cmd/tendermint/commands/run_node.go b/cmd/tendermint/commands/run_node.go index 51b370300..fd33faefe 100644 --- a/cmd/tendermint/commands/run_node.go +++ b/cmd/tendermint/commands/run_node.go @@ -12,6 +12,38 @@ import ( "github.com/tendermint/tendermint/types" ) +func init() { + AddNodeFlags(RunNodeCmd) +} + +// AddNodeFlags exposes some common configuration options on the command-line +// These are exposed for convenience of commands embedding a tendermint node +func AddNodeFlags(cmd *cobra.Command) { + // bind flags + cmd.Flags().String("moniker", config.Moniker, "Node Name") + + // node flags + cmd.Flags().Bool("fast_sync", config.FastSync, "Fast blockchain syncing") + + // abci flags + cmd.Flags().String("proxy_app", config.ProxyApp, "Proxy app address, or 'nilapp' or 'dummy' for local testing.") + cmd.Flags().String("abci", config.ABCI, "Specify abci transport (socket | grpc)") + + // rpc flags + cmd.Flags().String("rpc.laddr", config.RPC.ListenAddress, "RPC listen address. Port required") + cmd.Flags().String("rpc.grpc_laddr", config.RPC.GRPCListenAddress, "GRPC listen address (BroadcastTx only). Port required") + cmd.Flags().Bool("rpc.unsafe", config.RPC.Unsafe, "Enabled unsafe rpc methods") + + // p2p flags + cmd.Flags().String("p2p.laddr", config.P2P.ListenAddress, "Node listen address. (0.0.0.0:0 means any interface, any port)") + cmd.Flags().String("p2p.seeds", config.P2P.Seeds, "Comma delimited host:port seed nodes") + cmd.Flags().Bool("p2p.skip_upnp", config.P2P.SkipUPNP, "Skip UPNP configuration") + cmd.Flags().Bool("p2p.pex", config.P2P.PexReactor, "Enable Peer-Exchange (dev feature)") + + // consensus flags + cmd.Flags().Bool("consensus.create_empty_blocks", config.Consensus.CreateEmptyBlocks, "Set this to false to only produce blocks when there are txs or when the AppHash changes") +} + // RunNodeCmd creates and starts a tendermint node. var RunNodeCmd = &cobra.Command{ Use: "node", @@ -19,8 +51,8 @@ var RunNodeCmd = &cobra.Command{ RunE: runNode, } -// NewRunNodeCmd creates and starts a tendermint node. It allows the user to -// use a custom PrivValidator. +// NewRunNodeCmd returns the command that allows the CLI to start a +// node. It can be used with a custom PrivValidator. func NewRunNodeCmd(privVal *types.PrivValidator) *cobra.Command { return &cobra.Command{ Use: "node", @@ -43,7 +75,12 @@ func NewRunNodeCmd(privVal *types.PrivValidator) *cobra.Command { config.ChainID = genDoc.ChainID // Create & start node - n := node.NewNode(config, privVal, proxy.DefaultClientCreator(config.ProxyApp, config.ABCI, config.DBDir()), logger) + var n *node.Node + if privVal == nil { + n = node.NewNodeDefault(config, logger.With("module", "node")) + } + n = node.NewNode(config, privVal, proxy.DefaultClientCreator(config.ProxyApp, config.ABCI, config.DBDir()), logger) + if _, err := n.Start(); err != nil { return fmt.Errorf("Failed to start node: %v", err) } else { @@ -58,38 +95,6 @@ func NewRunNodeCmd(privVal *types.PrivValidator) *cobra.Command { } } -func init() { - AddNodeFlags(RunNodeCmd) -} - -// AddNodeFlags exposes some common configuration options on the command-line -// These are exposed for convenience of commands embedding a tendermint node -func AddNodeFlags(cmd *cobra.Command) { - // bind flags - cmd.Flags().String("moniker", config.Moniker, "Node Name") - - // node flags - cmd.Flags().Bool("fast_sync", config.FastSync, "Fast blockchain syncing") - - // abci flags - cmd.Flags().String("proxy_app", config.ProxyApp, "Proxy app address, or 'nilapp' or 'dummy' for local testing.") - cmd.Flags().String("abci", config.ABCI, "Specify abci transport (socket | grpc)") - - // rpc flags - cmd.Flags().String("rpc.laddr", config.RPC.ListenAddress, "RPC listen address. Port required") - cmd.Flags().String("rpc.grpc_laddr", config.RPC.GRPCListenAddress, "GRPC listen address (BroadcastTx only). Port required") - cmd.Flags().Bool("rpc.unsafe", config.RPC.Unsafe, "Enabled unsafe rpc methods") - - // p2p flags - cmd.Flags().String("p2p.laddr", config.P2P.ListenAddress, "Node listen address. (0.0.0.0:0 means any interface, any port)") - cmd.Flags().String("p2p.seeds", config.P2P.Seeds, "Comma delimited host:port seed nodes") - cmd.Flags().Bool("p2p.skip_upnp", config.P2P.SkipUPNP, "Skip UPNP configuration") - cmd.Flags().Bool("p2p.pex", config.P2P.PexReactor, "Enable Peer-Exchange (dev feature)") - - // consensus flags - cmd.Flags().Bool("consensus.create_empty_blocks", config.Consensus.CreateEmptyBlocks, "Set this to false to only produce blocks when there are txs or when the AppHash changes") -} - // Users wishing to: // * Use an external signer for their validators // * Supply an in-proc abci app diff --git a/cmd/tendermint/commands/show_validator.go b/cmd/tendermint/commands/show_validator.go index 21cc90270..86a665f0c 100644 --- a/cmd/tendermint/commands/show_validator.go +++ b/cmd/tendermint/commands/show_validator.go @@ -9,6 +9,7 @@ import ( "github.com/tendermint/tendermint/types" ) +// ShowValidatorCmd adds capabilities for showing the validator info. var ShowValidatorCmd = &cobra.Command{ Use: "show_validator", Short: "Show this node's validator info", @@ -16,7 +17,7 @@ var ShowValidatorCmd = &cobra.Command{ } func showValidator(cmd *cobra.Command, args []string) { - privValidator := types.LoadOrGenPrivValidator(config.PrivValidatorFile(), logger) + privValidator := types.LoadOrGenPrivValidator(config.PrivValidatorFile()) pubKeyJSONBytes, _ := data.ToJSON(privValidator.PubKey) fmt.Println(string(pubKeyJSONBytes)) } diff --git a/cmd/tendermint/commands/testnet.go b/cmd/tendermint/commands/testnet.go index 75e016c9d..617b66597 100644 --- a/cmd/tendermint/commands/testnet.go +++ b/cmd/tendermint/commands/testnet.go @@ -11,12 +11,6 @@ import ( cmn "github.com/tendermint/tmlibs/common" ) -var TestnetFilesCmd = &cobra.Command{ - Use: "testnet", - Short: "Initialize files for a Tendermint testnet", - Run: testnetFiles, -} - //flags var ( nValidators int @@ -30,6 +24,14 @@ func init() { "Directory to store initialization data for the testnet") } +// TestnetFilesCmd allows initialisation of files for a +// Tendermint testnet. +var TestnetFilesCmd = &cobra.Command{ + Use: "testnet", + Short: "Initialize files for a Tendermint testnet", + Run: testnetFiles, +} + func testnetFiles(cmd *cobra.Command, args []string) { genVals := make([]types.GenesisValidator, nValidators) diff --git a/cmd/tendermint/commands/version.go b/cmd/tendermint/commands/version.go index 692cba4ad..b212adc70 100644 --- a/cmd/tendermint/commands/version.go +++ b/cmd/tendermint/commands/version.go @@ -8,6 +8,7 @@ import ( "github.com/tendermint/tendermint/version" ) +// VersionCmd ... var VersionCmd = &cobra.Command{ Use: "version", Short: "Show version infoooooooo", diff --git a/cmd/tendermint/main.go b/cmd/tendermint/main.go index 5493e4f2f..d70df634d 100644 --- a/cmd/tendermint/main.go +++ b/cmd/tendermint/main.go @@ -3,11 +3,29 @@ package main import ( "os" - "github.com/tendermint/tendermint/cmd/tendermint/commands" + // crypto "github.com/tendermint/go-crypto" + "github.com/tendermint/tmlibs/cli" + + . "github.com/tendermint/tendermint/cmd/tendermint/commands" + // "github.com/tendermint/tendermint/types" ) func main() { - cmd := cli.PrepareBaseCmd(commands.RootCmd, "TM", os.ExpandEnv("$HOME/.tendermint")) + rootCmd := RootCmd + rootCmd.AddCommand(GenValidatorCmd, InitFilesCmd, ProbeUpnpCmd, + ReplayCmd, ReplayConsoleCmd, ResetAllCmd, ResetPrivValidatorCmd, + ShowValidatorCmd, TestnetFilesCmd, VersionCmd) + + // NOTE: Implement your own type that implements the Signer interface + // and then instantiate it here. + // signer := types.NewDefaultSigner(pk) + // privValidator := types.LoadPrivValidatorWithSigner(signer) + // rootCmd.AddCommand(NewRunNodeCmd(privValidator)) + + // Create & start node + rootCmd.AddCommand(RunNodeCmd) + + cmd := cli.PrepareBaseCmd(rootCmd, "TM", os.ExpandEnv("$HOME/.tendermint")) cmd.Execute() } diff --git a/consensus/common_test.go b/consensus/common_test.go index 6a05b74e3..cde56a3db 100644 --- a/consensus/common_test.go +++ b/consensus/common_test.go @@ -261,7 +261,7 @@ func newConsensusStateWithConfig(thisConfig *cfg.Config, state *sm.State, pv *ty func loadPrivValidator(config *cfg.Config) *types.PrivValidator { privValidatorFile := config.PrivValidatorFile() ensureDir(path.Dir(privValidatorFile), 0700) - privValidator := types.LoadOrGenPrivValidator(privValidatorFile, log.TestingLogger()) + privValidator := types.LoadOrGenPrivValidator(privValidatorFile) privValidator.Reset() return privValidator } diff --git a/node/node.go b/node/node.go index e0ddeb5d4..e831ba1d0 100644 --- a/node/node.go +++ b/node/node.go @@ -60,7 +60,7 @@ type Node struct { func NewNodeDefault(config *cfg.Config, logger log.Logger) *Node { // Get PrivValidator - privValidator := types.LoadOrGenPrivValidator(config.PrivValidatorFile(), logger) + privValidator := types.LoadOrGenPrivValidator(config.PrivValidatorFile()) return NewNode(config, privValidator, proxy.DefaultClientCreator(config.ProxyApp, config.ABCI, config.DBDir()), logger) } diff --git a/rpc/test/helpers.go b/rpc/test/helpers.go index 14da15c94..132c4d4d9 100644 --- a/rpc/test/helpers.go +++ b/rpc/test/helpers.go @@ -79,7 +79,7 @@ func NewTendermint(app abci.Application) *nm.Node { logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)) logger = log.NewFilter(logger, log.AllowError()) privValidatorFile := config.PrivValidatorFile() - privValidator := types.LoadOrGenPrivValidator(privValidatorFile, logger) + privValidator := types.LoadOrGenPrivValidator(privValidatorFile) papp := proxy.NewLocalClientCreator(app) node := nm.NewNode(config, privValidator, papp, logger) return node diff --git a/types/priv_validator.go b/types/priv_validator.go index 9dfd95b5f..ed0cde070 100644 --- a/types/priv_validator.go +++ b/types/priv_validator.go @@ -12,7 +12,6 @@ import ( crypto "github.com/tendermint/go-crypto" data "github.com/tendermint/go-wire/data" . "github.com/tendermint/tmlibs/common" - "github.com/tendermint/tmlibs/log" ) // TODO: type ? @@ -35,30 +34,6 @@ func voteToStep(vote *Vote) int8 { } } -// PrivValidator implements the functionality for signing blocks. -type PrivValidator struct { - Address data.Bytes `json:"address"` - PubKey crypto.PubKey `json:"pub_key"` - LastHeight int `json:"last_height"` - LastRound int `json:"last_round"` - LastStep int8 `json:"last_step"` - LastSignature crypto.Signature `json:"last_signature,omitempty"` // so we dont lose signatures - LastSignBytes data.Bytes `json:"last_signbytes,omitempty"` // so we dont lose signatures - - // PrivKey should be empty if a Signer other than the default is being used. - PrivKey crypto.PrivKey `json:"priv_key"` - Signer `json:"-"` - - // For persistence. - // Overloaded for testing. - filePath string - mtx sync.Mutex -} - - -type SignerGenerator func(pk crypto.PrivKey) (Signer) - - // This is used to sign votes. // It is the caller's duty to verify the msg before calling Sign, // eg. to avoid double signing. @@ -90,38 +65,39 @@ func (ds *DefaultSigner) PubKey() crypto.PubKey { return ds.priv.PubKey() } -func (privVal *PrivValidator) SetSigner(s Signer) { - privVal.Signer = s - privVal.setPubKeyAndAddress() -} +// PrivValidator implements the functionality for signing blocks. +type PrivValidator struct { + Address data.Bytes `json:"address"` + PubKey crypto.PubKey `json:"pub_key"` + LastHeight int `json:"last_height"` + LastRound int `json:"last_round"` + LastStep int8 `json:"last_step"` + LastSignature crypto.Signature `json:"last_signature,omitempty"` // so we dont lose signatures + LastSignBytes data.Bytes `json:"last_signbytes,omitempty"` // so we dont lose signatures -// Overwrite address and pubkey for convenience -func (privVal *PrivValidator) setPubKeyAndAddress() { - privVal.PubKey = privVal.Signer.PubKey() - privVal.Address = privVal.PubKey.Address() + // PrivKey should be empty if a Signer other than the default is being used. + PrivKey crypto.PrivKey `json:"priv_key"` + Signer `json:"-"` + + // For persistence. + // Overloaded for testing. + filePath string + mtx sync.Mutex } -// Generates a new validator with private key. -func GenPrivValidator() *PrivValidator { - privKey := crypto.GenPrivKeyEd25519().Wrap() - pubKey := privKey.PubKey() - return &PrivValidator{ - Address: pubKey.Address(), - PubKey: pubKey, - PrivKey: privKey, - LastStep: stepNone, - filePath: "", - Signer: NewDefaultSigner(privKey), +func LoadOrGenPrivValidator(filePath string) *PrivValidator { + var privValidator *PrivValidator + if _, err := os.Stat(filePath); err == nil { + privValidator = LoadPrivValidator(filePath) + } else { + privValidator = GenPrivValidator() + privValidator.SetFile(filePath) + privValidator.Save() } + return privValidator } func LoadPrivValidator(filePath string) *PrivValidator { - return LoadPrivValidatorWithSigner(filePath, func(pk crypto.PrivKey) Signer { - return NewDefaultSigner(pk) - }) -} - -func LoadPrivValidatorWithSigner(filePath string, generator SignerGenerator) *PrivValidator { privValJSONBytes, err := ioutil.ReadFile(filePath) if err != nil { Exit(err.Error()) @@ -133,25 +109,44 @@ func LoadPrivValidatorWithSigner(filePath string, generator SignerGenerator) *Pr } privVal.filePath = filePath - privVal.Signer = generator(privVal.PrivKey) - + privVal.Signer = NewDefaultSigner(privVal.PrivKey) privVal.setPubKeyAndAddress() return &privVal } -func LoadOrGenPrivValidator(filePath string, logger log.Logger) *PrivValidator { - var privValidator *PrivValidator - if _, err := os.Stat(filePath); err == nil { - privValidator = LoadPrivValidator(filePath) - logger.Info("Loaded PrivValidator", - "file", filePath, "privValidator", privValidator) - } else { - privValidator = GenPrivValidator() - privValidator.SetFile(filePath) - privValidator.Save() - logger.Info("Generated PrivValidator", "file", filePath) +// Generates a new validator with private key. +func GenPrivValidator() *PrivValidator { + privKey := crypto.GenPrivKeyEd25519().Wrap() + pubKey := privKey.PubKey() + return &PrivValidator{ + Address: pubKey.Address(), + PubKey: pubKey, + PrivKey: privKey, + LastStep: stepNone, + filePath: "", + Signer: NewDefaultSigner(privKey), } - return privValidator +} + +func LoadPrivValidatorWithSigner(signer Signer) *PrivValidator { + return &PrivValidator{ + Address: signer.PubKey().Address(), + PubKey: signer.PubKey(), + LastStep: stepNone, + filePath: "", + Signer: signer, + } +} + +func (privVal *PrivValidator) SetSigner(s Signer) { + privVal.Signer = s + privVal.setPubKeyAndAddress() +} + +// Overwrite address and pubkey for convenience +func (privVal *PrivValidator) setPubKeyAndAddress() { + privVal.PubKey = privVal.Signer.PubKey() + privVal.Address = privVal.PubKey.Address() } func (privVal *PrivValidator) SetFile(filePath string) {