From 88fca5db00ec28c8eb67d4b762f8a46c8a66291f Mon Sep 17 00:00:00 2001 From: Francis <11526661+francismars@users.noreply.github.com> Date: Fri, 11 Sep 2020 19:13:43 +0100 Subject: [PATCH] Add faucet command (#93) * added faucet command * chopsticks ports imported from env * changed order of assignments * test: sleep after start nigiri * sleep after each strat and each stop * small changes on faucet * added check for txId * json err control * correcting json err control * small fixes * fixes on faucet command * http.StatusOK * try with 0.0.0.0 interface * try with 127.0.0.1 interface * fixes in travis Co-authored-by: Marco Argentieri <3596602+tiero@users.noreply.github.com> --- .travis.yml | 2 +- cli/cmd/faucet.go | 109 +++++++++++++++++++++++++++++++++++++ cli/cmd/faucet_test.go | 81 +++++++++++++++++++++++++++ cli/cmd/flags.go | 2 + cli/cmd/start_stop_test.go | 9 +++ 5 files changed, 202 insertions(+), 1 deletion(-) create mode 100644 cli/cmd/faucet.go create mode 100644 cli/cmd/faucet_test.go diff --git a/.travis.yml b/.travis.yml index 1675596..cd6ffaa 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,4 +9,4 @@ script: - if [ -n "$(gofmt -l .)" ]; then echo "Go code is not formatted"; exit 1; fi - bash scripts/install - sudo chmod -R 777 . - - go test -v ./... + - go test -short -v ./... diff --git a/cli/cmd/faucet.go b/cli/cmd/faucet.go new file mode 100644 index 0000000..1ac7132 --- /dev/null +++ b/cli/cmd/faucet.go @@ -0,0 +1,109 @@ +package cmd + +import ( + "bytes" + "encoding/json" + "errors" + "fmt" + "io/ioutil" + "net/http" + "strconv" + + "github.com/spf13/cobra" + "github.com/vulpemventures/nigiri/cli/constants" + "github.com/vulpemventures/nigiri/cli/controller" +) + +var FaucetCmd = &cobra.Command{ + Args: func(cmd *cobra.Command, args []string) error { + + if len(args) != 1 { + return errors.New("Insert receiving address") + } + return nil + }, + Use: "faucet
", + Short: "Generate and send bitcoin to given address", + RunE: faucet, + PreRunE: faucetChecks, +} + +func faucetChecks(cmd *cobra.Command, args []string) error { + datadir, _ := cmd.Flags().GetString("datadir") + isLiquidService, _ := cmd.Flags().GetBool("liquid") + + ctl, err := controller.NewController() + if err != nil { + return err + } + + if err := ctl.ParseDatadir(datadir); err != nil { + return err + } + if len(args) != 1 { + return constants.ErrInvalidArgs + } + + if isRunning, err := ctl.IsNigiriRunning(); err != nil { + return err + } else if !isRunning { + return constants.ErrNigiriNotRunning + } + + if err := ctl.ReadConfigFile(datadir); err != nil { + return err + } + + if isLiquidService && isLiquidService != ctl.GetConfigBoolField(constants.AttachLiquid) { + return constants.ErrNigiriLiquidNotEnabled + } + + return nil +} + +func faucet(cmd *cobra.Command, address []string) error { + isLiquidService, err := cmd.Flags().GetBool("liquid") + datadir, _ := cmd.Flags().GetString("datadir") + if err != nil { + return err + } + request := map[string]string{ + "address": address[0], + } + ctl, err := controller.NewController() + if err != nil { + return err + } + envPath := ctl.GetResourcePath(datadir, "env") + env, _ := ctl.ReadComposeEnvironment(envPath) + envPorts := env["ports"].(map[string]map[string]int) + requestPort := envPorts["bitcoin"]["chopsticks"] + if isLiquidService { + requestPort = envPorts["liquid"]["chopsticks"] + } + payload, err := json.Marshal(request) + if err != nil { + return err + } + res, err := http.Post("http://127.0.0.1:"+strconv.Itoa(requestPort)+"/faucet", "application/json", bytes.NewBuffer(payload)) + if err != nil { + return err + } + data, err := ioutil.ReadAll(res.Body) + if err != nil { + return err + } + if res.StatusCode != http.StatusOK { + return errors.New(string(data)) + } + + var dat map[string]string + if err := json.Unmarshal([]byte(data), &dat); err != nil { + return errors.New("Internal error. Try again.") + } + if dat["txId"] == "" { + return errors.New("Not Successful") + } + fmt.Println("txId: " + dat["txId"]) + return nil +} diff --git a/cli/cmd/faucet_test.go b/cli/cmd/faucet_test.go new file mode 100644 index 0000000..eadaec5 --- /dev/null +++ b/cli/cmd/faucet_test.go @@ -0,0 +1,81 @@ +package cmd + +import ( + "testing" + + "github.com/vulpemventures/nigiri/cli/constants" +) + +const ( + btcAddress = "mpSGWQvbAiRt2UNLST1CdWUufoPVsVwLyK" + liquidAddress = "CTEsqL1x9ooWWG9HBaHUpvS2DGJJ4haYdkTQPKj9U8CCdwT5vcudhbYUT8oQwwoS11aYtdznobfgT8rj" +) + +func TestFaucetBitcoinServices(t *testing.T) { + if testing.Short() { + t.Skip("skipping testing in short mode") + } + testStart(t, bitcoin) + + if err := testCommand("faucet", btcAddress, bitcoin); err != nil { + t.Fatal(err) + } + + testDelete(t) +} + +func TestFaucetLiquidServices(t *testing.T) { + if testing.Short() { + t.Skip("skipping testing in short mode") + } + testStart(t, liquid) + + if err := testCommand("faucet", liquidAddress, liquid); err != nil { + t.Fatal(err) + } + + testDelete(t) +} + +func TestFaucetShouldFail(t *testing.T) { + if testing.Short() { + t.Skip("skipping testing in short mode") + } + expectedError := constants.ErrNigiriNotRunning.Error() + + err := testCommand("faucet", btcAddress, bitcoin) + if err == nil { + t.Fatal("Should return error when Nigiri is stopped") + } + if err.Error() != expectedError { + t.Fatalf("Expected error: %s, got: %s", expectedError, err) + } + + err = testCommand("faucet", liquidAddress, liquid) + if err == nil { + t.Fatal("Should return error when Nigiri is stopped") + } + if err.Error() != expectedError { + t.Fatalf("Expected error: %s, got: %s", expectedError, err) + } +} + +func TestStartBitcoinAndFaucetNigiriServicesShouldFail(t *testing.T) { + if testing.Short() { + t.Skip("skipping testing in short mode") + } + testStart(t, bitcoin) + + expectedError := constants.ErrNigiriLiquidNotEnabled.Error() + + err := testCommand("faucet", liquidAddress, liquid) + if err == nil { + t.Fatal("Should return error when trying logging liquid services if not running") + } + + if err.Error() != expectedError { + t.Fatalf("Expected error: %s, got: %s", expectedError, err) + } + + testDelete(t) +} diff --git a/cli/cmd/flags.go b/cli/cmd/flags.go index c29c4d1..4818f02 100644 --- a/cli/cmd/flags.go +++ b/cli/cmd/flags.go @@ -38,10 +38,12 @@ func init() { StartCmd.PersistentFlags().StringVar(&flagEnv, "env", string(defaultJSON), "Set compose env in JSON format") StopCmd.PersistentFlags().BoolVar(&flagDelete, "delete", false, "Stop and delete nigiri") LogsCmd.PersistentFlags().BoolVar(&flagLiquidService, "liquid", false, "Set to see logs of a liquid service") + FaucetCmd.PersistentFlags().BoolVar(&flagLiquidService, "liquid", false, "Set to donate liquid btc") RootCmd.AddCommand(StartCmd) RootCmd.AddCommand(StopCmd) RootCmd.AddCommand(LogsCmd) + RootCmd.AddCommand(FaucetCmd) viper.BindPFlag(constants.Datadir, RootCmd.PersistentFlags().Lookup("datadir")) viper.BindPFlag(constants.Network, StartCmd.PersistentFlags().Lookup("network")) diff --git a/cli/cmd/start_stop_test.go b/cli/cmd/start_stop_test.go index 5cff502..f7866a4 100644 --- a/cli/cmd/start_stop_test.go +++ b/cli/cmd/start_stop_test.go @@ -3,6 +3,7 @@ package cmd import ( "fmt" "testing" + "time" "github.com/vulpemventures/nigiri/cli/constants" "github.com/vulpemventures/nigiri/cli/controller" @@ -96,6 +97,8 @@ func testStart(t *testing.T, flag bool) { if err := testCommand("start", "", flag); err != nil { t.Fatal(err) } + //Give some time to nigiri to be ready before calling + time.Sleep(5 * time.Second) if isRunning, err := ctl.IsNigiriRunning(); err != nil { t.Fatal(err) } else if !isRunning { @@ -111,6 +114,8 @@ func testStop(t *testing.T) { if err := testCommand("stop", "", !delete); err != nil { t.Fatal(err) } + //Give some time to nigiri to be ready before calling + time.Sleep(5 * time.Second) if isStopped, err := ctl.IsNigiriStopped(); err != nil { t.Fatal(err) } else if !isStopped { @@ -150,6 +155,10 @@ func testCommand(command, arg string, flag bool) error { logsCmd := []string{command, arg, fmt.Sprintf("--liquid=%t", flag)} cmd.SetArgs(logsCmd) } + if command == "faucet" { + faucetCmd := []string{command, arg, fmt.Sprintf("--liquid=%t", flag)} + cmd.SetArgs(faucetCmd) + } if err := cmd.Execute(); err != nil { return err