diff --git a/app/params/config.go b/app/params/config.go index 190a58d847..b89f19f57f 100644 --- a/app/params/config.go +++ b/app/params/config.go @@ -107,8 +107,6 @@ func setValidatorTypeTendermintConfig(config *tmcfg.Config) { // setFullnodeTypeTendermintConfig sets common Tendermint config for fullnode-like nodes func setFullnodeTypeTendermintConfig(config *tmcfg.Config) { config.TxIndex.Indexer = []string{"kv"} // Full nodes need tx indexing for queries - config.RPC.ListenAddress = "tcp://0.0.0.0:26657" - config.P2P.ListenAddress = "tcp://0.0.0.0:26656" } // SetTendermintConfigByMode sets Tendermint config values based on node mode diff --git a/cmd/seid/cmd/root.go b/cmd/seid/cmd/root.go index 29faa31f58..b308ef8f32 100644 --- a/cmd/seid/cmd/root.go +++ b/cmd/seid/cmd/root.go @@ -8,7 +8,6 @@ import ( "math/rand" "os" "path/filepath" - "strings" "time" "github.com/cosmos/cosmos-sdk/baseapp" @@ -96,12 +95,6 @@ func NewRootCmd() (*cobra.Command, params.EncodingConfig) { return err } - // Skip creating config.toml/app.toml when running "init"; init creates them itself. - // Otherwise the PreRun would create them in the init home, and init would then error - if strings.HasPrefix(cmd.Use, "init") { - return nil - } - customAppTemplate, customAppConfig := initAppConfig() return server.InterceptConfigsPreRunHandler(cmd, customAppTemplate, customAppConfig) diff --git a/evmrpc/filter.go b/evmrpc/filter.go index 8cf7c8652e..523f021a25 100644 --- a/evmrpc/filter.go +++ b/evmrpc/filter.go @@ -934,6 +934,14 @@ func (f *LogFetcher) tryFilterLogsRange(_ context.Context, fromBlock, toBlock ui return nil, err } + // Sort logs by block number and index (should already be sorted from DuckDB, but ensure consistency) + sort.Slice(logs, func(i, j int) bool { + if logs[i].BlockNumber != logs[j].BlockNumber { + return logs[i].BlockNumber < logs[j].BlockNumber + } + return logs[i].Index < logs[j].Index + }) + return logs, nil } diff --git a/go.mod b/go.mod index 50eae85241..95bb80d62f 100644 --- a/go.mod +++ b/go.mod @@ -17,7 +17,6 @@ require ( github.com/creachadair/atomicfile v0.4.0 github.com/creachadair/taskgroup v0.3.2 github.com/creachadair/tomledit v0.0.29 - github.com/duckdb/duckdb-go/v2 v2.5.3 github.com/dvsekhvalnov/jose2go v1.5.0 github.com/ethereum/evmc/v12 v12.1.0 github.com/ethereum/go-ethereum v1.16.8 @@ -53,7 +52,6 @@ require ( github.com/mroth/weightedrand v1.0.0 github.com/oasisprotocol/curve25519-voi v0.0.0-20210609091139-0a56a4bca00b github.com/ory/dockertest v3.3.5+incompatible - github.com/parquet-go/parquet-go v0.25.1 github.com/patrickmn/go-cache v2.1.0+incompatible github.com/pkg/errors v0.9.1 github.com/prometheus/client_golang v1.23.2 @@ -75,7 +73,7 @@ require ( github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d github.com/tendermint/tm-db v0.6.8-0.20220519162814-e24b96538a12 github.com/tidwall/btree v1.6.0 - github.com/tidwall/gjson v1.14.2 + github.com/tidwall/gjson v1.10.2 github.com/tidwall/wal v1.2.1 github.com/zbiljic/go-filelock v0.0.0-20170914061330-1dbf7103ab7d github.com/zeebo/blake3 v0.2.4 @@ -112,13 +110,14 @@ require ( require ( 4d63.com/gochecknoglobals v0.1.0 // indirect cosmossdk.io/errors v1.0.0 // indirect + dario.cat/mergo v1.0.2 // indirect filippo.io/edwards25519 v1.0.0-rc.1 // indirect github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect github.com/99designs/keyring v1.2.1 // indirect github.com/Abirdcfly/dupword v0.0.7 // indirect github.com/Antonboom/errname v0.1.7 // indirect github.com/Antonboom/nilnil v0.1.1 // indirect - github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect + github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c // indirect github.com/DataDog/zstd v1.5.7 // indirect github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24 // indirect github.com/GaijinEntertainment/go-exhaustruct/v2 v2.3.0 // indirect @@ -131,8 +130,6 @@ require ( github.com/VictoriaMetrics/fastcache v1.12.2 // indirect github.com/alexkohler/prealloc v1.0.0 // indirect github.com/alingse/asasalint v0.0.11 // indirect - github.com/andybalholm/brotli v1.2.0 // indirect - github.com/apache/arrow-go/v18 v18.4.1 // indirect github.com/ashanbrown/forbidigo v1.3.0 // indirect github.com/ashanbrown/makezero v1.1.1 // indirect github.com/beorn7/perks v1.0.1 // indirect @@ -177,17 +174,10 @@ require ( github.com/dgraph-io/badger/v3 v3.2103.2 // indirect github.com/dgraph-io/ristretto v0.2.0 // indirect github.com/dlclark/regexp2 v1.7.0 // indirect - github.com/docker/go-connections v0.4.0 // indirect - github.com/docker/go-units v0.4.0 // indirect + github.com/docker/cli v29.2.0+incompatible // indirect + github.com/docker/go-connections v0.6.0 // indirect + github.com/docker/go-units v0.5.0 // indirect github.com/dop251/goja v0.0.0-20230605162241-28ee0ee714f3 // indirect - github.com/duckdb/duckdb-go-bindings v0.1.23 // indirect - github.com/duckdb/duckdb-go-bindings/darwin-amd64 v0.1.23 // indirect - github.com/duckdb/duckdb-go-bindings/darwin-arm64 v0.1.23 // indirect - github.com/duckdb/duckdb-go-bindings/linux-amd64 v0.1.23 // indirect - github.com/duckdb/duckdb-go-bindings/linux-arm64 v0.1.23 // indirect - github.com/duckdb/duckdb-go-bindings/windows-amd64 v0.1.23 // indirect - github.com/duckdb/duckdb-go/arrowmapping v0.0.26 // indirect - github.com/duckdb/duckdb-go/mapping v0.0.25 // indirect github.com/dustin/go-humanize v1.0.1 // indirect github.com/esimonov/ifshort v1.0.4 // indirect github.com/ethereum/c-kzg-4844 v1.0.0 // indirect @@ -214,10 +204,9 @@ require ( github.com/go-toolsmith/astp v1.0.0 // indirect github.com/go-toolsmith/strparse v1.0.0 // indirect github.com/go-toolsmith/typep v1.0.2 // indirect - github.com/go-viper/mapstructure/v2 v2.4.0 // indirect + github.com/go-viper/mapstructure/v2 v2.3.0 // indirect github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b // indirect github.com/gobwas/glob v0.2.3 // indirect - github.com/goccy/go-json v0.10.5 // indirect github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect github.com/gofrs/flock v0.13.0 // indirect github.com/gogo/gateway v1.1.0 // indirect @@ -232,7 +221,7 @@ require ( github.com/golangci/misspell v0.3.5 // indirect github.com/golangci/revgrep v0.0.0-20220804021717-745bb2f7c2e6 // indirect github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4 // indirect - github.com/google/flatbuffers v25.2.10+incompatible // indirect + github.com/google/flatbuffers v23.5.26+incompatible // indirect github.com/google/pprof v0.0.0-20230207041349-798e818bf904 // indirect github.com/gordonklaus/ineffassign v0.0.0-20210914165742-4cc7213b9bc8 // indirect github.com/gorilla/handlers v1.5.1 // indirect @@ -267,7 +256,7 @@ require ( github.com/kisielk/gotool v1.0.0 // indirect github.com/kkHAIKE/contextcheck v1.1.3 // indirect github.com/klauspost/compress v1.18.3 // indirect - github.com/klauspost/cpuid/v2 v2.3.0 // indirect + github.com/klauspost/cpuid/v2 v2.2.5 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect github.com/kulti/thelper v0.6.3 // indirect @@ -283,12 +272,15 @@ require ( github.com/matoous/godox v0.0.0-20210227103229-6504466cf951 // indirect github.com/mattn/go-colorable v0.1.14 // indirect github.com/mattn/go-isatty v0.0.20 // indirect - github.com/mattn/go-runewidth v0.0.16 // indirect + github.com/mattn/go-runewidth v0.0.13 // indirect github.com/mbilski/exhaustivestruct v1.2.0 // indirect github.com/mgechev/revive v1.2.4 // indirect github.com/minio/minlz v1.0.1-0.20250507153514-87eb42fe8882 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/pointerstructure v1.2.0 // indirect + github.com/moby/moby/api v1.53.0 // indirect + github.com/moby/moby/client v0.2.2 // indirect + github.com/moby/term v0.5.2 // indirect github.com/moricho/tparallel v0.2.1 // indirect github.com/mtibben/percent v0.2.1 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect @@ -298,12 +290,11 @@ require ( github.com/nishanths/predeclared v0.2.2 // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect - github.com/opencontainers/image-spec v1.0.2 // indirect + github.com/opencontainers/image-spec v1.1.1 // indirect github.com/opencontainers/runc v1.1.14 // indirect github.com/pelletier/go-toml/v2 v2.2.4 // indirect github.com/petermattis/goid v0.0.0-20230317030725-371a4b8eda08 // indirect github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d // indirect - github.com/pierrec/lz4/v4 v4.1.22 // indirect github.com/pion/dtls/v2 v2.2.7 // indirect github.com/pion/logging v0.2.2 // indirect github.com/pion/stun/v2 v2.0.0 // indirect @@ -360,7 +351,6 @@ require ( github.com/yagipy/maintidx v1.0.0 // indirect github.com/yeya24/promlinter v0.2.0 // indirect github.com/yusufpapurcu/wmi v1.2.4 // indirect - github.com/zeebo/xxh3 v1.0.2 // indirect github.com/zondax/golem v0.27.0 // indirect github.com/zondax/hid v0.9.2 // indirect github.com/zondax/ledger-go v1.0.1 // indirect @@ -368,17 +358,16 @@ require ( go.etcd.io/bbolt v1.3.7 // indirect go.opencensus.io v0.24.0 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.64.0 // indirect go.opentelemetry.io/otel/exporters/jaeger v1.9.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect go.yaml.in/yaml/v2 v2.4.3 // indirect golang.org/x/exp/typeparams v0.0.0-20231108232855-2478ac86f678 // indirect golang.org/x/mod v0.32.0 // indirect - golang.org/x/telemetry v0.0.0-20260109210033-bd525da824e2 // indirect golang.org/x/term v0.39.0 // indirect golang.org/x/text v0.33.0 // indirect golang.org/x/tools v0.41.0 // indirect - golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect google.golang.org/genproto v0.0.0-20250603155806-513f23925822 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20250818200422-3122310a409c // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect diff --git a/go.sum b/go.sum index 2c31401c25..d3641f1fe5 100644 --- a/go.sum +++ b/go.sum @@ -595,6 +595,8 @@ cloud.google.com/go/workflows v1.9.0/go.mod h1:ZGkj1aFIOd9c8Gerkjjq7OW7I5+l6cSvT cloud.google.com/go/workflows v1.10.0/go.mod h1:fZ8LmRmZQWacon9UCX1r/g/DfAXx5VcPALq2CxzdePw= cosmossdk.io/errors v1.0.0 h1:nxF07lmlBbB8NKQhtJ+sJm6ef5uV1XkvPXG2bUntb04= cosmossdk.io/errors v1.0.0/go.mod h1:+hJZLuhdDE0pYN8HkOrVNwrIOYvUGnn6+4fjnJs/oV0= +dario.cat/mergo v1.0.2 h1:85+piFYR1tMbRrLcDwR18y4UKJ3aH1Tbzi24VRW1TK8= +dario.cat/mergo v1.0.2/go.mod h1:E/hbnu0NxMFBjpMIE34DRGLWqDy0g5FuKDhCb31ngxA= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= filippo.io/edwards25519 v1.0.0-rc.1 h1:m0VOOB23frXZvAOK44usCgLWvtsxIoMCTBGJZlpmGfU= filippo.io/edwards25519 v1.0.0-rc.1/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns= @@ -621,8 +623,8 @@ github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/internal v1.0.0/go.mod h1: github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources v1.0.0/go.mod h1:s1tW/At+xHqjNFvWU4G0c0Qv33KOhvbGNj0RCTQDV8s= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage v1.2.0/go.mod h1:c+Lifp3EDEamAkPVzMooRNOK6CZjNSdEnf1A7jsI9u4= github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.2.0/go.mod h1:+6KLcKIVgxoBDMqMO/Nvy7bZ9a0nbU3I1DtFQK3YvB4= -github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0= -github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= +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/AzureAD/microsoft-authentication-library-for-go v0.4.0/go.mod h1:Vt9sXTKwMyGcOxSmLDMnGPgqsUg7m8pe215qMLrDXw4= github.com/AzureAD/microsoft-authentication-library-for-go v1.0.0/go.mod h1:kgDmCTgBzIEPFElEF+FK0SdjAor06dRq2Go927dnQ6o= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= @@ -702,18 +704,12 @@ github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= -github.com/andybalholm/brotli v1.2.0 h1:ukwgCxwYrmACq68yiUqwIWnGY0cTPox/M94sVwToPjQ= -github.com/andybalholm/brotli v1.2.0/go.mod h1:rzTDkvFWvIrjDXZHkuS16NPggd91W3kUSvPlQ1pLaKY= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= -github.com/apache/arrow-go/v18 v18.4.1 h1:q/jVkBWCJOB9reDgaIZIdruLQUb1kbkvOnOFezVH1C4= -github.com/apache/arrow-go/v18 v18.4.1/go.mod h1:tLyFubsAl17bvFdUAy24bsSvA/6ww95Iqi67fTpGu3E= github.com/apache/arrow/go/v10 v10.0.1/go.mod h1:YvhnlEePVnBS4+0z3fhPfUy7W1Ikj0Ih0vcRo/gZ1M0= github.com/apache/arrow/go/v11 v11.0.0/go.mod h1:Eg5OsL5H+e299f7u5ssuXsuHQVEGC4xei5aX110hRiI= github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/apache/thrift v0.16.0/go.mod h1:PHK3hniurgQaNMZYaCLEqXKsYK8upmhPbmdP2FXSqgU= -github.com/apache/thrift v0.22.0 h1:r7mTJdj51TMDe6RtcmNdQxgn9XcyfGDOzegMDRg47uc= -github.com/apache/thrift v0.22.0/go.mod h1:1e7J/O1Ae6ZQMTYdy9xa3w9k+XHWPfRvdPyJeynQ+/g= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= @@ -866,6 +862,10 @@ github.com/consensys/gnark-crypto v0.18.0 h1:vIye/FqI50VeAr0B3dx+YjeIvmc3LWz4yEf github.com/consensys/gnark-crypto v0.18.0/go.mod h1:L3mXGFTe1ZN+RSJ+CLjUt9x7PNdx8ubaYfDROyp2Z8c= github.com/containerd/continuity v0.3.0 h1:nisirsYROK15TAMVukJOUyGJjz4BNQJBVsNvAXZJ/eg= github.com/containerd/continuity v0.3.0/go.mod h1:wJEAIwKOm/pBZuBd0JmeTvnLquTB1Ag8espWhkykbPM= +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/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= @@ -955,20 +955,20 @@ github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 h1:fAjc9m62+UWV/WA github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= +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/djherbis/atime v1.1.0/go.mod h1:28OF6Y8s3NQWwacXc5eZTsEsiMzp7LF8MbXE+XJPdBE= github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= github.com/dlclark/regexp2 v1.7.0 h1:7lJfhqlPssTb1WQx4yvTHN0uElPEv52sbaECrAQxjAo= github.com/dlclark/regexp2 v1.7.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= github.com/dnaeon/go-vcr v1.1.0/go.mod h1:M7tiix8f0r6mKKJ3Yq/kqU1OYf3MnfmBWVbPx/yU9ko= github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ= -github.com/docker/cli v20.10.17+incompatible h1:eO2KS7ZFeov5UJeaDmIs1NFEDRf32PaqRpvoEkKBy5M= -github.com/docker/cli v20.10.17+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= -github.com/docker/docker v25.0.6+incompatible h1:5cPwbwriIcsua2REJe8HqQV+6WlWc1byg2QSXzBxBGg= -github.com/docker/docker v25.0.6+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= -github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= -github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw= -github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/docker/cli v29.2.0+incompatible h1:9oBd9+YM7rxjZLfyMGxjraKBKE4/nVyvVfN4qNl9XRM= +github.com/docker/cli v29.2.0+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= +github.com/docker/go-connections v0.6.0 h1:LlMG9azAe1TqfR7sO+NJttz1gy6KO7VJBh+pMmjSD94= +github.com/docker/go-connections v0.6.0/go.mod h1:AahvXYshr6JgfUJGdDCs2b5EZG/vmaMAntpSFH5BFKE= +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/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= github.com/donovanhide/eventsource v0.0.0-20210830082556-c59027999da0/go.mod h1:56wL82FO0bfMU5RvfXoIwSOP2ggqqxT+tAfNEIyxuHw= github.com/dop251/goja v0.0.0-20211022113120-dc8c55024d06/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk= @@ -976,24 +976,6 @@ github.com/dop251/goja v0.0.0-20230605162241-28ee0ee714f3 h1:+3HCtB74++ClLy8GgjU github.com/dop251/goja v0.0.0-20230605162241-28ee0ee714f3/go.mod h1:QMWlm50DNe14hD7t24KEqZuUdC9sOTy8W6XbCU1mlw4= github.com/dop251/goja_nodejs v0.0.0-20210225215109-d91c329300e7/go.mod h1:hn7BA7c8pLvoGndExHudxTDKZ84Pyvv+90pbBjbTz0Y= github.com/dop251/goja_nodejs v0.0.0-20211022123610-8dd9abb0616d/go.mod h1:DngW8aVqWbuLRMHItjPUyqdj+HWPvnQe8V8y1nDpIbM= -github.com/duckdb/duckdb-go-bindings v0.1.23 h1:sJRXraxfC/gdHI2T7oHqrdp1VdKemrgqWGQ8986mH1c= -github.com/duckdb/duckdb-go-bindings v0.1.23/go.mod h1:WA7U/o+b37MK2kiOPPueVZ+FIxt5AZFCjszi8hHeH18= -github.com/duckdb/duckdb-go-bindings/darwin-amd64 v0.1.23 h1:Xyw1fWu4jzOtv2Hqkaehr7f+qbIWNRfBMbZyD+g8dyU= -github.com/duckdb/duckdb-go-bindings/darwin-amd64 v0.1.23/go.mod h1:jfbOHwGZqNCpMAxV4g4g5jmWr0gKdMvh2fGusPubxC4= -github.com/duckdb/duckdb-go-bindings/darwin-arm64 v0.1.23 h1:85Xomx5NxZ+Nt+VepUJzuMYbBTH+nB6JlBXIyJuTovA= -github.com/duckdb/duckdb-go-bindings/darwin-arm64 v0.1.23/go.mod h1:zLVtv1a7TBuTPvuAi32AIbnuw7jjaX5JElZ+urv1ydc= -github.com/duckdb/duckdb-go-bindings/linux-amd64 v0.1.23 h1:RGw8mDqQl9JdlCYV0PAfGBuVAgOguiL5Vz5W8pH8fGw= -github.com/duckdb/duckdb-go-bindings/linux-amd64 v0.1.23/go.mod h1:GCaBoYnuLZEva7BXzdXehTbqh9VSvpLB80xcmxGBGs8= -github.com/duckdb/duckdb-go-bindings/linux-arm64 v0.1.23 h1:f8NHa8DGes7vg55BxeMVm0ycddEJTRHEt813USdL0/I= -github.com/duckdb/duckdb-go-bindings/linux-arm64 v0.1.23/go.mod h1:kpQSpJmDSSZQ3ikbZR1/8UqecqMeUkWFjFX2xZxlCuI= -github.com/duckdb/duckdb-go-bindings/windows-amd64 v0.1.23 h1:HJqVo+09gT6LQWW6PlN/c7K8s0eQhv5giE7kJcMGMSU= -github.com/duckdb/duckdb-go-bindings/windows-amd64 v0.1.23/go.mod h1:wa+egSGXTPS16NPADFCK1yFyt3VSXxUS6Pt2fLnvRPM= -github.com/duckdb/duckdb-go/arrowmapping v0.0.26 h1:XKhWpNkLtIbcBE2vnKm7FaAju3daplxo8MJIXOAY/Zg= -github.com/duckdb/duckdb-go/arrowmapping v0.0.26/go.mod h1:R7egXxZcy0hxKY/MsoM2xjkMvRo4H07TffDhYCnhKfQ= -github.com/duckdb/duckdb-go/mapping v0.0.25 h1:z4RhivKCIRv0MWQwtYekqH+ikoA29/n8L+rzgreKvsc= -github.com/duckdb/duckdb-go/mapping v0.0.25/go.mod h1:CIo3WbNx3Txl+VO9+P5eNCN9ZifUA/KIp9NY1rTG/uo= -github.com/duckdb/duckdb-go/v2 v2.5.3 h1:GlT+bXW+/gCYo0Q8P9L6IvvKRzMM0/tDXj5fKkoAfCM= -github.com/duckdb/duckdb-go/v2 v2.5.3/go.mod h1:+mGhZCF5tHYIdBWrp7+KGj6JnTXdm+sBTh3ZSLhXorE= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= @@ -1154,8 +1136,8 @@ github.com/go-toolsmith/strparse v1.0.0 h1:Vcw78DnpCAKlM20kSbAyO4mPfJn/lyYA4BJUD github.com/go-toolsmith/strparse v1.0.0/go.mod h1:YI2nUKP9YGZnL/L1/DLFBfixrcjslWct4wyljWhSRy8= github.com/go-toolsmith/typep v1.0.2 h1:8xdsa1+FSIH/RhEkgnD1j2CJOy5mNllW1Q9tRiYwvlk= github.com/go-toolsmith/typep v1.0.2/go.mod h1:JSQCQMUPdRlMZFswiq3TGpNp1GMktqkR2Ns5AIQkATU= -github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs= -github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= +github.com/go-viper/mapstructure/v2 v2.3.0 h1:27XbWsHIqhbdR5TIC911OfYvgSaW93HM+dX7970Q7jk= +github.com/go-viper/mapstructure/v2 v2.3.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b h1:khEcpUM4yFcxg4/FHQWkvVRmgijNXRfzkIDHh23ggEo= github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b/go.mod h1:aUCEOzzezBEjDBbFBoSiya/gduyIiWYRP6CnSFIV8AM= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= @@ -1171,9 +1153,8 @@ github.com/gobwas/ws v1.1.0 h1:7RFti/xnNkMJnrK7D1yQ/iCIB5OrrY/54/H930kIbHA= github.com/gobwas/ws v1.1.0/go.mod h1:nzvNcVha5eUziGrbxFCo6qFIojQHjJV5cLYIbezhfL0= github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/goccy/go-json v0.9.11/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= +github.com/goccy/go-json v0.10.4 h1:JSwxQzIqKfmFX1swYPpUThQZp/Ka4wzJdK0LWVytLPM= github.com/goccy/go-json v0.10.4/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= -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 v0.0.0-20190726142602-4481cbc300e2 h1:ZpnhV/YsD2/4cESfV5+Hoeu/iUR3ruzNvZ+yQfO03a0= github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= @@ -1276,8 +1257,8 @@ github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg= github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= github.com/google/flatbuffers v1.12.1/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= github.com/google/flatbuffers v2.0.8+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= -github.com/google/flatbuffers v25.2.10+incompatible h1:F3vclr7C3HpB1k9mxCGRMXq6FdUalZ6H/pNX4FP1v0Q= -github.com/google/flatbuffers v25.2.10+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= +github.com/google/flatbuffers v23.5.26+incompatible h1:M9dgRyhJemaM4Sw8+66GHBu8ioaQmyPLg1b8VwK5WJg= +github.com/google/flatbuffers v23.5.26+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= 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= @@ -1476,8 +1457,6 @@ github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47 github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20220319035150-800ac71e25c2/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w= -github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk= -github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg= github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= github.com/improbable-eng/grpc-web v0.14.1 h1:NrN4PY71A6tAz2sKDvC5JCauENWp0ykG8Oq1H3cpFvw= github.com/improbable-eng/grpc-web v0.14.1/go.mod h1:zEjGHa8DAlkoOXmswrNvhUGEYQA9UI7DhrGeHR1DMGU= @@ -1553,7 +1532,6 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o github.com/kkHAIKE/contextcheck v1.1.3 h1:l4pNvrb8JSwRd51ojtcOxOeHJzHek+MtOyXbaR0uvmw= github.com/kkHAIKE/contextcheck v1.1.3/go.mod h1:PG/cwd6c0705/LM0KTr1acO2gORUxkSVWyLJOFW5qoo= github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= -github.com/klauspost/asmfmt v1.3.2 h1:4Ri7ox3EwapiOjCki+hw14RyKk201CN4rzyCJRFLpK4= github.com/klauspost/asmfmt v1.3.2/go.mod h1:AG8TuvYojzulgDAMCnYn50l/5QV3Bs/tp6j0HLHbNSE= github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.11.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= @@ -1566,8 +1544,8 @@ github.com/klauspost/compress v1.18.3 h1:9PJRvfbmTabkOX8moIpXPbMMbYN60bWImDDU7L+ github.com/klauspost/compress v1.18.3/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4= github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y= -github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= +github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg= +github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= @@ -1664,9 +1642,8 @@ github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= +github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= -github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= -github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/mattn/go-sqlite3 v1.14.5/go.mod h1:WVKg1VTActs4Qso6iwGbiFih2UIHo0ENGwNd0Lj+XmI= github.com/mattn/go-sqlite3 v1.14.14/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= @@ -1681,9 +1658,7 @@ github.com/mgechev/revive v1.2.4 h1:+2Hd/S8oO2H0Ikq2+egtNwQsVhAeELHjxjIUFX5ajLI= github.com/mgechev/revive v1.2.4/go.mod h1:iAWlQishqCuj4yhV24FTnKSXGpbAA+0SckXB8GQMX/Q= github.com/microcosm-cc/bluemonday v1.0.23/go.mod h1:mN70sk7UkkF8TUr2IGBpNN0jAgStuPzlK76QuruE/z4= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= -github.com/minio/asm2plan9s v0.0.0-20200509001527-cdd76441f9d8 h1:AMFGa4R4MiIpspGNG7Z948v4n35fFGB3RR3G/ry4FWs= github.com/minio/asm2plan9s v0.0.0-20200509001527-cdd76441f9d8/go.mod h1:mC1jAcsrzbxHt8iiaC+zU4b1ylILSosueou12R++wfY= -github.com/minio/c2goasm v0.0.0-20190812172519-36a3d3bbc4f3 h1:+n/aFZefKZp7spd8DFdX7uMikMLXX4oubIzJF4kv/wI= github.com/minio/c2goasm v0.0.0-20190812172519-36a3d3bbc4f3/go.mod h1:RagcQ7I8IeTMnF8JTXieKnO4Z6JCsikNEzj0DwauVzE= github.com/minio/highwayhash v1.0.2/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY= github.com/minio/minlz v1.0.1-0.20250507153514-87eb42fe8882 h1:0lgqHvJWHLGW5TuObJrfyEi6+ASTKDBWikGvPqy9Yiw= @@ -1709,8 +1684,14 @@ github.com/mitchellh/pointerstructure v1.2.0 h1:O+i9nHnXS3l/9Wu7r4NrEdwA2VFTicjU github.com/mitchellh/pointerstructure v1.2.0/go.mod h1:BRAsLI5zgXmw97Lf6s25bs8ohIXc3tViBH44KcwB2g4= 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/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0= -github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= +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/moby/api v1.53.0 h1:PihqG1ncw4W+8mZs69jlwGXdaYBeb5brF6BL7mPIS/w= +github.com/moby/moby/api v1.53.0/go.mod h1:8mb+ReTlisw4pS6BRzCMts5M49W5M7bKt1cJy/YbAqc= +github.com/moby/moby/client v0.2.2 h1:Pt4hRMCAIlyjL3cr8M5TrXCwKzguebPAc2do2ur7dEM= +github.com/moby/moby/client v0.2.2/go.mod h1:2EkIPVNCqR05CMIzL1mfA07t0HvVUUOl85pasRz/GmQ= +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= @@ -1806,8 +1787,8 @@ github.com/onsi/gomega v1.27.1/go.mod h1:aHX5xOykVYzWOV4WqQy0sy8BQptgukenXpCXfad github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= 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.0.2 h1:9yCKha/T5XdGtO0q9Q9a6T5NUCsTn/DrBg0D7ufOcFM= -github.com/opencontainers/image-spec v1.0.2/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= +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/opencontainers/runc v1.1.14 h1:rgSuzbmgz5DUJjeSnw337TxDbRuqjs6iqQck/2weR6w= github.com/opencontainers/runc v1.1.14/go.mod h1:E4C2z+7BxR7GHXp0hAY53mek+x49X1LjPNeMTfRGvOA= github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= @@ -1829,8 +1810,6 @@ github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6 github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo= github.com/otiai10/mint v1.3.1/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc= github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= -github.com/parquet-go/parquet-go v0.25.1 h1:l7jJwNM0xrk0cnIIptWMtnSnuxRkwq53S+Po3KG8Xgo= -github.com/parquet-go/parquet-go v0.25.1/go.mod h1:AXBuotO1XiBtcqJb/FKFyjBG4aqa3aQAAWF3ZPzCanY= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= @@ -1856,8 +1835,6 @@ github.com/phpdave11/gofpdi v1.0.13/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pierrec/lz4/v4 v4.1.15/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= -github.com/pierrec/lz4/v4 v4.1.22 h1:cKFw6uJDK+/gfw5BcDL0JL5aBsAFdsIT18eRtLj7VIU= -github.com/pierrec/lz4/v4 v4.1.22/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= github.com/pion/dtls/v2 v2.2.7 h1:cSUBsETxepsCSFSxC3mc/aDo14qQLMSL+O6IjG28yV8= @@ -2163,9 +2140,8 @@ github.com/tetafro/godot v1.4.11/go.mod h1:LR3CJpxDVGlYOWn3ZZg1PgNZdTUvzsZWu8xaE github.com/tidwall/btree v1.6.0 h1:LDZfKfQIBHGHWSwckhXI0RPSXzlo+KYdjK7FWSqOzzg= github.com/tidwall/btree v1.6.0/go.mod h1:twD9XRA5jj9VUQGELzDO4HPQTNJsoWWfYEL+EUQ2cKY= github.com/tidwall/gjson v1.6.7/go.mod h1:zeFuBCIqD4sN/gmqBzZ4j7Jd6UcA2Fc56x7QFsv+8fI= +github.com/tidwall/gjson v1.10.2 h1:APbLGOM0rrEkd8WBw9C24nllro4ajFuJu0Sc9hRz8Bo= github.com/tidwall/gjson v1.10.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= -github.com/tidwall/gjson v1.14.2 h1:6BBkirS0rAHjumnjHF6qgy5d2YAJ1TLIaFE2lzfOLqo= -github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/match v1.0.3/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= @@ -2239,8 +2215,6 @@ github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1: github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= 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/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU= -github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E= github.com/yagipy/maintidx v1.0.0 h1:h5NvIsCz+nRDapQ0exNv4aJ0yXSI0420omVANTv3GJM= github.com/yagipy/maintidx v1.0.0/go.mod h1:0qNf/I/CCZXSMhsRsrEPDZ+DkekpKLXAJfsTACwgXLk= github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI= @@ -2269,7 +2243,6 @@ github.com/zeebo/blake3 v0.2.4 h1:KYQPkhpRtcqh0ssGYcKLG1JYvddkEA8QwCM/yBqhaZI= github.com/zeebo/blake3 v0.2.4/go.mod h1:7eeQ6d2iXWRGF6npfaxl2CU+xy2Fjo2gxeyZGCRUjcE= github.com/zeebo/pcg v1.0.1 h1:lyqfGeWiv4ahac6ttHs+I5hwtH/+1mrhlCtVNQM2kHo= github.com/zeebo/pcg v1.0.1/go.mod h1:09F0S9iiKrwn9rlI5yjLkmrug154/YRW6KnnXVDM/l4= -github.com/zeebo/xxh3 v1.0.2 h1:xZmwmqxHZA8AI603jOQ0tMqmBr9lPeFwGg6d+xy9DC0= github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA= github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= github.com/zondax/golem v0.27.0 h1:IbBjGIXF3SoGOZHsILJvIM/F/ylwJzMcHAcggiqniPw= @@ -2302,6 +2275,8 @@ go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.64.0 h1:ssfIgGNANqpVFCndZvcuyKbl0g+UAVcbBcqGkG28H0Y= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.64.0/go.mod h1:GQ/474YrbE4Jx8gZ4q5I4hrhUzM6UPzyrqJYV2AqPoQ= go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48= go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8= go.opentelemetry.io/otel/exporters/jaeger v1.9.0 h1:gAEgEVGDWwFjcis9jJTOJqZNxDzoZfR12WNIxr7g9Ww= @@ -2339,6 +2314,7 @@ go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= go.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0= go.yaml.in/yaml/v2 v2.4.3/go.mod h1:zSxWcmIDjOzPXpjlTTbAsKokqkDNAVtZO0WOMiT90s8= +go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= @@ -2699,8 +2675,6 @@ golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE= golang.org/x/telemetry v0.0.0-20240521205824-bda55230c457/go.mod h1:pRgIJT+bRLFKnoM1ldnzKoxTIn14Yxz928LQRYYgIN0= -golang.org/x/telemetry v0.0.0-20260109210033-bd525da824e2 h1:O1cMQHRfwNpDfDJerqRoE2oD+AFlyid87D40L/OkkJo= -golang.org/x/telemetry v0.0.0-20260109210033-bd525da824e2/go.mod h1:b7fPSJ0pKZ3ccUh8gnTONJxhn3c/PS6tyzQvyqw4iA8= 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.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -2879,14 +2853,10 @@ golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= -golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da h1:noIWHXmPHxILtqtCOPIhSt0ABwskkZKjD3bXGnZGpNY= -golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= gonum.org/v1/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0= gonum.org/v1/gonum v0.9.3/go.mod h1:TZumC3NeyVQskjXqmyWt4S3bINhy7B4eYwW69EbyX+0= gonum.org/v1/gonum v0.11.0/go.mod h1:fSG4YDCxxUZQJ7rKsQrj0gMOg00Il0Z96/qMA4bVQhA= -gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= -gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc= gonum.org/v1/plot v0.9.0/go.mod h1:3Pcqqmp6RHvJI72kgb8fThyUnav364FOsdDo2aGW5lY= diff --git a/go.work.sum b/go.work.sum index 8398346ce7..cbbe309371 100644 --- a/go.work.sum +++ b/go.work.sum @@ -1,519 +1,508 @@ -atomicgo.dev/cursor v0.2.0/go.mod h1:Lr4ZJB3U7DfPPOkbH7/6TOtJ4vFGHlgj1nc+n900IpU= -atomicgo.dev/keyboard v0.2.9/go.mod h1:BC4w9g00XkxH/f1HXhW2sXmJFOCWbKn9xrOunSFtExQ= -atomicgo.dev/schedule v0.1.0/go.mod h1:xeUa3oAkiuHYh8bKiQBRojqAMq3PXXbJujjb0hw8pEU= bazil.org/fuse v0.0.0-20200407214033-5883e5a4b512 h1:SRsZGA7aFnCZETmov57jwPrWuTmaZK6+4R4v5FUe1/c= bitbucket.org/creachadair/shell v0.0.6 h1:reJflDbKqnlnqb4Oo2pQ1/BqmY/eCWcNGHrIUO8qIzc= cel.dev/expr v0.15.0/go.mod h1:TRSuuV7DlVCE/uwv5QbAiW/v8l5O8C4eEPHeu7gf7Sg= -cel.dev/expr v0.16.0/go.mod h1:TRSuuV7DlVCE/uwv5QbAiW/v8l5O8C4eEPHeu7gf7Sg= cel.dev/expr v0.16.1 h1:NR0+oFYzR1CqLFhTAqg3ql59G9VfN8fKq1TCHJ6gq1g= cel.dev/expr v0.16.1/go.mod h1:AsGA5zb3WruAEQeQng1RZdGEXmBj0jvMWh6l5SnNuC8= -cel.dev/expr v0.19.0/go.mod h1:MrpN08Q+lEBs+bGYdLxxHkZoUSsCp0nSKTs0nTymJgw= -cel.dev/expr v0.19.2/go.mod h1:MrpN08Q+lEBs+bGYdLxxHkZoUSsCp0nSKTs0nTymJgw= +cel.dev/expr v0.20.0 h1:OunBvVCfvpWlt4dN7zg3FM6TDkzOePe1+foGJ9AXeeI= cel.dev/expr v0.20.0/go.mod h1:MrpN08Q+lEBs+bGYdLxxHkZoUSsCp0nSKTs0nTymJgw= cloud.google.com/go v0.98.0/go.mod h1:ua6Ush4NALrHk5QXDWnjvZHN93OuF0HfuEPq9I1X0cM= -cloud.google.com/go v0.112.2/go.mod h1:iEqjp//KquGIJV/m+Pk3xecgKNhV+ry+vVTsy4TbDms= cloud.google.com/go v0.116.0 h1:B3fRrSDkLRt5qSHWe40ERJvhvnQwdZiHu0bJOpldweE= cloud.google.com/go v0.116.0/go.mod h1:cEPSRWPzZEswwdr9BxE6ChEn01dWlTaF05LiC2Xs70U= -cloud.google.com/go v0.118.1/go.mod h1:CFO4UPEPi8oV21xoezZCrd3d81K4fFkDTEJu4R8K+9M= -cloud.google.com/go v0.118.3/go.mod h1:Lhs3YLnBlwJ4KA6nuObNMZ/fCbOQBPuWKPoE0Wa/9Vc= -cloud.google.com/go v0.120.0/go.mod h1:/beW32s8/pGRuj4IILWQNd4uuebeT4dkOhKmkfit64Q= -cloud.google.com/go v0.121.0/go.mod h1:rS7Kytwheu/y9buoDmu5EIpMMCI4Mb8ND4aeN4Vwj7Q= +cloud.google.com/go v0.121.1 h1:S3kTQSydxmu1JfLRLpKtxRPA7rSrYPRPEUmL/PavVUw= cloud.google.com/go v0.121.1/go.mod h1:nRFlrHq39MNVWu+zESP2PosMWA0ryJw8KUBZ2iZpxbw= cloud.google.com/go/accessapproval v1.8.2 h1:h4u1MypgeYXTGvnNc1luCBLDN4Kb9Re/gw0Atvoi8HE= cloud.google.com/go/accessapproval v1.8.2/go.mod h1:aEJvHZtpjqstffVwF/2mCXXSQmpskyzvw6zKLvLutZM= -cloud.google.com/go/accessapproval v1.8.3/go.mod h1:3speETyAv63TDrDmo5lIkpVueFkQcQchkiw/TAMbBo4= +cloud.google.com/go/accessapproval v1.8.6 h1:UkmDPCKvj24bkGVrvgJPcgSDkmIPw/bAmOiDb9avOiE= cloud.google.com/go/accessapproval v1.8.6/go.mod h1:FfmTs7Emex5UvfnnpMkhuNkRCP85URnBFt5ClLxhZaQ= cloud.google.com/go/accesscontextmanager v1.9.2 h1:P0uVixQft8aacbZ7VDZStNZdrftF24Hk8JkA3kfvfqI= cloud.google.com/go/accesscontextmanager v1.9.2/go.mod h1:T0Sw/PQPyzctnkw1pdmGAKb7XBA84BqQzH0fSU7wzJU= -cloud.google.com/go/accesscontextmanager v1.9.3/go.mod h1:S1MEQV5YjkAKBoMekpGrkXKfrBdsi4x6Dybfq6gZ8BU= +cloud.google.com/go/accesscontextmanager v1.9.6 h1:2LnncRqfYB8NEdh9+FeYxAt9POTW/0zVboktnRlO11w= cloud.google.com/go/accesscontextmanager v1.9.6/go.mod h1:884XHwy1AQpCX5Cj2VqYse77gfLaq9f8emE2bYriilk= cloud.google.com/go/aiplatform v1.69.0 h1:XvBzK8e6/6ufbi/i129Vmn/gVqFwbNPmRQ89K+MGlgc= cloud.google.com/go/aiplatform v1.69.0/go.mod h1:nUsIqzS3khlnWvpjfJbP+2+h+VrFyYsTm7RNCAViiY8= -cloud.google.com/go/aiplatform v1.74.0/go.mod h1:hVEw30CetNut5FrblYd1AJUWRVSIjoyIvp0EVUh51HA= +cloud.google.com/go/aiplatform v1.89.0 h1:niSJYc6ldWWVM9faXPo1Et1MVSQoLvVGriD7fwbJdtE= cloud.google.com/go/aiplatform v1.89.0/go.mod h1:TzZtegPkinfXTtXVvZZpxx7noINFMVDrLkE7cEWhYEk= cloud.google.com/go/analytics v0.25.2 h1:KgJ5Taxtsnro/co7WIhmAHi5pzYAtvxu8LMqenPAlSo= cloud.google.com/go/analytics v0.25.2/go.mod h1:th0DIunqrhI1ZWVlT3PH2Uw/9ANX8YHfFDEPqf/+7xM= -cloud.google.com/go/analytics v0.26.0/go.mod h1:KZWJfs8uX/+lTjdIjvT58SFa86V9KM6aPXwZKK6uNVI= +cloud.google.com/go/analytics v0.28.1 h1:W2ft49J/LeEj9A07Jsd5Q2kAzajK0j0IffOyyzbxw04= cloud.google.com/go/analytics v0.28.1/go.mod h1:iPaIVr5iXPB3JzkKPW1JddswksACRFl3NSHgVHsuYC4= cloud.google.com/go/apigateway v1.7.2 h1:TRB5q0vvbT5Yx4bNSCWlqLJFJnhc7tDlCR9ccpo1vzg= cloud.google.com/go/apigateway v1.7.2/go.mod h1:+weId+9aR9J6GRwDka7jIUSrKEX60XGcikX7dGU8O7M= -cloud.google.com/go/apigateway v1.7.3/go.mod h1:uK0iRHdl2rdTe79bHW/bTsKhhXPcFihjUdb7RzhTPf4= +cloud.google.com/go/apigateway v1.7.6 h1:do+u3rjDYuTxD2ypRfv4uwTMoy/VHFLclvaYcb5Mv6I= cloud.google.com/go/apigateway v1.7.6/go.mod h1:SiBx36VPjShaOCk8Emf63M2t2c1yF+I7mYZaId7OHiA= cloud.google.com/go/apigeeconnect v1.7.2 h1:GHg0ddEQUZ08C1qC780P5wwY/jaIW8UtxuRQXLLuRXs= cloud.google.com/go/apigeeconnect v1.7.2/go.mod h1:he/SWi3A63fbyxrxD6jb67ak17QTbWjva1TFbT5w8Kw= -cloud.google.com/go/apigeeconnect v1.7.3/go.mod h1:2ZkT5VCAqhYrDqf4dz7lGp4N/+LeNBSfou8Qs5bIuSg= +cloud.google.com/go/apigeeconnect v1.7.6 h1:ijEJSni5xROOn1YyiHgqcW0B0TWr0di9VgIi2gvyNjY= cloud.google.com/go/apigeeconnect v1.7.6/go.mod h1:zqDhHY99YSn2li6OeEjFpAlhXYnXKl6DFb/fGu0ye2w= cloud.google.com/go/apigeeregistry v0.9.2 h1:fC3ZXEk2QsBxUlZZDZpbBGXC/ZQglCBmHDGgY5aNipg= cloud.google.com/go/apigeeregistry v0.9.2/go.mod h1:A5n/DwpG5NaP2fcLYGiFA9QfzpQhPRFNATO1gie8KM8= -cloud.google.com/go/apigeeregistry v0.9.3/go.mod h1:oNCP2VjOeI6U8yuOuTmU4pkffdcXzR5KxeUD71gF+Dg= +cloud.google.com/go/apigeeregistry v0.9.6 h1:TgdjAoGoRY81DEc2LYsYvi/OqCFImMzAk/TVKiSRsQw= cloud.google.com/go/apigeeregistry v0.9.6/go.mod h1:AFEepJBKPtGDfgabG2HWaLH453VVWWFFs3P4W00jbPs= cloud.google.com/go/apikeys v0.6.0 h1:B9CdHFZTFjVti89tmyXXrO+7vSNo2jvZuHG8zD5trdQ= cloud.google.com/go/appengine v1.9.2 h1:pxAQ//FsyEQsaF9HJduPCOEvj9GV4fvnLARGz1+KDzM= cloud.google.com/go/appengine v1.9.2/go.mod h1:bK4dvmMG6b5Tem2JFZcjvHdxco9g6t1pwd3y/1qr+3s= -cloud.google.com/go/appengine v1.9.3/go.mod h1:DtLsE/z3JufM/pCEIyVYebJ0h9UNPpN64GZQrYgOSyM= +cloud.google.com/go/appengine v1.9.6 h1:JJyY8icMmQeWfQ+d36IhkGvd3Guzvw0UAkvxT0wmUx8= cloud.google.com/go/appengine v1.9.6/go.mod h1:jPp9T7Opvzl97qytaRGPwoH7pFI3GAcLDaui1K8PNjY= cloud.google.com/go/area120 v0.9.2 h1:LODm6TjW27/LJ4z4fBNJHRb+tlvy0gSu6Vb8j2lfluY= cloud.google.com/go/area120 v0.9.2/go.mod h1:Ar/KPx51UbrTWGVGgGzFnT7hFYQuk/0VOXkvHdTbQMI= -cloud.google.com/go/area120 v0.9.3/go.mod h1:F3vxS/+hqzrjJo55Xvda3Jznjjbd+4Foo43SN5eMd8M= +cloud.google.com/go/area120 v0.9.6 h1:iJrZ6AleZr4l+q0/fWVANFOhs90KiSB1Ccait5OYyNg= cloud.google.com/go/area120 v0.9.6/go.mod h1:qKSokqe0iTmwBDA3tbLWonMEnh0pMAH4YxiceiHUed4= cloud.google.com/go/artifactregistry v1.16.0 h1:BZpz0x8HCG7hwTkD+GlUwPQVFGOo9w84t8kxQwwc0DA= cloud.google.com/go/artifactregistry v1.16.0/go.mod h1:LunXo4u2rFtvJjrGjO0JS+Gs9Eco2xbZU6JVJ4+T8Sk= -cloud.google.com/go/artifactregistry v1.16.1/go.mod h1:sPvFPZhfMavpiongKwfg93EOwJ18Tnj9DIwTU9xWUgs= +cloud.google.com/go/artifactregistry v1.17.1 h1:A20kj2S2HO9vlyBVyVFHPxArjxkXvLP5LjcdE7NhaPc= cloud.google.com/go/artifactregistry v1.17.1/go.mod h1:06gLv5QwQPWtaudI2fWO37gfwwRUHwxm3gA8Fe568Hc= cloud.google.com/go/asset v1.20.3 h1:/jQBAkZVUbsIczRepDkwaf/K5NcRYvQ6MBiWg5i20fU= cloud.google.com/go/asset v1.20.3/go.mod h1:797WxTDwdnFAJzbjZ5zc+P5iwqXc13yO9DHhmS6wl+o= -cloud.google.com/go/asset v1.20.4/go.mod h1:DP09pZ+SoFWUZyPZx26xVroHk+6+9umnQv+01yfJxbM= +cloud.google.com/go/asset v1.21.1 h1:i55wWC/EwVdHMyJgRfbLp/L6ez4nQuOpZwSxkuqN9ek= cloud.google.com/go/asset v1.21.1/go.mod h1:7AzY1GCC+s1O73yzLM1IpHFLHz3ws2OigmCpOQHwebk= cloud.google.com/go/assuredworkloads v1.12.2 h1:6Y6a4V7CD50qtjvayhu7f5o35UFJP8ade7IbHNfdQEc= cloud.google.com/go/assuredworkloads v1.12.2/go.mod h1:/WeRr/q+6EQYgnoYrqCVgw7boMoDfjXZZev3iJxs2Iw= -cloud.google.com/go/assuredworkloads v1.12.3/go.mod h1:iGBkyMGdtlsxhCi4Ys5SeuvIrPTeI6HeuEJt7qJgJT8= +cloud.google.com/go/assuredworkloads v1.12.6 h1:ip/shfJYx6lrHBWYADjrrrubcm7uZzy50TTF5tPG7ek= cloud.google.com/go/assuredworkloads v1.12.6/go.mod h1:QyZHd7nH08fmZ+G4ElihV1zoZ7H0FQCpgS0YWtwjCKo= -cloud.google.com/go/auth v0.3.0/go.mod h1:lBv6NKTWp8E3LPzmO1TbiiRKc4drLOfHsgmlH9ogv5w= cloud.google.com/go/auth v0.13.0 h1:8Fu8TZy167JkW8Tj3q7dIkr2v4cndv41ouecJx0PAHs= cloud.google.com/go/auth v0.13.0/go.mod h1:COOjD9gwfKNKz+IIduatIhYJQIc0mG3H102r/EMxX6Q= -cloud.google.com/go/auth v0.14.0/go.mod h1:CYsoRL1PdiDuqeQpZE0bP2pnPrGqFcOkI0nldEQis+A= -cloud.google.com/go/auth v0.15.0/go.mod h1:WJDGqZ1o9E9wKIL+IwStfyn/+s59zl4Bi+1KQNVXLZ8= -cloud.google.com/go/auth v0.16.0/go.mod h1:1howDHJ5IETh/LwYs3ZxvlkXF48aSqqJUM+5o02dNOI= cloud.google.com/go/auth v0.16.2/go.mod h1:sRBas2Y1fB1vZTdurouM0AzuYQBMZinrUYL8EufhtEA= +cloud.google.com/go/auth v0.16.4 h1:fXOAIQmkApVvcIn7Pc2+5J8QTMVbUGLscnSVNl11su8= cloud.google.com/go/auth v0.16.4/go.mod h1:j10ncYwjX/g3cdX7GpEzsdM+d+ZNsXAbb6qXA7p1Y5M= -cloud.google.com/go/auth/oauth2adapt v0.2.2/go.mod h1:wcYjgpZI9+Yu7LyYBg4pqSiaRkfEK3GQcpb7C/uyF1Q= cloud.google.com/go/auth/oauth2adapt v0.2.6 h1:V6a6XDu2lTwPZWOawrAa9HUK+DB2zfJyTuciBG5hFkU= cloud.google.com/go/auth/oauth2adapt v0.2.6/go.mod h1:AlmsELtlEBnaNTL7jCj8VQFLy6mbZv0s4Q7NGBeQ5E8= -cloud.google.com/go/auth/oauth2adapt v0.2.7/go.mod h1:NTbTTzfvPl1Y3V1nPpOgl2w6d/FjO7NNUQaWSox6ZMc= +cloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIiLpZnkHRbnc= cloud.google.com/go/auth/oauth2adapt v0.2.8/go.mod h1:XQ9y31RkqZCcwJWNSx2Xvric3RrU88hAYYbjDWYDL+c= cloud.google.com/go/automl v1.14.2 h1:RzR5Nx78iaF2FNAfaaQ/7o2b4VuQ17YbOaeK/DLYSW4= cloud.google.com/go/automl v1.14.2/go.mod h1:mIat+Mf77W30eWQ/vrhjXsXaRh8Qfu4WiymR0hR6Uxk= -cloud.google.com/go/automl v1.14.4/go.mod h1:sVfsJ+g46y7QiQXpVs9nZ/h8ntdujHm5xhjHW32b3n4= +cloud.google.com/go/automl v1.14.7 h1:ZLj48Ur2Qcso4M3bgOtjsOmeV5Ee92N14wuOc8OW+L0= cloud.google.com/go/automl v1.14.7/go.mod h1:8a4XbIH5pdvrReOU72oB+H3pOw2JBxo9XTk39oljObE= cloud.google.com/go/baremetalsolution v1.3.2 h1:rhawlI+9gy/i1ZQbN/qL6FXHGXusWbfr6UoQdcCpybw= cloud.google.com/go/baremetalsolution v1.3.2/go.mod h1:3+wqVRstRREJV/puwaKAH3Pnn7ByreZG2aFRsavnoBQ= -cloud.google.com/go/baremetalsolution v1.3.3/go.mod h1:uF9g08RfmXTF6ZKbXxixy5cGMGFcG6137Z99XjxLOUI= +cloud.google.com/go/baremetalsolution v1.3.6 h1:9bdGlpY1LgLONQjFsDwrkjLzdPTlROpfU+GhA97YpOk= cloud.google.com/go/baremetalsolution v1.3.6/go.mod h1:7/CS0LzpLccRGO0HL3q2Rofxas2JwjREKut414sE9iM= cloud.google.com/go/batch v1.11.2 h1:OVhgpMMJc+mrFw51R3C06JKC0D6u125RlEBULpg78No= cloud.google.com/go/batch v1.11.2/go.mod h1:ehsVs8Y86Q4K+qhEStxICqQnNqH8cqgpCxx89cmU5h4= -cloud.google.com/go/batch v1.12.0/go.mod h1:CATSBh/JglNv+tEU/x21Z47zNatLQ/gpGnpyKOzbbcM= +cloud.google.com/go/batch v1.12.2 h1:gWQdvdPplptpvrkqF6ibtxZkOsYKLTFbxYawHa/TvCg= cloud.google.com/go/batch v1.12.2/go.mod h1:tbnuTN/Iw59/n1yjAYKV2aZUjvMM2VJqAgvUgft6UEU= cloud.google.com/go/beyondcorp v1.1.2 h1:hzKZf9ScvqTWqR8xGKVvD35ScQuxbMySELvJ0OW1usI= cloud.google.com/go/beyondcorp v1.1.2/go.mod h1:q6YWSkEsSZTU2WDt1qtz6P5yfv79wgktGtNbd0FJTLI= -cloud.google.com/go/beyondcorp v1.1.3/go.mod h1:3SlVKnlczNTSQFuH5SSyLuRd4KaBSc8FH/911TuF/Cc= +cloud.google.com/go/beyondcorp v1.1.6 h1:4FcR+4QmcNGkhVij6TrYS4AQVNLBo7PBXKxNrKzpclQ= cloud.google.com/go/beyondcorp v1.1.6/go.mod h1:V1PigSWPGh5L/vRRmyutfnjAbkxLI2aWqJDdxKbwvsQ= cloud.google.com/go/bigquery v1.64.0 h1:vSSZisNyhr2ioJE1OuYBQrnrpB7pIhRQm4jfjc7E/js= cloud.google.com/go/bigquery v1.64.0/go.mod h1:gy8Ooz6HF7QmA+TRtX8tZmXBKH5mCFBwUApGAb3zI7Y= -cloud.google.com/go/bigquery v1.66.2/go.mod h1:+Yd6dRyW8D/FYEjUGodIbu0QaoEmgav7Lwhotup6njo= +cloud.google.com/go/bigquery v1.69.0 h1:rZvHnjSUs5sHK3F9awiuFk2PeOaB8suqNuim21GbaTc= cloud.google.com/go/bigquery v1.69.0/go.mod h1:TdGLquA3h/mGg+McX+GsqG9afAzTAcldMjqhdjHTLew= cloud.google.com/go/bigtable v1.33.0 h1:2BDaWLRAwXO14DJL/u8crbV2oUbMZkIa2eGq8Yao1bk= cloud.google.com/go/bigtable v1.33.0/go.mod h1:HtpnH4g25VT1pejHRtInlFPnN5sjTxbQlsYBjh9t5l0= -cloud.google.com/go/bigtable v1.35.0/go.mod h1:EabtwwmTcOJFXp+oMZAT/jZkyDIjNwrv53TrS4DGrrM= +cloud.google.com/go/bigtable v1.37.0 h1:Q+x7y04lQ0B+WXp03wc1/FLhFt4CwcQdkwWT0M4Jp3w= cloud.google.com/go/bigtable v1.37.0/go.mod h1:HXqddP6hduwzrtiTCqZPpj9ij4hGZb4Zy1WF/dT+yaU= cloud.google.com/go/billing v1.19.2 h1:shcyz1UkrUxbPsqHL6L84ZdtBZ7yocaFFCxMInTsrNo= cloud.google.com/go/billing v1.19.2/go.mod h1:AAtih/X2nka5mug6jTAq8jfh1nPye0OjkHbZEZgU59c= -cloud.google.com/go/billing v1.20.1/go.mod h1:DhT80hUZ9gz5UqaxtK/LNoDELfxH73704VTce+JZqrY= +cloud.google.com/go/billing v1.20.4 h1:pqM5/c9UGydB9H90IPCxSvfCNLUPazAOSMsZkz5q5P4= cloud.google.com/go/billing v1.20.4/go.mod h1:hBm7iUmGKGCnBm6Wp439YgEdt+OnefEq/Ib9SlJYxIU= cloud.google.com/go/binaryauthorization v1.9.2 h1:zZX4cvtYSXc5ogOar1w5KA1BLz3j464RPSaR/HhroJ8= cloud.google.com/go/binaryauthorization v1.9.2/go.mod h1:T4nOcRWi2WX4bjfSRXJkUnpliVIqjP38V88Z10OvEv4= -cloud.google.com/go/binaryauthorization v1.9.3/go.mod h1:f3xcb/7vWklDoF+q2EaAIS+/A/e1278IgiYxonRX+Jk= +cloud.google.com/go/binaryauthorization v1.9.5 h1:T0zYEroXT+y0O/x/yZd5SwQdFv4UbUINjvJyJKzDm0Q= cloud.google.com/go/binaryauthorization v1.9.5/go.mod h1:CV5GkS2eiY461Bzv+OH3r5/AsuB6zny+MruRju3ccB8= cloud.google.com/go/certificatemanager v1.9.2 h1:/lO1ejN415kRaiO6DNNCHj0UvQujKP714q3l8gp4lsY= cloud.google.com/go/certificatemanager v1.9.2/go.mod h1:PqW+fNSav5Xz8bvUnJpATIRo1aaABP4mUg/7XIeAn6c= -cloud.google.com/go/certificatemanager v1.9.3/go.mod h1:O5T4Lg/dHbDHLFFooV2Mh/VsT3Mj2CzPEWRo4qw5prc= +cloud.google.com/go/certificatemanager v1.9.5 h1:+ZPglfDurCcsv4azizDFpBucD1IkRjWjbnU7zceyjfY= cloud.google.com/go/certificatemanager v1.9.5/go.mod h1:kn7gxT/80oVGhjL8rurMUYD36AOimgtzSBPadtAeffs= cloud.google.com/go/channel v1.19.1 h1:l4XcnfzJ5UGmqZQls0atcpD6ERDps4PLd5hXSyTWFv0= cloud.google.com/go/channel v1.19.1/go.mod h1:ungpP46l6XUeuefbA/XWpWWnAY3897CSRPXUbDstwUo= -cloud.google.com/go/channel v1.19.2/go.mod h1:syX5opXGXFt17DHCyCdbdlM464Tx0gHMi46UlEWY9Gg= +cloud.google.com/go/channel v1.19.5 h1:UI+ZsRkS15hi9DRF+WAvTVLVuSeZiRmvCU8cjkjOwUU= cloud.google.com/go/channel v1.19.5/go.mod h1:vevu+LK8Oy1Yuf7lcpDbkQQQm5I7oiY5fFTn3uwfQLY= cloud.google.com/go/cloudbuild v1.19.0 h1:Uo0bL251yvyWsNtO3Og9m5Z4S48cgGf3IUX7xzOcl8s= cloud.google.com/go/cloudbuild v1.19.0/go.mod h1:ZGRqbNMrVGhknIIjwASa6MqoRTOpXIVMSI+Ew5DMPuY= -cloud.google.com/go/cloudbuild v1.22.0/go.mod h1:p99MbQrzcENHb/MqU3R6rpqFRk/X+lNG3PdZEIhM95Y= +cloud.google.com/go/cloudbuild v1.22.2 h1:4LlrIFa3IFLgD1mGEXmUE4cm9fYoU71OLwTvjM7Dg3c= cloud.google.com/go/cloudbuild v1.22.2/go.mod h1:rPyXfINSgMqMZvuTk1DbZcbKYtvbYF/i9IXQ7eeEMIM= cloud.google.com/go/clouddms v1.8.2 h1:U53ztLRgTkclaxgmBBles+tv+nNcZ5fhbRbw3b2axFw= cloud.google.com/go/clouddms v1.8.2/go.mod h1:pe+JSp12u4mYOkwXpSMouyCCuQHL3a6xvWH2FgOcAt4= -cloud.google.com/go/clouddms v1.8.4/go.mod h1:RadeJ3KozRwy4K/gAs7W74ZU3GmGgVq5K8sRqNs3HfA= +cloud.google.com/go/clouddms v1.8.7 h1:IWJbQBEECTaNanDRN1XdR7FU53MJ1nylTl3s9T3MuyI= cloud.google.com/go/clouddms v1.8.7/go.mod h1:DhWLd3nzHP8GoHkA6hOhso0R9Iou+IGggNqlVaq/KZ4= +cloud.google.com/go/cloudsqlconn v1.18.0 h1:mP6TY/7I+nrnIh6vmbWCRJPxpFBZSL6AZhW6HaYC/OI= cloud.google.com/go/cloudsqlconn v1.18.0/go.mod h1:58bxZZ17Mz5D83ddMT8x6w56yKpcmVXyaOwGWkzGcMw= cloud.google.com/go/cloudtasks v1.13.2 h1:x6Qw5JyNbH3reL0arUtlYf77kK6OVjZZ//8JCvUkLro= cloud.google.com/go/cloudtasks v1.13.2/go.mod h1:2pyE4Lhm7xY8GqbZKLnYk7eeuh8L0JwAvXx1ecKxYu8= -cloud.google.com/go/cloudtasks v1.13.3/go.mod h1:f9XRvmuFTm3VhIKzkzLCPyINSU3rjjvFUsFVGR5wi24= +cloud.google.com/go/cloudtasks v1.13.6 h1:Fwan19UiNoFD+3KY0MnNHE5DyixOxNzS1mZ4ChOdpy0= cloud.google.com/go/cloudtasks v1.13.6/go.mod h1:/IDaQqGKMixD+ayM43CfsvWF2k36GeomEuy9gL4gLmU= cloud.google.com/go/compute v1.29.0 h1:Lph6d8oPi38NHkOr6S55Nus/Pbbcp37m/J0ohgKAefs= cloud.google.com/go/compute v1.29.0/go.mod h1:HFlsDurE5DpQZClAGf/cYh+gxssMhBxBovZDYkEn/Og= -cloud.google.com/go/compute v1.34.0/go.mod h1:zWZwtLwZQyonEvIQBuIa0WvraMYK69J5eDCOw9VZU4g= +cloud.google.com/go/compute v1.38.0 h1:MilCLYQW2m7Dku8hRIIKo4r0oKastlD74sSu16riYKs= cloud.google.com/go/compute v1.38.0/go.mod h1:oAFNIuXOmXbK/ssXm3z4nZB8ckPdjltJ7xhHCdbWFZM= cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= cloud.google.com/go/compute/metadata v0.6.0 h1:A6hENjEsCDtC1k8byVsgwvVcioamEHvZ4j01OwKxG9I= cloud.google.com/go/compute/metadata v0.6.0/go.mod h1:FjyFAW1MW0C203CEOMDTu3Dk1FlqW3Rga40jzHL4hfg= cloud.google.com/go/compute/metadata v0.7.0/go.mod h1:j5MvL9PprKL39t166CoB1uVHfQMs4tFQZZcKwksXUjo= +cloud.google.com/go/compute/metadata v0.8.0 h1:HxMRIbao8w17ZX6wBnjhcDkW6lTFpgcaobyVfZWqRLA= cloud.google.com/go/compute/metadata v0.8.0/go.mod h1:sYOGTp851OV9bOFJ9CH7elVvyzopvWQFNNghtDQ/Biw= cloud.google.com/go/contactcenterinsights v1.15.1 h1:cR/gQMweaG8RIWAlS5Jo1ARi8LUVQJ51t84EUefHeZ8= cloud.google.com/go/contactcenterinsights v1.15.1/go.mod h1:cFGxDVm/OwEVAHbU9UO4xQCtQFn0RZSrSUcF/oJ0Bbs= -cloud.google.com/go/contactcenterinsights v1.17.1/go.mod h1:n8OiNv7buLA2AkGVkfuvtW3HU13AdTmEwAlAu46bfxY= +cloud.google.com/go/contactcenterinsights v1.17.3 h1:lenyU3uzHwKDveCwmpfNxHYvLS3uEBWdn+O7+rSxy+Q= cloud.google.com/go/contactcenterinsights v1.17.3/go.mod h1:7Uu2CpxS3f6XxhRdlEzYAkrChpR5P5QfcdGAFEdHOG8= cloud.google.com/go/container v1.42.0 h1:sH9Hj9SoLeP+uKvLXc/04nWyWDiMo4Q85xfb1Nl5sAg= cloud.google.com/go/container v1.42.0/go.mod h1:YL6lDgCUi3frIWNIFU9qrmF7/6K1EYrtspmFTyyqJ+k= -cloud.google.com/go/container v1.42.2/go.mod h1:y71YW7uR5Ck+9Vsbst0AF2F3UMgqmsN4SP8JR9xEsR8= +cloud.google.com/go/container v1.43.0 h1:A6J92FJPfxTvyX7MHF+w4t2W9WCqvHOi9UB5SAeSy3w= cloud.google.com/go/container v1.43.0/go.mod h1:ETU9WZ1KM9ikEKLzrhRVao7KHtalDQu6aPqM34zDr/U= cloud.google.com/go/containeranalysis v0.13.2 h1:AG2gOcfZJFRiz+3SZCPnxU+gwbzKe++QSX/ej71Lom8= cloud.google.com/go/containeranalysis v0.13.2/go.mod h1:AiKvXJkc3HiqkHzVIt6s5M81wk+q7SNffc6ZlkTDgiE= -cloud.google.com/go/containeranalysis v0.13.3/go.mod h1:0SYnagA1Ivb7qPqKNYPkCtphhkJn3IzgaSp3mj+9XAY= +cloud.google.com/go/containeranalysis v0.14.1 h1:1SoHlNqL3XrhqcoozB+3eoHif2sRUFtp/JeASQTtGKo= cloud.google.com/go/containeranalysis v0.14.1/go.mod h1:28e+tlZgauWGHmEbnI5UfIsjMmrkoR1tFN0K2i71jBI= cloud.google.com/go/datacatalog v1.23.0 h1:9F2zIbWNNmtrSkPIyGRQNsIugG5VgVVFip6+tXSdWLg= cloud.google.com/go/datacatalog v1.23.0/go.mod h1:9Wamq8TDfL2680Sav7q3zEhBJSPBrDxJU8WtPJ25dBM= -cloud.google.com/go/datacatalog v1.24.3/go.mod h1:Z4g33XblDxWGHngDzcpfeOU0b1ERlDPTuQoYG6NkF1s= +cloud.google.com/go/datacatalog v1.26.0 h1:eFgygb3DTufTWWUB8ARk+dSuXz+aefNJXTlkWlQcWwE= cloud.google.com/go/datacatalog v1.26.0/go.mod h1:bLN2HLBAwB3kLTFT5ZKLHVPj/weNz6bR0c7nYp0LE14= cloud.google.com/go/dataflow v0.10.2 h1:o9P5/zR2mOYJmCnfp9/7RprKFZCwmSu3TvemQSmCaFM= cloud.google.com/go/dataflow v0.10.2/go.mod h1:+HIb4HJxDCZYuCqDGnBHZEglh5I0edi/mLgVbxDf0Ag= -cloud.google.com/go/dataflow v0.10.3/go.mod h1:5EuVGDh5Tg4mDePWXMMGAG6QYAQhLNyzxdNQ0A1FfW4= +cloud.google.com/go/dataflow v0.11.0 h1:AdhB4cAkMOC9NtrHJxpKOVvO/VqBLaIyk0tEEhbGjYM= cloud.google.com/go/dataflow v0.11.0/go.mod h1:gNHC9fUjlV9miu0hd4oQaXibIuVYTQvZhMdPievKsPk= cloud.google.com/go/dataform v0.10.2 h1:t16DoejuOHoxJR88qrpdmFFlCXA9+x5PKrqI9qiDYz0= cloud.google.com/go/dataform v0.10.2/go.mod h1:oZHwMBxG6jGZCVZqqMx+XWXK+dA/ooyYiyeRbUxI15M= -cloud.google.com/go/dataform v0.10.3/go.mod h1:8SruzxHYCxtvG53gXqDZvZCx12BlsUchuV/JQFtyTCw= +cloud.google.com/go/dataform v0.12.0 h1:0eCPTPUC/RZ863aVfXTJLkg0tEpdpn62VD6ywSmmzxM= cloud.google.com/go/dataform v0.12.0/go.mod h1:PuDIEY0lSVuPrZqcFji1fmr5RRvz3DGz4YP/cONc8g4= cloud.google.com/go/datafusion v1.8.2 h1:RPoHvIeXexXwlWhEU6DNgrYCh+C+FR2EXbrnMs2ptpI= cloud.google.com/go/datafusion v1.8.2/go.mod h1:XernijudKtVG/VEvxtLv08COyVuiYPraSxm+8hd4zXA= -cloud.google.com/go/datafusion v1.8.3/go.mod h1:hyglMzE57KRf0Rf/N2VRPcHCwKfZAAucx+LATY6Jc6Q= +cloud.google.com/go/datafusion v1.8.6 h1:GZ6J+CR8CEeWAj8luRCtr8GvImSQRkArIIqGiZOnzBA= cloud.google.com/go/datafusion v1.8.6/go.mod h1:fCyKJF2zUKC+O3hc2F9ja5EUCAbT4zcH692z8HiFZFw= cloud.google.com/go/datalabeling v0.9.2 h1:UesbU2kYIUWhHUcnFS86ANPbugEq98X9k1whTNcenlc= cloud.google.com/go/datalabeling v0.9.2/go.mod h1:8me7cCxwV/mZgYWtRAd3oRVGFD6UyT7hjMi+4GRyPpg= -cloud.google.com/go/datalabeling v0.9.3/go.mod h1:3LDFUgOx+EuNUzDyjU7VElO8L+b5LeaZEFA/ZU1O1XU= +cloud.google.com/go/datalabeling v0.9.6 h1:VOZ5U+78ttnhNCEID7qdeogqZQzK5N+LPHIQ9Q3YDsc= cloud.google.com/go/datalabeling v0.9.6/go.mod h1:n7o4x0vtPensZOoFwFa4UfZgkSZm8Qs0Pg/T3kQjXSM= cloud.google.com/go/dataplex v1.19.2 h1:R2xnsZnuWpHi2NmBR0e43GZk2IZcQ1AFEAo1fUI0xsw= cloud.google.com/go/dataplex v1.19.2/go.mod h1:vsxxdF5dgk3hX8Ens9m2/pMNhQZklUhSgqTghZtF1v4= -cloud.google.com/go/dataplex v1.22.0/go.mod h1:g166QMCGHvwc3qlTG4p34n+lHwu7JFfaNpMfI2uO7b8= +cloud.google.com/go/dataplex v1.25.3 h1:Xr0Toh6wyBlmL3H4EPu1YKwxUtkDSzzq+IP0iLc88kk= cloud.google.com/go/dataplex v1.25.3/go.mod h1:wOJXnOg6bem0tyslu4hZBTncfqcPNDpYGKzed3+bd+E= cloud.google.com/go/dataproc v1.12.0 h1:W47qHL3W4BPkAIbk4SWmIERwsWBaNnWm0P2sdx3YgGU= cloud.google.com/go/dataproc/v2 v2.10.0 h1:B0b7eLRXzFTzb4UaxkGGidIF23l/Xpyce28m1Q0cHmU= cloud.google.com/go/dataproc/v2 v2.10.0/go.mod h1:HD16lk4rv2zHFhbm8gGOtrRaFohMDr9f0lAUMLmg1PM= -cloud.google.com/go/dataproc/v2 v2.11.0/go.mod h1:9vgGrn57ra7KBqz+B2KD+ltzEXvnHAUClFgq/ryU99g= +cloud.google.com/go/dataproc/v2 v2.11.2 h1:KhC8wdLILpAs17yeTG6Miwg1v0nOP/OXD+9QNg3w6AQ= cloud.google.com/go/dataproc/v2 v2.11.2/go.mod h1:xwukBjtfiO4vMEa1VdqyFLqJmcv7t3lo+PbLDcTEw+g= cloud.google.com/go/dataqna v0.9.2 h1:hrEcid5jK5fEdlYZ0eS8HJoq+ZCTRWSV7Av42V/G994= cloud.google.com/go/dataqna v0.9.2/go.mod h1:WCJ7pwD0Mi+4pIzFQ+b2Zqy5DcExycNKHuB+VURPPgs= -cloud.google.com/go/dataqna v0.9.3/go.mod h1:PiAfkXxa2LZYxMnOWVYWz3KgY7txdFg9HEMQPb4u1JA= +cloud.google.com/go/dataqna v0.9.7 h1:qTRAG/E3T63Xj1orefRlwupfwH9c9ERUAnWSRGp75so= cloud.google.com/go/dataqna v0.9.7/go.mod h1:4ac3r7zm7Wqm8NAc8sDIDM0v7Dz7d1e/1Ka1yMFanUM= cloud.google.com/go/datastore v1.20.0 h1:NNpXoyEqIJmZFc0ACcwBEaXnmscUpcG4NkKnbCePmiM= cloud.google.com/go/datastore v1.20.0/go.mod h1:uFo3e+aEpRfHgtp5pp0+6M0o147KoPaYNaPAKpfh8Ew= cloud.google.com/go/datastream v1.11.2 h1:vgtrwwPfY7JFEDD0VARJK4qyiApnFnPkFRQVuczYb/w= cloud.google.com/go/datastream v1.11.2/go.mod h1:RnFWa5zwR5SzHxeZGJOlQ4HKBQPcjGfD219Qy0qfh2k= -cloud.google.com/go/datastream v1.13.0/go.mod h1:GrL2+KC8mV4GjbVG43Syo5yyDXp3EH+t6N2HnZb1GOQ= +cloud.google.com/go/datastream v1.14.1 h1:j+y0lUKm9pbDjJn0YcWxPI/hXNGUQ80GE6yrFuJC/JA= cloud.google.com/go/datastream v1.14.1/go.mod h1:JqMKXq/e0OMkEgfYe0nP+lDye5G2IhIlmencWxmesMo= cloud.google.com/go/deploy v1.25.0 h1:nYLFG2TSsYMJuengVru5P8iWnA5mNA4rKFV5YoOWQ3M= cloud.google.com/go/deploy v1.25.0/go.mod h1:h9uVCWxSDanXUereI5WR+vlZdbPJ6XGy+gcfC25v5rM= -cloud.google.com/go/deploy v1.26.2/go.mod h1:XpS3sG/ivkXCfzbzJXY9DXTeCJ5r68gIyeOgVGxGNEs= +cloud.google.com/go/deploy v1.27.2 h1:C0VqBhFyQFp6+xgPHZAD7LeRA4XGy5YLzGmPQ2NhlLk= cloud.google.com/go/deploy v1.27.2/go.mod h1:4NHWE7ENry2A4O1i/4iAPfXHnJCZ01xckAKpZQwhg1M= cloud.google.com/go/dialogflow v1.60.0 h1:H+Q1SUeVU2La0Y0ZGEaKkhEXg3bj9Ceg5YKcMbyNOEc= cloud.google.com/go/dialogflow v1.60.0/go.mod h1:PjsrI+d2FI4BlGThxL0+Rua/g9vLI+2A1KL7s/Vo3pY= -cloud.google.com/go/dialogflow v1.66.0/go.mod h1:BPiRTnnXP/tHLot5h/U62Xcp+i6ekRj/bq6uq88p+Lw= +cloud.google.com/go/dialogflow v1.68.2 h1:bXpoqPRf37KKxB79PKr20B/TAU/Z5iA0FnB6C5N2jrA= cloud.google.com/go/dialogflow v1.68.2/go.mod h1:E0Ocrhf5/nANZzBju8RX8rONf0PuIvz2fVj3XkbAhiY= cloud.google.com/go/dlp v1.20.0 h1:Wwz1FoZp3pyrTNkS5fncaAccP/AbqzLQuN5WMi3aVYQ= cloud.google.com/go/dlp v1.20.0/go.mod h1:nrGsA3r8s7wh2Ct9FWu69UjBObiLldNyQda2RCHgdaY= -cloud.google.com/go/dlp v1.21.0/go.mod h1:Y9HOVtPoArpL9sI1O33aN/vK9QRwDERU9PEJJfM8DvE= +cloud.google.com/go/dlp v1.23.0 h1:3xWRKylXxhysaQaV+DLev1YcIywFUCc7yJEE6R7ZGDQ= cloud.google.com/go/dlp v1.23.0/go.mod h1:vVT4RlyPMEMcVHexdPT6iMVac3seq3l6b8UPdYpgFrg= cloud.google.com/go/documentai v1.35.0 h1:DO4ut86a+Xa0gBq7j3FZJPavnKBNoznrg44csnobqIY= cloud.google.com/go/documentai v1.35.0/go.mod h1:ZotiWUlDE8qXSUqkJsGMQqVmfTMYATwJEYqbPXTR9kk= -cloud.google.com/go/documentai v1.35.2/go.mod h1:oh/0YXosgEq3hVhyH4ZQ7VNXPaveRO4eLVM3tBSZOsI= +cloud.google.com/go/documentai v1.37.0 h1:7fla8GcarupO15eatRTUveXCob6DOSW1Wa+1i63CM3Q= cloud.google.com/go/documentai v1.37.0/go.mod h1:qAf3ewuIUJgvSHQmmUWvM3Ogsr5A16U2WPHmiJldvLA= cloud.google.com/go/domains v0.10.2 h1:ekJCkuzbciXyPKkwPwvI+2Ov1GcGJtMXj/fbgilPFqg= cloud.google.com/go/domains v0.10.2/go.mod h1:oL0Wsda9KdJvvGNsykdalHxQv4Ri0yfdDkIi3bzTUwk= -cloud.google.com/go/domains v0.10.3/go.mod h1:m7sLe18p0PQab56bVH3JATYOJqyRHhmbye6gz7isC7o= +cloud.google.com/go/domains v0.10.6 h1:TI+Aavwc31KD8huOquJz0ISchCq1zSEWc9M+JcPJyxc= cloud.google.com/go/domains v0.10.6/go.mod h1:3xzG+hASKsVBA8dOPc4cIaoV3OdBHl1qgUpAvXK7pGY= cloud.google.com/go/edgecontainer v1.4.0 h1:vpKTEkQPpkl55d6aUU2rzDFvTkMUATvBXfZSlI2KMR0= cloud.google.com/go/edgecontainer v1.4.0/go.mod h1:Hxj5saJT8LMREmAI9tbNTaBpW5loYiWFyisCjDhzu88= -cloud.google.com/go/edgecontainer v1.4.1/go.mod h1:ubMQvXSxsvtEjJLyqcPFrdWrHfvjQxdoyt+SUrAi5ek= +cloud.google.com/go/edgecontainer v1.4.3 h1:9tfGCicvrki927T+hGMB0yYmwIbRuZY6JR1/awrKiZ0= cloud.google.com/go/edgecontainer v1.4.3/go.mod h1:q9Ojw2ox0uhAvFisnfPRAXFTB1nfRIOIXVWzdXMZLcE= cloud.google.com/go/errorreporting v0.3.1 h1:E/gLk+rL7u5JZB9oq72iL1bnhVlLrnfslrgcptjJEUE= cloud.google.com/go/errorreporting v0.3.1/go.mod h1:6xVQXU1UuntfAf+bVkFk6nld41+CPyF2NSPCyXE3Ztk= +cloud.google.com/go/errorreporting v0.3.2 h1:isaoPwWX8kbAOea4qahcmttoS79+gQhvKsfg5L5AgH8= cloud.google.com/go/errorreporting v0.3.2/go.mod h1:s5kjs5r3l6A8UUyIsgvAhGq6tkqyBCUss0FRpsoVTww= cloud.google.com/go/essentialcontacts v1.7.2 h1:a/reGTn7WblM5DgieiLbX6CswHgTneWrA4ZNS5E+1Bg= cloud.google.com/go/essentialcontacts v1.7.2/go.mod h1:NoCBlOIVteJFJU+HG9dIG/Cc9kt1K9ys9mbOaGPUmPc= -cloud.google.com/go/essentialcontacts v1.7.3/go.mod h1:uimfZgDbhWNCmBpwUUPHe4vcMY2azsq/axC9f7vZFKI= +cloud.google.com/go/essentialcontacts v1.7.6 h1:ysHZ4gr4plW1CL1Ur/AucUUfh20hDjSFbfjxSK0q/sk= cloud.google.com/go/essentialcontacts v1.7.6/go.mod h1:/Ycn2egr4+XfmAfxpLYsJeJlVf9MVnq9V7OMQr9R4lA= cloud.google.com/go/eventarc v1.15.0 h1:IVU2EOR8P2f6N8eneuwspN122LR87v9G54B+7ihd1TY= cloud.google.com/go/eventarc v1.15.0/go.mod h1:PAd/pPIZdJtJQFJI1yDEUms1mqohdNuM1BFEVHHlVFg= -cloud.google.com/go/eventarc v1.15.1/go.mod h1:K2luolBpwaVOujZQyx6wdG4n2Xum4t0q1cMBmY1xVyI= +cloud.google.com/go/eventarc v1.15.5 h1:bZW7ZMM+XXNErg6rOZcgxUzAgz4vpReRDP3ZiGf7/sI= cloud.google.com/go/eventarc v1.15.5/go.mod h1:vDCqGqyY7SRiickhEGt1Zhuj81Ya4F/NtwwL3OZNskg= cloud.google.com/go/filestore v1.9.2 h1:DYwMNAcF5bELHHMxRdkIWWZ3XicKp+ZpEBy+c6Gt4uY= cloud.google.com/go/filestore v1.9.2/go.mod h1:I9pM7Hoetq9a7djC1xtmtOeHSUYocna09ZP6x+PG1Xw= -cloud.google.com/go/filestore v1.9.3/go.mod h1:Me0ZRT5JngT/aZPIKpIK6N4JGMzrFHRtGHd9ayUS4R4= +cloud.google.com/go/filestore v1.10.2 h1:LjoAyp9TvVNBns3sUUzPaNsQiGpR2BReGmTS3bUCuBE= cloud.google.com/go/filestore v1.10.2/go.mod h1:w0Pr8uQeSRQfCPRsL0sYKW6NKyooRgixCkV9yyLykR4= cloud.google.com/go/firestore v1.17.0 h1:iEd1LBbkDZTFsLw3sTH50eyg4qe8eoG6CjocmEXO9aQ= cloud.google.com/go/firestore v1.17.0/go.mod h1:69uPx1papBsY8ZETooc71fOhoKkD70Q1DwMrtKuOT/Y= +cloud.google.com/go/firestore v1.18.0 h1:cuydCaLS7Vl2SatAeivXyhbhDEIR8BDmtn4egDhIn2s= cloud.google.com/go/firestore v1.18.0/go.mod h1:5ye0v48PhseZBdcl0qbl3uttu7FIEwEYVaWm0UIEOEU= cloud.google.com/go/functions v1.19.2 h1:Cu2Gj1JBBJv9gi89r8LrZNsJhGwePnhttn4Blqw/EYI= cloud.google.com/go/functions v1.19.2/go.mod h1:SBzWwWuaFDLnUyStDAMEysVN1oA5ECLbP3/PfJ9Uk7Y= -cloud.google.com/go/functions v1.19.3/go.mod h1:nOZ34tGWMmwfiSJjoH/16+Ko5106x+1Iji29wzrBeOo= +cloud.google.com/go/functions v1.19.6 h1:vJgWlvxtJG6p/JrbXAkz83DbgwOyFhZZI1Y32vUddjY= cloud.google.com/go/functions v1.19.6/go.mod h1:0G0RnIlbM4MJEycfbPZlCzSf2lPOjL7toLDwl+r0ZBw= cloud.google.com/go/gaming v1.9.0 h1:7vEhFnZmd931Mo7sZ6pJy7uQPDxF7m7v8xtBheG08tc= cloud.google.com/go/gkebackup v1.6.2 h1:lWaSgjSonOXe41UhwQjts6lhDZdr5e882LNUTtnjZS0= cloud.google.com/go/gkebackup v1.6.2/go.mod h1:WsTSWqKJkGan1pkp5dS30oxb+Eaa6cLvxEUxKTUALwk= -cloud.google.com/go/gkebackup v1.6.3/go.mod h1:JJzGsA8/suXpTDtqI7n9RZW97PXa2CIp+n8aRC/y57k= +cloud.google.com/go/gkebackup v1.8.0 h1:eBqOt61yEChvj7I/GDPBbdCCRdUPudD1qrQYfYWV3Ok= cloud.google.com/go/gkebackup v1.8.0/go.mod h1:FjsjNldDilC9MWKEHExnK3kKJyTDaSdO1vF0QeWSOPU= cloud.google.com/go/gkeconnect v0.12.0 h1:MuA3/aIuncXkXuUDGdbT7OLnIp7xpFhciuHAnQaoQz4= cloud.google.com/go/gkeconnect v0.12.0/go.mod h1:zn37LsFiNZxPN4iO7YbUk8l/E14pAJ7KxpoXoxt7Ly0= -cloud.google.com/go/gkeconnect v0.12.1/go.mod h1:L1dhGY8LjINmWfR30vneozonQKRSIi5DWGIHjOqo58A= +cloud.google.com/go/gkeconnect v0.12.4 h1:67/rnPmF/I1Wmf7jWyKH+z4OWjU8ZUI0Vmzxvmzf3KY= cloud.google.com/go/gkeconnect v0.12.4/go.mod h1:bvpU9EbBpZnXGo3nqJ1pzbHWIfA9fYqgBMJ1VjxaZdk= cloud.google.com/go/gkehub v0.15.2 h1:CR5MPEP/Ogk5IahCq3O2fKS6TJZQi8mrnrysGHCs0g8= cloud.google.com/go/gkehub v0.15.2/go.mod h1:8YziTOpwbM8LM3r9cHaOMy2rNgJHXZCrrmGgcau9zbQ= -cloud.google.com/go/gkehub v0.15.3/go.mod h1:nzFT/Q+4HdQES/F+FP1QACEEWR9Hd+Sh00qgiH636cU= +cloud.google.com/go/gkehub v0.15.6 h1:9iogrmNNa+drDPf/zkLH/6KGgUf7FuuyokmithoGwMQ= cloud.google.com/go/gkehub v0.15.6/go.mod h1:sRT0cOPAgI1jUJrS3gzwdYCJ1NEzVVwmnMKEwrS2QaM= cloud.google.com/go/gkemulticloud v1.4.1 h1:SvVD2nJTGScEDYygIQ5dI14oFYhgtJx8HazkT3aufEI= cloud.google.com/go/gkemulticloud v1.4.1/go.mod h1:KRvPYcx53bztNwNInrezdfNF+wwUom8Y3FuJBwhvFpQ= -cloud.google.com/go/gkemulticloud v1.5.1/go.mod h1:OdmhfSPXuJ0Kn9dQ2I3Ou7XZ3QK8caV4XVOJZwrIa3s= +cloud.google.com/go/gkemulticloud v1.5.3 h1:334aZmOzIt3LVBpguCof8IHaLaftcZlx+L0TGBukYkY= cloud.google.com/go/gkemulticloud v1.5.3/go.mod h1:KPFf+/RcfvmuScqwS9/2MF5exZAmXSuoSLPuaQ98Xlk= cloud.google.com/go/grafeas v0.3.11 h1:CobnwnyeY1j1Defi5vbEircI+jfrk3ci5m004ZjiFP4= cloud.google.com/go/grafeas v0.3.11/go.mod h1:dcQyG2+T4tBgG0MvJAh7g2wl/xHV2w+RZIqivwuLjNg= +cloud.google.com/go/grafeas v0.3.15 h1:lBjwKmhpiqOAFaE0xdqF8CqO74a99s8tUT5mCkBBxPs= cloud.google.com/go/grafeas v0.3.15/go.mod h1:irwcwIQOBlLBotGdMwme8PipnloOPqILfIvMwlmu8Pk= cloud.google.com/go/gsuiteaddons v1.7.2 h1:Rma+a2tCB2PV0Rm87Ywr4P96dCwGIm8vw8gF23ZlYoY= cloud.google.com/go/gsuiteaddons v1.7.2/go.mod h1:GD32J2rN/4APilqZw4JKmwV84+jowYYMkEVwQEYuAWc= -cloud.google.com/go/gsuiteaddons v1.7.4/go.mod h1:gpE2RUok+HUhuK7RPE/fCOEgnTffS0lCHRaAZLxAMeE= +cloud.google.com/go/gsuiteaddons v1.7.7 h1:sk0SxpCGIA7tIO//XdiiG29f2vrF6Pq/dsxxyBGiRBY= cloud.google.com/go/gsuiteaddons v1.7.7/go.mod h1:zTGmmKG/GEBCONsvMOY2ckDiEsq3FN+lzWGUiXccF9o= cloud.google.com/go/iam v1.2.2 h1:ozUSofHUGf/F4tCNy/mu9tHLTaxZFLOUiKzjcgWHGIA= cloud.google.com/go/iam v1.2.2/go.mod h1:0Ys8ccaZHdI1dEUilwzqng/6ps2YB6vRsjIe00/+6JY= -cloud.google.com/go/iam v1.4.0/go.mod h1:gMBgqPaERlriaOV0CUl//XUzDhSfXevn4OEUbg6VRs4= -cloud.google.com/go/iam v1.5.0/go.mod h1:U+DOtKQltF/LxPEtcDLoobcsZMilSRwR7mgNL7knOpo= +cloud.google.com/go/iam v1.5.2 h1:qgFRAGEmd8z6dJ/qyEchAuL9jpswyODjA2lS+w234g8= cloud.google.com/go/iam v1.5.2/go.mod h1:SE1vg0N81zQqLzQEwxL2WI6yhetBdbNQuTvIKCSkUHE= cloud.google.com/go/iap v1.10.2 h1:rvM+FNIF2wIbwUU8299FhhVGak2f7oOvbW8J/I5oflE= cloud.google.com/go/iap v1.10.2/go.mod h1:cClgtI09VIfazEK6VMJr6bX8KQfuQ/D3xqX+d0wrUlI= -cloud.google.com/go/iap v1.10.3/go.mod h1:xKgn7bocMuCFYhzRizRWP635E2LNPnIXT7DW0TlyPJ8= +cloud.google.com/go/iap v1.11.2 h1:VIioCrYsyWiRGx7Y8RDNylpI6d4t1Qx5ZgSLUVmWWPo= cloud.google.com/go/iap v1.11.2/go.mod h1:Bh99DMUpP5CitL9lK0BC8MYgjjYO4b3FbyhgW1VHJvg= cloud.google.com/go/ids v1.5.2 h1:EDYZQraE+Eq6BewUQxVRY8b3VUUo/MnjMfzSh1NGjx8= cloud.google.com/go/ids v1.5.2/go.mod h1:P+ccDD96joXlomfonEdCnyrHvE68uLonc7sJBPVM5T0= -cloud.google.com/go/ids v1.5.3/go.mod h1:a2MX8g18Eqs7yxD/pnEdid42SyBUm9LIzSWf8Jux9OY= +cloud.google.com/go/ids v1.5.6 h1:uKGuaWozDcjg3wyf54Gd7tCH2YK8BFeH9qo1xBNiPKE= cloud.google.com/go/ids v1.5.6/go.mod h1:y3SGLmEf9KiwKsH7OHvYYVNIJAtXybqsD2z8gppsziQ= cloud.google.com/go/iot v1.8.2 h1:KMN0wujrPV7q0yfs4rt5CUl9Di8sQhJ0uohJn1h6yaI= cloud.google.com/go/iot v1.8.2/go.mod h1:UDwVXvRD44JIcMZr8pzpF3o4iPsmOO6fmbaIYCAg1ww= -cloud.google.com/go/iot v1.8.3/go.mod h1:dYhrZh+vUxIQ9m3uajyKRSW7moF/n0rYmA2PhYAkMFE= +cloud.google.com/go/iot v1.8.6 h1:A3AhugnIViAZkC3/lHAQDaXBIk2ZOPBZS0XQCyZsjjc= cloud.google.com/go/iot v1.8.6/go.mod h1:MThnkiihNkMysWNeNje2Hp0GSOpEq2Wkb/DkBCVYa0U= cloud.google.com/go/kms v1.20.1 h1:og29Wv59uf2FVaZlesaiDAqHFzHaoUyHI3HYp9VUHVg= cloud.google.com/go/kms v1.20.1/go.mod h1:LywpNiVCvzYNJWS9JUcGJSVTNSwPwi0vBAotzDqn2nc= -cloud.google.com/go/kms v1.21.0/go.mod h1:zoFXMhVVK7lQ3JC9xmhHMoQhnjEDZFoLAr5YMwzBLtk= +cloud.google.com/go/kms v1.22.0 h1:dBRIj7+GDeeEvatJeTB19oYZNV0aj6wEqSIT/7gLqtk= cloud.google.com/go/kms v1.22.0/go.mod h1:U7mf8Sva5jpOb4bxYZdtw/9zsbIjrklYwPcvMk34AL8= cloud.google.com/go/language v1.14.2 h1:rwrIOwcAgPTYbigOaiMSjKCvBy0xHZJbRc7HB/xMECA= cloud.google.com/go/language v1.14.2/go.mod h1:dviAbkxT9art+2ioL9AM05t+3Ql6UPfMpwq1cDsF+rg= -cloud.google.com/go/language v1.14.3/go.mod h1:hjamj+KH//QzF561ZuU2J+82DdMlFUjmiGVWpovGGSA= +cloud.google.com/go/language v1.14.5 h1:BVJ/POtlnJ55LElvnQY19UOxpMVtHoHHkFJW2uHJsVU= cloud.google.com/go/language v1.14.5/go.mod h1:nl2cyAVjcBct1Hk73tzxuKebk0t2eULFCaruhetdZIA= cloud.google.com/go/lifesciences v0.10.2 h1:eZSaRgBwbnb/oXwCj1SGE0Kp534DuXpg55iYBWgN024= cloud.google.com/go/lifesciences v0.10.2/go.mod h1:vXDa34nz0T/ibUNoeHnhqI+Pn0OazUTdxemd0OLkyoY= -cloud.google.com/go/lifesciences v0.10.3/go.mod h1:hnUUFht+KcZcliixAg+iOh88FUwAzDQQt5tWd7iIpNg= +cloud.google.com/go/lifesciences v0.10.6 h1:Vu7XF4s5KJ8+mSLIL4eaQM6JTyWXvSB54oqC+CUZH20= cloud.google.com/go/lifesciences v0.10.6/go.mod h1:1nnZwaZcBThDujs9wXzECnd1S5d+UiDkPuJWAmhRi7Q= cloud.google.com/go/logging v1.12.0 h1:ex1igYcGFd4S/RZWOCU51StlIEuey5bjqwH9ZYjHibk= cloud.google.com/go/logging v1.12.0/go.mod h1:wwYBt5HlYP1InnrtYI0wtwttpVU1rifnMT7RejksUAM= +cloud.google.com/go/logging v1.13.0 h1:7j0HgAp0B94o1YRDqiqm26w4q1rDMH7XNRU34lJXHYc= cloud.google.com/go/logging v1.13.0/go.mod h1:36CoKh6KA/M0PbhPKMq6/qety2DCAErbhXT62TuXALA= -cloud.google.com/go/longrunning v0.5.6/go.mod h1:vUaDrWYOMKRuhiv6JBnn49YxCPz2Ayn9GqyjaBT8/mA= cloud.google.com/go/longrunning v0.6.2 h1:xjDfh1pQcWPEvnfjZmwjKQEcHnpz6lHjfy7Fo0MK+hc= cloud.google.com/go/longrunning v0.6.2/go.mod h1:k/vIs83RN4bE3YCswdXC5PFfWVILjm3hpEUlSko4PiI= -cloud.google.com/go/longrunning v0.6.4/go.mod h1:ttZpLCe6e7EXvn9OxpBRx7kZEB0efv8yBO6YnVMfhJs= -cloud.google.com/go/longrunning v0.6.6/go.mod h1:hyeGJUrPHcx0u2Uu1UFSoYZLn4lkMrccJig0t4FI7yw= +cloud.google.com/go/longrunning v0.6.7 h1:IGtfDWHhQCgCjwQjV9iiLnUta9LBCo8R9QmAFsS/PrE= cloud.google.com/go/longrunning v0.6.7/go.mod h1:EAFV3IZAKmM56TyiE6VAP3VoTzhZzySwI/YI1s/nRsY= cloud.google.com/go/managedidentities v1.7.2 h1:oWxuIhIwQC1Vfs1SZi1x389W2TV9uyPsAyZMJgZDND4= cloud.google.com/go/managedidentities v1.7.2/go.mod h1:t0WKYzagOoD3FNtJWSWcU8zpWZz2i9cw2sKa9RiPx5I= -cloud.google.com/go/managedidentities v1.7.3/go.mod h1:H9hO2aMkjlpY+CNnKWRh+WoQiUIDO8457wWzUGsdtLA= +cloud.google.com/go/managedidentities v1.7.6 h1:zrZVWXZJlmHnfpyCrTQIbDBGUBHrcOOvrsjMjoXRxrk= cloud.google.com/go/managedidentities v1.7.6/go.mod h1:pYCWPaI1AvR8Q027Vtp+SFSM/VOVgbjBF4rxp1/z5p4= cloud.google.com/go/maps v1.15.0 h1:bmFHlO6BL/smC6GD45r5j0ChjsyyevuJCSARdOL62TI= cloud.google.com/go/maps v1.15.0/go.mod h1:ZFqZS04ucwFiHSNU8TBYDUr3wYhj5iBFJk24Ibvpf3o= -cloud.google.com/go/maps v1.19.0/go.mod h1:goHUXrmzoZvQjUVd0KGhH8t3AYRm17P8b+fsyR1UAmQ= +cloud.google.com/go/maps v1.21.0 h1:El61AfMxC1sU/RU8Wzs9dkZEgltyunKM86aKF9aDlaE= cloud.google.com/go/maps v1.21.0/go.mod h1:cqzZ7+DWUKKbPTgqE+KuNQtiCRyg/o7WZF9zDQk+HQs= cloud.google.com/go/mediatranslation v0.9.2 h1:p37R/k9+L33bUMO87gFyv93MwJ+9nuzVhXM5X+6ULwA= cloud.google.com/go/mediatranslation v0.9.2/go.mod h1:1xyRoDYN32THzy+QaU62vIMciX0CFexplju9t30XwUc= -cloud.google.com/go/mediatranslation v0.9.3/go.mod h1:KTrFV0dh7duYKDjmuzjM++2Wn6yw/I5sjZQVV5k3BAA= +cloud.google.com/go/mediatranslation v0.9.6 h1:SDGatA73TgZ8iCvILVXpk/1qhTK5DJyufUDEWgbmbV8= cloud.google.com/go/mediatranslation v0.9.6/go.mod h1:WS3QmObhRtr2Xu5laJBQSsjnWFPPthsyetlOyT9fJvE= cloud.google.com/go/memcache v1.11.2 h1:GGgC2A9AClJN8VLbMUAPUxj/dNMFwz6Lj01gDxPw7os= cloud.google.com/go/memcache v1.11.2/go.mod h1:jIzHn79b0m5wbkax2SdlW5vNSbpaEk0yWHbeLpMIYZE= -cloud.google.com/go/memcache v1.11.3/go.mod h1:UeWI9cmY7hvjU1EU6dwJcQb6EFG4GaM3KNXOO2OFsbI= +cloud.google.com/go/memcache v1.11.6 h1:33IVqQEmFiITsBXwGHeTkUhWz0kLNKr90nV3e22uLPs= cloud.google.com/go/memcache v1.11.6/go.mod h1:ZM6xr1mw3F8TWO+In7eq9rKlJc3jlX2MDt4+4H+/+cc= cloud.google.com/go/metastore v1.14.2 h1:Euc9kLTKS8T6M1JVqQavwDFHu9UtT1//lGXSKjpO3/0= cloud.google.com/go/metastore v1.14.2/go.mod h1:dk4zOBhZIy3TFOQlI8sbOa+ef0FjAcCHEnd8dO2J+LE= -cloud.google.com/go/metastore v1.14.3/go.mod h1:HlbGVOvg0ubBLVFRk3Otj3gtuzInuzO/TImOBwsKlG4= +cloud.google.com/go/metastore v1.14.7 h1:dLm59AHHZCorveCylj7c2iWhkQsmMIeWTsV+tG/BXtY= cloud.google.com/go/metastore v1.14.7/go.mod h1:0dka99KQofeUgdfu+K/Jk1KeT9veWZlxuZdJpZPtuYU= cloud.google.com/go/monitoring v1.21.2 h1:FChwVtClH19E7pJ+e0xUhJPGksctZNVOk2UhMmblmdU= cloud.google.com/go/monitoring v1.21.2/go.mod h1:hS3pXvaG8KgWTSz+dAdyzPrGUYmi2Q+WFX8g2hqVEZU= -cloud.google.com/go/monitoring v1.22.1/go.mod h1:AuZZXAoN0WWWfsSvET1Cpc4/1D8LXq8KRDU87fMS6XY= -cloud.google.com/go/monitoring v1.24.0/go.mod h1:Bd1PRK5bmQBQNnuGwHBfUamAV1ys9049oEPHnn4pcsc= +cloud.google.com/go/monitoring v1.24.2 h1:5OTsoJ1dXYIiMiuL+sYscLc9BumrL3CarVLL7dd7lHM= cloud.google.com/go/monitoring v1.24.2/go.mod h1:x7yzPWcgDRnPEv3sI+jJGBkwl5qINf+6qY4eq0I9B4U= cloud.google.com/go/networkconnectivity v1.15.2 h1:CuBLrRKhPbzXkFGADopQUpMcdY+SSfoy/3RqsMH2pq4= cloud.google.com/go/networkconnectivity v1.15.2/go.mod h1:N1O01bEk5z9bkkWwXLKcN2T53QN49m/pSpjfUvlHDQY= -cloud.google.com/go/networkconnectivity v1.16.1/go.mod h1:GBC1iOLkblcnhcnfRV92j4KzqGBrEI6tT7LP52nZCTk= +cloud.google.com/go/networkconnectivity v1.17.1 h1:RQcG1rZNCNV5Dn3tnINs4TYswDXk2hKH+85eh+JvoWU= cloud.google.com/go/networkconnectivity v1.17.1/go.mod h1:DTZCq8POTkHgAlOAAEDQF3cMEr/B9k1ZbpklqvHEBtg= cloud.google.com/go/networkmanagement v1.16.0 h1:oT7c2Oo9NT54XjnP4GMNj/HEywrFnBz0u6QLJ2iu8NE= cloud.google.com/go/networkmanagement v1.16.0/go.mod h1:Yc905R9U5jik5YMt76QWdG5WqzPU4ZsdI/mLnVa62/Q= -cloud.google.com/go/networkmanagement v1.18.0/go.mod h1:yTxpAFuvQOOKgL3W7+k2Rp1bSKTxyRcZ5xNHGdHUM6w= +cloud.google.com/go/networkmanagement v1.19.1 h1:ecukgArkYCVcK5w2h7WDDd+nHgmBAp9Bst7ClmVKz5A= cloud.google.com/go/networkmanagement v1.19.1/go.mod h1:icgk265dNnilxQzpr6rO9WuAuuCmUOqq9H6WBeM2Af4= cloud.google.com/go/networksecurity v0.10.2 h1://zFZM8XZZs+3Y6QKuLqwD5tZ+B/17KUo/rJpGW2tJs= cloud.google.com/go/networksecurity v0.10.2/go.mod h1:puU3Gwchd6Y/VTyMkL50GI2RSRMS3KXhcDBY1HSOcck= -cloud.google.com/go/networksecurity v0.10.3/go.mod h1:G85ABVcPscEgpw+gcu+HUxNZJWjn3yhTqEU7+SsltFM= +cloud.google.com/go/networksecurity v0.10.6 h1:6b6fcCG9BFNcmtNO+VuPE04vkZb5TKNX9+7ZhYMgstE= cloud.google.com/go/networksecurity v0.10.6/go.mod h1:FTZvabFPvK2kR/MRIH3l/OoQ/i53eSix2KA1vhBMJec= cloud.google.com/go/notebooks v1.12.2 h1:BHIH9kf/02wSCcLAVttEXHSFAgSotgRg2y1YjR7VDCc= cloud.google.com/go/notebooks v1.12.2/go.mod h1:EkLwv8zwr8DUXnvzl944+sRBG+b73HEKzV632YYAGNI= -cloud.google.com/go/notebooks v1.12.3/go.mod h1:I0pMxZct+8Rega2LYrXL8jGAGZgLchSmh8Ksc+0xNyA= +cloud.google.com/go/notebooks v1.12.6 h1:nCfZwVihArMPP2atRoxRrXOXJ/aC9rAgpBQGCc2zpYw= cloud.google.com/go/notebooks v1.12.6/go.mod h1:3Z4TMEqAKP3pu6DI/U+aEXrNJw9hGZIVbp+l3zw8EuA= cloud.google.com/go/optimization v1.7.2 h1:yM4teRB60qyIm8cV4VRW4wepmHbXCoqv3QKGfKzylEQ= cloud.google.com/go/optimization v1.7.2/go.mod h1:msYgDIh1SGSfq6/KiWJQ/uxMkWq8LekPyn1LAZ7ifNE= -cloud.google.com/go/optimization v1.7.3/go.mod h1:GlYFp4Mju0ybK5FlOUtV6zvWC00TIScdbsPyF6Iv144= +cloud.google.com/go/optimization v1.7.6 h1:jDvIuSxDsXI2P7l2sYXm6CoX1YBIIT6Khm5m0hq0/KQ= cloud.google.com/go/optimization v1.7.6/go.mod h1:4MeQslrSJGv+FY4rg0hnZBR/tBX2awJ1gXYp6jZpsYY= cloud.google.com/go/orchestration v1.11.1 h1:uZOwdQoAamx8+X0UdMqY/lro3/h/Zhb7SnfArufNVcc= cloud.google.com/go/orchestration v1.11.1/go.mod h1:RFHf4g88Lbx6oKhwFstYiId2avwb6oswGeAQ7Tjjtfw= -cloud.google.com/go/orchestration v1.11.4/go.mod h1:UKR2JwogaZmDGnAcBgAQgCPn89QMqhXFUCYVhHd31vs= +cloud.google.com/go/orchestration v1.11.9 h1:PnlZ/O4R/eiounpxUkhI9ZXRMWbG7vFqxc6L6sR+31k= cloud.google.com/go/orchestration v1.11.9/go.mod h1:KKXK67ROQaPt7AxUS1V/iK0Gs8yabn3bzJ1cLHw4XBg= cloud.google.com/go/orgpolicy v1.14.1 h1:c1QLoM5v8/aDKgYVCUaC039lD3GPvqAhTVOwsGhIoZQ= cloud.google.com/go/orgpolicy v1.14.1/go.mod h1:1z08Hsu1mkoH839X7C8JmnrqOkp2IZRSxiDw7W/Xpg4= -cloud.google.com/go/orgpolicy v1.14.2/go.mod h1:2fTDMT3X048iFKxc6DEgkG+a/gN+68qEgtPrHItKMzo= +cloud.google.com/go/orgpolicy v1.15.0 h1:uQziDu3UKYk9ZwUgneZAW5aWxZFKgOXXsuVKFKh0z7Y= cloud.google.com/go/orgpolicy v1.15.0/go.mod h1:NTQLwgS8N5cJtdfK55tAnMGtvPSsy95JJhESwYHaJVs= cloud.google.com/go/osconfig v1.14.2 h1:iBN87PQc+EGh5QqijM3CuxcibvDWmF+9k0eOJT27FO4= cloud.google.com/go/osconfig v1.14.2/go.mod h1:kHtsm0/j8ubyuzGciBsRxFlbWVjc4c7KdrwJw0+g+pQ= -cloud.google.com/go/osconfig v1.14.3/go.mod h1:9D2MS1Etne18r/mAeW5jtto3toc9H1qu9wLNDG3NvQg= +cloud.google.com/go/osconfig v1.14.6 h1:4uJrA1obzMBp1I+DF15y/MvsXKIODevuANpq3QhvX30= cloud.google.com/go/osconfig v1.14.6/go.mod h1:LS39HDBH0IJDFgOUkhSZUHFQzmcWaCpYXLrc3A4CVzI= cloud.google.com/go/oslogin v1.14.2 h1:6ehIKkALrLe9zUHwEmfXRVuSPm3HiUmEnnDRr7yLIo8= cloud.google.com/go/oslogin v1.14.2/go.mod h1:M7tAefCr6e9LFTrdWRQRrmMeKHbkvc4D9g6tHIjHySA= -cloud.google.com/go/oslogin v1.14.3/go.mod h1:fDEGODTG/W9ZGUTHTlMh8euXWC1fTcgjJ9Kcxxy14a8= +cloud.google.com/go/oslogin v1.14.6 h1:BDKVcxo1OO4ZT+PbuFchZjnbrlUGfChilt6+pITY1VI= cloud.google.com/go/oslogin v1.14.6/go.mod h1:xEvcRZTkMXHfNSKdZ8adxD6wvRzeyAq3cQX3F3kbMRw= cloud.google.com/go/phishingprotection v0.9.2 h1:SaW0IPf/1fflnzomjy7+9EMtReXuxkYpUAf/77m5xL8= cloud.google.com/go/phishingprotection v0.9.2/go.mod h1:mSCiq3tD8fTJAuXq5QBHFKZqMUy8SfWsbUM9NpzJIRQ= -cloud.google.com/go/phishingprotection v0.9.3/go.mod h1:ylzN9HruB/X7dD50I4sk+FfYzuPx9fm5JWsYI0t7ncc= +cloud.google.com/go/phishingprotection v0.9.6 h1:yl572bBQbPjflX250SOflN6gwO2uYoddN2uRp36fDTo= cloud.google.com/go/phishingprotection v0.9.6/go.mod h1:VmuGg03DCI0wRp/FLSvNyjFj+J8V7+uITgHjCD/x4RQ= cloud.google.com/go/policytroubleshooter v1.11.2 h1:sTIH5AQ8tcgmnqrqlZfYWymjMhPh4ZEt4CvQGgG+kzc= cloud.google.com/go/policytroubleshooter v1.11.2/go.mod h1:1TdeCRv8Qsjcz2qC3wFltg/Mjga4HSpv8Tyr5rzvPsw= -cloud.google.com/go/policytroubleshooter v1.11.3/go.mod h1:AFHlORqh4AnMC0twc2yPKfzlozp3DO0yo9OfOd9aNOs= +cloud.google.com/go/policytroubleshooter v1.11.6 h1:Z8+tO2z21MY1arBBuJjwrOjbw8fbZb13AZTHXdzkl2U= cloud.google.com/go/policytroubleshooter v1.11.6/go.mod h1:jdjYGIveoYolk38Dm2JjS5mPkn8IjVqPsDHccTMu3mY= cloud.google.com/go/privatecatalog v0.10.2 h1:01RPfn8IL2//8UHAmImRraTFYM/3gAEiIxudWLWrp+0= cloud.google.com/go/privatecatalog v0.10.2/go.mod h1:o124dHoxdbO50ImR3T4+x3GRwBSTf4XTn6AatP8MgsQ= -cloud.google.com/go/privatecatalog v0.10.4/go.mod h1:n/vXBT+Wq8B4nSRUJNDsmqla5BYjbVxOlHzS6PjiF+w= +cloud.google.com/go/privatecatalog v0.10.7 h1:R951ikhxIanXEijBCu0xnoUAOteS5m/Xplek0YvsNTE= cloud.google.com/go/privatecatalog v0.10.7/go.mod h1:Fo/PF/B6m4A9vUYt0nEF1xd0U6Kk19/Je3eZGrQ6l60= cloud.google.com/go/pubsub v1.45.1 h1:ZC/UzYcrmK12THWn1P72z+Pnp2vu/zCZRXyhAfP1hJY= cloud.google.com/go/pubsub v1.45.1/go.mod h1:3bn7fTmzZFwaUjllitv1WlsNMkqBgGUb3UdMhI54eCc= -cloud.google.com/go/pubsub v1.47.0/go.mod h1:LaENesmga+2u0nDtLkIOILskxsfvn/BXX9Ak1NFxOs8= +cloud.google.com/go/pubsub v1.49.0 h1:5054IkbslnrMCgA2MAEPcsN3Ky+AyMpEZcii/DoySPo= cloud.google.com/go/pubsub v1.49.0/go.mod h1:K1FswTWP+C1tI/nfi3HQecoVeFvL4HUOB1tdaNXKhUY= cloud.google.com/go/pubsublite v1.8.2 h1:jLQozsEVr+c6tOU13vDugtnaBSUy/PD5zK6mhm+uF1Y= cloud.google.com/go/pubsublite v1.8.2/go.mod h1:4r8GSa9NznExjuLPEJlF1VjOPOpgf3IT6k8x/YgaOPI= cloud.google.com/go/recaptchaenterprise v1.3.1 h1:u6EznTGzIdsyOsvm+Xkw0aSuKFXQlyjGE9a4exk6iNQ= cloud.google.com/go/recaptchaenterprise/v2 v2.19.0 h1:J/J7ZeVOX+sqn0hxzkOBfnQfBAzPZt8KaAuQoarQWQM= cloud.google.com/go/recaptchaenterprise/v2 v2.19.0/go.mod h1:vnbA2SpVPPwKeoFrCQxR+5a0JFRRytwBBG69Zj9pGfk= -cloud.google.com/go/recaptchaenterprise/v2 v2.19.4/go.mod h1:WaglfocMJGkqZVdXY/FVB7OhoVRONPS4uXqtNn6HfX0= +cloud.google.com/go/recaptchaenterprise/v2 v2.20.4 h1:P4QMryKcWdi4LIe1Sx0b2ZOAQv5gVfdzPt2peXcN32Y= cloud.google.com/go/recaptchaenterprise/v2 v2.20.4/go.mod h1:3H8nb8j8N7Ss2eJ+zr+/H7gyorfzcxiDEtVBDvDjwDQ= cloud.google.com/go/recommendationengine v0.9.2 h1:RHVdmoNBdzgRJXI/3SV+GB5TTv/umsVguiaEvmKOh98= cloud.google.com/go/recommendationengine v0.9.2/go.mod h1:DjGfWZJ68ZF5ZuNgoTVXgajFAG0yLt4CJOpC0aMK3yw= -cloud.google.com/go/recommendationengine v0.9.3/go.mod h1:QRnX5aM7DCvtqtSs7I0zay5Zfq3fzxqnsPbZF7pa1G8= +cloud.google.com/go/recommendationengine v0.9.6 h1:slN7h23vswGccW8x3f+xUXCu9Yo18/GNkazH93LJbFk= cloud.google.com/go/recommendationengine v0.9.6/go.mod h1:nZnjKJu1vvoxbmuRvLB5NwGuh6cDMMQdOLXTnkukUOE= cloud.google.com/go/recommender v1.13.2 h1:xDFzlFk5Xp5MXnac468eicKM3MUo6UNdxoYuBMOF1mE= cloud.google.com/go/recommender v1.13.2/go.mod h1:XJau4M5Re8F4BM+fzF3fqSjxNJuM66fwF68VCy/ngGE= -cloud.google.com/go/recommender v1.13.3/go.mod h1:6yAmcfqJRKglZrVuTHsieTFEm4ai9JtY3nQzmX4TC0Q= +cloud.google.com/go/recommender v1.13.5 h1:cIsyRKGNw4LpCfY5c8CCQadhlp54jP4fHtP+d5Sy2xE= cloud.google.com/go/recommender v1.13.5/go.mod h1:v7x/fzk38oC62TsN5Qkdpn0eoMBh610UgArJtDIgH/E= cloud.google.com/go/redis v1.17.2 h1:QbW264RBH+NSVEQqlDoHfoxcreXK8QRRByTOR2CFbJs= cloud.google.com/go/redis v1.17.2/go.mod h1:h071xkcTMnJgQnU/zRMOVKNj5J6AttG16RDo+VndoNo= -cloud.google.com/go/redis v1.18.0/go.mod h1:fJ8dEQJQ7DY+mJRMkSafxQCuc8nOyPUwo9tXJqjvNEY= +cloud.google.com/go/redis v1.18.2 h1:JlHLceAOILEmbn+NIS7l+vmUKkFuobLToCWTxL7NGcQ= cloud.google.com/go/redis v1.18.2/go.mod h1:q6mPRhLiR2uLf584Lcl4tsiRn0xiFlu6fnJLwCORMtY= cloud.google.com/go/resourcemanager v1.10.2 h1:LpqZZGM0uJiu1YWM878AA8zZ/qOQ/Ngno60Q8RAraAI= cloud.google.com/go/resourcemanager v1.10.2/go.mod h1:5f+4zTM/ZOTDm6MmPOp6BQAhR0fi8qFPnvVGSoWszcc= -cloud.google.com/go/resourcemanager v1.10.3/go.mod h1:JSQDy1JA3K7wtaFH23FBGld4dMtzqCoOpwY55XYR8gs= +cloud.google.com/go/resourcemanager v1.10.6 h1:LIa8kKE8HF71zm976oHMqpWFiaDHVw/H1YMO71lrGmo= cloud.google.com/go/resourcemanager v1.10.6/go.mod h1:VqMoDQ03W4yZmxzLPrB+RuAoVkHDS5tFUUQUhOtnRTg= cloud.google.com/go/resourcesettings v1.8.2 h1:ISRX2HZHNS17F/EuIwzPrQwEyIyUJayGuLrS51yt6Wk= cloud.google.com/go/resourcesettings v1.8.2/go.mod h1:uEgtPiMA+xuBUM4Exu+ZkNpMYP0BLlYeJbyNHfrc+U0= +cloud.google.com/go/resourcesettings v1.8.3 h1:13HOFU7v4cEvIHXSAQbinF4wp2Baybbq7q9FMctg1Ek= cloud.google.com/go/resourcesettings v1.8.3/go.mod h1:BzgfXFHIWOOmHe6ZV9+r3OWfpHJgnqXy8jqwx4zTMLw= cloud.google.com/go/retail v1.19.1 h1:FVzvA+VuEdNoMz2WzWZ5KwfG+CX+jSv+SOspyQPLuRs= cloud.google.com/go/retail v1.19.1/go.mod h1:W48zg0zmt2JMqmJKCuzx0/0XDLtovwzGAeJjmv6VPaE= -cloud.google.com/go/retail v1.19.2/go.mod h1:71tRFYAcR4MhrZ1YZzaJxr030LvaZiIcupH7bXfFBcY= +cloud.google.com/go/retail v1.21.0 h1:8jgWgtAg1mk91WmaoWRTlL9CcvazPwqZ3YT9n6Gva9U= cloud.google.com/go/retail v1.21.0/go.mod h1:LuG+QvBdLfKfO+7nnF3eA3l1j4TQw3Sg+UqlUorquRc= cloud.google.com/go/run v1.7.0 h1:GJtHWUgi8CK+YPhmTR3tKBAmDmU9RRMYqiGKCmIgFG8= cloud.google.com/go/run v1.7.0/go.mod h1:IvJOg2TBb/5a0Qkc6crn5yTy5nkjcgSWQLhgO8QL8PQ= -cloud.google.com/go/run v1.9.0/go.mod h1:Dh0+mizUbtBOpPEzeXMM22t8qYQpyWpfmUiWQ0+94DU= +cloud.google.com/go/run v1.10.0 h1:CDhz0PPzI/cVpmNFyHe3Yp21jNpiAqtkfRxuoLi+JU0= cloud.google.com/go/run v1.10.0/go.mod h1:z7/ZidaHOCjdn5dV0eojRbD+p8RczMk3A7Qi2L+koHg= cloud.google.com/go/scheduler v1.11.2 h1:PfkvJP1qKu9NvFB65Ja/s918bPZWMBcYkg35Ljdw1Oc= cloud.google.com/go/scheduler v1.11.2/go.mod h1:GZSv76T+KTssX2I9WukIYQuQRf7jk1WI+LOcIEHUUHk= -cloud.google.com/go/scheduler v1.11.4/go.mod h1:0ylvH3syJnRi8EDVo9ETHW/vzpITR/b+XNnoF+GPSz4= +cloud.google.com/go/scheduler v1.11.7 h1:zkMEJ0UbEJ3O7NwEUlKLIp6eXYv1L7wHjbxyxznajKM= cloud.google.com/go/scheduler v1.11.7/go.mod h1:gqYs8ndLx2M5D0oMJh48aGS630YYvC432tHCnVWN13s= cloud.google.com/go/secretmanager v1.14.2 h1:2XscWCfy//l/qF96YE18/oUaNJynAx749Jg3u0CjQr8= cloud.google.com/go/secretmanager v1.14.2/go.mod h1:Q18wAPMM6RXLC/zVpWTlqq2IBSbbm7pKBlM3lCKsmjw= -cloud.google.com/go/secretmanager v1.14.5/go.mod h1:GXznZF3qqPZDGZQqETZwZqHw4R6KCaYVvcGiRBA+aqY= cloud.google.com/go/secretmanager v1.14.7/go.mod h1:uRuB4F6NTFbg0vLQ6HsT7PSsfbY7FqHbtJP1J94qxGc= +cloud.google.com/go/secretmanager v1.15.0 h1:RtkCMgTpaBMbzozcRUGfZe46jb9a3qh5EdEtVRUATF8= cloud.google.com/go/secretmanager v1.15.0/go.mod h1:1hQSAhKK7FldiYw//wbR/XPfPc08eQ81oBsnRUHEvUc= cloud.google.com/go/security v1.18.2 h1:9Nzp9LGjiDvHqy7X7Q9GrS5lIHN0bI8RvDjkrl4ILO0= cloud.google.com/go/security v1.18.2/go.mod h1:3EwTcYw8554iEtgK8VxAjZaq2unFehcsgFIF9nOvQmU= -cloud.google.com/go/security v1.18.3/go.mod h1:NmlSnEe7vzenMRoTLehUwa/ZTZHDQE59IPRevHcpCe4= +cloud.google.com/go/security v1.18.5 h1:6hqzvuwC8za9jyCTxygmEHnp4vZ8hfhwKVArxSCAVCo= cloud.google.com/go/security v1.18.5/go.mod h1:D1wuUkDwGqTKD0Nv7d4Fn2Dc53POJSmO4tlg1K1iS7s= cloud.google.com/go/securitycenter v1.35.2 h1:XkkE+IRE5/88drGPIuvETCSN7dAnWoqJahZzDbP5Hog= cloud.google.com/go/securitycenter v1.35.2/go.mod h1:AVM2V9CJvaWGZRHf3eG+LeSTSissbufD27AVBI91C8s= -cloud.google.com/go/securitycenter v1.36.0/go.mod h1:AErAQqIvrSrk8cpiItJG1+ATl7SD7vQ6lgTFy/Tcs4Q= +cloud.google.com/go/securitycenter v1.36.2 h1:hLA58IBYmWrNiXDIONvuCUQ4sHLVPy8JvDo2j1wSYCw= cloud.google.com/go/securitycenter v1.36.2/go.mod h1:80ocoXS4SNWxmpqeEPhttYrmlQzCPVGaPzL3wVcoJvE= cloud.google.com/go/servicecontrol v1.11.1 h1:d0uV7Qegtfaa7Z2ClDzr9HJmnbJW7jn0WhZ7wOX6hLE= cloud.google.com/go/servicedirectory v1.12.2 h1:W/oZmTUzlWbeSTujRbmG9v7HZyHcorj608tkcD3vVYE= cloud.google.com/go/servicedirectory v1.12.2/go.mod h1:F0TJdFjqqotiZRlMXgIOzszaplk4ZAmUV8ovHo08M2U= -cloud.google.com/go/servicedirectory v1.12.3/go.mod h1:dwTKSCYRD6IZMrqoBCIvZek+aOYK/6+jBzOGw8ks5aY= +cloud.google.com/go/servicedirectory v1.12.6 h1:pl/KUNvFzlXpxgnPgzQjyTQQcv5WsQ97zCHaPrLQlYA= cloud.google.com/go/servicedirectory v1.12.6/go.mod h1:OojC1KhOMDYC45oyTn3Mup08FY/S0Kj7I58dxUMMTpg= cloud.google.com/go/servicemanagement v1.8.0 h1:fopAQI/IAzlxnVeiKn/8WiV6zKndjFkvi+gzu+NjywY= cloud.google.com/go/serviceusage v1.6.0 h1:rXyq+0+RSIm3HFypctp7WoXxIA563rn206CfMWdqXX4= cloud.google.com/go/shell v1.8.2 h1:lSfdEng3n7zZHzC40BJ4trEMyme3CGnLLnA09MlLQdQ= cloud.google.com/go/shell v1.8.2/go.mod h1:QQR12T6j/eKvqAQLv6R3ozeoqwJ0euaFSz2qLqG93Bs= -cloud.google.com/go/shell v1.8.3/go.mod h1:OYcrgWF6JSp/uk76sNTtYFlMD0ho2+Cdzc7U3P/bF54= +cloud.google.com/go/shell v1.8.6 h1:jLWyztGlNWBx55QXBM4HbWvfv7aiRjPzRKTUkZA8dXk= cloud.google.com/go/shell v1.8.6/go.mod h1:GNbTWf1QA/eEtYa+kWSr+ef/XTCDkUzRpV3JPw0LqSk= cloud.google.com/go/spanner v1.73.0 h1:0bab8QDn6MNj9lNK6XyGAVFhMlhMU2waePPa6GZNoi8= cloud.google.com/go/spanner v1.73.0/go.mod h1:mw98ua5ggQXVWwp83yjwggqEmW9t8rjs9Po1ohcUGW4= -cloud.google.com/go/spanner v1.76.1/go.mod h1:YtwoE+zObKY7+ZeDCBtZ2ukM+1/iPaMfUM+KnTh/sx0= +cloud.google.com/go/spanner v1.82.0 h1:w9uO8RqEoBooBLX4nqV1RtgudyU2ZX780KTLRgeVg60= cloud.google.com/go/spanner v1.82.0/go.mod h1:BzybQHFQ/NqGxvE/M+/iU29xgutJf7Q85/4U9RWMto0= cloud.google.com/go/speech v1.25.2 h1:rKOXU9LAZTOYHhRNB4gZDekNjJx21TktQpetBa5IzOk= cloud.google.com/go/speech v1.25.2/go.mod h1:KPFirZlLL8SqPaTtG6l+HHIFHPipjbemv4iFg7rTlYs= -cloud.google.com/go/speech v1.26.0/go.mod h1:78bqDV2SgwFlP/M4n3i3PwLthFq6ta7qmyG6lUV7UCA= +cloud.google.com/go/speech v1.27.1 h1:+OktATNlQc+4WH78OrQadIP4CzXb9mBucdDGCO1NrlI= cloud.google.com/go/speech v1.27.1/go.mod h1:efCfklHFL4Flxcdt9gpEMEJh9MupaBzw3QiSOVeJ6ck= cloud.google.com/go/storage v1.49.0 h1:zenOPBOWHCnojRd9aJZAyQXBYqkJkdQS42dxL55CIMw= cloud.google.com/go/storage v1.49.0/go.mod h1:k1eHhhpLvrPjVGfo0mOUPEJ4Y2+a/Hv5PiwehZI9qGU= -cloud.google.com/go/storage v1.52.0/go.mod h1:4wrBAbAYUvYkbrf19ahGm4I5kDQhESSqN3CGEkMGvOY= +cloud.google.com/go/storage v1.53.0 h1:gg0ERZwL17pJ+Cz3cD2qS60w1WMDnwcm5YPAIQBHUAw= cloud.google.com/go/storage v1.53.0/go.mod h1:7/eO2a/srr9ImZW9k5uufcNahT2+fPb8w5it1i5boaA= cloud.google.com/go/storagetransfer v1.11.2 h1:hMcP8ECmxedXjPxr2j3Ca45ro/TKEF+1YYjq2p5LMTI= cloud.google.com/go/storagetransfer v1.11.2/go.mod h1:FcM29aY4EyZ3yVPmW5SxhqUdhjgPBUOFyy4rqiQbias= -cloud.google.com/go/storagetransfer v1.12.1/go.mod h1:hQqbfs8/LTmObJyCC0KrlBw8yBJ2bSFlaGila0qBMk4= +cloud.google.com/go/storagetransfer v1.13.0 h1:uqKX3OgcYzR1W1YI943ZZ45id0RqA2eXXoCBSPstlbw= cloud.google.com/go/storagetransfer v1.13.0/go.mod h1:+aov7guRxXBYgR3WCqedkyibbTICdQOiXOdpPcJCKl8= cloud.google.com/go/talent v1.7.2 h1:KONR7KX/EXI3pO2cbSIDOBqhBzvgDS71vaMz8k4qRCg= cloud.google.com/go/talent v1.7.2/go.mod h1:k1sqlDgS9gbc0gMTRuRQpX6C6VB7bGUxSPcoTRWJod8= -cloud.google.com/go/talent v1.8.0/go.mod h1:/gvOzSrtMcfTL/9xWhdYaZATaxUNhQ+L+3ZaGOGs7bA= +cloud.google.com/go/talent v1.8.3 h1:wDP+++O/P1cTJBMkYlSY46k0a6atSoyO+UkBGuU9+Ao= cloud.google.com/go/talent v1.8.3/go.mod h1:oD3/BilJpJX8/ad8ZUAxlXHCslTg2YBbafFH3ciZSLQ= cloud.google.com/go/texttospeech v1.10.0 h1:icRAxYDtq3zO1T0YBT/fe8C/7pXoIqfkY4iYr5zG39I= cloud.google.com/go/texttospeech v1.10.0/go.mod h1:215FpCOyRxxrS7DSb2t7f4ylMz8dXsQg8+Vdup5IhP4= -cloud.google.com/go/texttospeech v1.11.0/go.mod h1:7M2ro3I2QfIEvArFk1TJ+pqXJqhszDtxUpnIv/150As= +cloud.google.com/go/texttospeech v1.13.0 h1:oWWFQp0yFl4EJOr3opDkKH9304wUsZjgPjrTDS6S1a8= cloud.google.com/go/texttospeech v1.13.0/go.mod h1:g/tW/m0VJnulGncDrAoad6WdELMTes8eb77Idz+4HCo= cloud.google.com/go/tpu v1.7.2 h1:xPBJd7xZgtl3CgrZoaUf7zFPVVj68jmzzGTSzkcsOtQ= cloud.google.com/go/tpu v1.7.2/go.mod h1:0Y7dUo2LIbDUx0yQ/vnLC6e18FK6NrDfAhYS9wZ/2vs= -cloud.google.com/go/tpu v1.8.0/go.mod h1:XyNzyK1xc55WvL5rZEML0Z9/TUHDfnq0uICkQw6rWMo= +cloud.google.com/go/tpu v1.8.3 h1:S4Ptq+yFIPNLEzQ/OQwiIYDNzk5I2vYmhf0SmFQOmWo= cloud.google.com/go/tpu v1.8.3/go.mod h1:Do6Gq+/Jx6Xs3LcY2WhHyGwKDKVw++9jIJp+X+0rxRE= cloud.google.com/go/trace v1.11.2 h1:4ZmaBdL8Ng/ajrgKqY5jfvzqMXbrDcBsUGXOT9aqTtI= cloud.google.com/go/trace v1.11.2/go.mod h1:bn7OwXd4pd5rFuAnTrzBuoZ4ax2XQeG3qNgYmfCy0Io= -cloud.google.com/go/trace v1.11.3/go.mod h1:pt7zCYiDSQjC9Y2oqCsh9jF4GStB/hmjrYLsxRR27q8= +cloud.google.com/go/trace v1.11.6 h1:2O2zjPzqPYAHrn3OKl029qlqG6W8ZdYaOWRyr8NgMT4= cloud.google.com/go/trace v1.11.6/go.mod h1:GA855OeDEBiBMzcckLPE2kDunIpC72N+Pq8WFieFjnI= -cloud.google.com/go/translate v1.10.3/go.mod h1:GW0vC1qvPtd3pgtypCv4k4U8B7EdgK9/QEF2aJEUovs= cloud.google.com/go/translate v1.12.2 h1:qECivi8O+jFI/vnvN9elK6CME+WAWy56GIBszF+/rNc= cloud.google.com/go/translate v1.12.2/go.mod h1:jjLVf2SVH2uD+BNM40DYvRRKSsuyKxVvs3YjTW/XSWY= -cloud.google.com/go/translate v1.12.3/go.mod h1:qINOVpgmgBnY4YTFHdfVO4nLrSBlpvlIyosqpGEgyEg= +cloud.google.com/go/translate v1.12.5 h1:QPMNi4WCtHwc2PPfxbyUMwdN/0+cyCGLaKi2tig41J8= cloud.google.com/go/translate v1.12.5/go.mod h1:o/v+QG/bdtBV1d1edmtau0PwTfActvxPk/gtqdSDBi4= cloud.google.com/go/video v1.23.2 h1:CGAPOXTJMoZm9PeHkohBlMTy8lqN6VWCNDjp5VODfy8= cloud.google.com/go/video v1.23.2/go.mod h1:rNOr2pPHWeCbW0QsOwJRIe0ZiuwHpHtumK0xbiYB1Ew= -cloud.google.com/go/video v1.23.3/go.mod h1:Kvh/BheubZxGZDXSb0iO6YX7ZNcaYHbLjnnaC8Qyy3g= +cloud.google.com/go/video v1.24.0 h1:KTB2BEXjGm2K/JcKxQXEgx3nSoMTByepnPZa4kln064= cloud.google.com/go/video v1.24.0/go.mod h1:h6Bw4yUbGNEa9dH4qMtUMnj6cEf+OyOv/f2tb70G6Fk= cloud.google.com/go/videointelligence v1.12.2 h1:ZLElysepw9vfQGAKWfnxdnSnHSKbEn/nU/tmBnCJLfA= cloud.google.com/go/videointelligence v1.12.2/go.mod h1:8xKGlq0lNVyT8JgTkkCUCpyNJnYYEJVWGdqzv+UcwR8= -cloud.google.com/go/videointelligence v1.12.3/go.mod h1:dUA6V+NH7CVgX6TePq0IelVeBMGzvehxKPR4FGf1dtw= +cloud.google.com/go/videointelligence v1.12.6 h1:heq7jEO39sH5TycBh8TGFJ827XCxK0tIWatmBY/n0jI= cloud.google.com/go/videointelligence v1.12.6/go.mod h1:/l34WMndN5/bt04lHodxiYchLVuWPQjCU6SaiTswrIw= cloud.google.com/go/vision v1.2.0 h1:/CsSTkbmO9HC8iQpxbK8ATms3OQaX3YQUeTMGCxlaK4= cloud.google.com/go/vision/v2 v2.9.2 h1:u4pu3gKps88oUe76WwVPeX9dgWVyyYopZ1s05FwsKEk= cloud.google.com/go/vision/v2 v2.9.2/go.mod h1:WuxjVQdAy4j4WZqY5Rr655EdAgi8B707Vdb5T8c90uo= -cloud.google.com/go/vision/v2 v2.9.3/go.mod h1:weAcT8aNYSgrWWVTC2PuJTc7fcXKvUeAyDq8B6HkLSg= +cloud.google.com/go/vision/v2 v2.9.5 h1:UJZ0H6UlOaYKgCn6lWG2iMAOJIsJZLnseEfzBR8yIqQ= cloud.google.com/go/vision/v2 v2.9.5/go.mod h1:1SiNZPpypqZDbOzU052ZYRiyKjwOcyqgGgqQCI/nlx8= cloud.google.com/go/vmmigration v1.8.2 h1:Hpqv3fZ3Ri1OMhTNVJgxxsTou2ZlRzKbnc1dSybTP5Y= cloud.google.com/go/vmmigration v1.8.2/go.mod h1:FBejrsr8ZHmJb949BSOyr3D+/yCp9z9Hk0WtsTiHc1Q= -cloud.google.com/go/vmmigration v1.8.3/go.mod h1:8CzUpK9eBzohgpL4RvBVtW4sY/sDliVyQonTFQfWcJ4= +cloud.google.com/go/vmmigration v1.8.6 h1:68hOQDhs1DOITrCrhritrwr8xy6s8QMdwDyMzMiFleU= cloud.google.com/go/vmmigration v1.8.6/go.mod h1:uZ6/KXmekwK3JmC8PzBM/cKQmq404TTfWtThF6bbf0U= cloud.google.com/go/vmwareengine v1.3.2 h1:LmkojgSLvsRwU1+c0iiY2XoBkXYKzpArElHC9IDWakg= cloud.google.com/go/vmwareengine v1.3.2/go.mod h1:JsheEadzT0nfXOGkdnwtS1FhFAnj4g8qhi4rKeLi/AU= -cloud.google.com/go/vmwareengine v1.3.3/go.mod h1:G7vz05KGijha0c0dj1INRKyDAaQW8TRMZt/FrfOZVXc= +cloud.google.com/go/vmwareengine v1.3.5 h1:OsGd1SB91y9fDuzdzFngMv4UcT4cqmRxjsCsS4Xmcu8= cloud.google.com/go/vmwareengine v1.3.5/go.mod h1:QuVu2/b/eo8zcIkxBYY5QSwiyEcAy6dInI7N+keI+Jg= cloud.google.com/go/vpcaccess v1.8.2 h1:nvrkqAjS2sorOu4YGCIXWz+Kk+5aAAdnaMD2tnsqeFg= cloud.google.com/go/vpcaccess v1.8.2/go.mod h1:4yvYKNjlNjvk/ffgZ0PuEhpzNJb8HybSM1otG2aDxnY= -cloud.google.com/go/vpcaccess v1.8.3/go.mod h1:bqOhyeSh/nEmLIsIUoCiQCBHeNPNjaK9M3bIvKxFdsY= +cloud.google.com/go/vpcaccess v1.8.6 h1:RYtUB9rQEijX9Tc6lQcGst58ZOzPgaYTkz6+2pyPQTM= cloud.google.com/go/vpcaccess v1.8.6/go.mod h1:61yymNplV1hAbo8+kBOFO7Vs+4ZHYI244rSFgmsHC6E= cloud.google.com/go/webrisk v1.10.2 h1:X7zSwS1mX2bxoZ30Ozh6lqiSLezl7RMBWwp5a3Mkxp4= cloud.google.com/go/webrisk v1.10.2/go.mod h1:c0ODT2+CuKCYjaeHO7b0ni4CUrJ95ScP5UFl9061Qq8= -cloud.google.com/go/webrisk v1.10.3/go.mod h1:rRAqCA5/EQOX8ZEEF4HMIrLHGTK/Y1hEQgWMnih+jAw= +cloud.google.com/go/webrisk v1.11.1 h1:yZKNB7zRxOMriLrhP5WDE+BjxXVl0wJHHZSdaYzbdVU= cloud.google.com/go/webrisk v1.11.1/go.mod h1:+9SaepGg2lcp1p0pXuHyz3R2Yi2fHKKb4c1Q9y0qbtA= cloud.google.com/go/websecurityscanner v1.7.2 h1:8/4rfJXcyxozbfzI0lDFPcPShRE6bJ4HQwgDAG9J4oQ= cloud.google.com/go/websecurityscanner v1.7.2/go.mod h1:728wF9yz2VCErfBaACA5px2XSYHQgkK812NmHcUsDXA= -cloud.google.com/go/websecurityscanner v1.7.3/go.mod h1:gy0Kmct4GNLoCePWs9xkQym1D7D59ld5AjhXrjipxSs= +cloud.google.com/go/websecurityscanner v1.7.6 h1:cIPKJKZA3l7D8DfL4nxce8HGOWXBw3WAUBF0ymOW9GQ= cloud.google.com/go/websecurityscanner v1.7.6/go.mod h1:ucaaTO5JESFn5f2pjdX01wGbQ8D6h79KHrmO2uGZeiY= cloud.google.com/go/workflows v1.13.2 h1:jYIxrDOVCGvTBHIAVhqQ+P8fhE0trm+Hf2hgL1YzmK0= cloud.google.com/go/workflows v1.13.2/go.mod h1:l5Wj2Eibqba4BsADIRzPLaevLmIuYF2W+wfFBkRG3vU= -cloud.google.com/go/workflows v1.13.3/go.mod h1:Xi7wggEt/ljoEcyk+CB/Oa1AHBCk0T1f5UH/exBB5CE= +cloud.google.com/go/workflows v1.14.2 h1:phBz5TOAES0YGogxZ6Q7ISSudaf618lRhE3euzBpE9U= cloud.google.com/go/workflows v1.14.2/go.mod h1:5nqKjMD+MsJs41sJhdVrETgvD5cOK3hUcAs8ygqYvXQ= contrib.go.opencensus.io/exporter/stackdriver v0.13.4 h1:ksUxwH3OD5sxkjzEqGxNTl+Xjsmu3BnC/300MhSVTSc= crawshaw.io/sqlite v0.3.3-0.20220618202545-d1964889ea3c h1:wvzox0eLO6CKQAMcOqz7oH3UFqMpMmK7kwmwV+22HIs= @@ -532,7 +521,9 @@ github.com/AzureAD/microsoft-authentication-library-for-go v1.0.0 h1:OBhqkivkhkM github.com/BurntSushi/toml v0.4.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/toml v1.2.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802 h1:1BDTz0u9nC3//pOCMdNH+CiXJVYJh5UQNCOBG7jbELc= +github.com/ClickHouse/ch-go v0.67.0 h1:18MQF6vZHj+4/hTRaK7JbS/TIzn4I55wC+QzO24uiqc= github.com/ClickHouse/ch-go v0.67.0/go.mod h1:2MSAeyVmgt+9a2k2SQPPG1b4qbTPzdGDpf1+bcHh+18= +github.com/ClickHouse/clickhouse-go/v2 v2.40.1 h1:PbwsHBgqXRydU7jKULD1C8CHmifczffvQqmFvltM2W4= github.com/ClickHouse/clickhouse-go/v2 v2.40.1/go.mod h1:GDzSBLVhladVm8V01aEB36IoBOVLLICfyeuiIp/8Ezc= github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53 h1:sR+/8Yb4slttB4vD+b9btVEnWgL3Q00OBTzVT8B9C0c= github.com/CloudyKit/jet/v6 v6.2.0 h1:EpcZ6SR9n28BUGtNJSvlBqf90IpjeFr36Tizxhn/oME= @@ -540,18 +531,21 @@ github.com/DataDog/datadog-go v3.2.0+incompatible h1:qSG2N4FghB1He/r2mFrWKCaL7dX github.com/GoogleCloudPlatform/cloudsql-proxy v0.0.0-20190129172621-c8b1d7a94ddf h1:8F6fjL5iQP6sArGtPuXh0l6hggdcIpAm4ChjVJE4oTs= github.com/GoogleCloudPlatform/grpc-gcp-go/grpcgcp v1.5.0 h1:oVLqHXhnYtUwM89y9T1fXGaK9wTkXHgNp8/ZNMQzUxE= github.com/GoogleCloudPlatform/grpc-gcp-go/grpcgcp v1.5.0/go.mod h1:dppbR7CwXD4pgtV9t3wD1812RaLDcBjtblcDF5f1vI0= +github.com/GoogleCloudPlatform/grpc-gcp-go/grpcgcp v1.5.2 h1:DBjmt6/otSdULyJdVg2BlG0qGZO5tKL4VzOs0jpvw5Q= github.com/GoogleCloudPlatform/grpc-gcp-go/grpcgcp v1.5.2/go.mod h1:dppbR7CwXD4pgtV9t3wD1812RaLDcBjtblcDF5f1vI0= github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.25.0 h1:3c8yed4lgqTt+oTQ+JNMDo+F4xprBf+O/il4ZC0nRLw= github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.25.0/go.mod h1:obipzmGjfSjam60XLwGfqUkJsfiheAl+TUjG+4yzyPM= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.27.0 h1:ErKg/3iS1AKcTkf3yixlZ54f9U1rljCkQyEXWUnIUxc= github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.27.0/go.mod h1:yAZHSGnqScoU556rBOVkwLze6WP5N+U11RHuWaGVxwY= github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.48.1 h1:UQ0AhxogsIRZDkElkblfnwjc3IaltCm2HUMvezQaL7s= github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.48.1/go.mod h1:jyqM3eLpJ3IbIFDTKVz2rF9T/xWGW0rIriGwnz8l9Tk= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.51.0 h1:fYE9p3esPxA/C0rQ0AHhP0drtPXDRhaWiwg1DPqO7IU= github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.51.0/go.mod h1:BnBReJLvVYx2CS/UHOgVz2BXKXD9wsQPxZug20nZhd0= github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock v0.48.1 h1:oTX4vsorBZo/Zdum6OKPA4o7544hm6smoRv1QjpTwGo= github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock v0.48.1/go.mod h1:0wEl7vrAD8mehJyohS9HZy+WyEOaQO2mJx86Cvh93kM= -github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock v0.51.0/go.mod h1:SZiPHWGOOk3bl8tkevxkoiwPgsIl6CwrWcbwjfHZpdM= github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.48.1 h1:8nn+rsCvTq9axyEh382S0PFLBeaFwNsT43IrPWzctRU= github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.48.1/go.mod h1:viRWSEhtMZqz1rhwmOVKkWl6SwmVowfL9O2YR5gI2PE= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.51.0 h1:6/0iUd0xrnX7qt+mLNRwg5c0PGv8wpE8K90ryANQwMI= github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.51.0/go.mod h1:otE2jQekW/PqXk1Awf5lmfokJx4uwuqcj1ab5SpGeW0= github.com/HdrHistogram/hdrhistogram-go v1.1.2 h1:5IcZpTvzydCQeHzK4Ef/D5rrSqwxob0t8PQPMybUNFM= github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c h1:RGWPOewvKIROun94nF7v2cua9qP+thov/7M50KEoeSU= @@ -585,6 +579,7 @@ github.com/alecthomas/kingpin/v2 v2.4.0/go.mod h1:0gyi0zQnjuFk8xrkNKamJoyUo382HR github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM= github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 h1:s6gZFSlWYmbqAuRjVTiNNhvNRfY2Wxp9nhfyel4rklc= github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= +github.com/alicebob/miniredis/v2 v2.35.0 h1:QwLphYqCEAo1eu1TqPRN2jgVMPBweeQcR21jeqDCONI= github.com/alicebob/miniredis/v2 v2.35.0/go.mod h1:TcL7YfarKPGDAthEtl5NBeHZfeUQj6OXMm/+iu5cLMM= github.com/anacrolix/chansync v0.3.0 h1:lRu9tbeuw3wl+PhMu/r+JJCRu5ArFXIluOgdF0ao6/U= github.com/anacrolix/chansync v0.3.0/go.mod h1:DZsatdsdXxD0WiwcGl0nJVwyjCKMDv+knl1q2iBjA2k= @@ -621,8 +616,9 @@ github.com/anacrolix/utp v0.1.0/go.mod h1:MDwc+vsGEq7RMw6lr2GKOEqjWny5hO5OZXRVNa github.com/andybalholm/brotli v1.0.2/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y= github.com/andybalholm/brotli v1.0.3/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs= +github.com/andybalholm/brotli v1.2.0 h1:ukwgCxwYrmACq68yiUqwIWnGY0cTPox/M94sVwToPjQ= +github.com/andybalholm/brotli v1.2.0/go.mod h1:rzTDkvFWvIrjDXZHkuS16NPggd91W3kUSvPlQ1pLaKY= github.com/antihax/optional v1.0.0 h1:xK2lYat7ZLaVVcIuj82J8kIro4V6kDe0AUDFboUCwcg= -github.com/antlr4-go/antlr/v4 v4.13.1/go.mod h1:GKmUxMtwp6ZgGwZSva4eWPC5mS6vUAmOABFgjdkM7Nw= github.com/aokoli/goutils v1.0.1 h1:7fpzNGoJ3VA8qcrm++XEE1QUe0mIwNeLa02Nwq7RDkg= github.com/apache/arrow/go/v10 v10.0.1 h1:n9dERvixoC/1JjDmBcs9FPaEryoANa2sCgVFo6ez9cI= github.com/apache/arrow/go/v11 v11.0.0 h1:hqauxvFQxww+0mEU/2XHG6LT7eZternCZq+A5Yly2uM= @@ -654,7 +650,6 @@ github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPn github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg= github.com/bazelbuild/rules_go v0.49.0 h1:5vCbuvy8Q11g41lseGJDc5vxhDjJtfxr6nM/IC4VmqM= github.com/bazelbuild/rules_go v0.49.0/go.mod h1:Dhcz716Kqg1RHNWos+N6MlXNkjNP2EwZQ0LukRKJfMs= -github.com/bits-and-blooms/bitset v1.20.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= github.com/bketelsen/crypt v0.0.4 h1:w/jqZtC9YD4DS/Vp9GhWfWcCpuAL58oTnLoI8vE9YHU= github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= github.com/boombuler/barcode v1.0.1 h1:NDBbPmhS+EqABEs5Kg3n/5ZNjy73Pz7SIV+KCeqyXcs= @@ -672,6 +667,7 @@ github.com/casbin/casbin/v2 v2.37.0 h1:/poEwPSovi4bTOcP752/CsTQiRz2xycyVKFG7GUhb github.com/casbin/casbin/v2 v2.37.0/go.mod h1:vByNa/Fchek0KZUgG5wEsl7iFsiviAYKRtgrQfcJqHg= github.com/cenkalti/backoff/v4 v4.1.1 h1:G2HAfAmvm/GcKan2oOQpBXOd2tT2G57ZnZGWa1PxPBQ= github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= +github.com/cenkalti/backoff/v5 v5.0.2 h1:rIfFVxEf1QsI7E1ZHfp/B4DF/6QBAUhmgkxc0H7Zss8= github.com/cenkalti/backoff/v5 v5.0.2/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw= github.com/census-instrumentation/opencensus-proto v0.4.1 h1:iKLQ0xPNFxR/2hzXZMrBo8f1j86j5WHzznCCQxV/b8g= github.com/checkpoint-restore/go-criu/v5 v5.0.0 h1:TW8f/UvntYoVDMN1K2HlT82qH1rb0sOjpGw3m6Ym+i4= @@ -691,17 +687,16 @@ github.com/cloudflare/cloudflare-go v0.114.0 h1:ucoti4/7Exo0XQ+rzpn1H+IfVVe++zgi github.com/cncf/udpa/go v0.0.0-20220112060539-c52dc94e7fbe h1:QQ3GSy+MqSHxm/d8nCtnAiZdYFd45cYZPs8vOOIYKfk= github.com/cncf/xds/go v0.0.0-20211130200136-a8f946100490/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20240423153145-555b57ec207b/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8= -github.com/cncf/xds/go v0.0.0-20240723142845-024c85f92f20/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8= github.com/cncf/xds/go v0.0.0-20240905190251-b4127c9b8d78 h1:QVw89YDxXxEe+l8gU8ETbOasdwEV+avkR75ZzsVV9WI= github.com/cncf/xds/go v0.0.0-20240905190251-b4127c9b8d78/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8= +github.com/cncf/xds/go v0.0.0-20250121191232-2f005788dc42 h1:Om6kYQYDUk5wWbT0t0q6pvyM49i9XZAv9dDrkDA7gjk= github.com/cncf/xds/go v0.0.0-20250121191232-2f005788dc42/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8= -github.com/cockroachdb/apd/v3 v3.2.1/go.mod h1:klXJcjp+FffLTHlhIG69tezTDvdP065naDsHzKhYSqc= github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd h1:qMd81Ts1T2OTKmB4acZcyKaMtRnY5Y44NuXGX2GFJ1w= github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0 h1:sDMmm+q/3+BukdIpxwO365v/Rbspp2Nt5XntgQRXq8Q= github.com/consensys/bavard v0.1.31-0.20250406004941-2db259e4b582 h1:dTlIwEdFQmldzFf5F6bbTcYWhvnAgZai2g8eq3Wwxqg= github.com/consensys/bavard v0.1.31-0.20250406004941-2db259e4b582/go.mod h1:k/zVjHHC4B+PQy1Pg7fgvG3ALicQw540Crag8qx+dZs= github.com/containerd/console v1.0.2 h1:Pi6D+aZXM+oUw1czuKgH5IJ+y0jhYcwBJfx5/Ghn9dE= -github.com/containerd/console v1.0.5/go.mod h1:YynlIjWYF8myEu6sdkwKIvGQq+cOckRm6So2avqoYAk= +github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U= github.com/coreos/bbolt v1.3.2 h1:wZwiHHUieZCquLkDL0B8UhzreNWsPHooDAG3q34zk0s= github.com/coreos/etcd v3.3.10+incompatible h1:jFneRYjIvLMLhDLCzuTuU4rSJUjRplcJQ7pD7MnhC04= github.com/coreos/go-etcd v2.0.0+incompatible h1:bXhRBIXoTm9BYHS3gE0TtQuyNZyeEMux2sDi4oo5YOo= @@ -710,13 +705,13 @@ github.com/coreos/go-systemd v0.0.0-20190620071333-e64a0ec8b42a h1:W8b4lQ4tFF21a github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f h1:lBNOc5arjvs8E5mO2tbpBpLoyyu8B6e44T7hJy6potg= github.com/cpuguy83/go-md2man v1.0.10 h1:BSKMNlYxDvnunlTymqtgONjNnaRV1sTpcovwwjF22jk= -github.com/crate-crypto/go-eth-kzg v1.3.0 h1:05GrhASN9kDAidaFJOda6A4BEvgvuXbazXg/0E3OOdI= +github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/crate-crypto/go-eth-kzg v1.3.0/go.mod h1:J9/u5sWfznSObptgfa92Jq8rTswn6ahQWEuiLHOjCUI= github.com/creachadair/command v0.0.0-20220426235536-a748effdf6a1 h1:r626P+s8TKpQaHwIaLmA2nGetfIVYEhtqcs3g2U1dC8= github.com/creachadair/command v0.0.0-20220426235536-a748effdf6a1/go.mod h1:bAM+qFQb/KwWyCc9MLC4U1jvn3XyakqP5QRkds5T6cY= github.com/creachadair/command v0.2.0/go.mod h1:j+Ar+uYnFsHpkMeV9kGj6lJ45y9u2xqtg8FYy6cm+0o= github.com/creack/pty v1.1.9 h1:uDmaGzcdjhF4i/plgjmEsriH11Y0o7RKapEf/LDaM3w= -github.com/creasty/defaults v1.8.0/go.mod h1:iGzKe6pbEHnpMPtfDXZEr0NVxWnPTjb1bbDy08fPzYM= +github.com/creack/pty v1.1.24/go.mod h1:08sCNb52WyoAwi2QDyzUCTgcvVFhUzewun7wtTfvcwE= github.com/cristalhq/acmd v0.8.1 h1:mtFp/cbeJNY5jokF9zPz5mRllGHropRrOkOVxeGS6FI= github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c h1:/ovYnF02fwL0kvspmy9AuyKg1JhdTRUgPw4nUxd9oZM= github.com/cyphar/filepath-securejoin v0.2.2 h1:jCwT2GTP+PY5nBz3c/YL5PAIbusElVrPujOBSCj8xRg= @@ -729,6 +724,7 @@ github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/r github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954 h1:RMLoZVzv4GliuWafOuPuQDKSm1SJph7uCRnnS61JAn4= github.com/djherbis/atime v1.1.0 h1:rgwVbP/5by8BvvjBNrbh64Qz33idKT3pSnMSJsxhi0g= github.com/dnaeon/go-vcr v1.2.0 h1:zHCHvJYTMh1N7xnV7zf1m1GPBF9Ad0Jk/whtQ1663qI= +github.com/docker/docker v25.0.6+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815 h1:bWDMxwH3px2JBh6AyO7hdCn/PkvCZXii8TGj7sbtEbQ= github.com/donovanhide/eventsource v0.0.0-20210830082556-c59027999da0 h1:C7t6eeMaEQVy6e8CarIhscYQlNmw5e3G36y7l7Y21Ao= github.com/dop251/goja_nodejs v0.0.0-20211022123610-8dd9abb0616d h1:W1n4DvpzZGOISgp7wWNtraLcHtnmnTwBlJidqtMIuwQ= @@ -738,18 +734,18 @@ github.com/eapache/queue v1.1.0 h1:YOEu7KNc61ntiQlcEeUIoDTJ2o8mQznoNvUhiigpIqc= github.com/edsrzf/mmap-go v1.1.0 h1:6EUwBLQ/Mcr1EYLE4Tn1VdW1A4ckqCQWZBw8Hr0kjpQ= github.com/edsrzf/mmap-go v1.1.0/go.mod h1:19H/e8pUPLicwkyNgOykDXkJ9F0MHE+Z52B8EIth78Q= github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385 h1:clC1lXBpe2kTj2VHdaIu9ajZQe4kcEY9j0NsnDDBZ3o= +github.com/emicklei/go-restful/v3 v3.12.2 h1:DhwDP0vY3k8ZzE0RunuJy8GhNpPL6zqLkDf9B/a0/xU= github.com/emicklei/go-restful/v3 v3.12.2/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/envoyproxy/go-control-plane v0.10.1/go.mod h1:AY7fTTXNdv/aJ2O5jwpxAPOWUZ7hQAEvzN5Pf27BkQQ= github.com/envoyproxy/go-control-plane v0.13.1 h1:vPfJZCkob6yTMEgS+0TwfTUfbHjfy/6vOJ8hUWX/uXE= github.com/envoyproxy/go-control-plane v0.13.1/go.mod h1:X45hY0mufo6Fd0KW3rqsGvQMw58jvjymeCzBU3mWyHw= -github.com/envoyproxy/go-control-plane v0.13.4/go.mod h1:kDfuBlDVsSj2MjrLEtRWtHlsWIFcGyB2RMO44Dc5GZA= -github.com/envoyproxy/go-control-plane/envoy v1.32.3/go.mod h1:F6hWupPfh75TBXGKA++MCT/CZHFq5r9/uwt/kQYkZfE= +github.com/envoyproxy/go-control-plane/envoy v1.32.4 h1:jb83lalDRZSpPWW2Z7Mck/8kXZ5CQAFYVjQcdVIr83A= github.com/envoyproxy/go-control-plane/envoy v1.32.4/go.mod h1:Gzjc5k8JcJswLjAx1Zm+wSYE20UrLtt7JZMWiWQXQEw= -github.com/envoyproxy/go-control-plane/ratelimit v0.1.0/go.mod h1:Wk+tMFAFbCXaJPzVVHnPgRKdUdwW/KdbRt94AzgRee4= github.com/envoyproxy/protoc-gen-validate v0.6.2/go.mod h1:2t7qjJNvHPx8IjnBOzl9E9/baC+qXE/TeeyBRzgJDws= github.com/envoyproxy/protoc-gen-validate v1.0.4/go.mod h1:qys6tmnRsYrQqIhm2bvKZH4Blx/1gTIZ2UKVY1M+Yew= github.com/envoyproxy/protoc-gen-validate v1.1.0 h1:tntQDh69XqOCOZsDz0lVJQez/2L6Uu2PdjCQwWCJ3bM= github.com/envoyproxy/protoc-gen-validate v1.1.0/go.mod h1:sXRDRVmzEbkM7CVcM06s9shE/m23dg3wzjl0UWqJ2q4= +github.com/envoyproxy/protoc-gen-validate v1.2.1 h1:DEo3O99U8j4hBFwbJfrz9VtgcDfUKS7KJ7spH3d86P8= github.com/envoyproxy/protoc-gen-validate v1.2.1/go.mod h1:d/C80l/jxXLdfEIhX1W2TmLfsJ31lvEjwamM4DxlWXU= github.com/ethereum/c-kzg-4844/v2 v2.1.1 h1:KhzBVjmURsfr1+S3k/VE35T02+AW2qU9t9gr4R6YpSo= github.com/ethereum/c-kzg-4844/v2 v2.1.1/go.mod h1:TC48kOKjJKPbN7C++qIgt0TJzZ70QznYR7Ob+WXl57E= @@ -761,15 +757,20 @@ github.com/fogleman/gg v1.3.0 h1:/7zJX8F6AaYQc57WQCyN9cAIz+4bCJGO9B+dyW29am8= github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db h1:gb2Z18BhTPJPpLQWj4T+rfKHYCHxRHCtRxhKKjRidVw= github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8 h1:a9ENSRDFBUPkJ5lCgVZh26+ZbGyoVJG7yb5SSzF5H54= github.com/fullstorydev/grpcurl v1.6.0 h1:p8BB6VZF8O7w6MxGr3KJ9E6EVKaswCevSALK6FBtMzA= +github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM= github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ= github.com/garslo/gogen v0.0.0-20170306192744-1d203ffc1f61 h1:IZqZOB2fydHte3kUgxrzK5E1fW7RQGeDwE8F/ZZnUYc= github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff h1:tY80oXqGNY4FhTFhk+o9oFHGINQ/+vhlm8HFzi6znCI= github.com/getkin/kin-openapi v0.53.0 h1:7WzP+MZRRe7YQz2Kc74Ley3dukJmXDvifVbElGmQfoA= github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/go-chi/chi/v5 v5.0.0 h1:DBPx88FjZJH3FsICfDAfIfnb7XxKIYVGG6lOPlhENAg= +github.com/go-chi/chi/v5 v5.2.2 h1:CMwsvRVTbXVytCk1Wd72Zy1LAsAh9GxMmSNWLHCG618= github.com/go-chi/chi/v5 v5.2.2/go.mod h1:L2yAIGWB3H+phAw1NxKwWM+7eUH/lU8pOMm5hHcoops= +github.com/go-chi/cors v1.2.2 h1:Jmey33TE+b+rB7fT8MUy1u0I4L+NARQlK6LhzKPSyQE= github.com/go-chi/cors v1.2.2/go.mod h1:sSbTewc+6wYHBBCW7ytsFSn836hqM7JxpglAy2Vzc58= +github.com/go-faster/city v1.0.1 h1:4WAxSZ3V2Ws4QRDrscLEDcibJY8uf41H6AhXDrNDcGw= github.com/go-faster/city v1.0.1/go.mod h1:jKcUJId49qdW3L1qKHH/3wPeUstCVpVSXTM6vO3VcTw= +github.com/go-faster/errors v0.7.1 h1:MkJTnDoEdi9pDabt1dpWf7AA8/BaSYZqibYyhZ20AYg= github.com/go-faster/errors v0.7.1/go.mod h1:5ySTjWFiphBs07IKuiL69nxdfd5+fzh1u7FPGZP2quo= github.com/go-fonts/dejavu v0.1.0 h1:JSajPXURYqpr+Cu8U9bt8K+XcACIHWqWrvWCKyeFmVQ= github.com/go-fonts/latin-modern v0.2.0 h1:5/Tv1Ek/QCr20C6ZOz15vw3g7GELYL98KWr8Hgo+3vk= @@ -777,34 +778,39 @@ github.com/go-fonts/liberation v0.2.0 h1:jAkAWJP4S+OsrPLZM4/eC9iW7CtHy+HBXrEwZXW github.com/go-fonts/stix v0.1.0 h1:UlZlgrvvmT/58o573ot7NFw0vZasZ5I6bcIft/oMdgg= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1 h1:QbL/5oDUmRBzO9/Z7Seo6zf912W/a6Sr4Eu0G/3Jho0= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4 h1:WtGNWLvXpe6ZudgnXrq0barxBImvnnJoMEhXAzcbM0I= +github.com/go-jose/go-jose/v4 v4.0.4 h1:VsjPI33J0SB9vQM6PLmNjoHqMQNGPiZ0rHL7Ni7Q6/E= github.com/go-jose/go-jose/v4 v4.0.4/go.mod h1:NKb5HO1EZccyMpiZNbdUw/14tiXNyUJh188dfnMCAfc= github.com/go-latex/latex v0.0.0-20210823091927-c0d11ff05a81 h1:6zl3BbBhdnMkpSj2YY30qV3gDcVBGtFgVsV3+/i+mKQ= -github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ= github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg= github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab h1:xveKWz2iaueeTaUgdetzel+U7exyigDYBryyVfV/rZk= github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY= +github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= +github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= github.com/go-openapi/swag v0.19.5 h1:lTz6Ys4CmqqCQmZPBlbQENR1/GucA2bzYTE12Pw4tFY= +github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= github.com/go-pdf/fpdf v0.6.0 h1:MlgtGIfsdMEEQJr2le6b/HNr1ZlQwxyWr77r2aj2U/8= github.com/go-redis/redis v6.15.8+incompatible h1:BKZuG6mCnRj5AOaWJXoCgf6rqTYnYJLe4en2hxT7r9o= github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI= +github.com/go-redsync/redsync/v4 v4.13.0 h1:49X6GJfnbLGaIpBBREM/zA4uIMDXKAh1NDkvQ1EkZKA= github.com/go-redsync/redsync/v4 v4.13.0/go.mod h1:HMW4Q224GZQz6x1Xc7040Yfgacukdzu7ifTDAKiyErQ= +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-stack/stack v1.8.1 h1:ntEHSVwIt7PNXNpgPmVfMrNhLtgjlmnZha2kOpuRiDw= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I= -github.com/go-viper/mapstructure/v2 v2.3.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/go-zookeeper/zk v1.0.2 h1:4mx0EYENAdX/B/rbunjlt5+4RTA/a9SMHBRuSKdGxPM= github.com/go-zookeeper/zk v1.0.2/go.mod h1:nOB03cncLtlp4t+UAkGSV+9beXP/akpekBwL+UX1Qcw= -github.com/goccy/go-yaml v1.17.1/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA= github.com/godbus/dbus/v5 v5.0.4 h1:9349emZab16e7zQvpmsbtjc18ykshndd8y2PG3sgJbA= github.com/godbus/dbus/v5 v5.0.6/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gogo/googleapis v1.4.1 h1:1Yx4Myt7BxzvUr5ldGSbwYiZG6t9wGBZ+8/fX3Wvtq0= github.com/gogo/status v1.1.0 h1:+eIkrewn5q6b30y+g/BJINVVdi2xH7je5MPJ3ZPK3JA= github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g= +github.com/golang/glog v1.0.0 h1:nfP3RFugxnNRyKgeWd4oI1nYvXpxrx8ck8ZrcizshdQ= github.com/gonum/blas v0.0.0-20181208220705-f22b278b28ac h1:Q0Jsdxl5jbxouNs1TQYt0gxesYMU4VXRbsTlgDloZ50= github.com/gonum/floats v0.0.0-20181209220543-c233463c7e82 h1:EvokxLQsaaQjcWVWSV38221VAK7qc2zhaO17bKys/18= github.com/gonum/internal v0.0.0-20181124074243-f884aa714029 h1:8jtTdc+Nfj9AR+0soOeia9UZSvYBvETVHZrugUowJ7M= @@ -812,6 +818,7 @@ github.com/gonum/lapack v0.0.0-20181123203213-e4cdc5a0bff9 h1:7qnwS9+oeSiOIsiUMa github.com/gonum/matrix v0.0.0-20181209220409-c518dec07be9 h1:V2IgdyerlBa/MxaEFRbV5juy/C3MGdj4ePi+g6ePIp4= github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= github.com/google/certificate-transparency-go v1.1.1 h1:6JHXZhXEvilMcTjR4MGZn5KV0IRkcFl4CJx5iHVhjFE= +github.com/google/gnostic-models v0.7.0 h1:qwTtogB15McXDaNqTZdzPJRHvaVJlAl+HVQnLmJEJxo= github.com/google/gnostic-models v0.7.0/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ= github.com/google/go-pkcs11 v0.3.0 h1:PVRnTgtArZ3QQqTGtbtjtnIkzl2iY2kt24yqbrf7td8= github.com/google/go-pkcs11 v0.3.0/go.mod h1:6eQoGcuNJpa7jnd5pMGdkSaQpNDYvPlXWMcjXXThLlY= @@ -822,30 +829,29 @@ github.com/google/martian/v3 v3.3.3/go.mod h1:iEPrYcgCF7jA9OtScMFQyAlZZ4YXTKEtJ1 github.com/google/renameio v0.1.0 h1:GOZbcHa3HfsPKPlmyPyN2KEohoMXOhdMbHrvbpl2QaA= github.com/google/s2a-go v0.1.8 h1:zZDs9gcbt9ZPLV0ndSyQk6Kacx2g/X+SKYovpnz3SMM= github.com/google/s2a-go v0.1.8/go.mod h1:6iNWHTpQ+nfNRN5E00MSdfDwVesa8hhS32PhPO8deJA= +github.com/google/s2a-go v0.1.9 h1:LGD7gtMgezd8a/Xak7mEWL0PjoTQFvpRudN895yqKW0= github.com/google/s2a-go v0.1.9/go.mod h1:YA0Ei2ZQL3acow2O62kdp9UlnvMmU7kA6Eutn0dXayM= github.com/google/safehtml v0.0.2 h1:ZOt2VXg4x24bW0m2jtzAOkhoXV0iM8vNKc0paByCZqM= github.com/google/subcommands v1.2.0 h1:vWQspBTo2nEqTUFita5/KeEWlUL8kQObDFbub/EN9oE= github.com/google/trillian v1.3.11 h1:pPzJPkK06mvXId1LHEAJxIegGgHzzp/FUnycPYfoCMI= github.com/googleapis/cloud-bigtable-clients-test v0.0.2 h1:S+sCHWAiAc+urcEnvg5JYJUOdlQEm/SEzQ/c/IdAH5M= github.com/googleapis/cloud-bigtable-clients-test v0.0.2/go.mod h1:mk3CrkrouRgtnhID6UZQDK3DrFFa7cYCAJcEmNsHYrY= +github.com/googleapis/cloud-bigtable-clients-test v0.0.3 h1:afMKTvA/jc6jSTMkeHBZGFDTt8Cc+kb1ATFzqMK85hw= github.com/googleapis/cloud-bigtable-clients-test v0.0.3/go.mod h1:TWtDzrrAI70C3dNLDY+nZN3gxHtFdZIbpL9rCTFyxE0= -github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0= github.com/googleapis/enterprise-certificate-proxy v0.3.4 h1:XYIDZApgAnrN1c855gTgghdIA6Stxb52D5RnLI1SLyw= github.com/googleapis/enterprise-certificate-proxy v0.3.4/go.mod h1:YKe7cfqYXjKGpGvmSg28/fFvhNzinZQm8DGnaburhGA= -github.com/googleapis/enterprise-certificate-proxy v0.3.5/go.mod h1:MkHOF77EYAE7qfSuSS9PU6g4Nt4e11cnsDUowfwewLA= +github.com/googleapis/enterprise-certificate-proxy v0.3.6 h1:GW/XbdyBFQ8Qe+YAmFU9uHLo7OnF5tL52HFAgMmyrf4= github.com/googleapis/enterprise-certificate-proxy v0.3.6/go.mod h1:MkHOF77EYAE7qfSuSS9PU6g4Nt4e11cnsDUowfwewLA= github.com/googleapis/gax-go v0.0.0-20161107002406-da06d194a00e h1:CYRpN206UTHUinz3VJoLaBdy1gEGeJNsqT0mvswDcMw= -github.com/googleapis/gax-go/v2 v2.12.3/go.mod h1:AKloxT6GtNbaLm8QTNSidHUVsHYcBHwWRvkNFJUQcS4= -github.com/googleapis/gax-go/v2 v2.14.0/go.mod h1:lhBCnjdLrWRaPvLWhmc8IS24m9mr07qSYnHncrgo+zk= github.com/googleapis/gax-go/v2 v2.14.1 h1:hb0FFeiPaQskmvakKu5EbCbpntQn48jyHuvrkurSS/Q= github.com/googleapis/gax-go/v2 v2.14.1/go.mod h1:Hb/NubMaVM88SrNkvl8X/o8XWwDJEPqouaLeN2IUxoA= github.com/googleapis/gax-go/v2 v2.14.2/go.mod h1:ON64QhlJkhVtSqp4v1uaK92VyZ2gmvDQsweuyLV+8+w= +github.com/googleapis/gax-go/v2 v2.15.0 h1:SyjDc1mGgZU5LncH8gimWo9lW1DtIfPibOG81vgd/bo= github.com/googleapis/gax-go/v2 v2.15.0/go.mod h1:zVVkkxAQHa1RQpg9z2AUCMnKhi0Qld9rcmyfL1OZhoc= github.com/googleapis/go-type-adapters v1.0.0 h1:9XdMn+d/G57qq1s8dNc5IesGCXHf6V2HZ2JwRxfA2tA= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8 h1:tlyzajkF3030q6M8SvmJSemC9DTHL/xaMa18b65+JM4= github.com/gookit/color v1.5.1 h1:Vjg2VEcdHpwq+oY63s/ksHrgJYCTo0bwWvmmYWdE9fQ= github.com/gookit/color v1.5.1/go.mod h1:wZFzea4X8qN6vHOSP2apMb4/+w/orMznEzYsIHPaqKM= -github.com/gookit/color v1.5.4/go.mod h1:pZJOeOS8DM43rXbp4AZo1n9zCU2qjpcRko0b6/QJi9w= github.com/gopherjs/gopherjs v1.17.2 h1:fQnZVsXk8uxXIStYb0N4bGk7jeyTalG/wsZjQ25dO0g= github.com/gorhill/cronexpr v0.0.0-20180427100037-88b0669f7d75 h1:f0n1xnMSmBLzVfsMMvriDyA75NB/oBgILX2GcHXIQzY= github.com/gorilla/context v1.1.1 h1:AWwleXJkX/nhcU9bZSnZoi3h/qGYqQAGhq6zZe/aQW8= @@ -854,12 +860,13 @@ github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyC github.com/gostaticanalysis/analysisutil v0.4.1/go.mod h1:18U/DLpRgIUd459wGxVHE0fRgmo1UgHDcbw7F5idXu0= github.com/graph-gophers/graphql-go v1.3.0 h1:Eb9x/q6MFpCLz7jBCiP/WTxjSDrYLR1QY41SORZyNJ0= github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 h1:+ngKgrYPPJrOjhax5N+uePQ0Fh1Z7PheYoUI/0nzkPA= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 h1:YBftPWNWd4WwGqtY2yeZL2ef8rHAxPBD8KFhJpmcqms= github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0/go.mod h1:YN5jB8ie0yfIUg6VvR9Kz84aCaG7AsGZnLjhHbUqwPg= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.25.1/go.mod h1:RBRO7fro65R6tjKzYgLAFo0t1QEXY1Dp+i/bvpRiqiQ= +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/grpc-ecosystem/grpc-gateway/v2 v2.27.1 h1:X5VWvz21y3gzm9Nw/kaUeku/1+uBhcekkmy4IkffJww= github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1/go.mod h1:Zanoh4+gvIgluNqcfMVTJueD4wSS5hT7zTt4Mrutd90= github.com/guptarohit/asciigraph v0.5.5 h1:ccFnUF8xYIOUPPY3tmdvRyHqmn1MYI9iv1pLKX+/ZkQ= -github.com/hamba/avro/v2 v2.29.0/go.mod h1:Pk3T+x74uJoJOFmHrdJ8PRdgSEL/kEKteJ31NytCKxI= github.com/hashicorp/consul/api v1.10.1/go.mod h1:XjsvQN+RJGWI2TWy1/kqaE16HrR2J/FWgkYjdZQsX9M= github.com/hashicorp/consul/api v1.11.0/go.mod h1:XjsvQN+RJGWI2TWy1/kqaE16HrR2J/FWgkYjdZQsX9M= github.com/hashicorp/consul/api v1.12.0 h1:k3y1FYv6nuKyNTqj6w9gXOx5r5CfLj/k/euUeBXj1OY= @@ -893,6 +900,7 @@ github.com/iancoleman/strcase v0.3.0 h1:nTXanmYxhfFAMjZL34Ov6gkzEsSJZ5DbhxWjvSAS github.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= github.com/ianlancetaylor/demangle v0.0.0-20220319035150-800ac71e25c2 h1:rcanfLhLDA8nozr/K289V1zcntHr3V+SHlXwzz1ZI2g= github.com/imdario/mergo v0.3.8 h1:CGgOkSJeqMRmt0D9XLWExdT4m4F1vd3FV3VPt+0VxkQ= +github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg= github.com/imkira/go-interpol v1.1.0 h1:KIiKr0VSG2CUW1hl1jpiyuzuJeKUUpC8iM1AIE7N1Vk= github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/influxdata/influxdb-client-go/v2 v2.4.0 h1:HGBfZYStlx3Kqvsv1h2pJixbCl/jhnFtxpKFAv9Tu5k= @@ -901,15 +909,21 @@ github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839 h1:W9WBk7 github.com/iris-contrib/go.uuid v2.0.0+incompatible h1:XZubAYg61/JwnJNbZilGjf3b3pB80+OQg2qf6c8BfWE= github.com/iris-contrib/httpexpect/v2 v2.12.1 h1:3cTZSyBBen/kfjCtgNFoUKi1u0FVXNaAjyRJOo6AVS4= github.com/iris-contrib/schema v0.0.6 h1:CPSBLyx2e91H2yJzPuhGuifVRnZBBJ3pCOMbOvPZaTw= +github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= +github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo= github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= +github.com/jackc/pgx/v5 v5.7.5 h1:JHGfMnQY+IEtGM63d+NGMjoRpysB2JBwDr5fsngwmJs= github.com/jackc/pgx/v5 v5.7.5/go.mod h1:aruU7o91Tc2q2cFp5h4uP3f6ztExVpyVv88Xl/8Vl8M= +github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo= github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= github.com/jedisct1/go-minisign v0.0.0-20230811132847-661be99b8267 h1:TMtDYDHKYY15rFihtRfck/bfFqNfvcabqvXAFQfAUpY= github.com/jessevdk/go-flags v1.4.0 h1:4IU2WS7AumrZ/40jfhf4QVDMsQwqA7VEHozFRrGARJA= github.com/jhump/gopoet v0.1.0 h1:gYjOPnzHd2nzB37xYQZxj4EIQNpBrBskRqQQ3q4ZgSg= github.com/jhump/goprotoc v0.5.0 h1:Y1UgUX+txUznfqcGdDef8ZOVlyQvnV0pKWZH08RmZuo= +github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= +github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= github.com/jmoiron/sqlx v1.2.0 h1:41Ip0zITnmWNR/vHV+S4m+VoUivnWY5E4OJfLZjCJMA= github.com/jonboulle/clockwork v0.2.0 h1:J2SLSdy7HgElq8ekSl2Mxh6vrRNFxqbXGenYH2I02Vs= @@ -937,6 +951,7 @@ github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNU github.com/keybase/go-keychain v0.0.0-20190712205309-48d3d31d256d h1:Z+RDyXzjKE0i2sTjZ/b1uxiGtPhFy34Ou/Tk0qwN0kM= github.com/kilic/bls12-381 v0.1.0 h1:encrdjqKMEvabVQ7qYOKu1OvhqpK4s47wDYtNiPtlp4= github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23 h1:FOOIBWrEkLgmlgGfMuZT83xIwfPDxEI2OHu6xUmJMFE= +github.com/klauspost/asmfmt v1.3.2 h1:4Ri7ox3EwapiOjCki+hw14RyKk201CN4rzyCJRFLpK4= github.com/klauspost/compress v1.13.4/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/compress v1.13.5/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8= @@ -958,7 +973,6 @@ github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-b github.com/lightstep/lightstep-tracer-go v0.18.1 h1:vi1F1IQ8N7hNWytK9DpJsUfQhGuNSc19z330K6vl4zk= github.com/lispad/go-generics-tools v1.1.0 h1:mbSgcxdFVmpoyso1X/MJHXbSbSL3dD+qhRryyxk+/XY= github.com/lispad/go-generics-tools v1.1.0/go.mod h1:2csd1EJljo/gy5qG4khXol7ivCPptNjG5Uv2X8MgK84= -github.com/lithammer/fuzzysearch v1.1.8/go.mod h1:IdqeyBClc3FFqSzYq/MXESsS4S0FsZ5ajtkr5xPLts4= github.com/lucasjones/reggen v0.0.0-20180717132126-cdb49ff09d77 h1:6xiz3+ZczT3M4+I+JLpcPGG1bQKm8067HktB17EDWEE= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4= github.com/lyft/protoc-gen-star v0.5.3/go.mod h1:V0xaHgaf5oCCqmcxYcWiDfTiKsZsRc87/1qhoTACD8w= @@ -973,6 +987,7 @@ github.com/matryer/moq v0.3.0 h1:4j0goF/XK3pMTc7fJB3fveuTJoQNdavRX/78vlK3Xb4= github.com/matryer/moq v0.3.0/go.mod h1:RJ75ZZZD71hejp39j4crZLsEDszGk6iH4v4YsWFKH4s= github.com/matryer/try v0.0.0-20161228173917-9ac251b645a2 h1:JAEbJn3j/FrhdWA9jW8B5ajsLIjeuEHLi8xE4fk997o= github.com/mattn/go-sqlite3 v1.14.14 h1:qZgc/Rwetq+MtyE18WhzjokPD93dNqLGNT3QJuLvBGw= +github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/mediocregopher/radix/v3 v3.8.1 h1:rOkHflVuulFKlwsLY01/M2cM2tWCjDoETcMqKbAWu1M= @@ -982,8 +997,9 @@ github.com/microcosm-cc/bluemonday v1.0.23 h1:SMZe2IGa0NuHvnVNAZ+6B38gsTbi5e4sVi github.com/miekg/dns v1.1.43 h1:JKfpVSCB84vrAmHzyrsxB5NAr5kLoMXZArPSw7Qlgyg= github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4= github.com/miekg/pkcs11 v1.0.3 h1:iMwmD7I5225wv84WxIG/bmxz9AXjWvTWIbM/TYHvWtw= +github.com/minio/asm2plan9s v0.0.0-20200509001527-cdd76441f9d8 h1:AMFGa4R4MiIpspGNG7Z948v4n35fFGB3RR3G/ry4FWs= +github.com/minio/c2goasm v0.0.0-20190812172519-36a3d3bbc4f3 h1:+n/aFZefKZp7spd8DFdX7uMikMLXX4oubIzJF4kv/wI= github.com/minio/highwayhash v1.0.2 h1:Aak5U0nElisjDCfPSG79Tgzkn2gl66NxOMspRrKnA/g= -github.com/minio/sha256-simd v1.0.0 h1:v1ta+49hkWZyvaKwrQB8elexRqm6Y0aMLjCNsrYxo6g= github.com/mitchellh/cli v1.1.0 h1:tEElEatulEHDeedTxwckzyYMA5c86fbmNIUL1hBIiTg= github.com/mitchellh/copystructure v1.0.0 h1:Laisrj+bAB6b/yJwB5Bt3ITZhGJdqmxquMKeZ+mmkFQ= github.com/mitchellh/go-ps v1.0.0 h1:i6ampVEEF4wQFF+bkYfwYgY+F/uYJDktmvLPf7qIgjc= @@ -997,6 +1013,8 @@ github.com/mmcloughlin/addchain v0.4.0 h1:SobOdjm2xLj1KkXN5/n0xTIWyZA2+s99UCY1iP github.com/mmcloughlin/profile v0.1.1 h1:jhDmAqPyebOsVDOCICJoINoLb/AnLBaUw58nFzxWS2w= github.com/moby/sys/mountinfo v0.4.1 h1:1O+1cHA1aujwEwwVMa2Xm2l+gIpUHyd3+D+d7LZh1kM= github.com/moby/sys/mountinfo v0.5.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU= +github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0= +github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= github.com/modocache/gover v0.0.0-20171022184752-b58185e213c5 h1:8Q0qkMVC/MmWkpIdlvZgcv2o2jrlF6zqVOh7W5YHdMA= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= github.com/montanaflynn/stats v0.7.0 h1:r3y12KyNxj/Sb/iOE46ws+3mS1+MZca1wlHQFPsY/JU= @@ -1017,10 +1035,10 @@ github.com/nats-io/nats-server/v2 v2.9.11 h1:4y5SwWvWI59V5mcqtuoqKq6L9NDUydOP3Ek github.com/nats-io/nats.go v1.23.0 h1:lR28r7IX44WjYgdiKz9GmUeW0uh/m33uD3yEjLZ2cOE= github.com/nats-io/nkeys v0.3.0 h1:cgM5tL53EvYRU+2YLXIK0G2mJtK12Ft9oeooSZMA2G8= github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw= -github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls= github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86 h1:D6paGObi5Wud7xg83MaEFyjxQB1W5bz5d0IFppr+ymk= github.com/neelance/sourcemap v0.0.0-20200213170602-2833bce08e4c h1:bY6ktFuJkt+ZXkX0RChQch2FtHpWQLVS8Qo1YasiIVk= github.com/neilotoole/errgroup v0.1.5 h1:DxEGoIfFm5ooGicidR+okiHjoOaGRKFaSxDPVZuuu2I= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/oklog/oklog v0.3.2 h1:wVfs8F+in6nTBMkA7CbRw+zZMIB7nNM825cM1wuzoTk= github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw= github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4= @@ -1042,6 +1060,7 @@ github.com/openzipkin/zipkin-go v0.2.5/go.mod h1:KpXfKdgRDnnhsxw4pNIH9Md5lyFqKUa github.com/otiai10/curr v1.0.0 h1:TJIWdbX0B+kpNagQrjgq8bCMrbhiuX73M2XwgtDMoOI= github.com/otiai10/mint v1.3.1 h1:BCmzIS3n71sGfHB5NMNDB3lHYPz8fWSkCAErHed//qc= github.com/pact-foundation/pact-go v1.0.4 h1:OYkFijGHoZAYbOIb1LWXrwKQbMMRUv1oQ89blD2Mh2Q= +github.com/paulmach/orb v0.11.1 h1:3koVegMC4X/WeiXYz9iswopaTwMem53NzTJuTF20JzU= github.com/paulmach/orb v0.11.1/go.mod h1:5mULz1xQfs3bmQm63QEJA6lNGujuRafwA5S/EnuLaLU= github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 h1:onHthvaw9LFnH4t2DcNVpwGmV9E1BkGknEliJkfwQj0= github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58/go.mod h1:DXv8WO4yhMYhSNPKjeNKa5WY9YCIEBRbNzFFPJbWO6Y= @@ -1058,6 +1077,8 @@ github.com/phpdave11/gofpdi v1.0.13 h1:o61duiW8M9sMlkVXWlvP92sZJtGKENvW3VExs6dZu github.com/pierrec/lz4 v2.0.5+incompatible h1:2xWsjqPFWcplujydGg4WmhC/6fZqK42wMM8aXeqhl0I= github.com/pierrec/lz4/v4 v4.1.18 h1:xaKrnTkyoqfh1YItXl56+6KJNVYWlEEPuAQW9xsplYQ= github.com/pierrec/lz4/v4 v4.1.18/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= +github.com/pierrec/lz4/v4 v4.1.22 h1:cKFw6uJDK+/gfw5BcDL0JL5aBsAFdsIT18eRtLj7VIU= +github.com/pierrec/lz4/v4 v4.1.22/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= github.com/pion/datachannel v1.5.2 h1:piB93s8LGmbECrpO84DnkIVWasRMk3IimbcXkTQLE6E= github.com/pion/datachannel v1.5.2/go.mod h1:FTGQWaHrdCwIJ1rw6xBIfZVkslikjShim5yr05XFuCQ= github.com/pion/ice/v2 v2.2.6 h1:R/vaLlI1J2gCx141L5PEwtuGAGcyS6e7E0hDeJFq5Ig= @@ -1098,9 +1119,7 @@ github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g= github.com/prometheus/client_golang v1.20.4/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= github.com/prometheus/client_model v0.6.0/go.mod h1:NTQHnmxFpouOD0DpvP4XujX3CdOAGQPoaGhyTchlyt8= -github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= -github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is= github.com/prometheus/tsdb v0.7.1 h1:YZcsG11NqnK4czYLrWd9mpEuAJIHVQLwdrleYfszMAA= github.com/protolambda/bls12-381-util v0.1.0 h1:05DU2wJN7DTU7z28+Q+zejXkIsA/MF8JZQGhtBZZiWk= github.com/protolambda/messagediff v1.4.0 h1:fk6gxK7WybJCaeOFK1yuh2Ldplx7qYMLibiMwWFcSZY= @@ -1109,13 +1128,11 @@ github.com/protolambda/ztyp v0.2.2 h1:rVcL3vBu9W/aV646zF6caLS/dyn9BN8NYiuJzicLNy github.com/prysmaticlabs/gohashtree v0.0.1-alpha.0.20220714111606-acbb2962fb48 h1:cSo6/vk8YpvkLbk9v3FO97cakNmUoxwi2KMP8hd5WIw= github.com/pseudomuto/protoc-gen-doc v1.3.2 h1:61vWZuxYa8D7Rn4h+2dgoTNqnluBmJya2MgbqO32z6g= github.com/pseudomuto/protokit v0.2.0 h1:hlnBDcy3YEDXH7kc9gV+NLaN0cDzhDvD1s7Y6FZ8RpM= -github.com/pterm/pterm v0.12.81/go.mod h1:TyuyrPjnxfwP+ccJdBTeWHtd/e0ybQHkOS/TakajZCw= github.com/quasilyte/go-ruleguard/dsl v0.3.22 h1:wd8zkOhSNr+I+8Qeciml08ivDt1pSXe60+5DqOpCjPE= github.com/quasilyte/go-ruleguard/dsl v0.3.22/go.mod h1:KeCP03KrjuSO0H1kTuZQCWlQPulDV6YMIXmpQss17rU= github.com/quasilyte/go-ruleguard/rules v0.0.0-20211022131956-028d6511ab71 h1:CNooiryw5aisadVfzneSZPswRWvnVW8hF1bS/vo8ReI= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a h1:9ZKAASQSHhDYGoxY8uLVpewe1GDZ2vu2Tr/vTdVAkFQ= github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 h1:OdAsTTz6OkFY5QxjkYwrChwuRruF69c169dPK26NUlk= -github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/remyoudompheng/go-dbus v0.0.0-20121104212943-b7232d34b1d5 h1:CvqZS4QYHBRvx7AeFdimd16HCbLlYsvQMcKDACpJW/c= github.com/remyoudompheng/go-dbus v0.0.0-20121104212943-b7232d34b1d5/go.mod h1:+u151txRmLpwxBmpYn9z3d1sdJdjRPQpsXuYeY9jNls= github.com/remyoudompheng/go-liblzma v0.0.0-20190506200333-81bf2d431b96 h1:J8J/cgLDRuqXJnwIrRDBvtl+LLsdg7De74znW/BRRq4= @@ -1124,10 +1141,11 @@ github.com/remyoudompheng/go-misc v0.0.0-20190427085024-2d6ac652a50e h1:eTWZyPUn github.com/remyoudompheng/go-misc v0.0.0-20190427085024-2d6ac652a50e/go.mod h1:80FQABjoFzZ2M5uEa6FUaJYEmqU2UOKojlFVak1UAwI= github.com/rogpeppe/fastuuid v1.2.0 h1:Ppwyp6VYCF1nvBTXL3trRso7mXMlRrw9ooo375wvi2s= github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= -github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= github.com/rs/dnscache v0.0.0-20211102005908-e0241e321417 h1:Lt9DzQALzHoDwMBGJ6v8ObDPR0dzr2a6sXTB1Fq7IHs= github.com/rs/dnscache v0.0.0-20211102005908-e0241e321417/go.mod h1:qe5TWALJ8/a1Lqznoc5BDHpYX/8HU60Hm2AwRmqzxqA= github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo= +github.com/russross/blackfriday v1.6.0 h1:KqfZb0pUVN2lYqZUYRddxF4OR8ZMURnJIG5Y3VRLtww= +github.com/russross/blackfriday v1.6.0/go.mod h1:ti0ldHuxg49ri4ksnFxlkCfN+hvslNlmVHqNRXXJNAY= github.com/ruudk/golang-pdf417 v0.0.0-20201230142125-a7e3863a1245 h1:K1Xf3bKttbF+koVGaX5xngRIZ5bVjbmPnaxE/dR08uY= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f h1:UFr9zpz4xgTnIE5yIMtWAMngCdZ9p/+q6lTbgelo80M= github.com/sagikazarmark/crypt v0.3.0/go.mod h1:uD/D+6UF4SrIR1uGEv7bBNkNqLGqUr43MRiaGWX1Nig= @@ -1135,17 +1153,20 @@ github.com/sagikazarmark/crypt v0.6.0 h1:REOEXCs/NFY/1jOCEouMuT4zEniE5YoXbvpC5X/ github.com/sagikazarmark/crypt v0.6.0/go.mod h1:U8+INwJo3nBv1m6A/8OBXAq7Jnpspk5AxSgDyEQcea8= github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da h1:p3Vo3i64TCLY7gIfzeQaUJ+kppEO5WQG3cL8iE8tGHU= github.com/sanity-io/litter v1.5.5 h1:iE+sBxPBzoK6uaEP5Lt3fHNgpKcHXc/A2HGETy0uJQo= +github.com/santhosh-tekuri/jsonschema/v5 v5.3.1/go.mod h1:uToXkOrWAZ6/Oc07xWQrPOhJotwFIyu2bBVN41fcDUY= github.com/schollz/closestmatch v2.1.0+incompatible h1:Uel2GXEpJqOWBrlyI+oY9LTiyyjYS17cCYRqP13/SHk= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I= github.com/seccomp/libseccomp-golang v0.9.1 h1:NJjM5DNFOs0s3kYE1WUOr6G8V97sdt46rlXTMfXGWBo= github.com/seccomp/libseccomp-golang v0.9.2-0.20220502022130-f33da4d89646/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg= +github.com/segmentio/asm v1.2.0 h1:9BQrFxC+YOHJlTlHGkTrFWf59nbL3XnCoFLTwDCI7ys= github.com/segmentio/asm v1.2.0/go.mod h1:BqMnlJP91P8d+4ibuonYZw9mfnzI9HfxselHZr5aAcs= github.com/segmentio/fasthash v1.0.3 h1:EI9+KE1EwvMLBWwjpRDc+fEM+prwxDYbslddQGtrmhM= -github.com/sei-protocol/go-ethereum v1.15.8-wip h1:isUcMF8DkzsrCoYIxlMKAw7bR5rmzJqwWurunv/t/kI= -github.com/sei-protocol/go-ethereum v1.15.8-wip/go.mod h1:+S9k+jFzlyVTNcYGvqFhzN/SFhI6vA+aOY4T5tLSPL0= +github.com/sei-protocol/go-ethereum v1.15.7-sei-12 h1:3Wj5nU7X0+mKcDho6mwf0leVytQWmNEq6xFv9Wr+HOs= +github.com/sei-protocol/go-ethereum v1.15.7-sei-12/go.mod h1:+S9k+jFzlyVTNcYGvqFhzN/SFhI6vA+aOY4T5tLSPL0= github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= github.com/shirou/gopsutil/v3 v3.22.9/go.mod h1:bBYl1kjgEJpWpxeHmLI+dVHWtyAwfcmSBLDsp2TNT8A= github.com/shirou/gopsutil/v3 v3.23.2 h1:PAWSuiAszn7IhPMBtXsbSCafej7PqUOvY6YywlQUExU= +github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k= github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME= github.com/shurcooL/go v0.0.0-20200502201357-93f07166e636 h1:aSISeOcal5irEhJd1M+IrApc0PdcN7e7Aj4yuEnOrfQ= github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041 h1:llrF3Fs4018ePo4+G/HV/uQUqEI1HMDjCeOf2V6puPc= @@ -1162,18 +1183,15 @@ github.com/spf13/afero v1.10.0/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb github.com/spf13/cobra v1.3.0/go.mod h1:BrRVncBjOJa/eUcVVm9CE+oC6as8k+VYr4NY7WCi9V4= github.com/spf13/cobra v1.6.0/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY= github.com/spf13/viper v1.10.0/go.mod h1:SoyBPwAtKDzypXNDFKN5kzH7ppppbGZtls1UpIy5AsM= +github.com/spiffe/go-spiffe/v2 v2.5.0 h1:N2I01KCUkv1FAjZXJMwh95KK1ZIQLYbPfhaxw8WS0hE= github.com/spiffe/go-spiffe/v2 v2.5.0/go.mod h1:P+NxobPc6wXhVtINNtFjNWGBTreew1GBUCwT2wPmb7g= github.com/status-im/keycard-go v0.2.0 h1:QDLFswOQu1r5jsycloeQh3bVU8n/NatHHaZobtDnDzA= -github.com/stoewer/go-strcase v1.3.1/go.mod h1:fAH5hQ5pehh+j3nZfvwdk2RgEgQjAoM8wodgtPmh1xo= github.com/streadway/amqp v1.0.0 h1:kuuDrUJFZL1QYL9hUNuCxNObNzB0bV/ZG5jV3RWAQgo= github.com/streadway/amqp v1.0.0/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= github.com/streadway/handy v0.0.0-20200128134331-0f66f006fb2e h1:mOtuXaRAbVZsxAHVdPR3IjfmN8T1h2iczJLynhLybf8= github.com/streadway/handy v0.0.0-20200128134331-0f66f006fb2e/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= github.com/stretchr/testify v1.7.5/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/subosito/gotenv v1.4.1/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= -github.com/substrait-io/substrait v0.69.0/go.mod h1:MPFNw6sToJgpD5Z2rj0rQrdP/Oq8HG7Z2t3CAEHtkHw= -github.com/substrait-io/substrait-go/v4 v4.4.0/go.mod h1:GzpaFqO5VRtMkEjATgRxGK5p82OmEtCmszAVYxE+iWc= -github.com/substrait-io/substrait-protobuf/go v0.71.0/go.mod h1:hn+Szm1NmZZc91FwWK9EXD/lmuGBSRTJ5IvHhlG1YnQ= github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 h1:kdXcSzyDtseVEc4yCz2qF8ZrQvIDBJLl4S1c3GCXmoI= github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/tailscale/depaware v0.0.0-20210622194025-720c4b409502 h1:34icjjmqJ2HPjrSuJYEkdZ+0ItmGQAQ75cRHIiftIyE= @@ -1183,7 +1201,6 @@ github.com/tdewolff/test v1.0.7 h1:8Vs0142DmPFW/bQeHRP3MV19m1gvndjUb1sn8yy74LM= github.com/tendermint/tendermint v0.37.0-dev h1:kmktXDtTYcwUj0x5BvkmZ+SGe8E1YJiXVDX9MhgBuCQ= github.com/tendermint/tendermint v0.37.0-dev/go.mod h1:cEvyfTDZKrgpt13uLeFX8+xstdh1FWgrspp/IsNXrPY= github.com/tidwall/sjson v1.1.4 h1:bTSsPLdAYF5QNLSwYsKfBKKTnlGbIuhqL3CpRsjzGhg= -github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= github.com/tklauser/go-sysconf v0.3.10/go.mod h1:C8XykCvCb+Gn0oNCWPIlcb0RuglQTYaQ2hGm7jmxEFk= github.com/tklauser/numcpus v0.4.0/go.mod h1:1+UI3pD8NW14VMwdgJNJ1ESk2UnwhAnz5hMwiKKqXCQ= github.com/tmc/grpc-websocket-proxy v0.0.0-20200427203606-3cfed13b9966 h1:j6JEOq5QWFker+d7mFQYOhjTZonQ7YkLTHm56dbn+yM= @@ -1192,7 +1209,9 @@ github.com/torquem-ch/mdbx-go v0.27.5 h1:bbhXQGFCmoxbRDXKYEJwxSOOTeBKwoD4pFBUpK9 github.com/torquem-ch/mdbx-go v0.27.5/go.mod h1:T2fsoJDVppxfAPTLd1svUgH1kpPmeXdPESmroSHcL1E= github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c h1:u6SKchux2yDvFQnDHS3lPnIRmfVJ5Sxy3ao2SIdysLQ= github.com/tyler-smith/go-bip39 v1.0.2 h1:+t3w+KwLXO6154GNJY+qUtIxLTmFjfUmpguQT1OlOT8= +github.com/uptrace/opentelemetry-go-extra/otelgorm v0.3.2 h1:Jjn3zoRz13f8b1bR6LrXWglx93Sbh4kYfwgmPju3E2k= github.com/uptrace/opentelemetry-go-extra/otelgorm v0.3.2/go.mod h1:wocb5pNrj/sjhWB9J5jctnC0K2eisSdz/nJJBNFHo+A= +github.com/uptrace/opentelemetry-go-extra/otelsql v0.3.2 h1:ZjUj9BLYf9PEqBn8W/OapxhPjVRdC6CsXTdULHsyk5c= github.com/uptrace/opentelemetry-go-extra/otelsql v0.3.2/go.mod h1:O8bHQfyinKwTXKkiKNGmLQS7vRsqRxIQTFZpYpHK3IQ= github.com/urfave/cli v1.22.1 h1:+mkCCcOFKPnCmVYVcURKps1Xe+3zP90gSYGNfRkjoIY= github.com/urfave/negroni v1.0.0 h1:kIimOitoypq34K7TG7DUaJ9kq/N4Ofuwi1sjz0KipXc= @@ -1215,13 +1234,14 @@ github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17 github.com/vmihailenco/msgpack/v5 v5.3.5 h1:5gO0H1iULLWGhs2H5tbAHIZTV8/cYafcFOr9znI5mJU= github.com/vmihailenco/tagparser v0.1.2 h1:gnjoVuB/kljJ5wICEEOpx98oXMWPLj22G67Vbd1qPqc= github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= +github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c= github.com/xhit/go-str2duration/v2 v2.1.0 h1:lxklc02Drh6ynqX+DdPyp5pCKLUQpRT8bp8Ydu2Bstc= github.com/xhit/go-str2duration/v2 v2.1.0/go.mod h1:ohY8p+0f07DiV6Em5LKB0s2YpLtXVyJfNt1+BlmyAsU= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8= github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 h1:QldyIu/L63oPpyvQmHgvgickp1Yw510KJOqX7H24mg8= -github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM= +github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778/go.mod h1:2MuV+tbUrU1zIOPMxZ5EncGwgmMJsa+9ucAQZXxsObs= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77 h1:ESFSdwYZvkeru3RtdrYueztKhOBCSAAzS4Gf+k0tEow= github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0 h1:6fRhSjgLCkTD3JnJxvaJ4Sj+TYblw757bqYgZaOq5ZY= github.com/ybbus/jsonrpc v2.1.2+incompatible h1:V4mkE9qhbDQ92/MLMIhlhMSbz8jNXdagC3xBR5NDwaQ= @@ -1230,12 +1250,16 @@ github.com/yudai/gojsondiff v1.0.0 h1:27cbfqXLVEJ1o8I6v3y9lg8Ydm53EKqHXAOMxEGlCO github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 h1:BHyfKlQyqbsFN5p3IfnEUduWvb9is428/nNb5L3U01M= github.com/yudai/pp v2.0.1+incompatible h1:Q4//iY4pNF6yPLZIigmvcl7k/bPgrcTPIFIcmawg5bI= github.com/yuin/goldmark v1.4.13 h1:fVcFKWvrslecOb/tg+Cc05dkeYx540o0FuFt3nUVDoE= +github.com/yuin/gopher-lua v1.1.1 h1:kYKnWBjvbNP4XLT3+bPEwAXJx262OhaHDWDVOPjL46M= github.com/yuin/gopher-lua v1.1.1/go.mod h1:GBR0iDaNXjAgGg9zfCvksxSRnQx76gclCIb7kdAd1Pw= github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg= +github.com/zeebo/errs v1.4.0 h1:XNdoD/RRMKP7HD0UhJnIzUy74ISdGGxURlYG8HSWSfM= github.com/zeebo/errs v1.4.0/go.mod h1:sgbWHsvVuTPHcqJJGQ1WhI5KbWlHYz+2+2C/LSEtCw4= +github.com/zeebo/xxh3 v1.0.2 h1:xZmwmqxHZA8AI603jOQ0tMqmBr9lPeFwGg6d+xy9DC0= github.com/zenazn/goji v0.9.0 h1:RSQQAbXGArQ0dIDEq+PI6WqN6if+5KHu6x2Cx/GXLTQ= go.einride.tech/aip v0.68.0 h1:4seM66oLzTpz50u4K1zlJyOXQ3tCzcJN7I22tKkjipw= go.einride.tech/aip v0.68.0/go.mod h1:7y9FF8VtPWqpxuAxl0KQWqaULxW4zFIesD6zF5RIHHg= +go.einride.tech/aip v0.68.1 h1:16/AfSxcQISGN5z9C5lM+0mLYXihrHbQ1onvYTr93aQ= go.einride.tech/aip v0.68.1/go.mod h1:XaFtaj4HuA3Zwk9xoBtTWgNubZ0ZZXv9BZJCkuKuWbg= go.etcd.io/etcd v0.0.0-20200513171258-e048e166ab9c h1:/RwRVN9EdXAVtdHxP7Ndn/tfmM9/goiwU0QTnLBgS4w= go.etcd.io/etcd/api/v3 v3.5.1/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= @@ -1252,71 +1276,60 @@ go.etcd.io/etcd/client/v3 v3.5.4 h1:p83BUL3tAYS0OT/r0qglgc3M1JjhM0diV8DSWAhVXv4= go.etcd.io/etcd/client/v3 v3.5.4/go.mod h1:ZaRkVgBZC+L+dLCjTcF1hRXpgZXQPOvnA/Ak/gq3kiY= go.etcd.io/gofail v0.1.0 h1:XItAMIhOojXFQMgrxjnd2EIIHun/d5qL0Pf7FzVTkFg= go.mozilla.org/mozlog v0.0.0-20170222151521-4bb13139d403 h1:rKyWXYDfrVOpMFBion4Pmx5sJbQreQNXycHvm4KwJSg= -go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= +go.opentelemetry.io/contrib/bridges/otelzap v0.12.0 h1:FGre0nZh5BSw7G73VpT3xs38HchsfPsa2aZtMp0NPOs= go.opentelemetry.io/contrib/bridges/otelzap v0.12.0/go.mod h1:X2PYPViI2wTPIMIOBjG17KNybTzsrATnvPJ02kkz7LM= go.opentelemetry.io/contrib/detectors/gcp v1.29.0 h1:TiaiXB4DpGD3sdzNlYQxruQngn5Apwzi1X0DRhuGvDQ= go.opentelemetry.io/contrib/detectors/gcp v1.29.0/go.mod h1:GW2aWZNwR2ZxDLdv8OyC2G8zkRoQBuURgV7RPQgcPoU= +go.opentelemetry.io/contrib/detectors/gcp v1.35.0 h1:bGvFt68+KTiAKFlacHW6AhA56GF2rS0bdD3aJYEnmzA= go.opentelemetry.io/contrib/detectors/gcp v1.35.0/go.mod h1:qGWP8/+ILwMRIUf9uIVLloR1uo5ZYAslM4O6OqUi1DA= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0/go.mod h1:Mjt1i1INqiaoZOMGR1RIUJN+i3ChKoFRqzrRQhlkbs0= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.54.0 h1:r6I7RJCN86bpD/FQwedZ0vSixDpwuWREjW9oRMsmqDc= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.54.0/go.mod h1:B9yO6b04uB80CzjedvewuqDhxJxi11s7/GtiGa8bAjI= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.58.0/go.mod h1:HDBUsEjOuRC0EzKZ1bSaRGZWUBAzo+MhAcUUORSr4D0= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.59.0/go.mod h1:ijPqXp5P6IRRByFVVg9DY8P5HkxkHE5ARIa+86aXPf4= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0/go.mod h1:rg+RlpR5dKwaS95IyyZqj5Wd4E13lk/msnTS0Xl9lJM= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0 h1:q4XOmH/0opmeuJtPsbFNivyl7bCt7yRBbeEm2sC/XtQ= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0/go.mod h1:snMWehoOh2wsEwnvvwtDyFCxVeDAODenXHtn5vzrKjo= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0/go.mod h1:p8pYQP+m5XfbZm9fxtSKAbM6oIllS7s2AfxrChvc7iw= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0 h1:TT4fX+nBOA/+LUkobKGW1ydGcn+G3vRw9+g5HwCphpk= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0/go.mod h1:L7UH0GbB0p47T4Rri3uHjbpCFYrVrwc1I25QhNPiGK8= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0/go.mod h1:umTcuxiv1n/s/S6/c2AT/g2CQ7u5C59sHDNmfSwgz7Q= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.0/go.mod h1:FRmFuRJfag1IZ2dPkHnEoSFVgTVPUd2qf5Vi69hLb8I= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0/go.mod h1:69uWxva0WgAA/4bu2Yy70SLDBwZXuQ6PbBpbsa5iZrQ= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 h1:F7Jx+6hwnZ41NSFTO5q4LYDtJRXBf2PD0rNBkeB/lus= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0/go.mod h1:UHB22Z8QsdRDrnAtX4PntOl36ajSxcdUMt1sF7Y6E7Q= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.62.0 h1:Hf9xI/XLML9ElpiHVDNwvqI0hIFlzV8dgIr35kV1kRU= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.62.0/go.mod h1:NfchwuyNoMcZ5MLHwPrODwUF1HWCXWrL31s8gSAdIKY= +go.opentelemetry.io/contrib/propagators/b3 v1.37.0 h1:0aGKdIuVhy5l4GClAjl72ntkZJhijf2wg1S7b5oLoYA= go.opentelemetry.io/contrib/propagators/b3 v1.37.0/go.mod h1:nhyrxEJEOQdwR15zXrCKI6+cJK60PXAkJ/jRyfhr2mg= +go.opentelemetry.io/contrib/propagators/jaeger v1.37.0 h1:pW+qDVo0jB0rLsNeaP85xLuz20cvsECUcN7TE+D8YTM= go.opentelemetry.io/contrib/propagators/jaeger v1.37.0/go.mod h1:x7bd+t034hxLTve1hF9Yn9qQJlO/pP8H5pWIt7+gsFM= -go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo= go.opentelemetry.io/otel v1.29.0/go.mod h1:N/WtXPs1CNCUEx+Agz5uouwCba+i+bJGFicT8SR4NP8= -go.opentelemetry.io/otel v1.30.0/go.mod h1:tFw4Br9b7fOS+uEao81PJjVMjW/5fvNCbpsDIXqP0pc= -go.opentelemetry.io/otel v1.31.0/go.mod h1:O0C14Yl9FgkjqcCZAsE053C13OaddMYr/hz6clDkEJE= -go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI= -go.opentelemetry.io/otel v1.35.0/go.mod h1:UEqy8Zp11hpkUrL73gSlELM0DupHoiq72dR+Zqel/+Y= -go.opentelemetry.io/otel v1.36.0/go.mod h1:/TcFMXYjyRNh8khOAO9ybYkqaDBb/70aVwkNML4pP8E= go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.13.0 h1:z6lNIajgEBVtQZHjfw2hAccPEBDs+nx58VemmXWa2ec= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.13.0/go.mod h1:+kyc3bRx/Qkq05P6OCu3mTEIOxYRYzoIg+JsUp5X+PM= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.13.0 h1:zUfYw8cscHHLwaY8Xz3fiJu+R59xBnkgq2Zr1lwmK/0= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.13.0/go.mod h1:514JLMCcFLQFS8cnTepOk6I09cKWJ5nGHBxHrMJ8Yfg= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.37.0 h1:zG8GlgXCJQd5BU98C0hZnBbElszTmUgCNCfYneaDL0A= go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.37.0/go.mod h1:hOfBCz8kv/wuq73Mx2H2QnWokh/kHZxkh6SNF2bdKtw= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0 h1:OeNbIYk/2C15ckl7glBlOBp5+WlYsOElzTNmiPW/x60= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0/go.mod h1:7Bept48yIeqxP2OZ9/AqIpYS94h2or0aB4FypJTc8ZM= +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/otlptracegrpc v1.34.0 h1:tgJ0uaNS4c98WRNUEx5U3aDlrDOI5Rs+1Vifcw4DJ8U= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0/go.mod h1:U7HYyW0zt/a9x5J1Kjs+r1f/d4ZHnYFclhYY2+YbeoE= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.37.0 h1:EtFWSnwW9hGObjkIdmlnWSydO+Qs8OwzfzXLUPg4xOc= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.37.0/go.mod h1:QjUEoiGCPkvFZ/MjK6ZZfNOS6mfVEVKYE99dFhuN2LI= go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.29.0 h1:WDdP9acbMYjbKIyJUhTvtzj601sVJOqgWdUxSdR/Ysc= go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.29.0/go.mod h1:BLbf7zbNIONBLPwvFnwNHGj4zge8uTCM/UPIVW1Mq2I= -go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.35.0/go.mod h1:U2R3XyVPzn0WX7wOIypPuptulsMcPDPs/oiSVOMVnHY= +go.opentelemetry.io/otel/log v0.13.0 h1:yoxRoIZcohB6Xf0lNv9QIyCzQvrtGZklVbdCoyb7dls= go.opentelemetry.io/otel/log v0.13.0/go.mod h1:INKfG4k1O9CL25BaM1qLe0zIedOpvlS5Z7XgSbmN83E= -go.opentelemetry.io/otel/metric v1.24.0/go.mod h1:VYhLe1rFfxuTXLgj4CBiyz+9WYBA8pNGJgDcSFRKBco= go.opentelemetry.io/otel/metric v1.29.0/go.mod h1:auu/QWieFVWx+DmQOUMgj0F8LHWdgalxXqvp7BII/W8= -go.opentelemetry.io/otel/metric v1.31.0/go.mod h1:C3dEloVbLuYoX41KpmAhOqNriGbA+qqH6PQ5E5mUfnY= -go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE= -go.opentelemetry.io/otel/metric v1.35.0/go.mod h1:nKVFgxBZ2fReX6IlyW28MgZojkoAkJGaE8CpgeAU3oE= -go.opentelemetry.io/otel/metric v1.36.0/go.mod h1:zC7Ks+yeyJt4xig9DEw9kuUFe5C3zLbVjV2PzT6qzbs= go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E= go.opentelemetry.io/otel/sdk v1.29.0/go.mod h1:pM8Dx5WKnvxLCb+8lG1PRNIDxu9g9b9g59Qr7hfAAok= -go.opentelemetry.io/otel/sdk v1.31.0/go.mod h1:TfRbMdhvxIIr/B2N2LQW2S5v9m3gOQ/08KsbbO5BPT0= -go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU= -go.opentelemetry.io/otel/sdk v1.35.0/go.mod h1:+ga1bZliga3DxJ3CQGg3updiaAJoNECOgJREo9KHGQg= go.opentelemetry.io/otel/sdk v1.37.0/go.mod h1:VredYzxUvuo2q3WRcDnKDjbdvmO0sCzOvVAiY+yUkAg= +go.opentelemetry.io/otel/sdk/log v0.13.0 h1:I3CGUszjM926OphK8ZdzF+kLqFvfRY/IIoFq/TjwfaQ= go.opentelemetry.io/otel/sdk/log v0.13.0/go.mod h1:lOrQyCCXmpZdN7NchXb6DOZZa1N5G1R2tm5GMMTpDBw= go.opentelemetry.io/otel/sdk/metric v1.29.0/go.mod h1:6zZLdCl2fkauYoZIOn/soQIDSWFmNSRcICarHfuhNJQ= -go.opentelemetry.io/otel/sdk/metric v1.31.0/go.mod h1:CRInTMVvNhUKgSAMbKyTMxqOBC0zgyxzW55lZzX43Y8= -go.opentelemetry.io/otel/sdk/metric v1.35.0/go.mod h1:is6XYCUMpcKi+ZsOvfluY5YstFnhW0BidkR+gL+qN+w= +go.opentelemetry.io/otel/sdk/metric v1.36.0/go.mod h1:qTNOhFDfKRwX0yXOqJYegL5WRaW376QbB7P4Pb0qva4= go.opentelemetry.io/otel/sdk/metric v1.37.0/go.mod h1:cNen4ZWfiD37l5NhS+Keb5RXVWZWpRE+9WyVCpbo5ps= -go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU= go.opentelemetry.io/otel/trace v1.29.0/go.mod h1:eHl3w0sp3paPkYstJOmAimxhiFXPg+MMTlEh3nsQgWQ= -go.opentelemetry.io/otel/trace v1.31.0/go.mod h1:TXZkRk7SM2ZQLtR6eoAWQFIHPvzQ06FJAsO1tJg480A= -go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE= -go.opentelemetry.io/otel/trace v1.35.0/go.mod h1:WUk7DtFp1Aw2MkvqGdwiXYDZZNvA/1J8o6xRXLrIkyc= -go.opentelemetry.io/otel/trace v1.36.0/go.mod h1:gQ+OnDZzrybY4k4seLzPAWNwVBBVlF2szhehOBB/tGA= go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0= -go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I= go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM= +go.opentelemetry.io/proto/otlp v1.5.0 h1:xJvq7gMzB31/d406fB8U5CBdyQGw4P399D1aQWU/3i4= +go.opentelemetry.io/proto/otlp v1.5.0/go.mod h1:keN8WnHxOy8PG0rQZjJJ5A2ebUoafqWp0eVQ4yIXvJ4= +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/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/automaxprocs v1.5.2 h1:2LxUOGiR3O6tw8ui5sZa2LAaHnsviZdVOUZw4fvbnME= @@ -1324,16 +1337,13 @@ go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN8 go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4= go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU= golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e/go.mod h1:Kr81I6Kryrl9sr8s2FK3vxD90NdsKWRuOIl2O4CvYbA= -golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE= golang.org/x/exp/typeparams v0.0.0-20220613132600-b0d781184e0d/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= golang.org/x/image v0.0.0-20220302094943-723b81ca9867 h1:TcHcE0vrmgzNH1v3ppjcMGbhG5+9fMuvOmUYwNEF4q4= golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028 h1:4+4C/Iv2U4fMZBiMCc98MG1In4gJY5YRhtpDNeDeHWs= golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= -golang.org/x/mod v0.24.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww= -golang.org/x/mod v0.26.0/go.mod h1:/j6NAhSk8iQ723BGAUyoAcn7SlD7s15Dp9Nd/SfeaFQ= -golang.org/x/mod v0.31.0/go.mod h1:43JraMp9cGx1Rx3AqioxrbrhNsLl2l/iNAvuBkrezpg= golang.org/x/net v0.0.0-20210510120150-4163338589ed/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= @@ -1343,20 +1353,15 @@ golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk= golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= -golang.org/x/net v0.39.0/go.mod h1:X7NRbYVEA+ewNkCNyJ513WmMdQ3BineSwVtN2zD/d+E= golang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds= golang.org/x/net v0.42.0/go.mod h1:FF1RA5d3u7nAYA4z2TkclSCKh68eSXtiFwcWQpPXdt8= -golang.org/x/oauth2 v0.19.0/go.mod h1:vYi7skDa1x015PmRRYZ7+s1cWyPgrPiSYRe4rnsexc8= -golang.org/x/oauth2 v0.24.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg= +golang.org/x/net v0.46.0/go.mod h1:Q9BGdFy1y4nkUwiLvT5qtyhAnEHgnQ/zd8PfU6nc210= golang.org/x/oauth2 v0.25.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/oauth2 v0.27.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8= -golang.org/x/oauth2 v0.28.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8= -golang.org/x/oauth2 v0.29.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8= golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI= golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU= golang.org/x/perf v0.0.0-20230113213139-801c7ef9e5c5 h1:ObuXPmIgI4ZMyQLIz48cJYgSyWdjUXc2SZAdyJMwEAU= -golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= -golang.org/x/sync v0.13.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sync v0.15.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20211205182925-97ca703d548d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1364,157 +1369,125 @@ golang.org/x/sys v0.0.0-20220627191245-f75cf1eec38b/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= -golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/sys v0.34.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/telemetry v0.0.0-20240521205824-bda55230c457 h1:zf5N6UOrA487eEFacMePxjXAJctxKmyjKUsjA11Uzuk= -golang.org/x/telemetry v0.0.0-20250807160809-1a19826ec488/go.mod h1:fGb/2+tgXXjhjHsTNdVEEMZNWA0quBnfrO+AfoDSAKw= +golang.org/x/telemetry v0.0.0-20251008203120-078029d740a8 h1:LvzTn0GQhWuvKH/kVRS3R3bVAsdQWI7hvfLHGgh9+lU= +golang.org/x/telemetry v0.0.0-20251008203120-078029d740a8/go.mod h1:Pi4ztBfryZoJEkyFTI5/Ocsu2jXyDr6iSdgJiYE/uwE= +golang.org/x/telemetry v0.0.0-20260109210033-bd525da824e2/go.mod h1:b7fPSJ0pKZ3ccUh8gnTONJxhn3c/PS6tyzQvyqw4iA8= golang.org/x/term v0.32.0/go.mod h1:uZG1FhGx848Sqfsq4/DlJr3xGGsYMu/L5GW4abiaEPQ= golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= -golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU= golang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA= golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA= -golang.org/x/text v0.27.0/go.mod h1:1D28KMCvyooCX9hBiosv5Tz/+YLxj0j7XhWjpSUF7CU= -golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU= golang.org/x/time v0.8.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= -golang.org/x/time v0.10.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= -golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= golang.org/x/tools v0.1.11-0.20220513221640-090b14e8501f/go.mod h1:SgwaegtQh8clINPpECJMqnxLv9I09HLqnW3RMqW0CA4= golang.org/x/tools v0.1.12-0.20220628192153-7743d1d949f1/go.mod h1:SgwaegtQh8clINPpECJMqnxLv9I09HLqnW3RMqW0CA4= golang.org/x/tools v0.15.0/go.mod h1:hpksKq4dtpQWS1uQ61JkdqWM3LscIS6Slf+VVkm+wQk= +golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0= -golang.org/x/tools v0.32.0/go.mod h1:ZxrU41P/wAbZD8EDa6dDCa6XfpkhJ7HFMjHJXfBDu8s= -golang.org/x/tools v0.35.0/go.mod h1:NKdj5HkL/73byiZSJjqJgKn3ep7KjFkBOkR/Hps3VPw= -golang.org/x/tools v0.40.0/go.mod h1:Ik/tzLRlbscWpqqMRjyWYDisX8bG13FrdXp3o4Sr9lc= +golang.org/x/tools v0.37.0/go.mod h1:MBN5QPQtLMHVdvsbtarmTNukZDdgwdwlO5qGacAzF0w= +golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da h1:noIWHXmPHxILtqtCOPIhSt0ABwskkZKjD3bXGnZGpNY= +golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= gonum.org/v1/gonum v0.11.0 h1:f1IJhK4Km5tBJmaiJXtk/PkL4cdVX6J+tGiM187uT5E= gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0 h1:OE9mWmgKkjJyEmDAAtGMPjXu+YNeGvK9VTSHY6+Qihc= gonum.org/v1/plot v0.10.1 h1:dnifSs43YJuNMDzB7v8wV64O4ABBHReuAVAoBxqBqS4= google.golang.org/api v0.62.0/go.mod h1:dKmwPCydfsad4qCH08MSdgWjfHOyfpd4VtDGgRFdavw= -google.golang.org/api v0.177.0/go.mod h1:srbhue4MLjkjbkux5p3dw/ocYOSZTaIEvf7bCOnFQDw= -google.golang.org/api v0.211.0/go.mod h1:XOloB4MXFH4UTlQSGuNUxw0UT74qdENK8d6JNsXKLi0= -google.golang.org/api v0.214.0/go.mod h1:bYPpLG8AyeMWwDU6NXoB00xC0DFkikVvd5MfwoxjLqE= google.golang.org/api v0.215.0 h1:jdYF4qnyczlEz2ReWIsosNLDuzXyvFHJtI5gcr0J7t0= google.golang.org/api v0.215.0/go.mod h1:fta3CVtuJYOEdugLNWm6WodzOS8KdFckABwN4I40hzY= -google.golang.org/api v0.216.0/go.mod h1:K9wzQMvWi47Z9IU7OgdOofvZuw75Ge3PPITImZR/UyI= -google.golang.org/api v0.218.0/go.mod h1:5VGHBAkxrA/8EFjLVEYmMUJ8/8+gWWQ3s4cFH0FxG2M= -google.golang.org/api v0.224.0/go.mod h1:3V39my2xAGkodXy0vEqcEtkqgw2GtrFL5WuBZlCTCOQ= -google.golang.org/api v0.227.0/go.mod h1:EIpaG6MbTgQarWF5xJvX0eOJPK9n/5D4Bynb9j2HXvQ= -google.golang.org/api v0.229.0/go.mod h1:wyDfmq5g1wYJWn29O22FDWN48P7Xcz0xz+LBpptYvB0= -google.golang.org/api v0.230.0/go.mod h1:aqvtoMk7YkiXx+6U12arQFExiRV9D/ekvMCwCd/TksQ= google.golang.org/api v0.237.0/go.mod h1:cOVEm2TpdAGHL2z+UwyS+kmlGr3bVWQQ6sYEqkKje50= google.golang.org/api v0.239.0/go.mod h1:cOVEm2TpdAGHL2z+UwyS+kmlGr3bVWQQ6sYEqkKje50= +google.golang.org/api v0.247.0 h1:tSd/e0QrUlLsrwMKmkbQhYVa109qIintOls2Wh6bngc= google.golang.org/api v0.247.0/go.mod h1:r1qZOPmxXffXg6xS5uhx16Fa/UFY8QU/K4bfKrnvovM= google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= google.golang.org/genproto v0.0.0-20211129164237-f09f9a12af12/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211203200212-54befc351ae9/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20250106144421-5f5ef82da422/go.mod h1:1NPAxoesyw/SgLPqaUp9u1f9PWCLAk/jVmhx7gJZStg= -google.golang.org/genproto v0.0.0-20250122153221-138b5a5a4fd4/go.mod h1:qbZzneIOXSq+KFAFut9krLfRLZiFLzZL5u2t8SV83EE= -google.golang.org/genproto v0.0.0-20250303144028-a0af3efb3deb h1:ITgPrl429bc6+2ZraNSzMDk3I95nmQln2fuPstKwFDE= -google.golang.org/genproto v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:sAo5UzpjUwgFBCzupwhcLcxHVDK7vG5IqI30YnwX2eE= google.golang.org/genproto v0.0.0-20250505200425-f936aa4a68b2/go.mod h1:49MsLSx0oWMOZqcpB3uL8ZOkAh1+TndpJ8ONoCBWiZk= google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d/go.mod h1:KjSP20unUpOx5kyQUFa7k4OJg0qeJ7DEZflGDu2p6Bk= -google.golang.org/genproto/googleapis/api v0.0.0-20240429193739-8cf5692501f6/go.mod h1:10yRODfgim2/T8csjQsMPgZOMvtytXKTDRzH6HRGzRw= google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157/go.mod h1:99sLkeliLXfdj2J75X3Ho+rrVCaJze0uwN7zDDkjPVU= -google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142/go.mod h1:d6be+8HhtEtucleCbxpPW9PA9XwISACu8nvpPqF0BVo= google.golang.org/genproto/googleapis/api v0.0.0-20240826202546-f6391c0de4c7/go.mod h1:OCdP9MfskevB/rbYvHTsXTtKC+3bHWajPdoKgjcYkfo= google.golang.org/genproto/googleapis/api v0.0.0-20241113202542-65e8d215514f/go.mod h1:Yo94eF2nj7igQt+TiJ49KxjIH8ndLYPZMIRSiRcEbg0= -google.golang.org/genproto/googleapis/api v0.0.0-20241118233622-e639e219e697/go.mod h1:+D9ySVjN8nY8YCVjc5O7PZDIdZporIDY3KaGfJunh88= -google.golang.org/genproto/googleapis/api v0.0.0-20241202173237-19429a94021a/go.mod h1:jehYqy3+AhJU9ve55aNOaSml7wUXjF9x6z2LcCfpAhY= -google.golang.org/genproto/googleapis/api v0.0.0-20250106144421-5f5ef82da422/go.mod h1:b6h1vNKhxaSoEI+5jc3PJUCustfli/mRab7295pY7rw= -google.golang.org/genproto/googleapis/api v0.0.0-20250124145028-65684f501c47/go.mod h1:AfA77qWLcidQWywD0YgqfpJzf50w2VjzBml3TybHeJU= -google.golang.org/genproto/googleapis/api v0.0.0-20250227231956-55c901821b1e/go.mod h1:Xsh8gBVxGCcbV8ZeTB9wI5XPyZ5RvC6V3CTeeplHbiA= +google.golang.org/genproto/googleapis/api v0.0.0-20250102185135-69823020774d/go.mod h1:2v7Z7gP2ZUOGsaFyxATQSRoBnKygqVq2Cwnvom7QiqY= google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:jbe3Bkdp+Dh2IrslsFCklNhweNTBgSYanP1UXhJDhKg= -google.golang.org/genproto/googleapis/api v0.0.0-20250313205543-e70fdf4c4cb4/go.mod h1:c8q6Z6OCqnfVIqUFJkCzKcrj8eCvUrz+K4KRzSTuANg= -google.golang.org/genproto/googleapis/api v0.0.0-20250414145226-207652e42e2e h1:UdXH7Kzbj+Vzastr5nVfccbmFsmYNygVLSPk1pEfDoY= -google.golang.org/genproto/googleapis/api v0.0.0-20250414145226-207652e42e2e/go.mod h1:085qFyf2+XaZlRdCgKNCIZ3afY2p4HHZdoIRpId8F4A= google.golang.org/genproto/googleapis/api v0.0.0-20250528174236-200df99c418a/go.mod h1:a77HrdMjoeKbnd2jmgcWdaS++ZLZAEq3orIOAEIKiVw= google.golang.org/genproto/googleapis/bytestream v0.0.0-20241223144023-3abc09e42ca8 h1:qlXhWiX84AGgaN7LuORWBEQCCTqj3szNbh2am45O3W8= google.golang.org/genproto/googleapis/bytestream v0.0.0-20241223144023-3abc09e42ca8/go.mod h1:bLYPejkLzwgJuAHlIk1gdPOlx9CUYXLZi2rZxL/ursM= -google.golang.org/genproto/googleapis/bytestream v0.0.0-20250414145226-207652e42e2e/go.mod h1:h6yxum/C2qRb4txaZRLDHK8RyS0H/o2oEDeKY4onY/Y= +google.golang.org/genproto/googleapis/bytestream v0.0.0-20250804133106-a7a43d27e69b h1:YzmLjVBzUKrr0zPM1KkGPEicd3WHSccw1k9RivnvngU= google.golang.org/genproto/googleapis/bytestream v0.0.0-20250804133106-a7a43d27e69b/go.mod h1:h6yxum/C2qRb4txaZRLDHK8RyS0H/o2oEDeKY4onY/Y= google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240429193739-8cf5692501f6/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY= google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157/go.mod h1:EfXuqaE1J41VCDicxHzUDm+8rk+7ZdXzHV0IhO/I6s0= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= google.golang.org/genproto/googleapis/rpc v0.0.0-20240826202546-f6391c0de4c7/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= google.golang.org/genproto/googleapis/rpc v0.0.0-20241113202542-65e8d215514f/go.mod h1:GX3210XPVPUjJbTUbvwI8f2IpZDMZuPJWDzDuebbviI= -google.golang.org/genproto/googleapis/rpc v0.0.0-20241202173237-19429a94021a/go.mod h1:5uTbfoYQed2U9p3KIj2/Zzm02PYhndfdmML0qC3q3FU= google.golang.org/genproto/googleapis/rpc v0.0.0-20241206012308-a4fef0638583/go.mod h1:5uTbfoYQed2U9p3KIj2/Zzm02PYhndfdmML0qC3q3FU= -google.golang.org/genproto/googleapis/rpc v0.0.0-20241209162323-e6fa225c2576/go.mod h1:5uTbfoYQed2U9p3KIj2/Zzm02PYhndfdmML0qC3q3FU= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250106144421-5f5ef82da422/go.mod h1:3ENsm/5D1mzDyhpzeRi1NR784I0BcofWBoSc5QqqMK4= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250124145028-65684f501c47/go.mod h1:+2Yz8+CLJbIfL9z73EW45avw8Lmge3xVElCP9zEKi50= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250218202821-56aae31c358a/go.mod h1:uRxBH1mhmO8PGhU89cMcHaXKZqO+OfakD8QQO0oYwlQ= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250102185135-69823020774d/go.mod h1:3ENsm/5D1mzDyhpzeRi1NR784I0BcofWBoSc5QqqMK4= google.golang.org/genproto/googleapis/rpc v0.0.0-20250227231956-55c901821b1e/go.mod h1:LuRYeWDFV6WOn90g357N17oMCaxpgCnbi/44qJvDn2I= google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:LuRYeWDFV6WOn90g357N17oMCaxpgCnbi/44qJvDn2I= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250313205543-e70fdf4c4cb4/go.mod h1:LuRYeWDFV6WOn90g357N17oMCaxpgCnbi/44qJvDn2I= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250409194420-de1ac958c67a/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250414145226-207652e42e2e/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250425173222-7b384671a197/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= google.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= google.golang.org/genproto/googleapis/rpc v0.0.0-20250804133106-a7a43d27e69b/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= +google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.2.0 h1:TLkBREm4nIsEcexnCjgQd5GQWaHcqMzwQV0TX9pq8S0= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.2.0/go.mod h1:DNq5QpG7LJqD2AamLZ7zvKE0DEpVl2BSEVjFycAAjRY= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.3.0 h1:rNBFJjBCOgVr9pWD7rs/knKL4FRTKgpZmsRfV214zcA= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.3.0/go.mod h1:Dk1tviKTvMCz5tvh7t+fh94dhmQVHuCt2OzJB3CTW9Y= google.golang.org/protobuf v1.35.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= google.golang.org/protobuf v1.36.0/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= google.golang.org/protobuf v1.36.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= -google.golang.org/protobuf v1.36.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= google.golang.org/protobuf v1.36.3/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= -google.golang.org/protobuf v1.36.4/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= google.golang.org/protobuf v1.36.7/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= -google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc= gopkg.in/cheggaaa/pb.v1 v1.0.28 h1:n1tBJnnK2r7g9OW2btFH91V92STTUevLXYFb8gy9EMk= gopkg.in/errgo.v2 v2.1.0 h1:0vLT13EuvQ0hNvakwLuFZ/jYrLp5F3kcWHXdRggjCE8= +gopkg.in/evanphx/json-patch.v4 v4.13.0 h1:czT3CmqEaQ1aanPc5SdlgQrrEIb8w/wwCvWWnfEbYzo= gopkg.in/evanphx/json-patch.v4 v4.13.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/gcfg.v1 v1.2.3 h1:m8OOJ4ccYHnx2f4gQwpno8nAX5OGOh7RLaaz0pj3Ogs= +gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/ini.v1 v1.66.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/resty.v1 v1.12.0 h1:CuXP0Pjfw9rOuY6EP+UvtNvt5DSqHpIxILZKT/quCZI= gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= +gorm.io/driver/clickhouse v0.7.0 h1:BCrqvgONayvZRgtuA6hdya+eAW5P2QVagV3OlEp1vtA= gorm.io/driver/clickhouse v0.7.0/go.mod h1:TmNo0wcVTsD4BBObiRnCahUgHJHjBIwuRejHwYt3JRs= +gorm.io/driver/postgres v1.6.0 h1:2dxzU8xJ+ivvqTRph34QX+WrRaJlmfyPqXmoGVjMBa4= gorm.io/driver/postgres v1.6.0/go.mod h1:vUw0mrGgrTK+uPHEhAdV4sfFELrByKVGnaVRkXDhtWo= +gorm.io/gorm v1.30.1 h1:lSHg33jJTBxs2mgJRfRZeLDG+WZaHYCk3Wtfl6Ngzo4= gorm.io/gorm v1.30.1/go.mod h1:8Z33v652h4//uMA76KjeDH8mJXPm1QNCYrMeatR0DOE= +gotest.tools/v3 v3.5.2/go.mod h1:LtdLGcnqToBH83WByAAi/wiwSFCArdFIUV/xxN4pcjA= +k8s.io/api v0.35.0 h1:iBAU5LTyBI9vw3L5glmat1njFK34srdLmktWwLTprlY= k8s.io/api v0.35.0/go.mod h1:AQ0SNTzm4ZAczM03QH42c7l3bih1TbAXYo0DkF8ktnA= +k8s.io/apimachinery v0.35.0 h1:Z2L3IHvPVv/MJ7xRxHEtk6GoJElaAqDCCU0S6ncYok8= k8s.io/apimachinery v0.35.0/go.mod h1:jQCgFZFR1F4Ik7hvr2g84RTJSZegBc8yHgFWKn//hns= +k8s.io/client-go v0.35.0 h1:IAW0ifFbfQQwQmga0UdoH0yvdqrbwMdq9vIFEhRpxBE= k8s.io/client-go v0.35.0/go.mod h1:q2E5AAyqcbeLGPdoRB+Nxe3KYTfPce1Dnu1myQdqz9o= +k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= +k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 h1:Y3gxNAuB0OBLImH611+UDZcmKS3g6CthxToOb37KgwE= k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ= +k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 h1:SjGebBtkBqHFOli+05xYbK8YF1Dzkbzn+gDM4X9T4Ck= k8s.io/utils v0.0.0-20251002143259-bc988d571ff4/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= lukechampine.com/uint128 v1.2.0 h1:mBi/5l91vocEN8otkC5bDLhi2KdCticRiwbdB0O+rjI= modernc.org/cc/v3 v3.36.3 h1:uISP3F66UlixxWEcKuIWERa4TwrZENHSL8tWxZz8bHg= modernc.org/ccgo/v3 v3.16.9 h1:AXquSwg7GuMk11pIdw7fmO1Y/ybgazVkMhsZWCV0mHM= modernc.org/ccorpus v1.11.6 h1:J16RXiiqiCgua6+ZvQot4yUuUy8zxgqbqEEUuGPlISk= -modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6/go.mod h1:Qz0X07sNOR1jWYCrJMEnbW/X55x206Q7Vt4mz6/wHp4= modernc.org/httpfs v1.0.6 h1:AAgIpFZRXuYnkjftxTAZwMIiwEqAfk8aVB2/oA6nAeM= modernc.org/libc v1.17.1 h1:Q8/Cpi36V/QBfuQaFVeisEBs3WqoGAJprZzmf7TfEYI= -modernc.org/libc v1.41.0/go.mod h1:w0eszPsiXoOnoMJgrXjglgLuDy/bt5RR4y3QzUUeodY= modernc.org/mathutil v1.5.0 h1:rV0Ko/6SfM+8G+yKiyI830l3Wuz1zRutdslNoQ0kfiQ= -modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= modernc.org/memory v1.2.1 h1:dkRh86wgmq/bJu2cAS2oqBCz/KsMZU7TUM4CibQ7eBs= -modernc.org/memory v1.7.2/go.mod h1:NO4NVCQy0N7ln+T9ngWqOQfi7ley4vpwvARR+Hjw95E= modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4= modernc.org/sqlite v1.18.1 h1:ko32eKt3jf7eqIkCgPAeHMBXw3riNSLhl2f3loEF7o8= -modernc.org/sqlite v1.29.6/go.mod h1:S02dvcmm7TnTRvGhv8IGYyLnIt7AS2KPaB1F/71p75U= modernc.org/strutil v1.1.3 h1:fNMm+oJklMGYfU9Ylcywl0CO5O6nTfaowNsh2wpPjzY= -modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0= modernc.org/tcl v1.13.1 h1:npxzTwFTZYM8ghWicVIX1cRWzj7Nd8i6AqqX2p+IYao= modernc.org/token v1.0.0 h1:a0jaWiNMDhDUtqOj09wvjWWAqd3q7WpBulmL9H2egsk= -modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= modernc.org/z v1.5.1 h1:RTNHdsrOpeoSeOF4FbzTo8gBYByaJ5xT7NgZ9ZqRiJM= moul.io/http2curl/v2 v2.3.0 h1:9r3JfDzWPcbIklMOs2TnIFzDYvfAZvjeavG6EzP7jYs= rsc.io/binaryregexp v0.2.0 h1:HfqmD5MEmC0zvwBuF187nq9mdnXjXsSivRiXN7SmRkE= @@ -1522,9 +1495,12 @@ rsc.io/pdf v0.1.1 h1:k1MczvYDUvJBe93bYd7wrZLLUEcLZAuF824/I4e5Xr4= rsc.io/quote/v3 v3.1.0 h1:9JKUTTIUgS6kzR9mK1YuGKv6Nl+DijDNIc0ghT58FaY= rsc.io/sampler v1.3.0 h1:7uVkIFmeBqHfdjD+gZwtXXI+RODJ2Wc4O7MPEh/QiW4= rsc.io/tmplfunc v0.0.3 h1:53XFQh69AfOa8Tw0Jm7t+GV7KZhOi6jzsCzTtKbMvzU= +sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg= sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= +sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU= sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= +sigs.k8s.io/structured-merge-diff/v6 v6.3.0 h1:jTijUJbW353oVOd9oTlifJqOGEkUw2jB/fXCbTiQEco= sigs.k8s.io/structured-merge-diff/v6 v6.3.0/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE= -sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs= +sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs= sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4= sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0 h1:ucqkfpjg9WzSUubAO62csmucvxl4/JeW3F4I4909XkM= diff --git a/scripts/benchmark.sh b/scripts/benchmark.sh index 6da97ddccb..4fdbe8c717 100755 --- a/scripts/benchmark.sh +++ b/scripts/benchmark.sh @@ -77,7 +77,7 @@ else make install-bench fi # initialize chain with chain ID and add the first key -~/go/bin/seid init demo --chain-id sei-chain --overwrite +~/go/bin/seid init demo --chain-id sei-chain ~/go/bin/seid keys add $keyname --keyring-backend test # add the key as a genesis account with massive balances of several different tokens ~/go/bin/seid add-genesis-account $(~/go/bin/seid keys show $keyname -a --keyring-backend test) 100000000000000000000usei,100000000000000000000uusdc,100000000000000000000uatom --keyring-backend test diff --git a/sei-db/common/evm/keys.go b/sei-db/common/evm/keys.go index 7e5d992a48..b3b177c824 100644 --- a/sei-db/common/evm/keys.go +++ b/sei-db/common/evm/keys.go @@ -3,8 +3,6 @@ package evm import ( "bytes" "errors" - - evmtypes "github.com/sei-protocol/sei-chain/x/evm/types" ) const ( @@ -12,6 +10,22 @@ const ( slotLen = 32 ) +// EVM key prefixes — mirrored from x/evm/types/keys.go. +// These are immutable on-disk format markers; changing them would break +// all existing state, so duplicating here is safe and avoids pulling in the +// heavy x/evm/types dependency (which transitively imports cosmos-sdk). +var ( + stateKeyPrefix = []byte{0x03} + codeKeyPrefix = []byte{0x07} + codeHashKeyPrefix = []byte{0x08} + codeSizeKeyPrefix = []byte{0x09} + nonceKeyPrefix = []byte{0x0a} +) + +// StateKeyPrefix returns the storage state key prefix (0x03). +// Exported for callers that need the raw prefix (e.g. iterator bounds). +func StateKeyPrefix() []byte { return stateKeyPrefix } + var ( // ErrMalformedEVMKey indicates invalid EVM key encoding. ErrMalformedEVMKey = errors.New("sei-db: malformed evm key") @@ -29,10 +43,14 @@ const ( EVMKeyLegacy // Full original key preserved (address mappings, codesize, etc.) ) +// EVMKeyUnknown is an alias for EVMKeyEmpty, used by FlatKV to test for +// unrecognised/empty keys. +const EVMKeyUnknown = EVMKeyEmpty + // ParseEVMKey parses an EVM key from the x/evm store keyspace. // // For optimized keys (nonce, code, codehash, storage), keyBytes is the stripped key. -// For legacy keys (all other EVM data), keyBytes is the full original key. +// For legacy keys (all other EVM data including codesize), keyBytes is the full original key. // Only returns EVMKeyEmpty for zero-length keys. func ParseEVMKey(key []byte) (kind EVMKeyKind, keyBytes []byte) { if len(key) == 0 { @@ -40,31 +58,71 @@ func ParseEVMKey(key []byte) (kind EVMKeyKind, keyBytes []byte) { } switch { - case bytes.HasPrefix(key, evmtypes.NonceKeyPrefix): - if len(key) != len(evmtypes.NonceKeyPrefix)+addressLen { + case bytes.HasPrefix(key, nonceKeyPrefix): + if len(key) != len(nonceKeyPrefix)+addressLen { return EVMKeyLegacy, key // Malformed but still EVM data } - return EVMKeyNonce, key[len(evmtypes.NonceKeyPrefix):] + return EVMKeyNonce, key[len(nonceKeyPrefix):] - case bytes.HasPrefix(key, evmtypes.CodeHashKeyPrefix): - if len(key) != len(evmtypes.CodeHashKeyPrefix)+addressLen { + case bytes.HasPrefix(key, codeHashKeyPrefix): + if len(key) != len(codeHashKeyPrefix)+addressLen { return EVMKeyLegacy, key } - return EVMKeyCodeHash, key[len(evmtypes.CodeHashKeyPrefix):] + return EVMKeyCodeHash, key[len(codeHashKeyPrefix):] - case bytes.HasPrefix(key, evmtypes.CodeKeyPrefix): - if len(key) != len(evmtypes.CodeKeyPrefix)+addressLen { + case bytes.HasPrefix(key, codeKeyPrefix): + if len(key) != len(codeKeyPrefix)+addressLen { return EVMKeyLegacy, key } - return EVMKeyCode, key[len(evmtypes.CodeKeyPrefix):] + return EVMKeyCode, key[len(codeKeyPrefix):] - case bytes.HasPrefix(key, evmtypes.StateKeyPrefix): - if len(key) != len(evmtypes.StateKeyPrefix)+addressLen+slotLen { + case bytes.HasPrefix(key, stateKeyPrefix): + if len(key) != len(stateKeyPrefix)+addressLen+slotLen { return EVMKeyLegacy, key } - return EVMKeyStorage, key[len(evmtypes.StateKeyPrefix):] + return EVMKeyStorage, key[len(stateKeyPrefix):] } // All other EVM keys go to legacy store (address mappings, codesize, etc.) return EVMKeyLegacy, key } + +// BuildMemIAVLEVMKey builds a memiavl key from internal bytes. +// This is the reverse of ParseEVMKey for optimized key types. +// +// NOTE: This is primarily used for tests and temporary compatibility. +// FlatKV stores data in internal format; this function converts back to +// memiavl format for Iterator/Exporter output. +func BuildMemIAVLEVMKey(kind EVMKeyKind, keyBytes []byte) []byte { + var prefix []byte + switch kind { + case EVMKeyStorage: + prefix = stateKeyPrefix + case EVMKeyNonce: + prefix = nonceKeyPrefix + case EVMKeyCodeHash: + prefix = codeHashKeyPrefix + case EVMKeyCode: + prefix = codeKeyPrefix + default: + return nil + } + + result := make([]byte, 0, len(prefix)+len(keyBytes)) + result = append(result, prefix...) + result = append(result, keyBytes...) + return result +} + +// InternalKeyLen returns the expected internal key length for a given kind. +// Used for validation in Iterator and tests. +func InternalKeyLen(kind EVMKeyKind) int { + switch kind { + case EVMKeyStorage: + return addressLen + slotLen // 52 bytes + case EVMKeyNonce, EVMKeyCodeHash, EVMKeyCode: + return addressLen // 20 bytes + default: + return 0 + } +} diff --git a/sei-db/common/evm/keys_test.go b/sei-db/common/evm/keys_test.go index 21a041d644..c60659e7ff 100644 --- a/sei-db/common/evm/keys_test.go +++ b/sei-db/common/evm/keys_test.go @@ -3,10 +3,19 @@ package evm import ( "testing" - evmtypes "github.com/sei-protocol/sei-chain/x/evm/types" "github.com/stretchr/testify/require" ) +// Test-local copies of x/evm/types key prefixes. +// Kept here (rather than importing evmtypes) to avoid a circular dependency: +// +// common/evm (test) -> x/evm/types -> cosmos-sdk/server/config +// -> sei-db/config -> sei-db/state_db/sc/flatkv -> common/evm +var ( + testEVMAddrToSeiPrefix = []byte{0x01} + testSeiAddrToEVMPrefix = []byte{0x02} +) + func TestParseEVMKey(t *testing.T) { addr := make([]byte, addressLen) for i := range addr { @@ -33,47 +42,46 @@ func TestParseEVMKey(t *testing.T) { // Optimized keys - stripped { name: "Nonce", - key: concat(evmtypes.NonceKeyPrefix, addr), + key: concat(nonceKeyPrefix, addr), wantKind: EVMKeyNonce, wantBytes: addr, }, { name: "CodeHash", - key: concat(evmtypes.CodeHashKeyPrefix, addr), + key: concat(codeHashKeyPrefix, addr), wantKind: EVMKeyCodeHash, wantBytes: addr, }, + { + name: "CodeSize goes to Legacy", + key: concat(codeSizeKeyPrefix, addr), + wantKind: EVMKeyLegacy, + wantBytes: concat(codeSizeKeyPrefix, addr), // Full key preserved + }, { name: "Code", - key: concat(evmtypes.CodeKeyPrefix, addr), + key: concat(codeKeyPrefix, addr), wantKind: EVMKeyCode, wantBytes: addr, }, { name: "Storage", - key: concat(concat(evmtypes.StateKeyPrefix, addr), slot), + key: concat(concat(stateKeyPrefix, addr), slot), wantKind: EVMKeyStorage, wantBytes: concat(addr, slot), }, - // CodeSize goes to legacy (not its own optimized DB) - { - name: "CodeSize goes to Legacy", - key: concat(evmtypes.CodeSizeKeyPrefix, addr), - wantKind: EVMKeyLegacy, - wantBytes: concat(evmtypes.CodeSizeKeyPrefix, addr), // Full key preserved - }, // Legacy keys - keep full key (address mappings, unknown prefix, malformed, etc.) { name: "EVMAddressToSeiAddress goes to Legacy", - key: concat(evmtypes.EVMAddressToSeiAddressKeyPrefix, addr), + key: concat(testEVMAddrToSeiPrefix, addr), wantKind: EVMKeyLegacy, - wantBytes: concat(evmtypes.EVMAddressToSeiAddressKeyPrefix, addr), // Full key preserved + wantBytes: concat(testEVMAddrToSeiPrefix, addr), // Full key preserved }, { name: "SeiAddressToEVMAddress goes to Legacy", - key: concat(evmtypes.SeiAddressToEVMAddressKeyPrefix, addr), + key: concat(testSeiAddrToEVMPrefix, addr), wantKind: EVMKeyLegacy, - wantBytes: concat(evmtypes.SeiAddressToEVMAddressKeyPrefix, addr), // Full key preserved + wantBytes: concat(testSeiAddrToEVMPrefix, addr), // Full key preserved }, { name: "UnknownPrefix goes to Legacy", @@ -89,33 +97,33 @@ func TestParseEVMKey(t *testing.T) { }, { name: "NonceTooShort goes to Legacy", - key: evmtypes.NonceKeyPrefix, + key: nonceKeyPrefix, wantKind: EVMKeyLegacy, - wantBytes: evmtypes.NonceKeyPrefix, + wantBytes: nonceKeyPrefix, }, { name: "NonceWrongLenShort goes to Legacy", - key: concat(evmtypes.NonceKeyPrefix, addr[:addressLen-1]), + key: concat(nonceKeyPrefix, addr[:addressLen-1]), wantKind: EVMKeyLegacy, - wantBytes: concat(evmtypes.NonceKeyPrefix, addr[:addressLen-1]), + wantBytes: concat(nonceKeyPrefix, addr[:addressLen-1]), }, { name: "NonceWrongLenLong goes to Legacy", - key: concat(evmtypes.NonceKeyPrefix, concat(addr, []byte{0x00})), + key: concat(nonceKeyPrefix, concat(addr, []byte{0x00})), wantKind: EVMKeyLegacy, - wantBytes: concat(evmtypes.NonceKeyPrefix, concat(addr, []byte{0x00})), + wantBytes: concat(nonceKeyPrefix, concat(addr, []byte{0x00})), }, { name: "StorageTooShort goes to Legacy", - key: concat(evmtypes.StateKeyPrefix, addr), + key: concat(stateKeyPrefix, addr), wantKind: EVMKeyLegacy, - wantBytes: concat(evmtypes.StateKeyPrefix, addr), + wantBytes: concat(stateKeyPrefix, addr), }, { name: "StorageWrongLenLong goes to Legacy", - key: concat(concat(concat(evmtypes.StateKeyPrefix, addr), slot), []byte{0x00}), + key: concat(concat(concat(stateKeyPrefix, addr), slot), []byte{0x00}), wantKind: EVMKeyLegacy, - wantBytes: concat(concat(concat(evmtypes.StateKeyPrefix, addr), slot), []byte{0x00}), + wantBytes: concat(concat(concat(stateKeyPrefix, addr), slot), []byte{0x00}), }, } @@ -127,3 +135,80 @@ func TestParseEVMKey(t *testing.T) { }) } } + +func TestBuildMemIAVLEVMKey(t *testing.T) { + addr := make([]byte, addressLen) + for i := range addr { + addr[i] = 0xAA + } + slot := make([]byte, slotLen) + for i := range slot { + slot[i] = 0xBB + } + + concat := func(a, b []byte) []byte { + out := make([]byte, 0, len(a)+len(b)) + out = append(out, a...) + out = append(out, b...) + return out + } + + tests := []struct { + name string + kind EVMKeyKind + keyBytes []byte + want []byte + }{ + { + name: "Nonce", + kind: EVMKeyNonce, + keyBytes: addr, + want: concat(nonceKeyPrefix, addr), + }, + { + name: "CodeHash", + kind: EVMKeyCodeHash, + keyBytes: addr, + want: concat(codeHashKeyPrefix, addr), + }, + { + name: "Code", + kind: EVMKeyCode, + keyBytes: addr, + want: concat(codeKeyPrefix, addr), + }, + { + name: "Storage", + kind: EVMKeyStorage, + keyBytes: concat(addr, slot), + want: concat(stateKeyPrefix, concat(addr, slot)), + }, + { + name: "Unknown", + kind: EVMKeyUnknown, + keyBytes: addr, + want: nil, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + got := BuildMemIAVLEVMKey(tc.kind, tc.keyBytes) + require.Equal(t, tc.want, got) + }) + } +} + +func TestInternalKeyLen(t *testing.T) { + require.Equal(t, addressLen+slotLen, InternalKeyLen(EVMKeyStorage)) + require.Equal(t, addressLen, InternalKeyLen(EVMKeyNonce)) + require.Equal(t, addressLen, InternalKeyLen(EVMKeyCodeHash)) + require.Equal(t, addressLen, InternalKeyLen(EVMKeyCode)) + require.Equal(t, 0, InternalKeyLen(EVMKeyUnknown)) +} + +func TestEVMKeyUnknownAlias(t *testing.T) { + // Verify EVMKeyUnknown == EVMKeyEmpty so FlatKV's "skip unknown" checks + // still work correctly after introducing EVMKeyLegacy. + require.Equal(t, EVMKeyEmpty, EVMKeyUnknown) +} diff --git a/sei-db/config/toml.go b/sei-db/config/toml.go index 1a39f48273..018b52bd72 100644 --- a/sei-db/config/toml.go +++ b/sei-db/config/toml.go @@ -51,6 +51,20 @@ sc-snapshot-prefetch-threshold = {{ .StateCommit.MemIAVLConfig.SnapshotPrefetchT # Maximum snapshot write rate in MB/s (global across all trees). 0 = unlimited. Default 100. sc-snapshot-write-rate-mbps = {{ .StateCommit.MemIAVLConfig.SnapshotWriteRateMBps }} +############################################################################### +### FlatKV (EVM) Configuration ### +############################################################################### + +[state-commit.flatkv] +# Fsync controls whether data DB writes use fsync for durability. +# When true (default): all data DB writes use Sync=true for maximum durability. +# When false: data DBs use Sync=false for better performance. +# WAL and metaDB always use sync writes regardless. +fsync = {{ .StateCommit.FlatKVConfig.Fsync }} + +# AsyncWriteBuffer defines the size of the async write buffer for data DBs. +# Set <= 0 for synchronous writes. +async-write-buffer = {{ .StateCommit.FlatKVConfig.AsyncWriteBuffer }} ` // StateStoreConfigTemplate defines the configuration template for state-store @@ -102,7 +116,7 @@ const ReceiptStoreConfigTemplate = ` [receipt-store] # Backend defines the receipt store backend. -# Supported backends: pebble (aka pebbledb), parquet +# Supported backends: pebble (aka pebbledb) # defaults to pebbledb rs-backend = "{{ .ReceiptStore.Backend }}" ` diff --git a/sei-db/config/toml_test.go b/sei-db/config/toml_test.go index 1b7ddb665a..3796439603 100644 --- a/sei-db/config/toml_test.go +++ b/sei-db/config/toml_test.go @@ -248,13 +248,15 @@ func TestStateCommitConfigValidate(t *testing.T) { // and renamed fields. func TestTemplateFieldPathsExist(t *testing.T) { type TemplateConfig struct { - StateCommit StateCommitConfig - StateStore StateStoreConfig + StateCommit StateCommitConfig + StateStore StateStoreConfig + ReceiptStore ReceiptStoreConfig } cfg := TemplateConfig{ - StateCommit: DefaultStateCommitConfig(), - StateStore: DefaultStateStoreConfig(), + StateCommit: DefaultStateCommitConfig(), + StateStore: DefaultStateStoreConfig(), + ReceiptStore: DefaultReceiptStoreConfig(), } templates := []struct { @@ -263,6 +265,7 @@ func TestTemplateFieldPathsExist(t *testing.T) { }{ {"StateCommitConfigTemplate", StateCommitConfigTemplate}, {"StateStoreConfigTemplate", StateStoreConfigTemplate}, + {"ReceiptStoreConfigTemplate", ReceiptStoreConfigTemplate}, } for _, tt := range templates { diff --git a/sei-db/db_engine/parquet/placeholder.go b/sei-db/db_engine/parquet/placeholder.go new file mode 100644 index 0000000000..d59caa7f94 --- /dev/null +++ b/sei-db/db_engine/parquet/placeholder.go @@ -0,0 +1 @@ +package parquet diff --git a/sei-db/ledger_db/parquet/reader.go b/sei-db/ledger_db/parquet/reader.go deleted file mode 100644 index 289dfca7d4..0000000000 --- a/sei-db/ledger_db/parquet/reader.go +++ /dev/null @@ -1,459 +0,0 @@ -package parquet - -import ( - "context" - "database/sql" - "fmt" - "log" - "path/filepath" - "runtime" - "sort" - "strconv" - "strings" - "sync" - - "github.com/duckdb/duckdb-go/v2" - "github.com/ethereum/go-ethereum/common" -) - -// Reader provides DuckDB-based reading of parquet files. -type Reader struct { - db *sql.DB - basePath string - maxBlocksPerFile uint64 - mu sync.RWMutex - closedReceiptFiles []string - closedLogFiles []string -} - -// FilePair represents a matched pair of receipt and log parquet files. -type FilePair struct { - ReceiptFile string - LogFile string - StartBlock uint64 -} - -// NewReader creates a new parquet reader for the given base path. -func NewReader(basePath string) (*Reader, error) { - return NewReaderWithMaxBlocksPerFile(basePath, defaultMaxBlocksPerFile) -} - -// NewReaderWithMaxBlocksPerFile creates a new parquet reader with a configured file span. -func NewReaderWithMaxBlocksPerFile(basePath string, maxBlocksPerFile uint64) (*Reader, error) { - if maxBlocksPerFile == 0 { - maxBlocksPerFile = defaultMaxBlocksPerFile - } - - connector, err := duckdb.NewConnector("", nil) - if err != nil { - return nil, fmt.Errorf("failed to create DuckDB connector: %w", err) - } - - db := sql.OpenDB(connector) - numCPU := runtime.NumCPU() - db.SetMaxOpenConns(numCPU * 2) - db.SetMaxIdleConns(numCPU) - - settings := []string{ - fmt.Sprintf("SET threads TO %d", numCPU), - "SET memory_limit = '1GB'", - "SET enable_object_cache = true", - "SET enable_progress_bar = false", - "SET preserve_insertion_order = false", - } - for _, statement := range settings { - if _, err = db.Exec(statement); err != nil { - _ = db.Close() - return nil, fmt.Errorf("failed to configure duckdb (%s): %w", statement, err) - } - } - if err = configureParquetMetadataCache(db); err != nil { - _ = db.Close() - return nil, err - } - - reader := &Reader{ - db: db, - basePath: basePath, - maxBlocksPerFile: maxBlocksPerFile, - } - reader.scanExistingFiles() - return reader, nil -} - -func configureParquetMetadataCache(db *sql.DB) error { - const sizeSetting = "SET parquet_metadata_cache_size = 500" - if _, err := db.Exec(sizeSetting); err == nil { - return nil - } else if !strings.Contains(err.Error(), "unrecognized configuration parameter") { - return fmt.Errorf("failed to configure duckdb (%s): %w", sizeSetting, err) - } - - const toggleSetting = "SET parquet_metadata_cache = true" - if _, err := db.Exec(toggleSetting); err != nil { - return fmt.Errorf("failed to configure duckdb (%s): %w", toggleSetting, err) - } - - return nil -} - -// Close closes the reader. -func (r *Reader) Close() error { - return r.db.Close() -} - -func (r *Reader) scanExistingFiles() { - r.mu.Lock() - defer r.mu.Unlock() - - receiptPattern := filepath.Join(r.basePath, "receipts_*.parquet") - receiptFiles, err := filepath.Glob(receiptPattern) - if err != nil { - log.Printf("failed to glob receipt parquet files with pattern %q: %v", receiptPattern, err) - } - r.closedReceiptFiles = r.validateFiles(receiptFiles) - - logPattern := filepath.Join(r.basePath, "logs_*.parquet") - logFiles, err := filepath.Glob(logPattern) - if err != nil { - log.Printf("failed to glob log parquet files with pattern %q: %v", logPattern, err) - } - r.closedLogFiles = r.validateFiles(logFiles) -} - -func (r *Reader) validateFiles(files []string) []string { - if len(files) == 0 { - return nil - } - - sort.Slice(files, func(i, j int) bool { - return ExtractBlockNumber(files[i]) < ExtractBlockNumber(files[j]) - }) - - lastFile := files[len(files)-1] - if r.isFileReadable(lastFile) { - return files - } - return files[:len(files)-1] -} - -func (r *Reader) isFileReadable(path string) bool { - // #nosec G201 -- path comes from validated local files, not user input - _, err := r.db.Exec(fmt.Sprintf("SELECT 1 FROM read_parquet(%s) LIMIT 1", quoteSQLString(path))) - return err == nil -} - -// OnFileRotation notifies the reader that a file has been rotated. -func (r *Reader) OnFileRotation(closedFileStartBlock uint64) { - r.mu.Lock() - defer r.mu.Unlock() - - receiptFile := filepath.Join(r.basePath, fmt.Sprintf("receipts_%d.parquet", closedFileStartBlock)) - logFile := filepath.Join(r.basePath, fmt.Sprintf("logs_%d.parquet", closedFileStartBlock)) - r.closedReceiptFiles = append(r.closedReceiptFiles, receiptFile) - r.closedLogFiles = append(r.closedLogFiles, logFile) -} - -// ClosedReceiptFileCount returns the number of closed receipt files. -func (r *Reader) ClosedReceiptFileCount() int { - r.mu.RLock() - defer r.mu.RUnlock() - return len(r.closedReceiptFiles) -} - -// GetFilesBeforeBlock returns files whose start block is before the given block. -// These files contain only data older than the prune threshold. -func (r *Reader) GetFilesBeforeBlock(pruneBeforeBlock uint64) []FilePair { - r.mu.RLock() - defer r.mu.RUnlock() - - var result []FilePair - for _, f := range r.closedReceiptFiles { - startBlock := ExtractBlockNumber(f) - // Only prune files that are entirely before the prune threshold - // We need to check that the NEXT file starts before pruneBeforeBlock, - // meaning this file's data is all older than the threshold - if startBlock+r.maxBlocksPerFile <= pruneBeforeBlock { - logFile := filepath.Join(r.basePath, fmt.Sprintf("logs_%d.parquet", startBlock)) - result = append(result, FilePair{ - ReceiptFile: f, - LogFile: logFile, - StartBlock: startBlock, - }) - } - } - return result -} - -// RemoveTrackedReceiptFile removes a specific receipt file from reader tracking. -func (r *Reader) RemoveTrackedReceiptFile(startBlock uint64) { - r.mu.Lock() - defer r.mu.Unlock() - - newFiles := make([]string, 0, len(r.closedReceiptFiles)) - for _, f := range r.closedReceiptFiles { - if ExtractBlockNumber(f) != startBlock { - newFiles = append(newFiles, f) - } - } - r.closedReceiptFiles = newFiles -} - -// RemoveTrackedLogFile removes a specific log file from reader tracking. -func (r *Reader) RemoveTrackedLogFile(startBlock uint64) { - r.mu.Lock() - defer r.mu.Unlock() - - newFiles := make([]string, 0, len(r.closedLogFiles)) - for _, f := range r.closedLogFiles { - if ExtractBlockNumber(f) != startBlock { - newFiles = append(newFiles, f) - } - } - r.closedLogFiles = newFiles -} - -// AddTrackedReceiptFile adds a specific receipt file to reader tracking if missing. -func (r *Reader) AddTrackedReceiptFile(startBlock uint64) { - r.mu.Lock() - defer r.mu.Unlock() - - path := filepath.Join(r.basePath, fmt.Sprintf("receipts_%d.parquet", startBlock)) - for _, f := range r.closedReceiptFiles { - if f == path { - return - } - } - r.closedReceiptFiles = append(r.closedReceiptFiles, path) - sort.Slice(r.closedReceiptFiles, func(i, j int) bool { - return ExtractBlockNumber(r.closedReceiptFiles[i]) < ExtractBlockNumber(r.closedReceiptFiles[j]) - }) -} - -// AddTrackedLogFile adds a specific log file to reader tracking if missing. -func (r *Reader) AddTrackedLogFile(startBlock uint64) { - r.mu.Lock() - defer r.mu.Unlock() - - path := filepath.Join(r.basePath, fmt.Sprintf("logs_%d.parquet", startBlock)) - for _, f := range r.closedLogFiles { - if f == path { - return - } - } - r.closedLogFiles = append(r.closedLogFiles, path) - sort.Slice(r.closedLogFiles, func(i, j int) bool { - return ExtractBlockNumber(r.closedLogFiles[i]) < ExtractBlockNumber(r.closedLogFiles[j]) - }) -} - -// MaxReceiptBlockNumber returns the maximum block number in the receipt files. -func (r *Reader) MaxReceiptBlockNumber(ctx context.Context) (uint64, bool, error) { - r.mu.RLock() - closedFiles := r.closedReceiptFiles - r.mu.RUnlock() - if len(closedFiles) == 0 { - return 0, false, nil - } - - var parquetFiles string - if len(closedFiles) == 1 { - parquetFiles = quoteSQLString(closedFiles[0]) - } else { - parquetFiles = fmt.Sprintf("[%s]", joinQuoted(closedFiles)) - } - - // #nosec G201 -- parquetFiles derived from local file paths - query := fmt.Sprintf("SELECT MAX(block_number) FROM read_parquet(%s, union_by_name=true)", parquetFiles) - row := r.db.QueryRowContext(ctx, query) - var max sql.NullInt64 - if err := row.Scan(&max); err != nil { - return 0, false, fmt.Errorf("failed to query max block number: %w", err) - } - if !max.Valid { - return 0, false, nil - } - if max.Int64 < 0 { - return 0, false, fmt.Errorf("invalid negative block number: %d", max.Int64) - } - return uint64(max.Int64), true, nil -} - -// GetReceiptByTxHash queries for a receipt by transaction hash. -func (r *Reader) GetReceiptByTxHash(ctx context.Context, txHash common.Hash) (*ReceiptResult, error) { - r.mu.RLock() - closedFiles := r.closedReceiptFiles - r.mu.RUnlock() - - if len(closedFiles) == 0 { - return nil, nil - } - - var parquetFiles string - if len(closedFiles) == 1 { - parquetFiles = quoteSQLString(closedFiles[0]) - } else { - parquetFiles = fmt.Sprintf("[%s]", joinQuoted(closedFiles)) - } - - // #nosec G201 -- parquetFiles derived from local file paths - query := fmt.Sprintf(` - SELECT - tx_hash, block_number, receipt_bytes - FROM read_parquet(%s, union_by_name=true) - WHERE tx_hash = $1 - LIMIT 1 - `, parquetFiles) - - row := r.db.QueryRowContext(ctx, query, txHash[:]) - var rec ReceiptResult - if err := row.Scan(&rec.TxHash, &rec.BlockNumber, &rec.ReceiptBytes); err != nil { - if err == sql.ErrNoRows { - return nil, nil - } - return nil, fmt.Errorf("failed to query receipt: %w", err) - } - return &rec, nil -} - -// GetLogs queries logs matching the given filter. -func (r *Reader) GetLogs(ctx context.Context, filter LogFilter) ([]LogResult, error) { - r.mu.RLock() - closedFiles := r.closedLogFiles - r.mu.RUnlock() - - if len(closedFiles) == 0 { - return nil, nil - } - - files := make([]string, 0, len(closedFiles)) - for _, f := range closedFiles { - startBlock := ExtractBlockNumber(f) - if filter.ToBlock != nil && startBlock > *filter.ToBlock { - continue - } - files = append(files, f) - } - if len(files) == 0 { - return nil, nil - } - - return r.queryLogFiles(ctx, files, filter) -} - -func (r *Reader) queryLogFiles(ctx context.Context, files []string, filter LogFilter) ([]LogResult, error) { - var parquetFiles string - if len(files) == 1 { - parquetFiles = quoteSQLString(files[0]) - } else { - parquetFiles = fmt.Sprintf("[%s]", joinQuoted(files)) - } - - // #nosec G201 -- parquetFiles derived from local file paths - query := fmt.Sprintf(` - SELECT - block_number, tx_hash, tx_index, log_index, address, - topic0, topic1, topic2, topic3, data, block_hash, removed - FROM read_parquet(%s, union_by_name=true) - WHERE 1=1 - `, parquetFiles) - - var args []any - argIdx := 1 - - if filter.FromBlock != nil { - query += fmt.Sprintf(" AND block_number >= $%d", argIdx) - args = append(args, *filter.FromBlock) - argIdx++ - } - - if filter.ToBlock != nil { - query += fmt.Sprintf(" AND block_number <= $%d", argIdx) - args = append(args, *filter.ToBlock) - argIdx++ - } - - if len(filter.Addresses) > 0 { - placeholders := make([]string, len(filter.Addresses)) - for i, addr := range filter.Addresses { - placeholders[i] = fmt.Sprintf("$%d", argIdx) - args = append(args, addr[:]) - argIdx++ - } - query += fmt.Sprintf(" AND address IN (%s)", strings.Join(placeholders, ", ")) - } - - topicCols := []string{"topic0", "topic1", "topic2", "topic3"} - for i, topicList := range filter.Topics { - if i >= 4 { - break - } - if len(topicList) == 0 { - continue - } - - if len(topicList) == 1 { - query += fmt.Sprintf(" AND %s = $%d", topicCols[i], argIdx) - args = append(args, topicList[0][:]) - argIdx++ - } else { - placeholders := make([]string, len(topicList)) - for j, topic := range topicList { - placeholders[j] = fmt.Sprintf("$%d", argIdx) - args = append(args, topic[:]) - argIdx++ - } - query += fmt.Sprintf(" AND %s IN (%s)", topicCols[i], strings.Join(placeholders, ", ")) - } - } - - query += " ORDER BY block_number, tx_index, log_index" - if filter.Limit > 0 { - query += fmt.Sprintf(" LIMIT %d", filter.Limit) - } - - rows, err := r.db.QueryContext(ctx, query, args...) - if err != nil { - return nil, fmt.Errorf("failed to query logs: %w", err) - } - defer func() { _ = rows.Close() }() - - var results []LogResult - for rows.Next() { - var log LogResult - if err := rows.Scan( - &log.BlockNumber, &log.TxHash, &log.TxIndex, &log.LogIndex, - &log.Address, &log.Topic0, &log.Topic1, &log.Topic2, &log.Topic3, - &log.Data, &log.BlockHash, &log.Removed, - ); err != nil { - return nil, fmt.Errorf("failed to scan log: %w", err) - } - results = append(results, log) - } - - return results, rows.Err() -} - -// ExtractBlockNumber extracts the block number from a parquet filename. -func ExtractBlockNumber(path string) uint64 { - base := filepath.Base(path) - base = strings.TrimSuffix(base, ".parquet") - parts := strings.Split(base, "_") - if len(parts) < 2 { - return 0 - } - num, _ := strconv.ParseUint(parts[len(parts)-1], 10, 64) - return num -} - -func joinQuoted(files []string) string { - quoted := make([]string, len(files)) - for i, f := range files { - quoted[i] = quoteSQLString(f) - } - return strings.Join(quoted, ", ") -} - -func quoteSQLString(s string) string { - return "'" + strings.ReplaceAll(s, "'", "''") + "'" -} diff --git a/sei-db/ledger_db/parquet/store.go b/sei-db/ledger_db/parquet/store.go deleted file mode 100644 index 040a89be01..0000000000 --- a/sei-db/ledger_db/parquet/store.go +++ /dev/null @@ -1,578 +0,0 @@ -package parquet - -import ( - "context" - "fmt" - "math/rand" - "os" - "path/filepath" - "strings" - "sync" - "sync/atomic" - "time" - - "github.com/ethereum/go-ethereum/common" - "github.com/parquet-go/parquet-go" - dbLogger "github.com/sei-protocol/sei-chain/sei-db/common/logger" - dbwal "github.com/sei-protocol/sei-chain/sei-db/wal" -) - -const ( - maxInt64 = int64(^uint64(0) >> 1) - maxUint32 = ^uint32(0) - - defaultBlockFlushInterval uint64 = 1 - defaultMaxBlocksPerFile uint64 = 500 -) - -var removeFile = os.Remove - -// StoreConfig configures the parquet store. -type StoreConfig struct { - DBDirectory string - KeepRecent int64 - PruneIntervalSeconds int64 - BlockFlushInterval uint64 - MaxBlocksPerFile uint64 -} - -// DefaultStoreConfig returns the default store configuration. -func DefaultStoreConfig() StoreConfig { - return StoreConfig{ - BlockFlushInterval: defaultBlockFlushInterval, - MaxBlocksPerFile: defaultMaxBlocksPerFile, - } -} - -// ReceiptInput is the input for storing a receipt. -type ReceiptInput struct { - BlockNumber uint64 - Receipt ReceiptRecord - Logs []LogRecord - ReceiptBytes []byte // For WAL -} - -// Store is the parquet-based receipt store. -type Store struct { - basePath string - receiptWriter *parquet.GenericWriter[ReceiptRecord] - logWriter *parquet.GenericWriter[LogRecord] - receiptFile *os.File - logFile *os.File - - mu sync.Mutex - fileStartBlock uint64 - receiptsBuffer []ReceiptRecord - logsBuffer []LogRecord - config StoreConfig - lastSeenBlock uint64 - blocksSinceFlush uint64 - blocksInFile uint64 - - Reader *Reader - wal dbwal.GenericWAL[WALEntry] - latestVersion atomic.Int64 - earliestVersion atomic.Int64 - closeOnce sync.Once - - log dbLogger.Logger - pruneStop chan struct{} - - // WarmupRecords holds receipts recovered from WAL for cache warming. - WarmupRecords []ReceiptRecord -} - -// NewStore creates a new parquet store. -func NewStore(log dbLogger.Logger, cfg StoreConfig) (*Store, error) { - storeCfg := resolveStoreConfig(cfg) - - if err := os.MkdirAll(cfg.DBDirectory, 0o750); err != nil { - return nil, fmt.Errorf("failed to create parquet base directory: %w", err) - } - - reader, err := NewReaderWithMaxBlocksPerFile(cfg.DBDirectory, storeCfg.MaxBlocksPerFile) - if err != nil { - return nil, err - } - - walDir := filepath.Join(cfg.DBDirectory, "parquet-wal") - receiptWAL, err := NewWAL(log, walDir) - if err != nil { - return nil, err - } - - store := &Store{ - basePath: cfg.DBDirectory, - receiptsBuffer: make([]ReceiptRecord, 0, 1000), - logsBuffer: make([]LogRecord, 0, 10000), - config: storeCfg, - Reader: reader, - wal: receiptWAL, - log: log, - pruneStop: make(chan struct{}), - } - - if maxBlock, ok, err := reader.MaxReceiptBlockNumber(context.Background()); err != nil { - return nil, err - } else if ok { - latest, err := int64FromUint64(maxBlock) - if err != nil { - return nil, err - } - store.latestVersion.Store(latest) - if maxBlock < ^uint64(0) { - store.fileStartBlock = maxBlock + 1 - } - } - - if reader.ClosedReceiptFileCount() == 0 { - store.fileStartBlock = 0 - } - - if err := store.initWriters(); err != nil { - return nil, err - } - - store.startPruning(cfg.PruneIntervalSeconds) - - return store, nil -} - -func resolveStoreConfig(cfg StoreConfig) StoreConfig { - resolved := DefaultStoreConfig() - resolved.DBDirectory = cfg.DBDirectory - resolved.KeepRecent = cfg.KeepRecent - resolved.PruneIntervalSeconds = cfg.PruneIntervalSeconds - if cfg.BlockFlushInterval > 0 { - resolved.BlockFlushInterval = cfg.BlockFlushInterval - } - if cfg.MaxBlocksPerFile > 0 { - resolved.MaxBlocksPerFile = cfg.MaxBlocksPerFile - } - return resolved -} - -// LatestVersion returns the latest version stored. -func (s *Store) LatestVersion() int64 { - return s.latestVersion.Load() -} - -// SetLatestVersion sets the latest version. -func (s *Store) SetLatestVersion(version int64) { - s.latestVersion.Store(version) -} - -// SetEarliestVersion sets the earliest version. -func (s *Store) SetEarliestVersion(version int64) { - s.earliestVersion.Store(version) -} - -// CacheRotateInterval returns the interval at which the cache should rotate. -func (s *Store) CacheRotateInterval() uint64 { - return s.config.MaxBlocksPerFile -} - -// GetReceiptByTxHash retrieves a receipt by transaction hash. -func (s *Store) GetReceiptByTxHash(ctx context.Context, txHash common.Hash) (*ReceiptResult, error) { - return s.Reader.GetReceiptByTxHash(ctx, txHash) -} - -// GetLogs retrieves logs matching the filter. -func (s *Store) GetLogs(ctx context.Context, filter LogFilter) ([]LogResult, error) { - return s.Reader.GetLogs(ctx, filter) -} - -// WriteReceipts writes multiple receipts, batching WAL writes per block. -func (s *Store) WriteReceipts(inputs []ReceiptInput) error { - if len(inputs) == 0 { - return nil - } - - // Group receipt bytes by block number for batched WAL writes. - // Preserve encounter order so WAL entries are written in block order. - type blockBatch struct { - blockNumber uint64 - receipts [][]byte - } - var batches []blockBatch - batchIdx := make(map[uint64]int) - - for i := range inputs { - bn := inputs[i].BlockNumber - if idx, ok := batchIdx[bn]; ok { - batches[idx].receipts = append(batches[idx].receipts, inputs[i].ReceiptBytes) - } else { - batchIdx[bn] = len(batches) - batches = append(batches, blockBatch{ - blockNumber: bn, - receipts: [][]byte{inputs[i].ReceiptBytes}, - }) - } - } - - // Write one WAL entry per block - for _, b := range batches { - entry := WALEntry{ - BlockNumber: b.blockNumber, - Receipts: b.receipts, - } - if err := s.wal.Write(entry); err != nil { - return err - } - } - - s.mu.Lock() - defer s.mu.Unlock() - - for i := range inputs { - if err := s.applyReceiptLocked(inputs[i]); err != nil { - return err - } - } - - return nil -} - -// UpdateLatestVersion updates the latest version if the new value is higher. -func (s *Store) UpdateLatestVersion(version int64) { - if version > s.latestVersion.Load() { - s.latestVersion.Store(version) - } -} - -// Close closes the store. -func (s *Store) Close() error { - var err error - s.closeOnce.Do(func() { - if s.pruneStop != nil { - close(s.pruneStop) - } - - s.mu.Lock() - defer s.mu.Unlock() - - if flushErr := s.flushLocked(); flushErr != nil { - err = flushErr - return - } - if closeErr := s.closeWritersLocked(); closeErr != nil { - err = closeErr - return - } - if closeErr := s.wal.Close(); closeErr != nil { - err = closeErr - return - } - if closeErr := s.Reader.Close(); closeErr != nil { - err = closeErr - } - }) - - return err -} - -// WAL returns the WAL for replay purposes. -func (s *Store) WAL() dbwal.GenericWAL[WALEntry] { - return s.wal -} - -// ApplyReceiptFromReplay applies a receipt during WAL replay. -func (s *Store) ApplyReceiptFromReplay(input ReceiptInput) error { - s.mu.Lock() - defer s.mu.Unlock() - return s.applyReceiptLocked(input) -} - -// FileStartBlock returns the current file start block. -func (s *Store) FileStartBlock() uint64 { - return s.fileStartBlock -} - -// ClearWAL truncates the WAL after a successful file rotation. -func (s *Store) ClearWAL() error { - firstOffset, errFirst := s.wal.FirstOffset() - if errFirst != nil || firstOffset <= 0 { - return nil - } - lastOffset, errLast := s.wal.LastOffset() - if errLast != nil || lastOffset <= 0 { - return nil - } - if lastOffset < firstOffset { - return nil - } - if err := s.wal.TruncateBefore(lastOffset + 1); err != nil { - if strings.Contains(err.Error(), "out of range") { - return nil - } - return fmt.Errorf("failed to truncate parquet WAL before offset %d: %w", lastOffset+1, err) - } - return nil -} - -func (s *Store) startPruning(pruneIntervalSeconds int64) { - if s.config.KeepRecent <= 0 || pruneIntervalSeconds <= 0 { - return - } - go func() { - for { - latestVersion := s.latestVersion.Load() - pruneBeforeBlock := latestVersion - s.config.KeepRecent - if pruneBeforeBlock > 0 { - pruned := s.pruneOldFiles(uint64(pruneBeforeBlock)) - if pruned > 0 && s.log != nil { - s.log.Info(fmt.Sprintf("Pruned %d parquet file pairs older than block %d", pruned, pruneBeforeBlock)) - } - } - - // Add random jitter (up to 50% of base interval) to avoid thundering herd - jitter := time.Duration(rand.Float64()*float64(pruneIntervalSeconds)*0.5) * time.Second - sleepDuration := time.Duration(pruneIntervalSeconds)*time.Second + jitter - - select { - case <-s.pruneStop: - return - case <-time.After(sleepDuration): - // Continue to next iteration - } - } - }() -} - -func (s *Store) pruneOldFiles(pruneBeforeBlock uint64) int { - // Get list of files to prune from the reader - filesToPrune := s.Reader.GetFilesBeforeBlock(pruneBeforeBlock) - if len(filesToPrune) == 0 { - return 0 - } - - prunedCount := 0 - for _, filePair := range filesToPrune { - receiptRemoved := filePair.ReceiptFile == "" - if filePair.ReceiptFile != "" { - s.Reader.RemoveTrackedReceiptFile(filePair.StartBlock) - if err := removeFile(filePair.ReceiptFile); err != nil && !os.IsNotExist(err) { - s.Reader.AddTrackedReceiptFile(filePair.StartBlock) - if s.log != nil { - s.log.Error("failed to prune receipt file", "file", filePair.ReceiptFile, "err", err) - } - } else { - receiptRemoved = true - } - } - - logRemoved := filePair.LogFile == "" - if filePair.LogFile != "" { - s.Reader.RemoveTrackedLogFile(filePair.StartBlock) - if err := removeFile(filePair.LogFile); err != nil && !os.IsNotExist(err) { - s.Reader.AddTrackedLogFile(filePair.StartBlock) - if s.log != nil { - s.log.Error("failed to prune log file", "file", filePair.LogFile, "err", err) - } - } else { - logRemoved = true - } - } - - if receiptRemoved && logRemoved { - prunedCount++ - } - } - - return prunedCount -} - -func (s *Store) applyReceiptLocked(input ReceiptInput) error { - blockNumber := input.BlockNumber - isNewBlock := blockNumber != s.lastSeenBlock - if isNewBlock { - if s.lastSeenBlock != 0 { - s.blocksSinceFlush++ - s.blocksInFile++ - } - s.lastSeenBlock = blockNumber - } - - s.receiptsBuffer = append(s.receiptsBuffer, input.Receipt) - if len(input.Logs) > 0 { - s.logsBuffer = append(s.logsBuffer, input.Logs...) - } - - if s.config.BlockFlushInterval > 0 && s.blocksSinceFlush >= s.config.BlockFlushInterval { - if err := s.flushLocked(); err != nil { - return err - } - s.blocksSinceFlush = 0 - } - - if isNewBlock && s.shouldRotateFile() { - if err := s.rotateFileLocked(blockNumber); err != nil { - return err - } - } - - return nil -} - -func (s *Store) shouldRotateFile() bool { - if s.config.MaxBlocksPerFile > 0 && s.blocksInFile >= s.config.MaxBlocksPerFile { - return true - } - return false -} - -func (s *Store) rotateFileLocked(newBlockNumber uint64) error { - if err := s.flushLocked(); err != nil { - return err - } - - oldStartBlock := s.fileStartBlock - if err := s.closeWritersLocked(); err != nil { - return err - } - - s.Reader.OnFileRotation(oldStartBlock) - if err := s.ClearWAL(); err != nil { - return err - } - - s.fileStartBlock = newBlockNumber - s.blocksInFile = 0 - - return s.initWriters() -} - -func (s *Store) initWriters() error { - receiptPath := filepath.Join(s.basePath, fmt.Sprintf("receipts_%d.parquet", s.fileStartBlock)) - logPath := filepath.Join(s.basePath, fmt.Sprintf("logs_%d.parquet", s.fileStartBlock)) - - // #nosec G304 -- paths are constructed from configured base directory - receiptFile, err := os.Create(receiptPath) - if err != nil { - return fmt.Errorf("failed to create receipt parquet file: %w", err) - } - - // #nosec G304 -- paths are constructed from configured base directory - logFile, err := os.Create(logPath) - if err != nil { - if closeErr := receiptFile.Close(); closeErr != nil { - return fmt.Errorf("failed to create log parquet file: %w; close receipt file error: %v", err, closeErr) - } - return fmt.Errorf("failed to create log parquet file: %w", err) - } - - blockNumberSorting := parquet.SortingWriterConfig( - parquet.SortingColumns(parquet.Ascending("block_number")), - ) - - receiptWriter := parquet.NewGenericWriter[ReceiptRecord](receiptFile, - parquet.Compression(&parquet.Snappy), - blockNumberSorting, - ) - logWriter := parquet.NewGenericWriter[LogRecord](logFile, - parquet.Compression(&parquet.Snappy), - blockNumberSorting, - ) - - s.receiptFile = receiptFile - s.logFile = logFile - s.receiptWriter = receiptWriter - s.logWriter = logWriter - - return nil -} - -func (s *Store) flushLocked() error { - if len(s.receiptsBuffer) == 0 { - return nil - } - - if _, err := s.receiptWriter.Write(s.receiptsBuffer); err != nil { - return fmt.Errorf("failed to write receipts to parquet: %w", err) - } - if err := s.receiptWriter.Flush(); err != nil { - return fmt.Errorf("failed to flush receipt parquet writer: %w", err) - } - - if len(s.logsBuffer) > 0 { - if _, err := s.logWriter.Write(s.logsBuffer); err != nil { - return fmt.Errorf("failed to write logs to parquet: %w", err) - } - if err := s.logWriter.Flush(); err != nil { - return fmt.Errorf("failed to flush log parquet writer: %w", err) - } - } - - s.receiptsBuffer = s.receiptsBuffer[:0] - s.logsBuffer = s.logsBuffer[:0] - return nil -} - -func (s *Store) closeWritersLocked() error { - var errs []error - - if s.receiptWriter != nil { - if err := s.receiptWriter.Close(); err != nil { - errs = append(errs, fmt.Errorf("receipt writer: %w", err)) - } - } - if s.logWriter != nil { - if err := s.logWriter.Close(); err != nil { - errs = append(errs, fmt.Errorf("log writer: %w", err)) - } - } - if s.receiptFile != nil { - if err := s.receiptFile.Sync(); err != nil { - errs = append(errs, fmt.Errorf("receipt file sync: %w", err)) - } - if err := s.receiptFile.Close(); err != nil { - errs = append(errs, fmt.Errorf("receipt file: %w", err)) - } - } - if s.logFile != nil { - if err := s.logFile.Sync(); err != nil { - errs = append(errs, fmt.Errorf("log file sync: %w", err)) - } - if err := s.logFile.Close(); err != nil { - errs = append(errs, fmt.Errorf("log file: %w", err)) - } - } - - if len(errs) > 0 { - return fmt.Errorf("close errors: %v", errs) - } - return nil -} - -func int64FromUint64(value uint64) (int64, error) { - if value > uint64(maxInt64) { - return 0, fmt.Errorf("value %d overflows int64", value) - } - return int64(value), nil -} - -// Uint32FromUint safely converts uint to uint32. -func Uint32FromUint(value uint) uint32 { - if value > uint(maxUint32) { - return maxUint32 - } - return uint32(value) -} - -// CopyBytes creates a copy of a byte slice. -func CopyBytes(src []byte) []byte { - if len(src) == 0 { - return make([]byte, 0) - } - dst := make([]byte, len(src)) - copy(dst, src) - return dst -} - -// CopyBytesOrEmpty creates a copy of a byte slice, returning empty slice for nil. -func CopyBytesOrEmpty(src []byte) []byte { - if src == nil { - return make([]byte, 0) - } - return CopyBytes(src) -} diff --git a/sei-db/ledger_db/parquet/store_config_test.go b/sei-db/ledger_db/parquet/store_config_test.go deleted file mode 100644 index 34ed1debf7..0000000000 --- a/sei-db/ledger_db/parquet/store_config_test.go +++ /dev/null @@ -1,104 +0,0 @@ -package parquet - -import ( - "errors" - "strings" - "testing" - - dbLogger "github.com/sei-protocol/sei-chain/sei-db/common/logger" - "github.com/stretchr/testify/require" -) - -type mockParquetWAL struct { - first uint64 - last uint64 - truncateErr error -} - -func (m *mockParquetWAL) Write(_ WALEntry) error { return nil } - -func (m *mockParquetWAL) TruncateBefore(_ uint64) error { return m.truncateErr } - -func (m *mockParquetWAL) TruncateAfter(_ uint64) error { return nil } - -func (m *mockParquetWAL) ReadAt(_ uint64) (WALEntry, error) { return WALEntry{}, nil } - -func (m *mockParquetWAL) FirstOffset() (uint64, error) { return m.first, nil } - -func (m *mockParquetWAL) LastOffset() (uint64, error) { return m.last, nil } - -func (m *mockParquetWAL) Replay(_, _ uint64, _ func(index uint64, entry WALEntry) error) error { - return nil -} - -func (m *mockParquetWAL) Close() error { return nil } - -func TestNewStoreAppliesConfiguredIntervals(t *testing.T) { - store, err := NewStore(dbLogger.NewNopLogger(), StoreConfig{ - DBDirectory: t.TempDir(), - BlockFlushInterval: 7, - MaxBlocksPerFile: 11, - }) - require.NoError(t, err) - t.Cleanup(func() { _ = store.Close() }) - - require.Equal(t, uint64(7), store.config.BlockFlushInterval) - require.Equal(t, uint64(11), store.config.MaxBlocksPerFile) - require.Equal(t, uint64(11), store.CacheRotateInterval()) - - store.Reader.OnFileRotation(0) - require.Len(t, store.Reader.GetFilesBeforeBlock(11), 1) -} - -func TestNewStoreUsesDefaultIntervalsWhenUnset(t *testing.T) { - store, err := NewStore(dbLogger.NewNopLogger(), StoreConfig{ - DBDirectory: t.TempDir(), - }) - require.NoError(t, err) - t.Cleanup(func() { _ = store.Close() }) - - require.Equal(t, defaultBlockFlushInterval, store.config.BlockFlushInterval) - require.Equal(t, defaultMaxBlocksPerFile, store.config.MaxBlocksPerFile) - require.Equal(t, defaultMaxBlocksPerFile, store.CacheRotateInterval()) -} - -func TestPruneOldFilesKeepsTrackingOnDeleteFailure(t *testing.T) { - store, err := NewStore(dbLogger.NewNopLogger(), StoreConfig{ - DBDirectory: t.TempDir(), - }) - require.NoError(t, err) - t.Cleanup(func() { _ = store.Close() }) - - store.Reader.OnFileRotation(0) - require.Equal(t, 1, store.Reader.ClosedReceiptFileCount()) - - origRemove := removeFile - removeFile = func(path string) error { - if strings.Contains(path, "receipts_0.parquet") { - return errors.New("permission denied") - } - return nil - } - t.Cleanup(func() { removeFile = origRemove }) - - // 0 + 500 <= 600, so file pair is prune-eligible. - pruned := store.pruneOldFiles(600) - require.Equal(t, 0, pruned) - - // Receipt file should remain tracked because delete failed. - require.Equal(t, 1, store.Reader.ClosedReceiptFileCount()) -} - -func TestClearWALReturnsTruncateError(t *testing.T) { - store := &Store{ - wal: &mockParquetWAL{ - first: 1, - last: 2, - truncateErr: errors.New("truncate failed"), - }, - } - - err := store.ClearWAL() - require.Error(t, err) - require.ErrorContains(t, err, "failed to truncate parquet WAL") -} diff --git a/sei-db/ledger_db/parquet/types.go b/sei-db/ledger_db/parquet/types.go deleted file mode 100644 index ce3b73396e..0000000000 --- a/sei-db/ledger_db/parquet/types.go +++ /dev/null @@ -1,60 +0,0 @@ -package parquet - -import "github.com/ethereum/go-ethereum/common" - -// ReceiptResult holds the raw receipt data returned from a query. -type ReceiptResult struct { - TxHash []byte - BlockNumber uint64 - ReceiptBytes []byte -} - -// LogFilter specifies criteria for filtering logs. -type LogFilter struct { - FromBlock *uint64 - ToBlock *uint64 - Addresses []common.Address - Topics [][]common.Hash - Limit int -} - -// LogResult holds log data returned from a query. -type LogResult struct { - BlockNumber uint64 - TxHash []byte - TxIndex uint32 - LogIndex uint32 - Address []byte - Topic0 []byte - Topic1 []byte - Topic2 []byte - Topic3 []byte - Data []byte - BlockHash []byte - Removed bool -} - -// ReceiptRecord is a parquet-specific record for storing receipts. -type ReceiptRecord struct { - TxHash []byte `parquet:"tx_hash"` - BlockNumber uint64 `parquet:"block_number"` - ReceiptBytes []byte `parquet:"receipt_bytes"` -} - -// LogRecord is a parquet-specific record for storing log entries. -type LogRecord struct { - BlockNumber uint64 `parquet:"block_number"` - TxHash []byte `parquet:"tx_hash"` - TxIndex uint32 `parquet:"tx_index"` - LogIndex uint32 `parquet:"log_index"` - Address []byte `parquet:"address"` - BlockHash []byte `parquet:"block_hash"` - Removed bool `parquet:"removed"` - - Topic0 []byte `parquet:"topic0"` - Topic1 []byte `parquet:"topic1"` - Topic2 []byte `parquet:"topic2"` - Topic3 []byte `parquet:"topic3"` - - Data []byte `parquet:"data"` -} diff --git a/sei-db/ledger_db/parquet/wal.go b/sei-db/ledger_db/parquet/wal.go deleted file mode 100644 index d0a4ccbd07..0000000000 --- a/sei-db/ledger_db/parquet/wal.go +++ /dev/null @@ -1,118 +0,0 @@ -package parquet - -import ( - "encoding/binary" - "fmt" - "os" - - dbLogger "github.com/sei-protocol/sei-chain/sei-db/common/logger" - dbwal "github.com/sei-protocol/sei-chain/sei-db/wal" -) - -// WALEntry represents a batch of receipts for a single block in the WAL. -type WALEntry struct { - BlockNumber uint64 - Receipts [][]byte -} - -// encodeWALEntry encodes a WALEntry to binary format: -// [blockNumber:8][numReceipts:4][len1:4][receipt1]...[lenN:4][receiptN] -func encodeWALEntry(entry WALEntry) ([]byte, error) { - if err := validateUint32Int(len(entry.Receipts), "receipt count"); err != nil { - return nil, err - } - - size := 8 + 4 // blockNumber + numReceipts - for _, r := range entry.Receipts { - if err := validateUint32Int(len(r), "receipt length"); err != nil { - return nil, err - } - size += 4 + len(r) // length prefix + data - } - - buf := make([]byte, size) - offset := 0 - - binary.LittleEndian.PutUint64(buf[offset:], entry.BlockNumber) - offset += 8 - - putUint32FromInt(buf[offset:], len(entry.Receipts)) - offset += 4 - - for _, r := range entry.Receipts { - if err := validateUint32Int(len(r), "receipt length"); err != nil { - return nil, err - } - putUint32FromInt(buf[offset:], len(r)) - offset += 4 - copy(buf[offset:], r) - offset += len(r) - } - - return buf, nil -} - -// decodeWALEntry decodes a binary WALEntry. -func decodeWALEntry(data []byte) (WALEntry, error) { - if len(data) < 12 { - return WALEntry{}, fmt.Errorf("WAL entry too short: %d bytes", len(data)) - } - - offset := 0 - blockNumber := binary.LittleEndian.Uint64(data[offset:]) - offset += 8 - - numReceipts := binary.LittleEndian.Uint32(data[offset:]) - offset += 4 - - receipts := make([][]byte, 0, numReceipts) - for i := uint32(0); i < numReceipts; i++ { - if offset+4 > len(data) { - return WALEntry{}, fmt.Errorf("WAL entry truncated at receipt %d length", i) - } - rLen := binary.LittleEndian.Uint32(data[offset:]) - offset += 4 - - if offset+int(rLen) > len(data) { - return WALEntry{}, fmt.Errorf("WAL entry truncated at receipt %d data", i) - } - r := make([]byte, rLen) - copy(r, data[offset:offset+int(rLen)]) - offset += int(rLen) - - receipts = append(receipts, r) - } - - return WALEntry{ - BlockNumber: blockNumber, - Receipts: receipts, - }, nil -} - -func validateUint32Int(value int, field string) error { - if value < 0 || uint64(value) > uint64(maxUint32) { - return fmt.Errorf("%s exceeds uint32 range: %d", field, value) - } - return nil -} - -func putUint32FromInt(dst []byte, value int) { - dst[0] = byte(value) - dst[1] = byte(value >> 8) - dst[2] = byte(value >> 16) - dst[3] = byte(value >> 24) -} - -// NewWAL creates a new WAL for parquet receipts. -func NewWAL(logger dbLogger.Logger, dir string) (dbwal.GenericWAL[WALEntry], error) { - if err := os.MkdirAll(dir, 0o750); err != nil { - return nil, err - } - return dbwal.NewWAL( - encodeWALEntry, - decodeWALEntry, - logger, - dir, - dbwal.Config{}, - ) -} diff --git a/sei-db/ledger_db/receipt/cached_receipt_store.go b/sei-db/ledger_db/receipt/cached_receipt_store.go index b8d264b5d0..28222b8bf1 100644 --- a/sei-db/ledger_db/receipt/cached_receipt_store.go +++ b/sei-db/ledger_db/receipt/cached_receipt_store.go @@ -1,7 +1,6 @@ package receipt import ( - "sort" "sync" sdk "github.com/cosmos/cosmos-sdk/types" @@ -14,14 +13,6 @@ import ( // Keep in sync with the parquet default max blocks per file to retain a similar cache window. const defaultReceiptCacheRotateInterval = 500 -type cacheRotateIntervalProvider interface { - cacheRotateInterval() uint64 -} - -type cacheWarmupProvider interface { - warmupReceipts() []ReceiptRecord -} - type cachedReceiptStore struct { backend ReceiptStore cache *ledgerCache @@ -34,19 +25,10 @@ func newCachedReceiptStore(backend ReceiptStore) ReceiptStore { if backend == nil { return nil } - interval := uint64(defaultReceiptCacheRotateInterval) - if provider, ok := backend.(cacheRotateIntervalProvider); ok { - if v := provider.cacheRotateInterval(); v > 0 { - interval = v - } - } store := &cachedReceiptStore{ backend: backend, cache: newLedgerCache(), - cacheRotateInterval: interval, - } - if provider, ok := backend.(cacheWarmupProvider); ok { - store.cacheReceipts(provider.warmupReceipts()) + cacheRotateInterval: defaultReceiptCacheRotateInterval, } return store } @@ -86,60 +68,9 @@ func (s *cachedReceiptStore) SetReceipts(ctx sdk.Context, receipts []ReceiptReco } // FilterLogs queries logs across a range of blocks. -// Checks the cache first for recent blocks, then delegates to the backend. +// Delegates to the backend which may use efficient range queries (parquet/DuckDB). func (s *cachedReceiptStore) FilterLogs(ctx sdk.Context, fromBlock, toBlock uint64, crit filters.FilterCriteria) ([]*ethtypes.Log, error) { - // First get logs from backend (parquet closed files) - backendLogs, err := s.backend.FilterLogs(ctx, fromBlock, toBlock, crit) - if err != nil { - return nil, err - } - - // Then check cache for blocks that might not be in closed files yet - cacheLogs := s.cache.FilterLogs(fromBlock, toBlock, crit) - - // Merge results, avoiding duplicates by tracking seen (blockNum, txIndex, logIndex) - if len(cacheLogs) == 0 { - return backendLogs, nil - } - if len(backendLogs) == 0 { - sortLogs(cacheLogs) - return cacheLogs, nil - } - - // Build set of backend log keys to deduplicate - type logKey struct { - blockNum uint64 - txIndex uint - logIndex uint - } - seen := make(map[logKey]struct{}, len(backendLogs)) - for _, lg := range backendLogs { - seen[logKey{lg.BlockNumber, lg.TxIndex, lg.Index}] = struct{}{} - } - - // Add cache logs that aren't already in backend results - result := backendLogs - for _, lg := range cacheLogs { - key := logKey{lg.BlockNumber, lg.TxIndex, lg.Index} - if _, exists := seen[key]; !exists { - result = append(result, lg) - } - } - - sortLogs(result) - return result, nil -} - -func sortLogs(logs []*ethtypes.Log) { - sort.Slice(logs, func(i, j int) bool { - if logs[i].BlockNumber != logs[j].BlockNumber { - return logs[i].BlockNumber < logs[j].BlockNumber - } - if logs[i].TxIndex != logs[j].TxIndex { - return logs[i].TxIndex < logs[j].TxIndex - } - return logs[i].Index < logs[j].Index - }) + return s.backend.FilterLogs(ctx, fromBlock, toBlock, crit) } func (s *cachedReceiptStore) Close() error { @@ -155,24 +86,18 @@ func (s *cachedReceiptStore) cacheReceipts(receipts []ReceiptRecord) { defer s.cacheMu.Unlock() var ( - currentBlock uint64 - hasBlock bool - logStartIndex uint - cacheLogs []*ethtypes.Log + currentBlock uint64 + hasBlock bool ) cacheEntries := make([]receiptCacheEntry, 0, len(receipts)) fillCache := func(blockNumber uint64) { - if len(cacheEntries) == 0 && len(cacheLogs) == 0 { + if len(cacheEntries) == 0 { return } s.maybeRotateCacheLocked(blockNumber) s.cache.AddReceiptsBatch(blockNumber, cacheEntries) - if len(cacheLogs) > 0 { - s.cache.AddLogsForBlock(blockNumber, cacheLogs) - } cacheEntries = cacheEntries[:0] - cacheLogs = cacheLogs[:0] } for _, record := range receipts { @@ -189,17 +114,12 @@ func (s *cachedReceiptStore) cacheReceipts(receipts []ReceiptRecord) { if blockNumber != currentBlock { fillCache(currentBlock) currentBlock = blockNumber - logStartIndex = 0 } - txLogs := getLogsForTx(receipt, logStartIndex) - logStartIndex += uint(len(txLogs)) - cacheEntries = append(cacheEntries, receiptCacheEntry{ TxHash: record.TxHash, Receipt: receipt, }) - cacheLogs = append(cacheLogs, txLogs...) } if hasBlock { diff --git a/sei-db/ledger_db/receipt/cached_receipt_store_test.go b/sei-db/ledger_db/receipt/cached_receipt_store_test.go index 078c1b3af3..d8b66ca947 100644 --- a/sei-db/ledger_db/receipt/cached_receipt_store_test.go +++ b/sei-db/ledger_db/receipt/cached_receipt_store_test.go @@ -13,7 +13,6 @@ import ( type fakeReceiptBackend struct { receipts map[common.Hash]*types.Receipt - logs []*ethtypes.Log getReceiptCalls int filterLogCalls int } @@ -60,7 +59,7 @@ func (f *fakeReceiptBackend) SetReceipts(_ sdk.Context, receipts []ReceiptRecord func (f *fakeReceiptBackend) FilterLogs(_ sdk.Context, _, _ uint64, _ filters.FilterCriteria) ([]*ethtypes.Log, error) { f.filterLogCalls++ - return append([]*ethtypes.Log(nil), f.logs...), nil + return []*ethtypes.Log{}, nil } func (f *fakeReceiptBackend) Close() error { @@ -99,47 +98,12 @@ func TestCachedReceiptStoreFilterLogsDelegates(t *testing.T) { require.NoError(t, store.SetReceipts(ctx, []ReceiptRecord{{TxHash: txHash, Receipt: receipt}})) backend.filterLogCalls = 0 - // FilterLogs checks both backend and cache + // FilterLogs now delegates to the backend for range queries logs, err := store.FilterLogs(ctx, 9, 9, filters.FilterCriteria{ Addresses: []common.Address{addr}, Topics: [][]common.Hash{{topic}}, }) require.NoError(t, err) - require.Len(t, logs, 1) // cache has the log (backend returns empty) - require.Equal(t, 1, backend.filterLogCalls) // still delegates to backend -} - -func TestCachedReceiptStoreFilterLogsReturnsSortedLogs(t *testing.T) { - ctx, _ := newTestContext() - backend := newFakeReceiptBackend() - backend.logs = []*ethtypes.Log{ - { - BlockNumber: 12, - TxIndex: 1, - Index: 2, - }, - { - BlockNumber: 10, - TxIndex: 0, - Index: 0, - }, - } - store := newCachedReceiptStore(backend) - - receiptA := makeTestReceipt(common.HexToHash("0xa"), 11, 1, common.HexToAddress("0x210"), []common.Hash{common.HexToHash("0x1")}) - receiptB := makeTestReceipt(common.HexToHash("0xb"), 11, 0, common.HexToAddress("0x220"), []common.Hash{common.HexToHash("0x2")}) - require.NoError(t, store.SetReceipts(ctx, []ReceiptRecord{ - {TxHash: common.HexToHash("0xa"), Receipt: receiptA}, - {TxHash: common.HexToHash("0xb"), Receipt: receiptB}, - })) - - logs, err := store.FilterLogs(ctx, 10, 12, filters.FilterCriteria{}) - require.NoError(t, err) - require.Len(t, logs, 4) - require.Equal(t, uint64(10), logs[0].BlockNumber) - require.Equal(t, uint64(11), logs[1].BlockNumber) - require.Equal(t, uint(0), logs[1].TxIndex) - require.Equal(t, uint64(11), logs[2].BlockNumber) - require.Equal(t, uint(1), logs[2].TxIndex) - require.Equal(t, uint64(12), logs[3].BlockNumber) + require.Len(t, logs, 0) // fake backend returns empty + require.Equal(t, 1, backend.filterLogCalls) } diff --git a/sei-db/ledger_db/receipt/parquet_store.go b/sei-db/ledger_db/receipt/parquet_store.go deleted file mode 100644 index fca90e0ad7..0000000000 --- a/sei-db/ledger_db/receipt/parquet_store.go +++ /dev/null @@ -1,420 +0,0 @@ -package receipt - -import ( - "fmt" - "strings" - - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/ethereum/go-ethereum/common" - ethtypes "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/eth/filters" - dbLogger "github.com/sei-protocol/sei-chain/sei-db/common/logger" - dbconfig "github.com/sei-protocol/sei-chain/sei-db/config" - "github.com/sei-protocol/sei-chain/sei-db/ledger_db/parquet" - "github.com/sei-protocol/sei-chain/x/evm/types" -) - -// parquetReceiptStore wraps the parquet.Store and implements ReceiptStore. -type parquetReceiptStore struct { - store *parquet.Store - storeKey sdk.StoreKey -} - -func newParquetReceiptStore(log dbLogger.Logger, cfg dbconfig.ReceiptStoreConfig, storeKey sdk.StoreKey) (ReceiptStore, error) { - storeCfg := parquet.StoreConfig{ - DBDirectory: cfg.DBDirectory, - KeepRecent: int64(cfg.KeepRecent), - PruneIntervalSeconds: int64(cfg.PruneIntervalSeconds), - } - - store, err := parquet.NewStore(log, storeCfg) - if err != nil { - return nil, err - } - - wrapper := &parquetReceiptStore{ - store: store, - storeKey: storeKey, - } - - if err := wrapper.replayWAL(); err != nil { - return nil, err - } - - return wrapper, nil -} - -func (s *parquetReceiptStore) LatestVersion() int64 { - return s.store.LatestVersion() -} - -func (s *parquetReceiptStore) SetLatestVersion(version int64) error { - s.store.SetLatestVersion(version) - return nil -} - -func (s *parquetReceiptStore) SetEarliestVersion(version int64) error { - s.store.SetEarliestVersion(version) - return nil -} - -func (s *parquetReceiptStore) cacheRotateInterval() uint64 { - return s.store.CacheRotateInterval() -} - -func (s *parquetReceiptStore) warmupReceipts() []ReceiptRecord { - records := make([]ReceiptRecord, 0, len(s.store.WarmupRecords)) - for _, rec := range s.store.WarmupRecords { - receipt := &types.Receipt{} - if err := receipt.Unmarshal(rec.ReceiptBytes); err != nil { - continue - } - records = append(records, ReceiptRecord{ - TxHash: common.BytesToHash(rec.TxHash), - Receipt: receipt, - }) - } - s.store.WarmupRecords = nil - return records -} - -func (s *parquetReceiptStore) GetReceipt(ctx sdk.Context, txHash common.Hash) (*types.Receipt, error) { - result, err := s.store.GetReceiptByTxHash(ctx.Context(), txHash) - if err != nil { - return nil, err - } - if result != nil { - receipt := &types.Receipt{} - if err := receipt.Unmarshal(result.ReceiptBytes); err != nil { - return nil, err - } - return receipt, nil - } - - store := ctx.KVStore(s.storeKey) - bz := store.Get(types.ReceiptKey(txHash)) - if bz == nil { - return nil, ErrNotFound - } - var r types.Receipt - if err := r.Unmarshal(bz); err != nil { - return nil, err - } - return &r, nil -} - -func (s *parquetReceiptStore) GetReceiptFromStore(ctx sdk.Context, txHash common.Hash) (*types.Receipt, error) { - result, err := s.store.GetReceiptByTxHash(ctx.Context(), txHash) - if err != nil { - return nil, err - } - if result == nil { - return nil, ErrNotFound - } - - receipt := &types.Receipt{} - if err := receipt.Unmarshal(result.ReceiptBytes); err != nil { - return nil, err - } - return receipt, nil -} - -func (s *parquetReceiptStore) SetReceipts(ctx sdk.Context, receipts []ReceiptRecord) error { - if len(receipts) == 0 { - if ctx.BlockHeight() > s.store.LatestVersion() { - s.store.SetLatestVersion(ctx.BlockHeight()) - } - return nil - } - - blockHash := common.Hash{} - - inputs := make([]parquet.ReceiptInput, 0, len(receipts)) - - var ( - currentBlock uint64 - logStartIndex uint - maxBlock uint64 - ) - - for _, record := range receipts { - if record.Receipt == nil { - continue - } - - receipt := record.Receipt - blockNumber := receipt.BlockNumber - if blockNumber > maxBlock { - maxBlock = blockNumber - } - - if currentBlock == 0 { - currentBlock = blockNumber - } - if blockNumber != currentBlock { - currentBlock = blockNumber - logStartIndex = 0 - } - - receiptBytes := record.ReceiptBytes - if len(receiptBytes) == 0 { - var err error - receiptBytes, err = receipt.Marshal() - if err != nil { - return err - } - } - - txLogs := getLogsForTx(receipt, logStartIndex) - logStartIndex += uint(len(txLogs)) - for _, lg := range txLogs { - lg.BlockHash = blockHash - } - - inputs = append(inputs, parquet.ReceiptInput{ - BlockNumber: blockNumber, - Receipt: parquet.ReceiptRecord{ - TxHash: parquet.CopyBytes(record.TxHash[:]), - BlockNumber: blockNumber, - ReceiptBytes: parquet.CopyBytesOrEmpty(receiptBytes), - }, - Logs: buildParquetLogRecords(txLogs, blockHash), - ReceiptBytes: parquet.CopyBytesOrEmpty(receiptBytes), - }) - } - - if err := s.store.WriteReceipts(inputs); err != nil { - return err - } - - if maxBlock > 0 { - s.store.UpdateLatestVersion(int64(maxBlock)) //nolint:gosec // block numbers won't exceed int64 max - } - - return nil -} - -func (s *parquetReceiptStore) FilterLogs(ctx sdk.Context, fromBlock, toBlock uint64, crit filters.FilterCriteria) ([]*ethtypes.Log, error) { - if fromBlock > toBlock { - return nil, fmt.Errorf("fromBlock (%d) > toBlock (%d)", fromBlock, toBlock) - } - - filter := parquet.LogFilter{ - FromBlock: &fromBlock, - ToBlock: &toBlock, - Addresses: crit.Addresses, - Topics: crit.Topics, - } - - results, err := s.store.GetLogs(ctx.Context(), filter) - if err != nil { - return nil, err - } - - logs := make([]*ethtypes.Log, 0, len(results)) - for i := range results { - lr := results[i] - logEntry := ðtypes.Log{ - BlockNumber: lr.BlockNumber, - TxHash: common.BytesToHash(lr.TxHash), - TxIndex: uint(lr.TxIndex), - Index: uint(lr.LogIndex), - Data: lr.Data, - Removed: lr.Removed, - BlockHash: common.BytesToHash(lr.BlockHash), - } - copy(logEntry.Address[:], lr.Address) - logEntry.Topics = buildTopicsFromParquetLogResult(lr) - logs = append(logs, logEntry) - } - - return logs, nil -} - -func (s *parquetReceiptStore) Close() error { - return s.store.Close() -} - -func (s *parquetReceiptStore) replayWAL() error { - wal := s.store.WAL() - if wal == nil { - return nil - } - - firstOffset, errFirst := wal.FirstOffset() - if errFirst != nil || firstOffset <= 0 { - return nil - } - lastOffset, errLast := wal.LastOffset() - if errLast != nil || lastOffset <= 0 { - return nil - } - - var ( - currentBlock uint64 - logStartIndex uint - maxBlock uint64 - dropOffset uint64 - ) - - blockHash := common.Hash{} - fileStartBlock := s.store.FileStartBlock() - - err := wal.Replay(firstOffset, lastOffset, func(offset uint64, entry parquet.WALEntry) error { - if len(entry.Receipts) == 0 { - return nil - } - - blockNumber := entry.BlockNumber - if blockNumber < fileStartBlock { - dropOffset = offset - return nil - } - - if currentBlock == 0 { - currentBlock = blockNumber - } - if blockNumber != currentBlock { - currentBlock = blockNumber - logStartIndex = 0 - } - - for _, receiptBytes := range entry.Receipts { - if len(receiptBytes) == 0 { - continue - } - - receipt := &types.Receipt{} - if err := receipt.Unmarshal(receiptBytes); err != nil { - return err - } - - txHash := common.HexToHash(receipt.TxHashHex) - s.store.WarmupRecords = append(s.store.WarmupRecords, parquet.ReceiptRecord{ - TxHash: parquet.CopyBytes(txHash[:]), - BlockNumber: blockNumber, - ReceiptBytes: parquet.CopyBytesOrEmpty(receiptBytes), - }) - - txLogs := getLogsForTx(receipt, logStartIndex) - logStartIndex += uint(len(txLogs)) - for _, lg := range txLogs { - lg.BlockHash = blockHash - } - - input := parquet.ReceiptInput{ - BlockNumber: blockNumber, - Receipt: parquet.ReceiptRecord{ - TxHash: parquet.CopyBytes(txHash[:]), - BlockNumber: blockNumber, - ReceiptBytes: parquet.CopyBytesOrEmpty(receiptBytes), - }, - Logs: buildParquetLogRecords(txLogs, blockHash), - } - - if err := s.store.ApplyReceiptFromReplay(input); err != nil { - return err - } - - if blockNumber > maxBlock { - maxBlock = blockNumber - } - } - - return nil - }) - if err != nil { - return err - } - - if maxBlock > 0 { - s.store.UpdateLatestVersion(int64(maxBlock)) //nolint:gosec // block numbers won't exceed int64 max - } - if err := truncateReplayWAL(wal, dropOffset); err != nil { - return err - } - return nil -} - -func truncateReplayWAL(w interface{ TruncateBefore(offset uint64) error }, dropOffset uint64) error { - if dropOffset == 0 { - return nil - } - if err := w.TruncateBefore(dropOffset + 1); err != nil { - if strings.Contains(err.Error(), "out of range") { - return nil - } - return fmt.Errorf("failed to truncate replay WAL before offset %d: %w", dropOffset+1, err) - } - return nil -} - -func buildParquetLogRecords(logs []*ethtypes.Log, blockHash common.Hash) []parquet.LogRecord { - if len(logs) == 0 { - return nil - } - - records := make([]parquet.LogRecord, 0, len(logs)) - for _, lg := range logs { - topic0, topic1, topic2, topic3 := extractLogTopics(lg.Topics) - rec := parquet.LogRecord{ - BlockNumber: lg.BlockNumber, - TxHash: lg.TxHash[:], - TxIndex: parquet.Uint32FromUint(lg.TxIndex), - LogIndex: parquet.Uint32FromUint(lg.Index), - Address: lg.Address[:], - BlockHash: blockHash[:], - Removed: lg.Removed, - Topic0: topic0, - Topic1: topic1, - Topic2: topic2, - Topic3: topic3, - Data: lg.Data, - } - records = append(records, rec) - } - - return records -} - -func buildTopicsFromParquetLogResult(lr parquet.LogResult) []common.Hash { - var topicList []common.Hash - if len(lr.Topic0) > 0 { - topicList = append(topicList, common.BytesToHash(lr.Topic0)) - } - if len(lr.Topic1) > 0 { - topicList = append(topicList, common.BytesToHash(lr.Topic1)) - } - if len(lr.Topic2) > 0 { - topicList = append(topicList, common.BytesToHash(lr.Topic2)) - } - if len(lr.Topic3) > 0 { - topicList = append(topicList, common.BytesToHash(lr.Topic3)) - } - return topicList -} - -func extractLogTopics(topics []common.Hash) ([]byte, []byte, []byte, []byte) { - t0 := make([]byte, 0) - t1 := make([]byte, 0) - t2 := make([]byte, 0) - t3 := make([]byte, 0) - - if len(topics) > 0 { - t0 = make([]byte, common.HashLength) - copy(t0, topics[0][:]) - } - if len(topics) > 1 { - t1 = make([]byte, common.HashLength) - copy(t1, topics[1][:]) - } - if len(topics) > 2 { - t2 = make([]byte, common.HashLength) - copy(t2, topics[2][:]) - } - if len(topics) > 3 { - t3 = make([]byte, common.HashLength) - copy(t3, topics[3][:]) - } - return t0, t1, t2, t3 -} diff --git a/sei-db/ledger_db/receipt/parquet_store_test.go b/sei-db/ledger_db/receipt/parquet_store_test.go deleted file mode 100644 index e101c3998e..0000000000 --- a/sei-db/ledger_db/receipt/parquet_store_test.go +++ /dev/null @@ -1,349 +0,0 @@ -package receipt - -import ( - "errors" - "os" - "path/filepath" - "testing" - - "github.com/ethereum/go-ethereum/common" - ethtypes "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/eth/filters" - pqgo "github.com/parquet-go/parquet-go" - dbLogger "github.com/sei-protocol/sei-chain/sei-db/common/logger" - dbconfig "github.com/sei-protocol/sei-chain/sei-db/config" - "github.com/sei-protocol/sei-chain/sei-db/ledger_db/parquet" - "github.com/sei-protocol/sei-chain/x/evm/types" - "github.com/stretchr/testify/require" -) - -type truncateOnlyWAL struct { - truncateErr error -} - -func (w *truncateOnlyWAL) TruncateBefore(_ uint64) error { return w.truncateErr } - -func TestLedgerCacheReceiptsAndLogs(t *testing.T) { - cache := newLedgerCache() - txHash := common.HexToHash("0x1") - blockNumber := uint64(10) - - cache.AddReceiptsBatch(blockNumber, []receiptCacheEntry{ - { - TxHash: txHash, - Receipt: &types.Receipt{TxHashHex: txHash.Hex(), BlockNumber: blockNumber}, - }, - }) - - got, ok := cache.GetReceipt(txHash) - require.True(t, ok) - require.Equal(t, txHash.Hex(), got.TxHashHex) - - addr := common.HexToAddress("0x100") - topic := common.HexToHash("0xabc") - cache.AddLogsForBlock(blockNumber, []*ethtypes.Log{ - { - Address: addr, - Topics: []common.Hash{topic}, - BlockNumber: blockNumber, - TxHash: txHash, - TxIndex: 0, - Index: 0, - }, - }) - - require.Len(t, cache.FilterLogs(blockNumber, blockNumber, filters.FilterCriteria{}), 1) - require.Len(t, cache.FilterLogs(blockNumber+1, blockNumber+1, filters.FilterCriteria{}), 0) -} - -func TestLedgerCacheRotatePrunes(t *testing.T) { - cache := newLedgerCache() - txHash := common.HexToHash("0x2") - blockNumber := uint64(1) - cache.AddReceiptsBatch(blockNumber, []receiptCacheEntry{ - { - TxHash: txHash, - Receipt: &types.Receipt{TxHashHex: txHash.Hex(), BlockNumber: blockNumber}, - }, - }) - - _, ok := cache.GetReceipt(txHash) - require.True(t, ok) - - cache.Rotate() - cache.Rotate() - - _, ok = cache.GetReceipt(txHash) - require.False(t, ok) -} - -func TestParquetReceiptStoreCacheLogs(t *testing.T) { - ctx, storeKey := newTestContext() - cfg := dbconfig.DefaultReceiptStoreConfig() - cfg.Backend = "parquet" - cfg.DBDirectory = t.TempDir() - - store, err := NewReceiptStore(dbLogger.NewNopLogger(), cfg, storeKey) - require.NoError(t, err) - t.Cleanup(func() { _ = store.Close() }) - - txHash := common.HexToHash("0x10") - addr := common.HexToAddress("0x200") - topic := common.HexToHash("0x1234") - receipt := makeTestReceipt(txHash, 10, 2, addr, []common.Hash{topic}) - - require.NoError(t, store.SetReceipts(ctx, []ReceiptRecord{ - {TxHash: txHash, Receipt: receipt}, - })) - - logs, err := store.FilterLogs(ctx, 10, 10, filters.FilterCriteria{ - Addresses: []common.Address{addr}, - Topics: [][]common.Hash{{topic}}, - }) - require.NoError(t, err) - require.Len(t, logs, 1) - require.Equal(t, uint64(10), logs[0].BlockNumber) - require.Equal(t, uint(2), logs[0].TxIndex) -} - -func TestParquetReceiptStoreReopenQueries(t *testing.T) { - ctx, storeKey := newTestContext() - cfg := dbconfig.DefaultReceiptStoreConfig() - cfg.Backend = "parquet" - cfg.DBDirectory = t.TempDir() - - store, err := NewReceiptStore(dbLogger.NewNopLogger(), cfg, storeKey) - require.NoError(t, err) - - txHash := common.HexToHash("0x20") - addr := common.HexToAddress("0x300") - topic := common.HexToHash("0x5678") - receipt := makeTestReceipt(txHash, 5, 1, addr, []common.Hash{topic}) - - require.NoError(t, store.SetReceipts(ctx, []ReceiptRecord{ - {TxHash: txHash, Receipt: receipt}, - })) - require.NoError(t, store.Close()) - - store, err = NewReceiptStore(dbLogger.NewNopLogger(), cfg, storeKey) - require.NoError(t, err) - t.Cleanup(func() { _ = store.Close() }) - - got, err := store.GetReceiptFromStore(ctx, txHash) - require.NoError(t, err) - require.Equal(t, receipt.TxHashHex, got.TxHashHex) - - // Query blocks 3-5, receipt is in block 5 - logs, err := store.FilterLogs(ctx, 3, 5, filters.FilterCriteria{ - Addresses: []common.Address{addr}, - Topics: [][]common.Hash{{topic}}, - }) - require.NoError(t, err) - require.Len(t, logs, 1) - require.Equal(t, uint64(5), logs[0].BlockNumber) -} - -func TestParquetReceiptStoreWALReplay(t *testing.T) { - ctx, storeKey := newTestContext() - cfg := dbconfig.DefaultReceiptStoreConfig() - cfg.Backend = "parquet" - cfg.DBDirectory = t.TempDir() - - store, err := NewReceiptStore(dbLogger.NewNopLogger(), cfg, storeKey) - require.NoError(t, err) - - txHash := common.HexToHash("0x30") - addr := common.HexToAddress("0x400") - topic := common.HexToHash("0x9abc") - receipt := makeTestReceipt(txHash, 3, 0, addr, []common.Hash{topic}) - - require.NoError(t, store.SetReceipts(ctx, []ReceiptRecord{ - {TxHash: txHash, Receipt: receipt}, - })) - require.NoError(t, store.Close()) - - receiptFiles, err := filepath.Glob(filepath.Join(cfg.DBDirectory, "receipts_*.parquet")) - require.NoError(t, err) - for _, file := range receiptFiles { - require.NoError(t, os.Remove(file)) - } - - logFiles, err := filepath.Glob(filepath.Join(cfg.DBDirectory, "logs_*.parquet")) - require.NoError(t, err) - for _, file := range logFiles { - require.NoError(t, os.Remove(file)) - } - - store, err = NewReceiptStore(dbLogger.NewNopLogger(), cfg, storeKey) - require.NoError(t, err) - t.Cleanup(func() { _ = store.Close() }) - - got, err := store.GetReceiptFromStore(ctx, txHash) - require.NoError(t, err) - require.Equal(t, receipt.TxHashHex, got.TxHashHex) -} - -func TestParquetFilePruning(t *testing.T) { - ctx, storeKey := newTestContext() - cfg := dbconfig.DefaultReceiptStoreConfig() - cfg.Backend = "parquet" - cfg.DBDirectory = t.TempDir() - cfg.KeepRecent = 600 // Keep 600 blocks, so files with blocks < (latest - 600) get pruned - - store, err := NewReceiptStore(dbLogger.NewNopLogger(), cfg, storeKey) - require.NoError(t, err) - - // Write receipts across multiple files (500 blocks per file) - // File 0: blocks 1-500 - // File 1: blocks 501-1000 - // File 2: blocks 1001-1500 - for block := uint64(1); block <= 1500; block++ { - txHash := common.BigToHash(common.Big1.SetUint64(block)) - receipt := makeTestReceipt(txHash, block, 0, common.HexToAddress("0x1"), nil) - err := store.SetReceipts(ctx.WithBlockHeight(int64(block)), []ReceiptRecord{ - {TxHash: txHash, Receipt: receipt}, - }) - require.NoError(t, err) - } - - // Close to flush all files - require.NoError(t, store.Close()) - - // Verify we have at least 2 receipt and log files - receiptFiles, err := filepath.Glob(filepath.Join(cfg.DBDirectory, "receipts_*.parquet")) - require.NoError(t, err) - require.GreaterOrEqual(t, len(receiptFiles), 2, "should have at least 2 receipt files") - - logFiles, err := filepath.Glob(filepath.Join(cfg.DBDirectory, "logs_*.parquet")) - require.NoError(t, err) - require.GreaterOrEqual(t, len(logFiles), 2, "should have at least 2 log files") - - // Reopen store - pruning will run in background - store, err = NewReceiptStore(dbLogger.NewNopLogger(), cfg, storeKey) - require.NoError(t, err) - t.Cleanup(func() { _ = store.Close() }) - - // Verify we can still query recent data - txHash := common.BigToHash(common.Big1.SetUint64(1400)) - _, err = store.GetReceiptFromStore(ctx, txHash) - require.NoError(t, err) -} - -func TestParquetReaderGetFilesBeforeBlock(t *testing.T) { - dir := t.TempDir() - - // Create mock parquet files - createMockParquetFile(t, dir, "receipts_0.parquet") - createMockParquetFile(t, dir, "receipts_500.parquet") - createMockParquetFile(t, dir, "receipts_1000.parquet") - createMockParquetFile(t, dir, "logs_0.parquet") - createMockParquetFile(t, dir, "logs_500.parquet") - createMockParquetFile(t, dir, "logs_1000.parquet") - - reader, err := parquet.NewReader(dir) - require.NoError(t, err) - defer reader.Close() - - // Test: prune before block 600 - // File 0 (blocks 0-499) should be pruned (0 + 500 <= 600) - // File 500 (blocks 500-999) should NOT be pruned (500 + 500 > 600) - files := reader.GetFilesBeforeBlock(600) - require.Len(t, files, 1) - require.Contains(t, files[0].ReceiptFile, "receipts_0.parquet") - - // Test: prune before block 1100 - // Files 0 and 500 should be pruned - files = reader.GetFilesBeforeBlock(1100) - require.Len(t, files, 2) - - // Test: prune before block 400 - // No files should be pruned (0 + 500 > 400) - files = reader.GetFilesBeforeBlock(400) - require.Len(t, files, 0) -} - -func TestParquetPruneOldFiles(t *testing.T) { - ctx, storeKey := newTestContext() - cfg := dbconfig.DefaultReceiptStoreConfig() - cfg.Backend = "parquet" - cfg.DBDirectory = t.TempDir() - cfg.KeepRecent = 0 // Disable auto-pruning - - store, err := NewReceiptStore(dbLogger.NewNopLogger(), cfg, storeKey) - require.NoError(t, err) - - // Write enough data to create multiple files - for block := uint64(1); block <= 1200; block++ { - txHash := common.BigToHash(common.Big1.SetUint64(block)) - receipt := makeTestReceipt(txHash, block, 0, common.HexToAddress("0x1"), nil) - err := store.SetReceipts(ctx.WithBlockHeight(int64(block)), []ReceiptRecord{ - {TxHash: txHash, Receipt: receipt}, - }) - require.NoError(t, err) - } - require.NoError(t, store.Close()) - - // Count files before pruning - receiptFilesBefore, _ := filepath.Glob(filepath.Join(cfg.DBDirectory, "receipts_*.parquet")) - require.GreaterOrEqual(t, len(receiptFilesBefore), 2, "should have at least 2 receipt files") - - // Reopen store - store, err = NewReceiptStore(dbLogger.NewNopLogger(), cfg, storeKey) - require.NoError(t, err) - t.Cleanup(func() { _ = store.Close() }) - - // Verify we can still query data - txHash := common.BigToHash(common.Big1.SetUint64(1000)) - _, err = store.GetReceiptFromStore(ctx, txHash) - require.NoError(t, err) -} - -func TestExtractBlockNumber(t *testing.T) { - tests := []struct { - path string - expected uint64 - }{ - {"receipts_0.parquet", 0}, - {"receipts_500.parquet", 500}, - {"receipts_1000.parquet", 1000}, - {"/path/to/receipts_12345.parquet", 12345}, - {"logs_0.parquet", 0}, - {"logs_999.parquet", 999}, - {"invalid.parquet", 0}, - {"receipts_.parquet", 0}, - } - - for _, tt := range tests { - t.Run(tt.path, func(t *testing.T) { - result := parquet.ExtractBlockNumber(tt.path) - require.Equal(t, tt.expected, result) - }) - } -} - -func TestTruncateReplayWALReturnsError(t *testing.T) { - wal := &truncateOnlyWAL{truncateErr: errors.New("truncate failed")} - err := truncateReplayWAL(wal, 10) - require.Error(t, err) - require.ErrorContains(t, err, "failed to truncate replay WAL") -} - -// createMockParquetFile creates a minimal valid parquet file for testing -func createMockParquetFile(t *testing.T, dir, name string) { - t.Helper() - path := filepath.Join(dir, name) - - // Create a valid parquet file with minimal data that DuckDB can read - f, err := os.Create(path) - require.NoError(t, err) - - // Use parquet-go to write a minimal valid file - type minimalRecord struct { - BlockNumber uint64 `parquet:"block_number"` - } - writer := pqgo.NewGenericWriter[minimalRecord](f) - _, err = writer.Write([]minimalRecord{{BlockNumber: 0}}) - require.NoError(t, err) - require.NoError(t, writer.Close()) - require.NoError(t, f.Close()) -} diff --git a/sei-db/ledger_db/receipt/receipt_cache.go b/sei-db/ledger_db/receipt/receipt_cache.go index 0c94ca564d..c6f2eb363b 100644 --- a/sei-db/ledger_db/receipt/receipt_cache.go +++ b/sei-db/ledger_db/receipt/receipt_cache.go @@ -5,8 +5,6 @@ import ( "sync/atomic" "github.com/ethereum/go-ethereum/common" - ethtypes "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/eth/filters" "github.com/sei-protocol/sei-chain/x/evm/types" ) @@ -18,22 +16,14 @@ type receiptCacheEntry struct { Receipt *types.Receipt } -type logChunk struct { - logs map[uint64][]*ethtypes.Log // blockNum -> logs -} - type receiptChunk struct { receipts map[uint64]map[common.Hash]*types.Receipt // blockNum -> (txHash -> receipt) receiptIndex map[common.Hash]uint64 // txHash -> blockNum } -// ledgerCache stores recent receipts and logs in rotating chunks. +// ledgerCache stores recent receipts in rotating chunks. // It keeps two most-recent chunks and prunes the oldest on rotation. type ledgerCache struct { - logChunks [numCacheChunks]atomic.Pointer[logChunk] - logWriteSlot atomic.Int32 - logMu sync.RWMutex - receiptChunks [numCacheChunks]atomic.Pointer[receiptChunk] receiptWriteSlot atomic.Int32 receiptMu sync.RWMutex @@ -42,12 +32,6 @@ type ledgerCache struct { func newLedgerCache() *ledgerCache { c := &ledgerCache{} - firstLogChunk := &logChunk{ - logs: make(map[uint64][]*ethtypes.Log), - } - c.logChunks[0].Store(firstLogChunk) - c.logWriteSlot.Store(0) - firstReceiptChunk := &receiptChunk{ receipts: make(map[uint64]map[common.Hash]*types.Receipt), receiptIndex: make(map[common.Hash]uint64), @@ -59,20 +43,6 @@ func newLedgerCache() *ledgerCache { } func (c *ledgerCache) Rotate() { - // Rotate logs - c.logMu.Lock() - oldLogSlot := c.logWriteSlot.Load() - newLogSlot := (oldLogSlot + 1) % numCacheChunks - pruneLogSlot := (newLogSlot + 1) % numCacheChunks - - newLogChunk := &logChunk{ - logs: make(map[uint64][]*ethtypes.Log), - } - c.logChunks[newLogSlot].Store(newLogChunk) - c.logWriteSlot.Store(newLogSlot) - c.logChunks[pruneLogSlot].Store(nil) - c.logMu.Unlock() - // Rotate receipts c.receiptMu.Lock() oldReceiptSlot := c.receiptWriteSlot.Load() @@ -110,43 +80,12 @@ func (c *ledgerCache) GetReceipt(txHash common.Hash) (*types.Receipt, bool) { } receipt, found := blockReceipts[txHash] if found { - // Callers (e.g. RPC response formatting) may normalize TransactionIndex in-place. - // Clone to avoid mutating the cached receipt and corrupting future lookups. - return cloneReceipt(receipt), true + return receipt, true } } return nil, false } -// cloneReceipt makes a deep copy to keep cached receipts immutable to callers. -func cloneReceipt(r *types.Receipt) *types.Receipt { - if r == nil { - return nil - } - c := *r - if r.Logs != nil { - logs := make([]*types.Log, len(r.Logs)) - for i, lg := range r.Logs { - if lg == nil { - continue - } - logCopy := *lg - if lg.Topics != nil { - logCopy.Topics = append([]string(nil), lg.Topics...) - } - if lg.Data != nil { - logCopy.Data = append([]byte(nil), lg.Data...) - } - logs[i] = &logCopy - } - c.Logs = logs - } - if r.LogsBloom != nil { - c.LogsBloom = append([]byte(nil), r.LogsBloom...) - } - return &c -} - func (c *ledgerCache) AddReceiptsBatch(blockNumber uint64, receipts []receiptCacheEntry) { if len(receipts) == 0 { return @@ -174,93 +113,3 @@ func (c *ledgerCache) AddReceiptsBatch(blockNumber uint64, receipts []receiptCac chunk.receiptIndex[receipts[i].TxHash] = blockNumber } } - -func (c *ledgerCache) AddLogsForBlock(blockNumber uint64, logs []*ethtypes.Log) { - if len(logs) == 0 { - return - } - - logsCopy := make([]*ethtypes.Log, len(logs)) - for i, lg := range logs { - logCopy := *lg - logsCopy[i] = &logCopy - } - - c.logMu.Lock() - defer c.logMu.Unlock() - - slot := c.logWriteSlot.Load() - chunk := c.logChunks[slot].Load() - if chunk == nil { - chunk = &logChunk{ - logs: make(map[uint64][]*ethtypes.Log), - } - c.logChunks[slot].Store(chunk) - } - chunk.logs[blockNumber] = logsCopy -} - -// FilterLogs returns cached logs matching the filter criteria. -func (c *ledgerCache) FilterLogs(fromBlock, toBlock uint64, crit filters.FilterCriteria) []*ethtypes.Log { - c.logMu.RLock() - defer c.logMu.RUnlock() - - var result []*ethtypes.Log - for i := 0; i < numCacheChunks; i++ { - chunk := c.logChunks[i].Load() - if chunk == nil { - continue - } - for blockNum, logs := range chunk.logs { - if blockNum < fromBlock || blockNum > toBlock { - continue - } - for _, lg := range logs { - if matchLog(lg, crit) { - logCopy := *lg - result = append(result, &logCopy) - } - } - } - } - return result -} - -// matchLog checks if a log matches the filter criteria. -func matchLog(lg *ethtypes.Log, crit filters.FilterCriteria) bool { - // Check address filter - if len(crit.Addresses) > 0 { - found := false - for _, addr := range crit.Addresses { - if lg.Address == addr { - found = true - break - } - } - if !found { - return false - } - } - - // Check topic filters - for i, topicList := range crit.Topics { - if len(topicList) == 0 { - continue - } - if i >= len(lg.Topics) { - return false - } - found := false - for _, topic := range topicList { - if lg.Topics[i] == topic { - found = true - break - } - } - if !found { - return false - } - } - - return true -} diff --git a/sei-db/ledger_db/receipt/receipt_store.go b/sei-db/ledger_db/receipt/receipt_store.go index c7c8d5ad65..bb87279d55 100644 --- a/sei-db/ledger_db/receipt/receipt_store.go +++ b/sei-db/ledger_db/receipt/receipt_store.go @@ -45,9 +45,8 @@ type ReceiptStore interface { } type ReceiptRecord struct { - TxHash common.Hash - Receipt *types.Receipt - ReceiptBytes []byte // Optional pre-marshaled receipt (must match Receipt if set) + TxHash common.Hash + Receipt *types.Receipt } type receiptStore struct { @@ -57,17 +56,12 @@ type receiptStore struct { closeOnce sync.Once } -const ( - receiptBackendPebble = "pebble" - receiptBackendParquet = "parquet" -) +const receiptBackendPebble = "pebble" func normalizeReceiptBackend(backend string) string { switch strings.ToLower(strings.TrimSpace(backend)) { case "", "pebbledb", receiptBackendPebble: return receiptBackendPebble - case receiptBackendParquet: - return receiptBackendParquet default: return strings.ToLower(strings.TrimSpace(backend)) } @@ -91,8 +85,6 @@ func newReceiptBackend(log dbLogger.Logger, config dbconfig.ReceiptStoreConfig, backend := normalizeReceiptBackend(config.Backend) switch backend { - case receiptBackendParquet: - return newParquetReceiptStore(log, config, storeKey) case receiptBackendPebble: ssConfig := dbconfig.DefaultStateStoreConfig() ssConfig.DBDirectory = config.DBDirectory @@ -188,13 +180,9 @@ func (s *receiptStore) SetReceipts(ctx sdk.Context, receipts []ReceiptRecord) er if record.Receipt == nil { continue } - marshalledReceipt := record.ReceiptBytes - if len(marshalledReceipt) == 0 { - var err error - marshalledReceipt, err = record.Receipt.Marshal() - if err != nil { - return err - } + marshalledReceipt, err := record.Receipt.Marshal() + if err != nil { + return err } kvPair := &iavl.KVPair{ Key: types.ReceiptKey(record.TxHash), diff --git a/sei-db/ledger_db/receipt/receipt_store_test.go b/sei-db/ledger_db/receipt/receipt_store_test.go index 78955567db..d544aefd43 100644 --- a/sei-db/ledger_db/receipt/receipt_store_test.go +++ b/sei-db/ledger_db/receipt/receipt_store_test.go @@ -9,6 +9,7 @@ import ( "github.com/cosmos/cosmos-sdk/testutil" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/ethereum/go-ethereum/common" + ethtypes "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/eth/filters" dbLogger "github.com/sei-protocol/sei-chain/sei-db/common/logger" dbutils "github.com/sei-protocol/sei-chain/sei-db/common/utils" @@ -56,6 +57,13 @@ func makeReceipt(txHash common.Hash, addr common.Address, topics []common.Hash, } } +func withBloom(r *types.Receipt) *types.Receipt { + logs := receipt.GetLogsForTx(r, 0) + bloom := ethtypes.CreateBloom(ðtypes.Receipt{Logs: logs}) + r.LogsBloom = bloom.Bytes() + return r +} + func TestNewReceiptStoreConfigErrors(t *testing.T) { storeKey := storetypes.NewKVStoreKey("evm") cfg := dbconfig.DefaultReceiptStoreConfig() @@ -75,12 +83,6 @@ func TestNewReceiptStoreConfigErrors(t *testing.T) { require.NoError(t, err) require.NotNil(t, store) require.NoError(t, store.Close()) - - cfg.Backend = "parquet" - store, err = receipt.NewReceiptStore(nil, cfg, storeKey) - require.NoError(t, err) - require.NotNil(t, store) - require.NoError(t, store.Close()) } func TestSetReceiptsAndGet(t *testing.T) { diff --git a/sei-db/state_db/sc/composite/store.go b/sei-db/state_db/sc/composite/store.go index 40ccbaa414..8c86066f8f 100644 --- a/sei-db/state_db/sc/composite/store.go +++ b/sei-db/state_db/sc/composite/store.go @@ -1,9 +1,13 @@ +// Package composite provides a unified commit store that coordinates +// between Cosmos (memiavl) and EVM (flatkv) committers. package composite import ( + "errors" "fmt" + "math" - "github.com/sei-protocol/sei-chain/sei-db/common/errors" + commonerrors "github.com/sei-protocol/sei-chain/sei-db/common/errors" "github.com/sei-protocol/sei-chain/sei-db/common/logger" "github.com/sei-protocol/sei-chain/sei-db/config" "github.com/sei-protocol/sei-chain/sei-db/proto" @@ -23,10 +27,10 @@ var _ types.Committer = (*CompositeCommitStore)(nil) type CompositeCommitStore struct { logger logger.Logger - // cosmosSC is the Cosmos (memiavl) backend - always initialized + // cosmosCommitter is the Cosmos (memiavl) backend - always initialized cosmosCommitter *memiavl.CommitStore - // flatkvSC is the FlatKV backend - may be nil if not enabled + // evmCommitter is the FlatKV backend - may be nil if not enabled evmCommitter flatkv.Store // homeDir is the base directory for the store @@ -36,23 +40,29 @@ type CompositeCommitStore struct { config config.StateCommitConfig } -// NewCompositeCommitStore creates a new composite commit store +// NewCompositeCommitStore creates a new composite commit store. +// Note: The store is NOT opened yet. Call LoadVersion to open and initialize the DBs. +// This matches the memiavl.NewCommitStore pattern. func NewCompositeCommitStore( homeDir string, logger logger.Logger, cfg config.StateCommitConfig, ) *CompositeCommitStore { - // Always initialize the Cosmos backend - cosmosSC := memiavl.NewCommitStore(homeDir, logger, cfg.MemIAVLConfig) + // Always initialize the Cosmos backend (creates struct only, not opened) + cosmosCommitter := memiavl.NewCommitStore(homeDir, logger, cfg.MemIAVLConfig) store := &CompositeCommitStore{ logger: logger, - cosmosCommitter: cosmosSC, + cosmosCommitter: cosmosCommitter, homeDir: homeDir, config: cfg, } - // TODO: initialize FlatKV store for evmSC when cfg.WriteMode != config.CosmosOnlyWrite + // Initialize FlatKV store struct if write mode requires it + // Note: DB is NOT opened here, will be opened in LoadVersion + if cfg.WriteMode == config.DualWrite || cfg.WriteMode == config.SplitWrite { + store.evmCommitter = flatkv.NewCommitStore(homeDir, logger, cfg.FlatKVConfig) + } return store } @@ -68,7 +78,7 @@ func (cs *CompositeCommitStore) SetInitialVersion(initialVersion int64) error { } // LoadVersion loads the specified version of the database. -// Being used for two scenario: +// Being used for two scenarios: // ReadOnly: Either for state sync or for historical proof // Writable: Opened during initialization for root multistore func (cs *CompositeCommitStore) LoadVersion(targetVersion int64, readOnly bool) (types.Committer, error) { @@ -81,14 +91,33 @@ func (cs *CompositeCommitStore) LoadVersion(targetVersion int64, readOnly bool) if !ok { return nil, fmt.Errorf("unexpected committer type from cosmos LoadVersion") } - return &CompositeCommitStore{ + + newStore := &CompositeCommitStore{ logger: cs.logger, cosmosCommitter: cosmosCommitter, homeDir: cs.homeDir, config: cs.config, - // TODO: Also load evmCommitter for readOnly if enabled - }, nil + } + + // Load evmCommitter if initialized (nil when WriteMode is CosmosOnlyWrite). + // This is the single entry point for evmCommitter.LoadVersion — CMS calls + // CompositeCommitStore.LoadVersion(), which internally loads both backends. + if cs.evmCommitter != nil { + evmStore, err := cs.evmCommitter.LoadVersion(targetVersion, readOnly) + if err != nil { + // FlatKV doesn't support read-only mode yet - fall back to Cosmos-only + if errors.Is(err, flatkv.ErrReadOnlyNotSupported) { + cs.logger.Info("FlatKV read-only not supported, using Cosmos backend only") + // Leave evmCommitter nil for this read-only instance + } else { + return nil, fmt.Errorf("failed to load FlatKV version: %w", err) + } + } else { + newStore.evmCommitter = evmStore + } + } + return newStore, nil } // ApplyChangeSets applies changesets to the appropriate backends based on config. @@ -108,8 +137,19 @@ func (cs *CompositeCommitStore) ApplyChangeSets(changesets []*proto.NamedChangeS cosmosChangeset = append(cosmosChangeset, changeset) } } - if cs.config.WriteMode == config.CosmosOnlyWrite || cs.config.WriteMode == config.DualWrite { + + // Handle write mode routing + switch cs.config.WriteMode { + case config.CosmosOnlyWrite: + // All data goes to cosmos + cosmosChangeset = changesets + evmChangeset = nil + case config.DualWrite: + // EVM data goes to both, non-EVM only to cosmos cosmosChangeset = changesets + // evmChangeset already filtered above + case config.SplitWrite: + // EVM goes to EVM store, non-EVM to cosmos (already filtered above) } // Cosmos changesets always goes to cosmos commit store @@ -119,7 +159,7 @@ func (cs *CompositeCommitStore) ApplyChangeSets(changesets []*proto.NamedChangeS } } - if cs.evmCommitter != nil { + if cs.evmCommitter != nil && len(evmChangeset) > 0 { if err := cs.evmCommitter.ApplyChangeSets(evmChangeset); err != nil { return fmt.Errorf("failed to apply EVM changesets: %w", err) } @@ -157,13 +197,10 @@ func (cs *CompositeCommitStore) Commit() (int64, error) { // Version returns the current version func (cs *CompositeCommitStore) Version() int64 { - if cs.cosmosCommitter != nil { - return cs.cosmosCommitter.Version() - } else if cs.evmCommitter != nil { - return cs.evmCommitter.Version() - } else { + if cs.cosmosCommitter == nil { return 0 } + return cs.cosmosCommitter.Version() } // GetLatestVersion returns the latest version @@ -198,10 +235,8 @@ func (cs *CompositeCommitStore) GetChildStoreByName(name string) types.CommitKVS // Rollback rolls back to the specified version func (cs *CompositeCommitStore) Rollback(targetVersion int64) error { - if cs.cosmosCommitter != nil { - if err := cs.cosmosCommitter.Rollback(targetVersion); err != nil { - return fmt.Errorf("failed to rollback cosmos commit store: %w", err) - } + if err := cs.cosmosCommitter.Rollback(targetVersion); err != nil { + return fmt.Errorf("failed to rollback cosmos commit store: %w", err) } if cs.evmCommitter != nil { @@ -215,12 +250,18 @@ func (cs *CompositeCommitStore) Rollback(targetVersion int64) error { // Exporter returns an exporter for state sync func (cs *CompositeCommitStore) Exporter(version int64) (types.Exporter, error) { + if version < 0 || version > math.MaxUint32 { + return nil, fmt.Errorf("version %d out of range", version) + } // TODO: Add evm committer for exporter return cs.cosmosCommitter.Exporter(version) } // Importer returns an importer for state sync func (cs *CompositeCommitStore) Importer(version int64) (types.Importer, error) { + if version < 0 || version > math.MaxUint32 { + return nil, fmt.Errorf("version %d out of range", version) + } // TODO: Add evm committer for Importer return cs.cosmosCommitter.Importer(version) } @@ -241,5 +282,5 @@ func (cs *CompositeCommitStore) Close() error { } } - return errors.Join(errs...) + return commonerrors.Join(errs...) } diff --git a/sei-db/state_db/sc/flatkv/api.go b/sei-db/state_db/sc/flatkv/api.go index 9c499c2e3b..7f6ed7f42e 100644 --- a/sei-db/state_db/sc/flatkv/api.go +++ b/sei-db/state_db/sc/flatkv/api.go @@ -1,12 +1,18 @@ package flatkv import ( + "errors" "io" "github.com/sei-protocol/sei-chain/sei-db/proto" ) -// Exporter streams FlatKV state (in x/evm memiavl key format) for snapshots. +// ErrReadOnlyNotSupported is returned when LoadVersion is called with readOnly=true. +// Callers should fall back to Cosmos-only mode when this error is returned. +var ErrReadOnlyNotSupported = errors.New("FlatKV read-only mode not yet supported") + +// Exporter streams FlatKV state for snapshots. +// NOTE: Not yet implemented. Will be implemented with state-sync support. type Exporter interface { // Next returns the next key/value pair. Returns (nil, nil, io.EOF) when done. Next() (key, value []byte, err error) @@ -17,7 +23,7 @@ type Exporter interface { // Options configures a FlatKV store. type Options struct { // Dir is the base directory containing - // accounts/, + // account/, // code/, // storage/, // changelog/, @@ -27,10 +33,16 @@ type Options struct { // Store provides EVM state storage with LtHash integrity. // +// Lifecycle: NewCommitStore (create) → LoadVersion (open) → ApplyChangeSets/Commit → Close. // Write path: ApplyChangeSets (buffer) → Commit (persist). // Read path: Get/Has/Iterator read committed state only. // Key format: x/evm memiavl keys (mapped internally to account/code/storage DBs). type Store interface { + // LoadVersion opens the database at the specified version. + // Note: FlatKV only stores latest state, so targetVersion is for verification only. + // readOnly=true is NOT YET SUPPORTED and returns an error (requires snapshot implementation). + LoadVersion(targetVersion int64, readOnly bool) (Store, error) + // ApplyChangeSets buffers EVM changesets (x/evm memiavl keys) and updates LtHash. // Non-EVM modules are ignored. Call Commit to persist. ApplyChangeSets(cs []*proto.NamedChangeSet) error @@ -46,13 +58,11 @@ type Store interface { // Iterator returns an iterator over [start, end) in memiavl key order. // Pass nil for unbounded. - // - // Multiplexes across internal DBs to return keys in standard memiavl prefix order: - // 0x03 (Storage), 0x07 (Code), 0x08 (CodeHash), 0x09 (CodeSize), 0x0a (Nonce). Iterator(start, end []byte) Iterator // IteratorByPrefix iterates all keys with the given prefix (more efficient than Iterator). - // Supported: StateKeyPrefix||addr, NonceKeyPrefix, CodeKeyPrefix. + // Currently only supports: StateKeyPrefix||addr (storage iteration). + // Account/code iteration will be added with state-sync support. IteratorByPrefix(prefix []byte) Iterator // RootHash returns the 32-byte checksum of the working LtHash. @@ -75,8 +85,12 @@ type Store interface { io.Closer } -// Iterator provides ordered iteration over EVM keys (memiavl format). +// Iterator provides ordered iteration over EVM keys. // Follows PebbleDB semantics: not positioned on creation. +// +// Keys are returned in internal format (without memiavl prefix). +// Concrete implementations (e.g. dbIterator) expose Kind() for callers +// that need to distinguish key types. type Iterator interface { Domain() (start, end []byte) Valid() bool @@ -90,7 +104,10 @@ type Iterator interface { Next() bool Prev() bool - // Key returns the current key (valid until next move). + // Key returns the current key in internal format (valid until next move). + // Internal formats: + // - Storage: addr(20) || slot(32) + // - Nonce/Code/CodeHash: addr(20) Key() []byte // Value returns the current value (valid until next move). diff --git a/sei-db/state_db/sc/flatkv/config.go b/sei-db/state_db/sc/flatkv/config.go index 7cf19be319..f9ed452c15 100644 --- a/sei-db/state_db/sc/flatkv/config.go +++ b/sei-db/state_db/sc/flatkv/config.go @@ -1,8 +1,24 @@ package flatkv +// Config defines configuration for the FlatKV (EVM) commit store. type Config struct { + // Fsync controls whether data DB writes use fsync for durability. + // When true (default): all data DB writes use Sync=true for maximum durability. + // When false: data DBs use Sync=false for better performance. + // WAL and metaDB always use sync writes regardless of this setting. + // Default: true + Fsync bool `mapstructure:"fsync"` + + // AsyncWriteBuffer defines the size of the async write buffer for data DBs. + // Set <= 0 for synchronous writes. + // Default: 0 (synchronous) + AsyncWriteBuffer int `mapstructure:"async-write-buffer"` } +// DefaultConfig returns Config with safe default values. func DefaultConfig() Config { - return Config{} + return Config{ + Fsync: true, + AsyncWriteBuffer: 0, + } } diff --git a/sei-db/state_db/sc/flatkv/iterator.go b/sei-db/state_db/sc/flatkv/iterator.go new file mode 100644 index 0000000000..f4c805f14c --- /dev/null +++ b/sei-db/state_db/sc/flatkv/iterator.go @@ -0,0 +1,250 @@ +package flatkv + +import ( + "bytes" + "fmt" + + "github.com/sei-protocol/sei-chain/sei-db/common/evm" + db_engine "github.com/sei-protocol/sei-chain/sei-db/db_engine" +) + +// dbIterator is a generic iterator that wraps a PebbleDB iterator +// and converts keys between internal and external (memiavl) formats. +type dbIterator struct { + iter db_engine.Iterator + kind evm.EVMKeyKind // key type for conversion + start []byte // external format start key + end []byte // external format end key + err error + closed bool +} + +// Compile-time interface checks +var ( + _ Iterator = (*dbIterator)(nil) + _ Iterator = (*emptyIterator)(nil) +) + +// newDBIterator creates a new dbIterator for the given key kind. +func newDBIterator(db db_engine.DB, kind evm.EVMKeyKind, start, end []byte) Iterator { + // Convert external bounds to internal bounds + var internalStart, internalEnd []byte + startMatches := start == nil // nil start means unbounded + endMatches := end == nil // nil end means unbounded + + if start != nil { + parsedKind, keyBytes := evm.ParseEVMKey(start) + if parsedKind == kind { + internalStart = keyBytes + startMatches = true + } + } + if end != nil { + parsedKind, keyBytes := evm.ParseEVMKey(end) + if parsedKind == kind { + internalEnd = keyBytes + endMatches = true + } + } + + if !startMatches || !endMatches { + return &emptyIterator{} + } + + // Exclude metadata key (0x00) + if internalStart == nil { + internalStart = metaKeyLowerBound() + } + + iter, err := db.NewIter(&db_engine.IterOptions{ + LowerBound: internalStart, + UpperBound: internalEnd, + }) + if err != nil { + return &emptyIterator{err: err} + } + + return &dbIterator{ + iter: iter, + kind: kind, + start: start, + end: end, + } +} + +// newDBPrefixIterator creates a new dbIterator for prefix scanning. +func newDBPrefixIterator(db db_engine.DB, kind evm.EVMKeyKind, internalPrefix []byte, externalPrefix []byte) Iterator { + internalEnd := PrefixEnd(internalPrefix) + + // Exclude metadata key (0x00) + if internalPrefix == nil || bytes.Compare(internalPrefix, metaKeyLowerBound()) < 0 { + internalPrefix = metaKeyLowerBound() + } + + iter, err := db.NewIter(&db_engine.IterOptions{ + LowerBound: internalPrefix, + UpperBound: internalEnd, + }) + if err != nil { + return &emptyIterator{err: err} + } + + externalEnd := PrefixEnd(externalPrefix) + + return &dbIterator{ + iter: iter, + kind: kind, + start: externalPrefix, + end: externalEnd, + } +} + +func (it *dbIterator) Domain() ([]byte, []byte) { + return it.start, it.end +} + +func (it *dbIterator) Valid() bool { + if it.closed || it.err != nil { + return false + } + return it.iter.Valid() +} + +func (it *dbIterator) Error() error { + if it.err != nil { + return it.err + } + return it.iter.Error() +} + +func (it *dbIterator) Close() error { + if it.closed { + return nil + } + it.closed = true + return it.iter.Close() +} + +func (it *dbIterator) First() bool { + if it.closed { + return false + } + return it.iter.First() +} + +func (it *dbIterator) Last() bool { + if it.closed { + return false + } + return it.iter.Last() +} + +func (it *dbIterator) SeekGE(key []byte) bool { + if it.closed { + return false + } + + kind, internalKey := evm.ParseEVMKey(key) + if kind != it.kind { + it.err = fmt.Errorf("key type mismatch: expected %d, got %d", it.kind, kind) + return false + } + + return it.iter.SeekGE(internalKey) +} + +func (it *dbIterator) SeekLT(key []byte) bool { + if it.closed { + return false + } + + kind, internalKey := evm.ParseEVMKey(key) + if kind != it.kind { + it.err = fmt.Errorf("key type mismatch: expected %d, got %d", it.kind, kind) + return false + } + + return it.iter.SeekLT(internalKey) +} + +func (it *dbIterator) Next() bool { + if it.closed { + return false + } + return it.iter.Next() +} + +func (it *dbIterator) Prev() bool { + if it.closed { + return false + } + return it.iter.Prev() +} + +func (it *dbIterator) Kind() evm.EVMKeyKind { + return it.kind +} + +func (it *dbIterator) Key() []byte { + if !it.Valid() { + return nil + } + // Return internal key format (without memiavl prefix) + return it.iter.Key() +} + +func (it *dbIterator) Value() []byte { + if !it.Valid() { + return nil + } + return it.iter.Value() +} + +// CommitStore factory methods for creating iterators + +func (s *CommitStore) newStorageIterator(start, end []byte) Iterator { + return newDBIterator(s.storageDB, evm.EVMKeyStorage, start, end) +} + +func (s *CommitStore) newStoragePrefixIterator(internalPrefix, internalEnd []byte, memiavlPrefix []byte) Iterator { + return newDBPrefixIterator(s.storageDB, evm.EVMKeyStorage, internalPrefix, memiavlPrefix) +} + +func (s *CommitStore) newCodeIterator(start, end []byte) Iterator { + return newDBIterator(s.codeDB, evm.EVMKeyCode, start, end) +} + +// emptyIterator is used when no data matches the query. +// If err is set, it indicates a creation failure (e.g. PebbleDB error). +type emptyIterator struct { + err error +} + +func (it *emptyIterator) Domain() ([]byte, []byte) { return nil, nil } +func (it *emptyIterator) Valid() bool { return false } +func (it *emptyIterator) Error() error { return it.err } +func (it *emptyIterator) Close() error { return nil } +func (it *emptyIterator) First() bool { return false } +func (it *emptyIterator) Last() bool { return false } +func (it *emptyIterator) SeekGE(key []byte) bool { return false } +func (it *emptyIterator) SeekLT(key []byte) bool { return false } +func (it *emptyIterator) Next() bool { return false } +func (it *emptyIterator) Prev() bool { return false } +func (it *emptyIterator) Kind() evm.EVMKeyKind { return evm.EVMKeyUnknown } +func (it *emptyIterator) Key() []byte { return nil } +func (it *emptyIterator) Value() []byte { return nil } + +// notImplementedExporter is a placeholder for the Exporter interface. +// Actual implementation will be added with state-sync support. +type notImplementedExporter struct{} + +// Compile-time check: notImplementedExporter implements Exporter +var _ Exporter = (*notImplementedExporter)(nil) + +func (e *notImplementedExporter) Next() ([]byte, []byte, error) { + return nil, nil, fmt.Errorf("exporter not implemented: will be added with state-sync support") +} + +func (e *notImplementedExporter) Close() error { + return nil +} diff --git a/sei-db/state_db/sc/flatkv/keys.go b/sei-db/state_db/sc/flatkv/keys.go index 8caf63ae1f..cbac724520 100644 --- a/sei-db/state_db/sc/flatkv/keys.go +++ b/sei-db/state_db/sc/flatkv/keys.go @@ -6,15 +6,55 @@ import ( "fmt" ) +// DBLocalMetaKey is the key for per-DB local metadata. +// It is a single-byte key (0x00), which cannot collide with any valid user key +// because all user keys have minimum length of 20 bytes (EVM address). +// +// Invariant: All user keys are >= 20 bytes (address=20, storage=52). +var DBLocalMetaKey = []byte{0x00} + +// metaKeyLowerBound returns the iterator lower bound that excludes DBLocalMetaKey. +// Lexicographically: 0x00 (1 byte) < 0x00,0x00 (2 bytes) < any user key (>=20 bytes). +// This ensures metadata key is excluded while all user keys (even those starting +// with 0x00) are included. +func metaKeyLowerBound() []byte { + return []byte{0x00, 0x00} +} + const ( AddressLen = 20 CodeHashLen = 32 SlotLen = 32 BalanceLen = 32 + NonceLen = 8 - NonceLen = 8 + // localMetaSize is the serialized size of LocalMeta (version = 8 bytes) + localMetaSize = 8 ) +// LocalMeta stores per-DB version tracking metadata. +// Stored inside each DB at DBLocalMetaKey (0x00). +type LocalMeta struct { + CommittedVersion int64 // Current committed version in this DB +} + +// MarshalLocalMeta encodes LocalMeta as fixed 8 bytes (big-endian). +func MarshalLocalMeta(m *LocalMeta) []byte { + buf := make([]byte, localMetaSize) + binary.BigEndian.PutUint64(buf, uint64(m.CommittedVersion)) //nolint:gosec // version is always non-negative + return buf +} + +// UnmarshalLocalMeta decodes LocalMeta from bytes. +func UnmarshalLocalMeta(data []byte) (*LocalMeta, error) { + if len(data) != localMetaSize { + return nil, fmt.Errorf("invalid LocalMeta size: got %d, want %d", len(data), localMetaSize) + } + return &LocalMeta{ + CommittedVersion: int64(binary.BigEndian.Uint64(data)), //nolint:gosec // version won't exceed int64 max + }, nil +} + // Address is an EVM address (20 bytes). type Address [AddressLen]byte @@ -54,52 +94,35 @@ func SlotFromBytes(b []byte) (Slot, bool) { return s, true } -// AccountKey is a type-safe account DB key. -type AccountKey struct{ b []byte } - -func (k AccountKey) isZero() bool { return len(k.b) == 0 } -func (k AccountKey) bytes() []byte { return k.b } +// ============================================================================= +// DB Key Builders +// ============================================================================= -// AccountKeyFor returns the account DB key for addr. -func AccountKeyFor(addr Address) AccountKey { - b := make([]byte, AddressLen) - copy(b, addr[:]) - return AccountKey{b: b} +// AccountKey returns the accountDB key for addr. +// Key format: addr(20) +func AccountKey(addr Address) []byte { + return addr[:] } -// CodeKey is a type-safe code DB key. -type CodeKey struct{ b []byte } - -func (k CodeKey) isZero() bool { return len(k.b) == 0 } -func (k CodeKey) bytes() []byte { return k.b } - -// CodeKeyFor returns the code DB key for codeHash. -func CodeKeyFor(codeHash CodeHash) CodeKey { - b := make([]byte, CodeHashLen) - copy(b, codeHash[:]) - return CodeKey{b: b} +// CodeKey returns the codeDB key for codeHash. +// Key format: codeHash(32) +func CodeKey(codeHash CodeHash) []byte { + return codeHash[:] } -// StorageKey is a type-safe storage DB key (or prefix). -// Encodes: nil (unbounded), addr (prefix), or addr||slot (full key). -type StorageKey struct{ b []byte } - -func (k StorageKey) isZero() bool { return len(k.b) == 0 } -func (k StorageKey) bytes() []byte { return k.b } - -// StoragePrefix returns the storage DB prefix key for addr. -func StoragePrefix(addr Address) StorageKey { - b := make([]byte, AddressLen) - copy(b, addr[:]) - return StorageKey{b: b} +// StorageKey returns the storageDB key for (addr, slot). +// Key format: addr(20) || slot(32) = 52 bytes +func StorageKey(addr Address, slot Slot) []byte { + key := make([]byte, AddressLen+SlotLen) + copy(key[:AddressLen], addr[:]) + copy(key[AddressLen:], slot[:]) + return key } -// StorageKeyFor returns the storage DB key for (addr, slot). -func StorageKeyFor(addr Address, slot Slot) StorageKey { - b := make([]byte, 0, AddressLen+SlotLen) - b = append(b, addr[:]...) - b = append(b, slot[:]...) - return StorageKey{b: b} +// StoragePrefix returns the storageDB prefix for iterating all slots of addr. +// Prefix format: addr(20) +func StoragePrefix(addr Address) []byte { + return addr[:] } // PrefixEnd returns the exclusive upper bound for prefix iteration (or nil). @@ -144,6 +167,11 @@ func (v AccountValue) HasCode() bool { return v.CodeHash != CodeHash{} } +// Encode encodes the AccountValue to bytes. +func (v AccountValue) Encode() []byte { + return EncodeAccountValue(v) +} + // EncodeAccountValue encodes v into a variable-length slice. // EOA accounts (no code) are encoded as 40 bytes, contracts as 72 bytes. func EncodeAccountValue(v AccountValue) []byte { diff --git a/sei-db/state_db/sc/flatkv/keys_test.go b/sei-db/state_db/sc/flatkv/keys_test.go index b412c5de68..0bc44ba372 100644 --- a/sei-db/state_db/sc/flatkv/keys_test.go +++ b/sei-db/state_db/sc/flatkv/keys_test.go @@ -186,3 +186,58 @@ func TestFlatKVTypeConversions(t *testing.T) { require.False(t, ok) }) } + +func TestLocalMetaSerialization(t *testing.T) { + t.Run("RoundTripZero", func(t *testing.T) { + original := &LocalMeta{CommittedVersion: 0} + encoded := MarshalLocalMeta(original) + require.Equal(t, localMetaSize, len(encoded)) + + decoded, err := UnmarshalLocalMeta(encoded) + require.NoError(t, err) + require.Equal(t, original.CommittedVersion, decoded.CommittedVersion) + }) + + t.Run("RoundTripPositive", func(t *testing.T) { + original := &LocalMeta{CommittedVersion: 12345} + encoded := MarshalLocalMeta(original) + require.Equal(t, localMetaSize, len(encoded)) + + decoded, err := UnmarshalLocalMeta(encoded) + require.NoError(t, err) + require.Equal(t, original.CommittedVersion, decoded.CommittedVersion) + }) + + t.Run("RoundTripMaxInt64", func(t *testing.T) { + original := &LocalMeta{CommittedVersion: math.MaxInt64} + encoded := MarshalLocalMeta(original) + require.Equal(t, localMetaSize, len(encoded)) + + decoded, err := UnmarshalLocalMeta(encoded) + require.NoError(t, err) + require.Equal(t, original.CommittedVersion, decoded.CommittedVersion) + }) + + t.Run("InvalidLength", func(t *testing.T) { + // Too short + _, err := UnmarshalLocalMeta([]byte{0x00}) + require.Error(t, err) + require.Contains(t, err.Error(), "invalid LocalMeta size") + + // Too long + _, err = UnmarshalLocalMeta(make([]byte, localMetaSize+1)) + require.Error(t, err) + require.Contains(t, err.Error(), "invalid LocalMeta size") + }) + + t.Run("BigEndianEncoding", func(t *testing.T) { + // Verify big-endian encoding: version 0x0102030405060708 + meta := &LocalMeta{CommittedVersion: 0x0102030405060708} + encoded := MarshalLocalMeta(meta) + + // Big-endian: most significant byte first + require.Equal(t, byte(0x01), encoded[0]) + require.Equal(t, byte(0x02), encoded[1]) + require.Equal(t, byte(0x08), encoded[7]) + }) +} diff --git a/sei-db/state_db/sc/flatkv/store.go b/sei-db/state_db/sc/flatkv/store.go new file mode 100644 index 0000000000..78f4bcade5 --- /dev/null +++ b/sei-db/state_db/sc/flatkv/store.go @@ -0,0 +1,278 @@ +package flatkv + +import ( + "fmt" + "io" + "os" + "path/filepath" + + "github.com/sei-protocol/sei-chain/sei-db/common/logger" + db_engine "github.com/sei-protocol/sei-chain/sei-db/db_engine" + "github.com/sei-protocol/sei-chain/sei-db/db_engine/pebbledb" + "github.com/sei-protocol/sei-chain/sei-db/proto" + "github.com/sei-protocol/sei-chain/sei-db/state_db/sc/flatkv/lthash" + "github.com/sei-protocol/sei-chain/sei-db/wal" +) + +const ( + // DB subdirectories + accountDBDir = "account" + codeDBDir = "code" + storageDBDir = "storage" + legacyDBDir = "legacy" + metadataDir = "metadata" + + // Metadata DB keys + MetaGlobalVersion = "_meta/version" // Global committed version watermark (8 bytes) + MetaGlobalLtHash = "_meta/hash" // Global LtHash (2048 bytes) +) + +// pendingKVWrite tracks a buffered key-value write for code/storage DBs. +type pendingKVWrite struct { + key []byte // Internal DB key + value []byte + isDelete bool +} + +// pendingAccountWrite tracks a buffered account write. +// Uses AccountValue structure: balance(32) || nonce(8) || codehash(32) +type pendingAccountWrite struct { + addr Address + value AccountValue + isDelete bool +} + +// CommitStore implements flatkv.Store for EVM state storage. +// NOT thread-safe; callers must serialize all operations. +type CommitStore struct { + log logger.Logger + config Config + homeDir string + + // Five separate PebbleDB instances + metadataDB db_engine.DB // Global version + LtHash watermark + accountDB db_engine.DB // addr(20) → AccountValue (40 or 72 bytes) + codeDB db_engine.DB // addr(20) → bytecode + storageDB db_engine.DB // addr(20)||slot(32) → value(32) + legacyDB db_engine.DB // Legacy data for backward compatibility + + // Per-DB local metadata (stored inside each DB at 0x00) + // Tracks committed version for recovery and consistency checks. + // Keyed by DB directory name (accountDBDir, codeDBDir, storageDBDir). + localMeta map[string]*LocalMeta + + // LtHash state for integrity checking + committedVersion int64 + committedLtHash *lthash.LtHash + workingLtHash *lthash.LtHash + + // Pending writes buffer + // accountWrites: key = address string (20 bytes), value = AccountValue + // codeWrites/storageWrites: key = internal DB key string, value = raw bytes + accountWrites map[string]*pendingAccountWrite + codeWrites map[string]*pendingKVWrite + storageWrites map[string]*pendingKVWrite + + // Changelog WAL for atomic writes and replay + changelog wal.ChangelogWAL + + // Pending changesets (for changelog) + pendingChangeSets []*proto.NamedChangeSet +} + +// Compile-time check: CommitStore implements Store interface +var _ Store = (*CommitStore)(nil) + +// NewCommitStore creates a new FlatKV commit store. +// Note: The store is NOT opened yet. Call LoadVersion to open and initialize the DB. +// This matches the memiavl.NewCommitStore pattern. +func NewCommitStore(homeDir string, log logger.Logger, cfg Config) *CommitStore { + if log == nil { + log = logger.NewNopLogger() + } + + return &CommitStore{ + log: log, + config: cfg, + homeDir: homeDir, + localMeta: make(map[string]*LocalMeta), + accountWrites: make(map[string]*pendingAccountWrite), + codeWrites: make(map[string]*pendingKVWrite), + storageWrites: make(map[string]*pendingKVWrite), + pendingChangeSets: make([]*proto.NamedChangeSet, 0), + committedLtHash: lthash.New(), + workingLtHash: lthash.New(), + } +} + +// LoadVersion loads the specified version of the database. +func (s *CommitStore) LoadVersion(targetVersion int64, readOnly bool) (Store, error) { + s.log.Info("FlatKV LoadVersion", "targetVersion", targetVersion, "readOnly", readOnly) + + if readOnly { + // Read-only mode requires snapshot support (not yet implemented). + // Return sentinel error so callers can fall back to Cosmos-only mode. + return nil, ErrReadOnlyNotSupported + } + + // Close existing resources if already open + if s.metadataDB != nil { + _ = s.Close() + } + + // Open the store + if err := s.open(); err != nil { + return nil, fmt.Errorf("failed to open FlatKV store: %w", err) + } + + // Verify version if specified + if targetVersion > 0 && s.committedVersion != targetVersion { + return nil, fmt.Errorf("FlatKV version mismatch: requested %d, current %d", + targetVersion, s.committedVersion) + } + + return s, nil +} + +// open opens all database instances. Called by LoadVersion. +// On failure, all already-opened resources are closed via deferred cleanup. +func (s *CommitStore) open() (retErr error) { + dir := filepath.Join(s.homeDir, "flatkv") + + // Create directory structure + if err := os.MkdirAll(dir, 0750); err != nil { + return fmt.Errorf("failed to create base directory: %w", err) + } + + accountPath := filepath.Join(dir, accountDBDir) + codePath := filepath.Join(dir, codeDBDir) + storagePath := filepath.Join(dir, storageDBDir) + legacyPath := filepath.Join(dir, legacyDBDir) + metadataPath := filepath.Join(dir, metadataDir) + + for _, path := range []string{accountPath, codePath, storagePath, legacyPath, metadataPath} { + if err := os.MkdirAll(path, 0750); err != nil { + return fmt.Errorf("failed to create directory %s: %w", path, err) + } + } + + // Track opened resources for cleanup on failure + var toClose []io.Closer + defer func() { + if retErr != nil { + for _, c := range toClose { + _ = c.Close() + } + // Clear fields to avoid dangling references to closed handles + s.metadataDB = nil + s.accountDB = nil + s.codeDB = nil + s.storageDB = nil + s.legacyDB = nil + s.changelog = nil + s.localMeta = make(map[string]*LocalMeta) + } + }() + + // Open metadata DB first (needed for catchup) + metaDB, err := pebbledb.Open(metadataPath, db_engine.OpenOptions{}) + if err != nil { + return fmt.Errorf("failed to open metadata DB: %w", err) + } + toClose = append(toClose, metaDB) + + // Open PebbleDB instances + accountDB, err := pebbledb.Open(accountPath, db_engine.OpenOptions{}) + if err != nil { + return fmt.Errorf("failed to open accountDB: %w", err) + } + toClose = append(toClose, accountDB) + + codeDB, err := pebbledb.Open(codePath, db_engine.OpenOptions{}) + if err != nil { + return fmt.Errorf("failed to open codeDB: %w", err) + } + toClose = append(toClose, codeDB) + + storageDB, err := pebbledb.Open(storagePath, db_engine.OpenOptions{}) + if err != nil { + return fmt.Errorf("failed to open storageDB: %w", err) + } + toClose = append(toClose, storageDB) + + legacyDB, err := pebbledb.Open(legacyPath, db_engine.OpenOptions{}) + if err != nil { + return fmt.Errorf("failed to open legacyDB: %w", err) + } + toClose = append(toClose, legacyDB) + + // Open changelog WAL + changelogPath := filepath.Join(dir, "changelog") + changelog, err := wal.NewChangelogWAL(s.log, changelogPath, wal.Config{ + WriteBufferSize: 0, // Synchronous writes for Phase 1 + KeepRecent: 0, // No pruning for Phase 1 + PruneInterval: 0, + }) + if err != nil { + return fmt.Errorf("failed to open changelog: %w", err) + } + toClose = append(toClose, changelog) + + // Load per-DB local metadata (or initialize if not present) + dataDBs := map[string]db_engine.DB{ + accountDBDir: accountDB, + codeDBDir: codeDB, + storageDBDir: storageDB, + } + for name, db := range dataDBs { + meta, err := loadLocalMeta(db) + if err != nil { + return fmt.Errorf("failed to load %s local meta: %w", name, err) + } + s.localMeta[name] = meta + } + + // Assign to store fields + s.metadataDB = metaDB + s.accountDB = accountDB + s.codeDB = codeDB + s.storageDB = storageDB + s.legacyDB = legacyDB + s.changelog = changelog + + // Load committed state from metadataDB + globalVersion, err := s.loadGlobalVersion() + if err != nil { + return fmt.Errorf("failed to load global version: %w", err) + } + s.committedVersion = globalVersion + + globalLtHash, err := s.loadGlobalLtHash() + if err != nil { + return fmt.Errorf("failed to load global LtHash: %w", err) + } + if globalLtHash != nil { + s.committedLtHash = globalLtHash + s.workingLtHash = globalLtHash.Clone() + } else { + s.committedLtHash = lthash.New() + s.workingLtHash = lthash.New() + } + + // TODO: Run catchup to recover from any incomplete commits + // Catchup will be added in a future PR with state-sync support. + + s.log.Info("FlatKV store opened", "dir", dir, "version", s.committedVersion) + return nil +} + +// Version returns the latest committed version. +func (s *CommitStore) Version() int64 { + return s.committedVersion +} + +// RootHash returns the Blake3-256 digest of the working LtHash. +func (s *CommitStore) RootHash() []byte { + checksum := s.workingLtHash.Checksum() + return checksum[:] +} diff --git a/sei-db/state_db/sc/flatkv/store_lifecycle.go b/sei-db/state_db/sc/flatkv/store_lifecycle.go new file mode 100644 index 0000000000..e75a91e97e --- /dev/null +++ b/sei-db/state_db/sc/flatkv/store_lifecycle.go @@ -0,0 +1,72 @@ +package flatkv + +import ( + "errors" + "fmt" +) + +// Close closes all database instances. +func (s *CommitStore) Close() error { + var errs []error + + if s.changelog != nil { + if err := s.changelog.Close(); err != nil { + errs = append(errs, fmt.Errorf("changelog close: %w", err)) + } + } + + if s.metadataDB != nil { + if err := s.metadataDB.Close(); err != nil { + errs = append(errs, fmt.Errorf("metadataDB close: %w", err)) + } + } + + if s.storageDB != nil { + if err := s.storageDB.Close(); err != nil { + errs = append(errs, fmt.Errorf("storageDB close: %w", err)) + } + } + if s.codeDB != nil { + if err := s.codeDB.Close(); err != nil { + errs = append(errs, fmt.Errorf("codeDB close: %w", err)) + } + } + if s.accountDB != nil { + if err := s.accountDB.Close(); err != nil { + errs = append(errs, fmt.Errorf("accountDB close: %w", err)) + } + } + + if s.legacyDB != nil { + if err := s.legacyDB.Close(); err != nil { + errs = append(errs, fmt.Errorf("legacyDB close: %w", err)) + } + } + + if len(errs) > 0 { + return errors.Join(errs...) + } + + s.log.Info("FlatKV store closed") + return nil +} + +// Exporter creates an exporter for the given version. +// NOTE: Not yet implemented. Will be added with state-sync support. +// The future implementation will export each DB separately with internal key format. +func (s *CommitStore) Exporter(version int64) (Exporter, error) { + // Return a placeholder exporter that indicates not implemented + return ¬ImplementedExporter{}, nil +} + +// WriteSnapshot writes a complete snapshot to the given directory. +func (s *CommitStore) WriteSnapshot(dir string) error { + // TODO: Implement snapshot writing + return fmt.Errorf("WriteSnapshot not implemented") +} + +// Rollback restores state to targetVersion. +func (s *CommitStore) Rollback(targetVersion int64) error { + s.log.Info("FlatKV Rollback called (no-op)", "targetVersion", targetVersion) + return nil +} diff --git a/sei-db/state_db/sc/flatkv/store_meta.go b/sei-db/state_db/sc/flatkv/store_meta.go new file mode 100644 index 0000000000..78fc51f1b4 --- /dev/null +++ b/sei-db/state_db/sc/flatkv/store_meta.go @@ -0,0 +1,81 @@ +package flatkv + +import ( + "encoding/binary" + "fmt" + "math" + + db_engine "github.com/sei-protocol/sei-chain/sei-db/db_engine" + "github.com/sei-protocol/sei-chain/sei-db/state_db/sc/flatkv/lthash" +) + +// loadLocalMeta loads the local metadata from a DB, or returns default if not present. +func loadLocalMeta(db db_engine.DB) (*LocalMeta, error) { + val, err := db.Get(DBLocalMetaKey) + // Check for real errors first to avoid masking I/O issues + if err != nil && !db_engine.IsNotFound(err) { + return nil, fmt.Errorf("could not get DBLocalMetaKey: %w", err) + } + // Only return default for truly missing keys + if db_engine.IsNotFound(err) || val == nil { + return &LocalMeta{CommittedVersion: 0}, nil + } + return UnmarshalLocalMeta(val) +} + +// loadGlobalVersion reads the global committed version from metadata DB. +// Returns 0 if not found (fresh start). +func (s *CommitStore) loadGlobalVersion() (int64, error) { + data, err := s.metadataDB.Get([]byte(MetaGlobalVersion)) + if db_engine.IsNotFound(err) { + return 0, nil + } + if err != nil { + return 0, fmt.Errorf("failed to read global version: %w", err) + } + if len(data) != 8 { + return 0, fmt.Errorf("invalid global version length: got %d, want 8", len(data)) + } + v := binary.BigEndian.Uint64(data) + if v > math.MaxInt64 { + return 0, fmt.Errorf("global version overflow: %d exceeds max int64", v) + } + return int64(v), nil //nolint:gosec // overflow checked above +} + +// loadGlobalLtHash reads the global committed LtHash from metadata DB. +// Returns nil if not found (fresh start). +func (s *CommitStore) loadGlobalLtHash() (*lthash.LtHash, error) { + data, err := s.metadataDB.Get([]byte(MetaGlobalLtHash)) + if db_engine.IsNotFound(err) { + return nil, nil + } + if err != nil { + return nil, fmt.Errorf("failed to read global lthash: %w", err) + } + return lthash.Unmarshal(data) +} + +// commitGlobalMetadata atomically commits global version and LtHash to metadata DB. +// This is the global watermark written AFTER all per-DB commits succeed. +func (s *CommitStore) commitGlobalMetadata(version int64, hash *lthash.LtHash) error { + batch := s.metadataDB.NewBatch() + defer func() { _ = batch.Close() }() + + // Encode version (version should always be non-negative in practice) + versionBuf := make([]byte, 8) + binary.BigEndian.PutUint64(versionBuf, uint64(version)) //nolint:gosec // version is always non-negative + + // Write global metadata + if err := batch.Set([]byte(MetaGlobalVersion), versionBuf); err != nil { + return fmt.Errorf("failed to set global version: %w", err) + } + + lthashBytes := hash.Marshal() + if err := batch.Set([]byte(MetaGlobalLtHash), lthashBytes); err != nil { + return fmt.Errorf("failed to set global lthash: %w", err) + } + + // Atomic commit with fsync + return batch.Commit(db_engine.WriteOptions{Sync: true}) +} diff --git a/sei-db/state_db/sc/flatkv/store_meta_test.go b/sei-db/state_db/sc/flatkv/store_meta_test.go new file mode 100644 index 0000000000..93776caddc --- /dev/null +++ b/sei-db/state_db/sc/flatkv/store_meta_test.go @@ -0,0 +1,152 @@ +package flatkv + +import ( + "testing" + + "github.com/sei-protocol/sei-chain/sei-db/db_engine" + "github.com/sei-protocol/sei-chain/sei-db/proto" + "github.com/sei-protocol/sei-chain/sei-db/state_db/sc/flatkv/lthash" + "github.com/stretchr/testify/require" +) + +// ============================================================================= +// LocalMeta and Global Metadata +// ============================================================================= + +func TestLoadLocalMeta(t *testing.T) { + t.Run("NewDB_ReturnsDefault", func(t *testing.T) { + db := setupTestDB(t) + defer db.Close() + + meta, err := loadLocalMeta(db) + require.NoError(t, err) + require.NotNil(t, meta) + require.Equal(t, int64(0), meta.CommittedVersion) + }) + + t.Run("ExistingMeta_LoadsCorrectly", func(t *testing.T) { + db := setupTestDB(t) + defer db.Close() + + // Write metadata + original := &LocalMeta{CommittedVersion: 42} + err := db.Set(DBLocalMetaKey, MarshalLocalMeta(original), db_engine.WriteOptions{}) + require.NoError(t, err) + + // Load it back + loaded, err := loadLocalMeta(db) + require.NoError(t, err) + require.Equal(t, original.CommittedVersion, loaded.CommittedVersion) + }) + + t.Run("CorruptedMeta_ReturnsError", func(t *testing.T) { + db := setupTestDB(t) + defer db.Close() + + // Write invalid data (wrong size) + err := db.Set(DBLocalMetaKey, []byte{0x01, 0x02}, db_engine.WriteOptions{}) + require.NoError(t, err) + + // Should fail to load + _, err = loadLocalMeta(db) + require.Error(t, err) + require.Contains(t, err.Error(), "invalid LocalMeta size") + }) +} + +func TestStoreCommitBatchesUpdatesLocalMeta(t *testing.T) { + s := setupTestStore(t) + defer s.Close() + + addr := Address{0x12} + slot := Slot{0x34} + key := memiavlStorageKey(addr, slot) + + cs := makeChangeSet(key, []byte{0x56}, false) + require.NoError(t, s.ApplyChangeSets([]*proto.NamedChangeSet{cs})) + v := commitAndCheck(t, s) + require.Equal(t, int64(1), v) + + // LocalMeta should be updated + require.Equal(t, int64(1), s.localMeta[storageDBDir].CommittedVersion) + + // Verify it's persisted in DB + data, err := s.storageDB.Get(DBLocalMetaKey) + require.NoError(t, err) + meta, err := UnmarshalLocalMeta(data) + require.NoError(t, err) + require.Equal(t, int64(1), meta.CommittedVersion) +} + +func TestStoreMetadataOperations(t *testing.T) { + t.Run("LoadGlobalVersion_NewDB", func(t *testing.T) { + s := setupTestStore(t) + defer s.Close() + + version, err := s.loadGlobalVersion() + require.NoError(t, err) + require.Equal(t, int64(0), version) + }) + + t.Run("LoadGlobalLtHash_NewDB", func(t *testing.T) { + s := setupTestStore(t) + defer s.Close() + + hash, err := s.loadGlobalLtHash() + require.NoError(t, err) + require.Nil(t, hash) + }) + + t.Run("CommitGlobalMetadata_RoundTrip", func(t *testing.T) { + s := setupTestStore(t) + defer s.Close() + + // Commit metadata + expectedVersion := int64(100) + expectedHash := lthash.New() + + err := s.commitGlobalMetadata(expectedVersion, expectedHash) + require.NoError(t, err) + + // Load it back + version, err := s.loadGlobalVersion() + require.NoError(t, err) + require.Equal(t, expectedVersion, version) + + hash, err := s.loadGlobalLtHash() + require.NoError(t, err) + require.NotNil(t, hash) + require.Equal(t, expectedHash.Marshal(), hash.Marshal()) + }) + + t.Run("CommitGlobalMetadata_Atomicity", func(t *testing.T) { + s := setupTestStore(t) + defer s.Close() + + // Commit multiple times + for v := int64(1); v <= 10; v++ { + hash := lthash.New() + err := s.commitGlobalMetadata(v, hash) + require.NoError(t, err) + + // Verify immediately + version, err := s.loadGlobalVersion() + require.NoError(t, err) + require.Equal(t, v, version) + } + }) + + t.Run("LoadGlobalVersion_InvalidData", func(t *testing.T) { + s := setupTestStore(t) + defer s.Close() + + // Write invalid data (wrong size) + err := s.metadataDB.Set([]byte(MetaGlobalVersion), []byte{0x01}, db_engine.WriteOptions{}) + require.NoError(t, err) + + // Should return error + _, err = s.loadGlobalVersion() + require.Error(t, err) + require.Contains(t, err.Error(), "invalid global version length") + }) +} diff --git a/sei-db/state_db/sc/flatkv/store_read.go b/sei-db/state_db/sc/flatkv/store_read.go new file mode 100644 index 0000000000..3d81d0cfdb --- /dev/null +++ b/sei-db/state_db/sc/flatkv/store_read.go @@ -0,0 +1,271 @@ +package flatkv + +import ( + "bytes" + "encoding/binary" + "fmt" + + "github.com/sei-protocol/sei-chain/sei-db/common/evm" + db_engine "github.com/sei-protocol/sei-chain/sei-db/db_engine" +) + +// Get returns the value for the given memiavl key. +// Returns (value, true) if found, (nil, false) if not found. +func (s *CommitStore) Get(key []byte) ([]byte, bool) { + kind, keyBytes := evm.ParseEVMKey(key) + if kind == evm.EVMKeyUnknown { + return nil, false + } + + switch kind { + case evm.EVMKeyStorage: + // Storage: keyBytes = addr(20) || slot(32) + // Check pending writes first + if pw, ok := s.storageWrites[string(keyBytes)]; ok { + if pw.isDelete { + return nil, false + } + return pw.value, true + } + + // Read from storageDB + value, err := s.storageDB.Get(keyBytes) + if err != nil { + return nil, false + } + return value, true + + case evm.EVMKeyNonce, evm.EVMKeyCodeHash: + // Account data: keyBytes = addr(20) + // accountDB stores AccountValue at key=addr(20) + addr, ok := AddressFromBytes(keyBytes) + if !ok { + return nil, false + } + + // Check pending writes first + if paw, found := s.accountWrites[string(addr[:])]; found { + if paw.isDelete { + return nil, false + } + // Extract specific field from AccountValue + if kind == evm.EVMKeyNonce { + nonce := make([]byte, NonceLen) + binary.BigEndian.PutUint64(nonce, paw.value.Nonce) + return nonce, true + } + // CodeHash + if paw.value.CodeHash == (CodeHash{}) { + return nil, false // No codehash + } + return paw.value.CodeHash[:], true + } + + // Read from accountDB + encoded, err := s.accountDB.Get(AccountKey(addr)) + if err != nil { + return nil, false + } + av, err := DecodeAccountValue(encoded) + if err != nil { + return nil, false + } + + // Extract specific field from AccountValue + if kind == evm.EVMKeyNonce { + nonce := make([]byte, NonceLen) + binary.BigEndian.PutUint64(nonce, av.Nonce) + return nonce, true + } + // CodeHash + if av.CodeHash == (CodeHash{}) { + return nil, false // No codehash (EOA) + } + return av.CodeHash[:], true + + case evm.EVMKeyCode: + // Code: keyBytes = addr(20) - per x/evm/types/keys.go + // Check pending writes first + if pw, ok := s.codeWrites[string(keyBytes)]; ok { + if pw.isDelete { + return nil, false + } + return pw.value, true + } + + // Read from codeDB + value, err := s.codeDB.Get(keyBytes) + if err != nil { + return nil, false + } + return value, true + + default: + return nil, false + } +} + +// Has reports whether the given memiavl key exists. +func (s *CommitStore) Has(key []byte) bool { + _, found := s.Get(key) + return found +} + +// Iterator returns an iterator over [start, end) in memiavl key order. +// +// IMPORTANT: Iterator only reads COMMITTED state from the underlying DBs. +// Pending writes from ApplyChangeSets are NOT visible until after Commit(). +// +// Current limitation: Only storage keys (0x03) are supported. +// Account/code iteration will be added with state-sync support. +func (s *CommitStore) Iterator(start, end []byte) Iterator { + // Validate bounds: start must be < end + if start != nil && end != nil && bytes.Compare(start, end) >= 0 { + return &emptyIterator{} // Invalid range [start, end) + } + + // Check if start/end are storage keys before iterating storage + if start != nil { + kind, _ := evm.ParseEVMKey(start) + if kind != evm.EVMKeyUnknown && kind != evm.EVMKeyStorage { + return &emptyIterator{} + } + } + if end != nil { + kind, _ := evm.ParseEVMKey(end) + if kind != evm.EVMKeyUnknown && kind != evm.EVMKeyStorage { + return &emptyIterator{} + } + } + + return s.newStorageIterator(start, end) +} + +// IteratorByPrefix returns an iterator for keys with the given prefix. +// More efficient than Iterator for single-address queries. +// +// IMPORTANT: Like Iterator(), this only reads COMMITTED state. +// Pending writes are not visible until Commit(). +func (s *CommitStore) IteratorByPrefix(prefix []byte) Iterator { + if len(prefix) == 0 { + return s.Iterator(nil, nil) + } + + // Handle storage address prefix specially. + // ParseMemIAVLEVMKey requires full key length (prefix + addr + slot = 53 bytes), + // but a storage prefix is only (prefix + addr = 21 bytes). + // Detect storage prefix: 0x03 || addr(20) = 21 bytes + statePrefix := evm.StateKeyPrefix() + if len(prefix) == len(statePrefix)+AddressLen && + bytes.HasPrefix(prefix, statePrefix) { + // Storage address prefix: iterate all slots for this address + // Internal key format: addr(20) || slot(32) + // For prefix scan: use addr(20) as prefix + addrBytes := prefix[len(statePrefix):] + internalEnd := PrefixEnd(addrBytes) + + return s.newStoragePrefixIterator(addrBytes, internalEnd, prefix) + } + + // Try parsing as full key + kind, keyBytes := evm.ParseEVMKey(prefix) + if kind == evm.EVMKeyUnknown { + // Invalid prefix, return empty iterator + return &emptyIterator{} + } + + switch kind { + case evm.EVMKeyStorage: + // Full storage key as prefix (addr+slot): rare but supported + internalEnd := PrefixEnd(keyBytes) + return s.newStoragePrefixIterator(keyBytes, internalEnd, prefix) + + case evm.EVMKeyNonce, evm.EVMKeyCodeHash, evm.EVMKeyCode: + return &emptyIterator{} + + default: + return &emptyIterator{} + } +} + +// ============================================================================= +// Internal Getters (used by ApplyChangeSets for LtHash computation) +// ============================================================================= + +// getAccountValue loads AccountValue from pending writes or DB. +// Returns zero AccountValue if not found (new account). +// Returns error if existing data is corrupted (decode fails) or I/O error occurs. +func (s *CommitStore) getAccountValue(addr Address) (AccountValue, error) { + // Check pending writes first + if paw, ok := s.accountWrites[string(addr[:])]; ok { + return paw.value, nil + } + + // Read from accountDB + value, err := s.accountDB.Get(AccountKey(addr)) + if err != nil { + if db_engine.IsNotFound(err) { + return AccountValue{}, nil // New account + } + return AccountValue{}, fmt.Errorf("accountDB I/O error for addr %x: %w", addr, err) + } + + av, err := DecodeAccountValue(value) + if err != nil { + return AccountValue{}, fmt.Errorf("corrupted AccountValue for addr %x: %w", addr, err) + } + return av, nil +} + +// getAccountValueFromDB loads AccountValue directly from DB (ignoring pending writes). +// Used for LtHash computation to get the committed "old" value. +func (s *CommitStore) getAccountValueFromDB(addr Address) (AccountValue, error) { + value, err := s.accountDB.Get(AccountKey(addr)) + if err != nil { + if db_engine.IsNotFound(err) { + return AccountValue{}, nil + } + return AccountValue{}, err + } + return DecodeAccountValue(value) +} + +// getStorageValue returns the storage value from pending writes or DB. +// Returns (nil, nil) if not found. +// Returns (nil, error) if I/O error occurs. +func (s *CommitStore) getStorageValue(key []byte) ([]byte, error) { + if pw, ok := s.storageWrites[string(key)]; ok { + if pw.isDelete { + return nil, nil + } + return pw.value, nil + } + value, err := s.storageDB.Get(key) + if err != nil { + if db_engine.IsNotFound(err) { + return nil, nil + } + return nil, fmt.Errorf("storageDB I/O error for key %x: %w", key, err) + } + return value, nil +} + +// getCodeValue returns the code value from pending writes or DB. +// Returns (nil, nil) if not found. +// Returns (nil, error) if I/O error occurs. +func (s *CommitStore) getCodeValue(key []byte) ([]byte, error) { + if pw, ok := s.codeWrites[string(key)]; ok { + if pw.isDelete { + return nil, nil + } + return pw.value, nil + } + value, err := s.codeDB.Get(key) + if err != nil { + if db_engine.IsNotFound(err) { + return nil, nil + } + return nil, fmt.Errorf("codeDB I/O error for key %x: %w", key, err) + } + return value, nil +} diff --git a/sei-db/state_db/sc/flatkv/store_read_test.go b/sei-db/state_db/sc/flatkv/store_read_test.go new file mode 100644 index 0000000000..5b16b75466 --- /dev/null +++ b/sei-db/state_db/sc/flatkv/store_read_test.go @@ -0,0 +1,332 @@ +package flatkv + +import ( + "testing" + + "github.com/sei-protocol/sei-chain/sei-db/common/evm" + "github.com/sei-protocol/sei-chain/sei-db/proto" + iavl "github.com/sei-protocol/sei-chain/sei-iavl/proto" + "github.com/stretchr/testify/require" +) + +// ============================================================================= +// Get, Has, and Pending Writes +// ============================================================================= + +func TestStoreGetPendingWrites(t *testing.T) { + s := setupTestStore(t) + defer s.Close() + + addr := Address{0x11} + slot := Slot{0x22} + value := []byte{0x33} + key := memiavlStorageKey(addr, slot) + + // No data initially + _, found := s.Get(key) + require.False(t, found) + + // Apply changeset (adds to pending writes) + cs := makeChangeSet(key, value, false) + require.NoError(t, s.ApplyChangeSets([]*proto.NamedChangeSet{cs})) + + // Should be readable from pending writes + got, found := s.Get(key) + require.True(t, found) + require.Equal(t, value, got) + + // Commit + commitAndCheck(t, s) + + // Should still be readable after commit + got, found = s.Get(key) + require.True(t, found) + require.Equal(t, value, got) +} + +func TestStoreGetPendingDelete(t *testing.T) { + s := setupTestStore(t) + defer s.Close() + + addr := Address{0x44} + slot := Slot{0x55} + key := memiavlStorageKey(addr, slot) + + // Write and commit + cs1 := makeChangeSet(key, []byte{0x66}, false) + require.NoError(t, s.ApplyChangeSets([]*proto.NamedChangeSet{cs1})) + commitAndCheck(t, s) + + // Verify exists + _, found := s.Get(key) + require.True(t, found) + + // Apply delete (pending) + cs2 := makeChangeSet(key, nil, true) + require.NoError(t, s.ApplyChangeSets([]*proto.NamedChangeSet{cs2})) + + // Should not be found (pending delete) + _, found = s.Get(key) + require.False(t, found) + + // Commit delete + commitAndCheck(t, s) + + // Still should not be found + _, found = s.Get(key) + require.False(t, found) +} + +func TestStoreGetNonStorageKeys(t *testing.T) { + s := setupTestStore(t) + defer s.Close() + + addr := Address{0x77} + + // Non-storage keys should return not found (before write) + nonStorageKeys := [][]byte{ + evm.BuildMemIAVLEVMKey(evm.EVMKeyNonce, addr[:]), + evm.BuildMemIAVLEVMKey(evm.EVMKeyCodeHash, addr[:]), + evm.BuildMemIAVLEVMKey(evm.EVMKeyCode, addr[:]), + } + + for _, key := range nonStorageKeys { + _, found := s.Get(key) + require.False(t, found, "non-storage keys should not be found before write") + } +} + +func TestStoreHas(t *testing.T) { + s := setupTestStore(t) + defer s.Close() + + addr := Address{0x88} + slot := Slot{0x99} + key := memiavlStorageKey(addr, slot) + + // Initially not found + require.False(t, s.Has(key)) + + // Write and commit + cs := makeChangeSet(key, []byte{0xAA}, false) + require.NoError(t, s.ApplyChangeSets([]*proto.NamedChangeSet{cs})) + commitAndCheck(t, s) + + // Now should exist + require.True(t, s.Has(key)) +} + +// ============================================================================= +// Delete +// ============================================================================= + +func TestStoreDelete(t *testing.T) { + s := setupTestStore(t) + defer s.Close() + + addr := Address{0x55} + slot := Slot{0x66} + key := memiavlStorageKey(addr, slot) + + // Write + cs1 := makeChangeSet(key, []byte{0x77}, false) + require.NoError(t, s.ApplyChangeSets([]*proto.NamedChangeSet{cs1})) + commitAndCheck(t, s) + + // Verify exists + got, found := s.Get(key) + require.True(t, found) + require.Equal(t, []byte{0x77}, got) + + // Delete + cs2 := makeChangeSet(key, nil, true) + require.NoError(t, s.ApplyChangeSets([]*proto.NamedChangeSet{cs2})) + commitAndCheck(t, s) + + // Should not exist + _, found = s.Get(key) + require.False(t, found) +} + +// ============================================================================= +// Iterator +// ============================================================================= + +func TestStoreIteratorEmpty(t *testing.T) { + s := setupTestStore(t) + defer s.Close() + + // Empty store + iter := s.Iterator(nil, nil) + defer iter.Close() + + require.False(t, iter.Valid(), "empty store should have invalid iterator") +} + +func TestStoreIteratorSingleKey(t *testing.T) { + s := setupTestStore(t) + defer s.Close() + + addr := Address{0xAA} + slot := Slot{0xBB} + value := []byte{0xCC} + memiavlKey := memiavlStorageKey(addr, slot) + internalKey := StorageKey(addr, slot) // addr(20) || slot(32) + + cs := makeChangeSet(memiavlKey, value, false) + require.NoError(t, s.ApplyChangeSets([]*proto.NamedChangeSet{cs})) + commitAndCheck(t, s) + + // Iterate all + iter := s.Iterator(nil, nil) + defer iter.Close() + + require.True(t, iter.First()) + require.True(t, iter.Valid()) + require.Equal(t, internalKey, iter.Key()) // internal key format + require.Equal(t, value, iter.Value()) + + // Only one key + iter.Next() + require.False(t, iter.Valid()) +} + +func TestStoreIteratorMultipleKeys(t *testing.T) { + s := setupTestStore(t) + defer s.Close() + + addr := Address{0xDD} + + // Write multiple slots + entries := []struct { + slot Slot + value byte + }{ + {Slot{0x01}, 0xAA}, + {Slot{0x02}, 0xBB}, + {Slot{0x03}, 0xCC}, + } + + pairs := make([]*iavl.KVPair, len(entries)) + for i, e := range entries { + key := memiavlStorageKey(addr, e.slot) + pairs[i] = &iavl.KVPair{Key: key, Value: []byte{e.value}} + } + + cs := &proto.NamedChangeSet{ + Name: "test", + Changeset: iavl.ChangeSet{ + Pairs: pairs, + }, + } + + require.NoError(t, s.ApplyChangeSets([]*proto.NamedChangeSet{cs})) + commitAndCheck(t, s) + + // Iterate all + iter := s.Iterator(nil, nil) + defer iter.Close() + + count := 0 + for iter.First(); iter.Valid(); iter.Next() { + count++ + require.NotNil(t, iter.Key()) + require.NotNil(t, iter.Value()) + } + require.Equal(t, len(entries), count) +} + +func TestStoreIteratorNonStorageKeys(t *testing.T) { + s := setupTestStore(t) + defer s.Close() + + // Iterating non-storage keys should return empty iterator (Phase 1) + addr := Address{0xCC} + nonceKey := evm.BuildMemIAVLEVMKey(evm.EVMKeyNonce, addr[:]) + + iter := s.Iterator(nonceKey, PrefixEnd(nonceKey)) + defer iter.Close() + + require.False(t, iter.Valid(), "non-storage key iteration should be empty in Phase 1") +} + +// ============================================================================= +// Prefix Iterator +// ============================================================================= + +func TestStoreStoragePrefixIteration(t *testing.T) { + s := setupTestStore(t) + defer s.Close() + + addr := Address{0xAB} + + // Write multiple slots + for i := byte(1); i <= 3; i++ { + slot := Slot{i} + key := memiavlStorageKey(addr, slot) + cs := makeChangeSet(key, []byte{i * 10}, false) + require.NoError(t, s.ApplyChangeSets([]*proto.NamedChangeSet{cs})) + } + commitAndCheck(t, s) + + // Iterate by address prefix + prefix := append(evm.StateKeyPrefix(), addr[:]...) + iter := s.IteratorByPrefix(prefix) + defer iter.Close() + + count := 0 + for iter.First(); iter.Valid(); iter.Next() { + count++ + require.NotNil(t, iter.Key()) + require.NotNil(t, iter.Value()) + } + require.Equal(t, 3, count) +} + +func TestStoreIteratorByPrefixAddress(t *testing.T) { + s := setupTestStore(t) + defer s.Close() + + addr1 := Address{0xAA} + addr2 := Address{0xBB} + + // Write slots for addr1 + for i := byte(1); i <= 3; i++ { + slot := Slot{i} + key := memiavlStorageKey(addr1, slot) + cs := makeChangeSet(key, []byte{i * 10}, false) + require.NoError(t, s.ApplyChangeSets([]*proto.NamedChangeSet{cs})) + } + + // Write slots for addr2 + for i := byte(1); i <= 2; i++ { + slot := Slot{i} + key := memiavlStorageKey(addr2, slot) + cs := makeChangeSet(key, []byte{i * 20}, false) + require.NoError(t, s.ApplyChangeSets([]*proto.NamedChangeSet{cs})) + } + + commitAndCheck(t, s) + + // Iterate by addr1 prefix + prefix1 := append(evm.StateKeyPrefix(), addr1[:]...) + iter1 := s.IteratorByPrefix(prefix1) + defer iter1.Close() + + count1 := 0 + for iter1.First(); iter1.Valid(); iter1.Next() { + count1++ + } + require.Equal(t, 3, count1, "should find 3 slots for addr1") + + // Iterate by addr2 prefix + prefix2 := append(evm.StateKeyPrefix(), addr2[:]...) + iter2 := s.IteratorByPrefix(prefix2) + defer iter2.Close() + + count2 := 0 + for iter2.First(); iter2.Valid(); iter2.Next() { + count2++ + } + require.Equal(t, 2, count2, "should find 2 slots for addr2") +} diff --git a/sei-db/state_db/sc/flatkv/store_test.go b/sei-db/state_db/sc/flatkv/store_test.go new file mode 100644 index 0000000000..3c6c9f463c --- /dev/null +++ b/sei-db/state_db/sc/flatkv/store_test.go @@ -0,0 +1,438 @@ +package flatkv + +import ( + "testing" + + "github.com/sei-protocol/sei-chain/sei-db/common/evm" + "github.com/sei-protocol/sei-chain/sei-db/db_engine" + "github.com/sei-protocol/sei-chain/sei-db/db_engine/pebbledb" + "github.com/sei-protocol/sei-chain/sei-db/proto" + iavl "github.com/sei-protocol/sei-chain/sei-iavl/proto" + "github.com/stretchr/testify/require" +) + +// ============================================================================= +// Interface Compliance Tests +// ============================================================================= + +// TestCommitStoreImplementsStore verifies that CommitStore implements flatkv.Store +func TestCommitStoreImplementsStore(t *testing.T) { + // Compile-time check is in store.go: var _ Store = (*CommitStore)(nil) + // This test verifies runtime behavior of interface methods + + s := setupTestStore(t) + defer s.Close() + + // Verify Store interface methods + require.Equal(t, int64(0), s.Version()) + require.NotNil(t, s.RootHash()) + require.Len(t, s.RootHash(), 32) +} + +// ============================================================================= +// Test Helpers +// ============================================================================= + +// memiavlStorageKey builds a memiavl-format storage key for testing external API. +func memiavlStorageKey(addr Address, slot Slot) []byte { + internal := StorageKey(addr, slot) + return evm.BuildMemIAVLEVMKey(evm.EVMKeyStorage, internal) +} + +// makeChangeSet creates a changeset +func makeChangeSet(key, value []byte, delete bool) *proto.NamedChangeSet { + return &proto.NamedChangeSet{ + Name: "test", + Changeset: iavl.ChangeSet{ + Pairs: []*iavl.KVPair{ + {Key: key, Value: value, Delete: delete}, + }, + }, + } +} + +// setupTestDB creates a temporary PebbleDB for testing +func setupTestDB(t *testing.T) db_engine.DB { + t.Helper() + dir := t.TempDir() + db, err := pebbledb.Open(dir, db_engine.OpenOptions{}) + require.NoError(t, err) + return db +} + +// setupTestStore creates a minimal test store +func setupTestStore(t *testing.T) *CommitStore { + t.Helper() + dir := t.TempDir() + s := NewCommitStore(dir, nil, DefaultConfig()) + _, err := s.LoadVersion(0, false) + require.NoError(t, err) + return s +} + +// setupTestStoreWithConfig creates a test store with custom config +func setupTestStoreWithConfig(t *testing.T, cfg Config) *CommitStore { + t.Helper() + dir := t.TempDir() + s := NewCommitStore(dir, nil, cfg) + _, err := s.LoadVersion(0, false) + require.NoError(t, err) + return s +} + +// commitAndCheck commits and asserts no error, returns the version +func commitAndCheck(t *testing.T, s *CommitStore) int64 { + t.Helper() + v, err := s.Commit() + require.NoError(t, err) + return v +} + +// ============================================================================= +// Basic Store Operations +// ============================================================================= + +func TestStoreOpenClose(t *testing.T) { + dir := t.TempDir() + s := NewCommitStore(dir, nil, DefaultConfig()) + _, err := s.LoadVersion(0, false) + require.NoError(t, err) + + require.NoError(t, s.Close()) +} + +func TestStoreClose(t *testing.T) { + dir := t.TempDir() + s := NewCommitStore(dir, nil, DefaultConfig()) + _, err := s.LoadVersion(0, false) + require.NoError(t, err) + + // Close should succeed + require.NoError(t, s.Close()) + + // Double close should not panic (idempotent) + require.NoError(t, s.Close()) +} + +// ============================================================================= +// Apply and Commit +// ============================================================================= + +func TestStoreCommitVersionAutoIncrement(t *testing.T) { + s := setupTestStore(t) + defer s.Close() + + addr := Address{0xAA} + slot := Slot{0xBB} + key := memiavlStorageKey(addr, slot) + + cs := makeChangeSet(key, []byte{0xCC}, false) + + // Initial version is 0 + require.Equal(t, int64(0), s.Version()) + + // First commit should return version 1 + require.NoError(t, s.ApplyChangeSets([]*proto.NamedChangeSet{cs})) + v1, err := s.Commit() + require.NoError(t, err) + require.Equal(t, int64(1), v1) + require.Equal(t, int64(1), s.Version()) + + // Second commit should return version 2 + require.NoError(t, s.ApplyChangeSets([]*proto.NamedChangeSet{cs})) + v2, err := s.Commit() + require.NoError(t, err) + require.Equal(t, int64(2), v2) + require.Equal(t, int64(2), s.Version()) + + // Third commit should return version 3 + require.NoError(t, s.ApplyChangeSets([]*proto.NamedChangeSet{cs})) + v3, err := s.Commit() + require.NoError(t, err) + require.Equal(t, int64(3), v3) + require.Equal(t, int64(3), s.Version()) +} + +func TestStoreApplyAndCommit(t *testing.T) { + s := setupTestStore(t) + defer s.Close() + + addr := Address{0x11} + slot := Slot{0x22} + value := []byte{0x33} + key := memiavlStorageKey(addr, slot) + + cs := makeChangeSet(key, value, false) + + // Apply but not commit - should be readable from pending writes + require.NoError(t, s.ApplyChangeSets([]*proto.NamedChangeSet{cs})) + got, found := s.Get(key) + require.True(t, found, "should be readable from pending writes") + require.Equal(t, value, got) + + // Commit + commitAndCheck(t, s) + + // Still should be readable after commit + got, found = s.Get(key) + require.True(t, found) + require.Equal(t, value, got) +} + +func TestStoreMultipleWrites(t *testing.T) { + s := setupTestStore(t) + defer s.Close() + + addr := Address{0x44} + entries := []struct { + slot Slot + value byte + }{ + {Slot{0x01}, 0xAA}, + {Slot{0x02}, 0xBB}, + {Slot{0x03}, 0xCC}, + } + + // Create multiple pairs in one changeset + pairs := make([]*iavl.KVPair, len(entries)) + for i, e := range entries { + key := memiavlStorageKey(addr, e.slot) + pairs[i] = &iavl.KVPair{Key: key, Value: []byte{e.value}} + } + + cs := &proto.NamedChangeSet{ + Name: "test", + Changeset: iavl.ChangeSet{ + Pairs: pairs, + }, + } + + require.NoError(t, s.ApplyChangeSets([]*proto.NamedChangeSet{cs})) + commitAndCheck(t, s) + + // Verify all entries + for _, e := range entries { + key := memiavlStorageKey(addr, e.slot) + got, found := s.Get(key) + require.True(t, found) + require.Equal(t, []byte{e.value}, got) + } +} + +func TestStoreEmptyChangesets(t *testing.T) { + s := setupTestStore(t) + defer s.Close() + + // Empty changeset should not cause issues + emptyCS := &proto.NamedChangeSet{ + Name: "empty", + Changeset: iavl.ChangeSet{Pairs: nil}, + } + + require.NoError(t, s.ApplyChangeSets([]*proto.NamedChangeSet{emptyCS})) + commitAndCheck(t, s) + + require.Equal(t, int64(1), s.Version()) +} + +func TestStoreClearsPendingAfterCommit(t *testing.T) { + s := setupTestStore(t) + defer s.Close() + + addr := Address{0xAA} + slot := Slot{0xBB} + key := memiavlStorageKey(addr, slot) + + cs := makeChangeSet(key, []byte{0xCC}, false) + require.NoError(t, s.ApplyChangeSets([]*proto.NamedChangeSet{cs})) + + // Should have pending writes + require.Len(t, s.storageWrites, 1) + require.Len(t, s.pendingChangeSets, 1) + + commitAndCheck(t, s) + + // Should be cleared after commit + require.Len(t, s.storageWrites, 0) + require.Len(t, s.pendingChangeSets, 0) +} + +// ============================================================================= +// Versioning and Persistence +// ============================================================================= + +func TestStoreVersioning(t *testing.T) { + s := setupTestStore(t) + defer s.Close() + + addr := Address{0x88} + slot := Slot{0x99} + key := memiavlStorageKey(addr, slot) + + // Version 1 + cs1 := makeChangeSet(key, []byte{0x01}, false) + require.NoError(t, s.ApplyChangeSets([]*proto.NamedChangeSet{cs1})) + commitAndCheck(t, s) + + require.Equal(t, int64(1), s.Version()) + + // Version 2 with updated value + cs2 := makeChangeSet(key, []byte{0x02}, false) + require.NoError(t, s.ApplyChangeSets([]*proto.NamedChangeSet{cs2})) + commitAndCheck(t, s) + + require.Equal(t, int64(2), s.Version()) + + // Latest value should be from version 2 + got, found := s.Get(key) + require.True(t, found) + require.Equal(t, []byte{0x02}, got) +} + +func TestStorePersistence(t *testing.T) { + dir := t.TempDir() + + addr := Address{0xDD} + slot := Slot{0xEE} + value := []byte{0xFF} + key := memiavlStorageKey(addr, slot) + + // Write and close + s1 := NewCommitStore(dir, nil, DefaultConfig()) + _, err := s1.LoadVersion(0, false) + require.NoError(t, err) + + cs := makeChangeSet(key, value, false) + require.NoError(t, s1.ApplyChangeSets([]*proto.NamedChangeSet{cs})) + commitAndCheck(t, s1) + require.NoError(t, s1.Close()) + + // Reopen and verify + s2 := NewCommitStore(dir, nil, DefaultConfig()) + _, err = s2.LoadVersion(0, false) + require.NoError(t, err) + defer s2.Close() + + got, found := s2.Get(key) + require.True(t, found) + require.Equal(t, value, got) + + require.Equal(t, int64(1), s2.Version()) +} + +// ============================================================================= +// RootHash (LtHash) +// ============================================================================= + +func TestStoreRootHashChanges(t *testing.T) { + s := setupTestStore(t) + defer s.Close() + + // Initial hash + hash1 := s.RootHash() + require.NotNil(t, hash1) + require.Equal(t, 32, len(hash1)) // Blake3-256 + + // Apply changeset + addr := Address{0xAB} + slot := Slot{0xCD} + key := memiavlStorageKey(addr, slot) + + cs := makeChangeSet(key, []byte{0xEF}, false) + require.NoError(t, s.ApplyChangeSets([]*proto.NamedChangeSet{cs})) + + // Working hash should change + hash2 := s.RootHash() + require.NotEqual(t, hash1, hash2) + + commitAndCheck(t, s) + + // Committed hash should match working hash + hash3 := s.RootHash() + require.Equal(t, hash2, hash3) +} + +func TestStoreRootHashChangesOnApply(t *testing.T) { + s := setupTestStore(t) + defer s.Close() + + // Initial hash + hash1 := s.RootHash() + require.NotNil(t, hash1) + require.Equal(t, 32, len(hash1)) // Blake3-256 + + // Apply changeset + addr := Address{0xEE} + slot := Slot{0xFF} + key := memiavlStorageKey(addr, slot) + + cs := makeChangeSet(key, []byte{0x11}, false) + require.NoError(t, s.ApplyChangeSets([]*proto.NamedChangeSet{cs})) + + // Working hash should change + hash2 := s.RootHash() + require.NotEqual(t, hash1, hash2, "hash should change after ApplyChangeSets") +} + +func TestStoreRootHashStableAfterCommit(t *testing.T) { + s := setupTestStore(t) + defer s.Close() + + addr := Address{0x12} + slot := Slot{0x34} + key := memiavlStorageKey(addr, slot) + + cs := makeChangeSet(key, []byte{0x56}, false) + require.NoError(t, s.ApplyChangeSets([]*proto.NamedChangeSet{cs})) + + // Get working hash + workingHash := s.RootHash() + + commitAndCheck(t, s) + + // Committed hash should match working hash + committedHash := s.RootHash() + require.Equal(t, workingHash, committedHash) +} + +// ============================================================================= +// Exporter (Not Implemented - placeholder for state-sync) +// ============================================================================= + +func TestStoreExporterNotImplemented(t *testing.T) { + s := setupTestStore(t) + defer s.Close() + + // Exporter returns a placeholder that indicates not implemented + exporter, err := s.Exporter(0) + require.NoError(t, err) + require.NotNil(t, exporter) + defer exporter.Close() + + // Next() should return not implemented error + _, _, err = exporter.Next() + require.Error(t, err) + require.Contains(t, err.Error(), "not implemented") +} + +// ============================================================================= +// Lifecycle (WriteSnapshot, Rollback) +// ============================================================================= + +func TestStoreWriteSnapshotNotImplemented(t *testing.T) { + s := setupTestStore(t) + defer s.Close() + + err := s.WriteSnapshot(t.TempDir()) + require.Error(t, err) + require.Contains(t, err.Error(), "not implemented") +} + +func TestStoreRollbackNoOp(t *testing.T) { + s := setupTestStore(t) + defer s.Close() + + // Rollback is currently a no-op - doesn't error + err := s.Rollback(1) + require.NoError(t, err) +} diff --git a/sei-db/state_db/sc/flatkv/store_write.go b/sei-db/state_db/sc/flatkv/store_write.go new file mode 100644 index 0000000000..1f1f82b7c9 --- /dev/null +++ b/sei-db/state_db/sc/flatkv/store_write.go @@ -0,0 +1,378 @@ +package flatkv + +import ( + "encoding/binary" + "fmt" + + "github.com/sei-protocol/sei-chain/sei-db/common/evm" + db_engine "github.com/sei-protocol/sei-chain/sei-db/db_engine" + "github.com/sei-protocol/sei-chain/sei-db/proto" + "github.com/sei-protocol/sei-chain/sei-db/state_db/sc/flatkv/lthash" +) + +// ApplyChangeSets buffers EVM changesets and updates LtHash. +// +// LtHash is computed based on actual storage format (internal keys): +// - storageDB: key=addr||slot, value=storage_value +// - accountDB: key=addr, value=AccountValue (balance(32)||nonce(8)||codehash(32) +// - codeDB: key=addr, value=bytecode +func (s *CommitStore) ApplyChangeSets(cs []*proto.NamedChangeSet) error { + // Save original changesets for changelog + s.pendingChangeSets = append(s.pendingChangeSets, cs...) + + // Collect LtHash pairs per DB (using internal key format) + var storagePairs []lthash.KVPairWithLastValue + var codePairs []lthash.KVPairWithLastValue + // Account pairs are collected at the end after all account changes are processed + + // Track which accounts were modified (for LtHash computation) + modifiedAccounts := make(map[string]bool) + + for _, namedCS := range cs { + if namedCS.Changeset.Pairs == nil { + continue + } + + for _, pair := range namedCS.Changeset.Pairs { + // Parse memiavl key to determine type + kind, keyBytes := evm.ParseEVMKey(pair.Key) + if kind == evm.EVMKeyUnknown { + // Skip non-EVM keys silently + continue + } + + // Route to appropriate DB based on key type + switch kind { + case evm.EVMKeyStorage: + // Get old value for LtHash + oldValue, err := s.getStorageValue(keyBytes) + if err != nil { + return fmt.Errorf("failed to get storage value: %w", err) + } + + // Storage: keyBytes = addr(20) || slot(32) + keyStr := string(keyBytes) + if pair.Delete { + s.storageWrites[keyStr] = &pendingKVWrite{ + key: keyBytes, + isDelete: true, + } + } else { + s.storageWrites[keyStr] = &pendingKVWrite{ + key: keyBytes, + value: pair.Value, + } + } + + // LtHash pair: internal key directly + storagePairs = append(storagePairs, lthash.KVPairWithLastValue{ + Key: keyBytes, + Value: pair.Value, + LastValue: oldValue, + Delete: pair.Delete, + }) + + case evm.EVMKeyNonce, evm.EVMKeyCodeHash: + // Account data: keyBytes = addr(20) + addr, ok := AddressFromBytes(keyBytes) + if !ok { + return fmt.Errorf("invalid address length %d for key kind %d", len(keyBytes), kind) + } + addrStr := string(addr[:]) + + // Track this account as modified for LtHash + modifiedAccounts[addrStr] = true + // Get or create pending account write + paw := s.accountWrites[addrStr] + if paw == nil { + // Load existing value from DB + existingValue, err := s.getAccountValue(addr) + if err != nil { + return fmt.Errorf("failed to load existing account value: %w", err) + } + paw = &pendingAccountWrite{ + addr: addr, + value: existingValue, + } + s.accountWrites[addrStr] = paw + } + + if pair.Delete { + if kind == evm.EVMKeyNonce { + paw.value.Nonce = 0 + } else { + paw.value.CodeHash = CodeHash{} + } + } else { + if kind == evm.EVMKeyNonce { + if len(pair.Value) != NonceLen { + return fmt.Errorf("invalid nonce value length: got %d, expected %d", len(pair.Value), NonceLen) + } + paw.value.Nonce = binary.BigEndian.Uint64(pair.Value) + } else { + if len(pair.Value) != CodeHashLen { + return fmt.Errorf("invalid codehash value length: got %d, expected %d", len(pair.Value), CodeHashLen) + } + copy(paw.value.CodeHash[:], pair.Value) + } + } + + case evm.EVMKeyCode: + // Get old value for LtHash + oldValue, err := s.getCodeValue(keyBytes) + if err != nil { + return fmt.Errorf("failed to get code value: %w", err) + } + + // Code: keyBytes = addr(20) - per x/evm/types/keys.go + keyStr := string(keyBytes) + if pair.Delete { + s.codeWrites[keyStr] = &pendingKVWrite{ + key: keyBytes, + isDelete: true, + } + } else { + s.codeWrites[keyStr] = &pendingKVWrite{ + key: keyBytes, + value: pair.Value, + } + } + + // LtHash pair: internal key directly + codePairs = append(codePairs, lthash.KVPairWithLastValue{ + Key: keyBytes, + Value: pair.Value, + LastValue: oldValue, + Delete: pair.Delete, + }) + + default: + // EVMKeyLegacy (including CodeSize) and other unhandled kinds + // are silently ignored — FlatKV only stores optimized key types. + } + } + } + + // Build account LtHash pairs based on full AccountValue changes + accountPairs := make([]lthash.KVPairWithLastValue, 0, len(modifiedAccounts)) + for addrStr := range modifiedAccounts { + addr, ok := AddressFromBytes([]byte(addrStr)) + if !ok { + return fmt.Errorf("invalid address in modifiedAccounts: %x", addrStr) + } + + // Get old AccountValue from DB (committed state) + oldAV, err := s.getAccountValueFromDB(addr) + if err != nil { + return fmt.Errorf("failed to get old account value for addr %x: %w", addr, err) + } + oldValue := oldAV.Encode() + + // Get new AccountValue (from pending writes or DB) + var newValue []byte + var isDelete bool + if paw, ok := s.accountWrites[addrStr]; ok { + newValue = paw.value.Encode() + isDelete = paw.isDelete + } else { + // No pending write means no change (shouldn't happen, but be safe) + continue + } + + accountPairs = append(accountPairs, lthash.KVPairWithLastValue{ + Key: AccountKey(addr), + Value: newValue, + LastValue: oldValue, + Delete: isDelete, + }) + } + + // Combine all pairs and update working LtHash + allPairs := append(storagePairs, accountPairs...) + allPairs = append(allPairs, codePairs...) + + if len(allPairs) > 0 { + newLtHash, _ := lthash.ComputeLtHash(s.workingLtHash, allPairs) + s.workingLtHash = newLtHash + } + + return nil +} + +// Commit persists buffered writes and advances the version. +// Protocol: WAL → per-DB batch (with LocalMeta) → flush → update metaDB. +// On crash, catchup replays WAL to recover incomplete commits. +func (s *CommitStore) Commit() (int64, error) { + // Auto-increment version + version := s.committedVersion + 1 + + // Step 1: Write Changelog (WAL) - source of truth (always sync) + changelogEntry := proto.ChangelogEntry{ + Version: version, + Changesets: s.pendingChangeSets, + } + if err := s.changelog.Write(changelogEntry); err != nil { + return 0, fmt.Errorf("changelog write: %w", err) + } + + // Step 2: Commit to each DB (data + LocalMeta.CommittedVersion atomically) + if err := s.commitBatches(version); err != nil { + return 0, fmt.Errorf("db commit: %w", err) + } + + // Step 3: Update in-memory committed state + s.committedVersion = version + s.committedLtHash = s.workingLtHash.Clone() + + // Step 4: Flush data DBs if not using fsync (ensures data is on disk before metaDB update) + if !s.config.Fsync { + if err := s.flushAllDBs(); err != nil { + return 0, fmt.Errorf("flush: %w", err) + } + } + + // Step 5: Persist global metadata to metadata DB (always every block) + if err := s.commitGlobalMetadata(version, s.committedLtHash); err != nil { + return 0, fmt.Errorf("metadata DB commit: %w", err) + } + + // Step 6: Clear pending buffers + s.clearPendingWrites() + + s.log.Info("Committed version", "version", version) + return version, nil +} + +// flushAllDBs flushes all data DBs to ensure data is on disk. +func (s *CommitStore) flushAllDBs() error { + if err := s.accountDB.Flush(); err != nil { + return fmt.Errorf("accountDB flush: %w", err) + } + if err := s.codeDB.Flush(); err != nil { + return fmt.Errorf("codeDB flush: %w", err) + } + if err := s.storageDB.Flush(); err != nil { + return fmt.Errorf("storageDB flush: %w", err) + } + return nil +} + +// clearPendingWrites clears all pending write buffers +func (s *CommitStore) clearPendingWrites() { + s.accountWrites = make(map[string]*pendingAccountWrite) + s.codeWrites = make(map[string]*pendingKVWrite) + s.storageWrites = make(map[string]*pendingKVWrite) + s.pendingChangeSets = make([]*proto.NamedChangeSet, 0) +} + +// commitBatches commits pending writes to their respective DBs atomically. +// Each DB batch includes LocalMeta update for crash recovery. +// Also called by catchup to replay WAL without re-writing changelog. +func (s *CommitStore) commitBatches(version int64) error { + syncOpt := db_engine.WriteOptions{Sync: s.config.Fsync} + + // Commit to accountDB + // accountDB uses AccountValue structure: key=addr(20), value=balance(32)||nonce(8)||codehash(32) + if len(s.accountWrites) > 0 || version > s.localMeta[accountDBDir].CommittedVersion { + batch := s.accountDB.NewBatch() + defer func() { _ = batch.Close() }() + + for _, paw := range s.accountWrites { + key := AccountKey(paw.addr) + if paw.isDelete { + if err := batch.Delete(key); err != nil { + return fmt.Errorf("accountDB delete: %w", err) + } + } else { + // Encode AccountValue and store with addr as key + encoded := EncodeAccountValue(paw.value) + if err := batch.Set(key, encoded); err != nil { + return fmt.Errorf("accountDB set: %w", err) + } + } + } + + // Update local meta atomically with data (same batch) + newLocalMeta := &LocalMeta{ + CommittedVersion: version, + } + if err := batch.Set(DBLocalMetaKey, MarshalLocalMeta(newLocalMeta)); err != nil { + return fmt.Errorf("accountDB local meta set: %w", err) + } + + if err := batch.Commit(syncOpt); err != nil { + return fmt.Errorf("accountDB commit: %w", err) + } + + // Update in-memory local meta after successful commit + s.localMeta[accountDBDir] = newLocalMeta + } + + // Commit to codeDB + if len(s.codeWrites) > 0 || version > s.localMeta[codeDBDir].CommittedVersion { + batch := s.codeDB.NewBatch() + defer func() { _ = batch.Close() }() + + for _, pw := range s.codeWrites { + if pw.isDelete { + if err := batch.Delete(pw.key); err != nil { + return fmt.Errorf("codeDB delete: %w", err) + } + } else { + if err := batch.Set(pw.key, pw.value); err != nil { + return fmt.Errorf("codeDB set: %w", err) + } + } + } + + // Update local meta atomically with data (same batch) + newLocalMeta := &LocalMeta{ + CommittedVersion: version, + } + if err := batch.Set(DBLocalMetaKey, MarshalLocalMeta(newLocalMeta)); err != nil { + return fmt.Errorf("codeDB local meta set: %w", err) + } + + if err := batch.Commit(syncOpt); err != nil { + return fmt.Errorf("codeDB commit: %w", err) + } + + // Update in-memory local meta after successful commit + s.localMeta[codeDBDir] = newLocalMeta + } + + // Commit to storageDB + if len(s.storageWrites) > 0 || version > s.localMeta[storageDBDir].CommittedVersion { + batch := s.storageDB.NewBatch() + defer func() { _ = batch.Close() }() + + for _, pw := range s.storageWrites { + if pw.isDelete { + if err := batch.Delete(pw.key); err != nil { + return fmt.Errorf("storageDB delete: %w", err) + } + } else { + if err := batch.Set(pw.key, pw.value); err != nil { + return fmt.Errorf("storageDB set: %w", err) + } + } + } + + // Update local meta atomically with data (same batch) + newLocalMeta := &LocalMeta{ + CommittedVersion: version, + } + if err := batch.Set(DBLocalMetaKey, MarshalLocalMeta(newLocalMeta)); err != nil { + return fmt.Errorf("storageDB local meta set: %w", err) + } + + if err := batch.Commit(syncOpt); err != nil { + return fmt.Errorf("storageDB commit: %w", err) + } + + // Update in-memory local meta after successful commit + s.localMeta[storageDBDir] = newLocalMeta + } + + return nil +} diff --git a/sei-db/state_db/sc/flatkv/store_write_test.go b/sei-db/state_db/sc/flatkv/store_write_test.go new file mode 100644 index 0000000000..1f7b4efc5a --- /dev/null +++ b/sei-db/state_db/sc/flatkv/store_write_test.go @@ -0,0 +1,407 @@ +package flatkv + +import ( + "testing" + + "github.com/sei-protocol/sei-chain/sei-db/common/evm" + "github.com/sei-protocol/sei-chain/sei-db/proto" + iavl "github.com/sei-protocol/sei-chain/sei-iavl/proto" + "github.com/stretchr/testify/require" +) + +// ============================================================================= +// Multi-DB Write (Account, Code, Storage) +// ============================================================================= + +func TestStoreNonStorageKeys(t *testing.T) { + s := setupTestStore(t) + defer s.Close() + + addr := Address{0x99} + codeHash := CodeHash{0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, + 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x00, + 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, + 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x00} + + // Write non-storage keys (now supported with AccountValue) + nonceKey := evm.BuildMemIAVLEVMKey(evm.EVMKeyNonce, addr[:]) + codeHashKey := evm.BuildMemIAVLEVMKey(evm.EVMKeyCodeHash, addr[:]) + + // Write nonce (8 bytes) + cs1 := makeChangeSet(nonceKey, []byte{0, 0, 0, 0, 0, 0, 0, 17}, false) + require.NoError(t, s.ApplyChangeSets([]*proto.NamedChangeSet{cs1})) + + // Write codehash (32 bytes) + cs2 := makeChangeSet(codeHashKey, codeHash[:], false) + require.NoError(t, s.ApplyChangeSets([]*proto.NamedChangeSet{cs2})) + + commitAndCheck(t, s) + + // Nonce should be found + nonceValue, found := s.Get(nonceKey) + require.True(t, found, "nonce should be found") + require.Equal(t, []byte{0, 0, 0, 0, 0, 0, 0, 17}, nonceValue) + + // CodeHash should be found + codeHashValue, found := s.Get(codeHashKey) + require.True(t, found, "codehash should be found") + require.Equal(t, codeHash[:], codeHashValue) +} + +func TestStoreWriteAllDBs(t *testing.T) { + s := setupTestStore(t) + defer s.Close() + + addr := Address{0x12, 0x34} + slot := Slot{0x56, 0x78} + + // Create changesets for all three key types + pairs := []*iavl.KVPair{ + // Storage key + { + Key: evm.BuildMemIAVLEVMKey(evm.EVMKeyStorage, StorageKey(addr, slot)), + Value: []byte{0x11, 0x22}, + }, + // Account nonce key + { + Key: evm.BuildMemIAVLEVMKey(evm.EVMKeyNonce, addr[:]), + Value: []byte{0, 0, 0, 0, 0, 0, 0, 42}, // nonce = 42 + }, + // Code key - keyed by address, not codeHash + { + Key: evm.BuildMemIAVLEVMKey(evm.EVMKeyCode, addr[:]), + Value: []byte{0x60, 0x60, 0x60}, // some bytecode + }, + } + + cs := &proto.NamedChangeSet{ + Name: "test", + Changeset: iavl.ChangeSet{ + Pairs: pairs, + }, + } + + require.NoError(t, s.ApplyChangeSets([]*proto.NamedChangeSet{cs})) + commitAndCheck(t, s) + + // Verify all three DBs have their LocalMeta updated to version 1 + require.Equal(t, int64(1), s.localMeta[storageDBDir].CommittedVersion, "storageDB should be at version 1") + require.Equal(t, int64(1), s.localMeta[accountDBDir].CommittedVersion, "accountDB should be at version 1") + require.Equal(t, int64(1), s.localMeta[codeDBDir].CommittedVersion, "codeDB should be at version 1") + + // Verify LocalMeta is persisted in each DB + storageMetaBytes, err := s.storageDB.Get(DBLocalMetaKey) + require.NoError(t, err) + storageMeta, err := UnmarshalLocalMeta(storageMetaBytes) + require.NoError(t, err) + require.Equal(t, int64(1), storageMeta.CommittedVersion) + + accountMetaBytes, err := s.accountDB.Get(DBLocalMetaKey) + require.NoError(t, err) + accountMeta, err := UnmarshalLocalMeta(accountMetaBytes) + require.NoError(t, err) + require.Equal(t, int64(1), accountMeta.CommittedVersion) + + codeMetaBytes, err := s.codeDB.Get(DBLocalMetaKey) + require.NoError(t, err) + codeMeta, err := UnmarshalLocalMeta(codeMetaBytes) + require.NoError(t, err) + require.Equal(t, int64(1), codeMeta.CommittedVersion) + + // Verify storage data was written + storageData, err := s.storageDB.Get(StorageKey(addr, slot)) + require.NoError(t, err) + require.Equal(t, []byte{0x11, 0x22}, storageData) + + // Verify account and code data was written + // Use Store.Get method which handles the kind prefix correctly + nonceKey := evm.BuildMemIAVLEVMKey(evm.EVMKeyNonce, addr[:]) + nonceValue, found := s.Get(nonceKey) + require.True(t, found, "Nonce should be found") + require.Equal(t, []byte{0, 0, 0, 0, 0, 0, 0, 42}, nonceValue) + + codeKey := evm.BuildMemIAVLEVMKey(evm.EVMKeyCode, addr[:]) + codeValue, found := s.Get(codeKey) + require.True(t, found, "Code should be found") + require.Equal(t, []byte{0x60, 0x60, 0x60}, codeValue) +} + +func TestStoreWriteEmptyCommit(t *testing.T) { + s := setupTestStore(t) + defer s.Close() + + // Commit version 1 with no writes + emptyCS := &proto.NamedChangeSet{ + Name: "empty", + Changeset: iavl.ChangeSet{Pairs: nil}, + } + require.NoError(t, s.ApplyChangeSets([]*proto.NamedChangeSet{emptyCS})) + commitAndCheck(t, s) + + // All DBs should have LocalMeta at version 1 + require.Equal(t, int64(1), s.localMeta[storageDBDir].CommittedVersion) + require.Equal(t, int64(1), s.localMeta[accountDBDir].CommittedVersion) + require.Equal(t, int64(1), s.localMeta[codeDBDir].CommittedVersion) + + // Commit version 2 with storage write only + addr := Address{0x99} + slot := Slot{0x88} + key := memiavlStorageKey(addr, slot) + cs := makeChangeSet(key, []byte{0x77}, false) + require.NoError(t, s.ApplyChangeSets([]*proto.NamedChangeSet{cs})) + commitAndCheck(t, s) + + // All DBs should have LocalMeta at version 2, even though only storage had data + require.Equal(t, int64(2), s.localMeta[storageDBDir].CommittedVersion) + require.Equal(t, int64(2), s.localMeta[accountDBDir].CommittedVersion) + require.Equal(t, int64(2), s.localMeta[codeDBDir].CommittedVersion) +} + +func TestStoreWriteAccountAndCode(t *testing.T) { + s := setupTestStore(t) + defer s.Close() + + addr1 := Address{0xAA} + addr2 := Address{0xBB} + + // Write account nonces and codes + // Note: Code is keyed by address (not codeHash) per x/evm/types/keys.go + pairs := []*iavl.KVPair{ + { + Key: evm.BuildMemIAVLEVMKey(evm.EVMKeyNonce, addr1[:]), + Value: []byte{0, 0, 0, 0, 0, 0, 0, 1}, // nonce = 1 + }, + { + Key: evm.BuildMemIAVLEVMKey(evm.EVMKeyNonce, addr2[:]), + Value: []byte{0, 0, 0, 0, 0, 0, 0, 2}, // nonce = 2 + }, + { + Key: evm.BuildMemIAVLEVMKey(evm.EVMKeyCode, addr1[:]), + Value: []byte{0x60, 0x80}, + }, + { + Key: evm.BuildMemIAVLEVMKey(evm.EVMKeyCode, addr2[:]), + Value: []byte{0x60, 0xA0}, + }, + } + + cs := &proto.NamedChangeSet{ + Name: "test", + Changeset: iavl.ChangeSet{ + Pairs: pairs, + }, + } + + require.NoError(t, s.ApplyChangeSets([]*proto.NamedChangeSet{cs})) + commitAndCheck(t, s) + + // Verify LocalMeta is updated in all DBs for version consistency + require.Equal(t, int64(1), s.localMeta[accountDBDir].CommittedVersion) + require.Equal(t, int64(1), s.localMeta[codeDBDir].CommittedVersion) + require.Equal(t, int64(1), s.localMeta[storageDBDir].CommittedVersion) + + // Verify account data was written + nonceKey1 := evm.BuildMemIAVLEVMKey(evm.EVMKeyNonce, addr1[:]) + nonce1, found := s.Get(nonceKey1) + require.True(t, found, "Nonce1 should be found") + require.Equal(t, []byte{0, 0, 0, 0, 0, 0, 0, 1}, nonce1) + + nonceKey2 := evm.BuildMemIAVLEVMKey(evm.EVMKeyNonce, addr2[:]) + nonce2, found := s.Get(nonceKey2) + require.True(t, found, "Nonce2 should be found") + require.Equal(t, []byte{0, 0, 0, 0, 0, 0, 0, 2}, nonce2) + + // Verify code data was written + codeKey1 := evm.BuildMemIAVLEVMKey(evm.EVMKeyCode, addr1[:]) + code1, found := s.Get(codeKey1) + require.True(t, found, "Code1 should be found") + require.Equal(t, []byte{0x60, 0x80}, code1) + + codeKey2 := evm.BuildMemIAVLEVMKey(evm.EVMKeyCode, addr2[:]) + code2, found := s.Get(codeKey2) + require.True(t, found, "Code2 should be found") + require.Equal(t, []byte{0x60, 0xA0}, code2) + + // Verify LtHash was updated (includes all keys) + hash := s.RootHash() + require.NotNil(t, hash) + require.Equal(t, 32, len(hash)) +} + +func TestStoreWriteDelete(t *testing.T) { + s := setupTestStore(t) + defer s.Close() + + addr := Address{0xCC} + slot := Slot{0xDD} + + // Write initial data + // Note: Code is keyed by address per x/evm/types/keys.go + pairs := []*iavl.KVPair{ + { + Key: evm.BuildMemIAVLEVMKey(evm.EVMKeyStorage, StorageKey(addr, slot)), + Value: []byte{0x11}, + }, + { + Key: evm.BuildMemIAVLEVMKey(evm.EVMKeyNonce, addr[:]), + Value: []byte{0, 0, 0, 0, 0, 0, 0, 1}, + }, + { + Key: evm.BuildMemIAVLEVMKey(evm.EVMKeyCode, addr[:]), + Value: []byte{0x60}, + }, + } + + cs1 := &proto.NamedChangeSet{ + Name: "write", + Changeset: iavl.ChangeSet{Pairs: pairs}, + } + require.NoError(t, s.ApplyChangeSets([]*proto.NamedChangeSet{cs1})) + commitAndCheck(t, s) + + // Delete storage and code (actual deletes) + // For account, "delete" means setting fields to zero in AccountValue + deletePairs := []*iavl.KVPair{ + { + Key: evm.BuildMemIAVLEVMKey(evm.EVMKeyStorage, StorageKey(addr, slot)), + Delete: true, + }, + { + Key: evm.BuildMemIAVLEVMKey(evm.EVMKeyNonce, addr[:]), + Delete: true, // Sets nonce to 0 in AccountValue + }, + { + Key: evm.BuildMemIAVLEVMKey(evm.EVMKeyCode, addr[:]), + Delete: true, + }, + } + + cs2 := &proto.NamedChangeSet{ + Name: "delete", + Changeset: iavl.ChangeSet{Pairs: deletePairs}, + } + require.NoError(t, s.ApplyChangeSets([]*proto.NamedChangeSet{cs2})) + commitAndCheck(t, s) + + // Verify storage is deleted + _, err := s.storageDB.Get(StorageKey(addr, slot)) + require.Error(t, err, "storage should be deleted") + + // Verify nonce is set to 0 (delete in AccountValue context) + nonceKeyDel := evm.BuildMemIAVLEVMKey(evm.EVMKeyNonce, addr[:]) + nonceValue, found := s.Get(nonceKeyDel) + require.True(t, found, "nonce entry should still exist but be zero") + require.Equal(t, []byte{0, 0, 0, 0, 0, 0, 0, 0}, nonceValue, "nonce should be 0 after delete") + + // Verify code is deleted + codeKeyDel := evm.BuildMemIAVLEVMKey(evm.EVMKeyCode, addr[:]) + _, found = s.Get(codeKeyDel) + require.False(t, found, "code should be deleted") + + // LocalMeta should still be at version 2 + require.Equal(t, int64(2), s.localMeta[storageDBDir].CommittedVersion) + require.Equal(t, int64(2), s.localMeta[accountDBDir].CommittedVersion) + require.Equal(t, int64(2), s.localMeta[codeDBDir].CommittedVersion) +} + +func TestAccountValueStorage(t *testing.T) { + s := setupTestStore(t) + defer s.Close() + + addr := Address{0xFF, 0xFF} + expectedCodeHash := CodeHash{0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB} + + // Write both Nonce and CodeHash for the same address + // AccountValue stores: balance(32) || nonce(8) || codehash(32) + pairs := []*iavl.KVPair{ + { + Key: evm.BuildMemIAVLEVMKey(evm.EVMKeyNonce, addr[:]), + Value: []byte{0, 0, 0, 0, 0, 0, 0, 42}, // nonce = 42 + }, + { + Key: evm.BuildMemIAVLEVMKey(evm.EVMKeyCodeHash, addr[:]), + Value: expectedCodeHash[:], // 32-byte codehash + }, + } + + cs := &proto.NamedChangeSet{ + Name: "test", + Changeset: iavl.ChangeSet{Pairs: pairs}, + } + + require.NoError(t, s.ApplyChangeSets([]*proto.NamedChangeSet{cs})) + + // AccountValue structure: one entry per address containing both nonce and codehash + require.Equal(t, 1, len(s.accountWrites), "should have 1 account write (AccountValue)") + + // Commit + commitAndCheck(t, s) + + // Verify AccountValue is stored in accountDB with addr as key + stored, err := s.accountDB.Get(addr[:]) + require.NoError(t, err) + require.NotNil(t, stored) + + // Decode and verify + av, err := DecodeAccountValue(stored) + require.NoError(t, err) + require.Equal(t, uint64(42), av.Nonce, "Nonce should be 42") + require.Equal(t, expectedCodeHash, av.CodeHash, "CodeHash should match") + require.Equal(t, Balance{}, av.Balance, "Balance should be zero") + + // Get method should return individual fields + nonceKey := evm.BuildMemIAVLEVMKey(evm.EVMKeyNonce, addr[:]) + nonceValue, found := s.Get(nonceKey) + require.True(t, found, "Nonce should be found") + require.Equal(t, []byte{0, 0, 0, 0, 0, 0, 0, 42}, nonceValue, "Nonce should be 42") + + codeHashKey := evm.BuildMemIAVLEVMKey(evm.EVMKeyCodeHash, addr[:]) + codeHashValue, found := s.Get(codeHashKey) + require.True(t, found, "CodeHash should be found") + require.Equal(t, expectedCodeHash[:], codeHashValue, "CodeHash should match") +} + +// ============================================================================= +// Fsync Config Tests +// ============================================================================= + +func TestStoreFsyncConfig(t *testing.T) { + t.Run("DefaultConfig", func(t *testing.T) { + dir := t.TempDir() + store := NewCommitStore(dir, nil, DefaultConfig()) + _, err := store.LoadVersion(0, false) + require.NoError(t, err) + defer store.Close() + + // Verify defaults + require.True(t, store.config.Fsync) + require.Equal(t, 0, store.config.AsyncWriteBuffer) + }) + + t.Run("FsyncDisabled", func(t *testing.T) { + dir := t.TempDir() + store := NewCommitStore(dir, nil, Config{ + Fsync: false, + }) + _, err := store.LoadVersion(0, false) + require.NoError(t, err) + defer store.Close() + + addr := Address{0xAA} + slot := Slot{0xBB} + key := memiavlStorageKey(addr, slot) + + // Write and commit with fsync disabled + cs := makeChangeSet(key, []byte{0xCC}, false) + require.NoError(t, store.ApplyChangeSets([]*proto.NamedChangeSet{cs})) + commitAndCheck(t, store) + + // Data should be readable + got, found := store.Get(key) + require.True(t, found) + require.Equal(t, []byte{0xCC}, got) + + // Version should be updated + require.Equal(t, int64(1), store.Version()) + }) +}