Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Add devnet command
Browse files Browse the repository at this point in the history
fmoura committed Nov 9, 2023
1 parent 43ce948 commit c2d28d5
Showing 13 changed files with 382 additions and 55 deletions.
18 changes: 0 additions & 18 deletions cmd/cartesi-rollups-node/devnet.go

This file was deleted.

21 changes: 0 additions & 21 deletions cmd/cartesi-rollups-node/prepareAnvil.go

This file was deleted.

1 change: 0 additions & 1 deletion cmd/cartesi-rollups-node/root.go
Original file line number Diff line number Diff line change
@@ -15,5 +15,4 @@ func init() {
rootCmd.AddCommand(reader)
rootCmd.AddCommand(validator)
rootCmd.AddCommand(noBackend)
rootCmd.AddCommand(devnetCmd)
}
Empty file added devnet/LICENSE
Empty file.
51 changes: 51 additions & 0 deletions devnet/cmd/root.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
Copyright © 2023 NAME HERE <EMAIL ADDRESS>
*/
package cmd

import (
"os"

"github.com/spf13/cobra"
)



// rootCmd represents the base command when called without any subcommands
var rootCmd = &cobra.Command{
Use: "devnet",
Short: "A brief description of your application",
Long: `A longer description that spans multiple lines and likely contains
examples and usage of using your application. For example:
Cobra is a CLI library for Go that empowers applications.
This application is a tool to generate the needed files
to quickly create a Cobra application.`,
// Uncomment the following line if your bare application
// has an action associated with it:
// Run: func(cmd *cobra.Command, args []string) { },
}

// Execute adds all child commands to the root command and sets flags appropriately.
// This is called by main.main(). It only needs to happen once to the rootCmd.
func Execute() {
err := rootCmd.Execute()
if err != nil {
os.Exit(1)
}
}

func init() {
// Here you will define your flags and configuration settings.
// Cobra supports persistent flags, which, if defined here,
// will be global for your application.

// rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.devnet.yaml)")

// Cobra also supports local flags, which will only run
// when this action is called directly.
rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
}


11 changes: 11 additions & 0 deletions devnet/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/*
Copyright © 2023 NAME HERE <EMAIL ADDRESS>
*/
package main

import "github.com/cartesi/rollups-node/devnet/cmd"

func main() {
cmd.Execute()
}
42 changes: 36 additions & 6 deletions go.mod
Original file line number Diff line number Diff line change
@@ -2,23 +2,53 @@ module github.com/cartesi/rollups-node

go 1.21.1

require github.com/spf13/cobra v1.7.0
require github.com/spf13/cobra v1.8.0

require (
dario.cat/mergo v1.0.0 // indirect
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
github.com/Microsoft/go-winio v0.6.1 // indirect
github.com/Microsoft/hcsshim v0.11.1 // indirect
github.com/cenkalti/backoff/v4 v4.2.1 // indirect
github.com/containerd/containerd v1.7.7 // indirect
github.com/containerd/log v0.1.0 // indirect
github.com/cpuguy83/dockercfg v0.3.1 // indirect
github.com/distribution/reference v0.5.0 // indirect
github.com/docker/distribution v2.8.3+incompatible // indirect
github.com/docker/docker v24.0.7+incompatible // indirect
github.com/docker/go-connections v0.4.0 // indirect
github.com/docker/go-units v0.5.0 // indirect
github.com/go-ole/go-ole v1.2.6 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/google/uuid v1.3.1 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/klauspost/compress v1.16.0 // indirect
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
github.com/magiconair/properties v1.8.7 // indirect
github.com/moby/patternmatcher v0.6.0 // indirect
github.com/moby/sys/sequential v0.5.0 // indirect
github.com/moby/term v0.5.0 // indirect
github.com/morikuni/aec v1.0.0 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/opencontainers/image-spec v1.0.2 // indirect
github.com/opencontainers/image-spec v1.1.0-rc5 // indirect
github.com/opencontainers/runc v1.1.5 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
github.com/shirou/gopsutil/v3 v3.23.9 // indirect
github.com/shoenig/go-m1cpu v0.1.6 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
github.com/spf13/pflag v1.0.5 // indirect
golang.org/x/mod v0.8.0 // indirect
golang.org/x/net v0.6.0 // indirect
golang.org/x/sys v0.5.0 // indirect
golang.org/x/tools v0.6.0 // indirect
github.com/testcontainers/testcontainers-go v0.26.0 // indirect
github.com/tklauser/go-sysconf v0.3.12 // indirect
github.com/tklauser/numcpus v0.6.1 // indirect
github.com/yusufpapurcu/wmi v1.2.3 // indirect
golang.org/x/exp v0.0.0-20230510235704-dd950f8aeaea // indirect
golang.org/x/mod v0.9.0 // indirect
golang.org/x/net v0.17.0 // indirect
golang.org/x/sys v0.13.0 // indirect
golang.org/x/tools v0.7.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19 // indirect
google.golang.org/grpc v1.57.1 // indirect
google.golang.org/protobuf v1.30.0 // indirect
)
138 changes: 138 additions & 0 deletions go.sum

Large diffs are not rendered by default.

73 changes: 64 additions & 9 deletions internal/docker/docker.go
Original file line number Diff line number Diff line change
@@ -8,18 +8,54 @@ import (
"context"
"fmt"

"github.com/cartesi/rollups-node/internal/logger"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/client"
"github.com/docker/go-connections/nat"
)

func StartNewContainer(image string, bindings []string) (string, error) {
type DockerContainer struct {
containerName string
containerId string
}

func createDockerClient() *client.Client {
cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
fmt.Println("Unable to create docker client")
panic(err)
}
return cli
}

func (c DockerContainer) Start(ctx context.Context) error {
cli := createDockerClient()

startError := cli.ContainerStart(context.Background(), c.containerId, types.ContainerStartOptions{})
if startError != nil {
return startError
}
fmt.Printf("Container %s : %s is started", c.containerId, c.containerName)

go func() {
//cli.ContainerWait(ctx,c.containerId)
<-ctx.Done()
logger.Info.Printf("Stopping %v: %v\n", c.containerName, ctx.Err())

if err := cli.ContainerStop(context.Background(), c.containerId, container.StopOptions{}); err != nil {
msg := "%v: failed to send SIGTERM to %v\n"
logger.Error.Printf(msg, c.containerName, c.containerId)

}
}()

return nil

}

func CreateDockerContainer(image string, bindings []string, containerName string) (*DockerContainer, error) {
cli := createDockerClient()

allPortsMappings := nat.PortMap{}
exposedPorts := nat.PortSet{}
@@ -29,7 +65,7 @@ func StartNewContainer(image string, bindings []string) (string, error) {
portMappings, err := nat.ParsePortSpec(binding)

if err != nil {
return "", fmt.Errorf("Error parsing port binding spec %s", binding)
return nil, fmt.Errorf("Error parsing port binding spec %s", binding)
}

for _, portMapping := range portMappings {
@@ -47,15 +83,34 @@ func StartNewContainer(image string, bindings []string) (string, error) {
&container.HostConfig{
PortBindings: allPortsMappings,
AutoRemove: true,
}, nil, nil, "")
}, nil, nil, containerName)
if err != nil {
panic(err)
return nil, err
}

startError := cli.ContainerStart(context.Background(), cont.ID, types.ContainerStartOptions{})
if startError != nil {
return "", startError
containerInfo, infoError := cli.ContainerInspect(context.Background(), cont.ID)
if infoError != nil {
return nil, infoError
}
fmt.Printf("Container %s is started", cont.ID)
return cont.ID, nil

return &DockerContainer{
containerName: containerInfo.Name,
containerId: cont.ID,
}, nil

}

func StartNewContainer(ctx context.Context, image string, bindings []string) (*DockerContainer, error) {

container, err := CreateDockerContainer(image, bindings, "")
if err != nil {
return nil, err
}

startErr := container.Start(ctx)
if startErr != nil {
return container, startErr
}

return container, nil
}
53 changes: 53 additions & 0 deletions internal/docker/docker_container_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// (c) Cartesi and individual authors (see AUTHORS)
// SPDX-License-Identifier: Apache-2.0 (see LICENSE)

package docker

import (
"context"
"os/exec"
"syscall"
"testing"
"time"

"github.com/cartesi/rollups-node/internal/logger"
)

func setup() {
logger.Init("warning", false)
}
func TestSimpleService(t *testing.T) {

t.Run("it stops when the context is cancelled", func(t *testing.T) {
setup()
container, cerr := CreateDockerContainer("docker.io/cartesi/anvil:devel", nil, "")
if cerr != nil {
t.Logf("Error creating container: %v", cerr)
t.FailNow()
}

ctx, cancel := context.WithCancel(context.Background())
exit := make(chan error)

go func() {
if err := container.Start(ctx); err != nil {
exit <- err
}
}()

<-time.After(50000 * time.Millisecond)
cancel()

err := <-exit
exitError, ok := err.(*exec.ExitError)
if !ok || !assertExitErrorWasCausedBy(exitError, syscall.SIGTERM) {
t.Logf("service exited for the wrong reason: %v", err)
t.FailNow()
}
})
}

func assertExitErrorWasCausedBy(err *exec.ExitError, signal syscall.Signal) bool {
status := err.Sys().(syscall.WaitStatus)
return status.Signal() == signal
}
11 changes: 11 additions & 0 deletions node-execution/anvil/eth_dump
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/usr/bin/env sh

# dump the state from the JSON-RPC server, convert from the hex anvil returns to text, which is a JSON string
curl \
-sL \
-X POST \
-H 'Content-Type: application/json' \
--data '{"id":1,"jsonrpc":"2.0","method":"anvil_dumpState","params":[]}' "${RPC_URL:-http://127.0.0.1:8545}" | \
jq -r .result| \
cut -c 3- | \
xxd -r -p
4 changes: 4 additions & 0 deletions node-execution/anvil/eth_isready
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/usr/bin/env sh

# https://ethereum.org/en/developers/docs/apis/json-rpc/#net_listening
curl -X POST -s -H 'Content-Type: application/json' -d '{"jsonrpc":"2.0","id":"1","method":"net_listening","params":[]}' ${RPC_URL:-http://127.0.0.1:8545} | jq '.result'
14 changes: 14 additions & 0 deletions node-execution/anvil/eth_load
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/usr/bin/env sh
set -e
RPC_URL="${RPC_URL:-http://127.0.0.1:8545}"

# use a large column value so we have everything on one line, even though man says 256 is the maximum
STATE=$(xxd -ps -c 1000000000)

# build the JSON-RPC request, and write to a file because it's too long for the curl call
DATA="{\"id\":2,\"jsonrpc\":\"2.0\",\"method\":\"anvil_loadState\",\"params\":[\"0x$STATE\"]}"
TMPFILE=$(mktemp)
echo "$DATA" > "$TMPFILE"

echo "Loading state into ${RPC}"
curl -sL -H 'Content-Type: application/json' -d @"$TMPFILE" "$RPC_URL" | jq -r .result

0 comments on commit c2d28d5

Please sign in to comment.