diff --git a/.gitignore b/.gitignore index 1d2567c..7bad17d 100644 --- a/.gitignore +++ b/.gitignore @@ -3,7 +3,10 @@ geth/execution/geth .test/ deposit_manifest.json /attacknet -/.DS_Store +.DS_Store .idea .vscode -artifacts \ No newline at end of file +artifacts +webhook +attacknetruns +metrics-server.yaml diff --git a/.vscode/launch.json b/.vscode/launch.json deleted file mode 100644 index 64e1197..0000000 --- a/.vscode/launch.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - // Use IntelliSense to learn about possible attributes. - // Hover to view descriptions of existing attributes. - // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 - "version": "0.2.0", - "configurations": [ - { - "name": "Attacknet start suite", - "type": "go", - "request": "launch", - "mode": "auto", - "program": "./cmd/attacknet/main.go", - "args": ["start", "suite"], - "cwd": "${workspaceFolder}" - } - ] -} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index f3c76b1..0000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "sarif-viewer.connectToGithubCodeScanning": "off", - "go.lintTool": "golangci-lint", - -} \ No newline at end of file diff --git a/CODEOWNERS b/CODEOWNERS new file mode 100644 index 0000000..4932555 --- /dev/null +++ b/CODEOWNERS @@ -0,0 +1,5 @@ +* @bsamuels453 +terraform/ @barnabasbusa +planner-configs/ @parithosh @barnabasbusa +network-configs/ @parithosh @barnabasbusa +test-suites/ @parithosh @barnabasbusa \ No newline at end of file diff --git a/README.md b/README.md index 2c89b0e..11ee2ce 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ The overall architecture of Attacknet relies on Kubernetes to run the workloads, [Chaos Mesh](https://chaos-mesh.org/) to inject faults into it. Attacknet can then be configured to run healthchecks and reports back the state of the network at the end of a test. -![architecture-diag.png](architecture-diag.png) +![docs/attacknet.svg](docs/attacknet.svg) ### TLDR; Capabilities Attacknet can be used in the following ways: @@ -137,12 +137,15 @@ network_params: num_validator_keys_per_node: 32 # required. kurtosis_package: "github.com/kurtosis-tech/ethereum-package" kubernetes_namespace: kt-ethereum +topology: + bootnode_el: geth # self explanatory + bootnode_cl: prysm + targets_as_percent_of_network: 0.25 # [optional] defines what percentage of the network contains the target client. 0.25 means only 25% of nodes will contain the client defined in the fault spec. Warning: low percentages may lead to massive networks. + target_node_multiplier: 2 # optional, default:1. Adds duplicate el/cl combinations based on the multiplier. Useful for testing weird edge cases in consensus fault_config: fault_type: ClockSkew # which fault to use. A list of faults currently supported by the planner can be found in pkg/plan/suite/types.go in FaultTypeEnum target_client: reth # which client to test. this can be an exec client or a consensus client. must show up in the client definitions above. wait_before_first_test: 300s # how long to wait before running the first test. Set this to 25 minutes to test against a finalized network. - bootnode_el: geth - bootnode_cl: prysm fault_config_dimensions: # the different fault configurations to use when creating tests. At least one config dimension is required. - skew: -2m # these configs differ for each fault duration: 1m @@ -212,16 +215,23 @@ If you're just trying to test things out, use `attacknet start suite`. This refe ## Changelog -**Dec 15, 2023 version v0.1 (internal)** -- Initial internal release +**TBD** -**Jan 11, 2024 version v0.2 (internal)** -- Updated to kurtosis v0.86.1 -- Updated to Go 1.21 -- Grafana port-forwarding has been temporarily disabled -- Introduces multi-step tests. This allows multiple faults and other actions to be composed into a single test. -- Introduces the suite planner. The suite planner allows the user to define a set of testing criteria/dimensions, which the planner turns into a suite containing multiple tests. -- Successful & failed test suites now emit test artifacts summarizing the results of the test. +First public release! + +**New** +- Added two new configuration options in the test planner: + - target_node_multiplier, which duplicates the number of nodes on the network containing the client under test + - targets_as_percent_of_network, which adds more non-test nodes to the network to improve client diversity testing +- Added new fault options to the test planner: + - Network latency faults + - Network packet loss faults +- Beacon chain clients are now included in health checking. + +**Fixed** +- Fixed an issue where the test planner's resultant network topology was non-deterministic +- Fixed an issue where a dropped port-forwarding connection to a pod may result in a panic +- Fixed an issue where Chaos Mesh would fail to find targets in networks with more than 10 nodes **Jan 30, 2024 version v0.3 (internal)** - Fixed the demo example suite @@ -232,9 +242,21 @@ If you're just trying to test things out, use `attacknet start suite`. This refe - Peer scoring is now disabled for all planner-generated network configurations. - Bootnodes are no longer targetable by planner-generated test suites. +**Jan 11, 2024 version v0.2 (internal)** +- Updated to kurtosis v0.86.1 +- Updated to Go 1.21 +- Grafana port-forwarding has been temporarily disabled +- Introduces multi-step tests. This allows multiple faults and other actions to be composed into a single test. +- Introduces the suite planner. The suite planner allows the user to define a set of testing criteria/dimensions, which the planner turns into a suite containing multiple tests. +- Successful & failed test suites now emit test artifacts summarizing the results of the test. + +**Dec 15, 2023 version v0.1 (internal)** +- Initial internal release + ## Developing (wip) 1. Install pre-commit - `brew install pre-commit` - `pre-commit install` +When making pull requests, target the `develop` branch, not main. diff --git a/architecture-diag.png b/architecture-diag.png deleted file mode 100644 index ca98d75..0000000 Binary files a/architecture-diag.png and /dev/null differ diff --git a/cmd/attacknet/main.go b/cmd/attacknet/main.go index 191c9f3..7aa83c0 100644 --- a/cmd/attacknet/main.go +++ b/cmd/attacknet/main.go @@ -22,6 +22,7 @@ var CLI struct { Name string `arg:"" optional:"" name:"name" help:"The name of the test suite to be generated"` Path string `arg:"" optional:"" type:"existingfile" name:"path" help:"Location of the planner configuration."` } `cmd:"" help:"Construct an attacknet suite for a client"` + // Explore struct{} `cmd:"" help:"Run in exploration mode"` } func main() { @@ -68,6 +69,44 @@ func main() { log.Fatal(err) os.Exit(1) } + /* + case "explore": + topo, err := plan.LoadPlannerConfigFromPath("planner-configs/network-latency-reth.yaml") + if err != nil { + log.Fatal(err) + } + suiteCfg, err := project.LoadSuiteConfigFromName("plan/network-latency-reth") + if err != nil { + log.Fatal(err) + } + + f, err := os.ReadFile("webhook") + if err != nil { + log.Fatal(err) + } + w := string(f) + client, err := webhook.NewWithURL(w) + if err != nil { + log.Fatal(err) + } + + err = exploration.StartExploration(topo, suiteCfg) + if err != nil { + message, err := client.CreateContent(fmt.Sprintf("attacknet run completed with error %s", err.Error())) + if err != nil { + log.Fatal(err) + } + _ = message + log.Fatal(err) + } + + message, err := client.CreateContent("attacknet run completed with error ") + if err != nil { + log.Fatal(err) + } + _ = message + os.Exit(1) + */ default: log.Fatal("unrecognized arguments") } diff --git a/docs/attacknet.svg b/docs/attacknet.svg new file mode 100644 index 0000000..5b278c8 --- /dev/null +++ b/docs/attacknet.svg @@ -0,0 +1,4 @@ + + + +
Attacknet
Attacknet
Kurtosis
Kurtosis
Kubernetes
Kubernetes
Chaos Mesh Controller
Chaos Mesh Controller
Network Under Test
Network Under Test
Deploy
Deploy
Node 1
Node 1
EL Client
EL Client
CL Client
CL Client
Node 2
Node 2
EL Client
EL Client
CL Client
CL Client
Node N
Node N
EL Client
EL Client
CL Client
CL Client
Health Checks
Health Checks
Fault Manifests
Fault Manifests
Desired Network Topology
Desired Network Topology
Fault Types & Intensities
Fault Types & Intensities
Targeting Criteria
(e.g. target Reth nodes)
Targeting Criteria...
Genesis Config
Genesis Config
Client Images
Client Images
\ No newline at end of file diff --git a/go.mod b/go.mod index 8dda516..3af5dc1 100644 --- a/go.mod +++ b/go.mod @@ -6,12 +6,16 @@ toolchain go1.21.3 require ( github.com/alecthomas/kong v0.8.1 + github.com/attestantio/go-eth2-client v0.19.10 github.com/chaos-mesh/chaos-mesh/api v0.0.0-20240104130649-f55576898805 + github.com/disgoorg/disgo v0.17.2 github.com/ethereum/go-ethereum v1.13.8 github.com/grafana-tools/sdk v0.0.0-20220919052116-6562121319fc github.com/kurtosis-tech/kurtosis/api/golang v0.86.1 github.com/kurtosis-tech/stacktrace v0.0.0-20211028211901-1c67a77b5409 + github.com/rs/zerolog v1.29.1 github.com/sirupsen/logrus v1.9.3 + golang.org/x/exp v0.0.0-20240103183307-be819d1f06fc gopkg.in/yaml.v3 v3.0.1 k8s.io/api v0.29.0 k8s.io/apimachinery v0.29.0 @@ -20,13 +24,10 @@ require ( ) require ( - connectrpc.com/connect v1.11.1 // indirect github.com/Masterminds/semver/v3 v3.2.1 // indirect github.com/Microsoft/go-winio v0.6.1 // indirect - github.com/StackExchange/wmi v1.2.1 // indirect github.com/adrg/xdg v0.4.0 // indirect github.com/alecthomas/units v0.0.0-20231202071711-9a357b53e9c9 // indirect - github.com/andybalholm/brotli v1.0.4 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bits-and-blooms/bitset v1.13.0 // indirect github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect @@ -37,21 +38,26 @@ require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/deckarep/golang-set/v2 v2.6.0 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect + github.com/disgoorg/json v1.1.0 // indirect + github.com/disgoorg/snowflake/v2 v2.0.1 // indirect github.com/docker/go-units v0.5.0 // indirect github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5 // indirect github.com/emicklei/go-restful/v3 v3.11.1 // indirect github.com/ethereum/c-kzg-4844 v0.4.0 // indirect github.com/evanphx/json-patch/v5 v5.7.0 // indirect + github.com/fatih/color v1.16.0 // indirect + github.com/ferranbt/fastssz v0.1.3 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/ghodss/yaml v1.0.0 // indirect github.com/go-logr/logr v1.4.1 // indirect + github.com/go-logr/stdr v1.2.2 // indirect github.com/go-logr/zapr v1.3.0 // indirect github.com/go-ole/go-ole v1.3.0 // indirect github.com/go-openapi/jsonpointer v0.20.2 // indirect github.com/go-openapi/jsonreference v0.20.4 // indirect github.com/go-openapi/swag v0.22.7 // indirect - github.com/go-stack/stack v1.8.1 // indirect github.com/go-yaml/yaml v2.1.0+incompatible // indirect + github.com/goccy/go-yaml v1.9.2 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.3 // indirect @@ -64,20 +70,22 @@ require ( github.com/gosimple/slug v1.13.1 // indirect github.com/gosimple/unidecode v1.0.1 // indirect github.com/holiman/uint256 v1.2.4 // indirect + github.com/huandu/go-clone v1.6.0 // indirect github.com/imdario/mergo v0.3.16 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/klauspost/compress v1.16.7 // indirect - github.com/klauspost/pgzip v1.2.5 // indirect + github.com/klauspost/cpuid/v2 v2.2.6 // indirect github.com/kurtosis-tech/kurtosis-portal/api/golang v0.0.0-20231031173452-349f1ec9a443 // indirect github.com/kurtosis-tech/kurtosis/contexts-config-store v0.0.0-20240109102239-4ba41ce90af0 // indirect github.com/kurtosis-tech/kurtosis/grpc-file-transfer/golang v0.0.0-20240109102239-4ba41ce90af0 // indirect github.com/kurtosis-tech/kurtosis/utils v0.0.0-20240109102239-4ba41ce90af0 // indirect github.com/mailru/easyjson v0.7.7 // indirect - github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect github.com/mholt/archiver v3.1.1+incompatible // indirect - github.com/mholt/archiver/v3 v3.5.1 // indirect + github.com/minio/sha256-simd v1.0.1 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mmcloughlin/addchain v0.4.0 // indirect github.com/moby/spdystream v0.2.0 // indirect @@ -87,15 +95,16 @@ require ( github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect github.com/nwaples/rardecode v1.1.3 // indirect github.com/pierrec/lz4 v2.6.1+incompatible // indirect - github.com/pierrec/lz4/v4 v4.1.15 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/prometheus/client_golang v1.18.0 // indirect github.com/prometheus/client_model v0.5.0 // indirect github.com/prometheus/common v0.45.0 // indirect github.com/prometheus/procfs v0.12.0 // indirect - github.com/rainycape/unidecode v0.0.0-20150907023854-cb7f23ec59be // indirect + github.com/prysmaticlabs/go-bitfield v0.0.0-20210809151128-385d8c5e3fb7 // indirect + github.com/r3labs/sse/v2 v2.10.0 // indirect github.com/robfig/cron/v3 v3.0.1 // indirect + github.com/sasha-s/go-csync v0.0.0-20240107134140-fcbab37b09ad // indirect github.com/shirou/gopsutil v3.21.11+incompatible // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/stretchr/objx v0.5.1 // indirect @@ -106,10 +115,12 @@ require ( github.com/ulikunitz/xz v0.5.11 // indirect github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect github.com/yusufpapurcu/wmi v1.2.3 // indirect + go.opentelemetry.io/otel v1.19.0 // indirect + go.opentelemetry.io/otel/metric v1.19.0 // indirect + go.opentelemetry.io/otel/trace v1.19.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.26.0 // indirect golang.org/x/crypto v0.18.0 // indirect - golang.org/x/exp v0.0.0-20240103183307-be819d1f06fc // indirect golang.org/x/mod v0.14.0 // indirect golang.org/x/net v0.20.0 // indirect golang.org/x/oauth2 v0.16.0 // indirect @@ -119,6 +130,7 @@ require ( golang.org/x/text v0.14.0 // indirect golang.org/x/time v0.5.0 // indirect golang.org/x/tools v0.16.1 // indirect + golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect google.golang.org/appengine v1.6.8 // indirect google.golang.org/genproto v0.0.0-20240108191215-35c7eff3a6b1 // indirect @@ -126,6 +138,7 @@ require ( google.golang.org/genproto/googleapis/rpc v0.0.0-20240108191215-35c7eff3a6b1 // indirect google.golang.org/grpc v1.60.1 // indirect google.golang.org/protobuf v1.32.0 // indirect + gopkg.in/cenkalti/backoff.v1 v1.1.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect k8s.io/apiextensions-apiserver v0.29.0 // indirect diff --git a/go.sum b/go.sum index 8044c50..1d9b533 100644 --- a/go.sum +++ b/go.sum @@ -1,51 +1,37 @@ -connectrpc.com/connect v1.11.1 h1:dqRwblixqkVh+OFBOOL1yIf1jS/yP0MSJLijRj29bFg= -connectrpc.com/connect v1.11.1/go.mod h1:3AGaO6RRGMx5IKFfqbe3hvK1NqLosFNP2BxDYTPmNPo= -dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= -dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= github.com/DataDog/zstd v1.4.5 h1:EndNeuB0l9syBZhut0wns3gV1hL8zX8LIu6ZiVHWLIQ= -github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc= -github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= +github.com/DataDog/zstd v1.4.5/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0= github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= -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= +github.com/VictoriaMetrics/fastcache v1.12.1/go.mod h1:tX04vaqcNoQeGLD+ra5pU5sWkuxnzWhEzLwhP9w653o= github.com/adrg/xdg v0.4.0 h1:RzRqFcjH4nE5C6oTAxhBtoE2IRyjBSa62SCbyPidvls= github.com/adrg/xdg v0.4.0/go.mod h1:N6ag73EX4wyxeaoeHctc1mas01KZgsj5tYiAIwqJE/E= github.com/alecthomas/assert/v2 v2.1.0 h1:tbredtNcQnoSd3QBhQWI7QZ3XHOVkw1Moklp2ojoH/0= -github.com/alecthomas/kong v0.8.0 h1:ryDCzutfIqJPnNn0omnrgHLbAggDQM2VWHikE1xqK7s= -github.com/alecthomas/kong v0.8.0/go.mod h1:n1iCIO2xS46oE8ZfYCNDqdR0b0wZNrXAIAqro/2132U= +github.com/alecthomas/assert/v2 v2.1.0/go.mod h1:b/+1DI2Q6NckYi+3mXyH3wFb8qG37K/DuK80n7WefXA= github.com/alecthomas/kong v0.8.1 h1:acZdn3m4lLRobeh3Zi2S2EpnXTd1mOL6U7xVml+vfkY= github.com/alecthomas/kong v0.8.1/go.mod h1:n1iCIO2xS46oE8ZfYCNDqdR0b0wZNrXAIAqro/2132U= github.com/alecthomas/repr v0.1.0 h1:ENn2e1+J3k09gyj2shc0dHr/yjaWSHRlrJ4DPMevDqE= -github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 h1:s6gZFSlWYmbqAuRjVTiNNhvNRfY2Wxp9nhfyel4rklc= -github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= +github.com/alecthomas/repr v0.1.0/go.mod h1:2kn6fqh/zIyPLmm3ugklbEi5hg5wS435eygvNfaDQL8= github.com/alecthomas/units v0.0.0-20231202071711-9a357b53e9c9 h1:ez/4by2iGztzR4L0zgAOR8lTQK9VlyBVVd7G4omaOQs= github.com/alecthomas/units v0.0.0-20231202071711-9a357b53e9c9/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= -github.com/andybalholm/brotli v1.0.1/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y= -github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY3JY= -github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= -github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= -github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= +github.com/attestantio/go-eth2-client v0.19.10 h1:NLs9mcBvZpBTZ3du7Ey2NHQoj8d3UePY7pFBXX6C6qs= +github.com/attestantio/go-eth2-client v0.19.10/go.mod h1:TTz7YF6w4z6ahvxKiHuGPn6DbQn7gH6HPuWm/DEQeGE= 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/bits-and-blooms/bitset v1.13.0 h1:bAQ9OPNFYbGHV6Nez0tmNI0RiEu7/hxlYJRUA0wFAVE= github.com/bits-and-blooms/bitset v1.13.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= -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/btcec/v2 v2.3.2 h1:5n0X6hX0Zk+6omWcihdYvdAlGf2DfasC0GMf7DClJ3U= github.com/btcsuite/btcd/btcec/v2 v2.3.2/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOFYSNEs0TFnxxnS9+4U= +github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= github.com/bxcodec/faker v2.0.1+incompatible h1:P0KUpUw5w6WJXwrPfv35oc91i4d8nf40Nwln+M/+faA= +github.com/bxcodec/faker v2.0.1+incompatible/go.mod h1:BNzfpVdTwnFJ6GtfYTcQu6l6rHShT+veBxNCnjCx5XM= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/chaos-mesh/chaos-mesh/api v0.0.0-20230927082628-87b6322f9b46 h1:rYxhAD4Swa38Drk/DiCGLvgn/pRq2GhVTAk5cm79an0= -github.com/chaos-mesh/chaos-mesh/api v0.0.0-20230927082628-87b6322f9b46/go.mod h1:D0MCl3VJDwy+kjliAbf/RIBk1aeE5fOsvjzNSmZHF6E= github.com/chaos-mesh/chaos-mesh/api v0.0.0-20240104130649-f55576898805 h1:QjGJQDB+rcJkUEPjn4z3Ur6DgJHBbGobwdOX2i4WQ14= github.com/chaos-mesh/chaos-mesh/api v0.0.0-20240104130649-f55576898805/go.mod h1:x11iCbZV6hzzSQWMq610B6Wl5Lg1dhwqcVfeiWQQnQQ= github.com/chromedp/cdproto v0.0.0-20210526005521-9e51b9051fd0/go.mod h1:At5TxYYdxkbQL0TSefRjhLE3Q0lgvqKKMSFUglJ7i1U= @@ -56,91 +42,101 @@ github.com/chromedp/chromedp v0.7.3/go.mod h1:9gC521Yzgrk078Ulv6KIgG7hJ2x9aWrxMB github.com/chromedp/sysutil v1.0.0 h1:+ZxhTpfpZlmchB58ih/LBHX52ky7w2VhQVKQMucy3Ic= github.com/chromedp/sysutil v1.0.0/go.mod h1:kgWmDdq8fTzXYcKIBqIYvRRTnYb9aNS9moAV0xufSww= github.com/cockroachdb/errors v1.8.1 h1:A5+txlVZfOqFBDa4mGz2bUWSp0aHElvHX2bKkdbQu+Y= +github.com/cockroachdb/errors v1.8.1/go.mod h1:qGwQn6JmZ+oMjuLwjWzUNqblqk0xl4CVV3SQbGwK7Ac= github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f h1:o/kfcElHqOiXqcou5a3rIlMc7oJbMQkeLk0VQJ7zgqY= +github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI= github.com/cockroachdb/pebble v0.0.0-20230928194634-aa077af62593 h1:aPEJyR4rPBvDmeyi+l/FS/VtA00IWvjeFvjen1m1l1A= +github.com/cockroachdb/pebble v0.0.0-20230928194634-aa077af62593/go.mod h1:6hk1eMY/u5t+Cf18q5lFMUA1Rc+Sm5I6Ra1QuPyxXCo= github.com/cockroachdb/redact v1.0.8 h1:8QG/764wK+vmEYoOlfobpe12EQcS81ukx/a4hdVMxNw= +github.com/cockroachdb/redact v1.0.8/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= github.com/cockroachdb/sentry-go v0.6.1-cockroachdb.2 h1:IKgmqgMQlVJIZj19CdocBeSfSaiCbEBZGKODaixqtHM= +github.com/cockroachdb/sentry-go v0.6.1-cockroachdb.2/go.mod h1:8BT+cPK6xvFOcRlk0R8eg+OTkcqI6baNH4xAkpiYVvQ= github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 h1:zuQyyAKVxetITBuuhv3BI9cMrmStnpT18zmgmTxunpo= +github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06/go.mod h1:7nc4anLGjupUW/PeY5qiNYsdNXj7zopG+eqsS7To5IQ= github.com/consensys/bavard v0.1.13 h1:oLhMLOFGTLdlda/kma4VOJazblc7IM5y5QPd2A/YjhQ= github.com/consensys/bavard v0.1.13/go.mod h1:9ItSMtA/dXMAiL7BG6bqW2m3NdSEObYWoH223nGHukI= github.com/consensys/gnark-crypto v0.12.1 h1:lHH39WuuFgVHONRl3J0LRBtuYdQTumFSDtJF7HpyG8M= github.com/consensys/gnark-crypto v0.12.1/go.mod h1:v2Gy7L/4ZRosZ7Ivs+9SfUDr0f5UlG+EM5t7MPHiLuY= +github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= +github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/crate-crypto/go-ipa v0.0.0-20231025140028-3c0104f4b233 h1:d28BXYi+wUpz1KBmiF9bWrjEMacUEREV6MBi2ODnrfQ= +github.com/crate-crypto/go-ipa v0.0.0-20231025140028-3c0104f4b233/go.mod h1:geZJZH3SzKCqnz5VT0q/DyIG/tvu/dZk+VIfXicupJs= github.com/crate-crypto/go-kzg-4844 v0.7.0 h1:C0vgZRk4q4EZ/JgPfzuSoxdCq3C3mOZMBShovmncxvA= github.com/crate-crypto/go-kzg-4844 v0.7.0/go.mod h1:1kMhvPgI0Ky3yIa+9lFySEBUBXkYxeOi8ZF1sYioxhc= -github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/deckarep/golang-set/v2 v2.1.0 h1:g47V4Or+DUdzbs8FxCCmgb6VYd+ptPAngjM6dtGktsI= -github.com/deckarep/golang-set/v2 v2.1.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= github.com/deckarep/golang-set/v2 v2.6.0 h1:XfcQbWM1LlMB8BsJ8N9vW5ehnnPVIw0je80NsVHagjM= github.com/deckarep/golang-set/v2 v2.6.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= -github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= -github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 h1:YLtO71vCjJRCBcrPMtQ9nqBsqpA1m5sE92cU+pd5Mcc= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs= +github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y= +github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= +github.com/disgoorg/disgo v0.17.2 h1:RxiLq8guMtk+9tArFwve02iya2APQ9yZVtV30ySKNtw= +github.com/disgoorg/disgo v0.17.2/go.mod h1:8r3h9fXSz7BbACxLPsPbtB6LX8gaQFUETgPKV/0gAKQ= +github.com/disgoorg/json v1.1.0 h1:7xigHvomlVA9PQw9bMGO02PHGJJPqvX5AnwlYg/Tnys= +github.com/disgoorg/json v1.1.0/go.mod h1:BHDwdde0rpQFDVsRLKhma6Y7fTbQKub/zdGO5O9NqqA= +github.com/disgoorg/snowflake/v2 v2.0.1 h1:CuUxGLwggUxEswZOmZ+mZ5i0xSumQdXW9tXW7uGqe+0= +github.com/disgoorg/snowflake/v2 v2.0.1/go.mod h1:SPU9c2CNn5DSyb86QcKtdZgix9osEtKrHLW4rMhfLCs= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5 h1:iFaUwBSo5Svw6L7HYpRu/0lE3e0BaElwnNO1qkNQxBY= github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5/go.mod h1:qssHWj60/X5sZFNxpG4HBPDHVqxNm4DfnCKgrbZOT+s= github.com/dsnet/golib v0.0.0-20171103203638-1ea166775780/go.mod h1:Lj+Z9rebOhdfkVLjJ8T6VcRQv3SXugXy999NBtR9aFY= -github.com/emicklei/go-restful/v3 v3.10.1 h1:rc42Y5YTp7Am7CS630D7JmhRjq4UlEUuEKfrDac4bSQ= -github.com/emicklei/go-restful/v3 v3.10.1/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/emicklei/go-restful/v3 v3.11.1 h1:S+9bSbua1z3FgCnV0KKOSSZ3mDthb5NyEPL5gEpCvyk= github.com/emicklei/go-restful/v3 v3.11.1/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/ethereum/c-kzg-4844 v0.4.0 h1:3MS1s4JtA868KpJxroZoepdV0ZKBp3u/O5HcZ7R3nlY= github.com/ethereum/c-kzg-4844 v0.4.0/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1aQputP83wc0= -github.com/ethereum/go-ethereum v1.13.5 h1:U6TCRciCqZRe4FPXmy1sMGxTfuk8P7u2UoinF3VbaFk= -github.com/ethereum/go-ethereum v1.13.5/go.mod h1:yMTu38GSuyxaYzQMViqNmQ1s3cE84abZexQmTgenWk0= github.com/ethereum/go-ethereum v1.13.8 h1:1od+thJel3tM52ZUNQwvpYOeRHlbkVFZ5S8fhi0Lgsg= github.com/ethereum/go-ethereum v1.13.8/go.mod h1:sc48XYQxCzH3fG9BcrXCOOgQk2JfZzNAmIKnceogzsA= github.com/evanphx/json-patch v5.6.0+incompatible h1:jBYDEEiFBPxA0v50tFdvOzQQTCvpL6mnFh5mB2/l16U= -github.com/evanphx/json-patch/v5 v5.6.0 h1:b91NhWfaz02IuVxO9faSllyAtNXHMPkC5J8sJCLunww= -github.com/evanphx/json-patch/v5 v5.6.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4= +github.com/evanphx/json-patch v5.6.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch/v5 v5.7.0 h1:nJqP7uwL84RJInrohHfW0Fx3awjbm8qZeFv0nW9SYGc= github.com/evanphx/json-patch/v5 v5.7.0/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq14uClGH4abBuQ= +github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= +github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= +github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= +github.com/ferranbt/fastssz v0.1.3 h1:ZI+z3JH05h4kgmFXdHuR1aWYsgrg7o+Fw7/NCzM16Mo= +github.com/ferranbt/fastssz v0.1.3/go.mod h1:0Y9TEd/9XuFlh7mskMPfXiI2Dkw4Ddg9EyXt1W7MRvE= github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 h1:FtmdgXiUlNeRsoNMFlKLDt+S+6hbjVMEW6RGQ7aUf7c= -github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= -github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= +github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= +github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= +github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff h1:tY80oXqGNY4FhTFhk+o9oFHGINQ/+vhlm8HFzi6znCI= +github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= +github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46 h1:BAIP2GihuqhwdILrV+7GJel5lyPV3u1+PgzrWLc0TkE= +github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46/go.mod h1:QNpY22eby74jVhqH4WhDLDwxc/vqsern6pW+u2kbkpc= github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= -github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= -github.com/go-logr/zapr v1.2.4 h1:QHVo+6stLbfJmYGkQ7uGHUCu5hnAFAj6mDe6Ea0SeOo= -github.com/go-logr/zapr v1.2.4/go.mod h1:FyHWQIzQORZ0QVE1BtVHv3cKtNLuXsbNLtpuhNapBOA= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ= github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg= -github.com/go-ole/go-ole v1.2.5 h1:t4MGB5xEDZvXI+0rMjjsfBsD7yAgp/s9ZDkL1JndXwY= -github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE= github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78= -github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= -github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= github.com/go-openapi/jsonpointer v0.20.2 h1:mQc3nmndL8ZBzStEo3JYF8wzmeWffDH4VbXz58sAx6Q= github.com/go-openapi/jsonpointer v0.20.2/go.mod h1:bHen+N0u1KEO3YlmqOjTT9Adn1RfD91Ar825/PuiRVs= -github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= -github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= github.com/go-openapi/jsonreference v0.20.4 h1:bKlDxQxQJgwpUSgOENiMPzCTBVuc7vTdXSSgNeAhojU= github.com/go-openapi/jsonreference v0.20.4/go.mod h1:5pZJyJP2MnYCpoeoMAql78cCHauHj0V9Lhc506VOpw4= -github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g= -github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= -github.com/go-openapi/swag v0.22.4/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= github.com/go-openapi/swag v0.22.7 h1:JWrc1uc/P9cSomxfnsFSVWoE1FW6bNbrVPmpQYpCcR8= github.com/go-openapi/swag v0.22.7/go.mod h1:Gl91UqO+btAM0plGGxHqJcQZ1ZTy6jbmridBTsDy8A0= -github.com/go-stack/stack v1.8.1 h1:ntEHSVwIt7PNXNpgPmVfMrNhLtgjlmnZha2kOpuRiDw= -github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4= +github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q= +github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= +github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no= +github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= +github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7aM3F26W0hOn+GE= +github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= github.com/go-yaml/yaml v2.1.0+incompatible h1:RYi2hDdss1u4YE7GwixGzWwVo47T8UQwnTLB6vQiq+o= github.com/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaLENm+P+Tv+MfurjSw0= github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU= @@ -149,25 +145,26 @@ github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og= github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= github.com/gobwas/ws v1.1.0-rc.5 h1:QOAag7FoBaBYYHRqzqkhhd8fq5RTubvI4v3Ft/gDVVQ= github.com/gobwas/ws v1.1.0-rc.5/go.mod h1:nzvNcVha5eUziGrbxFCo6qFIojQHjJV5cLYIbezhfL0= +github.com/goccy/go-yaml v1.9.2 h1:2Njwzw+0+pjU2gb805ZC1B/uBuAs2VcZ3K+ZgHwDs7w= +github.com/goccy/go-yaml v1.9.2/go.mod h1:U/jl18uSupI5rdI2jmuCswEA2htH9eXfferR3KfscvA= +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= +github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= +github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/golang/snappy v0.0.2/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb h1:PBC98N2aIaM3XXiurYmW7fx4GZkL8feAMVq7nEjURHk= github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= @@ -175,17 +172,13 @@ github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/ github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/pprof v0.0.0-20230207041349-798e818bf904 h1:4/hN5RUoecvl+RmJRE2YxKWtnnQls6rQjjW5oV7qg2U= +github.com/google/pprof v0.0.0-20230207041349-798e818bf904/go.mod h1:uglQLonpP8qtYCYyzA+8c/9qtqgA3qsXGYqCPKARAFg= 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.4.0/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.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= -github.com/gosimple/slug v1.1.1 h1:fRu/digW+NMwBIP+RmviTK97Ho/bEj/C9swrCspN3D4= github.com/gosimple/slug v1.1.1/go.mod h1:ER78kgg1Mv0NQGlXiDe57DpCyfbNywXXZ9mIorhxAf0= github.com/gosimple/slug v1.13.1 h1:bQ+kpX9Qa6tHRaK+fZR0A0M2Kd7Pa5eHPPsb1JpHD+Q= github.com/gosimple/slug v1.13.1/go.mod h1:UiRaFH+GEilHstLUmcBgWcI42viBN7mAb818JrYOeFQ= @@ -194,20 +187,27 @@ github.com/gosimple/unidecode v1.0.1/go.mod h1:CP0Cr1Y1kogOtx0bJblKzsVWrqYaqfNOn github.com/grafana-tools/sdk v0.0.0-20220919052116-6562121319fc h1:PXZQA2WCxe85Tnn+WEvr8fDpfwibmEPgfgFEaC87G24= github.com/grafana-tools/sdk v0.0.0-20220919052116-6562121319fc/go.mod h1:AHHlOEv1+GGQ3ktHMlhuTUwo3zljV3QJbC0+8o2kn+4= github.com/hashicorp/go-bexpr v0.1.10 h1:9kuI5PFotCboP3dkDYFr/wi0gg0QVbSNz5oFRpxn4uE= +github.com/hashicorp/go-bexpr v0.1.10/go.mod h1:oxlubA2vC/gFVfX1A6JGp7ls7uCDlfJn732ehYYg+g0= github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= +github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= github.com/holiman/billy v0.0.0-20230718173358-1c7e68d277a7 h1:3JQNjnMRil1yD0IfZKHF9GxxWKDJGj8I0IqOUol//sw= +github.com/holiman/billy v0.0.0-20230718173358-1c7e68d277a7/go.mod h1:5GuXa7vkL8u9FkFuWdVvfR5ix8hRB7DbOAaYULamFpc= github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao= -github.com/holiman/uint256 v1.2.3 h1:K8UWO1HUJpRMXBxbmaY1Y8IAMZC/RsKB+ArEnnK4l5o= -github.com/holiman/uint256 v1.2.3/go.mod h1:SC8Ryt4n+UBbPbIBKaG9zbbDlp4jOru9xFZmPzLUTxw= +github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA= github.com/holiman/uint256 v1.2.4 h1:jUc4Nk8fm9jZabQuqr2JzednajVmBpC+oiTiXZJEApU= github.com/holiman/uint256 v1.2.4/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E= +github.com/huandu/go-assert v1.1.5 h1:fjemmA7sSfYHJD7CUqs9qTwwfdNAx7/j2/ZlHXzNB3c= +github.com/huandu/go-assert v1.1.5/go.mod h1:yOLvuqZwmcHIC5rIzrBhT7D3Q9c3GFnd0JrPVhn/06U= +github.com/huandu/go-clone v1.6.0 h1:HMo5uvg4wgfiy5FoGOqlFLQED/VGRm2D9Pi8g1FXPGc= +github.com/huandu/go-clone v1.6.0/go.mod h1:ReGivhG6op3GYr+UY3lS6mxjKp7MIGTknuU5TbTVaXE= +github.com/huandu/go-clone/generic v1.6.0 h1:Wgmt/fUZ28r16F2Y3APotFD59sHk1p78K0XLdbUYN5U= +github.com/huandu/go-clone/generic v1.6.0/go.mod h1:xgd9ZebcMsBWWcBx5mVMCoqMX24gLWr5lQicr+nVXNs= github.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc= -github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk= -github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg= +github.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= -github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= @@ -215,74 +215,56 @@ github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHm 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.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= -github.com/klauspost/compress v1.11.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I= github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= -github.com/klauspost/pgzip v1.2.5 h1:qnWYvvKqedOF2ulHpMG72XQol4ILEJ8k2wwRl/Km8oE= -github.com/klauspost/pgzip v1.2.5/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= -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/klauspost/cpuid/v2 v2.2.6 h1:ndNyv040zDGIDh8thGkXYjnFtiN02M1PVVF+JE/48xc= +github.com/klauspost/cpuid/v2 v2.2.6/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/kurtosis-tech/kurtosis-portal/api/golang v0.0.0-20230818182330-1a86869414d2 h1:izciXrFyFR+ihJ7nLTOkoIX5GzBPIp8gVKlw94gIc98= -github.com/kurtosis-tech/kurtosis-portal/api/golang v0.0.0-20230818182330-1a86869414d2/go.mod h1:bWSMQK3WHVTGHX9CjxPAb/LtzcmfOxID2wdzakSWQxo= github.com/kurtosis-tech/kurtosis-portal/api/golang v0.0.0-20231031173452-349f1ec9a443 h1:jqFVT4FcZU+wG+y5FV+Xz9+IwNqSyredbcFKHfK2Kh8= github.com/kurtosis-tech/kurtosis-portal/api/golang v0.0.0-20231031173452-349f1ec9a443/go.mod h1:bWSMQK3WHVTGHX9CjxPAb/LtzcmfOxID2wdzakSWQxo= -github.com/kurtosis-tech/kurtosis/api/golang v0.85.9 h1:LJDnBYFGu1+cosa67Flks04K8j68jjPJZ/DyB2RtYbA= -github.com/kurtosis-tech/kurtosis/api/golang v0.85.9/go.mod h1:JSS7/iBtztvqgR4eyVXx6jaI8hpU+WtEBk8S11nYFKU= -github.com/kurtosis-tech/kurtosis/api/golang v0.85.56-0.20240105153304-05099e567004 h1:jspygYW+p6QGEwJh97oGIP95OO3Ld/ns7JOeebTYjMQ= -github.com/kurtosis-tech/kurtosis/api/golang v0.85.56-0.20240105153304-05099e567004/go.mod h1:eT43r9WAooqDCpIs0+QlyUFR/fqAaqpSKcYPNKD2Zcg= -github.com/kurtosis-tech/kurtosis/api/golang v0.85.56 h1:ZQqJwzJBnjdVkv6+so4VTHuC7CisqduDJNeAr5BFNs8= -github.com/kurtosis-tech/kurtosis/api/golang v0.85.56/go.mod h1:eT43r9WAooqDCpIs0+QlyUFR/fqAaqpSKcYPNKD2Zcg= github.com/kurtosis-tech/kurtosis/api/golang v0.86.1 h1:Lz3nFRulFHLlCykTrv5et01gTGPvU07b68iyayFrsZo= github.com/kurtosis-tech/kurtosis/api/golang v0.86.1/go.mod h1:eT43r9WAooqDCpIs0+QlyUFR/fqAaqpSKcYPNKD2Zcg= -github.com/kurtosis-tech/kurtosis/contexts-config-store v0.0.0-20230818184218-f4e3e773463b h1:hMoIM99QKcYQqsnK4AF7Lovi9ZD9ac6lZLZ5D/jx2x8= -github.com/kurtosis-tech/kurtosis/contexts-config-store v0.0.0-20230818184218-f4e3e773463b/go.mod h1:4pFdrRwDz5R+Fov2ZuTaPhAVgjA2jhGh1Izf832sX7A= -github.com/kurtosis-tech/kurtosis/contexts-config-store v0.0.0-20240105153304-05099e567004 h1:gQLztIZ4CWwc0N6lOcnFfwPctZHSESUym2W0HtTfKYY= -github.com/kurtosis-tech/kurtosis/contexts-config-store v0.0.0-20240105153304-05099e567004/go.mod h1:bm+jMBhirwvfuXG99TDZFuvmSwDfeziVJPobRvHgafc= -github.com/kurtosis-tech/kurtosis/contexts-config-store v0.0.0-20240108104845-8e7cf71acdac h1:DlUe7n8VZang9cXRKcFlUi8lTg6ZNaufPL9C7z4yiZk= -github.com/kurtosis-tech/kurtosis/contexts-config-store v0.0.0-20240108104845-8e7cf71acdac/go.mod h1:bm+jMBhirwvfuXG99TDZFuvmSwDfeziVJPobRvHgafc= github.com/kurtosis-tech/kurtosis/contexts-config-store v0.0.0-20240109102239-4ba41ce90af0 h1:/anRCavLbkzCdRMRovtZAx6Dg6di5CgqLciWiQUdNLY= github.com/kurtosis-tech/kurtosis/contexts-config-store v0.0.0-20240109102239-4ba41ce90af0/go.mod h1:bm+jMBhirwvfuXG99TDZFuvmSwDfeziVJPobRvHgafc= -github.com/kurtosis-tech/kurtosis/grpc-file-transfer/golang v0.0.0-20230803130419-099ee7a4e3dc h1:7IlEpSehmWcNXOFpNP24Cu5HQI3af7GCBQw//m+LnvQ= -github.com/kurtosis-tech/kurtosis/grpc-file-transfer/golang v0.0.0-20230803130419-099ee7a4e3dc/go.mod h1:TOWMQgvAJH/NiWWERGXg/plT9lS7aFcXFxCa0M5sfHo= -github.com/kurtosis-tech/kurtosis/grpc-file-transfer/golang v0.0.0-20240105153304-05099e567004 h1:0jkNMJP12Cb4Df5kupD7IGnf6OwuN5j7i6o4sQGlkfQ= -github.com/kurtosis-tech/kurtosis/grpc-file-transfer/golang v0.0.0-20240105153304-05099e567004/go.mod h1:XWnZw30gs8O8ySajNTQubyOOmwkKxxwCzDKuJ7YzZYk= -github.com/kurtosis-tech/kurtosis/grpc-file-transfer/golang v0.0.0-20240108104845-8e7cf71acdac h1:9Nk84UHRt0N5u72ZJTJpaUY8dk/ccDhjJRPFjFtDTwE= -github.com/kurtosis-tech/kurtosis/grpc-file-transfer/golang v0.0.0-20240108104845-8e7cf71acdac/go.mod h1:XWnZw30gs8O8ySajNTQubyOOmwkKxxwCzDKuJ7YzZYk= github.com/kurtosis-tech/kurtosis/grpc-file-transfer/golang v0.0.0-20240109102239-4ba41ce90af0 h1:Er0K/PnwBWI+PgKf5KWRjaHccveJwIW4wrM1ebvWMg8= github.com/kurtosis-tech/kurtosis/grpc-file-transfer/golang v0.0.0-20240109102239-4ba41ce90af0/go.mod h1:XWnZw30gs8O8ySajNTQubyOOmwkKxxwCzDKuJ7YzZYk= -github.com/kurtosis-tech/kurtosis/utils v0.0.0-20240105153304-05099e567004 h1:gx8OqZZGKKs2OhYpb1Hy27cnZa6cvuKEzyCiUvACyOs= -github.com/kurtosis-tech/kurtosis/utils v0.0.0-20240105153304-05099e567004/go.mod h1:Wswa+3L2+lvd62qFKgjlb4Q+kgTNL5Tk9rUK+naBku4= -github.com/kurtosis-tech/kurtosis/utils v0.0.0-20240108104845-8e7cf71acdac h1:tg1TYA/lZK3ICVE80mjyETcXRvJVRvKbbyRuf5B/P+U= -github.com/kurtosis-tech/kurtosis/utils v0.0.0-20240108104845-8e7cf71acdac/go.mod h1:Wswa+3L2+lvd62qFKgjlb4Q+kgTNL5Tk9rUK+naBku4= github.com/kurtosis-tech/kurtosis/utils v0.0.0-20240109102239-4ba41ce90af0 h1:EkPhst4mcaWgLJWXn0lwIhpmStl3KYi7HlaSeXxz4iY= github.com/kurtosis-tech/kurtosis/utils v0.0.0-20240109102239-4ba41ce90af0/go.mod h1:Wswa+3L2+lvd62qFKgjlb4Q+kgTNL5Tk9rUK+naBku4= github.com/kurtosis-tech/stacktrace v0.0.0-20211028211901-1c67a77b5409 h1:YQTATifMUwZEtZYb0LVA7DK2pj8s71iY8rzweuUQ5+g= github.com/kurtosis-tech/stacktrace v0.0.0-20211028211901-1c67a77b5409/go.mod h1:y5weVs5d9wXXHcDA1awRxkIhhHC1xxYJN8a7aXnE6S8= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= +github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= +github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= +github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= -github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= -github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= -github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= +github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 h1:jWpvCLoY8Z/e3VKvlsiIGKtc+UG6U5vzxaoagmhXfyg= github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0/go.mod h1:QUyp042oQthUoa9bqDv0ER0wrtXnBruoNd7aNjkbP+k= github.com/mholt/archiver v3.1.1+incompatible h1:1dCVxuqs0dJseYEhi5pl7MYPH9zDa1wBi7mF09cbNkU= github.com/mholt/archiver v3.1.1+incompatible/go.mod h1:Dh2dOXnSdiLxRiPoVfIr/fI1TwETms9B8CTWfeh7ROU= -github.com/mholt/archiver/v3 v3.5.1 h1:rDjOBX9JSF5BvoJGvjqK479aL70qh9DIpZCl+k7Clwo= -github.com/mholt/archiver/v3 v3.5.1/go.mod h1:e3dqJ7H78uzsRSEACH1joayhuSyhnonssnDhppzS1L4= -github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag= +github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM= +github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/pointerstructure v1.2.0 h1:O+i9nHnXS3l/9Wu7r4NrEdwA2VFTicjUEN1uBnDo34A= +github.com/mitchellh/pointerstructure v1.2.0/go.mod h1:BRAsLI5zgXmw97Lf6s25bs8ohIXc3tViBH44KcwB2g4= github.com/mmcloughlin/addchain v0.4.0 h1:SobOdjm2xLj1KkXN5/n0xTIWyZA2+s99UCY1iPfkHRY= github.com/mmcloughlin/addchain v0.4.0/go.mod h1:A86O+tHqZLMNO4w6ZZ4FlVQEadcoqkyU72HC5wJ4RlU= github.com/mmcloughlin/profile v0.1.1/go.mod h1:IhHD7q1ooxgwTgjxQYkACGA77oFTDdFVejUS1/tS/qU= @@ -297,60 +279,58 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= -github.com/nwaples/rardecode v1.1.0/go.mod h1:5DzqNKiOdpKKBH87u8VlvAnPZMXcGRhxWkRpHbbfGS0= github.com/nwaples/rardecode v1.1.3 h1:cWCaZwfM5H7nAD6PyEdcVnczzV8i/JtotnyW/dD9lEc= github.com/nwaples/rardecode v1.1.3/go.mod h1:5DzqNKiOdpKKBH87u8VlvAnPZMXcGRhxWkRpHbbfGS0= github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= -github.com/onsi/ginkgo/v2 v2.12.0 h1:UIVDowFPwpg6yMUpPjGkYvf06K3RAiJXUhCxEwQVHRI= -github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= +github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= +github.com/onsi/ginkgo/v2 v2.13.0 h1:0jY9lJquiL8fcf3M4LAXN5aMlS/b2BV86HFFPCPMgE4= +github.com/onsi/ginkgo/v2 v2.13.0/go.mod h1:TE309ZR8s5FsKKpuB1YAQYBzCaAfUgatB/xlT/ETL/o= +github.com/onsi/gomega v1.29.0 h1:KIA/t2t5UBzoirT4H9tsML45GEbo3ouUnBHsCfD2tVg= +github.com/onsi/gomega v1.29.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ= github.com/pierrec/lz4 v2.6.1+incompatible h1:9UY3+iC23yxF0UfGaYrGplQ+79Rg+h/q9FV9ix19jjM= github.com/pierrec/lz4 v2.6.1+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= -github.com/pierrec/lz4/v4 v4.1.2/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= -github.com/pierrec/lz4/v4 v4.1.15 h1:MO0/ucJhngq7299dKLwIMtgTfbkoSPF6AoMYDd8Q4q0= -github.com/pierrec/lz4/v4 v4.1.15/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_golang v1.16.0 h1:yk/hx9hDbrGHovbci4BY+pRMfSuuat626eFsHb7tmT8= -github.com/prometheus/client_golang v1.16.0/go.mod h1:Zsulrv/L9oM40tJ7T815tM89lFEugiJ9HzIqaAx4LKc= github.com/prometheus/client_golang v1.18.0 h1:HzFfmkOzH5Q8L8G+kSJKUx5dtG87sewO+FoDDqP5Tbk= github.com/prometheus/client_golang v1.18.0/go.mod h1:T+GXkCk5wSJyOqMIzVgvvjFDlkOQntgjkJWKrN5txjA= -github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY= -github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU= github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw= github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI= -github.com/prometheus/common v0.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdOOfY= -github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY= github.com/prometheus/common v0.45.0 h1:2BGz0eBc2hdMDLnO/8n0jeB3oPrt2D08CekT0lneoxM= github.com/prometheus/common v0.45.0/go.mod h1:YJmSTw9BoKxJplESWWxlbyttQR4uaEcGyv9MZjVOJsY= -github.com/prometheus/procfs v0.10.1 h1:kYK1Va/YMlutzCGazswoHKo//tZVlFpKYh+PymziUAg= -github.com/prometheus/procfs v0.10.1/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM= github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= -github.com/rainycape/unidecode v0.0.0-20150907023854-cb7f23ec59be h1:ta7tUOvsPHVHGom5hKW5VXNc2xZIkfCKP8iaqOyYtUQ= +github.com/prysmaticlabs/go-bitfield v0.0.0-20210809151128-385d8c5e3fb7 h1:0tVE4tdWQK9ZpYygoV7+vS6QkDvQVySboMVEIxBJmXw= +github.com/prysmaticlabs/go-bitfield v0.0.0-20210809151128-385d8c5e3fb7/go.mod h1:wmuf/mdK4VMD+jA9ThwcUKjg3a2XWM9cVfFYjDyY4j4= +github.com/r3labs/sse/v2 v2.10.0 h1:hFEkLLFY4LDifoHdiCN/LlGBAdVJYsANaLqNYa1l/v0= +github.com/r3labs/sse/v2 v2.10.0/go.mod h1:Igau6Whc+F17QUgML1fYe1VPZzTV6EMCnYktEmkNJ7I= github.com/rainycape/unidecode v0.0.0-20150907023854-cb7f23ec59be/go.mod h1:MIDFMn7db1kT65GmV94GzpX9Qdi7N/pQlwb+AN8wh+Q= github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= -github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= +github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= +github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik= +github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= +github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= +github.com/rs/zerolog v1.29.1 h1:cO+d60CHkknCbvzEWxP0S9K6KqyTjrCNUy1LdQLCGPc= +github.com/rs/zerolog v1.29.1/go.mod h1:Le6ESbR7hc+DP6Lt1THiV8CQSdkkNrd3R0XbEgp3ZBU= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= -github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible h1:Bn1aCHHRnjv4Bl16T8rcaFjYSrGrIZvpiGO6P3Q4GpU= -github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/sasha-s/go-csync v0.0.0-20240107134140-fcbab37b09ad h1:qIQkSlF5vAUHxEmTbaqt1hkJ/t6skqEGYiMag343ucI= +github.com/sasha-s/go-csync v0.0.0-20240107134140-fcbab37b09ad/go.mod h1:/pA7k3zsXKdjjAiUhB5CjuKib9KJGCaLvZwtxGC8U0s= github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI= github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= -github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= -github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= 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/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= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/objx v0.5.1 h1:4VhoImhV/Bm0ToFkXFi8hXNXwpDRZ/ynw3amt82mzq0= github.com/stretchr/objx v0.5.1/go.mod h1:/iHQpkQwBD6DLUmQ4pE+s1TXdob1mORJ4/UFdrifcy0= @@ -359,133 +339,101 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P 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= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/supranational/blst v0.3.11 h1:LyU6FolezeWAhvQk0k6O/d49jqgO52MSDDfYgbeoEm4= github.com/supranational/blst v0.3.11/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= -github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU= -github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI= +github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= github.com/tklauser/go-sysconf v0.3.13 h1:GBUpcahXSpR2xN01jhkNAbTLRk2Yzgggk8IM08lq3r4= github.com/tklauser/go-sysconf v0.3.13/go.mod h1:zwleP4Q4OehZHGn4CYZDipCgg9usW5IJePewFCGVEa0= -github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk= -github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY= github.com/tklauser/numcpus v0.7.0 h1:yjuerZP127QG9m5Zh/mSO4wqurYil27tHrqwRoRjpr4= github.com/tklauser/numcpus v0.7.0/go.mod h1:bb6dMVcj8A42tSE7i32fsIUCbQNllK5iDguyOZRUzAY= github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8= +github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U= github.com/ulikunitz/xz v0.5.8/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= -github.com/ulikunitz/xz v0.5.9/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= -github.com/ulikunitz/xz v0.5.10 h1:t92gobL9l3HE202wg3rlk19F6X+JOxl9BBrCCMYEYd8= -github.com/ulikunitz/xz v0.5.10/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= github.com/ulikunitz/xz v0.5.11 h1:kpFauv27b6ynzBNT/Xy+1k+fK4WswhN/6PN5WhFAGw8= github.com/ulikunitz/xz v0.5.11/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= +github.com/umbracle/gohashtree v0.0.2-alpha.0.20230207094856-5b775a815c10 h1:CQh33pStIp/E30b7TxDlXfM0145bn2e8boI30IxAhTg= +github.com/umbracle/gohashtree v0.0.2-alpha.0.20230207094856-5b775a815c10/go.mod h1:x/Pa0FF5Te9kdrlZKJK82YmAkvL8+f989USgz6Jiw7M= github.com/urfave/cli/v2 v2.25.7 h1:VAzn5oq403l5pHjc4OhD54+XGO9cdKVL/7lDjF+iKUs= +github.com/urfave/cli/v2 v2.25.7/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ= github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 h1:nIPpBwaJSVYIxUFsDv3M8ofmx9yWTog9BfvIu0q41lo= github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos= github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= +github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw= github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= -go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= +go.opentelemetry.io/otel v1.19.0 h1:MuS/TNf4/j4IXsZuJegVzI1cwut7Qc00344rgH7p8bs= +go.opentelemetry.io/otel v1.19.0/go.mod h1:i0QyjOq3UPoTzff0PJB2N66fb4S0+rSbSB15/oyH9fY= +go.opentelemetry.io/otel/metric v1.19.0 h1:aTzpGtV0ar9wlV4Sna9sdJyII5jTVJEvKETPiOKwvpE= +go.opentelemetry.io/otel/metric v1.19.0/go.mod h1:L5rUsV9kM1IxCj1MmSdS+JQAcVm319EUrDVLrt7jqt8= +go.opentelemetry.io/otel/trace v1.19.0 h1:DFVQmlVbfVeOuBRrwdtaehRrWiL1JoVs9CPIQ1Dzxpg= +go.opentelemetry.io/otel/trace v1.19.0/go.mod h1:mfaSyvGyEJEI0nyV2I4qhNQnbBOUUmYZpYojqMnX2vo= go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A= -go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= +go.uber.org/goleak v1.2.1/go.mod h1:qlT2yGI9QafXHhZZLxlSuNsMw3FFLxBr+tBRlmO1xH4= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= -go.uber.org/zap v1.25.0 h1:4Hvk6GtkucQ790dqmj7l1eEnRdKm3k3ZUrUMS2d5+5c= -go.uber.org/zap v1.25.0/go.mod h1:JIAUzQIH94IC4fOJQm7gMmBJP5k7wQfdcnYdPoEXJYk= go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -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/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc= golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= -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/exp v0.0.0-20240103183307-be819d1f06fc h1:ao2WRsKSzW6KuUY9IWPwWahcHCgR0s52IfwutMfEbdM= golang.org/x/exp v0.0.0-20240103183307-be819d1f06fc/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI= -golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= -golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191116160921-f9c825593386/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -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/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo= golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= -golang.org/x/oauth2 v0.8.0 h1:6dkIjl3j3LtZ/O3sTgZTMsLKSftL/B8Zgq4huOIIUu8= -golang.org/x/oauth2 v0.8.0/go.mod h1:yr7u4HXZRm1R1kBWqr/xKNqewf0plRYoB7sla+BCIXE= -golang.org/x/oauth2 v0.15.0 h1:s8pnnxNVzjWyrvYdFUQq5llS1PX2zhPXmccZv99h7uQ= -golang.org/x/oauth2 v0.15.0/go.mod h1:q48ptWNTY5XWf+JNten23lcvHpLJ0ZSxF5ttTHKVCAM= golang.org/x/oauth2 v0.16.0 h1:aDkGMBSYxElaoP81NpoUoz2oo2R2wHdZpGToUxfyQrQ= golang.org/x/oauth2 v0.16.0/go.mod h1:hqZ+0LWXsiVoZpeld6jVt06P3adbS2Uu911W1SsJv2o= -golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 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= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= -golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201207223542-d4d67f95c62d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210525143221-35b2ab0089ea/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.11.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/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek= -golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= -golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4= -golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= golang.org/x/term v0.16.0 h1:m+B6fahuftsE9qjo0VWp2FW0mB3MTJvR0BaMQrq0pmE= golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -493,124 +441,78 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= -golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= -golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= 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/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= 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= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ= -golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/tools v0.16.1 h1:TLyB3WofjdOEepBHAU20JdNC1Zbg87elYofWYAY5oZA= golang.org/x/tools v0.16.1/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 h1:+cNy6SZtPcJQH3LJVLOSmiC7MMxXNOb3PU/VUEz+EhU= +golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw= gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= -google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= -google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= -google.golang.org/genproto v0.0.0-20230706204954-ccb25ca9f130 h1:Au6te5hbKUV8pIYWHqOUZ1pva5qK/rwbIhoXEUB9Lu8= -google.golang.org/genproto v0.0.0-20230706204954-ccb25ca9f130/go.mod h1:O9kGHb51iE/nOGvQaDUuadVYqovW56s5emA88lQnj6Y= -google.golang.org/genproto v0.0.0-20240102182953-50ed04b92917 h1:nz5NESFLZbJGPFxDT/HCn+V1mZ8JGNoY4nUpmW/Y2eg= -google.golang.org/genproto v0.0.0-20240102182953-50ed04b92917/go.mod h1:pZqR+glSb11aJ+JQcczCvgf47+duRuzNSKqE8YAQnV0= google.golang.org/genproto v0.0.0-20240108191215-35c7eff3a6b1 h1:/IWabOtPziuXTEtI1KYCpM6Ss7vaAkeMxk+uXV/xvZs= google.golang.org/genproto v0.0.0-20240108191215-35c7eff3a6b1/go.mod h1:+Rvu7ElI+aLzyDQhpHMFMMltsD6m7nqpuWDd2CwJw3k= -google.golang.org/genproto/googleapis/api v0.0.0-20230711160842-782d3b101e98 h1:FmF5cCW94Ij59cfpoLiwTgodWmm60eEV0CjlsVg2fuw= -google.golang.org/genproto/googleapis/api v0.0.0-20230711160842-782d3b101e98/go.mod h1:rsr7RhLuwsDKL7RmgDDCUc6yaGr1iqceVb5Wv6f6YvQ= -google.golang.org/genproto/googleapis/api v0.0.0-20240102182953-50ed04b92917 h1:rcS6EyEaoCO52hQDupoSfrxI3R6C2Tq741is7X8OvnM= -google.golang.org/genproto/googleapis/api v0.0.0-20240102182953-50ed04b92917/go.mod h1:CmlNWB9lSezaYELKS5Ym1r44VrrbPUa7JTvw+6MbpJ0= google.golang.org/genproto/googleapis/api v0.0.0-20240108191215-35c7eff3a6b1 h1:OPXtXn7fNMaXwO3JvOmF1QyTc00jsSFFz1vXXBOdCDo= google.golang.org/genproto/googleapis/api v0.0.0-20240108191215-35c7eff3a6b1/go.mod h1:B5xPO//w8qmBDjGReYLpR6UJPnkldGkCSMoH/2vxJeg= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230706204954-ccb25ca9f130 h1:2FZP5XuJY9zQyGM5N0rtovnoXjiMUEIUMvw0m9wlpLc= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230706204954-ccb25ca9f130/go.mod h1:8mL13HKkDa+IuJ8yruA3ci0q+0vsUz4m//+ottjwS5o= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240102182953-50ed04b92917 h1:6G8oQ016D88m1xAKljMlBOOGWDZkes4kMhgGFlf8WcQ= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240102182953-50ed04b92917/go.mod h1:xtjpI3tXFPP051KaWnhvxkiubL/6dJ18vLVf7q2pTOU= google.golang.org/genproto/googleapis/rpc v0.0.0-20240108191215-35c7eff3a6b1 h1:gphdwh0npgs8elJ4T6J+DQJHPVF7RsuJHCfwztUb4J4= google.golang.org/genproto/googleapis/rpc v0.0.0-20240108191215-35c7eff3a6b1/go.mod h1:daQN87bsDqDoe316QbbvX60nMoJQa4r6Ds0ZuoAe5yA= -google.golang.org/grpc v1.56.2 h1:fVRFRnXvU+x6C4IlHZewvJOVHoOv1TUuQyoRsYnB4bI= -google.golang.org/grpc v1.56.2/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s= -google.golang.org/grpc v1.56.3/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s= google.golang.org/grpc v1.60.1 h1:26+wFr+cNqSGFcOXcabYC0lUVJVRa2Sb2ortSK7VrEU= google.golang.org/grpc v1.60.1/go.mod h1:OlCHIeLYqSSsLi6i49B5QGdzaMZK9+M7LXN2FKz4eGM= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= -google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I= google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +gopkg.in/cenkalti/backoff.v1 v1.1.0 h1:Arh75ttbsvlpVA7WtVpH4u9h6Zl46xuptxqLxPiSo4Y= +gopkg.in/cenkalti/backoff.v1 v1.1.0/go.mod h1:J6Vskwqd+OMVJl8C33mmtxTBs2gyzfv7UDAkHu8BrjI= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc= +gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -k8s.io/api v0.28.2 h1:9mpl5mOb6vXZvqbQmankOfPIGiudghwCoLl1EYfUZbw= -k8s.io/api v0.28.2/go.mod h1:RVnJBsjU8tcMq7C3iaRSGMeaKt2TWEUXcpIt/90fjEg= k8s.io/api v0.29.0 h1:NiCdQMY1QOp1H8lfRyeEf8eOwV6+0xA6XEE44ohDX2A= k8s.io/api v0.29.0/go.mod h1:sdVmXoz2Bo/cb77Pxi71IPTSErEW32xa4aXwKH7gfBA= -k8s.io/apiextensions-apiserver v0.28.1 h1:l2ThkBRjrWpw4f24uq0Da2HaEgqJZ7pcgiEUTKSmQZw= -k8s.io/apiextensions-apiserver v0.28.1/go.mod h1:sVvrI+P4vxh2YBBcm8n2ThjNyzU4BQGilCQ/JAY5kGs= k8s.io/apiextensions-apiserver v0.29.0 h1:0VuspFG7Hj+SxyF/Z/2T0uFbI5gb5LRgEyUVE3Q4lV0= k8s.io/apiextensions-apiserver v0.29.0/go.mod h1:TKmpy3bTS0mr9pylH0nOt/QzQRrW7/h7yLdRForMZwc= -k8s.io/apimachinery v0.28.2 h1:KCOJLrc6gu+wV1BYgwik4AF4vXOlVJPdiqn0yAWWwXQ= -k8s.io/apimachinery v0.28.2/go.mod h1:RdzF87y/ngqk9H4z3EL2Rppv5jj95vGS/HaFXrLDApU= k8s.io/apimachinery v0.29.0 h1:+ACVktwyicPz0oc6MTMLwa2Pw3ouLAfAon1wPLtG48o= k8s.io/apimachinery v0.29.0/go.mod h1:eVBxQ/cwiJxH58eK/jd/vAk4mrxmVlnpBH5J2GbMeis= -k8s.io/client-go v0.28.2 h1:DNoYI1vGq0slMBN/SWKMZMw0Rq+0EQW6/AK4v9+3VeY= -k8s.io/client-go v0.28.2/go.mod h1:sMkApowspLuc7omj1FOSUxSoqjr+d5Q0Yc0LOFnYFJY= k8s.io/client-go v0.29.0 h1:KmlDtFcrdUzOYrBhXHgKw5ycWzc3ryPX5mQe0SkG3y8= k8s.io/client-go v0.29.0/go.mod h1:yLkXH4HKMAywcrD82KMSmfYg2DlE8mepPR4JGSo5n38= -k8s.io/component-base v0.28.2 h1:Yc1yU+6AQSlpJZyvehm/NkJBII72rzlEsd6MkBQ+G0E= -k8s.io/component-base v0.28.2/go.mod h1:4IuQPQviQCg3du4si8GpMrhAIegxpsgPngPRR/zWpzc= k8s.io/component-base v0.29.0 h1:T7rjd5wvLnPBV1vC4zWd/iWRbV8Mdxs+nGaoaFzGw3s= k8s.io/component-base v0.29.0/go.mod h1:sADonFTQ9Zc9yFLghpDpmNXEdHyQmFIGbiuZbqAXQ1M= -k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg= -k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= k8s.io/klog/v2 v2.110.1 h1:U/Af64HJf7FcwMcXyKm2RPM22WZzyR7OSpYj5tg3cL0= k8s.io/klog/v2 v2.110.1/go.mod h1:YGtd1984u+GgbuZ7e08/yBuAfKLSO0+uR1Fhi6ExXjo= -k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 h1:LyMgNKD2P8Wn1iAwQU5OhxCKlKJy0sHc+PcDwFB24dQ= -k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9/go.mod h1:wZK2AVp1uHCp4VamDVgBP2COHZjqD1T68Rf0CM3YjSM= k8s.io/kube-openapi v0.0.0-20240105020646-a37d4de58910 h1:1Rp/XEKP5uxPs6QrsngEHAxBjaAR78iJRiJq5Fi7LSU= k8s.io/kube-openapi v0.0.0-20240105020646-a37d4de58910/go.mod h1:Pa1PvrP7ACSkuX6I7KYomY6cmMA0Tx86waBhDUgoKPw= -k8s.io/utils v0.0.0-20230406110748-d93618cff8a2 h1:qY1Ad8PODbnymg2pRbkyMT/ylpTrCM8P2RJ0yroCyIk= -k8s.io/utils v0.0.0-20230406110748-d93618cff8a2/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= k8s.io/utils v0.0.0-20240102154912-e7106e64919e h1:eQ/4ljkx21sObifjzXwlPKpdGLrCfRziVtos3ofG/sQ= k8s.io/utils v0.0.0-20240102154912-e7106e64919e/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= rsc.io/tmplfunc v0.0.3 h1:53XFQh69AfOa8Tw0Jm7t+GV7KZhOi6jzsCzTtKbMvzU= rsc.io/tmplfunc v0.0.3/go.mod h1:AG3sTPzElb1Io3Yg4voV9AGZJuleGAwaVRxL9M49PhA= -sigs.k8s.io/controller-runtime v0.16.2 h1:mwXAVuEk3EQf478PQwQ48zGOXvW27UJc8NHktQVuIPU= -sigs.k8s.io/controller-runtime v0.16.2/go.mod h1:vpMu3LpI5sYWtujJOa2uPK61nB5rbwlN7BAB8aSLvGU= sigs.k8s.io/controller-runtime v0.16.3 h1:2TuvuokmfXvDUamSx1SuAOO3eTyye+47mJCigwG62c4= sigs.k8s.io/controller-runtime v0.16.3/go.mod h1:j7bialYoSn142nv9sCOJmQgDXQXxnroFU4VnX/brVJ0= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= -sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE= -sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E= sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4= sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08= -sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= -sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= diff --git a/network-configs/plan/network-latency-reth.yaml b/network-configs/plan/network-latency-reth.yaml new file mode 100644 index 0000000..ee3455b --- /dev/null +++ b/network-configs/plan/network-latency-reth.yaml @@ -0,0 +1,200 @@ +participants: + - el_client_type: geth + el_client_image: ethereum/client-go:v1.13.11 + cl_client_type: prysm + cl_client_image: gcr.io/prysmaticlabs/prysm/beacon-chain:v4.2.1,gcr.io/prysmaticlabs/prysm/validator:v4.2.1 + el_min_cpu: 768 + el_max_cpu: 768 + el_min_mem: 1024 + el_max_mem: 1024 + bn_min_cpu: 1000 + bn_max_cpu: 1000 + bn_min_mem: 2048 + bn_max_mem: 2048 + v_min_cpu: 500 + v_max_cpu: 500 + v_min_mem: 512 + v_max_mem: 512 + count: 1 + - el_client_type: reth + el_client_image: ghcr.io/paradigmxyz/reth:v0.1.0-alpha.17 + cl_client_type: lighthouse + cl_client_image: sigp/lighthouse:v4.6.0 + el_min_cpu: 768 + el_max_cpu: 768 + el_min_mem: 1024 + el_max_mem: 1024 + bn_min_cpu: 1000 + bn_max_cpu: 1000 + bn_min_mem: 2048 + bn_max_mem: 2048 + v_min_cpu: 500 + v_max_cpu: 500 + v_min_mem: 512 + v_max_mem: 512 + count: 1 + - el_client_type: reth + el_client_image: ghcr.io/paradigmxyz/reth:v0.1.0-alpha.17 + cl_client_type: prysm + cl_client_image: gcr.io/prysmaticlabs/prysm/beacon-chain:v4.2.1,gcr.io/prysmaticlabs/prysm/validator:v4.2.1 + el_min_cpu: 768 + el_max_cpu: 768 + el_min_mem: 1024 + el_max_mem: 1024 + bn_min_cpu: 1000 + bn_max_cpu: 1000 + bn_min_mem: 2048 + bn_max_mem: 2048 + v_min_cpu: 500 + v_max_cpu: 500 + v_min_mem: 512 + v_max_mem: 512 + count: 1 + - el_client_type: reth + el_client_image: ghcr.io/paradigmxyz/reth:v0.1.0-alpha.17 + cl_client_type: teku + cl_client_image: consensys/teku:24.1.1-amd64 + el_min_cpu: 768 + el_max_cpu: 768 + el_min_mem: 1024 + el_max_mem: 1024 + bn_min_cpu: 1000 + bn_max_cpu: 1000 + bn_min_mem: 3072 + bn_max_mem: 3072 + count: 1 + - el_client_type: reth + el_client_image: ghcr.io/paradigmxyz/reth:v0.1.0-alpha.17 + cl_client_type: lodestar + cl_client_image: chainsafe/lodestar:v1.15.1 + el_min_cpu: 768 + el_max_cpu: 768 + el_min_mem: 1024 + el_max_mem: 1024 + bn_min_cpu: 1000 + bn_max_cpu: 1000 + bn_min_mem: 2048 + bn_max_mem: 2048 + v_min_cpu: 500 + v_max_cpu: 500 + v_min_mem: 512 + v_max_mem: 512 + count: 1 + - el_client_type: reth + el_client_image: ghcr.io/paradigmxyz/reth:v0.1.0-alpha.17 + cl_client_type: nimbus + cl_client_image: ethpandaops/nimbus:unstable + el_min_cpu: 768 + el_max_cpu: 768 + el_min_mem: 1024 + el_max_mem: 1024 + bn_min_cpu: 1000 + bn_max_cpu: 1000 + bn_min_mem: 2048 + bn_max_mem: 2048 + count: 1 + - el_client_type: geth + el_client_image: ethereum/client-go:v1.13.11 + cl_client_type: lighthouse + cl_client_image: sigp/lighthouse:v4.6.0 + el_min_cpu: 768 + el_max_cpu: 768 + el_min_mem: 1024 + el_max_mem: 1024 + bn_min_cpu: 1000 + bn_max_cpu: 1000 + bn_min_mem: 2048 + bn_max_mem: 2048 + v_min_cpu: 500 + v_max_cpu: 500 + v_min_mem: 512 + v_max_mem: 512 + count: 1 + - el_client_type: geth + el_client_image: ethereum/client-go:v1.13.11 + cl_client_type: prysm + cl_client_image: gcr.io/prysmaticlabs/prysm/beacon-chain:v4.2.1,gcr.io/prysmaticlabs/prysm/validator:v4.2.1 + el_min_cpu: 768 + el_max_cpu: 768 + el_min_mem: 1024 + el_max_mem: 1024 + bn_min_cpu: 1000 + bn_max_cpu: 1000 + bn_min_mem: 2048 + bn_max_mem: 2048 + v_min_cpu: 500 + v_max_cpu: 500 + v_min_mem: 512 + v_max_mem: 512 + count: 1 + - el_client_type: geth + el_client_image: ethereum/client-go:v1.13.11 + cl_client_type: teku + cl_client_image: consensys/teku:24.1.1-amd64 + el_min_cpu: 768 + el_max_cpu: 768 + el_min_mem: 1024 + el_max_mem: 1024 + bn_min_cpu: 1000 + bn_max_cpu: 1000 + bn_min_mem: 3072 + bn_max_mem: 3072 + count: 1 + - el_client_type: geth + el_client_image: ethereum/client-go:v1.13.11 + cl_client_type: lodestar + cl_client_image: chainsafe/lodestar:v1.15.1 + el_min_cpu: 768 + el_max_cpu: 768 + el_min_mem: 1024 + el_max_mem: 1024 + bn_min_cpu: 1000 + bn_max_cpu: 1000 + bn_min_mem: 2048 + bn_max_mem: 2048 + v_min_cpu: 500 + v_max_cpu: 500 + v_min_mem: 512 + v_max_mem: 512 + count: 1 + - el_client_type: geth + el_client_image: ethereum/client-go:v1.13.11 + cl_client_type: nimbus + cl_client_image: ethpandaops/nimbus:unstable + el_min_cpu: 768 + el_max_cpu: 768 + el_min_mem: 1024 + el_max_mem: 1024 + bn_min_cpu: 1000 + bn_max_cpu: 1000 + bn_min_mem: 2048 + bn_max_mem: 2048 + count: 1 + - el_client_type: erigon + el_client_image: thorax/erigon:v2.57.3 + cl_client_type: lighthouse + cl_client_image: sigp/lighthouse:v4.6.0 + el_min_cpu: 768 + el_max_cpu: 768 + el_min_mem: 1024 + el_max_mem: 1024 + bn_min_cpu: 1000 + bn_max_cpu: 1000 + bn_min_mem: 2048 + bn_max_mem: 2048 + v_min_cpu: 500 + v_max_cpu: 500 + v_min_mem: 512 + v_max_mem: 512 + count: 1 +network_params: + num_validator_keys_per_node: 32 + deneb_fork_epoch: 5 +additional_services: + - prometheus_grafana + - dora + - tx_spammer + - blob_spammer +parallel_keystore_generation: false +persistent: false +disable_peer_scoring: true diff --git a/network-configs/plan/restart-resillience-reth.yaml b/network-configs/plan/restart-resillience-reth.yaml new file mode 100644 index 0000000..35e5087 --- /dev/null +++ b/network-configs/plan/restart-resillience-reth.yaml @@ -0,0 +1,213 @@ +participants: + - el_client_type: nethermind + el_client_image: nethermind/nethermind:1.25.1 + cl_client_type: prysm + cl_client_image: prysmaticlabs/prysm-beacon-chain:latest,prysmaticlabs/prysm-validator:latest + el_min_cpu: 1000 + el_max_cpu: 1000 + el_min_mem: 1024 + el_max_mem: 1024 + bn_min_cpu: 1000 + bn_max_cpu: 1000 + bn_min_mem: 2048 + bn_max_mem: 2048 + v_min_cpu: 1000 + v_max_cpu: 1000 + v_min_mem: 1024 + v_max_mem: 1024 + count: 1 + - el_client_type: reth + el_client_image: ghcr.io/paradigmxyz/reth:v0.1.0-alpha.13 + cl_client_type: lighthouse + cl_client_image: sigp/lighthouse:latest + el_min_cpu: 1000 + el_max_cpu: 1000 + el_min_mem: 1024 + el_max_mem: 1024 + bn_min_cpu: 1000 + bn_max_cpu: 1000 + bn_min_mem: 2048 + bn_max_mem: 2048 + v_min_cpu: 1000 + v_max_cpu: 1000 + v_min_mem: 1024 + v_max_mem: 1024 + count: 1 + - el_client_type: reth + el_client_image: ghcr.io/paradigmxyz/reth:v0.1.0-alpha.13 + cl_client_type: prysm + cl_client_image: prysmaticlabs/prysm-beacon-chain:latest,prysmaticlabs/prysm-validator:latest + el_min_cpu: 1000 + el_max_cpu: 1000 + el_min_mem: 1024 + el_max_mem: 1024 + bn_min_cpu: 1000 + bn_max_cpu: 1000 + bn_min_mem: 2048 + bn_max_mem: 2048 + v_min_cpu: 1000 + v_max_cpu: 1000 + v_min_mem: 1024 + v_max_mem: 1024 + count: 1 + - el_client_type: reth + el_client_image: ghcr.io/paradigmxyz/reth:v0.1.0-alpha.13 + cl_client_type: lodestar + cl_client_image: chainsafe/lodestar:v1.12.1 + el_min_cpu: 1000 + el_max_cpu: 1000 + el_min_mem: 1024 + el_max_mem: 1024 + bn_min_cpu: 1000 + bn_max_cpu: 1000 + bn_min_mem: 2048 + bn_max_mem: 2048 + v_min_cpu: 1000 + v_max_cpu: 1000 + v_min_mem: 1024 + v_max_mem: 1024 + count: 1 + - el_client_type: geth + el_client_image: ethereum/client-go:latest + cl_client_type: lighthouse + cl_client_image: sigp/lighthouse:latest + el_min_cpu: 1000 + el_max_cpu: 1000 + el_min_mem: 1024 + el_max_mem: 1024 + bn_min_cpu: 1000 + bn_max_cpu: 1000 + bn_min_mem: 2048 + bn_max_mem: 2048 + v_min_cpu: 1000 + v_max_cpu: 1000 + v_min_mem: 1024 + v_max_mem: 1024 + count: 1 + - el_client_type: erigon + el_client_image: thorax/erigon:v2.53.4 + cl_client_type: prysm + cl_client_image: prysmaticlabs/prysm-beacon-chain:latest,prysmaticlabs/prysm-validator:latest + el_min_cpu: 1000 + el_max_cpu: 1000 + el_min_mem: 1024 + el_max_mem: 1024 + bn_min_cpu: 1000 + bn_max_cpu: 1000 + bn_min_mem: 2048 + bn_max_mem: 2048 + v_min_cpu: 1000 + v_max_cpu: 1000 + v_min_mem: 1024 + v_max_mem: 1024 + count: 1 + - el_client_type: nethermind + el_client_image: nethermind/nethermind:1.25.1 + cl_client_type: lodestar + cl_client_image: chainsafe/lodestar:v1.12.1 + el_min_cpu: 1000 + el_max_cpu: 1000 + el_min_mem: 1024 + el_max_mem: 1024 + bn_min_cpu: 1000 + bn_max_cpu: 1000 + bn_min_mem: 2048 + bn_max_mem: 2048 + v_min_cpu: 1000 + v_max_cpu: 1000 + v_min_mem: 1024 + v_max_mem: 1024 + count: 1 + - el_client_type: geth + el_client_image: ethereum/client-go:latest + cl_client_type: lighthouse + cl_client_image: sigp/lighthouse:latest + el_min_cpu: 1000 + el_max_cpu: 1000 + el_min_mem: 1024 + el_max_mem: 1024 + bn_min_cpu: 1000 + bn_max_cpu: 1000 + bn_min_mem: 2048 + bn_max_mem: 2048 + v_min_cpu: 1000 + v_max_cpu: 1000 + v_min_mem: 1024 + v_max_mem: 1024 + count: 1 + - el_client_type: erigon + el_client_image: thorax/erigon:v2.53.4 + cl_client_type: prysm + cl_client_image: prysmaticlabs/prysm-beacon-chain:latest,prysmaticlabs/prysm-validator:latest + el_min_cpu: 1000 + el_max_cpu: 1000 + el_min_mem: 1024 + el_max_mem: 1024 + bn_min_cpu: 1000 + bn_max_cpu: 1000 + bn_min_mem: 2048 + bn_max_mem: 2048 + v_min_cpu: 1000 + v_max_cpu: 1000 + v_min_mem: 1024 + v_max_mem: 1024 + count: 1 + - el_client_type: nethermind + el_client_image: nethermind/nethermind:1.25.1 + cl_client_type: lodestar + cl_client_image: chainsafe/lodestar:v1.12.1 + el_min_cpu: 1000 + el_max_cpu: 1000 + el_min_mem: 1024 + el_max_mem: 1024 + bn_min_cpu: 1000 + bn_max_cpu: 1000 + bn_min_mem: 2048 + bn_max_mem: 2048 + v_min_cpu: 1000 + v_max_cpu: 1000 + v_min_mem: 1024 + v_max_mem: 1024 + count: 1 + - el_client_type: geth + el_client_image: ethereum/client-go:latest + cl_client_type: lighthouse + cl_client_image: sigp/lighthouse:latest + el_min_cpu: 1000 + el_max_cpu: 1000 + el_min_mem: 1024 + el_max_mem: 1024 + bn_min_cpu: 1000 + bn_max_cpu: 1000 + bn_min_mem: 2048 + bn_max_mem: 2048 + v_min_cpu: 1000 + v_max_cpu: 1000 + v_min_mem: 1024 + v_max_mem: 1024 + count: 1 + - el_client_type: erigon + el_client_image: thorax/erigon:v2.53.4 + cl_client_type: prysm + cl_client_image: prysmaticlabs/prysm-beacon-chain:latest,prysmaticlabs/prysm-validator:latest + el_min_cpu: 1000 + el_max_cpu: 1000 + el_min_mem: 1024 + el_max_mem: 1024 + bn_min_cpu: 1000 + bn_max_cpu: 1000 + bn_min_mem: 2048 + bn_max_mem: 2048 + v_min_cpu: 1000 + v_max_cpu: 1000 + v_min_mem: 1024 + v_max_mem: 1024 + count: 1 +network_params: + num_validator_keys_per_node: 32 +additional_services: + - prometheus_grafana + - dora +parallel_keystore_generation: false +persistent: false +disable_peer_scoring: true diff --git a/pkg/artifacts/types.go b/pkg/artifacts/types.go deleted file mode 100644 index 33378d0..0000000 --- a/pkg/artifacts/types.go +++ /dev/null @@ -1 +0,0 @@ -package artifacts diff --git a/pkg/chaos-mesh/client.go b/pkg/chaos-mesh/client.go index d8a5de8..ec0a0ae 100644 --- a/pkg/chaos-mesh/client.go +++ b/pkg/chaos-mesh/client.go @@ -19,7 +19,6 @@ import ( ) type ChaosClient struct { - //kubeApiClient *apiextensionclientset.Clientset kubeApiClient pkgclient.Client chaosNamespace string } @@ -101,95 +100,3 @@ func (c *ChaosClient) GetPodLabels(ctx context.Context, podName string) (map[str return labels, nil } - -/* -func Test(ctx context.Context) error { - - kubeConfig, _, err := kubernetes.CreateKubeClient() - if err != nil { - return stacktrace.Propagate(err, "aaaaaaa") - } - chaosClient, err := CreateClient("kt-ethereum") - if err != nil { - return stacktrace.Propagate(err, "aaaaaaa") - } - - test := map[string]interface{}{ - "apiVersion": "chaos-mesh.org/v1alpha1", - "kind": "NetworkChaos", - "metadata": map[string]interface{}{ - "name": "example-myresource", - "namespace": "chaos-mesh", - }, - "spec": map[string]interface{}{ - "myvalue": "Hello, World!", - }, - } - - _, err = chaosClient.StartFault(ctx, test) - return err - - apiExtensionClient, err := apiextensionclientset.NewForConfig(kubeConfig) - if err != nil { - return stacktrace.Propagate(err, "aaaaaaa") - } - crdName := "networkchaos.chaos-mesh.org" - - crd, err := apiExtensionClient.ApiextensionsV1().CustomResourceDefinitions().Get(ctx, crdName, metav1.GetOptions{}) - if err != nil { - return stacktrace.Propagate(err, "bbbbb") - } - - //dynamicClient, err := dynamic.NewForConfig(kubeConfig) - if err != nil { - log.Log.Error(err, "See error") - // Handle the fatal error explicitly after logging - os.Exit(1) - } - - //c := &v1alpha1.NetworkChaos{} - //gvr := schema.GroupVersionResource{Group: "chaos-mesh.org", Version: "v1", Resource: "networkchaos"} - - client, err := pkgclient.New(kubeConfig, pkgclient.Options{}) - if err != nil { - log.Log.Error(err, "See error") - // Handle the fatal error explicitly after logging - os.Exit(1) - } - - myresourceInstance := &unstructured.Unstructured{ - Object: map[string]interface{}{ - "apiVersion": "chaos-mesh.org/v1alpha1", - "kind": "networkchaos", - "metadata": map[string]interface{}{ - "name": "example-myresource", - "namespace": "default", - }, - "spec": map[string]interface{}{ - "myvalue": "Hello, World!", - }, - }, - } - - err = client.Create(ctx, myresourceInstance) - if err != nil { - log.Log.Error(err, "See error") - // Handle the fatal error explicitly after logging - os.Exit(1) - } - - _ = crd - - /* - crds, err := apiExtensionClient.ApiextensionsV1().CustomResourceDefinitions().List(ctx, metav1.ListOptions{}) - if err != nil { - return stacktrace.Propagate(err, "bbbbb") - } - - for _, crd := range crds.Items { - fmt.Printf("Found CRD: %s\n", crd.Name) - } -*/ - -// return nil -//} diff --git a/pkg/chaos-mesh/session.go b/pkg/chaos-mesh/session.go index e3ac3ee..9cce46a 100644 --- a/pkg/chaos-mesh/session.go +++ b/pkg/chaos-mesh/session.go @@ -27,10 +27,6 @@ const ( var FaultHasNoDurationErr = fmt.Errorf("this fault has no expected duration") -// succeeded (inject worked, now back to normal) -// failure? -// time out? - type FaultSession struct { client *ChaosClient faultKind *api.ChaosKind diff --git a/pkg/exploration/explore.go b/pkg/exploration/explore.go new file mode 100644 index 0000000..2a46412 --- /dev/null +++ b/pkg/exploration/explore.go @@ -0,0 +1,278 @@ +package exploration + +const WaitBetweenTestsSecs = 60 +const Seed = 666 + +/* +func getRandomAttackSize() suite.AttackSize { + //return suite.AttackOne + sizes := []suite.AttackSize{ + suite.AttackOne, + suite.AttackAll, + suite.AttackMajority, + suite.AttackMinority, + suite.AttackSupermajority, + suite.AttackSuperminority, + } + i := len(sizes) + return sizes[rand.Intn(i)] +} + +func getTargetSpec() suite.TargetingSpec { + targetSpecs := []suite.TargetingSpec{ + suite.TargetMatchingClient, + suite.TargetMatchingNode, + } + _ = targetSpecs + //return suite.TargetMatchingClient + return targetSpecs[rand.Intn(2)] +} + +func buildRandomLatencyTest(testIdx int, targetDescription string, targetSelectors []*suite.ChaosTargetSelector) (*types.SuiteTest, error) { + minDelayMilliSeconds := 10 + maxDelayMilliSeconds := 1000 + minDurationSeconds := 10 + maxDurationSeconds := 300 + minJitterMilliseconds := 10 + maxJitterMilliseconds := 1000 + minCorrelation := 0 + maxCorrelation := 100 + + grace := time.Second * 600 + duration := time.Second * time.Duration(rand.Intn(maxDurationSeconds-minDurationSeconds)+minDurationSeconds) + delay := time.Millisecond * time.Duration(rand.Intn(maxDelayMilliSeconds-minDelayMilliSeconds)+minDelayMilliSeconds) + jitter := time.Millisecond * time.Duration(rand.Intn(maxJitterMilliseconds-minJitterMilliseconds)+minJitterMilliseconds) + correlation := rand.Intn(maxCorrelation-minCorrelation) + minCorrelation + loc := time.FixedZone("GMT", 0) + timefmt := time.Now().In(loc).Format(http.TimeFormat) + description := fmt.Sprintf("Apply %s network latency for %s. Jitter: %s, correlation: %d against %d targets. %s. TestIdx: %d, TestTime: %d, %s", delay, duration, jitter, correlation, len(targetSelectors), targetDescription, testIdx, time.Now().Unix(), timefmt) + log.Info(description) + return suite.ComposeNetworkLatencyTest( + description, + targetSelectors, + &delay, + &jitter, + &duration, + &grace, + correlation, + ) +} + +func buildRandomClockSkewTest(testIdx int, targetDescription string, targetSelectors []*suite.ChaosTargetSelector) (*types.SuiteTest, error) { + minDelaySeconds := -900 + maxDelaySeconds := 900 + minDurationSeconds := 10 + maxDurationSeconds := 600 + + grace := time.Second * 600 + delay := fmt.Sprintf("%ds", rand.Intn(maxDelaySeconds-minDelaySeconds)+minDelaySeconds) + duration := fmt.Sprintf("%ds", rand.Intn(maxDurationSeconds-minDurationSeconds)+minDurationSeconds) + + loc := time.FixedZone("GMT", 0) + timefmt := time.Now().In(loc).Format(http.TimeFormat) + description := fmt.Sprintf("Apply %s clock skew for %s against %d targets. %s. TestIdx: %d, TestTime: %d, %s", delay, duration, len(targetSelectors), targetDescription, testIdx, time.Now().Unix(), timefmt) + log.Info(description) + return suite.ComposeNodeClockSkewTest( + description, + targetSelectors, + delay, + duration, + &grace, + ) +} + +func buildRandomTest(testIdx int, targetDescription string, targetSelectors []*suite.ChaosTargetSelector) (*types.SuiteTest, error) { + testId := rand.Intn(2) + if testId == 0 { + return buildRandomLatencyTest(testIdx, targetDescription, targetSelectors) + } + if testId == 1 { + return buildRandomClockSkewTest(testIdx, targetDescription, targetSelectors) + } + return nil, stacktrace.NewError("unknown test id") +} + +func pickRandomClient(config *plan.PlannerConfig) (string, bool) { + //return "reth", true + isExec := rand.Intn(2) + if isExec == 1 { + numExecClients := len(config.ExecutionClients) + idx := rand.Intn(numExecClients) + return config.ExecutionClients[idx].Name, true + } else { + numBeaconClients := len(config.ConsensusClients) + idx := rand.Intn(numBeaconClients) + return config.ConsensusClients[idx].Name, false + } +} + +func StartExploration(config *plan.PlannerConfig, suitecfg *types.ConfigParsed) error { + // todo: big refactor + ctx, cancelCtxFunc := context.WithCancel(context.Background()) + defer cancelCtxFunc() + + enclave, err := runtime.SetupEnclave(ctx, suitecfg) + if err != nil { + return err + } + _ = enclave + + nodes, err := network.ComposeNetworkTopology( + config.Topology, + config.FaultConfig.TargetClient, + config.ExecutionClients, + config.ConsensusClients, + ) + if err != nil { + return err + } + testableNodes := nodes[1:] + + for _, n := range nodes { + log.Infof("%s", suite.ConvertToNodeIdTag(len(nodes), n, "execution")) + log.Infof("%s", suite.ConvertToNodeIdTag(len(nodes), n, "consensus")) + } + + // dedupe from runtime? + kubeClient, err := kubernetes.CreateKubeClient(config.KubernetesNamespace) + if err != nil { + return err + } + rand.Seed(Seed) + // create chaos-mesh client + log.Infof("Creating a chaos-mesh client") + chaosClient, err := chaos_mesh.CreateClient(config.KubernetesNamespace, kubeClient) + if err != nil { + return err + } + + var testArtifacts []*artifacts.TestArtifact + var done = make(chan bool, 2) + sigs := make(chan os.Signal, 2) + signal.Notify(sigs, syscall.SIGINT) + go func() { + sig := <-sigs + fmt.Println() + fmt.Println(sig, "Signal received. Ending after next test is completed.") + done <- true // Signal that we're done + + }() + killall := false + testIdx := 1 + skipUntilTest := 29 + for { + loc := time.FixedZone("GMT", 0) + log.Infof("Start loop. GMT time: %s", time.Now().In(loc).Format(http.TimeFormat)) + select { + case <-done: + fmt.Println("Writing test artifacts") + return cleanup(testArtifacts) + default: + if killall { + fmt.Println("Writing test artifacts") + return cleanup(testArtifacts) + } + clientUnderTest, isExec := pickRandomClient(config) + targetSpec := getTargetSpec() + attackSize := getRandomAttackSize() + + targetFilter, err := suite.TargetSpecEnumToLambda(targetSpec, isExec) + if err != nil { + return err + } + nodeFilter := suite.BuildNodeFilteringLambda(clientUnderTest, isExec) + targetSelectors, err := suite.BuildChaosMeshTargetSelectors(len(nodes), testableNodes, attackSize, nodeFilter, targetFilter) + if err != nil { + log.Warn("unable to satisfy targeting constraint. skipping") + continue + } + + for _, selector := range targetSelectors { + for _, s := range selector.Selector { + msg := "Hitting " + for _, target := range s.Values { + msg = fmt.Sprintf("%s %s,", msg, target) + } + log.Info(msg) + } + } + log.Infof("time: %d", time.Now().Unix()) + + var targetingDescription string + if targetSpec == suite.TargetMatchingNode { + targetingDescription = fmt.Sprintf("Impacting the full node of targeted %s clients. Injecting into %s of the matching targets.", clientUnderTest, attackSize) + } else { + targetingDescription = fmt.Sprintf("Impacting the client of targeted %s clients. Injecting into %s of the matching targets.", clientUnderTest, attackSize) + } + + test, err := buildRandomTest( + testIdx, + targetingDescription, + targetSelectors, + ) + + if err != nil { + return err + } + + if skipUntilTest != -1 { + if testIdx < skipUntilTest { + testIdx += 1 + continue + } + } + + testIdx += 1 + log.Info("Running test") + executor := test_executor.CreateTestExecutor(chaosClient, *test) + + err = executor.RunTestPlan(ctx) + if err != nil { + log.Errorf("Error while running test") + fmt.Println("Writing test artifacts") + return cleanup(testArtifacts) + } else { + log.Infof("Test steps completed.") + } + + log.Infof("Starting health checks at %s", time.Now().In(loc).Format(http.TimeFormat)) + podsUnderTest, err := executor.GetPodsUnderTest() + if err != nil { + return err + } + + hc, err := health.BuildHealthChecker(kubeClient, podsUnderTest, test.HealthConfig) + if err != nil { + return err + } + results, err := hc.RunChecks(ctx) + if err != nil { + + fmt.Println("Writing test artifacts") + err := cleanup(testArtifacts) + return err + } + testArtifact := artifacts.BuildTestArtifact(results, podsUnderTest, *test) + testArtifacts = append(testArtifacts, testArtifact) + if !testArtifact.TestPassed { + log.Warn("Some health checks failed. Stopping test suite.") + return cleanup(testArtifacts) + } + + //time.Sleep(WaitBetweenTestsSecs * time.Second) + } + } + + //cleanup(testArtifacts) + //return nil +} + +func cleanup(testArtifacts []*artifacts.TestArtifact) error { + err := artifacts.SerializeTestArtifacts(testArtifacts) + if err != nil { + return err + } + return nil +} + +*/ diff --git a/pkg/health/checker.go b/pkg/health/checker.go index 3c6fb35..1c2cabb 100644 --- a/pkg/health/checker.go +++ b/pkg/health/checker.go @@ -17,9 +17,8 @@ type CheckOrchestrator struct { gracePeriod *time.Duration } -func BuildHealthChecker(cfg *confTypes.ConfigParsed, kubeClient *kubernetes.KubeClient, podsUnderTest []*chaos_mesh.PodUnderTest, healthCheckConfig confTypes.HealthCheckConfig) (*CheckOrchestrator, error) { - networkType := cfg.HarnessConfig.NetworkType - +func BuildHealthChecker(kubeClient *kubernetes.KubeClient, podsUnderTest []*chaos_mesh.PodUnderTest, healthCheckConfig confTypes.HealthCheckConfig) (*CheckOrchestrator, error) { + networkType := "ethereum" var checkerImpl types.GenericNetworkChecker switch networkType { @@ -53,7 +52,7 @@ func (hc *CheckOrchestrator) RunChecks(ctx context.Context) (*types.HealthCheckR } if time.Now().After(latestAllowable) { - log.Warn("Grace period elapsed and a health check is still failing") + log.Warnf("Grace period elapsed and a health check is still failing. Time: %d", time.Now().Unix()) return results, nil } else { log.Warn("Health checks failed but still in grace period") @@ -75,6 +74,18 @@ func AllChecksPassed(checks *types.HealthCheckResult) bool { if len(checks.FinalizedElBlockResult.FailingClientsReportedHash) > 0 { return false } + if len(checks.LatestClBlockResult.FailingClientsReportedBlock) > 0 { + return false + } + if len(checks.LatestClBlockResult.FailingClientsReportedHash) > 0 { + return false + } + if len(checks.FinalizedClBlockResult.FailingClientsReportedBlock) > 0 { + return false + } + if len(checks.FinalizedClBlockResult.FailingClientsReportedHash) > 0 { + return false + } return true } diff --git a/pkg/health/ethereum/beacon_rpc.go b/pkg/health/ethereum/beacon_rpc.go new file mode 100644 index 0000000..87d30b8 --- /dev/null +++ b/pkg/health/ethereum/beacon_rpc.go @@ -0,0 +1,200 @@ +package ethereum + +import ( + "attacknet/cmd/pkg/health/types" + "attacknet/cmd/pkg/kubernetes" + "context" + "encoding/hex" + "errors" + "fmt" + eth2client "github.com/attestantio/go-eth2-client" + "github.com/attestantio/go-eth2-client/api" + "github.com/attestantio/go-eth2-client/http" + "github.com/kurtosis-tech/stacktrace" + "github.com/rs/zerolog" + log "github.com/sirupsen/logrus" + "strings" + "time" +) + +type BeaconClientRpc struct { + session *kubernetes.PortForwardsSession + client eth2client.BeaconBlockHeadersProvider +} + +func (e *EthNetworkChecker) getBeaconClientConsensus(ctx context.Context, clients []*BeaconClientRpc, blockType string, maxAttempts int) (*types.BlockConsensusTestResult, error) { + forkChoice, err := getBeaconNetworkConsensus(ctx, clients, blockType) + if err != nil { + return nil, err + } + // determine whether the nodes are in consensus + consensusBlockNum, wrongBlockNum, consensusBlockHash, wrongBlockHash := determineForkConsensus(forkChoice) + if len(wrongBlockNum) > 0 { + if maxAttempts > 0 { + log.Debugf("Nodes not at consensus for %s block. Waiting and re-trying in case we're on block propagation boundary. Attempts left: %d", blockType, maxAttempts-1) + time.Sleep(1 * time.Second) + return e.getBeaconClientConsensus(ctx, clients, blockType, maxAttempts-1) + } else { + reportConsensusDataToLogger(blockType, consensusBlockNum, wrongBlockNum, consensusBlockHash, wrongBlockHash) + } + } + + blockNumWrong := make(map[string]uint64) + for _, node := range wrongBlockNum { + blockNumWrong[node.Pod.GetName()] = node.BlockNumber + } + + blockHashWrong := make(map[string]string) + + for _, node := range wrongBlockHash { + blockHashWrong[node.Pod.GetName()] = node.BlockHash + } + reportConsensusDataToLogger(blockType, consensusBlockNum, wrongBlockNum, consensusBlockHash, wrongBlockHash) + return &types.BlockConsensusTestResult{ + ConsensusBlock: (consensusBlockNum)[0].BlockNumber, + ConsensusHash: consensusBlockHash[0].BlockHash, + FailingClientsReportedBlock: blockNumWrong, + FailingClientsReportedHash: blockHashWrong, + }, nil +} + +func (e *EthNetworkChecker) dialToBeaconClients(ctx context.Context) ([]*BeaconClientRpc, error) { + labelKey := "kurtosistech.com.custom/ethereum-package.client-type" + labelValue := "beacon" + podsToHealthCheck, err := getPodsToHealthCheck( + ctx, + e.kubeClient, + e.podsUnderTest, + e.podsUnderTestLookup, + labelKey, + labelValue) + if err != nil { + return nil, err + } + + // todo: fix this when kurtosis pkg supports setting the port + var port4000Batch []kubernetes.KubePod + var port3500Batch []kubernetes.KubePod + + for _, pod := range podsToHealthCheck { + if strings.Contains(pod.GetName(), "prysm") { + port3500Batch = append(port3500Batch, pod) + } else { + port4000Batch = append(port4000Batch, pod) + } + } + + log.Debugf("Starting port forward sessions to %d pods", len(podsToHealthCheck)) + + portForwardSessions3500, err := e.kubeClient.StartMultiPortForwardToLabeledPods( + port3500Batch, + labelKey, + labelValue, + 3500) + if err != nil { + return nil, err + } + + portForwardSessions4000, err := e.kubeClient.StartMultiPortForwardToLabeledPods( + port4000Batch, + labelKey, + labelValue, + 4000) + if err != nil { + return nil, err + } + + portForwardSessions := append(portForwardSessions3500, portForwardSessions4000...) + + // dial out to clients + rpcClients := make([]*BeaconClientRpc, len(portForwardSessions)) + for i, s := range portForwardSessions { + client, err := dialBeaconRpcClient(ctx, s) + if err != nil { + return nil, err + } + rpcClients[i] = client + } + return rpcClients, nil +} + +func dialBeaconRpcClient(ctx context.Context, session *kubernetes.PortForwardsSession) (*BeaconClientRpc, error) { + // 3 attempts + retryCount := 8 + for i := 0; i <= retryCount; i++ { + httpClient, err := http.New(ctx, + http.WithAddress(fmt.Sprintf("http://localhost:%d", session.LocalPort)), + http.WithLogLevel(zerolog.WarnLevel), + ) + if err != nil { + if i == retryCount { + return nil, stacktrace.Propagate(err, "err while dialing RPC for %s", session.Pod.GetName()) + } else { + time.Sleep(1 * time.Second) + continue + } + + } + provider, isProvider := httpClient.(eth2client.BeaconBlockHeadersProvider) + if !isProvider { + return nil, stacktrace.NewError("unable to cast http client to beacon rpc provider for %s", session.Pod.GetName()) + } + return &BeaconClientRpc{ + session: session, + client: provider, + }, nil + } + return nil, stacktrace.NewError("unreachable beacon rpc") +} + +func (c *BeaconClientRpc) Close() { + c.session.Close() +} + +func (c *BeaconClientRpc) GetLatestBlockBy(ctx context.Context, blockType string) (*ClientForkChoice, error) { + // todo: handle pods that died and we didn't expect it + result, err := c.client.BeaconBlockHeader(ctx, &api.BeaconBlockHeaderOpts{Block: blockType}) + if err != nil { + var apiErr *api.Error + if errors.As(err, &apiErr) { + switch apiErr.StatusCode { + case 404: + if blockType == "finalized" { + choice := &ClientForkChoice{ + Pod: c.session.Pod, + BlockNumber: 0, + BlockHash: "None", + } + return choice, nil + } + } + } + // chock it up to a failure we need to retry + // note: at this time this retry logic isn't actually hooked up. I havent seen any failures to hit this RPC + // endpoint yet, so setting up a retry mechanism may just be over-engineering. + choice := &ClientForkChoice{ + Pod: c.session.Pod, + BlockNumber: 0, + BlockHash: "N/A", + } + return choice, nil + //return nil, stacktrace.Propagate(err, "Unable to query for blockType %s with client for %s", blockType, c.session.Pod.GetName()) + } + + slot := uint64(result.Data.Header.Message.Slot) + bodyHash := hex.EncodeToString(result.Data.Header.Message.BodyRoot[:]) + + if slot == 0 && blockType == "finalized" { + return &ClientForkChoice{ + Pod: c.session.Pod, + BlockNumber: slot, + BlockHash: "None", + }, nil + } else { + return &ClientForkChoice{ + Pod: c.session.Pod, + BlockNumber: slot, + BlockHash: bodyHash, + }, nil + } +} diff --git a/pkg/health/ethereum/consensus.go b/pkg/health/ethereum/consensus.go index 7e03067..9479757 100644 --- a/pkg/health/ethereum/consensus.go +++ b/pkg/health/ethereum/consensus.go @@ -4,6 +4,7 @@ import ( "attacknet/cmd/pkg/kubernetes" "context" log "github.com/sirupsen/logrus" + "time" ) // var UnableToReachLatestConsensusError = fmt.Errorf("there are nodes that disagree on the latest block") @@ -29,6 +30,19 @@ func getExecNetworkConsensus(ctx context.Context, nodeClients []*ExecClientRPC, return clientForkVotes, nil } +func getBeaconNetworkConsensus(ctx context.Context, nodeClients []*BeaconClientRpc, blockType string) ([]*ClientForkChoice, error) { + clientForkVotes := make([]*ClientForkChoice, len(nodeClients)) + for i, client := range nodeClients { + choice, err := client.GetLatestBlockBy(ctx, blockType) + if err != nil { + return nil, err + } + + clientForkVotes[i] = choice + } + return clientForkVotes, nil +} + func determineForkConsensus(nodes []*ClientForkChoice) ( consensusBlockNum []*ClientForkChoice, wrongBlockNum []*ClientForkChoice, @@ -88,7 +102,7 @@ func reportConsensusDataToLogger(consensusType string, log.Infof("Consensus %s block height: %d", consensusType, consensusBlockNum[0].BlockNumber) if len(wrongBlockNum) > 0 { - log.Warnf("Some nodes are out of consensus for block type '%s'", consensusType) + log.Warnf("Some nodes are out of consensus for block type '%s'. Time: %d", consensusType, time.Now().Unix()) for _, n := range wrongBlockNum { log.Warnf("---> Node: %s %s BlockHeight: %d BlockHash: %s", n.Pod.GetName(), consensusType, n.BlockNumber, n.BlockHash) } diff --git a/pkg/health/ethereum/execution_rpc.go b/pkg/health/ethereum/execution_rpc.go index 42f3a6c..10d863a 100644 --- a/pkg/health/ethereum/execution_rpc.go +++ b/pkg/health/ethereum/execution_rpc.go @@ -56,25 +56,16 @@ func (e *EthNetworkChecker) getExecBlockConsensus(ctx context.Context, clients [ func (e *EthNetworkChecker) dialToExecutionClients(ctx context.Context) ([]*ExecClientRPC, error) { labelKey := "kurtosistech.com.custom/ethereum-package.client-type" labelValue := "execution" - var podsToHealthCheck []kubernetes.KubePod - // add pods under test that match the label criteria - for _, pod := range e.podsUnderTest { - if pod.MatchesLabel(labelKey, labelValue) && !pod.ExpectDeath { - podsToHealthCheck = append(podsToHealthCheck, pod) - } - } - // add pods that were not targeted by a fault - bystanders, err := e.kubeClient.PodsMatchingLabel(ctx, labelKey, labelValue) + podsToHealthCheck, err := getPodsToHealthCheck( + ctx, + e.kubeClient, + e.podsUnderTest, + e.podsUnderTestLookup, + labelKey, + labelValue) if err != nil { return nil, err } - for _, pod := range bystanders { - _, match := e.podsUnderTestLookup[pod.GetName()] - // don't add pods we've already added - if !match { - podsToHealthCheck = append(podsToHealthCheck, pod) - } - } log.Debugf("Starting port forward sessions to %d pods", len(podsToHealthCheck)) portForwardSessions, err := e.kubeClient.StartMultiPortForwardToLabeledPods( diff --git a/pkg/health/ethereum/network_checker.go b/pkg/health/ethereum/network_checker.go index 93fad68..27c4ae0 100644 --- a/pkg/health/ethereum/network_checker.go +++ b/pkg/health/ethereum/network_checker.go @@ -37,25 +37,43 @@ func (e *EthNetworkChecker) RunAllChecks(ctx context.Context, prevHealthCheckRes if err != nil { return nil, err } + beaconRpcClients, err := e.dialToBeaconClients(ctx) + if err != nil { + return nil, err + } log.Debug("Ready to query for health checks") - latestResult, err := e.getExecBlockConsensus(ctx, execRpcClients, "latest", 15) + latestElResult, err := e.getExecBlockConsensus(ctx, execRpcClients, "latest", 15) if err != nil { return nil, err } - latestArtifact := e.convertResultToArtifact(prevHealthCheckResult.LatestElBlockResult, latestResult) + latestElArtifact := e.convertResultToArtifact(prevHealthCheckResult.LatestElBlockResult, latestElResult) - finalResult, err := e.getExecBlockConsensus(ctx, execRpcClients, "finalized", 3) + finalElResult, err := e.getExecBlockConsensus(ctx, execRpcClients, "finalized", 3) if err != nil { return nil, err } - finalArtifact := e.convertResultToArtifact(prevHealthCheckResult.FinalizedElBlockResult, finalResult) + finalElArtifact := e.convertResultToArtifact(prevHealthCheckResult.FinalizedElBlockResult, finalElResult) - log.Debugf("Finalization -> latest lag: %d", latestResult.ConsensusBlock-finalResult.ConsensusBlock) + log.Debugf("Finalization -> latest lag: %d", latestElResult.ConsensusBlock-finalElResult.ConsensusBlock) + + latestClResult, err := e.getBeaconClientConsensus(ctx, beaconRpcClients, "head", 15) + if err != nil { + return nil, err + } + latestClArtifact := e.convertResultToArtifact(prevHealthCheckResult.LatestClBlockResult, latestClResult) + + finalClResult, err := e.getBeaconClientConsensus(ctx, beaconRpcClients, "finalized", 3) + if err != nil { + return nil, err + } + finalClArtifact := e.convertResultToArtifact(prevHealthCheckResult.FinalizedClBlockResult, finalClResult) results := &types.HealthCheckResult{ - LatestElBlockResult: latestArtifact, - FinalizedElBlockResult: finalArtifact, + LatestElBlockResult: latestElArtifact, + FinalizedElBlockResult: finalElArtifact, + LatestClBlockResult: latestClArtifact, + FinalizedClBlockResult: finalClArtifact, } return results, nil diff --git a/pkg/health/ethereum/util.go b/pkg/health/ethereum/util.go new file mode 100644 index 0000000..1a8787b --- /dev/null +++ b/pkg/health/ethereum/util.go @@ -0,0 +1,39 @@ +package ethereum + +import ( + chaos_mesh "attacknet/cmd/pkg/chaos-mesh" + "attacknet/cmd/pkg/kubernetes" + "context" +) + +func getPodsToHealthCheck( + ctx context.Context, + kubeClient *kubernetes.KubeClient, + podsUnderTest []*chaos_mesh.PodUnderTest, + podsUnderTestLookup map[string]*chaos_mesh.PodUnderTest, + labelKey, labelValue string, +) ([]kubernetes.KubePod, error) { + + var podsToHealthCheck []kubernetes.KubePod + // add pods under test that match the label criteria _and_ aren't expected to die + // todo: depending on whether we're testing network recovery or node recovery, we may want to health check nodes we're expecting to die + for _, pod := range podsUnderTest { + if pod.MatchesLabel(labelKey, labelValue) && !pod.ExpectDeath { + podsToHealthCheck = append(podsToHealthCheck, pod) + } + } + + // add pods that were not targeted by a fault + bystanders, err := kubeClient.PodsMatchingLabel(ctx, labelKey, labelValue) + if err != nil { + return nil, err + } + for _, pod := range bystanders { + _, match := podsUnderTestLookup[pod.GetName()] + // don't add pods we've already added + if !match { + podsToHealthCheck = append(podsToHealthCheck, pod) + } + } + return podsToHealthCheck, nil +} diff --git a/pkg/health/types/types.go b/pkg/health/types/types.go index 79a3e8d..95932a0 100644 --- a/pkg/health/types/types.go +++ b/pkg/health/types/types.go @@ -23,4 +23,6 @@ type BlockConsensusArtifact struct { type HealthCheckResult struct { LatestElBlockResult *BlockConsensusArtifact `yaml:"latest_el_block_health_result"` FinalizedElBlockResult *BlockConsensusArtifact `yaml:"finalized_el_block_health_result"` + LatestClBlockResult *BlockConsensusArtifact `yaml:"latest_cl_block_health_result"` + FinalizedClBlockResult *BlockConsensusArtifact `yaml:"finalized_cl_block_health_result"` } diff --git a/pkg/kubernetes/kubernetes.go b/pkg/kubernetes/kubernetes.go index 9fd3443..a9e64e2 100644 --- a/pkg/kubernetes/kubernetes.go +++ b/pkg/kubernetes/kubernetes.go @@ -19,8 +19,7 @@ import ( type KubeClient struct { clientInternal *rest.Config clientset *kubernetes.Clientset - //clientWithSpecs pkgclient.Client - namespace string + namespace string } func CreateKubeClient(namespace string) (*KubeClient, error) { @@ -35,19 +34,6 @@ func CreateKubeClient(namespace string) (*KubeClient, error) { if err != nil { return nil, stacktrace.Propagate(err, "Unable to build a kubernetes client for the default types") } - /* - chaosScheme := runtime.NewScheme() - err = api.AddToScheme(chaosScheme) - if err != nil { - return nil, stacktrace.Propagate(err, "unable to add chaos-mesh v1alpha1 to scheme") - } - - err = corev1.AddToScheme(chaosScheme) - if err != nil { - return nil, stacktrace.Propagate(err, "unable to add kubernetes core to scheme") - } - */ - //client, err := pkgclient.New(kubeConfig, pkgclient.Options{Scheme: chaosScheme}) if err != nil { return nil, stacktrace.Propagate(err, "unable to create a kubernetes API client") @@ -56,8 +42,7 @@ func CreateKubeClient(namespace string) (*KubeClient, error) { c := &KubeClient{ clientInternal: kubeConfig, clientset: kubeClient, - //clientWithSpecs: client, - namespace: namespace, + namespace: namespace, } return c, nil diff --git a/pkg/kubernetes/port_forward.go b/pkg/kubernetes/port_forward.go index d02c3ae..ecb1f99 100644 --- a/pkg/kubernetes/port_forward.go +++ b/pkg/kubernetes/port_forward.go @@ -6,6 +6,7 @@ import ( "github.com/kurtosis-tech/stacktrace" log "github.com/sirupsen/logrus" "io" + "k8s.io/apimachinery/pkg/util/httpstream" "k8s.io/client-go/tools/portforward" "k8s.io/client-go/transport/spdy" "net" @@ -79,24 +80,9 @@ func getFreeEphemeralPort() (int, error) { return port, nil } -func (c *KubeClient) StartPortForwarding(pod string, localPort, remotePort int, printToStdout bool) (stopCh chan struct{}, err error) { - roundTripper, upgrader, err := spdy.RoundTripperFor(c.clientInternal) - if err != nil { - return nil, stacktrace.Propagate(err, "Unable to create roundtripper") - } - - path := fmt.Sprintf("/api/v1/namespaces/%s/pods/%s/portforward", c.namespace, pod) - serverURL, err := url.Parse(c.clientInternal.Host) - if err != nil { - return nil, stacktrace.Propagate(err, "unable to decode kubeconfig.Host: %s", c.clientInternal.Host) - } - serverURL.Path = path - - dialer := spdy.NewDialer(upgrader, &http.Client{Transport: roundTripper}, http.MethodPost, serverURL) - portFwd := fmt.Sprintf("%d:%d", localPort, remotePort) - +func openPortForward(target string, dialer httpstream.Dialer, printToStdout bool, retriesRemaining int) (chan struct{}, error) { readyCh := make(chan struct{}, 1) - stopCh = make(chan struct{}, 1) + stopCh := make(chan struct{}, 1) errLogger := io.Discard stdLogger := io.Discard if printToStdout { @@ -104,35 +90,59 @@ func (c *KubeClient) StartPortForwarding(pod string, localPort, remotePort int, errLogger = CreatePrefixWriter("[port-forward] ", logger.WriterLevel(log.ErrorLevel)) stdLogger = CreatePrefixWriter("[port-forward] ", logger.WriterLevel(log.InfoLevel)) } - - portForward, err := portforward.New(dialer, []string{portFwd}, stopCh, readyCh, stdLogger, errLogger) + + portForward, err := portforward.New(dialer, []string{target}, stopCh, readyCh, stdLogger, errLogger) if err != nil { return nil, stacktrace.Propagate(err, "unable to create port forward dialer") } - log.Debugf("Starting port-forward to pod/%s:%d", pod, remotePort) portForwardIssueCh := make(chan error, 1) + retryCh := make(chan bool, 1) defer close(portForwardIssueCh) + defer close(retryCh) - retries := 3 - go func(retriesRem int) { - for retriesRem > 0 { - if err = portForward.ForwardPorts(); err == nil { - retriesRem-- - if retriesRem == 0 { - portForwardIssueCh <- stacktrace.Propagate(err, "unable to start port forward session") - } + go func() { + err = portForward.ForwardPorts() + if err != nil { + if retriesRemaining == 0 { + portForwardIssueCh <- stacktrace.Propagate(err, "unable to start port forward session") + } else { + retryCh <- true } } - }(retries) + }() select { case <-readyCh: - log.Debugf("Port-forward established to pod/%s:%d", pod, remotePort) - case <-time.After(time.Minute): - return nil, errors.New("timed out after waiting to establish port forward") + return stopCh, nil case err = <-portForwardIssueCh: return nil, err + case <-retryCh: + time.Sleep(200 * time.Millisecond) + return openPortForward(target, dialer, printToStdout, retriesRemaining-1) + case <-time.After(time.Minute): + return nil, errors.New("timed out after waiting to establish port forward") + } +} + +func (c *KubeClient) StartPortForwarding(pod string, localPort, remotePort int, printToStdout bool) (stopCh chan struct{}, err error) { + roundTripper, upgrader, err := spdy.RoundTripperFor(c.clientInternal) + if err != nil { + return nil, stacktrace.Propagate(err, "Unable to create roundtripper") } - return stopCh, nil + + path := fmt.Sprintf("/api/v1/namespaces/%s/pods/%s/portforward", c.namespace, pod) + serverURL, err := url.Parse(c.clientInternal.Host) + if err != nil { + return nil, stacktrace.Propagate(err, "unable to decode kubeconfig.Host: %s", c.clientInternal.Host) + } + serverURL.Path = path + + dialer := spdy.NewDialer(upgrader, &http.Client{Transport: roundTripper}, http.MethodPost, serverURL) + target := fmt.Sprintf("%d:%d", localPort, remotePort) + + stopCh, err = openPortForward(target, dialer, printToStdout, 5) + + log.Debugf("Port-forward established to pod/%s:%d", pod, remotePort) + return stopCh, err } diff --git a/pkg/kurtosis/kurtosis.go b/pkg/kurtosis/kurtosis.go index 05dba03..54b7672 100644 --- a/pkg/kurtosis/kurtosis.go +++ b/pkg/kurtosis/kurtosis.go @@ -161,10 +161,6 @@ func StartNetwork(ctx context.Context, enclaveCtx *EnclaveContextWrapper, harnes return stacktrace.Propagate(errors.New("kurtosis deployment failed during execution"), "%s", e.String()) } - // ins := t.GetInstruction() - // if ins != nil { - // } - insRes := t.GetInstructionResult() if insRes != nil { log.Infof("[Kurtosis] %s", insRes.SerializedInstructionResult) diff --git a/pkg/plan/config.go b/pkg/plan/config.go index 5211fe7..b466971 100644 --- a/pkg/plan/config.go +++ b/pkg/plan/config.go @@ -11,11 +11,7 @@ func validatePlannerFaultConfiguration(c PlannerConfig) error { // fault type _, ok := suite.FaultTypes[c.FaultConfig.FaultType] if !ok { - faults := make([]suite.FaultTypeEnum, 0, len(suite.FaultTypes)) - for k := range suite.FaultTypes { - faults = append(faults, k) - } - return stacktrace.NewError("the fault type '%s' is not supported. Supported faults: %v", c.FaultConfig.FaultType, faults) + return stacktrace.NewError("the fault type '%s' is not supported. Supported faults: %v", c.FaultConfig.FaultType, suite.FaultTypesList) } // target client @@ -28,11 +24,7 @@ func validatePlannerFaultConfiguration(c PlannerConfig) error { for _, spec := range c.FaultConfig.TargetingDimensions { _, ok := suite.TargetingSpecs[spec] if !ok { - specs := make([]suite.TargetingSpec, 0, len(suite.TargetingSpecs)) - for k := range suite.TargetingSpecs { - specs = append(specs, k) - } - return stacktrace.NewError("the fault targeting dimension %s is not supported. Supported dimensions: %v", spec, specs) + return stacktrace.NewError("the fault targeting dimension %s is not supported. Supported dimensions: %v", spec, suite.TargetingSpecList) } } @@ -40,11 +32,7 @@ func validatePlannerFaultConfiguration(c PlannerConfig) error { for _, attackSize := range c.FaultConfig.AttackSizeDimensions { _, ok := suite.AttackSizes[attackSize] if !ok { - sizes := make([]suite.AttackSize, 0, len(suite.AttackSizes)) - for k := range suite.AttackSizes { - sizes = append(sizes, k) - } - return stacktrace.NewError("the attack size dimension %s is not supported. Supported dimensions: %v", attackSize, sizes) + return stacktrace.NewError("the attack size dimension %s is not supported. Supported dimensions: %v", attackSize, suite.AttackSizesList) } } diff --git a/pkg/plan/network/consensus.go b/pkg/plan/network/consensus.go index a698f24..2bd46f5 100644 --- a/pkg/plan/network/consensus.go +++ b/pkg/plan/network/consensus.go @@ -6,49 +6,34 @@ import ( ) const defaultClCpu = 1000 -const defaultValCpu = 1000 +const defaultValCpu = 500 -const defaultClMem = 2048 -const defaultValMem = 1024 - -func composeConsensusTesterNetwork(bootEl, bootCl, consensusClient string, execClients, consClients []ClientVersion) ([]*Node, error) { - execClientMap, consClientMap, err := clientListsToMaps(execClients, consClients) - if err != nil { - return nil, err - } +const defaultClMem = 1536 +const defaultValMem = 512 +func composeConsensusTesterNetwork(nodeMultiplier int, consensusClient string, execClientList []ClientVersion, consClientMap map[string]ClientVersion) ([]*Node, error) { // make sure consensusClient actually exists clientUnderTest, ok := consClientMap[consensusClient] if !ok { return nil, stacktrace.NewError("unknown consensus client %s", consensusClient) } - var nodes []*Node - index := 1 - bootnode, err := composeBootnode(bootEl, bootCl, execClientMap, consClientMap) - if err != nil { - return nil, err - } - nodes = append(nodes, bootnode) - index += 1 - - n, err := composeNodesForClTesting(index, clientUnderTest, execClientMap) - nodes = append(nodes, n...) - if err != nil { - return nil, err - } - - return nodes, nil + // start from 2 because bootnode is index 1 + index := 2 + nodes, err := composeNodesForClTesting(nodeMultiplier, index, clientUnderTest, execClientList) + return nodes, err } -func composeNodesForClTesting(index int, consensusClient ClientVersion, execClients map[string]ClientVersion) ([]*Node, error) { +func composeNodesForClTesting(nodeMultiplier, index int, consensusClient ClientVersion, execClients []ClientVersion) ([]*Node, error) { var nodes []*Node for _, execClient := range execClients { - node := buildNode(index, execClient, consensusClient) - nodes = append(nodes, node) + for i := 0; i < nodeMultiplier; i++ { + node := buildNode(index, execClient, consensusClient) + nodes = append(nodes, node) - index += 1 + index += 1 + } } return nodes, nil } diff --git a/pkg/plan/network/execution.go b/pkg/plan/network/execution.go index fb58e3d..51c5eb5 100644 --- a/pkg/plan/network/execution.go +++ b/pkg/plan/network/execution.go @@ -4,47 +4,32 @@ import ( "github.com/kurtosis-tech/stacktrace" ) -const defaultElCpu = 1000 +const defaultElCpu = 768 const defaultElMem = 1024 -func composeExecTesterNetwork(bootEl, bootCl, execClient string, execClients, consClients []ClientVersion) ([]*Node, error) { - execClientMap, consClientMap, err := clientListsToMaps(execClients, consClients) - if err != nil { - return nil, err - } - +func composeExecTesterNetwork(nodeMultiplier int, execClient string, consClientList []ClientVersion, execClientMap map[string]ClientVersion) ([]*Node, error) { // make sure execClient actually exists clientUnderTest, ok := execClientMap[execClient] if !ok { return nil, stacktrace.NewError("unknown execution client %s", execClient) } - var nodes []*Node - index := 1 - bootnode, err := composeBootnode(bootEl, bootCl, execClientMap, consClientMap) - if err != nil { - return nil, err - } - nodes = append(nodes, bootnode) - index += 1 - - n, err := composeNodesForElTesting(index, clientUnderTest, consClientMap) - nodes = append(nodes, n...) - if err != nil { - return nil, err - } - - return nodes, nil + // start from 2 because bootnode is index 1 + index := 2 + nodes, err := composeNodesForElTesting(nodeMultiplier, index, clientUnderTest, consClientList) + return nodes, err } -func composeNodesForElTesting(index int, execClient ClientVersion, consensusClients map[string]ClientVersion) ([]*Node, error) { +func composeNodesForElTesting(nodeMultiplier, index int, execClient ClientVersion, consClientList []ClientVersion) ([]*Node, error) { var nodes []*Node - for _, consensusClient := range consensusClients { - node := buildNode(index, execClient, consensusClient) - nodes = append(nodes, node) + for _, consensusClient := range consClientList { + for i := 0; i < nodeMultiplier; i++ { + node := buildNode(index, execClient, consensusClient) + nodes = append(nodes, node) - index += 1 + index += 1 + } } return nodes, nil } diff --git a/pkg/plan/network/network_builder.go b/pkg/plan/network/network_builder.go index ac3db74..4cd7739 100644 --- a/pkg/plan/network/network_builder.go +++ b/pkg/plan/network/network_builder.go @@ -2,6 +2,7 @@ package network import ( "github.com/kurtosis-tech/stacktrace" + log "github.com/sirupsen/logrus" ) func clientListsToMaps(execClients, consClients []ClientVersion) (execClientMap, consClientMap map[string]ClientVersion, err error) { @@ -30,22 +31,142 @@ func clientListsToMaps(execClients, consClients []ClientVersion) (execClientMap, return execClientMap, consClientMap, nil } -func ComposeNetworkTopology(bootEl, bootCl, client string, execClients, consClients []ClientVersion) ([]*Node, error) { - if client == "all" { - return nil, stacktrace.NewError("target client 'all' not supported yet") +func ComposeNetworkTopology(topology Topology, clientUnderTest string, execClients, consClients []ClientVersion) ([]*Node, error) { + if clientUnderTest == "all" { + return nil, stacktrace.NewError("target clientUnderTest 'all' not supported yet") } isExecutionClient := false for _, execClient := range execClients { - if execClient.Name == client { + if execClient.Name == clientUnderTest { isExecutionClient = true break } } - // assume already checked client is a member of consClients or execClients + + execClientMap, consClientMap, err := clientListsToMaps(execClients, consClients) + if err != nil { + return nil, err + } + + var nodes []*Node + bootnode, err := composeBootnode(topology.BootnodeEL, topology.BootnodeCl, execClientMap, consClientMap) + if err != nil { + return nil, err + } + nodes = append(nodes, bootnode) + + // determine whether a node multiplier is applied. + var nodeMultiplier int = 1 + if topology.TargetNodeMultiplier != 0 { + nodeMultiplier = int(topology.TargetNodeMultiplier) + } + + // assume already checked clientUnderTest is a member of consClients or execClients + var nodesToTest []*Node if isExecutionClient { - return composeExecTesterNetwork(bootEl, bootCl, client, execClients, consClients) + nodesToTest, err = composeExecTesterNetwork(nodeMultiplier, clientUnderTest, consClients, execClientMap) } else { - return composeConsensusTesterNetwork(bootEl, bootCl, client, execClients, consClients) + nodesToTest, err = composeConsensusTesterNetwork(nodeMultiplier, clientUnderTest, execClients, consClientMap) } + if err != nil { + return nil, err + } + nodes = append(nodes, nodesToTest...) + + // add more nodes to the network to satisfy target percent threshold + extraNodes, err := composeNodesToSatisfyTargetPercent( + topology.TargetsAsPercentOfNetwork, + len(nodes)-1, + nodes[len(nodes)-1].Index+1, + clientUnderTest, + execClients, + consClients, + ) + if err != nil { + return nil, err + } + nodes = append(nodes, extraNodes...) + return nodes, nil +} + +func composeNodesToSatisfyTargetPercent(percentTarget float32, targetedNodeCount int, startIndex int, clientUnderTest string, execClients, consClients []ClientVersion) ([]*Node, error) { + // percent target is unconfigured + if percentTarget == 0 { + return []*Node{}, nil + } + + nodesToAdd, err := calcNodesNeededToSatisfyTarget(percentTarget, targetedNodeCount) + if err != nil { + return nil, err + } + + nodes, err := pickExtraNodeClients(startIndex, nodesToAdd, clientUnderTest, execClients, consClients) + return nodes, err +} + +func pickExtraNodeClients(startNodeIndex, nodeCount int, clientUnderTest string, execClients, consClients []ClientVersion) ([]*Node, error) { + var nodes []*Node + //execIndex := 0 + //consIndex := 0 +Exit: + for { + for execIndex := 0; execIndex < len(execClients); execIndex++ { + if execClients[execIndex].Name == clientUnderTest { + continue + } + + for consIndex := 0; consIndex < len(consClients); consIndex++ { + if consClients[consIndex].Name == clientUnderTest { + continue + } + nodes = append(nodes, buildNode(startNodeIndex, execClients[execIndex], consClients[consIndex])) + startNodeIndex += 1 + if len(nodes) == nodeCount { + break Exit + } + } + } + } + return nodes, nil +} + +func pickClient(startIndex int, clientUnderTest string, clients []ClientVersion) (ClientVersion, int, bool, error) { + looped := false + for i := 0; i < len(clients); i++ { + c := clients[startIndex] + + startIndex += 1 + if startIndex >= len(clients) { + looped = true + startIndex = 0 + } + + if c.Name != clientUnderTest { + return c, startIndex, looped, nil + } + } + return ClientVersion{}, 0, looped, stacktrace.NewError("Unable to find any clients defined other than %s. Cannot add more nodes.", clientUnderTest) +} + +func calcNodesNeededToSatisfyTarget(percentTarget float32, targetedNodeCount int) (int, error) { + if percentTarget > 1.0 || percentTarget < 0 { + return 0, stacktrace.NewError("invalid value for targets_as_percent_of_network, must be >=0 and < 1") + } + //if percentTarget > 0.9 + + networkSize := float32(targetedNodeCount) / percentTarget + if networkSize-float32(targetedNodeCount) < 1 { + return 0, stacktrace.NewError("unable to compose a network where targeted nodes are %.2f of the network. The presence of the bootnode prevents this value from exceeding %.2f", percentTarget, float32(targetedNodeCount)/(float32(targetedNodeCount)+1)) + } + + if percentTarget <= 0.30 { + log.Warnf("The currently configured targets_as_percent_of_network of %.2f will create a network of %d nodes", percentTarget, int(networkSize)) + } else { + log.Infof("The currently configured targets_as_percent_of_network of %.2f will create a network of %d nodes", percentTarget, int(networkSize)) + + } + + nodesToAdd := int(networkSize) - targetedNodeCount - 1 + return nodesToAdd, nil } diff --git a/pkg/plan/network/types.go b/pkg/plan/network/types.go index 2db9ef0..d296196 100644 --- a/pkg/plan/network/types.go +++ b/pkg/plan/network/types.go @@ -18,6 +18,13 @@ type GenesisConfig struct { NumValKeysPerNode int `yaml:"num_validator_keys_per_node"` } +type Topology struct { + BootnodeEL string `yaml:"bootnode_el"` + BootnodeCl string `yaml:"bootnode_cl"` + TargetsAsPercentOfNetwork float32 `yaml:"targets_as_percent_of_network"` + TargetNodeMultiplier uint `yaml:"target_node_multiplier"` +} + type ClientVersion struct { Name string `yaml:"name"` Image string `yaml:"image"` diff --git a/pkg/plan/plan.go b/pkg/plan/plan.go index 819a640..ef1eab1 100644 --- a/pkg/plan/plan.go +++ b/pkg/plan/plan.go @@ -15,8 +15,7 @@ func BuildPlan(planName string, config *PlannerConfig) error { } nodes, err := network.ComposeNetworkTopology( - config.FaultConfig.BootnodeEL, - config.FaultConfig.BootnodeCl, + config.Topology, config.FaultConfig.TargetClient, config.ExecutionClients, config.ConsensusClients, diff --git a/pkg/plan/suite/faults.go b/pkg/plan/suite/faults.go index 90f18e3..c8f51aa 100644 --- a/pkg/plan/suite/faults.go +++ b/pkg/plan/suite/faults.go @@ -4,7 +4,8 @@ import ( "attacknet/cmd/pkg/types" "fmt" "github.com/kurtosis-tech/stacktrace" - "gopkg.in/yaml.v3" + yaml "gopkg.in/yaml.v3" + "strconv" "strings" "time" ) @@ -80,7 +81,61 @@ type IOChaosWrapper struct { IOChaosFault `yaml:"chaosFaultSpec"` } -func convertFaultSpecToMap(s interface{}) (map[string]interface{}, error) { +type NetworkDelaySpec struct { + Latency *time.Duration `yaml:"latency"` + Correlation string `yaml:"correlation,omitempty"` + Jitter *time.Duration `yaml:"jitter,omitempty"` +} +type NetworkLossSpec struct { + Loss string `yaml:"loss"` + Correlation string `yaml:"correlation,omitempty"` +} + +type NetworkDuplicateSpec struct { + Duplicate float32 `yaml:"duplicate"` + Correlation string `yaml:"correlation,omitempty"` +} + +type NetworkCorruptSpec struct { + Corrupt float32 `yaml:"duplicate"` + Correlation string `yaml:"correlation,omitempty"` +} + +type NetworkBandwidthSpec struct { + Rate string `yaml:"rate"` + Limit uint32 `yaml:"limit"` + Buffer uint32 `yaml:"buffer"` + PeakRate *uint64 `yaml:"peak_rate,omitempty"` +} + +type NetworkDropSpec struct { + Loss uint32 `yaml:"loss"` +} + +type NetworkChaosSpec struct { + Selector `yaml:"selector"` + Mode string `yaml:"mode"` + Action string `yaml:"action"` + Duration *time.Duration `yaml:"duration"` + Delay *NetworkDelaySpec `yaml:"delay,omitempty"` + Loss *NetworkLossSpec `yaml:"loss,omitempty"` + Duplicate *NetworkDuplicateSpec `yaml:"duplicate,omitempty"` + Corrupt *NetworkCorruptSpec `yaml:"corrupt,omitempty"` + Bandwidth *NetworkBandwidthSpec `yaml:"bandwidth,omitempty"` + Direction string `yaml:"direction,omitempty"` +} + +type NetworkChaosFault struct { + Spec NetworkChaosSpec `yaml:"spec"` + Kind string `yaml:"kind"` + ApiVersion string `yaml:"apiVersion"` +} + +type NetworkChaosWrapper struct { + NetworkChaosFault `yaml:"chaosFaultSpec"` +} + +func convertFaultSpecToMap[T any](s T) (map[string]interface{}, error) { // convert to map[string]interface{} using yaml intermediate. seriously. bs, err := yaml.Marshal(s) if err != nil { @@ -95,8 +150,48 @@ func convertFaultSpecToMap(s interface{}) (map[string]interface{}, error) { return faultSpec, nil } -func buildClockSkewFault(description, timeOffset, duration string, expressionSelectors []ChaosExpressionSelector) (*types.PlanStep, error) { +func convertFaultSpecToMapSpecial(s NetworkChaosWrapper) (map[string]interface{}, error) { + // convert to map[string]interface{} using yaml intermediate. seriously. + bs, err := yaml.Marshal(s) + if err != nil { + return nil, stacktrace.Propagate(err, "intermediate yaml marshalling failed") + } + + var faultSpec map[string]interface{} + err = yaml.Unmarshal(bs, &faultSpec) + if err != nil { + return nil, stacktrace.Propagate(err, "unable to deserialize intermediate yaml") + } + return faultSpec, nil +} + +func convertFaultSpecToInjectStep(description string, s interface{}) (*types.PlanStep, error) { + faultSpecMap, err := convertFaultSpecToMap(s) + if err != nil { + return nil, err + } + + return &types.PlanStep{ + StepType: types.InjectFault, + StepDescription: description, + Spec: faultSpecMap, + }, nil +} + +func convertFaultSpecToInjectStepSpecial(description string, s NetworkChaosWrapper) (*types.PlanStep, error) { + faultSpecMap, err := convertFaultSpecToMapSpecial(s) + if err != nil { + return nil, err + } + + return &types.PlanStep{ + StepType: types.InjectFault, + StepDescription: description, + Spec: faultSpecMap, + }, nil +} +func buildClockSkewFault(description, timeOffset, duration string, expressionSelectors []ChaosExpressionSelector) (*types.PlanStep, error) { t := TimeChaosWrapper{ TimeChaosFault: TimeChaosFault{ Kind: "TimeChaos", @@ -112,18 +207,7 @@ func buildClockSkewFault(description, timeOffset, duration string, expressionSel }, }, } - - faultSpec, err := convertFaultSpecToMap(t) - if err != nil { - return nil, err - } - - step := &types.PlanStep{ - StepType: types.InjectFault, - StepDescription: description, - Spec: faultSpec, - } - return step, nil + return convertFaultSpecToInjectStep(description, t) } func buildPodRestartFault(description string, expressionSelectors []ChaosExpressionSelector) (*types.PlanStep, error) { @@ -142,17 +226,7 @@ func buildPodRestartFault(description string, expressionSelectors []ChaosExpress }, } - faultSpec, err := convertFaultSpecToMap(t) - if err != nil { - return nil, err - } - - step := &types.PlanStep{ - StepType: types.InjectFault, - StepDescription: description, - Spec: faultSpec, - } - return step, nil + return convertFaultSpecToInjectStep(description, t) } func getVolumePathForIOFault(podName string) (string, error) { @@ -198,18 +272,58 @@ func buildIOLatencyFault(description string, expressionSelector ChaosExpressionS }, } - faultSpec, err := convertFaultSpecToMap(t) + step, err := convertFaultSpecToInjectStep(description, t) if err != nil { return nil, err } - - step := types.PlanStep{ - StepType: types.InjectFault, - StepDescription: description, - Spec: faultSpec, - } - steps = append(steps, step) + steps = append(steps, *step) } return steps, nil } + +func buildNetworkLatencyFault(description string, expressionSelectors []ChaosExpressionSelector, delay, jitter, duration *time.Duration, correlation int) (*types.PlanStep, error) { + t := NetworkChaosWrapper{ + NetworkChaosFault: NetworkChaosFault{ + Kind: "NetworkChaos", + ApiVersion: "chaos-mesh.org/v1alpha1", + Spec: NetworkChaosSpec{ + Duration: duration, + Mode: "all", + Action: "delay", + Selector: Selector{ + ExpressionSelectors: expressionSelectors, + }, + Delay: &NetworkDelaySpec{ + Latency: delay, + Correlation: fmt.Sprintf("%d", correlation), + Jitter: jitter, + }, + }, + }, + } + + return convertFaultSpecToInjectStepSpecial(description, t) +} + +func buildPacketDropFault(description string, expressionSelectors []ChaosExpressionSelector, percent int, direction string, duration *time.Duration) (*types.PlanStep, error) { + t := NetworkChaosWrapper{ + NetworkChaosFault: NetworkChaosFault{ + Kind: "NetworkChaos", + ApiVersion: "chaos-mesh.org/v1alpha1", + Spec: NetworkChaosSpec{ + Duration: duration, + Mode: "all", + Action: "loss", + Selector: Selector{ + ExpressionSelectors: expressionSelectors, + }, + Direction: direction, + Loss: &NetworkLossSpec{ + Loss: strconv.Itoa(percent), + }, + }, + }, + } + return convertFaultSpecToInjectStepSpecial(description, t) +} diff --git a/pkg/plan/suite/step_builder.go b/pkg/plan/suite/step_builder.go index b25be22..e9e1927 100644 --- a/pkg/plan/suite/step_builder.go +++ b/pkg/plan/suite/step_builder.go @@ -17,14 +17,24 @@ const ( Validator clientType = "validator" ) -func convertToNodeIdTag(node *network.Node, client clientType) string { +func ConvertToNodeIdTag(networkNodeCount int, node *network.Node, client clientType) string { + nodeNumStr := "" + + if networkNodeCount < 10 { + nodeNumStr = fmt.Sprintf("%d", node.Index) + } else if networkNodeCount < 100 { + nodeNumStr = fmt.Sprintf("%02d", node.Index) + } else { + nodeNumStr = fmt.Sprintf("%03d", node.Index) + } + switch client { case Execution: - return fmt.Sprintf("el-%d-%s-%s", node.Index, node.Execution.Type, node.Consensus.Type) + return fmt.Sprintf("el-%s-%s-%s", nodeNumStr, node.Execution.Type, node.Consensus.Type) case Consensus: - return fmt.Sprintf("cl-%d-%s-%s", node.Index, node.Consensus.Type, node.Execution.Type) + return fmt.Sprintf("cl-%s-%s-%s", nodeNumStr, node.Consensus.Type, node.Execution.Type) case Validator: - return fmt.Sprintf("cl-%d-%s-%s-validator", node.Index, node.Consensus.Type, node.Execution.Type) + return fmt.Sprintf("cl-%s-%s-%s-validator", nodeNumStr, node.Consensus.Type, node.Execution.Type) default: log.Errorf("Unrecognized node type %s", client) return "" @@ -101,3 +111,33 @@ func composeIOLatencySteps(targetsSelected []*ChaosTargetSelector, delay *time.D return steps, nil } + +func composeNetworkLatencySteps(targetsSelected []*ChaosTargetSelector, delay, jitter, duration *time.Duration, correlation int) ([]types.PlanStep, error) { + var steps []types.PlanStep + for _, target := range targetsSelected { + description := fmt.Sprintf("Inject network latency on target %s", target.Description) + + skewStep, err := buildNetworkLatencyFault(description, target.Selector, delay, jitter, duration, correlation) + if err != nil { + return nil, err + } + steps = append(steps, *skewStep) + } + + return steps, nil +} + +func composePacketDropSteps(targetsSelected []*ChaosTargetSelector, percent int, direction string, duration *time.Duration) ([]types.PlanStep, error) { + var steps []types.PlanStep + for _, target := range targetsSelected { + description := fmt.Sprintf("Inject network latency on target %s", target.Description) + + skewStep, err := buildPacketDropFault(description, target.Selector, percent, direction, duration) + if err != nil { + return nil, err + } + steps = append(steps, *skewStep) + } + + return steps, nil +} diff --git a/pkg/plan/suite/suite_builder.go b/pkg/plan/suite/suite_builder.go index 21a6437..dbb0541 100644 --- a/pkg/plan/suite/suite_builder.go +++ b/pkg/plan/suite/suite_builder.go @@ -18,16 +18,16 @@ func ComposeTestSuite( var tests []types.SuiteTest runtimeEstimate := 0 - nodeFilter := buildNodeFilteringLambda(config.TargetClient, isExecClient) + nodeFilter := BuildNodeFilteringLambda(config.TargetClient, isExecClient) for _, targetDimension := range config.TargetingDimensions { - targetFilter, err := targetSpecEnumToLambda(targetDimension, isExecClient) + targetFilter, err := TargetSpecEnumToLambda(targetDimension, isExecClient) if err != nil { return nil, err } nodeCountsTested := make(map[int]bool) for _, attackSize := range config.AttackSizeDimensions { - targetSelectors, err := buildChaosMeshTargetSelectors(nodes, attackSize, nodeFilter, targetFilter) + targetSelectors, err := BuildChaosMeshTargetSelectors(len(nodes)+1, nodes, attackSize, nodeFilter, targetFilter) if err != nil { cannotMeet, ok := err.(CannotMeetConstraintError) if !ok { @@ -92,6 +92,38 @@ func getDurationValue(key string, m map[string]string) (*time.Duration, error) { return &duration, nil } +func getUintValue(key string, m map[string]string) (uint32, error) { + valueStr, ok := m[key] + if !ok { + return 0, stacktrace.NewError("missing %s field", key) + } + uintValue, err := strconv.ParseUint(valueStr, 10, 32) + if err != nil { + return 0, stacktrace.NewError("unable to convert %s field to a uint32", key) + } + return uint32(uintValue), nil +} + +func getFloat32Value(key string, m map[string]string) (float32, error) { + valueStr, ok := m[key] + if !ok { + return 0, stacktrace.NewError("missing %s field", key) + } + floatValue, err := strconv.ParseFloat(valueStr, 32) + if err != nil { + return 0, stacktrace.NewError("unable to convert %s field to a uint32", key) + } + return float32(floatValue), nil +} + +func getStringValue(key string, m map[string]string) (string, error) { + valueStr, ok := m[key] + if !ok { + return "", stacktrace.NewError("missing %s field", key) + } + return valueStr, nil +} + func composeTestForFaultType( faultType FaultTypeEnum, config map[string]string, @@ -115,7 +147,7 @@ func composeTestForFaultType( } description := fmt.Sprintf("Apply %s clock skew for %s against %d targets. %s", skew, duration, len(targetSelectors), targetingDescription) - return composeNodeClockSkewTest(description, targetSelectors, skew, duration, graceDuration) + return ComposeNodeClockSkewTest(description, targetSelectors, skew, duration, graceDuration) case FaultContainerRestart: graceDuration, err := getDurationValue("grace_period", config) @@ -149,6 +181,48 @@ func composeTestForFaultType( description := fmt.Sprintf("Apply %s i/o latency for %s. Impacting %d pct of i/o calls. against %d targets. %s", delay, faultDuration, percentInt, len(targetSelectors), targetingDescription) return composeIOLatencyTest(description, targetSelectors, delay, percentInt, faultDuration, grace) + case FaultNetworkLatency: + grace, err := getDurationValue("grace_period", config) + if err != nil { + return nil, err + } + delay, err := getDurationValue("delay", config) + if err != nil { + return nil, err + } + jitter, err := getDurationValue("jitter", config) + if err != nil { + return nil, err + } + duration, err := getDurationValue("duration", config) + if err != nil { + return nil, err + } + correlation, err := getUintValue("correlation", config) + if err != nil { + return nil, err + } + description := fmt.Sprintf("Apply %s network latency for %s. Jitter: %s, correlation: %d against %d targets. %s", delay, duration, jitter, correlation, len(targetSelectors), targetingDescription) + return ComposeNetworkLatencyTest(description, targetSelectors, delay, jitter, duration, grace, int(correlation)) + case FaultPacketLoss: + grace, err := getDurationValue("grace_period", config) + if err != nil { + return nil, err + } + duration, err := getDurationValue("duration", config) + if err != nil { + return nil, err + } + lossPercent, err := getUintValue("loss_percent", config) + if err != nil { + return nil, err + } + direction, err := getStringValue("direction", config) + if err != nil { + return nil, err + } + description := fmt.Sprintf("Apply %d packet drop for %s, direction: %s against %d targets. %s", lossPercent, duration, direction, len(targetSelectors), targetingDescription) + return ComposePacketDropTest(description, targetSelectors, int(lossPercent), direction, duration, grace) } return nil, nil diff --git a/pkg/plan/suite/targeting.go b/pkg/plan/suite/targeting.go index fea5e07..931aab4 100644 --- a/pkg/plan/suite/targeting.go +++ b/pkg/plan/suite/targeting.go @@ -22,9 +22,9 @@ func (e CannotMeetConstraintError) Error() string { type NodeFilterCriteria func(n *network.Node) bool type TargetCriteriaFilter func(AttackSize, int, []*network.Node) ([]*network.Node, error) -type NodeImpactSelector func(node *network.Node) *ChaosTargetSelector +type NodeImpactSelector func(networkNodeCount int, node *network.Node) *ChaosTargetSelector -func buildNodeFilteringLambda(clientType string, isExecClient bool) TargetCriteriaFilter { +func BuildNodeFilteringLambda(clientType string, isExecClient bool) TargetCriteriaFilter { if isExecClient { return filterNodesByExecClient(clientType) } else { @@ -110,17 +110,17 @@ func chooseTargetsUsingAttackSize(size AttackSize, networkSize int, targetable [ return targets, nil } -func createTargetSelectorForNode(node *network.Node) *ChaosTargetSelector { +func createTargetSelectorForNode(networkNodeCount int, node *network.Node) *ChaosTargetSelector { var targets []string - elId := convertToNodeIdTag(node, Execution) + elId := ConvertToNodeIdTag(networkNodeCount, node, Execution) targets = append(targets, elId) - clId := convertToNodeIdTag(node, Consensus) + clId := ConvertToNodeIdTag(networkNodeCount, node, Consensus) targets = append(targets, clId) if node.Consensus.HasValidatorSidecar { - valId := convertToNodeIdTag(node, Validator) + valId := ConvertToNodeIdTag(networkNodeCount, node, Validator) targets = append(targets, valId) } @@ -137,8 +137,8 @@ func createTargetSelectorForNode(node *network.Node) *ChaosTargetSelector { } } -func createTargetSelectorForExecClient(node *network.Node) *ChaosTargetSelector { - elId := convertToNodeIdTag(node, Execution) +func createTargetSelectorForExecClient(networkNodeCount int, node *network.Node) *ChaosTargetSelector { + elId := ConvertToNodeIdTag(networkNodeCount, node, Execution) selector := ChaosExpressionSelector{ Key: "kurtosistech.com/id", Operator: "In", @@ -152,13 +152,13 @@ func createTargetSelectorForExecClient(node *network.Node) *ChaosTargetSelector } } -func createTargetSelectorForConsensusClient(node *network.Node) *ChaosTargetSelector { +func createTargetSelectorForConsensusClient(networkNodeCount int, node *network.Node) *ChaosTargetSelector { var targets []string - clId := convertToNodeIdTag(node, Consensus) + clId := ConvertToNodeIdTag(networkNodeCount, node, Consensus) targets = append(targets, clId) if node.Consensus.HasValidatorSidecar { - valId := convertToNodeIdTag(node, Validator) + valId := ConvertToNodeIdTag(networkNodeCount, node, Validator) targets = append(targets, valId) } @@ -175,7 +175,7 @@ func createTargetSelectorForConsensusClient(node *network.Node) *ChaosTargetSele } } -func targetSpecEnumToLambda(targetSelector TargetingSpec, isExecClient bool) (func(node *network.Node) *ChaosTargetSelector, error) { +func TargetSpecEnumToLambda(targetSelector TargetingSpec, isExecClient bool) (func(networkNodeCount int, node *network.Node) *ChaosTargetSelector, error) { if targetSelector == TargetMatchingNode { return createTargetSelectorForNode, nil } @@ -195,7 +195,9 @@ func filterNodesByExecClient(elClientType string) TargetCriteriaFilter { return n.Execution.Type == elClientType } targetableNodes := filterNodes(nodes, criteria) - + if targetableNodes == nil { + return nil, stacktrace.NewError("unable to satisfy targeting constraint") + } return chooseTargetsUsingAttackSize(size, targetableSetSize, targetableNodes) } } @@ -222,7 +224,7 @@ func filterNodesByClientCombo(elClientType, clClientType string) TargetCriteriaF } } -func buildChaosMeshTargetSelectors(nodes []*network.Node, size AttackSize, targetCriteria TargetCriteriaFilter, impactSelector NodeImpactSelector) ([]*ChaosTargetSelector, error) { +func BuildChaosMeshTargetSelectors(networkNodeCount int, nodes []*network.Node, size AttackSize, targetCriteria TargetCriteriaFilter, impactSelector NodeImpactSelector) ([]*ChaosTargetSelector, error) { targets, err := targetCriteria(size, len(nodes)+1, nodes) if err != nil { return nil, err @@ -230,7 +232,7 @@ func buildChaosMeshTargetSelectors(nodes []*network.Node, size AttackSize, targe var targetSelectors []*ChaosTargetSelector for _, node := range targets { - targetSelectors = append(targetSelectors, impactSelector(node)) + targetSelectors = append(targetSelectors, impactSelector(networkNodeCount, node)) } return targetSelectors, nil } diff --git a/pkg/plan/suite/test_builder.go b/pkg/plan/suite/test_builder.go index 98b2bfb..712f069 100644 --- a/pkg/plan/suite/test_builder.go +++ b/pkg/plan/suite/test_builder.go @@ -5,7 +5,7 @@ import ( "time" ) -func composeNodeClockSkewTest(description string, targets []*ChaosTargetSelector, skew, duration string, graceDuration *time.Duration) (*types.SuiteTest, error) { +func ComposeNodeClockSkewTest(description string, targets []*ChaosTargetSelector, skew, duration string, graceDuration *time.Duration) (*types.SuiteTest, error) { var steps []types.PlanStep s, err := composeNodeClockSkewPlanSteps(targets, skew, duration) if err != nil { @@ -75,3 +75,49 @@ func composeIOLatencyTest(description string, targets []*ChaosTargetSelector, de return test, nil } + +func ComposeNetworkLatencyTest(description string, targets []*ChaosTargetSelector, delay, jitter, duration, grace *time.Duration, correlation int) (*types.SuiteTest, error) { + var steps []types.PlanStep + s, err := composeNetworkLatencySteps(targets, delay, jitter, duration, correlation) + if err != nil { + return nil, err + } + steps = append(steps, s...) + + waitStep := composeWaitForFaultCompletionStep() + steps = append(steps, *waitStep) + + test := &types.SuiteTest{ + TestName: description, + PlanSteps: steps, + HealthConfig: types.HealthCheckConfig{ + EnableChecks: true, + GracePeriod: grace, + }, + } + + return test, nil +} + +func ComposePacketDropTest(description string, targets []*ChaosTargetSelector, percent int, direction string, duration, grace *time.Duration) (*types.SuiteTest, error) { + var steps []types.PlanStep + s, err := composePacketDropSteps(targets, percent, direction, duration) + if err != nil { + return nil, err + } + steps = append(steps, s...) + + waitStep := composeWaitForFaultCompletionStep() + steps = append(steps, *waitStep) + + test := &types.SuiteTest{ + TestName: description, + PlanSteps: steps, + HealthConfig: types.HealthCheckConfig{ + EnableChecks: true, + GracePeriod: grace, + }, + } + + return test, nil +} diff --git a/pkg/plan/suite/types.go b/pkg/plan/suite/types.go index a8437b5..906fc24 100644 --- a/pkg/plan/suite/types.go +++ b/pkg/plan/suite/types.go @@ -14,6 +14,11 @@ var TargetingSpecs = map[TargetingSpec]bool{ TargetMatchingClient: true, } +var TargetingSpecList = []TargetingSpec{ + TargetMatchingNode, + TargetMatchingClient, +} + type AttackSize string const ( @@ -36,25 +41,43 @@ var AttackSizes = map[AttackSize]bool{ AttackSupermajority: true, } +var AttackSizesList = []AttackSize{ + AttackOne, + AttackAll, + AttackMinority, + AttackSuperminority, + AttackMajority, + AttackSupermajority, +} + type FaultTypeEnum string const ( FaultClockSkew FaultTypeEnum = "ClockSkew" FaultContainerRestart FaultTypeEnum = "RestartContainers" FaultIOLatency FaultTypeEnum = "IOLatency" + FaultNetworkLatency FaultTypeEnum = "NetworkLatency" + FaultPacketLoss FaultTypeEnum = "PacketLoss" ) var FaultTypes = map[FaultTypeEnum]bool{ FaultClockSkew: true, FaultContainerRestart: true, FaultIOLatency: true, + FaultNetworkLatency: true, +} + +var FaultTypesList = []FaultTypeEnum{ + FaultClockSkew, + FaultContainerRestart, + FaultIOLatency, + FaultNetworkLatency, + FaultPacketLoss, } type PlannerFaultConfiguration struct { FaultType FaultTypeEnum `yaml:"fault_type"` TargetClient string `yaml:"target_client"` - BootnodeEL string `yaml:"bootnode_el"` - BootnodeCl string `yaml:"bootnode_cl"` WaitBeforeFirstTest time.Duration `yaml:"wait_before_first_test"` FaultConfigDimensions []map[string]string `yaml:"fault_config_dimensions"` TargetingDimensions []TargetingSpec `yaml:"fault_targeting_dimensions"` diff --git a/pkg/plan/types.go b/pkg/plan/types.go index 5131145..ec651e8 100644 --- a/pkg/plan/types.go +++ b/pkg/plan/types.go @@ -8,6 +8,7 @@ import ( type PlannerConfig struct { ExecutionClients []network.ClientVersion `yaml:"execution"` ConsensusClients []network.ClientVersion `yaml:"consensus"` + Topology network.Topology `yaml:"topology"` GenesisParams network.GenesisConfig `yaml:"network_params"` KurtosisPackage string `yaml:"kurtosis_package"` KubernetesNamespace string `yaml:"kubernetes_namespace"` diff --git a/pkg/runtime.go b/pkg/runtime.go index 9a60046..96f9d65 100644 --- a/pkg/runtime.go +++ b/pkg/runtime.go @@ -5,16 +5,16 @@ import ( chaos_mesh "attacknet/cmd/pkg/chaos-mesh" "attacknet/cmd/pkg/health" "attacknet/cmd/pkg/kubernetes" + "attacknet/cmd/pkg/runtime" "attacknet/cmd/pkg/test_executor" "attacknet/cmd/pkg/types" "context" - "time" - log "github.com/sirupsen/logrus" + "time" ) func StartTestSuite(ctx context.Context, cfg *types.ConfigParsed) error { - enclave, err := setupEnclave(ctx, cfg) + enclave, err := runtime.SetupEnclave(ctx, cfg) if err != nil { return err } @@ -62,7 +62,7 @@ func StartTestSuite(ctx context.Context, cfg *types.ConfigParsed) error { return err } - hc, err := health.BuildHealthChecker(cfg, kubeClient, podsUnderTest, test.HealthConfig) + hc, err := health.BuildHealthChecker(kubeClient, podsUnderTest, test.HealthConfig) if err != nil { return err } diff --git a/pkg/devnet.go b/pkg/runtime/runtime.go similarity index 70% rename from pkg/devnet.go rename to pkg/runtime/runtime.go index c12349d..cf7c61e 100644 --- a/pkg/devnet.go +++ b/pkg/runtime/runtime.go @@ -1,10 +1,10 @@ -package pkg +package runtime import ( "attacknet/cmd/pkg/kurtosis" "attacknet/cmd/pkg/types" "context" - log "github.com/sirupsen/logrus" + "github.com/sirupsen/logrus" ) func setupDevnet(ctx context.Context, cfg *types.ConfigParsed) (enclave *kurtosis.EnclaveContextWrapper, err error) { @@ -14,14 +14,14 @@ func setupDevnet(ctx context.Context, cfg *types.ConfigParsed) (enclave *kurtosi return nil, err } - log.Infof("Creating a new Kurtosis enclave") + logrus.Infof("Creating a new Kurtosis enclave") enclaveCtx, _, err := kurtosis.CreateOrImportContext(ctx, kurtosisCtx, cfg) - log.Infof("New enclave created under namespace %s", enclaveCtx.Namespace) + logrus.Infof("New enclave created under namespace %s", enclaveCtx.Namespace) if err != nil { return nil, err } - log.Infof("Starting the blockchain genesis") + logrus.Infof("Starting the blockchain genesis") err = kurtosis.StartNetwork(ctx, enclaveCtx, cfg.HarnessConfig) if err != nil { return nil, err @@ -37,7 +37,7 @@ func loadEnclaveFromExistingDevnet(ctx context.Context, cfg *types.ConfigParsed) } namespace := cfg.AttacknetConfig.ExistingDevnetNamespace - log.Infof("Looking for existing enclave identified by namespace %s", namespace) + logrus.Infof("Looking for existing enclave identified by namespace %s", namespace) enclaveCtx, enclaveCreated, err := kurtosis.CreateOrImportContext(ctx, kurtosisCtx, cfg) if err != nil { return nil, err @@ -45,22 +45,22 @@ func loadEnclaveFromExistingDevnet(ctx context.Context, cfg *types.ConfigParsed) if enclaveCreated { // we need to genesis a new devnet regardless - log.Info("Since we created a new kurtosis enclave, we must now genesis the blockchain.") + logrus.Info("Since we created a new kurtosis enclave, we must now genesis the blockchain.") err = kurtosis.StartNetwork(ctx, enclaveCtx, cfg.HarnessConfig) if err != nil { return nil, err } } else { - log.Infof("An active enclave matching %s was found", namespace) + logrus.Infof("An active enclave matching %s was found", namespace) } return enclaveCtx, nil } -func setupEnclave(ctx context.Context, cfg *types.ConfigParsed) (enclave *kurtosis.EnclaveContextWrapper, err error) { +func SetupEnclave(ctx context.Context, cfg *types.ConfigParsed) (enclave *kurtosis.EnclaveContextWrapper, err error) { if cfg.AttacknetConfig.ExistingDevnetNamespace == "" { if cfg.AttacknetConfig.ReuseDevnetBetweenRuns { - log.Warn("Could not re-use an existing devnet because no existingDevnetNamespace was set.") + logrus.Warn("Could not re-use an existing devnet because no existingDevnetNamespace was set.") } enclave, err = setupDevnet(ctx, cfg) } else { diff --git a/pkg/test_executor/decoder.go b/pkg/test_executor/decoder.go deleted file mode 100644 index 1bcd49c..0000000 --- a/pkg/test_executor/decoder.go +++ /dev/null @@ -1,3 +0,0 @@ -package test_executor - -// todo: verify plan configs diff --git a/pkg/test_executor/executor.go b/pkg/test_executor/executor.go index 5354086..d74d2c2 100644 --- a/pkg/test_executor/executor.go +++ b/pkg/test_executor/executor.go @@ -72,6 +72,7 @@ func (te *TestExecutor) GetPodsUnderTest() ([]*chaos_mesh.PodUnderTest, error) { return nil, stacktrace.NewError("test %s has not been executed yet. cannot determine pods under test", te.testName) } pods := make(map[string]*chaos_mesh.PodUnderTest) + var retPods []*chaos_mesh.PodUnderTest for _, session := range te.faultSessions { for _, pod := range session.PodsUnderTest { @@ -83,6 +84,7 @@ func (te *TestExecutor) GetPodsUnderTest() ([]*chaos_mesh.PodUnderTest, error) { TouchedByFault: pod.TouchedByFault, } pods[pod.Name] = p + retPods = append(retPods, pod) } else { if pod.ExpectDeath && !val.ExpectDeath { val.ExpectDeath = true @@ -93,11 +95,6 @@ func (te *TestExecutor) GetPodsUnderTest() ([]*chaos_mesh.PodUnderTest, error) { } } } - - var retPods []*chaos_mesh.PodUnderTest - for _, pod := range pods { - retPods = append(retPods, pod) - } return retPods, nil } diff --git a/planner-configs/clock-skew-nethermind.yaml b/planner-configs/clock-skew-nethermind.yaml index 44c33dc..b6f9be2 100644 --- a/planner-configs/clock-skew-nethermind.yaml +++ b/planner-configs/clock-skew-nethermind.yaml @@ -29,6 +29,9 @@ network_params: num_validator_keys_per_node: 32 kurtosis_package: "github.com/kurtosis-tech/ethereum-package@060fd8fb3ed8e12be895a43912787313c1ad4a5f" kubernetes_namespace: kt-nethermind +topology: + bootnode_el: nethermind + bootnode_cl: prysm fault_config: fault_type: ClockSkew target_client: nethermind @@ -56,6 +59,7 @@ fault_config: grace_period: 300s fault_targeting_dimensions: - MatchingClient + - MatchingNode fault_attack_size_dimensions: - AttackOneMatching - AttackMinorityMatching diff --git a/planner-configs/clock-skew-reth.yaml b/planner-configs/clock-skew-reth.yaml index ec60220..06c5951 100644 --- a/planner-configs/clock-skew-reth.yaml +++ b/planner-configs/clock-skew-reth.yaml @@ -29,6 +29,10 @@ network_params: num_validator_keys_per_node: 32 kurtosis_package: "github.com/kurtosis-tech/ethereum-package@060fd8fb3ed8e12be895a43912787313c1ad4a5f" kubernetes_namespace: kt-ethereum +topology: + bootnode_el: nethermind + bootnode_cl: prysm + targets_as_percent_of_network: 0.25 fault_config: fault_type: ClockSkew target_client: reth diff --git a/planner-configs/io-latency-reth.yaml b/planner-configs/io-latency-reth.yaml index 759bb12..5a004f2 100644 --- a/planner-configs/io-latency-reth.yaml +++ b/planner-configs/io-latency-reth.yaml @@ -29,6 +29,10 @@ network_params: num_validator_keys_per_node: 32 kurtosis_package: "github.com/kurtosis-tech/ethereum-package@060fd8fb3ed8e12be895a43912787313c1ad4a5f" kubernetes_namespace: kt-ethereum +topology: + bootnode_el: nethermind + bootnode_cl: prysm + targets_as_percent_of_network: 0.25 fault_config: fault_type: IOLatency target_client: reth diff --git a/planner-configs/network-latency-reth.yaml b/planner-configs/network-latency-reth.yaml new file mode 100644 index 0000000..d69caea --- /dev/null +++ b/planner-configs/network-latency-reth.yaml @@ -0,0 +1,56 @@ +execution: + - name: geth + image: ethereum/client-go:v1.13.11 + - name: reth + image: parithoshj/reth:main-1a8440a-debug + - name: erigon + image: thorax/erigon:v2.57.3 + - name: nethermind + image: nethermind/nethermind:1.25.3 + - name: besu + image: hyperledger/besu:24.1.1 +consensus: + - name: lighthouse + image: sigp/lighthouse:v4.6.0 + has_sidecar: true + - name: prysm + image: gcr.io/prysmaticlabs/prysm/beacon-chain:v4.2.1,gcr.io/prysmaticlabs/prysm/validator:v4.2.1 + has_sidecar: true + - name: teku + image: consensys/teku:24.1.1-amd64 + has_sidecar: false + - name: lodestar + image: chainsafe/lodestar:v1.15.0 + has_sidecar: true + # https://github.com/kurtosis-tech/ethereum-package/issues/417 + - name: nimbus + image: ethpandaops/nimbus:unstable + has_sidecar: false +topology: + bootnode_el: geth + bootnode_cl: prysm + target_node_multiplier: 1 + targets_as_percent_of_network: 0.40 +network_params: + num_validator_keys_per_node: 32 +kurtosis_package: "github.com/kurtosis-tech/ethereum-package" +kubernetes_namespace: kt-restart-reth +fault_config: + fault_type: NetworkLatency + target_client: reth + wait_before_first_test: 300s + fault_config_dimensions: + - grace_period: 300s + delay: 500ms + jitter: 500ms + duration: 1m + correlation: 100 + fault_targeting_dimensions: + - MatchingClient + fault_attack_size_dimensions: + - AttackOneMatching + - AttackMinorityMatching + - AttackSuperminorityMatching + - AttackMajorityMatching + - AttackSupermajorityMatching + - AttackAllMatching \ No newline at end of file diff --git a/planner-configs/network-packet-drop-geth.yaml b/planner-configs/network-packet-drop-geth.yaml new file mode 100644 index 0000000..b4ef44e --- /dev/null +++ b/planner-configs/network-packet-drop-geth.yaml @@ -0,0 +1,54 @@ +execution: + - name: geth + image: ethereum/client-go:v1.13.11 + - name: reth + image: parithoshj/reth:main-1a8440a-debug + - name: erigon + image: thorax/erigon:v2.57.3 + - name: nethermind + image: nethermindeth/nethermind:1.25.4-5899434 + - name: besu + image: hyperledger/besu:24.1.1 +consensus: + - name: lighthouse + image: sigp/lighthouse:v4.6.0 + has_sidecar: true + - name: prysm + image: gcr.io/prysmaticlabs/prysm/beacon-chain:v4.2.1,gcr.io/prysmaticlabs/prysm/validator:v4.2.1 + has_sidecar: true + - name: teku + image: consensys/teku:24.1.1-amd64 + has_sidecar: false + - name: lodestar + image: chainsafe/lodestar:v1.15.0 + has_sidecar: true + - name: nimbus + image: ethpandaops/nimbus:unstable + has_sidecar: false +topology: + bootnode_el: geth + bootnode_cl: prysm + target_node_multiplier: 1 + targets_as_percent_of_network: 0.67 +network_params: + num_validator_keys_per_node: 32 +kurtosis_package: "github.com/kurtosis-tech/ethereum-package@060fd8fb3ed8e12be895a43912787313c1ad4a5f" +kubernetes_namespace: kt-packet-drop +fault_config: + fault_type: PacketLoss + target_client: geth + wait_before_first_test: 3s + fault_config_dimensions: + - grace_period: 300s + loss_percent: 100 + duration: 1m + direction: to + fault_targeting_dimensions: + - MatchingClient + fault_attack_size_dimensions: + - AttackOneMatching + - AttackMinorityMatching + - AttackSuperminorityMatching + - AttackMajorityMatching + - AttackSupermajorityMatching + - AttackAllMatching \ No newline at end of file diff --git a/planner-configs/restart-resillience-reth.yaml b/planner-configs/restart-resillience-reth.yaml index 6251af5..5154277 100644 --- a/planner-configs/restart-resillience-reth.yaml +++ b/planner-configs/restart-resillience-reth.yaml @@ -1,30 +1,36 @@ execution: - name: geth - image: ethereum/client-go:latest + image: ethereum/client-go:v1.13.11 - name: reth - image: ghcr.io/paradigmxyz/reth:v0.1.0-alpha.13 + image: parithoshj/reth:main-1a8440a-debug - name: erigon - image: thorax/erigon:v2.53.4 + image: thorax/erigon:v2.57.3 - name: nethermind - image: nethermind/nethermind:1.25.1 - #- name: besu - # image: hyperledger/besu:latest + image: nethermind/nethermind:1.25.3 + - name: besu + image: hyperledger/besu:24.1.1 consensus: - name: lighthouse - image: sigp/lighthouse:latest + image: sigp/lighthouse:v4.6.0 has_sidecar: true - name: prysm - image: prysmaticlabs/prysm-beacon-chain:latest,prysmaticlabs/prysm-validator:latest + image: gcr.io/prysmaticlabs/prysm/beacon-chain:v4.2.1,gcr.io/prysmaticlabs/prysm/validator:v4.2.1 has_sidecar: true - #- name: teku - # image: consensys/teku:23.12.0 - # has_sidecar: false + - name: teku + image: consensys/teku:24.1.1-amd64 + has_sidecar: false - name: lodestar - image: chainsafe/lodestar:v1.12.1 + image: chainsafe/lodestar:v1.15.0 has_sidecar: true # https://github.com/kurtosis-tech/ethereum-package/issues/417 -# - name: nimbus -# image: statusim/nimbus-eth2:amd64-v23.11.0 + - name: nimbus + image: ethpandaops/nimbus:unstable + has_sidecar: false +topology: + bootnode_el: nethermind + bootnode_cl: prysm + target_node_multiplier: 2 + targets_as_percent_of_network: 0.67 network_params: num_validator_keys_per_node: 32 kurtosis_package: "github.com/kurtosis-tech/ethereum-package@060fd8fb3ed8e12be895a43912787313c1ad4a5f" @@ -32,16 +38,15 @@ kubernetes_namespace: kt-restart-reth fault_config: fault_type: RestartContainers target_client: reth - bootnode_el: nethermind - bootnode_cl: prysm wait_before_first_test: 300s fault_config_dimensions: - grace_period: 300s fault_targeting_dimensions: - - MatchingNode - MatchingClient fault_attack_size_dimensions: - AttackOneMatching - AttackMinorityMatching - AttackSuperminorityMatching - - AttackMajorityMatching \ No newline at end of file + - AttackMajorityMatching + - AttackSupermajorityMatching + - AttackAllMatching \ No newline at end of file diff --git a/test-suites/clock-skew.yaml b/test-suites/clock-skew.yaml index 6c70e6b..99fa67d 100644 --- a/test-suites/clock-skew.yaml +++ b/test-suites/clock-skew.yaml @@ -1,9 +1,10 @@ attacknetConfig: grafanaPodName: grafana grafanaPodPort: 3000 - waitBeforeInjectionSeconds: 300 + waitBeforeInjectionSeconds: 0 reuseDevnetBetweenRuns: true allowPostFaultInspection: true + existingDevnetNamespace: kt-restart-reth harnessConfig: networkPackage: github.com/kurtosis-tech/ethereum-package @@ -25,12 +26,11 @@ testConfig: spec: selector: labelSelectors: - kurtosistech.com.custom/ethereum-package.client: lighthouse - kurtosistech.com.custom/ethereum-package.client-type: beacon + kurtosistech.com/id: cl-04-teku-reth mode: all action: delay - timeOffset: '-1m' - duration: 1m + timeOffset: '832s' + duration: 1000s - stepType: waitForFaultCompletion description: wait for faults to terminate diff --git a/test-suites/plan/network-latency-reth.yaml b/test-suites/plan/network-latency-reth.yaml new file mode 100644 index 0000000..149f04d --- /dev/null +++ b/test-suites/plan/network-latency-reth.yaml @@ -0,0 +1,288 @@ +attacknetConfig: + grafanaPodName: grafana + grafanaPodPort: "3000" + allowPostFaultInspection: false + waitBeforeInjectionSeconds: 300 + reuseDevnetBetweenRuns: true + existingDevnetNamespace: kt-restart-reth +harnessConfig: + networkType: ethereum + networkPackage: github.com/kurtosis-tech/ethereum-package + networkConfig: plan/network-latency-reth.yaml +testConfig: + tests: + - testName: 'Apply 500ms network latency for 1m0s. Jitter: 500ms, correlation: 100 against 1 targets. Impacting the client of targeted reth clients. Injecting into AttackOneMatching of the matching targets.' + planSteps: + - stepType: injectFault + description: 'Inject network latency on target reth client of reth/lighthouse Node (Node #2)' + chaosFaultSpec: + apiVersion: chaos-mesh.org/v1alpha1 + kind: NetworkChaos + spec: + action: delay + delay: + correlation: "100" + jitter: 500ms + latency: 500ms + duration: 1m0s + mode: all + selector: + expressionSelectors: + - key: kurtosistech.com/id + operator: In + values: + - el-02-reth-lighthouse + - stepType: waitForFaultCompletion + description: wait for faults to terminate + health: + enableChecks: true + gracePeriod: 5m0s + - testName: 'Apply 500ms network latency for 1m0s. Jitter: 500ms, correlation: 100 against 3 targets. Impacting the client of targeted reth clients. Injecting into AttackMinorityMatching of the matching targets.' + planSteps: + - stepType: injectFault + description: 'Inject network latency on target reth client of reth/lighthouse Node (Node #2)' + chaosFaultSpec: + apiVersion: chaos-mesh.org/v1alpha1 + kind: NetworkChaos + spec: + action: delay + delay: + correlation: "100" + jitter: 500ms + latency: 500ms + duration: 1m0s + mode: all + selector: + expressionSelectors: + - key: kurtosistech.com/id + operator: In + values: + - el-02-reth-lighthouse + - stepType: injectFault + description: 'Inject network latency on target reth client of reth/prysm Node (Node #3)' + chaosFaultSpec: + apiVersion: chaos-mesh.org/v1alpha1 + kind: NetworkChaos + spec: + action: delay + delay: + correlation: "100" + jitter: 500ms + latency: 500ms + duration: 1m0s + mode: all + selector: + expressionSelectors: + - key: kurtosistech.com/id + operator: In + values: + - el-03-reth-prysm + - stepType: injectFault + description: 'Inject network latency on target reth client of reth/teku Node (Node #4)' + chaosFaultSpec: + apiVersion: chaos-mesh.org/v1alpha1 + kind: NetworkChaos + spec: + action: delay + delay: + correlation: "100" + jitter: 500ms + latency: 500ms + duration: 1m0s + mode: all + selector: + expressionSelectors: + - key: kurtosistech.com/id + operator: In + values: + - el-04-reth-teku + - stepType: waitForFaultCompletion + description: wait for faults to terminate + health: + enableChecks: true + gracePeriod: 5m0s + - testName: 'Apply 500ms network latency for 1m0s. Jitter: 500ms, correlation: 100 against 4 targets. Impacting the client of targeted reth clients. Injecting into AttackSuperminorityMatching of the matching targets.' + planSteps: + - stepType: injectFault + description: 'Inject network latency on target reth client of reth/lighthouse Node (Node #2)' + chaosFaultSpec: + apiVersion: chaos-mesh.org/v1alpha1 + kind: NetworkChaos + spec: + action: delay + delay: + correlation: "100" + jitter: 500ms + latency: 500ms + duration: 1m0s + mode: all + selector: + expressionSelectors: + - key: kurtosistech.com/id + operator: In + values: + - el-02-reth-lighthouse + - stepType: injectFault + description: 'Inject network latency on target reth client of reth/prysm Node (Node #3)' + chaosFaultSpec: + apiVersion: chaos-mesh.org/v1alpha1 + kind: NetworkChaos + spec: + action: delay + delay: + correlation: "100" + jitter: 500ms + latency: 500ms + duration: 1m0s + mode: all + selector: + expressionSelectors: + - key: kurtosistech.com/id + operator: In + values: + - el-03-reth-prysm + - stepType: injectFault + description: 'Inject network latency on target reth client of reth/teku Node (Node #4)' + chaosFaultSpec: + apiVersion: chaos-mesh.org/v1alpha1 + kind: NetworkChaos + spec: + action: delay + delay: + correlation: "100" + jitter: 500ms + latency: 500ms + duration: 1m0s + mode: all + selector: + expressionSelectors: + - key: kurtosistech.com/id + operator: In + values: + - el-04-reth-teku + - stepType: injectFault + description: 'Inject network latency on target reth client of reth/lodestar Node (Node #5)' + chaosFaultSpec: + apiVersion: chaos-mesh.org/v1alpha1 + kind: NetworkChaos + spec: + action: delay + delay: + correlation: "100" + jitter: 500ms + latency: 500ms + duration: 1m0s + mode: all + selector: + expressionSelectors: + - key: kurtosistech.com/id + operator: In + values: + - el-05-reth-lodestar + - stepType: waitForFaultCompletion + description: wait for faults to terminate + health: + enableChecks: true + gracePeriod: 5m0s + - testName: 'Apply 500ms network latency for 1m0s. Jitter: 500ms, correlation: 100 against 5 targets. Impacting the client of targeted reth clients. Injecting into AttackAllMatching of the matching targets.' + planSteps: + - stepType: injectFault + description: 'Inject network latency on target reth client of reth/lighthouse Node (Node #2)' + chaosFaultSpec: + apiVersion: chaos-mesh.org/v1alpha1 + kind: NetworkChaos + spec: + action: delay + delay: + correlation: "100" + jitter: 500ms + latency: 500ms + duration: 1m0s + mode: all + selector: + expressionSelectors: + - key: kurtosistech.com/id + operator: In + values: + - el-02-reth-lighthouse + - stepType: injectFault + description: 'Inject network latency on target reth client of reth/prysm Node (Node #3)' + chaosFaultSpec: + apiVersion: chaos-mesh.org/v1alpha1 + kind: NetworkChaos + spec: + action: delay + delay: + correlation: "100" + jitter: 500ms + latency: 500ms + duration: 1m0s + mode: all + selector: + expressionSelectors: + - key: kurtosistech.com/id + operator: In + values: + - el-03-reth-prysm + - stepType: injectFault + description: 'Inject network latency on target reth client of reth/teku Node (Node #4)' + chaosFaultSpec: + apiVersion: chaos-mesh.org/v1alpha1 + kind: NetworkChaos + spec: + action: delay + delay: + correlation: "100" + jitter: 500ms + latency: 500ms + duration: 1m0s + mode: all + selector: + expressionSelectors: + - key: kurtosistech.com/id + operator: In + values: + - el-04-reth-teku + - stepType: injectFault + description: 'Inject network latency on target reth client of reth/lodestar Node (Node #5)' + chaosFaultSpec: + apiVersion: chaos-mesh.org/v1alpha1 + kind: NetworkChaos + spec: + action: delay + delay: + correlation: "100" + jitter: 500ms + latency: 500ms + duration: 1m0s + mode: all + selector: + expressionSelectors: + - key: kurtosistech.com/id + operator: In + values: + - el-05-reth-lodestar + - stepType: injectFault + description: 'Inject network latency on target reth client of reth/nimbus Node (Node #6)' + chaosFaultSpec: + apiVersion: chaos-mesh.org/v1alpha1 + kind: NetworkChaos + spec: + action: delay + delay: + correlation: "100" + jitter: 500ms + latency: 500ms + duration: 1m0s + mode: all + selector: + expressionSelectors: + - key: kurtosistech.com/id + operator: In + values: + - el-06-reth-nimbus + - stepType: waitForFaultCompletion + description: wait for faults to terminate + health: + enableChecks: true + gracePeriod: 5m0s diff --git a/test-suites/plan/restart-resillience-reth.yaml b/test-suites/plan/restart-resillience-reth.yaml new file mode 100644 index 0000000..d239f3e --- /dev/null +++ b/test-suites/plan/restart-resillience-reth.yaml @@ -0,0 +1,169 @@ +attacknetConfig: + grafanaPodName: grafana + grafanaPodPort: "3000" + allowPostFaultInspection: false + waitBeforeInjectionSeconds: 300 + reuseDevnetBetweenRuns: true + existingDevnetNamespace: kt-restart-reth +harnessConfig: + networkType: ethereum + networkPackage: github.com/kurtosis-tech/ethereum-package@060fd8fb3ed8e12be895a43912787313c1ad4a5f + networkConfig: plan/restart-resillience-reth.yaml +testConfig: + tests: + - testName: Restarting 1 targets. Impacting the full node of targeted reth clients. Injecting into AttackOneMatching of the matching targets. + planSteps: + - stepType: injectFault + description: 'Restart target reth/lighthouse Node (Node #2)' + chaosFaultSpec: + apiVersion: chaos-mesh.org/v1alpha1 + kind: PodChaos + spec: + action: pod-failure + duration: 5s + mode: all + selector: + expressionSelectors: + - key: kurtosistech.com/id + operator: In + values: + - el-2-reth-lighthouse + - cl-2-lighthouse-reth + - cl-2-lighthouse-reth-validator + - stepType: waitForFaultCompletion + description: wait for faults to terminate + health: + enableChecks: true + gracePeriod: 5m0s + - testName: Restarting 3 targets. Impacting the full node of targeted reth clients. Injecting into AttackMinorityMatching of the matching targets. + planSteps: + - stepType: injectFault + description: 'Restart target reth/lighthouse Node (Node #2)' + chaosFaultSpec: + apiVersion: chaos-mesh.org/v1alpha1 + kind: PodChaos + spec: + action: pod-failure + duration: 5s + mode: all + selector: + expressionSelectors: + - key: kurtosistech.com/id + operator: In + values: + - el-2-reth-lighthouse + - cl-2-lighthouse-reth + - cl-2-lighthouse-reth-validator + - stepType: injectFault + description: 'Restart target reth/prysm Node (Node #3)' + chaosFaultSpec: + apiVersion: chaos-mesh.org/v1alpha1 + kind: PodChaos + spec: + action: pod-failure + duration: 5s + mode: all + selector: + expressionSelectors: + - key: kurtosistech.com/id + operator: In + values: + - el-3-reth-prysm + - cl-3-prysm-reth + - cl-3-prysm-reth-validator + - stepType: injectFault + description: 'Restart target reth/lodestar Node (Node #4)' + chaosFaultSpec: + apiVersion: chaos-mesh.org/v1alpha1 + kind: PodChaos + spec: + action: pod-failure + duration: 5s + mode: all + selector: + expressionSelectors: + - key: kurtosistech.com/id + operator: In + values: + - el-4-reth-lodestar + - cl-4-lodestar-reth + - cl-4-lodestar-reth-validator + - stepType: waitForFaultCompletion + description: wait for faults to terminate + health: + enableChecks: true + gracePeriod: 5m0s + - testName: Restarting 1 targets. Impacting the client of targeted reth clients. Injecting into AttackOneMatching of the matching targets. + planSteps: + - stepType: injectFault + description: 'Restart target reth client of reth/lighthouse Node (Node #2)' + chaosFaultSpec: + apiVersion: chaos-mesh.org/v1alpha1 + kind: PodChaos + spec: + action: pod-failure + duration: 5s + mode: all + selector: + expressionSelectors: + - key: kurtosistech.com/id + operator: In + values: + - el-2-reth-lighthouse + - stepType: waitForFaultCompletion + description: wait for faults to terminate + health: + enableChecks: true + gracePeriod: 5m0s + - testName: Restarting 3 targets. Impacting the client of targeted reth clients. Injecting into AttackMinorityMatching of the matching targets. + planSteps: + - stepType: injectFault + description: 'Restart target reth client of reth/lighthouse Node (Node #2)' + chaosFaultSpec: + apiVersion: chaos-mesh.org/v1alpha1 + kind: PodChaos + spec: + action: pod-failure + duration: 5s + mode: all + selector: + expressionSelectors: + - key: kurtosistech.com/id + operator: In + values: + - el-2-reth-lighthouse + - stepType: injectFault + description: 'Restart target reth client of reth/prysm Node (Node #3)' + chaosFaultSpec: + apiVersion: chaos-mesh.org/v1alpha1 + kind: PodChaos + spec: + action: pod-failure + duration: 5s + mode: all + selector: + expressionSelectors: + - key: kurtosistech.com/id + operator: In + values: + - el-3-reth-prysm + - stepType: injectFault + description: 'Restart target reth client of reth/lodestar Node (Node #4)' + chaosFaultSpec: + apiVersion: chaos-mesh.org/v1alpha1 + kind: PodChaos + spec: + action: pod-failure + duration: 5s + mode: all + selector: + expressionSelectors: + - key: kurtosistech.com/id + operator: In + values: + - el-4-reth-lodestar + - stepType: waitForFaultCompletion + description: wait for faults to terminate + health: + enableChecks: true + gracePeriod: 5m0s diff --git a/test-suites/plan/test-lodestar-reth.yaml b/test-suites/plan/test-lodestar-reth.yaml new file mode 100644 index 0000000..3b23ffa --- /dev/null +++ b/test-suites/plan/test-lodestar-reth.yaml @@ -0,0 +1,13 @@ +attacknetConfig: + grafanaPodName: grafana + grafanaPodPort: "3000" + allowPostFaultInspection: false + waitBeforeInjectionSeconds: 300 + reuseDevnetBetweenRuns: true + existingDevnetNamespace: kt-lodestar-reth +harnessConfig: + networkType: ethereum + networkPackage: github.com/kurtosis-tech/ethereum-package + networkConfig: plan/test-lodestar-reth.yaml +testConfig: + tests: []