diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 46c184fd..f1ee3d5e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -2,42 +2,43 @@ name: build on: push: branches: [ "master" ] - # pull_request: - # branches: [ "master" ] + pull_request: + branches: [ "master", "dev" ] workflow_dispatch: +env: + GOLANG_PROTOBUF_REGISTRATION_CONFLICT: ignore + jobs: - run_build: - runs-on: ubuntu-latest - steps: - + build: + runs-on: ubuntu-latest + steps: + - name: clone repo uses: actions/checkout@v3 - + - name: download and install uses: actions/setup-go@v5 with: - go-version: '1.22.2' + go-version: '1.23.1' - - name: protobuff install - run: | - sudo apt update - sudo apt install protobuf-compiler - - - name: go_ins_1 - run: go install google.golang.org/protobuf/cmd/protoc-gen-go@latest + - name: install protoc (protobuf) + uses: arduino/setup-protoc@v3 + with: + version: "27.2" + include-pre-releases: false - - name: go_ins_2 - run: go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest + - name: chmod +x + run: chmod +x ./scripts/install_deps && chmod +x ./scripts/build - - name: generate - run: go generate ./... + - name: install dependencies + run: ./scripts/install_deps - - name: check version - run: go version + - name: build linux + run: ./scripts/build linux amd64 dev - - name: check folder - run: ls + - name: build darwin + run: ./scripts/build darwin amd64 dev - - name: do build - run: go build snetd/main.go + - name: build windows + run: ./scripts/build windows amd64 dev diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 31801194..9271854b 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,43 +1,37 @@ name: tests on: - # push: - # branches: [ "master" ] - pull_request: + push: branches: [ "master" ] + pull_request: + branches: [ "master", "dev" ] workflow_dispatch: +env: + GOLANG_PROTOBUF_REGISTRATION_CONFLICT: ignore + jobs: - run_tests: - runs-on: ubuntu-latest - steps: - + run_tests: + runs-on: ubuntu-latest + steps: - name: clone repo uses: actions/checkout@v3 - + - name: download and install uses: actions/setup-go@v5 with: - go-version: '1.22.2' + go-version: '1.23.1' - - name: protobuff install - run: | - sudo apt update - sudo apt install protobuf-compiler - - - name: go_ins_1 - run: go install google.golang.org/protobuf/cmd/protoc-gen-go@latest - - - name: go_ins_2 - run: go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest - - - name: generate - run: go generate ./... + - name: install protoc (protobuf) + uses: arduino/setup-protoc@v3 + with: + version: "27.2" + include-pre-releases: false - - name: check version - run: go version + - name: chmod to allow run script + run: chmod +x ./scripts/install_deps - - name: check folder - run: ls + - name: install dependencies + run: ./scripts/install_deps - - name: do tests + - name: go tests run: go test -v ./... diff --git a/.gitignore b/.gitignore index 8531d46e..7e2d8f0e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,30 +1,32 @@ # idea cache .idea/ -# npm cache and configs +# npm cache +resources/blockchain/package-lock.json resources/blockchain/node_modules/ resources/blockchain/build/ snetd.db + +# configs snetd.config.json -/vendor/ -/build/ -resources/blockchain/package-lock.json -# Autogenerated sources +# autogenerated sources blockchain/snet-contracts.go *.pb.go +/vendor/ -# Binaries for programs and plugins +# binaries for programs and plugins +/build/ *.exe *.exe~ *.dll *.so *.dylib -# Test binary, build with `go test -c` +# test binary, build with `go test -c` *.test -# Output of the go coverage tool, specifically when used with LiteIDE +# output of the go coverage tool, specifically when used with LiteIDE *.out # vim temporary files @@ -32,9 +34,23 @@ blockchain/snet-contracts.go *.swp *.swo -# etcd server temporary directories +# etcd server directories storage-* -*.pem -*log data.etcd/ +*.tmp +*.etcd + +# certs and keys +*.pem +*.crt +*.key + +# logs +*.log + +# vscode +.vscode + +# asdf +.tool-versions diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 00000000..455c3d75 --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,54 @@ +# This file configures github.com/golangci/golangci-lint. + +run: + concurrency: 4 + timeout: 5m + tests: false + issues-exit-code: 3 + modules-download-mode: readonly + allow-parallel-runners: true + +linters: + disable-all: true + enable: + - gosimple + - govet + - ineffassign + - misspell + - unconvert + - typecheck + - errcheck + # - unused + - staticcheck + - bidichk + - durationcheck + - goconst + - noctx + - whitespace + - revive # only certain checks enabled + +linters-settings: + gofmt: + simplify: true + revive: + enable-all-rules: false + # here we enable specific useful rules + # see https://golangci-lint.run/usage/linters/#revive for supported rules + rules: + - name: receiver-naming + severity: warning + disabled: false + exclude: [ "" ] + +issues: + exclude-dirs-use-default: true + exclude-dirs: + - bin + - build + - \.git + exclude-files: + - ".pb" + exclude-rules: + - linters: + - lll + source: "^//go:generate " \ No newline at end of file diff --git a/README.md b/README.md index d895dee9..26393560 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,11 @@ # SingularityNET Daemon -[![Coverage Status](https://coveralls.io/repos/github/singnet/snet-daemon/badge.svg)](https://coveralls.io/github/singnet/snet-daemon) +![ci/cd build]( https://github.com/singnet/snet-daemon/actions/workflows/build.yml/badge.svg) +![ci/cd build]( https://github.com/singnet/snet-daemon/actions/workflows/test.yml/badge.svg) +[![Go Report Card](https://goreportcard.com/badge/github.com/singnet/snet-daemon?style=flat-square)](https://goreportcard.com/report/github.com/singnet/snet-daemon) +[![Coverage](https://coveralls.io/repos/github/singnet/snet-daemon/badge.svg?branch=master)](https://coveralls.io/github/singnet/snet-daemon?branch=master) +[![Releases](https://img.shields.io/github/release/singnet/snet-daemon/all.svg?style=flat-square)](https://github.com/singnet/snet-daemon/releases) +[![LICENSE](https://img.shields.io/github/license/singnet/snet-daemon.svg?style=flat-square)](https://github.com/singnet/snet-daemon/blob/main/LICENSE) Users interested in deploying SingularityNET services should use this daemon @@ -8,172 +13,78 @@ The daemon is the adapter with which an otherwise SingularityNET-unaware service SingularityNET platform. It is designed to be deployed as a sidecar proxy alongside the service on a given host. The daemon abstracts the blockchain components away from the clients. The SNET Daemon interacts with the Multi Party Escrow to facilitate authorization and payment for services and acts as a -passthrough for making API calls to the service.The daemon is the endpoint a client will submit requests to, and they +passthrough for making API calls to the service. The daemon is the endpoint a client will submit requests to, and they are then passed to the service after validation by the daemon. -## Channel Claim command +# Table of contents -Gets the latest channel state of the Channel updated in ETCD by the daemons of the same group and then increments the -nonce of the channel. -It then sends and ON-Chain transaction to claim funds. The daemons continue their work independently without any -confirmation from the treasurer on the blockchain. - -## Releases - -**Usage without compiling:** -Precompiled binaries are published with each [release](https://github.com/singnet/snet-daemon/releases). - -## Development - -These instructions are intended to facilitate the development and testing of SingularityNET Daemon. - -### Prerequisites and dependencies +1. [Install and use](#use) +2. [Configuration](#configuration) + 1. [Main properties](#main_properties) + 2. [Additional properties](#other_properties) +3. [Channel Claim and other commands](#commands) +4. [Build and development](#build) -* [Go 1.22+](https://golang.org/dl/) -* [Protoc 25.0+](https://github.com/protocolbuffers/protobuf/releases) - -**Protoc (libprotoc), golang and $GOPATH/bin should be in environment variables.** +## Install and use -### Installing - -* Clone the git repository (for example $GOPATH/src/github.com/singnet/) +Precompiled binaries are published with each release, +download [from releases page](https://github.com/singnet/snet-daemon/releases) or use terminal: ```bash -$ git clone git@github.com:singnet/snet-daemon.git -$ cd snet-daemon +curl -LJO https://github.com/singnet/snet-daemon/releases/download/v5.1.4/snetd-linux-amd64-v5.1.4 +chmod +x snetd-linux-amd64-v5.1.4 ``` -* Install dependencies and generate bindings +#### Generate basic config file -```bash -$ ./scripts/install -``` - -* Build snet-daemon. Please note using ldflags, the latest tagged version , sha1 revision and the build time are set as - part of the build. - You need to pass the version as shown in the example below +For most users, a simple config is enough: ```bash -$ ./scripts/build +./snetd-linux-amd64-v5.1.4 init ``` -Example: - -```bash -$ ./scripts/build linux amd64 v5.1.2 -``` +This command will generate a file `snetd.config.json` in which you will need to +change [some parameters](#main_properties). -#### Generate default minimum config file for snet-daemon +#### Generate default full config file ```bash -$ ./build/snetd-linux-amd64 init +./snetd-linux-amd64-v5.1.4 init-full ``` -#### Generate default full config file for snet-daemon - -```bash -$ ./build/snetd-linux-amd64 init-full -``` - -#### Multi-compiling - -If you want to build snetd for several platforms, run `./scripts/build-all ` instead -of `./scripts/build`. - -You can edit the script to choose the specific platforms, but by default it will build for Linux, OSX, and Windows. - #### Run Daemon ```bash -$ ../build/snetd-linux-amd64 -``` - -### Signatures in Daemon - -[Payment](/escrow/README.md). -[Configuration](/configuration_service/README.md). - -### Main commands - -* Start ```snet-daemon``` - -```bash -$ ./snetd-linux-amd64 -``` - -* Claim funds from the channel - - Refer to the link below on an end to - end [Example of MPE](https://github.com/singnet/wiki/blob/master/multiPartyEscrowContract/MPE_fronttoback_example1.md) - - At the moment treasurer server is a part of snet-daemon command line interface. - -```bash -$ ./snetd-linux-amd64 claim --channel-id 0 - +./snetd-linux-amd64-v5.1.4 ``` -* Full list of commands, use --help to get more information. +Specifying the path to the config using the '-c' argument: ```bash -$ ./build/snetd-linux-amd64 --help -Usage: - snetd [flags] - snetd [command] - -Available Commands: - channel Manage operations on payment channels - freecall Manage operations on free call users - help Help about any command - init Write basic configuration to file - init-full Write full default configuration to file - list List channels, claims in progress, etc - serve Is the default option which starts the Daemon. - version List the current version of the Daemon. - -Flags: - -c, --config string config file (default "snetd.config.json") - -h, --help help for snetd - -Use "snetd [command] --help" for more information about a command. +./snetd-linux-amd64-v5.1.4 -c name_of_config.json ``` -* Unit Testing - -```bash -$ ./scripts/test -``` -or -```bash -$ go test ./... -``` - -### Configuration +## Configuration Configuration file is a main source of the configuration. Some properties can be set via environment variables or command line parameters see [table -below](#environment-variables-and-cli-parameters). Use `--config` -parameter with any command to set configuration file name. By default daemon +below](#table_conf). Use `--config` parameter with any command to set configuration file name. By default daemon use configuration file in JSON format `snetd.config.json` but other formats are -also supported via [Viper](https://github.com/spf13/viper). Use `snet init-full` +also supported via [Viper](https://github.com/spf13/viper). Use `init-full` or `init` command to save configuration file with default values. Following configuration properties can be set using configuration file. -#### Blockchain network config - -You can update the registry address or ethereum_json_rpc_endpoint in `resources/blockchain_network_config.json` before ./scripts/build. - -#### Main properties +### Main properties These properties you should usually change before starting daemon for the first time. -* **blockchain_network_selected** (required) +* **blockchain_network_selected** (required, default `"sepolia"`) Name of the network to be used for Daemon possible values are one of (goerli, sepolia, main, local). Daemon will automatically read the Registry address associated with this network For local network ( you can also specify the registry address manually), see the blockchain_network_config.json -* **daemon_end_point** (required;) - +* **daemon_end_point** (required, default `"127.0.0.1:8080"`) - Defines the ip and the port on which the daemon listens to. format is :`:`. @@ -182,9 +93,9 @@ time. Based on the network selected blockchain_network_selected the end point is auto determined Example `"https://sepolia.infura.io/v3"` for sepolia testnet. -* **blockchain_provider_api_key** (optional) - basic header authorization key for blockchain providers. Tested with - infura api - key secret. +* **blockchain_provider_api_key** (optional, default: `""`) - basic header authorization key for blockchain providers. + Tested with + [infura api key secret](https://docs.infura.io/dashboard/secure-an-api/api-key-secret). * **organization_id** (required) - Id of the organization to search for [service configuration @@ -210,11 +121,11 @@ time. endpoint of IPFS instance to get [service configuration metadata][service-configuration-metadata] -#### Other properties +### Other properties This options are less frequently needed. -* **service_credentials** (optional, for service_type http only): +* **service_credentials** (optional, for `"service_type":"http"` only): Array of credentials, example: ``` @@ -223,18 +134,16 @@ This options are less frequently needed. {"key": "X-API-Key", "value": "546bd7d4-d3e1-46ba-b752-bc45e4dc5b39", "location": "header"} ], ``` - Location can be: query, header or body. Query and header values must be string. - -* **allowed_user_flag** (optional;default:`false`) - You may need to protect the service provider 's service in test +* **allowed_user_flag** (optional; default:`false`) - You may need to protect the service provider 's service in test environment from being called by anyone, only Authorized users can make calls , when this flag is defined in the config, you can enforce this behaviour.You cannot set this flag to true in mainnet. This config is applicable only when you have the value to true. In which case it becomes mandatory to define the configuration `allowed_users`, -* **allowed_user_addresses** (optional;) - List of selected user addresses who can make requests to Daemon +* **allowed_user_addresses** (optional) - List of selected user addresses who can make requests to Daemon Is Applicable only when you have `allowed_user_flag` set to true. * **authentication_addresses** (required if `You need to update Daemon configurations remotely`) @@ -314,17 +223,14 @@ This options are less frequently needed. to this Daemon, metering service will ensure that the signer it receives matches the public key configured at its end. This is mandatory only when metering is enabled. - * **rate_limit_per_minute** (optional; default: `Infinity`) - see [rate limiting configuration](./ratelimit/README.md) - * **registry_address_key** (Optional) - Ethereum address of the Registry contract instance.This is auto determined if not specified based on the blockchain_network_selected If a value is specified, it will be used and no attempt will be made to auto determine the registry address. - * **alerts_email** (optional; default: `""`) - It must be a valid email. if it is empty, then it is considered as alerts disabled. see [daemon alerts/notifications configuration](./metrics/README.md) @@ -351,7 +257,7 @@ This options are less frequently needed. * **token_secret_key** (optional;) - This is the secret key used to sign a JWT token , please do add this in your configuration to make your tokens a lot more secure. -#### Environment variables and CLI parameters +#### Environment variables and CLI parameters | config file key | environment variable name | flag | |------------------------------|-----------------------------------|-----------------------| @@ -368,6 +274,139 @@ This options are less frequently needed. [service-configuration-metadata]: https://github.com/singnet/wiki/blob/master/multiPartyEscrowContract/MPEServiceMetadata.md +## Channel Claim and other commands + +Gets the latest channel state of the Channel updated in ETCD by the daemons of the same group and then increments the +nonce of the channel. +It then sends and ON-Chain transaction to claim funds. The daemons continue their work independently without any +confirmation from the treasurer on the blockchain. + +**Claim funds from the channel** + +Refer to the link below on an end to +end [Example of MPE](https://github.com/singnet/wiki/tree/master/multiPartyEscrowContract/front-to-back-examples) +At the moment treasurer server is a part of snet-daemon command line interface. + +```bash +./snetd-linux-amd64-v5.1.4 claim --channel-id 0 +``` + +**Full list of commands, use --help to get more information:** + +```bash +./snetd-linux-amd64-v5.1.4 --help + +Usage: + snetd [flags] + snetd [command] + +Available Commands: + channel Manage operations on payment channels + freecall Manage operations on free call users + help Help about any command + init Write basic configuration to file + init-full Write full default configuration to file + list List channels, claims in progress, etc + serve Is the default option which starts the Daemon. + version List the current version of the Daemon. + +Flags: + -c, --config string config file (default "snetd.config.json") + -h, --help help for snetd + +Use "snetd [command] --help" for more information about a command. +``` + +## Build & Development + +These instructions are intended to facilitate the development and testing of SingularityNET Daemon. + +### Prerequisites and dependencies + +* [Go 1.22+](https://golang.org/dl/) +* [Protoc 25.0+](https://github.com/protocolbuffers/protobuf/releases) + +**Protoc (libprotoc), golang and $GOPATH/bin are recommended to be in environment variables.** + +### Installing + +* Clone the git repository (for example, $GOPATH/src/github.com/singnet/) + +```bash +git clone git@github.com:singnet/snet-daemon.git +cd snet-daemon +``` + +**Install dependencies and generate bindings** + +Bash + +```bash +./scripts/install_deps +``` + +PowerShell + +```powershell +./scripts/install_deps.ps1 +``` + +**Build snet-daemon**. Please note using ldflags, the latest tagged version, sha1 revision and the build time are set as +part of the build. You need to pass the version as shown in the example below: + +```bash +./scripts/build +``` + +**Examples** + +Bash: + +```bash +./scripts/build linux amd64 v5.1.4 +``` + +Powershell: + +```powershell +./scripts/build.ps1 linux amd64 v5.1.4 +``` + +The final binaries will be in the `/build` folder. + +#### Multi-compiling + +If you want to build daemon for several platforms, run `./scripts/build-all ` instead +of `./scripts/build`. + +You can edit the script to choose the specific platforms, but by default it will build for Linux, Darwin (OSX), and +Windows. + +#### Unit Testing + +```bash +./scripts/test +``` + +or + +```bash +go test ./... +``` + +### Fixing errors + +If daemon panic with `panic: proto: file "record.proto" is already registered` +you should set environment var `GOLANG_PROTOBUF_REGISTRATION_CONFLICT=warn` + +### Blockchain network config + +You can edit `ethereum_json_rpc_endpoint` in `resources/blockchain_network_config.json` before ./scripts/build. + +### Signatures in Daemon + +* [Payment Signatures](/escrow/README.md). + ## Versioning We use [SemVer](http://semver.org/) for versioning. For the versions available, see the diff --git a/authutils/auth_service.go b/authutils/auth_service.go index c794e344..9001b078 100755 --- a/authutils/auth_service.go +++ b/authutils/auth_service.go @@ -1,4 +1,4 @@ -// authutils package provides functions for all authentication and singature validation related operations +// Package authutils provides functions for all authentication and signature validation related operations package authutils import ( @@ -67,21 +67,21 @@ func GetSignerAddressFromMessage(message, signature []byte) (signer *common.Addr return &keyOwnerAddress, nil } -// Verify the signature done by given singer or not -// returns nil if signer indeed sign the message and singature proves it, if not throws an error +// VerifySigner Verify the signature done by given singer or not +// returns nil if signer indeed sign the message and signature proves it, if not throws an error func VerifySigner(message []byte, signature []byte, signer common.Address) error { signerFromMessage, err := GetSignerAddressFromMessage(message, signature) if err != nil { - zap.L().Error("Gering error from getSignerAddressFromMessage", zap.Error(err)) + zap.L().Error("error from getSignerAddressFromMessage", zap.Error(err)) return err } if signerFromMessage.String() == signer.String() { return nil } - return fmt.Errorf("Incorrect signer.") + return fmt.Errorf("incorrect signer") } -// Check if the block number passed is not more +- 5 from the latest block number on chain +// CompareWithLatestBlockNumber Check if the block number passed is not more +- 5 from the latest block number on chain func CompareWithLatestBlockNumber(blockNumberPassed *big.Int) error { latestBlockNumber, err := CurrentBlock() if err != nil { @@ -94,7 +94,7 @@ func CompareWithLatestBlockNumber(blockNumberPassed *big.Int) error { return nil } -// Check if the block number ( date on which the token was issued is not more than 1 month) +// CheckIfTokenHasExpired Check if the block number ( date on which the token was issued is not more than 1 month) func CheckIfTokenHasExpired(expiredBlock *big.Int) error { currentBlockNumber, err := CurrentBlock() if err != nil { @@ -107,14 +107,14 @@ func CheckIfTokenHasExpired(expiredBlock *big.Int) error { return nil } -// Get the current block number from on chain +// CurrentBlock Get the current block number from on chain func CurrentBlock() (*big.Int, error) { - if ethClient, err := blockchain.GetEthereumClient(); err != nil { + if ethHttpClient, _, err := blockchain.CreateEthereumClients(); err != nil { return nil, err } else { - defer ethClient.RawClient.Close() + defer ethHttpClient.RawClient.Close() var currentBlockHex string - if err = ethClient.RawClient.CallContext(context.Background(), ¤tBlockHex, "eth_blockNumber"); err != nil { + if err = ethHttpClient.RawClient.CallContext(context.Background(), ¤tBlockHex, "eth_blockNumber"); err != nil { zap.L().Error("error determining current block", zap.Error(err)) return nil, fmt.Errorf("error determining current block: %v", err) } @@ -122,7 +122,7 @@ func CurrentBlock() (*big.Int, error) { } } -// Check if the payment address/signer passed matches to what is present in the metadata +// VerifyAddress Check if the payment address/signer passed matches to what is present in the metadata func VerifyAddress(address common.Address, otherAddress common.Address) error { isSameAddress := otherAddress == address if !isSameAddress { diff --git a/authutils/auth_service_test.go b/authutils/auth_service_test.go index e74fa1d3..cf5a57d9 100644 --- a/authutils/auth_service_test.go +++ b/authutils/auth_service_test.go @@ -1,9 +1,10 @@ -// authutils package provides functions for all authentication and singature validation related operations +// authutils package provides functions for all authentication and signature validation related operations package authutils import ( "math/big" "testing" + "time" "github.com/singnet/snet-daemon/config" "github.com/stretchr/testify/assert" @@ -28,9 +29,8 @@ func TestCheckAllowedBlockDifferenceForToken(t *testing.T) { currentBlockNum, _ := CurrentBlock() err := CheckIfTokenHasExpired(currentBlockNum.Sub(currentBlockNum, big.NewInt(20000))) assert.Equal(t, err.Error(), "authentication failed as the Free Call Token passed has expired") - + time.Sleep(250 * time.Millisecond) // because of HTTP 429 Too Many Requests currentBlockNum, _ = CurrentBlock() err = CheckIfTokenHasExpired(currentBlockNum.Add(currentBlockNum, big.NewInt(20))) assert.Equal(t, nil, err) - } diff --git a/blockchain/blockchain.go b/blockchain/blockchain.go index b336f0e8..bfa5b7e9 100644 --- a/blockchain/blockchain.go +++ b/blockchain/blockchain.go @@ -29,8 +29,10 @@ type jobInfo struct { type Processor struct { enabled bool - ethClient *ethclient.Client - rawClient *rpc.Client + ethHttpClient *ethclient.Client + rawHttpClient *rpc.Client + ethWSClient *ethclient.Client + rawWSClient *rpc.Client sigHasher func([]byte) []byte privateKey *ecdsa.PrivateKey address string @@ -55,11 +57,13 @@ func NewProcessor(metadata *ServiceMetadata) (Processor, error) { // Setup ethereum client - if ethclients, err := GetEthereumClient(); err != nil { + if ethHttpClients, ethWSClients, err := CreateEthereumClients(); err != nil { return p, errors.Wrap(err, "error creating RPC client") } else { - p.rawClient = ethclients.RawClient - p.ethClient = ethclients.EthClient + p.rawHttpClient = ethHttpClients.RawClient + p.ethHttpClient = ethHttpClients.EthClient + p.rawWSClient = ethWSClients.RawClient + p.ethWSClient = ethWSClients.EthClient } // TODO: if address is not in config, try to load it using network @@ -68,7 +72,7 @@ func NewProcessor(metadata *ServiceMetadata) (Processor, error) { p.escrowContractAddress = metadata.GetMpeAddress() - if mpe, err := NewMultiPartyEscrow(p.escrowContractAddress, p.ethClient); err != nil { + if mpe, err := NewMultiPartyEscrow(p.escrowContractAddress, p.ethHttpClient); err != nil { return p, errors.Wrap(err, "error instantiating MultiPartyEscrow contract") } else { p.multiPartyEscrow = mpe @@ -82,6 +86,23 @@ func NewProcessor(metadata *ServiceMetadata) (Processor, error) { return p, nil } +func (processor *Processor) ReconnectToWsClient() error { + processor.ethWSClient.Close() + processor.rawHttpClient.Close() + + zap.L().Debug("Try to reconnect to websocket client") + + newEthWSClients, err := CreateWSEthereumClient() + if err != nil { + return err + } + + processor.ethWSClient = newEthWSClients.EthClient + processor.rawWSClient = newEthWSClients.RawClient + + return nil +} + func (processor *Processor) Enabled() (enabled bool) { return processor.enabled } @@ -94,11 +115,19 @@ func (processor *Processor) MultiPartyEscrow() *MultiPartyEscrow { return processor.multiPartyEscrow } +func (processor *Processor) GetEthHttpClient() *ethclient.Client { + return processor.ethHttpClient +} + +func (processor *Processor) GetEthWSClient() *ethclient.Client { + return processor.ethWSClient +} + func (processor *Processor) CurrentBlock() (currentBlock *big.Int, err error) { // We have to do a raw call because the standard method of ethClient.HeaderByNumber(ctx, nil) errors on // unmarshaling the response currently. See https://github.com/ethereum/go-ethereum/issues/3230 var currentBlockHex string - if err = processor.rawClient.CallContext(context.Background(), ¤tBlockHex, "eth_blockNumber"); err != nil { + if err = processor.rawHttpClient.CallContext(context.Background(), ¤tBlockHex, "eth_blockNumber"); err != nil { zap.L().Error("error determining current block", zap.Error(err)) return nil, fmt.Errorf("error determining current block: %v", err) } @@ -114,6 +143,8 @@ func (processor *Processor) HasIdentity() bool { } func (processor *Processor) Close() { - processor.ethClient.Close() - processor.rawClient.Close() + processor.ethHttpClient.Close() + processor.rawHttpClient.Close() + processor.ethWSClient.Close() + processor.rawWSClient.Close() } diff --git a/blockchain/ethereumClient.go b/blockchain/ethereumClient.go index 0cd32b97..d394c874 100644 --- a/blockchain/ethereumClient.go +++ b/blockchain/ethereumClient.go @@ -3,10 +3,12 @@ package blockchain import ( "context" "encoding/base64" + + "github.com/singnet/snet-daemon/config" + "github.com/ethereum/go-ethereum/ethclient" "github.com/ethereum/go-ethereum/rpc" "github.com/pkg/errors" - "github.com/singnet/snet-daemon/config" ) type EthereumClient struct { @@ -19,21 +21,49 @@ func basicAuth(username, password string) string { return base64.StdEncoding.EncodeToString([]byte(auth)) } -func GetEthereumClient() (*EthereumClient, error) { +func CreateEthereumClients() (*EthereumClient, *EthereumClient, error) { + ethereumHttpClient, err := CreateHTTPEthereumClient() + if err != nil { + return nil, nil, err + } + + ethereumWsClient, err := CreateWSEthereumClient() + if err != nil { + return nil, nil, err + } + + return ethereumHttpClient, ethereumWsClient, nil +} - ethereumClient := new(EthereumClient) - if client, err := rpc.DialOptions(context.Background(), - config.GetBlockChainEndPoint(), - rpc.WithHeader("Authorization", "Basic "+basicAuth("", config.GetString(config.BlockchainProviderApiKey)))); err != nil { +func CreateHTTPEthereumClient() (*EthereumClient, error) { + ethereumHttpClient := new(EthereumClient) + httpClient, err := rpc.DialOptions( + context.Background(), + config.GetBlockChainHTTPEndPoint(), + rpc.WithHeader("Authorization", "Basic "+basicAuth("", config.GetString(config.BlockchainProviderApiKey)))) + if err != nil { return nil, errors.Wrap(err, "error creating RPC client") - } else { - ethereumClient.RawClient = client - ethereumClient.EthClient = ethclient.NewClient(client) } - return ethereumClient, nil + ethereumHttpClient.RawClient = httpClient + ethereumHttpClient.EthClient = ethclient.NewClient(httpClient) + return ethereumHttpClient, nil +} +func CreateWSEthereumClient() (*EthereumClient, error) { + ethereumWsClient := new(EthereumClient) + wsClient, err := rpc.DialOptions( + context.Background(), + config.GetBlockChainWSEndPoint(), + rpc.WithHeader("Authorization", "Basic "+basicAuth("", config.GetString(config.BlockchainProviderApiKey)))) + if err != nil { + return nil, errors.Wrap(err, "error creating RPC WebSocket client") + } + ethereumWsClient.RawClient = wsClient + ethereumWsClient.EthClient = ethclient.NewClient(wsClient) + return ethereumWsClient, nil } + func (ethereumClient *EthereumClient) Close() { if ethereumClient != nil { ethereumClient.EthClient.Close() diff --git a/blockchain/ethereum_test_util.go b/blockchain/ethereum_test_util.go index c25f52b2..2e23bfd9 100644 --- a/blockchain/ethereum_test_util.go +++ b/blockchain/ethereum_test_util.go @@ -3,12 +3,12 @@ package blockchain import ( "crypto/ecdsa" "fmt" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/ethclient/simulated" "math/big" "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/accounts/abi/bind/backends" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/crypto" ) @@ -19,7 +19,7 @@ type SimulatedEthereumEnvironment struct { ClientPrivateKey *ecdsa.PrivateKey ServerWallet *bind.TransactOpts ServerPrivateKey *ecdsa.PrivateKey - Backend *backends.SimulatedBackend + Backend *simulated.Backend SingularityNetToken *SingularityNetToken MultiPartyEscrowAddress common.Address MultiPartyEscrow *MultiPartyEscrow @@ -63,40 +63,48 @@ func (env *SimulatedEthereumEnvironment) Commit() *SimulatedEthereumEnvironment } func GetSimulatedEthereumEnvironment() (env SimulatedEthereumEnvironment) { - env.SingnetPrivateKey, env.SingnetWallet = getTestWallet() - env.ClientPrivateKey, env.ClientWallet = getTestWallet() - env.ServerPrivateKey, env.ServerWallet = getTestWallet() + var chainID = big.NewInt(11155111) + env.SingnetPrivateKey, env.SingnetWallet, _ = getTestWallet(chainID) + env.ClientPrivateKey, env.ClientWallet, _ = getTestWallet(chainID) + env.ServerPrivateKey, env.ServerWallet, _ = getTestWallet(chainID) - alloc := map[common.Address]core.GenesisAccount{ + alloc := map[common.Address]types.Account{ env.SingnetWallet.From: {Balance: big.NewInt(1000000000000)}, env.ClientWallet.From: {Balance: big.NewInt(1000000000000)}, env.ServerWallet.From: {Balance: big.NewInt(10000000)}, } - env.Backend = backends.NewSimulatedBackend(alloc, 0) + b := simulated.NewBackend(alloc, simulated.WithBlockGasLimit(0)) + + env.Backend = b deployContracts(&env) return } -func getTestWallet() (privateKey *ecdsa.PrivateKey, wallet *bind.TransactOpts) { - privateKey, err := crypto.GenerateKey() +func getTestWallet(chainID *big.Int) (privateKey *ecdsa.PrivateKey, wallet *bind.TransactOpts, err error) { + privateKey, err = crypto.GenerateKey() if err != nil { panic(fmt.Sprintf("Unable to generate private key, error: %v", err)) } - return privateKey, bind.NewKeyedTransactor(privateKey) + wallet, err = bind.NewKeyedTransactorWithChainID(privateKey, chainID) + if err != nil { + return nil, nil, err + } + + return privateKey, wallet, err } func deployContracts(env *SimulatedEthereumEnvironment) { - tokenAddress, _, token, err := DeploySingularityNetToken(EstimateGas(env.SingnetWallet), env.Backend, "SingularityNet Token", "AGI") + tokenAddress, _, token, err := DeploySingularityNetToken(EstimateGas(env.SingnetWallet), env.Backend.Client(), "SingularityNet Token", "AGI") if err != nil { panic(fmt.Sprintf("Unable to deploy SingularityNetToken contract, error: %v", err)) } env.Backend.Commit() env.SingularityNetToken = token - mpeAddress, _, mpe, err := DeployMultiPartyEscrow(EstimateGas(env.SingnetWallet), env.Backend, tokenAddress) + mpeAddress, _, mpe, err := DeployMultiPartyEscrow(EstimateGas(env.SingnetWallet), env.Backend.Client(), tokenAddress) if err != nil { panic(fmt.Sprintf("Unable to deploy MultiPartyEscrow contract, error: %v", err)) } diff --git a/blockchain/orginzationMetadata.go b/blockchain/orginzationMetadata.go index b8a54609..d868bdeb 100644 --- a/blockchain/orginzationMetadata.go +++ b/blockchain/orginzationMetadata.go @@ -98,23 +98,22 @@ type PaymentChannelStorageClient struct { Endpoints []string `json:"endpoints"` } -// Construct the Organization metadata from the JSON Passed -func InitOrganizationMetaDataFromJson(jsonData string) (metaData *OrganizationMetaData, err error) { +// InitOrganizationMetaDataFromJson Construct the Organization metadata from the JSON Passed +func InitOrganizationMetaDataFromJson(jsonData []byte) (metaData *OrganizationMetaData, err error) { metaData = new(OrganizationMetaData) - err = json.Unmarshal([]byte(jsonData), &metaData) + err = json.Unmarshal(jsonData, &metaData) if err != nil { - zap.L().Error("Error in unmarshaling metadata json", zap.Error(err), zap.Any("jsondata", jsonData)) + zap.L().Error("Error in unmarshalling metadata json", zap.Error(err), zap.Any("jsondata", jsonData)) return nil, err } - //Check for mandatory validations - + // Check for mandatory validations if err = setDerivedAttributes(metaData); err != nil { - zap.L().Error("Error in setting derived atrributes", zap.Error(err)) + zap.L().Error("Error in setting derived attributes", zap.Error(err)) return nil, err } if err = checkMandatoryFields(metaData); err != nil { - zap.L().Error("Error in check mdandatory fields", zap.Error(err)) + zap.L().Error("Error in check mandatory fields", zap.Error(err)) return nil, err } @@ -125,10 +124,11 @@ func checkMandatoryFields(metaData *OrganizationMetaData) (err error) { if metaData.daemonGroup.PaymentDetails.PaymentChannelStorageClient.Endpoints == nil { err = fmt.Errorf("Mandatory field : ETCD Client Endpoints are mising for the Group %v ", metaData.daemonGroup.GroupName) } - if &metaData.recipientPaymentAddress == nil { - err = fmt.Errorf("Mandatory field : Recepient Address is missing for the Group %v ", metaData.daemonGroup.GroupName) + + if metaData.recipientPaymentAddress == (common.Address{}) { + err = fmt.Errorf("Mandatory field : Recipient Address is missing for the Group %v ", metaData.daemonGroup.GroupName) } - return + return err } func setDerivedAttributes(metaData *OrganizationMetaData) (err error) { @@ -165,7 +165,7 @@ func GetOrganizationMetaData() *OrganizationMetaData { var err error if config.GetBool(config.BlockchainEnabledKey) { ipfsHash := string(getMetaDataURI()) - metadata, err = GetOrganizationMetaDataFromIPFS(FormatHash(ipfsHash)) + metadata, err = GetOrganizationMetaDataFromIPFS(ipfsHash) } else { metadata = &OrganizationMetaData{daemonGroup: &Group{}} } @@ -176,7 +176,10 @@ func GetOrganizationMetaData() *OrganizationMetaData { } func GetOrganizationMetaDataFromIPFS(hash string) (*OrganizationMetaData, error) { - jsondata := ipfsutils.GetIpfsFile(hash) + jsondata, err := ipfsutils.ReadFile(hash) + if err != nil { + return nil, err + } return InitOrganizationMetaDataFromJson(jsondata) } @@ -187,7 +190,7 @@ func getMetaDataURI() []byte { organizationRegistered, err := reg.GetOrganizationById(nil, orgId) if err != nil || !organizationRegistered.Found { - zap.L().Panic("Error Retrieving contract details for the Given Organization", zap.String("OrganizationId", config.GetString(config.OrganizationId))) + zap.L().Panic("Error Retrieving contract details for the Given Organization", zap.String("OrganizationId", config.GetString(config.OrganizationId)), zap.Error(err)) } return organizationRegistered.OrgMetadataURI[:] } diff --git a/blockchain/orginzationMetadata_test.go b/blockchain/orginzationMetadata_test.go index 3f7abe35..18460499 100644 --- a/blockchain/orginzationMetadata_test.go +++ b/blockchain/orginzationMetadata_test.go @@ -11,7 +11,7 @@ import ( var testJsonOrgGroupData = "{ \"org_name\": \"organization_name\", \"org_id\": \"org_id1\", \"groups\": [ { \"group_name\": \"default_group2\", \"group_id\": \"99ybRIg2wAx55mqVsA6sB4S7WxPQHNKqa4BPu/bhj+U=\", \"payment\": { \"payment_address\": \"0x671276c61943A35D5F230d076bDFd91B0c47bF09\", \"payment_expiration_threshold\": 40320, \"payment_channel_storage_type\": \"etcd\", \"payment_channel_storage_client\": { \"connection_timeout\": \"15s\", \"request_timeout\": \"13s\", \"endpoints\": [ \"http://127.0.0.1:2379\" ] } } }, { \"group_name\": \"default_group\", \"license_server_endpoints\": [\"https://licensendpoint:8082\"], \"group_id\": \"99ybRIg2wAx55mqVsA6sB4S7WxPQHNKqa4BPu/bhj+U=\", \"payment\": { \"payment_address\": \"0x671276c61943A35D5F230d076bDFd91B0c47bF09\", \"payment_expiration_threshold\": 40320, \"payment_channel_storage_type\": \"etcd\", \"payment_channel_storage_client\": { \"connection_timeout\": \"15s\", \"request_timeout\": \"13s\", \"endpoints\": [ \"http://127.0.0.1:2379\" ] } } } ] }" func TestGetOrganizationMetaData(t *testing.T) { - metadata, err := InitOrganizationMetaDataFromJson(testJsonOrgGroupData) + metadata, err := InitOrganizationMetaDataFromJson([]byte(testJsonOrgGroupData)) assert.Nil(t, err) assert.NotNil(t, metadata) assert.Equal(t, "organization_name", metadata.OrgName) @@ -25,16 +25,15 @@ func TestGetOrganizationMetaData(t *testing.T) { assert.Equal(t, 15*time.Second, metadata.GetConnectionTimeOut()) assert.Equal(t, 13*time.Second, metadata.GetRequestTimeOut()) assert.Equal(t, "https://licensendpoint:8082", metadata.GetLicenseEndPoints()[0]) - } func TestGetOrganizationMetaDataForError(t *testing.T) { - metadata, err := InitOrganizationMetaDataFromJson("bad json") + metadata, err := InitOrganizationMetaDataFromJson([]byte("bad json")) assert.Nil(t, metadata) assert.NotNil(t, err) config.Vip().Set(config.DaemonGroupName, "unknow") - if metadata, err = InitOrganizationMetaDataFromJson(testJsonOrgGroupData); err != nil { + if metadata, err = InitOrganizationMetaDataFromJson([]byte(testJsonOrgGroupData)); err != nil { assert.Nil(t, metadata) assert.Equal(t, "group name unknow in config is invalid, there was no group found with this name in the metadata", err.Error()) } diff --git a/blockchain/serviceMetadata.go b/blockchain/serviceMetadata.go index 31b5ab74..84c5dd2d 100644 --- a/blockchain/serviceMetadata.go +++ b/blockchain/serviceMetadata.go @@ -11,6 +11,7 @@ import ( "github.com/bufbuild/protocompile" pproto "github.com/emicklei/proto" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/ethclient" "github.com/pkg/errors" "github.com/singnet/snet-daemon/config" "github.com/singnet/snet-daemon/ipfsutils" @@ -142,18 +143,18 @@ import ( } */ const ( - IpfsPrefix = "ipfs://" serviceProto = "service.proto" ) type ServiceMetadata struct { - Version int `json:"version"` - DisplayName string `json:"display_name"` - Encoding string `json:"encoding"` - ServiceType string `json:"service_type"` - Groups []OrganizationGroup `json:"groups"` - ModelIpfsHash string `json:"model_ipfs_hash"` - MpeAddress string `json:"mpe_address"` + Version int `json:"version"` + DisplayName string `json:"display_name"` + Encoding string `json:"encoding"` + ServiceType string `json:"service_type"` + Groups []OrganizationGroup `json:"groups"` + ModelIpfsHash string `json:"model_ipfs_hash"` + ServiceApiSource string `json:"service_api_source"` + MpeAddress string `json:"mpe_address"` multiPartyEscrowAddress common.Address defaultPricing Pricing @@ -195,6 +196,7 @@ type Subscriptions struct { IsActive string `json:"isActive"` Subscription []Subscription `json:"subscription"` } + type Tier struct { Type string `json:"type"` PlanName string `json:"planName"` @@ -204,6 +206,7 @@ type Tier struct { DetailsURL string `json:"detailsUrl"` IsActive string `json:"isActive"` } + type Licenses struct { Subscriptions Subscriptions `json:"subscriptions,omitempty"` Tiers []Tier `json:"tiers"` @@ -251,14 +254,14 @@ func ServiceMetaData() *ServiceMetadata { var err error if config.GetBool(config.BlockchainEnabledKey) { ipfsHash := string(getServiceMetaDataUrifromRegistry()) - metadata, err = GetServiceMetaDataFromIPFS(FormatHash(ipfsHash)) + metadata, err = GetServiceMetaDataFromIPFS(ipfsHash) if err != nil { - zap.L().Panic("error on determining service metadata from file", zap.Error(err)) } } else { metadata = &ServiceMetadata{Encoding: "proto", ServiceType: "grpc"} } + zap.L().Debug("service_type: " + metadata.GetServiceType()) return metadata } @@ -267,9 +270,7 @@ func ReadServiceMetaDataFromLocalFile(filename string) (*ServiceMetadata, error) if err != nil { return nil, errors.Wrapf(err, "could not read file: %v", filename) } - strJson := string(file) - metadata, err := InitServiceMetaDataFromJson(strJson) - + metadata, err := InitServiceMetaDataFromJson(file) if err != nil { return nil, fmt.Errorf("error reading local file service_metadata.json ") } @@ -277,13 +278,22 @@ func ReadServiceMetaDataFromLocalFile(filename string) (*ServiceMetadata, error) } func getRegistryCaller() (reg *RegistryCaller) { - ethClient, err := GetEthereumClient() + ethHttpClient, err := CreateHTTPEthereumClient() if err != nil { zap.L().Panic("Unable to get Blockchain client ", zap.Error(err)) } - defer ethClient.Close() + defer ethHttpClient.Close() + registryContractAddress := getRegistryAddressKey() + reg, err = NewRegistryCaller(registryContractAddress, ethHttpClient.EthClient) + if err != nil { + zap.L().Panic("Error instantiating Registry contract for the given Contract Address", zap.Error(err), zap.Any("registryContractAddress", registryContractAddress)) + } + return reg +} + +func GetRegistryFilterer(ethWsClient *ethclient.Client) *RegistryFilterer { registryContractAddress := getRegistryAddressKey() - reg, err = NewRegistryCaller(registryContractAddress, ethClient.EthClient) + reg, err := NewRegistryFilterer(registryContractAddress, ethWsClient) if err != nil { zap.L().Panic("Error instantiating Registry contract for the given Contract Address", zap.Error(err), zap.Any("registryContractAddress", registryContractAddress)) } @@ -307,13 +317,16 @@ func getServiceMetaDataUrifromRegistry() []byte { } func GetServiceMetaDataFromIPFS(hash string) (*ServiceMetadata, error) { - jsondata := ipfsutils.GetIpfsFile(hash) + jsondata, err := ipfsutils.ReadFile(hash) + if err != nil { + return nil, err + } return InitServiceMetaDataFromJson(jsondata) } -func InitServiceMetaDataFromJson(jsonData string) (*ServiceMetadata, error) { +func InitServiceMetaDataFromJson(jsonData []byte) (*ServiceMetadata, error) { metaData := new(ServiceMetadata) - err := json.Unmarshal([]byte(jsonData), &metaData) + err := json.Unmarshal(jsonData, &metaData) if err != nil { zap.L().Error(err.Error(), zap.Any("jsondata", jsonData)) return nil, err @@ -340,7 +353,7 @@ func InitServiceMetaDataFromJson(jsonData string) (*ServiceMetadata, error) { zap.L().Error(err.Error()) } - zap.L().Debug("Traning method", zap.String("json", string(trainingMethodsJson))) + zap.L().Debug("Training method", zap.String("json", string(trainingMethodsJson))) return metaData, err } @@ -478,8 +491,22 @@ func isElementInArray(a string, list []string) bool { func setServiceProto(metaData *ServiceMetadata) (err error) { metaData.DynamicPriceMethodMapping = make(map[string]string, 0) metaData.TrainingMethods = make([]string, 0) - //This is to handler the scenario where there could be multiple protos associated with the service proto - protoFiles, err := ipfsutils.ReadFilesCompressed(ipfsutils.GetIpfsFile(metaData.ModelIpfsHash)) + var rawFile []byte + + // for backwards compatibility + if metaData.ModelIpfsHash != "" { + rawFile, err = ipfsutils.GetIpfsFile(metaData.ServiceApiSource) + } + + if metaData.ServiceApiSource != "" { + rawFile, err = ipfsutils.ReadFile(metaData.ServiceApiSource) + } + + if err != nil { + zap.L().Error("Error in retrieving file from filecoin/ipfs", zap.Error(err)) + } + + protoFiles, err := ipfsutils.ReadFilesCompressed(rawFile) if err != nil { return err } @@ -491,7 +518,7 @@ func setServiceProto(metaData *ServiceMetadata) (err error) { for _, file := range protoFiles { zap.L().Debug("Protofile", zap.String("file", file)) - //If Dynamic pricing is enabled ,there will be mandatory checks on the service proto + // If Dynamic pricing is enabled, there will be mandatory checks on the service proto //this is to ensure that the standards on how one defines the methods to invoke is followed if config.GetBool(config.EnableDynamicPricing) { if srvProto, err := parseServiceProto(file); err != nil { diff --git a/blockchain/serviceMetadata_test.go b/blockchain/serviceMetadata_test.go index 4e271190..91cf9fab 100644 --- a/blockchain/serviceMetadata_test.go +++ b/blockchain/serviceMetadata_test.go @@ -18,7 +18,7 @@ var testJsonData = "{ \"version\": 1, \"display_name\": \"Example1\", \"en func TestAllGetterMethods(t *testing.T) { fmt.Println(testJsonData) - metaData, err := InitServiceMetaDataFromJson(testJsonData) + metaData, err := InitServiceMetaDataFromJson([]byte(testJsonData)) assert.Equal(t, err, nil) assert.Equal(t, metaData.GetVersion(), 1) @@ -37,7 +37,7 @@ func TestAllGetterMethods(t *testing.T) { func TestSubscription(t *testing.T) { fmt.Println(testJsonData) - metaData, err := InitServiceMetaDataFromJson(testJsonData) + metaData, err := InitServiceMetaDataFromJson([]byte(testJsonData)) assert.Equal(t, err, nil) assert.Equal(t, 12, metaData.GetFreeCallsAllowed()) assert.Equal(t, metaData.GetLicenses().Subscriptions.Type, "Subscription") @@ -50,7 +50,7 @@ func TestSubscription(t *testing.T) { func TestTiers(t *testing.T) { fmt.Println(testJsonData) - metaData, err := InitServiceMetaDataFromJson(testJsonData) + metaData, err := InitServiceMetaDataFromJson([]byte(testJsonData)) assert.Equal(t, err, nil) assert.Equal(t, metaData.GetLicenses().Tiers[0].Type, "Tier") @@ -60,17 +60,17 @@ func TestTiers(t *testing.T) { } func TestInitServiceMetaDataFromJson(t *testing.T) { //Parse Bad JSON - _, err := InitServiceMetaDataFromJson(strings.Replace(testJsonData, "{", "", 1)) + _, err := InitServiceMetaDataFromJson([]byte(strings.Replace(testJsonData, "{", "", 1))) if err != nil { assert.Equal(t, err.Error(), "invalid character ':' after top-level value") } //Parse Bad JSON - _, err = InitServiceMetaDataFromJson(strings.Replace(testJsonData, "0x7DF35C98f41F3Af0df1dc4c7F7D4C19a71Dd059F", "", 1)) + _, err = InitServiceMetaDataFromJson([]byte(strings.Replace(testJsonData, "0x7DF35C98f41F3Af0df1dc4c7F7D4C19a71Dd059F", "", 1))) if err != nil { assert.Equal(t, err.Error(), "MetaData does not have 'free_call_signer_address defined correctly") } - _, err = InitServiceMetaDataFromJson(strings.Replace(testJsonData, "default_pricing", "dummy", 1)) + _, err = InitServiceMetaDataFromJson([]byte(strings.Replace(testJsonData, "default_pricing", "dummy", 1))) if err != nil { assert.Equal(t, err.Error(), "MetaData does not have the default pricing set ") } diff --git a/blockchain/utils.go b/blockchain/utils.go index eba3974b..6fb47b36 100644 --- a/blockchain/utils.go +++ b/blockchain/utils.go @@ -3,9 +3,6 @@ package blockchain import ( "encoding/base64" "fmt" - "regexp" - "strings" - "github.com/ethereum/go-ethereum/common" "go.uber.org/zap" ) @@ -43,21 +40,15 @@ func HexToBytes(str string) []byte { // HexToAddress converts hex string to Ethreum address. func HexToAddress(str string) common.Address { - return common.Address(common.BytesToAddress(HexToBytes(str))) + return common.BytesToAddress(HexToBytes(str)) } func StringToBytes32(str string) [32]byte { - var byte32 [32]byte - copy(byte32[:], []byte(str)) + copy(byte32[:], str) return byte32 } -func RemoveSpecialCharactersfromHash(pString string) string { - reg := regexp.MustCompile("[^a-zA-Z0-9=]") - return reg.ReplaceAllString(pString, "") -} - func ConvertBase64Encoding(str string) ([32]byte, error) { var byte32 [32]byte data, err := base64.StdEncoding.DecodeString(str) @@ -69,16 +60,26 @@ func ConvertBase64Encoding(str string) ([32]byte, error) { return byte32, nil } -func FormatHash(ipfsHash string) string { - zap.L().Debug("Before Formatting", zap.String("metadataHash", ipfsHash)) - ipfsHash = strings.Replace(ipfsHash, IpfsPrefix, "", -1) - ipfsHash = RemoveSpecialCharactersfromHash(ipfsHash) - zap.L().Debug("After Formatting", zap.String("metadataUri", ipfsHash)) - return ipfsHash -} - func ToChecksumAddress(hexAddress string) string { address := common.HexToAddress(hexAddress) mixedAddress := common.NewMixedcaseAddress(address) return mixedAddress.Address().String() } + +/* +MakeTopicFilterer is used to generate a filter for querying Ethereum logs or contract events. +Ethereum topics (such as for events) are 32-byte fixed-size values (common for hashing +in Ethereum logs). This function takes a string parameter, converts it into a 32-byte array, +and returns it in a slice. This allows developers to create filters when looking for +specific events or log entries based on the topic. +*/ +func MakeTopicFilterer(param string) [][32]byte { + // Create a 32-byte array + var param32Byte [32]byte + + // Convert the string to a byte slice and copy up to 32 bytes + copy(param32Byte[:], []byte(param)[:min(len(param), 32)]) + + // Return the filter with a single element (the 32-byte array) + return [][32]byte{param32Byte} +} diff --git a/blockchain/utils_test.go b/blockchain/utils_test.go index e25b0bef..e56456ab 100644 --- a/blockchain/utils_test.go +++ b/blockchain/utils_test.go @@ -11,49 +11,13 @@ func TestBytesToBase64(t *testing.T) { assert.Equal(t, "AQL+/w==", base64) } -func TestFormatHash(t *testing.T) { - s2 := []byte("ipfs://Here is a string....+=") - hash := FormatHash(string(s2)) - assert.Equal(t, hash, "Hereisastring=") - s2 = []byte("QmaGnQ3iVZPuPwdam2rEeQcCSoCYRpxjnZhQ6Z2oeeRSrp") - - b4 := append(s2, make([]byte, 3)...) - assert.NotEqual(t, "QmaGnQ3iVZPuPwdam2rEeQcCSoCYRpxjnZhQ6Z2oeeRSrp", string(b4)) - assert.Equal(t, "QmaGnQ3iVZPuPwdam2rEeQcCSoCYRpxjnZhQ6Z2oeeRSrp", FormatHash(string(b4))) -} func TestConvertBase64Encoding(t *testing.T) { - if _, err := ConvertBase64Encoding("n@@###zNEetD1kzU3PZqR4nHPS8erDkrUK0hN4iCBQ4vH5U"); err != nil { assert.Equal(t, err.Error(), "illegal base64 data at input byte 1") } - } func TestToChecksumAddress(t *testing.T) { - assert.Equal(t, "0xE9D09A6C296ACDd4C01b21F407aC93FDfC63e78c", ToChecksumAddress("0xe9d09A6C296aCdd4c01b21f407ac93fdfC63E78C")) - assert.Equal(t, "0xE9D09A6C296ACDd4C01b21F407aC93FDfC63e78c", ToChecksumAddress("0xe9d09A6C296aCdd4c01b21f407ac93fdfC63E78C")) } - -func TestRemoveSpecialCharactersfromHash(t *testing.T) { - testCases := []struct { - input string - expectedOutput string - }{ - {"abc123", "abc123"}, - {"abc123!@#", "abc123"}, - {"a1b2c3 ~`!@#$%^&*()_+-={}[]|\\:;\"'<>,.?/", "a1b2c3="}, - {"abc=123", "abc=123"}, - {"a1!b2@c3#=4", "a1b2c3=4"}, - } - - for _, tc := range testCases { - t.Run(tc.input, func(t *testing.T) { - output := RemoveSpecialCharactersfromHash(tc.input) - if output != tc.expectedOutput { - t.Errorf("RemoveSpecialCharactersfromHash(%q) = %q; want %q", tc.input, output, tc.expectedOutput) - } - }) - } -} diff --git a/config/blockchain_network_config.go b/config/blockchain_network_config.go index cd2f37d7..619d9b3e 100644 --- a/config/blockchain_network_config.go +++ b/config/blockchain_network_config.go @@ -12,17 +12,19 @@ import ( ) type NetworkSelected struct { - NetworkName string - EthereumJSONRPCEndpoint string - NetworkId string - RegistryAddressKey string + NetworkName string + EthereumJSONRPCHTTPEndpoint string + EthereumJSONRPCWSEndpoint string + NetworkId string + RegistryAddressKey string } const ( - BlockChainNetworkFileName = "resources/blockchain_network_config.json" - EthereumJsonRpcEndpointKey = "ethereum_json_rpc_endpoint" - NetworkId = "network_id" - RegistryAddressKey = "registry_address_key" + BlockChainNetworkFileName = "resources/blockchain_network_config.json" + EthereumJsonRpcHTTPEndpointKey = "ethereum_json_rpc_http_endpoint" + EthereumJsonRpcWSEndpointKey = "ethereum_json_rpc_ws_endpoint" + NetworkId = "network_id" + RegistryAddressKey = "registry_address_key" ) var networkSelected = &NetworkSelected{} @@ -38,7 +40,8 @@ func determineNetworkSelected(data []byte) (err error) { //Ethereum End point and Network ID mapped to networkSelected.NetworkName = networkName networkSelected.RegistryAddressKey = getDetailsFromJsonOrConfig(dynamicBinding[networkName].(map[string]any)[RegistryAddressKey], RegistryAddressKey) - networkSelected.EthereumJSONRPCEndpoint = getDetailsFromJsonOrConfig(dynamicBinding[networkName].(map[string]any)[EthereumJsonRpcEndpointKey], EthereumJsonRpcEndpointKey) + networkSelected.EthereumJSONRPCHTTPEndpoint = getDetailsFromJsonOrConfig(dynamicBinding[networkName].(map[string]any)[EthereumJsonRpcHTTPEndpointKey], EthereumJsonRpcHTTPEndpointKey) + networkSelected.EthereumJSONRPCWSEndpoint = getDetailsFromJsonOrConfig(dynamicBinding[networkName].(map[string]any)[EthereumJsonRpcWSEndpointKey], EthereumJsonRpcWSEndpointKey) networkSelected.NetworkId = fmt.Sprintf("%v", dynamicBinding[networkName].(map[string]any)[NetworkId]) return err @@ -61,9 +64,13 @@ func GetNetworkId() string { return networkSelected.NetworkId } -// Get the block chain end point associated with the Network selected -func GetBlockChainEndPoint() string { - return networkSelected.EthereumJSONRPCEndpoint +// Get the blockchain endpoint associated with the Network selected +func GetBlockChainHTTPEndPoint() string { + return networkSelected.EthereumJSONRPCHTTPEndpoint +} + +func GetBlockChainWSEndPoint() string { + return networkSelected.EthereumJSONRPCWSEndpoint } // Get the Registry address of the contract @@ -73,8 +80,7 @@ func GetRegistryAddress() string { // Read the Registry address from JSON file passed func setRegistryAddress() (err error) { - - //if address is already set in the config file and has been initialized , then skip the setting process + //if the address is already set in the config file and has been initialized, then skip the setting process if len(networkSelected.RegistryAddressKey) > 0 { return } @@ -110,9 +116,11 @@ func deriveDatafromJSON(data []byte) (err error) { networkSelected.RegistryAddressKey = fmt.Sprintf("%v", m[GetNetworkId()].(map[string]any)["address"]) zap.L().Info("Derive data from JSON", zap.String("Network", GetString(BlockChainNetworkSelected)), - zap.String("NetwrokId", GetNetworkId()), - zap.String("RegistryAddress", GetRegistryAddress()), - zap.String("Blockchain endpoint", GetBlockChainEndPoint())) + zap.String("Network id", GetNetworkId()), + zap.String("Registry address", GetRegistryAddress()), + zap.String("Blockchain http endpoint", GetBlockChainHTTPEndPoint()), + zap.String("Blockchain ws endpoint", GetBlockChainWSEndPoint()), + ) return nil } @@ -125,7 +133,6 @@ func ReadFromFile(filename string) ([]byte, error) { } } return file, nil - } // Read from the blockchain network config json diff --git a/config/blockchain_network_config_test.go b/config/blockchain_network_config_test.go index 9f6771c0..acaeff5e 100644 --- a/config/blockchain_network_config_test.go +++ b/config/blockchain_network_config_test.go @@ -16,31 +16,35 @@ func TestGetNetworkId(t *testing.T) { var defaultBlockChainNetworkConfig = ` { "local": { - "ethereum_json_rpc_endpoint": "http://localhost:8545", - "network_id": "42", + "ethereum_json_rpc_http_endpoint": "http://localhost:8545", + "ethereum_json_rpc_ws_endpoint": "ws://localhost:443", + "network_id": "42", "registry_address_key": "0x4e74fefa82e83e0964f0d9f53c68e03f7298a8b2" }, "main": { - "ethereum_json_rpc_endpoint": "https://mainnet.infura.io/v3", + "ethereum_json_rpc_http_endpoint": "https://mainnet.infura.io/v3", + "ethereum_json_rpc_ws_endpoint": "wss://mainnet.infura.io/v3", "network_id": "1" }, "goerli": { - "ethereum_json_rpc_endpoint": "https://goerli.infura.io/v3", + "ethereum_json_rpc_http_endpoint": "https://goerli.infura.io/v3", + "ethereum_json_rpc_ws_endpoint": "wss://goerli.infura.io/v3", "network_id": "5" }, "sepolia": { - "ethereum_json_rpc_endpoint": "https://sepolia.infura.io/v3", + "ethereum_json_rpc_http_endpoint": "https://sepolia.infura.io/v3", + "ethereum_json_rpc_ws_endpoint": "wss://sepolia.infura.io/v3", "network_id": "11155111" } }` func TestGetBlockChainEndPoint(t *testing.T) { Vip().Set(BlockChainNetworkSelected, "local") - determineNetworkSelected([]byte(defaultBlockChainNetworkConfig)) - - assert.Matches(t, GetBlockChainEndPoint(), GetString(BlockChainNetworkSelected)) + err := determineNetworkSelected([]byte(defaultBlockChainNetworkConfig)) + assert.Equal(t, err, nil) + assert.Matches(t, GetBlockChainHTTPEndPoint(), GetString(BlockChainNetworkSelected)) + assert.Matches(t, GetBlockChainWSEndPoint(), GetString(BlockChainNetworkSelected)) assert2.NotEqual(t, GetNetworkId(), nil) - } func TestGetRegistryAddress(t *testing.T) { @@ -92,7 +96,7 @@ func Test_GetDetailsFromJsonOrConfig(t *testing.T) { want string network string }{ - {EthereumJsonRpcEndpointKey, "https://sepolia.infura.io/v3", "sepolia"}, + {EthereumJsonRpcHTTPEndpointKey, "https://sepolia.infura.io/v3", "sepolia"}, {RegistryAddressKey, "0x4e74fefa82e83e0964f0d9f53c68e03f7298a8b2", "local"}, } for _, tt := range tests { diff --git a/config/config.go b/config/config.go index c88942dc..5e6c0647 100644 --- a/config/config.go +++ b/config/config.go @@ -13,10 +13,9 @@ import ( "time" "github.com/ethereum/go-ethereum/common" - "go.uber.org/zap" - "github.com/spf13/cast" "github.com/spf13/viper" + "go.uber.org/zap" ) const ( @@ -113,7 +112,8 @@ const ( }, "payment_channel_storage_client": { "connection_timeout": "0s", - "request_timeout": "0s" + "request_timeout": "0s", + "hot_reload": true }, "payment_channel_storage_server": { "id": "storage-1", @@ -406,11 +406,11 @@ func ValidateEmail(email string) bool { } func ValidateEndpoints(daemonEndpoint string, passthroughEndpoint string) error { - passthroughURL, err := url.Parse(passthroughEndpoint) if err != nil || passthroughURL.Host == "" { return errors.New("passthrough_endpoint is the endpoint of your AI service in the daemon config and needs to be a valid url.") } + daemonHost, daemonPort, err := net.SplitHostPort(daemonEndpoint) if err != nil { return errors.New("couldn't split host:post of daemon endpoint") @@ -443,7 +443,7 @@ func IsAllowedUser(address *common.Address) bool { // Set the list of allowed users func SetAllowedUsers() (err error) { users := vip.GetStringSlice(AllowedUserAddresses) - if users == nil || len(users) == 0 { + if len(users) == 0 { return fmt.Errorf("a valid Address needs to be specified for the config %v to ensure that, only these users can make calls", AllowedUserAddresses) } userAddress = make([]common.Address, len(users)) diff --git a/config/configuration_schema.go b/config/configuration_schema.go index 505dcf1c..16c78a62 100644 --- a/config/configuration_schema.go +++ b/config/configuration_schema.go @@ -87,7 +87,6 @@ func GetConfigurationSchema() ([]ConfigurationDetails, error) { _ = json.Unmarshal(configurationDetailsJSON, configDetails) allConfigurations = append(allConfigurations, *configDetails) } - } return allConfigurations, nil } diff --git a/config/configuration_schema_test.go b/config/configuration_schema_test.go index 00e2af8f..a639cf8a 100644 --- a/config/configuration_schema_test.go +++ b/config/configuration_schema_test.go @@ -31,12 +31,11 @@ func Test_getLeafNodeKey(t *testing.T) { } func TestGetSchemaConfiguration(t *testing.T) { - schemaDetails,err := GetConfigurationSchema() - for _,element := range schemaDetails { - if (element.Name == "blockchain_network_selected") { - assert.Equal(t,element.DefaultValue,"local") + schemaDetails, err := GetConfigurationSchema() + for _, element := range schemaDetails { + if element.Name == "blockchain_network_selected" { + assert.Equal(t, element.DefaultValue, "local") } } - assert.Nil(t,err) + assert.Nil(t, err) } - diff --git a/config/version.go b/config/version.go index d76f6a02..08bea229 100644 --- a/config/version.go +++ b/config/version.go @@ -2,7 +2,6 @@ package config import ( "encoding/json" - "errors" "fmt" "io" "net/http" @@ -39,7 +38,7 @@ func CheckVersionOfDaemon() (message string, err error) { latestVersionFromGit, err = GetLatestDaemonVersion() if len(versionTag) > 0 && err == nil { if strings.Compare(latestVersionFromGit, versionTag) != 0 { - err = errors.New(fmt.Sprintf("There is a newer version of the Daemon %v available. You are currently on %v, please consider upgrading.", latestVersionFromGit, versionTag)) + err = fmt.Errorf("there is a newer version of the Daemon %v available. You are currently on %v, please consider upgrading", latestVersionFromGit, versionTag) } } return message, err diff --git a/config/version_test.go b/config/version_test.go index 19088051..2392fa10 100644 --- a/config/version_test.go +++ b/config/version_test.go @@ -57,7 +57,7 @@ func TestCheckVersionOfDaemon(t *testing.T) { versionTag = "v5.1.2" message, err := CheckVersionOfDaemon() assert.NotNil(t, err) - assert.Contains(t, err.Error(), "There is a newer version of the Daemon") + assert.Contains(t, err.Error(), "there is a newer version of the Daemon") versionTag, _ = GetLatestDaemonVersion() message, err = CheckVersionOfDaemon() diff --git a/configuration_service/broadcast_message.go b/configuration_service/broadcast_message.go index 80ccda48..3d8164af 100644 --- a/configuration_service/broadcast_message.go +++ b/configuration_service/broadcast_message.go @@ -7,48 +7,44 @@ import ( type MessageBroadcaster struct { //Operator UI can trigger changes to the Daemon configuration or request the Daemon to stop/start processing requests will , // Hence we need a framework to receive this trigger and broadcast it to all the subscribers. - trigger chan int - quit chan int + trigger chan int + quit chan int subscribers []chan int - //This will be used to make sure , we dont interfere with other threads - mutex sync.Mutex + //This will be used to make sure, we don't interfere with other threads + mutex sync.Mutex } - func NewChannelBroadcaster() *MessageBroadcaster { broadcaster := &MessageBroadcaster{} - broadcaster.trigger = make(chan int,1) + broadcaster.trigger = make(chan int, 1) go broadcaster.Publish() return broadcaster } - -//Create a New Subscriber for this broadcaster message -//Interceptors or health checks can subscribe to this and react accordingly +// Create a New Subscriber for this broadcaster message +// Interceptors or health checks can subscribe to this and react accordingly func (broadcast *MessageBroadcaster) NewSubscriber() chan int { ch := make(chan int, 1) broadcast.mutex.Lock() defer broadcast.mutex.Unlock() if broadcast.subscribers == nil { - broadcast.subscribers = make([]chan int,0) + broadcast.subscribers = make([]chan int, 0) } broadcast.subscribers = append(broadcast.subscribers, ch) return ch } - -//Once a message is received, pass it down to all the subscribers +// Publish - Once a message is received, pass it down to all the subscribers func (broadcast *MessageBroadcaster) Publish() { for { - //Wait for the message to trigger the broadcast - msg := <- broadcast.trigger + // Wait for the message to trigger the broadcast + msg := <-broadcast.trigger broadcast.mutex.Lock() - defer broadcast.mutex.Unlock() for _, subscriber := range broadcast.subscribers { - //Now broad the message to all the subscribers. + // Now broad the message to all the subscribers. subscriber <- msg } - + broadcast.mutex.Unlock() } -} \ No newline at end of file +} diff --git a/configuration_service/broadcast_message_test.go b/configuration_service/broadcast_message_test.go index 69d066cb..66ecfece 100644 --- a/configuration_service/broadcast_message_test.go +++ b/configuration_service/broadcast_message_test.go @@ -12,18 +12,17 @@ func TestNewChannelBroadcaster(t *testing.T) { func TestChannelBroadcaster_NewSubscriber(t *testing.T) { broadcaster := NewChannelBroadcaster() - assert.NotNil(t,broadcaster) + assert.NotNil(t, broadcaster) channel1 := broadcaster.NewSubscriber() channel2 := broadcaster.NewSubscriber() - assert.NotNil(t,channel1) - assert.NotNil(t,channel2) + assert.NotNil(t, channel1) + assert.NotNil(t, channel2) //Add a message to trigger broadcaster.trigger <- 1 - msg1 := <- channel1 - msg2 := <- channel2 - assert.Equal(t,1,msg1) + msg1 := <-channel1 + msg2 := <-channel2 + assert.Equal(t, 1, msg1) //Check if all the subscribers received the same message - assert.Equal(t,msg2,msg1) + assert.Equal(t, msg2, msg1) close(broadcaster.trigger) } - diff --git a/configuration_service/configuration_service.go b/configuration_service/configuration_service.go index daf8a247..3a7479e0 100644 --- a/configuration_service/configuration_service.go +++ b/configuration_service/configuration_service.go @@ -38,15 +38,15 @@ const ( func getAuthenticationAddress() []common.Address { users := config.Vip().GetStringSlice(config.AuthenticationAddresses) userAddress := make([]common.Address, 0) - if users == nil || len(users) == 0 { + if len(users) == 0 { return userAddress } for _, user := range users { if !common.IsHexAddress(user) { - fmt.Errorf("%v is not a valid hex address", user) - } else { - userAddress = append(userAddress, common.BytesToAddress(common.FromHex(user))) + zap.L().Warn("not a valid hex address in config."+config.AuthenticationAddresses, zap.String("address", user)) + continue } + userAddress = append(userAddress, common.BytesToAddress(common.FromHex(user))) } return userAddress } diff --git a/contract_event_listener/contract_event_listener.go b/contract_event_listener/contract_event_listener.go new file mode 100644 index 00000000..cd6323e9 --- /dev/null +++ b/contract_event_listener/contract_event_listener.go @@ -0,0 +1,14 @@ +package contractlistener + +import ( + "github.com/singnet/snet-daemon/blockchain" + "github.com/singnet/snet-daemon/etcddb" +) + +type EventSignature string + +type ContractEventListener struct { + BlockchainProcessor *blockchain.Processor + CurrentOrganizationMetaData *blockchain.OrganizationMetaData + CurrentEtcdClient *etcddb.EtcdClient +} diff --git a/contract_event_listener/listen_organization_metadata_changing.go b/contract_event_listener/listen_organization_metadata_changing.go new file mode 100644 index 00000000..e574a2a0 --- /dev/null +++ b/contract_event_listener/listen_organization_metadata_changing.go @@ -0,0 +1,75 @@ +package contractlistener + +import ( + "context" + "slices" + + "github.com/singnet/snet-daemon/blockchain" + "github.com/singnet/snet-daemon/etcddb" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/gorilla/websocket" + "go.uber.org/zap" +) + +func (l *ContractEventListener) ListenOrganizationMetadataChanging() { + zap.L().Info("Starting contract event listener for organization metadata changing") + + watchOpts := &bind.WatchOpts{ + Start: nil, + Context: context.Background(), + } + + ethWSClient := l.BlockchainProcessor.GetEthWSClient() + + registryFilterer := blockchain.GetRegistryFilterer(ethWSClient) + orgIdFilter := blockchain.MakeTopicFilterer(l.CurrentOrganizationMetaData.OrgID) + + eventContractChannel := make(chan *blockchain.RegistryOrganizationModified) + sub, err := registryFilterer.WatchOrganizationModified(watchOpts, eventContractChannel, orgIdFilter) + + if err != nil { + zap.L().Fatal("Failed to subscribe to logs", zap.Error(err)) + } + + for { + select { + case err := <-sub.Err(): + if err != nil { + zap.L().Error("Subscription error: ", zap.Error(err)) + if websocket.IsCloseError( + err, + websocket.CloseNormalClosure, + websocket.CloseAbnormalClosure, + websocket.CloseGoingAway, + websocket.CloseServiceRestart, + websocket.CloseTryAgainLater, + websocket.CloseTLSHandshake, + ) { + err = l.BlockchainProcessor.ReconnectToWsClient() + if err != nil { + zap.L().Error("Error in reconnecting to websockets", zap.Error(err)) + } + } + } + case logData := <-eventContractChannel: + zap.L().Debug("Log received", zap.Any("value", logData)) + + // Get metaDataUri from smart contract and organizationMetaData from IPFS + newOrganizationMetaData := blockchain.GetOrganizationMetaData() + zap.L().Info("Get new organization metadata", zap.Any("value", newOrganizationMetaData)) + + if slices.Compare(l.CurrentOrganizationMetaData.GetPaymentStorageEndPoints(), newOrganizationMetaData.GetPaymentStorageEndPoints()) != 0 { + l.CurrentEtcdClient.Close() + newEtcdbClient, err := etcddb.Reconnect(newOrganizationMetaData) + if err != nil { + zap.L().Error("Error in reconnecting to etcd", zap.Error(err)) + } + l.CurrentEtcdClient = newEtcdbClient + } + + l.CurrentOrganizationMetaData = newOrganizationMetaData + zap.L().Info("Update current organization metadata", zap.Any("value", l.CurrentOrganizationMetaData)) + } + } +} diff --git a/escrow/allowed_user_payment_handler.go b/escrow/allowed_user_payment_handler.go index 54d81c33..f8c26dff 100644 --- a/escrow/allowed_user_payment_handler.go +++ b/escrow/allowed_user_payment_handler.go @@ -17,7 +17,7 @@ func AllowedUserPaymentHandler() handler.PaymentHandler { } } -//clients should be oblivious to this handler +// clients should be oblivious to this handler func (h *allowedUserPaymentHandler) Type() (typ string) { return EscrowPaymentType } diff --git a/escrow/control_service.go b/escrow/control_service.go index 333bf250..7225940f 100644 --- a/escrow/control_service.go +++ b/escrow/control_service.go @@ -98,7 +98,6 @@ If an error is encountered , then we return back whatever was successful and sto and return the error that was encountered. */ func (service *ProviderControlService) StartClaimForMultipleChannels(ctx context.Context, request *StartMultipleClaimRequest) (reply *PaymentsListReply, err error) { - if err := service.checkMpeAddress(request.GetMpeAddress()); err != nil { return nil, err } @@ -148,13 +147,10 @@ func (service *ProviderControlService) verifySignerForStartClaimForMultipleChann func getBytesOfChannelIds(request *StartMultipleClaimRequest) []byte { channelIds := make([]uint64, 0) - for _, channelId := range request.GetChannelIds() { - channelIds = append(channelIds, channelId) - } + channelIds = append(channelIds, request.GetChannelIds()...) //sort the channel Ids Uint64s(channelIds) channelIdInBytes := make([]byte, 0) - for index, channelId := range channelIds { if index == 0 { channelIdInBytes = bytes.Join([][]byte{ diff --git a/escrow/control_service_test.go b/escrow/control_service_test.go index eec5ba39..3fb78872 100644 --- a/escrow/control_service_test.go +++ b/escrow/control_service_test.go @@ -78,8 +78,8 @@ func (suite *ControlServiceTestSuite) SetupSuite() { println(errs) suite.receiverAddress = crypto.PubkeyToAddress(suite.receiverPvtKy.PublicKey) orgJson := strings.Replace(testJsonOrgGroupData, "0x671276c61943A35D5F230d076bDFd91B0c47bF09", suite.receiverAddress.Hex(), -1) - suite.orgMetaData, _ = blockchain.InitOrganizationMetaDataFromJson(orgJson) - suite.serviceMetaData, _ = blockchain.InitServiceMetaDataFromJson(testJsonData) + suite.orgMetaData, _ = blockchain.InitOrganizationMetaDataFromJson([]byte(orgJson)) + suite.serviceMetaData, _ = blockchain.InitServiceMetaDataFromJson([]byte(testJsonData)) println("suite.orgMetaData.GetPaymentAddress().Hex() " + suite.orgMetaData.GetPaymentAddress().Hex()) println("suite.receiverAddress.Hex()" + suite.receiverAddress.Hex()) diff --git a/escrow/escrow.go b/escrow/escrow.go index 5e043ad4..5f941024 100644 --- a/escrow/escrow.go +++ b/escrow/escrow.go @@ -50,8 +50,8 @@ func (h *lockingPaymentChannelService) PaymentChannel(key *PaymentChannelKey) (c blockchainChannel, blockchainOk, err := h.blockchainReader.GetChannelStateFromBlockchain(key) if !storageOk { - // Group ID check is only done for the first time , when the channel is added to storage from the block chain , - //if the channel is already present in the storage the group ID check is skipped. + // Group ID check is only done for the first time, when the channel is added to storage from the blockchain, + // if the channel is already present in the storage the group ID check is skipped. if blockchainChannel != nil { blockChainGroupID, err := h.replicaGroupID() if err = h.verifyGroupId(blockChainGroupID, blockchainChannel.GroupID); err != nil { diff --git a/escrow/free_call.go b/escrow/free_call.go index ecf101c4..7896bd24 100644 --- a/escrow/free_call.go +++ b/escrow/free_call.go @@ -150,7 +150,7 @@ func (transaction *freeCallTransaction) Commit() error { return nil } -func (payment *freeCallTransaction) Rollback() error { +func (transaction *freeCallTransaction) Rollback() error { defer func(payment *freeCallTransaction) { err := payment.lock.Unlock() if err != nil { @@ -159,6 +159,6 @@ func (payment *freeCallTransaction) Rollback() error { } else { zap.L().Debug("Free call Payment rolled back, free call user unlocked") } - }(payment) + }(transaction) return nil } diff --git a/escrow/free_call_payment_handler_test.go b/escrow/free_call_payment_handler_test.go index ef58f4f7..036fd517 100644 --- a/escrow/free_call_payment_handler_test.go +++ b/escrow/free_call_payment_handler_test.go @@ -43,8 +43,8 @@ func (suite *FreeCallPaymentHandlerTestSuite) SetupSuite() { suite.privateKey = GenerateTestPrivateKey() suite.memoryStorage = storage.NewMemStorage() suite.storage = NewFreeCallUserStorage(suite.memoryStorage) - orgMetadata, _ := blockchain.InitOrganizationMetaDataFromJson(testJsonOrgGroupData) - suite.metadata, _ = blockchain.InitServiceMetaDataFromJson(testJsonData) + orgMetadata, _ := blockchain.InitOrganizationMetaDataFromJson([]byte(testJsonOrgGroupData)) + suite.metadata, _ = blockchain.InitServiceMetaDataFromJson([]byte(testJsonData)) suite.data = &FreeCallUserData{FreeCallsMade: 12, UserId: "user1"} suite.key = suite.getKey("user1") suite.paymentHandler = freeCallPaymentHandler{ diff --git a/escrow/free_call_state_service_test.go b/escrow/free_call_state_service_test.go index 675ad31f..60ed19be 100644 --- a/escrow/free_call_state_service_test.go +++ b/escrow/free_call_state_service_test.go @@ -48,8 +48,8 @@ func (suite *FreeCallStateServiceSuite) SetupSuite() { testJsonData = "{ \"version\": 1, \"display_name\": \"Example1\", \"encoding\": \"grpc\", \"service_type\": \"grpc\", \"payment_expiration_threshold\": 40320, \"model_ipfs_hash\": \"Qmdiq8Hu6dYiwp712GtnbBxagyfYyvUY1HYqkH7iN76UCc\", " + " \"mpe_address\": \"0x7E6366Fbe3bdfCE3C906667911FC5237Cc96BD08\", \"groups\": [ { \"free_calls\": 12, \"free_call_signer_address\": \"0x94d04332C4f5273feF69c4a52D24f42a3aF1F207\", \"endpoints\": [\"http://34.344.33.1:2379\",\"http://34.344.33.1:2389\"], \"group_id\": \"88ybRIg2wAx55mqVsA6sB4S7WxPQHNKqa4BPu/bhj+U=\",\"group_name\": \"default_group\", \"pricing\": [ { \"price_model\": \"fixed_price\", \"price_in_cogs\": 2 }, { \"package_name\": \"example_service\", \"price_model\": \"fixed_price_per_method\", \"default\":true, \"details\": [ { \"service_name\": \"Calculator\", \"method_pricing\": [ { \"method_name\": \"add\", \"price_in_cogs\": 2 }, { \"method_name\": \"sub\", \"price_in_cogs\": 1 }, { \"method_name\": \"div\", \"price_in_cogs\": 2 }, { \"method_name\": \"mul\", \"price_in_cogs\": 3 } ] }, { \"service_name\": \"Calculator2\", \"method_pricing\": [ { \"method_name\": \"add\", \"price_in_cogs\": 2 }, { \"method_name\": \"sub\", \"price_in_cogs\": 1 }, { \"method_name\": \"div\", \"price_in_cogs\": 3 }, { \"method_name\": \"mul\", \"price_in_cogs\": 2 } ] } ] }] }, { \"endpoints\": [\"http://97.344.33.1:2379\",\"http://67.344.33.1:2389\"], \"group_id\": \"99ybRIg2wAx55mqVsA6sB4S7WxPQHNKqa4BPu/bhj+U=\", \"pricing\": [ { \"package_name\": \"example_service\", \"price_model\": \"fixed_price_per_method\", \"details\": [ { \"service_name\": \"Calculator\", \"method_pricing\": [ { \"method_name\": \"add\", \"price_in_cogs\": 2 }, { \"method_name\": \"sub\", \"price_in_cogs\": 1 }, { \"method_name\": \"div\", \"price_in_cogs\": 2 }, { \"method_name\": \"mul\", \"price_in_cogs\": 3 } ] }, { \"service_name\": \"Calculator2\", \"method_pricing\": [ { \"method_name\": \"add\", \"price_in_cogs\": 2 }, { \"method_name\": \"sub\", \"price_in_cogs\": 1 }, { \"method_name\": \"div\", \"price_in_cogs\": 3 }, { \"method_name\": \"mul\", \"price_in_cogs\": 2 } ] } ] }] } ] } " - suite.orgMetaData, _ = blockchain.InitOrganizationMetaDataFromJson(testJsonOrgGroupData) - suite.serviceMetaData, _ = blockchain.InitServiceMetaDataFromJson(testJsonData) + suite.orgMetaData, _ = blockchain.InitOrganizationMetaDataFromJson([]byte(testJsonOrgGroupData)) + suite.serviceMetaData, _ = blockchain.InitServiceMetaDataFromJson([]byte(testJsonData)) suite.memoryStorage = storage.NewMemStorage() suite.storage = NewFreeCallUserStorage(suite.memoryStorage) suite.service = NewFreeCallUserService(suite.storage, diff --git a/escrow/free_call_test.go b/escrow/free_call_test.go index c63f6793..e3705559 100644 --- a/escrow/free_call_test.go +++ b/escrow/free_call_test.go @@ -30,7 +30,7 @@ func (suite *FreeCallServiceSuite) FreeCallUserData() *FreeCallUserData { } func (suite *FreeCallServiceSuite) SetupSuite() { - metadata, err := blockchain.InitServiceMetaDataFromJson(testJsonData) + metadata, err := blockchain.InitServiceMetaDataFromJson([]byte(testJsonData)) assert.Nil(suite.T(), err, "Unexpected error: %v", err) suite.metadata = metadata suite.memoryStorage = storage.NewMemStorage() diff --git a/escrow/income.go b/escrow/income.go index 18a40e39..88c4b1ee 100644 --- a/escrow/income.go +++ b/escrow/income.go @@ -19,11 +19,11 @@ type IncomeData struct { GrpcContext *handler.GrpcStreamContext } -// IncomeValidator uses pricing information to check that call was payed +// IncomeValidator uses pricing information to check that call was paid // correctly by channel sender. This interface can be implemented differently -// depending on pricing policy. For instance one can verify that call is payed +// depending on pricing policy. For instance one can verify that call is paid // according to invoice. Each RPC method can have different price and so on. To -// implement this strategies additional information from gRPC context can be +// implement these strategies additional information from gRPC context can be // required. In such case it should be added into handler.GrpcStreamContext. type IncomeValidator interface { // Validate returns nil if validation is successful or correct PaymentError @@ -41,7 +41,6 @@ func NewIncomeValidator(pricing *pricing.PricingStrategy) (validator IncomeValid } func (validator *incomeValidator) Validate(data *IncomeData) (err error) { - //TO DO, the user request information from IncomeData needs to be passed here !!!! price, err := validator.priceStrategy.GetPrice(data.GrpcContext) if err != nil { return err diff --git a/escrow/income_test.go b/escrow/income_test.go index 9668ebab..6b319618 100644 --- a/escrow/income_test.go +++ b/escrow/income_test.go @@ -31,7 +31,7 @@ func (priceType MockPriceType) GetPriceType() string { var testJsonDataFixedPrice = "{ \"version\": 1, \"display_name\": \"Example1\", \"encoding\": \"grpc\", \"service_type\": \"grpc\", \"payment_expiration_threshold\": 40320, \"model_ipfs_hash\": \"Qmdiq8Hu6dYiwp712GtnbBxagyfYyvUY1HYqkH7iN76UCc\", \"mpe_address\": \"0x7E6366Fbe3bdfCE3C906667911FC5237Cc96BD08\", \"groups\": [ { \"endpoints\": [\"http://34.344.33.1:2379\",\"http://34.344.33.1:2389\"], \"group_id\": \"88ybRIg2wAx55mqVsA6sB4S7WxPQHNKqa4BPu/bhj+U=\",\"group_name\": \"default_group\", \"pricing\": [ { \"price_model\": \"fixed_price\", \"default\":true, \"price_in_cogs\": 2 }, { \"package_name\": \"example_service\", \"price_model\": \"fixed_price_per_method\", \"details\": [ { \"service_name\": \"Calculator\", \"method_pricing\": [ { \"method_name\": \"add\", \"price_in_cogs\": 2 }, { \"method_name\": \"sub\", \"price_in_cogs\": 1 }, { \"method_name\": \"div\", \"price_in_cogs\": 2 }, { \"method_name\": \"mul\", \"price_in_cogs\": 3 } ] }, { \"service_name\": \"Calculator2\", \"method_pricing\": [ { \"method_name\": \"add\", \"price_in_cogs\": 2 }, { \"method_name\": \"sub\", \"price_in_cogs\": 1 }, { \"method_name\": \"div\", \"price_in_cogs\": 3 }, { \"method_name\": \"mul\", \"price_in_cogs\": 2 } ] } ] }] }, { \"endpoints\": [\"http://97.344.33.1:2379\",\"http://67.344.33.1:2389\"], \"group_name\": \"99ybRIg2wAx55mqVsA6sB4S7WxPQHNKqa4BPu/bhj+U=\", \"group_id\": \"99ybRIg2wAx55mqVsA6sB4S7WxPQHNKqa4BPu/bhj+U=\", \"pricing\": [ { \"package_name\": \"example_service\", \"price_model\": \"fixed_price_per_method\", \"details\": [ { \"service_name\": \"Calculator\", \"method_pricing\": [ { \"method_name\": \"add\", \"price_in_cogs\": 2 }, { \"method_name\": \"sub\", \"price_in_cogs\": 1 }, { \"method_name\": \"div\", \"price_in_cogs\": 2 }, { \"method_name\": \"mul\", \"price_in_cogs\": 3 } ] }, { \"service_name\": \"Calculator2\", \"method_pricing\": [ { \"method_name\": \"add\", \"price_in_cogs\": 2 }, { \"method_name\": \"sub\", \"price_in_cogs\": 1 }, { \"method_name\": \"div\", \"price_in_cogs\": 3 }, { \"method_name\": \"mul\", \"price_in_cogs\": 2 } ] } ] }] } ] } " -var pricingMetadata, _ = blockchain.InitServiceMetaDataFromJson(testJsonDataFixedPrice) +var pricingMetadata, _ = blockchain.InitServiceMetaDataFromJson([]byte(testJsonDataFixedPrice)) func TestIncomeValidate(t *testing.T) { one := big.NewInt(1) diff --git a/escrow/lock.go b/escrow/lock.go index f7eceefa..5819d761 100644 --- a/escrow/lock.go +++ b/escrow/lock.go @@ -5,15 +5,15 @@ import ( "go.uber.org/zap" ) -// Lock is an aquired lock. +// Lock is an acquired lock. type Lock interface { // Unlock frees lock Unlock() (err error) } -// Locker is an interface to aquire lock +// Locker is an interface to acquire lock type Locker interface { - // Lock aquires and returns lock. ok is false if lock cannot be aquired. + // Lock acquires and returns lock. ok is false if lock cannot be acquired. Lock(name string) (lock Lock, ok bool, err error) } diff --git a/escrow/payment_channel_storage.go b/escrow/payment_channel_storage.go index e402e9e2..704f017f 100644 --- a/escrow/payment_channel_storage.go +++ b/escrow/payment_channel_storage.go @@ -44,8 +44,7 @@ func serialize(value any) (slice string, err error) { return } - slice = string(b.Bytes()) - return + return b.String(), err } func deserialize(slice string, value any) (err error) { @@ -119,10 +118,10 @@ func (reader *BlockchainChannelReader) GetChannelStateFromBlockchain(key *Paymen recipientPaymentAddress := reader.recipientPaymentAddress() if recipientPaymentAddress != ch.Recipient { - zap.L().Warn("Recipient Address from service metadata not Match on what was retrieved from Channel", + zap.L().Warn("Recipient Address from org metadata not Match on what was retrieved from Channel", zap.Any("recipientPaymentAddress", recipientPaymentAddress), zap.Any("ch.Recipient", ch.Recipient)) - return nil, false, fmt.Errorf("recipient Address from service metadata does not Match on what was retrieved from Channel") + return nil, false, fmt.Errorf("recipient Address from org metadata does not Match on what was retrieved from Channel") } return &PaymentChannelData{ ChannelID: key.ID, diff --git a/escrow/payment_channel_storage_test.go b/escrow/payment_channel_storage_test.go index 4ac97112..4b8b26e4 100644 --- a/escrow/payment_channel_storage_test.go +++ b/escrow/payment_channel_storage_test.go @@ -163,19 +163,20 @@ func (suite *BlockchainChannelReaderSuite) TestGetChannelState() { assert.Equal(suite.T(), suite.channel(), channel) } -func (suite *BlockchainChannelReaderSuite) TestGetChannelStateIncorrectRecipeintAddress() { +func (suite *BlockchainChannelReaderSuite) TestGetChannelStateIncorrectRecipientAddress() { reader := suite.reader reader.recipientPaymentAddress = func() common.Address { return crypto.PubkeyToAddress(GenerateTestPrivateKey().PublicKey) } channel, ok, err := reader.GetChannelStateFromBlockchain(suite.channelKey()) - assert.Equal(suite.T(), errors.New("recipient Address from service metadata does not Match on what was retrieved from Channel"), err) + assert.Equal(suite.T(), errors.New("recipient Address from org metadata does not Match on what was retrieved from Channel"), err) assert.False(suite.T(), ok) assert.Nil(suite.T(), channel) } func (suite *PaymentChannelStorageSuite) TestNewPaymentChannelStorage() { mpeStorage := storage.NewPrefixedAtomicStorage(storage.NewPrefixedAtomicStorage(suite.memoryStorage, "path1"), "path2") - mpeStorage.Put("key1", "value1") + err := mpeStorage.Put("key1", "value1") + assert.Nil(suite.T(), err) value, _, _ := mpeStorage.Get("key1") assert.Equal(suite.T(), value, "value1") values, err := suite.memoryStorage.GetByKeyPrefix("path1") diff --git a/escrow/payment_handler.go b/escrow/payment_handler.go index 8b68d91b..0ad64c04 100644 --- a/escrow/payment_handler.go +++ b/escrow/payment_handler.go @@ -27,7 +27,7 @@ type paymentChannelPaymentHandler struct { incomeValidator IncomeValidator } -// NewPaymentHandler retuns new MultiPartyEscrow contract payment handler. +// NewPaymentHandler returns new MultiPartyEscrow contract payment handler. func NewPaymentHandler( service PaymentChannelService, processor *blockchain.Processor, diff --git a/escrow/prepaid_handler.go b/escrow/prepaid_handler.go index 40df2439..d100e84d 100644 --- a/escrow/prepaid_handler.go +++ b/escrow/prepaid_handler.go @@ -34,7 +34,7 @@ type PrePaidPaymentHandler struct { func (validator *PrePaidPaymentValidator) Validate(payment *PrePaidPayment) (err error) { //Validate the token - return validator.tokenManager.VerifyToken(string(payment.AuthToken), payment.ChannelID) + return validator.tokenManager.VerifyToken(payment.AuthToken, payment.ChannelID) } // NewPaymentHandler returns new MultiPartyEscrow contract payment handler. diff --git a/escrow/token_service.go b/escrow/token_service.go index 68dfdb49..5cf7e630 100644 --- a/escrow/token_service.go +++ b/escrow/token_service.go @@ -164,5 +164,5 @@ func (service *TokenService) GetToken(ctx context.Context, request *TokenRequest } tokenGenerated, err := service.tokenManager.CreateToken(channelID) return &TokenReply{ChannelId: request.ChannelId, Token: fmt.Sprintf("%v", tokenGenerated), PlannedAmount: plannedAmount.Amount.Uint64(), - UsedAmount: usageAmount.Uint64()}, nil + UsedAmount: usageAmount.Uint64()}, err } diff --git a/escrow/token_service_test.go b/escrow/token_service_test.go index fe694414..d0aa2047 100644 --- a/escrow/token_service_test.go +++ b/escrow/token_service_test.go @@ -77,8 +77,8 @@ func (suite *TokenServiceTestSuite) SetupSuite() { suite.senderAddress = crypto.PubkeyToAddress(suite.senderPvtKy.PublicKey) suite.receiverAddress = crypto.PubkeyToAddress(suite.receiverPvtKy.PublicKey) orgJson := strings.Replace(testJsonOrgGroupData, "0x671276c61943A35D5F230d076bDFd91B0c47bF09", suite.receiverAddress.Hex(), -1) - suite.orgMetaData, _ = blockchain.InitOrganizationMetaDataFromJson(orgJson) - suite.serviceMetaData, _ = blockchain.InitServiceMetaDataFromJson(testJsonData) + suite.orgMetaData, _ = blockchain.InitOrganizationMetaDataFromJson([]byte(orgJson)) + suite.serviceMetaData, _ = blockchain.InitServiceMetaDataFromJson([]byte(testJsonData)) println("suite.orgMetaData.GetPaymentAddress().Hex() " + suite.orgMetaData.GetPaymentAddress().Hex()) println("suite.receiverAddress.Hex()" + suite.receiverAddress.Hex()) diff --git a/etcddb/etcddb_client.go b/etcddb/etcddb_client.go index 529f9ea4..a2e46512 100644 --- a/etcddb/etcddb_client.go +++ b/etcddb/etcddb_client.go @@ -35,11 +35,12 @@ func (mutex *EtcdClientMutex) Unlock(ctx context.Context) (err error) { return mutex.mutex.Unlock(ctx) } -// EtcdClient struct has some useful methods to wolrk with etcd client +// EtcdClient struct has some useful methods to work with an etcd client type EtcdClient struct { - timeout time.Duration - session *concurrency.Session - etcdv3 *clientv3.Client + hotReaload bool + timeout time.Duration + session *concurrency.Session + etcdv3 *clientv3.Client } // NewEtcdClient create new etcd storage client. @@ -64,25 +65,26 @@ func NewEtcdClientFromVip(vip *viper.Viper, metaData *blockchain.OrganizationMet var etcdv3 *clientv3.Client if utils.CheckIfHttps(metaData.GetPaymentStorageEndPoints()) { - if tlsConfig, err := getTlsConfig(); err == nil { - etcdv3, err = clientv3.New(clientv3.Config{ - Endpoints: metaData.GetPaymentStorageEndPoints(), - DialTimeout: conf.ConnectionTimeout, - TLS: tlsConfig, - }) - } else { + var tlsConfig *tls.Config + tlsConfig, err = getTlsConfig() + if err != nil { return nil, err } - + etcdv3, err = clientv3.New(clientv3.Config{ + Endpoints: conf.Endpoints, + DialTimeout: conf.ConnectionTimeout, + TLS: tlsConfig, + }) } else { - //Regular http call + // Regular http call etcdv3, err = clientv3.New(clientv3.Config{ - Endpoints: metaData.GetPaymentStorageEndPoints(), + Endpoints: conf.Endpoints, DialTimeout: conf.ConnectionTimeout, }) - if err != nil { - return nil, err - } + } + + if err != nil { + return nil, err } ctx, cancel := context.WithTimeout(context.Background(), conf.RequestTimeout) @@ -93,15 +95,24 @@ func NewEtcdClientFromVip(vip *viper.Viper, metaData *blockchain.OrganizationMet } client = &EtcdClient{ - timeout: conf.RequestTimeout, - session: session, - etcdv3: etcdv3, + hotReaload: conf.HotReload, + timeout: conf.RequestTimeout, + session: session, + etcdv3: etcdv3, } return } -func getTlsConfig() (*tls.Config, error) { +func Reconnect(metadata *blockchain.OrganizationMetaData) (*EtcdClient, error) { + etcdClient, err := NewEtcdClientFromVip(config.Vip(), metadata) + if err != nil { + return nil, err + } + zap.L().Info("Successful reconnect to new etcd endpoints", zap.Strings("New endpoints", metadata.GetPaymentStorageEndPoints())) + return etcdClient, nil +} +func getTlsConfig() (*tls.Config, error) { zap.L().Debug("enabling SSL support via X509 keypair") cert, err := tls.LoadX509KeyPair(config.GetString(config.PaymentChannelCertPath), config.GetString(config.PaymentChannelKeyPath)) @@ -119,12 +130,10 @@ func getTlsConfig() (*tls.Config, error) { RootCAs: caCertPool, } return tlsConfig, nil - } // Get gets value from etcd by key func (client *EtcdClient) Get(key string) (value string, ok bool, err error) { - ctx, cancel := context.WithTimeout(context.Background(), client.timeout) defer cancel() @@ -469,6 +478,10 @@ func (client *EtcdClient) StartTransaction(keys []string) (_transaction storage. return transaction, nil } +func (client *EtcdClient) IsHotReloadEnabled() bool { + return client.hotReaload +} + type keyValueVersion struct { Key string Value string diff --git a/etcddb/etcddb_client_test.go b/etcddb/etcddb_client_test.go index f84db835..b5e0aee7 100644 --- a/etcddb/etcddb_client_test.go +++ b/etcddb/etcddb_client_test.go @@ -4,7 +4,6 @@ import ( "testing" "github.com/magiconair/properties/assert" - _ "github.com/singnet/snet-daemon/fix-proto" "github.com/singnet/snet-daemon/utils" ) diff --git a/etcddb/etcddb_conf.go b/etcddb/etcddb_conf.go index 1414385a..ca33c890 100644 --- a/etcddb/etcddb_conf.go +++ b/etcddb/etcddb_conf.go @@ -7,6 +7,7 @@ import ( "github.com/singnet/snet-daemon/blockchain" "github.com/singnet/snet-daemon/config" "github.com/spf13/viper" + "go.uber.org/zap" ) // EtcdClientConf config @@ -16,18 +17,19 @@ import ( type EtcdClientConf struct { ConnectionTimeout time.Duration `json:"connection_timeout" mapstructure:"connection_timeout"` RequestTimeout time.Duration `json:"request_timeout" mapstructure:"request_timeout"` + HotReload bool `json:"hot_reload" mapstructure:"hot_reload"` Endpoints []string } -// GetEtcdClientConf gets EtcdServerConf from viper +// GetEtcdClientConf returns EtcdClientConf from viper and ipfs metadata // The DefaultEtcdClientConf is used in case the PAYMENT_CHANNEL_STORAGE_CLIENT field -// is not set in the configuration file -// Left Vip, just in case we need to read something from configuration in the future +// if ConnectionTimeout or RequestTimeout are set in the config, they will be taken from there func GetEtcdClientConf(vip *viper.Viper, metaData *blockchain.OrganizationMetaData) (conf *EtcdClientConf, err error) { conf = &EtcdClientConf{ ConnectionTimeout: metaData.GetConnectionTimeOut(), RequestTimeout: metaData.GetRequestTimeOut(), + HotReload: true, Endpoints: metaData.GetPaymentStorageEndPoints(), } @@ -47,6 +49,8 @@ func GetEtcdClientConf(vip *viper.Viper, metaData *blockchain.OrganizationMetaDa conf.ConnectionTimeout = confFromVip.ConnectionTimeout } + conf.HotReload = confFromVip.HotReload + zap.L().Info("Etcd client hot reload", zap.Bool("enable", conf.HotReload)) return } diff --git a/etcddb/etcddb_conf_test.go b/etcddb/etcddb_conf_test.go index e3868101..72d26fb2 100644 --- a/etcddb/etcddb_conf_test.go +++ b/etcddb/etcddb_conf_test.go @@ -15,7 +15,7 @@ import ( func TestDefaultEtcdClientConf(t *testing.T) { var testJsonOrgGroupData = "{ \"org_name\": \"organization_name\", \"org_id\": \"org_id1\", \"groups\": [ { \"group_name\": \"default_group2\", \"group_id\": \"99ybRIg2wAx55mqVsA6sB4S7WxPQHNKqa4BPu/bhj+U=\", \"payment\": { \"payment_address\": \"0x671276c61943A35D5F230d076bDFd91B0c47bF09\", \"payment_expiration_threshold\": 40320, \"payment_channel_storage_type\": \"etcd\", \"payment_channel_storage_client\": { \"connection_timeout\": \"5s\", \"request_timeout\": \"3s\", \"endpoints\": [ \"http://127.0.0.1:2379\" ] } } }, { \"group_name\": \"default_group\", \"group_id\": \"99ybRIg2wAx55mqVsA6sB4S7WxPQHNKqa4BPu/bhj+U=\", \"payment\": { \"payment_address\": \"0x671276c61943A35D5F230d076bDFd91B0c47bF09\", \"payment_expiration_threshold\": 40320, \"payment_channel_storage_type\": \"etcd\", \"payment_channel_storage_client\": { \"connection_timeout\": \"5s\", \"request_timeout\": \"3s\", \"endpoints\": [ \"http://127.0.0.1:2379\" ] } } } ] }" - metadata, err := blockchain.InitOrganizationMetaDataFromJson(testJsonOrgGroupData) + metadata, err := blockchain.InitOrganizationMetaDataFromJson([]byte(testJsonOrgGroupData)) conf, err := GetEtcdClientConf(config.Vip(), metadata) assert.Nil(t, err) @@ -28,7 +28,7 @@ func TestDefaultEtcdClientConf(t *testing.T) { func TestCustomEtcdClientConf(t *testing.T) { var testJsonOrgGroupData = "{ \"org_name\": \"organization_name\", \"org_id\": \"org_id1\", \"groups\": [ { \"group_name\": \"default_group\", \"group_id\": \"99ybRIg2wAx55mqVsA6sB4S7WxPQHNKqa4BPu/bhj+U=\", \"payment\": { \"payment_address\": \"0x671276c61943A35D5F230d076bDFd91B0c47bF09\", \"payment_expiration_threshold\": 40320, \"payment_channel_storage_type\": \"etcd\", \"payment_channel_storage_client\": { \"connection_timeout\": \"15s\", \"request_timeout\": \"5s\", \"endpoints\": [ \"http://127.0.0.1:2479\" ] } } }, { \"group_name\": \"default_group2\", \"group_id\": \"99ybRIg2wAx55mqVsA6sB4S7WxPQHNKqa4BPu/bhj+U=\", \"payment\": { \"payment_address\": \"0x671276c61943A35D5F230d076bDFd91B0c47bF09\", \"payment_expiration_threshold\": 40320, \"payment_channel_storage_type\": \"etcd\", \"payment_channel_storage_client\": { \"connection_timeout\": \"5s\", \"request_timeout\": \"3s\", \"endpoints\": [ \"http://127.0.0.1:2379\" ] } } } ] }" - metadata, err := blockchain.InitOrganizationMetaDataFromJson(testJsonOrgGroupData) + metadata, err := blockchain.InitOrganizationMetaDataFromJson([]byte(testJsonOrgGroupData)) conf, err := GetEtcdClientConf(nil, metadata) @@ -41,7 +41,7 @@ func TestCustomEtcdClientConf(t *testing.T) { func TestCustomEtcdClientConfWithDefault(t *testing.T) { var testJsonOrgGroupData = "{ \"org_name\": \"organization_name\", \"org_id\": \"org_id1\", \"groups\": [ { \"group_name\": \"default_group2\", \"group_id\": \"99ybRIg2wAx55mqVsA6sB4S7WxPQHNKqa4BPu/bhj+U=\", \"payment\": { \"payment_address\": \"0x671276c61943A35D5F230d076bDFd91B0c47bF09\", \"payment_expiration_threshold\": 40320, \"payment_channel_storage_type\": \"etcd\", \"payment_channel_storage_client\": { \"connection_timeout\": \"15s\", \"endpoints\": [ \"http://127.0.0.1:2479\" ] } } }, { \"group_name\": \"default_group\", \"group_id\": \"99ybRIg2wAx55mqVsA6sB4S7WxPQHNKqa4BPu/bhj+U=\", \"payment\": { \"payment_address\": \"0x671276c61943A35D5F230d076bDFd91B0c47bF09\", \"payment_expiration_threshold\": 40320, \"payment_channel_storage_type\": \"etcd\", \"payment_channel_storage_client\": { \"connection_timeout\": \"5s\", \"request_timeout\": \"3s\" } } } ] }" - metadata, err := blockchain.InitOrganizationMetaDataFromJson(testJsonOrgGroupData) + metadata, err := blockchain.InitOrganizationMetaDataFromJson([]byte(testJsonOrgGroupData)) assert.Nil(t, metadata) assert.NotNil(t, err) diff --git a/etcddb/etcddb_test.go b/etcddb/etcddb_test.go index e6344616..14f48e00 100644 --- a/etcddb/etcddb_test.go +++ b/etcddb/etcddb_test.go @@ -30,7 +30,7 @@ func TestEtcdTestSuite(t *testing.T) { func (suite *EtcdTestSuite) BeforeTest(suiteName string, testName string) { var testJsonOrgGroupData = "{ \"org_name\": \"organization_name\", \"org_id\": \"org_id1\", \"groups\": [ { \"group_name\": \"default_group2\", \"group_id\": \"99ybRIg2wAx55mqVsA6sB4S7WxPQHNKqa4BPu/bhj+U=\", \"payment\": { \"payment_address\": \"0x671276c61943A35D5F230d076bDFd91B0c47bF09\", \"payment_expiration_threshold\": 40320, \"payment_channel_storage_type\": \"etcd\", \"payment_channel_storage_client\": { \"connection_timeout\": \"500s\", \"request_timeout\": \"300s\", \"endpoints\": [ \"http://127.0.0.1:2379\" ] } } }, { \"group_name\": \"default_group\", \"group_id\": \"99ybRIg2wAx55mqVsA6sB4S7WxPQHNKqa4BPu/bhj+U=\", \"payment\": { \"payment_address\": \"0x671276c61943A35D5F230d076bDFd91B0c47bF09\", \"payment_expiration_threshold\": 40320, \"payment_channel_storage_type\": \"etcd\", \"payment_channel_storage_client\": { \"connection_timeout\": \"5s\", \"request_timeout\": \"3s\", \"endpoints\": [ \"http://127.0.0.1:2379\" ] } } } ] }" - suite.metaData, _ = blockchain.InitOrganizationMetaDataFromJson(testJsonOrgGroupData) + suite.metaData, _ = blockchain.InitOrganizationMetaDataFromJson([]byte(testJsonOrgGroupData)) const confJSON = ` { diff --git a/fix-proto/init.go b/fix-proto/init.go deleted file mode 100644 index 1c7aea66..00000000 --- a/fix-proto/init.go +++ /dev/null @@ -1,10 +0,0 @@ -package fix_proto - -import "os" - -func init() { - // fixing the panic due to the fact that the libraries have the same proto files by name: - // github.com/ipfs/go-cid conflicts with etcd library - // https://protobuf.dev/reference/go/faq/#fix-namespace-conflict - os.Setenv("GOLANG_PROTOBUF_REGISTRATION_CONFLICT", "warn") -} diff --git a/go.mod b/go.mod index ba1bfa1a..84905942 100644 --- a/go.mod +++ b/go.mod @@ -1,38 +1,39 @@ module github.com/singnet/snet-daemon -go 1.22 +go 1.23 require ( github.com/OneOfOne/go-utils v0.0.0-20180319162427-6019ff89a94e - github.com/bufbuild/protocompile v0.14.0 + github.com/bufbuild/protocompile v0.14.1 github.com/emicklei/proto v1.13.2 - github.com/ethereum/go-ethereum v1.14.7 + github.com/ethereum/go-ethereum v1.14.11 github.com/golang-collections/collections v0.0.0-20130729185459-604e922904d3 github.com/golang-jwt/jwt/v5 v5.2.1 github.com/gorilla/handlers v1.5.2 github.com/gorilla/rpc v1.2.1 + github.com/gorilla/websocket v1.5.3 github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 github.com/improbable-eng/grpc-web v0.15.0 github.com/ipfs/go-cid v0.4.1 - github.com/ipfs/kubo v0.29.0 + github.com/ipfs/kubo v0.30.0 github.com/magiconair/properties v1.8.7 github.com/pkg/errors v0.9.1 - github.com/rs/cors v1.11.0 - github.com/rs/xid v1.5.0 + github.com/rs/cors v1.11.1 + github.com/rs/xid v1.6.0 github.com/singnet/snet-ecosystem-contracts v0.1.1 github.com/soheilhy/cmux v0.1.5 - github.com/spf13/cast v1.6.0 + github.com/spf13/cast v1.7.0 github.com/spf13/cobra v1.8.1 github.com/spf13/pflag v1.0.5 github.com/spf13/viper v1.19.0 github.com/stretchr/testify v1.9.0 - go.etcd.io/etcd/client/v3 v3.5.14 - go.etcd.io/etcd/server/v3 v3.5.14 + go.etcd.io/etcd/client/v3 v3.5.16 + go.etcd.io/etcd/server/v3 v3.5.16 go.uber.org/zap v1.27.0 - golang.org/x/crypto v0.25.0 - golang.org/x/net v0.27.0 - golang.org/x/time v0.5.0 - google.golang.org/grpc v1.65.0 + golang.org/x/crypto v0.28.0 + golang.org/x/net v0.29.0 + golang.org/x/time v0.6.0 + google.golang.org/grpc v1.66.2 google.golang.org/protobuf v1.34.2 gopkg.in/natefinch/lumberjack.v2 v2.2.1 ) @@ -42,41 +43,40 @@ require ( github.com/Microsoft/go-winio v0.6.2 // indirect github.com/StackExchange/wmi v1.2.1 // indirect github.com/VictoriaMetrics/fastcache v1.12.2 // indirect - github.com/alecthomas/units v0.0.0-20231202071711-9a357b53e9c9 // indirect + github.com/alecthomas/units v0.0.0-20240626203959-61d1e3462e30 // indirect github.com/beorn7/perks v1.0.1 // indirect - github.com/bits-and-blooms/bitset v1.13.0 // indirect + github.com/bits-and-blooms/bitset v1.14.3 // indirect github.com/blang/semver/v4 v4.0.0 // indirect - github.com/btcsuite/btcd/btcec/v2 v2.3.3 // indirect + github.com/btcsuite/btcd/btcec/v2 v2.3.4 // indirect github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/cockroachdb/errors v1.11.3 // indirect github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce // indirect github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect - github.com/cockroachdb/pebble v1.1.1 // indirect + github.com/cockroachdb/pebble v1.1.2 // indirect github.com/cockroachdb/redact v1.1.5 // indirect github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect - github.com/consensys/bavard v0.1.13 // indirect - github.com/consensys/gnark-crypto v0.12.1 // indirect + github.com/consensys/bavard v0.1.22 // indirect + github.com/consensys/gnark-crypto v0.14.0 // indirect github.com/coreos/go-semver v0.3.1 // indirect github.com/coreos/go-systemd/v22 v22.5.0 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect github.com/crackcomm/go-gitignore v0.0.0-20231225121904-e25f5bc08668 // indirect - github.com/crate-crypto/go-ipa v0.0.0-20240223125850-b1e8a79f509c // indirect - github.com/crate-crypto/go-kzg-4844 v1.0.0 // indirect + github.com/crate-crypto/go-ipa v0.0.0-20240724233137-53bbb0ceb27a // indirect + github.com/crate-crypto/go-kzg-4844 v1.1.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/deckarep/golang-set/v2 v2.6.0 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f // indirect github.com/dustin/go-humanize v1.0.1 // indirect - github.com/ethereum/c-kzg-4844 v1.0.2 // indirect - github.com/ethereum/go-verkle v0.1.1-0.20240306133620-7d920df305f0 // indirect + github.com/ethereum/c-kzg-4844 v1.0.3 // indirect + github.com/ethereum/go-verkle v0.1.1-0.20240829091221-dffa7562dbe9 // indirect github.com/facebookgo/atomicfile v0.0.0-20151019160806-2de1f203e7d5 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect - github.com/fjl/memsize v0.0.2 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff // indirect github.com/getsentry/sentry-go v0.27.0 // indirect - github.com/go-logr/logr v1.4.1 // indirect + github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-ole/go-ole v1.3.0 // indirect github.com/gofrs/flock v0.8.1 // indirect @@ -87,7 +87,6 @@ require ( github.com/google/btree v1.1.2 // indirect github.com/google/gopacket v1.1.19 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/gorilla/websocket v1.5.1 // indirect github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 // indirect github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect @@ -99,17 +98,17 @@ require ( github.com/hashicorp/hcl v1.0.0 // indirect github.com/holiman/billy v0.0.0-20240216141850-2abb0c79d3c4 // indirect github.com/holiman/bloomfilter/v2 v2.0.3 // indirect - github.com/holiman/uint256 v1.3.0 // indirect + github.com/holiman/uint256 v1.3.1 // indirect github.com/huin/goupnp v1.3.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/ipfs/bbloom v0.0.4 // indirect - github.com/ipfs/boxo v0.20.0 // indirect + github.com/ipfs/boxo v0.23.0 // indirect github.com/ipfs/go-bitfield v1.1.0 // indirect github.com/ipfs/go-block-format v0.2.0 // indirect github.com/ipfs/go-datastore v0.6.0 // indirect github.com/ipfs/go-ds-measure v0.2.0 // indirect github.com/ipfs/go-fs-lock v0.0.7 // indirect - github.com/ipfs/go-ipfs-cmds v0.11.0 // indirect + github.com/ipfs/go-ipfs-cmds v0.13.0 // indirect github.com/ipfs/go-ipfs-util v0.0.3 // indirect github.com/ipfs/go-ipld-cbor v0.1.0 // indirect github.com/ipfs/go-ipld-format v0.6.0 // indirect @@ -117,32 +116,32 @@ require ( github.com/ipfs/go-log v1.0.5 // indirect github.com/ipfs/go-log/v2 v2.5.1 // indirect github.com/ipfs/go-metrics-interface v0.0.1 // indirect - github.com/ipfs/go-unixfsnode v1.9.0 // indirect + github.com/ipfs/go-unixfsnode v1.9.1 // indirect github.com/ipld/go-car/v2 v2.13.1 // indirect github.com/ipld/go-codec-dagpb v1.6.0 // indirect github.com/ipld/go-ipld-prime v0.21.0 // indirect github.com/jackpal/go-nat-pmp v1.0.2 // indirect github.com/jbenet/goprocess v0.1.4 // indirect - github.com/jonboulle/clockwork v0.2.2 // indirect + github.com/jonboulle/clockwork v0.4.0 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/klauspost/compress v1.17.8 // indirect + github.com/klauspost/compress v1.17.9 // indirect github.com/klauspost/cpuid/v2 v2.2.8 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/libp2p/go-cidranger v1.1.0 // indirect - github.com/libp2p/go-libp2p v0.34.1 // indirect + github.com/libp2p/go-libp2p v0.36.3 // indirect github.com/libp2p/go-libp2p-asn-util v0.4.1 // indirect - github.com/libp2p/go-libp2p-kad-dht v0.25.2 // indirect + github.com/libp2p/go-libp2p-kad-dht v0.26.1 // indirect github.com/libp2p/go-libp2p-kbucket v0.6.3 // indirect github.com/libp2p/go-libp2p-record v0.2.0 // indirect - github.com/libp2p/go-libp2p-routing-helpers v0.7.3 // indirect + github.com/libp2p/go-libp2p-routing-helpers v0.7.4 // indirect github.com/libp2p/go-msgio v0.3.0 // indirect github.com/libp2p/go-netroute v0.2.1 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-runewidth v0.0.13 // indirect - github.com/miekg/dns v1.1.59 // indirect + github.com/miekg/dns v1.1.61 // indirect github.com/minio/sha256-simd v1.0.1 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect @@ -153,13 +152,14 @@ require ( github.com/mr-tron/base58 v1.2.0 // indirect github.com/multiformats/go-base32 v0.1.0 // indirect github.com/multiformats/go-base36 v0.2.0 // indirect - github.com/multiformats/go-multiaddr v0.12.4 // indirect + github.com/multiformats/go-multiaddr v0.13.0 // indirect github.com/multiformats/go-multiaddr-dns v0.3.1 // indirect github.com/multiformats/go-multibase v0.2.0 // indirect github.com/multiformats/go-multicodec v0.9.0 // indirect github.com/multiformats/go-multihash v0.2.3 // indirect github.com/multiformats/go-multistream v0.5.0 // indirect github.com/multiformats/go-varint v0.0.7 // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect @@ -169,14 +169,14 @@ require ( github.com/polydawn/refmt v0.89.0 // indirect github.com/prometheus/client_golang v1.19.1 // indirect github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.53.0 // indirect - github.com/prometheus/procfs v0.15.0 // indirect + github.com/prometheus/common v0.55.0 // indirect + github.com/prometheus/procfs v0.15.1 // indirect github.com/rivo/uniseg v0.2.0 // indirect - github.com/rogpeppe/go-internal v1.10.0 // indirect + github.com/rogpeppe/go-internal v1.12.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/sagikazarmark/locafero v0.6.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect - github.com/samber/lo v1.39.0 // indirect + github.com/samber/lo v1.46.0 // indirect github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible // indirect github.com/sirupsen/logrus v1.9.3 // indirect github.com/sourcegraph/conc v0.3.0 // indirect @@ -184,7 +184,7 @@ require ( github.com/spf13/afero v1.11.0 // indirect github.com/status-im/keycard-go v0.2.0 // indirect github.com/subosito/gotenv v1.6.0 // indirect - github.com/supranational/blst v0.3.12 // indirect + github.com/supranational/blst v0.3.13 // indirect github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // indirect github.com/tklauser/go-sysconf v0.3.12 // indirect github.com/tklauser/numcpus v0.6.1 // indirect @@ -193,38 +193,38 @@ require ( github.com/urfave/cli/v2 v2.25.7 // indirect github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc // indirect github.com/whyrusleeping/cbor v0.0.0-20171005072247-63513f603b11 // indirect - github.com/whyrusleeping/cbor-gen v0.1.1 // indirect + github.com/whyrusleeping/cbor-gen v0.1.2 // indirect github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect github.com/xiang90/probing v0.0.0-20221125231312-a49e3df8f510 // indirect github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect - go.etcd.io/bbolt v1.3.10 // indirect - go.etcd.io/etcd/api/v3 v3.5.14 // indirect - go.etcd.io/etcd/client/pkg/v3 v3.5.14 // indirect - go.etcd.io/etcd/client/v2 v2.305.14 // indirect - go.etcd.io/etcd/pkg/v3 v3.5.14 // indirect - go.etcd.io/etcd/raft/v3 v3.5.14 // indirect + go.etcd.io/bbolt v1.3.11 // indirect + go.etcd.io/etcd/api/v3 v3.5.16 // indirect + go.etcd.io/etcd/client/pkg/v3 v3.5.16 // indirect + go.etcd.io/etcd/client/v2 v2.305.16 // indirect + go.etcd.io/etcd/pkg/v3 v3.5.16 // indirect + go.etcd.io/etcd/raft/v3 v3.5.16 // indirect go.opencensus.io v0.24.0 // indirect - go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.50.0 // indirect - go.opentelemetry.io/otel v1.26.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.26.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.26.0 // indirect - go.opentelemetry.io/otel/metric v1.26.0 // indirect - go.opentelemetry.io/otel/sdk v1.26.0 // indirect - go.opentelemetry.io/otel/trace v1.26.0 // indirect - go.opentelemetry.io/proto/otlp v1.2.0 // indirect + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0 // indirect + go.opentelemetry.io/otel v1.28.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0 // indirect + go.opentelemetry.io/otel/metric v1.28.0 // indirect + go.opentelemetry.io/otel/sdk v1.28.0 // indirect + go.opentelemetry.io/otel/trace v1.28.0 // indirect + go.opentelemetry.io/proto/otlp v1.3.1 // indirect go.uber.org/multierr v1.11.0 // indirect go4.org v0.0.0-20230225012048-214862532bf5 // indirect - golang.org/x/exp v0.0.0-20240707233637-46b078467d37 // indirect + golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect golang.org/x/mod v0.19.0 // indirect - golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.22.0 // indirect - golang.org/x/text v0.16.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/sys v0.26.0 // indirect + golang.org/x/text v0.19.0 // indirect golang.org/x/tools v0.23.0 // indirect - golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect + golang.org/x/xerrors v0.0.0-20240716161551-93cc26a95ae9 // indirect gonum.org/v1/gonum v0.15.0 // indirect - google.golang.org/genproto v0.0.0-20240318140521-94a12d6c2237 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d // indirect + google.golang.org/genproto v0.0.0-20240722135656-d784300faade // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240722135656-d784300faade // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect lukechampine.com/blake3 v1.3.0 // indirect diff --git a/go.sum b/go.sum index 8c0bd83a..f6ddceb8 100644 --- a/go.sum +++ b/go.sum @@ -43,8 +43,8 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= -github.com/alecthomas/units v0.0.0-20231202071711-9a357b53e9c9 h1:ez/4by2iGztzR4L0zgAOR8lTQK9VlyBVVd7G4omaOQs= -github.com/alecthomas/units v0.0.0-20231202071711-9a357b53e9c9/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= +github.com/alecthomas/units v0.0.0-20240626203959-61d1e3462e30 h1:t3eaIm0rUkzbrIewtiFmMK5RXHej2XnoXNhxVsAYUfg= +github.com/alecthomas/units v0.0.0-20240626203959-61d1e3462e30/go.mod h1:fvzegU4vN3H1qMT+8wDmzjAcDONcgo2/SZ/TyfdUOFs= github.com/alexbrainman/goissue34681 v0.0.0-20191006012335-3fc7a47baff5 h1:iW0a5ljuFxkLGPNem5Ui+KBjFJzKg4Fv2fnxe4dvzpM= github.com/alexbrainman/goissue34681 v0.0.0-20191006012335-3fc7a47baff5/go.mod h1:Y2QMoi1vgtOIfc+6DhrMOGkLoGzqSV2rKp4Sm+opsyA= github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah4HI848JfFxHt+iPb26b4zyfspmqY0/8= @@ -67,16 +67,16 @@ github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+Ce github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= -github.com/bits-and-blooms/bitset v1.13.0 h1:bAQ9OPNFYbGHV6Nez0tmNI0RiEu7/hxlYJRUA0wFAVE= -github.com/bits-and-blooms/bitset v1.13.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= +github.com/bits-and-blooms/bitset v1.14.3 h1:Gd2c8lSNf9pKXom5JtD7AaKO8o7fGQ2LtFj1436qilA= +github.com/bits-and-blooms/bitset v1.14.3/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= -github.com/btcsuite/btcd/btcec/v2 v2.3.3 h1:6+iXlDKE8RMtKsvK0gshlXIuPbyWM/h84Ensb7o3sC0= -github.com/btcsuite/btcd/btcec/v2 v2.3.3/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= +github.com/btcsuite/btcd/btcec/v2 v2.3.4 h1:3EJjcN70HCu/mwqlUsGK8GcNVyLVxFDlWurTXGPFfiQ= +github.com/btcsuite/btcd/btcec/v2 v2.3.4/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOFYSNEs0TFnxxnS9+4U= github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= -github.com/bufbuild/protocompile v0.14.0 h1:z3DW4IvXE5G/uTOnSQn+qwQQxvhckkTWLS/0No/o7KU= -github.com/bufbuild/protocompile v0.14.0/go.mod h1:N6J1NYzkspJo3ZwyL4Xjvli86XOj1xq4qAasUFxGups= +github.com/bufbuild/protocompile v0.14.1 h1:iA73zAf/fyljNjQKwYzUHD6AD4R8KMasmwa/FBatYVw= +github.com/bufbuild/protocompile v0.14.1/go.mod h1:ppVdAIhbr2H8asPk6k4pY7t9zB1OU5DoEw9xY/FUi1c= github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= @@ -108,17 +108,19 @@ github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce h1:giXvy4KSc/6g/e github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce/go.mod h1:9/y3cnZ5GKakj/H4y9r9GTjCvAFta7KLgSHPJJYc52M= github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b h1:r6VH0faHjZeQy818SGhaone5OnYfxFR/+AzdY3sf5aE= github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= -github.com/cockroachdb/pebble v1.1.1 h1:XnKU22oiCLy2Xn8vp1re67cXg4SAasg/WDt1NtcRFaw= -github.com/cockroachdb/pebble v1.1.1/go.mod h1:4exszw1r40423ZsmkG/09AFEG83I0uDgfujJdbL6kYU= +github.com/cockroachdb/pebble v1.1.2 h1:CUh2IPtR4swHlEj48Rhfzw6l/d0qA31fItcIszQVIsA= +github.com/cockroachdb/pebble v1.1.2/go.mod h1:4exszw1r40423ZsmkG/09AFEG83I0uDgfujJdbL6kYU= github.com/cockroachdb/redact v1.1.5 h1:u1PMllDkdFfPWaNGMyLD1+so+aq3uUItthCFqzwPJ30= github.com/cockroachdb/redact v1.1.5/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 h1:zuQyyAKVxetITBuuhv3BI9cMrmStnpT18zmgmTxunpo= github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06/go.mod h1:7nc4anLGjupUW/PeY5qiNYsdNXj7zopG+eqsS7To5IQ= github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= -github.com/consensys/bavard v0.1.13 h1:oLhMLOFGTLdlda/kma4VOJazblc7IM5y5QPd2A/YjhQ= -github.com/consensys/bavard v0.1.13/go.mod h1:9ItSMtA/dXMAiL7BG6bqW2m3NdSEObYWoH223nGHukI= -github.com/consensys/gnark-crypto v0.12.1 h1:lHH39WuuFgVHONRl3J0LRBtuYdQTumFSDtJF7HpyG8M= -github.com/consensys/gnark-crypto v0.12.1/go.mod h1:v2Gy7L/4ZRosZ7Ivs+9SfUDr0f5UlG+EM5t7MPHiLuY= +github.com/consensys/bavard v0.1.17 h1:53CdY/g35YSH9oRoa/b29tZinaiOEJYBmf9vydozPpE= +github.com/consensys/bavard v0.1.17/go.mod h1:9ItSMtA/dXMAiL7BG6bqW2m3NdSEObYWoH223nGHukI= +github.com/consensys/bavard v0.1.22 h1:Uw2CGvbXSZWhqK59X0VG/zOjpTFuOMcPLStrp1ihI0A= +github.com/consensys/bavard v0.1.22/go.mod h1:k/zVjHHC4B+PQy1Pg7fgvG3ALicQw540Crag8qx+dZs= +github.com/consensys/gnark-crypto v0.14.0 h1:DDBdl4HaBtdQsq/wfMwJvZNE80sHidrK3Nfrefatm0E= +github.com/consensys/gnark-crypto v0.14.0/go.mod h1:CU4UijNPsHawiVGNxe9co07FkzCeWHHrb1li/n1XoU0= github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM= github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= @@ -133,10 +135,10 @@ github.com/cpuguy83/go-md2man/v2 v2.0.4 h1:wfIWP927BUkWJb2NmU/kNDYIBTh/ziUX91+lV github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/crackcomm/go-gitignore v0.0.0-20231225121904-e25f5bc08668 h1:ZFUue+PNxmHlu7pYv+IYMtqlaO/0VwaGEqKepZf9JpA= github.com/crackcomm/go-gitignore v0.0.0-20231225121904-e25f5bc08668/go.mod h1:p1d6YEZWvFzEh4KLyvBcVSnrfNDDvK2zfK/4x2v/4pE= -github.com/crate-crypto/go-ipa v0.0.0-20240223125850-b1e8a79f509c h1:uQYC5Z1mdLRPrZhHjHxufI8+2UG/i25QG92j0Er9p6I= -github.com/crate-crypto/go-ipa v0.0.0-20240223125850-b1e8a79f509c/go.mod h1:geZJZH3SzKCqnz5VT0q/DyIG/tvu/dZk+VIfXicupJs= -github.com/crate-crypto/go-kzg-4844 v1.0.0 h1:TsSgHwrkTKecKJ4kadtHi4b3xHW5dCFUDFnUp1TsawI= -github.com/crate-crypto/go-kzg-4844 v1.0.0/go.mod h1:1kMhvPgI0Ky3yIa+9lFySEBUBXkYxeOi8ZF1sYioxhc= +github.com/crate-crypto/go-ipa v0.0.0-20240724233137-53bbb0ceb27a h1:W8mUrRp6NOVl3J+MYp5kPMoUZPp7aOYHtaua31lwRHg= +github.com/crate-crypto/go-ipa v0.0.0-20240724233137-53bbb0ceb27a/go.mod h1:sTwzHBvIzm2RfVCGNEBZgRyjwK40bVoun3ZnGOCafNM= +github.com/crate-crypto/go-kzg-4844 v1.1.0 h1:EN/u9k2TF6OWSHrCCDBBU6GLNMq88OspHHlMnHfoyU4= +github.com/crate-crypto/go-kzg-4844 v1.1.0/go.mod h1:JolLjpSff1tCCJKaJx4psrlEdlXuJEC996PL3tTAFks= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/cskr/pubsub v1.0.2 h1:vlOzMhl6PFn60gRlTQQsIfVwaPB/B/8MziK8FhEPt/0= @@ -169,8 +171,8 @@ github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5m github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= -github.com/elastic/gosigar v0.14.2 h1:Dg80n8cr90OZ7x+bAax/QjoW/XqTI11RmA79ZwIm9/4= -github.com/elastic/gosigar v0.14.2/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= +github.com/elastic/gosigar v0.14.3 h1:xwkKwPia+hSfg9GqrCUKYdId102m9qTJIIr7egmK/uo= +github.com/elastic/gosigar v0.14.3/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= github.com/emicklei/proto v1.13.2 h1:z/etSFO3uyXeuEsVPzfl56WNgzcvIr42aQazXaQmFZY= github.com/emicklei/proto v1.13.2/go.mod h1:rn1FgRS/FANiZdD2djyH7TMA9jdRDcYQ9IEN9yvjX0A= github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= @@ -178,19 +180,21 @@ github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymF github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/ethereum/c-kzg-4844 v1.0.2 h1:8tV84BCEiPeOkiVgW9mpYBeBUir2bkCNVqxPwwVeO+s= -github.com/ethereum/c-kzg-4844 v1.0.2/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1aQputP83wc0= -github.com/ethereum/go-ethereum v1.14.7 h1:EHpv3dE8evQmpVEQ/Ne2ahB06n2mQptdwqaMNhAT29g= -github.com/ethereum/go-ethereum v1.14.7/go.mod h1:Mq0biU2jbdmKSZoqOj29017ygFrMnB5/Rifwp980W4o= -github.com/ethereum/go-verkle v0.1.1-0.20240306133620-7d920df305f0 h1:KrE8I4reeVvf7C1tm8elRjj4BdscTYzz/WAbYyf/JI4= -github.com/ethereum/go-verkle v0.1.1-0.20240306133620-7d920df305f0/go.mod h1:D9AJLVXSyZQXJQVk8oh1EwjISE+sJTn2duYIZC0dy3w= +github.com/ethereum/c-kzg-4844 v1.0.3 h1:IEnbOHwjixW2cTvKRUlAAUOeleV7nNM/umJR+qy4WDs= +github.com/ethereum/c-kzg-4844 v1.0.3/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1aQputP83wc0= +github.com/ethereum/go-ethereum v1.14.9 h1:J7iwXDrtUyE9FUjUYbd4c9tyzwMh6dTJsKzo9i6SrwA= +github.com/ethereum/go-ethereum v1.14.9/go.mod h1:QeW+MtTpRdBEm2pUFoonByee8zfHv7kGp0wK0odvU1I= +github.com/ethereum/go-ethereum v1.14.10 h1:kC24WjYeRjDy86LVo6MfF5Xs7nnUu+XG4AjaYIaZYko= +github.com/ethereum/go-ethereum v1.14.10/go.mod h1:+l/fr42Mma+xBnhefL/+z11/hcmJ2egl+ScIVPjhc7E= +github.com/ethereum/go-ethereum v1.14.11 h1:8nFDCUUE67rPc6AKxFj7JKaOa2W/W1Rse3oS6LvvxEY= +github.com/ethereum/go-ethereum v1.14.11/go.mod h1:+l/fr42Mma+xBnhefL/+z11/hcmJ2egl+ScIVPjhc7E= +github.com/ethereum/go-verkle v0.1.1-0.20240829091221-dffa7562dbe9 h1:8NfxH2iXvJ60YRB8ChToFTUzl8awsc3cJ8CbLjGIl/A= +github.com/ethereum/go-verkle v0.1.1-0.20240829091221-dffa7562dbe9/go.mod h1:M3b90YRnzqKyyzBEWJGqj8Qff4IDeXnzFw0P9bFw3uk= github.com/facebookgo/atomicfile v0.0.0-20151019160806-2de1f203e7d5 h1:BBso6MBKW8ncyZLv37o+KNyy0HrrHgfnOaGQC2qvN+A= github.com/facebookgo/atomicfile v0.0.0-20151019160806-2de1f203e7d5/go.mod h1:JpoxHjuQauoxiFMl1ie8Xc/7TfLuMZ5eOCONd1sUBHg= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/fjl/memsize v0.0.2 h1:27txuSD9or+NZlnOWdKUxeBzTAUkWCVh+4Gf2dWFOzA= -github.com/fjl/memsize v0.0.2/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= github.com/flynn/noise v1.1.0 h1:KjPQoQCEFdZDiP03phOvGi11+SVVhBG2wOWAorLsstg= github.com/flynn/noise v1.1.0/go.mod h1:xbMo+0i6+IGbYdJhF31t2eR1BIU0CYc12+BNAKwUTag= github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk= @@ -203,8 +207,8 @@ github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMo github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= -github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= -github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= +github.com/gabriel-vasile/mimetype v1.4.4 h1:QjV6pZ7/XZ7ryI2KuyeEDE8wnh7fHP9YnQy+R0LnH8I= +github.com/gabriel-vasile/mimetype v1.4.4/go.mod h1:JwLei5XPtWdGiMFB5Pjle1oEeoSeEuJfJE+TtfvdB/s= github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff h1:tY80oXqGNY4FhTFhk+o9oFHGINQ/+vhlm8HFzi6znCI= github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= github.com/getsentry/sentry-go v0.27.0 h1:Pv98CIbtB3LkMWmXi4Joa5OOcwbmnX88sF5qbK3r3Ps= @@ -228,8 +232,8 @@ github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9 github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= -github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= +github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= @@ -247,7 +251,6 @@ github.com/go-playground/validator/v10 v10.11.1 h1:prmOlTVv+YjZjmRmNSF3VmspqJIxJ github.com/go-playground/validator/v10 v10.11.1/go.mod h1:i+3WkQ1FvaUjjxh1kSvIA4dMGDBiPU55YFDl0WbKdWU= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaLENm+P+Tv+MfurjSw0= @@ -328,8 +331,8 @@ github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXi github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20240509144519-723abb6459b7 h1:velgFPYr1X9TDwLIfkV7fWqsFlf7TeP11M/7kPd/dVI= -github.com/google/pprof v0.0.0-20240509144519-723abb6459b7/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw= +github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 h1:FKHo8hFI3A+7w0aUQuYXQ+6EN5stWmeY/AZqtM8xk9k= +github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -352,8 +355,8 @@ github.com/gorilla/rpc v1.2.1/go.mod h1:uNpOihAlF5xRFLuTYhfR0yfCTm0WTQSQttkMSptR github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= -github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= +github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= +github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.2.2/go.mod h1:EaizFBKfUKtMIF5iaDEhniwNedqGo9FuLFzppDr3uwI= github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 h1:UH//fgunKIs4JdUbpDl1VZCDaL56wXCB/5+wF6uHfaI= @@ -401,8 +404,8 @@ github.com/holiman/billy v0.0.0-20240216141850-2abb0c79d3c4 h1:X4egAf/gcS1zATw6w github.com/holiman/billy v0.0.0-20240216141850-2abb0c79d3c4/go.mod h1:5GuXa7vkL8u9FkFuWdVvfR5ix8hRB7DbOAaYULamFpc= github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao= github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA= -github.com/holiman/uint256 v1.3.0 h1:4wdcm/tnd0xXdu7iS3ruNvxkWwrb4aeBQv19ayYn8F4= -github.com/holiman/uint256 v1.3.0/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E= +github.com/holiman/uint256 v1.3.1 h1:JfTzmih28bittyHM8z360dCjIA9dbPIBlcTI6lmctQs= +github.com/holiman/uint256 v1.3.1/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= github.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc= @@ -420,8 +423,8 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c h1:7Uy github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c/go.mod h1:6EekK/jo+TynwSE/ZOiOJd4eEvRXoavEC3vquKtv4yI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.20.0 h1:umUl7q1v5g5AX8FPLTnZBvvagLmT+V0Tt61EigP81ec= -github.com/ipfs/boxo v0.20.0/go.mod h1:mwttn53Eibgska2DhVIj7ln3UViq7MVHRxOMb+ehSDM= +github.com/ipfs/boxo v0.23.0 h1:dY1PpcvPJ//VuUQ1TUd5TZvmaGuzxJ8dOP6mXaw+ke8= +github.com/ipfs/boxo v0.23.0/go.mod h1:ulu5I6avTmgGmvjuCaBRKwsaOOKjBfQw1EiOOQp8M6E= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.2.0 h1:ZqrkxBA2ICbDRbK8KJs/u0O3dlp6gmAuuXUJNiW1Ycs= @@ -449,12 +452,8 @@ github.com/ipfs/go-fs-lock v0.0.7 h1:6BR3dajORFrFTkb5EpCUFIAypsoxpGpDSVUdFwzgL9U github.com/ipfs/go-fs-lock v0.0.7/go.mod h1:Js8ka+FNYmgQRLrRXzU3CB/+Csr1BwrRilEcvYrHhhc= github.com/ipfs/go-ipfs-blockstore v1.3.1 h1:cEI9ci7V0sRNivqaOr0elDsamxXFxJMMMy7PTTDQNsQ= github.com/ipfs/go-ipfs-blockstore v1.3.1/go.mod h1:KgtZyc9fq+P2xJUiCAzbRdhhqJHvsw8u2Dlqy2MyRTE= -github.com/ipfs/go-ipfs-blocksutil v0.0.1 h1:Eh/H4pc1hsvhzsQoMEP3Bke/aW5P5rVM1IWFJMcGIPQ= -github.com/ipfs/go-ipfs-blocksutil v0.0.1/go.mod h1:Yq4M86uIOmxmGPUHv/uI7uKqZNtLb449gwKqXjIsnRk= -github.com/ipfs/go-ipfs-chunker v0.0.5 h1:ojCf7HV/m+uS2vhUGWcogIIxiO5ubl5O57Q7NapWLY8= -github.com/ipfs/go-ipfs-chunker v0.0.5/go.mod h1:jhgdF8vxRHycr00k13FM8Y0E+6BoalYeobXmUyTreP8= -github.com/ipfs/go-ipfs-cmds v0.11.0 h1:6AsTKwbVxwzrOkq2x89e6jYMGxzYqjt/WbAam69HZQE= -github.com/ipfs/go-ipfs-cmds v0.11.0/go.mod h1:DHp7YfJlOK+2IS07nk+hFmbKHK52tc29W38CaAgWHpk= +github.com/ipfs/go-ipfs-cmds v0.13.0 h1:+WVHZMrQNkPqwAQdrSFGbJgHpOc8H2G8eszNxnvoCQA= +github.com/ipfs/go-ipfs-cmds v0.13.0/go.mod h1:GYqjGSt6u9k9tyxIDT7M0ROWeB2raPGH94uuVnpWgY0= github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= github.com/ipfs/go-ipfs-delay v0.0.1 h1:r/UXYyRcddO6thwOnhiznIAiSvxMECGgtv35Xs1IeRQ= github.com/ipfs/go-ipfs-delay v0.0.1/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= @@ -491,14 +490,16 @@ github.com/ipfs/go-metrics-interface v0.0.1 h1:j+cpbjYvu4R8zbleSs36gvB7jR+wsL2fG github.com/ipfs/go-metrics-interface v0.0.1/go.mod h1:6s6euYU4zowdslK0GKHmqaIZ3j/b/tL7HTWtJ4VPgWY= github.com/ipfs/go-peertaskqueue v0.8.1 h1:YhxAs1+wxb5jk7RvS0LHdyiILpNmRIRnZVztekOF0pg= github.com/ipfs/go-peertaskqueue v0.8.1/go.mod h1:Oxxd3eaK279FxeydSPPVGHzbwVeHjatZ2GA8XD+KbPU= +github.com/ipfs/go-test v0.0.4 h1:DKT66T6GBB6PsDFLoO56QZPrOmzJkqU1FZH5C9ySkew= +github.com/ipfs/go-test v0.0.4/go.mod h1:qhIM1EluEfElKKM6fnWxGn822/z9knUGM1+I/OAQNKI= github.com/ipfs/go-unixfs v0.4.5 h1:wj8JhxvV1G6CD7swACwSKYa+NgtdWC1RUit+gFnymDU= github.com/ipfs/go-unixfs v0.4.5/go.mod h1:BIznJNvt/gEx/ooRMI4Us9K8+qeGO7vx1ohnbk8gjFg= -github.com/ipfs/go-unixfsnode v1.9.0 h1:ubEhQhr22sPAKO2DNsyVBW7YB/zA8Zkif25aBvz8rc8= -github.com/ipfs/go-unixfsnode v1.9.0/go.mod h1:HxRu9HYHOjK6HUqFBAi++7DVoWAHn0o4v/nZ/VA+0g8= +github.com/ipfs/go-unixfsnode v1.9.1 h1:2cdSIDQCt7emNhlyUqUFQnKo2XvecARoIcurIKFjPD8= +github.com/ipfs/go-unixfsnode v1.9.1/go.mod h1:u8WxhmXzyrq3xfSYkhfx+uI+n91O+0L7KFjq3TS7d6g= github.com/ipfs/go-verifcid v0.0.3 h1:gmRKccqhWDocCRkC+a59g5QW7uJw5bpX9HWBevXa0zs= github.com/ipfs/go-verifcid v0.0.3/go.mod h1:gcCtGniVzelKrbk9ooUSX/pM3xlH73fZZJDzQJRvOUw= -github.com/ipfs/kubo v0.29.0 h1:J5G5le0/gYkx8qLN/zxDl0LcEXKbHZyMh4FCuQN1nVo= -github.com/ipfs/kubo v0.29.0/go.mod h1:mLhuve/44BxEX5ujEihviRXiaxdlrja3kjJgEs2WhK0= +github.com/ipfs/kubo v0.30.0 h1:JX4z5Y4BpY7d2GWxCk+ZchRMRLLHC+h39Dy+b0atj84= +github.com/ipfs/kubo v0.30.0/go.mod h1:7VltOZtM2eUhhwSyw7e+gBEtnjGNbOAZQHOHSCAt7nI= github.com/ipld/go-car v0.6.2 h1:Hlnl3Awgnq8icK+ze3iRghk805lu8YNq3wlREDTF2qc= github.com/ipld/go-car v0.6.2/go.mod h1:oEGXdwp6bmxJCZ+rARSkDliTeYnVzv3++eXajZ+Bmr8= github.com/ipld/go-car/v2 v2.13.1 h1:KnlrKvEPEzr5IZHKTXLAEub+tPrzeAFQVRlSQvuxBO4= @@ -518,8 +519,8 @@ github.com/jbenet/goprocess v0.1.4 h1:DRGOFReOMqqDNXwW70QkacFW0YN9QnwLV0Vqk+3oU0 github.com/jbenet/goprocess v0.1.4/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= -github.com/jonboulle/clockwork v0.2.2 h1:UOGuzwb1PwsrDAObMuhUnj0p5ULPj8V/xJ7Kx9qUBdQ= -github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8= +github.com/jonboulle/clockwork v0.4.0 h1:p4Cf1aMWXnXAUh8lVfewRBx1zaTSYKrKMF2g3ST4RZ4= +github.com/jonboulle/clockwork v0.4.0/go.mod h1:xgRqUGwRcjKCO1vbZUEtSLrqKoPSsUpK7fnezOII0kc= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= @@ -539,8 +540,8 @@ github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= 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= -github.com/klauspost/compress v1.17.8 h1:YcnTYrq7MikUT7k0Yb5eceMmALQPYBW/Xltxn0NAMnU= -github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= +github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= +github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= github.com/klauspost/cpuid/v2 v2.2.8 h1:+StwCXwm9PdpiEkPyzBXIy+M9KUb4ODm0Zarf1kS5BM= github.com/klauspost/cpuid/v2 v2.2.8/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -558,8 +559,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= -github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= -github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= +github.com/leanovate/gopter v0.2.11 h1:vRjThO1EKPb/1NsDXuDrzldR28RLkBflWYcU9CvzWu4= +github.com/leanovate/gopter v0.2.11/go.mod h1:aK3tzZP/C+p1m3SPRE4SYZFGP7jjkuSI4f7Xvpt0S9c= github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w= github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= @@ -571,12 +572,12 @@ github.com/libp2p/go-doh-resolver v0.4.0 h1:gUBa1f1XsPwtpE1du0O+nnZCUqtG7oYi7Bb+ github.com/libp2p/go-doh-resolver v0.4.0/go.mod h1:v1/jwsFusgsWIGX/c6vCRrnJ60x7bhTiq/fs2qt0cAg= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.34.1 h1:fxn9vyLo7vJcXQRNvdRbyPjbzuQgi2UiqC8hEbn8a18= -github.com/libp2p/go-libp2p v0.34.1/go.mod h1:snyJQix4ET6Tj+LeI0VPjjxTtdWpeOhYt5lEY0KirkQ= +github.com/libp2p/go-libp2p v0.36.3 h1:NHz30+G7D8Y8YmznrVZZla0ofVANrvBl2c+oARfMeDQ= +github.com/libp2p/go-libp2p v0.36.3/go.mod h1:4Y5vFyCUiJuluEPmpnKYf6WFx5ViKPUYs/ixe9ANFZ8= github.com/libp2p/go-libp2p-asn-util v0.4.1 h1:xqL7++IKD9TBFMgnLPZR6/6iYhawHKHl950SO9L6n94= github.com/libp2p/go-libp2p-asn-util v0.4.1/go.mod h1:d/NI6XZ9qxw67b4e+NgpQexCIiFYJjErASrYW4PFDN8= -github.com/libp2p/go-libp2p-kad-dht v0.25.2 h1:FOIk9gHoe4YRWXTu8SY9Z1d0RILol0TrtApsMDPjAVQ= -github.com/libp2p/go-libp2p-kad-dht v0.25.2/go.mod h1:6za56ncRHYXX4Nc2vn8z7CZK0P4QiMcrn77acKLM2Oo= +github.com/libp2p/go-libp2p-kad-dht v0.26.1 h1:AazV3LCImYVkDUGAHx5lIEgZ9iUI2QQKH5GMRQU8uEA= +github.com/libp2p/go-libp2p-kad-dht v0.26.1/go.mod h1:mqRUGJ/+7ziQ3XknU2kKHfsbbgb9xL65DXjPOJwmZF8= github.com/libp2p/go-libp2p-kbucket v0.6.3 h1:p507271wWzpy2f1XxPzCQG9NiN6R6lHL9GiSErbQQo0= github.com/libp2p/go-libp2p-kbucket v0.6.3/go.mod h1:RCseT7AH6eJWxxk2ol03xtP9pEHetYSPXOaJnOiD8i0= github.com/libp2p/go-libp2p-pubsub v0.11.0 h1:+JvS8Kty0OiyUiN0i8H5JbaCgjnJTRnTHe4rU88dLFc= @@ -585,8 +586,8 @@ github.com/libp2p/go-libp2p-pubsub-router v0.6.0 h1:D30iKdlqDt5ZmLEYhHELCMRj8b4s github.com/libp2p/go-libp2p-pubsub-router v0.6.0/go.mod h1:FY/q0/RBTKsLA7l4vqC2cbRbOvyDotg8PJQ7j8FDudE= github.com/libp2p/go-libp2p-record v0.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0= github.com/libp2p/go-libp2p-record v0.2.0/go.mod h1:I+3zMkvvg5m2OcSdoL0KPljyJyvNDFGKX7QdlpYUcwk= -github.com/libp2p/go-libp2p-routing-helpers v0.7.3 h1:u1LGzAMVRK9Nqq5aYDVOiq/HaB93U9WWczBzGyAC5ZY= -github.com/libp2p/go-libp2p-routing-helpers v0.7.3/go.mod h1:cN4mJAD/7zfPKXBcs9ze31JGYAZgzdABEm+q/hkswb8= +github.com/libp2p/go-libp2p-routing-helpers v0.7.4 h1:6LqS1Bzn5CfDJ4tzvP9uwh42IB7TJLNFJA6dEeGBv84= +github.com/libp2p/go-libp2p-routing-helpers v0.7.4/go.mod h1:we5WDj9tbolBXOuF1hGOkR+r7Uh1408tQbAKaT5n1LE= github.com/libp2p/go-libp2p-testing v0.12.0 h1:EPvBb4kKMWO29qP4mZGyhVzUyR25dvfUIK5WDu6iPUA= github.com/libp2p/go-libp2p-testing v0.12.0/go.mod h1:KcGDRXyN7sQCllucn1cOOS+Dmm7ujhfEyXQL5lvkcPg= github.com/libp2p/go-libp2p-xor v0.1.0 h1:hhQwT4uGrBcuAkUGXADuPltalOdpf9aag9kaYNT2tLA= @@ -628,8 +629,8 @@ github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= -github.com/miekg/dns v1.1.59 h1:C9EXc/UToRwKLhK5wKU/I4QVsBUc8kE6MkHBkeypWZs= -github.com/miekg/dns v1.1.59/go.mod h1:nZpewl5p6IvctfgrckopVx2OlSEHPRO/U4SYkRklrEk= +github.com/miekg/dns v1.1.61 h1:nLxbwF3XxhwVSm8g9Dghm9MHPaUZuqhPiGL+675ZmEs= +github.com/miekg/dns v1.1.61/go.mod h1:mnAarhS3nWaW+NVP2wTkYVIZyHNJ098SJZUki3eykwQ= github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b h1:z78hV3sbSMAUoyUMM0I83AUIT6Hu17AWfgjzIbtrYFc= github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b/go.mod h1:lxPUiZwKoFL8DUUmalo2yJJUCxbPKtm8OKfqr2/FTNU= github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc h1:PTfri+PuQmWDqERdnNMiD9ZejrlswWrCpBEZgWOiTrc= @@ -671,8 +672,8 @@ github.com/multiformats/go-base32 v0.1.0/go.mod h1:Kj3tFY6zNr+ABYMqeUNeGvkIC/UYg github.com/multiformats/go-base36 v0.2.0 h1:lFsAbNOGeKtuKozrtBsAkSVhv1p9D0/qedU9rQyccr0= github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a1UV0xHgWc0hkp4= github.com/multiformats/go-multiaddr v0.2.0/go.mod h1:0nO36NvPpyV4QzvTLi/lafl2y95ncPj0vFwVF6k6wJ4= -github.com/multiformats/go-multiaddr v0.12.4 h1:rrKqpY9h+n80EwhhC/kkcunCZZ7URIF8yN1WEUt2Hvc= -github.com/multiformats/go-multiaddr v0.12.4/go.mod h1:sBXrNzucqkFJhvKOiwwLyqamGa/P5EIXNPLovyhQCII= +github.com/multiformats/go-multiaddr v0.13.0 h1:BCBzs61E3AGHcYYTv8dqRH43ZfyrqM8RXVPT8t13tLQ= +github.com/multiformats/go-multiaddr v0.13.0/go.mod h1:sBXrNzucqkFJhvKOiwwLyqamGa/P5EIXNPLovyhQCII= github.com/multiformats/go-multiaddr-dns v0.3.1 h1:QgQgR+LQVt3NPTjbrLLpsaT2ufAA2y0Mkk+QRVJbW3A= github.com/multiformats/go-multiaddr-dns v0.3.1/go.mod h1:G/245BRQ6FJGmryJCrOuTdB37AMA5AMOVuO6NY3JwTk= github.com/multiformats/go-multiaddr-fmt v0.1.0 h1:WLEFClPycPkp4fnIzoFoV9FVd49/eQsuaL3/CWe167E= @@ -691,6 +692,8 @@ github.com/multiformats/go-varint v0.0.1/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXS github.com/multiformats/go-varint v0.0.5/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= github.com/multiformats/go-varint v0.0.7 h1:sWSGR+f/eu5ABZA2ZpYKBILXTTs9JWpdEM/nEGOHFS8= github.com/multiformats/go-varint v0.0.7/go.mod h1:r8PUYw/fD/SjBCiKOoDlGF6QawOELpZAu9eioSos/OU= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= @@ -715,8 +718,8 @@ github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.14.0 h1:2mOpI4JVVPBN+WQRa0WKH2eXR+Ey+uK4n7Zj0aYpIQA= github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= -github.com/onsi/ginkgo/v2 v2.17.3 h1:oJcvKpIb7/8uLpDDtnQuf18xVnwKp8DTD7DQ6gTd/MU= -github.com/onsi/ginkgo/v2 v2.17.3/go.mod h1:nP2DPOQoNsQmsVyv5rDA8JkXQoCs6goXIvr/PRJ1eCc= +github.com/onsi/ginkgo/v2 v2.19.1 h1:QXgq3Z8Crl5EL1WBAC98A5sEBHARrAJNzAmMxzLcRF0= +github.com/onsi/ginkgo/v2 v2.19.1/go.mod h1:O3DtEWQkPa/F7fBMgmZQKKsluAy8pd3rEQdrjkPb9zA= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE= @@ -750,12 +753,12 @@ github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0 github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= 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/datachannel v1.5.6 h1:1IxKJntfSlYkpUj8LlYRSWpYiTTC02nUrOE8T3DqGeg= -github.com/pion/datachannel v1.5.6/go.mod h1:1eKT6Q85pRnr2mHiWHxJwO50SfZRtWHTsNIVb/NfGW4= -github.com/pion/dtls/v2 v2.2.11 h1:9U/dpCYl1ySttROPWJgqWKEylUdT0fXp/xst6JwY5Ks= -github.com/pion/dtls/v2 v2.2.11/go.mod h1:d9SYc9fch0CqK90mRk1dC7AkzzpwJj6u2GU3u+9pqFE= -github.com/pion/ice/v2 v2.3.24 h1:RYgzhH/u5lH0XO+ABatVKCtRd+4U1GEaCXSMjNr13tI= -github.com/pion/ice/v2 v2.3.24/go.mod h1:KXJJcZK7E8WzrBEYnV4UtqEZsGeWfHxsNqhVcVvgjxw= +github.com/pion/datachannel v1.5.8 h1:ph1P1NsGkazkjrvyMfhRBUAWMxugJjq2HfQifaOoSNo= +github.com/pion/datachannel v1.5.8/go.mod h1:PgmdpoaNBLX9HNzNClmdki4DYW5JtI7Yibu8QzbL3tI= +github.com/pion/dtls/v2 v2.2.12 h1:KP7H5/c1EiVAAKUmXyCzPiQe5+bCJrpOeKg/L05dunk= +github.com/pion/dtls/v2 v2.2.12/go.mod h1:d9SYc9fch0CqK90mRk1dC7AkzzpwJj6u2GU3u+9pqFE= +github.com/pion/ice/v2 v2.3.34 h1:Ic1ppYCj4tUOcPAp76U6F3fVrlSw8A9JtRXLqw6BbUM= +github.com/pion/ice/v2 v2.3.34/go.mod h1:mBF7lnigdqgtB+YHkaY/Y6s6tsyRyo4u4rPGRuOjUBQ= github.com/pion/interceptor v0.1.29 h1:39fsnlP1U8gw2JzOFWdfCU82vHvhW9o0rZnZF56wF+M= github.com/pion/interceptor v0.1.29/go.mod h1:ri+LGNjRUc5xUNtDEPzfdkmSqISixVTBF/z/Zms/6T4= github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY= @@ -766,22 +769,22 @@ github.com/pion/randutil v0.1.0 h1:CFG1UdESneORglEsnimhUjf33Rwjubwj6xfiOXBa3mA= github.com/pion/randutil v0.1.0/go.mod h1:XcJrSMMbbMRhASFVOlj/5hQial/Y8oH/HVo7TBZq+j8= github.com/pion/rtcp v1.2.14 h1:KCkGV3vJ+4DAJmvP0vaQShsb0xkRfWkO540Gy102KyE= github.com/pion/rtcp v1.2.14/go.mod h1:sn6qjxvnwyAkkPzPULIbVqSKI5Dv54Rv7VG0kNxh9L4= -github.com/pion/rtp v1.8.6 h1:MTmn/b0aWWsAzux2AmP8WGllusBVw4NPYPVFFd7jUPw= -github.com/pion/rtp v1.8.6/go.mod h1:pBGHaFt/yW7bf1jjWAoUjpSNoDnw98KTMg+jWWvziqU= -github.com/pion/sctp v1.8.16 h1:PKrMs+o9EMLRvFfXq59WFsC+V8mN1wnKzqrv+3D/gYY= -github.com/pion/sctp v1.8.16/go.mod h1:P6PbDVA++OJMrVNg2AL3XtYHV4uD6dvfyOovCgMs0PE= +github.com/pion/rtp v1.8.8 h1:EtYFHI0rpUEjT/RMnGfb1vdJhbYmPG77szD72uUnSxs= +github.com/pion/rtp v1.8.8/go.mod h1:pBGHaFt/yW7bf1jjWAoUjpSNoDnw98KTMg+jWWvziqU= +github.com/pion/sctp v1.8.20 h1:sOc3lkV/tQaP57ZUEXIMdM2V92IIB2ia5v/ygnBxaEg= +github.com/pion/sctp v1.8.20/go.mod h1:oTxw8i5m+WbDHZJL/xUpe6CPIn1Y0GIKKwTLF4h53H8= github.com/pion/sdp/v3 v3.0.9 h1:pX++dCHoHUwq43kuwf3PyJfHlwIj4hXA7Vrifiq0IJY= github.com/pion/sdp/v3 v3.0.9/go.mod h1:B5xmvENq5IXJimIO4zfp6LAe1fD9N+kFv+V/1lOdz8M= -github.com/pion/srtp/v2 v2.0.18 h1:vKpAXfawO9RtTRKZJbG4y0v1b11NZxQnxRl85kGuUlo= -github.com/pion/srtp/v2 v2.0.18/go.mod h1:0KJQjA99A6/a0DOVTu1PhDSw0CXF2jTkqOoMg3ODqdA= +github.com/pion/srtp/v2 v2.0.20 h1:HNNny4s+OUmG280ETrCdgFndp4ufx3/uy85EawYEhTk= +github.com/pion/srtp/v2 v2.0.20/go.mod h1:0KJQjA99A6/a0DOVTu1PhDSw0CXF2jTkqOoMg3ODqdA= github.com/pion/stun v0.6.1 h1:8lp6YejULeHBF8NmV8e2787BogQhduZugh5PdhDyyN4= github.com/pion/stun v0.6.1/go.mod h1:/hO7APkX4hZKu/D0f2lHzNyvdkTGtIy3NDmLR7kSz/8= -github.com/pion/transport/v2 v2.2.5 h1:iyi25i/21gQck4hfRhomF6SktmUQjRsRW4WJdhfc3Kc= -github.com/pion/transport/v2 v2.2.5/go.mod h1:q2U/tf9FEfnSBGSW6w5Qp5PFWRLRj3NjLhCCgpRK4p0= +github.com/pion/transport/v2 v2.2.10 h1:ucLBLE8nuxiHfvkFKnkDQRYWYfp8ejf4YBOPfaQpw6Q= +github.com/pion/transport/v2 v2.2.10/go.mod h1:sq1kSLWs+cHW9E+2fJP95QudkzbK7wscs8yYgQToO5E= github.com/pion/turn/v2 v2.1.6 h1:Xr2niVsiPTB0FPtt+yAWKFUkU1eotQbGgpTIld4x1Gc= github.com/pion/turn/v2 v2.1.6/go.mod h1:huEpByKKHix2/b9kmTAM3YoX6MKP+/D//0ClgUYR2fY= -github.com/pion/webrtc/v3 v3.2.40 h1:Wtfi6AZMQg+624cvCXUuSmrKWepSB7zfgYDOYqsSOVU= -github.com/pion/webrtc/v3 v3.2.40/go.mod h1:M1RAe3TNTD1tzyvqHrbVODfwdPGSXOUo/OgpoGGJqFY= +github.com/pion/webrtc/v3 v3.3.0 h1:Rf4u6n6U5t5sUxhYPQk/samzU/oDv7jk6BA5hyO2F9I= +github.com/pion/webrtc/v3 v3.3.0/go.mod h1:hVmrDJvwhEertRWObeb1xzulzHGeVUoPlWvxdGzcfU0= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -814,20 +817,20 @@ github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y8 github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.15.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= -github.com/prometheus/common v0.53.0 h1:U2pL9w9nmJwJDa4qqLQ3ZaePJ6ZTwt7cMD3AG3+aLCE= -github.com/prometheus/common v0.53.0/go.mod h1:BrxBKv3FWBIGXw89Mg1AeBq7FSyRzXWI3l3e7W3RN5U= +github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc= +github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.3.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/prometheus/procfs v0.15.0 h1:A82kmvXJq2jTu5YUhSGNlYoxh85zLnKgPz4bMZgI5Ek= -github.com/prometheus/procfs v0.15.0/go.mod h1:Y0RJ/Y5g5wJpkTisOtqwDSo4HwhGmLB4VQSw2sQJLHk= +github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= +github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= -github.com/quic-go/quic-go v0.44.0 h1:So5wOr7jyO4vzL2sd8/pD9Kesciv91zSk8BoFngItQ0= -github.com/quic-go/quic-go v0.44.0/go.mod h1:z4cx/9Ny9UtGITIPzmPTXh1ULfOyWh4qGQlpnPcWmek= +github.com/quic-go/quic-go v0.45.2 h1:DfqBmqjb4ExSdxRIb/+qXhPC+7k6+DUNZha4oeiC9fY= +github.com/quic-go/quic-go v0.45.2/go.mod h1:1dLehS7TIR64+vxGR70GDcatWTOtMX2PUtnKsjbTurI= github.com/quic-go/webtransport-go v0.8.0 h1:HxSrwun11U+LlmwpgM1kEqIqH90IT4N8auv/cD7QFJg= github.com/quic-go/webtransport-go v0.8.0/go.mod h1:N99tjprW432Ut5ONql/aUhSLT0YVSlwHohQsuac9WaM= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= @@ -839,13 +842,13 @@ github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6So github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= -github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= -github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= +github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= +github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= -github.com/rs/cors v1.11.0 h1:0B9GE/r9Bc2UxRMMtymBkHTenPkHDv0CW4Y98GBY+po= -github.com/rs/cors v1.11.0/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= -github.com/rs/xid v1.5.0 h1:mKX4bl4iPYJtEIxp6CYiUuLQ/8DYMoz0PUdtGgMFRVc= -github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= +github.com/rs/cors v1.11.1 h1:eU3gRzXLRK57F5rKMGMZURNdIG4EoAmX8k94r9wXWHA= +github.com/rs/cors v1.11.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= +github.com/rs/xid v1.6.0 h1:fV591PaemRlL6JfRxGDEPl69wICngIQ3shQtzfy2gxU= +github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= @@ -855,8 +858,8 @@ github.com/sagikazarmark/locafero v0.6.0 h1:ON7AQg37yzcRPU69mt7gwhFEBwxI6P9T4Qu3 github.com/sagikazarmark/locafero v0.6.0/go.mod h1:77OmuIc6VTraTXKXIs/uvUxKGUXjE1GbemJYHqdNjX0= github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= -github.com/samber/lo v1.39.0 h1:4gTz1wUhNYLhFSKl6O+8peW0v2F4BCY034GRpU9WnuA= -github.com/samber/lo v1.39.0/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA= +github.com/samber/lo v1.46.0 h1:w8G+oaCPgz1PoCJztqymCFaKwXt+5cCXn51uPxExFfQ= +github.com/samber/lo v1.46.0/go.mod h1:RmDH9Ct32Qy3gduHQuKJ3gW1fMHAnE/fAzQuf6He5cU= github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible h1:Bn1aCHHRnjv4Bl16T8rcaFjYSrGrIZvpiGO6P3Q4GpU= @@ -887,8 +890,8 @@ github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0b github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= -github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= -github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= +github.com/spf13/cast v1.7.0 h1:ntdiHjuueXFgm5nzDRdOS4yfT43P5Fnud6DH50rz/7w= +github.com/spf13/cast v1.7.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= @@ -919,8 +922,8 @@ github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsT github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= -github.com/supranational/blst v0.3.12 h1:Vfas2U2CFHhniv2QkUm2OVa1+pGTdqtpqm9NnhUUbZ8= -github.com/supranational/blst v0.3.12/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= +github.com/supranational/blst v0.3.13 h1:AYeSxdOMacwu7FBmpfloBz5pbFXDmJL33RuwnKtmTjk= +github.com/supranational/blst v0.3.13/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU= @@ -952,14 +955,16 @@ github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc h1:BCPnHtcboa github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc/go.mod h1:r45hJU7yEoA81k6MWNhpMj/kms0n14dkzkxYHoB96UM= github.com/whyrusleeping/cbor v0.0.0-20171005072247-63513f603b11 h1:5HZfQkwe0mIfyDmc1Em5GqlNRzcdtlv4HTNmdpt7XH0= github.com/whyrusleeping/cbor v0.0.0-20171005072247-63513f603b11/go.mod h1:Wlo/SzPmxVp6vXpGt/zaXhHH0fn4IxgqZc82aKg6bpQ= -github.com/whyrusleeping/cbor-gen v0.1.1 h1:eKfcJIoxivjMtwfCfmJAqSF56MHcWqyIScXwaC1VBgw= -github.com/whyrusleeping/cbor-gen v0.1.1/go.mod h1:pM99HXyEbSQHcosHc0iW7YFmwnscr+t9Te4ibko05so= +github.com/whyrusleeping/cbor-gen v0.1.2 h1:WQFlrPhpcQl+M2/3dP5cvlTLWPVsL6LGBb9jJt6l/cA= +github.com/whyrusleeping/cbor-gen v0.1.2/go.mod h1:pM99HXyEbSQHcosHc0iW7YFmwnscr+t9Te4ibko05so= github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f h1:jQa4QT2UP9WYv2nzyawpKMOCl+Z/jW7djv2/J50lj9E= github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f/go.mod h1:p9UJB6dDgdPgMJZs7UjUOdulKyRr9fqkS+6JKAInPy8= github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 h1:EKhdznlJHPMoKr0XTrX+IlJs1LH3lyx2nfr1dOlZ79k= github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1/go.mod h1:8UvriyWtv5Q5EOgjHaSseUEdkQfvwFv1I/In/O2M9gc= github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 h1:E9S12nwJwEOXe2d6gT6qxdvqMnNq+VnSsKPgm2ZZNds= github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7/go.mod h1:X2c0RVCI1eSUFI8eLcY3c0423ykwiUdxLJtkDvruhjI= +github.com/wlynxg/anet v0.0.3 h1:PvR53psxFXstc12jelG6f1Lv4MWqE0tI76/hHGjh9rg= +github.com/wlynxg/anet v0.0.3/go.mod h1:eay5PRQr7fIVAMbTbchTnO9gG65Hg/uYGdc7mguHxoA= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xiang90/probing v0.0.0-20221125231312-a49e3df8f510 h1:S2dVYn90KE98chqDkyE9Z4N61UnQd+KOfgp5Iu53llk= github.com/xiang90/probing v0.0.0-20221125231312-a49e3df8f510/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= @@ -970,23 +975,23 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.etcd.io/bbolt v1.3.10 h1:+BqfJTcCzTItrop8mq/lbzL8wSGtj94UO/3U31shqG0= -go.etcd.io/bbolt v1.3.10/go.mod h1:bK3UQLPJZly7IlNmV7uVHJDxfe5aK9Ll93e/74Y9oEQ= +go.etcd.io/bbolt v1.3.11 h1:yGEzV1wPz2yVCLsD8ZAiGHhHVlczyC9d1rP43/VCRJ0= +go.etcd.io/bbolt v1.3.11/go.mod h1:dksAq7YMXoljX0xu6VF5DMZGbhYYoLUalEiSySYAS4I= go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= -go.etcd.io/etcd/api/v3 v3.5.14 h1:vHObSCxyB9zlF60w7qzAdTcGaglbJOpSj1Xj9+WGxq0= -go.etcd.io/etcd/api/v3 v3.5.14/go.mod h1:BmtWcRlQvwa1h3G2jvKYwIQy4PkHlDej5t7uLMUdJUU= -go.etcd.io/etcd/client/pkg/v3 v3.5.14 h1:SaNH6Y+rVEdxfpA2Jr5wkEvN6Zykme5+YnbCkxvuWxQ= -go.etcd.io/etcd/client/pkg/v3 v3.5.14/go.mod h1:8uMgAokyG1czCtIdsq+AGyYQMvpIKnSvPjFMunkgeZI= -go.etcd.io/etcd/client/v2 v2.305.14 h1:v5ASLyFuMlVd/gKU6uf6Cod+vSWKa4Rsv9+eghl0Nwk= -go.etcd.io/etcd/client/v2 v2.305.14/go.mod h1:AWYT0lLEkBuqVaGw0UVMtA4rxCb3/oGE8PxZ8cUS4tI= -go.etcd.io/etcd/client/v3 v3.5.14 h1:CWfRs4FDaDoSz81giL7zPpZH2Z35tbOrAJkkjMqOupg= -go.etcd.io/etcd/client/v3 v3.5.14/go.mod h1:k3XfdV/VIHy/97rqWjoUzrj9tk7GgJGH9J8L4dNXmAk= -go.etcd.io/etcd/pkg/v3 v3.5.14 h1:keuxhJiDCPjTKpW77GxJnnVVD5n4IsfvkDaqiqUMNEQ= -go.etcd.io/etcd/pkg/v3 v3.5.14/go.mod h1:7o+DL6a7DYz9KSjWByX+NGmQPYinoH3D36VAu/B3JqA= -go.etcd.io/etcd/raft/v3 v3.5.14 h1:mHnpbljpBBftmK+YUfp+49ivaCc126aBPLAnwDw0DnE= -go.etcd.io/etcd/raft/v3 v3.5.14/go.mod h1:WnIK5blyJGRKsHA3efovdNoLv9QELTZHzpDOVIAuL2s= -go.etcd.io/etcd/server/v3 v3.5.14 h1:l/3gdiSSoGU6MyKAYiL+8WSOMq9ySG+NqQ04euLtZfY= -go.etcd.io/etcd/server/v3 v3.5.14/go.mod h1:SPh0rUtGNDgOZd/aTbkAUYZV+5FFHw5sdbGnO2/byw0= +go.etcd.io/etcd/api/v3 v3.5.16 h1:WvmyJVbjWqK4R1E+B12RRHz3bRGy9XVfh++MgbN+6n0= +go.etcd.io/etcd/api/v3 v3.5.16/go.mod h1:1P4SlIP/VwkDmGo3OlOD7faPeP8KDIFhqvciH5EfN28= +go.etcd.io/etcd/client/pkg/v3 v3.5.16 h1:ZgY48uH6UvB+/7R9Yf4x574uCO3jIx0TRDyetSfId3Q= +go.etcd.io/etcd/client/pkg/v3 v3.5.16/go.mod h1:V8acl8pcEK0Y2g19YlOV9m9ssUe6MgiDSobSoaBAM0E= +go.etcd.io/etcd/client/v2 v2.305.16 h1:kQrn9o5czVNaukf2A2At43cE9ZtWauOtf9vRZuiKXow= +go.etcd.io/etcd/client/v2 v2.305.16/go.mod h1:h9YxWCzcdvZENbfzBTFCnoNumr2ax3F19sKMqHFmXHE= +go.etcd.io/etcd/client/v3 v3.5.16 h1:sSmVYOAHeC9doqi0gv7v86oY/BTld0SEFGaxsU9eRhE= +go.etcd.io/etcd/client/v3 v3.5.16/go.mod h1:X+rExSGkyqxvu276cr2OwPLBaeqFu1cIl4vmRjAD/50= +go.etcd.io/etcd/pkg/v3 v3.5.16 h1:cnavs5WSPWeK4TYwPYfmcr3Joz9BH+TZ6qoUtz6/+mc= +go.etcd.io/etcd/pkg/v3 v3.5.16/go.mod h1:+lutCZHG5MBBFI/U4eYT5yL7sJfnexsoM20Y0t2uNuY= +go.etcd.io/etcd/raft/v3 v3.5.16 h1:zBXA3ZUpYs1AwiLGPafYAKKl/CORn/uaxYDwlNwndAk= +go.etcd.io/etcd/raft/v3 v3.5.16/go.mod h1:P4UP14AxofMJ/54boWilabqqWoW9eLodl6I5GdGzazI= +go.etcd.io/etcd/server/v3 v3.5.16 h1:d0/SAdJ3vVsZvF8IFVb1k8zqMZ+heGcNfft71ul9GWE= +go.etcd.io/etcd/server/v3 v3.5.16/go.mod h1:ynhyZZpdDp1Gq49jkUg5mfkDWZwXnn3eIqCqtJnrD/s= go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= @@ -995,30 +1000,30 @@ go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.50.0 h1:zvpPXY7RfYAGSdYQLjp6zxdJNSYD/+FFoCTQN9IPxBs= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.50.0/go.mod h1:BMn8NB1vsxTljvuorms2hyOs8IBuuBEq0pl7ltOfy30= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.51.0 h1:Xs2Ncz0gNihqu9iosIZ5SkBbWo5T8JhhLJFMQL1qmLI= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.51.0/go.mod h1:vy+2G/6NvVMpwGX/NyLqcC41fxepnuKHk16E6IZUcJc= -go.opentelemetry.io/otel v1.26.0 h1:LQwgL5s/1W7YiiRwxf03QGnWLb2HW4pLiAhaA5cZXBs= -go.opentelemetry.io/otel v1.26.0/go.mod h1:UmLkJHUAidDval2EICqBMbnAd0/m2vmpf/dAM+fvFs4= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.26.0 h1:1u/AyyOqAWzy+SkPxDpahCNZParHV8Vid1RnI2clyDE= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.26.0/go.mod h1:z46paqbJ9l7c9fIPCXTqTGwhQZ5XoTIsfeFYWboizjs= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.26.0 h1:Waw9Wfpo/IXzOI8bCB7DIk+0JZcqqsyn1JFnAc+iam8= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.26.0/go.mod h1:wnJIG4fOqyynOnnQF/eQb4/16VlX2EJAHhHgqIqWfAo= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.26.0 h1:1wp/gyxsuYtuE/JFxsQRtcCDtMrO2qMvlfXALU5wkzI= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.26.0/go.mod h1:gbTHmghkGgqxMomVQQMur1Nba4M0MQ8AYThXDUjsJ38= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.26.0 h1:0W5o9SzoR15ocYHEQfvfipzcNog1lBxOLfnex91Hk6s= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.26.0/go.mod h1:zVZ8nz+VSggWmnh6tTsJqXQ7rU4xLwRtna1M4x5jq58= -go.opentelemetry.io/otel/exporters/zipkin v1.26.0 h1:sBk6A62GgcQRwcxcBwRMPkqeuSizcpHkXyZNyP281Fw= -go.opentelemetry.io/otel/exporters/zipkin v1.26.0/go.mod h1:fLzYtPUxPFzu7rSqhYsCxYheT2dNoPjtKovCLzLm07w= -go.opentelemetry.io/otel/metric v1.26.0 h1:7S39CLuY5Jgg9CrnA9HHiEjGMF/X2VHvoXGgSllRz30= -go.opentelemetry.io/otel/metric v1.26.0/go.mod h1:SY+rHOI4cEawI9a7N1A4nIg/nTQXe1ccCNWYOJUrpX4= -go.opentelemetry.io/otel/sdk v1.26.0 h1:Y7bumHf5tAiDlRYFmGqetNcLaVUZmh4iYfmGxtmz7F8= -go.opentelemetry.io/otel/sdk v1.26.0/go.mod h1:0p8MXpqLeJ0pzcszQQN4F0S5FVjBLgypeGSngLsmirs= -go.opentelemetry.io/otel/trace v1.26.0 h1:1ieeAUb4y0TE26jUFrCIXKpTuVK7uJGN9/Z/2LP5sQA= -go.opentelemetry.io/otel/trace v1.26.0/go.mod h1:4iDxvGDQuUkHve82hJJ8UqrwswHYsZuWCBllGV2U2y0= -go.opentelemetry.io/proto/otlp v1.2.0 h1:pVeZGk7nXDC9O2hncA6nHldxEjm6LByfA2aN8IOkz94= -go.opentelemetry.io/proto/otlp v1.2.0/go.mod h1:gGpR8txAl5M03pDhMC79G6SdqNV26naRm/KDsgaHD8A= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0 h1:9G6E0TXzGFVfTnawRzrPl83iHOAV7L8NJiR8RSGYV1g= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0/go.mod h1:azvtTADFQJA8mX80jIH/akaE7h+dbm/sVuaHqN13w74= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.52.0 h1:9l89oX4ba9kHbBol3Xin3leYJ+252h0zszDtBwyKe2A= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.52.0/go.mod h1:XLZfZboOJWHNKUv7eH0inh0E9VV6eWDFB/9yJyTLPp0= +go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo= +go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 h1:3Q/xZUyC1BBkualc9ROb4G8qkH90LXEIICcs5zv1OYY= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0/go.mod h1:s75jGIWA9OfCMzF0xr+ZgfrB5FEbbV7UuYo32ahUiFI= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0 h1:R3X6ZXmNPRR8ul6i3WgFURCHzaXjHdm0karRG/+dj3s= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0/go.mod h1:QWFXnDavXWwMx2EEcZsf3yxgEKAqsxQ+Syjp+seyInw= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.27.0 h1:QY7/0NeRPKlzusf40ZE4t1VlMKbqSNT7cJRYzWuja0s= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.27.0/go.mod h1:HVkSiDhTM9BoUJU8qE6j2eSWLLXvi1USXjyd2BXT8PY= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.27.0 h1:/0YaXu3755A/cFbtXp+21lkXgI0QE5avTWA2HjU9/WE= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.27.0/go.mod h1:m7SFxp0/7IxmJPLIY3JhOcU9CoFzDaCPL6xxQIxhA+o= +go.opentelemetry.io/otel/exporters/zipkin v1.27.0 h1:aXcxb7F6ZDC1o2Z52LDfS2g6M2FB5CrxdR2gzY4QRNs= +go.opentelemetry.io/otel/exporters/zipkin v1.27.0/go.mod h1:+WMURoi4KmVB7ypbFPx3xtZTWen2Ca3lRK9u6DVTO5M= +go.opentelemetry.io/otel/metric v1.28.0 h1:f0HGvSl1KRAU1DLgLGFjrwVyismPlnuU6JD6bOeuA5Q= +go.opentelemetry.io/otel/metric v1.28.0/go.mod h1:Fb1eVBFZmLVTMb6PPohq3TO9IIhUisDsbJoL/+uQW4s= +go.opentelemetry.io/otel/sdk v1.28.0 h1:b9d7hIry8yZsgtbmM0DKyPWMMUMlK9NEKuIG4aBqWyE= +go.opentelemetry.io/otel/sdk v1.28.0/go.mod h1:oYj7ClPUA7Iw3m+r7GeEjz0qckQRJK2B8zjcZEfu7Pg= +go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= +go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= +go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= +go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= @@ -1028,8 +1033,8 @@ go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/dig v1.17.1 h1:Tga8Lz8PcYNsWsyHMZ1Vm0OQOUaJNDyvPImgbAu9YSc= go.uber.org/dig v1.17.1/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= -go.uber.org/fx v1.21.1 h1:RqBh3cYdzZS0uqwVeEjOX2p73dddLpym315myy/Bpb0= -go.uber.org/fx v1.21.1/go.mod h1:HT2M7d7RHo+ebKGh9NRcrsrHHfpZ60nW3QRubMRfv48= +go.uber.org/fx v1.22.1 h1:nvvln7mwyT5s1q201YE29V/BFrGor6vMiDNpU/78Mys= +go.uber.org/fx v1.22.1/go.mod h1:HT2M7d7RHo+ebKGh9NRcrsrHHfpZ60nW3QRubMRfv48= go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= @@ -1063,8 +1068,10 @@ golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= +golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= +golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw= +golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1074,8 +1081,8 @@ golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= -golang.org/x/exp v0.0.0-20240707233637-46b078467d37 h1:uLDX+AfeFCct3a2C7uIWBKMJIR3CJMhcgfrUAqjRK6w= -golang.org/x/exp v0.0.0-20240707233637-46b078467d37/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= +golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1137,8 +1144,8 @@ golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20211123203042-d83791d6bcd9/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= +golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= +golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1153,8 +1160,8 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1212,8 +1219,10 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= +golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= +golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= @@ -1225,14 +1234,16 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= +golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= +golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= -golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U= +golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -1274,8 +1285,8 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 h1:+cNy6SZtPcJQH3LJVLOSmiC7MMxXNOb3PU/VUEz+EhU= -golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= +golang.org/x/xerrors v0.0.0-20240716161551-93cc26a95ae9 h1:LLhsEBxRTBLuKlQxFBYUOU8xyFgXv6cOTp2HASDlsDk= +golang.org/x/xerrors v0.0.0-20240716161551-93cc26a95ae9/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= gonum.org/v1/gonum v0.15.0 h1:2lYxjRbTYyxkJxlhC+LvJIx3SsANPdRybu1tGj9/OrQ= gonum.org/v1/gonum v0.15.0/go.mod h1:xzZVBJBtS+Mz4q0Yl2LJTk+OxOg4jiXZ7qBoM0uISGo= google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= @@ -1311,12 +1322,12 @@ google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfG google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20210126160654-44e461bb6506/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20240318140521-94a12d6c2237 h1:PgNlNSx2Nq2/j4juYzQBG0/Zdr+WP4z5N01Vk4VYBCY= -google.golang.org/genproto v0.0.0-20240318140521-94a12d6c2237/go.mod h1:9sVD8c25Af3p0rGs7S7LLsxWKFiJt/65LdSyqXBkX/Y= -google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157 h1:7whR9kGa5LUwFtpLm2ArCEejtnxlGeLbAyjFY8sGNFw= -google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157/go.mod h1:99sLkeliLXfdj2J75X3Ho+rrVCaJze0uwN7zDDkjPVU= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d h1:JU0iKnSg02Gmb5ZdV8nYsKEKsP6o/FGVWTrw4i1DA9A= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= +google.golang.org/genproto v0.0.0-20240722135656-d784300faade h1:lKFsS7wpngDgSCeFn7MoLy+wBDQZ1UQIJD4UNM1Qvkg= +google.golang.org/genproto v0.0.0-20240722135656-d784300faade/go.mod h1:FfBgJBJg9GcpPvKIuHSZ/aE1g2ecGL74upMzGZjiGEY= +google.golang.org/genproto/googleapis/api v0.0.0-20240722135656-d784300faade h1:WxZOF2yayUHpHSbUE6NMzumUzBxYc3YGwo0YHnbzsJY= +google.golang.org/genproto/googleapis/api v0.0.0-20240722135656-d784300faade/go.mod h1:mw8MG/Qz5wfgYr6VqVCiZcHe/GJEfI+oGGDCohaVgB0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 h1:pPJltXNxVzT4pK9yD8vR9X75DaWYYmLGMsEvBfFQZzQ= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= @@ -1334,8 +1345,8 @@ google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3Iji google.golang.org/grpc v1.32.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= -google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= +google.golang.org/grpc v1.66.2 h1:3QdXkuq3Bkh7w+ywLdLvM56cmGvQHUMZpiCzt6Rqaoo= +google.golang.org/grpc v1.66.2/go.mod h1:s3/l6xSSCURdVfAnL+TqCNMyTDAGN6+lZeVxnZR128Y= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= diff --git a/handler/grpc.go b/handler/grpc.go index b36591d9..daaaaa34 100644 --- a/handler/grpc.go +++ b/handler/grpc.go @@ -10,21 +10,22 @@ import ( "os/exec" "strings" - "github.com/singnet/snet-daemon/blockchain" - "github.com/singnet/snet-daemon/codec" - "github.com/singnet/snet-daemon/config" - "github.com/gorilla/rpc/v2/json2" "go.uber.org/zap" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/credentials" + "google.golang.org/grpc/credentials/insecure" "google.golang.org/grpc/metadata" "google.golang.org/grpc/status" "google.golang.org/protobuf/encoding/protojson" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/types/dynamicpb" + + "github.com/singnet/snet-daemon/blockchain" + "github.com/singnet/snet-daemon/codec" + "github.com/singnet/snet-daemon/config" ) var grpcDesc = &grpc.StreamDesc{ServerStreams: true, ClientStreams: true} @@ -89,20 +90,19 @@ func NewGrpcHandler(serviceMetadata *blockchain.ServiceMetadata) grpc.StreamHand return nil } -func (h grpcHandler) getConnection(endpoint string) (conn *grpc.ClientConn) { +func (g grpcHandler) getConnection(endpoint string) (conn *grpc.ClientConn) { passthroughURL, err := url.Parse(endpoint) if err != nil { zap.L().Panic("error parsing passthrough endpoint", zap.Error(err)) } if strings.Compare(passthroughURL.Scheme, "https") == 0 { - conn, err = grpc.Dial(passthroughURL.Host, - grpc.WithTransportCredentials(credentials.NewClientTLSFromCert(nil, "")), h.options) + conn, err = grpc.NewClient(passthroughURL.Host, + grpc.WithTransportCredentials(credentials.NewClientTLSFromCert(nil, "")), g.options) if err != nil { zap.L().Panic("error dialing service", zap.Error(err)) } } else { - conn, err = grpc.Dial(passthroughURL.Host, grpc.WithInsecure(), h.options) - + conn, err = grpc.NewClient(passthroughURL.Host, grpc.WithTransportCredentials(insecure.NewCredentials()), g.options) if err != nil { zap.L().Panic("error dialing service", zap.Error(err)) } @@ -130,6 +130,7 @@ func (g grpcHandler) grpcToGRPC(srv any, inStream grpc.ServerStream) error { } outCtx, outCancel := context.WithCancel(inCtx) + defer outCancel() outCtx = metadata.NewOutgoingContext(outCtx, md.Copy()) isModelTraining := g.serviceMetaData.IsModelTraining(method) outStream, err := g.GrpcConn(isModelTraining).NewStream(outCtx, grpcDesc, method, grpc.CallContentSubtype(g.enc)) @@ -222,15 +223,14 @@ func forwardServerToClient(src grpc.ServerStream, dst grpc.ClientStream) chan er // first message sent by the client and pass this on the regular service call //This is done to be able to make calls to support regular Service call + Dynamic pricing call if i == 0 { - //todo we need to think through to determine price for every call on stream calls - //will be handled when we support streaming and pricing across all clients in snet-platform + // todo we need to think through to determine price for every call on stream calls + // will be handled when we support streaming and pricing across all clients in snet-platform if wrappedStream, ok := src.(*WrapperServerStream); ok { f = (wrappedStream.OriginalRecvMsg()).(*codec.GrpcFrame) } else if err := src.RecvMsg(f); err != nil { ret <- err break } - } else if err := src.RecvMsg(f); err != nil { ret <- err // this can be io.EOF which is happy case break @@ -321,7 +321,11 @@ func (g grpcHandler) grpcToHTTP(srv any, inStream grpc.ServerStream) error { } base.RawQuery = params.Encode() - zap.L().Debug("Calling URL", zap.String("Url", base.String())) + zap.L().Debug("Calling http service", + zap.String("url", base.String()), + zap.String("body", string(jsonBody)), + zap.String("method", "POST")) + httpReq, err := http.NewRequest("POST", base.String(), bytes.NewBuffer(jsonBody)) httpReq.Header = headers if err != nil { @@ -372,7 +376,7 @@ func jsonToProto(protoFile protoreflect.FileDescriptor, json []byte, methodName return proto } output := method.Output() - zap.L().Debug("output of calling method", zap.Any("method", output.FullName())) + zap.L().Debug("output msg descriptor", zap.Any("fullname", output.FullName())) proto = dynamicpb.NewMessage(output) err := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}.Unmarshal(json, proto) if err != nil { @@ -383,7 +387,6 @@ func jsonToProto(protoFile protoreflect.FileDescriptor, json []byte, methodName } func protoToJson(protoFile protoreflect.FileDescriptor, in []byte, methodName string) (json []byte) { - if protoFile.Services().Len() == 0 { zap.L().Warn("service in proto not found") return []byte("error, invalid proto file") diff --git a/handler/httphandler/http.go b/handler/httphandler/http.go index 52a6facb..645fa389 100644 --- a/handler/httphandler/http.go +++ b/handler/httphandler/http.go @@ -21,7 +21,7 @@ func NewHTTPHandler(blockProc blockchain.Processor) http.Handler { return &httpHandler{ passthroughEnabled: config.GetBool(config.PassthroughEnabledKey), passthroughEndpoint: config.GetString(config.PassthroughEndpointKey), - rateLimiter: ratelimit.NewRateLimiter(), + rateLimiter: *ratelimit.NewRateLimiter(), } } @@ -29,7 +29,7 @@ func (h *httpHandler) ServeHTTP(resp http.ResponseWriter, req *http.Request) { resp.Header().Set("Access-Control-Allow-Origin", "*") log.Printf("ServeHTTP: %#v \n", req) if h.passthroughEnabled { - if h.rateLimiter.Allow() == false { + if !h.rateLimiter.Allow() { http.Error(resp, http.StatusText(429), http.StatusTooManyRequests) return } diff --git a/handler/interceptors.go b/handler/interceptors.go index 5633eaac..6956ca09 100644 --- a/handler/interceptors.go +++ b/handler/interceptors.go @@ -92,7 +92,7 @@ type Payment any // Custom gRPC codes to return to the client const ( - // IncorrectNonce is returned to client when payment recieved contains + // IncorrectNonce is returned to client when payment received contains // incorrect nonce value. Client may use PaymentChannelStateService to get // latest channel state and correct nonce value. IncorrectNonce codes.Code = 1000 @@ -136,7 +136,7 @@ func NewGrpcErrorf(code codes.Code, format string, args ...any) *GrpcError { // PaymentHandler interface which is used by gRPC interceptor to get, validate // and complete payment. There are two payment handler implementations so far: -// jobPaymentHandler and escrowPaymentHandler. jobPaymentHandler is depreactted. +// jobPaymentHandler and escrowPaymentHandler. jobPaymentHandler is deprecated. type PaymentHandler interface { // Type is a content of PaymentTypeHeader field which triggers usage of the // payment handler. @@ -161,7 +161,7 @@ type rateLimitInterceptor struct { func GrpcRateLimitInterceptor(broadcast *configuration_service.MessageBroadcaster) grpc.StreamServerInterceptor { interceptor := &rateLimitInterceptor{ - rateLimiter: ratelimit.NewRateLimiter(), + rateLimiter: *ratelimit.NewRateLimiter(), messageBroadcaster: broadcast, processRequest: configuration_service.START_PROCESSING_ANY_REQUEST, requestProcessingNotification: broadcast.NewSubscriber(), @@ -182,8 +182,10 @@ func GrpcMeteringInterceptor() grpc.StreamServerInterceptor { // Monitor requests arrived and responses sent and publish these stats for Reporting func interceptMetering(srv any, ss grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error { - var err error - var start time.Time + var ( + err error + start time.Time + ) start = time.Now() //Get the method name methodName, _ := grpc.MethodFromServerStream(ss) @@ -196,7 +198,7 @@ func interceptMetering(srv any, ss grpc.ServerStream, info *grpc.StreamServerInf } defer func() { - go metrics.PublishResponseStats(commonStats, time.Now().Sub(start), err) + go metrics.PublishResponseStats(commonStats, time.Since(start), err) }() err = handler(srv, ss) if err != nil { diff --git a/handler/intergrationtests/grpc_stream_test.proto b/handler/intergrationtests/grpc_stream_test.proto new file mode 100644 index 00000000..689facb1 --- /dev/null +++ b/handler/intergrationtests/grpc_stream_test.proto @@ -0,0 +1,17 @@ +syntax = "proto3"; + +package handler; + +option go_package = "../intergrationtests"; + +service ExampleStreamingService { + rpc Stream(stream InStream) returns (stream OutStream) {} +} + +message InStream { + string message = 1; +} + +message OutStream { + string message = 1; +} \ No newline at end of file diff --git a/handler/intergrationtests/grpc_to_grpc_test.go b/handler/intergrationtests/grpc_to_grpc_test.go new file mode 100644 index 00000000..71f110a3 --- /dev/null +++ b/handler/intergrationtests/grpc_to_grpc_test.go @@ -0,0 +1,236 @@ +//go:generate protoc grpc_stream_test.proto --go-grpc_out=. --go_out=. + +package intergrationtests + +import ( + "context" + "io" + "net" + "testing" + "time" + + "github.com/singnet/snet-daemon/blockchain" + "github.com/singnet/snet-daemon/config" + "github.com/singnet/snet-daemon/handler" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/spf13/viper" + "go.uber.org/zap" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" +) + +type integrationTestEnvironment struct { + serverA *grpc.Server + listenerA *net.Listener + serverB *grpc.Server + listenerB *net.Listener +} + +func setupTestConfig() { + testConfigJson := ` +{ + "blockchain_enabled": true, + "blockchain_network_selected": "sepolia", + "daemon_end_point": "127.0.0.1:8080", + "daemon_group_name":"default_group", + "payment_channel_storage_type": "etcd", + "ipfs_end_point": "http://ipfs.singularitynet.io:80", + "ipfs_timeout" : 30, + "passthrough_enabled": true, + "passthrough_endpoint":"http://127.0.0.1:5002", + "service_id": "ExampleServiceId", + "organization_id": "ExampleOrganizationId", + "metering_enabled": false, + "ssl_cert": "", + "ssl_key": "", + "max_message_size_in_mb" : 4, + "daemon_type": "grpc", + "enable_dynamic_pricing":false, + "allowed_user_flag" :false, + "auto_ssl_domain": "", + "auto_ssl_cache_dir": ".certs", + "private_key": "", + "log": { + "level": "info", + "timezone": "UTC", + "formatter": { + "type": "text", + "timestamp_format": "2006-01-02T15:04:05.999Z07:00" + }, + "output": { + "type": ["file", "stdout"], + "file_pattern": "./snet-daemon.%Y%m%d.log", + "current_link": "./snet-daemon.log", + "max_size_in_mb": 10, + "max_age_in_days": 7, + "rotation_count": 0 + }, + "hooks": [] + }, + "payment_channel_storage_client": { + "connection_timeout": "0s", + "request_timeout": "0s", + "hot_reload": true + }, + "payment_channel_storage_server": { + "id": "storage-1", + "scheme": "http", + "host" : "127.0.0.1", + "client_port": 2379, + "peer_port": 2380, + "token": "unique-token", + "cluster": "storage-1=http://127.0.0.1:2380", + "startup_timeout": "1m", + "data_dir": "storage-data-dir-1.etcd", + "log_level": "info", + "log_outputs": ["./etcd-server.log"], + "enabled": false + }, + "alerts_email": "", + "service_heartbeat_type": "http", + "token_expiry_in_minutes": 1440, + "model_training_enabled": false +}` + + var testConfig = viper.New() + err := config.ReadConfigFromJsonString(testConfig, testConfigJson) + if err != nil { + zap.L().Fatal("Error in reading config") + } + + config.SetVip(testConfig) +} + +func startServerA(port string, h grpc.StreamHandler) (*grpc.Server, *net.Listener) { + lis, err := net.Listen("tcp", port) + if err != nil { + zap.L().Fatal("Failed to listen", zap.Error(err)) + } + + grpcServer := grpc.NewServer() + RegisterExampleStreamingServiceServer(grpcServer, &ServiceA{h: h}) + + go func() { + if err := grpcServer.Serve(lis); err != nil { + zap.L().Fatal("Failed to serve", zap.Error(err)) + } + }() + return grpcServer, &lis +} + +func startServerB(port string) (*grpc.Server, *net.Listener) { + lis, err := net.Listen("tcp", port) + if err != nil { + zap.L().Fatal("Failed to listen", zap.Error(err)) + } + + grpcServer := grpc.NewServer() + RegisterExampleStreamingServiceServer(grpcServer, &ServiceB{}) + + go func() { + if err := grpcServer.Serve(lis); err != nil { + zap.L().Fatal("Failed to serve", zap.Error(err)) + } + }() + return grpcServer, &lis +} + +func setupEnvironment() *integrationTestEnvironment { + setupTestConfig() + serviceMetadata := &blockchain.ServiceMetadata{ + ServiceType: "grpc", + Encoding: "proto", + } + grpcToGrpc := handler.NewGrpcHandler(serviceMetadata) + grpcServerA, listenerA := startServerA(":5001", grpcToGrpc) + grpcServerB, listenerB := startServerB(":5002") + + testEnv := &integrationTestEnvironment{ + serverA: grpcServerA, + listenerA: listenerA, + serverB: grpcServerB, + listenerB: listenerB, + } + + return testEnv +} + +func teardownEnvironment(env *integrationTestEnvironment) { + env.serverA.Stop() + env.serverB.Stop() + (*env.listenerA).Close() + (*env.listenerB).Close() +} + +type ServiceA struct { + UnimplementedExampleStreamingServiceServer + h grpc.StreamHandler +} + +type ServiceB struct { + UnimplementedExampleStreamingServiceServer +} + +func (s *ServiceA) Stream(stream ExampleStreamingService_StreamServer) error { + // Forward the stream to grpcToGrpc handler + err := s.h(nil, stream) + if err != nil { + return err + } + return nil +} + +func (s *ServiceB) Stream(stream ExampleStreamingService_StreamServer) error { + for { + // Receive the input from the proxied stream + req, err := stream.Recv() + if err == io.EOF { + return nil + } + if err != nil { + return err + } + + // Send back the response to the stream + err = stream.Send(&OutStream{ + Message: "Response from Server B: " + req.Message, + }) + if err != nil { + return err + } + } +} + +func TestGrpcToGrpc_StreamingIntegration(t *testing.T) { + // Setup test environment with real servers + testEnv := setupEnvironment() + defer teardownEnvironment(testEnv) + + // Create a gRPC client to interact with Server A + connA, err := grpc.NewClient((*testEnv.listenerA).Addr().String(), grpc.WithTransportCredentials(insecure.NewCredentials())) + require.NoError(t, err) + defer connA.Close() + + clientA := NewExampleStreamingServiceClient(connA) + + // Simulate a bidirectional streaming RPC call from clientA to Server A + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + + stream, err := clientA.Stream(ctx) + require.NoError(t, err) + + // Send a message from the client A to Server A + err = stream.Send(&InStream{Message: "Hello from client A"}) + require.NoError(t, err) + + // Receive the response from Server B (proxied by grpcToGrpc) + resp, err := stream.Recv() + require.NoError(t, err) + assert.Equal(t, "Response from Server B: Hello from client A", resp.Message) + + // Close the stream + stream.CloseSend() +} diff --git a/ipfsutils/common.go b/ipfsutils/common.go new file mode 100644 index 00000000..418959cb --- /dev/null +++ b/ipfsutils/common.go @@ -0,0 +1,35 @@ +package ipfsutils + +import ( + "go.uber.org/zap" + "regexp" + "strings" +) + +const ( + IpfsPrefix = "ipfs://" + FilecoinPrefix = "filecoin://" +) + +func ReadFile(hash string) (rawFile []byte, err error) { + if strings.HasPrefix(hash, FilecoinPrefix) { + rawFile, err = GetLighthouseFile(formatHash(hash)) + } else { + rawFile, err = GetIpfsFile(formatHash(hash)) + } + return rawFile, err +} + +func formatHash(hash string) string { + zap.L().Debug("Before Formatting", zap.String("metadataHash", hash)) + hash = strings.Replace(hash, IpfsPrefix, "", -1) + hash = strings.Replace(hash, FilecoinPrefix, "", -1) + hash = removeSpecialCharacters(hash) + zap.L().Debug("After Formatting", zap.String("metadataHash", hash)) + return hash +} + +func removeSpecialCharacters(pString string) string { + reg := regexp.MustCompile("[^a-zA-Z0-9=]") + return reg.ReplaceAllString(pString, "") +} diff --git a/ipfsutils/common_test.go b/ipfsutils/common_test.go new file mode 100644 index 00000000..25cea6e3 --- /dev/null +++ b/ipfsutils/common_test.go @@ -0,0 +1,45 @@ +package ipfsutils + +import ( + "github.com/stretchr/testify/assert" + "testing" +) + +func TestReadFile(t *testing.T) { + file, err := ReadFile("filecoin://bafkreibk4ham7y6mwad2qxwyrhpmxh2fho7xwvsfw26lcra5bt5r5fvcwe") + assert.Nil(t, err) + assert.NotNil(t, file) +} + +func TestFormatHash(t *testing.T) { + s2 := []byte("ipfs://Here is a string....+=") + hash := formatHash(string(s2)) + assert.Equal(t, hash, "Hereisastring=") + + s2 = []byte("filecoin://QmaGnQ3iVZPuPwdam2rEeQcCSoCYRpxjnZhQ6Z2oeeRSrp") + b4 := append(s2, make([]byte, 3)...) + assert.NotEqual(t, "QmaGnQ3iVZPuPwdam2rEeQcCSoCYRpxjnZhQ6Z2oeeRSrp", string(b4)) + assert.Equal(t, "QmaGnQ3iVZPuPwdam2rEeQcCSoCYRpxjnZhQ6Z2oeeRSrp", formatHash(string(b4))) +} + +func TestRemoveSpecialCharactersfromHash(t *testing.T) { + testCases := []struct { + input string + expectedOutput string + }{ + {"abc123", "abc123"}, + {"abc123!@#", "abc123"}, + {"a1b2c3 ~`!@#$%^&*()_+-={}[]|\\:;\"'<>,.?/", "a1b2c3="}, + {"abc=123", "abc=123"}, + {"a1!b2@c3#=4", "a1b2c3=4"}, + } + + for _, tc := range testCases { + t.Run(tc.input, func(t *testing.T) { + output := removeSpecialCharacters(tc.input) + if output != tc.expectedOutput { + t.Errorf("RemoveSpecialCharactersfromHash(%q) = %q; want %q", tc.input, output, tc.expectedOutput) + } + }) + } +} diff --git a/ipfsutils/compressed.go b/ipfsutils/compressed.go new file mode 100644 index 00000000..f1943518 --- /dev/null +++ b/ipfsutils/compressed.go @@ -0,0 +1,52 @@ +package ipfsutils + +import ( + "archive/tar" + "bytes" + "fmt" + "go.uber.org/zap" + "io" +) + +// ReadFilesCompressed - read all files which have been compressed, there can be more than one file +// We need to start reading the proto files associated with the service. +// proto files are compressed and stored as modelipfsHash +func ReadFilesCompressed(compressedFile []byte) (protofiles []string, err error) { + f := bytes.NewReader(compressedFile) + tarReader := tar.NewReader(f) + protofiles = make([]string, 0) + for { + header, err := tarReader.Next() + if err == io.EOF { + break + } + if err != nil { + zap.L().Error(err.Error()) + return nil, err + } + name := header.Name + switch header.Typeflag { + case tar.TypeDir: + zap.L().Debug("Directory name", zap.String("name", name)) + case tar.TypeReg: + zap.L().Debug("File name", zap.String("name", name)) + data := make([]byte, header.Size) + _, err := tarReader.Read(data) + if err != nil && err != io.EOF { + zap.L().Error(err.Error()) + return nil, err + } + protofiles = append(protofiles, string(data)) + default: + err = fmt.Errorf(fmt.Sprintf("%s : %c %s %s\n", + "Unknown file Type ", + header.Typeflag, + "in file", + name, + )) + zap.L().Error(err.Error()) + return nil, err + } + } + return protofiles, nil +} diff --git a/ipfsutils/ipfsutils.go b/ipfsutils/ipfsutils.go index 4debf671..87348316 100644 --- a/ipfsutils/ipfsutils.go +++ b/ipfsutils/ipfsutils.go @@ -1,10 +1,8 @@ package ipfsutils import ( - "archive/tar" "context" - "fmt" - + "errors" "github.com/ipfs/go-cid" "github.com/ipfs/kubo/client/rpc" "github.com/singnet/snet-daemon/config" @@ -12,54 +10,10 @@ import ( "io" "net/http" - "strings" "time" ) -// ReadFilesCompressed - read all files which have been compressed, there can be more than one file -// We need to start reading the proto files associated with the service. -// proto files are compressed and stored as modelipfsHash -func ReadFilesCompressed(compressedFile string) (protofiles []string, err error) { - f := strings.NewReader(compressedFile) - tarReader := tar.NewReader(f) - protofiles = make([]string, 0) - for true { - header, err := tarReader.Next() - if err == io.EOF { - break - } - if err != nil { - zap.L().Error(err.Error()) - return nil, err - } - name := header.Name - switch header.Typeflag { - case tar.TypeDir: - zap.L().Debug("Directory name", zap.Any("name", name)) - case tar.TypeReg: - zap.L().Debug("File name", zap.Any("name", name)) - data := make([]byte, header.Size) - _, err := tarReader.Read(data) - if err != nil && err != io.EOF { - zap.L().Error(err.Error()) - return nil, err - } - protofiles = append(protofiles, string(data)) - default: - err = fmt.Errorf(fmt.Sprintf("%s : %c %s %s\n", - "Unknown file Type ", - header.Typeflag, - "in file", - name, - )) - zap.L().Error(err.Error()) - return nil, err - } - } - return protofiles, nil -} - -func GetIpfsFile(hash string) (content string) { +func GetIpfsFile(hash string) (content []byte, err error) { zap.L().Debug("Hash Used to retrieve from IPFS", zap.String("hash", hash)) @@ -67,28 +21,35 @@ func GetIpfsFile(hash string) (content string) { cID, err := cid.Parse(hash) if err != nil { - zap.L().Panic("error parsing the ipfs hash", zap.String("hashFromMetaData", hash), zap.Error(err)) + zap.L().Error("error parsing the ipfs hash", zap.String("hashFromMetaData", hash), zap.Error(err)) + return nil, err } req := ipfsClient.Request("cat", cID.String()) - if err != nil { - zap.L().Panic("error executing the cat command in ipfs", zap.String("hashFromMetaData", hash), zap.Error(err)) - return + if req == nil { + zap.L().Error("error executing the cat command in ipfs: req is nil", zap.String("hashFromMetaData", hash)) + return nil, err } resp, err := req.Send(context.Background()) - defer resp.Close() if err != nil { - zap.L().Panic("error executing the cat command in ipfs", zap.String("hashFromMetaData", hash), zap.Error(err)) - return + zap.L().Error("error executing the cat command in ipfs", zap.String("hashFromMetaData", hash), zap.Error(err)) + return nil, err } + defer func(resp *rpc.Response) { + err := resp.Close() + if err != nil { + zap.L().Error(err.Error()) + } + }(resp) + if resp.Error != nil { - zap.L().Panic("error executing the cat command in ipfs", zap.String("hashFromMetaData", hash), zap.Error(err)) - return + zap.L().Error("error executing the cat command in ipfs", zap.String("hashFromMetaData", hash), zap.Error(err)) + return nil, err } fileContent, err := io.ReadAll(resp.Output) if err != nil { - zap.L().Panic("error: in Reading the meta data file", zap.Error(err), zap.String("hashFromMetaData", hash)) - return + zap.L().Error("error: in Reading the meta data file", zap.Error(err), zap.String("hashFromMetaData", hash)) + return nil, err } // log.WithField("hash", hash).WithField("blob", string(fileContent)).Debug("Blob of IPFS file with hash") @@ -96,18 +57,19 @@ func GetIpfsFile(hash string) (content string) { // Create a cid manually to check cid _, c, err := cid.CidFromBytes(append(cID.Bytes(), fileContent...)) if err != nil { - zap.L().Panic("error generating ipfs hash", zap.String("hashFromMetaData", hash), zap.Error(err)) - return + zap.L().Error("error generating ipfs hash", zap.String("hashFromMetaData", hash), zap.Error(err)) + return nil, err } // To test if two cid's are equivalent, be sure to use the 'Equals' method: if !c.Equals(cID) { - zap.L().Panic("IPFS hash verification failed. Generated hash doesnt match with expected hash", + zap.L().Error("IPFS hash verification failed. Generated hash doesnt match with expected hash", zap.String("expectedHash", hash), zap.String("hashFromIPFSContent", c.String())) + return nil, errors.New("IPFS hash doesnt match with expected hash") } - return string(fileContent) + return fileContent, nil } func GetIPFSClient() *rpc.HttpApi { @@ -116,7 +78,7 @@ func GetIPFSClient() *rpc.HttpApi { } ifpsClient, err := rpc.NewURLApiWithClient(config.GetString(config.IpfsEndPoint), &httpClient) if err != nil { - zap.L().Panic("Connection failed to IPFS", zap.String("IPFS", config.GetString(config.IpfsEndPoint)), zap.Error(err)) + zap.L().Fatal("Connection failed to IPFS", zap.String("IPFS", config.GetString(config.IpfsEndPoint)), zap.Error(err)) } return ifpsClient } diff --git a/ipfsutils/ipfsutils_test.go b/ipfsutils/ipfsutils_test.go new file mode 100644 index 00000000..abd1f406 --- /dev/null +++ b/ipfsutils/ipfsutils_test.go @@ -0,0 +1,60 @@ +package ipfsutils + +import ( + "testing" + + "github.com/ipfs/kubo/client/rpc" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/suite" + + _ "github.com/singnet/snet-daemon/config" +) + +type IpfsUtilsTestSuite struct { + suite.Suite + ipfsClient *rpc.HttpApi +} + +func TestIpfsUtilsTestSuite(t *testing.T) { + suite.Run(t, new(IpfsUtilsTestSuite)) +} + +func (suite *IpfsUtilsTestSuite) BeforeTest() { + suite.ipfsClient = GetIPFSClient() + assert.NotNil(suite.T(), suite.ipfsClient) +} + +func (suite *IpfsUtilsTestSuite) TestReadFiles() { + // For testing purposes, a hash is used from the calculator service. + hash := "QmeyrQkEyba8dd4rc3jrLd5pEwsxHutfH2RvsSaeSMqTtQ" + data, err := GetIpfsFile(hash) + assert.NotNil(suite.T(), data) + assert.Nil(suite.T(), err) + + protoFiles, err := ReadFilesCompressed(data) + + assert.Nil(suite.T(), err) + assert.NotNil(suite.T(), protoFiles) + + excpectedProtoFiles := []string{`syntax = "proto3"; + +package example_service; + +message Numbers { + float a = 1; + float b = 2; +} + +message Result { + float value = 1; +} + +service Calculator { + rpc add(Numbers) returns (Result) {} + rpc sub(Numbers) returns (Result) {} + rpc mul(Numbers) returns (Result) {} + rpc div(Numbers) returns (Result) {} +}`} + + assert.Equal(suite.T(), excpectedProtoFiles, protoFiles) +} diff --git a/ipfsutils/lighthouse.go b/ipfsutils/lighthouse.go new file mode 100644 index 00000000..4849e5a9 --- /dev/null +++ b/ipfsutils/lighthouse.go @@ -0,0 +1,20 @@ +package ipfsutils + +import ( + "io" + "net/http" +) + +const lighthouseURL = "https://gateway.lighthouse.storage/ipfs/" + +func GetLighthouseFile(cID string) ([]byte, error) { + resp, err := http.Get(lighthouseURL + cID) + if err != nil { + return nil, err + } + file, err := io.ReadAll(resp.Body) + if err != nil { + return nil, err + } + return file, nil +} diff --git a/license_server/license_api.go b/license_server/license_api.go index 382a6b7a..9302ceb5 100644 --- a/license_server/license_api.go +++ b/license_server/license_api.go @@ -22,7 +22,7 @@ type LicenseTransaction interface { Rollback() error } -//this is used to track the license Usage +// this is used to track the license Usage type licenseUsageTrackerTransactionImpl struct { channelId *big.Int usage Usage diff --git a/license_server/license_service_test.go b/license_server/license_service_test.go index c88aae87..e5b2bcd7 100644 --- a/license_server/license_service_test.go +++ b/license_server/license_service_test.go @@ -23,13 +23,14 @@ type LicenseServiceTestSuite struct { func (suite *LicenseServiceTestSuite) SetupSuite() { suite.channelID = big.NewInt(1) - suite.orgMetaData, _ = blockchain.InitOrganizationMetaDataFromJson(testJsonOrgGroupData) + suite.orgMetaData, _ = blockchain.InitOrganizationMetaDataFromJson([]byte(testJsonOrgGroupData)) suite.servMetaData, _ = blockchain.ReadServiceMetaDataFromLocalFile("../service_metadata.json") suite.licenseDetailsStorage = NewLicenseDetailsStorage(storage.NewMemStorage()) suite.licenseUsageStorage = NewLicenseUsageTrackerStorage(storage.NewMemStorage()) suite.service = NewLicenseService(suite.licenseDetailsStorage, suite.licenseUsageStorage, suite.orgMetaData, suite.servMetaData) } + func TestTokenServiceTestSuite(t *testing.T) { suite.Run(t, new(LicenseServiceTestSuite)) } @@ -41,5 +42,4 @@ func (suite *LicenseServiceTestSuite) TestCreateLicense() { usage, ok, err := suite.service.GetLicenseUsage(LicenseUsageTrackerKey{ChannelID: suite.channelID, ServiceID: "serviceId1", UsageType: PLANNED}) assert.True(suite.T(), ok) assert.Equal(suite.T(), usage.Usage.GetUsage(), big.NewInt(100)) - } diff --git a/license_server/license_storage.go b/license_server/license_storage.go index ba31c41a..3ece6801 100644 --- a/license_server/license_storage.go +++ b/license_server/license_storage.go @@ -354,13 +354,10 @@ func serializeLicenseDetailsData(value any) (slice string, err error) { gob.Register(&ServiceMethodCostDetails{}) err = e.Encode(value) - if err != nil { return } - - slice = string(b.Bytes()) - return + return b.String(), err } func deserializeLicenseDetailsData(slice string, value any) (err error) { b := bytes.NewBuffer([]byte(slice)) @@ -386,8 +383,7 @@ func serializeLicenseTrackerData(value any) (slice string, err error) { return } - slice = string(b.Bytes()) - return + return b.String(), err } func deserializeLicenseTrackerData(slice string, value any) (err error) { diff --git a/logger/hook.go b/logger/hook.go index 27b92eaf..c23f4914 100644 --- a/logger/hook.go +++ b/logger/hook.go @@ -165,7 +165,6 @@ func newTelegramBotHook(config *viper.Viper) (hook, error) { } func (t telegramBotHook) call(entry zapcore.Entry) error { - msg := "⚠️Daemon hook⚠️\r\n" + "\r\nOrgID: " + config.GetString(config.OrganizationId) + "\r\nServiceID: " + config.GetString(config.ServiceId) + diff --git a/metrics/clients.go b/metrics/clients.go index 61ee8caf..2f3de8c9 100644 --- a/metrics/clients.go +++ b/metrics/clients.go @@ -9,6 +9,7 @@ import ( "bytes" "context" "errors" + "google.golang.org/grpc/credentials/insecure" "io" "net/http" "time" @@ -27,7 +28,7 @@ type Response struct { // Calls a gRPC endpoint for heartbeat (gRPC Client) func callgRPCServiceHeartbeat(serviceUrl string) (grpc_health_v1.HealthCheckResponse_ServingStatus, error) { // Set up a connection to the server. - conn, err := grpc.Dial(serviceUrl, grpc.WithInsecure()) + conn, err := grpc.NewClient(serviceUrl, grpc.WithTransportCredentials(insecure.NewCredentials())) if err != nil { zap.L().Warn("unable to connect to grpc endpoint", zap.Error(err)) return grpc_health_v1.HealthCheckResponse_NOT_SERVING, err diff --git a/metrics/clients_test.go b/metrics/clients_test.go index 3f641f7e..f02d2715 100644 --- a/metrics/clients_test.go +++ b/metrics/clients_test.go @@ -7,12 +7,13 @@ package metrics import ( "context" + "net" + "testing" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" "google.golang.org/grpc" pb "google.golang.org/grpc/health/grpc_health_v1" - "net" - "testing" ) // server is used to implement api.HeartbeatServer @@ -101,14 +102,16 @@ func (suite *ClientTestSuite) Test_callHTTPServiceHeartbeat() { assert.True(suite.T(), err != nil) } -func (suite *ClientTestSuite) Test_callRegisterService() { +// TODO: refactor register service - daemonID := GetDaemonID() +// func (suite *ClientTestSuite) Test_callRegisterService() { - result := callRegisterService(daemonID, suite.serviceURL+"/register") - assert.Equal(suite.T(), true, result) +// daemonID := GetDaemonID() - result = callRegisterService(daemonID, suite.serviceURL+"/registererror") - assert.Equal(suite.T(), false, result) +// result := callRegisterService(daemonID, suite.serviceURL+"/register") +// assert.Equal(suite.T(), true, result) -} +// result = callRegisterService(daemonID, suite.serviceURL+"/registererror") +// assert.Equal(suite.T(), false, result) + +// } diff --git a/metrics/register_test.go b/metrics/register_test.go index 78982257..9192feed 100644 --- a/metrics/register_test.go +++ b/metrics/register_test.go @@ -6,9 +6,10 @@ package metrics import ( + "testing" + "github.com/stretchr/testify/suite" "google.golang.org/grpc" - "testing" "github.com/stretchr/testify/assert" ) @@ -40,15 +41,17 @@ func TestGetDaemonID(t *testing.T) { assert.NotEqual(t, "48d343313a1e06093c81830103b45496cc7c277f321049e9ee632fd03207d042", daemonID) } -func (suite *RegisterTestSuite) TestRegisterDaemon() { +// TODO: refactor register service - result := RegisterDaemon(suite.serviceURL + "/register") - assert.Equal(suite.T(), true, result) +// func (suite *RegisterTestSuite) TestRegisterDaemon() { - wrongserviceURL := "https://localhost:9999/registererror" - result = RegisterDaemon(wrongserviceURL) - assert.Equal(suite.T(), false, result) -} +// result := RegisterDaemon(suite.serviceURL + "/register") +// assert.Equal(suite.T(), true, result) + +// wrongserviceURL := "https://localhost:9999/registererror" +// result = RegisterDaemon(wrongserviceURL) +// assert.Equal(suite.T(), false, result) +// } func (suite *RegisterTestSuite) TestSetDaemonGrpId() { grpid := "group01" diff --git a/metrics/request_stats.go b/metrics/request_stats.go index 83e8cbac..d9eff875 100644 --- a/metrics/request_stats.go +++ b/metrics/request_stats.go @@ -6,7 +6,7 @@ import ( "strconv" ) -//Request stats that will be captured +// Request stats that will be captured type RequestStats struct { Type string `json:"type"` RegistryAddressKey string `json:"registry_address_key"` @@ -26,8 +26,6 @@ type RequestStats struct { ChannelId string `json:"channel_id"` } - - func (request *RequestStats) setDataFromContext(md metadata.MD) { request.InputDataSize = strconv.FormatUint(GetSize(md), 10) @@ -37,7 +35,7 @@ func createRequestStat(commonStat *CommonStats) *RequestStats { request := &RequestStats{ Type: "request", RegistryAddressKey: config.GetRegistryAddress(), - EthereumJsonRpcEndpointKey: config.GetBlockChainEndPoint(), + EthereumJsonRpcEndpointKey: config.GetBlockChainHTTPEndPoint(), RequestID: commonStat.ID, GroupID: commonStat.GroupID, DaemonEndPoint: commonStat.DaemonEndPoint, diff --git a/metrics/request_stats_test.go b/metrics/request_stats_test.go index 25d6dfca..f7dddaaf 100644 --- a/metrics/request_stats_test.go +++ b/metrics/request_stats_test.go @@ -20,7 +20,7 @@ func TestCreateRequestStat(t *testing.T) { commonStat.ClientType = "snet-cli" commonStat.UserDetails = "0x94d04332C4f5273feF69c4a52D24f42a3aF1F207" commonStat.UserAgent = "python/cli" - commonStat.ChannelId = "2" + commonStat.ChannelId = "2" request := createRequestStat(commonStat) assert.Equal(t, request.RequestID, commonStat.ID) assert.Equal(t, request.GroupID, daemonGroupId) diff --git a/metrics/response_stats.go b/metrics/response_stats.go index c30c3d43..72be4b09 100644 --- a/metrics/response_stats.go +++ b/metrics/response_stats.go @@ -1,17 +1,19 @@ package metrics import ( - "github.com/singnet/snet-daemon/config" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" "math/big" "strconv" "time" + + "github.com/singnet/snet-daemon/config" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" ) const ( - timeFormat="2006-01-02 15:04:05.999999999" + timeFormat = "2006-01-02 15:04:05.999999999" ) + type CommonStats struct { ID string ServiceMethod string @@ -31,14 +33,15 @@ type CommonStats struct { } type ChannelStats struct { - OrganizationID string - ServiceID string - GroupID string - AuthorizedAmount *big.Int - FullAmount *big.Int - ChannelId *big.Int - Nonce *big.Int + OrganizationID string + ServiceID string + GroupID string + AuthorizedAmount *big.Int + FullAmount *big.Int + ChannelId *big.Int + Nonce *big.Int } + func BuildCommonStats(receivedTime time.Time, methodName string) *CommonStats { commonStats := &CommonStats{ ID: GenXid(), @@ -53,7 +56,7 @@ func BuildCommonStats(receivedTime time.Time, methodName string) *CommonStats { } -//Response stats that will be captured and published +// Response stats that will be captured and published type ResponseStats struct { Type string `json:"type"` RegistryAddressKey string `json:"registry_address_key"` @@ -85,20 +88,20 @@ type ResponseStats struct { UserAddress string `json:"user_address"` } -//Publish response received as a payload for reporting /metrics analysis -//If there is an error in the response received from the service, then send out a notification as well. +// Publish response received as a payload for reporting /metrics analysis +// If there is an error in the response received from the service, then send out a notification as well. func PublishResponseStats(commonStats *CommonStats, duration time.Duration, err error) bool { response := createResponseStats(commonStats, duration, err) - return Publish(response, config.GetString(config.MeteringEndPoint) + "/metering/usage",commonStats) + return Publish(response, config.GetString(config.MeteringEndPoint)+"/metering/usage", commonStats) } func createResponseStats(commonStat *CommonStats, duration time.Duration, err error) *ResponseStats { - currentTime := time.Now().UTC().Format(timeFormat) + currentTime := time.Now().UTC().Format(timeFormat) response := &ResponseStats{ Type: "response", RegistryAddressKey: config.GetRegistryAddress(), - EthereumJsonRpcEndpointKey: config.GetBlockChainEndPoint(), + EthereumJsonRpcEndpointKey: config.GetBlockChainHTTPEndPoint(), RequestID: commonStat.ID, ResponseTime: strconv.FormatFloat(duration.Seconds(), 'f', 4, 64), GroupID: daemonGroupId, @@ -114,21 +117,23 @@ func createResponseStats(commonStat *CommonStats, duration time.Duration, err er UserDetails: commonStat.UserDetails, UserAgent: commonStat.UserAgent, ChannelId: commonStat.ChannelId, - UserName:commonStat.UserName, - StartTime:commonStat.RequestReceivedTime, - EndTime:currentTime, - Status:getStatus(err), - UsageValue:1, - UsageType:"apicall", - Operation:"read", - PaymentMode:commonStat.PaymentMode, - UserAddress:commonStat.UserAddress, + UserName: commonStat.UserName, + StartTime: commonStat.RequestReceivedTime, + EndTime: currentTime, + Status: getStatus(err), + UsageValue: 1, + UsageType: "apicall", + Operation: "read", + PaymentMode: commonStat.PaymentMode, + UserAddress: commonStat.UserAddress, } return response } func getStatus(err error) string { - if err != nil {return "failed"} + if err != nil { + return "failed" + } return "success" } diff --git a/metrics/response_stats_test.go b/metrics/response_stats_test.go index 544bc705..f62974ea 100644 --- a/metrics/response_stats_test.go +++ b/metrics/response_stats_test.go @@ -17,7 +17,7 @@ func TestCreateResponseStats(t *testing.T) { commonStat.UserAgent = "python/cli" commonStat.ChannelId = "1" commonStat.PaymentMode = "freecall" - commonStat.UserAddress="0x94d04332C4f5273feF69c4a52D24f42a3aF1F207" + commonStat.UserAddress = "0x94d04332C4f5273feF69c4a52D24f42a3aF1F207" response := createResponseStats(commonStat, time.Duration(1234566000), nil) assert.Equal(t, response.RequestID, commonStat.ID) assert.Equal(t, response.Version, commonStat.Version) @@ -56,38 +56,36 @@ func TestJsonCreated(t *testing.T) { fmt.Println(zone, offset) payload := &ResponseStats{ - Type:"grpc", - ChannelId:"123", - - RegistryAddressKey:"", - EthereumJsonRpcEndpointKey:"", - RequestID:"", - OrganizationID:config.GetString(config.OrganizationId), - GroupID:"", - ServiceMethod:"", - ResponseSentTime:"", - RequestReceivedTime:"", - ResponseTime:"", - ResponseCode:"", - ErrorMessage:"", - Version:"", - ClientType:"", - UserDetails:"", - UserAgent:"", - UserName:"whateverDappPasses", - Operation:"", - UsageType:"", - Status:"", - StartTime:"", - EndTime:"", - UsageValue:1, - TimeZone:zone, - + Type: "grpc", + ChannelId: "123", + RegistryAddressKey: "", + EthereumJsonRpcEndpointKey: "", + RequestID: "", + OrganizationID: config.GetString(config.OrganizationId), + GroupID: "", + ServiceMethod: "", + ResponseSentTime: "", + RequestReceivedTime: "", + ResponseTime: "", + ResponseCode: "", + ErrorMessage: "", + Version: "", + ClientType: "", + UserDetails: "", + UserAgent: "", + UserName: "whateverDappPasses", + Operation: "", + UsageType: "", + Status: "", + StartTime: "", + EndTime: "", + UsageValue: 1, + TimeZone: zone, } jsonBytes, err := ConvertStructToJSON(payload) - assert.NotNil(t,jsonBytes) - assert.Contains(t,string(jsonBytes),"whateverDappPasses") - assert.Nil(t,err) + assert.NotNil(t, jsonBytes) + assert.Contains(t, string(jsonBytes), "whateverDappPasses") + assert.Nil(t, err) } diff --git a/metrics/utils.go b/metrics/utils.go index f69c5b39..2ca2cff3 100644 --- a/metrics/utils.go +++ b/metrics/utils.go @@ -101,7 +101,6 @@ func sendRequest(json []byte, serviceURL string, commonStats *CommonStats) (*htt SignMessageForMetering(req, commonStats) return client.Do(req) - } func SignMessageForMetering(req *http.Request, commonStats *CommonStats) { @@ -178,6 +177,7 @@ func getTokenFromResponse(response *http.Response) (string, bool) { zap.L().Warn("Empty response received.") return "", false } + defer response.Body.Close() if response.StatusCode != http.StatusOK { zap.L().Warn("Service call failed", zap.Int("StatusCode", response.StatusCode)) return "", false @@ -188,9 +188,12 @@ func getTokenFromResponse(response *http.Response) (string, bool) { return "", false } var data TokenGenerated - json.Unmarshal(body, &data) + err = json.Unmarshal(body, &data) + if err != nil { + zap.L().Error("Can't unmarshal TokenGenerated", zap.Error(err)) + return "", false + } //close the body - defer response.Body.Close() return data.Data.Token, true } diff --git a/pricing/dynamic_method_pricing.go b/pricing/dynamic_method_pricing.go index 452673e6..8e7cff80 100644 --- a/pricing/dynamic_method_pricing.go +++ b/pricing/dynamic_method_pricing.go @@ -3,6 +3,7 @@ package pricing import ( "fmt" + "google.golang.org/grpc/credentials/insecure" "math/big" "net/url" @@ -51,7 +52,7 @@ func (priceType *DynamicMethodPrice) checkForDynamicPricing( grpc.MaxCallRecvMsgSize(config.GetInt(config.MaxMessageSizeInMB)*1024*1024), grpc.MaxCallSendMsgSize(config.GetInt(config.MaxMessageSizeInMB)*1024*1024)) - conn, _ := grpc.Dial(passThroughURL.Host, grpc.WithInsecure(), options) + conn, _ := grpc.NewClient(passThroughURL.Host, grpc.WithTransportCredentials(insecure.NewCredentials()), options) md, ok := metadata.FromIncomingContext(derivedContext.InStream.Context()) if !ok { @@ -67,6 +68,9 @@ func (priceType *DynamicMethodPrice) checkForDynamicPricing( clientStream, err := conn.NewStream(outCtx, &grpc.StreamDesc{ServerStreams: true, ClientStreams: true}, pricingMethod, grpc.CallContentSubtype("proto")) + if err != nil { + zap.L().Error(err.Error()) + } return priceType.getPriceFromPricingMethod(derivedContext.InStream, clientStream) } diff --git a/pricing/fixed_method_pricing_test.go b/pricing/fixed_method_pricing_test.go index c42044ca..aca7daac 100644 --- a/pricing/fixed_method_pricing_test.go +++ b/pricing/fixed_method_pricing_test.go @@ -13,28 +13,25 @@ import ( var testJsonDataFixedMethodPrice = "{ \"version\": 1, \"display_name\": \"Example1\", \"encoding\": \"grpc\", \"service_type\": \"grpc\", \"payment_expiration_threshold\": 40320, \"model_ipfs_hash\": \"Qmdiq8Hu6dYiwp712GtnbBxagyfYyvUY1HYqkH7iN76UCc\", \"mpe_address\": \"0x7E6366Fbe3bdfCE3C906667911FC5237Cc96BD08\", \"groups\": [ { \"endpoints\": [\"http://34.344.33.1:2379\",\"http://34.344.33.1:2389\"], \"group_id\": \"88ybRIg2wAx55mqVsA6sB4S7WxPQHNKqa4BPu/bhj+U=\",\"group_name\": \"default_group\", \"pricing\": [ { \"price_model\": \"fixed_price\", \"price_in_cogs\": 2 }, { \"package_name\": \"example_service\", \"price_model\": \"fixed_price_per_method\", \"default\":true, \"details\": [ { \"service_name\": \"Calculator\", \"method_pricing\": [ { \"method_name\": \"add\", \"price_in_cogs\": 2 }, { \"method_name\": \"sub\", \"price_in_cogs\": 1 }, { \"method_name\": \"div\", \"price_in_cogs\": 2 }, { \"method_name\": \"mul\", \"price_in_cogs\": 3 } ] }, { \"service_name\": \"Calculator2\", \"method_pricing\": [ { \"method_name\": \"add\", \"price_in_cogs\": 2 }, { \"method_name\": \"sub\", \"price_in_cogs\": 1 }, { \"method_name\": \"div\", \"price_in_cogs\": 3 }, { \"method_name\": \"mul\", \"price_in_cogs\": 2 } ] } ] }] }, { \"endpoints\": [\"http://97.344.33.1:2379\",\"http://67.344.33.1:2389\"], \"group_id\": \"99ybRIg2wAx55mqVsA6sB4S7WxPQHNKqa4BPu/bhj+U=\", \"pricing\": [ { \"package_name\": \"example_service\", \"price_model\": \"fixed_price_per_method\", \"details\": [ { \"service_name\": \"Calculator\", \"method_pricing\": [ { \"method_name\": \"add\", \"price_in_cogs\": 2 }, { \"method_name\": \"sub\", \"price_in_cogs\": 1 }, { \"method_name\": \"div\", \"price_in_cogs\": 2 }, { \"method_name\": \"mul\", \"price_in_cogs\": 3 } ] }, { \"service_name\": \"Calculator2\", \"method_pricing\": [ { \"method_name\": \"add\", \"price_in_cogs\": 2 }, { \"method_name\": \"sub\", \"price_in_cogs\": 1 }, { \"method_name\": \"div\", \"price_in_cogs\": 3 }, { \"method_name\": \"mul\", \"price_in_cogs\": 2 } ] } ] }] } ] } " - func TestFixedMethodPrice_initPricingData(t *testing.T) { - metadata,_ := blockchain.InitServiceMetaDataFromJson(testJsonDataFixedMethodPrice) - grpcCtx := &handler.GrpcStreamContext{Info:&grpc.StreamServerInfo{FullMethod:"/example_service.Calculator/add"}} - pricing,_ := InitPricingStrategy(metadata) - price,err := pricing.GetPrice(grpcCtx) - assert.Equal(t,price,big.NewInt(2)) - assert.Nil(t,err) + metadata, _ := blockchain.InitServiceMetaDataFromJson([]byte(testJsonDataFixedMethodPrice)) + grpcCtx := &handler.GrpcStreamContext{Info: &grpc.StreamServerInfo{FullMethod: "/example_service.Calculator/add"}} + pricing, _ := InitPricingStrategy(metadata) + price, err := pricing.GetPrice(grpcCtx) + assert.Equal(t, price, big.NewInt(2)) + assert.Nil(t, err) //Test with an undefined method Name - grpcCtx.Info.FullMethod= "NonDefinedMethod" - price,err = pricing.GetPrice(grpcCtx) - assert.Nil(t,price) + grpcCtx.Info.FullMethod = "NonDefinedMethod" + price, err = pricing.GetPrice(grpcCtx) + assert.Nil(t, price) if err != nil { assert.Equal(t, err.Error(), "price is not defined for the Method NonDefinedMethod") } -/* //Test if the metadata is not properly defined - //metadata.GetDefaultPricing().Details = nil + /* //Test if the metadata is not properly defined + //metadata.GetDefaultPricing().Details = nil - pricing,err = InitPricingStrategy(metadata) - assert.Equal(t,err.Error(),"service / method level pricing is not defined correctly") - assert.Nil(t,pricing)*/ + pricing,err = InitPricingStrategy(metadata) + assert.Equal(t,err.Error(),"service / method level pricing is not defined correctly") + assert.Nil(t,pricing)*/ } - - diff --git a/pricing/fixed_pricing_test.go b/pricing/fixed_pricing_test.go index c9f18876..6671c2aa 100644 --- a/pricing/fixed_pricing_test.go +++ b/pricing/fixed_pricing_test.go @@ -12,7 +12,7 @@ import ( var testJsonDataFixedPrice = "{ \"version\": 1, \"display_name\": \"Example1\", \"encoding\": \"grpc\", \"service_type\": \"grpc\", \"payment_expiration_threshold\": 40320, \"model_ipfs_hash\": \"Qmdiq8Hu6dYiwp712GtnbBxagyfYyvUY1HYqkH7iN76UCc\", \"mpe_address\": \"0x7E6366Fbe3bdfCE3C906667911FC5237Cc96BD08\", \"groups\": [ { \"endpoints\": [\"http://34.344.33.1:2379\",\"http://34.344.33.1:2389\"], \"group_id\": \"88ybRIg2wAx55mqVsA6sB4S7WxPQHNKqa4BPu/bhj+U=\",\"group_name\": \"default_group\", \"pricing\": [ { \"price_model\": \"fixed_price\", \"default\":true, \"price_in_cogs\": 2 }, { \"package_name\": \"example_service\", \"price_model\": \"fixed_price_per_method\", \"details\": [ { \"service_name\": \"Calculator\", \"method_pricing\": [ { \"method_name\": \"add\", \"price_in_cogs\": 2 }, { \"method_name\": \"sub\", \"price_in_cogs\": 1 }, { \"method_name\": \"div\", \"price_in_cogs\": 2 }, { \"method_name\": \"mul\", \"price_in_cogs\": 3 } ] }, { \"service_name\": \"Calculator2\", \"method_pricing\": [ { \"method_name\": \"add\", \"price_in_cogs\": 2 }, { \"method_name\": \"sub\", \"price_in_cogs\": 1 }, { \"method_name\": \"div\", \"price_in_cogs\": 3 }, { \"method_name\": \"mul\", \"price_in_cogs\": 2 } ] } ] }] }, { \"endpoints\": [\"http://97.344.33.1:2379\",\"http://67.344.33.1:2389\"], \"group_name\": \"99ybRIg2wAx55mqVsA6sB4S7WxPQHNKqa4BPu/bhj+U=\", \"group_id\": \"99ybRIg2wAx55mqVsA6sB4S7WxPQHNKqa4BPu/bhj+U=\", \"pricing\": [ { \"package_name\": \"example_service\", \"price_model\": \"fixed_price_per_method\", \"details\": [ { \"service_name\": \"Calculator\", \"method_pricing\": [ { \"method_name\": \"add\", \"price_in_cogs\": 2 }, { \"method_name\": \"sub\", \"price_in_cogs\": 1 }, { \"method_name\": \"div\", \"price_in_cogs\": 2 }, { \"method_name\": \"mul\", \"price_in_cogs\": 3 } ] }, { \"service_name\": \"Calculator2\", \"method_pricing\": [ { \"method_name\": \"add\", \"price_in_cogs\": 2 }, { \"method_name\": \"sub\", \"price_in_cogs\": 1 }, { \"method_name\": \"div\", \"price_in_cogs\": 3 }, { \"method_name\": \"mul\", \"price_in_cogs\": 2 } ] } ] }] } ] } " func TestFixedPrice_GetPrice(t *testing.T) { - metadata, _ := blockchain.InitServiceMetaDataFromJson(testJsonDataFixedPrice) + metadata, _ := blockchain.InitServiceMetaDataFromJson([]byte(testJsonDataFixedPrice)) grpcCtx := &handler.GrpcStreamContext{} pricing, _ := InitPricingStrategy(metadata) diff --git a/pricing/price_type.go b/pricing/price_type.go index 2ffb42ea..32174b9f 100644 --- a/pricing/price_type.go +++ b/pricing/price_type.go @@ -11,7 +11,7 @@ const ( DYNAMIC_PRICING = "dynamic_pricing" ) -//Based on the request passed, a particular strategy will be picked up for processing +// Based on the request passed, a particular strategy will be picked up for processing type PriceType interface { //Based on the user input determine how will the price be determined diff --git a/pricing/pricing_strategy_test.go b/pricing/pricing_strategy_test.go index c3d38f59..a32fdc43 100644 --- a/pricing/pricing_strategy_test.go +++ b/pricing/pricing_strategy_test.go @@ -10,7 +10,7 @@ import ( var testJsonData = "{ \"version\": 1, \"display_name\": \"Example1\", \"encoding\": \"grpc\", \"service_type\": \"grpc\", \"payment_expiration_threshold\": 40320, \"model_ipfs_hash\": \"Qmdiq8Hu6dYiwp712GtnbBxagyfYyvUY1HYqkH7iN76UCc\", \"mpe_address\": \"0x7E6366Fbe3bdfCE3C906667911FC5237Cc96BD08\", \"groups\": [ { \"endpoints\": [\"http://34.344.33.1:2379\",\"http://34.344.33.1:2389\"], \"group_id\": \"88ybRIg2wAx55mqVsA6sB4S7WxPQHNKqa4BPu/bhj+U=\",\"group_name\": \"default_group\", \"pricing\": [ { \"price_model\": \"fixed_price\", \"default\":true, \"price_in_cogs\": 2 }, { \"package_name\": \"example_service\", \"price_model\": \"fixed_price_per_method\", \"details\": [ { \"service_name\": \"Calculator\", \"method_pricing\": [ { \"method_name\": \"add\", \"price_in_cogs\": 2 }, { \"method_name\": \"sub\", \"price_in_cogs\": 1 }, { \"method_name\": \"div\", \"price_in_cogs\": 2 }, { \"method_name\": \"mul\", \"price_in_cogs\": 3 } ] }, { \"service_name\": \"Calculator2\", \"method_pricing\": [ { \"method_name\": \"add\", \"price_in_cogs\": 2 }, { \"method_name\": \"sub\", \"price_in_cogs\": 1 }, { \"method_name\": \"div\", \"price_in_cogs\": 3 }, { \"method_name\": \"mul\", \"price_in_cogs\": 2 } ] } ] }] }, { \"endpoints\": [\"http://97.344.33.1:2379\",\"http://67.344.33.1:2389\"], \"group_name\": \"99ybRIg2wAx55mqVsA6sB4S7WxPQHNKqa4BPu/bhj+U=\", \"group_id\": \"99ybRIg2wAx55mqVsA6sB4S7WxPQHNKqa4BPu/bhj+U=\", \"pricing\": [ { \"package_name\": \"example_service\", \"price_model\": \"fixed_price_per_method\", \"details\": [ { \"service_name\": \"Calculator\", \"method_pricing\": [ { \"method_name\": \"add\", \"price_in_cogs\": 2 }, { \"method_name\": \"sub\", \"price_in_cogs\": 1 }, { \"method_name\": \"div\", \"price_in_cogs\": 2 }, { \"method_name\": \"mul\", \"price_in_cogs\": 3 } ] }, { \"service_name\": \"Calculator2\", \"method_pricing\": [ { \"method_name\": \"add\", \"price_in_cogs\": 2 }, { \"method_name\": \"sub\", \"price_in_cogs\": 1 }, { \"method_name\": \"div\", \"price_in_cogs\": 3 }, { \"method_name\": \"mul\", \"price_in_cogs\": 2 } ] } ] }] } ] } " func TestPricing_GetPrice(t *testing.T) { - metadata, _ := blockchain.InitServiceMetaDataFromJson(testJsonData) + metadata, _ := blockchain.InitServiceMetaDataFromJson([]byte(testJsonData)) pricing, err := InitPricingStrategy(metadata) if pricing != nil { diff --git a/ratelimit/rateLimit.go b/ratelimit/rateLimit.go index b52b1902..dac3cf0f 100644 --- a/ratelimit/rateLimit.go +++ b/ratelimit/rateLimit.go @@ -8,20 +8,19 @@ import ( "time" ) -func NewRateLimiter() rate.Limiter { - //Please note that the burst size is ignored when getLimit() returns rate is infinity - //By Default set the maximum value possible for the Burst Size ( assuming rate was defined ,but burst was not defined) +func NewRateLimiter() *rate.Limiter { + // Please note that the burst size is ignored when getLimit() returns rate is infinity + // By Default set the maximum value possible for the Burst Size + // (assuming rate was defined, but burst was not defined) burstSize := config.GetInt(config.BurstSize) if burstSize == 0 { burstSize = math.MaxInt32 } - limiter := rate.NewLimiter(getLimit(), burstSize) - return *limiter + return rate.NewLimiter(getLimit(), burstSize) } func getLimit() rate.Limit { - ratePerMin, err := strconv.ParseFloat(config.GetString(config.RateLimitPerMinute), 32) if err != nil { return rate.Inf diff --git a/ratelimit/rateLimit_test.go b/ratelimit/rateLimit_test.go index 588f399a..549b159c 100644 --- a/ratelimit/rateLimit_test.go +++ b/ratelimit/rateLimit_test.go @@ -2,11 +2,11 @@ package ratelimit import ( assert2 "github.com/stretchr/testify/assert" - "testing" "math" + "testing" ) -//TO DO , Add more test cases +// TO DO , Add more test cases func TestGetRateLimiter(t *testing.T) { limit := getLimit() assert2.NotEqual(t, nil, limit) @@ -14,5 +14,5 @@ func TestGetRateLimiter(t *testing.T) { func TestNewRateLimiter(t *testing.T) { rateLimit := NewRateLimiter() - assert2.Equal(t,rateLimit.Burst(),math.MaxInt32) -} \ No newline at end of file + assert2.Equal(t, rateLimit.Burst(), math.MaxInt32) +} diff --git a/resources/blockchain_network_config.json b/resources/blockchain_network_config.json index 3b390c19..4e27d269 100644 --- a/resources/blockchain_network_config.json +++ b/resources/blockchain_network_config.json @@ -5,15 +5,18 @@ "registry_address_key": "0x4e74fefa82e83e0964f0d9f53c68e03f7298a8b2" }, "main": { - "ethereum_json_rpc_endpoint": "https://mainnet.infura.io/v3/09027f4a13e841d48dbfefc67e7685d5", + "ethereum_json_rpc_http_endpoint": "https://mainnet.infura.io/v3/09027f4a13e841d48dbfefc67e7685d5", + "ethereum_json_rpc_ws_endpoint": "wss://mainnet.infura.io/ws/v3/09027f4a13e841d48dbfefc67e7685d5", "network_id": "1" }, "goerli": { - "ethereum_json_rpc_endpoint": "https://goerli.infura.io/v3/09027f4a13e841d48dbfefc67e7685d5", + "ethereum_json_rpc_http_endpoint": "https://goerli.infura.io/v3/09027f4a13e841d48dbfefc67e7685d5", + "ethereum_json_rpc_ws_endpoint": "wss://goerli.infura.io/ws/v3/09027f4a13e841d48dbfefc67e7685d5", "network_id": "5" }, "sepolia": { - "ethereum_json_rpc_endpoint": "https://sepolia.infura.io/v3/09027f4a13e841d48dbfefc67e7685d5", + "ethereum_json_rpc_http_endpoint": "https://sepolia.infura.io/v3/09027f4a13e841d48dbfefc67e7685d5", + "ethereum_json_rpc_ws_endpoint": "wss://sepolia.infura.io/ws/v3/09027f4a13e841d48dbfefc67e7685d5", "network_id": "11155111" } } \ No newline at end of file diff --git a/resources/linuxbuild/Dockerfile b/resources/linuxbuild/Dockerfile index 576a6d6f..d62a305f 100644 --- a/resources/linuxbuild/Dockerfile +++ b/resources/linuxbuild/Dockerfile @@ -1,15 +1,11 @@ -FROM golang:latest -WORKDIR / -RUN curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh -RUN curl -sL https://deb.nodesource.com/setup_8.x -o nodesource_setup.sh -RUN chmod 755 nodesource_setup.sh -RUN bash nodesource_setup.sh -RUN apt-get install -y nodejs -RUN apt-get install -y protobuf-compiler libprotobuf-dev -RUN go get -u github.com/golang/protobuf/protoc-gen-go -RUN mkdir -p /go/src/github.com/singnet -WORKDIR /go/src/github.com/singnet -RUN git clone https://github.com/singnet/snet-daemon.git -WORKDIR /go/src/github.com/singnet/snet-daemon -RUN ./scripts/install -RUN ./scripts/build linux amd64 +FROM golang:alpine +RUN apk update && apk add --no-cache make protobuf-dev git bash +SHELL ["/bin/bash", "-c"] +RUN mkdir -p /snet-daemon +WORKDIR /snet-daemon +RUN git clone --single-branch --branch dev https://github.com/semyon-dev/snet-daemon.git . +RUN go install google.golang.org/protobuf/cmd/protoc-gen-go@latest +RUN go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest +RUN go generate ./... +RUN chmod +x ./scripts/build +RUN ./scripts/build linux amd64 dev diff --git a/scripts/build b/scripts/build index 0ee7f13c..6269370b 100755 --- a/scripts/build +++ b/scripts/build @@ -1,22 +1,51 @@ #!/bin/bash -set -ex +# for debug: +# set -ex -PARENT_PATH=$(dirname $(cd $(dirname $0); pwd -P)) +PARENT_PATH="$(dirname "$(cd "$("dirname" "$0")"; pwd -P)")" if [ $# -lt 3 ] then echo "arguments expected are of the form and for the build script , as an example: '/scripts/build linux amd64 v5.1.5'" exit 1 fi -pushd $PARENT_PATH +pushd "$PARENT_PATH" mkdir -p build now=$(date +'%Y-%m-%d_%T') -networkJson=$(cat resources/blockchain_network_config.json | tr -d '\t\n\r') -buildname=$1-$2-$3 -githash=`git rev-parse HEAD` +# reading blockchain config +networkJson=$( and for the build script, as an example: '/scripts/build linux amd64 v.0.1.8'" + exit 1 +} + +$GOOS = $args[0] # linux +$GOARCH = $args[1] # amd64 +$Version = $args[2] # v5.1.4 + +# change directory +Push-Location $ParentPath + +# create build directory if not exists +$BuildDirectory = Join-Path $ParentPath "build" +if (-not (Test-Path $BuildDirectory)) +{ + New-Item -ItemType Directory -Path $BuildDirectory | Out-Null +} + +# get current timestamp +$Now = Get-Date -Format "yyyy-MM-dd_HH:mm:ss" + +# reading blockchain config +$NetworkJson = Get-Content (Join-Path $ParentPath "resources\blockchain_network_config.json") -Raw + +# removing unnecessary symbols +$NetworkJson = $NetworkJson -replace ' ', '' +$NetworkJson = $NetworkJson -replace '\n', '' +$NetworkJson = $NetworkJson -replace '\r', '' +$NetworkJson = $NetworkJson -replace '\t', '' +Write-Output "Network config passed to daemon:" +Write-Output $NetworkJson + +# construct build name +$BuildName = 'snetd-{0}-{1}-{2}' -f $GOOS, $GOARCH, $Version + +# get git hash +$GitHash = git rev-parse HEAD + +# add .exe for windows +if ($GOOS -eq "windows") +{ + $BuildName += ".exe" +} + +# build with Go +$Env:CGO_ENABLED = 0; $Env:GOOS = $GOOS; $Env:GOARCH = $GOARCH; go build -ldflags " +-X google.golang.org/protobuf/reflect/protoregistry.conflictPolicy=ignore +-X github.com/singnet/snet-daemon/config.sha1Revision=$GitHash +-X github.com/singnet/snet-daemon/config.versionTag=$Version +-X github.com/singnet/snet-daemon/config.buildTime=$Now +-X 'github.com/singnet/snet-daemon/config.networkIdNameMapping=$NetworkJson'" -o (Join-Path $BuildDirectory $BuildName) snetd/main.go + +# return to previous directory +Pop-Location + +Write-Output "✅ The daemon has been successfully compiled to:"(Join-Path $BuildDirectory $BuildName) \ No newline at end of file diff --git a/scripts/build-all b/scripts/build_all_platforms old mode 100644 new mode 100755 similarity index 100% rename from scripts/build-all rename to scripts/build_all_platforms diff --git a/scripts/buildlinux b/scripts/build_in_docker old mode 100755 new mode 100644 similarity index 70% rename from scripts/buildlinux rename to scripts/build_in_docker index 3e5a7df7..ec3da4bb --- a/scripts/buildlinux +++ b/scripts/build_in_docker @@ -4,11 +4,11 @@ set -ex PARENT_PATH=$(dirname $(cd $(dirname $0); pwd -P)) -pushd $PARENT_PATH +pushd "$PARENT_PATH" mkdir -p build docker build -t snetd-linux-amd64:latest resources/linuxbuild docker run --name linux-build snetd-linux-amd64:latest -docker cp linux-build:/go/src/github.com/singnet/snet-daemon/build/snetd-linux-amd64 ./build +docker cp linux-build:/snet-daemon/build/snetd-linux-amd64-dev ./build docker rm linux-build docker rmi snetd-linux-amd64:latest popd diff --git a/scripts/install_daemon b/scripts/install_daemon new file mode 100644 index 00000000..d609ed84 --- /dev/null +++ b/scripts/install_daemon @@ -0,0 +1,12 @@ +#!/bin/bash + +set -ex + +#sometimes, the git link doesnt return a response and hence we pass in release number too +SNETD_VERSION=$(curl -s https://api.github.com/repos/singnet/snet-daemon/releases/latest | grep -oP '"tag_name": "\K(.*)(?=")' || echo "v5.1.4") + +echo 'version' "$SNETD_VERSION" + +wget https://github.com/singnet/snet-daemon/releases/download/"${SNETD_VERSION}"/snetd-linux-amd64-"${SNETD_VERSION}" +WITH_SUDO=$([ "$EUID" != 0 ] && echo "sudo" || echo "") +$WITH_SUDO mv snetd-linux-amd64-"${SNETD_VERSION}" /usr/bin/snetd diff --git a/scripts/install b/scripts/install_deps similarity index 91% rename from scripts/install rename to scripts/install_deps index 565f4c85..eb728401 100755 --- a/scripts/install +++ b/scripts/install_deps @@ -4,7 +4,7 @@ set -ex PARENT_PATH=$(dirname $(cd $(dirname $0); pwd -P)) -pushd $PARENT_PATH +pushd "$PARENT_PATH" go install google.golang.org/protobuf/cmd/protoc-gen-go@latest go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest diff --git a/scripts/install_deps.ps1 b/scripts/install_deps.ps1 new file mode 100644 index 00000000..36dbccb7 --- /dev/null +++ b/scripts/install_deps.ps1 @@ -0,0 +1,29 @@ +# Enable error handling and command tracing +$ErrorActionPreference = "Stop" +$VerbosePreference = "Continue" + +# Enable debug info in stdout +#Set-PSDebug -Trace 2 + +# Determine the parent directory of the script +$ScriptPath = $MyInvocation.MyCommand.Path +$ParentPath = Split-Path -Parent (Split-Path -Parent $ScriptPath) + +# Change to the parent directory +Push-Location -Path $ParentPath + +Write-Output "Install the required Go tools:" +Write-Output "go install protoc-gen-go@latest" +Write-Output "go install protoc-gen-go-grpc@latest" + +# Install the required Go tools +go install google.golang.org/protobuf/cmd/protoc-gen-go@latest +go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest + +Write-Output "go generate ./..." + +# Run go generate +go generate ./... + +# Return to the original directory +Pop-Location diff --git a/scripts/installdaemon b/scripts/installdaemon deleted file mode 100755 index 3fe36e66..00000000 --- a/scripts/installdaemon +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash - -set -ex -#sometimes , the git link doesnt return a response and hence we pass in release number too -SNETD_VERSION=`curl -s https://api.github.com/repos/singnet/snet-daemon/releases/latest | grep -oP '"tag_name": "\K(.*)(?=")' || echo "v3.1.0"` -echo 'version' $SNETD_VERSION -wget https://github.com/singnet/snet-daemon/releases/download/${SNETD_VERSION}/snet-daemon-${SNETD_VERSION}-linux-amd64.tar.gz -tar -xvf snet-daemon-${SNETD_VERSION}-linux-amd64.tar.gz -WITH_SUDO=$([ "$EUID" != 0 ] && echo "sudo" || echo "") -$WITH_SUDO mv snet-daemon-${SNETD_VERSION}-linux-amd64/snetd /usr/bin/snetd diff --git a/scripts/lint b/scripts/lint deleted file mode 100755 index c1b81125..00000000 --- a/scripts/lint +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/bash - -set -e - -PARENT_PATH=$(dirname $(cd $(dirname $0); pwd -P)) - -if ! command golint ; then - go get -u golang.org/x/lint/golint -fi - -pushd $PARENT_PATH -go list ./... | grep -v /vendor/ | xargs -n 1 golint -popd diff --git a/scripts/package b/scripts/package deleted file mode 100755 index 2d25fe7c..00000000 --- a/scripts/package +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/bash - -set -ex - -PARENT_PATH=$(dirname $(cd $(dirname $0); pwd -P)) - -pushd $PARENT_PATH -mkdir -p build -mkdir -p build/snetd-$1/darwin-amd64 -mkdir -p build/snetd-$1/linux-amd64 -cp build/snetd-darwin-amd64 build/snetd-$1/darwin-amd64/snetd -cp build/snetd-linux-amd64 build/snetd-$1/linux-amd64/snetd -pushd build/snetd-$1 -tar -zcvf ../snetd-$1.tar.gz ./* -popd -popd diff --git a/scripts/sonar b/scripts/sonar deleted file mode 100755 index 623c9599..00000000 --- a/scripts/sonar +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/bash - -set -ex - -PARENT_PATH=$(dirname $(cd $(dirname $0); pwd -P)) - -pushd $PARENT_PATH -sudo apt install unzip -y - -wget https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-4.6.2.2472-linux.zip -unzip sonar-scanner-cli-4.6.2.2472-linux.zip - -export SONAR_SCANNER_OPTS="-Xmx2048m" -sonar-scanner-4.6.2.2472-linux/bin/sonar-scanner -Dsonar.host.url=https://sonarqube.singularitynet.io -Dsonar.login=${SONAR_TOKEN} $SONAR_SCANNER_OPTS_CUSTOM -popd \ No newline at end of file diff --git a/scripts/test b/scripts/test index e93423bd..5a21e8d7 100755 --- a/scripts/test +++ b/scripts/test @@ -7,7 +7,7 @@ PARENT_PATH=$(dirname $(cd $(dirname $0); pwd -P)) pushd $PARENT_PATH # Run golint # NOTE: currently we are just printing lint violations, not failing the test if any errors are present -./scripts/lint +#./scripts/lint # Run integration tests # Run integration tests go get golang.org/x/tools/cmd/cover diff --git a/scripts/uninstall b/scripts/uninstall index d094e88d..69a6b97c 100755 --- a/scripts/uninstall +++ b/scripts/uninstall @@ -4,12 +4,12 @@ set -ex PARENT_PATH=$(dirname $(cd $(dirname $0); pwd -P)) -pushd $PARENT_PATH -rm -rf vendor -rm -rf $GOPATH/bin/abigen +pushd "$PARENT_PATH" +rm -rf "$GOPATH"/bin/abigen +rm -rf "$GOPATH"/bin/protoc-gen-go +rm -rf "$GOPATH"/bin/protoc-gen-go-grpc rm -rf resources/blockchain/node_modules rm -rf resources/blockchain/build -rm -rf resources/Agent.abi -rm -rf blockchain/agent.go +rm -rf blockchain/snet-contracts.go rm -rf build popd diff --git a/scripts/watcher_fsevents_cgo.go.patch b/scripts/watcher_fsevents_cgo.go.patch deleted file mode 100644 index 65580e6f..00000000 --- a/scripts/watcher_fsevents_cgo.go.patch +++ /dev/null @@ -1,22 +0,0 @@ ---- /home/joel/Downloads/watcher_fsevents_cgo.go 2019-03-20 13:14:12.643748593 +1300 -+++ watcher_fsevents_cgo.go 2019-03-20 12:49:33.489170174 +1300 -@@ -48,7 +48,7 @@ - // started and is ready via the wg. It also serves purpose of a dummy source, - // thanks to it the runloop does not return as it also has at least one source - // registered. --var source = C.CFRunLoopSourceCreate(nil, 0, &C.CFRunLoopSourceContext{ -+var source = C.CFRunLoopSourceCreate(C.kCFAllocatorDefault, 0, &C.CFRunLoopSourceContext{ - perform: (C.CFRunLoopPerformCallBack)(C.gosource), - }) - -@@ -162,8 +162,8 @@ - return nil - } - wg.Wait() -- p := C.CFStringCreateWithCStringNoCopy(nil, C.CString(s.path), C.kCFStringEncodingUTF8, nil) -- path := C.CFArrayCreate(nil, (*unsafe.Pointer)(unsafe.Pointer(&p)), 1, nil) -+ p := C.CFStringCreateWithCStringNoCopy(C.kCFAllocatorDefault, C.CString(s.path), C.kCFStringEncodingUTF8, C.kCFAllocatorDefault) -+ path := C.CFArrayCreate(C.kCFAllocatorDefault, (*unsafe.Pointer)(unsafe.Pointer(&p)), 1, nil) - ctx := C.FSEventStreamContext{} - ref := C.EventStreamCreate(&ctx, C.uintptr_t(s.info), path, C.FSEventStreamEventId(atomic.LoadUint64(&since)), latency, flags) - if ref == nilstream { diff --git a/snetd/cmd/certs_listener.go b/snetd/cmd/certs_listener.go new file mode 100644 index 00000000..5355f9c8 --- /dev/null +++ b/snetd/cmd/certs_listener.go @@ -0,0 +1,50 @@ +package cmd + +import ( + "crypto/tls" + "fmt" + "sync" + "time" + + "go.uber.org/zap" +) + +type CertReloader struct { + CertFile string // path to the x509 certificate for https + KeyFile string // path to the x509 private key matching + mutex *sync.Mutex + cachedCert *tls.Certificate +} + +func (cr *CertReloader) reloadCertificate() error { + pair, err := tls.LoadX509KeyPair(cr.CertFile, cr.KeyFile) + if err != nil { + return fmt.Errorf("failed loading tls key pair: %w", err) + } + cr.mutex.Lock() + cr.cachedCert = &pair + cr.mutex.Unlock() + return err +} + +func (cr *CertReloader) GetCertificate() *tls.Certificate { + cr.mutex.Lock() + defer cr.mutex.Unlock() + return cr.cachedCert +} + +func (cr *CertReloader) Listen() { + ticker := time.NewTicker(3 * time.Second) + + go func() { + for { + select { + case <-ticker.C: + err := cr.reloadCertificate() + if err != nil { + zap.L().Error("Error in reloading ssl certificates", zap.Error(err)) + } + } + } + }() +} diff --git a/snetd/cmd/serve.go b/snetd/cmd/serve.go index e51ddeb4..31dc1720 100644 --- a/snetd/cmd/serve.go +++ b/snetd/cmd/serve.go @@ -8,21 +8,24 @@ import ( "os" "os/signal" "strings" + "sync" "syscall" - "github.com/gorilla/handlers" - "github.com/improbable-eng/grpc-web/go/grpcweb" - "github.com/pkg/errors" - "github.com/rs/cors" "github.com/singnet/snet-daemon/blockchain" "github.com/singnet/snet-daemon/config" "github.com/singnet/snet-daemon/configuration_service" + contractListener "github.com/singnet/snet-daemon/contract_event_listener" "github.com/singnet/snet-daemon/escrow" "github.com/singnet/snet-daemon/handler" "github.com/singnet/snet-daemon/handler/httphandler" "github.com/singnet/snet-daemon/logger" "github.com/singnet/snet-daemon/metrics" "github.com/singnet/snet-daemon/training" + + "github.com/gorilla/handlers" + "github.com/improbable-eng/grpc-web/go/grpcweb" + "github.com/pkg/errors" + "github.com/rs/cors" "github.com/soheilhy/cmux" "github.com/spf13/cobra" "go.uber.org/zap" @@ -63,6 +66,18 @@ var ServeCmd = &cobra.Command{ d.start() defer d.stop() + // Check if the payment storage client is etcd by verifying if d.components.etcdClient exists. + // If etcdClient is not nil and hot reload is enabled, initialize a ContractEventListener + // to listen for changes in the organization metadata. + if d.components.etcdClient != nil && d.components.etcdClient.IsHotReloadEnabled() { + contractEventLister := contractListener.ContractEventListener{ + BlockchainProcessor: &d.blockProc, + CurrentOrganizationMetaData: components.OrganizationMetaData(), + CurrentEtcdClient: components.EtcdClient(), + } + go contractEventLister.ListenOrganizationMetadataChanging() + } + sigChan := make(chan os.Signal, 1) signal.Notify(sigChan, syscall.SIGTERM, syscall.SIGINT) <-sigChan @@ -121,7 +136,7 @@ func newDaemon(components *Components) (daemon, error) { if sslKey := config.GetString(config.SSLKeyPathKey); sslKey != "" { cert, err := tls.LoadX509KeyPair(config.GetString(config.SSLCertPathKey), sslKey) if err != nil { - return d, errors.Wrap(err, "unable to load specifiec SSL X509 keypair") + return d, errors.Wrap(err, "unable to load specific SSL X509 keypair") } d.sslCert = &cert } @@ -132,6 +147,19 @@ func newDaemon(components *Components) (daemon, error) { func (d *daemon) start() { var tlsConfig *tls.Config + var certReloader *CertReloader + + if config.GetString(config.SSLCertPathKey) != "" { + certReloader = &CertReloader{ + CertFile: config.GetString(config.SSLCertPathKey), + KeyFile: config.GetString(config.SSLKeyPathKey), + mutex: new(sync.Mutex), + } + } + + if certReloader != nil { + certReloader.Listen() + } if d.autoSSLDomain != "" { zap.L().Debug("enabling automatic SSL support") @@ -159,6 +187,9 @@ func (d *daemon) start() { } else if d.sslCert != nil { zap.L().Debug("enabling SSL support via X509 keypair") tlsConfig = &tls.Config{ + GetCertificate: func(c *tls.ClientHelloInfo) (*tls.Certificate, error) { + return certReloader.GetCertificate(), nil + }, Certificates: []tls.Certificate{*d.sslCert}, } } @@ -197,13 +228,11 @@ func (d *daemon) start() { return true })) httpHandler := http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) { - zap.L().Info("httpHandler path: ", zap.String("path", req.URL.Path)) - zap.L().Info("input request", zap.Any("request", req)) + zap.L().Info("http request: ", zap.String("path", req.URL.Path), zap.String("method", req.Method)) resp.Header().Set("Access-Control-Allow-Origin", "*") if grpcWebServer.IsGrpcWebRequest(req) || grpcWebServer.IsAcceptableGrpcCorsRequest(req) { + zap.L().Debug("GrpcWebRequest/IsAcceptableGrpcCorsRequest") grpcWebServer.ServeHTTP(resp, req) - zap.L().Info("IsGrpcWebRequest/IsAcceptableGrpcCorsRequest") - resp.Header().Set("Access-Control-Allow-Origin", "*") } else { switch strings.Split(req.URL.Path, "/")[1] { case "encoding": @@ -214,9 +243,9 @@ func (d *daemon) start() { http.NotFound(resp, req) } } - zap.L().Info("output headers:") + zap.L().Debug("output headers:") for key, values := range resp.Header() { - zap.L().Info("header", zap.String("key", key), zap.Strings("value", values)) + zap.L().Debug("header", zap.String("key", key), zap.Strings("value", values)) } }) diff --git a/snetd/cmd/serve_test.go b/snetd/cmd/serve_test.go index 55e88974..56891b59 100644 --- a/snetd/cmd/serve_test.go +++ b/snetd/cmd/serve_test.go @@ -4,7 +4,6 @@ import ( "testing" "github.com/singnet/snet-daemon/config" - _ "github.com/singnet/snet-daemon/fix-proto" "github.com/stretchr/testify/assert" ) diff --git a/snetd/cmd/version_details.go b/snetd/cmd/version_details.go index 7688fb42..3ab4b8f9 100644 --- a/snetd/cmd/version_details.go +++ b/snetd/cmd/version_details.go @@ -7,32 +7,29 @@ import ( "os" ) - -//Shows the current version of the Daemons -//Version tag: v0.1.4-181-g2fd9f04 was build on: 2019-03-19_13:52:58 with sha1 revision from github: 2fd9f04bfb279aaf66291cd6bd2ca734fd4f70b5 +// Shows the current version of the Daemons +// Version tag: v0.1.4-181-g2fd9f04 was build on: 2019-03-19_13:52:58 with sha1 revision from github: 2fd9f04bfb279aaf66291cd6bd2ca734fd4f70b5 var VersionCmd = &cobra.Command{ Use: "version", Short: "List the current version of the Daemon.", - Long: "To check the current version of the Daemon, the sha1 revision and the time the Binary was built User can use `snetd version`" , + Long: "To check the current version of the Daemon, the sha1 revision and the time the Binary was built User can use `snetd version`", RunE: func(cmd *cobra.Command, args []string) error { return RunAndCleanup(cmd, args, newListVersionCommand) }, } type ListVersionCommand struct { - } func newListVersionCommand(cmd *cobra.Command, args []string, components *Components) (command Command, err error) { - command = &ListVersionCommand { - } + command = &ListVersionCommand{} return } func (command *ListVersionCommand) Run() (err error) { - fmt.Printf("version tag: %s\n", config.GetVersionTag()) - fmt.Printf("built on: %s\n",config.GetBuildTime()) - fmt.Printf("sha1 revision: %s\n",config.GetSha1Revision()) - os.Exit(0) + fmt.Printf("version tag: %s\n", config.GetVersionTag()) + fmt.Printf("built on: %s\n", config.GetBuildTime()) + fmt.Printf("sha1 revision: %s\n", config.GetSha1Revision()) + os.Exit(0) return nil } diff --git a/snetd/main.go b/snetd/main.go index a770e19a..8183fcfb 100644 --- a/snetd/main.go +++ b/snetd/main.go @@ -1,7 +1,6 @@ package main import ( - _ "github.com/singnet/snet-daemon/fix-proto" "github.com/singnet/snet-daemon/snetd/cmd" "go.uber.org/zap" ) diff --git a/sonar-project.properties b/sonar-project.properties deleted file mode 100644 index 2c57393e..00000000 --- a/sonar-project.properties +++ /dev/null @@ -1,8 +0,0 @@ -sonar.projectKey=singnet-snet-daemon -sonar.projectName=snet-daemon -sonar.projectVersion=${GIT_TAG_NAME} -sonar.sources=. -sonar.tests=. -sonar.test.inclusions=**/*_test.go,**/testdata/** -sonar.go.exclusions=**/vendor/**,**/*_mock.go,**.pb.go,*_test.go -sonar.go.coverage.reportPaths=coverage.out diff --git a/storage/atomic_storage.go b/storage/atomic_storage.go index e72dc9dc..cc421f0d 100644 --- a/storage/atomic_storage.go +++ b/storage/atomic_storage.go @@ -217,7 +217,6 @@ func NewTypedAtomicStorageImpl(storage AtomicStorage, keySerializer func(key any keyType reflect.Type, valueSerializer func(value any) (serialized string, err error), valueDeserializer func(serialized string, value any) (err error), valueType reflect.Type) TypedAtomicStorage { - return &TypedAtomicStorageImpl{ atomicStorage: storage, keySerializer: keySerializer, @@ -226,7 +225,6 @@ func NewTypedAtomicStorageImpl(storage AtomicStorage, keySerializer func(key any valueDeserializer: valueDeserializer, valueType: valueType, } - } // Get implements TypedAtomicStorage.Get @@ -268,7 +266,7 @@ func (storage *TypedAtomicStorageImpl) GetAll() (array any, err error) { } values := reflect.MakeSlice( - reflect.SliceOf(reflect.PtrTo(storage.valueType)), + reflect.SliceOf(reflect.PointerTo(storage.valueType)), 0, len(stringValues)) for _, stringValue := range stringValues { @@ -380,7 +378,6 @@ func findKeyValueByKey(keyValueData []KeyValueData, key string) (keyValueString } func (storage *TypedAtomicStorageImpl) ExecuteTransaction(request TypedCASRequest) (ok bool, err error) { - updateFunction := func(conditionValues []KeyValueData) (update []KeyValueData, ok bool, err error) { typedValues, err := storage.convertKeyValueDataToTyped(request.ConditionKeys, conditionValues) if err != nil { diff --git a/storage/memory_storage.go b/storage/memory_storage.go index d1031b25..d937e489 100644 --- a/storage/memory_storage.go +++ b/storage/memory_storage.go @@ -108,10 +108,10 @@ func (storage *MemoryStorage) Clear() (err error) { return } -func (memStorage *MemoryStorage) StartTransaction(conditionKeys []string) (transaction Transaction, err error) { +func (storage *MemoryStorage) StartTransaction(conditionKeys []string) (transaction Transaction, err error) { conditionKeyValues := make([]KeyValueData, len(conditionKeys)) for i, key := range conditionKeys { - value, ok, err := memStorage.Get(key) + value, ok, err := storage.Get(key) if err != nil { return nil, err } else if !ok { @@ -119,7 +119,6 @@ func (memStorage *MemoryStorage) StartTransaction(conditionKeys []string) (trans } else { conditionKeyValues[i] = KeyValueData{Key: key, Value: value, Present: true} } - } transaction = &memoryStorageTransaction{ConditionKeys: conditionKeys, ConditionValues: conditionKeyValues} return transaction, nil @@ -165,9 +164,8 @@ func (storage *MemoryStorage) CompleteTransaction(transaction Transaction, updat return true, nil } -func (client *MemoryStorage) ExecuteTransaction(request CASRequest) (ok bool, err error) { - - transaction, err := client.StartTransaction(request.ConditionKeys) +func (storage *MemoryStorage) ExecuteTransaction(request CASRequest) (ok bool, err error) { + transaction, err := storage.StartTransaction(request.ConditionKeys) if err != nil { return false, err } @@ -180,7 +178,7 @@ func (client *MemoryStorage) ExecuteTransaction(request CASRequest) (ok bool, er if err != nil { return false, err } - ok, err = client.CompleteTransaction(transaction, newvalues) + ok, err = storage.CompleteTransaction(transaction, newvalues) if err != nil { return false, err } @@ -191,6 +189,7 @@ func (client *MemoryStorage) ExecuteTransaction(request CASRequest) (ok bool, er continue } } + // TODO: refactor this return true, nil } diff --git a/training/service.go b/training/service.go index aabd8296..028dbbf9 100644 --- a/training/service.go +++ b/training/service.go @@ -4,6 +4,7 @@ package training import ( "bytes" "fmt" + "google.golang.org/grpc/credentials/insecure" "math/big" "net/url" "strings" @@ -91,13 +92,13 @@ func getConnection(endpoint string) (conn *grpc.ClientConn) { zap.L().Panic("error parsing passthrough endpoint", zap.Error(err)) } if strings.Compare(passthroughURL.Scheme, "https") == 0 { - conn, err = grpc.Dial(passthroughURL.Host, + conn, err = grpc.NewClient(passthroughURL.Host, grpc.WithTransportCredentials(credentials.NewClientTLSFromCert(nil, "")), options) if err != nil { zap.L().Panic("error dialing service", zap.Error(err)) } } else { - conn, err = grpc.Dial(passthroughURL.Host, grpc.WithInsecure(), options) + conn, err = grpc.NewClient(passthroughURL.Host, grpc.WithTransportCredentials(insecure.NewCredentials()), options) if err != nil { zap.L().Panic("error dialing service", zap.Error(err)) @@ -176,6 +177,9 @@ func (service ModelService) deleteUserModelDetails(key *ModelKey, data *ModelDat if data, ok, err := service.userStorage.Get(userKey); ok && err == nil && data != nil { data.ModelIds = remove(data.ModelIds, key.ModelId) err = service.userStorage.Put(userKey, data) + if err != nil { + zap.L().Error(err.Error()) + } } } return @@ -225,7 +229,7 @@ func (service ModelService) updateModelDetails(request *UpdateModelRequest, resp key := service.getModelKeyToUpdate(request) oldAddresses := make([]string, 0) var latestAddresses []string - //by default add the creator to the Authorized list of Address + // by default add the creator to the Authorized list of Address if request.UpdateModelDetails.AddressList != nil || len(request.UpdateModelDetails.AddressList) > 0 { latestAddresses = request.UpdateModelDetails.AddressList } diff --git a/training/service_test.go b/training/service_test.go index f6572213..520e5515 100644 --- a/training/service_test.go +++ b/training/service_test.go @@ -72,8 +72,8 @@ func (suite *ModelServiceTestSuite) SetupSuite() { testJsonData := "{ \"version\": 1, \"display_name\": \"Example1\", \"encoding\": \"grpc\", \"service_type\": \"grpc\", \"payment_expiration_threshold\": 40320, \"model_ipfs_hash\": \"Qmdiq8Hu6dYiwp712GtnbBxagyfYyvUY1HYqkH7iN76UCc\", " + " \"mpe_address\": \"0x7E6366Fbe3bdfCE3C906667911FC5237Cc96BD08\", \"groups\": [ { \"free_calls\": 12, \"free_call_signer_address\": \"0x94d04332C4f5273feF69c4a52D24f42a3aF1F207\", \"endpoints\": [\"http://34.344.33.1:2379\",\"http://34.344.33.1:2389\"], \"group_id\": \"88ybRIg2wAx55mqVsA6sB4S7WxPQHNKqa4BPu/bhj+U=\",\"group_name\": \"default_group\", \"pricing\": [ { \"price_model\": \"fixed_price\", \"price_in_cogs\": 2 }, { \"package_name\": \"example_service\", \"price_model\": \"fixed_price_per_method\", \"default\":true, \"details\": [ { \"service_name\": \"Calculator\", \"method_pricing\": [ { \"method_name\": \"add\", \"price_in_cogs\": 2 }, { \"method_name\": \"sub\", \"price_in_cogs\": 1 }, { \"method_name\": \"div\", \"price_in_cogs\": 2 }, { \"method_name\": \"mul\", \"price_in_cogs\": 3 } ] }, { \"service_name\": \"Calculator2\", \"method_pricing\": [ { \"method_name\": \"add\", \"price_in_cogs\": 2 }, { \"method_name\": \"sub\", \"price_in_cogs\": 1 }, { \"method_name\": \"div\", \"price_in_cogs\": 3 }, { \"method_name\": \"mul\", \"price_in_cogs\": 2 } ] } ] }] }, { \"endpoints\": [\"http://97.344.33.1:2379\",\"http://67.344.33.1:2389\"], \"group_id\": \"99ybRIg2wAx55mqVsA6sB4S7WxPQHNKqa4BPu/bhj+U=\", \"pricing\": [ { \"package_name\": \"example_service\", \"price_model\": \"fixed_price_per_method\", \"details\": [ { \"service_name\": \"Calculator\", \"method_pricing\": [ { \"method_name\": \"add\", \"price_in_cogs\": 2 }, { \"method_name\": \"sub\", \"price_in_cogs\": 1 }, { \"method_name\": \"div\", \"price_in_cogs\": 2 }, { \"method_name\": \"mul\", \"price_in_cogs\": 3 } ] }, { \"service_name\": \"Calculator2\", \"method_pricing\": [ { \"method_name\": \"add\", \"price_in_cogs\": 2 }, { \"method_name\": \"sub\", \"price_in_cogs\": 1 }, { \"method_name\": \"div\", \"price_in_cogs\": 3 }, { \"method_name\": \"mul\", \"price_in_cogs\": 2 } ] } ] }] } ] } " - orgMetaData, _ := blockchain.InitOrganizationMetaDataFromJson(testJsonOrgGroupData) - serviceMetaData, _ := blockchain.InitServiceMetaDataFromJson(testJsonData) + orgMetaData, _ := blockchain.InitOrganizationMetaDataFromJson([]byte(testJsonOrgGroupData)) + serviceMetaData, _ := blockchain.InitServiceMetaDataFromJson([]byte(testJsonData)) suite.service = NewModelService(nil, serviceMetaData, orgMetaData, NewModelStorage(storage.NewMemStorage()), NewUerModelStorage(storage.NewMemStorage())) suite.senderPvtKy, _ = crypto.GenerateKey() diff --git a/utils/common.go b/utils/common.go index a62c6e7d..3352464a 100644 --- a/utils/common.go +++ b/utils/common.go @@ -18,7 +18,7 @@ func Serialize(value any) (slice string, err error) { return } - slice = string(b.Bytes()) + slice = b.String() return }