diff --git a/integration/faucet/faucet_test.go b/integration/faucet/faucet_test.go index b9a093a1a4..03302d1ac5 100644 --- a/integration/faucet/faucet_test.go +++ b/integration/faucet/faucet_test.go @@ -49,7 +49,6 @@ func TestFaucet(t *testing.T) { time.Sleep(2 * time.Second) faucetConfig := &faucet.Config{ - Port: startPort, Host: "localhost", HTTPPort: startPort + integration.DefaultHostRPCHTTPOffset, PK: "0x" + contractDeployerPrivateKeyHex, diff --git a/testnet/launcher/docker.go b/testnet/launcher/docker.go index 2f254307e1..10443d5cb7 100644 --- a/testnet/launcher/docker.go +++ b/testnet/launcher/docker.go @@ -10,6 +10,8 @@ import ( "github.com/ten-protocol/go-ten/go/obsclient" "github.com/ten-protocol/go-ten/go/rpc" "github.com/ten-protocol/go-ten/testnet/launcher/eth2network" + "github.com/ten-protocol/go-ten/testnet/launcher/faucet" + "github.com/ten-protocol/go-ten/testnet/launcher/gateway" l1cd "github.com/ten-protocol/go-ten/testnet/launcher/l1contractdeployer" l2cd "github.com/ten-protocol/go-ten/testnet/launcher/l2contractdeployer" @@ -149,6 +151,57 @@ func (t *Testnet) Start() error { } fmt.Println("L2 Contracts were successfully deployed...") + faucetPort := 99 + faucetInst, err := faucet.NewDockerFaucet( + faucet.NewFaucetConfig( + faucet.WithFaucetPort(faucetPort), + faucet.WithTenNodePort(13010), + faucet.WithTenNodeHost("validator-host"), + faucet.WithFaucetPrivKey("0x8dfb8083da6275ae3e4f41e3e8a8c19d028d32c9247e24530933782f2a05035b"), + faucet.WithDockerImage("testnetobscuronet.azurecr.io/obscuronet/faucet:latest"), + ), + ) + if err != nil { + return fmt.Errorf("unable to instantiate faucet - %w", err) + } + + if err = faucetInst.Start(); err != nil { + return fmt.Errorf("unable to start faucet - %w", err) + } + + if err = faucetInst.IsReady(); err != nil { + return fmt.Errorf("unable to wait for faucet to be ready - %w", err) + } + + fmt.Printf("Faucet ready to be accessed at http://127.0.0.1:%d/ ...\n", faucetPort) + fmt.Printf("Fund your account with `curl --request POST 'http://127.0.0.1:%d/fund/eth' --header 'Content-Type: application/json' --data-raw '{ \"address\":\"0x0....\" } `\n", faucetPort) + + gatewayPort := 3000 + gatewayInst, err := gateway.NewDockerGateway( + gateway.NewGatewayConfig( + gateway.WithGatewayHTTPPort(gatewayPort), + gateway.WithGatewayWSPort(3001), + gateway.WithTenNodeHTTPPort(13010), + gateway.WithTenNodeWSPort(13011), + gateway.WithTenNodeHost("validator-host"), + gateway.WithDockerImage("testnetobscuronet.azurecr.io/obscuronet/obscuro_gateway:latest"), + ), + ) + if err != nil { + return fmt.Errorf("unable to instantiate gateway - %w", err) + } + + if err = gatewayInst.Start(); err != nil { + return fmt.Errorf("unable to start gateway - %w", err) + } + + if err = gatewayInst.IsReady(); err != nil { + return fmt.Errorf("unable to wait for gateway to be ready - %w", err) + } + + fmt.Printf("Gateway ready to be accessed at http://127.0.0.1:%d ...\n", gatewayPort) + + fmt.Println("Network successfully launched !") return nil } diff --git a/testnet/launcher/faucet/config.go b/testnet/launcher/faucet/config.go new file mode 100644 index 0000000000..8279890eea --- /dev/null +++ b/testnet/launcher/faucet/config.go @@ -0,0 +1,53 @@ +package faucet + +// Option is a function that applies configs to a Config Object +type Option = func(c *Config) + +// Config holds the properties that configure the package +type Config struct { + tenNodeHost string + tenNodePort int + faucetPort int + faucetPrivKey string + dockerImage string +} + +func NewFaucetConfig(opts ...Option) *Config { + defaultConfig := &Config{} + + for _, opt := range opts { + opt(defaultConfig) + } + + return defaultConfig +} + +func WithTenNodeHost(s string) Option { + return func(c *Config) { + c.tenNodeHost = s + } +} + +func WithFaucetPrivKey(s string) Option { + return func(c *Config) { + c.faucetPrivKey = s + } +} + +func WithDockerImage(s string) Option { + return func(c *Config) { + c.dockerImage = s + } +} + +func WithTenNodePort(i int) Option { + return func(c *Config) { + c.tenNodePort = i + } +} + +func WithFaucetPort(i int) Option { + return func(c *Config) { + c.faucetPort = i + } +} diff --git a/testnet/launcher/faucet/docker.go b/testnet/launcher/faucet/docker.go new file mode 100644 index 0000000000..c6d9fd734a --- /dev/null +++ b/testnet/launcher/faucet/docker.go @@ -0,0 +1,55 @@ +package faucet + +import ( + "fmt" + "time" + + "github.com/sanity-io/litter" + "github.com/ten-protocol/go-ten/go/common/docker" + "github.com/ten-protocol/go-ten/go/common/retry" + "github.com/valyala/fasthttp" +) + +type DockerFaucet struct { + cfg *Config +} + +func NewDockerFaucet(cfg *Config) (*DockerFaucet, error) { + return &DockerFaucet{ + cfg: cfg, + }, nil // todo (@pedro) - add validation +} + +func (n *DockerFaucet) Start() error { + fmt.Printf("Starting faucet with config: \n%s\n\n", litter.Sdump(*n.cfg)) + + cmds := []string{ + "/home/obscuro/go-obscuro/tools/faucet/cmd/faucet", + "--nodeHost", n.cfg.tenNodeHost, + "--nodePort", fmt.Sprintf("%d", n.cfg.tenNodePort), + "--pk", n.cfg.faucetPrivKey, + "--jwtSecret", "someKey", + "--serverPort", fmt.Sprintf("%d", n.cfg.faucetPort), + } + + _, err := docker.StartNewContainer("faucet", n.cfg.dockerImage, cmds, []int{n.cfg.faucetPort}, nil, nil, nil) + return err +} + +func (n *DockerFaucet) IsReady() error { + timeout := time.Minute + interval := time.Second + + return retry.Do(func() error { + statusCode, _, err := fasthttp.Get(nil, fmt.Sprintf("http://127.0.0.1:%d/health/", n.cfg.faucetPort)) + if err != nil { + return err + } + + if statusCode != fasthttp.StatusOK { + return fmt.Errorf("status not ok - status received: %s", fasthttp.StatusMessage(statusCode)) + } + + return nil + }, retry.NewTimeoutStrategy(timeout, interval)) +} diff --git a/testnet/launcher/gateway/config.go b/testnet/launcher/gateway/config.go new file mode 100644 index 0000000000..507d5e6a19 --- /dev/null +++ b/testnet/launcher/gateway/config.go @@ -0,0 +1,60 @@ +package gateway + +// Option is a function that applies configs to a Config Object +type Option = func(c *Config) + +// Config holds the properties that configure the package +type Config struct { + tenNodeHost string + tenNodeHTTPPort int + tenNodeWSPort int + gatewayHTTPPort int + gatewayWSPort int + dockerImage string +} + +func NewGatewayConfig(opts ...Option) *Config { + defaultConfig := &Config{} + + for _, opt := range opts { + opt(defaultConfig) + } + + return defaultConfig +} + +func WithTenNodeHost(s string) Option { + return func(c *Config) { + c.tenNodeHost = s + } +} + +func WithDockerImage(s string) Option { + return func(c *Config) { + c.dockerImage = s + } +} + +func WithTenNodeHTTPPort(i int) Option { + return func(c *Config) { + c.tenNodeHTTPPort = i + } +} + +func WithTenNodeWSPort(i int) Option { + return func(c *Config) { + c.tenNodeWSPort = i + } +} + +func WithGatewayHTTPPort(i int) Option { + return func(c *Config) { + c.gatewayHTTPPort = i + } +} + +func WithGatewayWSPort(i int) Option { + return func(c *Config) { + c.gatewayWSPort = i + } +} diff --git a/testnet/launcher/gateway/docker.go b/testnet/launcher/gateway/docker.go new file mode 100644 index 0000000000..1827516cf9 --- /dev/null +++ b/testnet/launcher/gateway/docker.go @@ -0,0 +1,57 @@ +package gateway + +import ( + "fmt" + "time" + + "github.com/sanity-io/litter" + "github.com/ten-protocol/go-ten/go/common/docker" + "github.com/ten-protocol/go-ten/go/common/retry" + "github.com/valyala/fasthttp" +) + +type DockerGateway struct { + cfg *Config +} + +func NewDockerGateway(cfg *Config) (*DockerGateway, error) { + return &DockerGateway{ + cfg: cfg, + }, nil // todo (@pedro) - add validation +} + +func (n *DockerGateway) Start() error { + fmt.Printf("Starting gateway with config: \n%s\n\n", litter.Sdump(*n.cfg)) + + cmds := []string{ + "/home/obscuro/go-obscuro/tools/walletextension/bin/wallet_extension_linux", + "--host", "0.0.0.0", + "--port", fmt.Sprintf("%d", n.cfg.gatewayHTTPPort), + "--portWS", fmt.Sprintf("%d", n.cfg.gatewayWSPort), + "--nodePortHTTP", fmt.Sprintf("%d", n.cfg.tenNodeHTTPPort), + "--nodePortWS", fmt.Sprintf("%d", n.cfg.tenNodeWSPort), + "--nodeHost", n.cfg.tenNodeHost, + "--dbType", "sqlite", + } + + _, err := docker.StartNewContainer("gateway", n.cfg.dockerImage, cmds, []int{n.cfg.gatewayHTTPPort, n.cfg.gatewayWSPort}, nil, nil, nil) + return err +} + +func (n *DockerGateway) IsReady() error { + timeout := time.Minute + interval := time.Second + + return retry.Do(func() error { + statusCode, _, err := fasthttp.Get(nil, fmt.Sprintf("http://127.0.0.1:%d/health/", n.cfg.gatewayHTTPPort)) + if err != nil { + return err + } + + if statusCode != fasthttp.StatusOK { + return fmt.Errorf("status not ok - status received: %s", fasthttp.StatusMessage(statusCode)) + } + + return nil + }, retry.NewTimeoutStrategy(timeout, interval)) +} diff --git a/tools/faucet/cmd/cli.go b/tools/faucet/cmd/cli.go index 5f8832b29c..41ed031247 100644 --- a/tools/faucet/cmd/cli.go +++ b/tools/faucet/cmd/cli.go @@ -11,10 +11,6 @@ import ( const ( // Flag names, defaults and usages. - faucetPortName = "port" - faucetPortDefault = 80 - faucetPortUsage = "The port on which to serve the faucet endpoint. Default: 80." - nodeHostName = "nodeHost" nodeHostDefault = "erpc.sepolia-testnet.obscu.ro" nodeHostUsage = "The host on which to connect to the Obscuro node. Default: `erpc.sepolia-testnet.obscu.ro`." @@ -41,7 +37,6 @@ const ( ) func parseCLIArgs() *faucet.Config { - faucetPort := flag.Int(faucetPortName, faucetPortDefault, faucetPortUsage) nodeHost := flag.String(nodeHostName, nodeHostDefault, nodeHostUsage) nodeHTTPPort := flag.Int(nodeHTTPPortName, nodeHTTPPortDefault, nodeHTTPPortUsage) faucetPK := flag.String(faucetPKName, faucetPKDefault, faucetPKUsage) @@ -51,7 +46,6 @@ func parseCLIArgs() *faucet.Config { flag.Parse() return &faucet.Config{ - Port: *faucetPort, Host: *nodeHost, HTTPPort: *nodeHTTPPort, PK: *faucetPK, diff --git a/tools/faucet/faucet/faucet_config.go b/tools/faucet/faucet/faucet_config.go index 81ccb1db41..ff3a0d1030 100644 --- a/tools/faucet/faucet/faucet_config.go +++ b/tools/faucet/faucet/faucet_config.go @@ -3,7 +3,6 @@ package faucet import "math/big" type Config struct { - Port int Host string HTTPPort int PK string diff --git a/tools/faucet/webserver/web_server.go b/tools/faucet/webserver/web_server.go index 542024b68a..e2fce87f43 100644 --- a/tools/faucet/webserver/web_server.go +++ b/tools/faucet/webserver/web_server.go @@ -37,6 +37,8 @@ func NewWebServer(faucetServer *faucet.Faucet, bindAddress string, jwtSecret []b r.GET("/balance", balanceReqHandler(faucetServer)) + r.GET("/health", healthReqHandler()) + return &WebServer{ engine: r, faucet: faucetServer, @@ -170,3 +172,10 @@ func balanceReqHandler(faucetServer *faucet.Faucet) gin.HandlerFunc { c.JSON(http.StatusOK, gin.H{"balance": balance.String()}) } } + +// returns the remaining native balance of the faucet +func healthReqHandler() gin.HandlerFunc { + return func(c *gin.Context) { + c.JSON(http.StatusOK, gin.H{"healthy": true}) + } +}