diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000000..3ba282ed1e --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,3 @@ +# Default reviewers for the `ai-video` branch. +# TODO: Change if merged into `master` branch. +* @rickstaa diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 4a743ad9f8..4e6c29d416 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -4,7 +4,7 @@ on: pull_request: push: branches: - - master + - ai-video tags: - "v*" @@ -29,25 +29,25 @@ jobs: container: ubuntu:20.04 type: cpu - - GOOS: linux - GOARCH: arm64 - container: ubuntu:20.04 - type: cpu + # - GOOS: linux + # GOARCH: arm64 + # container: ubuntu-20.04 + # type: cpu - GOOS: linux GOARCH: amd64 container: livepeerci/cuda:12.0.0-cudnn8-devel-ubuntu20.04 type: gpu - - GOOS: linux - GOARCH: arm64 - container: livepeerci/cuda:12.0.0-cudnn8-devel-ubuntu20.04 - type: gpu + # - GOOS: linux + # GOARCH: arm64 + # container: livepeerci/cuda:12.0.0-cudnn8-devel-ubuntu20.04 + # type: gpu - - GOOS: windows - GOARCH: amd64 - container: ubuntu:22.04 - type: cpu + # - GOOS: windows + # GOARCH: amd64 + # container: ubuntu:22.04 + # type: cpu steps: - name: Setup ubuntu container @@ -69,7 +69,7 @@ jobs: id: go uses: actions/setup-go@v5 with: - go-version: 1.20.4 + go-version: 1.23.2 cache: true cache-dependency-path: go.sum @@ -100,7 +100,8 @@ jobs: && apt update \ && apt -yqq install \ nasm clang-14 clang-tools-14 lld-14 build-essential pkg-config autoconf git python3 \ - gcc-mingw-w64 libgcc-9-dev-arm64-cross mingw-w64-tools gcc-mingw-w64-x86-64 mingw-w64-x86-64-dev + gcc-mingw-w64 libgcc-9-dev-arm64-cross mingw-w64-tools gcc-mingw-w64-x86-64 mingw-w64-x86-64-dev \ + golang-goprotobuf-dev protobuf-compiler-grpc update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-14 30 \ && update-alternatives --install /usr/bin/clang clang /usr/bin/clang-14 30 \ @@ -170,7 +171,7 @@ jobs: id: go uses: actions/setup-go@v5 with: - go-version: 1.20.4 + go-version: 1.23.2 cache: true cache-dependency-path: go.sum @@ -212,7 +213,7 @@ jobs: id: match-tag with: text: ${{ github.ref_name }} - regex: '^(master|main|v[0-9]+\.\d+\.\d+)$' + regex: '^(master|main|ai-video|v[0-9]+\.\d+\.\d+)$' - name: Codesign and notarize binaries if: steps.match-tag.outputs.match != '' && matrix.target.GOOS == 'darwin' @@ -316,6 +317,38 @@ jobs: parent: false process_gcloudignore: false + # Get the latest release tag + - name: Get latest tag + id: get-latest-tag + run: | + git fetch --tags + latest_tag=$(git tag -l "v*" | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+-ai.[0-9]+$' | sort -V | tail -n 1) + echo "latest_tag=$latest_tag" >> $GITHUB_OUTPUT + echo "Latest tag: $latest_tag" + echo "GitHub Ref: ${{ github.ref }}" + + # Update the latest release + - name: Upload release archives to Google Cloud stable folder + id: upload-archives-latest + if: ${{ github.ref == format('refs/tags/{0}', steps.get-latest-tag.outputs.latest_tag) }} + uses: google-github-actions/upload-cloud-storage@v2 + with: + path: "releases" + destination: "build.livepeer.live/${{ github.event.repository.name }}/ai-video/stable" + parent: false + process_gcloudignore: false + + # Update the latest branch manifest + - name: Upload branch manifest file to Google Cloud stable folder + id: upload-manifest-latest + if: ${{ github.ref == format('refs/tags/{0}', steps.get-latest-tag.outputs.latest_tag) }} + uses: google-github-actions/upload-cloud-storage@v2 + with: + path: ${{ steps.branch-manifest.outputs.manifest-file }} + destination: "build.livepeer.live/${{ github.event.repository.name }}/ai-video/stable" + parent: false + process_gcloudignore: false + - name: Trigger discord webhook shell: bash env: diff --git a/.github/workflows/docker.yaml b/.github/workflows/docker.yaml index d43f65a3a8..8e4ac77482 100644 --- a/.github/workflows/docker.yaml +++ b/.github/workflows/docker.yaml @@ -4,7 +4,8 @@ on: pull_request: push: branches: - - master + # - master + - ai-video tags: - "v*" @@ -89,7 +90,8 @@ jobs: build-args: | BUILD_TAGS=${{ steps.build-tag.outputs.build-tags }} context: . - platforms: linux/amd64, linux/arm64 + # platforms: linux/amd64, linux/arm64 # NOTE: Arm64 not yet supported. + platforms: linux/amd64 push: true tags: ${{ steps.meta.outputs.tags }} file: "docker/Dockerfile" @@ -126,7 +128,7 @@ jobs: id: match-tag with: text: ${{ github.ref_name }} - regex: '^(main|master|v[0-9]+\.\d+\.\d+)$' + regex: '^(main|master|ai-video|v[0-9]+\.\d+\.\d+|v[0-9]+\.\d+\.\d+-ai-video-\d+)' - name: Get build tags id: build-tag @@ -177,7 +179,8 @@ jobs: build-args: | BUILD_TAGS=${{ steps.build-tag.outputs.build-tags }} context: . - platforms: linux/amd64, linux/arm64 + # platforms: linux/amd64, linux/arm64 # NOTE: Arm64 not yet supported. + platforms: linux/amd64 push: true tags: ${{ steps.meta-builder.outputs.tags }} file: "docker/Dockerfile" diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index d11ffec9fb..b3a52b335e 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -4,6 +4,7 @@ on: pull_request: branches: - master + - ai-video push: branches: - master @@ -43,7 +44,7 @@ jobs: id: go uses: actions/setup-go@v5 with: - go-version: 1.20.4 + go-version: 1.23.2 cache: true cache-dependency-path: go.sum @@ -94,9 +95,9 @@ jobs: - name: Lint uses: golangci/golangci-lint-action@v4 with: - version: v1.52.2 + version: v1.61.0 skip-pkg-cache: true - args: '--disable-all --enable=gofmt --enable=vet --enable=golint --deadline=4m pm verification' + args: '--out-format=colored-line-number --disable-all --enable=gofmt --enable=govet --enable=revive --timeout=4m pm verification' - name: Run Revive Action by building from repository uses: docker://morphy/revive-action:v2 diff --git a/.gitignore b/.gitignore index ec5f509ad1..9d493d245f 100644 --- a/.gitignore +++ b/.gitignore @@ -3,7 +3,10 @@ *.dll *.so *.dylib + +# IDE files *.vscode +*.code-workspace # Test binary, build with `go test -c` *.test diff --git a/ai/file_worker.go b/ai/file_worker.go new file mode 100644 index 0000000000..1ce5478204 --- /dev/null +++ b/ai/file_worker.go @@ -0,0 +1,102 @@ +package ai + +import ( + "context" + "encoding/json" + "errors" + "os" + + "github.com/livepeer/ai-worker/worker" +) + +type FileWorker struct { + files map[string]string +} + +func NewFileWorker(files map[string]string) *FileWorker { + return &FileWorker{files: files} +} + +func (w *FileWorker) TextToImage(ctx context.Context, req worker.GenTextToImageJSONRequestBody) (*worker.ImageResponse, error) { + fname, ok := w.files["text-to-image"] + if !ok { + return nil, errors.New("text-to-image response file not found") + } + + data, err := os.ReadFile(fname) + if err != nil { + return nil, err + } + + var resp worker.ImageResponse + if err := json.Unmarshal(data, &resp); err != nil { + return nil, err + } + + return &resp, nil +} + +func (w *FileWorker) ImageToImage(ctx context.Context, req worker.GenImageToImageMultipartRequestBody) (*worker.ImageResponse, error) { + fname, ok := w.files["image-to-image"] + if !ok { + return nil, errors.New("image-to-image response file not found") + } + + data, err := os.ReadFile(fname) + if err != nil { + return nil, err + } + + var resp worker.ImageResponse + if err := json.Unmarshal(data, &resp); err != nil { + return nil, err + } + + return &resp, nil +} + +func (w *FileWorker) ImageToVideo(ctx context.Context, req worker.GenImageToVideoMultipartRequestBody) (*worker.VideoResponse, error) { + fname, ok := w.files["image-to-video"] + if !ok { + return nil, errors.New("image-to-video response file not found") + } + + data, err := os.ReadFile(fname) + if err != nil { + return nil, err + } + + var resp worker.VideoResponse + if err := json.Unmarshal(data, &resp); err != nil { + return nil, err + } + + return &resp, nil +} + +func (w *FileWorker) Upscale(ctx context.Context, req worker.GenUpscaleMultipartRequestBody) (*worker.ImageResponse, error) { + fname, ok := w.files["upscale"] + if !ok { + return nil, errors.New("upscale response file not found") + } + + data, err := os.ReadFile(fname) + if err != nil { + return nil, err + } + + var resp worker.ImageResponse + if err := json.Unmarshal(data, &resp); err != nil { + return nil, err + } + + return &resp, nil +} + +func (w *FileWorker) Warm(ctx context.Context, containerName, modelID string) error { + return nil +} + +func (w *FileWorker) Stop(ctx context.Context, containerName string) error { + return nil +} diff --git a/cmd/devtool/README.md b/cmd/devtool/README.md index 71e95928e6..7710a0a078 100644 --- a/cmd/devtool/README.md +++ b/cmd/devtool/README.md @@ -2,31 +2,42 @@ An on-chain workflow testing tool that supports the following: -- Automatically submitting the necessary setup transactions for each node type -- Generating a Bash script with default CLI flags to start each node type +- Automatically submitting the necessary setup transactions for each node type +- Generating a Bash script with default CLI flags to start each node type ## Prerequisites -## Step 1: Set up a private ETH network with Livepeer protocol deployed +- [Docker](https://docs.docker.com/get-docker/) +- [Go](https://golang.org/doc/install) +- [Go-livepeer](https://github.com/livepeer/go-livepeer) build from source (see [the docs](https://docs.livepeer.org/orchestrators/guides/install-go-livepeer#build-from-source)). -``` +## Setting Up an On-Chain Development Environment + +### Step 1: Set up a private ETH network with Livepeer protocol deployed + +```bash docker pull livepeer/geth-with-livepeer-protocol:confluence docker run -p 8545:8545 -p 8546:8546 --name geth-with-livepeer-protocol livepeer/geth-with-livepeer-protocol:confluence ``` - -## Step 2: Set up a broadcaster +### Step 2: Set up a broadcaster `go run cmd/devtool/devtool.go setup broadcaster` This command will submit the setup transactions for a broadcaster and generate the Bash script `run_broadcaster_.sh` which can be used to start a broadcaster node. -## Step 3: Set up a orchestrator/transcoder +### Step 3: Set up a orchestrator/transcoder `go run cmd/devtool/devtool.go setup transcoder` This command will submit the setup transactions for an orchestrator/transcoder and generate the Bash scripts: -* `run_orchestrator_with_transcoder_.sh` which can be used to start an orchestrator node that contains a transcoder (combined OT) -* `run_orchestrator_standalone_.sh` and `run_transcoder_.sh` which can be used to start separate orchestrator and transcoder nodes (split O/T) +- `run_orchestrator_with_transcoder_.sh` which can be used to start an orchestrator node that contains a transcoder (combined OT) +- `run_orchestrator_standalone_.sh` and `run_transcoder_.sh` which can be used to start separate orchestrator and transcoder nodes (split O/T) + +## Extra Resources + +### Scripts + +Some helpful scripts are provided in the `scripts` directory. diff --git a/cmd/devtool/devtool.go b/cmd/devtool/devtool.go index 1b4ed17f33..61e9774fe6 100644 --- a/cmd/devtool/devtool.go +++ b/cmd/devtool/devtool.go @@ -5,6 +5,7 @@ import ( "fmt" "io" "io/ioutil" + "math/big" "os" "path/filepath" "strconv" @@ -28,6 +29,10 @@ func main() { miningAccountFlag := flag.String("miningaccount", "", "Override geth mining account (usually not needed)") ethControllerFlag := flag.String("controller", "", "Override controller address (usually not needed)") svcHost := flag.String("svchost", "127.0.0.1", "default service host") + cliPortStr := flag.String("cliport", "", "CLI port") + mediaPortStr := flag.String("mediaport", "", "Media port") + rtmpPortStr := flag.String("rtmpport", "", "RTMP port") + bondAmount := flag.String("bond", "500", "Orchestrator bonded amount in LPT") flag.Parse() @@ -47,6 +52,34 @@ func main() { serviceHost = *svcHost cfg.ServiceURI = fmt.Sprintf("https://%s:", serviceHost) } + if *cliPortStr != "" { + cliPortTmp, err := strconv.Atoi(*cliPortStr) + if err != nil { + glog.Errorf("Invalid cli port %v", *cliPortStr) + } + cliPort = cliPortTmp + } + if *mediaPortStr != "" { + mediaPortTmp, err := strconv.Atoi(*mediaPortStr) + if err != nil { + glog.Errorf("Invalid media port %v", *mediaPortStr) + } + mediaPort = mediaPortTmp + } + if *rtmpPortStr != "" { + rtmpPortTmp, err := strconv.Atoi(*rtmpPortStr) + if err != nil { + glog.Errorf("Invalid rtmp port %v", *rtmpPortStr) + } + rtmpPort = rtmpPortTmp + } + if *bondAmount != "" { + cfg.BondAmount = new(big.Int) + _, ok := cfg.BondAmount.SetString(*bondAmount, 10) + if !ok { + glog.Exitf("Invalid bond amount %v", *bondAmount) + } + } args := flag.Args() goodToGo := false isBroadcaster := true diff --git a/cmd/devtool/devtool/devtool_utils.go b/cmd/devtool/devtool/devtool_utils.go index b58b2657dc..b8d822398e 100644 --- a/cmd/devtool/devtool/devtool_utils.go +++ b/cmd/devtool/devtool/devtool_utils.go @@ -5,6 +5,12 @@ import ( "context" "errors" "fmt" + "io/ioutil" + "math/big" + "os" + "strings" + "time" + "github.com/ethereum/go-ethereum/accounts/keystore" ethcommon "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/console" @@ -13,11 +19,6 @@ import ( "github.com/ethereum/go-ethereum/rpc" "github.com/golang/glog" "github.com/livepeer/go-livepeer/eth" - "io/ioutil" - "math/big" - "os" - "strings" - "time" ) const ( @@ -35,6 +36,7 @@ type DevtoolConfig struct { Account string KeystoreDir string IsBroadcaster bool + BondAmount *big.Int } func NewDevtoolConfig() DevtoolConfig { @@ -300,7 +302,7 @@ func (d *Devtool) RegisterOrchestrator(cfg DevtoolConfig) error { // curl -d "blockRewardCut=10&feeShare=5&amount=500" --data-urlencode "serviceURI=https://$transcoderServiceAddr" \ // -H "Content-Type: application/x-www-form-urlencoded" \ // -X "POST" http://localhost:$transcoderCliPort/activateTranscoder\ - var amount *big.Int = big.NewInt(int64(500)) + var amount = cfg.BondAmount glog.Infof("Bonding %v to %s", amount, cfg.Account) tx, err := d.Client.Bond(amount, ethcommon.HexToAddress(cfg.Account)) diff --git a/cmd/devtool/scripts/create_multiple_transcoders.bash b/cmd/devtool/scripts/create_multiple_transcoders.bash new file mode 100644 index 0000000000..6330241581 --- /dev/null +++ b/cmd/devtool/scripts/create_multiple_transcoders.bash @@ -0,0 +1,26 @@ +# Script to create multiple transcoders on the ETH devnet. + +CLI_PORT=7935 +MEDIA_PORT=8935 +RTMP_PORT=1935 +BOND=50 + +if [ -z "$1" ]; then + echo "Usage: create_multiple_transcoders.bash " + exit 1 +fi + +num_transcoders=$1 + +# Run the go devtool transcoder script multiple times with different ports +echo "Creating $num_transcoders transcoders..." +for i in $(seq 1 $num_transcoders); do + echo "Creating transcoder $i..." + go run cmd/devtool/devtool.go --cliport $CLI_PORT --mediaport $MEDIA_PORT --rtmpport $RTMP_PORT -bond $BOND setup transcoder + CLI_PORT=$((CLI_PORT+10)) + MEDIA_PORT=$((MEDIA_PORT+10)) + RTMP_PORT=$((RTMP_PORT+10)) + BOND=$((BOND**10)) +done + +echo "Done creating $num_transcoders transcoders" diff --git a/cmd/livepeer/livepeer.go b/cmd/livepeer/livepeer.go index 446bbe5f20..49506cb946 100755 --- a/cmd/livepeer/livepeer.go +++ b/cmd/livepeer/livepeer.go @@ -104,7 +104,7 @@ func main() { case sig := <-c: glog.Infof("Exiting Livepeer: %v", sig) cancel() - time.Sleep(time.Millisecond * 500) //Give time for other processes to shut down completely + time.Sleep(time.Second * 2) //Give time for other processes to shut down completely case <-lc: } } @@ -135,6 +135,7 @@ func parseLivepeerConfig() starter.LivepeerConfig { cfg.OrchPerfStatsURL = flag.String("orchPerfStatsUrl", *cfg.OrchPerfStatsURL, "URL of Orchestrator Performance Stream Tester") cfg.Region = flag.String("region", *cfg.Region, "Region in which a broadcaster is deployed; used to select the region while using the orchestrator's performance stats") cfg.MaxPricePerUnit = flag.String("maxPricePerUnit", *cfg.MaxPricePerUnit, "The maximum transcoding price per 'pixelsPerUnit' a broadcaster is willing to accept. If not set explicitly, broadcaster is willing to accept ANY price. Can be specified in wei or a custom currency in the format (e.g. 0.50USD). When using a custom currency, a corresponding price feed must be configured with -priceFeedAddr") + cfg.MaxPricePerCapability = flag.String("maxPricePerCapability", *cfg.MaxPricePerCapability, `json list of prices per capability/model or path to json config file. Use "model_id": "default" to price all models in a pipeline the same. Example: {"capabilities_prices": [{"pipeline": "text-to-image", "model_id": "stabilityai/sd-turbo", "price_per_unit": 1000, "pixels_per_unit": 1}, {"pipeline": "upscale", "model_id": "default", price_per_unit": 1200, "pixels_per_unit": 1}]}`) cfg.IgnoreMaxPriceIfNeeded = flag.Bool("ignoreMaxPriceIfNeeded", *cfg.IgnoreMaxPriceIfNeeded, "Set to true to allow exceeding max price condition if there is no O that meets this requirement") cfg.MinPerfScore = flag.Float64("minPerfScore", *cfg.MinPerfScore, "The minimum orchestrator's performance score a broadcaster is willing to accept") cfg.DiscoveryTimeout = flag.Duration("discoveryTimeout", *cfg.DiscoveryTimeout, "Time to wait for orchestrators to return info to be included in transcoding sessions for manifest (default = 500ms)") @@ -154,6 +155,13 @@ func parseLivepeerConfig() starter.LivepeerConfig { cfg.TestTranscoder = flag.Bool("testTranscoder", *cfg.TestTranscoder, "Test Nvidia GPU transcoding at startup") cfg.HevcDecoding = flag.Bool("hevcDecoding", *cfg.HevcDecoding, "Enable or disable HEVC decoding") + // AI: + cfg.AIServiceRegistry = flag.Bool("aiServiceRegistry", *cfg.AIServiceRegistry, "Set to true to use an AI ServiceRegistry contract address") + cfg.AIWorker = flag.Bool("aiWorker", *cfg.AIWorker, "Set to true to run an AI worker") + cfg.AIModels = flag.String("aiModels", *cfg.AIModels, "Set models (pipeline:model_id) for AI worker to load upon initialization") + cfg.AIModelsDir = flag.String("aiModelsDir", *cfg.AIModelsDir, "Set directory where AI model weights are stored") + cfg.AIRunnerImage = flag.String("aiRunnerImage", *cfg.AIRunnerImage, "Set the docker image for the AI runner: Example - livepeer/ai-runner:0.0.1") + // Onchain: cfg.EthAcctAddr = flag.String("ethAcctAddr", *cfg.EthAcctAddr, "Existing Eth account address. For use when multiple ETH accounts exist in the keystore directory") cfg.EthPassword = flag.String("ethPassword", *cfg.EthPassword, "Password for existing Eth account address or path to file") diff --git a/cmd/livepeer/starter/starter.go b/cmd/livepeer/starter/starter.go index 92ba9079bb..72fd638de4 100755 --- a/cmd/livepeer/starter/starter.go +++ b/cmd/livepeer/starter/starter.go @@ -14,6 +14,7 @@ import ( "net/url" "os" "os/user" + "path" "path/filepath" "regexp" "strconv" @@ -26,6 +27,7 @@ import ( "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rpc" "github.com/golang/glog" + "github.com/livepeer/ai-worker/worker" "github.com/livepeer/go-livepeer/build" "github.com/livepeer/go-livepeer/common" "github.com/livepeer/go-livepeer/core" @@ -33,7 +35,6 @@ import ( "github.com/livepeer/go-livepeer/eth" "github.com/livepeer/go-livepeer/eth/blockwatch" "github.com/livepeer/go-livepeer/eth/watchers" - "github.com/livepeer/go-livepeer/monitor" lpmon "github.com/livepeer/go-livepeer/monitor" "github.com/livepeer/go-livepeer/pm" "github.com/livepeer/go-livepeer/server" @@ -60,6 +61,8 @@ var ( cleanupInterval = 10 * time.Minute // The time to live for cached max float values for PM senders (else they will be cleaned up) in seconds smTTL = 172800 // 2 days + + aiWorkerContainerStopTimeout = 5 * time.Second ) const ( @@ -69,6 +72,7 @@ const ( OrchestratorRpcPort = "8935" OrchestratorCliPort = "7935" TranscoderCliPort = "6935" + AIWorkerCliPort = "4935" RefreshPerfScoreInterval = 10 * time.Minute ) @@ -87,10 +91,13 @@ type LivepeerConfig struct { HttpIngest *bool Orchestrator *bool Transcoder *bool + AIServiceRegistry *bool + AIWorker *bool Gateway *bool Broadcaster *bool OrchSecret *string TranscodingOptions *string + AIModels *string MaxAttempts *int SelectRandWeight *float64 SelectStakeWeight *float64 @@ -99,6 +106,7 @@ type LivepeerConfig struct { OrchPerfStatsURL *string Region *string MaxPricePerUnit *string + MaxPricePerCapability *string IgnoreMaxPriceIfNeeded *bool MinPerfScore *float64 DiscoveryTimeout *time.Duration @@ -142,6 +150,7 @@ type LivepeerConfig struct { MetadataAmqpExchange *string MetadataPublishTimeout *time.Duration Datadir *string + AIModelsDir *string Objectstore *string Recordstore *string FVfailGsBucket *string @@ -151,6 +160,7 @@ type LivepeerConfig struct { OrchBlacklist *string OrchMinLivepeerVersion *string TestOrchAvail *bool + AIRunnerImage *string } // DefaultLivepeerConfig creates LivepeerConfig exactly the same as when no flags are passed to the livepeer process. @@ -188,6 +198,13 @@ func DefaultLivepeerConfig() LivepeerConfig { defaultHevcDecoding := false defaultTestTranscoder := true + // AI: + defaultAIServiceRegistry := false + defaultAIWorker := false + defaultAIModels := "" + defaultAIModelsDir := "" + defaultAIRunnerImage := "livepeer/ai-runner:latest" + // Onchain: defaultEthAcctAddr := "" defaultEthPassword := "" @@ -207,6 +224,7 @@ func DefaultLivepeerConfig() LivepeerConfig { defaultMaxTotalEV := "20000000000000" defaultDepositMultiplier := 1 defaultMaxPricePerUnit := "0" + defaultMaxPricePerCapability := "" defaultIgnoreMaxPriceIfNeeded := false defaultPixelsPerUnit := "1" defaultPriceFeedAddr := "0x639Fe6ab55C921f74e7fac1ee960C0B6293ba612" // ETH / USD price feed address on Arbitrum Mainnet @@ -280,6 +298,13 @@ func DefaultLivepeerConfig() LivepeerConfig { HevcDecoding: &defaultHevcDecoding, TestTranscoder: &defaultTestTranscoder, + // AI: + AIServiceRegistry: &defaultAIServiceRegistry, + AIWorker: &defaultAIWorker, + AIModels: &defaultAIModels, + AIModelsDir: &defaultAIModelsDir, + AIRunnerImage: &defaultAIRunnerImage, + // Onchain: EthAcctAddr: &defaultEthAcctAddr, EthPassword: &defaultEthPassword, @@ -299,6 +324,7 @@ func DefaultLivepeerConfig() LivepeerConfig { MaxTotalEV: &defaultMaxTotalEV, DepositMultiplier: &defaultDepositMultiplier, MaxPricePerUnit: &defaultMaxPricePerUnit, + MaxPricePerCapability: &defaultMaxPricePerCapability, IgnoreMaxPriceIfNeeded: &defaultIgnoreMaxPriceIfNeeded, PixelsPerUnit: &defaultPixelsPerUnit, PriceFeedAddr: &defaultPriceFeedAddr, @@ -331,8 +357,10 @@ func DefaultLivepeerConfig() LivepeerConfig { FVfailGsKey: &defaultFVfailGsKey, // API - AuthWebhookURL: &defaultAuthWebhookURL, - OrchWebhookURL: &defaultOrchWebhookURL, + AuthWebhookURL: &defaultAuthWebhookURL, + OrchWebhookURL: &defaultOrchWebhookURL, + + // Versioning constraints OrchMinLivepeerVersion: &defaultMinLivepeerVersion, // Flags @@ -532,15 +560,20 @@ func StartLivepeer(ctx context.Context, cfg LivepeerConfig) { n.TranscoderManager = core.NewRemoteTranscoderManager() n.Transcoder = n.TranscoderManager } + if !*cfg.AIWorker { + n.AIWorkerManager = core.NewRemoteAIWorkerManager() + } } else if *cfg.Transcoder { n.NodeType = core.TranscoderNode + } else if *cfg.AIWorker { + n.NodeType = core.AIWorkerNode } else if *cfg.Broadcaster { n.NodeType = core.BroadcasterNode glog.Warning("-broadcaster flag is deprecated and will be removed in a future release. Please use -gateway instead") } else if *cfg.Gateway { n.NodeType = core.BroadcasterNode } else if (cfg.Reward == nil || !*cfg.Reward) && !*cfg.InitializeRound { - exit("No services enabled; must be at least one of -gateway, -transcoder, -orchestrator, -redeemer, -reward or -initializeRound") + exit("No services enabled; must be at least one of -gateway, -transcoder, -aiWorker, -orchestrator, -redeemer, -reward or -initializeRound") } lpmon.NodeID = *cfg.EthAcctAddr @@ -567,6 +600,8 @@ func StartLivepeer(ctx context.Context, cfg LivepeerConfig) { nodeType = lpmon.Transcoder case core.RedeemerNode: nodeType = lpmon.Redeemer + case core.AIWorkerNode: + nodeType = lpmon.AIWorker } lpmon.InitCensus(nodeType, core.LivepeerVersion) } @@ -581,7 +616,6 @@ func StartLivepeer(ctx context.Context, cfg LivepeerConfig) { glog.Error(err) return } - } else { n.SelectionAlgorithm, err = createSelectionAlgorithm(cfg) if err != nil { @@ -674,6 +708,11 @@ func StartLivepeer(ctx context.Context, cfg LivepeerConfig) { CheckTxTimeout: time.Duration(int64(*cfg.TxTimeout) * int64(*cfg.MaxTxReplacements+1)), } + if *cfg.AIServiceRegistry { + // For the time-being Livepeer AI Subnet uses its own ServiceRegistry, so we define it here + ethCfg.ServiceRegistryAddr = ethcommon.HexToAddress("0x04C0b249740175999E5BF5c9ac1dA92431EF34C5") + } + client, err := eth.NewClient(ethCfg) if err != nil { glog.Errorf("Failed to create Livepeer Ethereum client: %v", err) @@ -797,24 +836,29 @@ func StartLivepeer(ctx context.Context, cfg LivepeerConfig) { // Can't divide by 0 panic(fmt.Errorf("-pixelsPerUnit must be > 0, provided %v", *cfg.PixelsPerUnit)) } - if cfg.PricePerUnit == nil { - // Prevent orchestrators from unknowingly providing free transcoding + if cfg.PricePerUnit == nil && !*cfg.AIWorker { + // Prevent orchestrators from unknowingly doing free work. panic(fmt.Errorf("-pricePerUnit must be set")) + } else if cfg.PricePerUnit != nil { + pricePerUnit, currency, err := parsePricePerUnit(*cfg.PricePerUnit) + if err != nil { + panic(fmt.Errorf("-pricePerUnit must be a valid integer with an optional currency, provided %v", *cfg.PricePerUnit)) + } else if pricePerUnit.Sign() < 0 { + panic(fmt.Errorf("-pricePerUnit must be >= 0, provided %s", pricePerUnit)) + } + pricePerPixel := new(big.Rat).Quo(pricePerUnit, pixelsPerUnit) + autoPrice, err := core.NewAutoConvertedPrice(currency, pricePerPixel, func(price *big.Rat) { + unit := "pixel" + if *cfg.AIWorker { + unit = "compute unit" + } + glog.Infof("Price: %v wei per %s\n", price.FloatString(3), unit) + }) + if err != nil { + panic(fmt.Errorf("Error converting price: %v", err)) + } + n.SetBasePrice("default", autoPrice) } - pricePerUnit, currency, err := parsePricePerUnit(*cfg.PricePerUnit) - if err != nil { - panic(fmt.Errorf("-pricePerUnit must be a valid integer with an optional currency, provided %v", *cfg.PricePerUnit)) - } else if pricePerUnit.Sign() < 0 { - panic(fmt.Errorf("-pricePerUnit must be >= 0, provided %s", pricePerUnit)) - } - pricePerPixel := new(big.Rat).Quo(pricePerUnit, pixelsPerUnit) - autoPrice, err := core.NewAutoConvertedPrice(currency, pricePerPixel, func(price *big.Rat) { - glog.Infof("Price: %v wei per pixel\n ", price.FloatString(3)) - }) - if err != nil { - panic(fmt.Errorf("Error converting price: %v", err)) - } - n.SetBasePrice("default", autoPrice) if *cfg.PricePerBroadcaster != "" { glog.Warning("-PricePerBroadcaster flag is deprecated and will be removed in a future release. Please use -PricePerGateway instead") @@ -894,7 +938,6 @@ func StartLivepeer(ctx context.Context, cfg LivepeerConfig) { mfv, _ := new(big.Int).SetString(*cfg.MaxFaceValue, 10) if mfv == nil { panic(fmt.Errorf("-maxFaceValue must be a valid integer, but %v provided. Restart the node with a different valid value for -maxFaceValue", *cfg.MaxFaceValue)) - return } else { n.SetMaxFaceValue(mfv) } @@ -940,11 +983,12 @@ func StartLivepeer(ctx context.Context, cfg LivepeerConfig) { if err != nil { panic(fmt.Errorf("The maximum price per unit must be a valid integer with an optional currency, provided %v instead\n", *cfg.MaxPricePerUnit)) } + if maxPricePerUnit.Sign() > 0 { pricePerPixel := new(big.Rat).Quo(maxPricePerUnit, pixelsPerUnit) autoPrice, err := core.NewAutoConvertedPrice(currency, pricePerPixel, func(price *big.Rat) { - if monitor.Enabled { - monitor.MaxTranscodingPrice(price) + if lpmon.Enabled { + lpmon.MaxTranscodingPrice(price) } glog.Infof("Maximum transcoding price: %v wei per pixel\n ", price.FloatString(3)) }) @@ -956,6 +1000,48 @@ func StartLivepeer(ctx context.Context, cfg LivepeerConfig) { glog.Infof("Maximum transcoding price per pixel is not greater than 0: %v, broadcaster is currently set to accept ANY price.\n", *cfg.MaxPricePerUnit) glog.Infoln("To update the broadcaster's maximum acceptable transcoding price per pixel, use the CLI or restart the broadcaster with the appropriate 'maxPricePerUnit' and 'pixelsPerUnit' values") } + + if *cfg.MaxPricePerCapability != "" { + maxCapabilityPrices := getCapabilityPrices(*cfg.MaxPricePerCapability) + for _, p := range maxCapabilityPrices { + if p.PixelsPerUnit == nil { + p.PixelsPerUnit = pixelsPerUnit + } else if p.PixelsPerUnit.Sign() <= 0 { + glog.Infof("Pixels per unit for capability=%v model_id=%v in 'maxPricePerCapability' config is not greater than 0, using default pixelsPerUnit=%v.\n", p.Pipeline, p.ModelID, *cfg.PixelsPerUnit) + p.PixelsPerUnit = pixelsPerUnit + } + + if p.PricePerUnit == nil || p.PricePerUnit.Sign() <= 0 { + if maxPricePerUnit.Sign() > 0 { + glog.Infof("Maximum price per unit not set for capability=%v model_id=%v in 'maxPricePerCapability' config, using maxPricePerUnit=%v.\n", p.Pipeline, p.ModelID, *cfg.MaxPricePerUnit) + p.PricePerUnit = maxPricePerUnit + } else { + glog.Warningf("Maximum price per unit for capability=%v model_id=%v in 'maxPricePerCapability' config is not greater than 0, and 'maxPricePerUnit' not set, gateway is currently set to accept ANY price.\n", p.Pipeline, p.ModelID) + continue + } + } + + maxCapabilityPrice := new(big.Rat).Quo(p.PricePerUnit, p.PixelsPerUnit) + + cap, err := core.PipelineToCapability(p.Pipeline) + if err != nil { + panic(fmt.Errorf("Pipeline in 'maxPricePerCapability' config is not valid capability: %v\n", p.Pipeline)) + } + capName := core.CapabilityNameLookup[cap] + modelID := p.ModelID + autoCapPrice, err := core.NewAutoConvertedPrice(p.Currency, maxCapabilityPrice, func(price *big.Rat) { + if lpmon.Enabled { + lpmon.MaxPriceForCapability(lpmon.ToPipeline(capName), modelID, price) + } + glog.Infof("Maximum price per unit set to %v wei for capability=%v model_id=%v", price.FloatString(3), p.Pipeline, p.ModelID) + }) + if err != nil { + panic(fmt.Errorf("Error converting price: %v", err)) + } + + server.BroadcastCfg.SetCapabilityMaxPrice(cap, p.ModelID, autoCapPrice) + } + } } if n.NodeType == core.RedeemerNode { @@ -1064,6 +1150,178 @@ func StartLivepeer(ctx context.Context, cfg LivepeerConfig) { }() } + var aiCaps []core.Capability + capabilityConstraints := make(core.PerCapabilityConstraints) + + if *cfg.AIWorker { + gpus := []string{} + if *cfg.Nvidia != "" { + var err error + gpus, err = common.ParseAccelDevices(*cfg.Nvidia, ffmpeg.Nvidia) + if err != nil { + glog.Errorf("Error parsing -nvidia for devices: %v", err) + return + } + } + + modelsDir := *cfg.AIModelsDir + if modelsDir == "" { + var err error + modelsDir, err = filepath.Abs(path.Join(*cfg.Datadir, "models")) + if err != nil { + glog.Error("Error creating absolute path for models dir: %v", modelsDir) + return + } + } + + if err := os.MkdirAll(modelsDir, 0755); err != nil { + glog.Error("Error creating models dir %v", modelsDir) + return + } + + n.AIWorker, err = worker.NewWorker(*cfg.AIRunnerImage, gpus, modelsDir) + if err != nil { + glog.Errorf("Error starting AI worker: %v", err) + return + } + + defer func() { + ctx, cancel := context.WithTimeout(context.Background(), aiWorkerContainerStopTimeout) + defer cancel() + if err := n.AIWorker.Stop(ctx); err != nil { + glog.Errorf("Error stopping AI worker containers: %v", err) + return + } + + glog.Infof("Stopped AI worker containers") + }() + } + + if *cfg.AIModels != "" { + configs, err := core.ParseAIModelConfigs(*cfg.AIModels) + if err != nil { + glog.Errorf("Error parsing -aiModels: %v", err) + return + } + + for _, config := range configs { + pipelineCap, err := core.PipelineToCapability(config.Pipeline) + if err != nil { + panic(fmt.Errorf("Pipeline is not valid capability: %v\n", config.Pipeline)) + } + if *cfg.AIWorker { + modelConstraint := &core.ModelConstraint{Warm: config.Warm, Capacity: 1} + // External containers do auto-scale; default to 1 or use provided capacity. + if config.URL != "" && config.Capacity != 0 { + modelConstraint.Capacity = config.Capacity + } + + if config.Warm || config.URL != "" { + // Register external container endpoint if URL is provided. + endpoint := worker.RunnerEndpoint{URL: config.URL, Token: config.Token} + + // Warm the AI worker container or register the endpoint. + if err := n.AIWorker.Warm(ctx, config.Pipeline, config.ModelID, endpoint, config.OptimizationFlags); err != nil { + glog.Errorf("Error AI worker warming %v container: %v", config.Pipeline, err) + return + } + } + + // Show warning if people set OptimizationFlags but not Warm. + if len(config.OptimizationFlags) > 0 && !config.Warm { + glog.Warningf("Model %v has 'optimization_flags' set without 'warm'. Optimization flags are currently only used for warm containers.", config.ModelID) + } + + // Add capability and model constraints. + if _, hasCap := capabilityConstraints[pipelineCap]; !hasCap { + aiCaps = append(aiCaps, pipelineCap) + capabilityConstraints[pipelineCap] = &core.CapabilityConstraints{ + Models: make(map[string]*core.ModelConstraint), + } + } + + model, exists := capabilityConstraints[pipelineCap].Models[config.ModelID] + if !exists { + capabilityConstraints[pipelineCap].Models[config.ModelID] = modelConstraint + } else if model.Warm == config.Warm { + model.Capacity += modelConstraint.Capacity + } else { + panic(fmt.Errorf("Cannot have same model_id (%v) as cold and warm in same AI worker, please fix aiModels json config", config.ModelID)) + } + + glog.V(6).Infof("Capability %s (ID: %v) advertised with model constraint %s", config.Pipeline, pipelineCap, config.ModelID) + } + + // Orch and combined Orch/AIWorker set the price. Remote AIWorker is always + // offchain and does not set the price. + if *cfg.Network != "offchain" { + if config.Gateway == "" { + config.Gateway = "default" + } + + // Get base pixels and price per unit. + pixelsPerUnitBase, ok := new(big.Rat).SetString(*cfg.PixelsPerUnit) + if !ok || !pixelsPerUnitBase.IsInt() { + panic(fmt.Errorf("-pixelsPerUnit must be a valid integer, provided %v", *cfg.PixelsPerUnit)) + } + if !ok || pixelsPerUnitBase.Sign() <= 0 { + // Can't divide by 0 + panic(fmt.Errorf("-pixelsPerUnit must be > 0, provided %v", *cfg.PixelsPerUnit)) + } + pricePerUnitBase := new(big.Rat) + currencyBase := "" + if cfg.PricePerUnit != nil { + pricePerUnit, currency, err := parsePricePerUnit(*cfg.PricePerUnit) + if err != nil || pricePerUnit.Sign() < 0 { + panic(fmt.Errorf("-pricePerUnit must be a valid positive integer with an optional currency, provided %v", *cfg.PricePerUnit)) + } + pricePerUnitBase = pricePerUnit + currencyBase = currency + } + + // Set price for capability. + var autoPrice *core.AutoConvertedPrice + pixelsPerUnit := config.PixelsPerUnit.Rat + if config.PixelsPerUnit.Rat == nil { + pixelsPerUnit = pixelsPerUnitBase + } else if !pixelsPerUnit.IsInt() || pixelsPerUnit.Sign() <= 0 { + panic(fmt.Errorf("'pixelsPerUnit' value specified for model '%v' in pipeline '%v' must be a valid positive integer, provided %v", config.ModelID, config.Pipeline, config.PixelsPerUnit)) + } + + pricePerUnit := config.PricePerUnit.Rat + currency := config.Currency + if pricePerUnit == nil { + if pricePerUnitBase.Sign() == 0 { + panic(fmt.Errorf("'pricePerUnit' must be set for model '%v' in pipeline '%v'", config.ModelID, config.Pipeline)) + } + pricePerUnit = pricePerUnitBase + currency = currencyBase + glog.Warningf("No 'pricePerUnit' specified for model '%v' in pipeline '%v'. Using default value from `-pricePerUnit`: %v", config.ModelID, config.Pipeline, *cfg.PricePerUnit) + } else if !pricePerUnit.IsInt() || pricePerUnit.Sign() <= 0 { + panic(fmt.Errorf("'pricePerUnit' value specified for model '%v' in pipeline '%v' must be a valid positive integer, provided %v", config.ModelID, config.Pipeline, config.PricePerUnit)) + } + + pricePerPixel := new(big.Rat).Quo(pricePerUnit, pixelsPerUnit) + + pipeline := config.Pipeline + modelID := config.ModelID + autoPrice, err = core.NewAutoConvertedPrice(currency, pricePerPixel, func(price *big.Rat) { + glog.V(6).Infof("Capability %s (ID: %v) with model constraint %s price set to %s wei per compute unit", pipeline, pipelineCap, modelID, price.FloatString(3)) + }) + if err != nil { + panic(fmt.Errorf("error converting price: %v", err)) + } + + n.SetBasePriceForCap(config.Gateway, pipelineCap, config.ModelID, autoPrice) + } + } + } else { + if n.NodeType == core.AIWorkerNode { + glog.Error("The '-aiWorker' flag was set, but no model configuration was provided. Please specify the model configuration using the '-aiModels' flag.") + return + } + } + if *cfg.Objectstore != "" { prepared, err := drivers.PrepareOSURL(*cfg.Objectstore) if err != nil { @@ -1212,17 +1470,34 @@ func StartLivepeer(ctx context.Context, cfg LivepeerConfig) { // if http addr is not provided, listen to all ifaces // take the port to listen to from the service URI *cfg.HttpAddr = defaultAddr(*cfg.HttpAddr, "", n.GetServiceURI().Port()) - if !*cfg.Transcoder && n.OrchSecret == "" { - glog.Exit("Running an orchestrator requires an -orchSecret for standalone mode or -transcoder for orchestrator+transcoder mode") + if !*cfg.Transcoder && !*cfg.AIWorker { + if n.OrchSecret == "" { + if *cfg.AIModels != "" { + glog.Info("Running an orchestrator in AI External Container mode") + } else { + glog.Exit("Running an orchestrator requires an -orchSecret for standalone mode or -transcoder for orchestrator+transcoder mode") + } + } } } else if n.NodeType == core.TranscoderNode { *cfg.CliAddr = defaultAddr(*cfg.CliAddr, "127.0.0.1", TranscoderCliPort) + } else if n.NodeType == core.AIWorkerNode { + *cfg.CliAddr = defaultAddr(*cfg.CliAddr, "127.0.0.1", AIWorkerCliPort) + // Need to have default Capabilities if not running transcoder. + if !*cfg.Transcoder { + aiCaps = append(aiCaps, core.DefaultCapabilities()...) + } } - n.Capabilities = core.NewCapabilities(transcoderCaps, core.MandatoryOCapabilities()) + n.Capabilities = core.NewCapabilities(append(transcoderCaps, aiCaps...), nil) + n.Capabilities.SetPerCapabilityConstraints(capabilityConstraints) if cfg.OrchMinLivepeerVersion != nil { n.Capabilities.SetMinVersionConstraint(*cfg.OrchMinLivepeerVersion) } + if n.AIWorkerManager != nil { + // Set min version constraint to prevent incompatible workers. + n.Capabilities.SetMinVersionConstraint(core.LivepeerVersion) + } if drivers.NodeStorage == nil { // base URI will be empty for broadcasters; that's OK @@ -1286,7 +1561,7 @@ func StartLivepeer(ctx context.Context, cfg LivepeerConfig) { orch := core.NewOrchestrator(s.LivepeerNode, timeWatcher) go func() { - err = server.StartTranscodeServer(orch, *cfg.HttpAddr, s.HTTPMux, n.WorkDir, n.TranscoderManager != nil, n) + err = server.StartTranscodeServer(orch, *cfg.HttpAddr, s.HTTPMux, n.WorkDir, n.TranscoderManager != nil, n.AIWorkerManager != nil, n) if err != nil { exit("Error starting Transcoder node: err=%q", err) } @@ -1306,7 +1581,7 @@ func StartLivepeer(ctx context.Context, cfg LivepeerConfig) { }() - if n.NodeType == core.TranscoderNode { + if n.NodeType == core.TranscoderNode || n.NodeType == core.AIWorkerNode { if n.OrchSecret == "" { glog.Exit("Missing -orchSecret") } @@ -1314,7 +1589,13 @@ func StartLivepeer(ctx context.Context, cfg LivepeerConfig) { glog.Exit("Missing -orchAddr") } - go server.RunTranscoder(n, orchURLs[0].Host, core.MaxSessions, transcoderCaps) + if n.NodeType == core.TranscoderNode { + go server.RunTranscoder(n, orchURLs[0].Host, core.MaxSessions, transcoderCaps) + } + + if n.NodeType == core.AIWorkerNode { + go server.RunAIWorker(n, orchURLs[0].Host, n.Capabilities.ToNetCapabilities()) + } } switch n.NodeType { @@ -1325,6 +1606,8 @@ func StartLivepeer(ctx context.Context, cfg LivepeerConfig) { glog.Infof("Video Ingest Endpoint - rtmp://%v", *cfg.RtmpAddr) case core.TranscoderNode: glog.Infof("**Liveepeer Running in Transcoder Mode***") + case core.AIWorkerNode: + glog.Infof("**Livepeer Running in AI Worker Mode**") case core.RedeemerNode: glog.Infof("**Livepeer Running in Redeemer Mode**") } @@ -1540,21 +1823,21 @@ func getGatewayPrices(gatewayPrices string) []GatewayPrice { // {"gateways":[{"ethaddress":"address1","priceperunit":0.5,"currency":"USD","pixelsperunit":1}, {"ethaddress":"address2","priceperunit":0.3,"currency":"USD","pixelsperunit":3}]} var pricesSet struct { Gateways []struct { - EthAddress string `json:"ethaddress"` - PixelsPerUnit json.RawMessage `json:"pixelsperunit"` - PricePerUnit json.RawMessage `json:"priceperunit"` - Currency string `json:"currency"` + EthAddress string `json:"ethaddress"` + PixelsPerUnit core.JSONRat `json:"pixelsperunit"` + PricePerUnit core.JSONRat `json:"priceperunit"` + Currency string `json:"currency"` } `json:"gateways"` // TODO: Keep the old name for backwards compatibility, remove in the future Broadcasters []struct { - EthAddress string `json:"ethaddress"` - PixelsPerUnit json.RawMessage `json:"pixelsperunit"` - PricePerUnit json.RawMessage `json:"priceperunit"` - Currency string `json:"currency"` + EthAddress string `json:"ethaddress"` + PixelsPerUnit core.JSONRat `json:"pixelsperunit"` + PricePerUnit core.JSONRat `json:"priceperunit"` + Currency string `json:"currency"` } `json:"broadcasters"` } - pricesFileContent, _ := common.ReadFromFile(gatewayPrices) + pricesFileContent, _ := common.ReadFromFile(gatewayPrices) err := json.Unmarshal([]byte(pricesFileContent), &pricesSet) if err != nil { glog.Errorf("gateway prices could not be parsed: %s", err) @@ -1571,21 +1854,62 @@ func getGatewayPrices(gatewayPrices string) []GatewayPrice { prices := make([]GatewayPrice, len(allGateways)) for i, p := range allGateways { - pixelsPerUnit, ok := new(big.Rat).SetString(string(p.PixelsPerUnit)) - if !ok { - glog.Errorf("Pixels per unit could not be parsed for gateway %v. must be a valid number, provided %s", p.EthAddress, p.PixelsPerUnit) - continue - } - pricePerUnit, ok := new(big.Rat).SetString(string(p.PricePerUnit)) - if !ok { - glog.Errorf("Price per unit could not be parsed for gateway %v. must be a valid number, provided %s", p.EthAddress, p.PricePerUnit) - continue - } prices[i] = GatewayPrice{ EthAddress: p.EthAddress, Currency: p.Currency, - PricePerUnit: pricePerUnit, - PixelsPerUnit: pixelsPerUnit, + PricePerUnit: p.PricePerUnit.Rat, + PixelsPerUnit: p.PixelsPerUnit.Rat, + } + } + + return prices +} + +type ModelPrice struct { + Pipeline string + ModelID string + PricePerUnit *big.Rat + PixelsPerUnit *big.Rat + Currency string +} + +func getCapabilityPrices(capabilitiesPrices string) []ModelPrice { + if capabilitiesPrices == "" { + return nil + } + + // Format of modelPrices json + // Model_id will be set to "default" to price all models in the pipeline if not specified. + // {"capabilities_prices": [ {"pipeline": "text-to-image", "model_id": "stabilityai/sd-turbo", "price_per_unit": 1000, "pixels_per_unit": 1}, {"pipeline": "image-to-video", "model_id": "default", "price_per_unit": 2000, "pixels_per_unit": 3} ] } + var pricesSet struct { + CapabilitiesPrices []struct { + Pipeline string `json:"pipeline"` + ModelID string `json:"model_id"` + PixelsPerUnit core.JSONRat `json:"pixels_per_unit"` + PricePerUnit core.JSONRat `json:"price_per_unit"` + Currency string `json:"currency"` + } `json:"capabilities_prices"` + } + + pricesFileContent, _ := common.ReadFromFile(capabilitiesPrices) + err := json.Unmarshal([]byte(pricesFileContent), &pricesSet) + if err != nil { + glog.Errorf("model prices could not be parsed: %s", err) + return nil + } + + prices := make([]ModelPrice, len(pricesSet.CapabilitiesPrices)) + for i, p := range pricesSet.CapabilitiesPrices { + if p.ModelID == "" { + p.ModelID = "default" + } + + prices[i] = ModelPrice{ + Pipeline: p.Pipeline, + ModelID: p.ModelID, + PricePerUnit: p.PricePerUnit.Rat, + PixelsPerUnit: p.PixelsPerUnit.Rat, + Currency: p.Currency, } } diff --git a/cmd/livepeer/starter/starter_test.go b/cmd/livepeer/starter/starter_test.go index 60df927897..9419b11a52 100644 --- a/cmd/livepeer/starter/starter_test.go +++ b/cmd/livepeer/starter/starter_test.go @@ -109,6 +109,34 @@ func TestParseGetGatewayPrices(t *testing.T) { } } +func TestMaxPricePerCapability(t *testing.T) { + assert := assert.New(t) + + jsonTemplate := `{"capabilities_prices": [ {"pipeline": "text-to-image", "model_id": "stabilityai/sd-turbo", "price_per_unit": 1000, "pixels_per_unit": 1}, {"pipeline": "image-to-video", "model_id": "default", "price_per_unit": 2000, "pixels_per_unit": 3}, {"pipeline": "image-to-image", "price_per_unit": 3000, "pixels_per_unit": 1} ] }` + + prices := getCapabilityPrices(jsonTemplate) + assert.NotNil(prices) + assert.Equal(3, len(prices)) + + // Confirm Pipeline and ModelID is parsed correctly + assert.Equal(prices[0].Pipeline, "text-to-image") + assert.Equal(prices[1].Pipeline, "image-to-video") + assert.Equal(prices[0].ModelID, "stabilityai/sd-turbo") + assert.Equal(prices[1].ModelID, "default") + + // Confirm prices are parsed correctly + price1 := new(big.Rat).Quo(prices[0].PricePerUnit, prices[0].PixelsPerUnit) + price2 := new(big.Rat).Quo(prices[1].PricePerUnit, prices[1].PixelsPerUnit) + assert.NotEqual(price1, price2) + assert.Equal(big.NewRat(1000, 1), price1) + assert.Equal(big.NewRat(2000, 3), price2) + + // Confirm modelID is "default" if not set and price set correctly + assert.Equal(prices[2].ModelID, "default") + price3 := new(big.Rat).Quo(prices[2].PricePerUnit, prices[2].PixelsPerUnit) + assert.Equal(big.NewRat(3000, 1), price3) +} + // Address provided to keystore file func TestParse_ParseEthKeystorePathValidFile(t *testing.T) { assert := assert.New(t) diff --git a/cmd/livepeer_cli/livepeer_cli.go b/cmd/livepeer_cli/livepeer_cli.go index a294bdab96..c6ea22fd12 100644 --- a/cmd/livepeer_cli/livepeer_cli.go +++ b/cmd/livepeer_cli/livepeer_cli.go @@ -102,6 +102,7 @@ func (w *wizard) initializeOptions() []wizardOpt { {desc: "Invoke \"cancel unlock of broadcasting funds\"", invoke: w.cancelUnlock, notOrchestrator: true}, {desc: "Invoke \"withdraw broadcasting funds\"", invoke: w.withdraw, notOrchestrator: true}, {desc: "Set broadcast config", invoke: w.setBroadcastConfig, notOrchestrator: true}, + {desc: "Set max price per capability", invoke: w.setBroadcastMaxPricePerCapability, notOrchestrator: true}, {desc: "Set maximum Ethereum gas price", invoke: w.setMaxGasPrice}, {desc: "Set minimum Ethereum gas price", invoke: w.setMinGasPrice}, {desc: "Get test LPT", invoke: w.requestTokens, testnet: true}, diff --git a/cmd/livepeer_cli/wizard_broadcast.go b/cmd/livepeer_cli/wizard_broadcast.go index 8f2c59e917..3dc3105b03 100644 --- a/cmd/livepeer_cli/wizard_broadcast.go +++ b/cmd/livepeer_cli/wizard_broadcast.go @@ -95,6 +95,38 @@ func (w *wizard) setBroadcastConfig() { } } +func (w *wizard) setBroadcastMaxPricePerCapability() { + fmt.Printf("Enter the pipeline to set price for - ") + pipeline := w.readString() + fmt.Printf("Enter the model id to set price for (default: default) - ") + modelID := w.readDefaultString("default") + fmt.Printf("Enter the maximum price to pay (default: 0) - ") + maxPricePerUnit := w.readDefaultString("0") + fmt.Printf("Enter the price currency (default: Wei) - ") + currency := w.readDefaultString("Wei") + pixelsPerUnit := "1" + + // Make default case insensitive. + if strings.EqualFold(modelID, "default") { + modelID = "default" + } + + val := url.Values{ + "maxPricePerUnit": {fmt.Sprintf("%v", maxPricePerUnit)}, + "pixelsPerUnit": {fmt.Sprintf("%v", pixelsPerUnit)}, + "currency": {fmt.Sprintf("%v", currency)}, + "pipeline": {fmt.Sprintf("%v", pipeline)}, + "modelID": {fmt.Sprintf("%v", modelID)}, + } + + resp, ok := httpPostWithParams(fmt.Sprintf("http://%v:%v/setMaxPriceForCapability", w.host, w.httpPort), val) + if !ok { + fmt.Printf("Error setting max price for capability: %v\n", resp) + } else { + fmt.Printf("Max price per capability set successfully\n") + } +} + func (w *wizard) idListToVideoProfileList(idList string, opts map[int]string) (string, error) { ids := strings.Split(idList, ",") diff --git a/common/testutil.go b/common/testutil.go index 7e957d072a..a3d98a6a9b 100644 --- a/common/testutil.go +++ b/common/testutil.go @@ -89,7 +89,8 @@ func IgnoreRoutines() []goleak.Option { "github.com/livepeer/go-livepeer/server.(*LivepeerServer).StartMediaServer", "github.com/livepeer/go-livepeer/core.(*RemoteTranscoderManager).Manage.func1", "github.com/livepeer/go-livepeer/server.(*LivepeerServer).HandlePush.func1", "github.com/rjeczalik/notify.(*nonrecursiveTree).dispatch", "github.com/rjeczalik/notify.(*nonrecursiveTree).internal", "github.com/livepeer/lpms/stream.NewBasicRTMPVideoStream.func1", "github.com/patrickmn/go-cache.(*janitor).Run", - "github.com/golang/glog.(*fileSink).flushDaemon", + "github.com/golang/glog.(*fileSink).flushDaemon", "github.com/livepeer/go-livepeer/core.(*LivepeerNode).transcodeFrames.func2", "github.com/ipfs/go-log/writer.(*MirrorWriter).logRoutine", + "github.com/livepeer/go-livepeer/core.(*Balances).StartCleanup", } res := make([]goleak.Option, 0, len(funcs2ignore)) diff --git a/common/types.go b/common/types.go index 8dc0845a77..dcb258add2 100644 --- a/common/types.go +++ b/common/types.go @@ -49,6 +49,7 @@ type Broadcaster interface { type CapabilityComparator interface { CompatibleWith(*net.Capabilities) bool LegacyOnly() bool + ToNetCapabilities() *net.Capabilities } const ( diff --git a/common/util.go b/common/util.go index b4d7396a8b..dd6e73b872 100644 --- a/common/util.go +++ b/common/util.go @@ -16,16 +16,15 @@ import ( "sort" "strconv" "strings" - "testing" "time" "github.com/ethereum/go-ethereum/crypto" - "github.com/golang/glog" "github.com/jaypipes/ghw" "github.com/jaypipes/ghw/pkg/gpu" "github.com/jaypipes/ghw/pkg/pci" "github.com/livepeer/go-livepeer/net" ffmpeg "github.com/livepeer/lpms/ffmpeg" + "github.com/oapi-codegen/runtime/types" "github.com/pkg/errors" "google.golang.org/grpc/peer" ) @@ -65,7 +64,6 @@ const priceScalingFactor = int64(1000) var ( ErrParseBigInt = fmt.Errorf("failed to parse big integer") - ErrProfile = fmt.Errorf("failed to parse profile") ErrChromaFormat = fmt.Errorf("unknown VideoProfile ChromaFormat") ErrFormatProto = fmt.Errorf("unknown VideoProfile format for protobufs") @@ -75,10 +73,19 @@ var ( ErrProfEncoder = fmt.Errorf("unknown VideoProfile encoder for protobufs") ErrProfName = fmt.Errorf("unknown VideoProfile profile name") + ErrAudioDurationCalculation = fmt.Errorf("audio duration calculation failed") + ErrNoExtensionsForType = fmt.Errorf("no extensions exist for mime type") + ext2mime = map[string]string{ ".ts": "video/mp2t", ".mp4": "video/mp4", } + mime2ext = map[string]string{ + "video/mp2t": ".ts", + "video/mp4": ".mp4", + "image/png": ".png", + "audio/wav": ".wav", + } ) func init() { @@ -96,93 +103,6 @@ func ParseBigInt(num string) (*big.Int, error) { } } -func WaitUntil(waitTime time.Duration, condition func() bool) { - start := time.Now() - for time.Since(start) < waitTime { - if condition() == false { - time.Sleep(100 * time.Millisecond) - continue - } - break - } -} - -func WaitAssert(t *testing.T, waitTime time.Duration, condition func() bool, msg string) { - start := time.Now() - for time.Since(start) < waitTime { - if condition() == false { - time.Sleep(100 * time.Millisecond) - continue - } - break - } - - if condition() == false { - t.Errorf(msg) - } -} - -func Retry(attempts int, sleep time.Duration, fn func() error) error { - if err := fn(); err != nil { - if attempts--; attempts > 0 { - time.Sleep(sleep) - return Retry(attempts, 2*sleep, fn) - } - return err - } - - return nil -} - -func TxDataToVideoProfile(txData string) ([]ffmpeg.VideoProfile, error) { - profiles := make([]ffmpeg.VideoProfile, 0) - - if len(txData) == 0 { - return profiles, nil - } - if len(txData) < VideoProfileIDSize { - return nil, ErrProfile - } - - for i := 0; i+VideoProfileIDSize <= len(txData); i += VideoProfileIDSize { - txp := txData[i : i+VideoProfileIDSize] - - p, ok := ffmpeg.VideoProfileLookup[VideoProfileNameLookup[txp]] - if !ok { - glog.Errorf("Cannot find video profile for job: %v", txp) - return nil, ErrProfile // monitor to see if this is too aggressive - } - profiles = append(profiles, p) - } - - return profiles, nil -} - -func BytesToVideoProfile(txData []byte) ([]ffmpeg.VideoProfile, error) { - profiles := make([]ffmpeg.VideoProfile, 0) - - if len(txData) == 0 { - return profiles, nil - } - if len(txData) < VideoProfileIDBytes { - return nil, ErrProfile - } - - for i := 0; i+VideoProfileIDBytes <= len(txData); i += VideoProfileIDBytes { - var txp [VideoProfileIDBytes]byte - copy(txp[:], txData[i:i+VideoProfileIDBytes]) - - p, ok := ffmpeg.VideoProfileLookup[VideoProfileByteLookup[txp]] - if !ok { - glog.Errorf("Cannot find video profile for job: %v", txp) - return nil, ErrProfile // monitor to see if this is too aggressive - } - profiles = append(profiles, p) - } - - return profiles, nil -} - func FFmpegProfiletoNetProfile(ffmpegProfiles []ffmpeg.VideoProfile) ([]*net.VideoProfile, error) { profiles := make([]*net.VideoProfile, 0, len(ffmpegProfiles)) for _, profile := range ffmpegProfiles { @@ -357,6 +277,16 @@ func FixedToPrice(price int64) *big.Rat { return big.NewRat(price, priceScalingFactor) } +// PriceToInt64 converts a *big.Rat to an *int64 if possible, otherwise returns an error. +func PriceToInt64(price *big.Rat) (*big.Rat, error) { + fixed := new(big.Int).Div(price.Num(), price.Denom()) + if !fixed.IsInt64() { + return nil, errors.New("price cannot be converted to int64") + } + + return big.NewRat(fixed.Int64(), 1), nil +} + // BaseTokenAmountToFixed converts the base amount of a token (i.e. ETH/LPT) represented as a big.Int into a fixed point number represented // as a int64 using a scalingFactor of 100000 resulting in max decimal places of 5 func BaseTokenAmountToFixed(baseAmount *big.Int) (int64, error) { @@ -532,6 +462,38 @@ func ParseEthAddr(strJsonKey string) (string, error) { return "", errors.New("Error parsing address from keyfile") } +// CalculateAudioDuration calculates audio file duration using the lpms/ffmpeg package. +func CalculateAudioDuration(audio types.File) (int64, error) { + read, err := audio.Reader() + if err != nil { + return 0, err + } + defer read.Close() + + bytearr, _ := audio.Bytes() + _, mediaFormat, err := ffmpeg.GetCodecInfoBytes(bytearr) + if err != nil { + return 0, errors.New("Error getting codec info") + } + + duration := int64(mediaFormat.DurSecs) + if duration <= 0 { + return 0, ErrAudioDurationCalculation + } + + return duration, nil +} + +// ValidateServiceURI checks if the serviceURI is valid. func ValidateServiceURI(serviceURI *url.URL) bool { return !strings.Contains(serviceURI.Host, "0.0.0.0") } + +// MimeTypeToExtension returns the file extension for a given MIME type. +func MimeTypeToExtension(mimeType string) (string, error) { + mimeType = strings.ToLower(mimeType) + if ext, ok := mime2ext[mimeType]; ok { + return ext, nil + } + return "", ErrNoExtensionsForType +} diff --git a/common/util_test.go b/common/util_test.go index 131631586e..9aa2e90914 100644 --- a/common/util_test.go +++ b/common/util_test.go @@ -1,7 +1,6 @@ package common import ( - "encoding/hex" "fmt" "math" "math/big" @@ -19,45 +18,6 @@ import ( "github.com/stretchr/testify/assert" ) -func TestTxDataToVideoProfile(t *testing.T) { - if res, err := TxDataToVideoProfile(""); err != nil && len(res) != 0 { - t.Error("Unexpected return on empty input") - } - if _, err := TxDataToVideoProfile("abc"); err != ErrProfile { - t.Error("Unexpected return on too-short input", err) - } - if _, err := TxDataToVideoProfile("abcdefghijk"); err != ErrProfile { - t.Error("Unexpected return on invalid input", err) - } - res, err := TxDataToVideoProfile("93c717e7c0a6517a") - if err != nil || res[1] != ffmpeg.P240p30fps16x9 || res[0] != ffmpeg.P360p30fps16x9 { - t.Error("Unexpected profile! ", err, res) - } -} - -func TestVideoProfileBytes(t *testing.T) { - if len(VideoProfileByteLookup) != len(VideoProfileNameLookup) { - t.Error("Video profile byte map was not created correctly") - } - if res, err := BytesToVideoProfile(nil); err != nil && len(res) != 0 { - t.Error("Unexpected return on empty input") - } - if res, err := BytesToVideoProfile([]byte{}); err != nil && len(res) != 0 { - t.Error("Unexpected return on empty input") - } - if _, err := BytesToVideoProfile([]byte("abc")); err != ErrProfile { - t.Error("Unexpected return on too-short input", err) - } - if _, err := BytesToVideoProfile([]byte("abcdefghijk")); err != ErrProfile { - t.Error("Unexpected return on invalid input", err) - } - b, _ := hex.DecodeString("93c717e7c0a6517a") - res, err := BytesToVideoProfile(b) - if err != nil || res[1] != ffmpeg.P240p30fps16x9 || res[0] != ffmpeg.P360p30fps16x9 { - t.Error("Unexpected profile! ", err, res) - } -} - func TestFFmpegProfiletoNetProfile(t *testing.T) { assert := assert.New(t) @@ -158,26 +118,6 @@ func TestFFmpegProfiletoNetProfile(t *testing.T) { assert.Nil(fullProfiles) } -func TestProfilesToHex(t *testing.T) { - assert := assert.New(t) - // Sanity checking against an existing eth impl that we know works - compare := func(profiles []ffmpeg.VideoProfile) { - pCopy := make([]ffmpeg.VideoProfile, len(profiles)) - copy(pCopy, profiles) - b1, err := hex.DecodeString(ProfilesToHex(profiles)) - assert.Nil(err, "Error hex encoding/decoding") - b2, err := BytesToVideoProfile(b1) - assert.Nil(err, "Error converting back to profile") - assert.Equal(pCopy, b2) - } - // XXX double check which one is wrong! ethcommon method produces "0" zero string - // compare(nil) - // compare([]ffmpeg.VideoProfile{}) - compare([]ffmpeg.VideoProfile{ffmpeg.P240p30fps16x9}) - compare([]ffmpeg.VideoProfile{ffmpeg.P240p30fps16x9, ffmpeg.P360p30fps16x9}) - compare([]ffmpeg.VideoProfile{ffmpeg.P360p30fps16x9, ffmpeg.P240p30fps16x9}) -} - func TestVideoProfile_FormatMimeType(t *testing.T) { inp := []ffmpeg.Format{ffmpeg.FormatNone, ffmpeg.FormatMPEGTS, ffmpeg.FormatMP4} exp := []string{"video/mp2t", "video/mp2t", "video/mp4"} @@ -519,3 +459,20 @@ func TestValidateServiceURI(t *testing.T) { } } } +func TestMimeTypeToExtension(t *testing.T) { + assert := assert.New(t) + + // Test valid content types + contentTypes := []string{"image/png", "video/mp4", "video/mp2t"} + expectedExtensions := []string{".png", ".mp4", ".ts"} + for i, contentType := range contentTypes { + ext, err := MimeTypeToExtension(contentType) + assert.Nil(err) + assert.Equal(expectedExtensions[i], ext) + } + + // Test invalid content type + invalidContentType := "invalid/type" + _, err := MimeTypeToExtension(invalidContentType) + assert.Equal(ErrNoExtensionsForType, err) +} diff --git a/core/ai.go b/core/ai.go new file mode 100644 index 0000000000..871b99b446 --- /dev/null +++ b/core/ai.go @@ -0,0 +1,235 @@ +package core + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "math/big" + "os" + "regexp" + "strconv" + "strings" + + "github.com/golang/glog" + "github.com/livepeer/ai-worker/worker" +) + +var errPipelineNotAvailable = errors.New("pipeline not available") + +type AI interface { + TextToImage(context.Context, worker.GenTextToImageJSONRequestBody) (*worker.ImageResponse, error) + ImageToImage(context.Context, worker.GenImageToImageMultipartRequestBody) (*worker.ImageResponse, error) + ImageToVideo(context.Context, worker.GenImageToVideoMultipartRequestBody) (*worker.VideoResponse, error) + Upscale(context.Context, worker.GenUpscaleMultipartRequestBody) (*worker.ImageResponse, error) + AudioToText(context.Context, worker.GenAudioToTextMultipartRequestBody) (*worker.TextResponse, error) + LLM(context.Context, worker.GenLLMFormdataRequestBody) (interface{}, error) + SegmentAnything2(context.Context, worker.GenSegmentAnything2MultipartRequestBody) (*worker.MasksResponse, error) + ImageToText(context.Context, worker.GenImageToTextMultipartRequestBody) (*worker.ImageToTextResponse, error) + TextToSpeech(context.Context, worker.GenTextToSpeechJSONRequestBody) (*worker.AudioResponse, error) + Warm(context.Context, string, string, worker.RunnerEndpoint, worker.OptimizationFlags) error + Stop(context.Context) error + HasCapacity(pipeline, modelID string) bool +} + +// Custom type to parse a big.Rat from a JSON number. +type JSONRat struct{ *big.Rat } + +func (s *JSONRat) UnmarshalJSON(data []byte) error { + rat, ok := new(big.Rat).SetString(string(data)) + if !ok { + return fmt.Errorf("value is not a number: %s", data) + } + *s = JSONRat{rat} + return nil +} + +func (s JSONRat) String() string { + return s.FloatString(2) +} + +// parsePipelineFromModelID converts a pipeline name to a capability enum. +func PipelineToCapability(pipeline string) (Capability, error) { + if pipeline == "" { + return Capability_Unused, errPipelineNotAvailable + } + + pipelineName := strings.ToUpper(pipeline[:1]) + strings.ReplaceAll(pipeline[1:], "-", " ") + + for cap, desc := range CapabilityNameLookup { + if pipelineName == desc { + return cap, nil + } + } + + // No capability description matches name. + return Capability_Unused, errPipelineNotAvailable +} + +type AIModelConfig struct { + Pipeline string `json:"pipeline"` + ModelID string `json:"model_id"` + // used by worker + URL string `json:"url,omitempty"` + Token string `json:"token,omitempty"` + Warm bool `json:"warm,omitempty"` + Capacity int `json:"capacity,omitempty"` + OptimizationFlags worker.OptimizationFlags `json:"optimization_flags,omitempty"` + // used by orchestrator + Gateway string `json:"gateway"` + PricePerUnit JSONRat `json:"price_per_unit,omitempty"` + PixelsPerUnit JSONRat `json:"pixels_per_unit,omitempty"` + Currency string `json:"currency,omitempty"` +} + +func ParseAIModelConfigs(config string) ([]AIModelConfig, error) { + var configs []AIModelConfig + + info, err := os.Stat(config) + if err == nil && !info.IsDir() { + data, err := os.ReadFile(config) + if err != nil { + return nil, err + } + + if err := json.Unmarshal(data, &configs); err != nil { + return nil, err + } + + return configs, nil + } + + models := strings.Split(config, ",") + for _, m := range models { + parts := strings.Split(m, ":") + if len(parts) < 3 { + return nil, errors.New("invalid AI model config expected ::") + } + + pipeline := parts[0] + modelID := parts[1] + warm, err := strconv.ParseBool(parts[2]) + if err != nil { + return nil, err + } + + configs = append(configs, AIModelConfig{Pipeline: pipeline, ModelID: modelID, Warm: warm}) + } + + return configs, nil +} + +// ParseStepsFromModelID parses the number of inference steps from the model ID suffix. +func ParseStepsFromModelID(modelID *string, defaultSteps float64) float64 { + numInferenceSteps := defaultSteps + + // Regular expression to find "_step" pattern anywhere in the model ID. + stepPattern := regexp.MustCompile(`_(\d+)step`) + matches := stepPattern.FindStringSubmatch(*modelID) + if len(matches) == 2 { + if parsedSteps, err := strconv.Atoi(matches[1]); err == nil { + numInferenceSteps = float64(parsedSteps) + } + } + + return numInferenceSteps +} + +// AddAICapabilities adds AI capabilities to the node. +func (n *LivepeerNode) AddAICapabilities(caps *Capabilities) { + aiConstraints := caps.PerCapability() + if aiConstraints == nil { + return + } + + n.Capabilities.mutex.Lock() + defer n.Capabilities.mutex.Unlock() + for aiCapability, aiConstraint := range aiConstraints { + _, capExists := n.Capabilities.constraints.perCapability[aiCapability] + if !capExists { + n.Capabilities.constraints.perCapability[aiCapability] = &CapabilityConstraints{ + Models: make(ModelConstraints), + } + } + + for modelId, modelConstraint := range aiConstraint.Models { + _, modelExists := n.Capabilities.constraints.perCapability[aiCapability].Models[modelId] + if modelExists { + n.Capabilities.constraints.perCapability[aiCapability].Models[modelId].Capacity += modelConstraint.Capacity + } else { + n.Capabilities.constraints.perCapability[aiCapability].Models[modelId] = &ModelConstraint{Warm: modelConstraint.Warm, Capacity: modelConstraint.Capacity} + } + } + } +} + +// RemoveAICapabilities removes AI capabilities from the node. +func (n *LivepeerNode) RemoveAICapabilities(caps *Capabilities) { + aiConstraints := caps.PerCapability() + if aiConstraints == nil { + return + } + + n.Capabilities.mutex.Lock() + defer n.Capabilities.mutex.Unlock() + for capability, constraint := range aiConstraints { + _, ok := n.Capabilities.constraints.perCapability[capability] + if ok { + for modelId, modelConstraint := range constraint.Models { + _, modelExists := n.Capabilities.constraints.perCapability[capability].Models[modelId] + if modelExists { + n.Capabilities.constraints.perCapability[capability].Models[modelId].Capacity -= modelConstraint.Capacity + if n.Capabilities.constraints.perCapability[capability].Models[modelId].Capacity <= 0 { + delete(n.Capabilities.constraints.perCapability[capability].Models, modelId) + } + } else { + glog.Errorf("failed to remove AI capability capacity, model does not exist pipeline=%v modelID=%v", capability, modelId) + } + } + } + } +} + +func (n *LivepeerNode) ReserveAICapability(pipeline string, modelID string) error { + cap, err := PipelineToCapability(pipeline) + if err != nil { + return err + } + + _, hasCap := n.Capabilities.constraints.perCapability[cap] + if hasCap { + _, hasModel := n.Capabilities.constraints.perCapability[cap].Models[modelID] + if hasModel { + n.Capabilities.mutex.Lock() + defer n.Capabilities.mutex.Unlock() + if n.Capabilities.constraints.perCapability[cap].Models[modelID].Capacity > 0 { + n.Capabilities.constraints.perCapability[cap].Models[modelID].Capacity -= 1 + } else { + return fmt.Errorf("failed to reserve AI capability capacity, model capacity is 0 pipeline=%v modelID=%v", pipeline, modelID) + } + return nil + } + return fmt.Errorf("failed to reserve AI capability capacity, model does not exist pipeline=%v modelID=%v", pipeline, modelID) + } + return fmt.Errorf("failed to reserve AI capability capacity, pipeline does not exist pipeline=%v modelID=%v", pipeline, modelID) +} + +func (n *LivepeerNode) ReleaseAICapability(pipeline string, modelID string) error { + cap, err := PipelineToCapability(pipeline) + if err != nil { + return err + } + _, hasCap := n.Capabilities.constraints.perCapability[cap] + if hasCap { + _, hasModel := n.Capabilities.constraints.perCapability[cap].Models[modelID] + if hasModel { + n.Capabilities.mutex.Lock() + defer n.Capabilities.mutex.Unlock() + n.Capabilities.constraints.perCapability[cap].Models[modelID].Capacity += 1 + + return nil + } + return fmt.Errorf("failed to release AI capability capacity, model does not exist pipeline=%v modelID=%v", pipeline, modelID) + } + return fmt.Errorf("failed to release AI capability capacity, pipeline does not exist pipeline=%v modelID=%v", pipeline, modelID) +} diff --git a/core/ai_test.go b/core/ai_test.go new file mode 100644 index 0000000000..dc924760ee --- /dev/null +++ b/core/ai_test.go @@ -0,0 +1,791 @@ +package core + +import ( + "context" + "fmt" + "os" + "path/filepath" + "strconv" + "sync" + "testing" + "time" + + "github.com/livepeer/ai-worker/worker" + "github.com/livepeer/go-livepeer/common" + "github.com/livepeer/go-livepeer/net" + "github.com/livepeer/go-tools/drivers" + + "github.com/stretchr/testify/assert" +) + +func TestPipelineToCapability(t *testing.T) { + good := "audio-to-text" + bad := "i-love-tests" + noSpaces := "llm" + + cap, err := PipelineToCapability(good) + assert.Nil(t, err) + assert.Equal(t, cap, Capability_AudioToText) + + cap, err = PipelineToCapability(bad) + assert.Error(t, err) + assert.Equal(t, cap, Capability_Unused) + + cap, err = PipelineToCapability(noSpaces) + assert.Nil(t, err) + assert.Equal(t, cap, Capability_LLM) +} + +func TestServeAIWorker(t *testing.T) { + n, _ := NewLivepeerNode(nil, "", nil) + n.Capabilities = NewCapabilities(DefaultCapabilities(), nil) + n.Capabilities.SetPerCapabilityConstraints(make(PerCapabilityConstraints)) + n.Capabilities.SetMinVersionConstraint("1.0") + n.AIWorkerManager = NewRemoteAIWorkerManager() + strm := &StubAIWorkerServer{} + + // test that an ai worker was created + caps := createAIWorkerCapabilities() + netCaps := caps.ToNetCapabilities() + go n.serveAIWorker(strm, netCaps) + time.Sleep(1 * time.Second) + + wkr, ok := n.AIWorkerManager.liveAIWorkers[strm] + if !ok { + t.Error("Unexpected transcoder type") + } + + // test shutdown + wkr.eof <- struct{}{} + time.Sleep(1 * time.Second) + + // stream should be removed + _, ok = n.AIWorkerManager.liveAIWorkers[strm] + if ok { + t.Error("Unexpected ai worker presence") + } +} +func TestServeAIWorker_IncompatibleVersion(t *testing.T) { + assert := assert.New(t) + n, _ := NewLivepeerNode(nil, "", nil) + n.Capabilities.SetPerCapabilityConstraints(make(PerCapabilityConstraints)) + n.Capabilities.SetMinVersionConstraint("1.1") + n.AIWorkerManager = NewRemoteAIWorkerManager() + strm := &StubAIWorkerServer{} + + // test that an ai worker was created + caps := createAIWorkerCapabilities() + netCaps := caps.ToNetCapabilities() + go n.serveAIWorker(strm, netCaps) + time.Sleep(5 * time.Second) + assert.Zero(len(n.AIWorkerManager.liveAIWorkers)) + assert.Zero(len(n.AIWorkerManager.remoteAIWorkers)) + assert.Zero(len(n.Capabilities.constraints.perCapability)) +} + +func TestRemoteAIWorkerManager(t *testing.T) { + m := NewRemoteAIWorkerManager() + initAIWorker := func() (*RemoteAIWorker, *StubAIWorkerServer) { + strm := &StubAIWorkerServer{manager: m} + caps := createAIWorkerCapabilities() + wkr := NewRemoteAIWorker(m, strm, caps) + return wkr, strm + } + //create worker and connect to manager + wkr, strm := initAIWorker() + + go func() { + m.Manage(strm, wkr.capabilities.ToNetCapabilities()) + }() + time.Sleep(1 * time.Millisecond) // allow the workers to activate + + //check workers connected + assert.Equal(t, 1, len(m.remoteAIWorkers)) + assert.NotNil(t, m.liveAIWorkers[strm]) + //create request + req := worker.GenTextToImageJSONRequestBody{} + req.Prompt = "a titan carrying steel ball with livepeer logo" + + // happy path + res, err := m.Process(context.TODO(), "request_id1", "text-to-image", "livepeer/model1", "", AIJobRequestData{Request: req}) + results, ok := res.Results.(worker.ImageResponse) + assert.True(t, ok) + assert.Nil(t, err) + assert.Equal(t, "image_url", results.Images[0].Url) + + // error on remote + strm.JobError = fmt.Errorf("JobError") + _, err = m.Process(context.TODO(), "request_id2", "text-to-image", "livepeer/model1", "", AIJobRequestData{Request: req}) + assert.NotNil(t, err) + strm.JobError = nil + + //check worker is still connected + assert.Equal(t, 1, len(m.remoteAIWorkers)) + + // simulate error with sending + // m.Process keeps retrying since error is not fatal + strm.SendError = ErrNoWorkersAvailable + _, err = m.Process(context.TODO(), "request_id3", "text-to-image", "livepeer/model1", "", AIJobRequestData{Request: req}) + _, fatal := err.(RemoteAIWorkerFatalError) + if !fatal && err.Error() != strm.SendError.Error() { + t.Error("Unexpected error ", err, fatal) + } + strm.SendError = nil + + //check worker is disconnected + assert.Equal(t, 0, len(m.remoteAIWorkers)) + assert.Nil(t, m.liveAIWorkers[strm]) +} + +func TestSelectAIWorker(t *testing.T) { + m := NewRemoteAIWorkerManager() + strm := &StubAIWorkerServer{manager: m, DelayResults: false} + strm2 := &StubAIWorkerServer{manager: m} + + capabilities := createAIWorkerCapabilities() + + extraModelCapabilities := createAIWorkerCapabilities() + extraModelCapabilities.constraints.perCapability[Capability_TextToImage].Models["livepeer/model2"] = &ModelConstraint{Warm: true, Capacity: 2} + extraModelCapabilities.constraints.perCapability[Capability_ImageToImage] = &CapabilityConstraints{Models: make(ModelConstraints)} + extraModelCapabilities.constraints.perCapability[Capability_ImageToImage].Models["livepeer/model2"] = &ModelConstraint{Warm: true, Capacity: 1} + + // sanity check that ai worker is not in liveAIWorkers or remoteAIWorkers + assert := assert.New(t) + assert.Nil(m.liveAIWorkers[strm]) + assert.Empty(m.remoteAIWorkers) + + // register ai workers, which adds ai worker to liveAIWorkers and remoteAIWorkers + wg := newWg(1) + go func() { m.Manage(strm, capabilities.ToNetCapabilities()) }() + time.Sleep(1 * time.Millisecond) // allow time for first stream to register + go func() { m.Manage(strm2, extraModelCapabilities.ToNetCapabilities()); wg.Done() }() + time.Sleep(1 * time.Millisecond) // allow time for second stream to register e for third stream to register + + //update worker.addr to be different + m.remoteAIWorkers[0].addr = string(RandomManifestID()) + m.remoteAIWorkers[1].addr = string(RandomManifestID()) + + assert.NotNil(m.liveAIWorkers[strm]) + assert.NotNil(m.liveAIWorkers[strm2]) + assert.Len(m.remoteAIWorkers, 2) + + testRequestId := "testID" + testRequestId2 := "testID2" + testRequestId3 := "testID3" + testRequestId4 := "testID4" + + // ai worker is returned from selectAIWorker + currentWorker, err := m.selectWorker(testRequestId, "text-to-image", "livepeer/model1") + assert.Nil(err) + assert.NotNil(currentWorker) + assert.NotNil(m.liveAIWorkers[strm]) + assert.Len(m.remoteAIWorkers, 2) + m.completeAIRequest(testRequestId, "text-to-image", "livepeer/model1") + + // check selecting model for one pipeline does not impact other pipeline with same model + _, err = m.selectWorker(testRequestId, "image-to-image", "livepeer/model2") + assert.Nil(err) + assert.Equal(0, m.remoteAIWorkers[1].capabilities.constraints.perCapability[Capability_ImageToImage].Models["livepeer/model2"].Capacity) + assert.Equal(2, m.remoteAIWorkers[1].capabilities.constraints.perCapability[Capability_TextToImage].Models["livepeer/model2"].Capacity) + m.completeAIRequest(testRequestId, "image-to-image", "livepeer/model2") + + // select all of capacity for ai workers model1 + _, err = m.selectWorker(testRequestId, "text-to-image", "livepeer/model1") + assert.Nil(err) + _, err = m.selectWorker(testRequestId2, "text-to-image", "livepeer/model1") + assert.Nil(err) + w1, err := m.selectWorker(testRequestId3, "text-to-image", "livepeer/model1") + assert.Nil(err) + w2, err := m.selectWorker(testRequestId4, "text-to-image", "livepeer/model1") + assert.Nil(err) + + assert.Equal(0, w1.capabilities.constraints.perCapability[Capability_TextToImage].Models["livepeer/model1"].Capacity) + assert.Equal(0, w2.capabilities.constraints.perCapability[Capability_TextToImage].Models["livepeer/model1"].Capacity) + assert.Equal(2, w2.capabilities.constraints.perCapability[Capability_TextToImage].Models["livepeer/model2"].Capacity) + // Capacity is zero for model, confirm no workers selected + w1, err = m.selectWorker(testRequestId, "text-to-image", "livepeer/model1") + assert.Nil(w1) + assert.EqualError(err, ErrNoCompatibleWorkersAvailable.Error()) + //return one capacity, check requestSessions is cleared for request_id + m.completeAIRequest(testRequestId, "text-to-image", "livepeer/model1") + _, requestIDHasWorker := m.requestSessions[testRequestId] + assert.False(requestIDHasWorker) + //return another one capacity, check combined capacity is 2 + m.completeAIRequest(testRequestId3, "text-to-image", "livepeer/model1") + w1Cap := m.remoteAIWorkers[0].capabilities.constraints.perCapability[Capability_TextToImage].Models["livepeer/model1"].Capacity + w2Cap := m.remoteAIWorkers[1].capabilities.constraints.perCapability[Capability_TextToImage].Models["livepeer/model1"].Capacity + assert.Equal(2, w1Cap+w2Cap) + // return the rest to capacity, check capacity is 4 again + m.completeAIRequest(testRequestId2, "text-to-image", "livepeer/model1") + m.completeAIRequest(testRequestId4, "text-to-image", "livepeer/model1") + w1Cap = m.remoteAIWorkers[0].capabilities.constraints.perCapability[Capability_TextToImage].Models["livepeer/model1"].Capacity + w2Cap = m.remoteAIWorkers[1].capabilities.constraints.perCapability[Capability_TextToImage].Models["livepeer/model1"].Capacity + assert.Equal(4, w1Cap+w2Cap) + + // select model 2 and check capacities + w2, err = m.selectWorker(testRequestId, "text-to-image", "livepeer/model2") + assert.Nil(err) + assert.Equal(2, w2.capabilities.constraints.perCapability[Capability_TextToImage].Models["livepeer/model1"].Capacity) + assert.Equal(1, w2.capabilities.constraints.perCapability[Capability_TextToImage].Models["livepeer/model2"].Capacity) + m.completeAIRequest(testRequestId, "text-to-image", "livepeer/model2") + + // no ai workers available for unsupported pipeline + worker, err := m.selectWorker(testRequestId, "new-pipeline", "livepeer/model1") + assert.NotNil(err) + assert.Nil(worker) + m.completeAIRequest(testRequestId, "new-pipeline", "livepeer/model1") + + // capacity does not change if wrong request id + w2, err = m.selectWorker(testRequestId, "text-to-image", "livepeer/model2") + assert.Nil(err) + m.completeAIRequest(testRequestId2, "text-to-image", "liveeer/model2") + assert.Equal(1, w2.capabilities.constraints.perCapability[Capability_TextToImage].Models["livepeer/model2"].Capacity) + // capacity returned if correct request id + m.completeAIRequest(testRequestId, "text-to-image", "livepeer/model2") + assert.Equal(2, w2.capabilities.constraints.perCapability[Capability_TextToImage].Models["livepeer/model2"].Capacity) + + // unregister ai worker + m.liveAIWorkers[strm2].eof <- struct{}{} + assert.True(wgWait(wg), "Wait timed out for ai worker to terminate") + assert.Nil(m.liveAIWorkers[strm2]) + assert.NotNil(m.liveAIWorkers[strm]) + // check that model only on disconnected worker is not available + w, err := m.selectWorker(testRequestId, "text-to-image", "livepeer/model2") + assert.Nil(w) + assert.NotNil(err) + assert.EqualError(err, ErrNoCompatibleWorkersAvailable.Error()) + + // reconnect worker and check pipeline only on second worker is available + go func() { m.Manage(strm2, extraModelCapabilities.ToNetCapabilities()); wg.Done() }() + time.Sleep(1 * time.Millisecond) + w, err = m.selectWorker(testRequestId, "image-to-image", "livepeer/model2") + assert.NotNil(w) + assert.Nil(err) + m.completeAIRequest(testRequestId, "image-to-image", "livepeer/model2") +} + +func TestManageAIWorkers(t *testing.T) { + m := NewRemoteAIWorkerManager() + strm := &StubAIWorkerServer{} + strm2 := &StubAIWorkerServer{manager: m} + + // sanity check that liveTranscoders and remoteTranscoders is empty + assert := assert.New(t) + assert.Nil(m.liveAIWorkers[strm]) + assert.Nil(m.liveAIWorkers[strm2]) + assert.Empty(m.remoteAIWorkers) + assert.Equal(0, len(m.liveAIWorkers)) + + capabilities := createAIWorkerCapabilities() + + // test that transcoder is added to liveTranscoders and remoteTranscoders + wg1 := newWg(1) + go func() { m.Manage(strm, capabilities.ToNetCapabilities()); wg1.Done() }() + time.Sleep(1 * time.Millisecond) // allow the manager to activate + + assert.NotNil(m.liveAIWorkers[strm]) + assert.Len(m.liveAIWorkers, 1) + assert.Len(m.remoteAIWorkers, 1) + assert.Equal(2, m.remoteAIWorkers[0].capabilities.constraints.perCapability[Capability_TextToImage].Models["livepeer/model1"].Capacity) + assert.Equal("TestAddress", m.remoteAIWorkers[0].addr) + + // test that additional transcoder is added to liveTranscoders and remoteTranscoders + wg2 := newWg(1) + go func() { m.Manage(strm2, capabilities.ToNetCapabilities()); wg2.Done() }() + time.Sleep(1 * time.Millisecond) // allow the manager to activate + + assert.NotNil(m.liveAIWorkers[strm]) + assert.NotNil(m.liveAIWorkers[strm2]) + assert.Len(m.liveAIWorkers, 2) + assert.Len(m.remoteAIWorkers, 2) + + // test that transcoders are removed from liveTranscoders and remoteTranscoders + m.liveAIWorkers[strm].eof <- struct{}{} + assert.True(wgWait(wg1)) // time limit + assert.Nil(m.liveAIWorkers[strm]) + assert.NotNil(m.liveAIWorkers[strm2]) + assert.Len(m.liveAIWorkers, 1) + assert.Len(m.remoteAIWorkers, 2) + + m.liveAIWorkers[strm2].eof <- struct{}{} + assert.True(wgWait(wg2)) // time limit + assert.Nil(m.liveAIWorkers[strm]) + assert.Nil(m.liveAIWorkers[strm2]) + assert.Len(m.liveAIWorkers, 0) + assert.Len(m.remoteAIWorkers, 2) +} + +func TestRemoteAIWorkerTimeout(t *testing.T) { + m := NewRemoteAIWorkerManager() + initAIWorker := func() (*RemoteAIWorker, *StubAIWorkerServer) { + strm := &StubAIWorkerServer{manager: m} + //create capabilities and constraints the ai worker sends to orch + caps := createAIWorkerCapabilities() + wkr := NewRemoteAIWorker(m, strm, caps) + return wkr, strm + } + //create a new worker + wkr, strm := initAIWorker() + //create request + req := worker.GenTextToImageJSONRequestBody{} + req.Prompt = "a titan carrying steel ball with livepeer logo" + + // check default timeout + strm.DelayResults = true + m.taskCount = 1001 + oldTimeout := aiWorkerRequestTimeout + defer func() { aiWorkerRequestTimeout = oldTimeout }() + aiWorkerRequestTimeout = 2 * time.Millisecond + + var wg sync.WaitGroup + wg.Add(1) + go func() { + start := time.Now() + _, timeoutErr := wkr.Process(context.TODO(), "text-to-image", "livepeer/model", "", AIJobRequestData{Request: req}) + took := time.Since(start) + assert.Greater(t, took, aiWorkerRequestTimeout) + assert.NotNil(t, timeoutErr) + assert.Equal(t, RemoteAIWorkerFatalError{ErrRemoteWorkerTimeout}.Error(), timeoutErr.Error()) + wg.Done() + }() + assert.True(t, wgWait(&wg), "worker took too long to timeout") +} + +func TestRemoveFromRemoteAIWorkers(t *testing.T) { + remoteWorkerList := []*RemoteAIWorker{} + assert := assert.New(t) + + // Create 6 ai workers + wkr := make([]*RemoteAIWorker, 5) + for i := 0; i < 5; i++ { + wkr[i] = &RemoteAIWorker{addr: "testAddress" + strconv.Itoa(i)} + } + + // Add to list + remoteWorkerList = append(remoteWorkerList, wkr...) + assert.Len(remoteWorkerList, 5) + + // Remove ai worker froms head of the list + remoteWorkerList = removeFromRemoteWorkers(wkr[0], remoteWorkerList) + assert.Equal(remoteWorkerList[0], wkr[1]) + assert.Equal(remoteWorkerList[1], wkr[2]) + assert.Equal(remoteWorkerList[2], wkr[3]) + assert.Equal(remoteWorkerList[3], wkr[4]) + assert.Len(remoteWorkerList, 4) + + // Remove ai worker from the middle of the list + remoteWorkerList = removeFromRemoteWorkers(wkr[3], remoteWorkerList) + assert.Equal(remoteWorkerList[0], wkr[1]) + assert.Equal(remoteWorkerList[1], wkr[2]) + assert.Equal(remoteWorkerList[2], wkr[4]) + assert.Len(remoteWorkerList, 3) + + // Remove ai worker from the middle of the list + remoteWorkerList = removeFromRemoteWorkers(wkr[2], remoteWorkerList) + assert.Equal(remoteWorkerList[0], wkr[1]) + assert.Equal(remoteWorkerList[1], wkr[4]) + assert.Len(remoteWorkerList, 2) + + // Remove ai worker from the end of the list + remoteWorkerList = removeFromRemoteWorkers(wkr[4], remoteWorkerList) + assert.Equal(remoteWorkerList[0], wkr[1]) + assert.Len(remoteWorkerList, 1) + + // Remove the last ai worker + remoteWorkerList = removeFromRemoteWorkers(wkr[1], remoteWorkerList) + assert.Len(remoteWorkerList, 0) + + // Remove a ai worker when list is empty + remoteWorkerList = removeFromRemoteWorkers(wkr[1], remoteWorkerList) + emptyTList := []*RemoteAIWorker{} + assert.Equal(remoteWorkerList, emptyTList) +} +func TestAITaskChan(t *testing.T) { + n := NewRemoteAIWorkerManager() + // Sanity check task ID + if n.taskCount != 0 { + t.Error("Unexpected taskid") + } + if len(n.taskChans) != int(n.taskCount) { + t.Error("Unexpected task chan length") + } + + // Adding task chans + const MaxTasks = 1000 + for i := 0; i < MaxTasks; i++ { + go n.addTaskChan() // hopefully concurrently... + } + for j := 0; j < 10; j++ { + n.taskMutex.RLock() + tid := n.taskCount + n.taskMutex.RUnlock() + if tid >= MaxTasks { + break + } + time.Sleep(10 * time.Millisecond) + } + if n.taskCount != MaxTasks { + t.Error("Time elapsed") + } + if len(n.taskChans) != int(n.taskCount) { + t.Error("Unexpected task chan length") + } + + // Accessing task chans + existingIds := []int64{0, 1, MaxTasks / 2, MaxTasks - 2, MaxTasks - 1} + for _, id := range existingIds { + _, err := n.getTaskChan(int64(id)) + if err != nil { + t.Error("Unexpected error getting task chan for ", id, err) + } + } + missingIds := []int64{-1, MaxTasks} + testNonexistentChans := func(ids []int64) { + for _, id := range ids { + _, err := n.getTaskChan(int64(id)) + if err == nil || err.Error() != "No AI Worker channel" { + t.Error("Did not get expected error for ", id, err) + } + } + } + testNonexistentChans(missingIds) + + // Removing task chans + for i := 0; i < MaxTasks; i++ { + go n.removeTaskChan(int64(i)) // hopefully concurrently... + } + for j := 0; j < 10; j++ { + n.taskMutex.RLock() + tlen := len(n.taskChans) + n.taskMutex.RUnlock() + if tlen <= 0 { + break + } + time.Sleep(10 * time.Millisecond) + } + if len(n.taskChans) != 0 { + t.Error("Time elapsed") + } + testNonexistentChans(existingIds) // sanity check for removal +} +func TestCheckAICapacity(t *testing.T) { + n, _ := NewLivepeerNode(nil, "", nil) + o := NewOrchestrator(n, nil) + wkr := stubAIWorker{} + n.Capabilities = createAIWorkerCapabilities() + n.AIWorker = &wkr + // Test when local AI worker has capacity + hasCapacity := o.CheckAICapacity("text-to-image", "livepeer/model1") + assert.True(t, hasCapacity) + + o.node.AIWorker = nil + o.node.AIWorkerManager = NewRemoteAIWorkerManager() + initAIWorker := func() (*RemoteAIWorker, *StubAIWorkerServer) { + strm := &StubAIWorkerServer{manager: o.node.AIWorkerManager} + caps := createAIWorkerCapabilities() + wkr := NewRemoteAIWorker(o.node.AIWorkerManager, strm, caps) + return wkr, strm + } + //create worker and connect to manager + wkr2, strm := initAIWorker() + + go func() { + o.node.AIWorkerManager.Manage(strm, wkr2.capabilities.ToNetCapabilities()) + }() + time.Sleep(1 * time.Millisecond) // allow the workers to activate + + hasCapacity = o.CheckAICapacity("text-to-image", "livepeer/model1") + assert.True(t, hasCapacity) + + // Test when remote AI worker does not have capacity + hasCapacity = o.CheckAICapacity("text-to-image", "livepeer/model2") + assert.False(t, hasCapacity) +} +func TestRemoteAIWorkerProcessPipelines(t *testing.T) { + drivers.NodeStorage = drivers.NewMemoryDriver(nil) + n, _ := NewLivepeerNode(nil, "", nil) + n.Capabilities = NewCapabilities(DefaultCapabilities(), nil) + n.Capabilities.version = "1.0" + n.Capabilities.SetPerCapabilityConstraints(make(PerCapabilityConstraints)) + n.AIWorkerManager = NewRemoteAIWorkerManager() + o := NewOrchestrator(n, nil) + + initAIWorker := func() (*RemoteAIWorker, *StubAIWorkerServer) { + strm := &StubAIWorkerServer{manager: o.node.AIWorkerManager} + caps := createAIWorkerCapabilities() + wkr := NewRemoteAIWorker(o.node.AIWorkerManager, strm, caps) + return wkr, strm + } + //create worker and connect to manager + wkr, strm := initAIWorker() + go o.node.serveAIWorker(strm, wkr.capabilities.ToNetCapabilities()) + time.Sleep(5 * time.Millisecond) // allow the workers to activate + + //check workers connected + assert.Equal(t, 1, len(o.node.AIWorkerManager.remoteAIWorkers)) + assert.NotNil(t, o.node.AIWorkerManager.liveAIWorkers[strm]) + + //test text-to-image + modelID := "livepeer/model1" + req := worker.GenTextToImageJSONRequestBody{} + req.Prompt = "a titan carrying steel ball with livepeer logo" + req.ModelId = &modelID + o.CreateStorageForRequest("request_id1") + res, err := o.TextToImage(context.TODO(), "request_id1", req) + results, ok := res.(worker.ImageResponse) + assert.True(t, ok) + assert.Nil(t, err) + assert.Equal(t, "/stream/request_id1/image_url", results.Images[0].Url) + // remove worker + wkr.eof <- struct{}{} + time.Sleep(1 * time.Second) + +} +func TestReserveAICapability(t *testing.T) { + n, _ := NewLivepeerNode(nil, "", nil) + n.Capabilities = createAIWorkerCapabilities() + + pipeline := "audio-to-text" + modelID := "livepeer/model1" + + // Add AI capability and model + caps := NewCapabilities(DefaultCapabilities(), nil) + caps.SetPerCapabilityConstraints(PerCapabilityConstraints{ + Capability_AudioToText: { + Models: ModelConstraints{ + modelID: {Warm: true, Capacity: 2}, + }, + }, + }) + n.AddAICapabilities(caps) + + // Reserve AI capability + err := n.ReserveAICapability(pipeline, modelID) + assert.Nil(t, err) + + // Check capacity is reduced + cap := n.Capabilities.constraints.perCapability[Capability_AudioToText] + assert.Equal(t, 1, cap.Models[modelID].Capacity) + + // Reserve AI capability again + err = n.ReserveAICapability(pipeline, modelID) + assert.Nil(t, err) + + // Check capacity is further reduced + cap = n.Capabilities.constraints.perCapability[Capability_AudioToText] + assert.Equal(t, 0, cap.Models[modelID].Capacity) + + // Reserve AI capability when capacity is already zero + err = n.ReserveAICapability(pipeline, modelID) + assert.NotNil(t, err) + assert.EqualError(t, err, fmt.Sprintf("failed to reserve AI capability capacity, model capacity is 0 pipeline=%v modelID=%v", pipeline, modelID)) + + // Reserve AI capability for non-existent pipeline + err = n.ReserveAICapability("invalid-pipeline", modelID) + assert.NotNil(t, err) + assert.EqualError(t, err, "pipeline not available") + + // Reserve AI capability for non-existent model + err = n.ReserveAICapability(pipeline, "invalid-model") + assert.NotNil(t, err) + assert.EqualError(t, err, fmt.Sprintf("failed to reserve AI capability capacity, model does not exist pipeline=%v modelID=invalid-model", pipeline)) +} + +func createAIWorkerCapabilities() *Capabilities { + //create capabilities and constraints the ai worker sends to orch + constraints := make(PerCapabilityConstraints) + constraints[Capability_TextToImage] = &CapabilityConstraints{Models: make(ModelConstraints)} + constraints[Capability_TextToImage].Models["livepeer/model1"] = &ModelConstraint{Warm: true, Capacity: 2} + caps := NewCapabilities(DefaultCapabilities(), MandatoryOCapabilities()) + caps.SetPerCapabilityConstraints(constraints) + caps.version = "1.0" + return caps +} + +type stubAIWorker struct{} + +func (a *stubAIWorker) TextToImage(ctx context.Context, req worker.GenTextToImageJSONRequestBody) (*worker.ImageResponse, error) { + return &worker.ImageResponse{ + Images: []worker.Media{ + {Url: "http://example.com/image.png"}, + }, + }, nil +} + +func (a *stubAIWorker) ImageToImage(ctx context.Context, req worker.GenImageToImageMultipartRequestBody) (*worker.ImageResponse, error) { + return &worker.ImageResponse{ + Images: []worker.Media{ + {Url: "http://example.com/image.png"}, + }, + }, nil +} + +func (a *stubAIWorker) ImageToVideo(ctx context.Context, req worker.GenImageToVideoMultipartRequestBody) (*worker.VideoResponse, error) { + return &worker.VideoResponse{ + Frames: [][]worker.Media{ + { + {Url: "http://example.com/frame1.png", Nsfw: false}, + {Url: "http://example.com/frame2.png", Nsfw: false}, + }, + { + {Url: "http://example.com/frame3.png", Nsfw: false}, + {Url: "http://example.com/frame4.png", Nsfw: false}, + }, + }, + }, nil +} + +func (a *stubAIWorker) Upscale(ctx context.Context, req worker.GenUpscaleMultipartRequestBody) (*worker.ImageResponse, error) { + return &worker.ImageResponse{ + Images: []worker.Media{ + {Url: "http://example.com/image.png"}, + }, + }, nil +} + +func (a *stubAIWorker) AudioToText(ctx context.Context, req worker.GenAudioToTextMultipartRequestBody) (*worker.TextResponse, error) { + return &worker.TextResponse{Text: "Transcribed text"}, nil +} + +func (a *stubAIWorker) SegmentAnything2(ctx context.Context, req worker.GenSegmentAnything2MultipartRequestBody) (*worker.MasksResponse, error) { + return &worker.MasksResponse{Logits: "logits", Masks: "masks", Scores: "scores"}, nil +} + +func (a *stubAIWorker) LLM(ctx context.Context, req worker.GenLLMFormdataRequestBody) (interface{}, error) { + return &worker.LLMResponse{Response: "response tokens", TokensUsed: 10}, nil +} + +func (a *stubAIWorker) ImageToText(ctx context.Context, req worker.GenImageToTextMultipartRequestBody) (*worker.ImageToTextResponse, error) { + return &worker.ImageToTextResponse{Text: "Transcribed text"}, nil +} + +func (a *stubAIWorker) TextToSpeech(ctx context.Context, req worker.GenTextToSpeechJSONRequestBody) (*worker.AudioResponse, error) { + return &worker.AudioResponse{Audio: worker.MediaURL{Url: "http://example.com/audio.wav"}}, nil +} + +func (a *stubAIWorker) Warm(ctx context.Context, arg1, arg2 string, endpoint worker.RunnerEndpoint, flags worker.OptimizationFlags) error { + return nil +} + +func (a *stubAIWorker) Stop(ctx context.Context) error { + return nil +} + +func (a *stubAIWorker) HasCapacity(pipeline, modelID string) bool { + return true +} + +type StubAIWorkerServer struct { + manager *RemoteAIWorkerManager + SendError error + JobError error + DelayResults bool + + common.StubServerStream +} + +func (s *StubAIWorkerServer) Send(n *net.NotifyAIJob) error { + var images []worker.Media + media := worker.Media{Nsfw: false, Seed: 111, Url: "image_url"} + images = append(images, media) + res := RemoteAIWorkerResult{ + Results: worker.ImageResponse{Images: images}, + Files: make(map[string][]byte), + Err: nil, + } + if s.JobError != nil { + res.Err = s.JobError + } + if s.SendError != nil { + return s.SendError + } + + if !s.DelayResults { + s.manager.aiResults(n.TaskId, &res) + } + + return nil + +} + +// Utility function to create a temporary file for file-based configurations +func mockFile(t *testing.T, content string) string { + tmpDir := t.TempDir() + filePath := filepath.Join(tmpDir, "config.json") + err := os.WriteFile(filePath, []byte(content), 0644) + if err != nil { + t.Fatalf("Failed to write mock file: %v", err) + } + return filePath +} + +func TestParseAIModelConfigs(t *testing.T) { + tests := []struct { + name string + input string + fileData string + expected []AIModelConfig + expectedErr string + }{{ + name: "Valid Inline String Config", + input: "pipeline1:model1:true,pipeline2:model2:false", + expected: []AIModelConfig{ + {Pipeline: "pipeline1", ModelID: "model1", Warm: true}, + {Pipeline: "pipeline2", ModelID: "model2", Warm: false}, + }, + }, + { + name: "Invalid Inline String Config Missing Parts", + input: "pipeline1:model1", + expectedErr: "invalid AI model config expected ::", + }, + { + name: "Valid File-Based Config", + fileData: `[{"pipeline": "pipeline1", "model_id": "model1", "warm": true}, {"pipeline": "pipeline2", "model_id": "model2", "warm": false}]`, + expected: []AIModelConfig{ + {Pipeline: "pipeline1", ModelID: "model1", Warm: true}, + {Pipeline: "pipeline2", ModelID: "model2", Warm: false}, + }, + }, + { + name: "Invalid File Config Corrupted JSON", + fileData: `[{"pipeline": "pipeline1", "model_id": "model1", "warm": true`, + expectedErr: "unexpected end of JSON input", + }, + { + name: "File Not Found", + input: "nonexistent.json", + expectedErr: "invalid AI model config expected ::", + }, + { + name: "Invalid Boolean Value in Inline String Config", + input: "pipeline1:model1:invalid_bool", + expectedErr: "strconv.ParseBool: parsing \"invalid_bool\": invalid syntax", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + var result []AIModelConfig + var err error + + // Mock file handling if fileData is provided + if tt.fileData != "" { + mockFilePath := mockFile(t, tt.fileData) + result, err = ParseAIModelConfigs(mockFilePath) + } else { + result, err = ParseAIModelConfigs(tt.input) + } + + // Verify error messages match + assert := assert.New(t) + if tt.expectedErr != "" { + assert.Equal(err.Error(), tt.expectedErr) + assert.Empty(result, err) + } else { + assert.Empty(err) + assert.Equal(tt.expected, result) + } + }) + } +} diff --git a/core/ai_worker.go b/core/ai_worker.go new file mode 100644 index 0000000000..8498191d97 --- /dev/null +++ b/core/ai_worker.go @@ -0,0 +1,1137 @@ +package core + +import ( + "bytes" + "context" + "encoding/json" + "errors" + "fmt" + "os" + "path" + "strconv" + "sync" + "time" + + "github.com/ethereum/go-ethereum/crypto" + "github.com/golang/glog" + "github.com/livepeer/ai-worker/worker" + "github.com/livepeer/go-livepeer/clog" + "github.com/livepeer/go-livepeer/common" + "github.com/livepeer/go-livepeer/monitor" + "github.com/livepeer/go-livepeer/net" + "github.com/livepeer/go-tools/drivers" + "github.com/livepeer/lpms/ffmpeg" +) + +var ErrRemoteWorkerTimeout = errors.New("Remote worker took too long") +var ErrNoCompatibleWorkersAvailable = errors.New("no workers can process job requested") +var ErrNoWorkersAvailable = errors.New("no workers available") + +// TODO: consider making this dynamic for each pipeline +var aiWorkerResultsTimeout = 10 * time.Minute +var aiWorkerRequestTimeout = 15 * time.Minute +var aiWorkerTranscodeLoopTimeout = 70 * time.Second + +type RemoteAIWorker struct { + manager *RemoteAIWorkerManager + stream net.AIWorker_RegisterAIWorkerServer + capabilities *Capabilities + eof chan struct{} + addr string +} + +func (rw *RemoteAIWorker) done() { + // select so we don't block indefinitely if there's no listener + select { + case rw.eof <- struct{}{}: + default: + } +} + +type RemoteAIWorkerManager struct { + remoteAIWorkers []*RemoteAIWorker + liveAIWorkers map[net.AIWorker_RegisterAIWorkerServer]*RemoteAIWorker + RWmutex sync.Mutex + + // For tracking tasks assigned to remote aiworkers + taskMutex *sync.RWMutex + taskChans map[int64]AIWorkerChan + taskCount int64 + + // Map for keeping track of sessions and their respective aiworkers + requestSessions map[string]*RemoteAIWorker +} + +func NewRemoteAIWorker(m *RemoteAIWorkerManager, stream net.AIWorker_RegisterAIWorkerServer, caps *Capabilities) *RemoteAIWorker { + return &RemoteAIWorker{ + manager: m, + stream: stream, + eof: make(chan struct{}, 1), + addr: common.GetConnectionAddr(stream.Context()), + capabilities: caps, + } +} + +func NewRemoteAIWorkerManager() *RemoteAIWorkerManager { + return &RemoteAIWorkerManager{ + remoteAIWorkers: []*RemoteAIWorker{}, + liveAIWorkers: map[net.AIWorker_RegisterAIWorkerServer]*RemoteAIWorker{}, + RWmutex: sync.Mutex{}, + + taskMutex: &sync.RWMutex{}, + taskChans: make(map[int64]AIWorkerChan), + + requestSessions: make(map[string]*RemoteAIWorker), + } +} + +func (orch *orchestrator) ServeAIWorker(stream net.AIWorker_RegisterAIWorkerServer, capabilities *net.Capabilities) { + orch.node.serveAIWorker(stream, capabilities) +} + +func (n *LivepeerNode) serveAIWorker(stream net.AIWorker_RegisterAIWorkerServer, capabilities *net.Capabilities) { + from := common.GetConnectionAddr(stream.Context()) + wkrCaps := CapabilitiesFromNetCapabilities(capabilities) + if n.Capabilities.LivepeerVersionCompatibleWith(capabilities) { + glog.Infof("Worker compatible, connecting worker_version=%s orchestrator_version=%s worker_addr=%s", capabilities.Version, n.Capabilities.constraints.minVersion, from) + n.Capabilities.AddCapacity(wkrCaps) + n.AddAICapabilities(wkrCaps) + defer n.Capabilities.RemoveCapacity(wkrCaps) + defer n.RemoveAICapabilities(wkrCaps) + + // Manage blocks while AI worker is connected + n.AIWorkerManager.Manage(stream, capabilities) + glog.V(common.DEBUG).Infof("Closing aiworker=%s channel", from) + } else { + glog.Errorf("worker %s not connected, version not compatible", from) + } +} + +// Manage adds aiworker to list of live aiworkers. Doesn't return until aiworker disconnects +func (rwm *RemoteAIWorkerManager) Manage(stream net.AIWorker_RegisterAIWorkerServer, capabilities *net.Capabilities) { + from := common.GetConnectionAddr(stream.Context()) + aiworker := NewRemoteAIWorker(rwm, stream, CapabilitiesFromNetCapabilities(capabilities)) + go func() { + ctx := stream.Context() + <-ctx.Done() + err := ctx.Err() + glog.Errorf("Stream closed for aiworker=%s, err=%q", from, err) + aiworker.done() + }() + + rwm.RWmutex.Lock() + rwm.liveAIWorkers[aiworker.stream] = aiworker + rwm.remoteAIWorkers = append(rwm.remoteAIWorkers, aiworker) + rwm.RWmutex.Unlock() + + <-aiworker.eof + glog.Infof("Got aiworker=%s eof, removing from live aiworkers map", from) + + rwm.RWmutex.Lock() + delete(rwm.liveAIWorkers, aiworker.stream) + rwm.RWmutex.Unlock() +} + +// RemoteAIworkerFatalError wraps error to indicate that error is fatal +type RemoteAIWorkerFatalError struct { + error +} + +// NewRemoteAIWorkerFatalError creates new RemoteAIWorkerFatalError +// Exported here to be used in other packages +func NewRemoteAIWorkerFatalError(err error) error { + return RemoteAIWorkerFatalError{err} +} + +// Process does actual AI job using remote worker from the pool +func (rwm *RemoteAIWorkerManager) Process(ctx context.Context, requestID string, pipeline string, modelID string, fname string, req AIJobRequestData) (*RemoteAIWorkerResult, error) { + worker, err := rwm.selectWorker(requestID, pipeline, modelID) + if err != nil { + return nil, err + } + res, err := worker.Process(ctx, pipeline, modelID, fname, req) + if err != nil { + rwm.completeAIRequest(requestID, pipeline, modelID) + } + _, fatal := err.(RemoteAIWorkerFatalError) + if fatal { + // Don't retry if we've timed out; gateway likely to have moved on + if err.(RemoteAIWorkerFatalError).error == ErrRemoteWorkerTimeout { + return res, err + } + return rwm.Process(ctx, requestID, pipeline, modelID, fname, req) + } + + rwm.completeAIRequest(requestID, pipeline, modelID) + return res, err +} + +func (rwm *RemoteAIWorkerManager) selectWorker(requestID string, pipeline string, modelID string) (*RemoteAIWorker, error) { + rwm.RWmutex.Lock() + defer rwm.RWmutex.Unlock() + + checkWorkers := func(rwm *RemoteAIWorkerManager) bool { + return len(rwm.remoteAIWorkers) > 0 + } + + findCompatibleWorker := func(rwm *RemoteAIWorkerManager) int { + cap, _ := PipelineToCapability(pipeline) + for idx, worker := range rwm.remoteAIWorkers { + rwCap, hasCap := worker.capabilities.constraints.perCapability[cap] + if hasCap { + _, hasModel := rwCap.Models[modelID] + if hasModel { + if rwCap.Models[modelID].Capacity > 0 { + rwm.remoteAIWorkers[idx].capabilities.constraints.perCapability[cap].Models[modelID].Capacity -= 1 + return idx + } + } + } + } + return -1 + } + + for checkWorkers(rwm) { + worker, sessionExists := rwm.requestSessions[requestID] + newWorker := findCompatibleWorker(rwm) + if newWorker == -1 { + return nil, ErrNoCompatibleWorkersAvailable + } + if !sessionExists { + worker = rwm.remoteAIWorkers[newWorker] + } + + if _, ok := rwm.liveAIWorkers[worker.stream]; !ok { + // Remove the stream session because the worker is no longer live + if sessionExists { + rwm.completeAIRequest(requestID, pipeline, modelID) + } + // worker does not exist in table; remove and retry + rwm.remoteAIWorkers = removeFromRemoteWorkers(worker, rwm.remoteAIWorkers) + continue + } + + if !sessionExists { + // Assigning worker to session for future use + rwm.requestSessions[requestID] = worker + } + return worker, nil + } + + return nil, ErrNoWorkersAvailable +} + +func (rwm *RemoteAIWorkerManager) workerHasCapacity(pipeline, modelID string) bool { + cap, err := PipelineToCapability(pipeline) + if err != nil { + return false + } + for _, worker := range rwm.remoteAIWorkers { + rw, hasCap := worker.capabilities.constraints.perCapability[cap] + if hasCap { + _, hasModel := rw.Models[modelID] + if hasModel { + if rw.Models[modelID].Capacity > 0 { + return true + } + } + } + } + // no worker has capacity + return false +} + +// completeRequestSessions end a AI request session for a remote ai worker +// caller should hold the mutex lock +func (rwm *RemoteAIWorkerManager) completeAIRequest(requestID, pipeline, modelID string) { + rwm.RWmutex.Lock() + defer rwm.RWmutex.Unlock() + + worker, ok := rwm.requestSessions[requestID] + if !ok { + return + } + + for idx, remoteWorker := range rwm.remoteAIWorkers { + if worker.addr == remoteWorker.addr { + cap, err := PipelineToCapability(pipeline) + if err == nil { + if _, hasCap := rwm.remoteAIWorkers[idx].capabilities.constraints.perCapability[cap]; hasCap { + if _, hasModel := rwm.remoteAIWorkers[idx].capabilities.constraints.perCapability[cap].Models[modelID]; hasModel { + rwm.remoteAIWorkers[idx].capabilities.constraints.perCapability[cap].Models[modelID].Capacity += 1 + } + } + + } + } + } + delete(rwm.requestSessions, requestID) +} + +func removeFromRemoteWorkers(rw *RemoteAIWorker, remoteWorkers []*RemoteAIWorker) []*RemoteAIWorker { + if len(remoteWorkers) == 0 { + // No workers to remove, return + return remoteWorkers + } + + newRemoteWs := make([]*RemoteAIWorker, 0) + for _, t := range remoteWorkers { + if t != rw { + newRemoteWs = append(newRemoteWs, t) + } + } + return newRemoteWs +} + +type RemoteAIWorkerResult struct { + Results interface{} + Files map[string][]byte + Err error + DownloadTime time.Duration +} + +type AIWorkerChan chan *RemoteAIWorkerResult + +func (rwm *RemoteAIWorkerManager) getTaskChan(taskID int64) (AIWorkerChan, error) { + rwm.taskMutex.RLock() + defer rwm.taskMutex.RUnlock() + if tc, ok := rwm.taskChans[taskID]; ok { + return tc, nil + } + return nil, fmt.Errorf("No AI Worker channel") +} + +func (rwm *RemoteAIWorkerManager) addTaskChan() (int64, AIWorkerChan) { + rwm.taskMutex.Lock() + defer rwm.taskMutex.Unlock() + taskID := rwm.taskCount + rwm.taskCount++ + if tc, ok := rwm.taskChans[taskID]; ok { + // should really never happen + glog.V(common.DEBUG).Info("AI Worker channel already exists for ", taskID) + return taskID, tc + } + rwm.taskChans[taskID] = make(AIWorkerChan, 1) + return taskID, rwm.taskChans[taskID] +} + +func (rwm *RemoteAIWorkerManager) removeTaskChan(taskID int64) { + rwm.taskMutex.Lock() + defer rwm.taskMutex.Unlock() + if _, ok := rwm.taskChans[taskID]; !ok { + glog.V(common.DEBUG).Info("AI Worker channel nonexistent for job ", taskID) + return + } + delete(rwm.taskChans, taskID) +} + +// Process does actual AI processing by sending work to remote ai worker and waiting for the result +func (rw *RemoteAIWorker) Process(logCtx context.Context, pipeline string, modelID string, fname string, req AIJobRequestData) (*RemoteAIWorkerResult, error) { + taskID, taskChan := rw.manager.addTaskChan() + defer rw.manager.removeTaskChan(taskID) + + signalEOF := func(err error) (*RemoteAIWorkerResult, error) { + rw.done() + clog.Errorf(logCtx, "Fatal error with remote AI worker=%s taskId=%d pipeline=%s model_id=%s err=%q", rw.addr, taskID, pipeline, modelID, err) + return nil, RemoteAIWorkerFatalError{err} + } + + reqParams, err := json.Marshal(req) + if err != nil { + return nil, err + } + + start := time.Now() + + jobData := &net.AIJobData{ + Pipeline: pipeline, + RequestData: reqParams, + } + msg := &net.NotifyAIJob{ + TaskId: taskID, + AIJobData: jobData, + } + err = rw.stream.Send(msg) + + if err != nil { + return signalEOF(err) + } + + clog.V(common.DEBUG).Infof(logCtx, "Job sent to AI worker worker=%s taskId=%d pipeline=%s model_id=%s", rw.addr, taskID, pipeline, modelID) + // set a minimum timeout to accommodate transport / processing overhead + // TODO: this should be set for each pipeline, using something long for now + dur := aiWorkerRequestTimeout + + ctx, cancel := context.WithTimeout(context.Background(), dur) + defer cancel() + select { + case <-ctx.Done(): + return signalEOF(ErrRemoteWorkerTimeout) + case chanData := <-taskChan: + clog.InfofErr(logCtx, "Successfully received results from remote worker=%s taskId=%d pipeline=%s model_id=%s dur=%v", + rw.addr, taskID, pipeline, modelID, time.Since(start), chanData.Err) + + if monitor.Enabled { + monitor.AIResultDownloaded(logCtx, pipeline, modelID, chanData.DownloadTime) + } + + return chanData, chanData.Err + } +} + +type AIResult struct { + Err error + Result *worker.ImageResponse + Files map[string]string +} + +type AIJobRequestData struct { + InputUrl string `json:"input_url"` + Request interface{} `json:"request"` +} + +// CheckAICapacity verifies if the orchestrator can process a request for a specific pipeline and modelID. +func (orch *orchestrator) CheckAICapacity(pipeline, modelID string) bool { + if orch.node.AIWorker != nil { + // confirm local worker has capacity + return orch.node.AIWorker.HasCapacity(pipeline, modelID) + } else { + // remote workers: RemoteAIWorkerManager only selects remote workers if they have capacity for the pipeline/model + if orch.node.AIWorkerManager != nil { + return orch.node.AIWorkerManager.workerHasCapacity(pipeline, modelID) + } else { + return false + } + } +} + +func (orch *orchestrator) AIResults(tcID int64, res *RemoteAIWorkerResult) { + orch.node.AIWorkerManager.aiResults(tcID, res) +} + +func (rwm *RemoteAIWorkerManager) aiResults(tcID int64, res *RemoteAIWorkerResult) { + remoteChan, err := rwm.getTaskChan(tcID) + if err != nil { + return // do we need to return anything? + } + + remoteChan <- res +} + +func (n *LivepeerNode) saveLocalAIWorkerResults(ctx context.Context, results interface{}, requestID string, contentType string) (interface{}, error) { + ext, _ := common.MimeTypeToExtension(contentType) + fileName := string(RandomManifestID()) + ext + + storage, exists := n.StorageConfigs[requestID] + if !exists { + return nil, errors.New("no storage available for request") + } + + var buf bytes.Buffer + switch resp := results.(type) { + case worker.ImageResponse: + for i, image := range resp.Images { + buf.Reset() + err := worker.ReadImageB64DataUrl(image.Url, &buf) + if err != nil { + // try to load local file (image to video returns local file) + f, err := os.ReadFile(image.Url) + if err != nil { + return nil, err + } + defer os.Remove(image.Url) + + buf = *bytes.NewBuffer(f) + } + + osUrl, err := storage.OS.SaveData(ctx, fileName, bytes.NewBuffer(buf.Bytes()), nil, 0) + if err != nil { + return nil, err + } + + resp.Images[i].Url = osUrl + } + + results = resp + case worker.AudioResponse: + err := worker.ReadAudioB64DataUrl(resp.Audio.Url, &buf) + if err != nil { + return nil, err + } + + osUrl, err := storage.OS.SaveData(ctx, fileName, bytes.NewBuffer(buf.Bytes()), nil, 0) + if err != nil { + return nil, err + } + resp.Audio.Url = osUrl + + results = resp + } + + //no file response to save, response is text + return results, nil +} + +func (n *LivepeerNode) saveRemoteAIWorkerResults(ctx context.Context, results *RemoteAIWorkerResult, requestID string) (*RemoteAIWorkerResult, error) { + if drivers.NodeStorage == nil { + return nil, fmt.Errorf("Missing local storage") + } + // save the file data to node and provide url for download + storage, exists := n.StorageConfigs[requestID] + if !exists { + return nil, errors.New("no storage available for request") + } + // worker.ImageResponse used by ***-to-image and image-to-video require saving binary data for download + // worker.AudioResponse used to text-to-speech also requires saving binary data for download + // other pipelines do not require saving data since they are text responses + switch resp := results.Results.(type) { + case worker.ImageResponse: + for idx := range resp.Images { + fileName := resp.Images[idx].Url + osUrl, err := storage.OS.SaveData(ctx, fileName, bytes.NewReader(results.Files[fileName]), nil, 0) + if err != nil { + return nil, err + } + + resp.Images[idx].Url = osUrl + delete(results.Files, fileName) + } + + // update results for url updates + results.Results = resp + case worker.AudioResponse: + fileName := resp.Audio.Url + osUrl, err := storage.OS.SaveData(ctx, fileName, bytes.NewReader(results.Files[fileName]), nil, 0) + if err != nil { + return nil, err + } + + resp.Audio.Url = osUrl + delete(results.Files, fileName) + + results.Results = resp + } + + // no file response to save, response is text + return results, nil +} + +func (orch *orchestrator) TextToImage(ctx context.Context, requestID string, req worker.GenTextToImageJSONRequestBody) (interface{}, error) { + // local AIWorker processes job if combined orchestrator/ai worker + if orch.node.AIWorker != nil { + workerResp, err := orch.node.TextToImage(ctx, req) + if err == nil { + return orch.node.saveLocalAIWorkerResults(ctx, *workerResp, requestID, "image/png") + } else { + clog.Errorf(ctx, "Error processing with local ai worker err=%q", err) + if monitor.Enabled { + monitor.AIResultSaveError(ctx, "text-to-image", *req.ModelId, string(monitor.SegmentUploadErrorUnknown)) + } + return nil, err + } + } + + // remote ai worker proceses job + res, err := orch.node.AIWorkerManager.Process(ctx, requestID, "text-to-image", *req.ModelId, "", AIJobRequestData{Request: req}) + if err != nil { + return nil, err + } + + res, err = orch.node.saveRemoteAIWorkerResults(ctx, res, requestID) + if err != nil { + clog.Errorf(ctx, "Error saving remote ai result err=%q", err) + if monitor.Enabled { + monitor.AIResultSaveError(ctx, "text-to-image", *req.ModelId, string(monitor.SegmentUploadErrorUnknown)) + } + return nil, err + } + + return res.Results, nil +} + +func (orch *orchestrator) ImageToImage(ctx context.Context, requestID string, req worker.GenImageToImageMultipartRequestBody) (interface{}, error) { + // local AIWorker processes job if combined orchestrator/ai worker + if orch.node.AIWorker != nil { + workerResp, err := orch.node.ImageToImage(ctx, req) + if err == nil { + return orch.node.saveLocalAIWorkerResults(ctx, *workerResp, requestID, "image/png") + } else { + clog.Errorf(ctx, "Error processing with local ai worker err=%q", err) + if monitor.Enabled { + monitor.AIResultSaveError(ctx, "image-to-image", *req.ModelId, string(monitor.SegmentUploadErrorUnknown)) + } + return nil, err + } + } + + // remote ai worker proceses job + imgBytes, err := req.Image.Bytes() + if err != nil { + return nil, err + } + + inputUrl, err := orch.SaveAIRequestInput(ctx, requestID, imgBytes) + if err != nil { + return nil, err + } + req.Image.InitFromBytes(nil, "") // remove image data + + res, err := orch.node.AIWorkerManager.Process(ctx, requestID, "image-to-image", *req.ModelId, inputUrl, AIJobRequestData{Request: req, InputUrl: inputUrl}) + if err != nil { + return nil, err + } + + res, err = orch.node.saveRemoteAIWorkerResults(ctx, res, requestID) + if err != nil { + clog.Errorf(ctx, "Error processing with local ai worker err=%q", err) + if monitor.Enabled { + monitor.AIResultSaveError(ctx, "image-to-image", *req.ModelId, string(monitor.SegmentUploadErrorUnknown)) + } + return nil, err + } + + return res.Results, nil +} + +func (orch *orchestrator) ImageToVideo(ctx context.Context, requestID string, req worker.GenImageToVideoMultipartRequestBody) (interface{}, error) { + // local AIWorker processes job if combined orchestrator/ai worker + if orch.node.AIWorker != nil { + workerResp, err := orch.node.ImageToVideo(ctx, req) + if err == nil { + return orch.node.saveLocalAIWorkerResults(ctx, *workerResp, requestID, "video/mp4") + } else { + clog.Errorf(ctx, "Error processing with local ai worker err=%q", err) + if monitor.Enabled { + monitor.AIResultSaveError(ctx, "image-to-video", *req.ModelId, string(monitor.SegmentUploadErrorUnknown)) + } + return nil, err + } + } + + // remote ai worker proceses job + imgBytes, err := req.Image.Bytes() + if err != nil { + return nil, err + } + + inputUrl, err := orch.SaveAIRequestInput(ctx, requestID, imgBytes) + if err != nil { + return nil, err + } + req.Image.InitFromBytes(nil, "") // remove image data + + res, err := orch.node.AIWorkerManager.Process(ctx, requestID, "image-to-video", *req.ModelId, inputUrl, AIJobRequestData{Request: req, InputUrl: inputUrl}) + if err != nil { + return nil, err + } + + res, err = orch.node.saveRemoteAIWorkerResults(ctx, res, requestID) + if err != nil { + clog.Errorf(ctx, "Error saving remote ai result err=%q", err) + if monitor.Enabled { + monitor.AIResultSaveError(ctx, "image-to-video", *req.ModelId, string(monitor.SegmentUploadErrorUnknown)) + } + return nil, err + } + + return res.Results, nil +} + +func (orch *orchestrator) Upscale(ctx context.Context, requestID string, req worker.GenUpscaleMultipartRequestBody) (interface{}, error) { + // local AIWorker processes job if combined orchestrator/ai worker + if orch.node.AIWorker != nil { + workerResp, err := orch.node.Upscale(ctx, req) + if err == nil { + return orch.node.saveLocalAIWorkerResults(ctx, *workerResp, requestID, "image/png") + } else { + clog.Errorf(ctx, "Error processing with local ai worker err=%q", err) + if monitor.Enabled { + monitor.AIResultSaveError(ctx, "upscale", *req.ModelId, string(monitor.SegmentUploadErrorUnknown)) + } + return nil, err + } + } + + // remote ai worker proceses job + imgBytes, err := req.Image.Bytes() + if err != nil { + return nil, err + } + + inputUrl, err := orch.SaveAIRequestInput(ctx, requestID, imgBytes) + if err != nil { + return nil, err + } + req.Image.InitFromBytes(nil, "") // remove image data + + res, err := orch.node.AIWorkerManager.Process(ctx, requestID, "upscale", *req.ModelId, inputUrl, AIJobRequestData{Request: req, InputUrl: inputUrl}) + if err != nil { + return nil, err + } + + res, err = orch.node.saveRemoteAIWorkerResults(ctx, res, requestID) + if err != nil { + clog.Errorf(ctx, "Error saving remote ai result err=%q", err) + if monitor.Enabled { + monitor.AIResultSaveError(ctx, "upscale", *req.ModelId, string(monitor.SegmentUploadErrorUnknown)) + } + return nil, err + } + + return res.Results, nil +} + +func (orch *orchestrator) AudioToText(ctx context.Context, requestID string, req worker.GenAudioToTextMultipartRequestBody) (interface{}, error) { + // local AIWorker processes job if combined orchestrator/ai worker + if orch.node.AIWorker != nil { + // no file response to save, response is text sent back to gateway + return orch.node.AudioToText(ctx, req) + } + + // remote ai worker proceses job + audioBytes, err := req.Audio.Bytes() + if err != nil { + return nil, err + } + + inputUrl, err := orch.SaveAIRequestInput(ctx, requestID, audioBytes) + if err != nil { + return nil, err + } + req.Audio.InitFromBytes(nil, "") // remove audio data + + res, err := orch.node.AIWorkerManager.Process(ctx, requestID, "audio-to-text", *req.ModelId, inputUrl, AIJobRequestData{Request: req, InputUrl: inputUrl}) + if err != nil { + return nil, err + } + + res, err = orch.node.saveRemoteAIWorkerResults(ctx, res, requestID) + if err != nil { + clog.Errorf(ctx, "Error saving remote ai result err=%q", err) + if monitor.Enabled { + monitor.AIResultSaveError(ctx, "audio-to-text", *req.ModelId, string(monitor.SegmentUploadErrorUnknown)) + } + return nil, err + } + + return res.Results, nil +} + +func (orch *orchestrator) SegmentAnything2(ctx context.Context, requestID string, req worker.GenSegmentAnything2MultipartRequestBody) (interface{}, error) { + // local AIWorker processes job if combined orchestrator/ai worker + if orch.node.AIWorker != nil { + // no file response to save, response is text sent back to gateway + return orch.node.SegmentAnything2(ctx, req) + } + + // remote ai worker proceses job + imgBytes, err := req.Image.Bytes() + if err != nil { + return nil, err + } + + inputUrl, err := orch.SaveAIRequestInput(ctx, requestID, imgBytes) + if err != nil { + return nil, err + } + req.Image.InitFromBytes(nil, "") // remove image data + + res, err := orch.node.AIWorkerManager.Process(ctx, requestID, "segment-anything-2", *req.ModelId, inputUrl, AIJobRequestData{Request: req, InputUrl: inputUrl}) + if err != nil { + return nil, err + } + + res, err = orch.node.saveRemoteAIWorkerResults(ctx, res, requestID) + if err != nil { + clog.Errorf(ctx, "Error saving remote ai result err=%q", err) + if monitor.Enabled { + monitor.AIResultSaveError(ctx, "segment-anything-2", *req.ModelId, string(monitor.SegmentUploadErrorUnknown)) + } + return nil, err + } + + return res.Results, nil +} + +// Return type is LLMResponse, but a stream is available as well as chan(string) +func (orch *orchestrator) LLM(ctx context.Context, requestID string, req worker.GenLLMFormdataRequestBody) (interface{}, error) { + // local AIWorker processes job if combined orchestrator/ai worker + if orch.node.AIWorker != nil { + // no file response to save, response is text sent back to gateway + return orch.node.AIWorker.LLM(ctx, req) + } + + res, err := orch.node.AIWorkerManager.Process(ctx, requestID, "llm", *req.ModelId, "", AIJobRequestData{Request: req}) + if err != nil { + return nil, err + } + + // non streaming response + if _, ok := res.Results.(worker.LLMResponse); ok { + res, err = orch.node.saveRemoteAIWorkerResults(ctx, res, requestID) + if err != nil { + clog.Errorf(ctx, "Error saving remote ai result err=%q", err) + if monitor.Enabled { + monitor.AIResultSaveError(ctx, "llm", *req.ModelId, string(monitor.SegmentUploadErrorUnknown)) + } + return nil, err + + } + } + + return res.Results, nil +} + +func (orch *orchestrator) ImageToText(ctx context.Context, requestID string, req worker.GenImageToTextMultipartRequestBody) (interface{}, error) { + // local AIWorker processes job if combined orchestrator/ai worker + if orch.node.AIWorker != nil { + // no file response to save, response is text sent back to gateway + return orch.node.ImageToText(ctx, req) + } + + // remote ai worker proceses job + imageBytes, err := req.Image.Bytes() + if err != nil { + return nil, err + } + + inputUrl, err := orch.SaveAIRequestInput(ctx, requestID, imageBytes) + if err != nil { + return nil, err + } + req.Image.InitFromBytes(nil, "") + + res, err := orch.node.AIWorkerManager.Process(ctx, requestID, "image-to-text", *req.ModelId, inputUrl, AIJobRequestData{Request: req, InputUrl: inputUrl}) + if err != nil { + return nil, err + } + + res, err = orch.node.saveRemoteAIWorkerResults(ctx, res, requestID) + if err != nil { + clog.Errorf(ctx, "Error saving remote ai result err=%q", err) + if monitor.Enabled { + monitor.AIResultSaveError(ctx, "image-to-text", *req.ModelId, string(monitor.SegmentUploadErrorUnknown)) + } + return nil, err + } + + return res.Results, nil +} + +func (orch *orchestrator) TextToSpeech(ctx context.Context, requestID string, req worker.GenTextToSpeechJSONRequestBody) (interface{}, error) { + // local AIWorker processes job if combined orchestrator/ai worker + if orch.node.AIWorker != nil { + workerResp, err := orch.node.TextToSpeech(ctx, req) + if err == nil { + return orch.node.saveLocalAIWorkerResults(ctx, *workerResp, requestID, "audio/wav") + } else { + clog.Errorf(ctx, "Error processing with local ai worker err=%q", err) + if monitor.Enabled { + monitor.AIResultSaveError(ctx, "text-to-speech", *req.ModelId, string(monitor.SegmentUploadErrorUnknown)) + } + return nil, err + } + } + + // remote ai worker proceses job + res, err := orch.node.AIWorkerManager.Process(ctx, requestID, "text-to-speech", *req.ModelId, "", AIJobRequestData{Request: req}) + if err != nil { + return nil, err + } + + res, err = orch.node.saveRemoteAIWorkerResults(ctx, res, requestID) + if err != nil { + clog.Errorf(ctx, "Error saving remote ai result err=%q", err) + if monitor.Enabled { + monitor.AIResultSaveError(ctx, "text-to-speech", *req.ModelId, string(monitor.SegmentUploadErrorUnknown)) + } + return nil, err + } + + return res.Results, nil +} + +// only used for sending work to remote AI worker +func (orch *orchestrator) SaveAIRequestInput(ctx context.Context, requestID string, fileData []byte) (string, error) { + node := orch.node + if drivers.NodeStorage == nil { + return "", fmt.Errorf("Missing local storage") + } + + storage, exists := node.StorageConfigs[requestID] + if !exists { + return "", errors.New("storage does not exist for request") + } + + url, err := storage.OS.SaveData(ctx, string(RandomManifestID())+".tempfile", bytes.NewReader(fileData), nil, 0) + if err != nil { + return "", err + } + + return url, nil +} + +func (o *orchestrator) GetStorageForRequest(requestID string) (drivers.OSSession, bool) { + session, exists := o.node.getStorageForRequest(requestID) + if exists { + return session, true + } else { + return nil, false + } +} + +func (n *LivepeerNode) getStorageForRequest(requestID string) (drivers.OSSession, bool) { + session, exists := n.StorageConfigs[requestID] + return session.OS, exists +} + +func (o *orchestrator) CreateStorageForRequest(requestID string) error { + return o.node.createStorageForRequest(requestID) +} + +func (n *LivepeerNode) createStorageForRequest(requestID string) error { + n.storageMutex.Lock() + defer n.storageMutex.Unlock() + _, exists := n.StorageConfigs[requestID] + if !exists { + os := drivers.NodeStorage.NewSession(requestID) + n.StorageConfigs[requestID] = &transcodeConfig{OS: os, LocalOS: os} + // TODO: Figure out a better way to end the OS session after a timeout than creating a new goroutine per request? + go func() { + ctx, cancel := context.WithTimeout(context.Background(), aiWorkerResultsTimeout) + defer cancel() + <-ctx.Done() + os.EndSession() + clog.Infof(ctx, "Ended session for requestID=%v", requestID) + }() + } + + return nil +} + +/* + * Methods used to process AI job requests on a AI Worker. + */ + +func (n *LivepeerNode) TextToImage(ctx context.Context, req worker.GenTextToImageJSONRequestBody) (*worker.ImageResponse, error) { + return n.AIWorker.TextToImage(ctx, req) +} + +func (n *LivepeerNode) ImageToImage(ctx context.Context, req worker.GenImageToImageMultipartRequestBody) (*worker.ImageResponse, error) { + return n.AIWorker.ImageToImage(ctx, req) +} + +func (n *LivepeerNode) Upscale(ctx context.Context, req worker.GenUpscaleMultipartRequestBody) (*worker.ImageResponse, error) { + return n.AIWorker.Upscale(ctx, req) +} + +func (n *LivepeerNode) AudioToText(ctx context.Context, req worker.GenAudioToTextMultipartRequestBody) (*worker.TextResponse, error) { + return n.AIWorker.AudioToText(ctx, req) +} + +func (n *LivepeerNode) ImageToText(ctx context.Context, req worker.GenImageToTextMultipartRequestBody) (*worker.ImageToTextResponse, error) { + return n.AIWorker.ImageToText(ctx, req) +} + +func (n *LivepeerNode) ImageToVideo(ctx context.Context, req worker.GenImageToVideoMultipartRequestBody) (*worker.ImageResponse, error) { + // We might support generating more than one video in the future (i.e. multiple input images/prompts) + numVideos := 1 + + // Generate frames + start := time.Now() + resp, err := n.AIWorker.ImageToVideo(ctx, req) + if err != nil { + return nil, err + } + + if len(resp.Frames) != numVideos { + return nil, fmt.Errorf("unexpected number of image-to-video outputs expected=%v actual=%v", numVideos, len(resp.Frames)) + } + + took := time.Since(start) + clog.V(common.DEBUG).Infof(ctx, "Generating frames took=%v", took) + + sessionID := string(RandomManifestID()) + framerate := 7 + if req.Fps != nil { + framerate = *req.Fps + } + inProfile := ffmpeg.VideoProfile{ + Framerate: uint(framerate), + FramerateDen: 1, + } + height := 576 + if req.Height != nil { + height = *req.Height + } + width := 1024 + if req.Width != nil { + width = *req.Width + } + outProfile := ffmpeg.VideoProfile{ + Name: "image-to-video", + Resolution: fmt.Sprintf("%vx%v", width, height), + Bitrate: "6000k", + Format: ffmpeg.FormatMP4, + } + // HACK: Re-use worker.ImageResponse to return results + // Transcode frames into segments. + videos := make([]worker.Media, len(resp.Frames)) + for i, batch := range resp.Frames { + // Create slice of frame urls for a batch + urls := make([]string, len(batch)) + for j, frame := range batch { + urls[j] = frame.Url + } + + // Transcode slice of frame urls into a segment + res := n.transcodeFrames(ctx, sessionID, urls, inProfile, outProfile) + if res.Err != nil { + return nil, res.Err + } + + // Assume only single rendition right now + seg := res.TranscodeData.Segments[0] + resultFile := fmt.Sprintf("%v.mp4", RandomManifestID()) + fname := path.Join(n.WorkDir, resultFile) + if err := os.WriteFile(fname, seg.Data, 0644); err != nil { + clog.Errorf(ctx, "AI Worker cannot write file err=%q", err) + return nil, err + } + + videos[i] = worker.Media{ + Url: fname, + } + + // NOTE: Seed is consistent for video; NSFW check applies to first frame only. + if len(batch) > 0 { + videos[i].Nsfw = batch[0].Nsfw + videos[i].Seed = batch[0].Seed + } + } + + return &worker.ImageResponse{Images: videos}, nil +} + +func (n *LivepeerNode) SegmentAnything2(ctx context.Context, req worker.GenSegmentAnything2MultipartRequestBody) (*worker.MasksResponse, error) { + return n.AIWorker.SegmentAnything2(ctx, req) +} + +func (n *LivepeerNode) LLM(ctx context.Context, req worker.GenLLMFormdataRequestBody) (interface{}, error) { + return n.AIWorker.LLM(ctx, req) +} + +func (n *LivepeerNode) TextToSpeech(ctx context.Context, req worker.GenTextToSpeechJSONRequestBody) (*worker.AudioResponse, error) { + return n.AIWorker.TextToSpeech(ctx, req) +} + +// transcodeFrames converts a series of image URLs into a video segment for the image-to-video pipeline. +func (n *LivepeerNode) transcodeFrames(ctx context.Context, sessionID string, urls []string, inProfile ffmpeg.VideoProfile, outProfile ffmpeg.VideoProfile) *TranscodeResult { + ctx = clog.AddOrchSessionID(ctx, sessionID) + + var fnamep *string + terr := func(err error) *TranscodeResult { + if fnamep != nil { + if err := os.RemoveAll(*fnamep); err != nil { + clog.Errorf(ctx, "Transcoder failed to cleanup %v", *fnamep) + } + } + return &TranscodeResult{Err: err} + } + + // We only support base64 png data urls right now + // We will want to support HTTP and file urls later on as well + dirPath := path.Join(n.WorkDir, "input", sessionID+"_"+string(RandomManifestID())) + fnamep = &dirPath + if err := os.MkdirAll(dirPath, 0700); err != nil { + clog.Errorf(ctx, "Transcoder cannot create frames dir err=%q", err) + return terr(err) + } + for i, url := range urls { + fname := path.Join(dirPath, strconv.Itoa(i)+".png") + if err := worker.SaveImageB64DataUrl(url, fname); err != nil { + clog.Errorf(ctx, "Transcoder failed to save image from url err=%q", err) + return terr(err) + } + } + + // Use local software transcoder instead of node's configured transcoder + // because if the node is using a nvidia transcoder there may be sporadic + // CUDA operation not permitted errors that are difficult to debug. + // The majority of the execution time for image-to-video is the frame generation + // so slower software transcoding should not be a big deal for now. + transcoder := NewLocalTranscoder(n.WorkDir) + + md := &SegTranscodingMetadata{ + Fname: path.Join(dirPath, "%d.png"), + ProfileIn: inProfile, + Profiles: []ffmpeg.VideoProfile{ + outProfile, + }, + AuthToken: &net.AuthToken{SessionId: sessionID}, + } + + los := drivers.NodeStorage.NewSession(sessionID) + + // TODO: Figure out a better way to end the OS session after a timeout than creating a new goroutine per request? + go func() { + ctx, cancel := context.WithTimeout(context.Background(), aiWorkerTranscodeLoopTimeout) + defer cancel() + <-ctx.Done() + los.EndSession() + clog.Infof(ctx, "Ended image-to-video session sessionID=%v", sessionID) + }() + + start := time.Now() + tData, err := transcoder.Transcode(ctx, md) + if err != nil { + if _, ok := err.(UnrecoverableError); ok { + panic(err) + } + clog.Errorf(ctx, "Error transcoding frames dirPath=%s err=%q", dirPath, err) + return terr(err) + } + + took := time.Since(start) + clog.V(common.DEBUG).Infof(ctx, "Transcoding frames took=%v", took) + + transcoder.EndTranscodingSession(md.AuthToken.SessionId) + + tSegments := tData.Segments + if len(tSegments) != len(md.Profiles) { + clog.Errorf(ctx, "Did not receive the correct number of transcoded segments; got %v expected %v", len(tSegments), + len(md.Profiles)) + return terr(fmt.Errorf("MismatchedSegments")) + } + + // Prepare the result object + var tr TranscodeResult + segHashes := make([][]byte, len(tSegments)) + + for i := range md.Profiles { + if tSegments[i].Data == nil || len(tSegments[i].Data) < 25 { + clog.Errorf(ctx, "Cannot find transcoded segment for bytes=%d", len(tSegments[i].Data)) + return terr(fmt.Errorf("ZeroSegments")) + } + clog.V(common.DEBUG).Infof(ctx, "Transcoded segment profile=%s bytes=%d", + md.Profiles[i].Name, len(tSegments[i].Data)) + hash := crypto.Keccak256(tSegments[i].Data) + segHashes[i] = hash + } + if err := os.RemoveAll(dirPath); err != nil { + clog.Errorf(ctx, "Transcoder failed to cleanup %v", dirPath) + } + tr.OS = los + tr.TranscodeData = tData + + if n == nil || n.Eth == nil { + return &tr + } + + segHash := crypto.Keccak256(segHashes...) + tr.Sig, tr.Err = n.Eth.Sign(segHash) + if tr.Err != nil { + clog.Errorf(ctx, "Unable to sign hash of transcoded segment hashes err=%q", tr.Err) + } + return &tr +} diff --git a/core/capabilities.go b/core/capabilities.go index a4666417b1..d2425fa988 100644 --- a/core/capabilities.go +++ b/core/capabilities.go @@ -12,11 +12,24 @@ import ( "github.com/livepeer/lpms/ffmpeg" ) +type ModelConstraints map[string]*ModelConstraint + +type ModelConstraint struct { + Warm bool + Capacity int +} + type Capability int type CapabilityString []uint64 type Constraints struct { - minVersion string + minVersion string + perCapability PerCapabilityConstraints +} +type CapabilityConstraints struct { + // Models contains a *ModelConstraint for each supported model ID + Models ModelConstraints } +type PerCapabilityConstraints map[Capability]*CapabilityConstraints type Capabilities struct { bitstring CapabilityString mandatories CapabilityString @@ -30,37 +43,46 @@ type CapabilityTest struct { outProfile ffmpeg.VideoProfile } -// Do not rearrange these values! Only append. const ( - Capability_Invalid Capability = iota - 2 - Capability_Unused - Capability_H264 - Capability_MPEGTS - Capability_MP4 - Capability_FractionalFramerates - Capability_StorageDirect - Capability_StorageS3 - Capability_StorageGCS - Capability_ProfileH264Baseline - Capability_ProfileH264Main - Capability_ProfileH264High - Capability_ProfileH264ConstrainedHigh - Capability_GOP - Capability_AuthToken - Capability_SceneClassification // Deprecated, but can't remove because of Capability ordering - Capability_MPEG7VideoSignature - Capability_HEVC_Decode - Capability_HEVC_Encode - Capability_VP8_Decode - Capability_VP9_Decode - Capability_VP8_Encode - Capability_VP9_Encode - Capability_H264_Decode_444_8bit - Capability_H264_Decode_422_8bit - Capability_H264_Decode_444_10bit - Capability_H264_Decode_422_10bit - Capability_H264_Decode_420_10bit - Capability_SegmentSlicing + Capability_Invalid Capability = -2 + Capability_Unused Capability = -1 + Capability_H264 Capability = 0 + Capability_MPEGTS Capability = 1 + Capability_MP4 Capability = 2 + Capability_FractionalFramerates Capability = 3 + Capability_StorageDirect Capability = 4 + Capability_StorageS3 Capability = 5 + Capability_StorageGCS Capability = 6 + Capability_ProfileH264Baseline Capability = 7 + Capability_ProfileH264Main Capability = 8 + Capability_ProfileH264High Capability = 9 + Capability_ProfileH264ConstrainedHigh Capability = 10 + Capability_GOP Capability = 11 + Capability_AuthToken Capability = 12 + Capability_SceneClassification Capability = 13 // Deprecated, but can't remove because of Capability ordering + Capability_MPEG7VideoSignature Capability = 14 + Capability_HEVC_Decode Capability = 15 + Capability_HEVC_Encode Capability = 16 + Capability_VP8_Decode Capability = 17 + Capability_VP9_Decode Capability = 18 + Capability_VP8_Encode Capability = 19 + Capability_VP9_Encode Capability = 20 + Capability_H264_Decode_444_8bit Capability = 21 + Capability_H264_Decode_422_8bit Capability = 22 + Capability_H264_Decode_444_10bit Capability = 23 + Capability_H264_Decode_422_10bit Capability = 24 + Capability_H264_Decode_420_10bit Capability = 25 + Capability_SegmentSlicing Capability = 26 + Capability_TextToImage Capability = 27 + Capability_ImageToImage Capability = 28 + Capability_ImageToVideo Capability = 29 + Capability_Upscale Capability = 30 + Capability_AudioToText Capability = 31 + Capability_SegmentAnything2 Capability = 32 + Capability_LLM Capability = 33 + Capability_ImageToText Capability = 34 + Capability_LiveVideoToVideo Capability = 35 + Capability_TextToSpeech Capability = 36 ) var CapabilityNameLookup = map[Capability]string{ @@ -92,6 +114,16 @@ var CapabilityNameLookup = map[Capability]string{ Capability_H264_Decode_422_10bit: "H264 Decode YUV422 10-bit", Capability_H264_Decode_420_10bit: "H264 Decode YUV420 10-bit", Capability_SegmentSlicing: "Segment slicing", + Capability_TextToImage: "Text to image", + Capability_ImageToImage: "Image to image", + Capability_ImageToVideo: "Image to video", + Capability_Upscale: "Upscale", + Capability_AudioToText: "Audio to text", + Capability_SegmentAnything2: "Segment anything 2", + Capability_LLM: "Llm", + Capability_ImageToText: "Image to text", + Capability_LiveVideoToVideo: "Live video to video", + Capability_TextToSpeech: "Text to speech", } var CapabilityTestLookup = map[Capability]CapabilityTest{ @@ -177,6 +209,14 @@ func OptionalCapabilities() []Capability { Capability_H264_Decode_444_10bit, Capability_H264_Decode_422_10bit, Capability_H264_Decode_420_10bit, + Capability_TextToImage, + Capability_ImageToImage, + Capability_ImageToVideo, + Capability_Upscale, + Capability_AudioToText, + Capability_SegmentAnything2, + Capability_ImageToText, + Capability_TextToSpeech, } } @@ -226,6 +266,43 @@ func (c1 CapabilityString) CompatibleWith(c2 CapabilityString) bool { return true } +func (c1 PerCapabilityConstraints) CompatibleWith(c2 PerCapabilityConstraints) bool { + for c1Cap, c1Constraints := range c1 { + c2Constraints, ok := c2[c1Cap] + if !ok { + // No constraints on this capability so assume compatibility + continue + } + + if !c1Constraints.CompatibleWith(c2Constraints) { + return false + } + } + + return true +} + +func (c1 *CapabilityConstraints) CompatibleWith(c2 *CapabilityConstraints) bool { + return c1.Models.CompatibleWith(c2.Models) +} + +func (c1 ModelConstraints) CompatibleWith(c2 ModelConstraints) bool { + for c1ModelID, c1ModelConstraint := range c1 { + c2ModelConstraint, ok := c2[c1ModelID] + if !ok { + // c2 does not support this model ID so it is incompatible + return false + } + + if c1ModelConstraint.Warm && !c2ModelConstraint.Warm { + // c1 requires the model ID to be warm, but c2's model ID is not warm so it is incompatible + return false + } + } + + return true +} + type chromaDepth struct { Chroma ffmpeg.ChromaSubsampling Depth ffmpeg.ColorDepthBits @@ -386,6 +463,11 @@ func (bcast *Capabilities) CompatibleWith(orch *net.Capabilities) bool { return false } + orchCapabilityConstraints := CapabilitiesFromNetCapabilities(orch).constraints.perCapability + if !bcast.constraints.perCapability.CompatibleWith(orchCapabilityConstraints) { + return false + } + return bcast.bitstring.CompatibleWith(orch.Bitstring) } @@ -395,10 +477,25 @@ func (c *Capabilities) ToNetCapabilities() *net.Capabilities { } c.mutex.Lock() defer c.mutex.Unlock() - netCaps := &net.Capabilities{Bitstring: c.bitstring, Mandatories: c.mandatories, Version: c.version, Capacities: make(map[uint32]uint32), Constraints: &net.Capabilities_Constraints{MinVersion: c.constraints.minVersion}} + netCaps := &net.Capabilities{Bitstring: c.bitstring, Mandatories: c.mandatories, Version: c.version, Capacities: make(map[uint32]uint32), Constraints: &net.Capabilities_Constraints{MinVersion: c.constraints.minVersion, PerCapability: make(map[uint32]*net.Capabilities_CapabilityConstraints)}} for capability, capacity := range c.capacities { netCaps.Capacities[uint32(capability)] = uint32(capacity) } + if c.constraints.perCapability != nil { + for capability, constraints := range c.constraints.perCapability { + models := make(map[string]*net.Capabilities_CapabilityConstraints_ModelConstraint) + for modelID, modelConstraint := range constraints.Models { + models[modelID] = &net.Capabilities_CapabilityConstraints_ModelConstraint{ + Warm: modelConstraint.Warm, + Capacity: uint32(modelConstraint.Capacity), + } + } + + netCaps.Constraints.PerCapability[uint32(capability)] = &net.Capabilities_CapabilityConstraints{ + Models: models, + } + } + } return netCaps } @@ -411,7 +508,7 @@ func CapabilitiesFromNetCapabilities(caps *net.Capabilities) *Capabilities { mandatories: caps.Mandatories, capacities: make(map[Capability]int), version: caps.Version, - constraints: Constraints{minVersion: caps.Constraints.GetMinVersion()}, + constraints: Constraints{minVersion: caps.Constraints.GetMinVersion(), perCapability: make(PerCapabilityConstraints)}, } if caps.Capacities == nil || len(caps.Capacities) == 0 { // build capacities map if not present (struct received from previous versions) @@ -428,11 +525,25 @@ func CapabilitiesFromNetCapabilities(caps *net.Capabilities) *Capabilities { coreCaps.capacities[Capability(capabilityInt)] = int(capacity) } } + + if caps.Constraints != nil && caps.Constraints.PerCapability != nil { + for capabilityInt, constraints := range caps.Constraints.PerCapability { + models := make(map[string]*ModelConstraint) + for modelID, modelConstraint := range constraints.Models { + models[modelID] = &ModelConstraint{Warm: modelConstraint.Warm, Capacity: int(modelConstraint.Capacity)} + } + + coreCaps.constraints.perCapability[Capability(capabilityInt)] = &CapabilityConstraints{ + Models: models, + } + } + } + return coreCaps } func NewCapabilities(caps []Capability, m []Capability) *Capabilities { - c := &Capabilities{capacities: make(map[Capability]int), version: LivepeerVersion} + c := &Capabilities{capacities: make(map[Capability]int), constraints: Constraints{perCapability: make(PerCapabilityConstraints)}, version: LivepeerVersion} if len(caps) > 0 { c.bitstring = NewCapabilityString(caps) // initialize capacities to 1 by default, mandatory capabilities doesn't have capacities @@ -510,6 +621,14 @@ func CapabilityToName(capability Capability) (string, error) { return capName, nil } +func (c Capability) String() string { + name, err := CapabilityToName(c) + if err != nil { + return fmt.Sprintf("%d", int(c)) + } + return name +} + func HasCapability(caps []Capability, capability Capability) bool { for _, c := range caps { if capability == c { @@ -619,6 +738,19 @@ func (bcast *Capabilities) LegacyOnly() bool { return bcast.bitstring.CompatibleWith(legacyCapabilityString) } +func (bcast *Capabilities) SetPerCapabilityConstraints(constraints PerCapabilityConstraints) { + if bcast != nil { + bcast.constraints.perCapability = constraints + } +} + +func (bcast *Capabilities) PerCapability() PerCapabilityConstraints { + if bcast != nil { + return bcast.constraints.perCapability + } + return nil +} + func (bcast *Capabilities) SetMinVersionConstraint(minVersionConstraint string) { if bcast != nil { bcast.constraints.minVersion = minVersionConstraint diff --git a/core/capabilities_test.go b/core/capabilities_test.go index ae0880301b..09fb1bb973 100644 --- a/core/capabilities_test.go +++ b/core/capabilities_test.go @@ -339,7 +339,7 @@ func TestCapability_CompatibleWithNetCap(t *testing.T) { orch.version = "0.4.0" assert.False(bcast.CompatibleWith(orch.ToNetCapabilities())) - // broadcaster is not compatible with orchestrator - the same version + // broadcaster is compatible with orchestrator - the same version orch = NewCapabilities(nil, nil) bcast = NewCapabilities(nil, nil) bcast.constraints.minVersion = "0.4.1" @@ -396,26 +396,35 @@ type stubOS struct { storageType int32 } +func (os *stubOS) OS() drivers.OSDriver { + return nil +} +func (os *stubOS) SaveData(context.Context, string, io.Reader, *drivers.FileProperties, time.Duration) (string, error) { + return "", nil +} +func (os *stubOS) EndSession() {} func (os *stubOS) GetInfo() *drivers.OSInfo { if os.storageType == stubOSMagic { return nil } return &drivers.OSInfo{StorageType: drivers.OSInfo_StorageType(os.storageType)} } -func (os *stubOS) EndSession() {} -func (os *stubOS) SaveData(context.Context, string, io.Reader, map[string]string, time.Duration) (string, error) { - return "", nil -} func (os *stubOS) IsExternal() bool { return false } func (os *stubOS) IsOwn(url string) bool { return true } func (os *stubOS) ListFiles(ctx context.Context, prefix, delim string) (drivers.PageInfo, error) { return nil, nil } +func (os *stubOS) DeleteFile(ctx context.Context, name string) error { + return nil +} func (os *stubOS) ReadData(ctx context.Context, name string) (*drivers.FileInfoReader, error) { return nil, nil } -func (os *stubOS) OS() drivers.OSDriver { - return nil +func (os *stubOS) ReadDataRange(ctx context.Context, name, byteRange string) (*drivers.FileInfoReader, error) { + return nil, nil +} +func (os *stubOS) Presign(name string, expire time.Duration) (string, error) { + return "", nil } func TestCapability_StorageToCapability(t *testing.T) { @@ -448,7 +457,7 @@ func TestCapability_ProfileToCapability(t *testing.T) { // iterate through lpms-defined profiles to ensure all are accounted for // need to put into a slice and sort to ensure consistent ordering profs := []int{} - for k, _ := range ffmpeg.ProfileParameters { + for k := range ffmpeg.ProfileParameters { profs = append(profs, int(k)) } sort.Ints(profs) @@ -621,3 +630,126 @@ func TestLiveeerVersionCompatibleWith(t *testing.T) { }) } } + +func TestCapability_String(t *testing.T) { + var unknownCap Capability = -100 + tests := []struct { + name string + c Capability + want string + }{ + { + name: "Capability_TextToImage", + c: Capability_TextToImage, + want: "Text to image", + }, + { + name: "Unknown", + c: unknownCap, + want: "-100", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + assert.Equal(t, tt.want, tt.c.String()) + }) + } +} + +func TestCapabilities_CapabilityConstraints(t *testing.T) { + assert := assert.New(t) + capabilities := []Capability{Capability_TextToImage} + mandatories := []Capability{4} + + // create model constraints + model_id1 := "Model1" + model_id2 := "Model2" + constraints := make(PerCapabilityConstraints) + constraints[Capability_TextToImage] = &CapabilityConstraints{ + Models: make(ModelConstraints), + } + model1Constraint := ModelConstraint{Warm: true, Capacity: 1} + constraints[Capability_TextToImage].Models[model_id1] = &ModelConstraint{Warm: true, Capacity: 1} + + // create capabilities with only Model1 + caps := NewCapabilities(capabilities, mandatories) + caps.SetPerCapabilityConstraints(constraints) + _, model1ConstraintExists := caps.constraints.perCapability[Capability_TextToImage].Models[model_id1] + assert.True(model1ConstraintExists) + + newModelConstraint := CapabilityConstraints{ + Models: make(ModelConstraints), + } + model2Constraint := ModelConstraint{Warm: true, Capacity: 1} + newModelConstraint.Models[model_id2] = &model2Constraint + + // add another model + caps.constraints.addCapabilityConstraints(Capability_TextToImage, newModelConstraint) + + checkCapsConstraints := caps.constraints.perCapability + + checkConstraint, model2ConstraintExists := checkCapsConstraints[Capability_TextToImage].Models[model_id2] + + assert.True(model2ConstraintExists) + // check that ModelConstraint values are the same but for two different modelIDs + assert.Equal(&model2Constraint, checkConstraint) + assert.Equal(model1Constraint, model2Constraint) + + // add another to Model2 + caps.constraints.addCapabilityConstraints(Capability_TextToImage, newModelConstraint) + checkCapsConstraints = caps.constraints.perCapability + // check capacity increased to 2 + checkConstraintCapacity := checkCapsConstraints[Capability_TextToImage].Models["Model2"].Capacity + assert.Equal(checkConstraintCapacity, 2) + // confirm Model1 capacity is still 1 + checkConstraintCapacity = checkCapsConstraints[Capability_TextToImage].Models["Model1"].Capacity + assert.Equal(checkConstraintCapacity, 1) + + // remove constraint and make sure is 1 + removeModel2Constraint := ModelConstraint{Warm: true, Capacity: 1} + newModelConstraint.Models[model_id2] = &removeModel2Constraint + caps.constraints.removeCapabilityConstraints(Capability_TextToImage, newModelConstraint) + assert.Equal(len(caps.constraints.perCapability[Capability_TextToImage].Models), 2) + assert.Equal(caps.constraints.perCapability[Capability_TextToImage].Models["Model2"].Capacity, 1) + + // remove constraint and make sure is removed from constraints + caps.constraints.removeCapabilityConstraints(Capability_TextToImage, newModelConstraint) + assert.Equal(len(caps.constraints.perCapability[Capability_TextToImage].Models), 1) + _, exists := caps.constraints.perCapability[Capability_TextToImage].Models["Model2"] + assert.False(exists) +} + +func (c *Constraints) addCapabilityConstraints(cap Capability, constraint CapabilityConstraints) { + // the capability should be added by AddCapacity + for modelID, modelConstraint := range constraint.Models { + if _, ok := c.perCapability[cap]; ok { + if _, ok := c.perCapability[cap].Models[modelID]; ok { + if c.perCapability[cap].Models[modelID].Warm == modelConstraint.Warm { + c.perCapability[cap].Models[modelID].Capacity += modelConstraint.Capacity + } else { + c.perCapability[cap].Models[modelID] = modelConstraint + } + } else { + c.perCapability[cap].Models[modelID] = modelConstraint + } + } else { + c.perCapability[cap] = &CapabilityConstraints{Models: make(ModelConstraints)} + } + } +} + +func (c *Constraints) removeCapabilityConstraints(cap Capability, constraint CapabilityConstraints) { + // the capability should be removed by RemoveCapacity + for modelID, modelConstraint := range constraint.Models { + if _, ok := c.perCapability[cap]; ok { + if _, ok := c.perCapability[cap].Models[modelID]; ok { + if c.perCapability[cap].Models[modelID].Warm == modelConstraint.Warm { + c.perCapability[cap].Models[modelID].Capacity -= modelConstraint.Capacity + if c.perCapability[cap].Models[modelID].Capacity <= 0 { + delete(c.perCapability[cap].Models, modelID) + } + } + } + } + } +} diff --git a/core/livepeernode.go b/core/livepeernode.go index d7b3fec041..4ef1fbcfd8 100644 --- a/core/livepeernode.go +++ b/core/livepeernode.go @@ -45,6 +45,7 @@ const ( OrchestratorNode TranscoderNode RedeemerNode + AIWorkerNode ) var nodeTypeStrs = map[NodeType]string{ @@ -53,6 +54,7 @@ var nodeTypeStrs = map[NodeType]string{ OrchestratorNode: "orchestrator", TranscoderNode: "transcoder", RedeemerNode: "redeemer", + AIWorkerNode: "aiworker", } func (t NodeType) String() string { @@ -63,6 +65,49 @@ func (t NodeType) String() string { return str } +type CapabilityPriceMenu struct { + modelPrices map[string]*AutoConvertedPrice +} + +func NewCapabilityPriceMenu() CapabilityPriceMenu { + return CapabilityPriceMenu{ + modelPrices: make(map[string]*AutoConvertedPrice), + } +} + +func (m CapabilityPriceMenu) SetPriceForModelID(modelID string, price *AutoConvertedPrice) { + m.modelPrices[modelID] = price +} + +func (m CapabilityPriceMenu) PriceForModelID(modelID string) *AutoConvertedPrice { + return m.modelPrices[modelID] +} + +type CapabilityPrices map[Capability]CapabilityPriceMenu + +func NewCapabilityPrices() CapabilityPrices { + return make(map[Capability]CapabilityPriceMenu) +} + +func (cp CapabilityPrices) SetPriceForModelID(cap Capability, modelID string, price *AutoConvertedPrice) { + menu, ok := cp[cap] + if !ok { + menu = NewCapabilityPriceMenu() + cp[cap] = menu + } + + menu.SetPriceForModelID(modelID, price) +} + +func (cp CapabilityPrices) PriceForModelID(cap Capability, modelID string) *AutoConvertedPrice { + menu, ok := cp[cap] + if !ok { + return nil + } + + return menu.PriceForModelID(modelID) +} + // LivepeerNode handles videos going in and coming out of the Livepeer network. type LivepeerNode struct { @@ -72,6 +117,10 @@ type LivepeerNode struct { NodeType NodeType Database *common.DB + // AI worker public fields + AIWorker AI + AIWorkerManager *RemoteAIWorkerManager + // Transcoder public fields SegmentChans map[ManifestID]SegmentChan Recipient pm.Recipient @@ -94,25 +143,27 @@ type LivepeerNode struct { StorageConfigs map[string]*transcodeConfig storageMutex *sync.RWMutex // Transcoder private fields - priceInfo map[string]*AutoConvertedPrice - serviceURI url.URL - segmentMutex *sync.RWMutex + priceInfo map[string]*AutoConvertedPrice + priceInfoForCaps map[string]CapabilityPrices + serviceURI url.URL + segmentMutex *sync.RWMutex } // NewLivepeerNode creates a new Livepeer Node. Eth can be nil. func NewLivepeerNode(e eth.LivepeerEthClient, wd string, dbh *common.DB) (*LivepeerNode, error) { rand.Seed(time.Now().UnixNano()) return &LivepeerNode{ - Eth: e, - WorkDir: wd, - Database: dbh, - AutoAdjustPrice: true, - SegmentChans: make(map[ManifestID]SegmentChan), - segmentMutex: &sync.RWMutex{}, - Capabilities: &Capabilities{capacities: map[Capability]int{}, version: LivepeerVersion}, - priceInfo: make(map[string]*AutoConvertedPrice), - StorageConfigs: make(map[string]*transcodeConfig), - storageMutex: &sync.RWMutex{}, + Eth: e, + WorkDir: wd, + Database: dbh, + AutoAdjustPrice: true, + SegmentChans: make(map[ManifestID]SegmentChan), + segmentMutex: &sync.RWMutex{}, + Capabilities: &Capabilities{capacities: map[Capability]int{}, version: LivepeerVersion}, + priceInfo: make(map[string]*AutoConvertedPrice), + priceInfoForCaps: make(map[string]CapabilityPrices), + StorageConfigs: make(map[string]*transcodeConfig), + storageMutex: &sync.RWMutex{}, }, nil } @@ -165,6 +216,37 @@ func (n *LivepeerNode) GetBasePrices() map[string]*big.Rat { return prices } +func (n *LivepeerNode) SetBasePriceForCap(b_eth_addr string, cap Capability, modelID string, price *AutoConvertedPrice) { + addr := strings.ToLower(b_eth_addr) + n.mu.Lock() + defer n.mu.Unlock() + + prices, ok := n.priceInfoForCaps[addr] + if !ok { + prices = NewCapabilityPrices() + n.priceInfoForCaps[addr] = prices + } + + prices.SetPriceForModelID(cap, modelID, price) +} + +func (n *LivepeerNode) GetBasePriceForCap(b_eth_addr string, cap Capability, modelID string) *big.Rat { + addr := strings.ToLower(b_eth_addr) + n.mu.RLock() + defer n.mu.RUnlock() + + prices, ok := n.priceInfoForCaps[addr] + if !ok { + return nil + } + + if price := prices.PriceForModelID(cap, modelID); price != nil { + return price.Value() + } + + return nil +} + // SetMaxFaceValue sets the faceValue upper limit for tickets received func (n *LivepeerNode) SetMaxFaceValue(maxfacevalue *big.Int) { n.mu.Lock() diff --git a/core/livepeernode_test.go b/core/livepeernode_test.go index 230f8dd421..d943086ba4 100644 --- a/core/livepeernode_test.go +++ b/core/livepeernode_test.go @@ -179,3 +179,29 @@ func TestSetAndGetBasePrice(t *testing.T) { assert.Zero(n.GetBasePrices()[addr1].Cmp(price1)) assert.Zero(n.GetBasePrices()[addr2].Cmp(price2)) } + +func TestSetAndGetCapabilityPrices(t *testing.T) { + require := require.New(t) + assert := assert.New(t) + + n, err := NewLivepeerNode(nil, "", nil) + require.Nil(err) + + price := big.NewRat(1, 1) + + n.SetBasePriceForCap("default", Capability_TextToImage, "default", NewFixedPrice(price)) + assert.Zero(n.priceInfoForCaps["default"].PriceForModelID(Capability_TextToImage, "default").Value().Cmp(price)) + assert.Zero(n.GetBasePriceForCap("default", Capability_TextToImage, "default").Cmp(price)) + + addr1 := "0x0000000000000000000000000000000000000000" + addr2 := "0x1000000000000000000000000000000000000000" + price1 := big.NewRat(2, 1) + price2 := big.NewRat(3, 1) + + n.SetBasePriceForCap(addr1, Capability_TextToImage, "default", NewFixedPrice(price1)) + n.SetBasePriceForCap(addr2, Capability_ImageToImage, "default", NewFixedPrice(price2)) + assert.Zero(n.priceInfoForCaps[addr1].PriceForModelID(Capability_TextToImage, "default").Value().Cmp(price1)) + assert.Zero(n.priceInfoForCaps[addr2].PriceForModelID(Capability_ImageToImage, "default").Value().Cmp(price2)) + assert.Zero(n.GetBasePriceForCap(addr1, Capability_TextToImage, "default").Cmp(price1)) + assert.Zero(n.GetBasePriceForCap(addr2, Capability_ImageToImage, "default").Cmp(price2)) +} diff --git a/core/orchestrator.go b/core/orchestrator.go index 3a2578c81a..beb8b72954 100644 --- a/core/orchestrator.go +++ b/core/orchestrator.go @@ -23,7 +23,6 @@ import ( "github.com/livepeer/go-livepeer/clog" "github.com/livepeer/go-livepeer/common" "github.com/livepeer/go-livepeer/eth" - "github.com/livepeer/go-livepeer/monitor" "github.com/livepeer/go-livepeer/net" "github.com/livepeer/go-livepeer/pm" "github.com/livepeer/go-tools/drivers" @@ -183,8 +182,8 @@ func (orch *orchestrator) ProcessPayment(ctx context.Context, payment net.Paymen if err != nil { clog.Errorf(ctx, "Error receiving ticket sessionID=%v recipientRandHash=%x senderNonce=%v: %v", manifestID, ticket.RecipientRandHash, ticket.SenderNonce, err) - if monitor.Enabled { - monitor.PaymentRecvError(ctx, sender.Hex(), err.Error()) + if lpmon.Enabled { + lpmon.PaymentRecvError(ctx, sender.Hex(), err.Error()) } if _, ok := err.(*pm.FatalReceiveErr); ok { return err @@ -217,10 +216,10 @@ func (orch *orchestrator) ProcessPayment(ctx context.Context, payment net.Paymen clog.V(common.DEBUG).Infof(ctx, "Payment tickets processed sessionID=%v faceValue=%v winProb=%v ev=%v", manifestID, eth.FormatUnits(totalFaceValue, "ETH"), totalWinProb.FloatString(10), totalEV.FloatString(2)) - if monitor.Enabled { - monitor.TicketValueRecv(ctx, sender.Hex(), totalEV) - monitor.TicketsRecv(ctx, sender.Hex(), totalTickets) - monitor.WinningTicketsRecv(ctx, sender.Hex(), totalWinningTickets) + if lpmon.Enabled { + lpmon.TicketValueRecv(ctx, sender.Hex(), totalEV) + lpmon.TicketsRecv(ctx, sender.Hex(), totalTickets) + lpmon.WinningTicketsRecv(ctx, sender.Hex(), totalWinningTickets) } if receiveErr != nil { @@ -264,13 +263,13 @@ func (orch *orchestrator) PriceInfo(sender ethcommon.Address, manifestID Manifes return nil, nil } - price, err := orch.priceInfo(sender, manifestID) + price, err := orch.priceInfo(sender, manifestID, nil) if err != nil { return nil, err } - if monitor.Enabled { - monitor.TranscodingPrice(sender.String(), price) + if lpmon.Enabled { + lpmon.TranscodingPrice(sender.String(), price) } return &net.PriceInfo{ @@ -279,10 +278,32 @@ func (orch *orchestrator) PriceInfo(sender ethcommon.Address, manifestID Manifes }, nil } -// priceInfo returns price per pixel as a fixed point number wrapped in a big.Rat -func (orch *orchestrator) priceInfo(sender ethcommon.Address, manifestID ManifestID) (*big.Rat, error) { - basePrice := orch.node.GetBasePrice(sender.String()) +func (orch *orchestrator) PriceInfoForCaps(sender ethcommon.Address, manifestID ManifestID, caps *net.Capabilities) (*net.PriceInfo, error) { + if orch.node == nil || orch.node.Recipient == nil { + return nil, nil + } + price, err := orch.priceInfo(sender, manifestID, caps) + if err != nil { + return nil, err + } + + if !price.Num().IsInt64() || !price.Denom().IsInt64() { + fixedPrice, err := common.PriceToInt64(price) + if err != nil { + return nil, errors.New("price cannot be converted to int64") + } + price = fixedPrice + } + + return &net.PriceInfo{ + PricePerUnit: price.Num().Int64(), + PixelsPerUnit: price.Denom().Int64(), + }, nil +} + +// priceInfo returns price per pixel as a fixed point number wrapped in a big.Rat +func (orch *orchestrator) priceInfo(sender ethcommon.Address, manifestID ManifestID, caps *net.Capabilities) (*big.Rat, error) { // If there is already a fixed price for the given session, use this price if manifestID != "" { if balances, ok := orch.node.Balances.balances[sender]; ok { @@ -293,8 +314,44 @@ func (orch *orchestrator) priceInfo(sender ethcommon.Address, manifestID Manifes } } - if basePrice == nil { - basePrice = orch.node.GetBasePrice("default") + transcodePrice := orch.node.GetBasePrice(sender.String()) + if transcodePrice == nil { + transcodePrice = orch.node.GetBasePrice("default") + } + + basePrice := big.NewRat(0, 1) + if caps == nil { + if transcodePrice != nil { + basePrice = transcodePrice + } + } else { + // The base price is the sum of the prices of individual capability + model ID pairs + if caps.Constraints != nil && caps.Constraints.PerCapability != nil { + for cap := range caps.Capacities { + // If the capability does not have constraints (and thus any model constraints) skip it + // because we only price a capability together with a model ID right now + constraints, ok := caps.Constraints.PerCapability[cap] + if !ok { + continue + } + for modelID := range constraints.Models { + price := orch.node.GetBasePriceForCap(sender.String(), Capability(cap), modelID) + if price == nil { + price = orch.node.GetBasePriceForCap("default", Capability(cap), modelID) + } + + if price != nil { + basePrice.Add(basePrice, price) + } + } + } + } + + // If no priced capabilities were signaled by the broadcaster assume that they are requesting + // transcoding and set the base price to the transcode price + if transcodePrice != nil && basePrice.Cmp(big.NewRat(0, 1)) == 0 { + basePrice = transcodePrice + } } if !orch.node.AutoAdjustPrice { @@ -347,6 +404,13 @@ func (orch *orchestrator) DebitFees(addr ethcommon.Address, manifestID ManifestI orch.node.Balances.Debit(addr, manifestID, priceRat.Mul(priceRat, big.NewRat(pixels, 1))) } +func (orch *orchestrator) Balance(addr ethcommon.Address, manifestID ManifestID) *big.Rat { + if orch.node == nil || orch.node.Balances == nil { + return nil + } + return orch.node.Balances.Balance(addr, manifestID) +} + func (orch *orchestrator) Capabilities() *net.Capabilities { if orch.node == nil { return nil @@ -613,8 +677,8 @@ func (n *LivepeerNode) transcodeSeg(ctx context.Context, config transcodeConfig, took := time.Since(start) clog.V(common.DEBUG).Infof(ctx, "Transcoding of segment took=%v", took) - if monitor.Enabled { - monitor.SegmentTranscoded(ctx, 0, seg.SeqNo, md.Duration, took, common.ProfilesNames(md.Profiles), true, true) + if lpmon.Enabled { + lpmon.SegmentTranscoded(ctx, 0, seg.SeqNo, md.Duration, took, common.ProfilesNames(md.Profiles), true, true) } // Prepare the result object @@ -945,12 +1009,12 @@ func (rtm *RemoteTranscoderManager) Manage(stream net.Transcoder_RegisterTransco rtm.remoteTranscoders = append(rtm.remoteTranscoders, transcoder) sort.Sort(byLoadFactor(rtm.remoteTranscoders)) var totalLoad, totalCapacity, liveTranscodersNum int - if monitor.Enabled { + if lpmon.Enabled { totalLoad, totalCapacity, liveTranscodersNum = rtm.totalLoadAndCapacity() } rtm.RTmutex.Unlock() - if monitor.Enabled { - monitor.SetTranscodersNumberAndLoad(totalLoad, totalCapacity, liveTranscodersNum) + if lpmon.Enabled { + lpmon.SetTranscodersNumberAndLoad(totalLoad, totalCapacity, liveTranscodersNum) } <-transcoder.eof @@ -958,12 +1022,12 @@ func (rtm *RemoteTranscoderManager) Manage(stream net.Transcoder_RegisterTransco rtm.RTmutex.Lock() delete(rtm.liveTranscoders, transcoder.stream) - if monitor.Enabled { + if lpmon.Enabled { totalLoad, totalCapacity, liveTranscodersNum = rtm.totalLoadAndCapacity() } rtm.RTmutex.Unlock() - if monitor.Enabled { - monitor.SetTranscodersNumberAndLoad(totalLoad, totalCapacity, liveTranscodersNum) + if lpmon.Enabled { + lpmon.SetTranscodersNumberAndLoad(totalLoad, totalCapacity, liveTranscodersNum) } } diff --git a/core/os.go b/core/os.go index 4c42df58b8..9a3978b82a 100644 --- a/core/os.go +++ b/core/os.go @@ -16,8 +16,8 @@ import ( "github.com/livepeer/go-tools/drivers" ) -func GetSegmentData(ctx context.Context, uri string) ([]byte, error) { - return getSegmentDataHTTP(ctx, uri) +func DownloadData(ctx context.Context, uri string) ([]byte, error) { + return downloadDataHTTP(ctx, uri) } var httpc = &http.Client{ @@ -73,7 +73,7 @@ func ToNetS3Info(storage *drivers.S3OSInfo) *net.S3OSInfo { } } -func getSegmentDataHTTP(ctx context.Context, uri string) ([]byte, error) { +func downloadDataHTTP(ctx context.Context, uri string) ([]byte, error) { clog.V(common.VERBOSE).Infof(ctx, "Downloading uri=%s", uri) started := time.Now() resp, err := httpc.Get(uri) diff --git a/core/streamdata.go b/core/streamdata.go index f575cd2c83..245e345f4f 100644 --- a/core/streamdata.go +++ b/core/streamdata.go @@ -59,6 +59,7 @@ type SegTranscodingMetadata struct { Fname string Seq int64 Hash ethcommon.Hash + ProfileIn ffmpeg.VideoProfile Profiles []ffmpeg.VideoProfile OS *net.OSInfo Duration time.Duration diff --git a/core/transcoder.go b/core/transcoder.go index da1cb5d177..353f90f6ba 100644 --- a/core/transcoder.go +++ b/core/transcoder.go @@ -47,8 +47,9 @@ func (lt *LocalTranscoder) Transcode(ctx context.Context, md *SegTranscodingMeta // Set up in / out config in := &ffmpeg.TranscodeOptionsIn{ - Fname: md.Fname, - Accel: ffmpeg.Software, + Fname: md.Fname, + Accel: ffmpeg.Software, + Profile: md.ProfileIn, } profiles := md.Profiles opts := profilesToTranscodeOptions(lt.workDir, ffmpeg.Software, md) @@ -129,10 +130,17 @@ func (nv *NvidiaTranscoder) Transcode(ctx context.Context, md *SegTranscodingMet // Returns UnrecoverableError instead of panicking to gracefully notify orchestrator about transcoder's failure defer recoverFromPanic(&retErr) + inAccel := ffmpeg.Nvidia + if filepath.Ext(md.Fname) == ".png" { + // If the input is a PNG file we need to use the software decoder + inAccel = ffmpeg.Software + } + in := &ffmpeg.TranscodeOptionsIn{ - Fname: md.Fname, - Accel: ffmpeg.Nvidia, - Device: nv.device, + Fname: md.Fname, + Accel: inAccel, + Device: nv.device, + Profile: md.ProfileIn, } profiles := md.Profiles out := profilesToTranscodeOptions(WorkDir, ffmpeg.Nvidia, md) diff --git a/discovery/db_discovery.go b/discovery/db_discovery.go index 36f9162aae..a1c657f229 100644 --- a/discovery/db_discovery.go +++ b/discovery/db_discovery.go @@ -277,7 +277,7 @@ func (dbo *DBOrchestratorPoolCache) cacheDBOrchs() error { return } - info, err := serverGetOrchInfo(ctx, dbo.bcast, uri) + info, err := serverGetOrchInfo(ctx, dbo.bcast, uri, nil) if err != nil { errc <- err return diff --git a/discovery/discovery.go b/discovery/discovery.go index bc488274cc..8ec9713c44 100644 --- a/discovery/discovery.go +++ b/discovery/discovery.go @@ -106,7 +106,7 @@ func (o *orchestratorPool) GetOrchestrators(ctx context.Context, numOrchestrator return caps.CompatibleWith(info.Capabilities) } getOrchInfo := func(ctx context.Context, od common.OrchestratorDescriptor, infoCh chan common.OrchestratorDescriptor, errCh chan error) { - info, err := serverGetOrchInfo(ctx, o.bcast, od.LocalInfo.URL) + info, err := serverGetOrchInfo(ctx, o.bcast, od.LocalInfo.URL, caps.ToNetCapabilities()) if err == nil && !isBlacklisted(info) && isCompatible(info) { od.RemoteInfo = info infoCh <- od diff --git a/discovery/discovery_test.go b/discovery/discovery_test.go index dccf8dab5c..8ffc2fe013 100644 --- a/discovery/discovery_test.go +++ b/discovery/discovery_test.go @@ -56,7 +56,7 @@ func TestDeadLock(t *testing.T) { first := true oldOrchInfo := serverGetOrchInfo defer func() { wg.Wait(); serverGetOrchInfo = oldOrchInfo }() - serverGetOrchInfo = func(ctx context.Context, bcast common.Broadcaster, orchestratorServer *url.URL) (*net.OrchestratorInfo, error) { + serverGetOrchInfo = func(ctx context.Context, bcast common.Broadcaster, orchestratorServer *url.URL, cap *net.Capabilities) (*net.OrchestratorInfo, error) { mu.Lock() defer wg.Done() if first { @@ -88,7 +88,7 @@ func TestDeadLock_NewOrchestratorPoolWithPred(t *testing.T) { first := true oldOrchInfo := serverGetOrchInfo defer func() { wg.Wait(); serverGetOrchInfo = oldOrchInfo }() - serverGetOrchInfo = func(ctx context.Context, bcast common.Broadcaster, orchestratorServer *url.URL) (*net.OrchestratorInfo, error) { + serverGetOrchInfo = func(ctx context.Context, bcast common.Broadcaster, orchestratorServer *url.URL, cap *net.Capabilities) (*net.OrchestratorInfo, error) { mu.Lock() defer wg.Done() if first { @@ -187,7 +187,7 @@ func TestNewDBOrchestorPoolCache_NoEthAddress(t *testing.T) { oldServerGetOrchInfo := serverGetOrchInfo defer func() { serverGetOrchInfo = oldServerGetOrchInfo }() var mu sync.Mutex - serverGetOrchInfo = func(ctx context.Context, bcast common.Broadcaster, orchestratorServer *url.URL) (*net.OrchestratorInfo, error) { + serverGetOrchInfo = func(ctx context.Context, bcast common.Broadcaster, orchestratorServer *url.URL, cap *net.Capabilities) (*net.OrchestratorInfo, error) { mu.Lock() defer mu.Unlock() @@ -244,7 +244,7 @@ func TestNewDBOrchestratorPoolCache_InvalidPrices(t *testing.T) { oldServerGetOrchInfo := serverGetOrchInfo defer func() { serverGetOrchInfo = oldServerGetOrchInfo }() var mu sync.Mutex - serverGetOrchInfo = func(ctx context.Context, bcast common.Broadcaster, orchestratorServer *url.URL) (*net.OrchestratorInfo, error) { + serverGetOrchInfo = func(ctx context.Context, bcast common.Broadcaster, orchestratorServer *url.URL, cap *net.Capabilities) (*net.OrchestratorInfo, error) { mu.Lock() defer mu.Unlock() @@ -294,7 +294,7 @@ func TestNewDBOrchestratorPoolCache_GivenListOfOrchs_CreatesPoolCacheCorrectly(t expPricePerPixel, _ := common.PriceToFixed(big.NewRat(999, 1)) var mu sync.Mutex first := true - serverGetOrchInfo = func(ctx context.Context, bcast common.Broadcaster, orchestratorServer *url.URL) (*net.OrchestratorInfo, error) { + serverGetOrchInfo = func(ctx context.Context, bcast common.Broadcaster, orchestratorServer *url.URL, cap *net.Capabilities) (*net.OrchestratorInfo, error) { mu.Lock() if first { time.Sleep(100 * time.Millisecond) @@ -346,7 +346,7 @@ func TestNewDBOrchestratorPoolCache_GivenListOfOrchs_CreatesPoolCacheCorrectly(t pool, err := NewDBOrchestratorPoolCache(ctx, node, &stubRoundsManager{}, []string{}, 500*time.Millisecond) require.NoError(err) assert.Equal(pool.Size(), 3) - orchs, err := pool.GetOrchestrators(context.TODO(), pool.Size(), newStubSuspender(), newStubCapabilities(), common.ScoreAtLeast(0)) + orchs, _ := pool.GetOrchestrators(context.TODO(), pool.Size(), newStubSuspender(), newStubCapabilities(), common.ScoreAtLeast(0)) for _, o := range orchs { assert.Equal(o.RemoteInfo.PriceInfo, expPriceInfo) assert.Equal(o.RemoteInfo.Transcoder, expTranscoder) @@ -386,7 +386,7 @@ func TestNewDBOrchestratorPoolCache_TestURLs(t *testing.T) { var mu sync.Mutex first := true - serverGetOrchInfo = func(ctx context.Context, bcast common.Broadcaster, orchestratorServer *url.URL) (*net.OrchestratorInfo, error) { + serverGetOrchInfo = func(ctx context.Context, bcast common.Broadcaster, orchestratorServer *url.URL, cap *net.Capabilities) (*net.OrchestratorInfo, error) { mu.Lock() if first { time.Sleep(100 * time.Millisecond) @@ -479,7 +479,7 @@ func TestNewDBOrchestorPoolCache_PollOrchestratorInfo(t *testing.T) { wg := sync.WaitGroup{} oldOrchInfo := serverGetOrchInfo defer func() { wg.Wait(); serverGetOrchInfo = oldOrchInfo }() - serverGetOrchInfo = func(ctx context.Context, bcast common.Broadcaster, orchestratorServer *url.URL) (*net.OrchestratorInfo, error) { + serverGetOrchInfo = func(ctx context.Context, bcast common.Broadcaster, orchestratorServer *url.URL, cap *net.Capabilities) (*net.OrchestratorInfo, error) { mu.Lock() defer mu.Unlock() // slightly unsafe to be adding to the wg counter here @@ -634,7 +634,7 @@ func TestCachedPool_AllOrchestratorsTooExpensive_ReturnsAllOrchestrators(t *test defer runtime.GOMAXPROCS(gmp) var mu sync.Mutex first := true - serverGetOrchInfo = func(ctx context.Context, bcast common.Broadcaster, orchestratorServer *url.URL) (*net.OrchestratorInfo, error) { + serverGetOrchInfo = func(ctx context.Context, bcast common.Broadcaster, orchestratorServer *url.URL, cap *net.Capabilities) (*net.OrchestratorInfo, error) { mu.Lock() if first { time.Sleep(100 * time.Millisecond) @@ -723,7 +723,7 @@ func TestCachedPool_GetOrchestrators_MaxBroadcastPriceNotSet(t *testing.T) { defer runtime.GOMAXPROCS(gmp) var mu sync.Mutex first := true - serverGetOrchInfo = func(ctx context.Context, bcast common.Broadcaster, orchestratorServer *url.URL) (*net.OrchestratorInfo, error) { + serverGetOrchInfo = func(ctx context.Context, bcast common.Broadcaster, orchestratorServer *url.URL, cap *net.Capabilities) (*net.OrchestratorInfo, error) { mu.Lock() if first { time.Sleep(100 * time.Millisecond) @@ -829,7 +829,7 @@ func TestCachedPool_N_OrchestratorsGoodPricing_ReturnsNOrchestrators(t *testing. defer runtime.GOMAXPROCS(gmp) var mu sync.Mutex first := true - serverGetOrchInfo = func(ctx context.Context, bcast common.Broadcaster, orchestratorServer *url.URL) (*net.OrchestratorInfo, error) { + serverGetOrchInfo = func(ctx context.Context, bcast common.Broadcaster, orchestratorServer *url.URL, cap *net.Capabilities) (*net.OrchestratorInfo, error) { mu.Lock() if first { time.Sleep(100 * time.Millisecond) @@ -932,7 +932,7 @@ func TestCachedPool_GetOrchestrators_TicketParamsValidation(t *testing.T) { server.BroadcastCfg.SetMaxPrice(nil) - serverGetOrchInfo = func(ctx context.Context, bcast common.Broadcaster, orchestratorServer *url.URL) (*net.OrchestratorInfo, error) { + serverGetOrchInfo = func(ctx context.Context, bcast common.Broadcaster, orchestratorServer *url.URL, cap *net.Capabilities) (*net.OrchestratorInfo, error) { return &net.OrchestratorInfo{ Address: pm.RandBytes(20), Transcoder: "transcoder", @@ -1006,7 +1006,7 @@ func TestCachedPool_GetOrchestrators_OnlyActiveOrchestrators(t *testing.T) { defer runtime.GOMAXPROCS(gmp) var mu sync.Mutex first := true - serverGetOrchInfo = func(ctx context.Context, bcast common.Broadcaster, orchestratorServer *url.URL) (*net.OrchestratorInfo, error) { + serverGetOrchInfo = func(ctx context.Context, bcast common.Broadcaster, orchestratorServer *url.URL, cap *net.Capabilities) (*net.OrchestratorInfo, error) { mu.Lock() if first { time.Sleep(100 * time.Millisecond) @@ -1113,7 +1113,7 @@ func TestNewWHOrchestratorPoolCache(t *testing.T) { wg := sync.WaitGroup{} oldOrchInfo := serverGetOrchInfo defer func() { wg.Wait(); serverGetOrchInfo = oldOrchInfo }() - serverGetOrchInfo = func(c context.Context, b common.Broadcaster, s *url.URL) (*net.OrchestratorInfo, error) { + serverGetOrchInfo = func(c context.Context, b common.Broadcaster, s *url.URL, cap *net.Capabilities) (*net.OrchestratorInfo, error) { defer wg.Done() return &net.OrchestratorInfo{Transcoder: "transcoder"}, nil } @@ -1276,7 +1276,7 @@ func TestOrchestratorPool_GetOrchestrators(t *testing.T) { orchCb := func() error { return nil } oldOrchInfo := serverGetOrchInfo defer func() { wg.Wait(); serverGetOrchInfo = oldOrchInfo }() - serverGetOrchInfo = func(ctx context.Context, bcast common.Broadcaster, server *url.URL) (*net.OrchestratorInfo, error) { + serverGetOrchInfo = func(ctx context.Context, bcast common.Broadcaster, server *url.URL, cap *net.Capabilities) (*net.OrchestratorInfo, error) { defer wg.Done() err := orchCb() return &net.OrchestratorInfo{ @@ -1341,7 +1341,7 @@ func TestOrchestratorPool_GetOrchestrators_SuspendedOrchs(t *testing.T) { orchCb := func() error { return nil } oldOrchInfo := serverGetOrchInfo defer func() { wg.Wait(); serverGetOrchInfo = oldOrchInfo }() - serverGetOrchInfo = func(ctx context.Context, bcast common.Broadcaster, server *url.URL) (*net.OrchestratorInfo, error) { + serverGetOrchInfo = func(ctx context.Context, bcast common.Broadcaster, server *url.URL, cap *net.Capabilities) (*net.OrchestratorInfo, error) { defer wg.Done() err := orchCb() return &net.OrchestratorInfo{ @@ -1413,7 +1413,7 @@ func TestOrchestratorPool_ShuffleGetOrchestrators(t *testing.T) { oldOrchInfo := serverGetOrchInfo defer func() { serverGetOrchInfo = oldOrchInfo }() - serverGetOrchInfo = func(ctx context.Context, bcast common.Broadcaster, server *url.URL) (*net.OrchestratorInfo, error) { + serverGetOrchInfo = func(ctx context.Context, bcast common.Broadcaster, server *url.URL, cap *net.Capabilities) (*net.OrchestratorInfo, error) { ch <- server return &net.OrchestratorInfo{Transcoder: server.String()}, nil } @@ -1476,7 +1476,7 @@ func TestOrchestratorPool_GetOrchestratorTimeout(t *testing.T) { ch := make(chan struct{}) oldOrchInfo := serverGetOrchInfo defer func() { serverGetOrchInfo = oldOrchInfo }() - serverGetOrchInfo = func(ctx context.Context, bcast common.Broadcaster, server *url.URL) (*net.OrchestratorInfo, error) { + serverGetOrchInfo = func(ctx context.Context, bcast common.Broadcaster, server *url.URL, cap *net.Capabilities) (*net.OrchestratorInfo, error) { ch <- struct{}{} // this will block if necessary to simulate a timeout return &net.OrchestratorInfo{}, nil } @@ -1591,7 +1591,7 @@ func TestOrchestratorPool_Capabilities(t *testing.T) { calls := 0 oldOrchInfo := serverGetOrchInfo defer func() { serverGetOrchInfo = oldOrchInfo }() - serverGetOrchInfo = func(ctx context.Context, bcast common.Broadcaster, server *url.URL) (*net.OrchestratorInfo, error) { + serverGetOrchInfo = func(ctx context.Context, bcast common.Broadcaster, server *url.URL, cap *net.Capabilities) (*net.OrchestratorInfo, error) { mu.Lock() defer func() { calls = (calls + 1) % len(responses) diff --git a/discovery/stub.go b/discovery/stub.go index 2f58652a0c..621a69a64e 100644 --- a/discovery/stub.go +++ b/discovery/stub.go @@ -103,3 +103,6 @@ func (s *stubCapabilities) CompatibleWith(caps *net.Capabilities) bool { func (s *stubCapabilities) LegacyOnly() bool { return s.isLegacy } +func (s *stubCapabilities) ToNetCapabilities() *net.Capabilities { + return &net.Capabilities{Bitstring: capCompatString} +} diff --git a/docker/Dockerfile b/docker/Dockerfile index 5e12c11c91..120dc74761 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -13,13 +13,13 @@ ENV GOARCH="$TARGETARCH" \ RUN apt update \ && apt install -yqq software-properties-common curl apt-transport-https lsb-release yasm \ - && curl -fsSL https://dl.google.com/go/go1.20.4.linux-${BUILDARCH}.tar.gz | tar -C /usr/local -xz \ + && curl -fsSL https://dl.google.com/go/go1.21.5.linux-${BUILDARCH}.tar.gz | tar -C /usr/local -xz \ && curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add - \ && add-apt-repository "deb [arch=${BUILDARCH}] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" \ && curl -fsSl https://apt.llvm.org/llvm-snapshot.gpg.key | apt-key add - \ && add-apt-repository "deb [arch=${BUILDARCH}] https://apt.llvm.org/$(lsb_release -cs)/ llvm-toolchain-$(lsb_release -cs)-14 main" \ && apt update \ - && apt -yqq install clang-14 clang-tools-14 lld-14 build-essential pkg-config autoconf git python docker-ce-cli pciutils gcc-multilib libgcc-8-dev-arm64-cross gcc-mingw-w64-x86-64 + && apt -yqq install clang-14 clang-tools-14 lld-14 build-essential pkg-config autoconf git python docker-ce-cli pciutils gcc-multilib libgcc-8-dev-arm64-cross gcc-mingw-w64-x86-64 zlib1g zlib1g-dev RUN update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-14 30 \ && update-alternatives --install /usr/bin/clang clang /usr/bin/clang-14 30 \ diff --git a/eth/client.go b/eth/client.go index e57ab112be..1ed4cc1e46 100644 --- a/eth/client.go +++ b/eth/client.go @@ -167,6 +167,9 @@ type LivepeerEthClientConfig struct { Signer types.Signer ControllerAddr ethcommon.Address CheckTxTimeout time.Duration + + // For the time-being Livepeer AI Subnet uses its own ServiceRegistry, so we define it here + ServiceRegistryAddr ethcommon.Address } func NewClient(cfg LivepeerEthClientConfig) (LivepeerEthClient, error) { @@ -174,11 +177,12 @@ func NewClient(cfg LivepeerEthClientConfig) (LivepeerEthClient, error) { backend := NewBackend(cfg.EthClient, cfg.Signer, cfg.GasPriceMonitor, cfg.TransactionManager) return &client{ - accountManager: cfg.AccountManager, - backend: backend, - tm: cfg.TransactionManager, - controllerAddr: cfg.ControllerAddr, - checkTxTimeout: cfg.CheckTxTimeout, + accountManager: cfg.AccountManager, + backend: backend, + tm: cfg.TransactionManager, + controllerAddr: cfg.ControllerAddr, + checkTxTimeout: cfg.CheckTxTimeout, + serviceRegistryAddr: cfg.ServiceRegistryAddr, }, nil } @@ -211,15 +215,15 @@ func (c *client) setContracts(opts *bind.TransactOpts) error { glog.V(common.SHORT).Infof("LivepeerToken: %v", c.tokenAddr.Hex()) - serviceRegistryAddr, err := c.GetContract(crypto.Keccak256Hash([]byte("ServiceRegistry"))) - if err != nil { - glog.Errorf("Error getting ServiceRegistry address: %v", err) - return err + if c.serviceRegistryAddr == (ethcommon.Address{}) { + c.serviceRegistryAddr, err = c.GetContract(crypto.Keccak256Hash([]byte("ServiceRegistry"))) + if err != nil { + glog.Errorf("Error getting ServiceRegistry address: %v", err) + return err + } } - c.serviceRegistryAddr = serviceRegistryAddr - - serviceRegistry, err := contracts.NewServiceRegistry(serviceRegistryAddr, c.backend) + serviceRegistry, err := contracts.NewServiceRegistry(c.serviceRegistryAddr, c.backend) if err != nil { glog.Errorf("Error creating ServiceRegistry binding: %v", err) return err diff --git a/go.mod b/go.mod index 4a40dbc93e..5c711e182d 100644 --- a/go.mod +++ b/go.mod @@ -1,58 +1,62 @@ module github.com/livepeer/go-livepeer -go 1.20 +go 1.23.2 require ( contrib.go.opencensus.io/exporter/prometheus v0.4.2 github.com/Masterminds/semver/v3 v3.2.1 github.com/cenkalti/backoff v2.2.1+incompatible github.com/ethereum/go-ethereum v1.13.5 - github.com/golang/glog v1.1.1 + github.com/getkin/kin-openapi v0.128.0 + github.com/golang/glog v1.2.1 github.com/golang/mock v1.6.0 github.com/golang/protobuf v1.5.4 github.com/jaypipes/ghw v0.10.0 github.com/jaypipes/pcidb v1.0.0 - github.com/livepeer/go-tools v0.0.0-20220805063103-76df6beb6506 + github.com/livepeer/ai-worker v0.12.1 + github.com/livepeer/go-tools v0.3.6-0.20240130205227-92479de8531b github.com/livepeer/livepeer-data v0.7.5-0.20231004073737-06f1f383fb18 github.com/livepeer/lpms v0.0.0-20240909171057-fe5aff1fa6a2 github.com/livepeer/m3u8 v0.11.1 github.com/mattn/go-sqlite3 v1.14.18 + github.com/oapi-codegen/nethttp-middleware v1.0.1 + github.com/oapi-codegen/runtime v1.1.1 github.com/olekukonko/tablewriter v0.0.5 github.com/patrickmn/go-cache v2.1.0+incompatible github.com/peterbourgon/ff/v3 v3.4.0 github.com/pkg/errors v0.9.1 github.com/prometheus/client_golang v1.14.0 - github.com/stretchr/testify v1.8.4 - github.com/testcontainers/testcontainers-go v0.26.0 + github.com/stretchr/testify v1.9.0 + github.com/testcontainers/testcontainers-go v0.34.0 github.com/urfave/cli v1.22.12 go.opencensus.io v0.24.0 go.uber.org/goleak v1.3.0 - golang.org/x/net v0.17.0 - google.golang.org/grpc v1.57.1 - google.golang.org/protobuf v1.33.0 + golang.org/x/net v0.28.0 + golang.org/x/sys v0.26.0 + google.golang.org/grpc v1.65.0 + google.golang.org/protobuf v1.34.1 pgregory.net/rapid v1.1.0 ) require ( - cloud.google.com/go v0.110.0 // indirect - cloud.google.com/go/compute v1.19.1 // indirect - cloud.google.com/go/compute/metadata v0.2.3 // indirect - cloud.google.com/go/iam v0.13.0 // indirect - cloud.google.com/go/storage v1.28.1 // indirect + cloud.google.com/go v0.110.8 // indirect + cloud.google.com/go/compute/metadata v0.3.0 // indirect + cloud.google.com/go/iam v1.1.2 // indirect + cloud.google.com/go/storage v1.30.1 // indirect dario.cat/mergo v1.0.0 // indirect + github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 // indirect github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect github.com/DataDog/zstd v1.4.5 // indirect - github.com/Microsoft/go-winio v0.6.1 // indirect - github.com/Microsoft/hcsshim v0.11.1 // indirect + github.com/Microsoft/go-winio v0.6.2 // indirect github.com/StackExchange/wmi v1.2.1 // indirect github.com/VictoriaMetrics/fastcache v1.12.1 // indirect - github.com/aws/aws-sdk-go v1.44.64 // indirect + github.com/apapsch/go-jsonmerge/v2 v2.0.0 // indirect + github.com/aws/aws-sdk-go v1.44.273 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bits-and-blooms/bitset v1.7.0 // indirect github.com/btcsuite/btcd/btcec/v2 v2.2.0 // indirect github.com/cenkalti/backoff/v4 v4.2.1 // indirect - github.com/cespare/cp v1.1.1 // indirect - github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/cockroachdb/errors v1.8.1 // indirect github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f // indirect github.com/cockroachdb/pebble v0.0.0-20230928194634-aa077af62593 // indirect @@ -61,30 +65,39 @@ require ( 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/containerd/containerd v1.7.7 // indirect github.com/containerd/log v0.1.0 // indirect - github.com/cpuguy83/dockercfg v0.3.1 // indirect + github.com/containerd/platforms v0.2.1 // indirect + github.com/cpuguy83/dockercfg v0.3.2 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect github.com/crate-crypto/go-kzg-4844 v0.7.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/deckarep/golang-set/v2 v2.1.0 // indirect - github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 // indirect github.com/deepmap/oapi-codegen v1.6.0 // indirect + github.com/deepmap/oapi-codegen/v2 v2.2.0 // indirect + github.com/distribution/reference v0.6.0 // indirect github.com/dlclark/regexp2 v1.7.0 // indirect - github.com/docker/distribution v2.8.2+incompatible // indirect - github.com/docker/docker v24.0.6+incompatible // indirect - github.com/docker/go-connections v0.4.0 // indirect + github.com/docker/cli v27.3.1+incompatible // indirect + github.com/docker/docker v27.3.1+incompatible // indirect + github.com/docker/go-connections v0.5.0 // indirect github.com/docker/go-units v0.5.0 // indirect github.com/dop251/goja v0.0.0-20230806174421-c933cf95e127 // indirect + github.com/dustin/go-humanize v1.0.1 // indirect github.com/ethereum/c-kzg-4844 v0.4.0 // indirect github.com/fatih/color v1.13.0 // indirect + github.com/felixge/httpsnoop v1.0.4 // indirect github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff // indirect github.com/ghodss/yaml v1.0.0 // indirect + github.com/go-chi/chi/v5 v5.1.0 // indirect github.com/go-kit/log v0.2.1 // indirect github.com/go-logfmt/logfmt v0.5.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.2.6 // indirect + github.com/go-openapi/jsonpointer v0.21.0 // indirect + github.com/go-openapi/swag v0.23.0 // indirect github.com/go-sourcemap/sourcemap v2.1.3+incompatible // indirect github.com/go-stack/stack v1.8.1 // indirect github.com/gofrs/flock v0.8.1 // indirect @@ -92,14 +105,16 @@ require ( github.com/golang-jwt/jwt/v4 v4.5.0 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect - github.com/google/go-cmp v0.5.9 // indirect github.com/google/pprof v0.0.0-20230207041349-798e818bf904 // indirect - github.com/google/uuid v1.3.1 // indirect - github.com/googleapis/enterprise-certificate-proxy v0.2.3 // indirect - github.com/googleapis/gax-go/v2 v2.7.1 // indirect + github.com/google/s2a-go v0.1.4 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/googleapis/enterprise-certificate-proxy v0.2.4 // indirect + github.com/googleapis/gax-go/v2 v2.12.0 // indirect + github.com/gorilla/mux v1.8.0 // indirect github.com/gorilla/websocket v1.4.2 // indirect github.com/graph-gophers/graphql-go v1.3.0 // indirect github.com/hashicorp/go-bexpr v0.1.10 // indirect + github.com/hashicorp/golang-lru v0.5.4 // indirect github.com/holiman/billy v0.0.0-20230718173358-1c7e68d277a7 // indirect github.com/holiman/bloomfilter/v2 v2.0.3 // indirect github.com/holiman/uint256 v1.2.3 // indirect @@ -107,34 +122,78 @@ require ( github.com/influxdata/influxdb-client-go/v2 v2.4.0 // indirect github.com/influxdata/influxdb1-client v0.0.0-20220302092344-a9ab5670611c // indirect github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839 // indirect + github.com/invopop/yaml v0.3.1 // indirect + github.com/ipfs/bbloom v0.0.4 // indirect + github.com/ipfs/go-block-format v0.1.2 // indirect + github.com/ipfs/go-blockservice v0.5.2 // indirect + github.com/ipfs/go-cid v0.4.1 // indirect + github.com/ipfs/go-datastore v0.6.0 // indirect + github.com/ipfs/go-ipfs-blockstore v1.3.1 // indirect + github.com/ipfs/go-ipfs-ds-help v1.1.1 // indirect + github.com/ipfs/go-ipfs-exchange-interface v0.2.1 // indirect + github.com/ipfs/go-ipfs-util v0.0.3 // indirect + github.com/ipfs/go-ipld-cbor v0.0.6 // indirect + github.com/ipfs/go-ipld-format v0.4.0 // indirect + github.com/ipfs/go-ipld-legacy v0.1.1 // indirect + github.com/ipfs/go-libipfs v0.4.0 // indirect + github.com/ipfs/go-log v1.0.5 // indirect + github.com/ipfs/go-log/v2 v2.5.1 // indirect + github.com/ipfs/go-merkledag v0.10.0 // indirect + github.com/ipfs/go-metrics-interface v0.0.1 // indirect + github.com/ipfs/go-unixfs v0.4.6 // indirect + github.com/ipfs/go-verifcid v0.0.3 // indirect + github.com/ipld/go-car v0.6.0 // indirect + github.com/ipld/go-codec-dagpb v1.6.0 // indirect + github.com/ipld/go-ipld-prime v0.20.0 // indirect github.com/jackpal/go-nat-pmp v1.0.2 // indirect + github.com/jbenet/goprocess v0.1.4 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect + github.com/josharian/intern v1.0.0 // indirect + github.com/json-iterator/go v1.1.12 // indirect github.com/karalabe/usb v0.0.2 // indirect - github.com/klauspost/compress v1.16.3 // indirect + github.com/klauspost/compress v1.17.4 // indirect + github.com/klauspost/cpuid/v2 v2.2.6 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect github.com/livepeer/joy4 v0.1.2-0.20191121080656-b2fea45cbded // indirect github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect github.com/magiconair/properties v1.8.7 // indirect + github.com/mailru/easyjson v0.7.7 // indirect github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.17 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-runewidth v0.0.13 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect + github.com/minio/md5-simd v1.1.2 // indirect + github.com/minio/minio-go/v7 v7.0.66 // indirect + github.com/minio/sha256-simd v1.0.1 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/mapstructure v1.4.1 // indirect github.com/mitchellh/pointerstructure v1.2.0 // indirect github.com/mmcloughlin/addchain v0.4.0 // indirect + github.com/moby/docker-image-spec v1.3.1 // indirect github.com/moby/patternmatcher v0.6.0 // indirect github.com/moby/sys/sequential v0.5.0 // indirect + github.com/moby/sys/user v0.3.0 // indirect + github.com/moby/sys/userns v0.1.0 // indirect github.com/moby/term v0.5.0 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect github.com/morikuni/aec v1.0.0 // indirect + 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-multibase v0.2.0 // indirect + github.com/multiformats/go-multihash v0.2.2 // indirect + github.com/multiformats/go-varint v0.0.7 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect - github.com/opencontainers/image-spec v1.1.0-rc5 // indirect - github.com/opencontainers/runc v1.1.5 // indirect - github.com/opentracing/opentracing-go v1.1.0 // indirect + github.com/opencontainers/image-spec v1.1.0 // indirect + github.com/opentracing/opentracing-go v1.2.0 // indirect + github.com/perimeterx/marshmallow v1.1.5 // indirect github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7 // indirect github.com/pierrec/lz4 v2.6.1+incompatible // indirect github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/polydawn/refmt v0.89.0 // indirect github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect github.com/prometheus/client_model v0.3.0 // indirect github.com/prometheus/common v0.42.0 // indirect @@ -143,41 +202,56 @@ require ( github.com/rabbitmq/amqp091-go v1.8.0 // indirect github.com/rabbitmq/rabbitmq-stream-go-client v1.1.1 // indirect github.com/rivo/uniseg v0.2.0 // indirect - github.com/rogpeppe/go-internal v1.9.0 // indirect + github.com/rogpeppe/go-internal v1.12.0 // indirect github.com/rs/cors v1.7.0 // indirect + github.com/rs/xid v1.5.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible // indirect - github.com/shirou/gopsutil/v3 v3.23.9 // indirect + github.com/shirou/gopsutil/v3 v3.23.12 // indirect github.com/shoenig/go-m1cpu v0.1.6 // indirect github.com/sirupsen/logrus v1.9.3 // indirect + github.com/spaolacci/murmur3 v1.1.0 // indirect github.com/status-im/keycard-go v0.2.0 // indirect - github.com/stretchr/objx v0.5.0 // indirect + github.com/stretchr/objx v0.5.2 // indirect github.com/supranational/blst v0.3.11 // 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 github.com/tyler-smith/go-bip39 v1.1.0 // indirect + github.com/ugorji/go/codec v1.2.11 // indirect github.com/urfave/cli/v2 v2.25.7 // indirect + github.com/vincent-petithory/dataurl v1.0.0 // indirect + github.com/whyrusleeping/cbor-gen v0.0.0-20230418232409-daab9ece03a0 // indirect github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect github.com/yusufpapurcu/wmi v1.2.3 // indirect - golang.org/x/crypto v0.14.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.56.0 // indirect + go.opentelemetry.io/otel v1.31.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0 // indirect + go.opentelemetry.io/otel/metric v1.31.0 // indirect + go.opentelemetry.io/otel/trace v1.31.0 // indirect + go.opentelemetry.io/proto/otlp v1.0.0 // indirect + go.uber.org/atomic v1.11.0 // indirect + go.uber.org/multierr v1.11.0 // indirect + go.uber.org/zap v1.24.0 // indirect + golang.org/x/crypto v0.26.0 // indirect golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect - golang.org/x/mod v0.12.0 // indirect - golang.org/x/oauth2 v0.7.0 // indirect - golang.org/x/sync v0.3.0 // indirect - golang.org/x/sys v0.13.0 // indirect - golang.org/x/text v0.13.0 // indirect - golang.org/x/time v0.3.0 // indirect - golang.org/x/tools v0.13.0 // indirect + golang.org/x/mod v0.20.0 // indirect + golang.org/x/oauth2 v0.20.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/text v0.17.0 // indirect + golang.org/x/time v0.5.0 // indirect + golang.org/x/tools v0.24.0 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect - google.golang.org/api v0.114.0 // indirect + google.golang.org/api v0.128.0 // indirect google.golang.org/appengine v1.6.7 // indirect - google.golang.org/genproto v0.0.0-20230526161137-0005af68ea54 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20230525234035-dd9d682886f9 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19 // indirect + google.golang.org/genproto v0.0.0-20230920204549-e6e6cdab5c13 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect howett.net/plist v1.0.0 // indirect + lukechampine.com/blake3 v1.2.1 // indirect rsc.io/tmplfunc v0.0.3 // indirect ) diff --git a/go.sum b/go.sum index b29ad7eb76..90b6f6bc1e 100644 --- a/go.sum +++ b/go.sum @@ -13,23 +13,20 @@ cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKV cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= -cloud.google.com/go v0.110.0 h1:Zc8gqp3+a9/Eyph2KDmcGaPtbKRIoqq4YTlL4NMD0Ys= -cloud.google.com/go v0.110.0/go.mod h1:SJnCLqQ0FCFGSZMUNUf84MV3Aia54kn7pi8st7tMzaY= +cloud.google.com/go v0.110.8 h1:tyNdfIxjzaWctIiLYOTalaLKZ17SI44SKFW26QbOhME= +cloud.google.com/go v0.110.8/go.mod h1:Iz8AkXJf1qmxC3Oxoep8R1T36w8B92yU29PcBhHO5fk= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= -cloud.google.com/go/compute v1.19.1 h1:am86mquDUgjGNWxiGn+5PGLbmgiWXlE/yNWpIpNvuXY= -cloud.google.com/go/compute v1.19.1/go.mod h1:6ylj3a05WF8leseCdIf77NK0g1ey+nj5IKd5/kvShxE= -cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= -cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= +cloud.google.com/go/compute/metadata v0.3.0 h1:Tz+eQXMEqDIKRsmY3cHTL6FVaynIjX2QxYC4trgAKZc= +cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= -cloud.google.com/go/iam v0.13.0 h1:+CmB+K0J/33d0zSQ9SlFWUeCCEn5XJA0ZMZ3pHE9u8k= -cloud.google.com/go/iam v0.13.0/go.mod h1:ljOg+rcNfzZ5d6f1nAUJ8ZIxOaZUVoS14bKCtaLZ/D0= -cloud.google.com/go/longrunning v0.4.1 h1:v+yFJOfKC3yZdY6ZUI933pIYdhyhV8S3NpWrXWmg7jM= +cloud.google.com/go/iam v1.1.2 h1:gacbrBdWcoVmGLozRuStX45YKvJtzIjJdAolzUs1sm4= +cloud.google.com/go/iam v1.1.2/go.mod h1:A5avdyVL2tCppe4unb0951eI9jreack+RJ0/d+KUZOU= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= @@ -39,20 +36,22 @@ cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0Zeo cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= -cloud.google.com/go/storage v1.28.1 h1:F5QDG5ChchaAVQhINh24U99OWHURqrW8OmQcGKXcbgI= -cloud.google.com/go/storage v1.28.1/go.mod h1:Qnisd4CqDdo6BGs2AD5LLnEsmSQ80wQ5ogcBBKhU86Y= +cloud.google.com/go/storage v1.30.1 h1:uOdMxAs8HExqBlnLtnQyP0YkvbiDpdGShGKtx6U/oNM= +cloud.google.com/go/storage v1.30.1/go.mod h1:NfxhC0UJE1aXSx7CIIbCf7y9HKT7BiccwkR7+P7gN8E= contrib.go.opencensus.io/exporter/prometheus v0.4.2 h1:sqfsYl5GIY/L570iT+l93ehxaWJs2/OwXtiWwew3oAg= contrib.go.opencensus.io/exporter/prometheus v0.4.2/go.mod h1:dvEHbiKmgvbr5pjaF9fpw1KeYcjrnC1J8B+JKjsZyRQ= dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 h1:bvDV9vkmnHYOMsOr4WLk+Vo07yKIzd94sVoIqshQ4bU= +github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8= github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= +github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/CloudyKit/fastprinter v0.0.0-20170127035650-74b38d55f37a/go.mod h1:EFZQ978U7x8IRnstaskI3IysnWY5Ao3QgZUKOXlsAdw= github.com/CloudyKit/jet v2.1.3-0.20180809161101-62edd43e4f88+incompatible/go.mod h1:HPYO+50pSWkPoj9Q/eq0aRGByCL6ScRlUmiEX5Zgm+w= @@ -62,10 +61,9 @@ github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKz github.com/Joker/jade v1.0.1-0.20190614124447-d475f43051e7/go.mod h1:6E6s8o2AE4KhCrqr6GRJjdC/gNfTdxkIXvuGZZda2VM= github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0= github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= -github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= -github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= -github.com/Microsoft/hcsshim v0.11.1 h1:hJ3s7GbWlGK4YVV92sO88BQSyF4ZLVy7/awqOlPxFbA= -github.com/Microsoft/hcsshim v0.11.1/go.mod h1:nFJmaO4Zr5Y7eADdFOpYswDDlNVbvcIJJNJLECr5JQg= +github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= +github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= +github.com/RaveNoX/go-jsoncommentstrip v1.0.0/go.mod h1:78ihd09MekBnJnxpICcwzCMzGrKSKYe4AqU6PDYYpjk= github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0= github.com/StackExchange/wmi v1.2.1 h1:VIkavFPXSjcnS+O8yTq7NI32k0R5Aj+v39y29VYDOSA= github.com/StackExchange/wmi v1.2.1/go.mod h1:rcmrprowKIVzvc+NUiLncP2uuArMWLCbu9SBzvHz7e8= @@ -80,42 +78,55 @@ github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk5 github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah4HI848JfFxHt+iPb26b4zyfspmqY0/8= github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/apapsch/go-jsonmerge/v2 v2.0.0 h1:axGnT1gRIfimI7gJifB699GoE/oq+F2MU7Dml6nw9rQ= +github.com/apapsch/go-jsonmerge/v2 v2.0.0/go.mod h1:lvDnEdqiQrp0O42VQGgmlKpxL1AP2+08jFMw88y4klk= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/aws/aws-sdk-go v1.44.64 h1:DuDZSBDkFBWW5H8q6i80RJDkBaaa/53KA6Jreqwjlqw= -github.com/aws/aws-sdk-go v1.44.64/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= +github.com/aws/aws-sdk-go v1.44.273 h1:CX8O0gK+cGrgUyv7bgJ6QQP9mQg7u5mweHdNzULH47c= +github.com/aws/aws-sdk-go v1.44.273/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= +github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= +github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= +github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bits-and-blooms/bitset v1.7.0 h1:YjAGVd3XmtK9ktAbX8Zg2g2PwLIMjGREZJHlV4j7NEo= github.com/bits-and-blooms/bitset v1.7.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= +github.com/bmatcuk/doublestar v1.1.1/go.mod h1:UD6OnuiIn0yFxxA2le/rnRU1G4RaI4UvFv1sNto9p6w= github.com/btcsuite/btcd/btcec/v2 v2.2.0 h1:fzn1qaOt32TuLjFlkzYSsBC35Q3KUjT1SwPxiMSCF5k= github.com/btcsuite/btcd/btcec/v2 v2.2.0/go.mod h1:U7MHm051Al6XmscBQ0BoNydpOTsFAn707034b5nY8zU= github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOFYSNEs0TFnxxnS9+4U= +github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/cespare/cp v1.1.1 h1:nCb6ZLdB7NRaqsm91JtQTAme2SKJzXVsdPIPkyJr1MU= -github.com/cespare/cp v1.1.1/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s= +github.com/cespare/cp v0.1.0 h1:SE+dxFebS7Iik5LK0tsi1k9ZCxEaFX4AjQmoyA+1dJk= +github.com/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/checkpoint-restore/go-criu/v5 v5.3.0/go.mod h1:E/eQpaFtUKGOOSEBZgmKAcn+zUUwWxqcaKZlF54wK8E= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/logex v1.2.0/go.mod h1:9+9sk7u7pGNWYMkh0hdiL++6OeibzJccyQU4p4MedaY= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/readline v1.5.0/go.mod h1:x22KAscuvRqlLoK9CsoYsmxoXZMMFVyOl86cAH8qUic= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/chzyer/test v0.0.0-20210722231415-061457976a23/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/cilium/ebpf v0.7.0/go.mod h1:/oI2+1shJiTGAMgl6/RgJr36Eo1jzrRcAWbcXO2usCA= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= +github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cockroachdb/datadriven v1.0.0/go.mod h1:5Ib8Meh+jk1RlHIXej6Pzevx/NLlNvQB9pmSBZErGA4= github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f h1:otljaYPt5hWxV3MUfO5dFPFiOXg9CyG5/kCfayTqsJ4= +github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU= github.com/cockroachdb/errors v1.6.1/go.mod h1:tm6FTP5G81vwJ5lC0SizQo374JNCOPrHyXGitRJoDqM= github.com/cockroachdb/errors v1.8.1 h1:A5+txlVZfOqFBDa4mGz2bUWSp0aHElvHX2bKkdbQu+Y= github.com/cockroachdb/errors v1.8.1/go.mod h1:qGwQn6JmZ+oMjuLwjWzUNqblqk0xl4CVV3SQbGwK7Ac= @@ -134,17 +145,15 @@ github.com/consensys/bavard v0.1.13 h1:oLhMLOFGTLdlda/kma4VOJazblc7IM5y5QPd2A/Yj 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/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U= -github.com/containerd/containerd v1.7.7 h1:QOC2K4A42RQpcrZyptP6z9EJZnlHfHJUfZrAAHe15q4= -github.com/containerd/containerd v1.7.7/go.mod h1:3c4XZv6VeT9qgf9GMTxNTMFxGJrGpI2vz1yk4ye+YY8= github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= +github.com/containerd/platforms v0.2.1 h1:zvwtM3rz2YHPQsF2CHYM8+KtB5dvhISiXh5ZpSBQv6A= +github.com/containerd/platforms v0.2.1/go.mod h1:XHCb+2/hzowdiut9rkudds9bE5yJ7npe7dG/wG+uFPw= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= -github.com/cpuguy83/dockercfg v0.3.1 h1:/FpZ+JaygUR/lZP2NlFI2DVfrOEMAIKP5wWEJdoYe9E= -github.com/cpuguy83/dockercfg v0.3.1/go.mod h1:sugsbF4//dDlL/i+S+rtpIWp+5h0BHJHfjj5/jFyUJc= +github.com/cpuguy83/dockercfg v0.3.2 h1:DlJTyZGBDlXqUZ2Dk2Q3xHs/FtnooJJVaad2S9GKorA= +github.com/cpuguy83/dockercfg v0.3.2/go.mod h1:sugsbF4//dDlL/i+S+rtpIWp+5h0BHJHfjj5/jFyUJc= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= @@ -153,8 +162,10 @@ github.com/crate-crypto/go-kzg-4844 v0.7.0 h1:C0vgZRk4q4EZ/JgPfzuSoxdCq3C3mOZMBS github.com/crate-crypto/go-kzg-4844 v0.7.0/go.mod h1:1kMhvPgI0Ky3yIa+9lFySEBUBXkYxeOi8ZF1sYioxhc= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= +github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= +github.com/cskr/pubsub v1.0.2 h1:vlOzMhl6PFn60gRlTQQsIfVwaPB/B/8MziK8FhEPt/0= +github.com/cskr/pubsub v1.0.2/go.mod h1:/8MzYXk/NJAz782G8RPkFzXTZVu63VotefPnR9TIRis= github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4= -github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -162,23 +173,26 @@ github.com/deckarep/golang-set/v2 v2.1.0 h1:g47V4Or+DUdzbs8FxCCmgb6VYd+ptPAngjM6 github.com/deckarep/golang-set/v2 v2.1.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 h1:YLtO71vCjJRCBcrPMtQ9nqBsqpA1m5sE92cU+pd5Mcc= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 h1:HbphB4TFFXpv7MNrT52FGrrgVXF1owhMVTHFZIlnvd4= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0/go.mod h1:DZGJHZMqrU4JJqFAWUS2UO1+lbSKsdiOoYi9Zzey7Fc= github.com/deepmap/oapi-codegen v1.6.0 h1:w/d1ntwh91XI0b/8ja7+u5SvA4IFfM0UNNLmiDR1gg0= github.com/deepmap/oapi-codegen v1.6.0/go.mod h1:ryDa9AgbELGeB+YEXE1dR53yAjHwFvE9iAUlWl9Al3M= +github.com/deepmap/oapi-codegen/v2 v2.2.0 h1:FW4f7C0Xb6EaezBSB3GYw2QGwHD5ChDflG+3xSZBdvY= +github.com/deepmap/oapi-codegen/v2 v2.2.0/go.mod h1:L4zUv7ULYDtYSb/aYk/xO3OYcQU6BoU/0viULkbi2DE= github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= +github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= +github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= github.com/dlclark/regexp2 v1.7.0 h1:7lJfhqlPssTb1WQx4yvTHN0uElPEv52sbaECrAQxjAo= github.com/dlclark/regexp2 v1.7.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= -github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= -github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v24.0.6+incompatible h1:hceabKCtUgDqPu+qm0NgsaXf28Ljf4/pWFL7xjWWDgE= -github.com/docker/docker v24.0.6+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= -github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= -github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/docker/cli v27.3.1+incompatible h1:qEGdFBF3Xu6SCvCYhc7CzaQTlBmqDuzxPDpigSyeKQQ= +github.com/docker/cli v27.3.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= +github.com/docker/docker v27.3.1+incompatible h1:KttF0XoteNTicmUtBO0L2tP+J7FGRFTjaEF4k6WdhfI= +github.com/docker/docker v27.3.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c= +github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/dop251/goja v0.0.0-20211022113120-dc8c55024d06/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk= @@ -187,10 +201,14 @@ github.com/dop251/goja v0.0.0-20230806174421-c933cf95e127/go.mod h1:QMWlm50DNe14 github.com/dop251/goja_nodejs v0.0.0-20210225215109-d91c329300e7/go.mod h1:hn7BA7c8pLvoGndExHudxTDKZ84Pyvv+90pbBjbTz0Y= github.com/dop251/goja_nodejs v0.0.0-20211022123610-8dd9abb0616d/go.mod h1:DngW8aVqWbuLRMHItjPUyqdj+HWPvnQe8V8y1nDpIbM= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= +github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw= github.com/ethereum/c-kzg-4844 v0.4.0 h1:3MS1s4JtA868KpJxroZoepdV0ZKBp3u/O5HcZ7R3nlY= @@ -201,11 +219,14 @@ github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= +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.0-20190710130421-bcb5799ab5e5 h1:FtmdgXiUlNeRsoNMFlKLDt+S+6hbjVMEW6RGQ7aUf7c= github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= github.com/flosch/pongo2 v0.0.0-20190707114632-bbf5a6c351f4/go.mod h1:T9YF2M40nIgbVgp3rreNmTged+9HrbNTIQf1PsaIiTA= github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= -github.com/frankban/quicktest v1.14.2 h1:SPb1KFFmM+ybpEjPUhCCkZOM5xlovT5UbrMvWnXyBns= +github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= +github.com/frankban/quicktest v1.14.4/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= @@ -214,12 +235,16 @@ github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv 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/getkin/kin-openapi v0.53.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4= +github.com/getkin/kin-openapi v0.128.0 h1:jqq3D9vC9pPq1dGcOCv7yOp1DaEe7c/T1vzcLbITSp4= +github.com/getkin/kin-openapi v0.128.0/go.mod h1:OZrfXzUfGrNbsKj+xmFBx6E5c6yH3At/tAKSc2UszXM= github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s= github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM= github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= github.com/go-chi/chi/v5 v5.0.0/go.mod h1:BBug9lr0cqtdAhsu6R4AAdvufI0/XBzAQSsUqJpoZOs= +github.com/go-chi/chi/v5 v5.1.0 h1:acVI1TYaD+hhedDJ3r54HyA6sExp3HfXq7QWEEY/xMw= +github.com/go-chi/chi/v5 v5.1.0/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= github.com/go-errors/errors v1.0.1 h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w= github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= @@ -236,23 +261,32 @@ github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-logfmt/logfmt v0.5.1 h1:otpy5pqBCBZ1ng9RQ0dPu4PN7ba75Y/aA+UpowDyNVA= github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= -github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +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-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= +github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= +github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= +github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= github.com/go-sourcemap/sourcemap v2.1.3+incompatible h1:W1iEw64niKVGogNgBN3ePyLFfuisuzeidWPMPWmECqU= github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-stack/stack v1.8.1 h1:ntEHSVwIt7PNXNpgPmVfMrNhLtgjlmnZha2kOpuRiDw= github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4= +github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM= +github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= +github.com/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaLENm+P+Tv+MfurjSw0= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= -github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/godbus/dbus/v5 v5.0.6/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= github.com/gogo/googleapis v0.0.0-20180223154316-0cd9801be74a/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= @@ -265,8 +299,8 @@ github.com/gogo/status v1.1.0/go.mod h1:BFv9nrluPLmrS0EmGVvLaPNmRosr9KapBYd5/hpY github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/glog v1.1.1 h1:jxpi2eWoU84wbX9iIEyAeeoac3FLuifZpY9tcNUD9kw= -github.com/golang/glog v1.1.1/go.mod h1:zR+okUeTbrL6EL3xHUDxZuEtGv04p5shwip1+mL/rLQ= +github.com/golang/glog v1.2.1 h1:OptwRhECazUx5ix5TTWC3EZhsZEHWcYWY4FQHTIubm4= +github.com/golang/glog v1.2.1/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -318,14 +352,18 @@ github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8= +github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo= github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/martian/v3 v3.3.2 h1:IqNFLAmvJOgVlpdEBiQbDc2EwKW77amAycfTuWKdfvw= +github.com/google/martian/v3 v3.3.2/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= 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-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= @@ -336,28 +374,40 @@ github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20230207041349-798e818bf904 h1:4/hN5RUoecvl+RmJRE2YxKWtnnQls6rQjjW5oV7qg2U= github.com/google/pprof v0.0.0-20230207041349-798e818bf904/go.mod h1:uglQLonpP8qtYCYyzA+8c/9qtqgA3qsXGYqCPKARAFg= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/s2a-go v0.1.4 h1:1kZ/sQM3srePvKs3tXAvQzo66XfcReoqFpIpIccE7Oc= +github.com/google/s2a-go v0.1.4/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A= github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= -github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/googleapis/enterprise-certificate-proxy v0.2.3 h1:yk9/cqRKtT9wXZSsRH9aurXEpJX+U6FLtpYTdC3R06k= -github.com/googleapis/enterprise-certificate-proxy v0.2.3/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/enterprise-certificate-proxy v0.2.4 h1:uGy6JWR/uMIILU8wbf+OkstIrNiMjGpEIyhx8f6W7s4= +github.com/googleapis/enterprise-certificate-proxy v0.2.4/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/googleapis/gax-go/v2 v2.7.1 h1:gF4c0zjUP2H/s/hEGyLA3I0fA2ZWjzYiONAD6cvPr8A= -github.com/googleapis/gax-go/v2 v2.7.1/go.mod h1:4orTrqY6hXxxaUL4LHIPl6lGo8vAE38/qKbhSAKP6QI= +github.com/googleapis/gax-go/v2 v2.12.0 h1:A+gCJKdRfqXkr+BIRGtZLibNXf0m1f9E4HG56etFpas= +github.com/googleapis/gax-go/v2 v2.12.0/go.mod h1:y+aIqrI5eb1YGMVJfuV3185Ts/D7qKpsEkdD5+I6QGU= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/graph-gophers/graphql-go v1.3.0 h1:Eb9x/q6MFpCLz7jBCiP/WTxjSDrYLR1QY41SORZyNJ0= github.com/graph-gophers/graphql-go v1.3.0/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc= +github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= +github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 h1:YBftPWNWd4WwGqtY2yeZL2ef8rHAxPBD8KFhJpmcqms= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0/go.mod h1:YN5jB8ie0yfIUg6VvR9Kz84aCaG7AsGZnLjhHbUqwPg= +github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= +github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= github.com/hashicorp/go-bexpr v0.1.10 h1:9kuI5PFotCboP3dkDYFr/wi0gg0QVbSNz5oFRpxn4uE= github.com/hashicorp/go-bexpr v0.1.10/go.mod h1:oxlubA2vC/gFVfX1A6JGp7ls7uCDlfJn732ehYYg+g0= github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= +github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/holiman/billy v0.0.0-20230718173358-1c7e68d277a7 h1:3JQNjnMRil1yD0IfZKHF9GxxWKDJGj8I0IqOUol//sw= github.com/holiman/billy v0.0.0-20230718173358-1c7e68d277a7/go.mod h1:5GuXa7vkL8u9FkFuWdVvfR5ix8hRB7DbOAaYULamFpc= @@ -379,6 +429,82 @@ github.com/influxdata/influxdb1-client v0.0.0-20220302092344-a9ab5670611c h1:qSH github.com/influxdata/influxdb1-client v0.0.0-20220302092344-a9ab5670611c/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839 h1:W9WBk7wlPfJLvMCdtV4zPulc4uCPrlywQOmbFOhgQNU= github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839/go.mod h1:xaLFMmpvUxqXtVkUJfg9QmT88cDaCJ3ZKgdZ78oO8Qo= +github.com/invopop/yaml v0.3.1 h1:f0+ZpmhfBSS4MhG+4HYseMdJhoeeopbSKbq5Rpeelso= +github.com/invopop/yaml v0.3.1/go.mod h1:PMOp3nn4/12yEZUFfmOuNHJsZToEEOwoWsT+D81KkeA= +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/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1HyQ= +github.com/ipfs/go-bitswap v0.11.0/go.mod h1:05aE8H3XOU+LXpTedeAS0OZpcO1WFsj5niYQH9a1Tmk= +github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= +github.com/ipfs/go-block-format v0.0.3/go.mod h1:4LmD4ZUw0mhO+JSKdpWwrzATiEfM7WWgQ8H5l6P8MVk= +github.com/ipfs/go-block-format v0.1.2 h1:GAjkfhVx1f4YTODS6Esrj1wt2HhrtwTnhEr+DyPUaJo= +github.com/ipfs/go-block-format v0.1.2/go.mod h1:mACVcrxarQKstUU3Yf/RdwbC4DzPV6++rO2a3d+a/KE= +github.com/ipfs/go-blockservice v0.5.2 h1:in9Bc+QcXwd1apOVM7Un9t8tixPKdaHQFdLSUM1Xgk8= +github.com/ipfs/go-blockservice v0.5.2/go.mod h1:VpMblFEqG67A/H2sHKAemeH9vlURVavlysbdUI632yk= +github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/ipfs/go-cid v0.0.2/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/ipfs/go-cid v0.0.3/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/ipfs/go-cid v0.0.4/go.mod h1:4LLaPOQwmk5z9LBgQnpkivrx8BJjUyGwTXCd5Xfj6+M= +github.com/ipfs/go-cid v0.0.6/go.mod h1:6Ux9z5e+HpkQdckYoX1PG/6xqKspzlEIR5SDmgqgC/I= +github.com/ipfs/go-cid v0.0.7/go.mod h1:6Ux9z5e+HpkQdckYoX1PG/6xqKspzlEIR5SDmgqgC/I= +github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s= +github.com/ipfs/go-cid v0.4.1/go.mod h1:uQHwDeX4c6CtyrFwdqyhpNcxVewur1M7l7fNU7LKwZk= +github.com/ipfs/go-datastore v0.6.0 h1:JKyz+Gvz1QEZw0LsX1IBn+JFCJQH4SJVFtM4uWU0Myk= +github.com/ipfs/go-datastore v0.6.0/go.mod h1:rt5M3nNbSO/8q1t4LNkLyUwRs8HupMeN/8O4Vn9YAT8= +github.com/ipfs/go-detect-race v0.0.1 h1:qX/xay2W3E4Q1U7d9lNs1sU9nvguX0a7319XbyQ6cOk= +github.com/ipfs/go-detect-race v0.0.1/go.mod h1:8BNT7shDZPo99Q74BpGMK+4D8Mn4j46UU0LZ723meps= +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-delay v0.0.1 h1:r/UXYyRcddO6thwOnhiznIAiSvxMECGgtv35Xs1IeRQ= +github.com/ipfs/go-ipfs-delay v0.0.1/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= +github.com/ipfs/go-ipfs-ds-help v1.1.1 h1:B5UJOH52IbcfS56+Ul+sv8jnIV10lbjLF5eOO0C66Nw= +github.com/ipfs/go-ipfs-ds-help v1.1.1/go.mod h1:75vrVCkSdSFidJscs8n4W+77AtTpCIAdDGAwjitJMIo= +github.com/ipfs/go-ipfs-exchange-interface v0.2.1 h1:jMzo2VhLKSHbVe+mHNzYgs95n0+t0Q69GQ5WhRDZV/s= +github.com/ipfs/go-ipfs-exchange-interface v0.2.1/go.mod h1:MUsYn6rKbG6CTtsDp+lKJPmVt3ZrCViNyH3rfPGsZ2E= +github.com/ipfs/go-ipfs-exchange-offline v0.3.0 h1:c/Dg8GDPzixGd0MC8Jh6mjOwU57uYokgWRFidfvEkuA= +github.com/ipfs/go-ipfs-exchange-offline v0.3.0/go.mod h1:MOdJ9DChbb5u37M1IcbrRB02e++Z7521fMxqCNRrz9s= +github.com/ipfs/go-ipfs-pq v0.0.2 h1:e1vOOW6MuOwG2lqxcLA+wEn93i/9laCY8sXAw76jFOY= +github.com/ipfs/go-ipfs-pq v0.0.2/go.mod h1:LWIqQpqfRG3fNc5XsnIhz/wQ2XXGyugQwls7BgUmUfY= +github.com/ipfs/go-ipfs-routing v0.3.0 h1:9W/W3N+g+y4ZDeffSgqhgo7BsBSJwPMcyssET9OWevc= +github.com/ipfs/go-ipfs-routing v0.3.0/go.mod h1:dKqtTFIql7e1zYsEuWLyuOU+E0WJWW8JjbTPLParDWo= +github.com/ipfs/go-ipfs-util v0.0.1/go.mod h1:spsl5z8KUnrve+73pOhSVZND1SIxPW5RyBCNzQxlJBc= +github.com/ipfs/go-ipfs-util v0.0.2/go.mod h1:CbPtkWJzjLdEcezDns2XYaehFVNXG9zrdrtMecczcsQ= +github.com/ipfs/go-ipfs-util v0.0.3 h1:2RFdGez6bu2ZlZdI+rWfIdbQb1KudQp3VGwPtdNCmE0= +github.com/ipfs/go-ipfs-util v0.0.3/go.mod h1:LHzG1a0Ig4G+iZ26UUOMjHd+lfM84LZCrn17xAKWBvs= +github.com/ipfs/go-ipld-cbor v0.0.6 h1:pYuWHyvSpIsOOLw4Jy7NbBkCyzLDcl64Bf/LZW7eBQ0= +github.com/ipfs/go-ipld-cbor v0.0.6/go.mod h1:ssdxxaLJPXH7OjF5V4NSjBbcfh+evoR4ukuru0oPXMA= +github.com/ipfs/go-ipld-format v0.0.1/go.mod h1:kyJtbkDALmFHv3QR6et67i35QzO3S0dCDnkOJhcZkms= +github.com/ipfs/go-ipld-format v0.2.0/go.mod h1:3l3C1uKoadTPbeNfrDi+xMInYKlx2Cvg1BuydPSdzQs= +github.com/ipfs/go-ipld-format v0.4.0 h1:yqJSaJftjmjc9jEOFYlpkwOLVKv68OD27jFLlSghBlQ= +github.com/ipfs/go-ipld-format v0.4.0/go.mod h1:co/SdBE8h99968X0hViiw1MNlh6fvxxnHpvVLnH7jSM= +github.com/ipfs/go-ipld-legacy v0.1.1 h1:BvD8PEuqwBHLTKqlGFTHSwrwFOMkVESEvwIYwR2cdcc= +github.com/ipfs/go-ipld-legacy v0.1.1/go.mod h1:8AyKFCjgRPsQFf15ZQgDB8Din4DML/fOmKZkkFkrIEg= +github.com/ipfs/go-libipfs v0.4.0 h1:TkUxJGjtPnSzAgkw7VjS0/DBay3MPjmTBa4dGdUQCDE= +github.com/ipfs/go-libipfs v0.4.0/go.mod h1:XsU2cP9jBhDrXoJDe0WxikB8XcVmD3k2MEZvB3dbYu8= +github.com/ipfs/go-log v1.0.5 h1:2dOuUCB1Z7uoczMWgAyDck5JLb72zHzrMnGnCNNbvY8= +github.com/ipfs/go-log v1.0.5/go.mod h1:j0b8ZoR+7+R99LD9jZ6+AJsrzkPbSXbZfGakb5JPtIo= +github.com/ipfs/go-log/v2 v2.1.3/go.mod h1:/8d0SH3Su5Ooc31QlL1WysJhvyOTDCjcCZ9Axpmri6g= +github.com/ipfs/go-log/v2 v2.5.1 h1:1XdUzF7048prq4aBjDQQ4SL5RxftpRGdXhNRwKSAlcY= +github.com/ipfs/go-log/v2 v2.5.1/go.mod h1:prSpmC1Gpllc9UYWxDiZDreBYw7zp4Iqp1kOLU9U5UI= +github.com/ipfs/go-merkledag v0.10.0 h1:IUQhj/kzTZfam4e+LnaEpoiZ9vZF6ldimVlby+6OXL4= +github.com/ipfs/go-merkledag v0.10.0/go.mod h1:zkVav8KiYlmbzUzNM6kENzkdP5+qR7+2mCwxkQ6GIj8= +github.com/ipfs/go-metrics-interface v0.0.1 h1:j+cpbjYvu4R8zbleSs36gvB7jR+wsL2fGD6n0jO4kdg= +github.com/ipfs/go-metrics-interface v0.0.1/go.mod h1:6s6euYU4zowdslK0GKHmqaIZ3j/b/tL7HTWtJ4VPgWY= +github.com/ipfs/go-peertaskqueue v0.8.0 h1:JyNO144tfu9bx6Hpo119zvbEL9iQ760FHOiJYsUjqaU= +github.com/ipfs/go-peertaskqueue v0.8.0/go.mod h1:cz8hEnnARq4Du5TGqiWKgMr/BOSQ5XOgMOh1K5YYKKM= +github.com/ipfs/go-unixfs v0.4.6 h1:4PCH8+ptflEqmD1ifrdjGu0hA/MfM1s4QlrsQb4BvJM= +github.com/ipfs/go-unixfs v0.4.6/go.mod h1:BIznJNvt/gEx/ooRMI4Us9K8+qeGO7vx1ohnbk8gjFg= +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/ipld/go-car v0.6.0 h1:d5QrGLnHAxiNLHor+DKGrLdqnM0dQJh2whfSXRDq6J0= +github.com/ipld/go-car v0.6.0/go.mod h1:tBrW1XZ3L2XipLxA69RnTVGW3rve6VX4TbaTYkq8aEA= +github.com/ipld/go-codec-dagpb v1.6.0 h1:9nYazfyu9B1p3NAgfVdpRco3Fs2nFC72DqVsMj6rOcc= +github.com/ipld/go-codec-dagpb v1.6.0/go.mod h1:ANzFhfP2uMJxRBr8CE+WQWs5UsNa0pYtmKZ+agnUw9s= +github.com/ipld/go-ipld-prime v0.9.1-0.20210324083106-dc342a9917db/go.mod h1:KvBLMr4PX1gWptgkzRjVZCrLmSGcZCb/jioOQwCqZN8= +github.com/ipld/go-ipld-prime v0.20.0 h1:Ud3VwE9ClxpO2LkCYP7vWPc0Fo+dYdYzgxUJZ3uRG4g= +github.com/ipld/go-ipld-prime v0.20.0/go.mod h1:PzqZ/ZR981eKbgdr3y2DJYeD/8bgMawdGVlJDE8kK+M= github.com/iris-contrib/blackfriday v2.0.0+incompatible/go.mod h1:UzZ2bDEoaSGPbkg6SAB4att1aAwTmVIx/5gCVqeyUdI= github.com/iris-contrib/go.uuid v2.0.0+incompatible/go.mod h1:iz2lgM/1UnEf1kP0L/+fafWORmlnuysV2EMP8MW+qe0= github.com/iris-contrib/i18n v0.0.0-20171121225848-987a633949d0/go.mod h1:pMCz62A0xJL6I+umB2YTlFRwWXaDFA0jy+5HzGiJjqI= @@ -389,20 +515,29 @@ github.com/jaypipes/ghw v0.10.0 h1:UHu9UX08Py315iPojADFPOkmjTsNzHj4g4adsNKKteY= github.com/jaypipes/ghw v0.10.0/go.mod h1:jeJGbkRB2lL3/gxYzNYzEDETV1ZJ56OKr+CSeSEym+g= github.com/jaypipes/pcidb v1.0.0 h1:vtZIfkiCUE42oYbJS0TAq9XSfSmcsgo9IdxSm9qzYU8= github.com/jaypipes/pcidb v1.0.0/go.mod h1:TnYUvqhPBzCKnH34KrIX22kAeEbDCSRJ9cqLRCuNDfk= +github.com/jbenet/go-cienv v0.1.0/go.mod h1:TqNnHUmJgXau0nCzC7kXWeotg3J9W34CUv5Djy1+FlA= +github.com/jbenet/goprocess v0.1.4 h1:DRGOFReOMqqDNXwW70QkacFW0YN9QnwLV0Vqk+3oU0o= +github.com/jbenet/goprocess v0.1.4/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/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.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= +github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/juju/errors v0.0.0-20181118221551-089d3ea4e4d5/go.mod h1:W54LbzXuIE0boCoNJfwqpmkKJ1O4TCTZMetAt6jGk7Q= +github.com/juju/gnuflag v0.0.0-20171113085948-2ce1bb71843d/go.mod h1:2PavIy+JPciBPrBUjwbNvtwB6RQlve+hkpll6QSNmOE= github.com/juju/loggo v0.0.0-20180524022052-584905176618/go.mod h1:vgyd7OREkbtVEN/8IXZe5Ooef3LQePvuBm9UWj6ZL8U= github.com/juju/testing v0.0.0-20180920084828-472a3e8b2073/go.mod h1:63prj8cnj0tU0S9OHjGJn+b1h0ZghCndfnbQolrYTwA= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= @@ -420,11 +555,17 @@ 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.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.9.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= -github.com/klauspost/compress v1.16.3 h1:XuJt9zzcnaz6a16/OU53ZjWp/v7/42WcR5t2a0PcNQY= -github.com/klauspost/compress v1.16.3/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/klauspost/compress v1.17.4 h1:Ej5ixsIri7BrIjBkRZLTo6ghwrEtHFk7ijlczPW4fZ4= +github.com/klauspost/compress v1.17.4/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= +github.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/klauspost/cpuid/v2 v2.2.6 h1:ndNyv040zDGIDh8thGkXYjnFtiN02M1PVVF+JE/48xc= +github.com/klauspost/cpuid/v2 v2.2.6/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/koron/go-ssdp v0.0.3 h1:JivLMY45N76b4p/vsWGOKewBQu6uf39y8l+AQ7sDKx8= +github.com/koron/go-ssdp v0.0.3/go.mod h1:b2MxI6yh02pKrsyNoQUsk4+YNikaGhe4894J+Q5lDvA= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= @@ -436,12 +577,37 @@ github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= 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/labstack/echo/v4 v4.1.11/go.mod h1:i541M3Fj6f76NZtHSj7TXnyM8n2gaodfvfxNnFqi74g= github.com/labstack/echo/v4 v4.2.1/go.mod h1:AA49e0DZ8kk5jTOOCKNuPR6oTnBS0dYiM4FW1e6jwpg= github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= -github.com/livepeer/go-tools v0.0.0-20220805063103-76df6beb6506 h1:qKon23c1RQPvL5Oya/hkImbaXNMkt6VdYtnh5jcIhoY= -github.com/livepeer/go-tools v0.0.0-20220805063103-76df6beb6506/go.mod h1:aLVS1DT0ur9kpr0IlNI4DNcm9vVjRRUjDnwuEUm0BdQ= +github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= +github.com/libp2p/go-buffer-pool v0.0.2/go.mod h1:MvaB6xw5vOrDl8rYZGLFdKAuk/hRoRZd1Vi32+RXyFM= +github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8= +github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg= +github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38yPW7c= +github.com/libp2p/go-cidranger v1.1.0/go.mod h1:KWZTfSr+r9qEo9OkI9/SIEeAtw+NNoU0dXIXt15Okic= +github.com/libp2p/go-libp2p v0.23.4 h1:hWi9XHSOVFR1oDWRk7rigfyA4XNMuYL20INNybP9LP8= +github.com/libp2p/go-libp2p v0.23.4/go.mod h1:s9DEa5NLR4g+LZS+md5uGU4emjMWFiqkZr6hBTY8UxI= +github.com/libp2p/go-libp2p-asn-util v0.2.0 h1:rg3+Os8jbnO5DxkC7K/Utdi+DkY3q/d1/1q+8WeNAsw= +github.com/libp2p/go-libp2p-asn-util v0.2.0/go.mod h1:WoaWxbHKBymSN41hWSq/lGKJEca7TNm58+gGJi2WsLI= +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-testing v0.12.0 h1:EPvBb4kKMWO29qP4mZGyhVzUyR25dvfUIK5WDu6iPUA= +github.com/libp2p/go-libp2p-testing v0.12.0/go.mod h1:KcGDRXyN7sQCllucn1cOOS+Dmm7ujhfEyXQL5lvkcPg= +github.com/libp2p/go-msgio v0.2.0 h1:W6shmB+FeynDrUVl2dgFQvzfBZcXiyqY4VmpQLu9FqU= +github.com/libp2p/go-msgio v0.2.0/go.mod h1:dBVM1gW3Jk9XqHkU4eKdGvVHdLa51hoGfll6jMJMSlY= +github.com/libp2p/go-nat v0.1.0 h1:MfVsH6DLcpa04Xr+p8hmVRG4juse0s3J8HyNWYHffXg= +github.com/libp2p/go-nat v0.1.0/go.mod h1:X7teVkwRHNInVNWQiO/tAiAVRwSr5zoRz4YSTC3uRBM= +github.com/libp2p/go-netroute v0.2.0 h1:0FpsbsvuSnAhXFnCY0VLFbJOzaK0VnP0r1QT/o4nWRE= +github.com/libp2p/go-netroute v0.2.0/go.mod h1:Vio7LTzZ+6hoT4CMZi5/6CpY3Snzh2vgZhWgxMNwlQI= +github.com/libp2p/go-openssl v0.1.0 h1:LBkKEcUv6vtZIQLVTegAil8jbNpJErQ9AnT+bWV+Ooo= +github.com/libp2p/go-openssl v0.1.0/go.mod h1:OiOxwPpL3n4xlenjx2h7AwSGaFSC/KZvf6gNdOBQMtc= +github.com/livepeer/ai-worker v0.12.1 h1:V6XGxnRmq02GuJP/PYRKTXIZAd2F1jTuErweO5boWxU= +github.com/livepeer/ai-worker v0.12.1/go.mod h1:/Deme7XXRP4BiYXt/j694Ygw+dh8rWJdikJsKY64sjE= +github.com/livepeer/go-tools v0.3.6-0.20240130205227-92479de8531b h1:VQcnrqtCA2UROp7q8ljkh2XA/u0KRgVv0S1xoUvOweE= +github.com/livepeer/go-tools v0.3.6-0.20240130205227-92479de8531b/go.mod h1:hwJ5DKhl+pTanFWl+EUpw1H7ukPO/H+MFpgA7jjshzw= github.com/livepeer/joy4 v0.1.2-0.20191121080656-b2fea45cbded h1:ZQlvR5RB4nfT+cOQee+WqmaDOgGtP2oDMhcVvR4L0yA= github.com/livepeer/joy4 v0.1.2-0.20191121080656-b2fea45cbded/go.mod h1:xkDdm+akniYxVT9KW1Y2Y7Hso6aW+rZObz3nrA9yTHw= github.com/livepeer/livepeer-data v0.7.5-0.20231004073737-06f1f383fb18 h1:4oH3NqV0NvcdS44Ld3zK2tO8IUiNozIggm74yobQeZg= @@ -457,6 +623,8 @@ github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0V github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/matryer/moq v0.0.0-20190312154309-6cfb0558e1bd/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= @@ -470,8 +638,10 @@ github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2y github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= -github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-pointer v0.0.1 h1:n+XhsuGeVO6MEAp7xyEukFINEa+Quek5psIR/ylA6o0= +github.com/mattn/go-pointer v0.0.1/go.mod h1:2zXcozF6qYGgmsG+SeTZz3oAbFLdD3OWqnUbNvJZAlc= github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= @@ -485,6 +655,18 @@ github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfr github.com/mediocregopher/mediocre-go-lib v0.0.0-20181029021733-cb65787f37ed/go.mod h1:dSsfyI2zABAdhcbvkXqgxOxrCsbYeHCPgrZkku60dSg= github.com/mediocregopher/radix/v3 v3.3.0/go.mod h1:EmfVyvspXz1uZEyPBMyGK+kjWiKQGvsUt6O3Pj+LDCQ= github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc= +github.com/miekg/dns v1.1.50 h1:DQUfb9uc6smULcREF09Uc+/Gd46YWqJd5DbpPE9xkcA= +github.com/miekg/dns v1.1.50/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= +github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34= +github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM= +github.com/minio/minio-go/v7 v7.0.66 h1:bnTOXOHjOqv/gcMuiVbN9o2ngRItvqE774dG9nq0Dzw= +github.com/minio/minio-go/v7 v7.0.66/go.mod h1:DHAgmyQEGdW3Cif0UooKOyrT3Vxs82zNdV6tkKhRtbs= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/minio/sha256-simd v0.1.1-0.20190913151208-6de447530771/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= +github.com/minio/sha256-simd v1.0.0/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy5RFepssQM= +github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM= +github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= @@ -495,22 +677,66 @@ github.com/mitchellh/pointerstructure v1.2.0/go.mod h1:BRAsLI5zgXmw97Lf6s25bs8oh github.com/mmcloughlin/addchain v0.4.0 h1:SobOdjm2xLj1KkXN5/n0xTIWyZA2+s99UCY1iPfkHRY= github.com/mmcloughlin/addchain v0.4.0/go.mod h1:A86O+tHqZLMNO4w6ZZ4FlVQEadcoqkyU72HC5wJ4RlU= github.com/mmcloughlin/profile v0.1.1/go.mod h1:IhHD7q1ooxgwTgjxQYkACGA77oFTDdFVejUS1/tS/qU= +github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0= +github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo= github.com/moby/patternmatcher v0.6.0 h1:GmP9lR19aU5GqSSFko+5pRqHi+Ohk1O69aFiKkVGiPk= github.com/moby/patternmatcher v0.6.0/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc= -github.com/moby/sys/mountinfo v0.5.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU= github.com/moby/sys/sequential v0.5.0 h1:OPvI35Lzn9K04PBbCLW0g4LcFAJgHsvXsRyewg5lXtc= github.com/moby/sys/sequential v0.5.0/go.mod h1:tH2cOOs5V9MlPiXcQzRC+eEyab644PWKGRYaaV5ZZlo= +github.com/moby/sys/user v0.3.0 h1:9ni5DlcW5an3SvRSx4MouotOygvzaXbaSrc/wGDFWPo= +github.com/moby/sys/user v0.3.0/go.mod h1:bG+tYYYJgaMtRKgEmuueC0hJEAZWwtIbZTB+85uoHjs= +github.com/moby/sys/userns v0.1.0 h1:tVLXkFOxVu9A64/yh59slHVv9ahO9UIev4JZusOLG/g= +github.com/moby/sys/userns v0.1.0/go.mod h1:IHUYgu/kao6N8YZlp9Cf444ySSvCmDlmzUcYfDHOl28= github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0= github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= +github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= github.com/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ= -github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ= +github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= +github.com/mr-tron/base58 v1.1.3/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= +github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= +github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= +github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= +github.com/multiformats/go-base32 v0.1.0 h1:pVx9xoSPqEIQG8o+UbAe7DNi51oej1NtK+aGkbLYxPE= +github.com/multiformats/go-base32 v0.1.0/go.mod h1:Kj3tFY6zNr+ABYMqeUNeGvkIC/UYgtWibDcT0rExnbI= +github.com/multiformats/go-base36 v0.1.0/go.mod h1:kFGE83c6s80PklsHO9sRn2NCoffoRdUUOENyW/Vv6sM= +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.8.0 h1:aqjksEcqK+iD/Foe1RRFsGZh8+XFiGo7FgUCZlpv3LU= +github.com/multiformats/go-multiaddr v0.8.0/go.mod h1:Fs50eBDWvZu+l3/9S6xAE7ZYj6yhxlvaVZjakWN7xRs= +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= +github.com/multiformats/go-multiaddr-fmt v0.1.0/go.mod h1:hGtDIW4PU4BqJ50gW2quDuPVjyWNZxToGUh/HwTZYJo= +github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs= +github.com/multiformats/go-multibase v0.0.3/go.mod h1:5+1R4eQrT3PkYZ24C3W2Ue2tPwIdYQD509ZjSb5y9Oc= +github.com/multiformats/go-multibase v0.2.0 h1:isdYCVLvksgWlMW9OZRYJEa9pZETFivncJHmHnnd87g= +github.com/multiformats/go-multibase v0.2.0/go.mod h1:bFBZX4lKCA/2lyOFSAoKH5SS6oPyjtnzK/XTFDPkNuk= +github.com/multiformats/go-multicodec v0.8.0 h1:evBmgkbSQux+Ds2IgfhkO38Dl2GDtRW8/Rp6YiSHX/Q= +github.com/multiformats/go-multicodec v0.8.0/go.mod h1:GUC8upxSBE4oG+q3kWZRw/+6yC1BqO550bjhWsJbZlw= +github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= +github.com/multiformats/go-multihash v0.0.10/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew= +github.com/multiformats/go-multihash v0.0.13/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc= +github.com/multiformats/go-multihash v0.0.14/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc= +github.com/multiformats/go-multihash v0.0.15/go.mod h1:D6aZrWNLFTV/ynMpKsNtB40mJzmCl4jb1alC0OvHiHg= +github.com/multiformats/go-multihash v0.2.2 h1:Uu7LWs/PmWby1gkj1S1DXx3zyd3aVabA4FiMKn/2tAc= +github.com/multiformats/go-multihash v0.2.2/go.mod h1:dXgKXCXjBzdscBLk9JkjINiEsCKRVch90MdaGiKsvSM= +github.com/multiformats/go-multistream v0.3.3 h1:d5PZpjwRgVlbwfdTDjife7XszfZd8KYWfROYFlGcR8o= +github.com/multiformats/go-multistream v0.3.3/go.mod h1:ODRoqamLUsETKS9BNcII4gcRsJBU5VAwRIv7O39cEXg= +github.com/multiformats/go-varint v0.0.5/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= +github.com/multiformats/go-varint v0.0.6/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/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/nats-io/nats.go v1.8.1/go.mod h1:BrFz9vVn0fU3AcH9Vn4Kd7W0NpJ651tD5omQ3M8LwxM= @@ -518,6 +744,10 @@ github.com/nats-io/nkeys v0.0.2/go.mod h1:dab7URMsZm6Z/jp9Z5UGa87Uutgc2mVpXLC4B7 github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/oapi-codegen/nethttp-middleware v1.0.1 h1:ZWvwfnMU0eloHX1VEJmQscQm3741t0vCm0eSIie1NIo= +github.com/oapi-codegen/nethttp-middleware v1.0.1/go.mod h1:P7xtAvpoqNB+5obR9qRCeefH7YlXWSK3KgPs/9WB8tE= +github.com/oapi-codegen/runtime v1.1.1 h1:EXLHh0DXIJnWhdRPN2w4MXAzFyE4CskzhNLUmtpMYro= +github.com/oapi-codegen/runtime v1.1.1/go.mod h1:SK9X900oXmPWilYR5/WKPzt3Kqxn/uS/+lbpREv+eCg= github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= @@ -526,22 +756,23 @@ github.com/onsi/ginkgo v1.13.0/go.mod h1:+REjRxOmWfHCjfv9TTWB1jD1Frx4XydAD3zm1ls 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.4.0 h1:+Ig9nvqgS5OBSACXNk15PLdp0U9XPYROt9CFzVdFGIs= +github.com/onsi/ginkgo/v2 v2.4.0/go.mod h1:iHkDK1fKGcBoEHT5W7YBq4RFWaQulw+caOMkAt4OrFo= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.22.1 h1:pY8O4lBfsHKZHM/6nrxkhVPUznOlIu3quZcKP/M20KI= +github.com/onsi/gomega v1.22.1/go.mod h1:x6n7VNe4hw0vkyYUM4mjIXx3JbLiPaBPNgB7PRQ1tuM= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= -github.com/opencontainers/image-spec v1.1.0-rc5 h1:Ygwkfw9bpDvs+c9E34SdgGOj41dX/cbdlwvlWt0pnFI= -github.com/opencontainers/image-spec v1.1.0-rc5/go.mod h1:X4pATf0uXsnn3g5aiGIsVnJBR4mxhKzfwmvK/B2NTm8= -github.com/opencontainers/runc v1.1.5 h1:L44KXEpKmfWDcS02aeGm8QNTFXTo2D+8MYGDIJ/GDEs= -github.com/opencontainers/runc v1.1.5/go.mod h1:1J5XiS+vdZ3wCyZybsuxXZWGrgSr8fFJHLXuG2PsnNg= -github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= -github.com/opencontainers/selinux v1.10.0/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI= -github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU= +github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug= +github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= +github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc= github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/perimeterx/marshmallow v1.1.5 h1:a2LALqQ1BlHM8PZblsDdidgv1mWi1DgC2UmX50IvK2s= +github.com/perimeterx/marshmallow v1.1.5/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw= github.com/peterbourgon/ff/v3 v3.4.0 h1:QBvM/rizZM1cB0p0lGMdmR7HxZeI/ZrBWB4DqLkMUBc= github.com/peterbourgon/ff/v3 v3.4.0/go.mod h1:zjJVUhx+twciwfDl0zBcFzl4dW8axCRyXE/eKY9RztQ= github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7 h1:oYW+YCJ1pachXTQmzR3rNLYGGz4g/UgFcjb28p/viDM= @@ -557,6 +788,10 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/polydawn/refmt v0.0.0-20190221155625-df39d6c2d992/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o= +github.com/polydawn/refmt v0.0.0-20190807091052-3d65705ee9f1/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o= +github.com/polydawn/refmt v0.89.0 h1:ADJTApkvkeBZsN0tBTx8QjpD9JkmxbKp0cxfr9qszm4= +github.com/polydawn/refmt v0.89.0/go.mod h1:/zvteZs/GwLtCgZ4BL6CBsk9IKIlexP43ObX9AxTqTw= github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw= github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= @@ -597,24 +832,27 @@ github.com/rabbitmq/rabbitmq-stream-go-client v1.1.1 h1:Fji7RgmMggroffCyL0QtrhMx github.com/rabbitmq/rabbitmq-stream-go-client v1.1.1/go.mod h1:2pRPe6/8y2ZenIbnucUULMhfrPpzM90EPfjOkpsedVo= github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +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.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= -github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +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 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= +github.com/rs/xid v1.5.0 h1:mKX4bl4iPYJtEIxp6CYiUuLQ/8DYMoz0PUdtGgMFRVc= +github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= 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= github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/sclevine/agouti v3.0.0+incompatible/go.mod h1:b4WX9W9L1sfQKXeJf1mUTLZKJ48R1S7H23Ji7oFO5Bw= -github.com/seccomp/libseccomp-golang v0.9.2-0.20220502022130-f33da4d89646/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible h1:Bn1aCHHRnjv4Bl16T8rcaFjYSrGrIZvpiGO6P3Q4GpU= github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= -github.com/shirou/gopsutil/v3 v3.23.9 h1:ZI5bWVeu2ep4/DIxB4U9okeYJ7zp/QLTO4auRb/ty/E= -github.com/shirou/gopsutil/v3 v3.23.9/go.mod h1:x/NWSb71eMcjFIO0vhyGW5nZ7oSIgVjrCnADckb85GA= +github.com/shirou/gopsutil/v3 v3.23.12 h1:z90NtUkp3bMtmICZKpC4+WaknU1eXtp5vtbQ11DgpE4= +github.com/shirou/gopsutil/v3 v3.23.12/go.mod h1:1FrWgea594Jp7qmjHUUPlJDTPgcsb9mGnXDxavtikzM= github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM= github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ= github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU= @@ -623,24 +861,34 @@ github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeV github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= -github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/assertions v1.2.0 h1:42S6lae5dvLc7BrLu/0ugRtcFVjoJNMC/N3yZFZkDFs= +github.com/smartystreets/assertions v1.2.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo= +github.com/smartystreets/goconvey v0.0.0-20190222223459-a17d461953aa/go.mod h1:2RVY1rIf+2J2o/IM9+vPq9RzmHDSseB7FoXiSNIUsoU= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/smartystreets/goconvey v1.7.2 h1:9RBaZCeXEQ3UselpuwUQHltGVXvdwm6cv1hgR6gDIPg= +github.com/smartystreets/goconvey v1.7.2/go.mod h1:Vw0tHAZW6lzCRk3xgdin6fKYcG+G3Pg9vgXWeJpQFMM= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 h1:RC6RW7j+1+HkWaX/Yh71Ee5ZHaHYt7ZP4sQgUrm6cDU= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc= +github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= +github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= +github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad/go.mod h1:qLr4V1qq6nMqFKkMo8ZTx3f+BZEkzsRUY10Xsm2mwU0= github.com/status-im/keycard-go v0.2.0 h1:QDLFswOQu1r5jsycloeQh3bVU8n/NatHHaZobtDnDzA= github.com/status-im/keycard-go v0.2.0/go.mod h1:wlp8ZLbsmrF6g6WjugPAx+IzoLrkdf9+mHxBEeo3Hbg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= @@ -650,16 +898,16 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/stvp/go-udp-testing v0.0.0-20201019212854-469649b16807/go.mod h1:7jxmlfBCDBXRzr0eAQJ48XC1hBu1np4CS5+cHEYfwpc= github.com/supranational/blst v0.3.11 h1:LyU6FolezeWAhvQk0k6O/d49jqgO52MSDDfYgbeoEm4= github.com/supranational/blst v0.3.11/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= -github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= 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/testcontainers/testcontainers-go v0.26.0 h1:uqcYdoOHBy1ca7gKODfBd9uTHVK3a7UL848z09MVZ0c= -github.com/testcontainers/testcontainers-go v0.26.0/go.mod h1:ICriE9bLX5CLxL9OFQ2N+2N+f+803LNJ1utJb1+Inx0= +github.com/testcontainers/testcontainers-go v0.34.0 h1:5fbgF0vIN5u+nD3IWabQwRybuB4GY8G2HHgCkbMzMHo= +github.com/testcontainers/testcontainers-go v0.34.0/go.mod h1:6P/kMkQe8yqPHfPWNulFGdFHTD8HB2vLq/231xY2iPQ= github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU= github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI= github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk= @@ -668,7 +916,9 @@ github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2n github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= -github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= +github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= +github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= +github.com/urfave/cli v1.22.10/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli v1.22.12 h1:igJgVw1JdKH+trcLWLeLwZjU9fEfPesQ+9/e4MQ44S8= github.com/urfave/cli v1.22.12/go.mod h1:sSBEIC79qR6OvcmsD4U3KABeOTxDqQtdDnaFuUN30b8= github.com/urfave/cli/v2 v2.25.7 h1:VAzn5oq403l5pHjc4OhD54+XGO9cdKVL/7lDjF+iKUs= @@ -679,8 +929,17 @@ github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBn github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= -github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE= -github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU= +github.com/vincent-petithory/dataurl v1.0.0 h1:cXw+kPto8NLuJtlMsI152irrVw9fRDX8AbShPRpg2CI= +github.com/vincent-petithory/dataurl v1.0.0/go.mod h1:FHafX5vmDzyP+1CQATJn7WFKc9CvnvxyvZy6I1MrG/U= +github.com/warpfork/go-testmark v0.11.0 h1:J6LnV8KpceDvo7spaNU4+DauH2n1x+6RaO2rJrmpQ9U= +github.com/warpfork/go-testmark v0.11.0/go.mod h1:jhEf8FVxd+F17juRubpmut64NEG6I2rgkUhlcqqXwE0= +github.com/warpfork/go-wish v0.0.0-20180510122957-5ad1f5abf436/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= +github.com/warpfork/go-wish v0.0.0-20200122115046-b9ea61034e4a/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= +github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0 h1:GDDkbFiaK8jsSDJfjId/PEGEShv6ugrt4kYsC5UIDaQ= +github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= +github.com/whyrusleeping/cbor-gen v0.0.0-20200123233031-1cdf64d27158/go.mod h1:Xj/M2wWU+QdTdRbu/L/1dIZY8/Wb2K9pAhtroQuxJJI= +github.com/whyrusleeping/cbor-gen v0.0.0-20230418232409-daab9ece03a0 h1:XYEgH2nJgsrcrj32p+SAbx6T3s/6QknOXezXtz7kzbg= +github.com/whyrusleeping/cbor-gen v0.0.0-20230418232409-daab9ece03a0/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= @@ -707,22 +966,57 @@ go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= 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/net/http/otelhttp v0.56.0 h1:UP6IpuHFkUgOQL9FFQFrZ+5LiwhhYRbi7VZSIx6Nj5s= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.56.0/go.mod h1:qxuZLtbq5QDtdeSHsS7bcf6EH6uO6jUAgk764zd3rhM= +go.opentelemetry.io/otel v1.31.0 h1:NsJcKPIW0D0H3NgzPDHmo0WW6SptzPdqg/L1zsIm2hY= +go.opentelemetry.io/otel v1.31.0/go.mod h1:O0C14Yl9FgkjqcCZAsE053C13OaddMYr/hz6clDkEJE= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0 h1:Mne5On7VWdx7omSrSSZvM4Kw7cS7NQkOOmLcgscI51U= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0/go.mod h1:IPtUMKL4O3tH5y+iXVyAXqpAwMuzC1IrxVS81rummfE= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.31.0 h1:lUsI2TYsQw2r1IASwoROaCnjdj2cvC2+Jbxvk6nHnWU= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.31.0/go.mod h1:2HpZxxQurfGxJlJDblybejHB6RX6pmExPNe517hREw4= +go.opentelemetry.io/otel/metric v1.31.0 h1:FSErL0ATQAmYHUIzSezZibnyVlft1ybhy4ozRPcF2fE= +go.opentelemetry.io/otel/metric v1.31.0/go.mod h1:C3dEloVbLuYoX41KpmAhOqNriGbA+qqH6PQ5E5mUfnY= +go.opentelemetry.io/otel/sdk v1.31.0 h1:xLY3abVHYZ5HSfOg3l2E5LUj2Cwva5Y7yGxnSW9H5Gk= +go.opentelemetry.io/otel/sdk v1.31.0/go.mod h1:TfRbMdhvxIIr/B2N2LQW2S5v9m3gOQ/08KsbbO5BPT0= +go.opentelemetry.io/otel/trace v1.31.0 h1:ffjsj1aRouKewfr85U2aGagJ46+MvodynlQ1HYdmJys= +go.opentelemetry.io/otel/trace v1.31.0/go.mod h1:TXZkRk7SM2ZQLtR6eoAWQFIHPvzQ06FJAsO1tJg480A= +go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= +go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I= +go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM= +go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +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/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.2.1/go.mod h1:qlT2yGI9QafXHhZZLxlSuNsMw3FFLxBr+tBRlmO1xH4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= +go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= +go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= +go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= +go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= +go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI= +go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= +go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 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-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= +golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= -golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= +golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= 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= @@ -757,8 +1051,8 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= -golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= +golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -795,16 +1089,17 @@ golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81R golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= -golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= +golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= +golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= +golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= 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= @@ -812,8 +1107,8 @@ golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4Iltr golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= -golang.org/x/oauth2 v0.7.0 h1:qe6s0zUXlPX80/dITx3440hWZ7GwMwgDDyrSGTPJG/g= -golang.org/x/oauth2 v0.7.0/go.mod h1:hPLQkd9LyjfXTiRohC/41GhcFqxisoUQ99sCUOHO9x4= +golang.org/x/oauth2 v0.20.0 h1:4mQdhULixXKP1rwYBW0vAijoXnkTG0BLCDRzfe1idMo= +golang.org/x/oauth2 v0.20.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -827,14 +1122,15 @@ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= -golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= 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= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -842,7 +1138,6 @@ golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -852,7 +1147,6 @@ golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -880,6 +1174,7 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -887,9 +1182,6 @@ golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -899,15 +1191,20 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= -golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.15.0/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-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU= +golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -917,15 +1214,16 @@ golang.org/x/text v0.3.5/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.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= -golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= -golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= +golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= 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.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= -golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= +golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181221001348-537d06c36207/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -945,6 +1243,8 @@ golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgw golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -973,9 +1273,10 @@ golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ= -golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= +golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= +golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -998,8 +1299,8 @@ google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0M google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= -google.golang.org/api v0.114.0 h1:1xQPji6cO2E2vLiI+C/XiFAnsn1WV3mjaEwGLhi3grE= -google.golang.org/api v0.114.0/go.mod h1:ifYI2ZsFK6/uGddGfAD5BMxlnkBqCmqHSDUVi45N5Yg= +google.golang.org/api v0.128.0 h1:RjPESny5CnQRn9V6siglged+DZCgfu9l6mO9dkX9VOg= +google.golang.org/api v0.128.0/go.mod h1:Y611qgqaE92On/7g65MQgxYul3c0rEB894kniWLY750= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -1032,18 +1333,19 @@ google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfG google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20230526161137-0005af68ea54 h1:9NWlQfY2ePejTmfwUH1OWwmznFa+0kKcHGPDvcPza9M= -google.golang.org/genproto v0.0.0-20230526161137-0005af68ea54/go.mod h1:zqTuNwFlFRsw5zIts5VnzLQxSRqh+CGOTVMlYbY0Eyk= -google.golang.org/genproto/googleapis/api v0.0.0-20230525234035-dd9d682886f9 h1:m8v1xLLLzMe1m5P+gCTF8nJB9epwZQUBERm20Oy1poQ= -google.golang.org/genproto/googleapis/api v0.0.0-20230525234035-dd9d682886f9/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19 h1:0nDDozoAU19Qb2HwhXadU8OcsiO/09cnTqhUtq2MEOM= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= +google.golang.org/genproto v0.0.0-20230920204549-e6e6cdab5c13 h1:vlzZttNJGVqTsRFU9AmdnrcO1Znh8Ew9kCD//yjigk0= +google.golang.org/genproto v0.0.0-20230920204549-e6e6cdab5c13/go.mod h1:CCviP9RmpZ1mxVr8MUjCnSiY09IbAXZxhLE6EhHIdPU= +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-20240528184218-531527333157 h1:Zy9XzmMEflZ/MAaA7vNcoebnRAld7FsPW1EeBB7V0m8= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157/go.mod h1:EfXuqaE1J41VCDicxHzUDm+8rk+7ZdXzHV0IhO/I6s0= google.golang.org/grpc v1.12.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= @@ -1057,9 +1359,12 @@ google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKa google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.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.57.1 h1:upNTNqv0ES+2ZOOqACwVtS3Il8M12/+Hz41RCPzAjQg= -google.golang.org/grpc v1.57.1/go.mod h1:Sd+9RMTACXwmub0zcNY2c4arhtrbBYD1AUHI/dt16Mo= +google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= +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/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= @@ -1072,11 +1377,11 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= +google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -1087,6 +1392,8 @@ gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y= +gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= +gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8= gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= @@ -1095,6 +1402,7 @@ gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWD gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0/go.mod h1:WDnlLJ4WF5VGsH/HVa3CI79GS0ol3YnhVnKP89i0kNg= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -1102,9 +1410,11 @@ gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gotest.tools/v3 v3.5.0 h1:Ljk6PdHdOhAb5aDMWXjDLMMhph+BpztA4v1QdqEW2eY= +gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU= +gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= @@ -1114,6 +1424,8 @@ honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9 honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= howett.net/plist v1.0.0 h1:7CrbWYbPPO/PyNy38b2EB/+gYbjCe2DXBxgtOOZbSQM= howett.net/plist v1.0.0/go.mod h1:lqaXoTrLY4hg8tnEzNru53gicrbv7rrk+2xJA/7hw9g= +lukechampine.com/blake3 v1.2.1 h1:YuqqRuaqsGV71BV/nm9xlI0MKUv4QC54jQnBChWbGnI= +lukechampine.com/blake3 v1.2.1/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k= pgregory.net/rapid v1.1.0 h1:CMa0sjHSru3puNx+J0MIAuiiEV4N0qj8/cMWGBBCsjw= pgregory.net/rapid v1.1.0/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= diff --git a/media/rtmp2segment.go b/media/rtmp2segment.go new file mode 100644 index 0000000000..a32b15b8a4 --- /dev/null +++ b/media/rtmp2segment.go @@ -0,0 +1,275 @@ +package media + +import ( + "bufio" + "encoding/base32" + "fmt" + "io" + "log/slog" + "math/rand" + "os" + "path/filepath" + "strings" + "sync" + "syscall" + "time" + + "github.com/livepeer/lpms/ffmpeg" + "golang.org/x/sys/unix" +) + +var waitTimeout = 20 * time.Second + +type MediaSegmenter struct { + Workdir string +} + +func (ms *MediaSegmenter) RunSegmentation(in string, segmentHandler SegmentHandler) { + + outFilePattern := filepath.Join(ms.Workdir, randomString()+"-%d.ts") + completionSignal := make(chan bool, 1) + wg := &sync.WaitGroup{} + wg.Add(1) + go func() { + defer wg.Done() + processSegments(segmentHandler, outFilePattern, completionSignal) + }() + ffmpeg.FfmpegSetLogLevel(ffmpeg.FFLogWarning) + ffmpeg.Transcode3(&ffmpeg.TranscodeOptionsIn{ + Fname: in, + }, []ffmpeg.TranscodeOptions{{ + Oname: outFilePattern, + AudioEncoder: ffmpeg.ComponentOptions{Name: "copy"}, + VideoEncoder: ffmpeg.ComponentOptions{Name: "copy"}, + Muxer: ffmpeg.ComponentOptions{Name: "segment"}, + }}) + completionSignal <- true + slog.Info("sent completion signal, now waiting") + wg.Wait() +} + +func createNamedPipe(pipeName string) { + err := syscall.Mkfifo(pipeName, 0666) + if err != nil && !os.IsExist(err) { + slog.Error("Failed to create named pipe", "pipeName", pipeName, "err", err) + } +} + +func cleanUpPipe(pipeName string) { + err := os.Remove(pipeName) + if err != nil { + slog.Error("Failed to remove pipe", "pipeName", pipeName, "err", err) + } +} + +func openNonBlockingWithRetry(name string, timeout time.Duration, completed <-chan bool) (*os.File, error) { + // Pipes block if there is no writer available + + // Attempt to open the named pipe in non-blocking mode once + fd, err := syscall.Open(name, syscall.O_RDONLY|syscall.O_NONBLOCK, 0666) + if err != nil { + return nil, fmt.Errorf("error opening file in non-blocking mode: %w", err) + } + + deadline := time.Now().Add(timeout) + + // setFd sets the given file descriptor in the fdSet + setFd := func(fd int, fdSet *syscall.FdSet) { + fdSet.Bits[fd/64] |= 1 << (uint(fd) % 64) + } + + // isFdSet checks if the given file descriptor is set in the fdSet + isFdSet := func(fd int, fdSet *syscall.FdSet) bool { + return fdSet.Bits[fd/64]&(1<<(uint(fd)%64)) != 0 + } + + for { + // Check if completed + select { + case <-completed: + syscall.Close(fd) + return nil, fmt.Errorf("Completed") + default: + // continue + } + // Calculate the remaining time until the deadline + timeLeft := time.Until(deadline) + if timeLeft <= 0 { + syscall.Close(fd) + return nil, fmt.Errorf("timeout waiting for file to be ready: %s", name) + } + + // Convert timeLeft to a syscall.Timeval for the select call + tv := syscall.NsecToTimeval((100 * time.Millisecond).Nanoseconds()) + + // Set up the read file descriptor set for select + readFds := &syscall.FdSet{} + setFd(fd, readFds) + + // Wait using select until the pipe is ready for reading + n, err := crossPlatformSelect(fd+1, readFds, nil, nil, &tv) + if err != nil { + if err == syscall.EINTR { + continue // Retry if interrupted by a signal + } + syscall.Close(fd) + return nil, fmt.Errorf("select error: %v", err) + } + + // Check if the file descriptor is ready + if n > 0 && isFdSet(fd, readFds) { + // Modify the file descriptor to blocking mode using fcntl + flags, err := unix.FcntlInt(uintptr(fd), syscall.F_GETFL, 0) + if err != nil { + syscall.Close(fd) + return nil, fmt.Errorf("error getting file flags: %w", err) + } + + // Clear the non-blocking flag + flags &^= syscall.O_NONBLOCK + if _, err := unix.FcntlInt(uintptr(fd), syscall.F_SETFL, flags); err != nil { + syscall.Close(fd) + return nil, fmt.Errorf("error setting file to blocking mode: %w", err) + } + + // Convert the file descriptor to an *os.File to return + return os.NewFile(uintptr(fd), name), nil + } + } +} + +func processSegments(segmentHandler SegmentHandler, outFilePattern string, completionSignal <-chan bool) { + + // things protected by the mutex mu + mu := &sync.Mutex{} + isComplete := false + var currentSegment *os.File = nil + pipeCompletion := make(chan bool, 1) + + // Start a goroutine to wait for the completion signal + go func() { + <-completionSignal + mu.Lock() + defer mu.Unlock() + if currentSegment != nil { + // Trigger EOF on the current segment by closing the file + slog.Info("Completion signal received. Closing current segment to trigger EOF.") + currentSegment.Close() + } + isComplete = true + pipeCompletion <- true + slog.Info("Got completion signal") + }() + + pipeNum := 0 + createNamedPipe(fmt.Sprintf(outFilePattern, pipeNum)) + + for { + pipeName := fmt.Sprintf(outFilePattern, pipeNum) + nextPipeName := fmt.Sprintf(outFilePattern, pipeNum+1) + + // Create the next pipe ahead of time + createNamedPipe(nextPipeName) + + // Open the current pipe for reading + // Blocks if no writer is available so do some tricks to it + file, err := openNonBlockingWithRetry(pipeName, waitTimeout, pipeCompletion) + if err != nil { + slog.Error("Error opening pipe", "pipeName", pipeName, "err", err) + cleanUpPipe(pipeName) + cleanUpPipe(nextPipeName) + break + } + + mu.Lock() + currentSegment = file + mu.Unlock() + + // Handle the reading process + readSegment(segmentHandler, file, pipeName) + + // Increment to the next pipe + pipeNum++ + + // Clean up the current pipe after reading + cleanUpPipe(pipeName) + + mu.Lock() + if isComplete { + cleanUpPipe(pipeName) + cleanUpPipe(nextPipeName) + mu.Unlock() + break + } + mu.Unlock() + + } +} + +func readSegment(segmentHandler SegmentHandler, file *os.File, pipeName string) { + defer file.Close() + + reader := bufio.NewReader(file) + firstByteRead := false + totalBytesRead := int64(0) + + buf := make([]byte, 32*1024) + + // TODO should be explicitly buffered for better management + interfaceReader, interfaceWriter := io.Pipe() + defer interfaceWriter.Close() + segmentHandler(interfaceReader) + + for { + n, err := reader.Read(buf) + if n > 0 { + if !firstByteRead { + slog.Debug("First byte read", "pipeName", pipeName) + firstByteRead = true + + } + totalBytesRead += int64(n) + if _, err := interfaceWriter.Write(buf[:n]); err != nil { + if err != io.EOF { + slog.Error("Error writing", "pipeName", pipeName, "err", err) + } + } + } + if n == len(buf) && n < 1024*1024 { + newLen := int(float64(len(buf)) * 1.5) + slog.Info("Max buf hit, increasing", "oldSize", humanBytes(int64(len(buf))), "newSize", humanBytes(int64(newLen))) + buf = make([]byte, newLen) + } + + if err != nil { + if err.Error() == "EOF" { + slog.Debug("Last byte read", "pipeName", pipeName, "totalRead", humanBytes(totalBytesRead)) + } else { + slog.Error("Error reading", "pipeName", pipeName, "err", err) + } + break + } + } +} + +func randomString() string { + // Create a random 4-byte string encoded as base32, trimming padding + b := make([]byte, 4) + for i := range b { + b[i] = byte(rand.Intn(256)) + } + return strings.TrimRight(base32.StdEncoding.EncodeToString(b), "=") +} + +func humanBytes(bytes int64) string { + var unit int64 = 1024 + if bytes < unit { + return fmt.Sprintf("%d B", bytes) + } + div, exp := unit, 0 + for n := bytes / unit; n >= unit; n /= unit { + div *= unit + exp++ + } + return fmt.Sprintf("%.1f %cB", float64(bytes)/float64(div), "KMGTPE"[exp]) +} diff --git a/media/segment_reader.go b/media/segment_reader.go new file mode 100644 index 0000000000..f059e7491b --- /dev/null +++ b/media/segment_reader.go @@ -0,0 +1,49 @@ +package media + +import ( + "io" + "sync" +) + +type SegmentHandler func(reader io.Reader) + +func NoopReader(reader io.Reader) { + go func() { + io.Copy(io.Discard, reader) + }() +} + +type EOSReader struct{} + +func (r EOSReader) Read(p []byte) (n int, err error) { + return 0, io.EOF +} + +type SwitchableSegmentReader struct { + mu sync.RWMutex + reader SegmentHandler +} + +func NewSwitchableSegmentReader() *SwitchableSegmentReader { + return &SwitchableSegmentReader{ + reader: NoopReader, + } +} + +func (sr *SwitchableSegmentReader) SwitchReader(newReader SegmentHandler) { + sr.mu.Lock() + defer sr.mu.Unlock() + sr.reader = newReader +} + +func (sr *SwitchableSegmentReader) Read(reader io.Reader) { + sr.mu.RLock() + defer sr.mu.RUnlock() + sr.reader(reader) +} + +func (sr *SwitchableSegmentReader) Close() { + sr.mu.RLock() + defer sr.mu.RUnlock() + sr.reader(&EOSReader{}) +} diff --git a/media/select_darwin.go b/media/select_darwin.go new file mode 100644 index 0000000000..0b06af0311 --- /dev/null +++ b/media/select_darwin.go @@ -0,0 +1,42 @@ +//go:build darwin + +package media + +import "syscall" + +func crossPlatformSelect(nfd int, r, w, e *syscall.FdSet, timeout *syscall.Timeval) (int, error) { + // On macOS, syscall.Select only returns an error + err := syscall.Select(nfd, r, w, e, timeout) + if err != nil { + return -1, err // Return -1 in case of an error + } + // We need to manually count the number of ready descriptors in FdSets + n := 0 + if r != nil { + n += countReadyDescriptors(r, nfd) + } + if w != nil { + n += countReadyDescriptors(w, nfd) + } + if e != nil { + n += countReadyDescriptors(e, nfd) + } + return n, nil + +} + +// countReadyDescriptors manually counts the number of ready file descriptors in an FdSet +func countReadyDescriptors(set *syscall.FdSet, nfd int) int { + count := 0 + for fd := 0; fd < nfd; fd++ { + if isSet(fd, set) { + count++ + } + } + return count +} + +// isSet checks if a file descriptor is set in an FdSet +func isSet(fd int, set *syscall.FdSet) bool { + return set.Bits[fd/64]&(1<<(uint(fd)%64)) != 0 +} diff --git a/media/select_linux.go b/media/select_linux.go new file mode 100644 index 0000000000..8b72ead89f --- /dev/null +++ b/media/select_linux.go @@ -0,0 +1,9 @@ +//go:build linux + +package media + +import "syscall" + +func crossPlatformSelect(nfd int, r, w, e *syscall.FdSet, timeout *syscall.Timeval) (int, error) { + return syscall.Select(nfd, r, w, e, timeout) +} diff --git a/monitor/census.go b/monitor/census.go index f9dae6babb..d4d52b317b 100644 --- a/monitor/census.go +++ b/monitor/census.go @@ -67,6 +67,7 @@ const ( Broadcaster NodeType = "bctr" Transcoder NodeType = "trcr" Redeemer NodeType = "rdmr" + AIWorker NodeType = "aiwk" segTypeRegular = "regular" segTypeRec = "recorded" // segment in the stream for which recording is enabled @@ -114,6 +115,8 @@ type ( kOrchestratorAddress tag.Key kOrchestratorVersion tag.Key kFVErrorType tag.Key + kPipeline tag.Key + kModelName tag.Key mSegmentSourceAppeared *stats.Int64Measure mSegmentEmerged *stats.Int64Measure mSegmentEmergedUnprocessed *stats.Int64Measure @@ -173,7 +176,7 @@ type ( mMinGasPrice *stats.Float64Measure mMaxGasPrice *stats.Float64Measure mTranscodingPrice *stats.Float64Measure - + mPricePerCapability *stats.Float64Measure // Metrics for calling rewards mRewardCallError *stats.Int64Measure @@ -191,6 +194,17 @@ type ( mSegmentClassProb *stats.Float64Measure mSceneClassification *stats.Int64Measure + // Metrics for AI jobs + mAIModelsRequested *stats.Int64Measure + mAIRequestLatencyScore *stats.Float64Measure + mAIRequestPrice *stats.Float64Measure + mAIRequestError *stats.Int64Measure + mAIResultDownloaded *stats.Int64Measure + mAIResultDownloadTime *stats.Float64Measure + mAIResultUploaded *stats.Int64Measure + mAIResultUploadTime *stats.Float64Measure + mAIResultSaveFailed *stats.Int64Measure + lock sync.Mutex emergeTimes map[uint64]map[uint64]time.Time // nonce:seqNo success map[uint64]*segmentsAverager @@ -218,6 +232,11 @@ type ( removedAt time.Time tries map[uint64]tryData // seqNo:try } + + AIJobInfo struct { + LatencyScore float64 + PricePerUnit float64 + } ) // Exporter Prometheus exporter that handles `/metrics` endpoint @@ -256,6 +275,8 @@ func InitCensus(nodeType NodeType, version string) { census.kOrchestratorVersion = tag.MustNewKey("orchestrator_version") census.kFVErrorType = tag.MustNewKey("fverror_type") census.kSegClassName = tag.MustNewKey("seg_class_name") + census.kModelName = tag.MustNewKey("model_name") + census.kPipeline = tag.MustNewKey("pipeline") census.ctx, err = tag.New(ctx, tag.Insert(census.kNodeType, string(nodeType)), tag.Insert(census.kNodeID, NodeID)) if err != nil { glog.Exit("Error creating context", err) @@ -322,6 +343,7 @@ func InitCensus(nodeType NodeType, version string) { census.mMinGasPrice = stats.Float64("min_gas_price", "MinGasPrice", "gwei") census.mMaxGasPrice = stats.Float64("max_gas_price", "MaxGasPrice", "gwei") census.mTranscodingPrice = stats.Float64("transcoding_price", "TranscodingPrice", "wei") + census.mPricePerCapability = stats.Float64("price_per_capability", "PricePerCapability", "wei") // Metrics for calling rewards census.mRewardCallError = stats.Int64("reward_call_errors", "RewardCallError", "tot") @@ -341,6 +363,17 @@ func InitCensus(nodeType NodeType, version string) { census.mSegmentClassProb = stats.Float64("segment_class_prob", "SegmentClassProb", "tot") census.mSceneClassification = stats.Int64("scene_classification_done", "SceneClassificationDone", "tot") + // Metrics for AI jobs + census.mAIModelsRequested = stats.Int64("ai_models_requested", "Number of AI models requested over time", "tot") + census.mAIRequestLatencyScore = stats.Float64("ai_request_latency_score", "AI request latency score, based on smallest pipeline unit", "") + census.mAIRequestPrice = stats.Float64("ai_request_price", "AI request price per unit, based on smallest pipeline unit", "") + census.mAIRequestError = stats.Int64("ai_request_errors", "Errors during AI request processing", "tot") + census.mAIResultDownloaded = stats.Int64("ai_result_downloaded_total", "AIResultDownloaded", "tot") + census.mAIResultDownloadTime = stats.Float64("ai_result_download_time_seconds", "Download (from Orchestrator) time", "sec") + census.mAIResultUploaded = stats.Int64("ai_result_uploaded_total", "AIResultUploaded", "tot") + census.mAIResultUploadTime = stats.Float64("ai_result_upload_time_seconds", "Upload (to Orchestrator) time", "sec") + census.mAIResultSaveFailed = stats.Int64("ai_result_upload_failed_total", "AIResultUploadFailed", "tot") + glog.Infof("Compiler: %s Arch %s OS %s Go version %s", runtime.Compiler, runtime.GOARCH, runtime.GOOS, runtime.Version()) glog.Infof("Livepeer version: %s", version) glog.Infof("Node type %s node ID %s", nodeType, NodeID) @@ -361,6 +394,7 @@ func InitCensus(nodeType NodeType, version string) { baseTagsWithEthAddr := baseTags baseTagsWithManifestIDAndEthAddr := baseTags baseTagsWithOrchInfo := baseTags + baseTagsWithGatewayInfo := baseTags if PerStreamMetrics { baseTagsWithManifestID = []tag.Key{census.kNodeID, census.kNodeType, census.kManifestID} baseTagsWithEthAddr = []tag.Key{census.kNodeID, census.kNodeType, census.kSender} @@ -370,9 +404,19 @@ func InitCensus(nodeType NodeType, version string) { if ExposeClientIP { baseTagsWithManifestIDAndIP = append([]tag.Key{census.kClientIP}, baseTagsWithManifestID...) } - baseTagsWithManifestIDAndOrchInfo := baseTagsWithManifestID baseTagsWithOrchInfo = append([]tag.Key{census.kOrchestratorURI, census.kOrchestratorAddress, census.kOrchestratorVersion}, baseTags...) - baseTagsWithManifestIDAndOrchInfo = append([]tag.Key{census.kOrchestratorURI, census.kOrchestratorAddress, census.kOrchestratorVersion}, baseTagsWithManifestID...) + baseTagsWithGatewayInfo = append([]tag.Key{census.kSender}, baseTags...) + baseTagsWithManifestIDAndOrchInfo := append([]tag.Key{census.kOrchestratorURI, census.kOrchestratorAddress, census.kOrchestratorVersion}, baseTagsWithManifestID...) + + // Add node type specific tags. + baseTagsWithNodeInfo := baseTags + aiRequestLatencyScoreTags := baseTags + if nodeType == Orchestrator { + baseTagsWithNodeInfo = baseTagsWithGatewayInfo + } else { + baseTagsWithNodeInfo = baseTagsWithOrchInfo + aiRequestLatencyScoreTags = baseTagsWithOrchInfo + } views := []*view.View{ { @@ -802,6 +846,13 @@ func InitCensus(nodeType NodeType, version string) { TagKeys: baseTagsWithEthAddr, Aggregation: view.LastValue(), }, + { + Name: "price_per_capability", + Measure: census.mPricePerCapability, + Description: "price per unit per capability", + TagKeys: append([]tag.Key{census.kPipeline, census.kModelName}, baseTags...), + Aggregation: view.LastValue(), + }, // Metrics for calling rewards { @@ -857,6 +908,71 @@ func InitCensus(nodeType NodeType, version string) { TagKeys: baseTags, Aggregation: view.Count(), }, + + // Metrics for AI jobs + { + Name: "ai_models_requested", + Measure: census.mAIModelsRequested, + Description: "Number of AI models requested over time", + TagKeys: append([]tag.Key{census.kPipeline, census.kModelName}, baseTags...), + Aggregation: view.Count(), + }, + { + Name: "ai_request_latency_score", + Measure: census.mAIRequestLatencyScore, + Description: "AI request latency score", + TagKeys: append([]tag.Key{census.kPipeline, census.kModelName}, aiRequestLatencyScoreTags...), + Aggregation: view.LastValue(), + }, + { + Name: "ai_request_price", + Measure: census.mAIRequestPrice, + Description: "AI request price per unit", + TagKeys: append([]tag.Key{census.kPipeline, census.kModelName}, baseTags...), + Aggregation: view.LastValue(), + }, + { + Name: "ai_result_downloaded_total", + Measure: census.mAIResultDownloaded, + Description: "AIResultDownloaded", + TagKeys: append([]tag.Key{census.kPipeline, census.kModelName}, baseTags...), + Aggregation: view.Count(), + }, + { + Name: "ai_result_download_time_seconds", + Measure: census.mAIResultDownloadTime, + Description: "AIResultDownloadtime", + TagKeys: append([]tag.Key{census.kPipeline, census.kModelName}, baseTags...), + Aggregation: view.Distribution(0, .10, .20, .50, .100, .150, .200, .500, .1000, .5000, 10.000), + }, + { + Name: "ai_request_errors", + Measure: census.mAIRequestError, + Description: "Errors when processing AI requests", + TagKeys: append([]tag.Key{census.kErrorCode, census.kPipeline, census.kModelName}, baseTagsWithNodeInfo...), + Aggregation: view.Sum(), + }, + { + Name: "ai_result_uploaded_total", + Measure: census.mAIResultUploaded, + Description: "AIResultUploaded", + TagKeys: append([]tag.Key{census.kOrchestratorURI, census.kPipeline, census.kModelName}, baseTags...), + Aggregation: view.Count(), + }, + { + Name: "ai_result_save_failed_total", + Measure: census.mAIResultSaveFailed, + Description: "AIResultSaveFailed", + TagKeys: append([]tag.Key{census.kErrorCode, census.kPipeline, census.kModelName}, baseTags...), + Aggregation: view.Count(), + }, + { + Name: "ai_result_upload_time_seconds", + Measure: census.mAIResultUploadTime, + Description: "AIResultUploadTime, seconds", + TagKeys: append([]tag.Key{census.kOrchestratorURI, census.kPipeline, census.kModelName}, baseTags...), + Aggregation: view.Distribution(0, .10, .20, .50, .100, .150, .200, .500, .1000, .5000, 10.000), + }, } // Register the views @@ -1581,6 +1697,16 @@ func MaxTranscodingPrice(maxPrice *big.Rat) { } } +func MaxPriceForCapability(pipeline string, modelName string, maxPrice *big.Rat) { + floatWei, _ := maxPrice.Float64() + if err := stats.RecordWithTags(census.ctx, + []tag.Mutator{tag.Insert(census.kPipeline, pipeline), tag.Insert(census.kModelName, modelName)}, + census.mPricePerCapability.M(floatWei)); err != nil { + + glog.Errorf("Error recording metrics err=%q", err) + } +} + // TicketValueRecv records the ticket value received from a sender for a manifestID func TicketValueRecv(ctx context.Context, sender string, value *big.Rat) { if value.Cmp(big.NewRat(0, 1)) <= 0 { @@ -1711,6 +1837,142 @@ func RewardCallError(sender string) { } } +// recordModelRequested increments request count for a specific AI model and pipeline. +func (cen *censusMetricsCounter) recordModelRequested(pipeline, modelName string) { + cen.lock.Lock() + defer cen.lock.Unlock() + + if err := stats.RecordWithTags(cen.ctx, + []tag.Mutator{tag.Insert(cen.kPipeline, pipeline), tag.Insert(cen.kModelName, modelName)}, cen.mAIModelsRequested.M(1)); err != nil { + glog.Errorf("Failed to record metrics with tags: %v", err) + } +} + +// AIRequestFinished records gateway AI job request metrics. +func AIRequestFinished(ctx context.Context, pipeline string, model string, jobInfo AIJobInfo, orchInfo *lpnet.OrchestratorInfo) { + census.recordModelRequested(pipeline, model) + census.recordAIRequestLatencyScore(pipeline, model, jobInfo.LatencyScore, orchInfo) + census.recordAIRequestPricePerUnit(pipeline, model, jobInfo.PricePerUnit) +} + +// recordAIRequestLatencyScore records the latency score for a AI job request. +func (cen *censusMetricsCounter) recordAIRequestLatencyScore(pipeline string, Model string, latencyScore float64, orchInfo *lpnet.OrchestratorInfo) { + cen.lock.Lock() + defer cen.lock.Unlock() + + tags := []tag.Mutator{tag.Insert(cen.kPipeline, pipeline), tag.Insert(cen.kModelName, Model), tag.Insert(cen.kOrchestratorURI, orchInfo.GetTranscoder()), tag.Insert(cen.kOrchestratorAddress, common.BytesToAddress(orchInfo.GetAddress()).String())} + capabilities := orchInfo.GetCapabilities() + if capabilities != nil { + tags = append(tags, tag.Insert(cen.kOrchestratorVersion, orchInfo.GetCapabilities().GetVersion())) + } + + if err := stats.RecordWithTags(cen.ctx, tags, cen.mAIRequestLatencyScore.M(latencyScore)); err != nil { + glog.Errorf("Error recording metrics err=%q", err) + } +} + +// recordAIRequestPricePerUnit records the price per unit for a AI job request. +func (cen *censusMetricsCounter) recordAIRequestPricePerUnit(pipeline string, Model string, pricePerUnit float64) { + cen.lock.Lock() + defer cen.lock.Unlock() + + if err := stats.RecordWithTags(cen.ctx, + []tag.Mutator{tag.Insert(cen.kPipeline, pipeline), tag.Insert(cen.kModelName, Model)}, + cen.mAIRequestPrice.M(pricePerUnit)); err != nil { + glog.Errorf("Error recording metrics err=%q", err) + } +} + +// AIRequestError logs an error in a gateway AI job request. +func AIRequestError(code string, pipeline string, model string, orchInfo *lpnet.OrchestratorInfo) { + orchAddr := "" + if addr := orchInfo.GetAddress(); addr != nil { + orchAddr = common.BytesToAddress(addr).String() + } + + tags := []tag.Mutator{tag.Insert(census.kErrorCode, code), tag.Insert(census.kPipeline, pipeline), tag.Insert(census.kModelName, model), tag.Insert(census.kOrchestratorURI, orchInfo.GetTranscoder()), tag.Insert(census.kOrchestratorAddress, orchAddr)} + capabilities := orchInfo.GetCapabilities() + if capabilities != nil { + tags = append(tags, tag.Insert(census.kOrchestratorVersion, orchInfo.GetCapabilities().GetVersion())) + } + + if err := stats.RecordWithTags(census.ctx, tags, census.mAIRequestError.M(1)); err != nil { + glog.Errorf("Error recording metrics err=%q", err) + } +} + +// AIJobProcessed records orchestrator AI job processing metrics. +func AIJobProcessed(ctx context.Context, pipeline string, model string, jobInfo AIJobInfo) { + census.recordModelRequested(pipeline, model) + census.recordAIJobLatencyScore(pipeline, model, jobInfo.LatencyScore) + census.recordAIJobPricePerUnit(pipeline, model, jobInfo.PricePerUnit) +} + +// recordAIJobLatencyScore records the latency score for a processed AI job. +func (cen *censusMetricsCounter) recordAIJobLatencyScore(pipeline string, Model string, latencyScore float64) { + cen.lock.Lock() + defer cen.lock.Unlock() + + if err := stats.RecordWithTags(cen.ctx, + []tag.Mutator{tag.Insert(cen.kPipeline, pipeline), tag.Insert(cen.kModelName, Model)}, + cen.mAIRequestLatencyScore.M(latencyScore)); err != nil { + glog.Errorf("Error recording metrics err=%q", err) + } +} + +// recordAIJobPricePerUnit logs the cost per unit of a processed AI job. +func (cen *censusMetricsCounter) recordAIJobPricePerUnit(pipeline string, Model string, pricePerUnit float64) { + cen.lock.Lock() + defer cen.lock.Unlock() + + if err := stats.RecordWithTags(cen.ctx, + []tag.Mutator{tag.Insert(cen.kPipeline, pipeline), tag.Insert(cen.kModelName, Model)}, + cen.mAIRequestPrice.M(pricePerUnit)); err != nil { + glog.Errorf("Error recording metrics err=%q", err) + } +} + +// AIProcessingError logs errors in orchestrator AI job processing. +func AIProcessingError(code string, pipeline string, model string, sender string) { + if err := stats.RecordWithTags(census.ctx, + []tag.Mutator{tag.Insert(census.kErrorCode, code), tag.Insert(census.kPipeline, pipeline), tag.Insert(census.kModelName, model), tag.Insert(census.kSender, sender)}, + census.mAIRequestError.M(1)); err != nil { + glog.Errorf("Error recording metrics err=%q", err) + } +} + +// AIResultUploaded logs the successful upload of an AI job result. +func AIResultUploaded(ctx context.Context, uploadDur time.Duration, pipeline, model, uri string) { + if err := stats.RecordWithTags(ctx, + []tag.Mutator{tag.Insert(census.kPipeline, pipeline), tag.Insert(census.kModelName, model)}, census.mAIResultUploaded.M(1)); err != nil { + glog.Errorf("Failed to record metrics with tags: %v", err) + } + if err := stats.RecordWithTags(census.ctx, + []tag.Mutator{tag.Insert(census.kPipeline, pipeline), tag.Insert(census.kModelName, model), tag.Insert(census.kOrchestratorURI, uri)}, + census.mAIResultUploadTime.M(uploadDur.Seconds())); err != nil { + clog.Errorf(ctx, "Error recording metrics err=%q", err) + } +} + +// AIResultSaveError logs an error in saving an AI job result to storage. +func AIResultSaveError(ctx context.Context, pipeline, model, code string) { + if err := stats.RecordWithTags(census.ctx, + []tag.Mutator{tag.Insert(census.kErrorCode, code), tag.Insert(census.kPipeline, pipeline), tag.Insert(census.kModelName, model)}, + census.mAIResultSaveFailed.M(1)); err != nil { + glog.Errorf("Error recording metrics err=%q", err) + } +} + +// AIResultDownloaded logs the successful download of an AI job result. +func AIResultDownloaded(ctx context.Context, pipeline string, model string, downloadDur time.Duration) { + if err := stats.RecordWithTags(census.ctx, + []tag.Mutator{tag.Insert(census.kPipeline, pipeline), tag.Insert(census.kModelName, model)}, + census.mAIResultDownloaded.M(1), + census.mAIResultDownloadTime.M(downloadDur.Seconds())); err != nil { + clog.Errorf(ctx, "Error recording metrics err=%q", err) + } +} + // Convert wei to gwei func wei2gwei(wei *big.Int) float64 { gwei, _ := new(big.Float).Quo(new(big.Float).SetInt(wei), big.NewFloat(float64(gweiConversionFactor))).Float64() @@ -1739,3 +2001,8 @@ func FastVerificationFailed(ctx context.Context, uri string, errtype int) { clog.Errorf(ctx, "Error recording metrics err=%q", err) } } + +// ToPipeline converts capability name into pipeline name +func ToPipeline(cap string) string { + return strings.Replace(strings.ToLower(cap), " ", "-", -1) +} diff --git a/net/lp_rpc.pb.go b/net/lp_rpc.pb.go index 5f1f72c83d..b95348261b 100644 --- a/net/lp_rpc.pb.go +++ b/net/lp_rpc.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.28.1 -// protoc v3.21.12 +// protoc-gen-go v1.33.0 +// protoc v3.21.4 // source: net/lp_rpc.proto package net @@ -418,6 +418,8 @@ type OrchestratorRequest struct { Address []byte `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` // Broadcaster's signature over its address Sig []byte `protobuf:"bytes,2,opt,name=sig,proto3" json:"sig,omitempty"` + // Features and constraints required by the broadcaster + Capabilities *Capabilities `protobuf:"bytes,3,opt,name=capabilities,proto3" json:"capabilities,omitempty"` } func (x *OrchestratorRequest) Reset() { @@ -466,6 +468,13 @@ func (x *OrchestratorRequest) GetSig() []byte { return nil } +func (x *OrchestratorRequest) GetCapabilities() *Capabilities { + if x != nil { + return x.Capabilities + } + return nil +} + // OSInfo needed to negotiate storages that will be used. // It carries info needed to write to the storage. type OSInfo struct { @@ -1547,6 +1556,55 @@ func (*TranscodeResult_Error) isTranscodeResult_Result() {} func (*TranscodeResult_Data) isTranscodeResult_Result() {} +// Response that an orchestrator sends after processing a payment. +type PaymentResult struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Used to notify a broadcaster of updated orchestrator information + Info *OrchestratorInfo `protobuf:"bytes,16,opt,name=info,proto3" json:"info,omitempty"` +} + +func (x *PaymentResult) Reset() { + *x = PaymentResult{} + if protoimpl.UnsafeEnabled { + mi := &file_net_lp_rpc_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PaymentResult) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PaymentResult) ProtoMessage() {} + +func (x *PaymentResult) ProtoReflect() protoreflect.Message { + mi := &file_net_lp_rpc_proto_msgTypes[16] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PaymentResult.ProtoReflect.Descriptor instead. +func (*PaymentResult) Descriptor() ([]byte, []int) { + return file_net_lp_rpc_proto_rawDescGZIP(), []int{16} +} + +func (x *PaymentResult) GetInfo() *OrchestratorInfo { + if x != nil { + return x.Info + } + return nil +} + // Sent by the transcoder to register itself to the orchestrator. type RegisterRequest struct { state protoimpl.MessageState @@ -1564,7 +1622,7 @@ type RegisterRequest struct { func (x *RegisterRequest) Reset() { *x = RegisterRequest{} if protoimpl.UnsafeEnabled { - mi := &file_net_lp_rpc_proto_msgTypes[16] + mi := &file_net_lp_rpc_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1577,7 +1635,7 @@ func (x *RegisterRequest) String() string { func (*RegisterRequest) ProtoMessage() {} func (x *RegisterRequest) ProtoReflect() protoreflect.Message { - mi := &file_net_lp_rpc_proto_msgTypes[16] + mi := &file_net_lp_rpc_proto_msgTypes[17] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1590,7 +1648,7 @@ func (x *RegisterRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RegisterRequest.ProtoReflect.Descriptor instead. func (*RegisterRequest) Descriptor() ([]byte, []int) { - return file_net_lp_rpc_proto_rawDescGZIP(), []int{16} + return file_net_lp_rpc_proto_rawDescGZIP(), []int{17} } func (x *RegisterRequest) GetSecret() string { @@ -1636,7 +1694,7 @@ type NotifySegment struct { func (x *NotifySegment) Reset() { *x = NotifySegment{} if protoimpl.UnsafeEnabled { - mi := &file_net_lp_rpc_proto_msgTypes[17] + mi := &file_net_lp_rpc_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1649,7 +1707,7 @@ func (x *NotifySegment) String() string { func (*NotifySegment) ProtoMessage() {} func (x *NotifySegment) ProtoReflect() protoreflect.Message { - mi := &file_net_lp_rpc_proto_msgTypes[17] + mi := &file_net_lp_rpc_proto_msgTypes[18] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1662,7 +1720,7 @@ func (x *NotifySegment) ProtoReflect() protoreflect.Message { // Deprecated: Use NotifySegment.ProtoReflect.Descriptor instead. func (*NotifySegment) Descriptor() ([]byte, []int) { - return file_net_lp_rpc_proto_rawDescGZIP(), []int{17} + return file_net_lp_rpc_proto_rawDescGZIP(), []int{18} } func (x *NotifySegment) GetUrl() string { @@ -1700,6 +1758,180 @@ func (x *NotifySegment) GetProfiles() []byte { return nil } +// Sent by the aiworker to register itself to the orchestrator. +type RegisterAIWorkerRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Shared secret for auth + Secret string `protobuf:"bytes,1,opt,name=secret,proto3" json:"secret,omitempty"` + // AIWorker capabilities + Capabilities *Capabilities `protobuf:"bytes,2,opt,name=capabilities,proto3" json:"capabilities,omitempty"` +} + +func (x *RegisterAIWorkerRequest) Reset() { + *x = RegisterAIWorkerRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_net_lp_rpc_proto_msgTypes[19] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RegisterAIWorkerRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RegisterAIWorkerRequest) ProtoMessage() {} + +func (x *RegisterAIWorkerRequest) ProtoReflect() protoreflect.Message { + mi := &file_net_lp_rpc_proto_msgTypes[19] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RegisterAIWorkerRequest.ProtoReflect.Descriptor instead. +func (*RegisterAIWorkerRequest) Descriptor() ([]byte, []int) { + return file_net_lp_rpc_proto_rawDescGZIP(), []int{19} +} + +func (x *RegisterAIWorkerRequest) GetSecret() string { + if x != nil { + return x.Secret + } + return "" +} + +func (x *RegisterAIWorkerRequest) GetCapabilities() *Capabilities { + if x != nil { + return x.Capabilities + } + return nil +} + +// Data included by the gateway when submitting a AI job. +type AIJobData struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // pipeline to use for the job + Pipeline string `protobuf:"bytes,1,opt,name=pipeline,proto3" json:"pipeline,omitempty"` + // AI job request data + RequestData []byte `protobuf:"bytes,2,opt,name=requestData,proto3" json:"requestData,omitempty"` +} + +func (x *AIJobData) Reset() { + *x = AIJobData{} + if protoimpl.UnsafeEnabled { + mi := &file_net_lp_rpc_proto_msgTypes[20] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AIJobData) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AIJobData) ProtoMessage() {} + +func (x *AIJobData) ProtoReflect() protoreflect.Message { + mi := &file_net_lp_rpc_proto_msgTypes[20] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AIJobData.ProtoReflect.Descriptor instead. +func (*AIJobData) Descriptor() ([]byte, []int) { + return file_net_lp_rpc_proto_rawDescGZIP(), []int{20} +} + +func (x *AIJobData) GetPipeline() string { + if x != nil { + return x.Pipeline + } + return "" +} + +func (x *AIJobData) GetRequestData() []byte { + if x != nil { + return x.RequestData + } + return nil +} + +// Sent by the orchestrator to the aiworker +type NotifyAIJob struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Configuration for the AI job + AIJobData *AIJobData `protobuf:"bytes,1,opt,name=AIJobData,proto3" json:"AIJobData,omitempty"` + // ID for this particular AI task. + TaskId int64 `protobuf:"varint,2,opt,name=taskId,proto3" json:"taskId,omitempty"` +} + +func (x *NotifyAIJob) Reset() { + *x = NotifyAIJob{} + if protoimpl.UnsafeEnabled { + mi := &file_net_lp_rpc_proto_msgTypes[21] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *NotifyAIJob) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*NotifyAIJob) ProtoMessage() {} + +func (x *NotifyAIJob) ProtoReflect() protoreflect.Message { + mi := &file_net_lp_rpc_proto_msgTypes[21] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use NotifyAIJob.ProtoReflect.Descriptor instead. +func (*NotifyAIJob) Descriptor() ([]byte, []int) { + return file_net_lp_rpc_proto_rawDescGZIP(), []int{21} +} + +func (x *NotifyAIJob) GetAIJobData() *AIJobData { + if x != nil { + return x.AIJobData + } + return nil +} + +func (x *NotifyAIJob) GetTaskId() int64 { + if x != nil { + return x.TaskId + } + return 0 +} + // Required parameters for probabilistic micropayment tickets type TicketParams struct { state protoimpl.MessageState @@ -1727,7 +1959,7 @@ type TicketParams struct { func (x *TicketParams) Reset() { *x = TicketParams{} if protoimpl.UnsafeEnabled { - mi := &file_net_lp_rpc_proto_msgTypes[18] + mi := &file_net_lp_rpc_proto_msgTypes[22] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1740,7 +1972,7 @@ func (x *TicketParams) String() string { func (*TicketParams) ProtoMessage() {} func (x *TicketParams) ProtoReflect() protoreflect.Message { - mi := &file_net_lp_rpc_proto_msgTypes[18] + mi := &file_net_lp_rpc_proto_msgTypes[22] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1753,7 +1985,7 @@ func (x *TicketParams) ProtoReflect() protoreflect.Message { // Deprecated: Use TicketParams.ProtoReflect.Descriptor instead. func (*TicketParams) Descriptor() ([]byte, []int) { - return file_net_lp_rpc_proto_rawDescGZIP(), []int{18} + return file_net_lp_rpc_proto_rawDescGZIP(), []int{22} } func (x *TicketParams) GetRecipient() []byte { @@ -1821,7 +2053,7 @@ type TicketSenderParams struct { func (x *TicketSenderParams) Reset() { *x = TicketSenderParams{} if protoimpl.UnsafeEnabled { - mi := &file_net_lp_rpc_proto_msgTypes[19] + mi := &file_net_lp_rpc_proto_msgTypes[23] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1834,7 +2066,7 @@ func (x *TicketSenderParams) String() string { func (*TicketSenderParams) ProtoMessage() {} func (x *TicketSenderParams) ProtoReflect() protoreflect.Message { - mi := &file_net_lp_rpc_proto_msgTypes[19] + mi := &file_net_lp_rpc_proto_msgTypes[23] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1847,7 +2079,7 @@ func (x *TicketSenderParams) ProtoReflect() protoreflect.Message { // Deprecated: Use TicketSenderParams.ProtoReflect.Descriptor instead. func (*TicketSenderParams) Descriptor() ([]byte, []int) { - return file_net_lp_rpc_proto_rawDescGZIP(), []int{19} + return file_net_lp_rpc_proto_rawDescGZIP(), []int{23} } func (x *TicketSenderParams) GetSenderNonce() uint32 { @@ -1879,7 +2111,7 @@ type TicketExpirationParams struct { func (x *TicketExpirationParams) Reset() { *x = TicketExpirationParams{} if protoimpl.UnsafeEnabled { - mi := &file_net_lp_rpc_proto_msgTypes[20] + mi := &file_net_lp_rpc_proto_msgTypes[24] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1892,7 +2124,7 @@ func (x *TicketExpirationParams) String() string { func (*TicketExpirationParams) ProtoMessage() {} func (x *TicketExpirationParams) ProtoReflect() protoreflect.Message { - mi := &file_net_lp_rpc_proto_msgTypes[20] + mi := &file_net_lp_rpc_proto_msgTypes[24] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1905,7 +2137,7 @@ func (x *TicketExpirationParams) ProtoReflect() protoreflect.Message { // Deprecated: Use TicketExpirationParams.ProtoReflect.Descriptor instead. func (*TicketExpirationParams) Descriptor() ([]byte, []int) { - return file_net_lp_rpc_proto_rawDescGZIP(), []int{20} + return file_net_lp_rpc_proto_rawDescGZIP(), []int{24} } func (x *TicketExpirationParams) GetCreationRound() int64 { @@ -1945,7 +2177,7 @@ type Payment struct { func (x *Payment) Reset() { *x = Payment{} if protoimpl.UnsafeEnabled { - mi := &file_net_lp_rpc_proto_msgTypes[21] + mi := &file_net_lp_rpc_proto_msgTypes[25] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1958,7 +2190,7 @@ func (x *Payment) String() string { func (*Payment) ProtoMessage() {} func (x *Payment) ProtoReflect() protoreflect.Message { - mi := &file_net_lp_rpc_proto_msgTypes[21] + mi := &file_net_lp_rpc_proto_msgTypes[25] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1971,7 +2203,7 @@ func (x *Payment) ProtoReflect() protoreflect.Message { // Deprecated: Use Payment.ProtoReflect.Descriptor instead. func (*Payment) Descriptor() ([]byte, []int) { - return file_net_lp_rpc_proto_rawDescGZIP(), []int{21} + return file_net_lp_rpc_proto_rawDescGZIP(), []int{25} } func (x *Payment) GetTicketParams() *TicketParams { @@ -2009,19 +2241,20 @@ func (x *Payment) GetExpectedPrice() *PriceInfo { return nil } -// Non-binary capability constraints, such as supported ranges. +// Non-binary constraints. type Capabilities_Constraints struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - MinVersion string `protobuf:"bytes,1,opt,name=minVersion,proto3" json:"minVersion,omitempty"` + MinVersion string `protobuf:"bytes,1,opt,name=minVersion,proto3" json:"minVersion,omitempty"` + PerCapability map[uint32]*Capabilities_CapabilityConstraints `protobuf:"bytes,2,rep,name=PerCapability,proto3" json:"PerCapability,omitempty" protobuf_key:"varint,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` } func (x *Capabilities_Constraints) Reset() { *x = Capabilities_Constraints{} if protoimpl.UnsafeEnabled { - mi := &file_net_lp_rpc_proto_msgTypes[23] + mi := &file_net_lp_rpc_proto_msgTypes[27] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2034,7 +2267,7 @@ func (x *Capabilities_Constraints) String() string { func (*Capabilities_Constraints) ProtoMessage() {} func (x *Capabilities_Constraints) ProtoReflect() protoreflect.Message { - mi := &file_net_lp_rpc_proto_msgTypes[23] + mi := &file_net_lp_rpc_proto_msgTypes[27] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2057,6 +2290,116 @@ func (x *Capabilities_Constraints) GetMinVersion() string { return "" } +func (x *Capabilities_Constraints) GetPerCapability() map[uint32]*Capabilities_CapabilityConstraints { + if x != nil { + return x.PerCapability + } + return nil +} + +// Non-binary capability constraints, such as supported ranges. +type Capabilities_CapabilityConstraints struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Models map[string]*Capabilities_CapabilityConstraints_ModelConstraint `protobuf:"bytes,1,rep,name=models,proto3" json:"models,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *Capabilities_CapabilityConstraints) Reset() { + *x = Capabilities_CapabilityConstraints{} + if protoimpl.UnsafeEnabled { + mi := &file_net_lp_rpc_proto_msgTypes[28] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Capabilities_CapabilityConstraints) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Capabilities_CapabilityConstraints) ProtoMessage() {} + +func (x *Capabilities_CapabilityConstraints) ProtoReflect() protoreflect.Message { + mi := &file_net_lp_rpc_proto_msgTypes[28] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Capabilities_CapabilityConstraints.ProtoReflect.Descriptor instead. +func (*Capabilities_CapabilityConstraints) Descriptor() ([]byte, []int) { + return file_net_lp_rpc_proto_rawDescGZIP(), []int{7, 2} +} + +func (x *Capabilities_CapabilityConstraints) GetModels() map[string]*Capabilities_CapabilityConstraints_ModelConstraint { + if x != nil { + return x.Models + } + return nil +} + +type Capabilities_CapabilityConstraints_ModelConstraint struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Warm bool `protobuf:"varint,1,opt,name=warm,proto3" json:"warm,omitempty"` + Capacity uint32 `protobuf:"varint,2,opt,name=capacity,proto3" json:"capacity,omitempty"` +} + +func (x *Capabilities_CapabilityConstraints_ModelConstraint) Reset() { + *x = Capabilities_CapabilityConstraints_ModelConstraint{} + if protoimpl.UnsafeEnabled { + mi := &file_net_lp_rpc_proto_msgTypes[30] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Capabilities_CapabilityConstraints_ModelConstraint) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Capabilities_CapabilityConstraints_ModelConstraint) ProtoMessage() {} + +func (x *Capabilities_CapabilityConstraints_ModelConstraint) ProtoReflect() protoreflect.Message { + mi := &file_net_lp_rpc_proto_msgTypes[30] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Capabilities_CapabilityConstraints_ModelConstraint.ProtoReflect.Descriptor instead. +func (*Capabilities_CapabilityConstraints_ModelConstraint) Descriptor() ([]byte, []int) { + return file_net_lp_rpc_proto_rawDescGZIP(), []int{7, 2, 0} +} + +func (x *Capabilities_CapabilityConstraints_ModelConstraint) GetWarm() bool { + if x != nil { + return x.Warm + } + return false +} + +func (x *Capabilities_CapabilityConstraints_ModelConstraint) GetCapacity() uint32 { + if x != nil { + return x.Capacity + } + return 0 +} + var File_net_lp_rpc_proto protoreflect.FileDescriptor var file_net_lp_rpc_proto_rawDesc = []byte{ @@ -2070,282 +2413,341 @@ var file_net_lp_rpc_proto_rawDesc = []byte{ 0x6e, 0x65, 0x74, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x09, 0x61, 0x75, 0x74, 0x68, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x1f, 0x0a, 0x1d, 0x45, 0x6e, 0x64, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, - 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x41, 0x0a, 0x13, 0x4f, 0x72, 0x63, + 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x78, 0x0a, 0x13, 0x4f, 0x72, 0x63, 0x68, 0x65, 0x73, 0x74, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x69, - 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x73, 0x69, 0x67, 0x22, 0x99, 0x01, 0x0a, - 0x06, 0x4f, 0x53, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x39, 0x0a, 0x0b, 0x73, 0x74, 0x6f, 0x72, 0x61, - 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x17, 0x2e, 0x6e, - 0x65, 0x74, 0x2e, 0x4f, 0x53, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, - 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0b, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x54, 0x79, - 0x70, 0x65, 0x12, 0x25, 0x0a, 0x06, 0x73, 0x33, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x10, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x53, 0x33, 0x4f, 0x53, 0x49, 0x6e, 0x66, - 0x6f, 0x52, 0x06, 0x73, 0x33, 0x69, 0x6e, 0x66, 0x6f, 0x22, 0x2d, 0x0a, 0x0b, 0x53, 0x74, 0x6f, - 0x72, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0a, 0x0a, 0x06, 0x44, 0x49, 0x52, 0x45, - 0x43, 0x54, 0x10, 0x00, 0x12, 0x06, 0x0a, 0x02, 0x53, 0x33, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, - 0x47, 0x4f, 0x4f, 0x47, 0x4c, 0x45, 0x10, 0x02, 0x22, 0xa2, 0x01, 0x0a, 0x08, 0x53, 0x33, 0x4f, - 0x53, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x6f, 0x73, 0x74, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, 0x6f, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x70, - 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, 0x6f, 0x6c, - 0x69, 0x63, 0x79, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, - 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x18, - 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, - 0x6c, 0x12, 0x1a, 0x0a, 0x08, 0x78, 0x41, 0x6d, 0x7a, 0x44, 0x61, 0x74, 0x65, 0x18, 0x06, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x08, 0x78, 0x41, 0x6d, 0x7a, 0x44, 0x61, 0x74, 0x65, 0x22, 0x55, 0x0a, - 0x09, 0x50, 0x72, 0x69, 0x63, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x22, 0x0a, 0x0c, 0x70, 0x72, - 0x69, 0x63, 0x65, 0x50, 0x65, 0x72, 0x55, 0x6e, 0x69, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, - 0x52, 0x0c, 0x70, 0x72, 0x69, 0x63, 0x65, 0x50, 0x65, 0x72, 0x55, 0x6e, 0x69, 0x74, 0x12, 0x24, - 0x0a, 0x0d, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x73, 0x50, 0x65, 0x72, 0x55, 0x6e, 0x69, 0x74, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x73, 0x50, 0x65, 0x72, - 0x55, 0x6e, 0x69, 0x74, 0x22, 0xda, 0x02, 0x0a, 0x0c, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, - 0x69, 0x74, 0x69, 0x65, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x62, 0x69, 0x74, 0x73, 0x74, 0x72, 0x69, - 0x6e, 0x67, 0x18, 0x01, 0x20, 0x03, 0x28, 0x04, 0x52, 0x09, 0x62, 0x69, 0x74, 0x73, 0x74, 0x72, - 0x69, 0x6e, 0x67, 0x12, 0x20, 0x0a, 0x0b, 0x6d, 0x61, 0x6e, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x69, - 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x04, 0x52, 0x0b, 0x6d, 0x61, 0x6e, 0x64, 0x61, 0x74, - 0x6f, 0x72, 0x69, 0x65, 0x73, 0x12, 0x41, 0x0a, 0x0a, 0x63, 0x61, 0x70, 0x61, 0x63, 0x69, 0x74, - 0x69, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x6e, 0x65, 0x74, 0x2e, - 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x2e, 0x43, 0x61, 0x70, - 0x61, 0x63, 0x69, 0x74, 0x69, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0a, 0x63, 0x61, - 0x70, 0x61, 0x63, 0x69, 0x74, 0x69, 0x65, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, - 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, - 0x6f, 0x6e, 0x12, 0x3f, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x74, - 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x43, 0x61, - 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x74, - 0x72, 0x61, 0x69, 0x6e, 0x74, 0x73, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x61, 0x69, - 0x6e, 0x74, 0x73, 0x1a, 0x3d, 0x0a, 0x0f, 0x43, 0x61, 0x70, 0x61, 0x63, 0x69, 0x74, 0x69, 0x65, - 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0d, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, - 0x38, 0x01, 0x1a, 0x2d, 0x0a, 0x0b, 0x43, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x74, - 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x6d, 0x69, 0x6e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6d, 0x69, 0x6e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, - 0x6e, 0x22, 0xc0, 0x02, 0x0a, 0x10, 0x4f, 0x72, 0x63, 0x68, 0x65, 0x73, 0x74, 0x72, 0x61, 0x74, - 0x6f, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1e, 0x0a, 0x0a, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x63, - 0x6f, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x74, 0x72, 0x61, 0x6e, - 0x73, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x12, 0x36, 0x0a, 0x0d, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x74, - 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, - 0x6e, 0x65, 0x74, 0x2e, 0x54, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, - 0x52, 0x0c, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x2d, - 0x0a, 0x0a, 0x70, 0x72, 0x69, 0x63, 0x65, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x50, 0x72, 0x69, 0x63, 0x65, 0x49, 0x6e, - 0x66, 0x6f, 0x52, 0x09, 0x70, 0x72, 0x69, 0x63, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x18, 0x0a, - 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, - 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x35, 0x0a, 0x0c, 0x63, 0x61, 0x70, 0x61, 0x62, - 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, - 0x6e, 0x65, 0x74, 0x2e, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, - 0x52, 0x0c, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x12, 0x2d, - 0x0a, 0x0a, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x06, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x54, 0x6f, 0x6b, - 0x65, 0x6e, 0x52, 0x09, 0x61, 0x75, 0x74, 0x68, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x25, 0x0a, - 0x07, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x18, 0x20, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0b, - 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x4f, 0x53, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x07, 0x73, 0x74, 0x6f, - 0x72, 0x61, 0x67, 0x65, 0x22, 0x60, 0x0a, 0x09, 0x41, 0x75, 0x74, 0x68, 0x54, 0x6f, 0x6b, 0x65, - 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x65, 0x73, 0x73, 0x69, - 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x65, 0x73, - 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x65, 0x78, 0x70, 0x69, 0x72, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x65, 0x78, 0x70, 0x69, - 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xf4, 0x04, 0x0a, 0x07, 0x53, 0x65, 0x67, 0x44, 0x61, - 0x74, 0x61, 0x12, 0x1e, 0x0a, 0x0a, 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x49, 0x64, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, - 0x49, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x65, 0x71, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, - 0x03, 0x73, 0x65, 0x71, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x66, - 0x69, 0x6c, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x66, - 0x69, 0x6c, 0x65, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x69, 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x03, 0x73, 0x69, 0x67, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x12, 0x35, 0x0a, 0x0c, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, - 0x65, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x43, - 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x52, 0x0c, 0x63, 0x61, 0x70, - 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x12, 0x2d, 0x0a, 0x0a, 0x61, 0x75, 0x74, - 0x68, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, - 0x6e, 0x65, 0x74, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x09, 0x61, - 0x75, 0x74, 0x68, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x30, 0x0a, 0x14, 0x63, 0x61, 0x6c, 0x63, - 0x5f, 0x70, 0x65, 0x72, 0x63, 0x65, 0x70, 0x74, 0x75, 0x61, 0x6c, 0x5f, 0x68, 0x61, 0x73, 0x68, - 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x63, 0x61, 0x6c, 0x63, 0x50, 0x65, 0x72, 0x63, - 0x65, 0x70, 0x74, 0x75, 0x61, 0x6c, 0x48, 0x61, 0x73, 0x68, 0x12, 0x25, 0x0a, 0x07, 0x73, 0x74, - 0x6f, 0x72, 0x61, 0x67, 0x65, 0x18, 0x20, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x6e, 0x65, - 0x74, 0x2e, 0x4f, 0x53, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x07, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, - 0x65, 0x12, 0x35, 0x0a, 0x0c, 0x66, 0x75, 0x6c, 0x6c, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, - 0x73, 0x18, 0x21, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x56, 0x69, - 0x64, 0x65, 0x6f, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x52, 0x0c, 0x66, 0x75, 0x6c, 0x6c, - 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x37, 0x0a, 0x0d, 0x66, 0x75, 0x6c, 0x6c, - 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x32, 0x18, 0x22, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x11, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x56, 0x69, 0x64, 0x65, 0x6f, 0x50, 0x72, 0x6f, 0x66, 0x69, - 0x6c, 0x65, 0x52, 0x0d, 0x66, 0x75, 0x6c, 0x6c, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, - 0x32, 0x12, 0x37, 0x0a, 0x0d, 0x66, 0x75, 0x6c, 0x6c, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, - 0x73, 0x33, 0x18, 0x23, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x56, + 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x73, 0x69, 0x67, 0x12, 0x35, 0x0a, 0x0c, + 0x63, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, + 0x69, 0x74, 0x69, 0x65, 0x73, 0x52, 0x0c, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, + 0x69, 0x65, 0x73, 0x22, 0x99, 0x01, 0x0a, 0x06, 0x4f, 0x53, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x39, + 0x0a, 0x0b, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0e, 0x32, 0x17, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x4f, 0x53, 0x49, 0x6e, 0x66, 0x6f, + 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0b, 0x73, 0x74, + 0x6f, 0x72, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x25, 0x0a, 0x06, 0x73, 0x33, 0x69, + 0x6e, 0x66, 0x6f, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x6e, 0x65, 0x74, 0x2e, + 0x53, 0x33, 0x4f, 0x53, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x06, 0x73, 0x33, 0x69, 0x6e, 0x66, 0x6f, + 0x22, 0x2d, 0x0a, 0x0b, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, + 0x0a, 0x0a, 0x06, 0x44, 0x49, 0x52, 0x45, 0x43, 0x54, 0x10, 0x00, 0x12, 0x06, 0x0a, 0x02, 0x53, + 0x33, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x47, 0x4f, 0x4f, 0x47, 0x4c, 0x45, 0x10, 0x02, 0x22, + 0xa2, 0x01, 0x0a, 0x08, 0x53, 0x33, 0x4f, 0x53, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x12, 0x0a, 0x04, + 0x68, 0x6f, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, 0x6f, 0x73, 0x74, + 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, + 0x65, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x06, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, + 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, + 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x64, + 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x72, + 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x12, 0x1a, 0x0a, 0x08, 0x78, 0x41, 0x6d, 0x7a, + 0x44, 0x61, 0x74, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x78, 0x41, 0x6d, 0x7a, + 0x44, 0x61, 0x74, 0x65, 0x22, 0x55, 0x0a, 0x09, 0x50, 0x72, 0x69, 0x63, 0x65, 0x49, 0x6e, 0x66, + 0x6f, 0x12, 0x22, 0x0a, 0x0c, 0x70, 0x72, 0x69, 0x63, 0x65, 0x50, 0x65, 0x72, 0x55, 0x6e, 0x69, + 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x70, 0x72, 0x69, 0x63, 0x65, 0x50, 0x65, + 0x72, 0x55, 0x6e, 0x69, 0x74, 0x12, 0x24, 0x0a, 0x0d, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x73, 0x50, + 0x65, 0x72, 0x55, 0x6e, 0x69, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x70, 0x69, + 0x78, 0x65, 0x6c, 0x73, 0x50, 0x65, 0x72, 0x55, 0x6e, 0x69, 0x74, 0x22, 0xbc, 0x06, 0x0a, 0x0c, + 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x12, 0x1c, 0x0a, 0x09, + 0x62, 0x69, 0x74, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x18, 0x01, 0x20, 0x03, 0x28, 0x04, 0x52, + 0x09, 0x62, 0x69, 0x74, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x12, 0x20, 0x0a, 0x0b, 0x6d, 0x61, + 0x6e, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x04, 0x52, + 0x0b, 0x6d, 0x61, 0x6e, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x12, 0x41, 0x0a, 0x0a, + 0x63, 0x61, 0x70, 0x61, 0x63, 0x69, 0x74, 0x69, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x21, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, + 0x69, 0x65, 0x73, 0x2e, 0x43, 0x61, 0x70, 0x61, 0x63, 0x69, 0x74, 0x69, 0x65, 0x73, 0x45, 0x6e, + 0x74, 0x72, 0x79, 0x52, 0x0a, 0x63, 0x61, 0x70, 0x61, 0x63, 0x69, 0x74, 0x69, 0x65, 0x73, 0x12, + 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x3f, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, + 0x73, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x74, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, + 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, + 0x73, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x74, 0x73, 0x52, 0x0b, 0x63, + 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x74, 0x73, 0x1a, 0x3d, 0x0a, 0x0f, 0x43, 0x61, + 0x70, 0x61, 0x63, 0x69, 0x74, 0x69, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, + 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, + 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0xf0, 0x01, 0x0a, 0x0b, 0x43, 0x6f, + 0x6e, 0x73, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x74, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x6d, 0x69, 0x6e, + 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6d, + 0x69, 0x6e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x56, 0x0a, 0x0d, 0x50, 0x65, 0x72, + 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x30, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, + 0x69, 0x65, 0x73, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x74, 0x73, 0x2e, + 0x50, 0x65, 0x72, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x52, 0x0d, 0x50, 0x65, 0x72, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, + 0x79, 0x1a, 0x69, 0x0a, 0x12, 0x50, 0x65, 0x72, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, + 0x74, 0x79, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0d, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x3d, 0x0a, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x43, + 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x2e, 0x43, 0x61, 0x70, 0x61, + 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x43, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x74, + 0x73, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x9b, 0x02, 0x0a, + 0x15, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x43, 0x6f, 0x6e, 0x73, 0x74, + 0x72, 0x61, 0x69, 0x6e, 0x74, 0x73, 0x12, 0x4b, 0x0a, 0x06, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x73, + 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x43, 0x61, 0x70, + 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x2e, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, + 0x6c, 0x69, 0x74, 0x79, 0x43, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x74, 0x73, 0x2e, + 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x6d, 0x6f, 0x64, + 0x65, 0x6c, 0x73, 0x1a, 0x41, 0x0a, 0x0f, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x43, 0x6f, 0x6e, 0x73, + 0x74, 0x72, 0x61, 0x69, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x77, 0x61, 0x72, 0x6d, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x77, 0x61, 0x72, 0x6d, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x61, + 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x63, 0x61, + 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, 0x1a, 0x72, 0x0a, 0x0b, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x73, + 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x4d, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x37, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x43, 0x61, 0x70, + 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x2e, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, + 0x6c, 0x69, 0x74, 0x79, 0x43, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x74, 0x73, 0x2e, + 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x43, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x74, 0x52, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xc0, 0x02, 0x0a, 0x10, 0x4f, + 0x72, 0x63, 0x68, 0x65, 0x73, 0x74, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x12, + 0x1e, 0x0a, 0x0a, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0a, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x12, + 0x36, 0x0a, 0x0d, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x54, 0x69, 0x63, + 0x6b, 0x65, 0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x0c, 0x74, 0x69, 0x63, 0x6b, 0x65, + 0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x2d, 0x0a, 0x0a, 0x70, 0x72, 0x69, 0x63, 0x65, + 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x6e, 0x65, + 0x74, 0x2e, 0x50, 0x72, 0x69, 0x63, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x09, 0x70, 0x72, 0x69, + 0x63, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, + 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, + 0x12, 0x35, 0x0a, 0x0c, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, + 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x43, 0x61, 0x70, + 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x52, 0x0c, 0x63, 0x61, 0x70, 0x61, 0x62, + 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x12, 0x2d, 0x0a, 0x0a, 0x61, 0x75, 0x74, 0x68, 0x5f, + 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x6e, 0x65, + 0x74, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x09, 0x61, 0x75, 0x74, + 0x68, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x25, 0x0a, 0x07, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, + 0x65, 0x18, 0x20, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x4f, 0x53, + 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x07, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x22, 0x60, 0x0a, + 0x09, 0x41, 0x75, 0x74, 0x68, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, + 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, + 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, + 0x1e, 0x0a, 0x0a, 0x65, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x03, 0x52, 0x0a, 0x65, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, + 0xf4, 0x04, 0x0a, 0x07, 0x53, 0x65, 0x67, 0x44, 0x61, 0x74, 0x61, 0x12, 0x1e, 0x0a, 0x0a, 0x6d, + 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x0a, 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x73, + 0x65, 0x71, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x03, 0x73, 0x65, 0x71, 0x12, 0x12, 0x0a, + 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x68, 0x61, 0x73, + 0x68, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x10, 0x0a, + 0x03, 0x73, 0x69, 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x73, 0x69, 0x67, 0x12, + 0x1a, 0x0a, 0x08, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, + 0x05, 0x52, 0x08, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x35, 0x0a, 0x0c, 0x63, + 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x11, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, + 0x74, 0x69, 0x65, 0x73, 0x52, 0x0c, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, + 0x65, 0x73, 0x12, 0x2d, 0x0a, 0x0a, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, + 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x41, 0x75, 0x74, + 0x68, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x09, 0x61, 0x75, 0x74, 0x68, 0x54, 0x6f, 0x6b, 0x65, + 0x6e, 0x12, 0x30, 0x0a, 0x14, 0x63, 0x61, 0x6c, 0x63, 0x5f, 0x70, 0x65, 0x72, 0x63, 0x65, 0x70, + 0x74, 0x75, 0x61, 0x6c, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x12, 0x63, 0x61, 0x6c, 0x63, 0x50, 0x65, 0x72, 0x63, 0x65, 0x70, 0x74, 0x75, 0x61, 0x6c, 0x48, + 0x61, 0x73, 0x68, 0x12, 0x25, 0x0a, 0x07, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x18, 0x20, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x4f, 0x53, 0x49, 0x6e, 0x66, + 0x6f, 0x52, 0x07, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x12, 0x35, 0x0a, 0x0c, 0x66, 0x75, + 0x6c, 0x6c, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x18, 0x21, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x11, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x56, 0x69, 0x64, 0x65, 0x6f, 0x50, 0x72, 0x6f, 0x66, + 0x69, 0x6c, 0x65, 0x52, 0x0c, 0x66, 0x75, 0x6c, 0x6c, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, + 0x73, 0x12, 0x37, 0x0a, 0x0d, 0x66, 0x75, 0x6c, 0x6c, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, + 0x73, 0x32, 0x18, 0x22, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x56, 0x69, 0x64, 0x65, 0x6f, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x52, 0x0d, 0x66, 0x75, 0x6c, - 0x6c, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x33, 0x12, 0x41, 0x0a, 0x12, 0x73, 0x65, - 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, - 0x18, 0x25, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x53, 0x65, 0x67, - 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x52, 0x11, 0x73, 0x65, 0x67, 0x6d, - 0x65, 0x6e, 0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x12, 0x2e, 0x0a, - 0x12, 0x46, 0x6f, 0x72, 0x63, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x69, - 0x6e, 0x69, 0x74, 0x18, 0x26, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x46, 0x6f, 0x72, 0x63, 0x65, - 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x69, 0x6e, 0x69, 0x74, 0x22, 0x33, 0x0a, - 0x0d, 0x53, 0x65, 0x67, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x12, 0x12, - 0x0a, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x66, 0x72, - 0x6f, 0x6d, 0x12, 0x0e, 0x0a, 0x02, 0x74, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x02, - 0x74, 0x6f, 0x22, 0xcc, 0x05, 0x0a, 0x0c, 0x56, 0x69, 0x64, 0x65, 0x6f, 0x50, 0x72, 0x6f, 0x66, - 0x69, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x10, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x77, 0x69, 0x64, 0x74, 0x68, - 0x18, 0x11, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x77, 0x69, 0x64, 0x74, 0x68, 0x12, 0x16, 0x0a, - 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x12, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x68, - 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x62, 0x69, 0x74, 0x72, 0x61, 0x74, 0x65, - 0x18, 0x13, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x62, 0x69, 0x74, 0x72, 0x61, 0x74, 0x65, 0x12, - 0x10, 0x0a, 0x03, 0x66, 0x70, 0x73, 0x18, 0x14, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x03, 0x66, 0x70, - 0x73, 0x12, 0x30, 0x0a, 0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, 0x15, 0x20, 0x01, 0x28, - 0x0e, 0x32, 0x18, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x56, 0x69, 0x64, 0x65, 0x6f, 0x50, 0x72, 0x6f, - 0x66, 0x69, 0x6c, 0x65, 0x2e, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x52, 0x06, 0x66, 0x6f, 0x72, - 0x6d, 0x61, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x70, 0x73, 0x44, 0x65, 0x6e, 0x18, 0x16, 0x20, - 0x01, 0x28, 0x0d, 0x52, 0x06, 0x66, 0x70, 0x73, 0x44, 0x65, 0x6e, 0x12, 0x33, 0x0a, 0x07, 0x70, - 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x17, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x6e, + 0x6c, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x32, 0x12, 0x37, 0x0a, 0x0d, 0x66, 0x75, + 0x6c, 0x6c, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x33, 0x18, 0x23, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x11, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x56, 0x69, 0x64, 0x65, 0x6f, 0x50, 0x72, 0x6f, + 0x66, 0x69, 0x6c, 0x65, 0x52, 0x0d, 0x66, 0x75, 0x6c, 0x6c, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, + 0x65, 0x73, 0x33, 0x12, 0x41, 0x0a, 0x12, 0x73, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x70, + 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x18, 0x25, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x12, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x53, 0x65, 0x67, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, + 0x65, 0x72, 0x73, 0x52, 0x11, 0x73, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x50, 0x61, 0x72, 0x61, + 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x12, 0x2e, 0x0a, 0x12, 0x46, 0x6f, 0x72, 0x63, 0x65, 0x53, + 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x69, 0x6e, 0x69, 0x74, 0x18, 0x26, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x12, 0x46, 0x6f, 0x72, 0x63, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, + 0x52, 0x65, 0x69, 0x6e, 0x69, 0x74, 0x22, 0x33, 0x0a, 0x0d, 0x53, 0x65, 0x67, 0x50, 0x61, 0x72, + 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x12, 0x0e, 0x0a, 0x02, 0x74, + 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x02, 0x74, 0x6f, 0x22, 0xcc, 0x05, 0x0a, 0x0c, + 0x56, 0x69, 0x64, 0x65, 0x6f, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x10, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x12, 0x14, 0x0a, 0x05, 0x77, 0x69, 0x64, 0x74, 0x68, 0x18, 0x11, 0x20, 0x01, 0x28, 0x05, 0x52, + 0x05, 0x77, 0x69, 0x64, 0x74, 0x68, 0x12, 0x16, 0x0a, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, + 0x18, 0x12, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x18, + 0x0a, 0x07, 0x62, 0x69, 0x74, 0x72, 0x61, 0x74, 0x65, 0x18, 0x13, 0x20, 0x01, 0x28, 0x05, 0x52, + 0x07, 0x62, 0x69, 0x74, 0x72, 0x61, 0x74, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x66, 0x70, 0x73, 0x18, + 0x14, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x03, 0x66, 0x70, 0x73, 0x12, 0x30, 0x0a, 0x06, 0x66, 0x6f, + 0x72, 0x6d, 0x61, 0x74, 0x18, 0x15, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x6e, 0x65, 0x74, + 0x2e, 0x56, 0x69, 0x64, 0x65, 0x6f, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x2e, 0x46, 0x6f, + 0x72, 0x6d, 0x61, 0x74, 0x52, 0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0x16, 0x0a, 0x06, + 0x66, 0x70, 0x73, 0x44, 0x65, 0x6e, 0x18, 0x16, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x66, 0x70, + 0x73, 0x44, 0x65, 0x6e, 0x12, 0x33, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x18, + 0x17, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x56, 0x69, 0x64, 0x65, + 0x6f, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x2e, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, + 0x52, 0x07, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x67, 0x6f, 0x70, + 0x18, 0x18, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x67, 0x6f, 0x70, 0x12, 0x36, 0x0a, 0x07, 0x65, + 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x18, 0x19, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x56, 0x69, 0x64, 0x65, 0x6f, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x2e, - 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, - 0x12, 0x10, 0x0a, 0x03, 0x67, 0x6f, 0x70, 0x18, 0x18, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x67, - 0x6f, 0x70, 0x12, 0x36, 0x0a, 0x07, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x18, 0x19, 0x20, - 0x01, 0x28, 0x0e, 0x32, 0x1c, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x56, 0x69, 0x64, 0x65, 0x6f, 0x50, - 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x2e, 0x56, 0x69, 0x64, 0x65, 0x6f, 0x43, 0x6f, 0x64, 0x65, - 0x63, 0x52, 0x07, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x6f, - 0x6c, 0x6f, 0x72, 0x44, 0x65, 0x70, 0x74, 0x68, 0x18, 0x1a, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, - 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x44, 0x65, 0x70, 0x74, 0x68, 0x12, 0x47, 0x0a, 0x0c, 0x63, 0x68, - 0x72, 0x6f, 0x6d, 0x61, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, 0x1b, 0x20, 0x01, 0x28, 0x0e, - 0x32, 0x23, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x56, 0x69, 0x64, 0x65, 0x6f, 0x50, 0x72, 0x6f, 0x66, - 0x69, 0x6c, 0x65, 0x2e, 0x43, 0x68, 0x72, 0x6f, 0x6d, 0x61, 0x53, 0x75, 0x62, 0x73, 0x61, 0x6d, - 0x70, 0x6c, 0x69, 0x6e, 0x67, 0x52, 0x0c, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x61, 0x46, 0x6f, 0x72, - 0x6d, 0x61, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x71, 0x75, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x18, 0x1c, - 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x71, 0x75, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x22, 0x1d, 0x0a, - 0x06, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0x0a, 0x0a, 0x06, 0x4d, 0x50, 0x45, 0x47, 0x54, - 0x53, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x4d, 0x50, 0x34, 0x10, 0x01, 0x22, 0x6a, 0x0a, 0x07, - 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x13, 0x0a, 0x0f, 0x45, 0x4e, 0x43, 0x4f, 0x44, - 0x45, 0x52, 0x5f, 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x10, 0x00, 0x12, 0x11, 0x0a, 0x0d, - 0x48, 0x32, 0x36, 0x34, 0x5f, 0x42, 0x41, 0x53, 0x45, 0x4c, 0x49, 0x4e, 0x45, 0x10, 0x01, 0x12, - 0x0d, 0x0a, 0x09, 0x48, 0x32, 0x36, 0x34, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x10, 0x02, 0x12, 0x0d, - 0x0a, 0x09, 0x48, 0x32, 0x36, 0x34, 0x5f, 0x48, 0x49, 0x47, 0x48, 0x10, 0x03, 0x12, 0x19, 0x0a, - 0x15, 0x48, 0x32, 0x36, 0x34, 0x5f, 0x43, 0x4f, 0x4e, 0x53, 0x54, 0x52, 0x41, 0x49, 0x4e, 0x45, - 0x44, 0x5f, 0x48, 0x49, 0x47, 0x48, 0x10, 0x04, 0x22, 0x32, 0x0a, 0x0a, 0x56, 0x69, 0x64, 0x65, - 0x6f, 0x43, 0x6f, 0x64, 0x65, 0x63, 0x12, 0x08, 0x0a, 0x04, 0x48, 0x32, 0x36, 0x34, 0x10, 0x00, - 0x12, 0x08, 0x0a, 0x04, 0x48, 0x32, 0x36, 0x35, 0x10, 0x01, 0x12, 0x07, 0x0a, 0x03, 0x56, 0x50, - 0x38, 0x10, 0x02, 0x12, 0x07, 0x0a, 0x03, 0x56, 0x50, 0x39, 0x10, 0x03, 0x22, 0x43, 0x0a, 0x11, - 0x43, 0x68, 0x72, 0x6f, 0x6d, 0x61, 0x53, 0x75, 0x62, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x69, 0x6e, - 0x67, 0x12, 0x0e, 0x0a, 0x0a, 0x43, 0x48, 0x52, 0x4f, 0x4d, 0x41, 0x5f, 0x34, 0x32, 0x30, 0x10, - 0x00, 0x12, 0x0e, 0x0a, 0x0a, 0x43, 0x48, 0x52, 0x4f, 0x4d, 0x41, 0x5f, 0x34, 0x32, 0x32, 0x10, - 0x01, 0x12, 0x0e, 0x0a, 0x0a, 0x43, 0x48, 0x52, 0x4f, 0x4d, 0x41, 0x5f, 0x34, 0x34, 0x34, 0x10, - 0x02, 0x22, 0x71, 0x0a, 0x15, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x63, 0x6f, 0x64, 0x65, 0x64, 0x53, - 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x44, 0x61, 0x74, 0x61, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, - 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, 0x16, 0x0a, 0x06, - 0x70, 0x69, 0x78, 0x65, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x70, 0x69, - 0x78, 0x65, 0x6c, 0x73, 0x12, 0x2e, 0x0a, 0x13, 0x70, 0x65, 0x72, 0x63, 0x65, 0x70, 0x74, 0x75, - 0x61, 0x6c, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x11, 0x70, 0x65, 0x72, 0x63, 0x65, 0x70, 0x74, 0x75, 0x61, 0x6c, 0x48, 0x61, 0x73, - 0x68, 0x55, 0x72, 0x6c, 0x22, 0x59, 0x0a, 0x0d, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x63, 0x6f, 0x64, - 0x65, 0x44, 0x61, 0x74, 0x61, 0x12, 0x36, 0x0a, 0x08, 0x73, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, - 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x54, 0x72, + 0x56, 0x69, 0x64, 0x65, 0x6f, 0x43, 0x6f, 0x64, 0x65, 0x63, 0x52, 0x07, 0x65, 0x6e, 0x63, 0x6f, + 0x64, 0x65, 0x72, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x44, 0x65, 0x70, 0x74, + 0x68, 0x18, 0x1a, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x44, 0x65, + 0x70, 0x74, 0x68, 0x12, 0x47, 0x0a, 0x0c, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x61, 0x46, 0x6f, 0x72, + 0x6d, 0x61, 0x74, 0x18, 0x1b, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x23, 0x2e, 0x6e, 0x65, 0x74, 0x2e, + 0x56, 0x69, 0x64, 0x65, 0x6f, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x2e, 0x43, 0x68, 0x72, + 0x6f, 0x6d, 0x61, 0x53, 0x75, 0x62, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x69, 0x6e, 0x67, 0x52, 0x0c, + 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x61, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0x18, 0x0a, 0x07, + 0x71, 0x75, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x18, 0x1c, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x71, + 0x75, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x22, 0x1d, 0x0a, 0x06, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, + 0x12, 0x0a, 0x0a, 0x06, 0x4d, 0x50, 0x45, 0x47, 0x54, 0x53, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, + 0x4d, 0x50, 0x34, 0x10, 0x01, 0x22, 0x6a, 0x0a, 0x07, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, + 0x12, 0x13, 0x0a, 0x0f, 0x45, 0x4e, 0x43, 0x4f, 0x44, 0x45, 0x52, 0x5f, 0x44, 0x45, 0x46, 0x41, + 0x55, 0x4c, 0x54, 0x10, 0x00, 0x12, 0x11, 0x0a, 0x0d, 0x48, 0x32, 0x36, 0x34, 0x5f, 0x42, 0x41, + 0x53, 0x45, 0x4c, 0x49, 0x4e, 0x45, 0x10, 0x01, 0x12, 0x0d, 0x0a, 0x09, 0x48, 0x32, 0x36, 0x34, + 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x10, 0x02, 0x12, 0x0d, 0x0a, 0x09, 0x48, 0x32, 0x36, 0x34, 0x5f, + 0x48, 0x49, 0x47, 0x48, 0x10, 0x03, 0x12, 0x19, 0x0a, 0x15, 0x48, 0x32, 0x36, 0x34, 0x5f, 0x43, + 0x4f, 0x4e, 0x53, 0x54, 0x52, 0x41, 0x49, 0x4e, 0x45, 0x44, 0x5f, 0x48, 0x49, 0x47, 0x48, 0x10, + 0x04, 0x22, 0x32, 0x0a, 0x0a, 0x56, 0x69, 0x64, 0x65, 0x6f, 0x43, 0x6f, 0x64, 0x65, 0x63, 0x12, + 0x08, 0x0a, 0x04, 0x48, 0x32, 0x36, 0x34, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x48, 0x32, 0x36, + 0x35, 0x10, 0x01, 0x12, 0x07, 0x0a, 0x03, 0x56, 0x50, 0x38, 0x10, 0x02, 0x12, 0x07, 0x0a, 0x03, + 0x56, 0x50, 0x39, 0x10, 0x03, 0x22, 0x43, 0x0a, 0x11, 0x43, 0x68, 0x72, 0x6f, 0x6d, 0x61, 0x53, + 0x75, 0x62, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x69, 0x6e, 0x67, 0x12, 0x0e, 0x0a, 0x0a, 0x43, 0x48, + 0x52, 0x4f, 0x4d, 0x41, 0x5f, 0x34, 0x32, 0x30, 0x10, 0x00, 0x12, 0x0e, 0x0a, 0x0a, 0x43, 0x48, + 0x52, 0x4f, 0x4d, 0x41, 0x5f, 0x34, 0x32, 0x32, 0x10, 0x01, 0x12, 0x0e, 0x0a, 0x0a, 0x43, 0x48, + 0x52, 0x4f, 0x4d, 0x41, 0x5f, 0x34, 0x34, 0x34, 0x10, 0x02, 0x22, 0x71, 0x0a, 0x15, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x63, 0x6f, 0x64, 0x65, 0x64, 0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x44, - 0x61, 0x74, 0x61, 0x52, 0x08, 0x73, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x10, 0x0a, - 0x03, 0x73, 0x69, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x73, 0x69, 0x67, 0x22, - 0x9a, 0x01, 0x0a, 0x0f, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x63, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x73, - 0x75, 0x6c, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x65, 0x71, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, - 0x52, 0x03, 0x73, 0x65, 0x71, 0x12, 0x16, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x28, 0x0a, - 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6e, 0x65, - 0x74, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x63, 0x6f, 0x64, 0x65, 0x44, 0x61, 0x74, 0x61, 0x48, - 0x00, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x29, 0x0a, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x18, - 0x10, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x4f, 0x72, 0x63, 0x68, - 0x65, 0x73, 0x74, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x04, 0x69, 0x6e, - 0x66, 0x6f, 0x42, 0x08, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x7c, 0x0a, 0x0f, - 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x16, 0x0a, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x61, 0x70, 0x61, 0x63, - 0x69, 0x74, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x63, 0x61, 0x70, 0x61, 0x63, - 0x69, 0x74, 0x79, 0x12, 0x35, 0x0a, 0x0c, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, - 0x69, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x6e, 0x65, 0x74, 0x2e, - 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x52, 0x0c, 0x63, 0x61, - 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x22, 0xa1, 0x01, 0x0a, 0x0d, 0x4e, - 0x6f, 0x74, 0x69, 0x66, 0x79, 0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x10, 0x0a, 0x03, - 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, 0x26, - 0x0a, 0x07, 0x73, 0x65, 0x67, 0x44, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x0c, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x53, 0x65, 0x67, 0x44, 0x61, 0x74, 0x61, 0x52, 0x07, 0x73, - 0x65, 0x67, 0x44, 0x61, 0x74, 0x61, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x61, 0x73, 0x6b, 0x49, 0x64, - 0x18, 0x10, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x74, 0x61, 0x73, 0x6b, 0x49, 0x64, 0x12, 0x16, - 0x0a, 0x06, 0x6f, 0x72, 0x63, 0x68, 0x49, 0x64, 0x18, 0x12, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, - 0x6f, 0x72, 0x63, 0x68, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, - 0x65, 0x73, 0x18, 0x11, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, - 0x65, 0x73, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x4a, 0x04, 0x08, 0x21, 0x10, 0x22, 0x22, 0x9f, - 0x02, 0x0a, 0x0c, 0x54, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, - 0x1c, 0x0a, 0x09, 0x72, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x12, 0x1d, 0x0a, - 0x0a, 0x66, 0x61, 0x63, 0x65, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x09, 0x66, 0x61, 0x63, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x19, 0x0a, 0x08, - 0x77, 0x69, 0x6e, 0x5f, 0x70, 0x72, 0x6f, 0x62, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, - 0x77, 0x69, 0x6e, 0x50, 0x72, 0x6f, 0x62, 0x12, 0x2e, 0x0a, 0x13, 0x72, 0x65, 0x63, 0x69, 0x70, - 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x72, 0x61, 0x6e, 0x64, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x0c, 0x52, 0x11, 0x72, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x52, - 0x61, 0x6e, 0x64, 0x48, 0x61, 0x73, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x65, 0x65, 0x64, 0x18, - 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x73, 0x65, 0x65, 0x64, 0x12, 0x29, 0x0a, 0x10, 0x65, - 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x18, - 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, 0x65, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x48, 0x0a, 0x11, 0x65, 0x78, 0x70, 0x69, 0x72, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x1b, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x54, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x45, 0x78, - 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x10, - 0x65, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, - 0x22, 0x49, 0x0a, 0x12, 0x54, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x53, 0x65, 0x6e, 0x64, 0x65, 0x72, - 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, - 0x5f, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x73, 0x65, - 0x6e, 0x64, 0x65, 0x72, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x69, 0x67, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x73, 0x69, 0x67, 0x22, 0x7a, 0x0a, 0x16, 0x54, - 0x69, 0x63, 0x6b, 0x65, 0x74, 0x45, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, - 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x5f, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x63, - 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x12, 0x39, 0x0a, 0x19, - 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x62, - 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x16, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x42, 0x6c, - 0x6f, 0x63, 0x6b, 0x48, 0x61, 0x73, 0x68, 0x22, 0xa5, 0x02, 0x0a, 0x07, 0x50, 0x61, 0x79, 0x6d, - 0x65, 0x6e, 0x74, 0x12, 0x36, 0x0a, 0x0d, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x5f, 0x70, 0x61, - 0x72, 0x61, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x6e, 0x65, 0x74, - 0x2e, 0x54, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x0c, 0x74, - 0x69, 0x63, 0x6b, 0x65, 0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x73, - 0x65, 0x6e, 0x64, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x73, 0x65, 0x6e, - 0x64, 0x65, 0x72, 0x12, 0x48, 0x0a, 0x11, 0x65, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, - 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x54, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x45, 0x78, 0x70, 0x69, 0x72, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x10, 0x65, 0x78, 0x70, - 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x49, 0x0a, - 0x14, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x5f, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x5f, 0x70, - 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x6e, 0x65, - 0x74, 0x2e, 0x54, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x53, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x50, 0x61, - 0x72, 0x61, 0x6d, 0x73, 0x52, 0x12, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x53, 0x65, 0x6e, 0x64, - 0x65, 0x72, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x35, 0x0a, 0x0e, 0x65, 0x78, 0x70, 0x65, - 0x63, 0x74, 0x65, 0x64, 0x5f, 0x70, 0x72, 0x69, 0x63, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x0e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x50, 0x72, 0x69, 0x63, 0x65, 0x49, 0x6e, 0x66, 0x6f, - 0x52, 0x0d, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x50, 0x72, 0x69, 0x63, 0x65, 0x32, - 0xd8, 0x01, 0x0a, 0x0c, 0x4f, 0x72, 0x63, 0x68, 0x65, 0x73, 0x74, 0x72, 0x61, 0x74, 0x6f, 0x72, - 0x12, 0x42, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x4f, 0x72, 0x63, 0x68, 0x65, 0x73, 0x74, 0x72, 0x61, - 0x74, 0x6f, 0x72, 0x12, 0x18, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x4f, 0x72, 0x63, 0x68, 0x65, 0x73, - 0x74, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, - 0x6e, 0x65, 0x74, 0x2e, 0x4f, 0x72, 0x63, 0x68, 0x65, 0x73, 0x74, 0x72, 0x61, 0x74, 0x6f, 0x72, - 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x5e, 0x0a, 0x15, 0x45, 0x6e, 0x64, 0x54, 0x72, 0x61, 0x6e, 0x73, - 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x21, 0x2e, - 0x6e, 0x65, 0x74, 0x2e, 0x45, 0x6e, 0x64, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x63, 0x6f, 0x64, 0x69, - 0x6e, 0x67, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x22, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x45, 0x6e, 0x64, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x63, - 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x24, 0x0a, 0x04, 0x50, 0x69, 0x6e, 0x67, 0x12, 0x0d, 0x2e, 0x6e, - 0x65, 0x74, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x6e, 0x67, 0x1a, 0x0d, 0x2e, 0x6e, 0x65, - 0x74, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x6e, 0x67, 0x32, 0x4e, 0x0a, 0x0a, 0x54, 0x72, - 0x61, 0x6e, 0x73, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x12, 0x40, 0x0a, 0x12, 0x52, 0x65, 0x67, 0x69, - 0x73, 0x74, 0x65, 0x72, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x12, 0x14, - 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x4e, 0x6f, 0x74, 0x69, 0x66, - 0x79, 0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x30, 0x01, 0x42, 0x07, 0x5a, 0x05, 0x2e, 0x2f, - 0x6e, 0x65, 0x74, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x61, 0x74, 0x61, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x73, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x73, 0x12, 0x2e, 0x0a, + 0x13, 0x70, 0x65, 0x72, 0x63, 0x65, 0x70, 0x74, 0x75, 0x61, 0x6c, 0x5f, 0x68, 0x61, 0x73, 0x68, + 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x70, 0x65, 0x72, 0x63, + 0x65, 0x70, 0x74, 0x75, 0x61, 0x6c, 0x48, 0x61, 0x73, 0x68, 0x55, 0x72, 0x6c, 0x22, 0x59, 0x0a, + 0x0d, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x63, 0x6f, 0x64, 0x65, 0x44, 0x61, 0x74, 0x61, 0x12, 0x36, + 0x0a, 0x08, 0x73, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x1a, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x63, 0x6f, 0x64, 0x65, + 0x64, 0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x44, 0x61, 0x74, 0x61, 0x52, 0x08, 0x73, 0x65, + 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x69, 0x67, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x03, 0x73, 0x69, 0x67, 0x22, 0x9a, 0x01, 0x0a, 0x0f, 0x54, 0x72, 0x61, + 0x6e, 0x73, 0x63, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x10, 0x0a, 0x03, + 0x73, 0x65, 0x71, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x03, 0x73, 0x65, 0x71, 0x12, 0x16, + 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, + 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x28, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, + 0x63, 0x6f, 0x64, 0x65, 0x44, 0x61, 0x74, 0x61, 0x48, 0x00, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, + 0x12, 0x29, 0x0a, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, + 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x4f, 0x72, 0x63, 0x68, 0x65, 0x73, 0x74, 0x72, 0x61, 0x74, 0x6f, + 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x42, 0x08, 0x0a, 0x06, 0x72, + 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x3a, 0x0a, 0x0d, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, + 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x29, 0x0a, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x10, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x4f, 0x72, 0x63, 0x68, 0x65, + 0x73, 0x74, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x04, 0x69, 0x6e, 0x66, + 0x6f, 0x22, 0x7c, 0x0a, 0x0f, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x1a, 0x0a, 0x08, + 0x63, 0x61, 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, + 0x63, 0x61, 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, 0x12, 0x35, 0x0a, 0x0c, 0x63, 0x61, 0x70, 0x61, + 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, + 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, + 0x73, 0x52, 0x0c, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x22, + 0xa1, 0x01, 0x0a, 0x0d, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e, + 0x74, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, + 0x75, 0x72, 0x6c, 0x12, 0x26, 0x0a, 0x07, 0x73, 0x65, 0x67, 0x44, 0x61, 0x74, 0x61, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x53, 0x65, 0x67, 0x44, 0x61, + 0x74, 0x61, 0x52, 0x07, 0x73, 0x65, 0x67, 0x44, 0x61, 0x74, 0x61, 0x12, 0x16, 0x0a, 0x06, 0x74, + 0x61, 0x73, 0x6b, 0x49, 0x64, 0x18, 0x10, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x74, 0x61, 0x73, + 0x6b, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x72, 0x63, 0x68, 0x49, 0x64, 0x18, 0x12, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x06, 0x6f, 0x72, 0x63, 0x68, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x70, + 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x18, 0x11, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x70, + 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x4a, 0x04, 0x08, + 0x21, 0x10, 0x22, 0x22, 0x68, 0x0a, 0x17, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x41, + 0x49, 0x57, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, + 0x0a, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, + 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x35, 0x0a, 0x0c, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69, + 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x6e, + 0x65, 0x74, 0x2e, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x52, + 0x0c, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x22, 0x49, 0x0a, + 0x09, 0x41, 0x49, 0x4a, 0x6f, 0x62, 0x44, 0x61, 0x74, 0x61, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x69, + 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x69, + 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x44, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x72, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x44, 0x61, 0x74, 0x61, 0x22, 0x53, 0x0a, 0x0b, 0x4e, 0x6f, 0x74, 0x69, + 0x66, 0x79, 0x41, 0x49, 0x4a, 0x6f, 0x62, 0x12, 0x2c, 0x0a, 0x09, 0x41, 0x49, 0x4a, 0x6f, 0x62, + 0x44, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x6e, 0x65, 0x74, + 0x2e, 0x41, 0x49, 0x4a, 0x6f, 0x62, 0x44, 0x61, 0x74, 0x61, 0x52, 0x09, 0x41, 0x49, 0x4a, 0x6f, + 0x62, 0x44, 0x61, 0x74, 0x61, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x61, 0x73, 0x6b, 0x49, 0x64, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x74, 0x61, 0x73, 0x6b, 0x49, 0x64, 0x22, 0x9f, 0x02, + 0x0a, 0x0c, 0x54, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x1c, + 0x0a, 0x09, 0x72, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x09, 0x72, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x12, 0x1d, 0x0a, 0x0a, + 0x66, 0x61, 0x63, 0x65, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x09, 0x66, 0x61, 0x63, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x77, + 0x69, 0x6e, 0x5f, 0x70, 0x72, 0x6f, 0x62, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x77, + 0x69, 0x6e, 0x50, 0x72, 0x6f, 0x62, 0x12, 0x2e, 0x0a, 0x13, 0x72, 0x65, 0x63, 0x69, 0x70, 0x69, + 0x65, 0x6e, 0x74, 0x5f, 0x72, 0x61, 0x6e, 0x64, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x11, 0x72, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x61, + 0x6e, 0x64, 0x48, 0x61, 0x73, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x65, 0x65, 0x64, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x73, 0x65, 0x65, 0x64, 0x12, 0x29, 0x0a, 0x10, 0x65, 0x78, + 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x18, 0x06, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, 0x65, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x48, 0x0a, 0x11, 0x65, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1b, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x54, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x45, 0x78, 0x70, + 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x10, 0x65, + 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x22, + 0x49, 0x0a, 0x12, 0x54, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x53, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x50, + 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x5f, + 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x73, 0x65, 0x6e, + 0x64, 0x65, 0x72, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x69, 0x67, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x73, 0x69, 0x67, 0x22, 0x7a, 0x0a, 0x16, 0x54, 0x69, + 0x63, 0x6b, 0x65, 0x74, 0x45, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x61, + 0x72, 0x61, 0x6d, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x5f, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x63, 0x72, + 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x12, 0x39, 0x0a, 0x19, 0x63, + 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x62, 0x6c, + 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x16, + 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x42, 0x6c, 0x6f, + 0x63, 0x6b, 0x48, 0x61, 0x73, 0x68, 0x22, 0xa5, 0x02, 0x0a, 0x07, 0x50, 0x61, 0x79, 0x6d, 0x65, + 0x6e, 0x74, 0x12, 0x36, 0x0a, 0x0d, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x5f, 0x70, 0x61, 0x72, + 0x61, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x6e, 0x65, 0x74, 0x2e, + 0x54, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x0c, 0x74, 0x69, + 0x63, 0x6b, 0x65, 0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x65, + 0x6e, 0x64, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x73, 0x65, 0x6e, 0x64, + 0x65, 0x72, 0x12, 0x48, 0x0a, 0x11, 0x65, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, + 0x6e, 0x65, 0x74, 0x2e, 0x54, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x45, 0x78, 0x70, 0x69, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x10, 0x65, 0x78, 0x70, 0x69, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x49, 0x0a, 0x14, + 0x74, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x5f, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x5f, 0x70, 0x61, + 0x72, 0x61, 0x6d, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x6e, 0x65, 0x74, + 0x2e, 0x54, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x53, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x50, 0x61, 0x72, + 0x61, 0x6d, 0x73, 0x52, 0x12, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x53, 0x65, 0x6e, 0x64, 0x65, + 0x72, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x35, 0x0a, 0x0e, 0x65, 0x78, 0x70, 0x65, 0x63, + 0x74, 0x65, 0x64, 0x5f, 0x70, 0x72, 0x69, 0x63, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x0e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x50, 0x72, 0x69, 0x63, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, + 0x0d, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x50, 0x72, 0x69, 0x63, 0x65, 0x32, 0xd8, + 0x01, 0x0a, 0x0c, 0x4f, 0x72, 0x63, 0x68, 0x65, 0x73, 0x74, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x12, + 0x42, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x4f, 0x72, 0x63, 0x68, 0x65, 0x73, 0x74, 0x72, 0x61, 0x74, + 0x6f, 0x72, 0x12, 0x18, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x4f, 0x72, 0x63, 0x68, 0x65, 0x73, 0x74, + 0x72, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x6e, + 0x65, 0x74, 0x2e, 0x4f, 0x72, 0x63, 0x68, 0x65, 0x73, 0x74, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x49, + 0x6e, 0x66, 0x6f, 0x12, 0x5e, 0x0a, 0x15, 0x45, 0x6e, 0x64, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x63, + 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x21, 0x2e, 0x6e, + 0x65, 0x74, 0x2e, 0x45, 0x6e, 0x64, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x63, 0x6f, 0x64, 0x69, 0x6e, + 0x67, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x22, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x45, 0x6e, 0x64, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x63, 0x6f, + 0x64, 0x69, 0x6e, 0x67, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x24, 0x0a, 0x04, 0x50, 0x69, 0x6e, 0x67, 0x12, 0x0d, 0x2e, 0x6e, 0x65, + 0x74, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x6e, 0x67, 0x1a, 0x0d, 0x2e, 0x6e, 0x65, 0x74, + 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x6e, 0x67, 0x32, 0x50, 0x0a, 0x08, 0x41, 0x49, 0x57, + 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x12, 0x44, 0x0a, 0x10, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, + 0x72, 0x41, 0x49, 0x57, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x12, 0x1c, 0x2e, 0x6e, 0x65, 0x74, 0x2e, + 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x41, 0x49, 0x57, 0x6f, 0x72, 0x6b, 0x65, 0x72, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x10, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x4e, 0x6f, + 0x74, 0x69, 0x66, 0x79, 0x41, 0x49, 0x4a, 0x6f, 0x62, 0x30, 0x01, 0x32, 0x4e, 0x0a, 0x0a, 0x54, + 0x72, 0x61, 0x6e, 0x73, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x12, 0x40, 0x0a, 0x12, 0x52, 0x65, 0x67, + 0x69, 0x73, 0x74, 0x65, 0x72, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x12, + 0x14, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x4e, 0x6f, 0x74, 0x69, + 0x66, 0x79, 0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x30, 0x01, 0x42, 0x07, 0x5a, 0x05, 0x2e, + 0x2f, 0x6e, 0x65, 0x74, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -2361,83 +2763,101 @@ func file_net_lp_rpc_proto_rawDescGZIP() []byte { } var file_net_lp_rpc_proto_enumTypes = make([]protoimpl.EnumInfo, 5) -var file_net_lp_rpc_proto_msgTypes = make([]protoimpl.MessageInfo, 24) +var file_net_lp_rpc_proto_msgTypes = make([]protoimpl.MessageInfo, 32) var file_net_lp_rpc_proto_goTypes = []interface{}{ - (OSInfo_StorageType)(0), // 0: net.OSInfo.StorageType - (VideoProfile_Format)(0), // 1: net.VideoProfile.Format - (VideoProfile_Profile)(0), // 2: net.VideoProfile.Profile - (VideoProfile_VideoCodec)(0), // 3: net.VideoProfile.VideoCodec - (VideoProfile_ChromaSubsampling)(0), // 4: net.VideoProfile.ChromaSubsampling - (*PingPong)(nil), // 5: net.PingPong - (*EndTranscodingSessionRequest)(nil), // 6: net.EndTranscodingSessionRequest - (*EndTranscodingSessionResponse)(nil), // 7: net.EndTranscodingSessionResponse - (*OrchestratorRequest)(nil), // 8: net.OrchestratorRequest - (*OSInfo)(nil), // 9: net.OSInfo - (*S3OSInfo)(nil), // 10: net.S3OSInfo - (*PriceInfo)(nil), // 11: net.PriceInfo - (*Capabilities)(nil), // 12: net.Capabilities - (*OrchestratorInfo)(nil), // 13: net.OrchestratorInfo - (*AuthToken)(nil), // 14: net.AuthToken - (*SegData)(nil), // 15: net.SegData - (*SegParameters)(nil), // 16: net.SegParameters - (*VideoProfile)(nil), // 17: net.VideoProfile - (*TranscodedSegmentData)(nil), // 18: net.TranscodedSegmentData - (*TranscodeData)(nil), // 19: net.TranscodeData - (*TranscodeResult)(nil), // 20: net.TranscodeResult - (*RegisterRequest)(nil), // 21: net.RegisterRequest - (*NotifySegment)(nil), // 22: net.NotifySegment - (*TicketParams)(nil), // 23: net.TicketParams - (*TicketSenderParams)(nil), // 24: net.TicketSenderParams - (*TicketExpirationParams)(nil), // 25: net.TicketExpirationParams - (*Payment)(nil), // 26: net.Payment - nil, // 27: net.Capabilities.CapacitiesEntry - (*Capabilities_Constraints)(nil), // 28: net.Capabilities.Constraints + (OSInfo_StorageType)(0), // 0: net.OSInfo.StorageType + (VideoProfile_Format)(0), // 1: net.VideoProfile.Format + (VideoProfile_Profile)(0), // 2: net.VideoProfile.Profile + (VideoProfile_VideoCodec)(0), // 3: net.VideoProfile.VideoCodec + (VideoProfile_ChromaSubsampling)(0), // 4: net.VideoProfile.ChromaSubsampling + (*PingPong)(nil), // 5: net.PingPong + (*EndTranscodingSessionRequest)(nil), // 6: net.EndTranscodingSessionRequest + (*EndTranscodingSessionResponse)(nil), // 7: net.EndTranscodingSessionResponse + (*OrchestratorRequest)(nil), // 8: net.OrchestratorRequest + (*OSInfo)(nil), // 9: net.OSInfo + (*S3OSInfo)(nil), // 10: net.S3OSInfo + (*PriceInfo)(nil), // 11: net.PriceInfo + (*Capabilities)(nil), // 12: net.Capabilities + (*OrchestratorInfo)(nil), // 13: net.OrchestratorInfo + (*AuthToken)(nil), // 14: net.AuthToken + (*SegData)(nil), // 15: net.SegData + (*SegParameters)(nil), // 16: net.SegParameters + (*VideoProfile)(nil), // 17: net.VideoProfile + (*TranscodedSegmentData)(nil), // 18: net.TranscodedSegmentData + (*TranscodeData)(nil), // 19: net.TranscodeData + (*TranscodeResult)(nil), // 20: net.TranscodeResult + (*PaymentResult)(nil), // 21: net.PaymentResult + (*RegisterRequest)(nil), // 22: net.RegisterRequest + (*NotifySegment)(nil), // 23: net.NotifySegment + (*RegisterAIWorkerRequest)(nil), // 24: net.RegisterAIWorkerRequest + (*AIJobData)(nil), // 25: net.AIJobData + (*NotifyAIJob)(nil), // 26: net.NotifyAIJob + (*TicketParams)(nil), // 27: net.TicketParams + (*TicketSenderParams)(nil), // 28: net.TicketSenderParams + (*TicketExpirationParams)(nil), // 29: net.TicketExpirationParams + (*Payment)(nil), // 30: net.Payment + nil, // 31: net.Capabilities.CapacitiesEntry + (*Capabilities_Constraints)(nil), // 32: net.Capabilities.Constraints + (*Capabilities_CapabilityConstraints)(nil), // 33: net.Capabilities.CapabilityConstraints + nil, // 34: net.Capabilities.Constraints.PerCapabilityEntry + (*Capabilities_CapabilityConstraints_ModelConstraint)(nil), // 35: net.Capabilities.CapabilityConstraints.ModelConstraint + nil, // 36: net.Capabilities.CapabilityConstraints.ModelsEntry } var file_net_lp_rpc_proto_depIdxs = []int32{ 14, // 0: net.EndTranscodingSessionRequest.auth_token:type_name -> net.AuthToken - 0, // 1: net.OSInfo.storageType:type_name -> net.OSInfo.StorageType - 10, // 2: net.OSInfo.s3info:type_name -> net.S3OSInfo - 27, // 3: net.Capabilities.capacities:type_name -> net.Capabilities.CapacitiesEntry - 28, // 4: net.Capabilities.constraints:type_name -> net.Capabilities.Constraints - 23, // 5: net.OrchestratorInfo.ticket_params:type_name -> net.TicketParams - 11, // 6: net.OrchestratorInfo.price_info:type_name -> net.PriceInfo - 12, // 7: net.OrchestratorInfo.capabilities:type_name -> net.Capabilities - 14, // 8: net.OrchestratorInfo.auth_token:type_name -> net.AuthToken - 9, // 9: net.OrchestratorInfo.storage:type_name -> net.OSInfo - 12, // 10: net.SegData.capabilities:type_name -> net.Capabilities - 14, // 11: net.SegData.auth_token:type_name -> net.AuthToken - 9, // 12: net.SegData.storage:type_name -> net.OSInfo - 17, // 13: net.SegData.fullProfiles:type_name -> net.VideoProfile - 17, // 14: net.SegData.fullProfiles2:type_name -> net.VideoProfile - 17, // 15: net.SegData.fullProfiles3:type_name -> net.VideoProfile - 16, // 16: net.SegData.segment_parameters:type_name -> net.SegParameters - 1, // 17: net.VideoProfile.format:type_name -> net.VideoProfile.Format - 2, // 18: net.VideoProfile.profile:type_name -> net.VideoProfile.Profile - 3, // 19: net.VideoProfile.encoder:type_name -> net.VideoProfile.VideoCodec - 4, // 20: net.VideoProfile.chromaFormat:type_name -> net.VideoProfile.ChromaSubsampling - 18, // 21: net.TranscodeData.segments:type_name -> net.TranscodedSegmentData - 19, // 22: net.TranscodeResult.data:type_name -> net.TranscodeData - 13, // 23: net.TranscodeResult.info:type_name -> net.OrchestratorInfo - 12, // 24: net.RegisterRequest.capabilities:type_name -> net.Capabilities - 15, // 25: net.NotifySegment.segData:type_name -> net.SegData - 25, // 26: net.TicketParams.expiration_params:type_name -> net.TicketExpirationParams - 23, // 27: net.Payment.ticket_params:type_name -> net.TicketParams - 25, // 28: net.Payment.expiration_params:type_name -> net.TicketExpirationParams - 24, // 29: net.Payment.ticket_sender_params:type_name -> net.TicketSenderParams - 11, // 30: net.Payment.expected_price:type_name -> net.PriceInfo - 8, // 31: net.Orchestrator.GetOrchestrator:input_type -> net.OrchestratorRequest - 6, // 32: net.Orchestrator.EndTranscodingSession:input_type -> net.EndTranscodingSessionRequest - 5, // 33: net.Orchestrator.Ping:input_type -> net.PingPong - 21, // 34: net.Transcoder.RegisterTranscoder:input_type -> net.RegisterRequest - 13, // 35: net.Orchestrator.GetOrchestrator:output_type -> net.OrchestratorInfo - 7, // 36: net.Orchestrator.EndTranscodingSession:output_type -> net.EndTranscodingSessionResponse - 5, // 37: net.Orchestrator.Ping:output_type -> net.PingPong - 22, // 38: net.Transcoder.RegisterTranscoder:output_type -> net.NotifySegment - 35, // [35:39] is the sub-list for method output_type - 31, // [31:35] is the sub-list for method input_type - 31, // [31:31] is the sub-list for extension type_name - 31, // [31:31] is the sub-list for extension extendee - 0, // [0:31] is the sub-list for field type_name + 12, // 1: net.OrchestratorRequest.capabilities:type_name -> net.Capabilities + 0, // 2: net.OSInfo.storageType:type_name -> net.OSInfo.StorageType + 10, // 3: net.OSInfo.s3info:type_name -> net.S3OSInfo + 31, // 4: net.Capabilities.capacities:type_name -> net.Capabilities.CapacitiesEntry + 32, // 5: net.Capabilities.constraints:type_name -> net.Capabilities.Constraints + 27, // 6: net.OrchestratorInfo.ticket_params:type_name -> net.TicketParams + 11, // 7: net.OrchestratorInfo.price_info:type_name -> net.PriceInfo + 12, // 8: net.OrchestratorInfo.capabilities:type_name -> net.Capabilities + 14, // 9: net.OrchestratorInfo.auth_token:type_name -> net.AuthToken + 9, // 10: net.OrchestratorInfo.storage:type_name -> net.OSInfo + 12, // 11: net.SegData.capabilities:type_name -> net.Capabilities + 14, // 12: net.SegData.auth_token:type_name -> net.AuthToken + 9, // 13: net.SegData.storage:type_name -> net.OSInfo + 17, // 14: net.SegData.fullProfiles:type_name -> net.VideoProfile + 17, // 15: net.SegData.fullProfiles2:type_name -> net.VideoProfile + 17, // 16: net.SegData.fullProfiles3:type_name -> net.VideoProfile + 16, // 17: net.SegData.segment_parameters:type_name -> net.SegParameters + 1, // 18: net.VideoProfile.format:type_name -> net.VideoProfile.Format + 2, // 19: net.VideoProfile.profile:type_name -> net.VideoProfile.Profile + 3, // 20: net.VideoProfile.encoder:type_name -> net.VideoProfile.VideoCodec + 4, // 21: net.VideoProfile.chromaFormat:type_name -> net.VideoProfile.ChromaSubsampling + 18, // 22: net.TranscodeData.segments:type_name -> net.TranscodedSegmentData + 19, // 23: net.TranscodeResult.data:type_name -> net.TranscodeData + 13, // 24: net.TranscodeResult.info:type_name -> net.OrchestratorInfo + 13, // 25: net.PaymentResult.info:type_name -> net.OrchestratorInfo + 12, // 26: net.RegisterRequest.capabilities:type_name -> net.Capabilities + 15, // 27: net.NotifySegment.segData:type_name -> net.SegData + 12, // 28: net.RegisterAIWorkerRequest.capabilities:type_name -> net.Capabilities + 25, // 29: net.NotifyAIJob.AIJobData:type_name -> net.AIJobData + 29, // 30: net.TicketParams.expiration_params:type_name -> net.TicketExpirationParams + 27, // 31: net.Payment.ticket_params:type_name -> net.TicketParams + 29, // 32: net.Payment.expiration_params:type_name -> net.TicketExpirationParams + 28, // 33: net.Payment.ticket_sender_params:type_name -> net.TicketSenderParams + 11, // 34: net.Payment.expected_price:type_name -> net.PriceInfo + 34, // 35: net.Capabilities.Constraints.PerCapability:type_name -> net.Capabilities.Constraints.PerCapabilityEntry + 36, // 36: net.Capabilities.CapabilityConstraints.models:type_name -> net.Capabilities.CapabilityConstraints.ModelsEntry + 33, // 37: net.Capabilities.Constraints.PerCapabilityEntry.value:type_name -> net.Capabilities.CapabilityConstraints + 35, // 38: net.Capabilities.CapabilityConstraints.ModelsEntry.value:type_name -> net.Capabilities.CapabilityConstraints.ModelConstraint + 8, // 39: net.Orchestrator.GetOrchestrator:input_type -> net.OrchestratorRequest + 6, // 40: net.Orchestrator.EndTranscodingSession:input_type -> net.EndTranscodingSessionRequest + 5, // 41: net.Orchestrator.Ping:input_type -> net.PingPong + 24, // 42: net.AIWorker.RegisterAIWorker:input_type -> net.RegisterAIWorkerRequest + 22, // 43: net.Transcoder.RegisterTranscoder:input_type -> net.RegisterRequest + 13, // 44: net.Orchestrator.GetOrchestrator:output_type -> net.OrchestratorInfo + 7, // 45: net.Orchestrator.EndTranscodingSession:output_type -> net.EndTranscodingSessionResponse + 5, // 46: net.Orchestrator.Ping:output_type -> net.PingPong + 26, // 47: net.AIWorker.RegisterAIWorker:output_type -> net.NotifyAIJob + 23, // 48: net.Transcoder.RegisterTranscoder:output_type -> net.NotifySegment + 44, // [44:49] is the sub-list for method output_type + 39, // [39:44] is the sub-list for method input_type + 39, // [39:39] is the sub-list for extension type_name + 39, // [39:39] is the sub-list for extension extendee + 0, // [0:39] is the sub-list for field type_name } func init() { file_net_lp_rpc_proto_init() } @@ -2639,7 +3059,7 @@ func file_net_lp_rpc_proto_init() { } } file_net_lp_rpc_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RegisterRequest); i { + switch v := v.(*PaymentResult); i { case 0: return &v.state case 1: @@ -2651,7 +3071,7 @@ func file_net_lp_rpc_proto_init() { } } file_net_lp_rpc_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*NotifySegment); i { + switch v := v.(*RegisterRequest); i { case 0: return &v.state case 1: @@ -2663,7 +3083,7 @@ func file_net_lp_rpc_proto_init() { } } file_net_lp_rpc_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*TicketParams); i { + switch v := v.(*NotifySegment); i { case 0: return &v.state case 1: @@ -2675,7 +3095,7 @@ func file_net_lp_rpc_proto_init() { } } file_net_lp_rpc_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*TicketSenderParams); i { + switch v := v.(*RegisterAIWorkerRequest); i { case 0: return &v.state case 1: @@ -2687,7 +3107,7 @@ func file_net_lp_rpc_proto_init() { } } file_net_lp_rpc_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*TicketExpirationParams); i { + switch v := v.(*AIJobData); i { case 0: return &v.state case 1: @@ -2699,7 +3119,19 @@ func file_net_lp_rpc_proto_init() { } } file_net_lp_rpc_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Payment); i { + switch v := v.(*NotifyAIJob); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_net_lp_rpc_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*TicketParams); i { case 0: return &v.state case 1: @@ -2711,6 +3143,42 @@ func file_net_lp_rpc_proto_init() { } } file_net_lp_rpc_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*TicketSenderParams); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_net_lp_rpc_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*TicketExpirationParams); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_net_lp_rpc_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Payment); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_net_lp_rpc_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Capabilities_Constraints); i { case 0: return &v.state @@ -2722,6 +3190,30 @@ func file_net_lp_rpc_proto_init() { return nil } } + file_net_lp_rpc_proto_msgTypes[28].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Capabilities_CapabilityConstraints); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_net_lp_rpc_proto_msgTypes[30].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Capabilities_CapabilityConstraints_ModelConstraint); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } file_net_lp_rpc_proto_msgTypes[15].OneofWrappers = []interface{}{ (*TranscodeResult_Error)(nil), @@ -2733,9 +3225,9 @@ func file_net_lp_rpc_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_net_lp_rpc_proto_rawDesc, NumEnums: 5, - NumMessages: 24, + NumMessages: 32, NumExtensions: 0, - NumServices: 2, + NumServices: 3, }, GoTypes: file_net_lp_rpc_proto_goTypes, DependencyIndexes: file_net_lp_rpc_proto_depIdxs, diff --git a/net/lp_rpc.proto b/net/lp_rpc.proto index b14f45db5e..c5504416f2 100644 --- a/net/lp_rpc.proto +++ b/net/lp_rpc.proto @@ -12,6 +12,13 @@ service Orchestrator { rpc Ping(PingPong) returns (PingPong); } +service AIWorker { + + // Called by the aiworker to register to an orchestrator. The orchestrator + // notifies registered aiworkers of jobs as they come in. + rpc RegisterAIWorker(RegisterAIWorkerRequest) returns (stream NotifyAIJob); +} + service Transcoder { // Called by the transcoder to register to an orchestrator. The orchestrator @@ -43,6 +50,9 @@ message OrchestratorRequest { // Broadcaster's signature over its address bytes sig = 2; + + // Features and constraints required by the broadcaster + Capabilities capabilities = 3; } /* @@ -109,10 +119,23 @@ message Capabilities { Constraints constraints = 5; - // Non-binary capability constraints, such as supported ranges. + // Non-binary constraints. message Constraints { - string minVersion = 1; + string minVersion = 1; + map PerCapability = 2; + } + + // Non-binary capability constraints, such as supported ranges. + message CapabilityConstraints { + message ModelConstraint { + bool warm = 1; + uint32 capacity = 2; + } + + map models = 1; } + + } // The orchestrator sends this in response to `GetOrchestrator`, containing @@ -315,6 +338,12 @@ message TranscodeResult { OrchestratorInfo info = 16; } +// Response that an orchestrator sends after processing a payment. +message PaymentResult { + // Used to notify a broadcaster of updated orchestrator information + OrchestratorInfo info = 16; +} + // Sent by the transcoder to register itself to the orchestrator. message RegisterRequest { @@ -356,6 +385,34 @@ message NotifySegment { reserved 33; // Formerly "repeated VideoProfile fullProfiles" } +// Sent by the aiworker to register itself to the orchestrator. +message RegisterAIWorkerRequest { + + // Shared secret for auth + string secret = 1; + + // AIWorker capabilities + Capabilities capabilities = 2; +} + +// Data included by the gateway when submitting a AI job. +message AIJobData { + // pipeline to use for the job + string pipeline = 1; + + // AI job request data + bytes requestData = 2; +} + +// Sent by the orchestrator to the aiworker +message NotifyAIJob { + // Configuration for the AI job + AIJobData AIJobData = 1; + + // ID for this particular AI task. + int64 taskId = 2; +} + // Required parameters for probabilistic micropayment tickets message TicketParams { // ETH address of the recipient diff --git a/net/lp_rpc_grpc.pb.go b/net/lp_rpc_grpc.pb.go index d998fd9a94..c563f9a5a9 100644 --- a/net/lp_rpc_grpc.pb.go +++ b/net/lp_rpc_grpc.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. // versions: -// - protoc-gen-go-grpc v1.2.0 -// - protoc v3.21.12 +// - protoc-gen-go-grpc v1.5.1 +// - protoc v3.21.4 // source: net/lp_rpc.proto package net @@ -15,12 +15,20 @@ import ( // This is a compile-time assertion to ensure that this generated file // is compatible with the grpc package it is being compiled against. -// Requires gRPC-Go v1.32.0 or later. -const _ = grpc.SupportPackageIsVersion7 +// Requires gRPC-Go v1.64.0 or later. +const _ = grpc.SupportPackageIsVersion9 + +const ( + Orchestrator_GetOrchestrator_FullMethodName = "/net.Orchestrator/GetOrchestrator" + Orchestrator_EndTranscodingSession_FullMethodName = "/net.Orchestrator/EndTranscodingSession" + Orchestrator_Ping_FullMethodName = "/net.Orchestrator/Ping" +) // OrchestratorClient is the client API for Orchestrator service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +// +// RPC calls implemented by the orchestrator type OrchestratorClient interface { // Called by the broadcaster to request transcoder info from an orchestrator. GetOrchestrator(ctx context.Context, in *OrchestratorRequest, opts ...grpc.CallOption) (*OrchestratorInfo, error) @@ -37,8 +45,9 @@ func NewOrchestratorClient(cc grpc.ClientConnInterface) OrchestratorClient { } func (c *orchestratorClient) GetOrchestrator(ctx context.Context, in *OrchestratorRequest, opts ...grpc.CallOption) (*OrchestratorInfo, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(OrchestratorInfo) - err := c.cc.Invoke(ctx, "/net.Orchestrator/GetOrchestrator", in, out, opts...) + err := c.cc.Invoke(ctx, Orchestrator_GetOrchestrator_FullMethodName, in, out, cOpts...) if err != nil { return nil, err } @@ -46,8 +55,9 @@ func (c *orchestratorClient) GetOrchestrator(ctx context.Context, in *Orchestrat } func (c *orchestratorClient) EndTranscodingSession(ctx context.Context, in *EndTranscodingSessionRequest, opts ...grpc.CallOption) (*EndTranscodingSessionResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(EndTranscodingSessionResponse) - err := c.cc.Invoke(ctx, "/net.Orchestrator/EndTranscodingSession", in, out, opts...) + err := c.cc.Invoke(ctx, Orchestrator_EndTranscodingSession_FullMethodName, in, out, cOpts...) if err != nil { return nil, err } @@ -55,8 +65,9 @@ func (c *orchestratorClient) EndTranscodingSession(ctx context.Context, in *EndT } func (c *orchestratorClient) Ping(ctx context.Context, in *PingPong, opts ...grpc.CallOption) (*PingPong, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(PingPong) - err := c.cc.Invoke(ctx, "/net.Orchestrator/Ping", in, out, opts...) + err := c.cc.Invoke(ctx, Orchestrator_Ping_FullMethodName, in, out, cOpts...) if err != nil { return nil, err } @@ -65,7 +76,9 @@ func (c *orchestratorClient) Ping(ctx context.Context, in *PingPong, opts ...grp // OrchestratorServer is the server API for Orchestrator service. // All implementations must embed UnimplementedOrchestratorServer -// for forward compatibility +// for forward compatibility. +// +// RPC calls implemented by the orchestrator type OrchestratorServer interface { // Called by the broadcaster to request transcoder info from an orchestrator. GetOrchestrator(context.Context, *OrchestratorRequest) (*OrchestratorInfo, error) @@ -74,9 +87,12 @@ type OrchestratorServer interface { mustEmbedUnimplementedOrchestratorServer() } -// UnimplementedOrchestratorServer must be embedded to have forward compatible implementations. -type UnimplementedOrchestratorServer struct { -} +// UnimplementedOrchestratorServer must be embedded to have +// forward compatible implementations. +// +// NOTE: this should be embedded by value instead of pointer to avoid a nil +// pointer dereference when methods are called. +type UnimplementedOrchestratorServer struct{} func (UnimplementedOrchestratorServer) GetOrchestrator(context.Context, *OrchestratorRequest) (*OrchestratorInfo, error) { return nil, status.Errorf(codes.Unimplemented, "method GetOrchestrator not implemented") @@ -88,6 +104,7 @@ func (UnimplementedOrchestratorServer) Ping(context.Context, *PingPong) (*PingPo return nil, status.Errorf(codes.Unimplemented, "method Ping not implemented") } func (UnimplementedOrchestratorServer) mustEmbedUnimplementedOrchestratorServer() {} +func (UnimplementedOrchestratorServer) testEmbeddedByValue() {} // UnsafeOrchestratorServer may be embedded to opt out of forward compatibility for this service. // Use of this interface is not recommended, as added methods to OrchestratorServer will @@ -97,6 +114,13 @@ type UnsafeOrchestratorServer interface { } func RegisterOrchestratorServer(s grpc.ServiceRegistrar, srv OrchestratorServer) { + // If the following call pancis, it indicates UnimplementedOrchestratorServer was + // embedded by pointer and is nil. This will cause panics if an + // unimplemented method is ever invoked, so we test this at initialization + // time to prevent it from happening at runtime later due to I/O. + if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { + t.testEmbeddedByValue() + } s.RegisterService(&Orchestrator_ServiceDesc, srv) } @@ -110,7 +134,7 @@ func _Orchestrator_GetOrchestrator_Handler(srv interface{}, ctx context.Context, } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/net.Orchestrator/GetOrchestrator", + FullMethod: Orchestrator_GetOrchestrator_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(OrchestratorServer).GetOrchestrator(ctx, req.(*OrchestratorRequest)) @@ -128,7 +152,7 @@ func _Orchestrator_EndTranscodingSession_Handler(srv interface{}, ctx context.Co } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/net.Orchestrator/EndTranscodingSession", + FullMethod: Orchestrator_EndTranscodingSession_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(OrchestratorServer).EndTranscodingSession(ctx, req.(*EndTranscodingSessionRequest)) @@ -146,7 +170,7 @@ func _Orchestrator_Ping_Handler(srv interface{}, ctx context.Context, dec func(i } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/net.Orchestrator/Ping", + FullMethod: Orchestrator_Ping_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(OrchestratorServer).Ping(ctx, req.(*PingPong)) @@ -178,29 +202,34 @@ var Orchestrator_ServiceDesc = grpc.ServiceDesc{ Metadata: "net/lp_rpc.proto", } -// TranscoderClient is the client API for Transcoder service. +const ( + AIWorker_RegisterAIWorker_FullMethodName = "/net.AIWorker/RegisterAIWorker" +) + +// AIWorkerClient is the client API for AIWorker service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. -type TranscoderClient interface { - // Called by the transcoder to register to an orchestrator. The orchestrator - // notifies registered transcoders of segments as they come in. - RegisterTranscoder(ctx context.Context, in *RegisterRequest, opts ...grpc.CallOption) (Transcoder_RegisterTranscoderClient, error) +type AIWorkerClient interface { + // Called by the aiworker to register to an orchestrator. The orchestrator + // notifies registered aiworkers of jobs as they come in. + RegisterAIWorker(ctx context.Context, in *RegisterAIWorkerRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[NotifyAIJob], error) } -type transcoderClient struct { +type aIWorkerClient struct { cc grpc.ClientConnInterface } -func NewTranscoderClient(cc grpc.ClientConnInterface) TranscoderClient { - return &transcoderClient{cc} +func NewAIWorkerClient(cc grpc.ClientConnInterface) AIWorkerClient { + return &aIWorkerClient{cc} } -func (c *transcoderClient) RegisterTranscoder(ctx context.Context, in *RegisterRequest, opts ...grpc.CallOption) (Transcoder_RegisterTranscoderClient, error) { - stream, err := c.cc.NewStream(ctx, &Transcoder_ServiceDesc.Streams[0], "/net.Transcoder/RegisterTranscoder", opts...) +func (c *aIWorkerClient) RegisterAIWorker(ctx context.Context, in *RegisterAIWorkerRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[NotifyAIJob], error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + stream, err := c.cc.NewStream(ctx, &AIWorker_ServiceDesc.Streams[0], AIWorker_RegisterAIWorker_FullMethodName, cOpts...) if err != nil { return nil, err } - x := &transcoderRegisterTranscoderClient{stream} + x := &grpc.GenericClientStream[RegisterAIWorkerRequest, NotifyAIJob]{ClientStream: stream} if err := x.ClientStream.SendMsg(in); err != nil { return nil, err } @@ -210,41 +239,140 @@ func (c *transcoderClient) RegisterTranscoder(ctx context.Context, in *RegisterR return x, nil } -type Transcoder_RegisterTranscoderClient interface { - Recv() (*NotifySegment, error) - grpc.ClientStream +// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. +type AIWorker_RegisterAIWorkerClient = grpc.ServerStreamingClient[NotifyAIJob] + +// AIWorkerServer is the server API for AIWorker service. +// All implementations must embed UnimplementedAIWorkerServer +// for forward compatibility. +type AIWorkerServer interface { + // Called by the aiworker to register to an orchestrator. The orchestrator + // notifies registered aiworkers of jobs as they come in. + RegisterAIWorker(*RegisterAIWorkerRequest, grpc.ServerStreamingServer[NotifyAIJob]) error + mustEmbedUnimplementedAIWorkerServer() } -type transcoderRegisterTranscoderClient struct { - grpc.ClientStream +// UnimplementedAIWorkerServer must be embedded to have +// forward compatible implementations. +// +// NOTE: this should be embedded by value instead of pointer to avoid a nil +// pointer dereference when methods are called. +type UnimplementedAIWorkerServer struct{} + +func (UnimplementedAIWorkerServer) RegisterAIWorker(*RegisterAIWorkerRequest, grpc.ServerStreamingServer[NotifyAIJob]) error { + return status.Errorf(codes.Unimplemented, "method RegisterAIWorker not implemented") } +func (UnimplementedAIWorkerServer) mustEmbedUnimplementedAIWorkerServer() {} +func (UnimplementedAIWorkerServer) testEmbeddedByValue() {} -func (x *transcoderRegisterTranscoderClient) Recv() (*NotifySegment, error) { - m := new(NotifySegment) - if err := x.ClientStream.RecvMsg(m); err != nil { +// UnsafeAIWorkerServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to AIWorkerServer will +// result in compilation errors. +type UnsafeAIWorkerServer interface { + mustEmbedUnimplementedAIWorkerServer() +} + +func RegisterAIWorkerServer(s grpc.ServiceRegistrar, srv AIWorkerServer) { + // If the following call pancis, it indicates UnimplementedAIWorkerServer was + // embedded by pointer and is nil. This will cause panics if an + // unimplemented method is ever invoked, so we test this at initialization + // time to prevent it from happening at runtime later due to I/O. + if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { + t.testEmbeddedByValue() + } + s.RegisterService(&AIWorker_ServiceDesc, srv) +} + +func _AIWorker_RegisterAIWorker_Handler(srv interface{}, stream grpc.ServerStream) error { + m := new(RegisterAIWorkerRequest) + if err := stream.RecvMsg(m); err != nil { + return err + } + return srv.(AIWorkerServer).RegisterAIWorker(m, &grpc.GenericServerStream[RegisterAIWorkerRequest, NotifyAIJob]{ServerStream: stream}) +} + +// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. +type AIWorker_RegisterAIWorkerServer = grpc.ServerStreamingServer[NotifyAIJob] + +// AIWorker_ServiceDesc is the grpc.ServiceDesc for AIWorker service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var AIWorker_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "net.AIWorker", + HandlerType: (*AIWorkerServer)(nil), + Methods: []grpc.MethodDesc{}, + Streams: []grpc.StreamDesc{ + { + StreamName: "RegisterAIWorker", + Handler: _AIWorker_RegisterAIWorker_Handler, + ServerStreams: true, + }, + }, + Metadata: "net/lp_rpc.proto", +} + +const ( + Transcoder_RegisterTranscoder_FullMethodName = "/net.Transcoder/RegisterTranscoder" +) + +// TranscoderClient is the client API for Transcoder service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type TranscoderClient interface { + // Called by the transcoder to register to an orchestrator. The orchestrator + // notifies registered transcoders of segments as they come in. + RegisterTranscoder(ctx context.Context, in *RegisterRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[NotifySegment], error) +} + +type transcoderClient struct { + cc grpc.ClientConnInterface +} + +func NewTranscoderClient(cc grpc.ClientConnInterface) TranscoderClient { + return &transcoderClient{cc} +} + +func (c *transcoderClient) RegisterTranscoder(ctx context.Context, in *RegisterRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[NotifySegment], error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + stream, err := c.cc.NewStream(ctx, &Transcoder_ServiceDesc.Streams[0], Transcoder_RegisterTranscoder_FullMethodName, cOpts...) + if err != nil { + return nil, err + } + x := &grpc.GenericClientStream[RegisterRequest, NotifySegment]{ClientStream: stream} + if err := x.ClientStream.SendMsg(in); err != nil { return nil, err } - return m, nil + if err := x.ClientStream.CloseSend(); err != nil { + return nil, err + } + return x, nil } +// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. +type Transcoder_RegisterTranscoderClient = grpc.ServerStreamingClient[NotifySegment] + // TranscoderServer is the server API for Transcoder service. // All implementations must embed UnimplementedTranscoderServer -// for forward compatibility +// for forward compatibility. type TranscoderServer interface { // Called by the transcoder to register to an orchestrator. The orchestrator // notifies registered transcoders of segments as they come in. - RegisterTranscoder(*RegisterRequest, Transcoder_RegisterTranscoderServer) error + RegisterTranscoder(*RegisterRequest, grpc.ServerStreamingServer[NotifySegment]) error mustEmbedUnimplementedTranscoderServer() } -// UnimplementedTranscoderServer must be embedded to have forward compatible implementations. -type UnimplementedTranscoderServer struct { -} +// UnimplementedTranscoderServer must be embedded to have +// forward compatible implementations. +// +// NOTE: this should be embedded by value instead of pointer to avoid a nil +// pointer dereference when methods are called. +type UnimplementedTranscoderServer struct{} -func (UnimplementedTranscoderServer) RegisterTranscoder(*RegisterRequest, Transcoder_RegisterTranscoderServer) error { +func (UnimplementedTranscoderServer) RegisterTranscoder(*RegisterRequest, grpc.ServerStreamingServer[NotifySegment]) error { return status.Errorf(codes.Unimplemented, "method RegisterTranscoder not implemented") } func (UnimplementedTranscoderServer) mustEmbedUnimplementedTranscoderServer() {} +func (UnimplementedTranscoderServer) testEmbeddedByValue() {} // UnsafeTranscoderServer may be embedded to opt out of forward compatibility for this service. // Use of this interface is not recommended, as added methods to TranscoderServer will @@ -254,6 +382,13 @@ type UnsafeTranscoderServer interface { } func RegisterTranscoderServer(s grpc.ServiceRegistrar, srv TranscoderServer) { + // If the following call pancis, it indicates UnimplementedTranscoderServer was + // embedded by pointer and is nil. This will cause panics if an + // unimplemented method is ever invoked, so we test this at initialization + // time to prevent it from happening at runtime later due to I/O. + if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { + t.testEmbeddedByValue() + } s.RegisterService(&Transcoder_ServiceDesc, srv) } @@ -262,21 +397,11 @@ func _Transcoder_RegisterTranscoder_Handler(srv interface{}, stream grpc.ServerS if err := stream.RecvMsg(m); err != nil { return err } - return srv.(TranscoderServer).RegisterTranscoder(m, &transcoderRegisterTranscoderServer{stream}) + return srv.(TranscoderServer).RegisterTranscoder(m, &grpc.GenericServerStream[RegisterRequest, NotifySegment]{ServerStream: stream}) } -type Transcoder_RegisterTranscoderServer interface { - Send(*NotifySegment) error - grpc.ServerStream -} - -type transcoderRegisterTranscoderServer struct { - grpc.ServerStream -} - -func (x *transcoderRegisterTranscoderServer) Send(m *NotifySegment) error { - return x.ServerStream.SendMsg(m) -} +// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. +type Transcoder_RegisterTranscoderServer = grpc.ServerStreamingServer[NotifySegment] // Transcoder_ServiceDesc is the grpc.ServiceDesc for Transcoder service. // It's only intended for direct use with grpc.RegisterService, diff --git a/pm/recipient_test.go b/pm/recipient_test.go index b7f2b88962..d84f5fab39 100644 --- a/pm/recipient_test.go +++ b/pm/recipient_test.go @@ -17,7 +17,7 @@ import ( "github.com/stretchr/testify/require" ) -func newRecipientFixtureOrFatal(t *testing.T) (ethcommon.Address, *stubBroker, *stubValidator, *stubGasPriceMonitor, *stubSenderMonitor, *stubTimeManager, TicketParamsConfig, []byte) { +func newRecipientFixtureOrFatal(_ *testing.T) (ethcommon.Address, *stubBroker, *stubValidator, *stubGasPriceMonitor, *stubSenderMonitor, *stubTimeManager, TicketParamsConfig, []byte) { sender := RandAddress() b := newStubBroker() diff --git a/pm/sender_test.go b/pm/sender_test.go index e145149160..5ae7c42bc8 100644 --- a/pm/sender_test.go +++ b/pm/sender_test.go @@ -608,7 +608,7 @@ func TestValidateTicketParams_AcceptableParams_NoError(t *testing.T) { assert.Nil(t, err) } -func defaultSender(t *testing.T) *sender { +func defaultSender(_ *testing.T) *sender { account := accounts.Account{ Address: RandAddress(), } @@ -626,7 +626,7 @@ func defaultSender(t *testing.T) *sender { return s.(*sender) } -func defaultTicketParams(t *testing.T, recipient ethcommon.Address) TicketParams { +func defaultTicketParams(_ *testing.T, recipient ethcommon.Address) TicketParams { recipientRandHash := RandHash() return TicketParams{ Recipient: recipient, diff --git a/pm/sendermonitor_test.go b/pm/sendermonitor_test.go index 7f24f9ca93..88a32a957b 100644 --- a/pm/sendermonitor_test.go +++ b/pm/sendermonitor_test.go @@ -677,7 +677,7 @@ func TestRedeemWinningTicket_CheckAvailableFundsAndFaceValue(t *testing.T) { // Trigger SuggestGasPrice() error gasPriceErr := errors.New("SuggestGasPrice() error") - cfg.SuggestGasPrice = func(ctx context.Context) (*big.Int, error) { return nil, gasPriceErr } + cfg.SuggestGasPrice = func(_ context.Context) (*big.Int, error) { return nil, gasPriceErr } sm = NewSenderMonitor(cfg, b, smgr, tm, ts) _, err = sm.redeemWinningTicket(signedT) assert.EqualError(err, gasPriceErr.Error()) @@ -700,7 +700,7 @@ func TestRedeemWinningTicket_CheckAvailableFundsAndFaceValue(t *testing.T) { // Trigger insufficient funds to cover redeem tx cost error when availableFunds < txCost cfg.RedeemGas = 1 - cfg.SuggestGasPrice = func(ctx context.Context) (*big.Int, error) { return big.NewInt(1000000000), nil } + cfg.SuggestGasPrice = func(_ context.Context) (*big.Int, error) { return big.NewInt(1000000000), nil } sm = NewSenderMonitor(cfg, b, smgr, tm, ts) _, err = sm.redeemWinningTicket(signedT) assert.Contains(err.Error(), "insufficient sender funds") @@ -709,7 +709,7 @@ func TestRedeemWinningTicket_CheckAvailableFundsAndFaceValue(t *testing.T) { funds, err := sm.availableFunds(addr) require.Nil(t, err) cfg.RedeemGas = 1 - cfg.SuggestGasPrice = func(ctx context.Context) (*big.Int, error) { return funds, nil } + cfg.SuggestGasPrice = func(_ context.Context) (*big.Int, error) { return funds, nil } sm = NewSenderMonitor(cfg, b, smgr, tm, ts) _, err = sm.redeemWinningTicket(signedT) assert.Contains(err.Error(), "insufficient sender funds") @@ -717,7 +717,7 @@ func TestRedeemWinningTicket_CheckAvailableFundsAndFaceValue(t *testing.T) { // Trigger insufficient face value to cover redeem tx cost error when face value < txCost txCost := new(big.Int).Sub(funds, big.NewInt(1)) cfg.RedeemGas = 1 - cfg.SuggestGasPrice = func(ctx context.Context) (*big.Int, error) { return txCost, nil } + cfg.SuggestGasPrice = func(_ context.Context) (*big.Int, error) { return txCost, nil } badSignedT := defaultSignedTicket(addr, uint32(0)) badSignedT.FaceValue = new(big.Int).Sub(txCost, big.NewInt(1)) sm = NewSenderMonitor(cfg, b, smgr, tm, ts) @@ -732,7 +732,7 @@ func TestRedeemWinningTicket_CheckAvailableFundsAndFaceValue(t *testing.T) { // Pass available funds and face value check when availableFunds > txCost and face value > txCost cfg.RedeemGas = 0 - cfg.SuggestGasPrice = func(ctx context.Context) (*big.Int, error) { return big.NewInt(0), nil } + cfg.SuggestGasPrice = func(_ context.Context) (*big.Int, error) { return big.NewInt(0), nil } sm = NewSenderMonitor(cfg, b, smgr, tm, ts) tx, err := sm.redeemWinningTicket(signedT) assert.Nil(err) @@ -966,7 +966,7 @@ func stubLocalSenderMonitorCfg() *LocalSenderMonitorConfig { CleanupInterval: 5 * time.Minute, TTL: 3600, RedeemGas: 0, - SuggestGasPrice: func(ctx context.Context) (*big.Int, error) { + SuggestGasPrice: func(_ context.Context) (*big.Int, error) { return big.NewInt(0), nil }, RPCTimeout: 5 * time.Minute, diff --git a/pm/stub.go b/pm/stub.go index 549f386472..44b8ab0961 100644 --- a/pm/stub.go +++ b/pm/stub.go @@ -58,7 +58,7 @@ func (ts *stubTicketStore) StoreWinningTicket(ticket *SignedTicket) error { return nil } -func (ts *stubTicketStore) SelectEarliestWinningTicket(sender ethcommon.Address, minCreationRound int64) (*SignedTicket, error) { +func (ts *stubTicketStore) SelectEarliestWinningTicket(sender ethcommon.Address, _ int64) (*SignedTicket, error) { ts.lock.Lock() defer ts.lock.Unlock() if ts.loadShouldFail { @@ -72,7 +72,7 @@ func (ts *stubTicketStore) SelectEarliestWinningTicket(sender ethcommon.Address, return nil, nil } -func (ts *stubTicketStore) MarkWinningTicketRedeemed(ticket *SignedTicket, txHash ethcommon.Hash) error { +func (ts *stubTicketStore) MarkWinningTicketRedeemed(ticket *SignedTicket, _ ethcommon.Hash) error { ts.lock.Lock() defer ts.lock.Unlock() ts.submitted[fmt.Sprintf("%x", ticket.Sig)] = true @@ -99,7 +99,7 @@ func (ts *stubTicketStore) RemoveWinningTicket(ticket *SignedTicket) error { return nil } -func (ts *stubTicketStore) WinningTicketCount(sender ethcommon.Address, minCreationRound int64) (int, error) { +func (ts *stubTicketStore) WinningTicketCount(sender ethcommon.Address, _ int64) (int, error) { ts.lock.Lock() defer ts.lock.Unlock() if ts.loadShouldFail { @@ -114,7 +114,7 @@ func (ts *stubTicketStore) WinningTicketCount(sender ethcommon.Address, minCreat return count, nil } -func (ts *stubTicketStore) IsOrchActive(addr ethcommon.Address, round *big.Int) (bool, error) { +func (ts *stubTicketStore) IsOrchActive(_ ethcommon.Address, _ *big.Int) (bool, error) { return ts.isActive, ts.err } @@ -130,7 +130,7 @@ func (sv *stubSigVerifier) SetVerifyResult(verifyResult bool) { sv.verifyResult = verifyResult } -func (sv *stubSigVerifier) Verify(addr ethcommon.Address, msg, sig []byte) bool { +func (sv *stubSigVerifier) Verify(_ ethcommon.Address, _, _ []byte) bool { return sv.verifyResult } @@ -156,15 +156,15 @@ func newStubBroker() *stubBroker { } } -func (b *stubBroker) FundDepositAndReserve(depositAmount, reserveAmount *big.Int) (*types.Transaction, error) { +func (b *stubBroker) FundDepositAndReserve(_, _ *big.Int) (*types.Transaction, error) { return nil, nil } -func (b *stubBroker) FundDeposit(amount *big.Int) (*types.Transaction, error) { +func (b *stubBroker) FundDeposit(_ *big.Int) (*types.Transaction, error) { return nil, nil } -func (b *stubBroker) FundReserve(amount *big.Int) (*types.Transaction, error) { +func (b *stubBroker) FundReserve(_ *big.Int) (*types.Transaction, error) { return nil, nil } @@ -180,7 +180,7 @@ func (b *stubBroker) Withdraw() (*types.Transaction, error) { return nil, nil } -func (b *stubBroker) RedeemWinningTicket(ticket *Ticket, sig []byte, recipientRand *big.Int) (*types.Transaction, error) { +func (b *stubBroker) RedeemWinningTicket(ticket *Ticket, _ []byte, _ *big.Int) (*types.Transaction, error) { b.mu.Lock() defer b.mu.Unlock() @@ -204,7 +204,7 @@ func (b *stubBroker) IsUsedTicket(ticket *Ticket) (bool, error) { return b.usedTickets[ticket.Hash()], nil } -func (b *stubBroker) ClaimableReserve(reserveHolder ethcommon.Address, claimant ethcommon.Address) (*big.Int, error) { +func (b *stubBroker) ClaimableReserve(reserveHolder ethcommon.Address, _ ethcommon.Address) (*big.Int, error) { if b.claimableReserveShouldFail { return nil, fmt.Errorf("stub broker ClaimableReserve error") } @@ -212,7 +212,7 @@ func (b *stubBroker) ClaimableReserve(reserveHolder ethcommon.Address, claimant return b.reserves[reserveHolder], nil } -func (b *stubBroker) CheckTx(tx *types.Transaction) error { +func (b *stubBroker) CheckTx(_ *types.Transaction) error { return b.checkTxErr } @@ -229,7 +229,7 @@ func (v *stubValidator) SetIsWinningTicket(isWinningTicket bool) { v.isWinningTicket = isWinningTicket } -func (v *stubValidator) ValidateTicket(recipient ethcommon.Address, ticket *Ticket, sig []byte, recipientRand *big.Int) error { +func (v *stubValidator) ValidateTicket(_ ethcommon.Address, _ *Ticket, _ []byte, _ *big.Int) error { if !v.isValidTicket { return fmt.Errorf("stub validator invalid ticket error") } @@ -237,7 +237,7 @@ func (v *stubValidator) ValidateTicket(recipient ethcommon.Address, ticket *Tick return nil } -func (v *stubValidator) IsWinningTicket(ticket *Ticket, sig []byte, recipientRand *big.Int) bool { +func (v *stubValidator) IsWinningTicket(_ *Ticket, _ []byte, _ *big.Int) bool { return v.isWinningTicket } @@ -252,7 +252,7 @@ type stubSigner struct { // TODO remove this function // NOTE: Keeping this function for now because removing it causes the tests to fail when run with the // logtostderr flag. -func (s *stubSigner) CreateTransactOpts(gasLimit uint64, gasPrice *big.Int) (*bind.TransactOpts, error) { +func (s *stubSigner) CreateTransactOpts(_ uint64, _ *big.Int) (*bind.TransactOpts, error) { return nil, nil } @@ -353,7 +353,7 @@ func (s *stubSenderManager) GetSenderInfo(addr ethcommon.Address) (*SenderInfo, return s.info[addr], nil } -func (s *stubSenderManager) ClaimedReserve(reserveHolder ethcommon.Address, claimant ethcommon.Address) (*big.Int, error) { +func (s *stubSenderManager) ClaimedReserve(reserveHolder ethcommon.Address, _ ethcommon.Address) (*big.Int, error) { if s.claimedReserveErr != nil { return nil, s.claimedReserveErr } @@ -413,7 +413,7 @@ func (s *stubSenderMonitor) QueueTicket(ticket *SignedTicket) error { return nil } -func (s *stubSenderMonitor) AddFloat(addr ethcommon.Address, amount *big.Int) error { +func (s *stubSenderMonitor) AddFloat(_ ethcommon.Address, _ *big.Int) error { if s.addFloatErr != nil { return s.addFloatErr } @@ -421,11 +421,11 @@ func (s *stubSenderMonitor) AddFloat(addr ethcommon.Address, amount *big.Int) er return nil } -func (s *stubSenderMonitor) SubFloat(addr ethcommon.Address, amount *big.Int) { +func (s *stubSenderMonitor) SubFloat(_ ethcommon.Address, amount *big.Int) { s.maxFloat.Sub(s.maxFloat, amount) } -func (s *stubSenderMonitor) MaxFloat(addr ethcommon.Address) (*big.Int, error) { +func (s *stubSenderMonitor) MaxFloat(_ ethcommon.Address) (*big.Int, error) { if s.maxFloatErr != nil { return nil, s.maxFloatErr } @@ -433,7 +433,7 @@ func (s *stubSenderMonitor) MaxFloat(addr ethcommon.Address) (*big.Int, error) { return s.maxFloat, nil } -func (s *stubSenderMonitor) ValidateSender(addr ethcommon.Address) error { return s.validateSenderErr } +func (s *stubSenderMonitor) ValidateSender(_ ethcommon.Address) error { return s.validateSenderErr } // MockRecipient is useful for testing components that depend on pm.Recipient type MockRecipient struct { @@ -495,7 +495,7 @@ func (m *MockRecipient) EV() *big.Rat { } // Sets the max ticket facevalue for the orchestrator -func (m *MockRecipient) SetMaxFaceValue(maxfacevalue *big.Int) { +func (m *MockRecipient) SetMaxFaceValue(_ *big.Int) { } diff --git a/server/ai_http.go b/server/ai_http.go new file mode 100644 index 0000000000..1913781d68 --- /dev/null +++ b/server/ai_http.go @@ -0,0 +1,643 @@ +package server + +// ai_http.go implements the HTTP server for AI-related requests at the Orchestrator. + +import ( + "bufio" + "context" + "encoding/base64" + "encoding/json" + "fmt" + "image" + "io" + "mime" + "mime/multipart" + "net/http" + "strconv" + "strings" + "time" + "unicode/utf8" + + "github.com/getkin/kin-openapi/openapi3filter" + "github.com/golang/glog" + "github.com/livepeer/ai-worker/worker" + "github.com/livepeer/go-livepeer/clog" + "github.com/livepeer/go-livepeer/common" + "github.com/livepeer/go-livepeer/core" + "github.com/livepeer/go-livepeer/monitor" + "github.com/livepeer/go-livepeer/trickle" + middleware "github.com/oapi-codegen/nethttp-middleware" +) + +var MaxAIRequestSize = 3000000000 // 3GB + +var TrickleHTTPPath = "/ai/trickle/" + +func startAIServer(lp lphttp) error { + swagger, err := worker.GetSwagger() + if err != nil { + return err + } + swagger.Servers = nil + + opts := &middleware.Options{ + Options: openapi3filter.Options{ + ExcludeRequestBody: true, + AuthenticationFunc: openapi3filter.NoopAuthenticationFunc, + }, + ErrorHandler: func(w http.ResponseWriter, message string, statusCode int) { + clog.Errorf(context.Background(), "oapi validation error statusCode=%v message=%v", statusCode, message) + }, + } + oapiReqValidator := middleware.OapiRequestValidatorWithOptions(swagger, opts) + + openapi3filter.RegisterBodyDecoder("image/png", openapi3filter.FileBodyDecoder) + + lp.trickleSrv = trickle.ConfigureServer(trickle.TrickleServerConfig{ + Mux: lp.transRPC, + BasePath: TrickleHTTPPath, + }) + + lp.transRPC.Handle("/text-to-image", oapiReqValidator(aiHttpHandle(&lp, jsonDecoder[worker.GenTextToImageJSONRequestBody]))) + lp.transRPC.Handle("/image-to-image", oapiReqValidator(aiHttpHandle(&lp, multipartDecoder[worker.GenImageToImageMultipartRequestBody]))) + lp.transRPC.Handle("/image-to-video", oapiReqValidator(aiHttpHandle(&lp, multipartDecoder[worker.GenImageToVideoMultipartRequestBody]))) + lp.transRPC.Handle("/upscale", oapiReqValidator(aiHttpHandle(&lp, multipartDecoder[worker.GenUpscaleMultipartRequestBody]))) + lp.transRPC.Handle("/audio-to-text", oapiReqValidator(aiHttpHandle(&lp, multipartDecoder[worker.GenAudioToTextMultipartRequestBody]))) + lp.transRPC.Handle("/llm", oapiReqValidator(aiHttpHandle(&lp, jsonDecoder[worker.GenLLMFormdataRequestBody]))) + lp.transRPC.Handle("/segment-anything-2", oapiReqValidator(aiHttpHandle(&lp, multipartDecoder[worker.GenSegmentAnything2MultipartRequestBody]))) + lp.transRPC.Handle("/image-to-text", oapiReqValidator(aiHttpHandle(&lp, multipartDecoder[worker.GenImageToTextMultipartRequestBody]))) + lp.transRPC.Handle("/text-to-speech", oapiReqValidator(aiHttpHandle(&lp, multipartDecoder[worker.GenTextToSpeechJSONRequestBody]))) + + lp.transRPC.Handle("/live-video-to-video", oapiReqValidator(lp.StartLiveVideoToVideo())) + // Additionally, there is the '/aiResults' endpoint registered in server/rpc.go + + return nil +} + +// aiHttpHandle handles AI requests by decoding the request body and processing it. +func aiHttpHandle[I any](h *lphttp, decoderFunc func(*I, *http.Request) error) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + orch := h.orchestrator + remoteAddr := getRemoteAddr(r) + ctx := clog.AddVal(r.Context(), clog.ClientIP, remoteAddr) + + var req I + if err := decoderFunc(&req, r); err != nil { + respondWithError(w, err.Error(), http.StatusBadRequest) + return + } + + handleAIRequest(ctx, w, r, orch, req) + }) +} + +func (h *lphttp) StartLiveVideoToVideo() http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + + // skipping handleAIRequest for now until we have payments + + var ( + mid = string(core.RandomManifestID()) + pubUrl = TrickleHTTPPath + mid + subUrl = pubUrl + "-out" + ) + jsonData, err := json.Marshal( + &worker.LiveVideoToVideoResponse{ + PublishUrl: pubUrl, + SubscribeUrl: subUrl, + }) + if err != nil { + respondWithError(w, err.Error(), http.StatusInternalServerError) + return + } + + respondJsonOk(w, jsonData) + }) +} + +func handleAIRequest(ctx context.Context, w http.ResponseWriter, r *http.Request, orch Orchestrator, req interface{}) { + payment, err := getPayment(r.Header.Get(paymentHeader)) + if err != nil { + respondWithError(w, err.Error(), http.StatusPaymentRequired) + return + } + sender := getPaymentSender(payment) + + _, ctx, err = verifySegCreds(ctx, orch, r.Header.Get(segmentHeader), sender) + if err != nil { + respondWithError(w, err.Error(), http.StatusForbidden) + return + } + + requestID := string(core.RandomManifestID()) + + var cap core.Capability + var pipeline string + var modelID string + var submitFn func(context.Context) (interface{}, error) + var outPixels int64 + + switch v := req.(type) { + case worker.GenTextToImageJSONRequestBody: + pipeline = "text-to-image" + cap = core.Capability_TextToImage + modelID = *v.ModelId + submitFn = func(ctx context.Context) (interface{}, error) { + return orch.TextToImage(ctx, requestID, v) + } + + // TODO: The orchestrator should require the broadcaster to always specify a height and width + height := int64(512) + if v.Height != nil { + height = int64(*v.Height) + } + width := int64(512) + if v.Width != nil { + width = int64(*v.Width) + } + // NOTE: Should be enforced by the gateway, added for backwards compatibility. + numImages := int64(1) + if v.NumImagesPerPrompt != nil { + numImages = int64(*v.NumImagesPerPrompt) + } + + outPixels = height * width * numImages + case worker.GenImageToImageMultipartRequestBody: + pipeline = "image-to-image" + cap = core.Capability_ImageToImage + modelID = *v.ModelId + submitFn = func(ctx context.Context) (interface{}, error) { + return orch.ImageToImage(ctx, requestID, v) + } + + imageRdr, err := v.Image.Reader() + if err != nil { + respondWithError(w, err.Error(), http.StatusBadRequest) + return + } + config, _, err := image.DecodeConfig(imageRdr) + if err != nil { + respondWithError(w, err.Error(), http.StatusBadRequest) + return + } + // NOTE: Should be enforced by the gateway, added for backwards compatibility. + numImages := int64(1) + if v.NumImagesPerPrompt != nil { + numImages = int64(*v.NumImagesPerPrompt) + } + + outPixels = int64(config.Height) * int64(config.Width) * numImages + case worker.GenUpscaleMultipartRequestBody: + pipeline = "upscale" + cap = core.Capability_Upscale + modelID = *v.ModelId + submitFn = func(ctx context.Context) (interface{}, error) { + return orch.Upscale(ctx, requestID, v) + } + + imageRdr, err := v.Image.Reader() + if err != nil { + respondWithError(w, err.Error(), http.StatusBadRequest) + return + } + config, _, err := image.DecodeConfig(imageRdr) + if err != nil { + respondWithError(w, err.Error(), http.StatusBadRequest) + return + } + outPixels = int64(config.Height) * int64(config.Width) + case worker.GenImageToVideoMultipartRequestBody: + pipeline = "image-to-video" + cap = core.Capability_ImageToVideo + modelID = *v.ModelId + submitFn = func(ctx context.Context) (interface{}, error) { + return orch.ImageToVideo(ctx, requestID, v) + } + + // TODO: The orchestrator should require the broadcaster to always specify a height and width + height := int64(576) + if v.Height != nil { + height = int64(*v.Height) + } + width := int64(1024) + if v.Width != nil { + width = int64(*v.Width) + } + // The # of frames outputted by stable-video-diffusion-img2vid-xt models + frames := int64(25) + + outPixels = height * width * int64(frames) + case worker.GenAudioToTextMultipartRequestBody: + pipeline = "audio-to-text" + cap = core.Capability_AudioToText + modelID = *v.ModelId + submitFn = func(ctx context.Context) (interface{}, error) { + return orch.AudioToText(ctx, requestID, v) + } + + outPixels, err = common.CalculateAudioDuration(v.Audio) + if err != nil { + respondWithError(w, "Unable to calculate duration", http.StatusBadRequest) + return + } + outPixels *= 1000 // Convert to milliseconds + case worker.GenLLMFormdataRequestBody: + pipeline = "llm" + cap = core.Capability_LLM + modelID = *v.ModelId + submitFn = func(ctx context.Context) (interface{}, error) { + return orch.LLM(ctx, requestID, v) + } + + if v.MaxTokens == nil { + respondWithError(w, "MaxTokens not specified", http.StatusBadRequest) + return + } + + // TODO: Improve pricing + outPixels = int64(*v.MaxTokens) + case worker.GenSegmentAnything2MultipartRequestBody: + pipeline = "segment-anything-2" + cap = core.Capability_SegmentAnything2 + modelID = *v.ModelId + submitFn = func(ctx context.Context) (interface{}, error) { + return orch.SegmentAnything2(ctx, requestID, v) + } + + imageRdr, err := v.Image.Reader() + if err != nil { + respondWithError(w, err.Error(), http.StatusBadRequest) + return + } + config, _, err := image.DecodeConfig(imageRdr) + if err != nil { + respondWithError(w, err.Error(), http.StatusBadRequest) + return + } + outPixels = int64(config.Height) * int64(config.Width) + case worker.GenImageToTextMultipartRequestBody: + pipeline = "image-to-text" + cap = core.Capability_ImageToText + modelID = *v.ModelId + submitFn = func(ctx context.Context) (interface{}, error) { + return orch.ImageToText(ctx, requestID, v) + } + + imageRdr, err := v.Image.Reader() + if err != nil { + respondWithError(w, err.Error(), http.StatusBadRequest) + return + } + config, _, err := image.DecodeConfig(imageRdr) + if err != nil { + respondWithError(w, err.Error(), http.StatusBadRequest) + return + } + outPixels = int64(config.Height) * int64(config.Width) + case worker.GenTextToSpeechJSONRequestBody: + pipeline = "text-to-speech" + cap = core.Capability_TextToSpeech + modelID = *v.ModelId + + submitFn = func(ctx context.Context) (interface{}, error) { + return orch.TextToSpeech(ctx, requestID, v) + } + + // TTS pricing is typically in characters, including punctuation. + words := utf8.RuneCountInString(*v.Text) + outPixels = int64(1000 * words) + default: + respondWithError(w, "Unknown request type", http.StatusBadRequest) + return + } + + clog.V(common.VERBOSE).Infof(ctx, "Received request id=%v cap=%v modelID=%v", requestID, cap, modelID) + + manifestID := core.ManifestID(strconv.Itoa(int(cap)) + "_" + modelID) + + // Check if there is capacity for the request. + if !orch.CheckAICapacity(pipeline, modelID) { + respondWithError(w, fmt.Sprintf("Insufficient capacity for pipeline=%v modelID=%v", pipeline, modelID), http.StatusServiceUnavailable) + return + } + + // Known limitation: + // This call will set a fixed price for all requests in a session identified by a manifestID. + // Since all requests for a capability + modelID are treated as "session" with a single manifestID, all + // requests for a capability + modelID will get the same fixed price for as long as the orch is running + if err := orch.ProcessPayment(ctx, payment, manifestID); err != nil { + respondWithError(w, err.Error(), http.StatusBadRequest) + return + } + + if payment.GetExpectedPrice().GetPricePerUnit() > 0 && !orch.SufficientBalance(sender, manifestID) { + respondWithError(w, "Insufficient balance", http.StatusBadRequest) + return + } + + err = orch.CreateStorageForRequest(requestID) + if err != nil { + respondWithError(w, "Could not create storage to receive results", http.StatusInternalServerError) + } + // Note: At the moment, we do not return a new OrchestratorInfo with updated ticket params + price with + // extended expiry because the response format does not include such a field. As a result, the broadcaster + // might encounter an expiration error for ticket params + price when it is using an old OrchestratorInfo returned + // by the orch during discovery. In that scenario, the broadcaster can use a GetOrchestrator() RPC call to get a + // a new OrchestratorInfo before submitting a request. + + start := time.Now() + resp, err := submitFn(ctx) + if err != nil { + if monitor.Enabled { + monitor.AIProcessingError(err.Error(), pipeline, modelID, sender.Hex()) + } + respondWithError(w, err.Error(), http.StatusInternalServerError) + return + } + + //backwards compatibility to old gateway api + //Gateway version through v0.7.9-ai.3 expects to receive base64 encoded images as results for text-to-image, image-to-image, and upscale pipelines + //The gateway now adds the protoVerAIWorker header to the request to indicate what version of the gateway is making the request + //UPDATE this logic as the communication protocol between the gateway and orchestrator is updated + if pipeline == "text-to-image" || pipeline == "image-to-image" || pipeline == "upscale" { + if r.Header.Get("Authorization") != protoVerAIWorker { + imgResp := resp.(worker.ImageResponse) + prefix := "data:image/png;base64," //https://github.com/livepeer/ai-worker/blob/78b58131f12867ce5a4d0f6e2b9038e70de5c8e3/runner/app/routes/util.py#L56 + storage, exists := orch.GetStorageForRequest(requestID) + if exists { + for i, image := range imgResp.Images { + fileData, err := storage.ReadData(ctx, image.Url) + if err == nil { + clog.V(common.VERBOSE).Infof(ctx, "replacing response with base64 for gateway on older api gateway_api=%v", r.Header.Get("Authorization")) + data, _ := io.ReadAll(fileData.Body) + imgResp.Images[i].Url = prefix + base64.StdEncoding.EncodeToString(data) + } else { + glog.Error(err) + } + } + } + //return the modified response + resp = imgResp + } + } + + took := time.Since(start) + clog.Infof(ctx, "Processed request id=%v cap=%v modelID=%v took=%v", requestID, cap, modelID, took) + + // At the moment, outPixels is expected to just be height * width * frames + // If the # of inference/denoising steps becomes configurable, a possible updated formula could be height * width * frames * steps + // If additional parameters that influence compute cost become configurable, then the formula should be reconsidered + orch.DebitFees(sender, manifestID, payment.GetExpectedPrice(), outPixels) + + if monitor.Enabled { + var latencyScore float64 + switch v := req.(type) { + case worker.GenTextToImageJSONRequestBody: + latencyScore = CalculateTextToImageLatencyScore(took, v, outPixels) + case worker.GenImageToImageMultipartRequestBody: + latencyScore = CalculateImageToImageLatencyScore(took, v, outPixels) + case worker.GenImageToVideoMultipartRequestBody: + latencyScore = CalculateImageToVideoLatencyScore(took, v, outPixels) + case worker.GenUpscaleMultipartRequestBody: + latencyScore = CalculateUpscaleLatencyScore(took, v, outPixels) + case worker.GenAudioToTextMultipartRequestBody: + durationSeconds, err := common.CalculateAudioDuration(v.Audio) + if err == nil { + latencyScore = CalculateAudioToTextLatencyScore(took, durationSeconds) + } + case worker.GenSegmentAnything2MultipartRequestBody: + latencyScore = CalculateSegmentAnything2LatencyScore(took, outPixels) + case worker.GenImageToTextMultipartRequestBody: + latencyScore = CalculateImageToTextLatencyScore(took, outPixels) + case worker.GenTextToSpeechJSONRequestBody: + latencyScore = CalculateTextToSpeechLatencyScore(took, outPixels) + } + + var pricePerAIUnit float64 + if priceInfo := payment.GetExpectedPrice(); priceInfo != nil && priceInfo.GetPixelsPerUnit() != 0 { + pricePerAIUnit = float64(priceInfo.GetPricePerUnit()) / float64(priceInfo.GetPixelsPerUnit()) + } + + monitor.AIJobProcessed(ctx, pipeline, modelID, monitor.AIJobInfo{LatencyScore: latencyScore, PricePerUnit: pricePerAIUnit}) + } + + // Check if the response is a streaming response + if streamChan, ok := resp.(<-chan worker.LlmStreamChunk); ok { + glog.Infof("Streaming response for request id=%v", requestID) + + // Set headers for SSE + w.Header().Set("Content-Type", "text/event-stream") + w.Header().Set("Cache-Control", "no-cache") + w.Header().Set("Connection", "keep-alive") + + flusher, ok := w.(http.Flusher) + if !ok { + http.Error(w, "Streaming unsupported!", http.StatusInternalServerError) + return + } + + for chunk := range streamChan { + data, err := json.Marshal(chunk) + if err != nil { + clog.Errorf(ctx, "Error marshaling stream chunk: %v", err) + continue + } + + fmt.Fprintf(w, "data: %s\n\n", data) + flusher.Flush() + + if chunk.Done { + break + } + } + } else { + // Non-streaming response + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + _ = json.NewEncoder(w).Encode(resp) + } + +} + +// +// Orchestrator receiving results from the remote AI worker +// + +func (h *lphttp) AIResults() http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + orch := h.orchestrator + + authType := r.Header.Get("Authorization") + if protoVerAIWorker != authType { + glog.Error("Invalid auth type ", authType) + http.Error(w, "Unauthorized", http.StatusUnauthorized) + return + } + + creds := r.Header.Get("Credentials") + + if creds != orch.TranscoderSecret() { + glog.Error("Invalid shared secret") + respondWithError(w, errSecret.Error(), http.StatusUnauthorized) + } + + mediaType, params, err := mime.ParseMediaType(r.Header.Get("Content-Type")) + if err != nil { + glog.Error("Error getting mime type ", err) + http.Error(w, err.Error(), http.StatusUnsupportedMediaType) + return + } + + tid, err := strconv.ParseInt(r.Header.Get("TaskId"), 10, 64) + if err != nil { + glog.Error("Could not parse task ID ", err) + http.Error(w, "Invalid Task ID", http.StatusBadRequest) + return + } + + pipeline := r.Header.Get("Pipeline") + + var workerResult core.RemoteAIWorkerResult + workerResult.Files = make(map[string][]byte) + + start := time.Now() + dlDur := time.Duration(0) // default to 0 in case of early return + resultType := "" + switch mediaType { + case aiWorkerErrorMimeType: + body, err := io.ReadAll(r.Body) + if err != nil { + glog.Errorf("Unable to read ai worker error body taskId=%v err=%q", tid, err) + workerResult.Err = err + } else { + workerResult.Err = fmt.Errorf(string(body)) + } + glog.Errorf("AI Worker error for taskId=%v err=%q", tid, workerResult.Err) + orch.AIResults(tid, &workerResult) + w.Write([]byte("OK")) + return + case "text/event-stream": + resultType = "streaming" + glog.Infof("Received %s response from remote worker=%s taskId=%d", resultType, r.RemoteAddr, tid) + resChan := make(chan worker.LlmStreamChunk, 100) + workerResult.Results = (<-chan worker.LlmStreamChunk)(resChan) + + defer r.Body.Close() + defer close(resChan) + //set a reasonable timeout to stop waiting for results + ctx, _ := context.WithTimeout(r.Context(), HTTPIdleTimeout) + + //pass results and receive from channel as the results are streamed + go orch.AIResults(tid, &workerResult) + // Read the streamed results from the request body + scanner := bufio.NewScanner(r.Body) + for scanner.Scan() { + select { + case <-ctx.Done(): + return + default: + line := scanner.Text() + if strings.HasPrefix(line, "data: ") { + data := strings.TrimPrefix(line, "data: ") + var chunk worker.LlmStreamChunk + if err := json.Unmarshal([]byte(data), &chunk); err != nil { + clog.Errorf(ctx, "Error unmarshaling stream data: %v", err) + continue + } + resChan <- chunk + } + } + } + if err := scanner.Err(); err != nil { + workerResult.Err = scanner.Err() + } + + dlDur = time.Since(start) + case "multipart/mixed": + resultType = "uploaded" + glog.Infof("Received %s response from remote worker=%s taskId=%d", resultType, r.RemoteAddr, tid) + workerResult := parseMultiPartResult(r.Body, params["boundary"], pipeline) + + //return results + dlDur = time.Since(start) + workerResult.DownloadTime = dlDur + orch.AIResults(tid, &workerResult) + } + + glog.V(common.VERBOSE).Infof("Processed %s results from remote worker=%s taskId=%d dur=%s", resultType, r.RemoteAddr, tid, dlDur) + + if workerResult.Err != nil { + http.Error(w, workerResult.Err.Error(), http.StatusInternalServerError) + return + } + + w.Write([]byte("OK")) + }) +} + +func parseMultiPartResult(body io.Reader, boundary string, pipeline string) core.RemoteAIWorkerResult { + wkrResult := core.RemoteAIWorkerResult{} + wkrResult.Files = make(map[string][]byte) + + mr := multipart.NewReader(body, boundary) + for { + p, err := mr.NextPart() + if err == io.EOF { + break + } + if err != nil { + glog.Error("Could not process multipart part ", err) + wkrResult.Err = err + break + } + body, err := common.ReadAtMost(p, MaxAIRequestSize) + if err != nil { + glog.Error("Error reading body ", err) + wkrResult.Err = err + break + } + + // this is where we would include metadata on each result if want to separate + // instead the multipart response includes the json and the files separately with the json "url" field matching to part names + cDisp := p.Header.Get("Content-Disposition") + if p.Header.Get("Content-Type") == "application/json" { + var results interface{} + switch pipeline { + case "text-to-image", "image-to-image", "upscale", "image-to-video": + var parsedResp worker.ImageResponse + + err := json.Unmarshal(body, &parsedResp) + if err != nil { + glog.Error("Error getting results json:", err) + wkrResult.Err = err + break + } + results = parsedResp + case "audio-to-text", "segment-anything-2", "llm", "image-to-text": + err := json.Unmarshal(body, &results) + if err != nil { + glog.Error("Error getting results json:", err) + wkrResult.Err = err + break + } + case "text-to-speech": + var parsedResp worker.AudioResponse + err := json.Unmarshal(body, &parsedResp) + if err != nil { + glog.Error("Error getting results json:", err) + wkrResult.Err = err + break + } + results = parsedResp + } + + wkrResult.Results = results + } else if cDisp != "" { + //these are the result files binary data + resultName := p.FileName() + wkrResult.Files[resultName] = body + } + } + + return wkrResult +} diff --git a/server/ai_http_test.go b/server/ai_http_test.go new file mode 100644 index 0000000000..4a3bb66a26 --- /dev/null +++ b/server/ai_http_test.go @@ -0,0 +1,125 @@ +package server + +import ( + "crypto/tls" + "io" + "net/http" + "net/http/httptest" + "net/url" + "testing" + "time" + + "github.com/livepeer/go-livepeer/core" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestAIWorkerResults_ErrorsWhenAuthHeaderMissing(t *testing.T) { + var l lphttp + + var w = httptest.NewRecorder() + r, err := http.NewRequest(http.MethodPost, "/aiResults", nil) + require.NoError(t, err) + + code, body := aiResultsTest(l, w, r) + + require.Equal(t, http.StatusUnauthorized, code) + require.Contains(t, body, "Unauthorized") +} + +func TestAIWorkerResults_ErrorsWhenCredentialsInvalid(t *testing.T) { + var l lphttp + l.orchestrator = newStubOrchestrator() + l.orchestrator.TranscoderSecret() + var w = httptest.NewRecorder() + + r, err := http.NewRequest(http.MethodPost, "/aiResults", nil) + require.NoError(t, err) + + r.Header.Set("Authorization", protoVerAIWorker) + r.Header.Set("Credentials", "BAD CREDENTIALS") + + code, body := aiResultsTest(l, w, r) + require.Equal(t, http.StatusUnauthorized, code) + require.Contains(t, body, "invalid secret") +} + +func TestAIWorkerResults_ErrorsWhenContentTypeMissing(t *testing.T) { + var l lphttp + l.orchestrator = newStubOrchestrator() + l.orchestrator.TranscoderSecret() + var w = httptest.NewRecorder() + + r, err := http.NewRequest(http.MethodPost, "/aiResults", nil) + require.NoError(t, err) + + r.Header.Set("Authorization", protoVerAIWorker) + r.Header.Set("Credentials", "") + + code, body := aiResultsTest(l, w, r) + + require.Equal(t, http.StatusUnsupportedMediaType, code) + require.Contains(t, body, "mime: no media type") +} + +func TestAIWorkerResults_ErrorsWhenTaskIDMissing(t *testing.T) { + var l lphttp + l.orchestrator = newStubOrchestrator() + l.orchestrator.TranscoderSecret() + var w = httptest.NewRecorder() + + r, err := http.NewRequest(http.MethodPost, "/aiResults", nil) + require.NoError(t, err) + + r.Header.Set("Authorization", protoVerAIWorker) + r.Header.Set("Credentials", "") + r.Header.Set("Content-Type", "application/json") + + code, body := aiResultsTest(l, w, r) + + require.Equal(t, http.StatusBadRequest, code) + require.Contains(t, body, "Invalid Task ID") +} + +func TestAIWorkerResults_BadRequestType(t *testing.T) { + httpc := &http.Client{Transport: &http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: true}}} + + assert := assert.New(t) + assert.Nil(nil) + resultData := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + _, err := io.ReadAll(r.Body) + assert.NoError(err) + w.Write([]byte("result binary data")) + })) + defer resultData.Close() + // sending bad request + notify := createAIJob(742, "text-to-image-invalid", "livepeer/model1", "") + + wkr := stubAIWorker{} + node, _ := core.NewLivepeerNode(nil, "/tmp/thisdirisnotactuallyusedinthistest", nil) + node.OrchSecret = "verbigsecret" + node.AIWorker = &wkr + node.Capabilities = createStubAIWorkerCapabilitiesForPipelineModelId("text-to-image", "livepeer/model1") + + var headers http.Header + var body []byte + ts := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + out, err := io.ReadAll(r.Body) + assert.NoError(err) + headers = r.Header + body = out + w.Write(nil) + })) + defer ts.Close() + parsedURL, _ := url.Parse(ts.URL) + // send empty request data + runAIJob(node, parsedURL.Host, httpc, notify) + time.Sleep(3 * time.Millisecond) + + assert.NotNil(body) + assert.Equal("742", headers.Get("TaskId")) + assert.Equal(aiWorkerErrorMimeType, headers.Get("Content-Type")) + assert.Equal(node.OrchSecret, headers.Get("Credentials")) + assert.Equal(protoVerAIWorker, headers.Get("Authorization")) + assert.Equal("AI request validation failed for", string(body)[0:32]) +} diff --git a/server/ai_live_video.go b/server/ai_live_video.go new file mode 100644 index 0000000000..f5eed6792e --- /dev/null +++ b/server/ai_live_video.go @@ -0,0 +1,36 @@ +package server + +import ( + "io" + "log/slog" + "net/url" + + "github.com/livepeer/go-livepeer/media" + "github.com/livepeer/go-livepeer/trickle" +) + +func startTricklePublish(url *url.URL, params aiRequestParams) { + publisher, err := trickle.NewTricklePublisher(url.String()) + if err != nil { + slog.Info("error publishing trickle", "err", err) + } + params.segmentReader.SwitchReader(func(reader io.Reader) { + // check for end of stream + if _, eos := reader.(*media.EOSReader); eos { + if err := publisher.Close(); err != nil { + slog.Info("Error closing trickle publisher", "err", err) + } + return + } + go func() { + // TODO this blocks! very bad! + if err := publisher.Write(reader); err != nil { + slog.Info("Error writing to trickle publisher", "err", err) + } + }() + }) + slog.Info("trickle pub", "url", url) +} + +func startTrickleSubscribe(url *url.URL, params aiRequestParams) { +} diff --git a/server/ai_mediaserver.go b/server/ai_mediaserver.go new file mode 100644 index 0000000000..b4f32645d7 --- /dev/null +++ b/server/ai_mediaserver.go @@ -0,0 +1,387 @@ +package server + +import ( + "bytes" + "context" + "encoding/json" + "errors" + "fmt" + "net/http" + "time" + + "github.com/getkin/kin-openapi/openapi3filter" + "github.com/livepeer/ai-worker/worker" + "github.com/livepeer/go-livepeer/clog" + "github.com/livepeer/go-livepeer/common" + "github.com/livepeer/go-livepeer/core" + "github.com/livepeer/go-livepeer/media" + "github.com/livepeer/go-tools/drivers" + middleware "github.com/oapi-codegen/nethttp-middleware" + "github.com/oapi-codegen/runtime" +) + +type ImageToVideoResponseAsync struct { + RequestID string `json:"request_id"` +} + +type ImageToVideoResultRequest struct { + RequestID string `json:"request_id"` +} + +type ImageToVideoResultResponse struct { + Result *ImageToVideoResult `json:"result,omitempty"` + Status ImageToVideoStatus `json:"status"` +} + +type ImageToVideoResult struct { + *worker.ImageResponse + Error *APIError `json:"error,omitempty"` +} + +type ImageToVideoStatus string + +const ( + Processing ImageToVideoStatus = "processing" + Complete ImageToVideoStatus = "complete" +) + +func startAIMediaServer(ls *LivepeerServer) error { + swagger, err := worker.GetSwagger() + if err != nil { + return err + } + swagger.Servers = nil + + opts := &middleware.Options{ + Options: openapi3filter.Options{ + ExcludeRequestBody: true, + AuthenticationFunc: openapi3filter.NoopAuthenticationFunc, + }, + ErrorHandler: func(w http.ResponseWriter, message string, statusCode int) { + clog.Errorf(context.Background(), "oapi validation error statusCode=%v message=%v", statusCode, message) + }, + } + oapiReqValidator := middleware.OapiRequestValidatorWithOptions(swagger, opts) + + openapi3filter.RegisterBodyDecoder("image/png", openapi3filter.FileBodyDecoder) + + ls.HTTPMux.Handle("/text-to-image", oapiReqValidator(aiMediaServerHandle(ls, jsonDecoder[worker.GenTextToImageJSONRequestBody], processTextToImage))) + ls.HTTPMux.Handle("/image-to-image", oapiReqValidator(aiMediaServerHandle(ls, multipartDecoder[worker.GenImageToImageMultipartRequestBody], processImageToImage))) + ls.HTTPMux.Handle("/upscale", oapiReqValidator(aiMediaServerHandle(ls, multipartDecoder[worker.GenUpscaleMultipartRequestBody], processUpscale))) + ls.HTTPMux.Handle("/image-to-video", oapiReqValidator(ls.ImageToVideo())) + ls.HTTPMux.Handle("/image-to-video/result", ls.ImageToVideoResult()) + ls.HTTPMux.Handle("/audio-to-text", oapiReqValidator(aiMediaServerHandle(ls, multipartDecoder[worker.GenAudioToTextMultipartRequestBody], processAudioToText))) + ls.HTTPMux.Handle("/llm", oapiReqValidator(ls.LLM())) + ls.HTTPMux.Handle("/segment-anything-2", oapiReqValidator(aiMediaServerHandle(ls, multipartDecoder[worker.GenSegmentAnything2MultipartRequestBody], processSegmentAnything2))) + ls.HTTPMux.Handle("/image-to-text", oapiReqValidator(aiMediaServerHandle(ls, multipartDecoder[worker.GenImageToTextMultipartRequestBody], processImageToText))) + ls.HTTPMux.Handle("/text-to-speech", oapiReqValidator(aiMediaServerHandle(ls, jsonDecoder[worker.GenTextToSpeechJSONRequestBody], processTextToSpeech))) + + // This is called by the media server when the stream is ready + ls.HTTPMux.Handle("/live/video-to-video/start", ls.StartLiveVideo()) + + return nil +} + +func aiMediaServerHandle[I, O any](ls *LivepeerServer, decoderFunc func(*I, *http.Request) error, processorFunc func(context.Context, aiRequestParams, I) (O, error)) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + remoteAddr := getRemoteAddr(r) + ctx := clog.AddVal(r.Context(), clog.ClientIP, remoteAddr) + requestID := string(core.RandomManifestID()) + ctx = clog.AddVal(ctx, "request_id", requestID) + + params := aiRequestParams{ + node: ls.LivepeerNode, + os: drivers.NodeStorage.NewSession(requestID), + sessManager: ls.AISessionManager, + } + + var req I + if err := decoderFunc(&req, r); err != nil { + respondJsonError(ctx, w, err, http.StatusBadRequest) + return + } + + resp, err := processorFunc(ctx, params, req) + if err != nil { + var serviceUnavailableErr *ServiceUnavailableError + var badRequestErr *BadRequestError + if errors.As(err, &serviceUnavailableErr) { + respondJsonError(ctx, w, err, http.StatusServiceUnavailable) + return + } + if errors.As(err, &badRequestErr) { + respondJsonError(ctx, w, err, http.StatusBadRequest) + return + } + respondJsonError(ctx, w, err, http.StatusInternalServerError) + return + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + _ = json.NewEncoder(w).Encode(resp) + }) +} + +func (ls *LivepeerServer) ImageToVideo() http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + remoteAddr := getRemoteAddr(r) + ctx := clog.AddVal(r.Context(), clog.ClientIP, remoteAddr) + requestID := string(core.RandomManifestID()) + ctx = clog.AddVal(ctx, "request_id", requestID) + + multiRdr, err := r.MultipartReader() + if err != nil { + respondJsonError(ctx, w, err, http.StatusBadRequest) + return + } + + var req worker.GenImageToVideoMultipartRequestBody + if err := runtime.BindMultipart(&req, *multiRdr); err != nil { + respondJsonError(ctx, w, err, http.StatusBadRequest) + return + } + + var async bool + prefer := r.Header.Get("Prefer") + if prefer == "respond-async" { + async = true + } + + clog.V(common.VERBOSE).Infof(ctx, "Received ImageToVideo request imageSize=%v model_id=%v async=%v", req.Image.FileSize(), *req.ModelId, async) + + params := aiRequestParams{ + node: ls.LivepeerNode, + os: drivers.NodeStorage.NewSession(requestID), + sessManager: ls.AISessionManager, + } + + if !async { + start := time.Now() + + resp, err := processImageToVideo(ctx, params, req) + if err != nil { + var serviceUnavailableErr *ServiceUnavailableError + var badRequestErr *BadRequestError + if errors.As(err, &serviceUnavailableErr) { + respondJsonError(ctx, w, err, http.StatusServiceUnavailable) + return + } + if errors.As(err, &badRequestErr) { + respondJsonError(ctx, w, err, http.StatusBadRequest) + return + } + respondJsonError(ctx, w, err, http.StatusInternalServerError) + return + } + + took := time.Since(start) + clog.Infof(ctx, "Processed ImageToVideo request imageSize=%v model_id=%v took=%v", req.Image.FileSize(), *req.ModelId, took) + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + _ = json.NewEncoder(w).Encode(resp) + return + } + + var data bytes.Buffer + if err := json.NewEncoder(&data).Encode(req); err != nil { + respondJsonError(ctx, w, err, http.StatusInternalServerError) + return + } + + path, err := params.os.SaveData(ctx, "request.json", bytes.NewReader(data.Bytes()), nil, 0) + if err != nil { + respondJsonError(ctx, w, err, http.StatusInternalServerError) + return + } + + clog.Infof(ctx, "Saved ImageToVideo request path=%v", requestID, path) + + cctx := clog.Clone(context.Background(), ctx) + go func(ctx context.Context) { + start := time.Now() + + var data bytes.Buffer + resp, err := processImageToVideo(ctx, params, req) + if err != nil { + clog.Errorf(ctx, "Error processing ImageToVideo request err=%v", err) + + handleAPIError(ctx, &data, err, http.StatusInternalServerError) + } else { + took := time.Since(start) + clog.Infof(ctx, "Processed ImageToVideo request imageSize=%v model_id=%v took=%v", req.Image.FileSize(), *req.ModelId, took) + + if err := json.NewEncoder(&data).Encode(resp); err != nil { + clog.Errorf(ctx, "Error JSON encoding ImageToVideo response err=%v", err) + return + } + } + + path, err := params.os.SaveData(ctx, "result.json", bytes.NewReader(data.Bytes()), nil, 0) + if err != nil { + clog.Errorf(ctx, "Error saving ImageToVideo result to object store err=%v", err) + return + } + + clog.Infof(ctx, "Saved ImageToVideo result path=%v", path) + }(cctx) + + resp := &ImageToVideoResponseAsync{ + RequestID: requestID, + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusAccepted) + _ = json.NewEncoder(w).Encode(resp) + }) +} + +func (ls *LivepeerServer) LLM() http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + remoteAddr := getRemoteAddr(r) + ctx := clog.AddVal(r.Context(), clog.ClientIP, remoteAddr) + requestID := string(core.RandomManifestID()) + ctx = clog.AddVal(ctx, "request_id", requestID) + + var req worker.GenLLMFormdataRequestBody + + multiRdr, err := r.MultipartReader() + if err != nil { + respondJsonError(ctx, w, err, http.StatusBadRequest) + return + } + + if err := runtime.BindMultipart(&req, *multiRdr); err != nil { + respondJsonError(ctx, w, err, http.StatusBadRequest) + return + } + + clog.V(common.VERBOSE).Infof(ctx, "Received LLM request prompt=%v model_id=%v stream=%v", req.Prompt, *req.ModelId, *req.Stream) + + params := aiRequestParams{ + node: ls.LivepeerNode, + os: drivers.NodeStorage.NewSession(requestID), + sessManager: ls.AISessionManager, + } + + start := time.Now() + resp, err := processLLM(ctx, params, req) + if err != nil { + var e *ServiceUnavailableError + if errors.As(err, &e) { + respondJsonError(ctx, w, err, http.StatusServiceUnavailable) + return + } + respondJsonError(ctx, w, err, http.StatusInternalServerError) + return + } + + took := time.Since(start) + clog.V(common.VERBOSE).Infof(ctx, "Processed LLM request prompt=%v model_id=%v took=%v", req.Prompt, *req.ModelId, took) + + if streamChan, ok := resp.(chan worker.LlmStreamChunk); ok { + // Handle streaming response (SSE) + w.Header().Set("Content-Type", "text/event-stream") + w.Header().Set("Cache-Control", "no-cache") + w.Header().Set("Connection", "keep-alive") + + for chunk := range streamChan { + data, _ := json.Marshal(chunk) + fmt.Fprintf(w, "data: %s\n\n", data) + w.(http.Flusher).Flush() + if chunk.Done { + break + } + } + } else if llmResp, ok := resp.(*worker.LLMResponse); ok { + // Handle non-streaming response + w.Header().Set("Content-Type", "application/json") + json.NewEncoder(w).Encode(llmResp) + } else { + http.Error(w, "Unexpected response type", http.StatusInternalServerError) + } + }) +} + +func (ls *LivepeerServer) ImageToVideoResult() http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + remoteAddr := getRemoteAddr(r) + ctx := clog.AddVal(r.Context(), clog.ClientIP, remoteAddr) + + var req ImageToVideoResultRequest + if err := json.NewDecoder(r.Body).Decode(&req); err != nil { + respondJsonError(ctx, w, err, http.StatusBadRequest) + return + } + + ctx = clog.AddVal(ctx, "request_id", req.RequestID) + + clog.V(common.VERBOSE).Infof(ctx, "Received ImageToVideoResult request request_id=%v", req.RequestID) + + sess := drivers.NodeStorage.NewSession(req.RequestID) + + _, err := sess.ReadData(ctx, "request.json") + if err != nil { + respondJsonError(ctx, w, errors.New("invalid request ID"), http.StatusBadRequest) + return + } + + resp := ImageToVideoResultResponse{ + Status: Processing, + } + + reader, err := sess.ReadData(ctx, "result.json") + if err != nil { + // TODO: Distinguish between error reading data vs. file DNE + // Right now we assume that this file will exist when processing is done even + // if an error was encountered + w.WriteHeader(http.StatusAccepted) + _ = json.NewEncoder(w).Encode(resp) + return + } + + resp.Status = Complete + + if err := json.NewDecoder(reader.Body).Decode(&resp.Result); err != nil { + respondJsonError(ctx, w, err, http.StatusInternalServerError) + return + } + + w.WriteHeader(http.StatusOK) + _ = json.NewEncoder(w).Encode(resp) + }) +} + +func (ls *LivepeerServer) StartLiveVideo() http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + streamName := r.FormValue("stream") + if streamName == "" { + http.Error(w, "Missing stream name", http.StatusBadRequest) + return + } + requestID := string(core.RandomManifestID()) + ctx := clog.AddVal(r.Context(), "request_id", requestID) + clog.Infof(ctx, "Received live video AI request for %s", streamName) + + // Kick off the RTMP pull and segmentation as soon as possible + ssr := media.NewSwitchableSegmentReader() + go func() { + ms := media.MediaSegmenter{Workdir: ls.LivepeerNode.WorkDir} + ms.RunSegmentation("rtmp://localhost/"+streamName, ssr.Read) + ssr.Close() + }() + + params := aiRequestParams{ + node: ls.LivepeerNode, + os: drivers.NodeStorage.NewSession(requestID), + sessManager: ls.AISessionManager, + segmentReader: ssr, + } + + req := worker.GenLiveVideoToVideoJSONRequestBody{ + // TODO set model and initial parameters here if necessary (eg, prompt) + } + processAIRequest(ctx, params, req) + }) +} diff --git a/server/ai_process.go b/server/ai_process.go new file mode 100644 index 0000000000..f5329910e5 --- /dev/null +++ b/server/ai_process.go @@ -0,0 +1,1539 @@ +package server + +import ( + "bufio" + "bytes" + "context" + "encoding/json" + "errors" + "fmt" + "image" + "io" + "math" + "math/big" + "net/http" + "net/url" + "path/filepath" + "strconv" + "strings" + "time" + + "github.com/livepeer/ai-worker/worker" + "github.com/livepeer/go-livepeer/clog" + "github.com/livepeer/go-livepeer/common" + "github.com/livepeer/go-livepeer/core" + "github.com/livepeer/go-livepeer/media" + "github.com/livepeer/go-livepeer/monitor" + "github.com/livepeer/go-tools/drivers" + "github.com/livepeer/lpms/stream" +) + +const processingRetryTimeout = 2 * time.Second +const defaultTextToImageModelID = "stabilityai/sdxl-turbo" +const defaultImageToImageModelID = "stabilityai/sdxl-turbo" +const defaultImageToVideoModelID = "stabilityai/stable-video-diffusion-img2vid-xt" +const defaultUpscaleModelID = "stabilityai/stable-diffusion-x4-upscaler" +const defaultAudioToTextModelID = "openai/whisper-large-v3" +const defaultLLMModelID = "meta-llama/llama-3.1-8B-Instruct" +const defaultSegmentAnything2ModelID = "facebook/sam2-hiera-large" +const defaultImageToTextModelID = "Salesforce/blip-image-captioning-large" +const defaultLiveVideoToVideoModelID = "cumulo-autumn/stream-diffusion" +const defaultTextToSpeechModelID = "parler-tts/parler-tts-large-v1" + +var errWrongFormat = fmt.Errorf("result not in correct format") + +type ServiceUnavailableError struct { + err error +} + +func (e *ServiceUnavailableError) Error() string { + return e.err.Error() +} + +type BadRequestError struct { + err error +} + +func (e *BadRequestError) Error() string { + return e.err.Error() +} + +// parseBadRequestError checks if the error is a bad request error and returns a BadRequestError. +func parseBadRequestError(err error) *BadRequestError { + if err == nil { + return nil + } + if err, ok := err.(*BadRequestError); ok { + return err + } + + const errorCode = "returned 400" + if !strings.Contains(err.Error(), errorCode) { + return nil + } + + parts := strings.SplitN(err.Error(), errorCode, 2) + detail := strings.TrimSpace(parts[1]) + if detail == "" { + detail = "bad request" + } + + return &BadRequestError{err: errors.New(detail)} +} + +type aiRequestParams struct { + node *core.LivepeerNode + os drivers.OSSession + sessManager *AISessionManager + + // For live video pipelines + segmentReader *media.SwitchableSegmentReader +} + +// CalculateTextToImageLatencyScore computes the time taken per pixel for an text-to-image request. +func CalculateTextToImageLatencyScore(took time.Duration, req worker.GenTextToImageJSONRequestBody, outPixels int64) float64 { + if outPixels <= 0 { + return 0 + } + + // TODO: Default values for the number of inference steps is currently hardcoded. + // These should be managed by the nethttpmiddleware. Refer to issue LIV-412 for more details. + numInferenceSteps := float64(50) + if req.NumInferenceSteps != nil { + numInferenceSteps = math.Max(1, float64(*req.NumInferenceSteps)) + } + // Handle special case for SDXL-Lightning model. + if strings.HasPrefix(*req.ModelId, "ByteDance/SDXL-Lightning") { + numInferenceSteps = math.Max(1, core.ParseStepsFromModelID(req.ModelId, 8)) + } + + return took.Seconds() / float64(outPixels) / numInferenceSteps +} + +func processTextToImage(ctx context.Context, params aiRequestParams, req worker.GenTextToImageJSONRequestBody) (*worker.ImageResponse, error) { + resp, err := processAIRequest(ctx, params, req) + if err != nil { + return nil, err + } + + imgResp, ok := resp.(*worker.ImageResponse) + if !ok { + return nil, errWrongFormat + } + + newMedia := make([]worker.Media, len(imgResp.Images)) + for i, media := range imgResp.Images { + var result []byte + var data bytes.Buffer + var name string + writer := bufio.NewWriter(&data) + err := worker.ReadImageB64DataUrl(media.Url, writer) + if err == nil { + // orchestrator sent base64 encoded result in .Url + name = string(core.RandomManifestID()) + ".png" + writer.Flush() + result = data.Bytes() + } else { + // orchestrator sent download url, get the data + name = filepath.Base(media.Url) + result, err = core.DownloadData(ctx, media.Url) + if err != nil { + return nil, err + } + } + + newUrl, err := params.os.SaveData(ctx, name, bytes.NewReader(result), nil, 0) + + if err != nil { + return nil, fmt.Errorf("error saving image to objectStore: %w", err) + } + + newMedia[i] = worker.Media{Nsfw: media.Nsfw, Seed: media.Seed, Url: newUrl} + } + + imgResp.Images = newMedia + + return imgResp, nil +} + +func submitTextToImage(ctx context.Context, params aiRequestParams, sess *AISession, req worker.GenTextToImageJSONRequestBody) (*worker.ImageResponse, error) { + client, err := worker.NewClientWithResponses(sess.Transcoder(), worker.WithHTTPClient(httpClient)) + + if err != nil { + if monitor.Enabled { + monitor.AIRequestError(err.Error(), "text-to-image", *req.ModelId, sess.OrchestratorInfo) + } + return nil, err + } + + if req.Height == nil { + req.Height = new(int) + *req.Height = 512 + } + if req.Width == nil { + req.Width = new(int) + *req.Width = 512 + } + + // TODO: Default values for the number of images is currently hardcoded. + // These should be managed by the nethttpmiddleware. Refer to issue LIV-412 for more details. + defaultNumImages := 1 + if req.NumImagesPerPrompt == nil { + req.NumImagesPerPrompt = &defaultNumImages + } else { + *req.NumImagesPerPrompt = int(math.Max(1, float64(*req.NumImagesPerPrompt))) + } + + outPixels := int64(*req.Height) * int64(*req.Width) * int64(*req.NumImagesPerPrompt) + + setHeaders, balUpdate, err := prepareAIPayment(ctx, sess, outPixels) + if err != nil { + if monitor.Enabled { + monitor.AIRequestError(err.Error(), "text-to-image", *req.ModelId, sess.OrchestratorInfo) + } + return nil, err + } + defer completeBalanceUpdate(sess.BroadcastSession, balUpdate) + + start := time.Now() + resp, err := client.GenTextToImageWithResponse(ctx, req, setHeaders) + took := time.Since(start) + + // TODO: Refine this rough estimate in future iterations. + sess.LatencyScore = CalculateTextToImageLatencyScore(took, req, outPixels) + + if err != nil { + if monitor.Enabled { + monitor.AIRequestError(err.Error(), "text-to-image", *req.ModelId, sess.OrchestratorInfo) + } + return nil, err + } + + if resp.JSON200 == nil { + // TODO: Replace trim newline with better error spec from O + return nil, errors.New(strings.TrimSuffix(string(resp.Body), "\n")) + } + + // We treat a response as "receiving change" where the change is the difference between the credit and debit for the update + if balUpdate != nil { + balUpdate.Status = ReceivedChange + } + + if monitor.Enabled { + var pricePerAIUnit float64 + if priceInfo := sess.OrchestratorInfo.GetPriceInfo(); priceInfo != nil && priceInfo.PixelsPerUnit != 0 { + pricePerAIUnit = float64(priceInfo.PricePerUnit) / float64(priceInfo.PixelsPerUnit) + } + + monitor.AIRequestFinished(ctx, "text-to-image", *req.ModelId, monitor.AIJobInfo{LatencyScore: sess.LatencyScore, PricePerUnit: pricePerAIUnit}, sess.OrchestratorInfo) + } + + return resp.JSON200, nil +} + +// CalculateImageToImageLatencyScore computes the time taken per pixel for an image-to-image request. +func CalculateImageToImageLatencyScore(took time.Duration, req worker.GenImageToImageMultipartRequestBody, outPixels int64) float64 { + if outPixels <= 0 { + return 0 + } + + // TODO: Default values for the number of inference steps is currently hardcoded. + // These should be managed by the nethttpmiddleware. Refer to issue LIV-412 for more details. + numInferenceSteps := float64(100) + if req.NumInferenceSteps != nil { + numInferenceSteps = math.Max(1, float64(*req.NumInferenceSteps)) + } + // Handle special case for SDXL-Lightning model. + if strings.HasPrefix(*req.ModelId, "ByteDance/SDXL-Lightning") { + numInferenceSteps = math.Max(1, core.ParseStepsFromModelID(req.ModelId, 8)) + } + + return took.Seconds() / float64(outPixels) / numInferenceSteps +} + +func processImageToImage(ctx context.Context, params aiRequestParams, req worker.GenImageToImageMultipartRequestBody) (*worker.ImageResponse, error) { + resp, err := processAIRequest(ctx, params, req) + if err != nil { + return nil, err + } + + imgResp, ok := resp.(*worker.ImageResponse) + if !ok { + return nil, errWrongFormat + } + + newMedia := make([]worker.Media, len(imgResp.Images)) + for i, media := range imgResp.Images { + var result []byte + var data bytes.Buffer + var name string + writer := bufio.NewWriter(&data) + err := worker.ReadImageB64DataUrl(media.Url, writer) + if err == nil { + // orchestrator sent bae64 encoded result in .Url + name = string(core.RandomManifestID()) + ".png" + writer.Flush() + result = data.Bytes() + } else { + // orchestrator sent download url, get the data + name = filepath.Base(media.Url) + result, err = core.DownloadData(ctx, media.Url) + if err != nil { + return nil, err + } + } + + newUrl, err := params.os.SaveData(ctx, name, bytes.NewReader(result), nil, 0) + if err != nil { + return nil, fmt.Errorf("error saving image to objectStore: %w", err) + } + + newMedia[i] = worker.Media{Nsfw: media.Nsfw, Seed: media.Seed, Url: newUrl} + } + + imgResp.Images = newMedia + + return imgResp, nil +} + +func submitImageToImage(ctx context.Context, params aiRequestParams, sess *AISession, req worker.GenImageToImageMultipartRequestBody) (*worker.ImageResponse, error) { + // TODO: Default values for the number of images is currently hardcoded. + // These should be managed by the nethttpmiddleware. Refer to issue LIV-412 for more details. + defaultNumImages := 1 + if req.NumImagesPerPrompt == nil { + req.NumImagesPerPrompt = &defaultNumImages + } else { + *req.NumImagesPerPrompt = int(math.Max(1, float64(*req.NumImagesPerPrompt))) + } + + var buf bytes.Buffer + mw, err := worker.NewImageToImageMultipartWriter(&buf, req) + if err != nil { + if monitor.Enabled { + monitor.AIRequestError(err.Error(), "image-to-image", *req.ModelId, sess.OrchestratorInfo) + } + return nil, err + } + + client, err := worker.NewClientWithResponses(sess.Transcoder(), worker.WithHTTPClient(httpClient)) + if err != nil { + if monitor.Enabled { + monitor.AIRequestError(err.Error(), "image-to-image", *req.ModelId, sess.OrchestratorInfo) + } + return nil, err + } + + imageRdr, err := req.Image.Reader() + if err != nil { + if monitor.Enabled { + monitor.AIRequestError(err.Error(), "image-to-image", *req.ModelId, sess.OrchestratorInfo) + } + return nil, err + } + config, _, err := image.DecodeConfig(imageRdr) + if err != nil { + if monitor.Enabled { + monitor.AIRequestError(err.Error(), "image-to-image", *req.ModelId, sess.OrchestratorInfo) + } + return nil, err + } + + outPixels := int64(config.Height) * int64(config.Width) * int64(*req.NumImagesPerPrompt) + + setHeaders, balUpdate, err := prepareAIPayment(ctx, sess, outPixels) + if err != nil { + if monitor.Enabled { + monitor.AIRequestError(err.Error(), "image-to-image", *req.ModelId, sess.OrchestratorInfo) + } + return nil, err + } + defer completeBalanceUpdate(sess.BroadcastSession, balUpdate) + + start := time.Now() + resp, err := client.GenImageToImageWithBodyWithResponse(ctx, mw.FormDataContentType(), &buf, setHeaders) + took := time.Since(start) + + // TODO: Refine this rough estimate in future iterations. + sess.LatencyScore = CalculateImageToImageLatencyScore(took, req, outPixels) + + if err != nil { + if monitor.Enabled { + monitor.AIRequestError(err.Error(), "image-to-image", *req.ModelId, sess.OrchestratorInfo) + } + return nil, err + } + + if resp.JSON200 == nil { + // TODO: Replace trim newline with better error spec from O + return nil, errors.New(strings.TrimSuffix(string(resp.Body), "\n")) + } + + // We treat a response as "receiving change" where the change is the difference between the credit and debit for the update + if balUpdate != nil { + balUpdate.Status = ReceivedChange + } + + if monitor.Enabled { + var pricePerAIUnit float64 + if priceInfo := sess.OrchestratorInfo.GetPriceInfo(); priceInfo != nil && priceInfo.PixelsPerUnit != 0 { + pricePerAIUnit = float64(priceInfo.PricePerUnit) / float64(priceInfo.PixelsPerUnit) + } + + monitor.AIRequestFinished(ctx, "image-to-image", *req.ModelId, monitor.AIJobInfo{LatencyScore: sess.LatencyScore, PricePerUnit: pricePerAIUnit}, sess.OrchestratorInfo) + } + + return resp.JSON200, nil +} + +// CalculateImageToVideoLatencyScore computes the time taken per pixel for an image-to-video request. +func CalculateImageToVideoLatencyScore(took time.Duration, req worker.GenImageToVideoMultipartRequestBody, outPixels int64) float64 { + if outPixels <= 0 { + return 0 + } + + // TODO: Default values for the number of inference steps is currently hardcoded. + // These should be managed by the nethttpmiddleware. Refer to issue LIV-412 for more details. + numInferenceSteps := float64(25) + if req.NumInferenceSteps != nil { + numInferenceSteps = math.Max(1, float64(*req.NumInferenceSteps)) + } + + return took.Seconds() / float64(outPixels) / numInferenceSteps +} + +func processImageToVideo(ctx context.Context, params aiRequestParams, req worker.GenImageToVideoMultipartRequestBody) (*worker.ImageResponse, error) { + resp, err := processAIRequest(ctx, params, req) + if err != nil { + return nil, err + } + + // HACK: Re-use worker.ImageResponse to return results + // TODO: Refactor to return worker.VideoResponse + imgResp, ok := resp.(*worker.ImageResponse) + if !ok { + return nil, errWrongFormat + } + + videos := make([]worker.Media, len(imgResp.Images)) + for i, media := range imgResp.Images { + data, err := core.DownloadData(ctx, media.Url) + if err != nil { + return nil, err + } + + name := filepath.Base(media.Url) + newUrl, err := params.os.SaveData(ctx, name, bytes.NewReader(data), nil, 0) + if err != nil { + return nil, fmt.Errorf("error saving video to objectStore: %w", err) + } + + videos[i] = worker.Media{ + Nsfw: media.Nsfw, + Seed: media.Seed, + Url: newUrl, + } + + } + + imgResp.Images = videos + + return imgResp, nil +} + +func submitImageToVideo(ctx context.Context, params aiRequestParams, sess *AISession, req worker.GenImageToVideoMultipartRequestBody) (*worker.ImageResponse, error) { + var buf bytes.Buffer + mw, err := worker.NewImageToVideoMultipartWriter(&buf, req) + if err != nil { + if monitor.Enabled { + monitor.AIRequestError(err.Error(), "image-to-video", *req.ModelId, sess.OrchestratorInfo) + } + return nil, err + } + + client, err := worker.NewClientWithResponses(sess.Transcoder(), worker.WithHTTPClient(httpClient)) + if err != nil { + if monitor.Enabled { + monitor.AIRequestError(err.Error(), "image-to-video", *req.ModelId, sess.OrchestratorInfo) + } + return nil, err + } + + if req.Height == nil { + req.Height = new(int) + *req.Height = 576 + } + if req.Width == nil { + req.Width = new(int) + *req.Width = 1024 + } + frames := int64(25) + + outPixels := int64(*req.Height) * int64(*req.Width) * frames + setHeaders, balUpdate, err := prepareAIPayment(ctx, sess, outPixels) + if err != nil { + if monitor.Enabled { + monitor.AIRequestError(err.Error(), "image-to-video", *req.ModelId, sess.OrchestratorInfo) + } + return nil, err + } + defer completeBalanceUpdate(sess.BroadcastSession, balUpdate) + + start := time.Now() + resp, err := client.GenImageToVideoWithBody(ctx, mw.FormDataContentType(), &buf, setHeaders) + took := time.Since(start) + if err != nil { + if monitor.Enabled { + monitor.AIRequestError(err.Error(), "image-to-video", *req.ModelId, sess.OrchestratorInfo) + } + return nil, err + } + defer resp.Body.Close() + + data, err := io.ReadAll(resp.Body) + if err != nil { + if monitor.Enabled { + monitor.AIRequestError(err.Error(), "image-to-video", *req.ModelId, sess.OrchestratorInfo) + } + return nil, err + } + + if resp.StatusCode != 200 { + return nil, errors.New(string(data)) + } + + // We treat a response as "receiving change" where the change is the difference between the credit and debit for the update + if balUpdate != nil { + balUpdate.Status = ReceivedChange + } + + var res worker.ImageResponse + if err := json.Unmarshal(data, &res); err != nil { + if monitor.Enabled { + monitor.AIRequestError(err.Error(), "image-to-video", *req.ModelId, sess.OrchestratorInfo) + } + return nil, err + } + + // TODO: Refine this rough estimate in future iterations + sess.LatencyScore = CalculateImageToVideoLatencyScore(took, req, outPixels) + + if monitor.Enabled { + var pricePerAIUnit float64 + if priceInfo := sess.OrchestratorInfo.GetPriceInfo(); priceInfo != nil && priceInfo.PixelsPerUnit != 0 { + pricePerAIUnit = float64(priceInfo.PricePerUnit) / float64(priceInfo.PixelsPerUnit) + } + + monitor.AIRequestFinished(ctx, "image-to-video", *req.ModelId, monitor.AIJobInfo{LatencyScore: sess.LatencyScore, PricePerUnit: pricePerAIUnit}, sess.OrchestratorInfo) + } + + return &res, nil +} + +// CalculateUpscaleLatencyScore computes the time taken per pixel for an upscale request. +func CalculateUpscaleLatencyScore(took time.Duration, req worker.GenUpscaleMultipartRequestBody, outPixels int64) float64 { + if outPixels <= 0 { + return 0 + } + + // TODO: Default values for the number of inference steps is currently hardcoded. + // These should be managed by the nethttpmiddleware. Refer to issue LIV-412 for more details. + numInferenceSteps := float64(75) + if req.NumInferenceSteps != nil { + numInferenceSteps = math.Max(1, float64(*req.NumInferenceSteps)) + } + + return took.Seconds() / float64(outPixels) / numInferenceSteps +} + +func processUpscale(ctx context.Context, params aiRequestParams, req worker.GenUpscaleMultipartRequestBody) (*worker.ImageResponse, error) { + resp, err := processAIRequest(ctx, params, req) + if err != nil { + return nil, err + } + + imgResp, ok := resp.(*worker.ImageResponse) + if !ok { + return nil, errWrongFormat + } + + newMedia := make([]worker.Media, len(imgResp.Images)) + for i, media := range imgResp.Images { + var result []byte + var data bytes.Buffer + var name string + writer := bufio.NewWriter(&data) + err := worker.ReadImageB64DataUrl(media.Url, writer) + if err == nil { + // orchestrator sent bae64 encoded result in .Url + name = string(core.RandomManifestID()) + ".png" + writer.Flush() + result = data.Bytes() + } else { + // orchestrator sent download url, get the data + name = filepath.Base(media.Url) + result, err = core.DownloadData(ctx, media.Url) + if err != nil { + return nil, err + } + } + + newUrl, err := params.os.SaveData(ctx, name, bytes.NewReader(result), nil, 0) + if err != nil { + return nil, fmt.Errorf("error saving image to objectStore: %w", err) + } + + newMedia[i] = worker.Media{Nsfw: media.Nsfw, Seed: media.Seed, Url: newUrl} + } + + imgResp.Images = newMedia + + return imgResp, nil +} + +func submitUpscale(ctx context.Context, params aiRequestParams, sess *AISession, req worker.GenUpscaleMultipartRequestBody) (*worker.ImageResponse, error) { + var buf bytes.Buffer + mw, err := worker.NewUpscaleMultipartWriter(&buf, req) + if err != nil { + if monitor.Enabled { + monitor.AIRequestError(err.Error(), "upscale", *req.ModelId, sess.OrchestratorInfo) + } + return nil, err + } + + client, err := worker.NewClientWithResponses(sess.Transcoder(), worker.WithHTTPClient(httpClient)) + if err != nil { + if monitor.Enabled { + monitor.AIRequestError(err.Error(), "upscale", *req.ModelId, sess.OrchestratorInfo) + } + return nil, err + } + + imageRdr, err := req.Image.Reader() + if err != nil { + if monitor.Enabled { + monitor.AIRequestError(err.Error(), "upscale", *req.ModelId, sess.OrchestratorInfo) + } + return nil, err + } + config, _, err := image.DecodeConfig(imageRdr) + if err != nil { + if monitor.Enabled { + monitor.AIRequestError(err.Error(), "upscale", *req.ModelId, sess.OrchestratorInfo) + } + return nil, err + } + outPixels := int64(config.Height) * int64(config.Width) + + setHeaders, balUpdate, err := prepareAIPayment(ctx, sess, outPixels) + if err != nil { + if monitor.Enabled { + monitor.AIRequestError(err.Error(), "upscale", *req.ModelId, sess.OrchestratorInfo) + } + return nil, err + } + defer completeBalanceUpdate(sess.BroadcastSession, balUpdate) + + start := time.Now() + resp, err := client.GenUpscaleWithBodyWithResponse(ctx, mw.FormDataContentType(), &buf, setHeaders) + took := time.Since(start) + if err != nil { + if monitor.Enabled { + monitor.AIRequestError(err.Error(), "upscale", *req.ModelId, sess.OrchestratorInfo) + } + return nil, err + } + + if resp.JSON200 == nil { + // TODO: Replace trim newline with better error spec from O + return nil, errors.New(strings.TrimSuffix(string(resp.Body), "\n")) + } + + // We treat a response as "receiving change" where the change is the difference between the credit and debit for the update + if balUpdate != nil { + balUpdate.Status = ReceivedChange + } + + // TODO: Refine this rough estimate in future iterations + sess.LatencyScore = CalculateUpscaleLatencyScore(took, req, outPixels) + + if monitor.Enabled { + var pricePerAIUnit float64 + if priceInfo := sess.OrchestratorInfo.GetPriceInfo(); priceInfo != nil && priceInfo.PixelsPerUnit != 0 { + pricePerAIUnit = float64(priceInfo.PricePerUnit) / float64(priceInfo.PixelsPerUnit) + } + + monitor.AIRequestFinished(ctx, "upscale", *req.ModelId, monitor.AIJobInfo{LatencyScore: sess.LatencyScore, PricePerUnit: pricePerAIUnit}, sess.OrchestratorInfo) + } + + return resp.JSON200, nil +} + +// CalculateSegmentAnything2LatencyScore computes the time taken per pixel for a segment-anything-2 request. +func CalculateSegmentAnything2LatencyScore(took time.Duration, outPixels int64) float64 { + if outPixels <= 0 { + return 0 + } + + return took.Seconds() / float64(outPixels) +} + +func processSegmentAnything2(ctx context.Context, params aiRequestParams, req worker.GenSegmentAnything2MultipartRequestBody) (*worker.MasksResponse, error) { + resp, err := processAIRequest(ctx, params, req) + if err != nil { + return nil, err + } + + txtResp := resp.(*worker.MasksResponse) + + return txtResp, nil +} + +func submitSegmentAnything2(ctx context.Context, params aiRequestParams, sess *AISession, req worker.GenSegmentAnything2MultipartRequestBody) (*worker.MasksResponse, error) { + var buf bytes.Buffer + mw, err := worker.NewSegmentAnything2MultipartWriter(&buf, req) + if err != nil { + if monitor.Enabled { + monitor.AIRequestError(err.Error(), "segment-anything-2", *req.ModelId, sess.OrchestratorInfo) + } + return nil, err + } + + client, err := worker.NewClientWithResponses(sess.Transcoder(), worker.WithHTTPClient(httpClient)) + if err != nil { + if monitor.Enabled { + monitor.AIRequestError(err.Error(), "segment-anything-2", *req.ModelId, sess.OrchestratorInfo) + } + return nil, err + } + + imageRdr, err := req.Image.Reader() + if err != nil { + if monitor.Enabled { + monitor.AIRequestError(err.Error(), "segment-anything-2", *req.ModelId, sess.OrchestratorInfo) + } + return nil, err + } + config, _, err := image.DecodeConfig(imageRdr) + if err != nil { + if monitor.Enabled { + monitor.AIRequestError(err.Error(), "segment-anything-2", *req.ModelId, sess.OrchestratorInfo) + } + return nil, err + } + outPixels := int64(config.Height) * int64(config.Width) + + setHeaders, balUpdate, err := prepareAIPayment(ctx, sess, outPixels) + if err != nil { + if monitor.Enabled { + monitor.AIRequestError(err.Error(), "segment-anything-2", *req.ModelId, sess.OrchestratorInfo) + } + return nil, err + } + defer completeBalanceUpdate(sess.BroadcastSession, balUpdate) + + start := time.Now() + resp, err := client.GenSegmentAnything2WithBodyWithResponse(ctx, mw.FormDataContentType(), &buf, setHeaders) + took := time.Since(start) + if err != nil { + if monitor.Enabled { + monitor.AIRequestError(err.Error(), "segment-anything-2", *req.ModelId, sess.OrchestratorInfo) + } + return nil, err + } + + if resp.JSON200 == nil { + // TODO: Replace trim newline with better error spec from O + return nil, errors.New(strings.TrimSuffix(string(resp.Body), "\n")) + } + + // We treat a response as "receiving change" where the change is the difference between the credit and debit for the update + if balUpdate != nil { + balUpdate.Status = ReceivedChange + } + + // TODO: Refine this rough estimate in future iterations + sess.LatencyScore = CalculateSegmentAnything2LatencyScore(took, outPixels) + + if monitor.Enabled { + var pricePerAIUnit float64 + if priceInfo := sess.OrchestratorInfo.GetPriceInfo(); priceInfo != nil && priceInfo.PixelsPerUnit != 0 { + pricePerAIUnit = float64(priceInfo.PricePerUnit) / float64(priceInfo.PixelsPerUnit) + } + + monitor.AIRequestFinished(ctx, "segment-anything-2", *req.ModelId, monitor.AIJobInfo{LatencyScore: sess.LatencyScore, PricePerUnit: pricePerAIUnit}, sess.OrchestratorInfo) + } + + return resp.JSON200, nil +} + +// CalculateTextToSpeechLatencyScore computes the time taken per character for a TextToSpeech request. +func CalculateTextToSpeechLatencyScore(took time.Duration, inCharacters int64) float64 { + if inCharacters <= 0 { + return 0 + } + + return took.Seconds() / float64(inCharacters) +} + +func processTextToSpeech(ctx context.Context, params aiRequestParams, req worker.GenTextToSpeechJSONRequestBody) (*worker.AudioResponse, error) { + resp, err := processAIRequest(ctx, params, req) + if err != nil { + return nil, err + } + + audioResp, ok := resp.(*worker.AudioResponse) + if !ok { + return nil, errWrongFormat + } + + var result []byte + var data bytes.Buffer + var name string + writer := bufio.NewWriter(&data) + err = worker.ReadAudioB64DataUrl(audioResp.Audio.Url, writer) + if err == nil { + // orchestrator sent bae64 encoded result in .Url + name = string(core.RandomManifestID()) + ".wav" + writer.Flush() + result = data.Bytes() + } else { + // orchestrator sent download url, get the data + name = filepath.Base(audioResp.Audio.Url) + result, err = core.DownloadData(ctx, audioResp.Audio.Url) + if err != nil { + return nil, err + } + } + + newUrl, err := params.os.SaveData(ctx, name, bytes.NewReader(result), nil, 0) + if err != nil { + return nil, fmt.Errorf("error saving image to objectStore: %w", err) + } + + audioResp.Audio.Url = newUrl + return audioResp, nil +} + +func submitTextToSpeech(ctx context.Context, params aiRequestParams, sess *AISession, req worker.GenTextToSpeechJSONRequestBody) (*worker.AudioResponse, error) { + client, err := worker.NewClientWithResponses(sess.Transcoder(), worker.WithHTTPClient(httpClient)) + if err != nil { + if monitor.Enabled { + monitor.AIRequestError(err.Error(), "text-to-speech", *req.ModelId, sess.OrchestratorInfo) + } + return nil, err + } + + if req.Text == nil { + return nil, &BadRequestError{errors.New("text field is required")} + } + + textLength := len(*req.Text) + clog.V(common.VERBOSE).Infof(ctx, "Submitting text-to-speech request with text length: %d", textLength) + inCharacters := int64(textLength) + setHeaders, balUpdate, err := prepareAIPayment(ctx, sess, inCharacters) + if err != nil { + if monitor.Enabled { + monitor.AIRequestError(err.Error(), "text-to-speech", *req.ModelId, sess.OrchestratorInfo) + } + return nil, err + } + defer completeBalanceUpdate(sess.BroadcastSession, balUpdate) + + start := time.Now() + resp, err := client.GenTextToSpeechWithResponse(ctx, req, setHeaders) + took := time.Since(start) + if err != nil { + if monitor.Enabled { + monitor.AIRequestError(err.Error(), "text-to-speech", *req.ModelId, sess.OrchestratorInfo) + } + return nil, err + } + + if resp.JSON200 == nil { + // TODO: Replace trim newline with better error spec from O + return nil, errors.New(strings.TrimSuffix(string(resp.Body), "\n")) + } + + // We treat a response as "receiving change" where the change is the difference between the credit and debit for the update + if balUpdate != nil { + balUpdate.Status = ReceivedChange + } + + // TODO: Refine this rough estimate in future iterations + sess.LatencyScore = CalculateSegmentAnything2LatencyScore(took, inCharacters) + + if monitor.Enabled { + var pricePerAIUnit float64 + if priceInfo := sess.OrchestratorInfo.GetPriceInfo(); priceInfo != nil && priceInfo.PixelsPerUnit != 0 { + pricePerAIUnit = float64(priceInfo.PricePerUnit) / float64(priceInfo.PixelsPerUnit) + } + + monitor.AIRequestFinished(ctx, "text-to-speech", *req.ModelId, monitor.AIJobInfo{LatencyScore: sess.LatencyScore, PricePerUnit: pricePerAIUnit}, sess.OrchestratorInfo) + } + + var res worker.AudioResponse + if err := json.Unmarshal(resp.Body, &res); err != nil { + if monitor.Enabled { + monitor.AIRequestError(err.Error(), "text-to-speech", *req.ModelId, sess.OrchestratorInfo) + } + return nil, err + } + + return &res, nil +} + +// CalculateAudioToTextLatencyScore computes the time taken per second of audio for an audio-to-text request. +func CalculateAudioToTextLatencyScore(took time.Duration, durationSeconds int64) float64 { + if durationSeconds <= 0 { + return 0 + } + + return took.Seconds() / float64(durationSeconds) +} + +func processAudioToText(ctx context.Context, params aiRequestParams, req worker.GenAudioToTextMultipartRequestBody) (*worker.TextResponse, error) { + resp, err := processAIRequest(ctx, params, req) + if err != nil { + return nil, err + } + + txtResp, ok := resp.(*worker.TextResponse) + if !ok { + return nil, errWrongFormat + } + + return txtResp, nil +} + +func submitAudioToText(ctx context.Context, params aiRequestParams, sess *AISession, req worker.GenAudioToTextMultipartRequestBody) (*worker.TextResponse, error) { + durationSeconds, err := common.CalculateAudioDuration(req.Audio) + if err != nil { + if monitor.Enabled { + monitor.AIRequestError(err.Error(), "audio-to-text", *req.ModelId, sess.OrchestratorInfo) + } + return nil, err + } + + // Add the duration to the request via 'metadata' field. + metadata := map[string]string{ + "duration": strconv.Itoa(int(durationSeconds)), + } + metadataStr := encodeReqMetadata(metadata) + req.Metadata = &metadataStr + + var buf bytes.Buffer + mw, err := worker.NewAudioToTextMultipartWriter(&buf, req) + if err != nil { + if monitor.Enabled { + monitor.AIRequestError(err.Error(), "audio-to-text", *req.ModelId, sess.OrchestratorInfo) + } + return nil, err + } + + client, err := worker.NewClientWithResponses(sess.Transcoder(), worker.WithHTTPClient(httpClient)) + if err != nil { + if monitor.Enabled { + monitor.AIRequestError(err.Error(), "audio-to-text", *req.ModelId, sess.OrchestratorInfo) + } + return nil, err + } + + clog.V(common.VERBOSE).Infof(ctx, "Submitting audio-to-text media with duration: %d seconds", durationSeconds) + setHeaders, balUpdate, err := prepareAIPayment(ctx, sess, durationSeconds*1000) + if err != nil { + if monitor.Enabled { + monitor.AIRequestError(err.Error(), "audio-to-text", *req.ModelId, sess.OrchestratorInfo) + } + return nil, err + } + defer completeBalanceUpdate(sess.BroadcastSession, balUpdate) + + start := time.Now() + resp, err := client.GenAudioToTextWithBody(ctx, mw.FormDataContentType(), &buf, setHeaders) + took := time.Since(start) + if err != nil { + if monitor.Enabled { + monitor.AIRequestError(err.Error(), "audio-to-text", *req.ModelId, sess.OrchestratorInfo) + } + return nil, err + } + defer resp.Body.Close() + + data, err := io.ReadAll(resp.Body) + if err != nil { + if monitor.Enabled { + monitor.AIRequestError(err.Error(), "audio-to-text", *req.ModelId, sess.OrchestratorInfo) + } + return nil, err + } + + if resp.StatusCode != 200 { + return nil, errors.New(string(data)) + } + + // We treat a response as "receiving change" where the change is the difference between the credit and debit for the update + if balUpdate != nil { + balUpdate.Status = ReceivedChange + } + + var res worker.TextResponse + if err := json.Unmarshal(data, &res); err != nil { + if monitor.Enabled { + monitor.AIRequestError(err.Error(), "audio-to-text", *req.ModelId, sess.OrchestratorInfo) + } + return nil, err + } + + // TODO: Refine this rough estimate in future iterations + sess.LatencyScore = CalculateAudioToTextLatencyScore(took, durationSeconds) + + if monitor.Enabled { + var pricePerAIUnit float64 + if priceInfo := sess.OrchestratorInfo.GetPriceInfo(); priceInfo != nil && priceInfo.PixelsPerUnit != 0 { + pricePerAIUnit = float64(priceInfo.PricePerUnit) / float64(priceInfo.PixelsPerUnit) + } + + monitor.AIRequestFinished(ctx, "audio-to-text", *req.ModelId, monitor.AIJobInfo{LatencyScore: sess.LatencyScore, PricePerUnit: pricePerAIUnit}, sess.OrchestratorInfo) + } + + return &res, nil +} + +func submitLiveVideoToVideo(ctx context.Context, params aiRequestParams, sess *AISession, req worker.GenLiveVideoToVideoJSONRequestBody) (any, error) { + client, err := worker.NewClientWithResponses(sess.Transcoder(), worker.WithHTTPClient(httpClient)) + if err != nil { + if monitor.Enabled { + monitor.AIRequestError(err.Error(), "LiveVideoToVideo", *req.ModelId, sess.OrchestratorInfo) + } + return nil, err + } + resp, err := client.GenLiveVideoToVideoWithResponse(ctx, req) + if err != nil { + return nil, err + } + if resp.JSON200 != nil { + // append orch hostname to the given url if necessary + appendHostname := func(urlPath string) (*url.URL, error) { + if urlPath == "" { + return nil, fmt.Errorf("invalid url from orch") + } + pu, err := url.Parse(urlPath) + if err != nil { + return nil, err + } + if pu.Hostname() != "" { + // url has a hostname already so use it + return pu, nil + } + // no hostname, so append one + u := sess.Transcoder() + urlPath + return url.Parse(u) + } + pub, err := appendHostname(resp.JSON200.PublishUrl) + if err != nil { + return nil, fmt.Errorf("pub url - %w", err) + } + sub, err := appendHostname(resp.JSON200.SubscribeUrl) + if err != nil { + return nil, fmt.Errorf("sub url %w", err) + } + clog.V(common.VERBOSE).Infof(ctx, "pub %s sub %s", pub, sub) + startTricklePublish(pub, params) + startTrickleSubscribe(sub, params) + } + return resp, nil +} + +func CalculateLLMLatencyScore(took time.Duration, tokensUsed int) float64 { + if tokensUsed <= 0 { + return 0 + } + + return took.Seconds() / float64(tokensUsed) +} + +func processLLM(ctx context.Context, params aiRequestParams, req worker.GenLLMFormdataRequestBody) (interface{}, error) { + resp, err := processAIRequest(ctx, params, req) + if err != nil { + return nil, err + } + + if req.Stream != nil && *req.Stream { + streamChan, ok := resp.(chan worker.LlmStreamChunk) + if !ok { + return nil, errors.New("unexpected response type for streaming request") + } + return streamChan, nil + } + + llmResp, ok := resp.(*worker.LLMResponse) + if !ok { + return nil, errors.New("unexpected response type") + } + + return llmResp, nil +} + +func submitLLM(ctx context.Context, params aiRequestParams, sess *AISession, req worker.GenLLMFormdataRequestBody) (interface{}, error) { + var buf bytes.Buffer + mw, err := worker.NewLLMMultipartWriter(&buf, req) + if err != nil { + if monitor.Enabled { + monitor.AIRequestError(err.Error(), "llm", *req.ModelId, nil) + } + return nil, err + } + + client, err := worker.NewClientWithResponses(sess.Transcoder(), worker.WithHTTPClient(httpClient)) + if err != nil { + if monitor.Enabled { + monitor.AIRequestError(err.Error(), "llm", *req.ModelId, sess.OrchestratorInfo) + } + return nil, err + } + + // TODO: Improve pricing + if req.MaxTokens == nil { + req.MaxTokens = new(int) + *req.MaxTokens = 256 + } + setHeaders, balUpdate, err := prepareAIPayment(ctx, sess, int64(*req.MaxTokens)) + if err != nil { + if monitor.Enabled { + monitor.AIRequestError(err.Error(), "llm", *req.ModelId, sess.OrchestratorInfo) + } + return nil, err + } + defer completeBalanceUpdate(sess.BroadcastSession, balUpdate) + + start := time.Now() + resp, err := client.GenLLMWithBody(ctx, mw.FormDataContentType(), &buf, setHeaders) + if err != nil { + if monitor.Enabled { + monitor.AIRequestError(err.Error(), "llm", *req.ModelId, sess.OrchestratorInfo) + } + return nil, err + } + + if resp.StatusCode != http.StatusOK { + body, _ := io.ReadAll(resp.Body) + return nil, fmt.Errorf("unexpected status code: %d, body: %s", resp.StatusCode, string(body)) + } + + if req.Stream != nil && *req.Stream { + return handleSSEStream(ctx, resp.Body, sess, req, start) + } + + return handleNonStreamingResponse(ctx, resp.Body, sess, req, start) +} + +func handleSSEStream(ctx context.Context, body io.ReadCloser, sess *AISession, req worker.GenLLMFormdataRequestBody, start time.Time) (chan worker.LlmStreamChunk, error) { + streamChan := make(chan worker.LlmStreamChunk, 100) + go func() { + defer close(streamChan) + defer body.Close() + scanner := bufio.NewScanner(body) + var totalTokens int + for scanner.Scan() { + line := scanner.Text() + if strings.HasPrefix(line, "data: ") { + data := strings.TrimPrefix(line, "data: ") + if data == "[DONE]" { + streamChan <- worker.LlmStreamChunk{Done: true, TokensUsed: totalTokens} + break + } + var chunk worker.LlmStreamChunk + if err := json.Unmarshal([]byte(data), &chunk); err != nil { + clog.Errorf(ctx, "Error unmarshaling SSE data: %v", err) + continue + } + totalTokens += chunk.TokensUsed + streamChan <- chunk + } + } + if err := scanner.Err(); err != nil { + clog.Errorf(ctx, "Error reading SSE stream: %v", err) + } + + took := time.Since(start) + sess.LatencyScore = CalculateLLMLatencyScore(took, totalTokens) + + if monitor.Enabled { + var pricePerAIUnit float64 + if priceInfo := sess.OrchestratorInfo.GetPriceInfo(); priceInfo != nil && priceInfo.PixelsPerUnit != 0 { + pricePerAIUnit = float64(priceInfo.PricePerUnit) / float64(priceInfo.PixelsPerUnit) + } + monitor.AIRequestFinished(ctx, "llm", *req.ModelId, monitor.AIJobInfo{LatencyScore: sess.LatencyScore, PricePerUnit: pricePerAIUnit}, sess.OrchestratorInfo) + } + }() + + return streamChan, nil +} + +func handleNonStreamingResponse(ctx context.Context, body io.ReadCloser, sess *AISession, req worker.GenLLMFormdataRequestBody, start time.Time) (*worker.LLMResponse, error) { + data, err := io.ReadAll(body) + defer body.Close() + if err != nil { + if monitor.Enabled { + monitor.AIRequestError(err.Error(), "llm", *req.ModelId, sess.OrchestratorInfo) + } + return nil, err + } + + var res worker.LLMResponse + if err := json.Unmarshal(data, &res); err != nil { + if monitor.Enabled { + monitor.AIRequestError(err.Error(), "llm", *req.ModelId, sess.OrchestratorInfo) + } + return nil, err + } + + took := time.Since(start) + sess.LatencyScore = CalculateLLMLatencyScore(took, res.TokensUsed) + + if monitor.Enabled { + var pricePerAIUnit float64 + if priceInfo := sess.OrchestratorInfo.GetPriceInfo(); priceInfo != nil && priceInfo.PixelsPerUnit != 0 { + pricePerAIUnit = float64(priceInfo.PricePerUnit) / float64(priceInfo.PixelsPerUnit) + } + monitor.AIRequestFinished(ctx, "llm", *req.ModelId, monitor.AIJobInfo{LatencyScore: sess.LatencyScore, PricePerUnit: pricePerAIUnit}, sess.OrchestratorInfo) + } + + return &res, nil +} + +func CalculateImageToTextLatencyScore(took time.Duration, outPixels int64) float64 { + if outPixels <= 0 { + return 0 + } + + return took.Seconds() / float64(outPixels) +} + +func submitImageToText(ctx context.Context, params aiRequestParams, sess *AISession, req worker.GenImageToTextMultipartRequestBody) (*worker.ImageToTextResponse, error) { + var buf bytes.Buffer + mw, err := worker.NewImageToTextMultipartWriter(&buf, req) + if err != nil { + if monitor.Enabled { + monitor.AIRequestError(err.Error(), "image-to-text", *req.ModelId, sess.OrchestratorInfo) + } + return nil, err + } + + client, err := worker.NewClientWithResponses(sess.Transcoder(), worker.WithHTTPClient(httpClient)) + if err != nil { + if monitor.Enabled { + monitor.AIRequestError(err.Error(), "image-to-text", *req.ModelId, sess.OrchestratorInfo) + } + return nil, err + } + + imageRdr, err := req.Image.Reader() + if err != nil { + if monitor.Enabled { + monitor.AIRequestError(err.Error(), "image-to-text", *req.ModelId, sess.OrchestratorInfo) + } + return nil, err + } + config, _, err := image.DecodeConfig(imageRdr) + if err != nil { + if monitor.Enabled { + monitor.AIRequestError(err.Error(), "image-to-text", *req.ModelId, sess.OrchestratorInfo) + } + return nil, err + } + + inPixels := int64(config.Height) * int64(config.Width) + + setHeaders, balUpdate, err := prepareAIPayment(ctx, sess, inPixels) + if err != nil { + if monitor.Enabled { + monitor.AIRequestError(err.Error(), "image-to-text", *req.ModelId, sess.OrchestratorInfo) + } + return nil, err + } + defer completeBalanceUpdate(sess.BroadcastSession, balUpdate) + + start := time.Now() + resp, err := client.GenImageToTextWithBodyWithResponse(ctx, mw.FormDataContentType(), &buf, setHeaders) + took := time.Since(start) + + // TODO: Refine this rough estimate in future iterations. + sess.LatencyScore = CalculateImageToTextLatencyScore(took, inPixels) + + if err != nil { + if monitor.Enabled { + monitor.AIRequestError(err.Error(), "image-to-text", *req.ModelId, sess.OrchestratorInfo) + } + return nil, err + } + + if resp.JSON200 == nil { + // TODO: Replace trim newline with better error spec from O + return nil, errors.New(strings.TrimSuffix(string(resp.Body), "\n")) + } + + // We treat a response as "receiving change" where the change is the difference between the credit and debit for the update + if balUpdate != nil { + balUpdate.Status = ReceivedChange + } + + if monitor.Enabled { + var pricePerAIUnit float64 + if priceInfo := sess.OrchestratorInfo.GetPriceInfo(); priceInfo != nil && priceInfo.PixelsPerUnit != 0 { + pricePerAIUnit = float64(priceInfo.PricePerUnit) / float64(priceInfo.PixelsPerUnit) + } + + monitor.AIRequestFinished(ctx, "image-to-text", *req.ModelId, monitor.AIJobInfo{LatencyScore: sess.LatencyScore, PricePerUnit: pricePerAIUnit}, sess.OrchestratorInfo) + } + + return resp.JSON200, nil +} + +func processImageToText(ctx context.Context, params aiRequestParams, req worker.GenImageToTextMultipartRequestBody) (*worker.ImageToTextResponse, error) { + resp, err := processAIRequest(ctx, params, req) + if err != nil { + return nil, err + } + + txtResp := resp.(*worker.ImageToTextResponse) + + return txtResp, nil +} + +func processAIRequest(ctx context.Context, params aiRequestParams, req interface{}) (interface{}, error) { + var cap core.Capability + var modelID string + var submitFn func(context.Context, aiRequestParams, *AISession) (interface{}, error) + + switch v := req.(type) { + case worker.GenTextToImageJSONRequestBody: + cap = core.Capability_TextToImage + modelID = defaultTextToImageModelID + if v.ModelId != nil { + modelID = *v.ModelId + } + submitFn = func(ctx context.Context, params aiRequestParams, sess *AISession) (interface{}, error) { + return submitTextToImage(ctx, params, sess, v) + } + ctx = clog.AddVal(ctx, "prompt", v.Prompt) + case worker.GenImageToImageMultipartRequestBody: + cap = core.Capability_ImageToImage + modelID = defaultImageToImageModelID + if v.ModelId != nil { + modelID = *v.ModelId + } + submitFn = func(ctx context.Context, params aiRequestParams, sess *AISession) (interface{}, error) { + return submitImageToImage(ctx, params, sess, v) + } + ctx = clog.AddVal(ctx, "prompt", v.Prompt) + case worker.GenImageToVideoMultipartRequestBody: + cap = core.Capability_ImageToVideo + modelID = defaultImageToVideoModelID + if v.ModelId != nil { + modelID = *v.ModelId + } + submitFn = func(ctx context.Context, params aiRequestParams, sess *AISession) (interface{}, error) { + return submitImageToVideo(ctx, params, sess, v) + } + case worker.GenUpscaleMultipartRequestBody: + cap = core.Capability_Upscale + modelID = defaultUpscaleModelID + if v.ModelId != nil { + modelID = *v.ModelId + } + submitFn = func(ctx context.Context, params aiRequestParams, sess *AISession) (interface{}, error) { + return submitUpscale(ctx, params, sess, v) + } + ctx = clog.AddVal(ctx, "prompt", v.Prompt) + case worker.GenAudioToTextMultipartRequestBody: + cap = core.Capability_AudioToText + modelID = defaultAudioToTextModelID + if v.ModelId != nil { + modelID = *v.ModelId + } + submitFn = func(ctx context.Context, params aiRequestParams, sess *AISession) (interface{}, error) { + return submitAudioToText(ctx, params, sess, v) + } + case worker.GenLLMFormdataRequestBody: + cap = core.Capability_LLM + modelID = defaultLLMModelID + if v.ModelId != nil { + modelID = *v.ModelId + } + submitFn = func(ctx context.Context, params aiRequestParams, sess *AISession) (interface{}, error) { + return submitLLM(ctx, params, sess, v) + } + ctx = clog.AddVal(ctx, "prompt", v.Prompt) + case worker.GenSegmentAnything2MultipartRequestBody: + cap = core.Capability_SegmentAnything2 + modelID = defaultSegmentAnything2ModelID + if v.ModelId != nil { + modelID = *v.ModelId + } + submitFn = func(ctx context.Context, params aiRequestParams, sess *AISession) (interface{}, error) { + return submitSegmentAnything2(ctx, params, sess, v) + } + case worker.GenImageToTextMultipartRequestBody: + cap = core.Capability_ImageToText + modelID = defaultImageToTextModelID + if v.ModelId != nil { + modelID = *v.ModelId + } + submitFn = func(ctx context.Context, params aiRequestParams, sess *AISession) (interface{}, error) { + return submitImageToText(ctx, params, sess, v) + } + case worker.GenTextToSpeechJSONRequestBody: + cap = core.Capability_TextToSpeech + modelID = defaultTextToSpeechModelID + if v.ModelId != nil { + modelID = *v.ModelId + } + submitFn = func(ctx context.Context, params aiRequestParams, sess *AISession) (interface{}, error) { + return submitTextToSpeech(ctx, params, sess, v) + } + case worker.GenLiveVideoToVideoJSONRequestBody: + cap = core.Capability_LiveVideoToVideo + modelID = defaultLiveVideoToVideoModelID + if v.ModelId != nil { + modelID = *v.ModelId + } + submitFn = func(ctx context.Context, params aiRequestParams, sess *AISession) (interface{}, error) { + return submitLiveVideoToVideo(ctx, params, sess, v) + } + default: + return nil, fmt.Errorf("unsupported request type %T", req) + } + capName := cap.String() + ctx = clog.AddVal(ctx, "capability", capName) + + clog.V(common.VERBOSE).Infof(ctx, "Received AI request model_id=%s", modelID) + start := time.Now() + defer clog.Infof(ctx, "Processed AI request model_id=%v took=%v", modelID, time.Since(start)) + + var resp interface{} + + cctx, cancel := context.WithTimeout(ctx, processingRetryTimeout) + defer cancel() + + tries := 0 + for { + select { + case <-cctx.Done(): + err := fmt.Errorf("no orchestrators available within %v timeout", processingRetryTimeout) + if monitor.Enabled { + monitor.AIRequestError(err.Error(), monitor.ToPipeline(capName), modelID, nil) + } + return nil, &ServiceUnavailableError{err: err} + default: + } + + tries++ + sess, err := params.sessManager.Select(ctx, cap, modelID) + if err != nil { + clog.Infof(ctx, "Error selecting session modelID=%v err=%v", modelID, err) + continue + } + + if sess == nil { + break + } + + resp, err = submitFn(ctx, params, sess) + if err == nil { + params.sessManager.Complete(ctx, sess) + break + } + + clog.Infof(ctx, "Error submitting request modelID=%v try=%v orch=%v err=%v", modelID, tries, sess.Transcoder(), err) + params.sessManager.Remove(ctx, sess) + + if errors.Is(err, common.ErrAudioDurationCalculation) { + return nil, &BadRequestError{err} + } + + if badRequestErr := parseBadRequestError(err); badRequestErr != nil { + return nil, badRequestErr + } + } + + if resp == nil { + errMsg := "no orchestrators available" + if monitor.Enabled { + monitor.AIRequestError(errMsg, monitor.ToPipeline(capName), modelID, nil) + } + return nil, &ServiceUnavailableError{err: errors.New(errMsg)} + } + return resp, nil +} + +func prepareAIPayment(ctx context.Context, sess *AISession, outPixels int64) (worker.RequestEditorFn, *BalanceUpdate, error) { + // genSegCreds expects a stream.HLSSegment so in order to reuse it here we pass a dummy object + segCreds, err := genSegCreds(sess.BroadcastSession, &stream.HLSSegment{}, nil, false) + if err != nil { + return nil, nil, err + } + + priceInfo, err := common.RatPriceInfo(sess.OrchestratorInfo.GetPriceInfo()) + if err != nil { + return nil, nil, err + } + + // At the moment, outPixels is expected to just be height * width * frames + // If the # of inference/denoising steps becomes configurable, a possible updated formula could be height * width * frames * steps + // If additional parameters that influence compute cost become configurable, then the formula should be reconsidered + fee, err := estimateAIFee(outPixels, priceInfo) + if err != nil { + return nil, nil, err + } + + balUpdate, err := newBalanceUpdate(sess.BroadcastSession, fee) + if err != nil { + return nil, nil, err + } + balUpdate.Debit = fee + + payment, err := genPayment(ctx, sess.BroadcastSession, balUpdate.NumTickets) + if err != nil { + clog.Errorf(ctx, "Could not create payment err=%q", err) + + if monitor.Enabled { + monitor.PaymentCreateError(ctx) + } + + return nil, nil, err + } + + // As soon as the request is sent to the orch consider the balance update's credit as spent + balUpdate.Status = CreditSpent + if monitor.Enabled { + monitor.TicketValueSent(ctx, balUpdate.NewCredit) + monitor.TicketsSent(ctx, balUpdate.NumTickets) + } + + setHeaders := func(_ context.Context, req *http.Request) error { + req.Header.Set(segmentHeader, segCreds) + req.Header.Set(paymentHeader, payment) + req.Header.Set("Authorization", protoVerAIWorker) + return nil + } + + return setHeaders, balUpdate, nil +} + +func estimateAIFee(outPixels int64, priceInfo *big.Rat) (*big.Rat, error) { + if priceInfo == nil { + return nil, nil + } + + fee := new(big.Rat).SetInt64(outPixels) + fee.Mul(fee, priceInfo) + + return fee, nil +} + +// encodeReqMetadata encodes a map of metadata into a JSON string. +func encodeReqMetadata(metadata map[string]string) string { + metadataBytes, _ := json.Marshal(metadata) + return string(metadataBytes) +} diff --git a/server/ai_process_test.go b/server/ai_process_test.go new file mode 100644 index 0000000000..52cf9b483b --- /dev/null +++ b/server/ai_process_test.go @@ -0,0 +1,125 @@ +package server + +import ( + "context" + "reflect" + "testing" + + "github.com/livepeer/ai-worker/worker" +) + +func Test_submitLLM(t *testing.T) { + type args struct { + ctx context.Context + params aiRequestParams + sess *AISession + req worker.GenLLMFormdataRequestBody + } + tests := []struct { + name string + args args + want interface{} + wantErr bool + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := submitLLM(tt.args.ctx, tt.args.params, tt.args.sess, tt.args.req) + if (err != nil) != tt.wantErr { + t.Errorf("submitLLM() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("submitLLM() = %v, want %v", got, tt.want) + } + }) + } +} + +func Test_submitAudioToText(t *testing.T) { + type args struct { + ctx context.Context + params aiRequestParams + sess *AISession + req worker.GenAudioToTextMultipartRequestBody + } + tests := []struct { + name string + args args + want interface{} + wantErr bool + }{ + { + name: "invalid request (no file)", + args: args{ + ctx: context.Background(), + params: aiRequestParams{}, + sess: &AISession{}, + req: worker.GenAudioToTextMultipartRequestBody{}, + }, + want: nil, + wantErr: true, + }, + { + name: "nil session", + args: args{ + ctx: context.Background(), + params: aiRequestParams{}, + sess: nil, + req: worker.GenAudioToTextMultipartRequestBody{}, + }, + want: nil, + wantErr: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := submitAudioToText(tt.args.ctx, tt.args.params, tt.args.sess, tt.args.req) + if (err != nil) != tt.wantErr { + t.Errorf("submitAudioToText() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !tt.wantErr && !reflect.DeepEqual(got, tt.want) { + t.Errorf("submitAudioToText() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestEncodeReqMetadata(t *testing.T) { + tests := []struct { + name string + metadata map[string]string + want string + }{ + { + name: "valid metadata", + metadata: map[string]string{ + "key1": "value1", + "key2": "value2", + }, + want: `{"key1":"value1","key2":"value2"}`, + }, + { + name: "empty metadata", + metadata: map[string]string{}, + want: `{}`, + }, + { + name: "nil metadata", + metadata: nil, + want: `null`, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := encodeReqMetadata(tt.metadata) + if got != tt.want { + t.Errorf("encodeReqMetadata() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/server/ai_session.go b/server/ai_session.go new file mode 100644 index 0000000000..63cb8134cc --- /dev/null +++ b/server/ai_session.go @@ -0,0 +1,417 @@ +package server + +import ( + "context" + "math" + "math/rand" + "strconv" + "sync" + "time" + + "github.com/livepeer/go-livepeer/clog" + "github.com/livepeer/go-livepeer/common" + "github.com/livepeer/go-livepeer/core" + "github.com/livepeer/go-tools/drivers" + "github.com/livepeer/lpms/stream" +) + +type AISession struct { + *BroadcastSession + + // Fields used by AISessionSelector for session lifecycle management + Cap core.Capability + ModelID string + Warm bool +} + +type AISessionPool struct { + selector BroadcastSessionsSelector + sessMap map[string]*BroadcastSession + inUseSess []*BroadcastSession + suspender *suspender + mu sync.RWMutex +} + +func NewAISessionPool(selector BroadcastSessionsSelector, suspender *suspender) *AISessionPool { + return &AISessionPool{ + selector: selector, + sessMap: make(map[string]*BroadcastSession), + suspender: suspender, + mu: sync.RWMutex{}, + } +} + +func (pool *AISessionPool) Select(ctx context.Context) *BroadcastSession { + pool.mu.Lock() + defer pool.mu.Unlock() + + for { + sess := pool.selector.Select(ctx) + if sess == nil { + sess = pool.selectInUse() + } else { + // Track in-use session the first time it is returned by the selector + pool.inUseSess = append(pool.inUseSess, sess) + } + + if sess == nil { + return nil + } + + if _, ok := pool.sessMap[sess.Transcoder()]; !ok { + // If the session is not tracked by sessMap skip it + continue + } + + // Track a dummy segment for the session in indicate an in-flight request + sess.pushSegInFlight(&stream.HLSSegment{}) + + return sess + } +} + +func (pool *AISessionPool) Complete(sess *BroadcastSession) { + pool.mu.Lock() + defer pool.mu.Unlock() + + existingSess, ok := pool.sessMap[sess.Transcoder()] + if !ok { + // If the session is not tracked by sessMap, skip returning it to the selector + return + } + + if sess != existingSess { + // If the session is tracked by sessMap AND it is different from what is tracked by sessMap + // skip returning it to the selector + return + } + + // If there are still in-flight requests for the session return early + // and do not return the session to the selector + inFlight, _ := sess.popSegInFlight() + if inFlight > 0 { + return + } + + pool.inUseSess = removeSessionFromList(pool.inUseSess, sess) + pool.selector.Complete(sess) +} + +func (pool *AISessionPool) Add(sessions []*BroadcastSession) { + pool.mu.Lock() + defer pool.mu.Unlock() + + // If we try to add new sessions to the pool the suspender + // should treat this as a refresh + pool.suspender.signalRefresh() + + var uniqueSessions []*BroadcastSession + for _, sess := range sessions { + if _, ok := pool.sessMap[sess.Transcoder()]; ok { + // Skip the session if it is already tracked by sessMap + continue + } + + pool.sessMap[sess.Transcoder()] = sess + uniqueSessions = append(uniqueSessions, sess) + } + + pool.selector.Add(uniqueSessions) +} + +func (pool *AISessionPool) Remove(sess *BroadcastSession) { + pool.mu.Lock() + defer pool.mu.Unlock() + + delete(pool.sessMap, sess.Transcoder()) + pool.inUseSess = removeSessionFromList(pool.inUseSess, sess) + + // Magic number for now + penalty := 3 + // If this method is called assume that the orch should be suspended + // as well + pool.suspender.suspend(sess.Transcoder(), penalty) +} + +func (pool *AISessionPool) Size() int { + pool.mu.RLock() + defer pool.mu.RUnlock() + + return len(pool.sessMap) +} + +func (pool *AISessionPool) selectInUse() *BroadcastSession { + if len(pool.inUseSess) == 0 { + return nil + } + // Select a random in-use session + return pool.inUseSess[rand.Intn(len(pool.inUseSess))] +} + +type AISessionSelector struct { + // Pool of sessions with orchs that have the requested model warm + warmPool *AISessionPool + // Pool of sessions with orchs that have the requested model cold + coldPool *AISessionPool + // The time until the pools should be refreshed with orchs from discovery + ttl time.Duration + lastRefreshTime time.Time + + cap core.Capability + modelID string + + node *core.LivepeerNode + suspender *suspender + os drivers.OSSession +} + +func NewAISessionSelector(cap core.Capability, modelID string, node *core.LivepeerNode, ttl time.Duration) (*AISessionSelector, error) { + var stakeRdr stakeReader + if node.Eth != nil { + stakeRdr = &storeStakeReader{store: node.Database} + } + + suspender := newSuspender() + + // Create caps for selector to get maxPrice + warmCaps := newAICapabilities(cap, modelID, true, node.Capabilities.MinVersionConstraint()) + coldCaps := newAICapabilities(cap, modelID, false, node.Capabilities.MinVersionConstraint()) + + // The latency score in this context is just the latency of the last completed request for a session + // The "good enough" latency score is set to 0.0 so the selector will always select unknown sessions first + minLS := 0.0 + warmPool := NewAISessionPool(NewMinLSSelector(stakeRdr, minLS, node.SelectionAlgorithm, node.OrchPerfScore, warmCaps), suspender) + coldPool := NewAISessionPool(NewMinLSSelector(stakeRdr, minLS, node.SelectionAlgorithm, node.OrchPerfScore, coldCaps), suspender) + sel := &AISessionSelector{ + warmPool: warmPool, + coldPool: coldPool, + ttl: ttl, + cap: cap, + modelID: modelID, + node: node, + suspender: suspender, + os: drivers.NodeStorage.NewSession(strconv.Itoa(int(cap)) + "_" + modelID), + } + + if err := sel.Refresh(context.Background()); err != nil { + return nil, err + } + + return sel, nil +} + +// newAICapabilities creates a new capabilities object with +func newAICapabilities(cap core.Capability, modelID string, warm bool, minVersion string) *core.Capabilities { + aiCaps := []core.Capability{cap} + capabilityConstraints := core.PerCapabilityConstraints{ + cap: &core.CapabilityConstraints{ + Models: map[string]*core.ModelConstraint{ + modelID: {Warm: warm}, + }, + }, + } + + caps := core.NewCapabilities(aiCaps, nil) + caps.SetPerCapabilityConstraints(capabilityConstraints) + caps.SetMinVersionConstraint(minVersion) + + return caps +} + +func (sel *AISessionSelector) Select(ctx context.Context) *AISession { + shouldRefreshSelector := func() bool { + // Refresh if the # of sessions across warm and cold pools falls below the smaller of the maxRefreshSessionsThreshold and + // 1/2 the total # of orchs that can be queried during discovery + discoveryPoolSize := sel.node.OrchestratorPool.Size() + if sel.warmPool.Size()+sel.coldPool.Size() < int(math.Min(maxRefreshSessionsThreshold, math.Ceil(float64(discoveryPoolSize)/2.0))) { + return true + } + + // Refresh if the selector has expired + if time.Now().After(sel.lastRefreshTime.Add(sel.ttl)) { + return true + } + + return false + } + + if shouldRefreshSelector() { + // Should this call be in a goroutine so the refresh can happen in the background? + if err := sel.Refresh(ctx); err != nil { + clog.Infof(ctx, "Error refreshing AISessionSelector err=%v", err) + } + } + + sess := sel.warmPool.Select(ctx) + if sess != nil { + return &AISession{BroadcastSession: sess, Cap: sel.cap, ModelID: sel.modelID, Warm: true} + } + + sess = sel.coldPool.Select(ctx) + if sess != nil { + return &AISession{BroadcastSession: sess, Cap: sel.cap, ModelID: sel.modelID, Warm: false} + } + + return nil +} + +func (sel *AISessionSelector) Complete(sess *AISession) { + if sess.Warm { + sel.warmPool.Complete(sess.BroadcastSession) + } else { + sel.coldPool.Complete(sess.BroadcastSession) + } +} + +func (sel *AISessionSelector) Remove(sess *AISession) { + if sess.Warm { + sel.warmPool.Remove(sess.BroadcastSession) + } else { + sel.coldPool.Remove(sess.BroadcastSession) + } +} + +func (sel *AISessionSelector) Refresh(ctx context.Context) error { + sessions, err := sel.getSessions(ctx) + if err != nil { + return err + } + + var warmSessions []*BroadcastSession + var coldSessions []*BroadcastSession + for _, sess := range sessions { + // If the constraints are missing for this capability skip this session + constraints, ok := sess.OrchestratorInfo.Capabilities.Constraints.PerCapability[uint32(sel.cap)] + if !ok { + continue + } + + // If the constraint for the modelID are missing skip this session + modelConstraint, ok := constraints.Models[sel.modelID] + if !ok { + continue + } + + if modelConstraint.Warm { + warmSessions = append(warmSessions, sess) + } else { + coldSessions = append(coldSessions, sess) + } + } + + sel.warmPool.Add(warmSessions) + sel.coldPool.Add(coldSessions) + + sel.lastRefreshTime = time.Now() + + return nil +} + +func (sel *AISessionSelector) getSessions(ctx context.Context) ([]*BroadcastSession, error) { + // No warm constraints applied here because we don't want to filter out orchs based on warm criteria at discovery time + // Instead, we want all orchs that support the model and then will filter for orchs that have a warm model separately + capabilityConstraints := core.PerCapabilityConstraints{ + sel.cap: { + Models: map[string]*core.ModelConstraint{ + sel.modelID: { + Warm: false, + }, + }, + }, + } + caps := core.NewCapabilities(append(core.DefaultCapabilities(), sel.cap), nil) + caps.SetPerCapabilityConstraints(capabilityConstraints) + caps.SetMinVersionConstraint(sel.node.Capabilities.MinVersionConstraint()) + + // Set numOrchs to the pool size so that discovery tries to find maximum # of compatible orchs within a timeout + numOrchs := sel.node.OrchestratorPool.Size() + + // Use a dummy manifestID specific to the capability + modelID + // Typically, a manifestID would identify a stream + // In the AI context, a manifestID can identify a capability + modelID and each + // request for the capability + modelID can be thought of as a part of the same "stream" + manifestID := strconv.Itoa(int(sel.cap)) + "_" + sel.modelID + streamParams := &core.StreamParameters{ + ManifestID: core.ManifestID(manifestID), + Capabilities: caps, + OS: sel.os, + } + // TODO: Implement cleanup for AI sessions. + return selectOrchestrator(ctx, sel.node, streamParams, numOrchs, sel.suspender, common.ScoreAtLeast(0), func(sessionID string) {}) +} + +type AISessionManager struct { + node *core.LivepeerNode + selectors map[string]*AISessionSelector + mu sync.Mutex + ttl time.Duration +} + +func NewAISessionManager(node *core.LivepeerNode, ttl time.Duration) *AISessionManager { + return &AISessionManager{ + node: node, + selectors: make(map[string]*AISessionSelector), + mu: sync.Mutex{}, + ttl: ttl, + } +} + +func (c *AISessionManager) Select(ctx context.Context, cap core.Capability, modelID string) (*AISession, error) { + sel, err := c.getSelector(ctx, cap, modelID) + if err != nil { + return nil, err + } + + sess := sel.Select(ctx) + if sess == nil { + return nil, nil + } + + if err := refreshSessionIfNeeded(ctx, sess.BroadcastSession); err != nil { + return nil, err + } + + return sess, nil +} + +func (c *AISessionManager) Remove(ctx context.Context, sess *AISession) error { + sel, err := c.getSelector(ctx, sess.Cap, sess.ModelID) + if err != nil { + return err + } + + sel.Remove(sess) + + return nil +} + +func (c *AISessionManager) Complete(ctx context.Context, sess *AISession) error { + sel, err := c.getSelector(ctx, sess.Cap, sess.ModelID) + if err != nil { + return err + } + + sel.Complete(sess) + + return nil +} + +func (c *AISessionManager) getSelector(ctx context.Context, cap core.Capability, modelID string) (*AISessionSelector, error) { + c.mu.Lock() + defer c.mu.Unlock() + + cacheKey := strconv.Itoa(int(cap)) + "_" + modelID + sel, ok := c.selectors[cacheKey] + if !ok { + // Create the selector + var err error + sel, err = NewAISessionSelector(cap, modelID, c.node, c.ttl) + if err != nil { + return nil, err + } + + c.selectors[cacheKey] = sel + } + + return sel, nil +} diff --git a/server/ai_worker.go b/server/ai_worker.go new file mode 100644 index 0000000000..34dc722bf8 --- /dev/null +++ b/server/ai_worker.go @@ -0,0 +1,580 @@ +package server + +import ( + "bytes" + "context" + "crypto/tls" + "encoding/json" + "errors" + "fmt" + "io" + "mime/multipart" + "net/http" + "net/textproto" + "os" + "os/signal" + "strconv" + "sync" + "syscall" + "time" + + "github.com/cenkalti/backoff" + "github.com/golang/glog" + "github.com/livepeer/ai-worker/worker" + "github.com/livepeer/go-livepeer/clog" + "github.com/livepeer/go-livepeer/common" + "github.com/livepeer/go-livepeer/core" + "github.com/livepeer/go-livepeer/monitor" + "github.com/livepeer/go-livepeer/net" + "golang.org/x/net/http2" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/credentials" + "google.golang.org/grpc/status" +) + +const protoVerAIWorker = "Livepeer-AI-Worker-1.0" +const aiWorkerErrorMimeType = "livepeer/ai-worker-error" + +// Orchestrator gRPC +func (h *lphttp) RegisterAIWorker(req *net.RegisterAIWorkerRequest, stream net.AIWorker_RegisterAIWorkerServer) error { + from := common.GetConnectionAddr(stream.Context()) + glog.Infof("Got a RegisterAIWorker request from aiworker=%s ", from) + + if req.Secret != h.orchestrator.TranscoderSecret() { + glog.Errorf("err=%q", errSecret.Error()) + return errSecret + } + // handle case of legacy Transcoder which do not advertise capabilities + if req.Capabilities == nil { + req.Capabilities = core.NewCapabilities(core.DefaultCapabilities(), nil).ToNetCapabilities() + } + // blocks until stream is finished + h.orchestrator.ServeAIWorker(stream, req.Capabilities) + return nil +} + +// Standalone AIWorker + +// RunAIWorker is main routing of standalone aiworker +// Exiting it will terminate executable +func RunAIWorker(n *core.LivepeerNode, orchAddr string, caps *net.Capabilities) { + expb := backoff.NewExponentialBackOff() + expb.MaxInterval = time.Minute + expb.MaxElapsedTime = 0 + backoff.Retry(func() error { + glog.Info("Registering AI worker to ", orchAddr) + err := runAIWorker(n, orchAddr, caps) + glog.Info("Unregistering AI worker: ", err) + if _, fatal := err.(core.RemoteAIWorkerFatalError); fatal { + glog.Info("Terminating AI Worker because of ", err) + // Returning nil here will make `backoff` to stop trying to reconnect and exit + return nil + } + // By returning error we tell `backoff` to try to connect again + return err + }, expb) +} + +func checkAIWorkerError(err error) error { + if err != nil { + s := status.Convert(err) + if s.Message() == errSecret.Error() { // consider this unrecoverable + return core.NewRemoteAIWorkerFatalError(errSecret) + } + if s.Message() == errZeroCapacity.Error() { // consider this unrecoverable + return core.NewRemoteAIWorkerFatalError(errZeroCapacity) + } + if status.Code(err) == codes.Canceled { + return core.NewRemoteAIWorkerFatalError(errInterrupted) + } + } + return err +} + +func runAIWorker(n *core.LivepeerNode, orchAddr string, caps *net.Capabilities) error { + tlsConfig := &tls.Config{InsecureSkipVerify: true} + conn, err := grpc.Dial(orchAddr, + grpc.WithTransportCredentials(credentials.NewTLS(tlsConfig))) + if err != nil { + glog.Error("Did not connect AI worker to orchesrator: ", err) + return err + } + defer conn.Close() + + c := net.NewAIWorkerClient(conn) + ctx := context.Background() + ctx, cancel := context.WithCancel(ctx) + // Silence linter + defer cancel() + r, err := c.RegisterAIWorker(ctx, &net.RegisterAIWorkerRequest{Secret: n.OrchSecret, Capabilities: caps}) + if err := checkAIWorkerError(err); err != nil { + glog.Error("Could not register aiworker to orchestrator ", err) + return err + } + + // Catch interrupt signal to shut down transcoder + exitc := make(chan os.Signal) + signal.Notify(exitc, os.Interrupt, syscall.SIGTERM) + defer signal.Stop(exitc) + go func() { + select { + case sig := <-exitc: + glog.Infof("Exiting Livepeer AIWorker: %v", sig) + // Cancelling context will close connection to orchestrator + cancel() + return + } + }() + + httpc := &http.Client{Transport: &http2.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: true}}} + var wg sync.WaitGroup + for { + notify, err := r.Recv() + if err := checkAIWorkerError(err); err != nil { + glog.Infof(`End of stream receive cycle because of err=%q, waiting for running aiworker jobs to complete`, err) + wg.Wait() + return err + } + wg.Add(1) + go func() { + runAIJob(n, orchAddr, httpc, notify) + wg.Done() + }() + } +} + +type AIJobRequestData struct { + InputUrl string `json:"input_url"` + Request json.RawMessage `json:"request"` +} + +func runAIJob(n *core.LivepeerNode, orchAddr string, httpc *http.Client, notify *net.NotifyAIJob) { + var contentType string + var body bytes.Buffer + + ctx := clog.AddVal(context.Background(), "taskId", strconv.FormatInt(notify.TaskId, 10)) + clog.Infof(ctx, "Received AI job, validating request") + + var processFn func(context.Context) (interface{}, error) + var resp interface{} // this is used for video as well because Frames received are transcoded to an MP4 + var err error + var resultType string + var reqOk bool + var modelID string + var input []byte + + start := time.Now() + var reqData AIJobRequestData + err = json.Unmarshal(notify.AIJobData.RequestData, &reqData) + if err != nil { + sendAIResult(ctx, n, orchAddr, notify.AIJobData.Pipeline, modelID, httpc, contentType, &body, err) + return + } + + switch notify.AIJobData.Pipeline { + case "text-to-image": + var req worker.GenTextToImageJSONRequestBody + err = json.Unmarshal(reqData.Request, &req) + if err != nil || req.ModelId == nil { + break + } + modelID = *req.ModelId + resultType = "image/png" + processFn = func(ctx context.Context) (interface{}, error) { + return n.TextToImage(ctx, req) + } + reqOk = true + case "image-to-image": + var req worker.GenImageToImageMultipartRequestBody + err = json.Unmarshal(reqData.Request, &req) + if err != nil || req.ModelId == nil { + break + } + input, err = core.DownloadData(ctx, reqData.InputUrl) + if err != nil { + break + } + modelID = *req.ModelId + resultType = "image/png" + req.Image.InitFromBytes(input, "image") + processFn = func(ctx context.Context) (interface{}, error) { + return n.ImageToImage(ctx, req) + } + reqOk = true + case "upscale": + var req worker.GenUpscaleMultipartRequestBody + err = json.Unmarshal(reqData.Request, &req) + if err != nil || req.ModelId == nil { + break + } + input, err = core.DownloadData(ctx, reqData.InputUrl) + if err != nil { + break + } + modelID = *req.ModelId + resultType = "image/png" + req.Image.InitFromBytes(input, "image") + processFn = func(ctx context.Context) (interface{}, error) { + return n.Upscale(ctx, req) + } + reqOk = true + case "image-to-video": + var req worker.GenImageToVideoMultipartRequestBody + err = json.Unmarshal(reqData.Request, &req) + if err != nil || req.ModelId == nil { + break + } + input, err = core.DownloadData(ctx, reqData.InputUrl) + if err != nil { + break + } + modelID = *req.ModelId + resultType = "video/mp4" + req.Image.InitFromBytes(input, "image") + processFn = func(ctx context.Context) (interface{}, error) { + return n.ImageToVideo(ctx, req) + } + reqOk = true + case "audio-to-text": + var req worker.GenAudioToTextMultipartRequestBody + err = json.Unmarshal(reqData.Request, &req) + if err != nil || req.ModelId == nil { + break + } + input, err = core.DownloadData(ctx, reqData.InputUrl) + if err != nil { + break + } + modelID = *req.ModelId + resultType = "application/json" + req.Audio.InitFromBytes(input, "audio") + processFn = func(ctx context.Context) (interface{}, error) { + return n.AudioToText(ctx, req) + } + reqOk = true + case "segment-anything-2": + var req worker.GenSegmentAnything2MultipartRequestBody + err = json.Unmarshal(reqData.Request, &req) + if err != nil || req.ModelId == nil { + break + } + input, err = core.DownloadData(ctx, reqData.InputUrl) + if err != nil { + break + } + modelID = *req.ModelId + resultType = "application/json" + req.Image.InitFromBytes(input, "image") + processFn = func(ctx context.Context) (interface{}, error) { + return n.SegmentAnything2(ctx, req) + } + reqOk = true + case "llm": + var req worker.GenLLMFormdataRequestBody + err = json.Unmarshal(reqData.Request, &req) + if err != nil || req.ModelId == nil { + break + } + modelID = *req.ModelId + resultType = "application/json" + if req.Stream != nil && *req.Stream { + resultType = "text/event-stream" + } + processFn = func(ctx context.Context) (interface{}, error) { + return n.LLM(ctx, req) + } + reqOk = true + case "image-to-text": + var req worker.GenImageToTextMultipartRequestBody + err = json.Unmarshal(reqData.Request, &req) + if err != nil || req.ModelId == nil { + break + } + input, err = core.DownloadData(ctx, reqData.InputUrl) + if err != nil { + break + } + modelID = *req.ModelId + resultType = "application/json" + req.Image.InitFromBytes(input, "image") + processFn = func(ctx context.Context) (interface{}, error) { + return n.ImageToText(ctx, req) + } + reqOk = true + case "text-to-speech": + var req worker.GenTextToSpeechJSONRequestBody + err = json.Unmarshal(reqData.Request, &req) + if err != nil || req.ModelId == nil { + break + } + modelID = *req.ModelId + resultType = "audio/wav" + processFn = func(ctx context.Context) (interface{}, error) { + return n.TextToSpeech(ctx, req) + } + reqOk = true + default: + err = errors.New("AI request pipeline type not supported") + } + + if !reqOk { + resp = nil + err = fmt.Errorf("AI request validation failed for %v pipeline err=%v", notify.AIJobData.Pipeline, err) + sendAIResult(ctx, n, orchAddr, notify.AIJobData.Pipeline, modelID, httpc, contentType, &body, err) + return + } + + // process the request + clog.Infof(ctx, "Processing AI job pipeline=%s modelID=%s", notify.AIJobData.Pipeline, modelID) + + // reserve the capabilities to process this request, release after work is done + err = n.ReserveAICapability(notify.AIJobData.Pipeline, modelID) + if err != nil { + clog.Errorf(ctx, "No capability available to process requested AI job with this node taskId=%d pipeline=%s modelID=%s err=%q", notify.TaskId, notify.AIJobData.Pipeline, modelID, core.ErrNoCompatibleWorkersAvailable) + sendAIResult(ctx, n, orchAddr, notify.AIJobData.Pipeline, modelID, httpc, contentType, &body, core.ErrNoCompatibleWorkersAvailable) + return + } + + // do the work and release the GPU for next job + resp, err = processFn(ctx) + n.ReleaseAICapability(notify.AIJobData.Pipeline, modelID) + + clog.V(common.VERBOSE).InfofErr(ctx, "AI job processing done for taskId=%d pipeline=%s modelID=%s dur=%v", notify.TaskId, notify.AIJobData.Pipeline, modelID, time.Since(start), err) + if err != nil { + if _, ok := err.(core.UnrecoverableError); ok { + defer panic(err) + } + sendAIResult(ctx, n, orchAddr, notify.AIJobData.Pipeline, modelID, httpc, contentType, &body, err) + return + } + + boundary := common.RandName() + w := multipart.NewWriter(&body) + + if resp != nil { + if resultType == "text/event-stream" { + streamChan, ok := resp.(<-chan worker.LlmStreamChunk) + if ok { + sendStreamingAIResult(ctx, n, orchAddr, notify.AIJobData.Pipeline, httpc, resultType, streamChan) + return + } else { + sendAIResult(ctx, n, orchAddr, notify.AIJobData.Pipeline, modelID, httpc, contentType, &body, fmt.Errorf("streaming not supported")) + return + } + } + + // create the multipart/mixed response to send to Orchestrator + // Parse data from runner to send back to orchestrator + // ***-to-image gets base64 encoded string of binary image from runner + // image-to-video processes frames from runner and returns ImageResponse with url to local file + var resBuf bytes.Buffer + length := 0 + switch wkrResp := resp.(type) { + case *worker.ImageResponse: + for i, image := range wkrResp.Images { + // read the data to binary and replace the url + switch resultType { + case "image/png": + err := worker.ReadImageB64DataUrl(image.Url, &resBuf) + if err != nil { + clog.Errorf(ctx, "AI Worker failed to save image from data url err=%q", err) + sendAIResult(ctx, n, orchAddr, notify.AIJobData.Pipeline, modelID, httpc, contentType, &body, err) + return + } + length = resBuf.Len() + wkrResp.Images[i].Url = fmt.Sprintf("%v.png", core.RandomManifestID()) // update json response to track filename attached + + // create the part + w.SetBoundary(boundary) + hdrs := textproto.MIMEHeader{ + "Content-Type": {resultType}, + "Content-Length": {strconv.Itoa(length)}, + "Content-Disposition": {"attachment; filename=" + wkrResp.Images[i].Url}, + } + fw, err := w.CreatePart(hdrs) + if err != nil { + clog.Errorf(ctx, "Could not create multipart part err=%q", err) + sendAIResult(ctx, n, orchAddr, notify.AIJobData.Pipeline, modelID, httpc, contentType, nil, err) + return + } + io.Copy(fw, &resBuf) + resBuf.Reset() + case "video/mp4": + // transcoded result is saved as local file + // TODO: enhance this to return the []bytes from transcoding in n.ImageToVideo create the part + f, err := os.ReadFile(image.Url) + if err != nil { + clog.Errorf(ctx, "Could not create multipart part err=%q", err) + sendAIResult(ctx, n, orchAddr, notify.AIJobData.Pipeline, modelID, httpc, contentType, nil, err) + return + } + defer os.Remove(image.Url) + wkrResp.Images[i].Url = fmt.Sprintf("%v.mp4", core.RandomManifestID()) + w.SetBoundary(boundary) + hdrs := textproto.MIMEHeader{ + "Content-Type": {resultType}, + "Content-Length": {strconv.Itoa(len(f))}, + "Content-Disposition": {"attachment; filename=" + wkrResp.Images[i].Url}, + } + fw, err := w.CreatePart(hdrs) + if err != nil { + clog.Errorf(ctx, "Could not create multipart part err=%q", err) + sendAIResult(ctx, n, orchAddr, notify.AIJobData.Pipeline, modelID, httpc, contentType, nil, err) + return + } + io.Copy(fw, bytes.NewBuffer(f)) + } + } + // update resp for image.Url updates + resp = wkrResp + case *worker.AudioResponse: + err := worker.ReadAudioB64DataUrl(wkrResp.Audio.Url, &resBuf) + if err != nil { + clog.Errorf(ctx, "AI Worker failed to save image from data url err=%q", err) + sendAIResult(ctx, n, orchAddr, notify.AIJobData.Pipeline, modelID, httpc, contentType, &body, err) + return + } + length = resBuf.Len() + wkrResp.Audio.Url = fmt.Sprintf("%v.wav", core.RandomManifestID()) // update json response to track filename attached + // create the part + w.SetBoundary(boundary) + hdrs := textproto.MIMEHeader{ + "Content-Type": {resultType}, + "Content-Length": {strconv.Itoa(length)}, + "Content-Disposition": {"attachment; filename=" + wkrResp.Audio.Url}, + } + fw, err := w.CreatePart(hdrs) + if err != nil { + clog.Errorf(ctx, "Could not create multipart part err=%q", err) + sendAIResult(ctx, n, orchAddr, notify.AIJobData.Pipeline, modelID, httpc, contentType, nil, err) + return + } + io.Copy(fw, &resBuf) + resBuf.Reset() + } + + // add the json to the response + // NOTE: audio-to-text has no file attachment because the response is json + jsonResp, err := json.Marshal(resp) + + if err != nil { + clog.Errorf(ctx, "Could not marshal json response err=%q", err) + sendAIResult(ctx, n, orchAddr, notify.AIJobData.Pipeline, modelID, httpc, contentType, nil, err) + return + } + + w.SetBoundary(boundary) + hdrs := textproto.MIMEHeader{ + "Content-Type": {"application/json"}, + "Content-Length": {strconv.Itoa(len(jsonResp))}, + } + fw, err := w.CreatePart(hdrs) + if err != nil { + clog.Errorf(ctx, "Could not create multipart part err=%q", err) + } + io.Copy(fw, bytes.NewBuffer(jsonResp)) + } + + w.Close() + contentType = "multipart/mixed; boundary=" + boundary + sendAIResult(ctx, n, orchAddr, notify.AIJobData.Pipeline, modelID, httpc, contentType, &body, nil) +} + +func sendAIResult(ctx context.Context, n *core.LivepeerNode, orchAddr string, pipeline string, modelID string, httpc *http.Client, + contentType string, body *bytes.Buffer, err error, +) { + taskId := clog.GetVal(ctx, "taskId") + clog.Infof(ctx, "sending results back to Orchestrator") + if err != nil { + clog.Errorf(ctx, "Unable to process AI job err=%q", err) + body.Write([]byte(err.Error())) + contentType = aiWorkerErrorMimeType + } + resultUrl := "https://" + orchAddr + "/aiResults" + req, err := http.NewRequest("POST", resultUrl, body) + if err != nil { + clog.Errorf(ctx, "Error posting results to orch=%s taskId=%d url=%s err=%q", orchAddr, + taskId, resultUrl, err) + return + } + req.Header.Set("Authorization", protoVerAIWorker) + req.Header.Set("Credentials", n.OrchSecret) + req.Header.Set("Content-Type", contentType) + req.Header.Set("TaskId", taskId) + req.Header.Set("Pipeline", pipeline) + + // TODO consider adding additional information in response header from the addlData field (e.g. transcoding includes Pixels) + + uploadStart := time.Now() + resp, err := httpc.Do(req) + if err != nil { + clog.Errorf(ctx, "Error submitting results err=%q", err) + } else { + rbody, rerr := io.ReadAll(resp.Body) + resp.Body.Close() + if resp.StatusCode < 200 || resp.StatusCode >= 300 { + if rerr != nil { + clog.Errorf(ctx, "Orchestrator returned HTTP statusCode=%v with unreadable body err=%q", resp.StatusCode, rerr) + } else { + clog.Errorf(ctx, "Orchestrator returned HTTP statusCode=%v err=%q", resp.StatusCode, string(rbody)) + } + } + } + uploadDur := time.Since(uploadStart) + clog.V(common.VERBOSE).InfofErr(ctx, "AI job processing done results sent for taskId=%d uploadDur=%v", taskId, pipeline, modelID, uploadDur, err) + + if monitor.Enabled { + monitor.AIResultUploaded(ctx, uploadDur, pipeline, modelID, orchAddr) + } +} + +func sendStreamingAIResult(ctx context.Context, n *core.LivepeerNode, orchAddr string, pipeline string, httpc *http.Client, + contentType string, streamChan <-chan worker.LlmStreamChunk, +) { + clog.Infof(ctx, "sending streaming results back to Orchestrator") + taskId := clog.GetVal(ctx, "taskId") + + pReader, pWriter := io.Pipe() + req, err := http.NewRequest("POST", "https://"+orchAddr+"/aiResults", pReader) + if err != nil { + clog.Errorf(ctx, "Failed to forward stream to target URL err=%q", err) + pWriter.CloseWithError(err) + return + } + + req.Header.Set("Authorization", protoVerAIWorker) + req.Header.Set("Credentials", n.OrchSecret) + req.Header.Set("TaskId", taskId) + req.Header.Set("Pipeline", pipeline) + req.Header.Set("Content-Type", contentType) + req.Header.Set("Cache-Control", "no-cache") + req.Header.Set("Connection", "keep-alive") + + // start separate go routine to forward the streamed response + go func() { + fwdResp, err := httpc.Do(req) + if err != nil { + clog.Errorf(ctx, "Failed to forward stream to target URL err=%q", err) + pWriter.CloseWithError(err) + return + } + defer fwdResp.Body.Close() + io.Copy(io.Discard, fwdResp.Body) + }() + + for chunk := range streamChan { + data, err := json.Marshal(chunk) + if err != nil { + clog.Errorf(ctx, "Error marshaling stream chunk: %v", err) + continue + } + fmt.Fprintf(pWriter, "data: %s\n\n", data) + + if chunk.Done { + pWriter.Close() + clog.Infof(ctx, "streaming results finished") + return + } + } +} diff --git a/server/ai_worker_test.go b/server/ai_worker_test.go new file mode 100644 index 0000000000..4ecbd8768e --- /dev/null +++ b/server/ai_worker_test.go @@ -0,0 +1,642 @@ +package server + +import ( + "bytes" + "context" + "crypto/tls" + "encoding/base64" + "encoding/json" + "errors" + "io" + "mime" + "net/http" + "net/http/httptest" + "net/url" + "os" + "testing" + "time" + + "github.com/livepeer/ai-worker/worker" + "github.com/livepeer/go-livepeer/common" + "github.com/livepeer/go-livepeer/core" + "github.com/livepeer/go-livepeer/eth" + "github.com/livepeer/go-livepeer/net" + "github.com/livepeer/go-tools/drivers" + oapitypes "github.com/oapi-codegen/runtime/types" + "github.com/stretchr/testify/assert" +) + +func TestRemoteAIWorker_Error(t *testing.T) { + httpc := &http.Client{Transport: &http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: true}}} + + assert := assert.New(t) + assert.Nil(nil) + var resultRead int + resultData := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + _, err := io.ReadAll(r.Body) + assert.NoError(err) + w.Write([]byte("result binary data")) + resultRead++ + })) + defer resultData.Close() + + wkr := stubAIWorker{} + node, _ := core.NewLivepeerNode(nil, "/tmp/thisdirisnotactuallyusedinthistest", nil) + node.OrchSecret = "verbigsecret" + node.AIWorker = &wkr + node.Capabilities = createStubAIWorkerCapabilities() + + var headers http.Header + var body []byte + ts := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + out, err := io.ReadAll(r.Body) + assert.NoError(err) + headers = r.Header + body = out + w.Write(nil) + })) + defer ts.Close() + parsedURL, _ := url.Parse(ts.URL) + //send empty request data + notify := createAIJob(742, "text-to-image-empty", "", "") + runAIJob(node, parsedURL.Host, httpc, notify) + time.Sleep(3 * time.Millisecond) + + assert.NotNil(body) + assert.Equal("742", headers.Get("TaskId")) + assert.Equal(aiWorkerErrorMimeType, headers.Get("Content-Type")) + assert.Equal(node.OrchSecret, headers.Get("Credentials")) + assert.Equal(protoVerAIWorker, headers.Get("Authorization")) + assert.NotNil(string(body)) + + //error in worker, good request + notify = createAIJob(742, "text-to-image", "livepeer/model1", "") + errText := "Some error" + wkr.Err = errors.New(errText) + + runAIJob(node, parsedURL.Host, httpc, notify) + time.Sleep(3 * time.Millisecond) + + assert.NotNil(body) + assert.Equal("742", headers.Get("TaskId")) + assert.Equal(aiWorkerErrorMimeType, headers.Get("Content-Type")) + assert.Equal(node.OrchSecret, headers.Get("Credentials")) + assert.Equal(protoVerAIWorker, headers.Get("Authorization")) + assert.Equal(errText, string(body)) + + // unrecoverable error + // send the response and panic + wkr.Err = core.NewUnrecoverableError(errors.New("some error")) + panicked := false + defer func() { + if r := recover(); r != nil { + panicked = true + } + }() + runAIJob(node, parsedURL.Host, httpc, notify) + time.Sleep(3 * time.Millisecond) + + assert.NotNil(body) + assert.Equal("some error", string(body)) + assert.True(panicked) + + //pipeline not compatible + wkr.Err = nil + notify = createAIJob(743, "unsupported-pipeline", "livepeer/model1", "") + + runAIJob(node, parsedURL.Host, httpc, notify) + time.Sleep(3 * time.Millisecond) + + assert.NotNil(body) + assert.Equal("743", headers.Get("TaskId")) + assert.Equal(aiWorkerErrorMimeType, headers.Get("Content-Type")) + assert.Equal(node.OrchSecret, headers.Get("Credentials")) + assert.Equal(protoVerAIWorker, headers.Get("Authorization")) + assert.Equal("AI request validation failed for", string(body)[:32]) + +} + +func TestRunAIJob(t *testing.T) { + ts := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.URL.Path == "/image.png" { + data, err := os.ReadFile("../test/ai/image") + if err != nil { + t.Fatalf("failed to read test image: %v", err) + } + imgData, err := base64.StdEncoding.DecodeString(string(data)) + if err != nil { + t.Fatalf("failed to decode base64 test image: %v", err) + } + w.Write(imgData) + return + } else if r.URL.Path == "/audio.mp3" { + data, err := os.ReadFile("../test/ai/audio") + if err != nil { + t.Fatalf("failed to read test audio: %v", err) + } + imgData, err := base64.StdEncoding.DecodeString(string(data)) + if err != nil { + t.Fatalf("failed to decode base64 test audio: %v", err) + } + w.Write(imgData) + return + } + })) + defer ts.Close() + parsedURL, _ := url.Parse(ts.URL) + httpc := &http.Client{Transport: &http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: true}}} + assert := assert.New(t) + modelId := "livepeer/model1" + tests := []struct { + inputFile oapitypes.File + name string + notify *net.NotifyAIJob + pipeline string + expectedErr string + expectedOutputs int + }{ + { + name: "TextToImage_Success", + notify: createAIJob(1, "text-to-image", modelId, ""), + pipeline: "text-to-image", + expectedErr: "", + expectedOutputs: 1, + }, + { + name: "ImageToImage_Success", + notify: createAIJob(2, "image-to-image", modelId, parsedURL.String()+"/image.png"), + pipeline: "image-to-image", + expectedErr: "", + expectedOutputs: 1, + }, + { + name: "Upscale_Success", + notify: createAIJob(3, "upscale", modelId, parsedURL.String()+"/image.png"), + pipeline: "upscale", + expectedErr: "", + expectedOutputs: 1, + }, + { + name: "ImageToVideo_Success", + notify: createAIJob(4, "image-to-video", modelId, parsedURL.String()+"/image.png"), + pipeline: "image-to-video", + expectedErr: "", + expectedOutputs: 2, + }, + { + name: "AudioToText_Success", + notify: createAIJob(5, "audio-to-text", modelId, parsedURL.String()+"/audio.mp3"), + pipeline: "audio-to-text", + expectedErr: "", + expectedOutputs: 1, + }, + { + name: "SegmentAnything2_Success", + notify: createAIJob(6, "segment-anything-2", modelId, parsedURL.String()+"/image.png"), + pipeline: "segment-anything-2", + expectedErr: "", + expectedOutputs: 1, + }, + { + name: "LLM_Success", + notify: createAIJob(7, "llm", modelId, ""), + pipeline: "llm", + expectedErr: "", + expectedOutputs: 1, + }, + { + name: "ImageToText_Success", + notify: createAIJob(8, "image-to-text", modelId, parsedURL.String()+"/image.png"), + pipeline: "image-to-text", + expectedErr: "", + expectedOutputs: 1, + }, + { + name: "TextToSpeech_Success", + notify: createAIJob(9, "text-to-speech", modelId, ""), + pipeline: "text-to-speech", + expectedErr: "", + expectedOutputs: 1, + }, + { + name: "UnsupportedPipeline", + notify: createAIJob(10, "unsupported-pipeline", modelId, ""), + pipeline: "unsupported-pipeline", + expectedErr: "AI request validation failed for", + expectedOutputs: 0, + }, + { + name: "InvalidRequestData", + notify: createAIJob(11, "text-to-image-invalid", modelId, ""), + pipeline: "text-to-image", + expectedErr: "AI request validation failed for", + expectedOutputs: 0, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + wkr := stubAIWorker{} + node, _ := core.NewLivepeerNode(nil, "/tmp/thisdirisnotactuallyusedinthistest", nil) + + node.OrchSecret = "verbigsecret" + node.AIWorker = &wkr + node.Capabilities = createStubAIWorkerCapabilitiesForPipelineModelId(tt.pipeline, modelId) + + var headers http.Header + var body []byte + ts := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + out, err := io.ReadAll(r.Body) + assert.NoError(err) + headers = r.Header + body = out + w.Write(nil) + })) + defer ts.Close() + parsedURL, _ := url.Parse(ts.URL) + drivers.NodeStorage = drivers.NewMemoryDriver(parsedURL) + runAIJob(node, parsedURL.Host, httpc, tt.notify) + time.Sleep(3 * time.Millisecond) + + _, params, _ := mime.ParseMediaType(headers.Get("Content-Type")) + //this part tests the multipart response reading in AIResults() + results := parseMultiPartResult(bytes.NewBuffer(body), params["boundary"], tt.pipeline) + json.Unmarshal(body, &results) + if tt.expectedErr != "" { + assert.NotNil(body) + assert.Contains(string(body), tt.expectedErr) + assert.Equal(aiWorkerErrorMimeType, headers.Get("Content-Type")) + } else { + assert.NotNil(body) + assert.NotEqual(aiWorkerErrorMimeType, headers.Get("Content-Type")) + + switch tt.pipeline { + case "text-to-image": + t2iResp, ok := results.Results.(worker.ImageResponse) + assert.True(ok) + assert.Equal("1", headers.Get("TaskId")) + assert.Equal(len(results.Files), 1) + expectedResp, _ := wkr.TextToImage(context.Background(), worker.GenTextToImageJSONRequestBody{}) + assert.Equal(expectedResp.Images[0].Seed, t2iResp.Images[0].Seed) + case "image-to-image": + i2iResp, ok := results.Results.(worker.ImageResponse) + assert.True(ok) + assert.Equal("2", headers.Get("TaskId")) + assert.Equal(len(results.Files), 1) + expectedResp, _ := wkr.ImageToImage(context.Background(), worker.GenImageToImageMultipartRequestBody{}) + assert.Equal(expectedResp.Images[0].Seed, i2iResp.Images[0].Seed) + case "upscale": + upsResp, ok := results.Results.(worker.ImageResponse) + assert.True(ok) + assert.Equal("3", headers.Get("TaskId")) + assert.Equal(len(results.Files), 1) + expectedResp, _ := wkr.Upscale(context.Background(), worker.GenUpscaleMultipartRequestBody{}) + assert.Equal(expectedResp.Images[0].Seed, upsResp.Images[0].Seed) + case "image-to-video": + vidResp, ok := results.Results.(worker.ImageResponse) + assert.True(ok) + assert.Equal("4", headers.Get("TaskId")) + assert.Equal(len(results.Files), 1) + expectedResp, _ := wkr.ImageToVideo(context.Background(), worker.GenImageToVideoMultipartRequestBody{}) + assert.Equal(expectedResp.Frames[0][0].Seed, vidResp.Images[0].Seed) + case "audio-to-text": + res, _ := json.Marshal(results.Results) + var jsonRes worker.TextResponse + json.Unmarshal(res, &jsonRes) + + assert.Equal("5", headers.Get("TaskId")) + assert.Equal(len(results.Files), 0) + expectedResp, _ := wkr.AudioToText(context.Background(), worker.GenAudioToTextMultipartRequestBody{}) + assert.Equal(expectedResp, &jsonRes) + case "segment-anything-2": + res, _ := json.Marshal(results.Results) + var jsonRes worker.MasksResponse + json.Unmarshal(res, &jsonRes) + + assert.Equal("6", headers.Get("TaskId")) + assert.Equal(len(results.Files), 0) + expectedResp, _ := wkr.SegmentAnything2(context.Background(), worker.GenSegmentAnything2MultipartRequestBody{}) + assert.Equal(expectedResp, &jsonRes) + case "llm": + res, _ := json.Marshal(results.Results) + var jsonRes worker.LLMResponse + json.Unmarshal(res, &jsonRes) + + assert.Equal("7", headers.Get("TaskId")) + assert.Equal(len(results.Files), 0) + expectedResp, _ := wkr.LLM(context.Background(), worker.GenLLMFormdataRequestBody{}) + assert.Equal(expectedResp, &jsonRes) + case "image-to-text": + res, _ := json.Marshal(results.Results) + var jsonRes worker.ImageToTextResponse + json.Unmarshal(res, &jsonRes) + + assert.Equal("8", headers.Get("TaskId")) + assert.Equal(len(results.Files), 0) + expectedResp, _ := wkr.ImageToText(context.Background(), worker.GenImageToTextMultipartRequestBody{}) + assert.Equal(expectedResp, &jsonRes) + case "text-to-speech": + audResp, ok := results.Results.(worker.AudioResponse) + assert.True(ok) + assert.Equal("9", headers.Get("TaskId")) + assert.Equal(len(results.Files), 1) + expectedResp, _ := wkr.TextToSpeech(context.Background(), worker.GenTextToSpeechJSONRequestBody{}) + var respFile bytes.Buffer + worker.ReadAudioB64DataUrl(expectedResp.Audio.Url, &respFile) + assert.Equal(len(results.Files[audResp.Audio.Url]), respFile.Len()) + } + } + }) + } +} + +func createAIJob(taskId int64, pipeline, modelId, inputUrl string) *net.NotifyAIJob { + var req interface{} + var inputFile oapitypes.File + switch pipeline { + case "text-to-image": + req = worker.GenTextToImageJSONRequestBody{Prompt: "test prompt", ModelId: &modelId} + case "image-to-image": + inputFile.InitFromBytes(nil, inputUrl) + req = worker.GenImageToImageMultipartRequestBody{Prompt: "test prompt", ModelId: &modelId, Image: inputFile} + case "upscale": + inputFile.InitFromBytes(nil, inputUrl) + req = worker.GenUpscaleMultipartRequestBody{Prompt: "test prompt", ModelId: &modelId, Image: inputFile} + case "image-to-video": + inputFile.InitFromBytes(nil, inputUrl) + req = worker.GenImageToVideoMultipartRequestBody{ModelId: &modelId, Image: inputFile} + case "audio-to-text": + inputFile.InitFromBytes(nil, inputUrl) + req = worker.GenAudioToTextMultipartRequestBody{ModelId: &modelId, Audio: inputFile} + case "segment-anything-2": + inputFile.InitFromBytes(nil, inputUrl) + req = worker.GenSegmentAnything2MultipartRequestBody{ModelId: &modelId, Image: inputFile} + case "llm": + req = worker.GenLLMFormdataRequestBody{Prompt: "tell me a story", ModelId: &modelId} + case "image-to-text": + inputFile.InitFromBytes(nil, inputUrl) + req = worker.GenImageToImageMultipartRequestBody{Prompt: "test prompt", ModelId: &modelId, Image: inputFile} + case "text-to-speech": + desc := "a young adult" + text := "let me tell you a story" + req = worker.GenTextToSpeechJSONRequestBody{Description: &desc, ModelId: &modelId, Text: &text} + case "unsupported-pipeline": + req = worker.GenTextToImageJSONRequestBody{Prompt: "test prompt", ModelId: &modelId} + case "text-to-image-invalid": + pipeline = "text-to-image" + req = []byte(`invalid json`) + case "text-to-image-empty": + pipeline = "text-to-image" + req = worker.GenTextToImageJSONRequestBody{} + } + + reqData, _ := json.Marshal(core.AIJobRequestData{Request: req, InputUrl: inputUrl}) + + jobData := &net.AIJobData{ + Pipeline: pipeline, + RequestData: reqData, + } + notify := &net.NotifyAIJob{ + TaskId: taskId, + AIJobData: jobData, + } + return notify +} + +type stubResult struct { + Attachment []byte + Result string +} + +func aiResultsTest(l lphttp, w *httptest.ResponseRecorder, r *http.Request) (int, string) { + handler := l.AIResults() + handler.ServeHTTP(w, r) + resp := w.Result() + defer resp.Body.Close() + body, _ := io.ReadAll(resp.Body) + + return resp.StatusCode, string(body) +} + +func newMockAIOrchestratorServer() *httptest.Server { + n, _ := core.NewLivepeerNode(ð.StubClient{}, "./tmp", nil) + n.NodeType = core.OrchestratorNode + n.AIWorkerManager = core.NewRemoteAIWorkerManager() + s, _ := NewLivepeerServer("127.0.0.1:1938", n, true, "") + mux := s.cliWebServerHandlers("addr") + srv := httptest.NewServer(mux) + return srv +} + +func connectWorker(n *core.LivepeerNode) { + strm := &StubAIWorkerServer{} + caps := createStubAIWorkerCapabilities() + go func() { n.AIWorkerManager.Manage(strm, caps.ToNetCapabilities()) }() + time.Sleep(1 * time.Millisecond) +} + +func createStubAIWorkerCapabilities() *core.Capabilities { + //create capabilities and constraints the ai worker sends to orch + constraints := make(core.PerCapabilityConstraints) + constraints[core.Capability_TextToImage] = &core.CapabilityConstraints{Models: make(core.ModelConstraints)} + constraints[core.Capability_TextToImage].Models["livepeer/model1"] = &core.ModelConstraint{Warm: true, Capacity: 2} + caps := core.NewCapabilities(core.DefaultCapabilities(), core.MandatoryOCapabilities()) + caps.SetPerCapabilityConstraints(constraints) + + return caps +} + +func createStubAIWorkerCapabilitiesForPipelineModelId(pipeline, modelId string) *core.Capabilities { + //create capabilities and constraints the ai worker sends to orch + cap, err := core.PipelineToCapability(pipeline) + if err != nil { + return nil + } + constraints := make(core.PerCapabilityConstraints) + constraints[cap] = &core.CapabilityConstraints{Models: make(core.ModelConstraints)} + constraints[cap].Models[modelId] = &core.ModelConstraint{Warm: true, Capacity: 1} + caps := core.NewCapabilities(core.DefaultCapabilities(), core.MandatoryOCapabilities()) + caps.SetPerCapabilityConstraints(constraints) + + return caps +} + +type StubAIWorkerServer struct { + manager *core.RemoteAIWorkerManager + SendError error + JobError error + DelayResults bool + + common.StubServerStream +} + +func (s *StubAIWorkerServer) Send(n *net.NotifyAIJob) error { + var images []worker.Media + media := worker.Media{Nsfw: false, Seed: 111, Url: "image_url"} + images = append(images, media) + res := core.RemoteAIWorkerResult{ + Results: worker.ImageResponse{Images: images}, + Files: make(map[string][]byte), + Err: nil, + } + if s.JobError != nil { + res.Err = s.JobError + } + if s.SendError != nil { + return s.SendError + } + + return nil +} + +type stubAIWorker struct { + Called int + Err error +} + +func (a *stubAIWorker) TextToImage(ctx context.Context, req worker.GenTextToImageJSONRequestBody) (*worker.ImageResponse, error) { + a.Called++ + if a.Err != nil { + return nil, a.Err + } else { + return &worker.ImageResponse{ + Images: []worker.Media{ + { + Url: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEUAAACnej3aAAAAAXRSTlMAQObYZgAAAApJREFUCNdjYAAAAAIAAeIhvDMAAAAASUVORK5CYII=", + Nsfw: false, + Seed: 111, + }, + }, + }, nil + } + +} + +func (a *stubAIWorker) ImageToImage(ctx context.Context, req worker.GenImageToImageMultipartRequestBody) (*worker.ImageResponse, error) { + a.Called++ + if a.Err != nil { + return nil, a.Err + } else { + return &worker.ImageResponse{ + Images: []worker.Media{ + { + Url: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEUAAACnej3aAAAAAXRSTlMAQObYZgAAAApJREFUCNdjYAAAAAIAAeIhvDMAAAAASUVORK5CYII=", + Nsfw: false, + Seed: 112, + }, + }, + }, nil + } +} + +func (a *stubAIWorker) ImageToVideo(ctx context.Context, req worker.GenImageToVideoMultipartRequestBody) (*worker.VideoResponse, error) { + a.Called++ + if a.Err != nil { + return nil, a.Err + } else { + return &worker.VideoResponse{ + Frames: [][]worker.Media{ + { + { + Url: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEUAAACnej3aAAAAAXRSTlMAQObYZgAAAApJREFUCNdjYAAAAAIAAeIhvDMAAAAASUVORK5CYII=", + Nsfw: false, + Seed: 113, + }, + { + Url: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEUAAACnej3aAAAAAXRSTlMAQObYZgAAAApJREFUCNdjYAAAAAIAAeIhvDMAAAAASUVORK5CYII=", + Nsfw: false, + Seed: 131, + }, + { + Url: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEUAAACnej3aAAAAAXRSTlMAQObYZgAAAApJREFUCNdjYAAAAAIAAeIhvDMAAAAASUVORK5CYII=", + Nsfw: false, + Seed: 311, + }, + }, + }, + }, nil + } +} + +func (a *stubAIWorker) Upscale(ctx context.Context, req worker.GenUpscaleMultipartRequestBody) (*worker.ImageResponse, error) { + a.Called++ + if a.Err != nil { + return nil, a.Err + } else { + return &worker.ImageResponse{ + Images: []worker.Media{ + { + Url: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEUAAACnej3aAAAAAXRSTlMAQObYZgAAAApJREFUCNdjYAAAAAIAAeIhvDMAAAAASUVORK5CYII=", + Nsfw: false, + Seed: 114, + }, + }, + }, nil + } +} + +func (a *stubAIWorker) AudioToText(ctx context.Context, req worker.GenAudioToTextMultipartRequestBody) (*worker.TextResponse, error) { + a.Called++ + if a.Err != nil { + return nil, a.Err + } else { + return &worker.TextResponse{Text: "Transcribed text"}, nil + } +} + +func (a *stubAIWorker) SegmentAnything2(ctx context.Context, req worker.GenSegmentAnything2MultipartRequestBody) (*worker.MasksResponse, error) { + a.Called++ + if a.Err != nil { + return nil, a.Err + } else { + return &worker.MasksResponse{ + Masks: "[[[2.84, 2.83, ...], [2.92, 2.91, ...], [3.22, 3.56, ...], ...]]", + Scores: "[0.50, 0.37, ...]", + Logits: "[[[2.84, 2.66, ...], [3.59, 5.20, ...], [5.07, 5.68, ...], ...]]", + }, nil + } +} + +func (a *stubAIWorker) LLM(ctx context.Context, req worker.GenLLMFormdataRequestBody) (interface{}, error) { + a.Called++ + if a.Err != nil { + return nil, a.Err + } else { + return &worker.LLMResponse{Response: "output tokens", TokensUsed: 10}, nil + } +} + +func (a *stubAIWorker) ImageToText(ctx context.Context, req worker.GenImageToTextMultipartRequestBody) (*worker.ImageToTextResponse, error) { + a.Called++ + if a.Err != nil { + return nil, a.Err + } else { + return &worker.ImageToTextResponse{Text: "Transcribed text"}, nil + } +} + +func (a *stubAIWorker) TextToSpeech(ctx context.Context, req worker.GenTextToSpeechJSONRequestBody) (*worker.AudioResponse, error) { + a.Called++ + if a.Err != nil { + return nil, a.Err + } else { + return &worker.AudioResponse{Audio: worker.MediaURL{ + Url: "data:audio/wav;base64,UklGRhYAAABXQVZFZm10IBAAAAABAAEAgD4AAAB9AAACABAAZGF0YQAAAAA="}, + }, nil + } +} + +func (a *stubAIWorker) Warm(ctx context.Context, arg1, arg2 string, endpoint worker.RunnerEndpoint, flags worker.OptimizationFlags) error { + a.Called++ + return nil +} + +func (a *stubAIWorker) Stop(ctx context.Context) error { + a.Called++ + return nil +} + +func (a *stubAIWorker) HasCapacity(pipeline, modelID string) bool { + a.Called++ + return true +} diff --git a/server/broadcast.go b/server/broadcast.go index 5e9c134685..ec18c53ee4 100755 --- a/server/broadcast.go +++ b/server/broadcast.go @@ -41,14 +41,14 @@ var maxRefreshSessionsThreshold = 8.0 var recordSegmentsMaxTimeout = 1 * time.Minute var Policy *verification.Policy -var BroadcastCfg = &BroadcastConfig{} +var BroadcastCfg = newBroadcastConfig() var MaxAttempts = 3 var MetadataQueue event.SimpleProducer var MetadataPublishTimeout = 1 * time.Second var getOrchestratorInfoRPC = GetOrchestratorInfo -var downloadSeg = core.GetSegmentData +var downloadSeg = core.DownloadData var submitMultiSession = func(ctx context.Context, sess *BroadcastSession, seg *stream.HLSSegment, segPar *core.SegmentParameters, nonce uint64, calcPerceptualHash bool, resc chan *SubmitResult) { go submitSegment(ctx, sess, seg, segPar, nonce, calcPerceptualHash, resc) @@ -56,8 +56,17 @@ var submitMultiSession = func(ctx context.Context, sess *BroadcastSession, seg * var maxTranscodeAttempts = errors.New("hit max transcode attempts") type BroadcastConfig struct { - maxPrice *core.AutoConvertedPrice - mu sync.RWMutex + maxPricePerCapability map[core.Capability]map[string]*core.AutoConvertedPrice + mu sync.RWMutex +} + +func newBroadcastConfig() *BroadcastConfig { + maxPrices := make(map[core.Capability]map[string]*core.AutoConvertedPrice) + models := make(map[string]*core.AutoConvertedPrice) + maxPrices[core.Capability_Unused] = models + return &BroadcastConfig{ + maxPricePerCapability: maxPrices, + } } type SegFlightMetadata struct { @@ -68,22 +77,82 @@ type SegFlightMetadata struct { func (cfg *BroadcastConfig) MaxPrice() *big.Rat { cfg.mu.RLock() defer cfg.mu.RUnlock() - if cfg.maxPrice == nil { + //base price is capability that won't be set with specific price + if cfg.maxPricePerCapability[core.Capability_Unused]["default"] == nil { return nil } - return cfg.maxPrice.Value() + return cfg.maxPricePerCapability[core.Capability_Unused]["default"].Value() } func (cfg *BroadcastConfig) SetMaxPrice(price *core.AutoConvertedPrice) { cfg.mu.Lock() defer cfg.mu.Unlock() - prevPrice := cfg.maxPrice - cfg.maxPrice = price + prevPrice := cfg.maxPricePerCapability[core.Capability_Unused]["default"] + cfg.maxPricePerCapability[core.Capability_Unused]["default"] = price if prevPrice != nil { prevPrice.Stop() } } +// GetCapabilitiesMaxPrice returns the max price for the given capabilities. +func (cfg *BroadcastConfig) GetCapabilitiesMaxPrice(caps common.CapabilityComparator) *big.Rat { + cfg.mu.RLock() + defer cfg.mu.RUnlock() + if caps == nil { + return cfg.MaxPrice() + } + netCaps := caps.ToNetCapabilities() + price := big.NewRat(0, 1) + for capabilityInt, constraints := range netCaps.Constraints.PerCapability { + for modelID := range constraints.Models { + if capPrice := cfg.getCapabilityMaxPrice(core.Capability(capabilityInt), modelID); capPrice != nil { + price = price.Add(price, capPrice) + } + } + } + + // If no prices set per model, return maxPrice + if price.Sign() == 0 { + return cfg.MaxPrice() + } + + return price +} + +func (cfg *BroadcastConfig) getCapabilityMaxPrice(cap core.Capability, modelID string) *big.Rat { + cfg.mu.RLock() + defer cfg.mu.RUnlock() + models, ok := cfg.maxPricePerCapability[cap] + if !ok { + // No price set for capability + return nil + } + if price, modelOk := models[modelID]; modelOk && price != nil { + return price.Value() + } + if defaultPrice, hasDefault := models["default"]; hasDefault { + return defaultPrice.Value() + } + + // No price set for the specific model or default + return nil +} + +func (cfg *BroadcastConfig) SetCapabilityMaxPrice(cap core.Capability, modelID string, newPrice *core.AutoConvertedPrice) { + cfg.mu.RLock() + defer cfg.mu.RUnlock() + if _, ok := cfg.maxPricePerCapability[cap]; !ok { + cfg.maxPricePerCapability[cap] = make(map[string]*core.AutoConvertedPrice) + } + + // Stop previous price subscription if it exists. + if prevPrice, exists := cfg.maxPricePerCapability[cap][modelID]; exists && prevPrice != nil { + prevPrice.Stop() + } + + cfg.maxPricePerCapability[cap][modelID] = newPrice +} + type sessionsCreator func() ([]*BroadcastSession, error) type sessionsCleanup func(sessionId string) type SessionPool struct { @@ -483,8 +552,8 @@ func NewSessionManager(ctx context.Context, node *core.LivepeerNode, params *cor bsm := &BroadcastSessionsManager{ mid: params.ManifestID, VerificationFreq: params.VerificationFreq, - trustedPool: NewSessionPool(params.ManifestID, int(trustedPoolSize), trustedNumOrchs, susTrusted, createSessionsTrusted, cleanupSession, NewMinLSSelector(stakeRdr, 1.0, node.SelectionAlgorithm, node.OrchPerfScore)), - untrustedPool: NewSessionPool(params.ManifestID, int(untrustedPoolSize), untrustedNumOrchs, susUntrusted, createSessionsUntrusted, cleanupSession, NewMinLSSelector(stakeRdr, 1.0, node.SelectionAlgorithm, node.OrchPerfScore)), + trustedPool: NewSessionPool(params.ManifestID, int(trustedPoolSize), trustedNumOrchs, susTrusted, createSessionsTrusted, cleanupSession, NewMinLSSelector(stakeRdr, 1.0, node.SelectionAlgorithm, node.OrchPerfScore, params.Capabilities)), + untrustedPool: NewSessionPool(params.ManifestID, int(untrustedPoolSize), untrustedNumOrchs, susUntrusted, createSessionsUntrusted, cleanupSession, NewMinLSSelector(stakeRdr, 1.0, node.SelectionAlgorithm, node.OrchPerfScore, params.Capabilities)), } bsm.trustedPool.refreshSessions(ctx) bsm.untrustedPool.refreshSessions(ctx) @@ -522,6 +591,21 @@ func (bs *BroadcastSession) pushSegInFlight(seg *stream.HLSSegment) { bs.lock.Unlock() } +// Pop a SegFlightMetadata from a session's SegsInFlight +// Returns the end length of a session's SegsInFlight and the popped SegFlightMetadata +func (bs *BroadcastSession) popSegInFlight() (int, SegFlightMetadata) { + bs.lock.Lock() + defer bs.lock.Unlock() + + if len(bs.SegsInFlight) == 0 { + return 0, SegFlightMetadata{} + } + + sm := bs.SegsInFlight[0] + bs.SegsInFlight = bs.SegsInFlight[1:] + return len(bs.SegsInFlight), sm +} + // selects number of sessions to use according to current algorithm func (bsm *BroadcastSessionsManager) selectSessions(ctx context.Context) (bs []*BroadcastSession, calcPerceptualHash bool, verified bool) { bsm.sessLock.Lock() @@ -605,14 +689,14 @@ func (bsm *BroadcastSessionsManager) chooseResults(ctx context.Context, seg *str segmToCheckIndex := rand.Intn(segmcount) // download trusted hashes - trustedHash, err := core.GetSegmentData(ctx, trustedResult.TranscodeResult.Segments[segmToCheckIndex].PerceptualHashUrl) + trustedHash, err := core.DownloadData(ctx, trustedResult.TranscodeResult.Segments[segmToCheckIndex].PerceptualHashUrl) if err != nil { err = fmt.Errorf("error downloading perceptual hash from url=%s err=%w", trustedResult.TranscodeResult.Segments[segmToCheckIndex].PerceptualHashUrl, err) return nil, nil, err } // download trusted video segment - trustedSegm, err := core.GetSegmentData(ctx, trustedResult.TranscodeResult.Segments[segmToCheckIndex].Url) + trustedSegm, err := core.DownloadData(ctx, trustedResult.TranscodeResult.Segments[segmToCheckIndex].Url) if err != nil { err = fmt.Errorf("error downloading segment from url=%s err=%w", trustedResult.TranscodeResult.Segments[segmToCheckIndex].Url, err) @@ -623,7 +707,7 @@ func (bsm *BroadcastSessionsManager) chooseResults(ctx context.Context, seg *str var sessionsToSuspend []*BroadcastSession for _, untrustedResult := range untrustedResults { ouri := untrustedResult.Session.Transcoder() - untrustedHash, err := core.GetSegmentData(ctx, untrustedResult.TranscodeResult.Segments[segmToCheckIndex].PerceptualHashUrl) + untrustedHash, err := core.DownloadData(ctx, untrustedResult.TranscodeResult.Segments[segmToCheckIndex].PerceptualHashUrl) if err != nil { err = fmt.Errorf("error uri=%s downloading perceptual hash from url=%s err=%w", ouri, untrustedResult.TranscodeResult.Segments[segmToCheckIndex].PerceptualHashUrl, err) @@ -646,7 +730,7 @@ func (bsm *BroadcastSessionsManager) chooseResults(ctx context.Context, seg *str vequal := false if equal { // download untrusted video segment - untrustedSegm, err := core.GetSegmentData(ctx, untrustedResult.TranscodeResult.Segments[segmToCheckIndex].Url) + untrustedSegm, err := core.DownloadData(ctx, untrustedResult.TranscodeResult.Segments[segmToCheckIndex].Url) if err != nil { err = fmt.Errorf("error uri=%s downloading segment from url=%s err=%w", ouri, untrustedResult.TranscodeResult.Segments[segmToCheckIndex].Url, err) @@ -895,7 +979,10 @@ func processSegment(ctx context.Context, cxn *rtmpConnection, seg *stream.HLSSeg ctx, cancel := clog.WithTimeout(context.Background(), ctx, recordSegmentsMaxTimeout) defer cancel() now := time.Now() - uri, err := drivers.SaveRetried(ctx, ros, name, seg.Data, map[string]string{"duration": segDurMs}, 3) + fields := &drivers.FileProperties{ + Metadata: map[string]string{"duration": segDurMs}, + } + uri, err := drivers.SaveRetried(ctx, ros, name, seg.Data, fields, 3) took := time.Since(now) if err != nil { clog.Errorf(ctx, "Error saving name=%s bytes=%d to record store err=%q", @@ -1099,7 +1186,7 @@ func transcodeSegment(ctx context.Context, cxn *rtmpConnection, seg *stream.HLSS return nil, info, err } segmToCheckIndex := rand.Intn(segmcount) - segHash, err := core.GetSegmentData(ctx, res.Segments[segmToCheckIndex].PerceptualHashUrl) + segHash, err := core.DownloadData(ctx, res.Segments[segmToCheckIndex].PerceptualHashUrl) if err != nil || len(segHash) <= 0 { err = fmt.Errorf("error downloading perceptual hash from url=%s err=%w", res.Segments[segmToCheckIndex].PerceptualHashUrl, err) @@ -1184,21 +1271,12 @@ func prepareForTranscoding(ctx context.Context, cxn *rtmpConnection, sess *Broad res.Name = uri // hijack seg.Name to convey the uploaded URI } - refresh, err := shouldRefreshSession(ctx, sess) - if err != nil { - clog.Errorf(ctx, "Error checking whether to refresh session manifestID=%s orch=%v err=%q", cxn.mid, sess.Transcoder(), err) + if err := refreshSessionIfNeeded(ctx, sess); err != nil { + clog.Errorf(ctx, "Error refreshing session manifestID=%s orch=%v err=%q", cxn.mid, sess.Transcoder(), err) cxn.sessManager.suspendAndRemoveOrch(sess) return nil, err } - if refresh { - err := refreshSession(ctx, sess) - if err != nil { - clog.Errorf(ctx, "Error refreshing session manifestID=%s orch=%v err=%q", cxn.mid, sess.Transcoder(), err) - cxn.sessManager.suspendAndRemoveOrch(sess) - return nil, err - } - } return res, nil } @@ -1268,7 +1346,10 @@ func downloadResults(ctx context.Context, cxn *rtmpConnection, seg *stream.HLSSe name := fmt.Sprintf("%s/%d%s", profile.Name, seg.SeqNo, ext) segDurMs := getSegDurMsString(seg) now := time.Now() - uri, err := drivers.SaveRetried(ctx, bros, name, data, map[string]string{"duration": segDurMs}, 3) + fields := &drivers.FileProperties{ + Metadata: map[string]string{"duration": segDurMs}, + } + uri, err := drivers.SaveRetried(ctx, bros, name, data, fields, 3) took := time.Since(now) if err != nil { clog.Errorf(ctx, "Error saving nonce=%d manifestID=%s name=%s to record store err=%q", nonce, cxn.mid, name, err) @@ -1490,6 +1571,17 @@ func updateSession(sess *BroadcastSession, res *ReceivedTranscodeResult) { } } +func refreshSessionIfNeeded(ctx context.Context, sess *BroadcastSession) error { + shouldRefresh, err := shouldRefreshSession(ctx, sess) + if err != nil { + return err + } + if shouldRefresh { + return refreshSession(ctx, sess) + } + return nil +} + func refreshSession(ctx context.Context, sess *BroadcastSession) error { uri, err := url.Parse(sess.Transcoder()) if err != nil { @@ -1498,7 +1590,7 @@ func refreshSession(ctx context.Context, sess *BroadcastSession) error { ctx, cancel := context.WithTimeout(ctx, refreshTimeout) defer cancel() - oInfo, err := getOrchestratorInfoRPC(ctx, sess.Broadcaster, uri) + oInfo, err := getOrchestratorInfoRPC(ctx, sess.Broadcaster, uri, sess.Params.Capabilities.ToNetCapabilities()) if err != nil { return err } diff --git a/server/broadcast_test.go b/server/broadcast_test.go index 21f11cb18d..48957bfb24 100644 --- a/server/broadcast_test.go +++ b/server/broadcast_test.go @@ -173,7 +173,10 @@ type stubOSSession struct { err error } -func (s *stubOSSession) SaveData(ctx context.Context, name string, data io.Reader, meta map[string]string, timeout time.Duration) (string, error) { +func (s *stubOSSession) OS() drivers.OSDriver { + return nil +} +func (s *stubOSSession) SaveData(ctx context.Context, name string, data io.Reader, meta *drivers.FileProperties, timeout time.Duration) (string, error) { s.saved = append(s.saved, name) return "saved_" + name, s.err } @@ -191,11 +194,17 @@ func (s *stubOSSession) IsOwn(url string) bool { func (s *stubOSSession) ListFiles(ctx context.Context, prefix, delim string) (drivers.PageInfo, error) { return nil, nil } +func (os *stubOSSession) DeleteFile(ctx context.Context, name string) error { + return nil +} func (s *stubOSSession) ReadData(ctx context.Context, name string) (*drivers.FileInfoReader, error) { return nil, nil } -func (s *stubOSSession) OS() drivers.OSDriver { - return nil +func (os *stubOSSession) ReadDataRange(ctx context.Context, name, byteRange string) (*drivers.FileInfoReader, error) { + return nil, nil +} +func (os *stubOSSession) Presign(name string, expire time.Duration) (string, error) { + return "", nil } type stubPlaylistManager struct { @@ -376,7 +385,7 @@ func TestSelectSession_MultipleInFlight2(t *testing.T) { defer func() { getOrchestratorInfoRPC = oldGetOrchestratorInfoRPC }() orchInfoCalled := 0 - getOrchestratorInfoRPC = func(ctx context.Context, bcast common.Broadcaster, orchestratorServer *url.URL) (*net.OrchestratorInfo, error) { + getOrchestratorInfoRPC = func(ctx context.Context, bcast common.Broadcaster, orchestratorServer *url.URL, caps *net.Capabilities) (*net.OrchestratorInfo, error) { orchInfoCalled++ return successOrchInfoUpdate, nil } @@ -596,7 +605,7 @@ func TestTranscodeSegment_RefreshSession(t *testing.T) { oldGetOrchestratorInfoRPC := getOrchestratorInfoRPC defer func() { getOrchestratorInfoRPC = oldGetOrchestratorInfoRPC }() - getOrchestratorInfoRPC = func(ctx context.Context, bcast common.Broadcaster, orchestratorServer *url.URL) (*net.OrchestratorInfo, error) { + getOrchestratorInfoRPC = func(ctx context.Context, bcast common.Broadcaster, orchestratorServer *url.URL, caps *net.Capabilities) (*net.OrchestratorInfo, error) { return successOrchInfoUpdate, nil } @@ -1497,7 +1506,7 @@ func TestRefreshSession(t *testing.T) { assert.Contains(err.Error(), "invalid control character in URL") // trigger getOrchestratorInfo error - getOrchestratorInfoRPC = func(ctx context.Context, bcast common.Broadcaster, orchestratorServer *url.URL) (*net.OrchestratorInfo, error) { + getOrchestratorInfoRPC = func(ctx context.Context, bcast common.Broadcaster, orchestratorServer *url.URL, caps *net.Capabilities) (*net.OrchestratorInfo, error) { return nil, errors.New("some error") } sess = StubBroadcastSession("foo") @@ -1505,7 +1514,7 @@ func TestRefreshSession(t *testing.T) { assert.EqualError(err, "some error") // trigger update - getOrchestratorInfoRPC = func(ctx context.Context, bcast common.Broadcaster, orchestratorServer *url.URL) (*net.OrchestratorInfo, error) { + getOrchestratorInfoRPC = func(ctx context.Context, bcast common.Broadcaster, orchestratorServer *url.URL, caps *net.Capabilities) (*net.OrchestratorInfo, error) { return successOrchInfoUpdate, nil } err = refreshSession(context.TODO(), sess) @@ -1516,7 +1525,7 @@ func TestRefreshSession(t *testing.T) { oldRefreshTimeout := refreshTimeout defer func() { refreshTimeout = oldRefreshTimeout }() refreshTimeout = 10 * time.Millisecond - getOrchestratorInfoRPC = func(ctx context.Context, bcast common.Broadcaster, serv *url.URL) (*net.OrchestratorInfo, error) { + getOrchestratorInfoRPC = func(ctx context.Context, bcast common.Broadcaster, serv *url.URL, caps *net.Capabilities) (*net.OrchestratorInfo, error) { // Wait until the refreshTimeout has elapsed select { case <-ctx.Done(): @@ -1815,3 +1824,122 @@ func TestVerifcationRunsBasedOnVerificationFrequency(t *testing.T) { require.Greater(t, float32(shouldSkipCount), float32(numTests)*(1-2/float32(verificationFreq))) require.Less(t, float32(shouldSkipCount), float32(numTests)*(1-0.5/float32(verificationFreq))) } + +func TestMaxPrice(t *testing.T) { + cfg := newBroadcastConfig() + + // Should return nil if max price is not set. + assert.Nil(t, cfg.MaxPrice()) + + // Should return correct price if max price is set. + price := core.NewFixedPrice(big.NewRat(10, 1)) + cfg.SetMaxPrice(price) + assert.Equal(t, big.NewRat(10, 1), cfg.MaxPrice()) + + // Should update the max price correctly. + newPrice := core.NewFixedPrice(big.NewRat(20, 1)) + cfg.SetMaxPrice(newPrice) + assert.Equal(t, big.NewRat(20, 1), cfg.MaxPrice()) + + // Should handle nil value gracefully. + cfg.SetMaxPrice(nil) + assert.Nil(t, cfg.MaxPrice()) +} + +func TestCapabilityMaxPrice(t *testing.T) { + cfg := newBroadcastConfig() + + // Should return nil if no price is set for the capability. + assert.Nil(t, cfg.getCapabilityMaxPrice(core.Capability(1), "model1")) + + // Should set and return the correct price for a capability and model. + capability1 := core.Capability(1) + modelID1 := "model1" + price1 := core.NewFixedPrice(big.NewRat(5, 1)) + cfg.SetCapabilityMaxPrice(capability1, modelID1, price1) + capability2 := core.Capability(2) + modelID2 := "model2" + price2 := core.NewFixedPrice(big.NewRat(7, 1)) + cfg.SetCapabilityMaxPrice(capability2, modelID2, price2) + assert.Equal(t, big.NewRat(5, 1), cfg.getCapabilityMaxPrice(capability1, modelID1)) + assert.Equal(t, big.NewRat(7, 1), cfg.getCapabilityMaxPrice(capability2, modelID2)) + + // Should return default price when no specific model price is set. + defaultPrice := core.NewFixedPrice(big.NewRat(3, 1)) + cfg.SetCapabilityMaxPrice(capability1, "default", defaultPrice) + assert.Equal(t, big.NewRat(3, 1), cfg.getCapabilityMaxPrice(capability1, "nonexistentModel")) + + // Should return nil when no model or default price is set for a capability. + assert.Nil(t, cfg.getCapabilityMaxPrice(capability2, "nonexistentModel")) + + // Should update the price for a capability and model correctly. + newPrice1 := core.NewFixedPrice(big.NewRat(10, 1)) + cfg.SetCapabilityMaxPrice(capability1, modelID1, newPrice1) + assert.Equal(t, big.NewRat(10, 1), cfg.getCapabilityMaxPrice(capability1, modelID1)) + + // Should handle nil value gracefully. + capability3 := core.Capability(3) + modelID23 := "model3" + cfg.SetCapabilityMaxPrice(capability3, "model3", nil) + assert.Nil(t, cfg.getCapabilityMaxPrice(capability3, modelID23)) +} + +func TestGetCapabilitiesMaxPrice(t *testing.T) { + cfg := newBroadcastConfig() + + // Should return nil if no max price is set and no capabilities are provided. + assert.Nil(t, cfg.GetCapabilitiesMaxPrice(nil)) + + // Should return the max price if no capabilities are provided. + price := core.NewFixedPrice(big.NewRat(10, 1)) + cfg.SetMaxPrice(price) + assert.Equal(t, big.NewRat(10, 1), cfg.GetCapabilitiesMaxPrice(nil)) + + // Create capabilities object. + capability1 := core.Capability(1) + modelID1 := "model1" + capability2 := core.Capability(2) + modelID2 := "model2" + netCaps := &net.Capabilities{ + Constraints: &net.Capabilities_Constraints{ + PerCapability: map[uint32]*net.Capabilities_CapabilityConstraints{ + uint32(capability1): { + Models: map[string]*net.Capabilities_CapabilityConstraints_ModelConstraint{ + modelID1: {}, + }, + }, + uint32(capability2): { + Models: map[string]*net.Capabilities_CapabilityConstraints_ModelConstraint{ + modelID2: {}, + }, + }, + }, + }, + } + capabilities := &StubCapabilityComparator{NetCaps: netCaps} + + // Should return the sum of prices for the given capabilities. + price1 := core.NewFixedPrice(big.NewRat(5, 1)) + cfg.SetCapabilityMaxPrice(capability1, modelID1, price1) + price2 := core.NewFixedPrice(big.NewRat(7, 1)) + cfg.SetCapabilityMaxPrice(capability2, modelID2, price2) + expectedPrice := big.NewRat(12, 1) + assert.Equal(t, expectedPrice, cfg.GetCapabilitiesMaxPrice(capabilities)) + + // Should test fallback to "default" model price. + defaultPrice := core.NewFixedPrice(big.NewRat(3, 1)) + cfg.SetCapabilityMaxPrice(capability1, "default", defaultPrice) + netCapsWithDefault := &net.Capabilities{ + Constraints: &net.Capabilities_Constraints{ + PerCapability: map[uint32]*net.Capabilities_CapabilityConstraints{ + uint32(capability1): { + Models: map[string]*net.Capabilities_CapabilityConstraints_ModelConstraint{ + "nonexistentModel": {}, + }, + }, + }, + }, + } + capabilitiesWithDefault := &StubCapabilityComparator{NetCaps: netCapsWithDefault} + assert.Equal(t, big.NewRat(3, 1), cfg.GetCapabilitiesMaxPrice(capabilitiesWithDefault)) +} diff --git a/server/handlers.go b/server/handlers.go index 0a5b44c17a..3f4673b6fe 100644 --- a/server/handlers.go +++ b/server/handlers.go @@ -1,8 +1,10 @@ package server import ( + "context" "encoding/json" "fmt" + "io" "math/big" "net/http" "net/url" @@ -16,6 +18,7 @@ import ( ethtypes "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/signer/core/apitypes" "github.com/golang/glog" + "github.com/livepeer/go-livepeer/clog" "github.com/livepeer/go-livepeer/common" "github.com/livepeer/go-livepeer/core" "github.com/livepeer/go-livepeer/eth" @@ -196,6 +199,74 @@ func setBroadcastConfigHandler() http.Handler { }) } +func (s *LivepeerServer) setMaxPriceForCapability() http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if s.LivepeerNode.NodeType == core.BroadcasterNode { + maxPricePerUnit := r.FormValue("maxPricePerUnit") + pixelsPerUnit := r.FormValue("pixelsPerUnit") + currency := r.FormValue("currency") + pipeline := r.FormValue("pipeline") + modelID := r.FormValue("modelID") + + if pipeline == "" || modelID == "" { + respond400(w, "pipeline and modelID must be set") + return + } + + cap, err := core.PipelineToCapability(pipeline) + if err != nil { + respond400(w, "pipeline not supported") + return + } + + // set max price + if maxPricePerUnit != "" && pixelsPerUnit != "" { + pr, ok := new(big.Rat).SetString(maxPricePerUnit) + if !ok { + respond400(w, fmt.Sprintf("Error parsing pricePerUnit value: %s", maxPricePerUnit)) + return + } + px, ok := new(big.Rat).SetString(pixelsPerUnit) + if !ok { + respond400(w, fmt.Sprintf("Error parsing pixelsPerUnit value: %s", pixelsPerUnit)) + return + } + if px.Sign() <= 0 { + respond400(w, fmt.Sprintf("pixels per unit must be greater than 0, provided %v", pixelsPerUnit)) + return + } + pricePerPixel := new(big.Rat).Quo(pr, px) + + var autoPrice *core.AutoConvertedPrice + if pricePerPixel.Sign() > 0 { + var err error + autoPrice, err = core.NewAutoConvertedPrice(currency, pricePerPixel, func(price *big.Rat) { + if monitor.Enabled { + monitor.MaxPriceForCapability(monitor.ToPipeline(core.CapabilityNameLookup[cap]), modelID, price) + } + glog.Infof("Maximum price per unit set to %v wei for capability=%v model_id=%v", price.FloatString(3), pipeline, modelID) + }) + if err != nil { + respond400(w, errors.Wrap(err, "error converting price").Error()) + return + } + + BroadcastCfg.SetCapabilityMaxPrice(cap, modelID, autoPrice) + respondOk(w, nil) + } else { + respond400(w, fmt.Sprintf("pricePerPixel needs to be > 0: %v", pricePerPixel.FloatString(3))) + } + } else { + respond400(w, "maxPricePerUnit and pixelsPerUnit need to be set") + return + } + } else { + respond400(w, "Node must be gateway node to set max price per capability") + return + } + }) +} + func getBroadcastConfigHandler() http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { var pNames []string @@ -1479,6 +1550,40 @@ func respondJsonOk(w http.ResponseWriter, msg []byte) { respondOk(w, msg) } +type APIErrorResponse struct { + Error error `json:"error"` +} + +type APIError struct { + Message string `json:"message"` +} + +func (err *APIError) Error() string { return err.Message } + +func handleAPIError(ctx context.Context, w io.Writer, err error, code int) { + clog.Errorf(ctx, "Error with API code=%v err=%v", code, err) + + apiErr := &APIError{Message: err.Error()} + + if code == http.StatusInternalServerError { + apiErr.Message = "Internal Server Error" + } else if code == http.StatusServiceUnavailable { + apiErr.Message = "Service Unavailable Error" + } + + resp := &APIErrorResponse{Error: apiErr} + if err := json.NewEncoder(w).Encode(resp); err != nil { + clog.Errorf(ctx, "Error with API JSON encoding err=%v", err) + } +} + +func respondJsonError(ctx context.Context, w http.ResponseWriter, err error, code int) { + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(code) + + handleAPIError(ctx, w, err, code) +} + func respond500(w http.ResponseWriter, errMsg string) { respondWithError(w, errMsg, http.StatusInternalServerError) } diff --git a/server/handlers_test.go b/server/handlers_test.go index 528282972e..3a309395b9 100644 --- a/server/handlers_test.go +++ b/server/handlers_test.go @@ -257,10 +257,143 @@ func TestSetBroadcastConfigHandler_Success(t *testing.T) { assert.Equal(profiles, BroadcastJobVideoProfiles) } +func TestSetMaxPriceForCapabilityHandler(t *testing.T) { + assert := assert.New(t) + s := stubServer() + s.LivepeerNode.NodeType = core.BroadcasterNode + + handler := s.setMaxPriceForCapability() + + //set default max price + basePrice, _ := core.NewAutoConvertedPrice("WEI", big.NewRat(10, 1), nil) + BroadcastCfg.SetMaxPrice(basePrice) + + //set price per unit for specific pipeline + p1, _ := core.NewAutoConvertedPrice("WEI", big.NewRat(1, 1), nil) + p2, _ := core.NewAutoConvertedPrice("WEI", big.NewRat(2, 1), nil) + p1_pipeline := "text-to-image" + p1_pipeline_cap, _ := core.PipelineToCapability(p1_pipeline) + p1_modelID := "default" + + p2_pipeline := "image-to-image" + p2_pipeline_cap, _ := core.PipelineToCapability(p2_pipeline) + p2_modelID := "default" + + status1, _ := postForm(handler, url.Values{ + "maxPricePerUnit": {"1"}, + "pixelsPerUnit": {"1"}, + "currency": {"WEI"}, + "pipeline": {p1_pipeline}, + "modelID": {p1_modelID}, + }) + + assert.Equal(http.StatusOK, status1) + assert.Equal(p1.Value(), BroadcastCfg.getCapabilityMaxPrice(p1_pipeline_cap, p1_modelID)) + + status2, _ := postForm(handler, url.Values{ + "maxPricePerUnit": {"2"}, + "pixelsPerUnit": {"1"}, + "currency": {"WEI"}, + "pipeline": {p2_pipeline}, + "modelID": {p2_modelID}, + }) + + assert.Equal(http.StatusOK, status2) + assert.Equal(p2.Value(), BroadcastCfg.getCapabilityMaxPrice(p2_pipeline_cap, p1_modelID)) + + p1_modelID = "stabilityai/sd-turbo" + status1, _ = postForm(handler, url.Values{ + "maxPricePerUnit": {"100"}, + "pixelsPerUnit": {"1"}, + "currency": {"WEI"}, + "pipeline": {p1_pipeline}, + "modelID": {p1_modelID}, + }) + assert.Equal(http.StatusOK, status1) + assert.NotEqual(p1.Value(), BroadcastCfg.getCapabilityMaxPrice(p1_pipeline_cap, p1_modelID)) + assert.Equal(big.NewRat(100, 1), BroadcastCfg.getCapabilityMaxPrice(p1_pipeline_cap, p1_modelID)) +} + +func TestSetMaxPriceForCapabilityHandler_NotGateway(t *testing.T) { + assert := assert.New(t) + s := stubServer() + s.LivepeerNode.NodeType = core.OrchestratorNode + + handler := s.setMaxPriceForCapability() + + status, _ := postForm(handler, url.Values{ + "maxPricePerUnit": {"10"}, + "pixelsPerUnit": {"1"}, + "currency": {"WEI"}, + "pipeline": {"text-to-image"}, + "modelID": {"default"}, + }) + + assert.Equal(http.StatusBadRequest, status) +} + +func TestSetMaxPriceForCapabilityHandler_WrongInput(t *testing.T) { + assert := assert.New(t) + s := stubServer() + s.LivepeerNode.NodeType = core.BroadcasterNode + + handler := s.setMaxPriceForCapability() + + //pricePerUnit is not int + status1, _ := postForm(handler, url.Values{ + "maxPricePerUnit": {"a"}, + "pixelsPerUnit": {"1"}, + "currency": {"WEI"}, + "pipeline": {"text-to-image"}, + "modelID": {"default"}, + }) + assert.Equal(http.StatusBadRequest, status1) + + //pixelsPerUnit is not int + status2, _ := postForm(handler, url.Values{ + "maxPricePerUnit": {"1"}, + "pixelsPerUnit": {"a"}, + "currency": {"WEI"}, + "pipeline": {"text-to-image"}, + "modelID": {"default"}, + }) + assert.Equal(http.StatusBadRequest, status2) + + //pipeline is not set + status4, _ := postForm(handler, url.Values{ + "maxPricePerUnit": {"1"}, + "pixelsPerUnit": {"1"}, + "currency": {"WEI"}, + "pipeline": {""}, + "modelID": {"default"}, + }) + assert.Equal(http.StatusBadRequest, status4) + + //modelID is not set + status5, _ := postForm(handler, url.Values{ + "maxPricePerUnit": {"1"}, + "pixelsPerUnit": {"1"}, + "currency": {"WEI"}, + "pipeline": {"text-to-image"}, + "modelID": {""}, + }) + assert.Equal(http.StatusBadRequest, status5) + + //pipeline not supported + status6, _ := postForm(handler, url.Values{ + "maxPricePerUnit": {"1"}, + "pixelsPerUnit": {"1"}, + "currency": {"WEI"}, + "pipeline": {"cool-new-pipeline"}, + "modelID": {"default"}, + }) + assert.Equal(http.StatusBadRequest, status6) +} + func TestGetBroadcastConfigHandler(t *testing.T) { assert := assert.New(t) - BroadcastCfg.maxPrice = core.NewFixedPrice(big.NewRat(1, 2)) + BroadcastCfg.SetMaxPrice(core.NewFixedPrice(big.NewRat(1, 2))) BroadcastJobVideoProfiles = []ffmpeg.VideoProfile{ ffmpeg.VideoProfileLookup["P240p25fps16x9"], } diff --git a/server/live_payment.go b/server/live_payment.go new file mode 100644 index 0000000000..0e20f48216 --- /dev/null +++ b/server/live_payment.go @@ -0,0 +1,152 @@ +package server + +import ( + "context" + "errors" + "io" + "math/big" + "net/http" + "time" + + ethcommon "github.com/ethereum/go-ethereum/common" + "github.com/golang/protobuf/proto" + "github.com/livepeer/go-livepeer/clog" + "github.com/livepeer/go-livepeer/common" + "github.com/livepeer/go-livepeer/core" + "github.com/livepeer/go-livepeer/monitor" + "github.com/livepeer/go-livepeer/net" + "github.com/livepeer/lpms/stream" +) + +const paymentRequestTimeout = 1 * time.Minute + +type SegmentInfoSender struct { + sess *BroadcastSession + inPixels int64 + priceInfo *net.PriceInfo +} + +type SegmentInfoReceiver struct { + sender ethcommon.Address + sessionID string + inPixels int64 + priceInfo *net.PriceInfo +} + +// LivePaymentSender is used in Gateway to send payment to Orchestrator +type LivePaymentSender interface { + // SendPayment process the streamInfo and sends a payment to Orchestrator if needed + SendPayment(ctx context.Context, segmentInfo *SegmentInfoSender) error +} + +// LivePaymentReceiver is used in Orchestrator to account for each processed segment +type LivePaymentReceiver interface { + // AccountSegment checks if the stream is paid and if not it returns error, so that stream can be stopped + AccountSegment(ctx context.Context, segmentInfo *SegmentInfoReceiver) error +} + +type livePaymentSender struct { + segmentsToPayUpfront int64 +} + +type livePaymentReceiver struct { + orchestrator Orchestrator +} + +func (r *livePaymentSender) SendPayment(ctx context.Context, segmentInfo *SegmentInfoSender) error { + sess := segmentInfo.sess + + if err := refreshSessionIfNeeded(ctx, sess); err != nil { + return err + } + + fee := calculateFee(segmentInfo.inPixels, segmentInfo.priceInfo) + + // We pay a few segments upfront to avoid race condition between payment and segment processing + minCredit := new(big.Rat).Mul(fee, new(big.Rat).SetInt64(r.segmentsToPayUpfront)) + balUpdate, err := newBalanceUpdate(sess, minCredit) + if err != nil { + return err + } + balUpdate.Debit = fee + balUpdate.Status = ReceivedChange + defer completeBalanceUpdate(sess, balUpdate) + + // Generate payment tickets + payment, err := genPayment(ctx, sess, balUpdate.NumTickets) + if err != nil { + clog.Errorf(ctx, "Could not create payment err=%q", err) + if monitor.Enabled { + monitor.PaymentCreateError(ctx) + } + return err + } + + // Generate segment credentials with an empty segment + segCreds, err := genSegCreds(sess, &stream.HLSSegment{}, nil, false) + if err != nil { + return err + } + + // Send payment to Orchestrator + url := sess.OrchestratorInfo.Transcoder + req, err := http.NewRequestWithContext(ctx, "POST", url+"/payment", nil) + if err != nil { + clog.Errorf(ctx, "Could not generate payment request to orch=%s", url) + return err + } + req.Header.Set(paymentHeader, payment) + req.Header.Set(segmentHeader, segCreds) + resp, err := sendReqWithTimeout(req, paymentRequestTimeout) + if err != nil { + clog.Errorf(ctx, "Could not send payment to orch=%s err=%q", url, err) + return err + } + defer resp.Body.Close() + if resp.StatusCode != http.StatusOK { + clog.Errorf(ctx, "Orchestrator did not accept payment status=%d", resp.StatusCode) + return err + } + + if monitor.Enabled { + monitor.TicketValueSent(ctx, balUpdate.NewCredit) + monitor.TicketsSent(ctx, balUpdate.NumTickets) + } + + data, err := io.ReadAll(resp.Body) + if err != nil { + clog.Errorf(ctx, "Could not read response from orchestrator=%s err=%q", url, err) + return err + } + + var pr net.PaymentResult + err = proto.Unmarshal(data, &pr) + if err != nil { + clog.Errorf(ctx, "Could not unmarshal response from orchestrator=%s err=%q", url) + return err + } + + // Update session to preserve the same AuthToken.SessionID between payments + updateSession(sess, &ReceivedTranscodeResult{Info: pr.Info}) + + clog.V(common.DEBUG).Infof(ctx, "Payment sent to orchestrator=%s", url) + return nil +} + +func (r *livePaymentReceiver) AccountPayment( + ctx context.Context, segmentInfo *SegmentInfoReceiver) error { + fee := calculateFee(segmentInfo.inPixels, segmentInfo.priceInfo) + + balance := r.orchestrator.Balance(segmentInfo.sender, core.ManifestID(segmentInfo.sessionID)) + if balance == nil || balance.Cmp(fee) < 0 { + return errors.New("insufficient balance") + } + r.orchestrator.DebitFees(segmentInfo.sender, core.ManifestID(segmentInfo.sessionID), segmentInfo.priceInfo, segmentInfo.inPixels) + clog.V(common.DEBUG).Infof(ctx, "Accounted payment for sessionID=%s, fee=%s", segmentInfo.sessionID, fee.FloatString(0)) + return nil +} + +func calculateFee(inPixels int64, price *net.PriceInfo) *big.Rat { + priceRat := big.NewRat(price.GetPricePerUnit(), price.GetPixelsPerUnit()) + return priceRat.Mul(priceRat, big.NewRat(inPixels, 1)) +} diff --git a/server/live_payment_test.go b/server/live_payment_test.go new file mode 100644 index 0000000000..4d93f30ad4 --- /dev/null +++ b/server/live_payment_test.go @@ -0,0 +1,145 @@ +package server + +import ( + "context" + ethcommon "github.com/ethereum/go-ethereum/common" + "github.com/golang/protobuf/proto" + "github.com/livepeer/go-livepeer/core" + "github.com/livepeer/go-livepeer/net" + "github.com/livepeer/go-livepeer/pm" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" + "math/big" + "net/http" + "testing" + "time" +) + +func TestSendPayment(t *testing.T) { + require := require.New(t) + + // given + + // Stub Orchestrator + ts, mux := stubTLSServer() + defer ts.Close() + tr := &net.PaymentResult{ + Info: &net.OrchestratorInfo{ + Transcoder: ts.URL, + PriceInfo: &net.PriceInfo{PricePerUnit: 7, PixelsPerUnit: 7}, + TicketParams: &net.TicketParams{ExpirationBlock: big.NewInt(100).Bytes()}, + AuthToken: stubAuthToken, + }, + } + buf, err := proto.Marshal(tr) + require.Nil(err) + + mux.HandleFunc("/payment", func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusOK) + w.Write(buf) + }) + + // Stub session + sess := StubBroadcastSession(ts.URL) + sess.Sender = mockSender() + sess.Balances = core.NewAddressBalances(1 * time.Minute) + sess.Balance = core.NewBalance(ethcommon.BytesToAddress(sess.OrchestratorInfo.Address), core.ManifestID(sess.OrchestratorInfo.AuthToken.SessionId), sess.Balances) + + // Create Payment sender and segment info + paymentSender := livePaymentSender{ + segmentsToPayUpfront: 10, + } + segmentInfo := &SegmentInfoSender{ + sess: sess, + inPixels: 1000000, + priceInfo: &net.PriceInfo{ + PricePerUnit: 1, + PixelsPerUnit: 1, + }, + } + + // when + err = paymentSender.SendPayment(context.TODO(), segmentInfo) + + // then + require.Nil(err) + // One segment costs 1000000 + // Paid upfront for 10 segments => 10000000 + // Spent cost for 1 segment => 1000000 + // The balance should be 9000000 + balance := sess.Balances.Balance(ethcommon.BytesToAddress(sess.OrchestratorInfo.Address), core.ManifestID(sess.OrchestratorInfo.AuthToken.SessionId)) + require.Equal(new(big.Rat).SetInt64(9000000), balance) +} + +func mockSender() pm.Sender { + sender := &pm.MockSender{} + sender.On("StartSession", mock.Anything).Return("foo") + sender.On("StopSession", mock.Anything).Times(3) + sender.On("EV", mock.Anything).Return(big.NewRat(1000000, 1), nil) + sender.On("CreateTicketBatch", mock.Anything, mock.Anything).Return(defaultTicketBatch(), nil) + sender.On("ValidateTicketParams", mock.Anything).Return(nil) + return sender +} + +func TestAccountPayment(t *testing.T) { + require := require.New(t) + + tests := []struct { + name string + credit *big.Rat + expErr bool + }{ + { + name: "No credit", + credit: nil, + expErr: true, + }, + { + name: "Insufficient balance", + credit: new(big.Rat).SetInt64(900000), + expErr: true, + }, + { + name: "Sufficient balance", + credit: new(big.Rat).SetInt64(1100000), + expErr: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // given + sessionID := "abcdef" + sender := ethcommon.HexToAddress("0x0000000000000000000000000000000000000001") + segmentInfo := &SegmentInfoReceiver{ + sender: sender, + sessionID: sessionID, + inPixels: 1000000, + priceInfo: &net.PriceInfo{ + PricePerUnit: 1, + PixelsPerUnit: 1, + }, + } + + node, _ := core.NewLivepeerNode(nil, "", nil) + balances := core.NewAddressBalances(1 * time.Minute) + node.Balances = balances + orch := core.NewOrchestrator(node, nil) + + paymentReceiver := livePaymentReceiver{orchestrator: orch} + if tt.credit != nil { + node.Balances.Credit(sender, core.ManifestID(sessionID), tt.credit) + } + + // when + err := paymentReceiver.AccountPayment(context.TODO(), segmentInfo) + + // then + if tt.expErr { + require.Error(err, "insufficient balance") + } else { + require.Nil(err) + } + }) + } +} diff --git a/server/mediaserver.go b/server/mediaserver.go index 7bdc2e2686..5bd7b5a2f9 100644 --- a/server/mediaserver.go +++ b/server/mediaserver.go @@ -62,6 +62,8 @@ const StreamKeyBytes = 6 const SegLen = 2 * time.Second const BroadcastRetry = 15 * time.Second +const AISessionManagerTTL = 10 * time.Minute + var BroadcastJobVideoProfiles = []ffmpeg.VideoProfile{ffmpeg.P240p30fps4x3, ffmpeg.P360p30fps16x9} var AuthWebhookURL *url.URL @@ -111,6 +113,8 @@ type LivepeerServer struct { ExposeCurrentManifest bool recordingsAuthResponses *cache.Cache + AISessionManager *AISessionManager + // Thread sensitive fields. All accesses to the // following fields should be protected by `connectionLock` rtmpConnections map[core.ManifestID]*rtmpConnection @@ -184,9 +188,12 @@ func NewLivepeerServer(rtmpAddr string, lpNode *core.LivepeerNode, httpIngest bo rtmpConnections: make(map[core.ManifestID]*rtmpConnection), internalManifests: make(map[core.ManifestID]core.ManifestID), recordingsAuthResponses: cache.New(time.Hour, 2*time.Hour), + AISessionManager: NewAISessionManager(lpNode, AISessionManagerTTL), } if lpNode.NodeType == core.BroadcasterNode && httpIngest { opts.HttpMux.HandleFunc("/live/", ls.HandlePush) + + startAIMediaServer(ls) } opts.HttpMux.HandleFunc("/recordings/", ls.HandleRecordings) return ls, nil diff --git a/server/mediaserver_test.go b/server/mediaserver_test.go index 09f4f53370..16b4d91e23 100644 --- a/server/mediaserver_test.go +++ b/server/mediaserver_test.go @@ -654,7 +654,7 @@ func TestCreateRTMPStreamHandlerWebhook(t *testing.T) { require.Error(t, err) assert.Nil(sid) - ts17 := makeServer(`{"manifestID":"a3", "objectStore": "s3+http://us:pass@object.store/path", "recordObjectStore": "s3+http://us:pass@record.store"}`) + ts17 := makeServer(`{"manifestID":"a3", "objectStore": "s3+http://us:pass@object.store/path", "recordObjectStore": "s3+http://us:pass@record.store/bucket"}`) defer ts17.Close() id4, err := createSid(u) require.NoError(t, err) diff --git a/server/ot_rpc.go b/server/ot_rpc.go index 62502ce256..871fe50cc0 100644 --- a/server/ot_rpc.go +++ b/server/ot_rpc.go @@ -166,7 +166,7 @@ func runTranscode(n *core.LivepeerNode, orchAddr string, httpc *http.Client, not sendTranscodeResult(ctx, n, orchAddr, httpc, notify, contentType, &body, tData, errCapabilities) return } - data, err := core.GetSegmentData(ctx, notify.Url) + data, err := core.DownloadData(ctx, notify.Url) if err != nil { clog.Errorf(ctx, "Transcoder cannot get segment from taskId=%d url=%s err=%q", notify.TaskId, notify.Url, err) sendTranscodeResult(ctx, n, orchAddr, httpc, notify, contentType, &body, tData, err) diff --git a/server/rpc.go b/server/rpc.go index 6c5d24637c..ca9ca05f74 100644 --- a/server/rpc.go +++ b/server/rpc.go @@ -16,11 +16,13 @@ import ( "google.golang.org/grpc" "google.golang.org/grpc/credentials" + "github.com/livepeer/ai-worker/worker" "github.com/livepeer/go-livepeer/clog" "github.com/livepeer/go-livepeer/common" "github.com/livepeer/go-livepeer/core" "github.com/livepeer/go-livepeer/net" "github.com/livepeer/go-livepeer/pm" + "github.com/livepeer/go-livepeer/trickle" "github.com/livepeer/go-tools/drivers" ffmpeg "github.com/livepeer/lpms/ffmpeg" "github.com/livepeer/lpms/stream" @@ -50,16 +52,32 @@ type Orchestrator interface { Sign([]byte) ([]byte, error) VerifySig(ethcommon.Address, string, []byte) bool CheckCapacity(core.ManifestID) error + CheckAICapacity(pipeline, modelID string) bool TranscodeSeg(context.Context, *core.SegTranscodingMetadata, *stream.HLSSegment) (*core.TranscodeResult, error) ServeTranscoder(stream net.Transcoder_RegisterTranscoderServer, capacity int, capabilities *net.Capabilities) TranscoderResults(job int64, res *core.RemoteTranscoderResult) + ServeAIWorker(stream net.AIWorker_RegisterAIWorkerServer, capabilities *net.Capabilities) + AIResults(job int64, res *core.RemoteAIWorkerResult) ProcessPayment(ctx context.Context, payment net.Payment, manifestID core.ManifestID) error TicketParams(sender ethcommon.Address, priceInfo *net.PriceInfo) (*net.TicketParams, error) PriceInfo(sender ethcommon.Address, manifestID core.ManifestID) (*net.PriceInfo, error) + PriceInfoForCaps(sender ethcommon.Address, manifestID core.ManifestID, caps *net.Capabilities) (*net.PriceInfo, error) SufficientBalance(addr ethcommon.Address, manifestID core.ManifestID) bool DebitFees(addr ethcommon.Address, manifestID core.ManifestID, price *net.PriceInfo, pixels int64) + Balance(addr ethcommon.Address, manifestID core.ManifestID) *big.Rat Capabilities() *net.Capabilities AuthToken(sessionID string, expiration int64) *net.AuthToken + CreateStorageForRequest(requestID string) error + GetStorageForRequest(requestID string) (drivers.OSSession, bool) + TextToImage(ctx context.Context, requestID string, req worker.GenTextToImageJSONRequestBody) (interface{}, error) + ImageToImage(ctx context.Context, requestID string, req worker.GenImageToImageMultipartRequestBody) (interface{}, error) + ImageToVideo(ctx context.Context, requestID string, req worker.GenImageToVideoMultipartRequestBody) (interface{}, error) + Upscale(ctx context.Context, requestID string, req worker.GenUpscaleMultipartRequestBody) (interface{}, error) + AudioToText(ctx context.Context, requestID string, req worker.GenAudioToTextMultipartRequestBody) (interface{}, error) + LLM(ctx context.Context, requestID string, req worker.GenLLMFormdataRequestBody) (interface{}, error) + SegmentAnything2(ctx context.Context, requestID string, req worker.GenSegmentAnything2MultipartRequestBody) (interface{}, error) + ImageToText(ctx context.Context, requestID string, req worker.GenImageToTextMultipartRequestBody) (interface{}, error) + TextToSpeech(ctx context.Context, requestID string, req worker.GenTextToSpeechJSONRequestBody) (interface{}, error) } // Balance describes methods for a session's balance maintenance @@ -157,9 +175,11 @@ type lphttp struct { orchestrator Orchestrator orchRPC *grpc.Server transRPC *http.ServeMux + trickleSrv *trickle.Server node *core.LivepeerNode net.UnimplementedOrchestratorServer net.UnimplementedTranscoderServer + net.UnimplementedAIWorkerServer } func (h *lphttp) EndTranscodingSession(ctx context.Context, request *net.EndTranscodingSessionRequest) (*net.EndTranscodingSessionResponse, error) { @@ -185,7 +205,7 @@ func (h *lphttp) Ping(context context.Context, req *net.PingPong) (*net.PingPong } // XXX do something about the implicit start of the http mux? this smells -func StartTranscodeServer(orch Orchestrator, bind string, mux *http.ServeMux, workDir string, acceptRemoteTranscoders bool, n *core.LivepeerNode) error { +func StartTranscodeServer(orch Orchestrator, bind string, mux *http.ServeMux, workDir string, acceptRemoteTranscoders bool, acceptRemoteAIWorkers bool, n *core.LivepeerNode) error { s := grpc.NewServer() lp := lphttp{ orchestrator: orch, @@ -195,11 +215,18 @@ func StartTranscodeServer(orch Orchestrator, bind string, mux *http.ServeMux, wo } net.RegisterOrchestratorServer(s, &lp) lp.transRPC.HandleFunc("/segment", lp.ServeSegment) + lp.transRPC.HandleFunc("/payment", lp.Payment) if acceptRemoteTranscoders { net.RegisterTranscoderServer(s, &lp) lp.transRPC.HandleFunc("/transcodeResults", lp.TranscodeResults) } + startAIServer(lp) + if acceptRemoteAIWorkers { + net.RegisterAIWorkerServer(s, &lp) + lp.transRPC.Handle("/aiResults", lp.AIResults()) + } + cert, key, err := getCert(orch.ServiceURI(), workDir) if err != nil { return err @@ -253,14 +280,14 @@ func ping(context context.Context, req *net.PingPong, orch Orchestrator) (*net.P } // GetOrchestratorInfo - the broadcaster calls GetOrchestratorInfo which invokes GetOrchestrator on the orchestrator -func GetOrchestratorInfo(ctx context.Context, bcast common.Broadcaster, orchestratorServer *url.URL) (*net.OrchestratorInfo, error) { +func GetOrchestratorInfo(ctx context.Context, bcast common.Broadcaster, orchestratorServer *url.URL, caps *net.Capabilities) (*net.OrchestratorInfo, error) { c, conn, err := startOrchestratorClient(ctx, orchestratorServer) if err != nil { return nil, err } defer conn.Close() - req, err := genOrchestratorReq(bcast) + req, err := genOrchestratorReq(bcast, caps) r, err := c.GetOrchestrator(ctx, req) if err != nil { return nil, errors.Wrapf(err, "Could not get orchestrator orch=%v", orchestratorServer) @@ -304,12 +331,12 @@ func startOrchestratorClient(ctx context.Context, uri *url.URL) (net.Orchestrato return c, conn, nil } -func genOrchestratorReq(b common.Broadcaster) (*net.OrchestratorRequest, error) { +func genOrchestratorReq(b common.Broadcaster, caps *net.Capabilities) (*net.OrchestratorRequest, error) { sig, err := b.Sign([]byte(fmt.Sprintf("%v", b.Address().Hex()))) if err != nil { return nil, err } - return &net.OrchestratorRequest{Address: b.Address().Bytes(), Sig: sig}, nil + return &net.OrchestratorRequest{Address: b.Address().Bytes(), Sig: sig, Capabilities: caps}, nil } func genEndSessionRequest(sess *BroadcastSession) (*net.EndTranscodingSessionRequest, error) { @@ -327,7 +354,11 @@ func getOrchestrator(orch Orchestrator, req *net.OrchestratorRequest) (*net.Orch } // currently, orchestrator == transcoder - return orchestratorInfo(orch, addr, orch.ServiceURI().String(), "") + if req.Capabilities == nil { + return orchestratorInfo(orch, addr, orch.ServiceURI().String(), "") + } + + return orchestratorInfoWithCaps(orch, addr, orch.ServiceURI().String(), "", req.Capabilities) } func endTranscodingSession(node *core.LivepeerNode, orch Orchestrator, req *net.EndTranscodingSessionRequest) (*net.EndTranscodingSessionResponse, error) { @@ -350,9 +381,23 @@ func getPriceInfo(orch Orchestrator, addr ethcommon.Address, manifestID core.Man } func orchestratorInfo(orch Orchestrator, addr ethcommon.Address, serviceURI string, manifestID core.ManifestID) (*net.OrchestratorInfo, error) { - priceInfo, err := getPriceInfo(orch, addr, manifestID) - if err != nil { - return nil, err + return orchestratorInfoWithCaps(orch, addr, serviceURI, manifestID, nil) +} + +func orchestratorInfoWithCaps(orch Orchestrator, addr ethcommon.Address, serviceURI string, manifestID core.ManifestID, caps *net.Capabilities) (*net.OrchestratorInfo, error) { + var priceInfo *net.PriceInfo + if caps == nil { + var err error + priceInfo, err = getPriceInfo(orch, addr, manifestID) + if err != nil { + return nil, err + } + } else { + var err error + priceInfo, err = orch.PriceInfoForCaps(addr, manifestID, caps) + if err != nil { + return nil, err + } } params, err := orch.TicketParams(addr, priceInfo) @@ -489,8 +534,6 @@ func coreSegMetadata(segData *net.SegData) (*core.SegTranscodingMetadata, error) profiles, err = makeFfmpegVideoProfiles(segData.FullProfiles2) } else if len(segData.FullProfiles) > 0 { profiles, err = makeFfmpegVideoProfiles(segData.FullProfiles) - } else if len(segData.Profiles) > 0 { - profiles, err = common.BytesToVideoProfile(segData.Profiles) } if err != nil { glog.Error("Unable to deserialize profiles ", err) diff --git a/server/rpc_test.go b/server/rpc_test.go index c0832a0c46..162dacc2e2 100644 --- a/server/rpc_test.go +++ b/server/rpc_test.go @@ -25,6 +25,7 @@ import ( "github.com/golang/protobuf/proto" + "github.com/livepeer/ai-worker/worker" "github.com/livepeer/go-livepeer/common" "github.com/livepeer/go-livepeer/core" "github.com/livepeer/go-livepeer/crypto" @@ -148,6 +149,14 @@ func (r *stubOrchestrator) SufficientBalance(addr ethcommon.Address, manifestID func (r *stubOrchestrator) DebitFees(addr ethcommon.Address, manifestID core.ManifestID, price *net.PriceInfo, pixels int64) { } +func (r *stubOrchestrator) Balance(addr ethcommon.Address, manifestID core.ManifestID) *big.Rat { + return big.NewRat(0, 1) +} + +func (o *mockOrchestrator) Balance(addr ethcommon.Address, manifestID core.ManifestID) *big.Rat { + return big.NewRat(0, 1) +} + func (r *stubOrchestrator) Capabilities() *net.Capabilities { if r.caps != nil { return r.caps.ToNetCapabilities() @@ -183,6 +192,50 @@ func (r *stubOrchestrator) TranscoderResults(job int64, res *core.RemoteTranscod func (r *stubOrchestrator) TranscoderSecret() string { return "" } +func (r *stubOrchestrator) PriceInfoForCaps(sender ethcommon.Address, manifestID core.ManifestID, caps *net.Capabilities) (*net.PriceInfo, error) { + return &net.PriceInfo{PricePerUnit: 4, PixelsPerUnit: 1}, nil +} +func (r *stubOrchestrator) TextToImage(ctx context.Context, requestID string, req worker.GenTextToImageJSONRequestBody) (interface{}, error) { + return nil, nil +} +func (r *stubOrchestrator) ImageToImage(ctx context.Context, requestID string, req worker.GenImageToImageMultipartRequestBody) (interface{}, error) { + return nil, nil +} +func (r *stubOrchestrator) ImageToVideo(ctx context.Context, requestID string, req worker.GenImageToVideoMultipartRequestBody) (interface{}, error) { + return nil, nil +} +func (r *stubOrchestrator) Upscale(ctx context.Context, requestID string, req worker.GenUpscaleMultipartRequestBody) (interface{}, error) { + return nil, nil +} +func (r *stubOrchestrator) AudioToText(ctx context.Context, requestID string, req worker.GenAudioToTextMultipartRequestBody) (interface{}, error) { + return nil, nil +} +func (r *stubOrchestrator) LLM(ctx context.Context, requestID string, req worker.GenLLMFormdataRequestBody) (interface{}, error) { + return nil, nil +} +func (r *stubOrchestrator) SegmentAnything2(ctx context.Context, requestID string, req worker.GenSegmentAnything2MultipartRequestBody) (interface{}, error) { + return nil, nil +} +func (r *stubOrchestrator) ImageToText(ctx context.Context, requestID string, req worker.GenImageToTextMultipartRequestBody) (interface{}, error) { + return nil, nil +} +func (r *stubOrchestrator) TextToSpeech(ctx context.Context, requestID string, req worker.GenTextToSpeechJSONRequestBody) (interface{}, error) { + return nil, nil +} + +func (r *stubOrchestrator) CheckAICapacity(pipeline, modelID string) bool { + return true +} +func (r *stubOrchestrator) AIResults(job int64, res *core.RemoteAIWorkerResult) { +} +func (r *stubOrchestrator) CreateStorageForRequest(requestID string) error { + return nil +} +func (r *stubOrchestrator) GetStorageForRequest(requestID string) (drivers.OSSession, bool) { + return drivers.NewMockOSSession(), true +} +func (r *stubOrchestrator) ServeAIWorker(stream net.AIWorker_RegisterAIWorkerServer, capabilities *net.Capabilities) { +} func stubBroadcaster2() *stubOrchestrator { return newStubOrchestrator() // lazy; leverage subtyping for interface commonalities } @@ -192,7 +245,7 @@ func TestRPCTranscoderReq(t *testing.T) { o := newStubOrchestrator() b := stubBroadcaster2() - req, err := genOrchestratorReq(b) + req, err := genOrchestratorReq(b, nil) if err != nil { t.Error("Unable to create orchestrator req ", req) } @@ -224,7 +277,7 @@ func TestRPCTranscoderReq(t *testing.T) { // error signing b.signErr = fmt.Errorf("Signing error") - _, err = genOrchestratorReq(b) + _, err = genOrchestratorReq(b, nil) if err == nil { t.Error("Did not expect to generate a orchestrator request with invalid address") } @@ -336,9 +389,6 @@ func TestRPCSeg(t *testing.T) { } } - // corrupt profiles - corruptSegData(&net.SegData{Profiles: []byte("abc"), AuthToken: authToken}, common.ErrProfile) - // corrupt sig sd := &net.SegData{ManifestId: []byte(s.Params.ManifestID), AuthToken: authToken} corruptSegData(sd, errSegSig) // missing sig @@ -1345,7 +1395,50 @@ func (o *mockOrchestrator) AuthToken(sessionID string, expiration int64) *net.Au } return nil } +func (r *mockOrchestrator) PriceInfoForCaps(sender ethcommon.Address, manifestID core.ManifestID, caps *net.Capabilities) (*net.PriceInfo, error) { + return &net.PriceInfo{PricePerUnit: 4, PixelsPerUnit: 1}, nil +} +func (r *mockOrchestrator) TextToImage(ctx context.Context, requestID string, req worker.GenTextToImageJSONRequestBody) (interface{}, error) { + return nil, nil +} +func (r *mockOrchestrator) ImageToImage(ctx context.Context, requestID string, req worker.GenImageToImageMultipartRequestBody) (interface{}, error) { + return nil, nil +} +func (r *mockOrchestrator) ImageToVideo(ctx context.Context, requestID string, req worker.GenImageToVideoMultipartRequestBody) (interface{}, error) { + return nil, nil +} +func (r *mockOrchestrator) Upscale(ctx context.Context, requestID string, req worker.GenUpscaleMultipartRequestBody) (interface{}, error) { + return nil, nil +} +func (r *mockOrchestrator) AudioToText(ctx context.Context, requestID string, req worker.GenAudioToTextMultipartRequestBody) (interface{}, error) { + return nil, nil +} +func (r *mockOrchestrator) LLM(ctx context.Context, requestID string, req worker.GenLLMFormdataRequestBody) (interface{}, error) { + return nil, nil +} +func (r *mockOrchestrator) SegmentAnything2(ctx context.Context, requestID string, req worker.GenSegmentAnything2MultipartRequestBody) (interface{}, error) { + return nil, nil +} +func (r *mockOrchestrator) ImageToText(ctx context.Context, requestID string, req worker.GenImageToTextMultipartRequestBody) (interface{}, error) { + return nil, nil +} +func (r *mockOrchestrator) TextToSpeech(ctx context.Context, requestID string, req worker.GenTextToSpeechJSONRequestBody) (interface{}, error) { + return nil, nil +} +func (r *mockOrchestrator) CheckAICapacity(pipeline, modelID string) bool { + return true +} +func (r *mockOrchestrator) AIResults(job int64, res *core.RemoteAIWorkerResult) { +} +func (r *mockOrchestrator) CreateStorageForRequest(requestID string) error { + return nil +} +func (r *mockOrchestrator) GetStorageForRequest(requestID string) (drivers.OSSession, bool) { + return drivers.NewMockOSSession(), true +} +func (r *mockOrchestrator) ServeAIWorker(stream net.AIWorker_RegisterAIWorkerServer, capabilities *net.Capabilities) { +} func defaultTicketParams() *net.TicketParams { return &net.TicketParams{ Recipient: pm.RandBytes(123), diff --git a/server/segment_rpc.go b/server/segment_rpc.go index 8c266411f9..3ef74cbc0f 100644 --- a/server/segment_rpc.go +++ b/server/segment_rpc.go @@ -68,62 +68,27 @@ var httpClient = &http.Client{ } func (h *lphttp) ServeSegment(w http.ResponseWriter, r *http.Request) { - orch := h.orchestrator - - remoteAddr := getRemoteAddr(r) - ctx := clog.AddVal(r.Context(), clog.ClientIP, remoteAddr) - - payment, err := getPayment(r.Header.Get(paymentHeader)) + payment, segData, oInfo, ctx, err := h.processPaymentAndSegmentHeaders(w, r) if err != nil { - clog.Errorf(ctx, "Could not parse payment") - http.Error(w, err.Error(), http.StatusPaymentRequired) return } - sender := getPaymentSender(payment) - ctx = clog.AddVal(ctx, "sender", sender.Hex()) - - // check the segment sig from the broadcaster - seg := r.Header.Get(segmentHeader) - - segData, ctx, err := verifySegCreds(ctx, orch, seg, sender) - if err != nil { - clog.Errorf(ctx, "Could not verify segment creds err=%q", err) - http.Error(w, err.Error(), http.StatusForbidden) - return - } ctx = clog.AddSeqNo(ctx, uint64(segData.Seq)) - clog.V(common.VERBOSE).Infof(ctx, "Received segment dur=%v", segData.Duration) - if monitor.Enabled { monitor.SegmentEmerged(ctx, 0, uint64(segData.Seq), len(segData.Profiles), segData.Duration.Seconds()) } - if err := orch.ProcessPayment(ctx, payment, core.ManifestID(segData.AuthToken.SessionId)); err != nil { - clog.Errorf(ctx, "error processing payment: %v", err) - http.Error(w, err.Error(), http.StatusBadRequest) - return - } - // Balance check is only necessary if the price is non-zero // We do not need to worry about differentiating between the case where the price is 0 as the default when no price is attached vs. // the case where the price is actually set to 0 because ProcessPayment() should guarantee a price attached - if payment.GetExpectedPrice().GetPricePerUnit() > 0 && !orch.SufficientBalance(sender, core.ManifestID(segData.AuthToken.SessionId)) { + sender := getPaymentSender(payment) + if payment.GetExpectedPrice().GetPricePerUnit() > 0 && !h.orchestrator.SufficientBalance(sender, core.ManifestID(segData.AuthToken.SessionId)) { clog.Errorf(ctx, "Insufficient credit balance for stream") http.Error(w, "Insufficient balance", http.StatusBadRequest) return } - oInfo, err := orchestratorInfo(orch, sender, orch.ServiceURI().String(), core.ManifestID(segData.AuthToken.SessionId)) - if err != nil { - clog.Errorf(ctx, "Error updating orchestrator info - err=%q", err) - http.Error(w, "Internal Server Error", http.StatusInternalServerError) - return - } - // Use existing auth token because new auth tokens should only be sent out in GetOrchestrator() RPC calls - oInfo.AuthToken = segData.AuthToken - // download the segment and check the hash dlStart := time.Now() data, err := common.ReadAtMost(r.Body, common.MaxSegSize) @@ -145,7 +110,7 @@ func (h *lphttp) ServeSegment(w http.ResponseWriter, r *http.Request) { uri = string(data) clog.V(common.DEBUG).Infof(ctx, "Start getting segment from url=%s", uri) start := time.Now() - data, err = core.GetSegmentData(ctx, uri) + data, err = core.DownloadData(ctx, uri) took := time.Since(start) clog.V(common.DEBUG).Infof(ctx, "Getting segment from url=%s took=%s bytes=%d", uri, took, len(data)) if err != nil { @@ -182,7 +147,7 @@ func (h *lphttp) ServeSegment(w http.ResponseWriter, r *http.Request) { Name: uri, } - res, err := orch.TranscodeSeg(ctx, segData, &hlsStream) + res, err := h.orchestrator.TranscodeSeg(ctx, segData, &hlsStream) // Upload to OS and construct segment result set var segments []*net.TranscodedSegmentData @@ -222,7 +187,7 @@ func (h *lphttp) ServeSegment(w http.ResponseWriter, r *http.Request) { } // Debit the fee for the total pixel count - orch.DebitFees(sender, core.ManifestID(segData.AuthToken.SessionId), payment.GetExpectedPrice(), pixels) + h.orchestrator.DebitFees(sender, core.ManifestID(segData.AuthToken.SessionId), payment.GetExpectedPrice(), pixels) if monitor.Enabled { monitor.MilPixelsProcessed(ctx, float64(pixels)/1000000.0) } @@ -254,6 +219,78 @@ func (h *lphttp) ServeSegment(w http.ResponseWriter, r *http.Request) { w.Write(buf) } +// Payment receives payment from Gateway and adds it into the orchestrator's balance +func (h *lphttp) Payment(w http.ResponseWriter, r *http.Request) { + payment, segData, oInfo, ctx, err := h.processPaymentAndSegmentHeaders(w, r) + if err != nil { + return + } + + buf, err := proto.Marshal(&net.PaymentResult{Info: oInfo}) + if err != nil { + clog.Errorf(ctx, "Unable to marshal transcode result err=%q", err) + return + } + clog.V(common.DEBUG).Infof(ctx, "Payment processed, current balance = %s", currentBalanceLog(h, payment, segData)) + + w.Write(buf) +} + +func currentBalanceLog(h *lphttp, payment net.Payment, segData *core.SegTranscodingMetadata) string { + if h == nil || h.node == nil || h.node.Balances == nil || segData == nil || segData.AuthToken == nil { + return "invalid configuration" + } + currentBalance := h.node.Balances.Balance(getPaymentSender(payment), core.ManifestID(segData.AuthToken.SessionId)) + if currentBalance == nil { + return "no balance available" + } + return currentBalance.FloatString(0) +} + +func (h *lphttp) processPaymentAndSegmentHeaders(w http.ResponseWriter, r *http.Request) (net.Payment, *core.SegTranscodingMetadata, *net.OrchestratorInfo, context.Context, error) { + orch := h.orchestrator + + remoteAddr := getRemoteAddr(r) + ctx := clog.AddVal(r.Context(), clog.ClientIP, remoteAddr) + + payment, err := getPayment(r.Header.Get(paymentHeader)) + if err != nil { + clog.Errorf(ctx, "Could not parse payment") + http.Error(w, err.Error(), http.StatusPaymentRequired) + return net.Payment{}, nil, nil, ctx, err + } + + sender := getPaymentSender(payment) + ctx = clog.AddVal(ctx, "sender", sender.Hex()) + + // check the segment sig from the broadcaster + seg := r.Header.Get(segmentHeader) + + segData, ctx, err := verifySegCreds(ctx, orch, seg, sender) + if err != nil { + clog.Errorf(ctx, "Could not verify segment creds err=%q", err) + http.Error(w, err.Error(), http.StatusForbidden) + return net.Payment{}, nil, nil, ctx, err + } + + if err := orch.ProcessPayment(ctx, payment, core.ManifestID(segData.AuthToken.SessionId)); err != nil { + clog.Errorf(ctx, "error processing payment: %v", err) + http.Error(w, err.Error(), http.StatusBadRequest) + return net.Payment{}, nil, nil, ctx, err + } + + oInfo, err := orchestratorInfo(orch, sender, orch.ServiceURI().String(), core.ManifestID(segData.AuthToken.SessionId)) + if err != nil { + clog.Errorf(ctx, "Error updating orchestrator info - err=%q", err) + http.Error(w, "Internal Server Error", http.StatusInternalServerError) + return net.Payment{}, nil, nil, ctx, err + } + // Use existing auth token because new auth tokens should only be sent out in GetOrchestrator() RPC calls + oInfo.AuthToken = segData.AuthToken + + return payment, segData, oInfo, ctx, nil +} + func getPayment(header string) (net.Payment, error) { buf, err := base64.StdEncoding.DecodeString(header) if err != nil { diff --git a/server/segment_rpc_test.go b/server/segment_rpc_test.go index 282e3187dc..a1f54ce822 100644 --- a/server/segment_rpc_test.go +++ b/server/segment_rpc_test.go @@ -220,27 +220,6 @@ func TestVerifySegCreds_Duration(t *testing.T) { assert.Nil(md) } -func TestCoreSegMetadata_Profiles(t *testing.T) { - assert := assert.New(t) - // testing with the following profiles doesn't work: ffmpeg.P720p60fps16x9, ffmpeg.P144p25fps16x9 - profiles := []ffmpeg.VideoProfile{ffmpeg.P576p30fps16x9, ffmpeg.P240p30fps4x3} - segData := &net.SegData{ - ManifestId: []byte("manifestID"), - Profiles: common.ProfilesToTranscodeOpts(profiles), - } - md, err := coreSegMetadata(segData) - assert.Nil(err) - assert.Equal(profiles, md.Profiles) - - // Check error handling with the default invalid Profiles - segData, err = core.NetSegData(&core.SegTranscodingMetadata{}) - assert.Nil(err) - assert.Equal([]byte("invalid"), segData.Profiles) - md, err = coreSegMetadata(segData) - assert.Nil(md) - assert.Equal(common.ErrProfile, err) -} - func TestGenSegCreds_FullProfiles(t *testing.T) { assert := assert.New(t) profiles := []ffmpeg.VideoProfile{ @@ -1225,7 +1204,7 @@ func TestServeSegment_InsufficientBalance(t *testing.T) { orch.On("SufficientBalance", mock.Anything, core.ManifestID(s.OrchestratorInfo.AuthToken.SessionId)).Return(false) url, _ := url.Parse("foo") orch.On("ServiceURI").Return(url) - orch.On("PriceInfo", mock.Anything).Return(nil, errors.New("PriceInfo error")) + orch.On("PriceInfo", mock.Anything).Return(nil, errors.New("PriceInfo error")).Times(1) // Check when price = 0 payment, err := genPayment(context.TODO(), s, 0) @@ -1245,6 +1224,11 @@ func TestServeSegment_InsufficientBalance(t *testing.T) { assert.Equal("Internal Server Error", strings.TrimSpace(string(body))) // Check when price > 0 + orch.On("PriceInfo", mock.Anything).Return(&net.PriceInfo{}, nil).Times(1) + orch.On("TicketParams", mock.Anything, mock.Anything).Return(&net.TicketParams{}, nil) + orch.On("Address").Return(ethcommon.Address{}) + + drivers.NodeStorage = drivers.NewMemoryDriver(nil) s.OrchestratorInfo.PriceInfo = &net.PriceInfo{PricePerUnit: 1, PixelsPerUnit: 1} payment, err = genPayment(context.TODO(), s, 0) require.Nil(err) diff --git a/server/selection.go b/server/selection.go index 985f2d2546..9904d9a7b5 100644 --- a/server/selection.go +++ b/server/selection.go @@ -99,12 +99,13 @@ type MinLSSelector struct { stakeRdr stakeReader selectionAlgorithm common.SelectionAlgorithm perfScore *common.PerfScore + capabilities common.CapabilityComparator minLS float64 } // NewMinLSSelector returns an instance of MinLSSelector configured with a good enough latency score -func NewMinLSSelector(stakeRdr stakeReader, minLS float64, selectionAlgorithm common.SelectionAlgorithm, perfScore *common.PerfScore) *MinLSSelector { +func NewMinLSSelector(stakeRdr stakeReader, minLS float64, selectionAlgorithm common.SelectionAlgorithm, perfScore *common.PerfScore, capabilities common.CapabilityComparator) *MinLSSelector { knownSessions := &sessHeap{} heap.Init(knownSessions) @@ -113,6 +114,7 @@ func NewMinLSSelector(stakeRdr stakeReader, minLS float64, selectionAlgorithm co stakeRdr: stakeRdr, selectionAlgorithm: selectionAlgorithm, perfScore: perfScore, + capabilities: capabilities, minLS: minLS, } } @@ -135,15 +137,12 @@ func (s *MinLSSelector) Select(ctx context.Context) *BroadcastSession { return s.selectUnknownSession(ctx) } - lowestLatencyScoreKnownSession := heap.Pop(s.knownSessions).(*BroadcastSession) - if lowestLatencyScoreKnownSession.LatencyScore <= s.minLS { - // known session has good enough latency score, use it - return lowestLatencyScoreKnownSession + minSess := sess.(*BroadcastSession) + if minSess.LatencyScore > s.minLS && len(s.unknownSessions) > 0 { + return s.selectUnknownSession(ctx) } - // known session does not have good enough latency score, clear the heap and use unknown session - s.knownSessions = &sessHeap{} - return s.selectUnknownSession(ctx) + return heap.Pop(s.knownSessions).(*BroadcastSession) } // Size returns the number of sessions stored by the selector @@ -188,7 +187,8 @@ func (s *MinLSSelector) selectUnknownSession(ctx context.Context) *BroadcastSess prices[addr] = big.NewRat(pi.PricePerUnit, pi.PixelsPerUnit) } } - maxPrice := BroadcastCfg.MaxPrice() + + maxPrice := BroadcastCfg.GetCapabilitiesMaxPrice(s.capabilities) stakes, err := s.stakeRdr.Stakes(addrs) if err != nil { diff --git a/server/selection_test.go b/server/selection_test.go index 9699bb7af5..1241875b27 100644 --- a/server/selection_test.go +++ b/server/selection_test.go @@ -160,7 +160,7 @@ func TestSessHeap(t *testing.T) { func TestMinLSSelector(t *testing.T) { assert := assert.New(t) - sel := NewMinLSSelector(nil, 1.0, stubSelectionAlgorithm{}, nil) + sel := NewMinLSSelector(nil, 1.0, stubSelectionAlgorithm{}, nil, nil) assert.Zero(sel.Size()) sessions := []*BroadcastSession{ @@ -183,39 +183,48 @@ func TestMinLSSelector(t *testing.T) { assert.Equal(sel.Size(), 2) assert.Equal(len(sel.unknownSessions), 2) - // Set sess1.LatencyScore to good enough - sess1.LatencyScore = 0.9 + // Set sess1.LatencyScore to not be good enough + sess1.LatencyScore = 1.1 sel.Complete(sess1) assert.Equal(sel.Size(), 3) assert.Equal(len(sel.unknownSessions), 2) assert.Equal(sel.knownSessions.Len(), 1) - // Select sess1 because it's a known session with good enough latency score - sess := sel.Select(context.TODO()) + // Select from unknownSessions + sess2 := sel.Select(context.TODO()) assert.Equal(sel.Size(), 2) - assert.Equal(len(sel.unknownSessions), 2) - assert.Equal(sel.knownSessions.Len(), 0) + assert.Equal(len(sel.unknownSessions), 1) + assert.Equal(sel.knownSessions.Len(), 1) - // Set sess.LatencyScore to not be good enough - sess.LatencyScore = 1.1 - sel.Complete(sess) + // Set sess2.LatencyScore to be good enough + sess2.LatencyScore = .9 + sel.Complete(sess2) assert.Equal(sel.Size(), 3) - assert.Equal(len(sel.unknownSessions), 2) - assert.Equal(sel.knownSessions.Len(), 1) + assert.Equal(len(sel.unknownSessions), 1) + assert.Equal(sel.knownSessions.Len(), 2) - // Select from unknownSessions, because sess2 does not have a good enough latency score - sess = sel.Select(context.TODO()) - sess.LatencyScore = 1.1 - sel.Complete(sess) + // Select from knownSessions + knownSess := sel.Select(context.TODO()) assert.Equal(sel.Size(), 2) assert.Equal(len(sel.unknownSessions), 1) assert.Equal(sel.knownSessions.Len(), 1) + assert.Equal(knownSess, sess2) - // Select the last unknown session - sess = sel.Select(context.TODO()) - assert.Equal(sel.Size(), 0) + // Set knownSess.LatencyScore to not be good enough + knownSess.LatencyScore = 1.1 + sel.Complete(knownSess) + // Clear unknownSessions + sess := sel.Select(context.TODO()) + sess.LatencyScore = 2.1 + sel.Complete(sess) + assert.Equal(len(sel.unknownSessions), 0) + assert.Equal(sel.knownSessions.Len(), 3) + + // Select from knownSessions + knownSess = sel.Select(context.TODO()) + assert.Equal(sel.Size(), 2) assert.Equal(len(sel.unknownSessions), 0) - assert.Equal(sel.knownSessions.Len(), 0) + assert.Equal(sel.knownSessions.Len(), 2) sel.Clear() assert.Zero(sel.Size()) @@ -227,7 +236,7 @@ func TestMinLSSelector(t *testing.T) { func TestMinLSSelector_RemoveUnknownSession(t *testing.T) { assert := assert.New(t) - sel := NewMinLSSelector(nil, 1.0, stubSelectionAlgorithm{}, nil) + sel := NewMinLSSelector(nil, 1.0, stubSelectionAlgorithm{}, nil, nil) // Use ManifestID to identify each session sessions := []*BroadcastSession{ @@ -328,7 +337,7 @@ func TestMinLSSelector_SelectUnknownSession(t *testing.T) { if tt.perfScores != nil { perfScore = &common.PerfScore{Scores: tt.perfScores} } - sel := NewMinLSSelector(stakeRdr, 1.0, selAlg, perfScore) + sel := NewMinLSSelector(stakeRdr, 1.0, selAlg, perfScore, nil) sel.Add(tt.unknownSessions) sess := sel.selectUnknownSession(context.TODO()) @@ -359,7 +368,7 @@ func session(recipientAddr string) *BroadcastSession { } func TestMinLSSelector_SelectUnknownSession_NilStakeReader(t *testing.T) { - sel := NewMinLSSelector(nil, 1.0, stubSelectionAlgorithm{}, nil) + sel := NewMinLSSelector(nil, 1.0, stubSelectionAlgorithm{}, nil, nil) sessions := make([]*BroadcastSession, 10) for i := 0; i < 10; i++ { diff --git a/server/stub.go b/server/stub.go new file mode 100644 index 0000000000..c0b5ca0fdf --- /dev/null +++ b/server/stub.go @@ -0,0 +1,23 @@ +package server + +import ( + "github.com/livepeer/go-livepeer/net" +) + +type StubCapabilityComparator struct { + NetCaps *net.Capabilities + IsLegacy bool +} + +func (s *StubCapabilityComparator) ToNetCapabilities() *net.Capabilities { + return s.NetCaps +} + +func (s *StubCapabilityComparator) CompatibleWith(other *net.Capabilities) bool { + // Implement the logic for compatibility check if needed + return true +} + +func (s *StubCapabilityComparator) LegacyOnly() bool { + return s.IsLegacy +} diff --git a/server/utils.go b/server/utils.go new file mode 100644 index 0000000000..657010c670 --- /dev/null +++ b/server/utils.go @@ -0,0 +1,24 @@ +package server + +// utils.go contains server utility functions. + +import ( + "encoding/json" + "net/http" + + "github.com/oapi-codegen/runtime" +) + +// Decoder for JSON requests. +func jsonDecoder[T any](req *T, r *http.Request) error { + return json.NewDecoder(r.Body).Decode(req) +} + +// Decoder for Multipart requests. +func multipartDecoder[T any](req *T, r *http.Request) error { + multiRdr, err := r.MultipartReader() + if err != nil { + return err + } + return runtime.BindMultipart(req, *multiRdr) +} diff --git a/server/webserver.go b/server/webserver.go index 9cabbcb970..cf1578b317 100644 --- a/server/webserver.go +++ b/server/webserver.go @@ -49,6 +49,7 @@ func (s *LivepeerServer) cliWebServerHandlers(bindAddr string) *http.ServeMux { mux.Handle("/setBroadcastConfig", mustHaveFormParams(setBroadcastConfigHandler())) mux.Handle("/getBroadcastConfig", getBroadcastConfigHandler()) mux.Handle("/getAvailableTranscodingOptions", getAvailableTranscodingOptionsHandler()) + mux.Handle("/setMaxPriceForCapability", mustHaveFormParams(s.setMaxPriceForCapability(), "maxPricePerUnit", "pixelsPerUnit", "currency", "pipeline", "modelID")) // Rounds mux.Handle("/currentRound", currentRoundHandler(client)) diff --git a/test/ai/audio b/test/ai/audio new file mode 100644 index 0000000000..5111e0c91d --- /dev/null +++ b/test/ai/audio @@ -0,0 +1 @@ +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JOBS5dE9MF9AKCWGxsN3MEAUQQgij9sIZa5MAw5CYlJQQNEKIJ0iCSzMry7NhINPjhpEQgaLrLl5LKZ/HAW0jFX4br28fOBIUKXHFJwXOW8qOcQqssQbWPata02w+3yLPeexu1PZ5JiFHLD7Kxxu1mDzOQu+XPpW29f/gcidWOR0P2f/zosTKPjQOSEr2mH1O1arLLa9mnex1pYq/vdDSC22ts03JveOuw2693Lv50CQ4i16kHVapXv+zOfBUPYGDYyGPIGGRxZjhqGXpUm/VWnZFHnARzmarHGaAKmCI+mdhvmKAvGSIoJrGC4DGDQjgYcTAgDzAoCx4CDCcVj34B7EYweky7yeyAJMZYcxAtCkEDzKCWoPUoEYVAbVwacU2daS7zGNTcxDZjkCzAAQEBX4X+WtRuku5xnhVK4r+zsBNZgV0mdT8ZjMteJnMVoGtQplMCJzKXQFDapX8UCUGXcsM60Sh6bcmdiTlOVPw0WmYCUZfVklE4+ucmJierV2ntaHUbTzT017zkSXWnpZdSiS7LK1at7eaXLYjo+hMTFgyMYl35aYDpbASj7616bNEoyemAcgBgIk1atW1//OgxP5MLBYoAu6Y3q1gOXTp6ToyjrtWXbWahMXqtLoVtVpj9a5bc8cRKjodIySJIIhTCe5MzlrLVrufASjJckxBTUUzLjEwMKqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqoAROyW26iIRiRLHCXIbonwWkFCEsEnH4U6BRyhYhQGIJoXDlFXG5yLXppgXiRpxZZR5BOLi/n7OUWUUWU7GnFlNebJxpRZpRcWzlFllXG5v/3NmpKLLi/6dnNZ2dpOLLKvP3Z3b/+aLdrjcqTmvNzZot43Nlv//uUacWWZef/zosR9KpP56H5LzBOzRpUXm5UlFnoLynhIiaBE0FokgUUKFkF5v/a8qadndtypONOOPjfJxoEUeJVqTEFNRTMuMTAwqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq \ No newline at end of file diff --git a/test/ai/image b/test/ai/image new file mode 100644 index 0000000000..1ae32b457f --- /dev/null +++ b/test/ai/image @@ -0,0 +1 @@ +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 \ No newline at end of file diff --git a/trickle/README.md b/trickle/README.md new file mode 100644 index 0000000000..8455001494 --- /dev/null +++ b/trickle/README.md @@ -0,0 +1,59 @@ +# Trickle Protocol + +Trickle is a segmented publish-subscribe protocol that streams data in realtime, mainly over HTTP. + +Breaking this down: + +1. Data streams are called *channels* , Channels are content agnostic - the data can be video, audio, JSON, logs, a custom format, etc. + +2. Segmented: Data for each channel is sent as discrete *segments*. For example, a video may use a segment for each GOP, or an API may use a segment for each JSON message, or a logging application may split segments on time intervals. The boundaries of each segment are application defined, but segments are preferably standalone such that a request for a single segment should return usable content on its own. + +3. Publish-subscribe: Publishers push segments, and subscribers pull them. + +4. Streaming: Content can be sent by publishers and received by subscribers in real-time as it is generated - data is *trickled* out. + +5. HTTP: Trickle is tied to HTTP with GET / POST semantics, status codes, path based routing, metadata in headers, etc. However, other implementations are possible, such as a local, in-memory trickle client. + +### Protocol Specification + +TODO: more details + +Publishers POST to /channel-name/seq + +Subscribers GET to /channel-name/seq + +The `channel-name` is any valid HTTP path part. + +The `seq` is an integer sequence number indicating the segment, and must increase sequentially without gaps. + +As data is published to `channel-name/seq`,the server will relay the data to all subscribers for `channel-name/seq`. + +Clients are responsible for maintaining their own position in the sequence. + +Servers may opt to keep the last N segments for subscribers to catch up on. + +Servers will 404 if a `channel-name` or a `seq` does not exist. + +Clients may pre-connect the next segment in order to set up the resource and minimize connection set-up time. + +Publishers should only actively send data to one `seq` at a time, although they may still pre-connect to `seq + 1` + +Publishers do not have to push content immeditely after preconnecting, however the server should have some reasonable timeout to avoid excessive idle connections. + +If a subscriber retrieves a segment mid-publish, the server should return all the content it has up until that point, and trickle down the rest as it receives it. + +If a timeout has been hit without sending (or receiving) content, the publisher (or subscriber) can re-connect to the same `seq`. (TODO; also indicate timeout via signaling) + +Servers may offer some grace with leading sequence numbers to avoid data races, eg allowing a GET for `seq+1` if a publisher hasn't yet preconnected that number. + +Publishers are responsible for segmenting content (if necessary) and subscribers are responsible for re-assembling content (if necessary) + +Subscribers can initiate a subscribe with a `seq` of -1 to retrieve the most recent publish. With preconnects, the subscriber may be waiting for the *next* publish. For video this allows clients to eg, start streaming at the live edge of the next GOP. + +Subscribers can retrieve the current `seq` with the `Lp-Trickle-Seq` metadata (HTTP header). This is useful in case `-1` was used to initiate the subscription; the subscribing client can then pre-connect to `Lp-Trickle-Seq + 1` + +Subscribers can initiate a subscribe with a `seq` of -N to get the Nth-from-last segment. (TODO) + +The server should send subscribers `Lp-Trickle-Size` metadata to indicate the size of the content up until now. This allows clients to know where the live edge is, eg video implementations can decode-and-discard frames up until the edge to achieve immediate playback without waiting for the next segment. (TODO) + +The server currently has a special changefeed channel named `_changes` which will send subscribers updates on streams that are added and removed. The changefeed is disabled by default. diff --git a/trickle/local_publisher.go b/trickle/local_publisher.go new file mode 100644 index 0000000000..8c95660844 --- /dev/null +++ b/trickle/local_publisher.go @@ -0,0 +1,75 @@ +package trickle + +import ( + "errors" + "io" + "log/slog" + "sync" +) + +// local (in-memory) publisher for trickle protocol + +type TrickleLocalPublisher struct { + channelName string + mimeType string + server *Server + + mu *sync.Mutex + seq int +} + +func NewLocalPublisher(sm *Server, channelName string, mimeType string) *TrickleLocalPublisher { + return &TrickleLocalPublisher{ + channelName: channelName, + server: sm, + mu: &sync.Mutex{}, + mimeType: mimeType, + } +} + +func (c *TrickleLocalPublisher) CreateChannel() { + c.server.getOrCreateStream(c.channelName, c.mimeType) +} + +func (c *TrickleLocalPublisher) Write(data io.Reader) error { + stream := c.server.getOrCreateStream(c.channelName, c.mimeType) + c.mu.Lock() + seq := c.seq + segment, exists := stream.getForWrite(seq) + if exists { + c.mu.Unlock() + return errors.New("Entry already exists for this sequence") + } + + // before we begin - let's pre-create the next segment + nextSeq := c.seq + 1 + if _, exists = stream.getForWrite(nextSeq); exists { + c.mu.Unlock() + return errors.New("Next entry alredy exists in this sequence") + } + c.seq = nextSeq + c.mu.Unlock() + + // now continue with the show + buf := make([]byte, 1024*32) // 32kb to begin with + totalRead := 0 + for { + n, err := data.Read(buf) + if n > 0 { + segment.writeData(buf[:n]) + totalRead += n + } + if err != nil { + if err == io.EOF { + break + } + slog.Info("Error reading published data", "channel", c.channelName, "seq", seq, "bytes written", totalRead, "err", err) + } + } + segment.close() + return nil +} + +func (c *TrickleLocalPublisher) Close() error { + return c.server.closeStream(c.channelName) +} diff --git a/trickle/local_subscriber.go b/trickle/local_subscriber.go new file mode 100644 index 0000000000..55f6a8dba8 --- /dev/null +++ b/trickle/local_subscriber.go @@ -0,0 +1,77 @@ +package trickle + +import ( + "errors" + "io" + "log/slog" + "strconv" + "sync" +) + +// local (in-memory) subscriber for trickle protocol + +type TrickleData struct { + Reader io.Reader + Metadata map[string]string +} + +type TrickleLocalSubscriber struct { + channelName string + server *Server + + mu *sync.Mutex + seq int +} + +func NewLocalSubscriber(sm *Server, channelName string) *TrickleLocalSubscriber { + return &TrickleLocalSubscriber{ + channelName: channelName, + server: sm, + mu: &sync.Mutex{}, + seq: -1, + } +} + +func (c *TrickleLocalSubscriber) Read() (*TrickleData, error) { + stream, exists := c.server.getStream(c.channelName) + if !exists { + return nil, errors.New("stream not found") + } + c.mu.Lock() + defer c.mu.Unlock() + segment, exists := stream.getForRead(c.seq) + if !exists { + return nil, errors.New("seq not found") + } + c.seq++ + r, w := io.Pipe() + go func() { + subscriber := &SegmentSubscriber{ + segment: segment, + } + for { + data, eof := subscriber.readData() + n, err := w.Write(data) + if err != nil { + slog.Info("Error writing", "channel", c.channelName, "seq", segment.idx, "err", err) + return + } + if n != len(data) { + slog.Info("Did not write enough data to local subscriber", "channel", c.channelName, "seq", segment.idx) + return + } + if eof { + // trigger eof on the reader + w.Close() + return + } + } + }() + return &TrickleData{ + Reader: r, + Metadata: map[string]string{ + "Lp-Trickle-Seq": strconv.Itoa(segment.idx), + "Content-Type": stream.mimeType, + }, // TODO take more metadata from http headers + }, nil +} diff --git a/trickle/trickle_publisher.go b/trickle/trickle_publisher.go new file mode 100644 index 0000000000..c6c41e1cb5 --- /dev/null +++ b/trickle/trickle_publisher.go @@ -0,0 +1,170 @@ +package trickle + +import ( + "crypto/tls" + "fmt" + "io" + "log/slog" + "net/http" + "sync" +) + +// TricklePublisher represents a trickle streaming client +type TricklePublisher struct { + baseURL string + index int // Current index for segments + writeLock sync.Mutex // Mutex to manage concurrent access + pendingPost *pendingPost // Pre-initialized POST request + contentType string +} + +// pendingPost represents a pre-initialized POST request waiting for data +type pendingPost struct { + index int + writer *io.PipeWriter +} + +// NewTricklePublisher creates a new trickle stream client +func NewTricklePublisher(url string) (*TricklePublisher, error) { + c := &TricklePublisher{ + baseURL: url, + contentType: "video/MP2T", + } + p, err := c.preconnect() + if err != nil { + return nil, err + } + c.pendingPost = p + + return c, nil +} + +// Acquire lock to manage access to pendingPost and index +// NB expects to have the lock already since we mutate the index +func (c *TricklePublisher) preconnect() (*pendingPost, error) { + + index := c.index + url := fmt.Sprintf("%s/%d", c.baseURL, index) + + slog.Debug("Preconnecting", "url", url) + + pr, pw := io.Pipe() + req, err := http.NewRequest("POST", url, pr) + if err != nil { + slog.Error("Failed to create request for segment", "url", url, "err", err) + return nil, err + } + req.Header.Set("Content-Type", c.contentType) + + // Start the POST request in a background goroutine + // TODO error handling for these + go func() { + slog.Debug("Initiailzing http client", "idx", index) + // Createa new client to prevent connection reuse + client := http.Client{Transport: &http.Transport{ + // ignore orch certs for now + TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, + }} + resp, err := client.Do(req) + if err != nil { + slog.Error("Failed to complete POST for segment", "url", url, "err", err) + return + } + body, err := io.ReadAll(resp.Body) + if err != nil { + slog.Error("Error reading body", "url", url, "err", err) + } + defer resp.Body.Close() + + if resp.StatusCode != http.StatusOK { + slog.Error("Failed POST segment", "url", url, "status_code", resp.StatusCode, "msg", string(body)) + } else { + slog.Debug("Uploaded segment", "url", url) + } + }() + + c.index += 1 + return &pendingPost{ + writer: pw, + index: index, + }, nil +} + +func (c *TricklePublisher) Close() error { + req, err := http.NewRequest("DELETE", c.baseURL, nil) + if err != nil { + return err + } + resp, err := (&http.Client{Transport: &http.Transport{ + // ignore orch certs for now + TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, + }}).Do(req) + if err != nil { + return err + } + defer resp.Body.Close() + if resp.StatusCode != http.StatusOK { + body, _ := io.ReadAll(resp.Body) + return fmt.Errorf("Failed to delete stream: %v - %s", resp.Status, string(body)) + } + return nil +} + +// Write sends data to the current segment, sets up the next segment concurrently, and blocks until completion +func (c *TricklePublisher) Write(data io.Reader) error { + + // Acquire lock to manage access to pendingPost and index + c.writeLock.Lock() + + // Get the writer to use + pp := c.pendingPost + if pp == nil { + p, err := c.preconnect() + if err != nil { + c.writeLock.Unlock() + return err + } + pp = p + } + writer := pp.writer + index := pp.index + + // Set up the next connection + nextPost, err := c.preconnect() + if err != nil { + c.writeLock.Unlock() + return err + } + c.pendingPost = nextPost + + // Now unlock so the copy does not block + c.writeLock.Unlock() + + // Start streaming data to the current POST request + n, err := io.Copy(writer, data) + if err != nil { + return fmt.Errorf("error streaming data to segment %d: %w", index, err) + } + + slog.Debug("Completed writing", "idx", index, "totalBytes", humanBytes(n)) + + // Close the pipe writer to signal end of data for the current POST request + if err := writer.Close(); err != nil { + return fmt.Errorf("error closing writer for segment %d: %w", index, err) + } + + return nil +} + +func humanBytes(bytes int64) string { + var unit int64 = 1024 + if bytes < unit { + return fmt.Sprintf("%d B", bytes) + } + div, exp := unit, 0 + for n := bytes / unit; n >= unit; n /= unit { + div *= unit + exp++ + } + return fmt.Sprintf("%.1f %cB", float64(bytes)/float64(div), "KMGTPE"[exp]) +} diff --git a/trickle/trickle_server.go b/trickle/trickle_server.go new file mode 100644 index 0000000000..a5c87634a2 --- /dev/null +++ b/trickle/trickle_server.go @@ -0,0 +1,461 @@ +package trickle + +import ( + "bytes" + "encoding/json" + "errors" + "fmt" + "io" + "log/slog" + "net/http" + "strconv" + "sync" + "time" +) + +// TODO sweep idle streams connections + +const CHANGEFEED = "_changes" + +type TrickleServerConfig struct { + BasePath string + Mux *http.ServeMux + Changefeed bool +} + +type Server struct { + mutex sync.RWMutex + streams map[string]*Stream + + // for internal channels + changefeed bool + internalPub *TrickleLocalPublisher +} + +type Stream struct { + mutex sync.RWMutex + segments []*Segment + latestWrite int + name string + mimeType string +} + +type Segment struct { + idx int + mutex *sync.Mutex + cond *sync.Cond + buffer *bytes.Buffer + closed bool +} + +type SegmentSubscriber struct { + segment *Segment + readPos int +} + +type Changefeed struct { + Added []string `json:"added,omitempty"` + Removed []string `json:"removed,omitempty"` +} + +const maxSegmentsPerStream = 5 + +var FirstByteTimeout = errors.New("pending read timeout") + +func applyDefaults(config *TrickleServerConfig) { + if config.BasePath == "" { + config.BasePath = "/" + } + if config.Mux == nil { + config.Mux = http.DefaultServeMux + } +} + +func ConfigureServer(config TrickleServerConfig) *Server { + streamManager := &Server{ + streams: make(map[string]*Stream), + changefeed: config.Changefeed, + } + + // set up changefeed + if streamManager.changefeed { + streamManager.internalPub = NewLocalPublisher(streamManager, CHANGEFEED, "application/json") + streamManager.internalPub.CreateChannel() + } + + applyDefaults(&config) + var ( + mux = config.Mux + basePath = config.BasePath + ) + + mux.HandleFunc("GET "+basePath+"{streamName}/{idx}", streamManager.handleGet) + mux.HandleFunc("POST "+basePath+"{streamName}/{idx}", streamManager.handlePost) + mux.HandleFunc("DELETE "+basePath+"{streamName}", streamManager.handleDelete) + return streamManager +} + +func (sm *Server) getStream(streamName string) (*Stream, bool) { + sm.mutex.RLock() + defer sm.mutex.RUnlock() + stream, exists := sm.streams[streamName] + return stream, exists +} + +func (sm *Server) getOrCreateStream(streamName, mimeType string) *Stream { + sm.mutex.Lock() + + stream, exists := sm.streams[streamName] + if !exists { + stream = &Stream{ + segments: make([]*Segment, maxSegmentsPerStream), + name: streamName, + mimeType: mimeType, + } + sm.streams[streamName] = stream + slog.Info("Creating stream", "stream", streamName) + } + sm.mutex.Unlock() + + // update changefeed + if !exists && sm.changefeed { + jb, _ := json.Marshal(&Changefeed{ + Added: []string{streamName}, + }) + sm.internalPub.Write(bytes.NewReader(jb)) + } + return stream +} + +func (sm *Server) clearAllStreams() { + sm.mutex.Lock() + defer sm.mutex.Unlock() + + // TODO update changefeed + + for _, stream := range sm.streams { + stream.clear() + } + sm.streams = make(map[string]*Stream) +} + +func (s *Stream) clear() { + s.mutex.Lock() + defer s.mutex.Unlock() + for _, segment := range s.segments { + segment.close() + } + s.segments = make([]*Segment, maxSegmentsPerStream) +} + +func (sm *Server) closeStream(streamName string) error { + stream, exists := sm.getStream(streamName) + if !exists { + return errors.New("Invalid stream") + } + + // TODO there is a bit of an issue around session reuse + + stream.clear() + sm.mutex.Lock() + delete(sm.streams, streamName) + sm.mutex.Unlock() + slog.Info("Deleted stream", "streamName", streamName) + + // update changefeed if needed + if !sm.changefeed { + return nil + } + jb, err := json.Marshal(&Changefeed{ + Removed: []string{streamName}, + }) + if err != nil { + return err + } + sm.internalPub.Write(bytes.NewReader(jb)) + return nil +} + +func (sm *Server) handleDelete(w http.ResponseWriter, r *http.Request) { + streamName := r.PathValue("streamName") + if err := sm.closeStream(streamName); err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } +} + +func (sm *Server) handlePost(w http.ResponseWriter, r *http.Request) { + stream := sm.getOrCreateStream(r.PathValue("streamName"), r.Header.Get("Content-Type")) + idx, err := strconv.Atoi(r.PathValue("idx")) + if err != nil { + http.Error(w, "Invalid idx", http.StatusBadRequest) + return + } + stream.handlePost(w, r, idx) +} + +type timeoutReader struct { + body io.Reader + timeout time.Duration + firstByteRead bool +} + +func (tr *timeoutReader) Read(p []byte) (int, error) { + if tr.firstByteRead { + // After the first byte is read, proceed normally + return tr.body.Read(p) + } + + done := make(chan struct{}) + var n int + var err error + + go func() { + n, err = tr.body.Read(p) + close(done) + }() + + select { + case <-done: + if n > 0 { + tr.firstByteRead = true + } + return n, err + case <-time.After(tr.timeout): + return 0, FirstByteTimeout + } +} + +// Handle post requests for a given index +func (s *Stream) handlePost(w http.ResponseWriter, r *http.Request, idx int) { + segment, exists := s.getForWrite(idx) + if exists { + slog.Warn("Overwriting existing entry", "idx", idx) + // Overwrite anything that exists now. TODO figure out a safer behavior? + http.Error(w, "Entry already exists for this index", http.StatusBadRequest) + return + } + + // Wrap the request body with the custom timeoutReader so we can send + // provisional headers (keepalives) until receiving the first byte + reader := &timeoutReader{ + body: r.Body, + // This can't be too short for now but ideally it'd be like 1 second + // https://github.com/golang/go/issues/65035 + timeout: 10 * time.Second, + } + defer r.Body.Close() + + buf := make([]byte, 1024*32) // 32kb to begin with + totalRead := 0 + for { + n, err := reader.Read(buf) + if n > 0 { + segment.writeData(buf[:n]) + if n == len(buf) && n < 1024*1024 { // 1 MB max + // filled the buffer, so double it for efficiency + buf = make([]byte, len(buf)*2) + } + totalRead += n + } + if err != nil { + if err == FirstByteTimeout { + // Keepalive via provisional headers + slog.Info("Sending provisional headers for", "stream", s.name, "idx", idx) + w.WriteHeader(http.StatusContinue) + continue + } else if err == io.EOF { + break + } + slog.Info("Error reading POST body", "stream", s.name, "idx", idx, "bytes written", totalRead, "err", err) + http.Error(w, "Server error", http.StatusInternalServerError) + return + } + } + + // Mark segment as closed + segment.close() +} + +func (s *Stream) getForWrite(idx int) (*Segment, bool) { + s.mutex.Lock() + defer s.mutex.Unlock() + if idx == -1 { + idx = s.latestWrite + } else { + s.latestWrite = idx + } + slog.Info("POST segment", "stream", s.name, "idx", idx, "latest", s.latestWrite) + segmentPos := idx % maxSegmentsPerStream + if segment := s.segments[segmentPos]; segment != nil { + if idx == segment.idx { + return segment, !segment.isFresh() + } + // something exists here but its not the expected segment + // probably an old segment so overwrite it + segment.close() + } + segment := newSegment(idx) + s.segments[segmentPos] = segment + return segment, false +} + +func (s *Stream) getForRead(idx int) (*Segment, bool) { + s.mutex.RLock() + defer s.mutex.RUnlock() + exists := func(seg *Segment, i int) bool { + return seg != nil && seg.idx == i + } + if idx == -1 { + idx = s.latestWrite + } + segmentPos := idx % maxSegmentsPerStream + segment := s.segments[segmentPos] + if !exists(segment, idx) && (idx == s.latestWrite+1 || (idx == 0 && s.latestWrite == 0)) { + // read request is just a little bit ahead of write head + segment = newSegment(idx) + s.segments[segmentPos] = segment + slog.Info("GET precreating", "stream", s.name, "idx", idx, "latest", s.latestWrite) + } + slog.Info("GET segment", "stream", s.name, "idx", idx, "latest", s.latestWrite, "exists?", exists(segment, idx)) + return segment, exists(segment, idx) +} + +func (sm *Server) handleGet(w http.ResponseWriter, r *http.Request) { + stream, exists := sm.getStream(r.PathValue("streamName")) + if !exists { + http.Error(w, "Stream not found", http.StatusNotFound) + return + } + idx, err := strconv.Atoi(r.PathValue("idx")) + if err != nil { + http.Error(w, "Invalid idx", http.StatusBadRequest) + return + } + stream.handleGet(w, r, idx) +} + +func (s *Stream) handleGet(w http.ResponseWriter, r *http.Request, idx int) { + segment, exists := s.getForRead(idx) + if !exists { + http.Error(w, "Entry not found", http.StatusNotFound) + return + } + + flusher, ok := w.(http.Flusher) + if !ok { + http.Error(w, "Streaming not supported", http.StatusInternalServerError) + return + } + + subscriber := &SegmentSubscriber{ + segment: segment, + } + + // Function to write data to the client + sendData := func() (int, error) { + totalWrites := 0 + for { + // Check if client disconnected + select { + case <-r.Context().Done(): + return totalWrites, fmt.Errorf("client disconnected") + default: + } + + data, eof := subscriber.readData() + if len(data) > 0 { + if totalWrites <= 0 { + w.Header().Set("Lp-Trickle-Seq", strconv.Itoa(segment.idx)) + w.Header().Set("Content-Type", s.mimeType) + } + n, err := w.Write(data) + totalWrites += n + if err != nil { + return totalWrites, err + } + // TODO error if bytes written != len(data) ? + flusher.Flush() + } + if eof { + if totalWrites <= 0 { + w.Header().Set("Lp-Trickle-Seq", strconv.Itoa(segment.idx)) + w.Header().Set("Lp-Trickle-Closed", "terminated") + } + return totalWrites, nil + } + } + } + + if n, err := sendData(); err != nil { + // Handle write error or client disconnect + slog.Error("Error sending data to client", "stream", s.name, "idx", segment.idx, "sentBytes", n, "err", err) + return + } +} + +func newSegment(idx int) *Segment { + mu := &sync.Mutex{} + return &Segment{ + idx: idx, + buffer: new(bytes.Buffer), + cond: sync.NewCond(mu), + mutex: mu, + } +} + +func (segment *Segment) writeData(data []byte) { + segment.mutex.Lock() + defer segment.mutex.Unlock() + + // Write to buffer + segment.buffer.Write(data) + + // Signal waiting readers + segment.cond.Broadcast() +} + +func (s *Segment) readData(startPos int) ([]byte, bool) { + s.mutex.Lock() + defer s.mutex.Unlock() + for { + totalLen := s.buffer.Len() + if startPos < totalLen { + data := s.buffer.Bytes()[startPos:totalLen] + return data, s.closed + } + if startPos > totalLen { + slog.Info("Invalid start pos, invoking eof") + return nil, true + } + if s.closed { + return nil, true + } + // Wait for new data + s.cond.Wait() + } +} + +func (s *Segment) close() { + if s == nil { + return // sometimes happens, weird + } + s.mutex.Lock() + defer s.mutex.Unlock() + if !s.closed { + s.closed = true + s.cond.Broadcast() + } +} +func (s *Segment) isFresh() bool { + // fresh segments have not been written to yet + s.mutex.Lock() + defer s.mutex.Unlock() + return !s.closed && s.buffer.Len() == 0 +} + +func (ss *SegmentSubscriber) readData() ([]byte, bool) { + data, eof := ss.segment.readData(ss.readPos) + ss.readPos += len(data) + return data, eof +} diff --git a/trickle/trickle_subscriber.go b/trickle/trickle_subscriber.go new file mode 100644 index 0000000000..afcc47ccc9 --- /dev/null +++ b/trickle/trickle_subscriber.go @@ -0,0 +1,187 @@ +package trickle + +import ( + "context" + "crypto/tls" + "errors" + "fmt" + "io" + "log/slog" + "net/http" + "strconv" + "sync" + "time" +) + +var EOS = errors.New("End of stream") + +const preconnectRefreshTimeout = 20 * time.Second + +// TrickleSubscriber represents a trickle streaming reader that always fetches from index -1 +type TrickleSubscriber struct { + url string + mu sync.Mutex // Mutex to manage concurrent access + pendingGet *http.Response // Pre-initialized GET request + idx int // Segment index to request + + // Number of errors from preconnect + preconnectErrorCount int +} + +// NewTrickleSubscriber creates a new trickle stream reader for GET requests +func NewTrickleSubscriber(url string) *TrickleSubscriber { + // No preconnect needed here; it will be handled by the first Read call. + return &TrickleSubscriber{ + url: url, + idx: -1, // shortcut for 'latest' + } +} + +func GetSeq(resp *http.Response) int { + if resp == nil { + return -99 // TODO hmm + } + v := resp.Header.Get("Lp-Trickle-Seq") + i, err := strconv.Atoi(v) + if err != nil { + // Fetch the latest index + // TODO think through whether this is desirable + return -98 + } + return i +} + +func IsEOS(resp *http.Response) bool { + return resp.Header.Get("Lp-Trickle-Closed") != "" +} + +func (c *TrickleSubscriber) connect(ctx context.Context) (*http.Response, error) { + url := fmt.Sprintf("%s/%d", c.url, c.idx) + slog.Debug("preconnecting", "url", url) + + req, err := http.NewRequestWithContext(ctx, "GET", url, nil) + if err != nil { + slog.Error("Failed to create request for segment", "url", url, "err", err) + return nil, err + } + + // Execute the GET request + resp, err := (&http.Client{Transport: &http.Transport{ + TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, + }}).Do(req) + if err != nil { + return nil, fmt.Errorf("failed to complete GET for next segment: %w", err) + } + + if resp.StatusCode != http.StatusOK { + body, _ := io.ReadAll(resp.Body) + resp.Body.Close() // Ensure we close the body to avoid leaking connections + return nil, fmt.Errorf("failed GET segment, status code: %d, msg: %s", resp.StatusCode, string(body)) + } + + // Return the pre-initialized GET request + return resp, nil +} + +// preconnect pre-initializes the next GET request for fetching the next segment +// This blocks until headers are received as soon as data is ready. +// If blocking takes a while, it re-creates the connection every so often. +func (c *TrickleSubscriber) preconnect() (*http.Response, error) { + respCh := make(chan *http.Response, 1) + errCh := make(chan error, 1) + runConnect := func(ctx context.Context) { + go func() { + resp, err := c.connect(ctx) + if err != nil { + if errors.Is(err, context.Canceled) { + // cancelled as part of a preconnect refresh, so ignore + return + } + errCh <- err + return + } + respCh <- resp + }() + } + ctx, cancel := context.WithCancel(context.Background()) + runConnect(ctx) + for { + select { + case err := <-errCh: + return nil, err + case resp := <-respCh: + return resp, nil + case <-time.After(preconnectRefreshTimeout): + cancel() + ctx, cancel = context.WithCancel(context.Background()) + runConnect(ctx) + } + } +} + +// Read retrieves data from the current segment and sets up the next segment concurrently. +// It returns the reader for the current segment's data. +func (c *TrickleSubscriber) Read() (*http.Response, error) { + + // Acquire lock to manage access to pendingGet + // Blocking is intentional if there is no preconnect + c.mu.Lock() + defer c.mu.Unlock() + + // TODO clean up this preconnect error handling! + hitMaxPreconnects := c.preconnectErrorCount > 5 + if hitMaxPreconnects { + slog.Error("Hit max preconnect error", "url", c.url, "idx", c.idx) + return nil, fmt.Errorf("Hit max preconnects") + } + + // Get the reader to use for the current segment + conn := c.pendingGet + if conn == nil { + // Preconnect if we don't have a pending GET + slog.Debug("No preconnect, connecting", "url", c.url, "idx", c.idx) + p, err := c.preconnect() + if err != nil { + c.preconnectErrorCount++ + return nil, err + } + conn = p + // reset preconnect error + c.preconnectErrorCount = 0 + } + + if IsEOS(conn) { + return nil, EOS + } + + // Set to use the next index for the next (pre-)connection + idx := GetSeq(conn) + if idx != -1 { + c.idx = idx + 1 + } + + // Set up the next connection + go func() { + c.mu.Lock() + defer c.mu.Unlock() + nextConn, err := c.preconnect() + if err != nil { + slog.Error("failed to preconnect next segment", "url", c.url, "idx", c.idx, "err", err) + c.preconnectErrorCount++ + return + } + + c.pendingGet = nextConn + idx := GetSeq(nextConn) + if idx != -1 { + c.idx = idx + 1 + } + // reset preconnect error + c.preconnectErrorCount = 0 + }() + + // Now the segment is set up and we have the reader for the current one + + // Return the reader for the current segment + return conn, nil +} diff --git a/verification/epic_test.go b/verification/epic_test.go index 5165cb3b53..8e957d39c2 100644 --- a/verification/epic_test.go +++ b/verification/epic_test.go @@ -170,7 +170,7 @@ func TestEpic_Verify(t *testing.T) { ts, mux := stubVerificationServer() defer ts.Close() - mux.HandleFunc("/verify", func(w http.ResponseWriter, r *http.Request) { + mux.HandleFunc("/verify", func(w http.ResponseWriter, _ *http.Request) { buf, err := json.Marshal(&epicResults{ Results: []epicResultFields{ {VideoAvailable: true, Tamper: 1, OCSVMDist: -1.0}, @@ -205,7 +205,7 @@ func TestEpic_Verify(t *testing.T) { // TODO Error out on `resp.Body` read and ensure the error is there? // Nil JSON body - mux.HandleFunc("/nilJSON", func(w http.ResponseWriter, r *http.Request) { + mux.HandleFunc("/nilJSON", func(w http.ResponseWriter, _ *http.Request) { w.Write(nil) }) ec.Addr = ts.URL + "/nilJSON" diff --git a/verification/verify_test.go b/verification/verify_test.go index c815e175ba..4d6d85738e 100644 --- a/verification/verify_test.go +++ b/verification/verify_test.go @@ -56,7 +56,7 @@ type stubVerifier struct { err error } -func (sv *stubVerifier) Verify(params *Params) (*Results, error) { +func (sv *stubVerifier) Verify(_ *Params) (*Results, error) { return sv.results, sv.err } @@ -180,7 +180,7 @@ func TestVerify(t *testing.T) { results: nil, err: nil, }, Retries: 2}, - verifySig: func(addr ethcommon.Address, msg []byte, sig []byte) bool { return addr == recipientAddr }, + verifySig: func(addr ethcommon.Address, _ []byte, _ []byte) bool { return addr == recipientAddr }, } data = &net.TranscodeData{Segments: []*net.TranscodedSegmentData{ @@ -198,7 +198,7 @@ func TestVerify(t *testing.T) { orchAddr = ethcommon.BytesToAddress([]byte("bar")) sv = &SegmentVerifier{ policy: &Policy{Verifier: &stubVerifier{}, Retries: 2}, - verifySig: func(addr ethcommon.Address, msg []byte, sig []byte) bool { return addr == orchAddr }, + verifySig: func(addr ethcommon.Address, _ []byte, _ []byte) bool { return addr == orchAddr }, } res, err = sv.Verify(&Params{Results: data, Orchestrator: &net.OrchestratorInfo{TicketParams: params, Address: orchAddr.Bytes()}, Renditions: renditions}) @@ -321,7 +321,7 @@ func TestPixels(t *testing.T) { } // helper function for TestVerifyPixels to test countPixels() -func verifyPixels(fname string, data []byte, reportedPixels int64) error { +func verifyPixels(_ string, data []byte, reportedPixels int64) error { c, err := countPixels(data) if err != nil { return err