diff --git a/cmd/cartesi-rollups-cli/root/inspect/get/get.go b/cmd/cartesi-rollups-cli/root/inspect/get/get.go new file mode 100644 index 000000000..67c3cdca8 --- /dev/null +++ b/cmd/cartesi-rollups-cli/root/inspect/get/get.go @@ -0,0 +1,57 @@ +// (c) Cartesi and individual authors (see AUTHORS) +// SPDX-License-Identifier: Apache-2.0 (see LICENSE) + +package get + +import ( + "bytes" + "encoding/json" + "fmt" + "io" + + "github.com/cartesi/rollups-node/pkg/inspectclient" + "github.com/spf13/cobra" +) + +var Cmd = &cobra.Command{ + Use: "get", + Short: "Calls inspect get endpoint", + Example: examples, + Run: run, +} + +const examples = `# Makes a get request with a "hi" payload: +cartesi-rollups-cli inspect get --payload "hi"` + +var ( + payload string + inspectEndpoint string +) + +func init() { + Cmd.Flags().StringVar(&payload, "payload", "", + "payload of the call") + + cobra.CheckErr(Cmd.MarkFlagRequired("payload")) + + Cmd.Flags().StringVar(&inspectEndpoint, "inspect-endpoint", "http://0.0.0.0:10009/inspect", + "address used to connect to graphql") +} + +func run(cmd *cobra.Command, args []string) { + ctx := cmd.Context() + client, err := inspectclient.NewClient(inspectEndpoint) + cobra.CheckErr(err) + + response, err := client.Inspect(ctx, payload) + cobra.CheckErr(err) + + respBytes, err := io.ReadAll(response.Body) + cobra.CheckErr(err) + + var prettyJSON bytes.Buffer + json.Indent(&prettyJSON, []byte(respBytes), "", " ") + cobra.CheckErr(err) + + fmt.Print(prettyJSON.String()) +} diff --git a/cmd/cartesi-rollups-cli/root/inspect/inspect.go b/cmd/cartesi-rollups-cli/root/inspect/inspect.go new file mode 100644 index 000000000..5270d8ffe --- /dev/null +++ b/cmd/cartesi-rollups-cli/root/inspect/inspect.go @@ -0,0 +1,21 @@ +// (c) Cartesi and individual authors (see AUTHORS) +// SPDX-License-Identifier: Apache-2.0 (see LICENSE) + +package inspect + +import ( + "github.com/cartesi/rollups-node/cmd/cartesi-rollups-cli/root/inspect/get" + "github.com/cartesi/rollups-node/cmd/cartesi-rollups-cli/root/inspect/post" + + "github.com/spf13/cobra" +) + +var Cmd = &cobra.Command{ + Use: "inspect", + Short: "Makes a call to the Inspect-state HTTP API", +} + +func init() { + Cmd.AddCommand(get.Cmd) + Cmd.AddCommand(post.Cmd) +} diff --git a/cmd/cartesi-rollups-cli/root/inspect/post/post.go b/cmd/cartesi-rollups-cli/root/inspect/post/post.go new file mode 100644 index 000000000..131cac34d --- /dev/null +++ b/cmd/cartesi-rollups-cli/root/inspect/post/post.go @@ -0,0 +1,60 @@ +// (c) Cartesi and individual authors (see AUTHORS) +// SPDX-License-Identifier: Apache-2.0 (see LICENSE) + +package post + +import ( + "bytes" + "encoding/json" + "fmt" + "io" + "strings" + + "github.com/cartesi/rollups-node/pkg/inspectclient" + "github.com/spf13/cobra" +) + +var Cmd = &cobra.Command{ + Use: "post", + Short: "Calls inspect post endpoint", + Example: examples, + Run: run, +} + +const examples = `# Makes a post request with a "hi" payload: +cartesi-rollups-cli inspect post --payload "hi"` + +var ( + payload string + inspectEndpoint string +) + +func init() { + Cmd.Flags().StringVar(&payload, "payload", "", + "payload of the call") + + cobra.CheckErr(Cmd.MarkFlagRequired("payload")) + + Cmd.Flags().StringVar(&inspectEndpoint, "inspect-endpoint", "http://0.0.0.0:10009/", + "address used to connect to graphql") +} + +func run(cmd *cobra.Command, args []string) { + ctx := cmd.Context() + client, err := inspectclient.NewClient(inspectEndpoint) + cobra.CheckErr(err) + + requestBody := strings.NewReader(payload) + + response, err := client.InspectPostWithBody(ctx, "application/octet-stream", requestBody) + cobra.CheckErr(err) + + respBytes, err := io.ReadAll(response.Body) + cobra.CheckErr(err) + + var prettyJSON bytes.Buffer + json.Indent(&prettyJSON, []byte(respBytes), "", " ") + cobra.CheckErr(err) + + fmt.Print(prettyJSON.String()) +} diff --git a/cmd/cartesi-rollups-cli/root/root.go b/cmd/cartesi-rollups-cli/root/root.go index 0057c3738..7b26a672d 100644 --- a/cmd/cartesi-rollups-cli/root/root.go +++ b/cmd/cartesi-rollups-cli/root/root.go @@ -4,6 +4,7 @@ package root import ( + "github.com/cartesi/rollups-node/cmd/cartesi-rollups-cli/root/inspect" "github.com/cartesi/rollups-node/cmd/cartesi-rollups-cli/root/read" "github.com/cartesi/rollups-node/cmd/cartesi-rollups-cli/root/savesnapshot" "github.com/cartesi/rollups-node/cmd/cartesi-rollups-cli/root/send" @@ -21,5 +22,6 @@ func init() { Cmd.AddCommand(send.Cmd) Cmd.AddCommand(read.Cmd) Cmd.AddCommand(savesnapshot.Cmd) + Cmd.AddCommand(inspect.Cmd) Cmd.DisableAutoGenTag = true } diff --git a/go.mod b/go.mod index 800c48052..06f42b6da 100644 --- a/go.mod +++ b/go.mod @@ -27,6 +27,7 @@ require ( github.com/agnivade/levenshtein v1.1.1 // indirect github.com/alexflint/go-arg v1.4.2 // indirect github.com/alexflint/go-scalar v1.0.0 // indirect + github.com/apapsch/go-jsonmerge/v2 v2.0.0 // indirect github.com/bits-and-blooms/bitset v1.7.0 // indirect github.com/btcsuite/btcd/btcec/v2 v2.2.0 // indirect github.com/cenkalti/backoff/v4 v4.2.1 // indirect @@ -50,11 +51,11 @@ require ( github.com/go-stack/stack v1.8.1 // 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/google/uuid v1.5.0 // indirect github.com/gorilla/websocket v1.5.0 // indirect github.com/holiman/uint256 v1.2.3 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/klauspost/compress v1.16.0 // indirect + github.com/klauspost/compress v1.16.7 // indirect github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect github.com/magiconair/properties v1.8.7 // indirect github.com/mmcloughlin/addchain v0.4.0 // indirect @@ -62,6 +63,7 @@ require ( 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/oapi-codegen/runtime v1.1.1 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/image-spec v1.1.0-rc5 // indirect github.com/opencontainers/runc v1.1.5 // indirect @@ -79,16 +81,16 @@ require ( github.com/tklauser/numcpus v0.6.1 // indirect github.com/vektah/gqlparser/v2 v2.5.1 // indirect github.com/yusufpapurcu/wmi v1.2.3 // indirect - golang.org/x/crypto v0.14.0 // indirect + golang.org/x/crypto v0.17.0 // indirect golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect golang.org/x/mod v0.12.0 // indirect - golang.org/x/net v0.17.0 // indirect + golang.org/x/net v0.19.0 // indirect golang.org/x/sync v0.3.0 // indirect - golang.org/x/sys v0.13.0 // indirect + golang.org/x/sys v0.15.0 // indirect golang.org/x/tools v0.13.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 + google.golang.org/protobuf v1.31.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect rsc.io/tmplfunc v0.0.3 // indirect diff --git a/go.sum b/go.sum index 5fcea9075..548a387bb 100644 --- a/go.sum +++ b/go.sum @@ -19,6 +19,7 @@ github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migc github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= github.com/Microsoft/hcsshim v0.11.1 h1:hJ3s7GbWlGK4YVV92sO88BQSyF4ZLVy7/awqOlPxFbA= github.com/Microsoft/hcsshim v0.11.1/go.mod h1:nFJmaO4Zr5Y7eADdFOpYswDDlNVbvcIJJNJLECr5JQg= +github.com/RaveNoX/go-jsoncommentstrip v1.0.0/go.mod h1:78ihd09MekBnJnxpICcwzCMzGrKSKYe4AqU6PDYYpjk= github.com/StackExchange/wmi v1.2.1 h1:VIkavFPXSjcnS+O8yTq7NI32k0R5Aj+v39y29VYDOSA= github.com/StackExchange/wmi v1.2.1/go.mod h1:rcmrprowKIVzvc+NUiLncP2uuArMWLCbu9SBzvHz7e8= github.com/VictoriaMetrics/fastcache v1.12.1 h1:i0mICQuojGDL3KblA7wUNlY5lOK6a4bwt3uRKnkZU40= @@ -31,11 +32,14 @@ github.com/alexflint/go-arg v1.4.2/go.mod h1:9iRbDxne7LcR/GSvEr7ma++GLpdIU1zrghf github.com/alexflint/go-scalar v1.0.0 h1:NGupf1XV/Xb04wXskDFzS0KWOLH632W/EO4fAFi+A70= github.com/alexflint/go-scalar v1.0.0/go.mod h1:GpHzbCOZXEKMEcygYQ5n/aa4Aq84zbxjy3MxYW0gjYw= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= +github.com/apapsch/go-jsonmerge/v2 v2.0.0 h1:axGnT1gRIfimI7gJifB699GoE/oq+F2MU7Dml6nw9rQ= +github.com/apapsch/go-jsonmerge/v2 v2.0.0/go.mod h1:lvDnEdqiQrp0O42VQGgmlKpxL1AP2+08jFMw88y4klk= github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bits-and-blooms/bitset v1.7.0 h1:YjAGVd3XmtK9ktAbX8Zg2g2PwLIMjGREZJHlV4j7NEo= github.com/bits-and-blooms/bitset v1.7.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= +github.com/bmatcuk/doublestar v1.1.1/go.mod h1:UD6OnuiIn0yFxxA2le/rnRU1G4RaI4UvFv1sNto9p6w= github.com/btcsuite/btcd/btcec/v2 v2.2.0 h1:fzn1qaOt32TuLjFlkzYSsBC35Q3KUjT1SwPxiMSCF5k= github.com/btcsuite/btcd/btcec/v2 v2.2.0/go.mod h1:U7MHm051Al6XmscBQ0BoNydpOTsFAn707034b5nY8zU= github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOFYSNEs0TFnxxnS9+4U= @@ -140,6 +144,8 @@ github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU= +github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= @@ -158,10 +164,13 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= +github.com/juju/gnuflag v0.0.0-20171113085948-2ce1bb71843d/go.mod h1:2PavIy+JPciBPrBUjwbNvtwB6RQlve+hkpll6QSNmOE= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.16.0 h1:iULayQNOReoYUe+1qtKOqw9CwJv3aNQu8ivo7lw1HU4= github.com/klauspost/compress v1.16.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I= +github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -182,6 +191,7 @@ github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxec github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= @@ -204,6 +214,8 @@ github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3 github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ= +github.com/oapi-codegen/runtime v1.1.1 h1:EXLHh0DXIJnWhdRPN2w4MXAzFyE4CskzhNLUmtpMYro= +github.com/oapi-codegen/runtime v1.1.1/go.mod h1:SK9X900oXmPWilYR5/WKPzt3Kqxn/uS/+lbpREv+eCg= github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= @@ -257,6 +269,7 @@ github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad/go.mod h1:qLr4V1qq6nMqFKkMo8ZTx3f+BZEkzsRUY10Xsm2mwU0= github.com/status-im/keycard-go v0.2.0 h1:QDLFswOQu1r5jsycloeQh3bVU8n/NatHHaZobtDnDzA= github.com/status-im/keycard-go v0.2.0/go.mod h1:wlp8ZLbsmrF6g6WjugPAx+IzoLrkdf9+mHxBEeo3Hbg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -264,6 +277,7 @@ github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSS github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.1.5-0.20170601210322-f6abca593680/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= @@ -305,6 +319,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= +golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k= +golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g= golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= @@ -318,6 +334,8 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= +golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= +golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -344,6 +362,8 @@ golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= +golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= @@ -351,6 +371,7 @@ golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= @@ -370,6 +391,8 @@ google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= +google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= diff --git a/pkg/inspectclient/generated.go b/pkg/inspectclient/generated.go new file mode 100644 index 000000000..a6c816fc8 --- /dev/null +++ b/pkg/inspectclient/generated.go @@ -0,0 +1,394 @@ +// Package inspectclient provides primitives to interact with the openapi HTTP API. +// +// Code generated by github.com/deepmap/oapi-codegen/v2 version v2.0.0 DO NOT EDIT. +package inspectclient + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "net/url" + "strings" + + "github.com/oapi-codegen/runtime" +) + +// Defines values for CompletionStatus. +const ( + Accepted CompletionStatus = "Accepted" + CycleLimitExceeded CompletionStatus = "CycleLimitExceeded" + Exception CompletionStatus = "Exception" + MachineHalted CompletionStatus = "MachineHalted" + Rejected CompletionStatus = "Rejected" + TimeLimitExceeded CompletionStatus = "TimeLimitExceeded" +) + +// CompletionStatus Whether inspection completed or not (and why not) +type CompletionStatus string + +// Error Detailed error message. +type Error = string + +// InspectResult defines model for InspectResult. +type InspectResult struct { + // ExceptionPayload Payload in the Ethereum hex binary format. + // The first two characters are '0x' followed by pairs of hexadecimal numbers that correspond to one byte. + // For instance, '0xdeadbeef' corresponds to a payload with length 4 and bytes 222, 173, 190, 175. + // An empty payload is represented by the string '0x'. + ExceptionPayload Payload `json:"exception_payload"` + + // ProcessedInputCount Number of processed inputs since genesis + ProcessedInputCount int `json:"processed_input_count"` + Reports []Report `json:"reports"` + + // Status Whether inspection completed or not (and why not) + Status CompletionStatus `json:"status"` +} + +// Payload Payload in the Ethereum hex binary format. +// The first two characters are '0x' followed by pairs of hexadecimal numbers that correspond to one byte. +// For instance, '0xdeadbeef' corresponds to a payload with length 4 and bytes 222, 173, 190, 175. +// An empty payload is represented by the string '0x'. +type Payload = string + +// Report defines model for Report. +type Report struct { + // Payload Payload in the Ethereum hex binary format. + // The first two characters are '0x' followed by pairs of hexadecimal numbers that correspond to one byte. + // For instance, '0xdeadbeef' corresponds to a payload with length 4 and bytes 222, 173, 190, 175. + // An empty payload is represented by the string '0x'. + Payload Payload `json:"payload"` +} + +// RequestEditorFn is the function signature for the RequestEditor callback function +type RequestEditorFn func(ctx context.Context, req *http.Request) error + +// Doer performs HTTP requests. +// +// The standard http.Client implements this interface. +type HttpRequestDoer interface { + Do(req *http.Request) (*http.Response, error) +} + +// Client which conforms to the OpenAPI3 specification for this service. +type Client struct { + // The endpoint of the server conforming to this interface, with scheme, + // https://api.deepmap.com for example. This can contain a path relative + // to the server, such as https://api.deepmap.com/dev-test, and all the + // paths in the swagger spec will be appended to the server. + Server string + + // Doer for performing requests, typically a *http.Client with any + // customized settings, such as certificate chains. + Client HttpRequestDoer + + // A list of callbacks for modifying requests which are generated before sending over + // the network. + RequestEditors []RequestEditorFn +} + +// ClientOption allows setting custom parameters during construction +type ClientOption func(*Client) error + +// Creates a new Client, with reasonable defaults +func NewClient(server string, opts ...ClientOption) (*Client, error) { + // create a client with sane default values + client := Client{ + Server: server, + } + // mutate client and add all optional params + for _, o := range opts { + if err := o(&client); err != nil { + return nil, err + } + } + // ensure the server URL always has a trailing slash + if !strings.HasSuffix(client.Server, "/") { + client.Server += "/" + } + // create httpClient, if not already present + if client.Client == nil { + client.Client = &http.Client{} + } + return &client, nil +} + +// WithHTTPClient allows overriding the default Doer, which is +// automatically created using http.Client. This is useful for tests. +func WithHTTPClient(doer HttpRequestDoer) ClientOption { + return func(c *Client) error { + c.Client = doer + return nil + } +} + +// WithRequestEditorFn allows setting up a callback function, which will be +// called right before sending the request. This can be used to mutate the request. +func WithRequestEditorFn(fn RequestEditorFn) ClientOption { + return func(c *Client) error { + c.RequestEditors = append(c.RequestEditors, fn) + return nil + } +} + +// The interface specification for the client above. +type ClientInterface interface { + // InspectPostWithBody request with any body + InspectPostWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) + + // Inspect request + Inspect(ctx context.Context, payload string, reqEditors ...RequestEditorFn) (*http.Response, error) +} + +func (c *Client) InspectPostWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewInspectPostRequestWithBody(c.Server, contentType, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) Inspect(ctx context.Context, payload string, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewInspectRequest(c.Server, payload) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +// NewInspectPostRequestWithBody generates requests for InspectPost with any type of body +func NewInspectPostRequestWithBody(server string, contentType string, body io.Reader) (*http.Request, error) { + var err error + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("inspect") + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("POST", queryURL.String(), body) + if err != nil { + return nil, err + } + + req.Header.Add("Content-Type", contentType) + + return req, nil +} + +// NewInspectRequest generates requests for Inspect +func NewInspectRequest(server string, payload string) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "payload", runtime.ParamLocationPath, payload) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("inspect/%s", pathParam0) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("GET", queryURL.String(), nil) + if err != nil { + return nil, err + } + + return req, nil +} + +func (c *Client) applyEditors(ctx context.Context, req *http.Request, additionalEditors []RequestEditorFn) error { + for _, r := range c.RequestEditors { + if err := r(ctx, req); err != nil { + return err + } + } + for _, r := range additionalEditors { + if err := r(ctx, req); err != nil { + return err + } + } + return nil +} + +// ClientWithResponses builds on ClientInterface to offer response payloads +type ClientWithResponses struct { + ClientInterface +} + +// NewClientWithResponses creates a new ClientWithResponses, which wraps +// Client with return type handling +func NewClientWithResponses(server string, opts ...ClientOption) (*ClientWithResponses, error) { + client, err := NewClient(server, opts...) + if err != nil { + return nil, err + } + return &ClientWithResponses{client}, nil +} + +// WithBaseURL overrides the baseURL. +func WithBaseURL(baseURL string) ClientOption { + return func(c *Client) error { + newBaseURL, err := url.Parse(baseURL) + if err != nil { + return err + } + c.Server = newBaseURL.String() + return nil + } +} + +// ClientWithResponsesInterface is the interface specification for the client with responses above. +type ClientWithResponsesInterface interface { + // InspectPostWithBodyWithResponse request with any body + InspectPostWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*InspectPostResponse, error) + + // InspectWithResponse request + InspectWithResponse(ctx context.Context, payload string, reqEditors ...RequestEditorFn) (*InspectResponse, error) +} + +type InspectPostResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *InspectResult +} + +// Status returns HTTPResponse.Status +func (r InspectPostResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r InspectPostResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type InspectResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *InspectResult +} + +// Status returns HTTPResponse.Status +func (r InspectResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r InspectResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +// InspectPostWithBodyWithResponse request with arbitrary body returning *InspectPostResponse +func (c *ClientWithResponses) InspectPostWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*InspectPostResponse, error) { + rsp, err := c.InspectPostWithBody(ctx, contentType, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseInspectPostResponse(rsp) +} + +// InspectWithResponse request returning *InspectResponse +func (c *ClientWithResponses) InspectWithResponse(ctx context.Context, payload string, reqEditors ...RequestEditorFn) (*InspectResponse, error) { + rsp, err := c.Inspect(ctx, payload, reqEditors...) + if err != nil { + return nil, err + } + return ParseInspectResponse(rsp) +} + +// ParseInspectPostResponse parses an HTTP response from a InspectPostWithResponse call +func ParseInspectPostResponse(rsp *http.Response) (*InspectPostResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &InspectPostResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest InspectResult + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + } + + return response, nil +} + +// ParseInspectResponse parses an HTTP response from a InspectWithResponse call +func ParseInspectResponse(rsp *http.Response) (*InspectResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &InspectResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest InspectResult + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + } + + return response, nil +} diff --git a/pkg/inspectclient/inspect.yaml b/pkg/inspectclient/inspect.yaml new file mode 100644 index 000000000..a6c466ebe --- /dev/null +++ b/pkg/inspectclient/inspect.yaml @@ -0,0 +1,145 @@ +openapi: 3.0.0 + +info: + title: Inspect-state HTTP API for Cartesi Rollups + version: 0.6.0 + license: + name: Apache-2.0 + url: https://www.apache.org/licenses/LICENSE-2.0.html + + description: | + API that allows the DApp frontend to make inspect-state requests to the DApp backend. + +paths: + inspect/{payload}: + get: + operationId: inspect + summary: Inspect DApp state via GET + description: | + This method sends an inspect-state request to the DApp backend, passing the payload string in the URL. + The payload string should be URL-encoded; the inspect server will decode the string to UTF-8. + If the DApp frontend needs to pass a binary string to the backend then it is advised to use the POST method. + + The response contains a status string and the reports generated by the DApp backend. + The status string can be either 'accept', 'reject', or 'exception'. + In case of exception, the field exception_payload will contain the exception payload; + Otherwise, this field will be null. + + When running on machine mode, the whole Cartesi machine is rolled back after processing the inspect-state request. + On host mode, it is advised against changing the DApp backend state when processing an inspect-state request. + Notice that this method is synchronous, so it is not advised to be used for performing resource-intensive operations. + + parameters: + - in: path + name: payload + required: true + schema: + type: string + + responses: + "200": + description: Inspect state response. + content: + application/json: + schema: + $ref: "#/components/schemas/InspectResult" + + default: + description: Error response. + content: + text/plain: + schema: + $ref: "#/components/schemas/Error" + + inspect: + post: + operationId: inspect_post + summary: Inspect DApp state via POST + description: | + Differently from the GET method, the POST method sends an inspect-state request to the DApp backend by passing its payload in the request body. + The payload should be a binary. + Other than that, it behaves the same way as described in the GET method. + + requestBody: + content: + application/octet-stream: + schema: + type: string + format: binary + + responses: + "200": + description: Inspect state response. + content: + application/json: + schema: + $ref: "#/components/schemas/InspectResult" + + default: + description: Error response. + content: + text/plain: + schema: + $ref: "#/components/schemas/Error" + +components: + schemas: + InspectResult: + type: object + properties: + status: + $ref: "#/components/schemas/CompletionStatus" + exception_payload: + $ref: "#/components/schemas/Payload" + reports: + type: array + items: + $ref: "#/components/schemas/Report" + processed_input_count: + type: integer + description: Number of processed inputs since genesis + example: 0 + required: + - status + - exception_payload + - reports + - processed_input_count + + CompletionStatus: + type: string + description: Whether inspection completed or not (and why not) + enum: + [ + Accepted, + Rejected, + Exception, + MachineHalted, + CycleLimitExceeded, + TimeLimitExceeded, + ] + example: "Accepted" + + Payload: + type: string + description: | + Payload in the Ethereum hex binary format. + The first two characters are '0x' followed by pairs of hexadecimal numbers that correspond to one byte. + For instance, '0xdeadbeef' corresponds to a payload with length 4 and bytes 222, 173, 190, 175. + An empty payload is represented by the string '0x'. + example: "0xdeadbeef" + pattern: "^0x([0-9a-fA-F]{2})*$" + format: hex + + Report: + type: object + properties: + payload: + $ref: "#/components/schemas/Payload" + required: + - payload + + Error: + type: string + description: Detailed error message. + example: "The request could not be understood by the server due to malformed syntax" + \ No newline at end of file