From 09bee96e6852be6be2448df670a1c43f0182187f Mon Sep 17 00:00:00 2001 From: skudasov Date: Fri, 23 Jan 2026 18:47:01 -0500 Subject: [PATCH 1/5] poc --- framework/cmd/tomldoc/go.mod | 141 +++++ framework/cmd/tomldoc/go.sum | 537 ++++++++++++++++++ framework/cmd/tomldoc/main.go | 121 ++++ framework/cmd/tomldoc/toml-docs.toml | 230 ++++++++ framework/components/blockchain/blockchain.go | 26 +- framework/docker.go | 4 +- 6 files changed, 1044 insertions(+), 15 deletions(-) create mode 100644 framework/cmd/tomldoc/go.mod create mode 100644 framework/cmd/tomldoc/go.sum create mode 100644 framework/cmd/tomldoc/main.go create mode 100644 framework/cmd/tomldoc/toml-docs.toml diff --git a/framework/cmd/tomldoc/go.mod b/framework/cmd/tomldoc/go.mod new file mode 100644 index 000000000..f81ab75ab --- /dev/null +++ b/framework/cmd/tomldoc/go.mod @@ -0,0 +1,141 @@ +module github.com/smartcontractkit/chainlink-testing-framework/framework/tomldoc + +go 1.24.4 + +replace ( + github.com/smartcontractkit/chainlink-testing-framework/framework => ../../ + github.com/smartcontractkit/chainlink-testing-framework/framework/components/fake => ../../components/fake + github.com/smartcontractkit/chainlink-testing-framework/wasp => ../../../wasp +) + +require ( + github.com/smartcontractkit/chainlink-testing-framework/framework v0.13.8 + github.com/smartcontractkit/chainlink-testing-framework/framework/components/fake v0.0.0-20250707095700-c7855f06ddd1 +) + +require ( + github.com/DataDog/zstd v1.5.2 // indirect + github.com/block-vision/sui-go-sdk v1.0.6 // indirect + github.com/cespare/cp v1.1.1 // indirect + github.com/containerd/errdefs v1.0.0 // indirect + github.com/containerd/errdefs/pkg v0.3.0 // indirect + github.com/creack/pty v1.1.24 // indirect + github.com/ethereum/go-ethereum v1.15.0 // indirect + github.com/go-resty/resty/v2 v2.16.5 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 // indirect + github.com/mattn/go-runewidth v0.0.16 // indirect + github.com/moby/go-archive v0.1.0 // indirect + github.com/rivo/uniseg v0.4.7 // indirect + github.com/rs/cors v1.11.1 // indirect + github.com/stretchr/testify v1.10.0 // indirect + github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect + github.com/testcontainers/testcontainers-go v0.37.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.34.0 // indirect +) + +require ( + dario.cat/mergo v1.0.1 // indirect + github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c // indirect + github.com/Microsoft/go-winio v0.6.2 // indirect + github.com/avast/retry-go/v4 v4.6.1 // indirect + github.com/bits-and-blooms/bitset v1.17.0 // indirect + github.com/bytedance/sonic v1.12.3 // indirect + github.com/bytedance/sonic/loader v0.2.0 // indirect + github.com/cenkalti/backoff/v4 v4.3.0 // indirect + github.com/cloudwego/base64x v0.1.4 // indirect + github.com/cloudwego/iasm v0.2.0 // indirect + github.com/consensys/bavard v0.1.22 // indirect + github.com/consensys/gnark-crypto v0.14.0 // indirect + github.com/containerd/log v0.1.0 // indirect + github.com/containerd/platforms v1.0.0-rc.1 // indirect + github.com/cpuguy83/dockercfg v0.3.2 // indirect + github.com/crate-crypto/go-ipa v0.0.0-20240724233137-53bbb0ceb27a // indirect + github.com/crate-crypto/go-kzg-4844 v1.1.0 // indirect + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect + github.com/deckarep/golang-set/v2 v2.6.0 // indirect + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect + github.com/distribution/reference v0.6.0 // indirect + github.com/docker/docker v28.3.3+incompatible // indirect + github.com/docker/go-connections v0.5.0 // indirect + github.com/docker/go-units v0.5.0 // indirect + github.com/ebitengine/purego v0.8.2 // indirect + github.com/ethereum/c-kzg-4844 v1.0.0 // indirect + github.com/ethereum/go-verkle v0.2.2 // indirect + github.com/felixge/httpsnoop v1.0.4 // indirect + github.com/fsnotify/fsnotify v1.8.0 // indirect + github.com/gabriel-vasile/mimetype v1.4.6 // indirect + github.com/gin-contrib/sse v0.1.0 // indirect + github.com/gin-gonic/gin v1.10.1 // indirect + github.com/go-logr/logr v1.4.3 // indirect + github.com/go-logr/stdr v1.2.2 // indirect + github.com/go-ole/go-ole v1.3.0 // indirect + github.com/go-playground/locales v0.14.1 // indirect + github.com/go-playground/universal-translator v0.18.1 // indirect + github.com/go-playground/validator/v10 v10.22.1 // indirect + github.com/goccy/go-json v0.10.5 // indirect + github.com/gogo/protobuf v1.3.3 // indirect + github.com/golang-jwt/jwt/v5 v5.3.0 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/gorilla/websocket v1.5.3 // indirect + github.com/holiman/uint256 v1.3.2 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/klauspost/compress v1.18.2 // indirect + github.com/klauspost/cpuid/v2 v2.2.9 // indirect + github.com/leodido/go-urn v1.4.0 // indirect + github.com/lufia/plan9stats v0.0.0-20240226150601-1dcf7310316a // indirect + github.com/magiconair/properties v1.8.10 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/mmcloughlin/addchain v0.4.0 // indirect + github.com/moby/docker-image-spec v1.3.1 // indirect + github.com/moby/patternmatcher v0.6.0 // indirect + github.com/moby/sys/sequential v0.6.0 // indirect + github.com/moby/sys/user v0.4.0 // indirect + github.com/moby/sys/userns v0.1.0 // indirect + github.com/moby/term v0.5.2 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/morikuni/aec v1.0.0 // indirect + github.com/opencontainers/go-digest v1.0.0 // indirect + github.com/opencontainers/image-spec v1.1.1 // indirect + github.com/pelletier/go-toml/v2 v2.2.3 + github.com/pkg/errors v0.9.1 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect + github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect + github.com/rs/zerolog v1.33.0 // indirect + github.com/shirou/gopsutil v3.21.11+incompatible // indirect + github.com/shirou/gopsutil/v4 v4.25.1 // indirect + github.com/sirupsen/logrus v1.9.3 // indirect + github.com/supranational/blst v0.3.13 // indirect + github.com/tidwall/gjson v1.17.0 // indirect + github.com/tidwall/match v1.1.1 // indirect + github.com/tidwall/pretty v1.2.1 // indirect + github.com/tklauser/go-sysconf v0.3.13 // indirect + github.com/tklauser/numcpus v0.7.0 // indirect + github.com/twitchyliquid64/golang-asm v0.15.1 // indirect + github.com/ugorji/go/codec v1.2.12 // indirect + github.com/yusufpapurcu/wmi v1.2.4 // indirect + go.opentelemetry.io/auto/sdk v1.1.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.0 // indirect + go.opentelemetry.io/otel v1.37.0 // indirect + go.opentelemetry.io/otel/metric v1.37.0 // indirect + go.opentelemetry.io/otel/trace v1.37.0 // indirect + go.uber.org/multierr v1.11.0 // indirect + golang.org/x/arch v0.11.0 // indirect + golang.org/x/crypto v0.39.0 // indirect + golang.org/x/exp v0.0.0-20250106191152-7588d65b2ba8 // indirect + golang.org/x/net v0.40.0 // indirect + golang.org/x/sync v0.15.0 // indirect + golang.org/x/sys v0.33.0 // indirect + golang.org/x/text v0.26.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20250528174236-200df99c418a // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 // indirect + google.golang.org/grpc v1.72.2 // indirect + google.golang.org/protobuf v1.36.6 // indirect + gopkg.in/guregu/null.v4 v4.0.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect + rsc.io/tmplfunc v0.0.3 // indirect +) + +// replicating the replace directive on cosmos SDK +replace github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 diff --git a/framework/cmd/tomldoc/go.sum b/framework/cmd/tomldoc/go.sum new file mode 100644 index 000000000..16fc69033 --- /dev/null +++ b/framework/cmd/tomldoc/go.sum @@ -0,0 +1,537 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s= +dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= +github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6 h1:He8afgbRMd7mFxO99hRNu+6tazq8nFF9lIwo9JFroBk= +github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8= +github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c h1:udKWzYgxTojEKWjV8V+WSxDXJ4NFATAsZjh8iIbsQIg= +github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/DataDog/zstd v1.5.2 h1:vUG4lAyuPCXO0TLbXvPv7EB7cNK1QV/luu55UHLrrn8= +github.com/DataDog/zstd v1.5.2/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= +github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= +github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= +github.com/VictoriaMetrics/fastcache v1.12.2 h1:N0y9ASrJ0F6h0QaC3o6uJb3NIZ9VKLjCM7NQbSmF7WI= +github.com/VictoriaMetrics/fastcache v1.12.2/go.mod h1:AmC+Nzz1+3G2eCPapF6UcsnkThDcMsQicp4xDukwJYI= +github.com/avast/retry-go/v4 v4.6.1 h1:VkOLRubHdisGrHnTu89g08aQEWEgRU7LVEop3GbIcMk= +github.com/avast/retry-go/v4 v4.6.1/go.mod h1:V6oF8njAwxJ5gRo1Q7Cxab24xs5NCWZBeaHHBklR8mA= +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.17.0 h1:1X2TS7aHz1ELcC0yU1y2stUs/0ig5oMU6STFZGrhvHI= +github.com/bits-and-blooms/bitset v1.17.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= +github.com/block-vision/sui-go-sdk v1.0.6 h1:FysCc4TJC8v4BEBbCjJPDR4iR5eKqJT1dxGwsT67etg= +github.com/block-vision/sui-go-sdk v1.0.6/go.mod h1:FyK1vGE8lWm9QA1fdQpf1agfXQSMbPT8AV1BICgx6d8= +github.com/bytedance/sonic v1.12.3 h1:W2MGa7RCU1QTeYRTPE3+88mVC0yXmsRQRChiyVocVjU= +github.com/bytedance/sonic v1.12.3/go.mod h1:B8Gt/XvtZ3Fqj+iSKMypzymZxw/FVwgIGKzMzT9r/rk= +github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= +github.com/bytedance/sonic/loader v0.2.0 h1:zNprn+lsIP06C/IqCHs3gPQIvnvpKbbxyXQP1iU4kWM= +github.com/bytedance/sonic/loader v0.2.0/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= +github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= +github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/cp v1.1.1 h1:nCb6ZLdB7NRaqsm91JtQTAme2SKJzXVsdPIPkyJr1MU= +github.com/cespare/cp v1.1.1/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y= +github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w= +github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg= +github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cockroachdb/errors v1.11.3 h1:5bA+k2Y6r+oz/6Z/RFlNeVCesGARKuC6YymtcDrbC/I= +github.com/cockroachdb/errors v1.11.3/go.mod h1:m4UIW4CDjx+R5cybPsNrRbreomiFqt8o1h1wUVazSd8= +github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce h1:giXvy4KSc/6g/esnpM7Geqxka4WSqI1SZc7sMJFd3y4= +github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce/go.mod h1:9/y3cnZ5GKakj/H4y9r9GTjCvAFta7KLgSHPJJYc52M= +github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b h1:r6VH0faHjZeQy818SGhaone5OnYfxFR/+AzdY3sf5aE= +github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= +github.com/cockroachdb/pebble v1.1.2 h1:CUh2IPtR4swHlEj48Rhfzw6l/d0qA31fItcIszQVIsA= +github.com/cockroachdb/pebble v1.1.2/go.mod h1:4exszw1r40423ZsmkG/09AFEG83I0uDgfujJdbL6kYU= +github.com/cockroachdb/redact v1.1.5 h1:u1PMllDkdFfPWaNGMyLD1+so+aq3uUItthCFqzwPJ30= +github.com/cockroachdb/redact v1.1.5/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= +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.22 h1:Uw2CGvbXSZWhqK59X0VG/zOjpTFuOMcPLStrp1ihI0A= +github.com/consensys/bavard v0.1.22/go.mod h1:k/zVjHHC4B+PQy1Pg7fgvG3ALicQw540Crag8qx+dZs= +github.com/consensys/gnark-crypto v0.14.0 h1:DDBdl4HaBtdQsq/wfMwJvZNE80sHidrK3Nfrefatm0E= +github.com/consensys/gnark-crypto v0.14.0/go.mod h1:CU4UijNPsHawiVGNxe9co07FkzCeWHHrb1li/n1XoU0= +github.com/containerd/errdefs v1.0.0 h1:tg5yIfIlQIrxYtu9ajqY42W3lpS19XqdxRQeEwYG8PI= +github.com/containerd/errdefs v1.0.0/go.mod h1:+YBYIdtsnF4Iw6nWZhJcqGSg/dwvV7tyJ/kCkyJ2k+M= +github.com/containerd/errdefs/pkg v0.3.0 h1:9IKJ06FvyNlexW690DXuQNx2KA2cUJXx151Xdx3ZPPE= +github.com/containerd/errdefs/pkg v0.3.0/go.mod h1:NJw6s9HwNuRhnjJhM7pylWwMyAkmCQvQ4GpJHEqRLVk= +github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= +github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= +github.com/containerd/platforms v1.0.0-rc.1 h1:83KIq4yy1erSRgOVHNk1HYdPvzdJ5CnsWaRoJX4C41E= +github.com/containerd/platforms v1.0.0-rc.1/go.mod h1:J71L7B+aiM5SdIEqmd9wp6THLVRzJGXfNuWCZCllLA4= +github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/cpuguy83/dockercfg v0.3.2 h1:DlJTyZGBDlXqUZ2Dk2Q3xHs/FtnooJJVaad2S9GKorA= +github.com/cpuguy83/dockercfg v0.3.2/go.mod h1:sugsbF4//dDlL/i+S+rtpIWp+5h0BHJHfjj5/jFyUJc= +github.com/cpuguy83/go-md2man/v2 v2.0.7 h1:zbFlGlXEAKlwXpmvle3d8Oe3YnkKIK4xSRTd3sHPnBo= +github.com/cpuguy83/go-md2man/v2 v2.0.7/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= +github.com/crate-crypto/go-ipa v0.0.0-20240724233137-53bbb0ceb27a h1:W8mUrRp6NOVl3J+MYp5kPMoUZPp7aOYHtaua31lwRHg= +github.com/crate-crypto/go-ipa v0.0.0-20240724233137-53bbb0ceb27a/go.mod h1:sTwzHBvIzm2RfVCGNEBZgRyjwK40bVoun3ZnGOCafNM= +github.com/crate-crypto/go-kzg-4844 v1.1.0 h1:EN/u9k2TF6OWSHrCCDBBU6GLNMq88OspHHlMnHfoyU4= +github.com/crate-crypto/go-kzg-4844 v1.1.0/go.mod h1:JolLjpSff1tCCJKaJx4psrlEdlXuJEC996PL3tTAFks= +github.com/creack/pty v1.1.24 h1:bJrF4RRfyJnbTJqzRLHzcGaZK1NeM5kTC9jGgovnR1s= +github.com/creack/pty v1.1.24/go.mod h1:08sCNb52WyoAwi2QDyzUCTgcvVFhUzewun7wtTfvcwE= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +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.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.3.0 h1:rpfIENRNNilwHwZeG5+P150SMrnNEcHYvcCuK6dPZSg= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= +github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= +github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= +github.com/docker/docker v28.3.3+incompatible h1:Dypm25kh4rmk49v1eiVbsAtpAsYURjYkaKubwuBdxEI= +github.com/docker/docker v28.3.3+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c= +github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc= +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/ebitengine/purego v0.8.2 h1:jPPGWs2sZ1UgOSgD2bClL0MJIqu58nOmIcBuXr62z1I= +github.com/ebitengine/purego v0.8.2/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/ethereum/c-kzg-4844 v1.0.0 h1:0X1LBXxaEtYD9xsyj9B9ctQEZIpnvVDeoBx8aHEwTNA= +github.com/ethereum/c-kzg-4844 v1.0.0/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1aQputP83wc0= +github.com/ethereum/go-ethereum v1.15.0 h1:LLb2jCPsbJZcB4INw+E/MgzUX5wlR6SdwXcv09/1ME4= +github.com/ethereum/go-ethereum v1.15.0/go.mod h1:4q+4t48P2C03sjqGvTXix5lEOplf5dz4CTosbjt5tGs= +github.com/ethereum/go-verkle v0.2.2 h1:I2W0WjnrFUIzzVPwm8ykY+7pL2d4VhlsePn4j7cnFk8= +github.com/ethereum/go-verkle v0.2.2/go.mod h1:M3b90YRnzqKyyzBEWJGqj8Qff4IDeXnzFw0P9bFw3uk= +github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= +github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= +github.com/fsnotify/fsnotify v1.8.0 h1:dAwr6QBTBZIkG8roQaJjGof0pp0EeF+tNV7YBP3F/8M= +github.com/fsnotify/fsnotify v1.8.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= +github.com/gabriel-vasile/mimetype v1.4.6 h1:3+PzJTKLkvgjeTbts6msPJt4DixhT4YtFNf1gtGe3zc= +github.com/gabriel-vasile/mimetype v1.4.6/go.mod h1:JX1qVKqZd40hUPpAfiNTe0Sne7hdfKSbOqqmkq8GCXc= +github.com/getsentry/sentry-go v0.27.0 h1:Pv98CIbtB3LkMWmXi4Joa5OOcwbmnX88sF5qbK3r3Ps= +github.com/getsentry/sentry-go v0.27.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY= +github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= +github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= +github.com/gin-gonic/gin v1.10.1 h1:T0ujvqyCSqRopADpgPgiTT63DUQVSfojyME59Ei63pQ= +github.com/gin-gonic/gin v1.10.1/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= +github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +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-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-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= +github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= +github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= +github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= +github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= +github.com/go-playground/validator/v10 v10.22.1 h1:40JcKH+bBNGFczGuoBYgX4I6m/i27HYW8P9FDk5PbgA= +github.com/go-playground/validator/v10 v10.22.1/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= +github.com/go-resty/resty/v2 v2.16.5 h1:hBKqmWrr7uRc3euHVqmh1HTHcKn99Smr7o5spptdhTM= +github.com/go-resty/resty/v2 v2.16.5/go.mod h1:hkJtXbA2iKHzJheXYvQ8snQES5ZLGKMwQ07xAwp/fiA= +github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= +github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4= +github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/gofrs/flock v0.12.1 h1:MTLVXXHf8ekldpJk3AKicLij9MdwOWkZ+a/jHHZby9E= +github.com/gofrs/flock v0.12.1/go.mod h1:9zxTsyu5xtJ9DK+1tFZyibEV7y3uwDxPPfbxeeHCoD0= +github.com/golang-jwt/jwt/v4 v4.5.1 h1:JdqV9zKUdtaa9gdPlywC3aeoEsR681PlKC+4F5gQgeo= +github.com/golang-jwt/jwt/v4 v4.5.1/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= +github.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo= +github.com/golang-jwt/jwt/v5 v5.3.0/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +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/snappy v0.0.4/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/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +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-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= +github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 h1:5ZPtiqj0JL5oKWmcsq4VMaAW5ukBEgSGXEN89zeH1Jo= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3/go.mod h1:ndYquD05frm2vACXE1nsccT4oJzjhw2arTS2cpUD1PI= +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/holiman/billy v0.0.0-20240216141850-2abb0c79d3c4 h1:X4egAf/gcS1zATw6wn4Ej8vjuVGxeHdan+bRb2ebyv4= +github.com/holiman/billy v0.0.0-20240216141850-2abb0c79d3c4/go.mod h1:5GuXa7vkL8u9FkFuWdVvfR5ix8hRB7DbOAaYULamFpc= +github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao= +github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA= +github.com/holiman/uint256 v1.3.2 h1:a9EgMPSC1AAaj1SZL5zIQD3WbwTuHrMGOerLjGmM/TA= +github.com/holiman/uint256 v1.3.2/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc= +github.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= +github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +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.18.2 h1:iiPHWW0YrcFgpBYhsA6D1+fqHssJscY/Tm/y2Uqnapk= +github.com/klauspost/compress v1.18.2/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4= +github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/klauspost/cpuid/v2 v2.2.9 h1:66ze0taIn2H33fBvCkXuv9BmCwDfafmiIVpKV9kKGuY= +github.com/klauspost/cpuid/v2 v2.2.9/go.mod h1:rqkxqrZ1EhYM9G+hXH7YdowN5R5RGN6NK4QwQ3WMXF8= +github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +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/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.11 h1:vRjThO1EKPb/1NsDXuDrzldR28RLkBflWYcU9CvzWu4= +github.com/leanovate/gopter v0.2.11/go.mod h1:aK3tzZP/C+p1m3SPRE4SYZFGP7jjkuSI4f7Xvpt0S9c= +github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= +github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= +github.com/lufia/plan9stats v0.0.0-20240226150601-1dcf7310316a h1:3Bm7EwfUQUvhNeKIkUct/gl9eod1TcXuj8stxvi/GoI= +github.com/lufia/plan9stats v0.0.0-20240226150601-1dcf7310316a/go.mod h1:ilwx/Dta8jXAgpFYFvSWEMwxmbWXyiUHkd5FwyKhb5k= +github.com/magiconair/properties v1.8.10 h1:s31yESBquKXCV9a/ScB3ESkOjUYYv+X0rg8SYxI99mE= +github.com/magiconair/properties v1.8.10/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +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.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= +github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/mitchellh/mapstructure v1.5.1-0.20220423185008-bf980b35cac4 h1:BpfhmLKZf+SjVanKKhCgf3bg+511DmU9eDQTen7LLbY= +github.com/mitchellh/mapstructure v1.5.1-0.20220423185008-bf980b35cac4/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= +github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0= +github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo= +github.com/moby/go-archive v0.1.0 h1:Kk/5rdW/g+H8NHdJW2gsXyZ7UnzvJNOy6VKJqueWdcQ= +github.com/moby/go-archive v0.1.0/go.mod h1:G9B+YoujNohJmrIYFBpSd54GTUB4lt9S+xVQvsJyFuo= +github.com/moby/patternmatcher v0.6.0 h1:GmP9lR19aU5GqSSFko+5pRqHi+Ohk1O69aFiKkVGiPk= +github.com/moby/patternmatcher v0.6.0/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc= +github.com/moby/sys/atomicwriter v0.1.0 h1:kw5D/EqkBwsBFi0ss9v1VG3wIkVhzGvLklJ+w3A14Sw= +github.com/moby/sys/atomicwriter v0.1.0/go.mod h1:Ul8oqv2ZMNHOceF643P6FKPXeCmYtlQMvpizfsSoaWs= +github.com/moby/sys/sequential v0.6.0 h1:qrx7XFUd/5DxtqcoH1h438hF5TmOvzC/lspjy7zgvCU= +github.com/moby/sys/sequential v0.6.0/go.mod h1:uyv8EUTrca5PnDsdMGXhZe6CCe8U/UiTWd+lL+7b/Ko= +github.com/moby/sys/user v0.4.0 h1:jhcMKit7SA80hivmFJcbB1vqmw//wU61Zdui2eQXuMs= +github.com/moby/sys/user v0.4.0/go.mod h1:bG+tYYYJgaMtRKgEmuueC0hJEAZWwtIbZTB+85uoHjs= +github.com/moby/sys/userns v0.1.0 h1:tVLXkFOxVu9A64/yh59slHVv9ahO9UIev4JZusOLG/g= +github.com/moby/sys/userns v0.1.0/go.mod h1:IHUYgu/kao6N8YZlp9Cf444ySSvCmDlmzUcYfDHOl28= +github.com/moby/term v0.5.2 h1:6qk3FJAFDs6i/q3W/pQ97SX192qKfZgGjCQqfCJkgzQ= +github.com/moby/term v0.5.2/go.mod h1:d3djjFCrjnB+fl8NJux+EJzu0msscUP+f8it8hPkFLc= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= +github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= +github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= +github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= +github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= +github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= +github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= +github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= +github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= +github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= +github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040= +github.com/opencontainers/image-spec v1.1.1/go.mod h1:qpqAh3Dmcf36wStyyWU+kCeDgrGnAve2nCC8+7h8Q0M= +github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M= +github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc= +github.com/pion/dtls/v2 v2.2.7 h1:cSUBsETxepsCSFSxC3mc/aDo14qQLMSL+O6IjG28yV8= +github.com/pion/dtls/v2 v2.2.7/go.mod h1:8WiMkebSHFD0T+dIU+UeBaoV7kDhOW5oDCzZ7WZ/F9s= +github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY= +github.com/pion/logging v0.2.2/go.mod h1:k0/tDVsRCX2Mb2ZEmTqNa7CWsQPc+YYCB7Q+5pahoms= +github.com/pion/stun/v2 v2.0.0 h1:A5+wXKLAypxQri59+tmQKVs7+l6mMM+3d+eER9ifRU0= +github.com/pion/stun/v2 v2.0.0/go.mod h1:22qRSh08fSEttYUmJZGlriq9+03jtVmXNODgLccj8GQ= +github.com/pion/transport/v2 v2.2.1 h1:7qYnCBlpgSJNYMbLCKuSY9KbQdBFoETvPNETv0y4N7c= +github.com/pion/transport/v2 v2.2.1/go.mod h1:cXXWavvCnFF6McHTft3DWS9iic2Mftcz1Aq29pGcU5g= +github.com/pion/transport/v3 v3.0.1 h1:gDTlPJwROfSfz6QfSi0ZmeCSkFcnWWiiR9ES0ouANiM= +github.com/pion/transport/v3 v3.0.1/go.mod h1:UY7kiITrlMv7/IKgd5eTUcaahZx5oUN3l9SzK5f5xE0= +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/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 h1:o4JXh1EVt9k/+g42oCprj/FisM4qX9L3sZB3upGN2ZU= +github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= +github.com/prometheus/client_golang v1.21.0-rc.0 h1:bR+RxBlwcr4q8hXkgSOA/J18j6n0/qH0Gb0DH+8c+RY= +github.com/prometheus/client_golang v1.21.0-rc.0/go.mod h1:U9NM32ykUErtVBxdvD3zfi+EuFkkaBvMb09mIfe0Zgg= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= +github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= +github.com/prometheus/common v0.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ2Io= +github.com/prometheus/common v0.62.0/go.mod h1:vyBcEuLSvWos9B1+CyL7JZ2up+uFzXhkqml0W5zIY1I= +github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= +github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= +github.com/regen-network/protobuf v1.3.3-alpha.regen.1 h1:OHEc+q5iIAXpqiqFKeLpu5NwTIkVXUs48vFMwzqpqY4= +github.com/regen-network/protobuf v1.3.3-alpha.regen.1/go.mod h1:2DjTFR1HhMQhiWC5sZ4OhQ3+NtdbZ6oBDKQwq5Ou+FI= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= +github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= +github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= +github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= +github.com/rs/cors v1.11.1 h1:eU3gRzXLRK57F5rKMGMZURNdIG4EoAmX8k94r9wXWHA= +github.com/rs/cors v1.11.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= +github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= +github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8= +github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= +github.com/russross/blackfriday v1.6.0 h1:KqfZb0pUVN2lYqZUYRddxF4OR8ZMURnJIG5Y3VRLtww= +github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +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/shirou/gopsutil/v4 v4.25.1 h1:QSWkTc+fu9LTAWfkZwZ6j8MSUk4A2LV7rbH0ZqmLjXs= +github.com/shirou/gopsutil/v4 v4.25.1/go.mod h1:RoUCUpndaJFtT+2zsZzzmhvbfGoDCJ7nFXKJf8GqJbI= +github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +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/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +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.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= +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.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/supranational/blst v0.3.13 h1:AYeSxdOMacwu7FBmpfloBz5pbFXDmJL33RuwnKtmTjk= +github.com/supranational/blst v0.3.13/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= +github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d h1:vfofYNRScrDdvS342BElfbETmL1Aiz3i2t0zfRj16Hs= +github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d/go.mod h1:RRCYJbIwD5jmqPI9XoAFR0OcDxqUctll6zUj/+B4S48= +github.com/testcontainers/testcontainers-go v0.37.0 h1:L2Qc0vkTw2EHWQ08djon0D2uw7Z/PtHS/QzZZ5Ra/hg= +github.com/testcontainers/testcontainers-go v0.37.0/go.mod h1:QPzbxZhQ6Bclip9igjLFj6z0hs01bU8lrl2dHQmgFGM= +github.com/tidwall/gjson v1.17.0 h1:/Jocvlh98kcTfpN2+JzGQWQcqrPQwDrVEMApx/M5ZwM= +github.com/tidwall/gjson v1.17.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= +github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= +github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= +github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4= +github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= +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.7.0 h1:yjuerZP127QG9m5Zh/mSO4wqurYil27tHrqwRoRjpr4= +github.com/tklauser/numcpus v0.7.0/go.mod h1:bb6dMVcj8A42tSE7i32fsIUCbQNllK5iDguyOZRUzAY= +github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= +github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= +github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE= +github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= +github.com/urfave/cli/v2 v2.27.7 h1:bH59vdhbjLv3LAvIu6gd0usJHgoTTPhCFib8qqOwXYU= +github.com/urfave/cli/v2 v2.27.7/go.mod h1:CyNAG/xg+iAOg0N4MPGZqVmv2rCoP267496AOXUZjA4= +github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4= +github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= +github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= +go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= +go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.0 h1:CV7UdSGJt/Ao6Gp4CXckLxVRRsRgDHoI8XjbL3PDl8s= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.0/go.mod h1:FRmFuRJfag1IZ2dPkHnEoSFVgTVPUd2qf5Vi69hLb8I= +go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ= +go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0 h1:Ahq7pZmv87yiyn3jeFz/LekZmPLLdKejuO3NcK9MssM= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0/go.mod h1:MJTqhM0im3mRLw1i8uGHnCvUEeS7VwRyxlLC78PA18M= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.34.0 h1:BEj3SPM81McUZHYjRS5pEgNgnmzGJ5tRpU5krWnV8Bs= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.34.0/go.mod h1:9cKLGBDzI/F3NoHLQGm4ZrYdIHsvGt6ej6hUowxY0J4= +go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE= +go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E= +go.opentelemetry.io/otel/sdk v1.37.0 h1:ItB0QUqnjesGRvNcmAcU0LyvkVyGJ2xftD29bWdDvKI= +go.opentelemetry.io/otel/sdk v1.37.0/go.mod h1:VredYzxUvuo2q3WRcDnKDjbdvmO0sCzOvVAiY+yUkAg= +go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4= +go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0= +go.opentelemetry.io/proto/otlp v1.7.0 h1:jX1VolD6nHuFzOYso2E73H85i92Mv8JQYk0K9vz09os= +go.opentelemetry.io/proto/otlp v1.7.0/go.mod h1:fSKjH6YJ7HDlwzltzyMj036AJ3ejJLCgCSHGj4efDDo= +go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +golang.org/x/arch v0.11.0 h1:KXV8WWKCXm6tRpLirl2szsO5j/oOODwZf4hATmGVNs4= +golang.org/x/arch v0.11.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= +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.39.0 h1:SHs+kF4LP+f+p14esP5jAoDpHU8Gu/v9lFRK6IT5imM= +golang.org/x/crypto v0.39.0/go.mod h1:L+Xg3Wf6HoL4Bn4238Z6ft6KfEpN0tJGo53AAPC632U= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20250106191152-7588d65b2ba8 h1:yqrTHse8TCMW1M1ZCP+VAR/l0kKxwaAIqN/il7x4voA= +golang.org/x/exp v0.0.0-20250106191152-7588d65b2ba8/go.mod h1:tujkw807nyEEAamNbDrEGzRav+ilXA7PCRAd6xsmwiU= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/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/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +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-20190620200207-3b0461eec859/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-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.40.0 h1:79Xs7wF06Gbdcg4kdCCIQArK11Z1hr5POQ6+fIYHNuY= +golang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/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.15.0 h1:KWH3jNZsfyT6xfAfKiz6MRNmd46ByHDYaZ7KSkCtdW8= +golang.org/x/sync v0.15.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +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-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/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-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/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-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw= +golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +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.32.0 h1:DR4lr0TjUs3epypdhTOkMmuF5CDFJ/8pOnbzMZPQ7bg= +golang.org/x/term v0.32.0/go.mod h1:uZG1FhGx848Sqfsq4/DlJr3xGGsYMu/L5GW4abiaEPQ= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +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.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.26.0 h1:P42AVeLghgTYr4+xUnTRKDMqpar+PtX7KWuNQL21L8M= +golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA= +golang.org/x/time v0.10.0 h1:3usCWA8tQn0L8+hFJQNgzpWbd89begxN66o1Ojdn5L4= +golang.org/x/time v0.10.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-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +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-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +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-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20200324203455-a04cca1dde73/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto/googleapis/api v0.0.0-20250528174236-200df99c418a h1:SGktgSolFCo75dnHJF2yMvnns6jCmHFJ0vE4Vn2JKvQ= +google.golang.org/genproto/googleapis/api v0.0.0-20250528174236-200df99c418a/go.mod h1:a77HrdMjoeKbnd2jmgcWdaS++ZLZAEq3orIOAEIKiVw= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 h1:fc6jSaCT0vBduLYZHYrBBNY4dsWuvgyff9noRNDdBeE= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= +google.golang.org/grpc v1.72.2 h1:TdbGzwb82ty4OusHWepvFWGLgIbNo1/SUynEN0ssqv8= +google.golang.org/grpc v1.72.2/go.mod h1:wH5Aktxcg25y1I3w7H69nHfXdOG3UiadoBtjh3izSDM= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +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.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= +google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/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/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/guregu/null.v4 v4.0.0 h1:1Wm3S1WEA2I26Kq+6vcW+w0gcDo44YKYD7YIEJNHDjg= +gopkg.in/guregu/null.v4 v4.0.0/go.mod h1:YoQhUrADuG3i9WqesrCmpNRwm1ypAgSHYqoOcTu/JrI= +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/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/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.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gotest.tools/v3 v3.5.2 h1:7koQfIKdy+I8UTetycgUqXWSDwpgv193Ka+qRsmBY8Q= +gotest.tools/v3 v3.5.2/go.mod h1:LtdLGcnqToBH83WByAAi/wiwSFCArdFIUV/xxN4pcjA= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= +rsc.io/tmplfunc v0.0.3 h1:53XFQh69AfOa8Tw0Jm7t+GV7KZhOi6jzsCzTtKbMvzU= +rsc.io/tmplfunc v0.0.3/go.mod h1:AG3sTPzElb1Io3Yg4voV9AGZJuleGAwaVRxL9M49PhA= diff --git a/framework/cmd/tomldoc/main.go b/framework/cmd/tomldoc/main.go new file mode 100644 index 000000000..70c355b93 --- /dev/null +++ b/framework/cmd/tomldoc/main.go @@ -0,0 +1,121 @@ +package main + +import ( + "flag" + "log" + "os" + "reflect" + + toml "github.com/pelletier/go-toml/v2" + "github.com/smartcontractkit/chainlink-testing-framework/framework/components/blockchain" + "github.com/smartcontractkit/chainlink-testing-framework/framework/components/fake" + "github.com/smartcontractkit/chainlink-testing-framework/framework/components/simple_node_set" +) + +// AllStructDocs is just an example that is unmarshalled to TOML +// with all "comment" tags so we can have a good configuration examples +// structs are initialized with initializeStruct +// when you add a new component just add a new type here +// and docs will be automatically generated +type AllStructDocs struct { + Fake *fake.Input `toml:"fakes" comment:"Fake HTTP server representing 3rd party dependencies"` + Blockchains []*blockchain.Input `toml:"blockchains" comment:"Various blockchains, see 'type' field comments"` + NodeSets []*simple_node_set.Input `toml:"nodesets" comment:"Chainlink Node Set including multiple Chainlink nodes forming a DON"` +} + +// initializeAny initializes any object so we can call Unmarshal method for all the fields +func initializeAny(obj any) { + v := reflect.ValueOf(obj).Elem() + // Check if it's a struct before we iterate the fields + if v.Kind() != reflect.Struct { + return + } + for i := 0; i < v.NumField(); i++ { + field := v.Field(i) + fieldType := v.Type().Field(i) + + // Skip unexported fields + if !fieldType.IsExported() { + continue + } + switch field.Kind() { + case reflect.Ptr: + if field.IsNil() { + elemType := field.Type().Elem() + // Check if it's a pointer to a struct + if elemType.Kind() == reflect.Struct { + newVal := reflect.New(elemType) + field.Set(newVal) + initializeAny(newVal.Interface()) + } else { + // For pointers to basic types, just create zero value + field.Set(reflect.New(elemType)) + } + } else { + // Already initialized, but might point to a struct + if field.Elem().Kind() == reflect.Struct { + initializeAny(field.Interface()) + } + } + + case reflect.Slice: + if field.Len() == 0 { + elemType := field.Type().Elem() + + // For slice of pointers to structs + if elemType.Kind() == reflect.Ptr { + ptrElemType := elemType.Elem() + if ptrElemType.Kind() == reflect.Struct { + newElem := reflect.New(ptrElemType) + // Initialize the struct element + initializeAny(newElem.Interface()) + // Create slice with one element + slice := reflect.MakeSlice(field.Type(), 1, 1) + slice.Index(0).Set(newElem) + field.Set(slice) + } + } else if elemType.Kind() == reflect.Struct { + // For slice of structs (not pointers) + newElem := reflect.New(elemType).Elem() + initializeAny(newElem.Addr().Interface()) + slice := reflect.MakeSlice(field.Type(), 1, 1) + slice.Index(0).Set(newElem) + field.Set(slice) + } + // For slices of basic types ([]string, []int, etc.) do nothing + } + + case reflect.Struct: + // For nested structs (not pointers) + initializeAny(field.Addr().Interface()) + case reflect.Map: + if field.IsNil() { + field.Set(reflect.MakeMap(field.Type())) + } + // For all other types (string, int, bool, etc.), do nothing, already initialized + } + } +} + +func main() { + outputFile := flag.String("output", "toml-docs.toml", "Output file to write all the struct examples to") + flag.Parse() + f, err := os.Create(*outputFile) + if err != nil { + log.Fatalf("Error creating file: %v", err) + } + defer f.Close() + + encoder := toml.NewEncoder(f) + // this also writes "comment" lines from fields as # comment on top of each field + encoder.SetIndentTables(true) + + // initialize all the framework structs + all := &AllStructDocs{} + initializeAny(all) + + // encode and write examples + if err := encoder.Encode(&all); err != nil { + log.Fatalf("Error encoding to file: %v", err) + } +} diff --git a/framework/cmd/tomldoc/toml-docs.toml b/framework/cmd/tomldoc/toml-docs.toml new file mode 100644 index 000000000..1a0cd65f8 --- /dev/null +++ b/framework/cmd/tomldoc/toml-docs.toml @@ -0,0 +1,230 @@ +# Fake HTTP server representing 3rd party dependencies +[fakes] + image = '' + port = 0 + + [fakes.out] + use_cache = false + base_url_host = '' + base_url_docker = '' + +# Various blockchains, see 'type' field comments +[[blockchains]] + # Type can be one of: anvil geth besu solana aptos tron sui ton canton, this struct describes common configuration we are using across all blockchains + type = '' + # Blockchain node image in format: $registry:$image, ex.: ghcr.io/foundry-rs/foundry:stable + image = '' + # Whether to pull image or not when creating Docker container + pull_image = false + # The port Docker container will expose + port = '' + # Docker container name + container_name = '' + # WebSocket port container will expose + port_ws = '' + # Blockchain chain ID + chain_id = '' + # Docker command parameters override, ex. for Anvil: ["-b", "1", "--mixed-mining"] + docker_cmd_params = [] + # Public key to mint when solana-test-validator starts + public_key = '' + # Solana's contracts directory + contracts_dir = '' + custom_ports = [] + faucet_port = '' + number_of_canton_validators = 0 + host_network_mode = false + certificates_path = '' + image_platform = '' + + # blockchain deployment output + [blockchains.out] + use_cache = false + type = '' + family = '' + container_name = '' + chain_id = '' + + [blockchains.out.network_specific_data] + [blockchains.out.network_specific_data.SuiAccount] + Alias = '' + Flag = 0 + KeyScheme = '' + Mnemonic = '' + PeerId = '' + PublicBase64Key = '' + SuiAddress = '' + + [blockchains.out.network_specific_data.CantonEndpoints] + ScanAPIURL = '' + RegistryAPIURL = '' + + [blockchains.out.network_specific_data.CantonEndpoints.SuperValidator] + JSONLedgerAPIURL = '' + GRPCLedgerAPIURL = '' + AdminAPIURL = '' + ValidatorAPIURL = '' + HTTPHealthCheckURL = '' + GRPCHealthCheckURL = '' + JWT = '' + + [[blockchains.out.network_specific_data.CantonEndpoints.Participants]] + JSONLedgerAPIURL = '' + GRPCLedgerAPIURL = '' + AdminAPIURL = '' + ValidatorAPIURL = '' + HTTPHealthCheckURL = '' + GRPCHealthCheckURL = '' + JWT = '' + + [[blockchains.out.nodes]] + ws_url = '' + http_url = '' + internal_ws_url = '' + internal_http_url = '' + + # Solana's programs, map of program name to program ID, there needs to be a matching .so file in contracts_dir + [blockchains.solana_programs] + + # Docker container resources + [blockchains.resources] + # CPU shares, ex.: 2 + cpus = 0.0 + # Memory in MegaBytes, ex.:"200" + memory_mb = 0 + + [blockchains.custom_env] + +# Chainlink Node Set including multiple Chainlink nodes forming a DON +[[nodesets]] + name = '' + nodes = 0 + http_port_range_start = 0 + p2p_port_range_start = 0 + dlv_port_range_start = 0 + override_mode = '' + no_dns = false + + [nodesets.db] + image = '' + port = 0 + name = '' + volume_name = '' + databases = 0 + jd_database = false + jd_sql_dump_path = '' + pull_image = false + + [nodesets.db.resources] + # CPU shares, ex.: 2 + cpus = 0.0 + # Memory in MegaBytes, ex.:"200" + memory_mb = 0 + + [nodesets.db.out] + url = '' + container_name = '' + internal_url = '' + jd_url = '' + jd_internal_url = '' + + [[nodesets.node_specs]] + no_dns = false + + [nodesets.node_specs.db] + image = '' + port = 0 + name = '' + volume_name = '' + databases = 0 + jd_database = false + jd_sql_dump_path = '' + pull_image = false + + [nodesets.node_specs.db.resources] + # CPU shares, ex.: 2 + cpus = 0.0 + # Memory in MegaBytes, ex.:"200" + memory_mb = 0 + + [nodesets.node_specs.db.out] + url = '' + container_name = '' + internal_url = '' + jd_url = '' + jd_internal_url = '' + + [nodesets.node_specs.node] + image = '' + name = '' + docker_file = '' + docker_ctx = '' + pull_image = false + capabilities = [] + capabilities_container_dir = '' + test_config_overrides = '' + user_config_overrides = '' + test_secrets_overrides = '' + user_secrets_overrides = '' + port = 0 + p2p_port = 0 + custom_ports = [] + debugger_port = 0 + + [nodesets.node_specs.node.docker_build_args] + + [nodesets.node_specs.node.resources] + # CPU shares, ex.: 2 + cpus = 0.0 + # Memory in MegaBytes, ex.:"200" + memory_mb = 0 + + [nodesets.node_specs.node.env_vars] + + [nodesets.node_specs.out] + use_cache = false + + [nodesets.node_specs.out.node] + api_auth_user = '' + api_auth_password = '' + container_name = '' + url = '' + internal_url = '' + p2p_internal_url = '' + internal_ip = '' + + [nodesets.node_specs.out.postgresql] + url = '' + container_name = '' + internal_url = '' + jd_url = '' + jd_internal_url = '' + + [nodesets.out] + use_cache = false + + [nodesets.out.db_out] + url = '' + container_name = '' + internal_url = '' + jd_url = '' + jd_internal_url = '' + + [[nodesets.out.cl_nodes]] + use_cache = false + + [nodesets.out.cl_nodes.node] + api_auth_user = '' + api_auth_password = '' + container_name = '' + url = '' + internal_url = '' + p2p_internal_url = '' + internal_ip = '' + + [nodesets.out.cl_nodes.postgresql] + url = '' + container_name = '' + internal_url = '' + jd_url = '' + jd_internal_url = '' diff --git a/framework/components/blockchain/blockchain.go b/framework/components/blockchain/blockchain.go index a992a1a7f..efd52d516 100644 --- a/framework/components/blockchain/blockchain.go +++ b/framework/components/blockchain/blockchain.go @@ -37,26 +37,26 @@ const ( // Input is a blockchain network configuration params type Input struct { // Common EVM fields - Type string `toml:"type" validate:"required,oneof=anvil geth besu solana aptos tron sui ton canton" envconfig:"net_type"` - Image string `toml:"image"` - PullImage bool `toml:"pull_image"` - Port string `toml:"port"` - ContainerName string `toml:"container_name"` + Type string `toml:"type" validate:"required,oneof=anvil geth besu solana aptos tron sui ton canton" envconfig:"net_type" comment:"Type can be one of: anvil geth besu solana aptos tron sui ton canton, this struct describes common configuration we are using across all blockchains"` + Image string `toml:"image" comment:"Blockchain node image in format: $registry:$image, ex.: ghcr.io/foundry-rs/foundry:stable"` + PullImage bool `toml:"pull_image" comment:"Whether to pull image or not when creating Docker container"` + Port string `toml:"port" comment:"The port Docker container will expose"` + ContainerName string `toml:"container_name" comment:"Docker container name"` // Not applicable to Solana, ws port for Solana is +1 of port - WSPort string `toml:"port_ws"` - ChainID string `toml:"chain_id"` - DockerCmdParamsOverrides []string `toml:"docker_cmd_params"` - Out *Output `toml:"out"` + WSPort string `toml:"port_ws" comment:"WebSocket port container will expose"` + ChainID string `toml:"chain_id" comment:"Blockchain chain ID"` + DockerCmdParamsOverrides []string `toml:"docker_cmd_params" comment:"Docker command parameters override, ex. for Anvil: [\"-b\", \"1\", \"--mixed-mining\"]"` + Out *Output `toml:"out" comment:"blockchain deployment output"` // Solana fields // publickey to mint when solana-test-validator starts - PublicKey string `toml:"public_key"` - ContractsDir string `toml:"contracts_dir"` + PublicKey string `toml:"public_key" comment:"Public key to mint when solana-test-validator starts"` + ContractsDir string `toml:"contracts_dir" comment:"Solana's contracts directory"` // programs to deploy on solana-test-validator start // a map of program name to program id // there needs to be a matching .so file in contracts_dir - SolanaPrograms map[string]string `toml:"solana_programs"` - ContainerResources *framework.ContainerResources `toml:"resources"` + SolanaPrograms map[string]string `toml:"solana_programs" comment:"Solana's programs, map of program name to program ID, there needs to be a matching .so file in contracts_dir"` + ContainerResources *framework.ContainerResources `toml:"resources" comment:"Docker container resources"` CustomPorts []string `toml:"custom_ports"` // Sui specific: faucet port for funding accounts diff --git a/framework/docker.go b/framework/docker.go index dab3a0d4d..46bc3c47c 100644 --- a/framework/docker.go +++ b/framework/docker.go @@ -474,8 +474,8 @@ func RemoveTestStack(name string) error { } type ContainerResources struct { - CPUs float64 `toml:"cpus" validate:"gte=0"` - MemoryMb uint `toml:"memory_mb"` + CPUs float64 `toml:"cpus" validate:"gte=0" comment:"CPU shares, ex.: 2"` + MemoryMb uint `toml:"memory_mb" comment:"Memory in MegaBytes, ex.:\"200\""` } // ResourceLimitsFunc returns a function to configure container resources based on the human-readable CPUs and memory in Mb From b435e32668a43c850eaa1c55b0917bd324546eef Mon Sep 17 00:00:00 2001 From: skudasov Date: Fri, 23 Jan 2026 22:22:12 -0500 Subject: [PATCH 2/5] document all fields --- .github/workflows/docs.yml | 10 + book/Makefile | 3 + book/README.md | 2 +- {framework/cmd/tomldoc => book}/go.mod | 8 +- {framework/cmd/tomldoc => book}/go.sum | 0 book/src/SUMMARY.md | 58 +-- .../components/blockchains/overview.md | 2 +- .../developer_environment/overview.md | 31 ++ .../framework/developer_environment/toml.md | 11 + book/src/toml.toml | 381 ++++++++++++++++++ .../cmd/tomldoc/main.go => book/tomldoc.go | 0 framework/cmd/tomldoc/toml-docs.toml | 230 ----------- framework/components/blockchain/blockchain.go | 40 +- framework/components/blockchain/canton.go | 45 ++- framework/components/blockchain/sui.go | 14 +- framework/components/clnode/clnode.go | 118 ++++-- framework/components/fake/fake.go | 12 +- framework/components/postgres/postgres.go | 53 ++- .../components/simple_node_set/node_set.go | 29 +- 19 files changed, 658 insertions(+), 389 deletions(-) rename {framework/cmd/tomldoc => book}/go.mod (97%) rename {framework/cmd/tomldoc => book}/go.sum (100%) create mode 100644 book/src/framework/developer_environment/overview.md create mode 100644 book/src/framework/developer_environment/toml.md create mode 100644 book/src/toml.toml rename framework/cmd/tomldoc/main.go => book/tomldoc.go (100%) delete mode 100644 framework/cmd/tomldoc/toml-docs.toml diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 26f9470ef..c9a206a35 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -26,6 +26,16 @@ jobs: run: | cargo install mdbook-alerts cargo install mdbook-cmdrun + + - name: Set up Go + uses: actions/setup-go@v5 + with: + go-version: '1.24.0' + + - name: Generate TOML examples + working-directory: book + run: | + make toml - name: Build working-directory: book diff --git a/book/Makefile b/book/Makefile index 6e640a1c2..bb45be69d 100644 --- a/book/Makefile +++ b/book/Makefile @@ -1,3 +1,6 @@ .PHONY: run run: mdbook serve -p 9999 + +toml: + go run tomldoc.go -output src/toml.toml diff --git a/book/README.md b/book/README.md index 4a1c93566..3d573174c 100644 --- a/book/README.md +++ b/book/README.md @@ -9,7 +9,7 @@ cargo install mdbook-mermaid Run it locally ``` -make run +make toml && make run ``` Open your browser [here](http://localhost:9999/) diff --git a/framework/cmd/tomldoc/go.mod b/book/go.mod similarity index 97% rename from framework/cmd/tomldoc/go.mod rename to book/go.mod index f81ab75ab..ea4041774 100644 --- a/framework/cmd/tomldoc/go.mod +++ b/book/go.mod @@ -1,11 +1,11 @@ -module github.com/smartcontractkit/chainlink-testing-framework/framework/tomldoc +module github.com/smartcontractkit/chainlink-testing-framework/book go 1.24.4 replace ( - github.com/smartcontractkit/chainlink-testing-framework/framework => ../../ - github.com/smartcontractkit/chainlink-testing-framework/framework/components/fake => ../../components/fake - github.com/smartcontractkit/chainlink-testing-framework/wasp => ../../../wasp + github.com/smartcontractkit/chainlink-testing-framework/framework => ../framework + github.com/smartcontractkit/chainlink-testing-framework/framework/components/fake => ../framework/components/fake + github.com/smartcontractkit/chainlink-testing-framework/wasp => ../../wasp ) require ( diff --git a/framework/cmd/tomldoc/go.sum b/book/go.sum similarity index 100% rename from framework/cmd/tomldoc/go.sum rename to book/go.sum diff --git a/book/src/SUMMARY.md b/book/src/SUMMARY.md index 23a16e894..882615c41 100644 --- a/book/src/SUMMARY.md +++ b/book/src/SUMMARY.md @@ -2,9 +2,10 @@ - [Overview](./overview.md) - [Framework](./framework/overview.md) +- [Developer Environment](./framework/developer_environment/overview.md) + - [Configuration](./framework/developer_environment/toml.md) - [Basic Usage](./framework/getting_started.md) - [Getting Started](./framework/getting_started.md) - - [Generating Developer Environment](./framework/generate.md) - [Advanced Usage](./framework/configuration.md) - [CLI](./framework/cli.md) - [Configuration](./framework/configuration.md) @@ -102,38 +103,39 @@ - [Havoc](./libs/havoc.md) - [Seth](./libs/seth.md) - [Sentinel](./libs/sentinel.md) + --- - [Legacy](./legacy.md) - [Overview](./legacy.md) - [CTFv1](lib.md) - - [Blockchain](lib/blockchain.md) - - [Concurrency](lib/concurrency.md) - - [Client](lib/client.md) - - [Anvil]() - - [AWS Secrets Manager](lib/client/aws_secrets_manager.md) - - [Github](lib/client/github.md) - - [Grafana](lib/client/grafana.md) - - [Kafka](lib/client/kafka.md) - - [Loki](lib/client/loki.md) - - [MockServer](lib/client/mockserver.md) - - [Postgres](lib/client/postgres.md) - - [Prometheus](lib/client/prometheus.md) - - [Kubernetes](lib/k8s_new/overview.md) - - [Creating environments](lib/k8s_new/environments.md) - - [Using remote runner](lib/k8s_new/remote_runner.md) - - [Passing test secrets](lib/k8s_new/test_secrets.md) - - [chain.link labels](lib/k8s/labels.md) - - [Kubernetes (legacy docs)](lib/k8s/KUBERNETES.md) - - [K8s Remote Run](lib/k8s/REMOTE_RUN.md) - - [K8s Tutorial](lib/k8s/TUTORIAL.md) - - [Config](lib/config/config.md) - - [Docker](lib/docker/overview.md) - - [Blockchain nodes](lib/docker/blockchain_nodes.md) - - [Chainlink ecosystem](lib/docker/chainlink_ecosystem.md) - - [Third party apps]() - - [Test helpers](lib/docker/test_helpers.md) - - [Logging](lib/logging.md) + - [Blockchain](lib/blockchain.md) + - [Concurrency](lib/concurrency.md) + - [Client](lib/client.md) + - [Anvil]() + - [AWS Secrets Manager](lib/client/aws_secrets_manager.md) + - [Github](lib/client/github.md) + - [Grafana](lib/client/grafana.md) + - [Kafka](lib/client/kafka.md) + - [Loki](lib/client/loki.md) + - [MockServer](lib/client/mockserver.md) + - [Postgres](lib/client/postgres.md) + - [Prometheus](lib/client/prometheus.md) + - [Kubernetes](lib/k8s_new/overview.md) + - [Creating environments](lib/k8s_new/environments.md) + - [Using remote runner](lib/k8s_new/remote_runner.md) + - [Passing test secrets](lib/k8s_new/test_secrets.md) + - [chain.link labels](lib/k8s/labels.md) + - [Kubernetes (legacy docs)](lib/k8s/KUBERNETES.md) + - [K8s Remote Run](lib/k8s/REMOTE_RUN.md) + - [K8s Tutorial](lib/k8s/TUTORIAL.md) + - [Config](lib/config/config.md) + - [Docker](lib/docker/overview.md) + - [Blockchain nodes](lib/docker/blockchain_nodes.md) + - [Chainlink ecosystem](lib/docker/chainlink_ecosystem.md) + - [Third party apps]() + - [Test helpers](lib/docker/test_helpers.md) + - [Logging](lib/logging.md) - [K8s Test Runner](k8s-test-runner/k8s-test-runner.md) --- diff --git a/book/src/framework/components/blockchains/overview.md b/book/src/framework/components/blockchains/overview.md index 4f12f9a1d..c3cf696f4 100644 --- a/book/src/framework/components/blockchains/overview.md +++ b/book/src/framework/components/blockchains/overview.md @@ -1,3 +1,3 @@ # Blockchain components -Here we keep blockchain simulators or real nodes we use for integration testing +Here we keep blockchain simulators or real nodes we use for integration testing. diff --git a/book/src/framework/developer_environment/overview.md b/book/src/framework/developer_environment/overview.md new file mode 100644 index 000000000..935b49db6 --- /dev/null +++ b/book/src/framework/developer_environment/overview.md @@ -0,0 +1,31 @@ +# Generating Chainlink Environment + +Our code generation tools automatically build complete Chainlink environments and test templates, which minimizes documentation and provides a framework that is both structured and easily extensible. + +We provide a single environment for both quick and local developer environment and production-ready environments in Kubernetes. + +## Local Environment + +Read `help` first and then build an environment for a single EVM network: + +```bash +ctf gen -h +# generate a new Chainlink environment in "devenv" directory with 4 Chainlink nodes and one EVM network. Generate CLI called "pcli" and enter the shell +ctf gen env --cli pcli --product-name MyProduct --output-dir devenv --nodes 4 +``` + +Follow further instructions in `devenv/README.md` + +## Remote Environment + +Infrastructure is deployed by internal operators so here we provide only configuration and tools to interact with deployed environments. + +# Generating Infrastructure Testing Template + +Generate performance and chaos testing template for a Kubernetes namespace. + +```bash +ctf gen load -h +# generate test suite named ChaosGen, with workload + default chaos experiments (fail + latency) for all the pods that have app.kubernetes.io/instance annotation +ctf gen load -w -n ChaosGen default +``` diff --git a/book/src/framework/developer_environment/toml.md b/book/src/framework/developer_environment/toml.md new file mode 100644 index 000000000..8859dd86b --- /dev/null +++ b/book/src/framework/developer_environment/toml.md @@ -0,0 +1,11 @@ +# Configuration + +We generate config specification for all our components automatically. + +Here is full specification for what can be specificed in `env.toml` for devenv. + +`.out` fields are useful in case you want to use remote component, or integrate in other language than `Go`, otherwise can be ignored. + +```toml +{{#include ../../toml.toml}} +``` diff --git a/book/src/toml.toml b/book/src/toml.toml new file mode 100644 index 000000000..1850e7d70 --- /dev/null +++ b/book/src/toml.toml @@ -0,0 +1,381 @@ +# Fake HTTP server representing 3rd party dependencies +[fakes] + # Fake service image, usually can be found in our ECR with $project-fakes name + image = '' + # The port which Docker container is exposing + port = 0 + + # Fakes service config output + [fakes.out] + # Whether to respect caching or not, if cache = true component won't be deployed again + use_cache = false + # Base URL which can be used when running locally + base_url_host = '' + # Base URL to reach fakes service from other Docker containers + base_url_docker = '' + +# Various blockchains, see 'type' field comments +[[blockchains]] + # Type can be one of: anvil geth besu solana aptos tron sui ton canton, this struct describes common configuration we are using across all blockchains + type = '' + # Blockchain node image in format: $registry:$image, ex.: ghcr.io/foundry-rs/foundry:stable + image = '' + # Whether to pull image or not when creating Docker container + pull_image = false + # The port Docker container will expose + port = '' + # Docker container name + container_name = '' + # WebSocket port container will expose + port_ws = '' + # Blockchain chain ID + chain_id = '' + # Docker command parameters override, ex. for Anvil: ["-b", "1", "--mixed-mining"] + docker_cmd_params = [] + # Public key to mint when solana-test-validator starts + public_key = '' + # Solana's contracts directory + contracts_dir = '' + # Custom ports pairs in format $host_port_number:$docker_port_number + custom_ports = [] + # Sui blockchain network faucet port + faucet_port = '' + # Number of Canton network validators + number_of_canton_validators = 0 + # GAPv2 specific paramter: host netowork mode, if 'true' will run environment in host network mode + host_network_mode = false + # GAPv2 specific parameter: path to default Ubuntu's certificates + certificates_path = '' + # Docker image platform, default is 'linux/amd64' + image_platform = '' + + # blockchain deployment output + [blockchains.out] + # Whether to respect caching or not, if cache = true component won't be deployed again + use_cache = false + # Type can be one of: anvil geth besu solana aptos tron sui ton canton, this struct describes common configuration we are using across all blockchains + type = '' + # Blockchain family, can be one of: evm solana aptos sui tron ton canton + family = '' + # Blockchain Docker container name + container_name = '' + # Chain ID + chain_id = '' + + # Blockchain network-specific data + [blockchains.out.network_specific_data] + # Sui network account info + [blockchains.out.network_specific_data.sui_account] + # Alias key name, usually null + alias = '' + # - + flag = 0 + # Sui key scheme + key_scheme = '' + # Sui key mnemonic + mnemonic = '' + # Sui key peer ID + peer_id = '' + # Sui key in base64 format + public_base64_key = '' + # Sui key address + sui_address = '' + + # Canton network endpoints info + [blockchains.out.network_specific_data.canton_endpoints] + # https://docs.sync.global/app_dev/scan_api/index.html + scan_api_url = '' + # https://docs.sync.global/app_dev/token_standard/index.html#api-references + registry_api_url = '' + + # Canton network super validator + [blockchains.out.network_specific_data.canton_endpoints.super_validator] + # https://docs.digitalasset.com/build/3.5/reference/json-api/json-api.html + json_ledger_api_url = '' + # https://docs.digitalasset.com/build/3.5/reference/lapi-proto-docs.html + grpc_ledger_api_url = '' + # https://docs.digitalasset.com/operate/3.5/howtos/configure/apis/admin_api.html + admin_api_url = '' + # https://docs.sync.global/app_dev/validator_api/index.html + validator_api_url = '' + # HTTP health check endpoint, responds on GET /health + http_health_check_url = '' + # GRPC health check endpoint, responds to grpc.health.v1.Health/Check + grpc_health_check_url = '' + # JSON Web Token for this participant + jwt = '' + + # Canton participant endpoints + [[blockchains.out.network_specific_data.canton_endpoints.participants]] + # https://docs.digitalasset.com/build/3.5/reference/json-api/json-api.html + json_ledger_api_url = '' + # https://docs.digitalasset.com/build/3.5/reference/lapi-proto-docs.html + grpc_ledger_api_url = '' + # https://docs.digitalasset.com/operate/3.5/howtos/configure/apis/admin_api.html + admin_api_url = '' + # https://docs.sync.global/app_dev/validator_api/index.html + validator_api_url = '' + # HTTP health check endpoint, responds on GET /health + http_health_check_url = '' + # GRPC health check endpoint, responds to grpc.health.v1.Health/Check + grpc_health_check_url = '' + # JSON Web Token for this participant + jwt = '' + + # Blockchain nodes info + [[blockchains.out.nodes]] + # External blockchain node WebSocket URL + ws_url = '' + # External blockchain node HTTP URL + http_url = '' + # Internal blockchain node WebSocket URL + internal_ws_url = '' + # Internal blockchain node HTTP URL + internal_http_url = '' + + # Solana's programs, map of program name to program ID, there needs to be a matching .so file in contracts_dir + [blockchains.solana_programs] + + # Docker container resources + [blockchains.resources] + # CPU shares, ex.: 2 + cpus = 0.0 + # Memory in MegaBytes, ex.:"200" + memory_mb = 0 + + # Docker container environment variables in TOML format key = value + [blockchains.custom_env] + +# Chainlink Node Set including multiple Chainlink nodes forming a DON +[[nodesets]] + # Node set name, ex.:'don-1', Docker containers will be prefixed with this name so tests can distinguish one DON from another + name = '' + # Number of nodes in node set + nodes = 0 + # HTTP ports range starting with port X and increasing by 1 + http_port_range_start = 0 + # P2P ports range starting with port X and increasing by 1 + p2p_port_range_start = 0 + # Delve debugger ports range starting with port X and increasing by 1 + dlv_port_range_start = 0 + # Override mode, applicable only to 'localcre'. Changes how config overrides to TOML nodes apply + override_mode = '' + # Turn DNS on, helpful to isolate container from the internet + no_dns = false + + # Shared node set data base input for PostgreSQL + [nodesets.db] + # PostgreSQL Docker image in format: $registry:$tag + image = '' + # PostgreSQL connection port + port = 0 + # PostgreSQL container name + name = '' + # PostgreSQL docker volume name + volume_name = '' + # Number of pre-created databases for Chainlink nodes + databases = 0 + # Whether to create JobDistributor database or not + jd_database = false + # JobDistributor database dump path to load + jd_sql_dump_path = '' + # Whether to pull PostgreSQL image or not + pull_image = false + + # Docker container resources + [nodesets.db.resources] + # CPU shares, ex.: 2 + cpus = 0.0 + # Memory in MegaBytes, ex.:"200" + memory_mb = 0 + + # PostgreSQL config output + [nodesets.db.out] + # PostgreSQL connection URL + url = '' + # Docker container name + container_name = '' + # PostgreSQL internal connection URL + internal_url = '' + # PostgreSQL internal connection URL to JobDistributor database + jd_url = '' + # PostgreSQL internal connection URL to JobDistributor database + jd_internal_url = '' + + # Chainlink node TOML configurations + [[nodesets.node_specs]] + # whether to allow DNS in Docker containers or not, useful for isolating containers from network if set to 'false' + no_dns = false + + # PostgreSQL database configuration + [nodesets.node_specs.db] + # PostgreSQL Docker image in format: $registry:$tag + image = '' + # PostgreSQL connection port + port = 0 + # PostgreSQL container name + name = '' + # PostgreSQL docker volume name + volume_name = '' + # Number of pre-created databases for Chainlink nodes + databases = 0 + # Whether to create JobDistributor database or not + jd_database = false + # JobDistributor database dump path to load + jd_sql_dump_path = '' + # Whether to pull PostgreSQL image or not + pull_image = false + + # Docker container resources + [nodesets.node_specs.db.resources] + # CPU shares, ex.: 2 + cpus = 0.0 + # Memory in MegaBytes, ex.:"200" + memory_mb = 0 + + # PostgreSQL config output + [nodesets.node_specs.db.out] + # PostgreSQL connection URL + url = '' + # Docker container name + container_name = '' + # PostgreSQL internal connection URL + internal_url = '' + # PostgreSQL internal connection URL to JobDistributor database + jd_url = '' + # PostgreSQL internal connection URL to JobDistributor database + jd_internal_url = '' + + # Chainlink node configuration + [nodesets.node_specs.node] + # Chainlink node Docker image in format $registry:$tag + image = '' + # Chainlink node Docker container name + name = '' + # Docker file path to rebuild, relative to 'docker_ctx' field path + docker_file = '' + # Docker build context path + docker_ctx = '' + # Whether to pull Docker image or not + pull_image = false + # Chainlink CRE capabilities paths for WASM binaries + capabilities = [] + # path to capabilities inside Docker container (capabilities are copied inside container from local path) + capabilities_container_dir = '' + # node config overrides field for programmatic usage in tests + test_config_overrides = '' + # node config overrides field for manual overrides from env.toml configs + user_config_overrides = '' + # node secrets config overrides field for programmatic usage in tests + test_secrets_overrides = '' + # node secrets config overrides field for manual overrides from env.toml configs + user_secrets_overrides = '' + # Chainlink node API HTTP port + port = 0 + # Chainlink node P2P port + p2p_port = 0 + # Custom ports pairs in format $host_port_number:$docker_port_number + custom_ports = [] + # Delve debugger port + debugger_port = 0 + + # Docker build args in format key = value or map format, ex.: "CL_IS_PROD_BUILD" = "false" + [nodesets.node_specs.node.docker_build_args] + + # Docker container resources + [nodesets.node_specs.node.resources] + # CPU shares, ex.: 2 + cpus = 0.0 + # Memory in MegaBytes, ex.:"200" + memory_mb = 0 + + # Docker container environment variables + [nodesets.node_specs.node.env_vars] + + # Chainlink node configuration output + [nodesets.node_specs.out] + # Whether to respect caching or not, if cache = true component won't be deployed again + use_cache = false + + # Chainlink node config output + [nodesets.node_specs.out.node] + # User name for basic login/password authorization in Chainlink node + api_auth_user = '' + # Password for basic login/password authorization in Chainlink node + api_auth_password = '' + # Node Docker contaner name + container_name = '' + # Node external API HTTP URL + url = '' + # Node internal API HTTP URL + internal_url = '' + # Node internal P2P URL + p2p_internal_url = '' + # Node internal IP + internal_ip = '' + + # PostgreSQL config output + [nodesets.node_specs.out.postgresql] + # PostgreSQL connection URL + url = '' + # Docker container name + container_name = '' + # PostgreSQL internal connection URL + internal_url = '' + # PostgreSQL internal connection URL to JobDistributor database + jd_url = '' + # PostgreSQL internal connection URL to JobDistributor database + jd_internal_url = '' + + # Nodeset config output + [nodesets.out] + # Whether to respect caching or not, if cache = true component won't be deployed again + use_cache = false + + # Nodeset shared database output (PostgreSQL) + [nodesets.out.db_out] + # PostgreSQL connection URL + url = '' + # Docker container name + container_name = '' + # PostgreSQL internal connection URL + internal_url = '' + # PostgreSQL internal connection URL to JobDistributor database + jd_url = '' + # PostgreSQL internal connection URL to JobDistributor database + jd_internal_url = '' + + # Chainlink node config outputs + [[nodesets.out.cl_nodes]] + # Whether to respect caching or not, if cache = true component won't be deployed again + use_cache = false + + # Chainlink node config output + [nodesets.out.cl_nodes.node] + # User name for basic login/password authorization in Chainlink node + api_auth_user = '' + # Password for basic login/password authorization in Chainlink node + api_auth_password = '' + # Node Docker contaner name + container_name = '' + # Node external API HTTP URL + url = '' + # Node internal API HTTP URL + internal_url = '' + # Node internal P2P URL + p2p_internal_url = '' + # Node internal IP + internal_ip = '' + + # PostgreSQL config output + [nodesets.out.cl_nodes.postgresql] + # PostgreSQL connection URL + url = '' + # Docker container name + container_name = '' + # PostgreSQL internal connection URL + internal_url = '' + # PostgreSQL internal connection URL to JobDistributor database + jd_url = '' + # PostgreSQL internal connection URL to JobDistributor database + jd_internal_url = '' diff --git a/framework/cmd/tomldoc/main.go b/book/tomldoc.go similarity index 100% rename from framework/cmd/tomldoc/main.go rename to book/tomldoc.go diff --git a/framework/cmd/tomldoc/toml-docs.toml b/framework/cmd/tomldoc/toml-docs.toml deleted file mode 100644 index 1a0cd65f8..000000000 --- a/framework/cmd/tomldoc/toml-docs.toml +++ /dev/null @@ -1,230 +0,0 @@ -# Fake HTTP server representing 3rd party dependencies -[fakes] - image = '' - port = 0 - - [fakes.out] - use_cache = false - base_url_host = '' - base_url_docker = '' - -# Various blockchains, see 'type' field comments -[[blockchains]] - # Type can be one of: anvil geth besu solana aptos tron sui ton canton, this struct describes common configuration we are using across all blockchains - type = '' - # Blockchain node image in format: $registry:$image, ex.: ghcr.io/foundry-rs/foundry:stable - image = '' - # Whether to pull image or not when creating Docker container - pull_image = false - # The port Docker container will expose - port = '' - # Docker container name - container_name = '' - # WebSocket port container will expose - port_ws = '' - # Blockchain chain ID - chain_id = '' - # Docker command parameters override, ex. for Anvil: ["-b", "1", "--mixed-mining"] - docker_cmd_params = [] - # Public key to mint when solana-test-validator starts - public_key = '' - # Solana's contracts directory - contracts_dir = '' - custom_ports = [] - faucet_port = '' - number_of_canton_validators = 0 - host_network_mode = false - certificates_path = '' - image_platform = '' - - # blockchain deployment output - [blockchains.out] - use_cache = false - type = '' - family = '' - container_name = '' - chain_id = '' - - [blockchains.out.network_specific_data] - [blockchains.out.network_specific_data.SuiAccount] - Alias = '' - Flag = 0 - KeyScheme = '' - Mnemonic = '' - PeerId = '' - PublicBase64Key = '' - SuiAddress = '' - - [blockchains.out.network_specific_data.CantonEndpoints] - ScanAPIURL = '' - RegistryAPIURL = '' - - [blockchains.out.network_specific_data.CantonEndpoints.SuperValidator] - JSONLedgerAPIURL = '' - GRPCLedgerAPIURL = '' - AdminAPIURL = '' - ValidatorAPIURL = '' - HTTPHealthCheckURL = '' - GRPCHealthCheckURL = '' - JWT = '' - - [[blockchains.out.network_specific_data.CantonEndpoints.Participants]] - JSONLedgerAPIURL = '' - GRPCLedgerAPIURL = '' - AdminAPIURL = '' - ValidatorAPIURL = '' - HTTPHealthCheckURL = '' - GRPCHealthCheckURL = '' - JWT = '' - - [[blockchains.out.nodes]] - ws_url = '' - http_url = '' - internal_ws_url = '' - internal_http_url = '' - - # Solana's programs, map of program name to program ID, there needs to be a matching .so file in contracts_dir - [blockchains.solana_programs] - - # Docker container resources - [blockchains.resources] - # CPU shares, ex.: 2 - cpus = 0.0 - # Memory in MegaBytes, ex.:"200" - memory_mb = 0 - - [blockchains.custom_env] - -# Chainlink Node Set including multiple Chainlink nodes forming a DON -[[nodesets]] - name = '' - nodes = 0 - http_port_range_start = 0 - p2p_port_range_start = 0 - dlv_port_range_start = 0 - override_mode = '' - no_dns = false - - [nodesets.db] - image = '' - port = 0 - name = '' - volume_name = '' - databases = 0 - jd_database = false - jd_sql_dump_path = '' - pull_image = false - - [nodesets.db.resources] - # CPU shares, ex.: 2 - cpus = 0.0 - # Memory in MegaBytes, ex.:"200" - memory_mb = 0 - - [nodesets.db.out] - url = '' - container_name = '' - internal_url = '' - jd_url = '' - jd_internal_url = '' - - [[nodesets.node_specs]] - no_dns = false - - [nodesets.node_specs.db] - image = '' - port = 0 - name = '' - volume_name = '' - databases = 0 - jd_database = false - jd_sql_dump_path = '' - pull_image = false - - [nodesets.node_specs.db.resources] - # CPU shares, ex.: 2 - cpus = 0.0 - # Memory in MegaBytes, ex.:"200" - memory_mb = 0 - - [nodesets.node_specs.db.out] - url = '' - container_name = '' - internal_url = '' - jd_url = '' - jd_internal_url = '' - - [nodesets.node_specs.node] - image = '' - name = '' - docker_file = '' - docker_ctx = '' - pull_image = false - capabilities = [] - capabilities_container_dir = '' - test_config_overrides = '' - user_config_overrides = '' - test_secrets_overrides = '' - user_secrets_overrides = '' - port = 0 - p2p_port = 0 - custom_ports = [] - debugger_port = 0 - - [nodesets.node_specs.node.docker_build_args] - - [nodesets.node_specs.node.resources] - # CPU shares, ex.: 2 - cpus = 0.0 - # Memory in MegaBytes, ex.:"200" - memory_mb = 0 - - [nodesets.node_specs.node.env_vars] - - [nodesets.node_specs.out] - use_cache = false - - [nodesets.node_specs.out.node] - api_auth_user = '' - api_auth_password = '' - container_name = '' - url = '' - internal_url = '' - p2p_internal_url = '' - internal_ip = '' - - [nodesets.node_specs.out.postgresql] - url = '' - container_name = '' - internal_url = '' - jd_url = '' - jd_internal_url = '' - - [nodesets.out] - use_cache = false - - [nodesets.out.db_out] - url = '' - container_name = '' - internal_url = '' - jd_url = '' - jd_internal_url = '' - - [[nodesets.out.cl_nodes]] - use_cache = false - - [nodesets.out.cl_nodes.node] - api_auth_user = '' - api_auth_password = '' - container_name = '' - url = '' - internal_url = '' - p2p_internal_url = '' - internal_ip = '' - - [nodesets.out.cl_nodes.postgresql] - url = '' - container_name = '' - internal_url = '' - jd_url = '' - jd_internal_url = '' diff --git a/framework/components/blockchain/blockchain.go b/framework/components/blockchain/blockchain.go index efd52d516..51c0377c2 100644 --- a/framework/components/blockchain/blockchain.go +++ b/framework/components/blockchain/blockchain.go @@ -57,47 +57,47 @@ type Input struct { // there needs to be a matching .so file in contracts_dir SolanaPrograms map[string]string `toml:"solana_programs" comment:"Solana's programs, map of program name to program ID, there needs to be a matching .so file in contracts_dir"` ContainerResources *framework.ContainerResources `toml:"resources" comment:"Docker container resources"` - CustomPorts []string `toml:"custom_ports"` + CustomPorts []string `toml:"custom_ports" comment:"Custom ports pairs in format $host_port_number:$docker_port_number"` // Sui specific: faucet port for funding accounts - FaucetPort string `toml:"faucet_port"` + FaucetPort string `toml:"faucet_port" comment:"Sui blockchain network faucet port"` // Canton specific - NumberOfCantonValidators int `toml:"number_of_canton_validators"` + NumberOfCantonValidators int `toml:"number_of_canton_validators" comment:"Number of Canton network validators"` // GAPv2 specific params - HostNetworkMode bool `toml:"host_network_mode"` - CertificatesPath string `toml:"certificates_path"` + HostNetworkMode bool `toml:"host_network_mode" comment:"GAPv2 specific paramter: host netowork mode, if 'true' will run environment in host network mode"` + CertificatesPath string `toml:"certificates_path" comment:"GAPv2 specific parameter: path to default Ubuntu's certificates"` // Optional params - ImagePlatform *string `toml:"image_platform"` + ImagePlatform *string `toml:"image_platform" comment:"Docker image platform, default is 'linux/amd64'"` // Custom environment variables for the container - CustomEnv map[string]string `toml:"custom_env"` + CustomEnv map[string]string `toml:"custom_env" comment:"Docker container environment variables in TOML format key = value"` } // Output is a blockchain network output, ChainID and one or more nodes that forms the network type Output struct { - UseCache bool `toml:"use_cache"` - Type string `toml:"type"` - Family string `toml:"family"` - ContainerName string `toml:"container_name"` - NetworkSpecificData *NetworkSpecificData `toml:"network_specific_data"` + UseCache bool `toml:"use_cache" comment:"Whether to respect caching or not, if cache = true component won't be deployed again"` + Type string `toml:"type" comment:"Type can be one of: anvil geth besu solana aptos tron sui ton canton, this struct describes common configuration we are using across all blockchains"` + Family string `toml:"family" comment:"Blockchain family, can be one of: evm solana aptos sui tron ton canton"` + ContainerName string `toml:"container_name" comment:"Blockchain Docker container name"` + NetworkSpecificData *NetworkSpecificData `toml:"network_specific_data" comment:"Blockchain network-specific data"` Container testcontainers.Container `toml:"-"` - ChainID string `toml:"chain_id"` - Nodes []*Node `toml:"nodes"` + ChainID string `toml:"chain_id" comment:"Chain ID"` + Nodes []*Node `toml:"nodes" comment:"Blockchain nodes info"` } type NetworkSpecificData struct { - SuiAccount *SuiWalletInfo - CantonEndpoints *CantonEndpoints + SuiAccount *SuiWalletInfo `toml:"sui_account" comment:"Sui network account info"` + CantonEndpoints *CantonEndpoints `toml:"canton_endpoints" comment:"Canton network endpoints info"` } // Node represents blockchain node output, URLs required for connection locally and inside docker network type Node struct { - ExternalWSUrl string `toml:"ws_url"` - ExternalHTTPUrl string `toml:"http_url"` - InternalWSUrl string `toml:"internal_ws_url"` - InternalHTTPUrl string `toml:"internal_http_url"` + ExternalWSUrl string `toml:"ws_url" comment:"External blockchain node WebSocket URL"` + ExternalHTTPUrl string `toml:"http_url" comment:"External blockchain node HTTP URL"` + InternalWSUrl string `toml:"internal_ws_url" comment:"Internal blockchain node WebSocket URL"` + InternalHTTPUrl string `toml:"internal_http_url" comment:"Internal blockchain node HTTP URL"` } func NewBlockchainNetwork(in *Input) (*Output, error) { diff --git a/framework/components/blockchain/canton.go b/framework/components/blockchain/canton.go index a0fd5ccd2..37256fdd4 100644 --- a/framework/components/blockchain/canton.go +++ b/framework/components/blockchain/canton.go @@ -12,30 +12,41 @@ import ( ) const ( + // DefaultCantonPort is a default Canton container port DefaultCantonPort = "8080" - TokenExpiry = time.Hour * 24 * 365 * 10 // 10 years + // TokenExpiry is JWT token expiry + TokenExpiry = time.Hour * 24 * 365 * 10 // 10 years ) type CantonEndpoints struct { - ScanAPIURL string // https://docs.sync.global/app_dev/scan_api/index.html - RegistryAPIURL string // https://docs.sync.global/app_dev/token_standard/index.html#api-references - - // The endpoints for the super validator - SuperValidator CantonParticipantEndpoints - // The endpoints for the participants, in order from participant1 to participantN - depending on the number of validators requested - Participants []CantonParticipantEndpoints + // ScanAPIURL https://docs.sync.global/app_dev/scan_api/index.html + ScanAPIURL string `toml:"scan_api_url" comment:"https://docs.sync.global/app_dev/scan_api/index.html"` + // RegistryAPIURL https://docs.sync.global/app_dev/token_standard/index.html#api-references + RegistryAPIURL string `toml:"registry_api_url" comment:"https://docs.sync.global/app_dev/token_standard/index.html#api-references"` + + // SuperValidator The endpoints for the super validator + SuperValidator CantonParticipantEndpoints `toml:"super_validator" comment:"Canton network super validator"` + // Participants The endpoints for the participants, in order from participant1 to participantN - depending on the number of validators requested + Participants []CantonParticipantEndpoints `toml:"participants" comment:"Canton participant endpoints"` } type CantonParticipantEndpoints struct { - JSONLedgerAPIURL string // https://docs.digitalasset.com/build/3.5/reference/json-api/json-api.html - GRPCLedgerAPIURL string // https://docs.digitalasset.com/build/3.5/reference/lapi-proto-docs.html - AdminAPIURL string // https://docs.digitalasset.com/operate/3.5/howtos/configure/apis/admin_api.html - ValidatorAPIURL string // https://docs.sync.global/app_dev/validator_api/index.html - - HTTPHealthCheckURL string // responds on GET /health - GRPCHealthCheckURL string // grpc.health.v1.Health/Check - - JWT string // JWT for this participant + // JSONLedgerAPIURL https://docs.digitalasset.com/build/3.5/reference/json-api/json-api.html + JSONLedgerAPIURL string `toml:"json_ledger_api_url" comment:"https://docs.digitalasset.com/build/3.5/reference/json-api/json-api.html"` + // GRPCLedgerAPIURL https://docs.digitalasset.com/build/3.5/reference/lapi-proto-docs.html + GRPCLedgerAPIURL string `toml:"grpc_ledger_api_url" comment:"https://docs.digitalasset.com/build/3.5/reference/lapi-proto-docs.html"` + // AdminAPIURL https://docs.digitalasset.com/operate/3.5/howtos/configure/apis/admin_api.html + AdminAPIURL string `toml:"admin_api_url" comment:"https://docs.digitalasset.com/operate/3.5/howtos/configure/apis/admin_api.html"` + // ValidatorAPIURL https://docs.sync.global/app_dev/validator_api/index.html + ValidatorAPIURL string `toml:"validator_api_url" comment:"https://docs.sync.global/app_dev/validator_api/index.html"` + + // HTTPHealthCheckURL responds on GET /health + HTTPHealthCheckURL string `toml:"http_health_check_url" comment:"HTTP health check endpoint, responds on GET /health"` + // GRPCHealthCheckURL grpc.health.v1.Health/Check + GRPCHealthCheckURL string `toml:"grpc_health_check_url" comment:"GRPC health check endpoint, responds to grpc.health.v1.Health/Check"` + + // JWT JSON Web Token for this participant + JWT string `toml:"jwt" comment:"JSON Web Token for this participant"` } // newCanton sets up a Canton blockchain network with the specified number of validators. diff --git a/framework/components/blockchain/sui.go b/framework/components/blockchain/sui.go index 5ec8fb13c..0bd8ca199 100644 --- a/framework/components/blockchain/sui.go +++ b/framework/components/blockchain/sui.go @@ -26,13 +26,13 @@ const ( // SuiWalletInfo info about Sui account/wallet type SuiWalletInfo struct { - Alias *string `json:"alias"` // Alias key name, usually "null" - Flag int `json:"flag"` // Flag is an integer - KeyScheme string `json:"keyScheme"` // Key scheme is a string - Mnemonic string `json:"mnemonic"` // Mnemonic is a string - PeerId string `json:"peerId"` // Peer ID is a string - PublicBase64Key string `json:"publicBase64Key"` // Public key in Base64 format - SuiAddress string `json:"suiAddress"` // Sui address is a 0x prefixed hex string + Alias *string `toml:"alias" json:"alias" comment:"Alias key name, usually null"` // Alias key name, usually "null" + Flag int `toml:"flag" json:"flag" comment:"-"` // Flag is an integer + KeyScheme string `toml:"key_scheme" json:"keyScheme" comment:"Sui key scheme"` // Key scheme is a string + Mnemonic string `toml:"mnemonic" json:"mnemonic" comment:"Sui key mnemonic"` // Mnemonic is a string + PeerId string `toml:"peer_id" json:"peerId" comment:"Sui key peer ID"` // Peer ID is a string + PublicBase64Key string `toml:"public_base64_key" json:"publicBase64Key" comment:"Sui key in base64 format"` // Public key in Base64 format + SuiAddress string `toml:"sui_address" json:"suiAddress" comment:"Sui key address"` // Sui address is a 0x prefixed hex string } // funds provided key using local faucet diff --git a/framework/components/clnode/clnode.go b/framework/components/clnode/clnode.go index 57e7bcab7..2b299bec2 100644 --- a/framework/components/clnode/clnode.go +++ b/framework/components/clnode/clnode.go @@ -33,56 +33,86 @@ const ( HomeVolumeName = "clnode-home" ) -var ( - once = &sync.Once{} -) +var once = &sync.Once{} // Input represents Chainlink node input type Input struct { - NoDNS bool `toml:"no_dns"` - DbInput *postgres.Input `toml:"db" validate:"required"` - Node *NodeInput `toml:"node" validate:"required"` - Out *Output `toml:"out"` + // NoDNS whether to allow DNS in Docker containers or not, useful for isolating containers from network if set to 'false' + NoDNS bool `toml:"no_dns" comment:"whether to allow DNS in Docker containers or not, useful for isolating containers from network if set to 'false'"` + // DbInput PostgreSQL database configuration + DbInput *postgres.Input `toml:"db" validate:"required" comment:"PostgreSQL database configuration"` + // Node Chainlink node configuration + Node *NodeInput `toml:"node" validate:"required" comment:"Chainlink node configuration"` + // Out Chainlink node configuration output + Out *Output `toml:"out" comment:"Chainlink node configuration output"` } // NodeInput is CL nod container inputs type NodeInput struct { - Image string `toml:"image" validate:"required"` - Name string `toml:"name"` - DockerFilePath string `toml:"docker_file"` - DockerContext string `toml:"docker_ctx"` - DockerBuildArgs map[string]string `toml:"docker_build_args"` - PullImage bool `toml:"pull_image"` - CapabilitiesBinaryPaths []string `toml:"capabilities"` - CapabilityContainerDir string `toml:"capabilities_container_dir"` - TestConfigOverrides string `toml:"test_config_overrides"` - UserConfigOverrides string `toml:"user_config_overrides"` - TestSecretsOverrides string `toml:"test_secrets_overrides"` - UserSecretsOverrides string `toml:"user_secrets_overrides"` - HTTPPort int `toml:"port"` - P2PPort int `toml:"p2p_port"` - CustomPorts []string `toml:"custom_ports"` - DebuggerPort int `toml:"debugger_port"` - ContainerResources *framework.ContainerResources `toml:"resources"` - EnvVars map[string]string `toml:"env_vars"` + // Image Chainlink node Docker image in format $registry:$tag + Image string `toml:"image" validate:"required" comment:"Chainlink node Docker image in format $registry:$tag"` + // Name Chainlink node Docker container name + Name string `toml:"name" comment:"Chainlink node Docker container name"` + // DockerFilePath Docker file path to rebuild, relative to 'docker_ctx' field path + DockerFilePath string `toml:"docker_file" comment:"Docker file path to rebuild, relative to 'docker_ctx' field path"` + // DockerContext Docker build context path + DockerContext string `toml:"docker_ctx" comment:"Docker build context path"` + // DockerBuildArgs Docker build args + DockerBuildArgs map[string]string `toml:"docker_build_args" comment:"Docker build args in format key = value or map format, ex.: \"CL_IS_PROD_BUILD\" = \"false\" "` + // PullImage whether to pull Docker image or not + PullImage bool `toml:"pull_image" comment:"Whether to pull Docker image or not"` + // CapabilitiesBinaryPaths Chainlink CRE capabilities paths for WASM binaries + CapabilitiesBinaryPaths []string `toml:"capabilities" comment:"Chainlink CRE capabilities paths for WASM binaries"` + // CapabilityContainerDir path to capabilities inside Docker container (capabilities are copied inside container from local path) + CapabilityContainerDir string `toml:"capabilities_container_dir" comment:"path to capabilities inside Docker container (capabilities are copied inside container from local path)"` + // TestConfigOverrides node config overrides field for programmatic usage in tests + TestConfigOverrides string `toml:"test_config_overrides" comment:"node config overrides field for programmatic usage in tests"` + // UserConfigOverrides node config overrides field for manual overrides from env.toml configs + UserConfigOverrides string `toml:"user_config_overrides" comment:"node config overrides field for manual overrides from env.toml configs"` + // TestSecretsOverrides node secrets config overrides field for programmatic usage in tests + TestSecretsOverrides string `toml:"test_secrets_overrides" comment:"node secrets config overrides field for programmatic usage in tests"` + // UserSecretsOverrides node secrets config overrides field for manual overrides from env.toml configs + UserSecretsOverrides string `toml:"user_secrets_overrides" comment:"node secrets config overrides field for manual overrides from env.toml configs"` + // HTTPPort Chainlink node API HTTP port + HTTPPort int `toml:"port" comment:"Chainlink node API HTTP port"` + // P2PPort Chainlink node P2P port + P2PPort int `toml:"p2p_port" comment:"Chainlink node P2P port"` + // CustomPorts Custom ports pairs in format $host_port_number:$docker_port_number + CustomPorts []string `toml:"custom_ports" comment:"Custom ports pairs in format $host_port_number:$docker_port_number"` + // DebuggerPort Delve debugger port + DebuggerPort int `toml:"debugger_port" comment:"Delve debugger port"` + // ContainerResources Docker container resources + ContainerResources *framework.ContainerResources `toml:"resources" comment:"Docker container resources"` + // EnvVars Docker container environment variables + EnvVars map[string]string `toml:"env_vars" comment:"Docker container environment variables"` } // Output represents Chainlink node output, nodes and databases connection URLs type Output struct { - UseCache bool `toml:"use_cache"` - Node *NodeOut `toml:"node"` - PostgreSQL *postgres.Output `toml:"postgresql"` + // UseCache Whether to respect caching or not, if cache = true component won't be deployed again + UseCache bool `toml:"use_cache" comment:"Whether to respect caching or not, if cache = true component won't be deployed again"` + // Node Chainlink node config output + Node *NodeOut `toml:"node" comment:"Chainlink node config output"` + // PostgreSQL PostgreSQL config output + PostgreSQL *postgres.Output `toml:"postgresql" comment:"PostgreSQL config output"` } // NodeOut is CL node container output, URLs to connect type NodeOut struct { - APIAuthUser string `toml:"api_auth_user"` - APIAuthPassword string `toml:"api_auth_password"` - ContainerName string `toml:"container_name"` - ExternalURL string `toml:"url"` - InternalURL string `toml:"internal_url"` - InternalP2PUrl string `toml:"p2p_internal_url"` - InternalIP string `toml:"internal_ip"` + // APIAuthUser user name for basic login/password authorization in Chainlink node + APIAuthUser string `toml:"api_auth_user" comment:"User name for basic login/password authorization in Chainlink node"` + // APIAuthPassword password for basic login/password authorization in Chainlink node + APIAuthPassword string `toml:"api_auth_password" comment:"Password for basic login/password authorization in Chainlink node"` + // ContainerName node Docker contaienr name + ContainerName string `toml:"container_name" comment:"Node Docker contaner name"` + // ExternalURL node external API HTTP URL + ExternalURL string `toml:"url" comment:"Node external API HTTP URL"` + // InternalURL node internal API HTTP URL + InternalURL string `toml:"internal_url" comment:"Node internal API HTTP URL"` + // InternalP2PUrl node internal P2P URL + InternalP2PUrl string `toml:"p2p_internal_url" comment:"Node internal P2P URL"` + // InternalIP node internal IP + InternalIP string `toml:"internal_ip" comment:"Node internal IP"` } // NewNodeWithDB create a new Chainlink node with some image:tag and one or several configs @@ -293,42 +323,42 @@ func newNode(ctx context.Context, in *Input, pgOut *postgres.Output) (*NodeOut, { HostFilePath: cfgPath.Name(), ContainerFilePath: "/config/config", - FileMode: 0644, + FileMode: 0o644, }, { HostFilePath: secretsPath.Name(), ContainerFilePath: "/config/secrets", - FileMode: 0644, + FileMode: 0o644, }, { HostFilePath: overridesFile.Name(), ContainerFilePath: "/config/overrides", - FileMode: 0644, + FileMode: 0o644, }, { HostFilePath: userOverridesFile.Name(), ContainerFilePath: "/config/user-overrides", - FileMode: 0644, + FileMode: 0o644, }, { HostFilePath: secretsOverridesFile.Name(), ContainerFilePath: "/config/secrets-overrides", - FileMode: 0644, + FileMode: 0o644, }, { HostFilePath: userSecretsOverridesFile.Name(), ContainerFilePath: "/config/user-secrets-overrides", - FileMode: 0644, + FileMode: 0o644, }, { HostFilePath: passwordPath.Name(), ContainerFilePath: "/config/node_password", - FileMode: 0644, + FileMode: 0o644, }, { HostFilePath: apiCredentialsPath.Name(), ContainerFilePath: "/config/apicredentials", - FileMode: 0644, + FileMode: 0o644, }, } if in.Node.CapabilityContainerDir == "" { @@ -340,7 +370,7 @@ func newNode(ctx context.Context, in *Input, pgOut *postgres.Output) (*NodeOut, files = append(files, tc.ContainerFile{ HostFilePath: cp, ContainerFilePath: filepath.Join(in.Node.CapabilityContainerDir, cpPath), - FileMode: 0777, + FileMode: 0o777, }) } req.Files = append(req.Files, files...) diff --git a/framework/components/fake/fake.go b/framework/components/fake/fake.go index f8b55b777..63030bc04 100644 --- a/framework/components/fake/fake.go +++ b/framework/components/fake/fake.go @@ -15,15 +15,15 @@ const ( ) type Input struct { - Image string `toml:"image"` - Port int `toml:"port" validate:"required"` - Out *Output `toml:"out"` + Image string `toml:"image" comment:"Fake service image, usually can be found in our ECR with $project-fakes name"` + Port int `toml:"port" validate:"required" comment:"The port which Docker container is exposing"` + Out *Output `toml:"out" comment:"Fakes service config output"` } type Output struct { - UseCache bool `toml:"use_cache"` - BaseURLHost string `toml:"base_url_host"` - BaseURLDocker string `toml:"base_url_docker"` + UseCache bool `toml:"use_cache" comment:"Whether to respect caching or not, if cache = true component won't be deployed again"` + BaseURLHost string `toml:"base_url_host" comment:"Base URL which can be used when running locally"` + BaseURLDocker string `toml:"base_url_docker" comment:"Base URL to reach fakes service from other Docker containers"` } var ( diff --git a/framework/components/postgres/postgres.go b/framework/components/postgres/postgres.go index 5cf8cbe97..6b60523d8 100644 --- a/framework/components/postgres/postgres.go +++ b/framework/components/postgres/postgres.go @@ -27,24 +27,39 @@ const ( ) type Input struct { - Image string `toml:"image" validate:"required"` - Port int `toml:"port"` - Name string `toml:"name"` - VolumeName string `toml:"volume_name"` - Databases int `toml:"databases"` - JDDatabase bool `toml:"jd_database"` - JDSQLDumpPath string `toml:"jd_sql_dump_path"` - PullImage bool `toml:"pull_image"` - ContainerResources *framework.ContainerResources `toml:"resources"` - Out *Output `toml:"out"` + // Image PostgreSQL Docker image in format: $registry:$tag + Image string `toml:"image" validate:"required" comment:"PostgreSQL Docker image in format: $registry:$tag"` + // Port PostgreSQL connection port + Port int `toml:"port" comment:"PostgreSQL connection port"` + // Name PostgreSQL container name + Name string `toml:"name" comment:"PostgreSQL container name"` + // VolumeName PostgreSQL Docker volume name + VolumeName string `toml:"volume_name" comment:"PostgreSQL docker volume name"` + // Databases number of pre-created databases for Chainlink nodes + Databases int `toml:"databases" comment:"Number of pre-created databases for Chainlink nodes"` + // JDDatabase whether to create JobDistributor database or not + JDDatabase bool `toml:"jd_database" comment:"Whether to create JobDistributor database or not"` + // JDSQLDumpPath JobDistributor SQL dump path to load + JDSQLDumpPath string `toml:"jd_sql_dump_path" comment:"JobDistributor database dump path to load"` + // PullImage whether to pull PostgreSQL image or not + PullImage bool `toml:"pull_image" comment:"Whether to pull PostgreSQL image or not"` + // ContainerResources Docker container resources + ContainerResources *framework.ContainerResources `toml:"resources" comment:"Docker container resources"` + // Out PostgreSQL config output + Out *Output `toml:"out" comment:"PostgreSQL config output"` } type Output struct { - Url string `toml:"url"` - ContainerName string `toml:"container_name"` - InternalURL string `toml:"internal_url"` - JDUrl string `toml:"jd_url"` - JDInternalURL string `toml:"jd_internal_url"` + // URL PostgreSQL connection URL + Url string `toml:"url" comment:"PostgreSQL connection URL"` + // ContainerName PostgreSQL Docker container name + ContainerName string `toml:"container_name" comment:"Docker container name"` + // InternalURL PostgreSQL internal connection URL + InternalURL string `toml:"internal_url" comment:"PostgreSQL internal connection URL"` + // JDUrl PostgreSQL external connection URL to JobDistributor database + JDUrl string `toml:"jd_url" comment:"PostgreSQL internal connection URL to JobDistributor database"` + // JDInternalURL PostgreSQL internal connection URL to JobDistributor database + JDInternalURL string `toml:"jd_internal_url" comment:"PostgreSQL internal connection URL to JobDistributor database"` } func NewPostgreSQL(in *Input) (*Output, error) { @@ -122,7 +137,7 @@ func NewWithContext(ctx context.Context, in *Input) (*Output, error) { { HostFilePath: initFile.Name(), ContainerFilePath: "/docker-entrypoint-initdb.d/init.sql", - FileMode: 0644, + FileMode: 0o644, }, }, Mounts: testcontainers.ContainerMounts{ @@ -133,8 +148,10 @@ func NewWithContext(ctx context.Context, in *Input) (*Output, error) { Target: "/var/lib/postgresql/data", }, }, - WaitingFor: tcwait.ForExec([]string{"psql", "-h", "127.0.0.1", - "-U", User, "-p", Port, "-c", "select", "1", "-d", Database}). + WaitingFor: tcwait.ForExec([]string{ + "psql", "-h", "127.0.0.1", + "-U", User, "-p", Port, "-c", "select", "1", "-d", Database, + }). WithStartupTimeout(3 * time.Minute). WithPollInterval(200 * time.Millisecond), } diff --git a/framework/components/simple_node_set/node_set.go b/framework/components/simple_node_set/node_set.go index 38f594700..4eacc4980 100644 --- a/framework/components/simple_node_set/node_set.go +++ b/framework/components/simple_node_set/node_set.go @@ -23,23 +23,26 @@ const ( // Input is a node set configuration input type Input struct { - Name string `toml:"name" validate:"required"` - Nodes int `toml:"nodes" validate:"required"` - HTTPPortRangeStart int `toml:"http_port_range_start"` - P2PPortRangeStart int `toml:"p2p_port_range_start"` - DlvPortRangeStart int `toml:"dlv_port_range_start"` - OverrideMode string `toml:"override_mode" validate:"required,oneof=all each"` - DbInput *postgres.Input `toml:"db" validate:"required"` - NodeSpecs []*clnode.Input `toml:"node_specs" validate:"required"` - NoDNS bool `toml:"no_dns"` - Out *Output `toml:"out"` + Name string `toml:"name" validate:"required" comment:"Node set name, ex.:'don-1', Docker containers will be prefixed with this name so tests can distinguish one DON from another"` + Nodes int `toml:"nodes" validate:"required" comment:"Number of nodes in node set"` + HTTPPortRangeStart int `toml:"http_port_range_start" comment:"HTTP ports range starting with port X and increasing by 1"` + P2PPortRangeStart int `toml:"p2p_port_range_start" comment:"P2P ports range starting with port X and increasing by 1"` + DlvPortRangeStart int `toml:"dlv_port_range_start" comment:"Delve debugger ports range starting with port X and increasing by 1"` + OverrideMode string `toml:"override_mode" validate:"required,oneof=all each" comment:"Override mode, applicable only to 'localcre'. Changes how config overrides to TOML nodes apply"` + DbInput *postgres.Input `toml:"db" validate:"required" comment:"Shared node set data base input for PostgreSQL"` + NodeSpecs []*clnode.Input `toml:"node_specs" validate:"required" comment:"Chainlink node TOML configurations"` + NoDNS bool `toml:"no_dns" comment:"Turn DNS on, helpful to isolate container from the internet"` + Out *Output `toml:"out" comment:"Nodeset config output"` } // Output is a node set configuration output, used for caching or external components type Output struct { - UseCache bool `toml:"use_cache"` - DBOut *postgres.Output `toml:"db_out"` - CLNodes []*clnode.Output `toml:"cl_nodes"` + // UseCache Whether to respect caching or not, if cache = true component won't be deployed again + UseCache bool `toml:"use_cache" comment:"Whether to respect caching or not, if cache = true component won't be deployed again"` + // DBOut Nodeset shared database output (PostgreSQL) + DBOut *postgres.Output `toml:"db_out" comment:"Nodeset shared database output (PostgreSQL)"` + // CLNodes Chainlink node config outputs + CLNodes []*clnode.Output `toml:"cl_nodes" comment:"Chainlink node config outputs"` } // NewSharedDBNodeSet create a new node set with a shared database instance From 996b964a8eb2b7e7e0296f95be117431e708209b Mon Sep 17 00:00:00 2001 From: skudasov Date: Sat, 24 Jan 2026 09:20:30 -0500 Subject: [PATCH 3/5] simplify --- book/Makefile | 2 +- .../developer_environment/blockchains.toml | 130 ++++++++++ .../framework/developer_environment/fake.toml | 14 ++ .../developer_environment/nodesets.toml | 232 ++++++++++++++++++ .../framework/developer_environment/toml.md | 22 +- book/tomldoc.go | 60 ++++- 6 files changed, 446 insertions(+), 14 deletions(-) create mode 100644 book/src/framework/developer_environment/blockchains.toml create mode 100644 book/src/framework/developer_environment/fake.toml create mode 100644 book/src/framework/developer_environment/nodesets.toml diff --git a/book/Makefile b/book/Makefile index bb45be69d..3e1935bd4 100644 --- a/book/Makefile +++ b/book/Makefile @@ -3,4 +3,4 @@ run: mdbook serve -p 9999 toml: - go run tomldoc.go -output src/toml.toml + go run tomldoc.go diff --git a/book/src/framework/developer_environment/blockchains.toml b/book/src/framework/developer_environment/blockchains.toml new file mode 100644 index 000000000..3bf8a845f --- /dev/null +++ b/book/src/framework/developer_environment/blockchains.toml @@ -0,0 +1,130 @@ +[[blockchains]] + # Type can be one of: anvil geth besu solana aptos tron sui ton canton, this struct describes common configuration we are using across all blockchains + type = '' + # Blockchain node image in format: $registry:$image, ex.: ghcr.io/foundry-rs/foundry:stable + image = '' + # Whether to pull image or not when creating Docker container + pull_image = false + # The port Docker container will expose + port = '' + # Docker container name + container_name = '' + # WebSocket port container will expose + port_ws = '' + # Blockchain chain ID + chain_id = '' + # Docker command parameters override, ex. for Anvil: ["-b", "1", "--mixed-mining"] + docker_cmd_params = [] + # Public key to mint when solana-test-validator starts + public_key = '' + # Solana's contracts directory + contracts_dir = '' + # Custom ports pairs in format $host_port_number:$docker_port_number + custom_ports = [] + # Sui blockchain network faucet port + faucet_port = '' + # Number of Canton network validators + number_of_canton_validators = 0 + # GAPv2 specific paramter: host netowork mode, if 'true' will run environment in host network mode + host_network_mode = false + # GAPv2 specific parameter: path to default Ubuntu's certificates + certificates_path = '' + # Docker image platform, default is 'linux/amd64' + image_platform = '' + + # blockchain deployment output + [blockchains.out] + # Whether to respect caching or not, if cache = true component won't be deployed again + use_cache = false + # Type can be one of: anvil geth besu solana aptos tron sui ton canton, this struct describes common configuration we are using across all blockchains + type = '' + # Blockchain family, can be one of: evm solana aptos sui tron ton canton + family = '' + # Blockchain Docker container name + container_name = '' + # Chain ID + chain_id = '' + + # Blockchain network-specific data + [blockchains.out.network_specific_data] + # Sui network account info + [blockchains.out.network_specific_data.sui_account] + # Alias key name, usually null + alias = '' + # - + flag = 0 + # Sui key scheme + key_scheme = '' + # Sui key mnemonic + mnemonic = '' + # Sui key peer ID + peer_id = '' + # Sui key in base64 format + public_base64_key = '' + # Sui key address + sui_address = '' + + # Canton network endpoints info + [blockchains.out.network_specific_data.canton_endpoints] + # https://docs.sync.global/app_dev/scan_api/index.html + scan_api_url = '' + # https://docs.sync.global/app_dev/token_standard/index.html#api-references + registry_api_url = '' + + # Canton network super validator + [blockchains.out.network_specific_data.canton_endpoints.super_validator] + # https://docs.digitalasset.com/build/3.5/reference/json-api/json-api.html + json_ledger_api_url = '' + # https://docs.digitalasset.com/build/3.5/reference/lapi-proto-docs.html + grpc_ledger_api_url = '' + # https://docs.digitalasset.com/operate/3.5/howtos/configure/apis/admin_api.html + admin_api_url = '' + # https://docs.sync.global/app_dev/validator_api/index.html + validator_api_url = '' + # HTTP health check endpoint, responds on GET /health + http_health_check_url = '' + # GRPC health check endpoint, responds to grpc.health.v1.Health/Check + grpc_health_check_url = '' + # JSON Web Token for this participant + jwt = '' + + # Canton participant endpoints + [[blockchains.out.network_specific_data.canton_endpoints.participants]] + # https://docs.digitalasset.com/build/3.5/reference/json-api/json-api.html + json_ledger_api_url = '' + # https://docs.digitalasset.com/build/3.5/reference/lapi-proto-docs.html + grpc_ledger_api_url = '' + # https://docs.digitalasset.com/operate/3.5/howtos/configure/apis/admin_api.html + admin_api_url = '' + # https://docs.sync.global/app_dev/validator_api/index.html + validator_api_url = '' + # HTTP health check endpoint, responds on GET /health + http_health_check_url = '' + # GRPC health check endpoint, responds to grpc.health.v1.Health/Check + grpc_health_check_url = '' + # JSON Web Token for this participant + jwt = '' + + # Blockchain nodes info + [[blockchains.out.nodes]] + # External blockchain node WebSocket URL + ws_url = '' + # External blockchain node HTTP URL + http_url = '' + # Internal blockchain node WebSocket URL + internal_ws_url = '' + # Internal blockchain node HTTP URL + internal_http_url = '' + + # Solana's programs, map of program name to program ID, there needs to be a matching .so file in contracts_dir + [blockchains.solana_programs] + + # Docker container resources + [blockchains.resources] + # CPU shares, ex.: 2 + cpus = 0.0 + # Memory in MegaBytes, ex.:"200" + memory_mb = 0 + + # Docker container environment variables in TOML format key = value + [blockchains.custom_env] diff --git a/book/src/framework/developer_environment/fake.toml b/book/src/framework/developer_environment/fake.toml new file mode 100644 index 000000000..76d6a13cc --- /dev/null +++ b/book/src/framework/developer_environment/fake.toml @@ -0,0 +1,14 @@ +[fakes] + # Fake service image, usually can be found in our ECR with $project-fakes name + image = '' + # The port which Docker container is exposing + port = 0 + + # Fakes service config output + [fakes.out] + # Whether to respect caching or not, if cache = true component won't be deployed again + use_cache = false + # Base URL which can be used when running locally + base_url_host = '' + # Base URL to reach fakes service from other Docker containers + base_url_docker = '' diff --git a/book/src/framework/developer_environment/nodesets.toml b/book/src/framework/developer_environment/nodesets.toml new file mode 100644 index 000000000..eed314365 --- /dev/null +++ b/book/src/framework/developer_environment/nodesets.toml @@ -0,0 +1,232 @@ +[[nodesets]] + # Node set name, ex.:'don-1', Docker containers will be prefixed with this name so tests can distinguish one DON from another + name = '' + # Number of nodes in node set + nodes = 0 + # HTTP ports range starting with port X and increasing by 1 + http_port_range_start = 0 + # P2P ports range starting with port X and increasing by 1 + p2p_port_range_start = 0 + # Delve debugger ports range starting with port X and increasing by 1 + dlv_port_range_start = 0 + # Override mode, applicable only to 'localcre'. Changes how config overrides to TOML nodes apply + override_mode = '' + # Turn DNS on, helpful to isolate container from the internet + no_dns = false + + # Shared node set data base input for PostgreSQL + [nodesets.db] + # PostgreSQL Docker image in format: $registry:$tag + image = '' + # PostgreSQL connection port + port = 0 + # PostgreSQL container name + name = '' + # PostgreSQL docker volume name + volume_name = '' + # Number of pre-created databases for Chainlink nodes + databases = 0 + # Whether to create JobDistributor database or not + jd_database = false + # JobDistributor database dump path to load + jd_sql_dump_path = '' + # Whether to pull PostgreSQL image or not + pull_image = false + + # Docker container resources + [nodesets.db.resources] + # CPU shares, ex.: 2 + cpus = 0.0 + # Memory in MegaBytes, ex.:"200" + memory_mb = 0 + + # PostgreSQL config output + [nodesets.db.out] + # PostgreSQL connection URL + url = '' + # Docker container name + container_name = '' + # PostgreSQL internal connection URL + internal_url = '' + # PostgreSQL internal connection URL to JobDistributor database + jd_url = '' + # PostgreSQL internal connection URL to JobDistributor database + jd_internal_url = '' + + # Chainlink node TOML configurations + [[nodesets.node_specs]] + # whether to allow DNS in Docker containers or not, useful for isolating containers from network if set to 'false' + no_dns = false + + # PostgreSQL database configuration + [nodesets.node_specs.db] + # PostgreSQL Docker image in format: $registry:$tag + image = '' + # PostgreSQL connection port + port = 0 + # PostgreSQL container name + name = '' + # PostgreSQL docker volume name + volume_name = '' + # Number of pre-created databases for Chainlink nodes + databases = 0 + # Whether to create JobDistributor database or not + jd_database = false + # JobDistributor database dump path to load + jd_sql_dump_path = '' + # Whether to pull PostgreSQL image or not + pull_image = false + + # Docker container resources + [nodesets.node_specs.db.resources] + # CPU shares, ex.: 2 + cpus = 0.0 + # Memory in MegaBytes, ex.:"200" + memory_mb = 0 + + # PostgreSQL config output + [nodesets.node_specs.db.out] + # PostgreSQL connection URL + url = '' + # Docker container name + container_name = '' + # PostgreSQL internal connection URL + internal_url = '' + # PostgreSQL internal connection URL to JobDistributor database + jd_url = '' + # PostgreSQL internal connection URL to JobDistributor database + jd_internal_url = '' + + # Chainlink node configuration + [nodesets.node_specs.node] + # Chainlink node Docker image in format $registry:$tag + image = '' + # Chainlink node Docker container name + name = '' + # Docker file path to rebuild, relative to 'docker_ctx' field path + docker_file = '' + # Docker build context path + docker_ctx = '' + # Whether to pull Docker image or not + pull_image = false + # Chainlink CRE capabilities paths for WASM binaries + capabilities = [] + # path to capabilities inside Docker container (capabilities are copied inside container from local path) + capabilities_container_dir = '' + # node config overrides field for programmatic usage in tests + test_config_overrides = '' + # node config overrides field for manual overrides from env.toml configs + user_config_overrides = '' + # node secrets config overrides field for programmatic usage in tests + test_secrets_overrides = '' + # node secrets config overrides field for manual overrides from env.toml configs + user_secrets_overrides = '' + # Chainlink node API HTTP port + port = 0 + # Chainlink node P2P port + p2p_port = 0 + # Custom ports pairs in format $host_port_number:$docker_port_number + custom_ports = [] + # Delve debugger port + debugger_port = 0 + + # Docker build args in format key = value or map format, ex.: "CL_IS_PROD_BUILD" = "false" + [nodesets.node_specs.node.docker_build_args] + + # Docker container resources + [nodesets.node_specs.node.resources] + # CPU shares, ex.: 2 + cpus = 0.0 + # Memory in MegaBytes, ex.:"200" + memory_mb = 0 + + # Docker container environment variables + [nodesets.node_specs.node.env_vars] + + # Chainlink node configuration output + [nodesets.node_specs.out] + # Whether to respect caching or not, if cache = true component won't be deployed again + use_cache = false + + # Chainlink node config output + [nodesets.node_specs.out.node] + # User name for basic login/password authorization in Chainlink node + api_auth_user = '' + # Password for basic login/password authorization in Chainlink node + api_auth_password = '' + # Node Docker contaner name + container_name = '' + # Node external API HTTP URL + url = '' + # Node internal API HTTP URL + internal_url = '' + # Node internal P2P URL + p2p_internal_url = '' + # Node internal IP + internal_ip = '' + + # PostgreSQL config output + [nodesets.node_specs.out.postgresql] + # PostgreSQL connection URL + url = '' + # Docker container name + container_name = '' + # PostgreSQL internal connection URL + internal_url = '' + # PostgreSQL internal connection URL to JobDistributor database + jd_url = '' + # PostgreSQL internal connection URL to JobDistributor database + jd_internal_url = '' + + # Nodeset config output + [nodesets.out] + # Whether to respect caching or not, if cache = true component won't be deployed again + use_cache = false + + # Nodeset shared database output (PostgreSQL) + [nodesets.out.db_out] + # PostgreSQL connection URL + url = '' + # Docker container name + container_name = '' + # PostgreSQL internal connection URL + internal_url = '' + # PostgreSQL internal connection URL to JobDistributor database + jd_url = '' + # PostgreSQL internal connection URL to JobDistributor database + jd_internal_url = '' + + # Chainlink node config outputs + [[nodesets.out.cl_nodes]] + # Whether to respect caching or not, if cache = true component won't be deployed again + use_cache = false + + # Chainlink node config output + [nodesets.out.cl_nodes.node] + # User name for basic login/password authorization in Chainlink node + api_auth_user = '' + # Password for basic login/password authorization in Chainlink node + api_auth_password = '' + # Node Docker contaner name + container_name = '' + # Node external API HTTP URL + url = '' + # Node internal API HTTP URL + internal_url = '' + # Node internal P2P URL + p2p_internal_url = '' + # Node internal IP + internal_ip = '' + + # PostgreSQL config output + [nodesets.out.cl_nodes.postgresql] + # PostgreSQL connection URL + url = '' + # Docker container name + container_name = '' + # PostgreSQL internal connection URL + internal_url = '' + # PostgreSQL internal connection URL to JobDistributor database + jd_url = '' + # PostgreSQL internal connection URL to JobDistributor database + jd_internal_url = '' diff --git a/book/src/framework/developer_environment/toml.md b/book/src/framework/developer_environment/toml.md index 8859dd86b..0a2d81224 100644 --- a/book/src/framework/developer_environment/toml.md +++ b/book/src/framework/developer_environment/toml.md @@ -6,6 +6,26 @@ Here is full specification for what can be specificed in `env.toml` for devenv. `.out` fields are useful in case you want to use remote component, or integrate in other language than `Go`, otherwise can be ignored. +## Fakes + +Fake HTTP service with recording capabilities. + +```toml +{{#include fake.toml}} +``` + +## Blockchains + +Various types of blockchain nodes. + +```toml +{{#include blockchains.toml}} +``` + +## Node Set + +Chainlink node set forming a Decentralized Oracle Network. + ```toml -{{#include ../../toml.toml}} +{{#include nodesets.toml}} ``` diff --git a/book/tomldoc.go b/book/tomldoc.go index 70c355b93..8a05500ec 100644 --- a/book/tomldoc.go +++ b/book/tomldoc.go @@ -1,10 +1,11 @@ package main import ( - "flag" "log" "os" + "path/filepath" "reflect" + "strings" toml "github.com/pelletier/go-toml/v2" "github.com/smartcontractkit/chainlink-testing-framework/framework/components/blockchain" @@ -23,6 +24,20 @@ type AllStructDocs struct { NodeSets []*simple_node_set.Input `toml:"nodesets" comment:"Chainlink Node Set including multiple Chainlink nodes forming a DON"` } +func callDefaultIfExists(obj any) { + v := reflect.ValueOf(obj) + if v.Kind() == reflect.Ptr && !v.IsNil() { + typ := v.Type() + for i := 0; i < typ.NumMethod(); i++ { + method := typ.Method(i) + if strings.HasPrefix(method.Name, "Default") { + v.Method(i).Call(nil) + return + } + } + } +} + // initializeAny initializes any object so we can call Unmarshal method for all the fields func initializeAny(obj any) { v := reflect.ValueOf(obj).Elem() @@ -30,6 +45,8 @@ func initializeAny(obj any) { if v.Kind() != reflect.Struct { return } + // Call Default() on the current struct if it exists + callDefaultIfExists(obj) for i := 0; i < v.NumField(); i++ { field := v.Field(i) fieldType := v.Type().Field(i) @@ -97,25 +114,44 @@ func initializeAny(obj any) { } } -func main() { - outputFile := flag.String("output", "toml-docs.toml", "Output file to write all the struct examples to") - flag.Parse() - f, err := os.Create(*outputFile) +func encodeAndWrite(outputFilePath string, obj any) { + f, err := os.Create(outputFilePath) if err != nil { log.Fatalf("Error creating file: %v", err) } defer f.Close() - encoder := toml.NewEncoder(f) // this also writes "comment" lines from fields as # comment on top of each field encoder.SetIndentTables(true) - - // initialize all the framework structs - all := &AllStructDocs{} - initializeAny(all) - // encode and write examples - if err := encoder.Encode(&all); err != nil { + if err := encoder.Encode(obj); err != nil { log.Fatalf("Error encoding to file: %v", err) } } + +func main() { + bookFilePath := filepath.Join("src", "framework", "developer_environment") + + // can be generalized but we want a nice page with headers for each component + // components rarely change, fields do + // top-level TOML tags are set how they are most commonly used, + // as slices, if we can deploy more than a single component + + f := struct { + Fakes *fake.Input `toml:"fakes"` + }{} + initializeAny(&f) + encodeAndWrite(filepath.Join(bookFilePath, "fake.toml"), &f) + + b := struct { + Blockchains []*blockchain.Input `toml:"blockchains"` + }{} + initializeAny(&b) + encodeAndWrite(filepath.Join(bookFilePath, "blockchains.toml"), &b) + + ns := struct { + NodeSets []*simple_node_set.Input `toml:"nodesets"` + }{} + initializeAny(&ns) + encodeAndWrite(filepath.Join(bookFilePath, "nodesets.toml"), &ns) +} From 568ca148b54ec294ee99f3669f60a4d673b3bcf7 Mon Sep 17 00:00:00 2001 From: skudasov Date: Sat, 24 Jan 2026 09:21:55 -0500 Subject: [PATCH 4/5] try generate docs --- .github/workflows/docs.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index c9a206a35..782b90229 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -3,10 +3,10 @@ name: GH Pages Deploy (Docs, mdbook) on: push: - branches: - - main - tags: - - '*' + # branches: + # - main + # tags: + # - '*' jobs: build-deploy: From 31aae8f8d9276957759475e6705559c05eb62fad Mon Sep 17 00:00:00 2001 From: skudasov Date: Sat, 24 Jan 2026 09:34:02 -0500 Subject: [PATCH 5/5] rollback generating docs --- .github/workflows/docs.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 782b90229..c9a206a35 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -3,10 +3,10 @@ name: GH Pages Deploy (Docs, mdbook) on: push: - # branches: - # - main - # tags: - # - '*' + branches: + - main + tags: + - '*' jobs: build-deploy: