diff --git a/.github/discord-embed-webhook.py b/.github/discord-embed-webhook.py new file mode 100644 index 0000000000..d580bff94a --- /dev/null +++ b/.github/discord-embed-webhook.py @@ -0,0 +1,87 @@ +import argparse +import os +import json +import pathlib +from typing import Any + +from requests import Response +from discord_webhook import DiscordEmbed, DiscordWebhook + + +GITHUB_CONTEXT_JSON = os.environ.get("GITHUB_CONTEXT_JSON", "{}") +DOWNLOAD_BASE_URL_TEMPLATE = ( + "https://build.livepeer.live/go-livepeer/{version}/{filename}" +) + + +def get_github_context_vars(context: dict[str, Any]) -> dict[str, str]: + context_vars = {} + event: dict[str, Any] = context["event"] + if context.get("event_name") == "pull_request": + pull_request_context: dict[str, Any] = event["pull_request"] + head = pull_request_context.get("head", {}) + repo = head.get("repo", {}) + sha = head.get("sha") + context_vars["title"] = head.get("ref") + context_vars["sha"] = sha + context_vars["commit_url"] = f'{repo.get("html_url")}/commit/{sha}' + elif context.get("event_name") == "push": + sha = event["after"] + context_vars["title"] = context["ref_name"] + context_vars["sha"] = sha + context_vars["commit_url"] = event["compare"] + return context_vars + + +def populate_embeds(embed: DiscordEmbed, ref_name: str, checksums: list[str]): + for line in checksums: + _, filename = line.split() + download_url = DOWNLOAD_BASE_URL_TEMPLATE.format( + version=ref_name, + filename=filename, + ) + title = filename.removeprefix("livepeer-").split(".")[0] + print(f"Adding embed field name={title} value={download_url}") + embed.add_embed_field(name=title, value=download_url, inline=False) + + +def main(args): + checksums = [] + github_context: dict[str, Any] = json.loads(GITHUB_CONTEXT_JSON) + context_vars = get_github_context_vars(github_context) + checksums_file = pathlib.Path("releases") / f"{args.ref_name}_checksums.txt" + checksums = checksums_file.read_text().splitlines() + webhook = DiscordWebhook( + url=args.discord_url, + content=":white_check_mark: Build succeeded for go-livepeer :white_check_mark:", + username="[BOT] Livepeer builder", + ) + webhook.add_file(filename=checksums_file.name, file=checksums_file.read_bytes()) + embed = DiscordEmbed( + title=context_vars.get("title"), + description=args.git_commit, + color=2928914, + url=context_vars.get("commit_url"), + ) + embed.add_embed_field(name="Commit SHA", value=context_vars.get("sha")) + embed.set_author(name=args.git_committer) + populate_embeds(embed, args.ref_name, checksums) + embed.set_timestamp() + webhook.add_embed(embed) + response: Response = webhook.execute() + print("sending webhook with content:") + print(webhook.json) + # Fail the script if discord returns anything except OK status + assert ( + response.ok + ), f"Discord webhook failed {response.status_code} {response.content}" + + +if __name__ == "__main__": + parser = argparse.ArgumentParser("Discord embed content generator for build system") + parser.add_argument("--discord-url", help="Discord webhook URL") + parser.add_argument("--ref-name", help="Tag/branch/commit for current build") + parser.add_argument("--git-commit", help="git commit message") + parser.add_argument("--git-committer", help="git commit author name") + args = parser.parse_args() + main(args) diff --git a/.github/requirements.txt b/.github/requirements.txt new file mode 100644 index 0000000000..3196568e1a --- /dev/null +++ b/.github/requirements.txt @@ -0,0 +1 @@ +discord-webhook diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 6e93599485..ace2b7e8e0 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -15,7 +15,7 @@ concurrency: jobs: linux-build: name: Build binaries for ${{ matrix.target.GOOS }}-${{ matrix.target.type }}-${{ matrix.target.GOARCH }} - runs-on: ${{ matrix.target.runner }} + runs-on: ubuntu-20.04 container: image: ${{ matrix.target.container }} env: @@ -26,31 +26,26 @@ jobs: target: - GOOS: linux GOARCH: amd64 - runner: ubuntu-20.04 container: ubuntu:20.04 type: cpu - GOOS: linux GOARCH: arm64 - runner: ubuntu-20.04 container: ubuntu:20.04 type: cpu - GOOS: linux GOARCH: amd64 - runner: ubuntu-20.04 container: livepeerci/cuda:12.0.0-cudnn8-devel-ubuntu20.04 type: gpu - GOOS: linux GOARCH: arm64 - runner: ubuntu-20.04 container: livepeerci/cuda:12.0.0-cudnn8-devel-ubuntu20.04 type: gpu - GOOS: windows GOARCH: amd64 - runner: ubuntu-20.04 container: ubuntu:22.04 type: cpu @@ -63,7 +58,7 @@ jobs: apt update && apt install -yqq git zip unzip zlib1g-dev zlib1g yasm - name: Check out code - uses: actions/checkout@v4.1.1 + uses: actions/checkout@v4.1.7 with: fetch-depth: 0 # Check https://github.com/livepeer/go-livepeer/pull/1891 @@ -78,19 +73,14 @@ jobs: cache: true cache-dependency-path: go.sum - - name: Cache ffmpeg - id: cache-ffmpeg - uses: actions/cache@v3 - with: - path: /home/runner/compiled - key: ${{ runner.os }}-${{ matrix.target.GOOS }}-${{ matrix.target.GOARCH }}-${{ matrix.target.type }}-ffmpeg-${{ hashFiles('**/install_ffmpeg.sh') }} - - name: Set build environment run: | echo "GOARCH=${{ matrix.target.GOARCH }}" >> $GITHUB_ENV echo "GOOS=${{ matrix.target.GOOS }}" >> $GITHUB_ENV echo "GO_BUILD_DIR=lp-builds/" >> $GITHUB_ENV echo "PKG_CONFIG_PATH=/github/home/compiled/lib/pkgconfig" >> $GITHUB_ENV + echo "LP_BUILD_DIR=livepeer-${{ matrix.target.GOOS }}-${{ matrix.target.GOARCH }}" >> $GITHUB_ENV + mkdir -p lp-builds/ releases/ - name: Set GPU build environment if: matrix.target.type == 'gpu' @@ -99,6 +89,7 @@ jobs: echo "LIBRARY_PATH=/usr/local/cuda_${{ matrix.target.GOARCH }}/lib64" >> $GITHUB_ENV echo "CGO_LDFLAGS=-L/usr/local/cuda_${{ matrix.target.GOARCH }}/lib64" >> $GITHUB_ENV echo "RELEASE_TAG=gpu" >> $GITHUB_ENV + echo "LP_BUILD_DIR=livepeer-${{ matrix.target.GOOS }}-gpu-${{ matrix.target.GOARCH }}" >> $GITHUB_ENV - name: Install dependencies run: | @@ -120,7 +111,6 @@ jobs: run: go mod download - name: Install ffmpeg - if: steps.cache-ffmpeg.outputs.cache-hit != 'true' run: ./install_ffmpeg.sh - name: Build binaries @@ -130,24 +120,28 @@ jobs: git config --global --add safe.directory '*' ./ci_env.sh make - - name: Upload build - if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository - env: - GHA_REF: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.ref || github.ref }} - GCLOUD_KEY: ${{ secrets.GCLOUD_KEY }} - GCLOUD_SECRET: ${{ secrets.GCLOUD_SECRET }} - DISCORD_URL: ${{ secrets.DISCORD_URL }} - run: ./upload_build.sh + - name: Archive binaries for windows + if: matrix.target.GOOS == 'windows' + run: | + mkdir -p "${GO_BUILD_DIR}/${LP_BUILD_DIR}/" + cd "$GO_BUILD_DIR/" + find . -type f -exec mv '{}' "$LP_BUILD_DIR/" \; + zip -9rq "../releases/$LP_BUILD_DIR.zip" ./ + + - name: Archive binaries + if: matrix.target.GOOS != 'windows' + run: | + mkdir -p "${GO_BUILD_DIR}/${LP_BUILD_DIR}/" + cd "$GO_BUILD_DIR/" + find . -type f -exec mv '{}' "$LP_BUILD_DIR" \; + tar -czvf "../releases/$LP_BUILD_DIR.tar.gz" ./ - name: Upload artifacts for cutting release - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: - name: release-artifacts + name: release-artifacts-${{ matrix.target.GOOS }}-${{ matrix.target.type }}-${{ matrix.target.GOARCH }} path: releases/ - - name: Notify new build upload - run: curl -X POST https://holy-bread-207a.livepeer.workers.dev - macos-build: name: Build binaries for ${{ matrix.target.GOOS }}-${{ matrix.target.GOARCH }} runs-on: ${{ matrix.target.runner }} @@ -161,11 +155,11 @@ jobs: - GOOS: darwin GOARCH: arm64 - runner: macos-latest + runner: macos-14-xlarge steps: - name: Check out code - uses: actions/checkout@v4.1.1 + uses: actions/checkout@v4.1.7 with: fetch-depth: 0 # Check https://github.com/livepeer/go-livepeer/pull/1891 @@ -185,10 +179,12 @@ jobs: echo "GOARCH=${{ matrix.target.GOARCH }}" >> $GITHUB_ENV echo "GOOS=${{ matrix.target.GOOS }}" >> $GITHUB_ENV echo "GO_BUILD_DIR=lp-builds/" >> $GITHUB_ENV + echo "LP_BUILD_DIR=livepeer-${{ matrix.target.GOOS }}-${{ matrix.target.GOARCH }}" >> $GITHUB_ENV + mkdir -p lp-builds/ releases/ - name: Cache ffmpeg id: cache-ffmpeg - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: ~/compiled key: ${{ runner.os }}-${{ matrix.target.GOOS }}-${{ matrix.target.GOARCH }}-ffmpeg-${{ hashFiles('**/install_ffmpeg.sh') }} @@ -230,45 +226,60 @@ jobs: app-notarization-team-id: ${{ secrets.CI_MACOS_NOTARIZATION_TEAM_ID }} binary-path: "lp-builds/" - - name: Upload build - if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository - env: - GHA_REF: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.ref || github.ref }} - GCLOUD_KEY: ${{ secrets.GCLOUD_KEY }} - GCLOUD_SECRET: ${{ secrets.GCLOUD_SECRET }} - DISCORD_URL: ${{ secrets.DISCORD_URL }} - run: ./upload_build.sh + - name: Archive binaries + if: matrix.platform.name != 'windows' + run: | + mkdir -p "${GO_BUILD_DIR}/${LP_BUILD_DIR}/" + cd "$GO_BUILD_DIR/" + find . -type f -exec mv '{}' "$LP_BUILD_DIR" \; + tar -czvf "../releases/${LP_BUILD_DIR}.tar.gz" . - name: Upload artifacts for cutting release - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: - name: release-artifacts + name: release-artifacts-${{ matrix.target.GOOS }}-${{ matrix.target.GOARCH }} path: releases/ - - name: Notify new build upload - run: curl -X POST https://holy-bread-207a.livepeer.workers.dev - upload: name: Upload artifacts to google bucket + if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository permissions: contents: "read" id-token: "write" - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 needs: - macos-build - linux-build steps: + - name: Check out code + uses: actions/checkout@v4.1.7 + with: + fetch-depth: 0 + # Check https://github.com/livepeer/go-livepeer/pull/1891 + # for ref value discussion + ref: ${{ github.event.pull_request.head.sha }} + + - name: Set up python + id: python + uses: actions/setup-python@v5 + with: + python-version: 3.12 + cache: pip + cache-dependency-path: .github/requirements.txt + update-environment: true + - name: Download artifacts - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: - name: release-artifacts + pattern: release-artifacts-* path: releases/ + merge-multiple: true - name: Generate sha256 checksum and gpg signatures for release artifacts uses: livepeer/action-gh-checksum-and-gpg-sign@latest with: artifacts-dir: releases - release-name: ${{ (github.ref_type == 'tag' && github.ref_name) || github.sha }} + release-name: ${{ (github.ref_type == 'tag' && github.ref_name) || (github.event.pull_request.head.sha || github.sha) }} gpg-key: ${{ secrets.CI_GPG_SIGNING_KEY }} gpg-key-passphrase: ${{ secrets.CI_GPG_SIGNING_PASSPHRASE }} @@ -289,16 +300,33 @@ jobs: - name: Upload release archives to Google Cloud id: upload-archives - uses: google-github-actions/upload-cloud-storage@v1 + uses: google-github-actions/upload-cloud-storage@v2 with: path: "releases" - destination: "build.livepeer.live/${{ github.event.repository.name }}/${{ (github.ref_type == 'tag' && github.ref_name) || github.sha }}" + destination: "build.livepeer.live/${{ github.event.repository.name }}/${{ (github.ref_type == 'tag' && github.ref_name) || (github.event.pull_request.head.sha || github.sha) }}" parent: false + process_gcloudignore: false - name: Upload branch manifest file id: upload-manifest - uses: google-github-actions/upload-cloud-storage@v1 + uses: google-github-actions/upload-cloud-storage@v2 with: path: ${{ steps.branch-manifest.outputs.manifest-file }} destination: "build.livepeer.live/${{ github.event.repository.name }}/" parent: false + process_gcloudignore: false + + - name: Trigger discord webhook + shell: bash + env: + GITHUB_CONTEXT_JSON: ${{ toJson(github) }} + run: | + pip install -r .github/requirements.txt + python .github/discord-embed-webhook.py \ + --ref-name="${{ (github.ref_type == 'tag' && github.ref_name) || (github.event.pull_request.head.sha || github.sha) }}" \ + --discord-url="${{ secrets.DISCORD_URL }}" \ + --git-commit="$(git log -1 --pretty=format:'%s')" \ + --git-committer="$(git log -1 --pretty=format:'%an')" + + - name: Notify new build upload + run: curl -X POST https://holy-bread-207a.livepeer.workers.dev diff --git a/.github/workflows/docker.yaml b/.github/workflows/docker.yaml index 44dd48fa14..d43f65a3a8 100644 --- a/.github/workflows/docker.yaml +++ b/.github/workflows/docker.yaml @@ -22,7 +22,7 @@ jobs: runs-on: oxford steps: - name: Check out code - uses: actions/checkout@v4.1.1 + uses: actions/checkout@v4.1.7 with: fetch-depth: 0 # Check https://github.com/livepeer/go-livepeer/pull/1891 @@ -106,7 +106,7 @@ jobs: runs-on: ubuntu-20.04 steps: - name: Check out code - uses: actions/checkout@v4.1.1 + uses: actions/checkout@v4.1.7 with: fetch-depth: 0 # Check https://github.com/livepeer/go-livepeer/pull/1891 diff --git a/.github/workflows/git.yaml b/.github/workflows/git.yaml index 9b0d1383b3..4ed7f0e431 100644 --- a/.github/workflows/git.yaml +++ b/.github/workflows/git.yaml @@ -9,10 +9,10 @@ concurrency: jobs: block-fixup: - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 steps: - name: Check out code - uses: actions/checkout@v4.1.1 + uses: actions/checkout@v4.1.7 - name: Block fixup commit merge uses: 13rac1/block-fixup-merge-action@v2.0.0 diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 6d7bab98e0..ad093b0a60 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -13,18 +13,27 @@ jobs: if: ${{ github.event.workflow_run.conclusion == 'success' }} steps: - name: checkout - uses: actions/checkout@v4.1.1 + uses: actions/checkout@v4.1.7 with: fetch-depth: 0 ref: ${{ github.event.workflow_run.head_branch }} - name: Download artifacts from build stage - uses: dawidd6/action-download-artifact@v3 + uses: dawidd6/action-download-artifact@v6 with: workflow: build.yaml - name: release-artifacts + run_id: ${{ github.event.workflow_run.id }} + name: release-artifacts-.* + name_is_regexp: true path: releases/ + - name: Flatten all downloaded artifacts to a single directory + shell: bash + run: | + cd releases/ + find . -type f -exec mv '{}' ./ \; + find . -type d -empty -delete + - uses: actions-ecosystem/action-regex-match@v2 id: match-tag with: @@ -41,7 +50,7 @@ jobs: gpg-key-passphrase: ${{ secrets.CI_GPG_SIGNING_PASSPHRASE }} - name: Release to github - uses: softprops/action-gh-release@v1 + uses: softprops/action-gh-release@v2 if: ${{ steps.match-tag.outputs.match != '' }} with: generate_release_notes: true diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 58897cd341..d11ffec9fb 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -28,7 +28,7 @@ jobs: sudo apt update && sudo apt install -yqq git zip unzip zlib1g-dev zlib1g - name: Check out code - uses: actions/checkout@v4.1.1 + uses: actions/checkout@v4.1.7 with: fetch-depth: 0 # Check https://github.com/livepeer/go-livepeer/pull/1891 @@ -49,7 +49,7 @@ jobs: - name: Cache ffmpeg id: cache-ffmpeg - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: /home/runner/compiled key: ${{ runner.os }}-ffmpeg-${{ hashFiles('install_ffmpeg.sh') }} @@ -124,11 +124,11 @@ jobs: codeql: name: Perform CodeQL analysis - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 steps: - name: Check out code - uses: actions/checkout@v4.1.1 + uses: actions/checkout@v4.1.7 with: fetch-depth: 0 # Check https://github.com/livepeer/go-livepeer/pull/1891 @@ -148,10 +148,10 @@ jobs: editorconfig: name: Run editorconfig checker - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 steps: - name: Check out code - uses: actions/checkout@v4.1.1 + uses: actions/checkout@v4.1.7 with: # Check https://github.com/livepeer/go-livepeer/pull/1891 # for ref value discussion diff --git a/CHANGELOG.md b/CHANGELOG.md index fb3c5d8036..29f376fbaf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,35 +1,64 @@ # Changelog -## v0.7.6 +## v0.7.9 -- [#3055](https://github.com/livepeer/go-livepeer/pull/3055) census: Rename broadcaster metrics to gateway metrics -- [#3053](https://github.com/livepeer/go-livepeer/pull/3053) cli: add `-gateway` flag and deprecate `-broadcaster` flag. -- [#3056](https://github.com/livepeer/go-livepeer/pull/3056) cli: add `-pricePerGateway` flag and deprecate `-pricePerBroadcaster` flag. -- [#3060](https://github.com/livepeer/go-livepeer/pull/3060) refactor: rename internal references from Broadcaster to Gateway - -### Breaking Changes 🚨🚨 +- [#3165](https://github.com/livepeer/go-livepeer/pull/3165) Add node version and orch addr to transcoded metadata ### Features ⚒ -#### General +#### Broadcaster + +- [#3158](https://github.com/livepeer/go-livepeer/pull/3158) Add a metric tag for Orchestrator version + +### Bug Fixes 🐞 #### Broadcaster -#### Orchestrator +- [#3164](https://github.com/livepeer/go-livepeer/pull/3164) Fix media compatibility check +- [#3166](https://github.com/livepeer/go-livepeer/pull/3166) Clean up inactive sessions +- [#3086](https://github.com/livepeer/go-livepeer/pull/3086) Clear known sessions with inadequate latency scores + +## v0.7.8 + +### Features ⚒ + +#### Broadcaster + +- [#3127](https://github.com/livepeer/go-livepeer/pull/3127) Add flag `-ignoreMaxPriceIfNeeded` (@leszko) + +## v0.7.7 + +This release includes a new `-hevcDecoding` flag for transcoders to configure HEVC decoding. If the flag is omitted, the default behavior on GPUs is unchanged, which is to auto-detect HEVC decoding support at transcoder start-up. Transcoders can disable HEVC decoding on GPUs if there is an issue with HEVC jobs via `-hevcDecoding=false`. CPU transcoders now have HEVC decoding disabled by default since processing HEVC jobs is CPU-heavy, but this can be enabled by setting the `-hevcDecoding` flag. + +The transcoder now support mid-stream input rotations, rather than crashing or outputting cropped video as it did before. + +### Breaking Changes 🚨🚨 + +- [#3119](https://github.com/livepeer/go-livepeer/pull/3119) CPU transcoders no longer decode HEVC or VP9 by default #### Transcoder +- [#3119](https://github.com/livepeer/go-livepeer/pull/3119) Add `-hevcDecoding` flag to toggle HEVC decoding + ### Bug Fixes 🐞 -#### CLI +#### Transcoder -#### General +- [#418](https://github.com/livepeer/lpms/pull/418) lpms: Fix CUVID crash on resolution change +- [#417](https://github.com/livepeer/lpms/pull/417) lpms: Clamp resolutions in filter expression +- [#416](https://github.com/livepeer/lpms/pull/416) lpms: Rescale DTS better during FPS passthrough -#### Broadcaster +## v0.7.6 -#### Orchestrator +- [#3055](https://github.com/livepeer/go-livepeer/pull/3055) census: Rename broadcaster metrics to gateway metrics +- [#3053](https://github.com/livepeer/go-livepeer/pull/3053) cli: add `-gateway` flag and deprecate `-broadcaster` flag. +- [#3056](https://github.com/livepeer/go-livepeer/pull/3056) cli: add `-pricePerGateway` flag and deprecate `-pricePerBroadcaster` flag. +- [#3060](https://github.com/livepeer/go-livepeer/pull/3060) refactor: rename internal references from Broadcaster to Gateway + +### Breaking Changes 🚨🚨 + +### Features ⚒ -#### Transcoder ## v0.7.5 @@ -48,16 +77,8 @@ - [#2995](https://github.com/livepeer/go-livepeer/pull/2995) server: Allow Os price to increase up to 2x mid-session (@victorges) - [#2999](https://github.com/livepeer/go-livepeer/pull/2999) server,discovery: Allow B to use any O in case none match maxPrice (@victorges) -#### Orchestrator - -#### Transcoder - ### Bug Fixes 🐞 -#### CLI - -#### General - #### Broadcaster - [#2994](https://github.com/livepeer/go-livepeer/pull/2994) server: Skip redundant maxPrice check in ongoing session (@victorges) diff --git a/CHANGELOG_PENDING.md b/CHANGELOG_PENDING.md index 3ca5044811..22f1b28ed7 100644 --- a/CHANGELOG_PENDING.md +++ b/CHANGELOG_PENDING.md @@ -1,6 +1,6 @@ # Unreleased Changes -## vX.X +## v0.X.X ### Breaking Changes 🚨🚨 diff --git a/VERSION b/VERSION index 4d01880a7f..1451d481e2 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.7.6 \ No newline at end of file +0.7.9 \ No newline at end of file diff --git a/cmd/livepeer/livepeer.go b/cmd/livepeer/livepeer.go index 70922549c5..446bbe5f20 100755 --- a/cmd/livepeer/livepeer.go +++ b/cmd/livepeer/livepeer.go @@ -135,7 +135,9 @@ 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.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)") // Transcoding: cfg.Orchestrator = flag.Bool("orchestrator", *cfg.Orchestrator, "Set to true to be an orchestrator") @@ -150,6 +152,7 @@ func parseLivepeerConfig() starter.LivepeerConfig { cfg.Nvidia = flag.String("nvidia", *cfg.Nvidia, "Comma-separated list of Nvidia GPU device IDs (or \"all\" for all available devices)") cfg.Netint = flag.String("netint", *cfg.Netint, "Comma-separated list of NetInt device GUIDs (or \"all\" for all available devices)") 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") // Onchain: cfg.EthAcctAddr = flag.String("ethAcctAddr", *cfg.EthAcctAddr, "Existing Eth account address. For use when multiple ETH accounts exist in the keystore directory") @@ -237,6 +240,9 @@ func updateNilsForUnsetFlags(cfg starter.LivepeerConfig) starter.LivepeerConfig if !isFlagSet["localVerify"] { res.LocalVerify = nil } + if !isFlagSet["hevcDecoding"] { + res.HevcDecoding = nil + } return res } diff --git a/cmd/livepeer/starter/starter.go b/cmd/livepeer/starter/starter.go index 5ef0e1e694..92ba9079bb 100755 --- a/cmd/livepeer/starter/starter.go +++ b/cmd/livepeer/starter/starter.go @@ -99,11 +99,14 @@ type LivepeerConfig struct { OrchPerfStatsURL *string Region *string MaxPricePerUnit *string + IgnoreMaxPriceIfNeeded *bool MinPerfScore *float64 + DiscoveryTimeout *time.Duration MaxSessions *string CurrentManifest *bool Nvidia *string Netint *string + HevcDecoding *bool TestTranscoder *bool EthAcctAddr *string EthPassword *string @@ -178,9 +181,11 @@ func DefaultLivepeerConfig() LivepeerConfig { defaultOrchPerfStatsURL := "" defaultRegion := "" defaultMinPerfScore := 0.0 + defaultDiscoveryTimeout := 500 * time.Millisecond defaultCurrentManifest := false defaultNvidia := "" defaultNetint := "" + defaultHevcDecoding := false defaultTestTranscoder := true // Onchain: @@ -202,6 +207,7 @@ func DefaultLivepeerConfig() LivepeerConfig { defaultMaxTotalEV := "20000000000000" defaultDepositMultiplier := 1 defaultMaxPricePerUnit := "0" + defaultIgnoreMaxPriceIfNeeded := false defaultPixelsPerUnit := "1" defaultPriceFeedAddr := "0x639Fe6ab55C921f74e7fac1ee960C0B6293ba612" // ETH / USD price feed address on Arbitrum Mainnet defaultAutoAdjustPrice := true @@ -267,9 +273,11 @@ func DefaultLivepeerConfig() LivepeerConfig { OrchPerfStatsURL: &defaultOrchPerfStatsURL, Region: &defaultRegion, MinPerfScore: &defaultMinPerfScore, + DiscoveryTimeout: &defaultDiscoveryTimeout, CurrentManifest: &defaultCurrentManifest, Nvidia: &defaultNvidia, Netint: &defaultNetint, + HevcDecoding: &defaultHevcDecoding, TestTranscoder: &defaultTestTranscoder, // Onchain: @@ -291,6 +299,7 @@ func DefaultLivepeerConfig() LivepeerConfig { MaxTotalEV: &defaultMaxTotalEV, DepositMultiplier: &defaultDepositMultiplier, MaxPricePerUnit: &defaultMaxPricePerUnit, + IgnoreMaxPriceIfNeeded: &defaultIgnoreMaxPriceIfNeeded, PixelsPerUnit: &defaultPixelsPerUnit, PriceFeedAddr: &defaultPriceFeedAddr, AutoAdjustPrice: &defaultAutoAdjustPrice, @@ -489,10 +498,30 @@ func StartLivepeer(ctx context.Context, cfg LivepeerConfig) { // Initialize LB transcoder n.Transcoder = core.NewLoadBalancingTranscoder(devices, tf) } else { - // for local software mode, enable all capabilities - transcoderCaps = append(core.DefaultCapabilities(), core.OptionalCapabilities()...) + // for local software mode, enable most capabilities but remove expensive decoders and non-H264 encoders + capsToRemove := []core.Capability{core.Capability_HEVC_Decode, core.Capability_HEVC_Encode, core.Capability_VP8_Encode, core.Capability_VP9_Decode, core.Capability_VP9_Encode} + caps := core.OptionalCapabilities() + for _, c := range capsToRemove { + caps = core.RemoveCapability(caps, c) + } + transcoderCaps = append(core.DefaultCapabilities(), caps...) n.Transcoder = core.NewLocalTranscoder(*cfg.Datadir) } + + if cfg.HevcDecoding == nil { + // do nothing; keep defaults + } else if *cfg.HevcDecoding { + if !core.HasCapability(transcoderCaps, core.Capability_HEVC_Decode) { + if accel != ffmpeg.Software { + glog.Info("Enabling HEVC decoding when the hardware does not support it") + } else { + glog.Info("Enabling HEVC decoding on CPU, may be slow") + } + transcoderCaps = core.AddCapability(transcoderCaps, core.Capability_HEVC_Decode) + } + } else if !*cfg.HevcDecoding { + transcoderCaps = core.RemoveCapability(transcoderCaps, core.Capability_HEVC_Decode) + } } if *cfg.Redeemer { @@ -822,6 +851,7 @@ func StartLivepeer(ctx context.Context, cfg LivepeerConfig) { glog.Errorf("Error setting up orchestrator: %v", err) return } + n.RecipientAddr = recipientAddr.Hex() sigVerifier := &pm.DefaultSigVerifier{} validator := pm.NewValidator(sigVerifier, timeWatcher) @@ -1096,7 +1126,7 @@ func StartLivepeer(ctx context.Context, cfg LivepeerConfig) { if *cfg.Network != "offchain" { ctx, cancel := context.WithCancel(ctx) defer cancel() - dbOrchPoolCache, err := discovery.NewDBOrchestratorPoolCache(ctx, n, timeWatcher, orchBlacklist) + dbOrchPoolCache, err := discovery.NewDBOrchestratorPoolCache(ctx, n, timeWatcher, orchBlacklist, *cfg.DiscoveryTimeout) if err != nil { exit("Could not create orchestrator pool with DB cache: %v", err) } @@ -1111,9 +1141,9 @@ func StartLivepeer(ctx context.Context, cfg LivepeerConfig) { glog.Exit("Error setting orch webhook URL ", err) } glog.Info("Using orchestrator webhook URL ", whurl) - n.OrchestratorPool = discovery.NewWebhookPool(bcast, whurl) + n.OrchestratorPool = discovery.NewWebhookPool(bcast, whurl, *cfg.DiscoveryTimeout) } else if len(orchURLs) > 0 { - n.OrchestratorPool = discovery.NewOrchestratorPool(bcast, orchURLs, common.Score_Trusted, orchBlacklist) + n.OrchestratorPool = discovery.NewOrchestratorPool(bcast, orchURLs, common.Score_Trusted, orchBlacklist, *cfg.DiscoveryTimeout) } if n.OrchestratorPool == nil { @@ -1173,6 +1203,11 @@ func StartLivepeer(ctx context.Context, cfg LivepeerConfig) { if err != nil { glog.Exit("Error getting service URI: ", err) } + + if *cfg.Network != "offchain" && !common.ValidateServiceURI(suri) { + glog.Warning("**Warning -serviceAddr is a not a public address or hostname; this is not recommended for onchain networks**") + } + n.SetServiceURI(suri) // if http addr is not provided, listen to all ifaces // take the port to listen to from the service URI @@ -1565,11 +1600,12 @@ func createSelectionAlgorithm(cfg LivepeerConfig) (common.SelectionAlgorithm, er *cfg.SelectStakeWeight, *cfg.SelectPriceWeight, *cfg.SelectRandWeight) } return server.ProbabilitySelectionAlgorithm{ - MinPerfScore: *cfg.MinPerfScore, - StakeWeight: *cfg.SelectStakeWeight, - PriceWeight: *cfg.SelectPriceWeight, - RandWeight: *cfg.SelectRandWeight, - PriceExpFactor: *cfg.SelectPriceExpFactor, + MinPerfScore: *cfg.MinPerfScore, + StakeWeight: *cfg.SelectStakeWeight, + PriceWeight: *cfg.SelectPriceWeight, + RandWeight: *cfg.SelectRandWeight, + PriceExpFactor: *cfg.SelectPriceExpFactor, + IgnoreMaxPriceIfNeeded: *cfg.IgnoreMaxPriceIfNeeded, }, nil } diff --git a/common/util.go b/common/util.go index 639cf07ccd..b4d7396a8b 100644 --- a/common/util.go +++ b/common/util.go @@ -11,6 +11,7 @@ import ( "math/big" "math/rand" "mime" + "net/url" "regexp" "sort" "strconv" @@ -530,3 +531,7 @@ func ParseEthAddr(strJsonKey string) (string, error) { } return "", errors.New("Error parsing address from keyfile") } + +func ValidateServiceURI(serviceURI *url.URL) bool { + return !strings.Contains(serviceURI.Host, "0.0.0.0") +} diff --git a/common/util_test.go b/common/util_test.go index 9a541669d6..131631586e 100644 --- a/common/util_test.go +++ b/common/util_test.go @@ -5,6 +5,7 @@ import ( "fmt" "math" "math/big" + "net/url" "strconv" "strings" "testing" @@ -483,3 +484,38 @@ func TestParseAccelDevices_CustomSelection(t *testing.T) { assert.Equal(ids[1], "3") assert.Equal(ids[2], "1") } +func TestValidateServiceURI(t *testing.T) { + // Valid service URIs + validURIs := []string{ + "https://8.8.8.8:8935", + "https://127.0.0.1:8935", + } + + for _, uri := range validURIs { + serviceURI, err := url.Parse(uri) + if err != nil { + t.Errorf("Failed to parse valid service URI: %v", err) + } + + if !ValidateServiceURI(serviceURI) { + t.Errorf("Expected service URI to be valid, but got invalid: %v", uri) + } + } + + // Invalid service URIs + invalidURIs := []string{ + "http://0.0.0.0", + "https://0.0.0.0", + } + + for _, uri := range invalidURIs { + serviceURI, err := url.Parse(uri) + if err != nil { + t.Errorf("Failed to parse invalid service URI: %v", err) + } + + if ValidateServiceURI(serviceURI) { + t.Errorf("Expected service URI to be invalid, but got valid: %v", uri) + } + } +} diff --git a/core/capabilities.go b/core/capabilities.go index 7bd4f00f5f..a4666417b1 100644 --- a/core/capabilities.go +++ b/core/capabilities.go @@ -188,6 +188,20 @@ func MandatoryOCapabilities() []Capability { } } +func RemoveCapability(haystack []Capability, needle Capability) []Capability { + for i, c := range haystack { + if c == needle { + // TODO use slices.Delete once go-livepeer updates to latest golang + return append(haystack[:i], haystack[i+1:]...) + } + } + return haystack +} + +func AddCapability(caps []Capability, newCap Capability) []Capability { + return append(caps, newCap) +} + func NewCapabilityString(caps []Capability) CapabilityString { capStr := CapabilityString{} for _, v := range caps { @@ -496,7 +510,7 @@ func CapabilityToName(capability Capability) (string, error) { return capName, nil } -func InArray(capability Capability, caps []Capability) bool { +func HasCapability(caps []Capability, capability Capability) bool { for _, c := range caps { if capability == c { return true diff --git a/core/capabilities_test.go b/core/capabilities_test.go index b165a3d9ca..ae0880301b 100644 --- a/core/capabilities_test.go +++ b/core/capabilities_test.go @@ -148,22 +148,22 @@ func TestCapability_TranscoderCapabilities(t *testing.T) { if devicesAvailable { nvidiaCaps, err := TestTranscoderCapabilities(devices, NewNvidiaTranscoder) assert.Nil(t, err) - assert.False(t, InArray(Capability_H264_Decode_444_8bit, nvidiaCaps), "Nvidia device should not support decode of 444_8bit") - assert.False(t, InArray(Capability_H264_Decode_422_8bit, nvidiaCaps), "Nvidia device should not support decode of 422_8bit") - assert.False(t, InArray(Capability_H264_Decode_444_10bit, nvidiaCaps), "Nvidia device should not support decode of 444_10bit") - assert.False(t, InArray(Capability_H264_Decode_422_10bit, nvidiaCaps), "Nvidia device should not support decode of 422_10bit") - assert.False(t, InArray(Capability_H264_Decode_420_10bit, nvidiaCaps), "Nvidia device should not support decode of 420_10bit") + assert.False(t, HasCapability(nvidiaCaps, Capability_H264_Decode_444_8bit), "Nvidia device should not support decode of 444_8bit") + assert.False(t, HasCapability(nvidiaCaps, Capability_H264_Decode_422_8bit), "Nvidia device should not support decode of 422_8bit") + assert.False(t, HasCapability(nvidiaCaps, Capability_H264_Decode_444_10bit), "Nvidia device should not support decode of 444_10bit") + assert.False(t, HasCapability(nvidiaCaps, Capability_H264_Decode_422_10bit), "Nvidia device should not support decode of 422_10bit") + assert.False(t, HasCapability(nvidiaCaps, Capability_H264_Decode_420_10bit), "Nvidia device should not support decode of 420_10bit") } // Same test with software transcoder: softwareCaps, err := TestSoftwareTranscoderCapabilities(tmpdir) assert.Nil(t, err) // Software transcoder supports: [h264_444_8bit h264_422_8bit h264_444_10bit h264_422_10bit h264_420_10bit] - assert.True(t, InArray(Capability_H264_Decode_444_8bit, softwareCaps), "software decoder should support 444_8bit input") - assert.True(t, InArray(Capability_H264_Decode_422_8bit, softwareCaps), "software decoder should support 422_8bit input") - assert.True(t, InArray(Capability_H264_Decode_444_10bit, softwareCaps), "software decoder should support 444_10bit input") - assert.True(t, InArray(Capability_H264_Decode_422_10bit, softwareCaps), "software decoder should support 422_10bit input") - assert.True(t, InArray(Capability_H264_Decode_420_10bit, softwareCaps), "software decoder should support 420_10bit input") + assert.True(t, HasCapability(softwareCaps, Capability_H264_Decode_444_8bit), "software decoder should support 444_8bit input") + assert.True(t, HasCapability(softwareCaps, Capability_H264_Decode_422_8bit), "software decoder should support 422_8bit input") + assert.True(t, HasCapability(softwareCaps, Capability_H264_Decode_444_10bit), "software decoder should support 444_10bit input") + assert.True(t, HasCapability(softwareCaps, Capability_H264_Decode_422_10bit), "software decoder should support 422_10bit input") + assert.True(t, HasCapability(softwareCaps, Capability_H264_Decode_420_10bit), "software decoder should support 420_10bit input") } func TestCapability_JobCapabilities(t *testing.T) { @@ -489,6 +489,50 @@ func TestCapabilities_LegacyCheck(t *testing.T) { assert.Len(legacyCapabilities, legacyLen) // sanity check no modifications } +func TestCapability_RemoveCapability(t *testing.T) { + tests := []struct { + name string + caps []Capability + toRemove Capability + expect []Capability + }{{ + name: "empty capability list", + caps: nil, + toRemove: Capability_H264, + expect: nil, + }, { + name: "capability not in list", + caps: []Capability{Capability_H264, Capability_MPEGTS}, + toRemove: Capability_MP4, + expect: []Capability{Capability_H264, Capability_MPEGTS}, + }, { + name: "capability at beginning of list", + caps: []Capability{Capability_H264, Capability_MPEGTS}, + toRemove: Capability_H264, + expect: []Capability{Capability_MPEGTS}, + }, { + name: "capability in middle of list", + caps: []Capability{Capability_H264, Capability_MP4, Capability_MPEGTS}, + toRemove: Capability_MP4, + expect: []Capability{Capability_H264, Capability_MPEGTS}, + }, { + name: "capability at end of list", + caps: []Capability{Capability_H264, Capability_MPEGTS}, + toRemove: Capability_MPEGTS, + expect: []Capability{Capability_H264}, + }, { + name: "last capability", + caps: []Capability{Capability_H264}, + toRemove: Capability_H264, + expect: []Capability{}, + }} + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + assert.Equal(t, tt.expect, RemoveCapability(tt.caps, tt.toRemove)) + }) + } +} + func TestLiveeerVersionCompatibleWith(t *testing.T) { tests := []struct { name string diff --git a/core/livepeernode.go b/core/livepeernode.go index 19839a185b..d7b3fec041 100644 --- a/core/livepeernode.go +++ b/core/livepeernode.go @@ -75,6 +75,7 @@ type LivepeerNode struct { // Transcoder public fields SegmentChans map[ManifestID]SegmentChan Recipient pm.Recipient + RecipientAddr string SelectionAlgorithm common.SelectionAlgorithm OrchestratorPool common.OrchestratorPool OrchPerfScore *common.PerfScore diff --git a/core/orchestrator.go b/core/orchestrator.go index 50d6ea9757..3a2578c81a 100644 --- a/core/orchestrator.go +++ b/core/orchestrator.go @@ -582,6 +582,17 @@ func (n *LivepeerNode) transcodeSeg(ctx context.Context, config transcodeConfig, } md.Fname = url + orchId := "offchain" + if n.RecipientAddr != "" { + orchId = n.RecipientAddr + } + if isRemote { + // huge hack to thread the orch id down to the transcoder + md.Metadata = map[string]string{"orchId": orchId} + } else { + md.Metadata = MakeMetadata(orchId) + } + //Do the transcoding start := time.Now() tData, err := transcoder.Transcode(ctx, md) @@ -816,6 +827,7 @@ func (rt *RemoteTranscoder) Transcode(logCtx context.Context, md *SegTranscoding msg := &net.NotifySegment{ Url: fname, TaskId: taskID, + OrchId: md.Metadata["orchId"], SegData: segData, // Triggers failure on Os that don't know how to use SegData Profiles: []byte("invalid"), diff --git a/core/streamdata.go b/core/streamdata.go index 6b2909e5c5..f575cd2c83 100644 --- a/core/streamdata.go +++ b/core/streamdata.go @@ -66,6 +66,7 @@ type SegTranscodingMetadata struct { AuthToken *net.AuthToken CalcPerceptualHash bool SegmentParameters *SegmentParameters + Metadata map[string]string } func (md *SegTranscodingMetadata) Flatten() []byte { @@ -192,3 +193,11 @@ func (id StreamID) String() string { func RandomManifestID() ManifestID { return ManifestID(common.RandomIDGenerator(DefaultManifestIDLength)) } + +func MakeMetadata(id string) map[string]string { + s := fmt.Sprintf("Livepeer Transcoder %s (%s)", LivepeerVersion, id) + return map[string]string{ + "service_provider": s, // for mpegts + "comment": "Processed by " + s, // for mp4 + } +} diff --git a/core/transcoder.go b/core/transcoder.go index e91aa56693..da1cb5d177 100644 --- a/core/transcoder.go +++ b/core/transcoder.go @@ -51,7 +51,7 @@ func (lt *LocalTranscoder) Transcode(ctx context.Context, md *SegTranscodingMeta Accel: ffmpeg.Software, } profiles := md.Profiles - opts := profilesToTranscodeOptions(lt.workDir, ffmpeg.Software, profiles, md.CalcPerceptualHash, md.SegmentParameters) + opts := profilesToTranscodeOptions(lt.workDir, ffmpeg.Software, md) _, seqNo, parseErr := parseURI(md.Fname) start := time.Now() @@ -100,7 +100,7 @@ func (nv *NetintTranscoder) Transcode(ctx context.Context, md *SegTranscodingMet Device: nv.device, } profiles := md.Profiles - out := profilesToTranscodeOptions(WorkDir, ffmpeg.Netint, profiles, md.CalcPerceptualHash, md.SegmentParameters) + out := profilesToTranscodeOptions(WorkDir, ffmpeg.Netint, md) _, seqNo, parseErr := parseURI(md.Fname) start := time.Now() @@ -135,7 +135,7 @@ func (nv *NvidiaTranscoder) Transcode(ctx context.Context, md *SegTranscodingMet Device: nv.device, } profiles := md.Profiles - out := profilesToTranscodeOptions(WorkDir, ffmpeg.Nvidia, profiles, md.CalcPerceptualHash, md.SegmentParameters) + out := profilesToTranscodeOptions(WorkDir, ffmpeg.Nvidia, md) _, seqNo, parseErr := parseURI(md.Fname) start := time.Now() @@ -172,7 +172,7 @@ type transcodeTestParams struct { } func (params transcodeTestParams) IsRequired() bool { - return InArray(params.Cap, DefaultCapabilities()) + return HasCapability(DefaultCapabilities(), params.Cap) } func (params transcodeTestParams) Kind() string { @@ -429,8 +429,13 @@ func resToTranscodeData(ctx context.Context, res *ffmpeg.TranscodeResults, opts }, nil } -func profilesToTranscodeOptions(workDir string, accel ffmpeg.Acceleration, profiles []ffmpeg.VideoProfile, calcPHash bool, - segPar *SegmentParameters) []ffmpeg.TranscodeOptions { +func profilesToTranscodeOptions(workDir string, accel ffmpeg.Acceleration, md *SegTranscodingMetadata) []ffmpeg.TranscodeOptions { + var ( + profiles []ffmpeg.VideoProfile = md.Profiles + calcPHash bool = md.CalcPerceptualHash + segPar *SegmentParameters = md.SegmentParameters + metadata map[string]string = md.Metadata + ) opts := make([]ffmpeg.TranscodeOptions, len(profiles)) for i := range profiles { @@ -440,6 +445,7 @@ func profilesToTranscodeOptions(workDir string, accel ffmpeg.Acceleration, profi Accel: accel, AudioEncoder: ffmpeg.ComponentOptions{Name: "copy"}, CalcSign: calcPHash, + Metadata: metadata, } if segPar != nil && segPar.Clip != nil { o.From = segPar.Clip.From diff --git a/core/transcoder_test.go b/core/transcoder_test.go index 25e19c5818..a6d687504e 100644 --- a/core/transcoder_test.go +++ b/core/transcoder_test.go @@ -178,14 +178,24 @@ func TestProfilesToTranscodeOptions(t *testing.T) { } defer func() { common.RandomIDGenerator = oldRandIDFunc }() + makeMeta := func(p []ffmpeg.VideoProfile, c bool) *SegTranscodingMetadata { + return &SegTranscodingMetadata{ + Profiles: p, + CalcPerceptualHash: c, + Metadata: map[string]string{ + "meta": "data", + }, + } + } + // Test 0 profiles profiles := []ffmpeg.VideoProfile{} - opts := profilesToTranscodeOptions(workDir, ffmpeg.Software, profiles, false, nil) + opts := profilesToTranscodeOptions(workDir, ffmpeg.Software, makeMeta(profiles, false)) assert.Equal(0, len(opts)) // Test 1 profile profiles = []ffmpeg.VideoProfile{ffmpeg.P144p30fps16x9} - opts = profilesToTranscodeOptions(workDir, ffmpeg.Software, profiles, false, nil) + opts = profilesToTranscodeOptions(workDir, ffmpeg.Software, makeMeta(profiles, false)) assert.Equal(1, len(opts)) assert.Equal("foo/out_bar.tempfile", opts[0].Oname) assert.Equal(ffmpeg.Software, opts[0].Accel) @@ -194,7 +204,7 @@ func TestProfilesToTranscodeOptions(t *testing.T) { // Test > 1 profile profiles = []ffmpeg.VideoProfile{ffmpeg.P144p30fps16x9, ffmpeg.P240p30fps16x9} - opts = profilesToTranscodeOptions(workDir, ffmpeg.Software, profiles, false, nil) + opts = profilesToTranscodeOptions(workDir, ffmpeg.Software, makeMeta(profiles, false)) assert.Equal(2, len(opts)) for i, p := range profiles { @@ -202,14 +212,17 @@ func TestProfilesToTranscodeOptions(t *testing.T) { assert.Equal(ffmpeg.Software, opts[i].Accel) assert.Equal(p, opts[i].Profile) assert.Equal("copy", opts[i].AudioEncoder.Name) + assert.Equal(opts[i].Metadata, map[string]string{ + "meta": "data", + }) } // Test different acceleration value - opts = profilesToTranscodeOptions(workDir, ffmpeg.Nvidia, profiles, false, nil) + opts = profilesToTranscodeOptions(workDir, ffmpeg.Nvidia, makeMeta(profiles, false)) assert.Equal(2, len(opts)) // Test signature calculation - opts = profilesToTranscodeOptions(workDir, ffmpeg.Nvidia, profiles, true, nil) + opts = profilesToTranscodeOptions(workDir, ffmpeg.Nvidia, makeMeta(profiles, true)) assert.True(opts[0].CalcSign) assert.True(opts[1].CalcSign) diff --git a/discovery/db_discovery.go b/discovery/db_discovery.go index 7747be9b72..36f9162aae 100644 --- a/discovery/db_discovery.go +++ b/discovery/db_discovery.go @@ -36,9 +36,10 @@ type DBOrchestratorPoolCache struct { rm common.RoundsManager bcast common.Broadcaster orchBlacklist []string + discoveryTimeout time.Duration } -func NewDBOrchestratorPoolCache(ctx context.Context, node *core.LivepeerNode, rm common.RoundsManager, orchBlacklist []string) (*DBOrchestratorPoolCache, error) { +func NewDBOrchestratorPoolCache(ctx context.Context, node *core.LivepeerNode, rm common.RoundsManager, orchBlacklist []string, discoveryTimeout time.Duration) (*DBOrchestratorPoolCache, error) { if node.Eth == nil { return nil, fmt.Errorf("could not create DBOrchestratorPoolCache: LivepeerEthClient is nil") } @@ -50,6 +51,7 @@ func NewDBOrchestratorPoolCache(ctx context.Context, node *core.LivepeerNode, rm rm: rm, bcast: core.NewBroadcaster(node), orchBlacklist: orchBlacklist, + discoveryTimeout: discoveryTimeout, } if err := dbo.cacheTranscoderPool(); err != nil { @@ -135,7 +137,7 @@ func (dbo *DBOrchestratorPoolCache) GetOrchestrators(ctx context.Context, numOrc return true } - orchPool := NewOrchestratorPoolWithPred(dbo.bcast, uris, pred, common.Score_Untrusted, dbo.orchBlacklist) + orchPool := NewOrchestratorPoolWithPred(dbo.bcast, uris, pred, common.Score_Untrusted, dbo.orchBlacklist, dbo.discoveryTimeout) orchInfos, err := orchPool.GetOrchestrators(ctx, numOrchestrators, suspender, caps, scorePred) if err != nil || len(orchInfos) <= 0 { return nil, err @@ -187,7 +189,8 @@ func (dbo *DBOrchestratorPoolCache) cacheOrchestratorStake() error { } resc, errc := make(chan *common.DBOrch, len(orchs)), make(chan error, len(orchs)) - ctx, cancel := context.WithTimeout(context.Background(), getOrchestratorsTimeoutLoop) + timeout := getOrchestratorTimeoutLoop //needs to be same or longer than GRPCConnectTimeout in server/rpc.go + ctx, cancel := context.WithTimeout(context.Background(), timeout) defer cancel() currentRound := dbo.rm.LastInitializedRound() @@ -263,7 +266,8 @@ func (dbo *DBOrchestratorPoolCache) cacheDBOrchs() error { } resc, errc := make(chan *common.DBOrch, len(orchs)), make(chan error, len(orchs)) - ctx, cancel := context.WithTimeout(context.Background(), getOrchestratorsTimeoutLoop) + timeout := getOrchestratorTimeoutLoop //needs to be same or longer than GRPCConnectTimeout in server/rpc.go + ctx, cancel := context.WithTimeout(context.Background(), timeout) defer cancel() getOrchInfo := func(dbOrch *common.DBOrch) { diff --git a/discovery/discovery.go b/discovery/discovery.go index 4b37b9c934..bc488274cc 100644 --- a/discovery/discovery.go +++ b/discovery/discovery.go @@ -20,20 +20,20 @@ import ( "github.com/golang/glog" ) -var getOrchestratorsTimeoutLoop = 3 * time.Second -var getOrchestratorsCutoffTimeout = 500 * time.Millisecond +var getOrchestratorTimeoutLoop = 3 * time.Second var maxGetOrchestratorCutoffTimeout = 6 * time.Second var serverGetOrchInfo = server.GetOrchestratorInfo type orchestratorPool struct { - infos []common.OrchestratorLocalInfo - pred func(info *net.OrchestratorInfo) bool - bcast common.Broadcaster - orchBlacklist []string + infos []common.OrchestratorLocalInfo + pred func(info *net.OrchestratorInfo) bool + bcast common.Broadcaster + orchBlacklist []string + discoveryTimeout time.Duration } -func NewOrchestratorPool(bcast common.Broadcaster, uris []*url.URL, score float32, orchBlacklist []string) *orchestratorPool { +func NewOrchestratorPool(bcast common.Broadcaster, uris []*url.URL, score float32, orchBlacklist []string, discoveryTimeout time.Duration) *orchestratorPool { if len(uris) <= 0 { // Should we return here? glog.Error("Orchestrator pool does not have any URIs") @@ -42,13 +42,13 @@ func NewOrchestratorPool(bcast common.Broadcaster, uris []*url.URL, score float3 for _, uri := range uris { infos = append(infos, common.OrchestratorLocalInfo{URL: uri, Score: score}) } - return &orchestratorPool{infos: infos, bcast: bcast, orchBlacklist: orchBlacklist} + return &orchestratorPool{infos: infos, bcast: bcast, orchBlacklist: orchBlacklist, discoveryTimeout: discoveryTimeout} } func NewOrchestratorPoolWithPred(bcast common.Broadcaster, addresses []*url.URL, - pred func(*net.OrchestratorInfo) bool, score float32, orchBlacklist []string) *orchestratorPool { + pred func(*net.OrchestratorInfo) bool, score float32, orchBlacklist []string, discoveryTimeout time.Duration) *orchestratorPool { - pool := NewOrchestratorPool(bcast, addresses, score, orchBlacklist) + pool := NewOrchestratorPool(bcast, addresses, score, orchBlacklist, discoveryTimeout) pool.pred = pred return pool } @@ -136,7 +136,7 @@ func (o *orchestratorPool) GetOrchestrators(ctx context.Context, numOrchestrator } // try to wait for orchestrators until at least 1 is found (with the exponential backoff timout) - timeout := getOrchestratorsCutoffTimeout + timeout := o.discoveryTimeout timer := time.NewTimer(timeout) for nbResp < numAvailableOrchs && len(ods) < numOrchestrators && !timedOut { diff --git a/discovery/discovery_test.go b/discovery/discovery_test.go index 33e20e5b79..dccf8dab5c 100644 --- a/discovery/discovery_test.go +++ b/discovery/discovery_test.go @@ -43,7 +43,7 @@ func TestNewDBOrchestratorPoolCache_NilEthClient_ReturnsError(t *testing.T) { } ctx, cancel := context.WithCancel(context.Background()) defer cancel() - pool, err := NewDBOrchestratorPoolCache(ctx, node, &stubRoundsManager{}, []string{}) + pool, err := NewDBOrchestratorPoolCache(ctx, node, &stubRoundsManager{}, []string{}, 500*time.Millisecond) assert.Nil(pool) assert.EqualError(err, "could not create DBOrchestratorPoolCache: LivepeerEthClient is nil") } @@ -73,7 +73,7 @@ func TestDeadLock(t *testing.T) { uris := stringsToURIs(addresses) assert := assert.New(t) wg.Add(len(uris)) - pool := NewOrchestratorPool(nil, uris, common.Score_Trusted, []string{}) + pool := NewOrchestratorPool(nil, uris, common.Score_Trusted, []string{}, 50*time.Millisecond) infos, err := pool.GetOrchestrators(context.TODO(), 1, newStubSuspender(), newStubCapabilities(), common.ScoreAtLeast(0)) assert.Nil(err, "Should not be error") assert.Len(infos, 1, "Should return one orchestrator") @@ -120,7 +120,7 @@ func TestDeadLock_NewOrchestratorPoolWithPred(t *testing.T) { } wg.Add(len(uris)) - pool := NewOrchestratorPoolWithPred(nil, uris, pred, common.Score_Trusted, []string{}) + pool := NewOrchestratorPoolWithPred(nil, uris, pred, common.Score_Trusted, []string{}, 50*time.Millisecond) infos, err := pool.GetOrchestrators(context.TODO(), 1, newStubSuspender(), newStubCapabilities(), common.ScoreAtLeast(0)) assert.Nil(err, "Should not be error") @@ -132,12 +132,12 @@ func TestPoolSize(t *testing.T) { addresses := stringsToURIs([]string{"https://127.0.0.1:8936", "https://127.0.0.1:8937", "https://127.0.0.1:8938"}) assert := assert.New(t) - pool := NewOrchestratorPool(nil, addresses, common.Score_Trusted, []string{}) + pool := NewOrchestratorPool(nil, addresses, common.Score_Trusted, []string{}, 50*time.Millisecond) assert.Equal(3, pool.Size()) // will results in len(uris) <= 0 -> log Error errorLogsBefore := glog.Stats.Error.Lines() - pool = NewOrchestratorPool(nil, nil, common.Score_Trusted, []string{}) + pool = NewOrchestratorPool(nil, nil, common.Score_Trusted, []string{}, 50*time.Millisecond) errorLogsAfter := glog.Stats.Error.Lines() assert.Equal(0, pool.Size()) assert.NotZero(t, errorLogsAfter-errorLogsBefore) @@ -163,7 +163,7 @@ func TestDBOrchestratorPoolCacheSize(t *testing.T) { goleak.VerifyNone(t, common.IgnoreRoutines()...) }() - emptyPool, err := NewDBOrchestratorPoolCache(ctx, node, &stubRoundsManager{}, []string{}) + emptyPool, err := NewDBOrchestratorPoolCache(ctx, node, &stubRoundsManager{}, []string{}, 500*time.Millisecond) require.NoError(err) require.NotNil(emptyPool) assert.Equal(0, emptyPool.Size()) @@ -174,7 +174,7 @@ func TestDBOrchestratorPoolCacheSize(t *testing.T) { dbh.UpdateOrch(ethOrchToDBOrch(o)) } - nonEmptyPool, err := NewDBOrchestratorPoolCache(ctx, node, &stubRoundsManager{}, []string{}) + nonEmptyPool, err := NewDBOrchestratorPoolCache(ctx, node, &stubRoundsManager{}, []string{}, 500*time.Millisecond) require.NoError(err) require.NotNil(nonEmptyPool) assert.Equal(len(addresses), nonEmptyPool.Size()) @@ -218,7 +218,7 @@ func TestNewDBOrchestorPoolCache_NoEthAddress(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - pool, err := NewDBOrchestratorPoolCache(ctx, node, rm, []string{}) + pool, err := NewDBOrchestratorPoolCache(ctx, node, rm, []string{}, 500*time.Millisecond) require.Nil(err) // Check that serverGetOrchInfo returns early and the orchestrator isn't updated @@ -272,7 +272,7 @@ func TestNewDBOrchestratorPoolCache_InvalidPrices(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - pool, err := NewDBOrchestratorPoolCache(ctx, node, rm, []string{}) + pool, err := NewDBOrchestratorPoolCache(ctx, node, rm, []string{}, 500*time.Millisecond) require.Nil(err) // priceInfo.PixelsPerUnit = 0 @@ -343,7 +343,7 @@ func TestNewDBOrchestratorPoolCache_GivenListOfOrchs_CreatesPoolCacheCorrectly(t sender.On("ValidateTicketParams", mock.Anything).Return(nil).Times(3) - pool, err := NewDBOrchestratorPoolCache(ctx, node, &stubRoundsManager{}, []string{}) + 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)) @@ -413,7 +413,7 @@ func TestNewDBOrchestratorPoolCache_TestURLs(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - pool, err := NewDBOrchestratorPoolCache(ctx, node, &stubRoundsManager{}, []string{}) + pool, err := NewDBOrchestratorPoolCache(ctx, node, &stubRoundsManager{}, []string{}, 500*time.Millisecond) require.NoError(err) // bad URLs are inserted in the database but are not included in the working set, as there is no returnable query for getting their priceInfo // And if URL is updated it won't be picked up until next cache update @@ -446,7 +446,7 @@ func TestNewDBOrchestratorPoolCache_TestURLs_Empty(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - pool, err := NewDBOrchestratorPoolCache(ctx, node, &stubRoundsManager{}, []string{}) + pool, err := NewDBOrchestratorPoolCache(ctx, node, &stubRoundsManager{}, []string{}, 500*time.Millisecond) require.NoError(err) assert.Equal(0, pool.Size()) infos := pool.GetInfos() @@ -531,7 +531,7 @@ func TestNewDBOrchestorPoolCache_PollOrchestratorInfo(t *testing.T) { origCacheRefreshInterval := cacheRefreshInterval cacheRefreshInterval = 200 * time.Millisecond defer func() { cacheRefreshInterval = origCacheRefreshInterval }() - pool, err := NewDBOrchestratorPoolCache(ctx, node, &stubRoundsManager{}, []string{}) + pool, err := NewDBOrchestratorPoolCache(ctx, node, &stubRoundsManager{}, []string{}, 500*time.Millisecond) require.NoError(err) // Ensure orchestrators exist in DB @@ -569,7 +569,7 @@ func TestNewOrchestratorPoolCache_GivenListOfOrchs_CreatesPoolCacheCorrectly(t * assert := assert.New(t) // creating NewOrchestratorPool with orch addresses - offchainOrch := NewOrchestratorPool(nil, addresses, common.Score_Trusted, []string{}) + offchainOrch := NewOrchestratorPool(nil, addresses, common.Score_Trusted, []string{}, 50*time.Millisecond) for i, info := range offchainOrch.infos { assert.Equal(info.URL.String(), addresses[i].String()) @@ -595,7 +595,7 @@ func TestNewOrchestratorPoolWithPred_TestPredicate(t *testing.T) { } uris := stringsToURIs(addresses) - pool := NewOrchestratorPoolWithPred(nil, uris, pred, common.Score_Trusted, []string{}) + pool := NewOrchestratorPoolWithPred(nil, uris, pred, common.Score_Trusted, []string{}, 50*time.Millisecond) oInfo := &net.OrchestratorInfo{ PriceInfo: &net.PriceInfo{ @@ -685,7 +685,7 @@ func TestCachedPool_AllOrchestratorsTooExpensive_ReturnsAllOrchestrators(t *test sender.On("ValidateTicketParams", mock.Anything).Return(nil) - pool, err := NewDBOrchestratorPoolCache(ctx, node, &stubRoundsManager{}, []string{}) + pool, err := NewDBOrchestratorPoolCache(ctx, node, &stubRoundsManager{}, []string{}, 500*time.Millisecond) require.NoError(err) // ensuring orchs exist in DB @@ -775,7 +775,7 @@ func TestCachedPool_GetOrchestrators_MaxBroadcastPriceNotSet(t *testing.T) { sender.On("ValidateTicketParams", mock.Anything).Return(nil) - pool, err := NewDBOrchestratorPoolCache(ctx, node, &stubRoundsManager{}, []string{}) + pool, err := NewDBOrchestratorPoolCache(ctx, node, &stubRoundsManager{}, []string{}, 500*time.Millisecond) require.NoError(err) // ensuring orchs exist in DB @@ -881,7 +881,7 @@ func TestCachedPool_N_OrchestratorsGoodPricing_ReturnsNOrchestrators(t *testing. sender.On("ValidateTicketParams", mock.Anything).Return(nil) - pool, err := NewDBOrchestratorPoolCache(ctx, node, &stubRoundsManager{}, []string{}) + pool, err := NewDBOrchestratorPoolCache(ctx, node, &stubRoundsManager{}, []string{}, 500*time.Millisecond) require.NoError(err) // ensuring orchs exist in DB @@ -928,7 +928,7 @@ func TestCachedPool_GetOrchestrators_TicketParamsValidation(t *testing.T) { gmp := runtime.GOMAXPROCS(50) defer runtime.GOMAXPROCS(gmp) // Disable retrying discovery with extended timeout - maxGetOrchestratorCutoffTimeout = getOrchestratorsCutoffTimeout + maxGetOrchestratorCutoffTimeout = 500 * time.Millisecond server.BroadcastCfg.SetMaxPrice(nil) @@ -971,7 +971,7 @@ func TestCachedPool_GetOrchestrators_TicketParamsValidation(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - pool, err := NewDBOrchestratorPoolCache(ctx, node, &stubRoundsManager{}, []string{}) + pool, err := NewDBOrchestratorPoolCache(ctx, node, &stubRoundsManager{}, []string{}, 500*time.Millisecond) require.NoError(err) // Test 25 out of 50 orchs pass ticket params validation @@ -1065,7 +1065,7 @@ func TestCachedPool_GetOrchestrators_OnlyActiveOrchestrators(t *testing.T) { sender.On("ValidateTicketParams", mock.Anything).Return(nil) - pool, err := NewDBOrchestratorPoolCache(ctx, node, &stubRoundsManager{round: big.NewInt(24)}, []string{}) + pool, err := NewDBOrchestratorPoolCache(ctx, node, &stubRoundsManager{round: big.NewInt(24)}, []string{}, 500*time.Millisecond) require.NoError(err) // ensuring orchs exist in DB @@ -1120,7 +1120,7 @@ func TestNewWHOrchestratorPoolCache(t *testing.T) { // assert created webhook pool is correct length whURL, _ := url.ParseRequestURI("https://livepeer.live/api/orchestrator") - whpool := NewWebhookPool(nil, whURL) + whpool := NewWebhookPool(nil, whURL, 500*time.Millisecond) assert.Equal(3, whpool.Size()) // assert that list is not refreshed if lastRequest is less than 1 min ago and hash is the same @@ -1270,6 +1270,7 @@ func TestOrchestratorPool_GetOrchestrators(t *testing.T) { assert := assert.New(t) addresses := stringsToURIs([]string{"https://127.0.0.1:8936", "https://127.0.0.1:8937", "https://127.0.0.1:8938"}) + orchTimeout := 500 * time.Millisecond wg := sync.WaitGroup{} orchCb := func() error { return nil } @@ -1283,7 +1284,7 @@ func TestOrchestratorPool_GetOrchestrators(t *testing.T) { }, err } - pool := NewOrchestratorPool(nil, addresses, common.Score_Trusted, []string{}) + pool := NewOrchestratorPool(nil, addresses, common.Score_Trusted, []string{}, orchTimeout) // Check that we receive everything wg.Add(len(addresses)) @@ -1326,7 +1327,7 @@ func TestOrchestratorPool_GetOrchestrators(t *testing.T) { assert.Len(res, len(addresses)-1) // Ensure that the timeout did not fire assert.Less(end.Sub(start).Milliseconds(), - getOrchestratorsTimeoutLoop.Milliseconds()) + pool.discoveryTimeout.Milliseconds()) } @@ -1348,7 +1349,7 @@ func TestOrchestratorPool_GetOrchestrators_SuspendedOrchs(t *testing.T) { }, err } - pool := NewOrchestratorPool(nil, addresses, common.Score_Trusted, []string{}) + pool := NewOrchestratorPool(nil, addresses, common.Score_Trusted, []string{}, 50*time.Millisecond) // suspend https://127.0.0.1:8938 sus := newStubSuspender() @@ -1417,7 +1418,7 @@ func TestOrchestratorPool_ShuffleGetOrchestrators(t *testing.T) { return &net.OrchestratorInfo{Transcoder: server.String()}, nil } - pool := NewOrchestratorPool(nil, addresses, common.Score_Trusted, []string{}) + pool := NewOrchestratorPool(nil, addresses, common.Score_Trusted, []string{}, 50*time.Millisecond) // Check that randomization happens: check for elements in a different order // Could fail sometimes due to scheduling; the order of execution is undefined @@ -1480,14 +1481,12 @@ func TestOrchestratorPool_GetOrchestratorTimeout(t *testing.T) { return &net.OrchestratorInfo{}, nil } - oldTimeout := getOrchestratorsTimeoutLoop - getOrchestratorsTimeoutLoop = 1 * time.Millisecond - defer func() { getOrchestratorsTimeoutLoop = oldTimeout }() + timeout := 1 * time.Millisecond - pool := NewOrchestratorPool(nil, addresses, common.Score_Trusted, []string{}) + pool := NewOrchestratorPool(nil, addresses, common.Score_Trusted, []string{}, timeout) timedOut := func(start, end time.Time) bool { - return end.Sub(start).Milliseconds() >= getOrchestratorsTimeoutLoop.Milliseconds() + return end.Sub(start).Milliseconds() >= pool.discoveryTimeout.Milliseconds() } // We may only return a subset of responses for a given test @@ -1529,7 +1528,7 @@ func TestOrchestratorPool_GetOrchestratorTimeout(t *testing.T) { assert.True(responsesDrained(), "Did not drain responses in time") // Sanity check we get addresses with a reasonable timeout and no forced delay - getOrchestratorsTimeoutLoop = 25 * time.Millisecond + pool.discoveryTimeout = 25 * time.Millisecond go drainOrchResponses(len(addresses)) start = time.Now() res, err = getOrchestrators(len(addresses)) @@ -1579,7 +1578,7 @@ func TestOrchestratorPool_Capabilities(t *testing.T) { responses := []*net.OrchestratorInfo{i1, i2, i3, i4, i5} addresses := stringsToURIs([]string{"a://b", "a://b", "a://b", "a://b", "a://b"}) - pool := NewOrchestratorPool(nil, addresses, common.Score_Trusted, []string{hex.EncodeToString(address)}) + pool := NewOrchestratorPool(nil, addresses, common.Score_Trusted, []string{hex.EncodeToString(address)}, 50*time.Millisecond) // some sanity checks assert.Len(addresses, len(responses)) @@ -1629,3 +1628,24 @@ func TestOrchestratorPool_Capabilities(t *testing.T) { assert.Len(infos, 1) assert.Equal(i4, infos[0].RemoteInfo) } + +func TestSetGetOrchestratorTimeout(t *testing.T) { + assert := assert.New(t) + dbh, _, err := common.TempDB(t) + require := require.New(t) + require.Nil(err) + + sender := &pm.MockSender{} + node := &core.LivepeerNode{ + Database: dbh, + Eth: ð.StubClient{TotalStake: big.NewInt(0)}, + Sender: sender, + } + + //set timeout to 1000ms + poolCache, err := NewDBOrchestratorPoolCache(context.TODO(), node, &stubRoundsManager{}, []string{}, 1000*time.Millisecond) + assert.Nil(err) + //confirm the timeout is now 1000ms + assert.Equal(poolCache.discoveryTimeout, 1000*time.Millisecond) + +} diff --git a/discovery/wh_discovery.go b/discovery/wh_discovery.go index 1c4c8539f3..7e552dfcce 100644 --- a/discovery/wh_discovery.go +++ b/discovery/wh_discovery.go @@ -21,19 +21,21 @@ type webhookResponse struct { } type webhookPool struct { - pool *orchestratorPool - callback *url.URL - responseHash ethcommon.Hash - lastRequest time.Time - mu *sync.RWMutex - bcast common.Broadcaster + pool *orchestratorPool + callback *url.URL + responseHash ethcommon.Hash + lastRequest time.Time + mu *sync.RWMutex + bcast common.Broadcaster + discoveryTimeout time.Duration } -func NewWebhookPool(bcast common.Broadcaster, callback *url.URL) *webhookPool { +func NewWebhookPool(bcast common.Broadcaster, callback *url.URL, discoveryTimeout time.Duration) *webhookPool { p := &webhookPool{ - callback: callback, - mu: &sync.RWMutex{}, - bcast: bcast, + callback: callback, + mu: &sync.RWMutex{}, + bcast: bcast, + discoveryTimeout: discoveryTimeout, } go p.getInfos() return p @@ -71,7 +73,7 @@ func (w *webhookPool) getInfos() ([]common.OrchestratorLocalInfo, error) { } // pool = NewOrchestratorPool(w.bcast, addrs) - pool = &orchestratorPool{infos: infos, bcast: w.bcast} + pool = &orchestratorPool{infos: infos, bcast: w.bcast, discoveryTimeout: w.discoveryTimeout} w.mu.Lock() w.responseHash = hash diff --git a/go.mod b/go.mod index 9347403796..4a40dbc93e 100644 --- a/go.mod +++ b/go.mod @@ -14,7 +14,7 @@ require ( github.com/jaypipes/pcidb v1.0.0 github.com/livepeer/go-tools v0.0.0-20220805063103-76df6beb6506 github.com/livepeer/livepeer-data v0.7.5-0.20231004073737-06f1f383fb18 - github.com/livepeer/lpms v0.0.0-20240711034524-d9c78b62effd + 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/olekukonko/tablewriter v0.0.5 diff --git a/go.sum b/go.sum index 92db740f3b..b29ad7eb76 100644 --- a/go.sum +++ b/go.sum @@ -446,8 +446,8 @@ github.com/livepeer/joy4 v0.1.2-0.20191121080656-b2fea45cbded h1:ZQlvR5RB4nfT+cO 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= github.com/livepeer/livepeer-data v0.7.5-0.20231004073737-06f1f383fb18/go.mod h1:Jpf4jHK+fbWioBHRDRM1WadNT1qmY27g2YicTdO0Rtc= -github.com/livepeer/lpms v0.0.0-20240711034524-d9c78b62effd h1:IdSZM8gUW7N4pHln8PyUFmvch6oK01QXyknYpycGA80= -github.com/livepeer/lpms v0.0.0-20240711034524-d9c78b62effd/go.mod h1:z5ROP1l5OzAKSoqVRLc34MjUdueil6wHSecQYV7llIw= +github.com/livepeer/lpms v0.0.0-20240909171057-fe5aff1fa6a2 h1:UYVfhBuJ2h6eYOCBaCzjoWoj3onhZ+6wFhXNllELYDA= +github.com/livepeer/lpms v0.0.0-20240909171057-fe5aff1fa6a2/go.mod h1:z5ROP1l5OzAKSoqVRLc34MjUdueil6wHSecQYV7llIw= github.com/livepeer/m3u8 v0.11.1 h1:VkUJzfNTyjy9mqsgp5JPvouwna8wGZMvd/gAfT5FinU= github.com/livepeer/m3u8 v0.11.1/go.mod h1:IUqAtwWPAG2CblfQa4SVzTQoDcEMPyfNOaBSxqHMS04= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4= diff --git a/monitor/census.go b/monitor/census.go index f6ee869231..f9dae6babb 100644 --- a/monitor/census.go +++ b/monitor/census.go @@ -112,6 +112,7 @@ type ( kClientIP tag.Key kOrchestratorURI tag.Key kOrchestratorAddress tag.Key + kOrchestratorVersion tag.Key kFVErrorType tag.Key mSegmentSourceAppeared *stats.Int64Measure mSegmentEmerged *stats.Int64Measure @@ -252,6 +253,7 @@ func InitCensus(nodeType NodeType, version string) { census.kClientIP = tag.MustNewKey("client_ip") census.kOrchestratorURI = tag.MustNewKey("orchestrator_uri") census.kOrchestratorAddress = tag.MustNewKey("orchestrator_address") + census.kOrchestratorVersion = tag.MustNewKey("orchestrator_version") census.kFVErrorType = tag.MustNewKey("fverror_type") census.kSegClassName = tag.MustNewKey("seg_class_name") census.ctx, err = tag.New(ctx, tag.Insert(census.kNodeType, string(nodeType)), tag.Insert(census.kNodeID, NodeID)) @@ -369,8 +371,8 @@ func InitCensus(nodeType NodeType, version string) { baseTagsWithManifestIDAndIP = append([]tag.Key{census.kClientIP}, baseTagsWithManifestID...) } baseTagsWithManifestIDAndOrchInfo := baseTagsWithManifestID - baseTagsWithOrchInfo = append([]tag.Key{census.kOrchestratorURI, census.kOrchestratorAddress}, baseTags...) - baseTagsWithManifestIDAndOrchInfo = append([]tag.Key{census.kOrchestratorURI, census.kOrchestratorAddress}, baseTagsWithManifestID...) + baseTagsWithOrchInfo = append([]tag.Key{census.kOrchestratorURI, census.kOrchestratorAddress, census.kOrchestratorVersion}, baseTags...) + baseTagsWithManifestIDAndOrchInfo = append([]tag.Key{census.kOrchestratorURI, census.kOrchestratorAddress, census.kOrchestratorVersion}, baseTagsWithManifestID...) views := []*view.View{ { @@ -914,6 +916,10 @@ func manifestIDTagAndOrchInfo(orchInfo *lpnet.OrchestratorInfo, ctx context.Cont tag.Insert(census.kOrchestratorURI, orchInfo.GetTranscoder()), tag.Insert(census.kOrchestratorAddress, common.BytesToAddress(orchInfo.GetAddress()).String()), ) + capabilities := orchInfo.GetCapabilities() + if capabilities != nil { + others = append(others, tag.Insert(census.kOrchestratorVersion, capabilities.Version)) + } return others } diff --git a/net/lp_rpc.pb.go b/net/lp_rpc.pb.go index d5102d77c5..5f1f72c83d 100644 --- a/net/lp_rpc.pb.go +++ b/net/lp_rpc.pb.go @@ -1,24 +1,24 @@ // Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.28.1 +// protoc v3.21.12 // source: net/lp_rpc.proto package net import ( - fmt "fmt" - proto "github.com/golang/protobuf/proto" - math "math" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" ) -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) type OSInfo_StorageType int32 @@ -28,24 +28,45 @@ const ( OSInfo_GOOGLE OSInfo_StorageType = 2 ) -var OSInfo_StorageType_name = map[int32]string{ - 0: "DIRECT", - 1: "S3", - 2: "GOOGLE", -} +// Enum value maps for OSInfo_StorageType. +var ( + OSInfo_StorageType_name = map[int32]string{ + 0: "DIRECT", + 1: "S3", + 2: "GOOGLE", + } + OSInfo_StorageType_value = map[string]int32{ + "DIRECT": 0, + "S3": 1, + "GOOGLE": 2, + } +) -var OSInfo_StorageType_value = map[string]int32{ - "DIRECT": 0, - "S3": 1, - "GOOGLE": 2, +func (x OSInfo_StorageType) Enum() *OSInfo_StorageType { + p := new(OSInfo_StorageType) + *p = x + return p } func (x OSInfo_StorageType) String() string { - return proto.EnumName(OSInfo_StorageType_name, int32(x)) + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) } +func (OSInfo_StorageType) Descriptor() protoreflect.EnumDescriptor { + return file_net_lp_rpc_proto_enumTypes[0].Descriptor() +} + +func (OSInfo_StorageType) Type() protoreflect.EnumType { + return &file_net_lp_rpc_proto_enumTypes[0] +} + +func (x OSInfo_StorageType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use OSInfo_StorageType.Descriptor instead. func (OSInfo_StorageType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_034e29c79f9ba827, []int{4, 0} + return file_net_lp_rpc_proto_rawDescGZIP(), []int{4, 0} } // Desired output format @@ -56,22 +77,43 @@ const ( VideoProfile_MP4 VideoProfile_Format = 1 ) -var VideoProfile_Format_name = map[int32]string{ - 0: "MPEGTS", - 1: "MP4", -} +// Enum value maps for VideoProfile_Format. +var ( + VideoProfile_Format_name = map[int32]string{ + 0: "MPEGTS", + 1: "MP4", + } + VideoProfile_Format_value = map[string]int32{ + "MPEGTS": 0, + "MP4": 1, + } +) -var VideoProfile_Format_value = map[string]int32{ - "MPEGTS": 0, - "MP4": 1, +func (x VideoProfile_Format) Enum() *VideoProfile_Format { + p := new(VideoProfile_Format) + *p = x + return p } func (x VideoProfile_Format) String() string { - return proto.EnumName(VideoProfile_Format_name, int32(x)) + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (VideoProfile_Format) Descriptor() protoreflect.EnumDescriptor { + return file_net_lp_rpc_proto_enumTypes[1].Descriptor() +} + +func (VideoProfile_Format) Type() protoreflect.EnumType { + return &file_net_lp_rpc_proto_enumTypes[1] +} + +func (x VideoProfile_Format) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) } +// Deprecated: Use VideoProfile_Format.Descriptor instead. func (VideoProfile_Format) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_034e29c79f9ba827, []int{12, 0} + return file_net_lp_rpc_proto_rawDescGZIP(), []int{12, 0} } type VideoProfile_Profile int32 @@ -84,28 +126,49 @@ const ( VideoProfile_H264_CONSTRAINED_HIGH VideoProfile_Profile = 4 ) -var VideoProfile_Profile_name = map[int32]string{ - 0: "ENCODER_DEFAULT", - 1: "H264_BASELINE", - 2: "H264_MAIN", - 3: "H264_HIGH", - 4: "H264_CONSTRAINED_HIGH", -} +// Enum value maps for VideoProfile_Profile. +var ( + VideoProfile_Profile_name = map[int32]string{ + 0: "ENCODER_DEFAULT", + 1: "H264_BASELINE", + 2: "H264_MAIN", + 3: "H264_HIGH", + 4: "H264_CONSTRAINED_HIGH", + } + VideoProfile_Profile_value = map[string]int32{ + "ENCODER_DEFAULT": 0, + "H264_BASELINE": 1, + "H264_MAIN": 2, + "H264_HIGH": 3, + "H264_CONSTRAINED_HIGH": 4, + } +) -var VideoProfile_Profile_value = map[string]int32{ - "ENCODER_DEFAULT": 0, - "H264_BASELINE": 1, - "H264_MAIN": 2, - "H264_HIGH": 3, - "H264_CONSTRAINED_HIGH": 4, +func (x VideoProfile_Profile) Enum() *VideoProfile_Profile { + p := new(VideoProfile_Profile) + *p = x + return p } func (x VideoProfile_Profile) String() string { - return proto.EnumName(VideoProfile_Profile_name, int32(x)) + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (VideoProfile_Profile) Descriptor() protoreflect.EnumDescriptor { + return file_net_lp_rpc_proto_enumTypes[2].Descriptor() +} + +func (VideoProfile_Profile) Type() protoreflect.EnumType { + return &file_net_lp_rpc_proto_enumTypes[2] +} + +func (x VideoProfile_Profile) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) } +// Deprecated: Use VideoProfile_Profile.Descriptor instead. func (VideoProfile_Profile) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_034e29c79f9ba827, []int{12, 1} + return file_net_lp_rpc_proto_rawDescGZIP(), []int{12, 1} } type VideoProfile_VideoCodec int32 @@ -117,26 +180,47 @@ const ( VideoProfile_VP9 VideoProfile_VideoCodec = 3 ) -var VideoProfile_VideoCodec_name = map[int32]string{ - 0: "H264", - 1: "H265", - 2: "VP8", - 3: "VP9", -} +// Enum value maps for VideoProfile_VideoCodec. +var ( + VideoProfile_VideoCodec_name = map[int32]string{ + 0: "H264", + 1: "H265", + 2: "VP8", + 3: "VP9", + } + VideoProfile_VideoCodec_value = map[string]int32{ + "H264": 0, + "H265": 1, + "VP8": 2, + "VP9": 3, + } +) -var VideoProfile_VideoCodec_value = map[string]int32{ - "H264": 0, - "H265": 1, - "VP8": 2, - "VP9": 3, +func (x VideoProfile_VideoCodec) Enum() *VideoProfile_VideoCodec { + p := new(VideoProfile_VideoCodec) + *p = x + return p } func (x VideoProfile_VideoCodec) String() string { - return proto.EnumName(VideoProfile_VideoCodec_name, int32(x)) + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) } +func (VideoProfile_VideoCodec) Descriptor() protoreflect.EnumDescriptor { + return file_net_lp_rpc_proto_enumTypes[3].Descriptor() +} + +func (VideoProfile_VideoCodec) Type() protoreflect.EnumType { + return &file_net_lp_rpc_proto_enumTypes[3] +} + +func (x VideoProfile_VideoCodec) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use VideoProfile_VideoCodec.Descriptor instead. func (VideoProfile_VideoCodec) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_034e29c79f9ba827, []int{12, 2} + return file_net_lp_rpc_proto_rawDescGZIP(), []int{12, 2} } type VideoProfile_ChromaSubsampling int32 @@ -147,185 +231,237 @@ const ( VideoProfile_CHROMA_444 VideoProfile_ChromaSubsampling = 2 ) -var VideoProfile_ChromaSubsampling_name = map[int32]string{ - 0: "CHROMA_420", - 1: "CHROMA_422", - 2: "CHROMA_444", -} +// Enum value maps for VideoProfile_ChromaSubsampling. +var ( + VideoProfile_ChromaSubsampling_name = map[int32]string{ + 0: "CHROMA_420", + 1: "CHROMA_422", + 2: "CHROMA_444", + } + VideoProfile_ChromaSubsampling_value = map[string]int32{ + "CHROMA_420": 0, + "CHROMA_422": 1, + "CHROMA_444": 2, + } +) -var VideoProfile_ChromaSubsampling_value = map[string]int32{ - "CHROMA_420": 0, - "CHROMA_422": 1, - "CHROMA_444": 2, +func (x VideoProfile_ChromaSubsampling) Enum() *VideoProfile_ChromaSubsampling { + p := new(VideoProfile_ChromaSubsampling) + *p = x + return p } func (x VideoProfile_ChromaSubsampling) String() string { - return proto.EnumName(VideoProfile_ChromaSubsampling_name, int32(x)) + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) } -func (VideoProfile_ChromaSubsampling) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_034e29c79f9ba827, []int{12, 3} +func (VideoProfile_ChromaSubsampling) Descriptor() protoreflect.EnumDescriptor { + return file_net_lp_rpc_proto_enumTypes[4].Descriptor() } -type PingPong struct { - // Implementation defined - Value []byte `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` +func (VideoProfile_ChromaSubsampling) Type() protoreflect.EnumType { + return &file_net_lp_rpc_proto_enumTypes[4] } -func (m *PingPong) Reset() { *m = PingPong{} } -func (m *PingPong) String() string { return proto.CompactTextString(m) } -func (*PingPong) ProtoMessage() {} -func (*PingPong) Descriptor() ([]byte, []int) { - return fileDescriptor_034e29c79f9ba827, []int{0} +func (x VideoProfile_ChromaSubsampling) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) } -func (m *PingPong) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_PingPong.Unmarshal(m, b) +// Deprecated: Use VideoProfile_ChromaSubsampling.Descriptor instead. +func (VideoProfile_ChromaSubsampling) EnumDescriptor() ([]byte, []int) { + return file_net_lp_rpc_proto_rawDescGZIP(), []int{12, 3} } -func (m *PingPong) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_PingPong.Marshal(b, m, deterministic) + +type PingPong struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Implementation defined + Value []byte `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"` } -func (m *PingPong) XXX_Merge(src proto.Message) { - xxx_messageInfo_PingPong.Merge(m, src) + +func (x *PingPong) Reset() { + *x = PingPong{} + if protoimpl.UnsafeEnabled { + mi := &file_net_lp_rpc_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *PingPong) XXX_Size() int { - return xxx_messageInfo_PingPong.Size(m) + +func (x *PingPong) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *PingPong) XXX_DiscardUnknown() { - xxx_messageInfo_PingPong.DiscardUnknown(m) + +func (*PingPong) ProtoMessage() {} + +func (x *PingPong) ProtoReflect() protoreflect.Message { + mi := &file_net_lp_rpc_proto_msgTypes[0] + 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) } -var xxx_messageInfo_PingPong proto.InternalMessageInfo +// Deprecated: Use PingPong.ProtoReflect.Descriptor instead. +func (*PingPong) Descriptor() ([]byte, []int) { + return file_net_lp_rpc_proto_rawDescGZIP(), []int{0} +} -func (m *PingPong) GetValue() []byte { - if m != nil { - return m.Value +func (x *PingPong) GetValue() []byte { + if x != nil { + return x.Value } return nil } // sent by Broadcaster to Orchestrator to terminate the transcoding session and free resources (used for verification sessions) type EndTranscodingSessionRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + // Data for transcoding authentication - AuthToken *AuthToken `protobuf:"bytes,1,opt,name=auth_token,json=authToken,proto3" json:"auth_token,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + AuthToken *AuthToken `protobuf:"bytes,1,opt,name=auth_token,json=authToken,proto3" json:"auth_token,omitempty"` } -func (m *EndTranscodingSessionRequest) Reset() { *m = EndTranscodingSessionRequest{} } -func (m *EndTranscodingSessionRequest) String() string { return proto.CompactTextString(m) } -func (*EndTranscodingSessionRequest) ProtoMessage() {} -func (*EndTranscodingSessionRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_034e29c79f9ba827, []int{1} +func (x *EndTranscodingSessionRequest) Reset() { + *x = EndTranscodingSessionRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_net_lp_rpc_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *EndTranscodingSessionRequest) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_EndTranscodingSessionRequest.Unmarshal(m, b) -} -func (m *EndTranscodingSessionRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_EndTranscodingSessionRequest.Marshal(b, m, deterministic) -} -func (m *EndTranscodingSessionRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_EndTranscodingSessionRequest.Merge(m, src) -} -func (m *EndTranscodingSessionRequest) XXX_Size() int { - return xxx_messageInfo_EndTranscodingSessionRequest.Size(m) +func (x *EndTranscodingSessionRequest) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *EndTranscodingSessionRequest) XXX_DiscardUnknown() { - xxx_messageInfo_EndTranscodingSessionRequest.DiscardUnknown(m) + +func (*EndTranscodingSessionRequest) ProtoMessage() {} + +func (x *EndTranscodingSessionRequest) ProtoReflect() protoreflect.Message { + mi := &file_net_lp_rpc_proto_msgTypes[1] + 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) } -var xxx_messageInfo_EndTranscodingSessionRequest proto.InternalMessageInfo +// Deprecated: Use EndTranscodingSessionRequest.ProtoReflect.Descriptor instead. +func (*EndTranscodingSessionRequest) Descriptor() ([]byte, []int) { + return file_net_lp_rpc_proto_rawDescGZIP(), []int{1} +} -func (m *EndTranscodingSessionRequest) GetAuthToken() *AuthToken { - if m != nil { - return m.AuthToken +func (x *EndTranscodingSessionRequest) GetAuthToken() *AuthToken { + if x != nil { + return x.AuthToken } return nil } type EndTranscodingSessionResponse struct { - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields } -func (m *EndTranscodingSessionResponse) Reset() { *m = EndTranscodingSessionResponse{} } -func (m *EndTranscodingSessionResponse) String() string { return proto.CompactTextString(m) } -func (*EndTranscodingSessionResponse) ProtoMessage() {} -func (*EndTranscodingSessionResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_034e29c79f9ba827, []int{2} +func (x *EndTranscodingSessionResponse) Reset() { + *x = EndTranscodingSessionResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_net_lp_rpc_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *EndTranscodingSessionResponse) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_EndTranscodingSessionResponse.Unmarshal(m, b) -} -func (m *EndTranscodingSessionResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_EndTranscodingSessionResponse.Marshal(b, m, deterministic) -} -func (m *EndTranscodingSessionResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_EndTranscodingSessionResponse.Merge(m, src) +func (x *EndTranscodingSessionResponse) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *EndTranscodingSessionResponse) XXX_Size() int { - return xxx_messageInfo_EndTranscodingSessionResponse.Size(m) -} -func (m *EndTranscodingSessionResponse) XXX_DiscardUnknown() { - xxx_messageInfo_EndTranscodingSessionResponse.DiscardUnknown(m) + +func (*EndTranscodingSessionResponse) ProtoMessage() {} + +func (x *EndTranscodingSessionResponse) ProtoReflect() protoreflect.Message { + mi := &file_net_lp_rpc_proto_msgTypes[2] + 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) } -var xxx_messageInfo_EndTranscodingSessionResponse proto.InternalMessageInfo +// Deprecated: Use EndTranscodingSessionResponse.ProtoReflect.Descriptor instead. +func (*EndTranscodingSessionResponse) Descriptor() ([]byte, []int) { + return file_net_lp_rpc_proto_rawDescGZIP(), []int{2} +} // This request is sent by the broadcaster in `GetTranscoder` to request // information on which transcoder to use. type OrchestratorRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + // Ethereum address of the broadcaster 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"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + Sig []byte `protobuf:"bytes,2,opt,name=sig,proto3" json:"sig,omitempty"` } -func (m *OrchestratorRequest) Reset() { *m = OrchestratorRequest{} } -func (m *OrchestratorRequest) String() string { return proto.CompactTextString(m) } -func (*OrchestratorRequest) ProtoMessage() {} -func (*OrchestratorRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_034e29c79f9ba827, []int{3} +func (x *OrchestratorRequest) Reset() { + *x = OrchestratorRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_net_lp_rpc_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *OrchestratorRequest) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_OrchestratorRequest.Unmarshal(m, b) -} -func (m *OrchestratorRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_OrchestratorRequest.Marshal(b, m, deterministic) -} -func (m *OrchestratorRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_OrchestratorRequest.Merge(m, src) +func (x *OrchestratorRequest) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *OrchestratorRequest) XXX_Size() int { - return xxx_messageInfo_OrchestratorRequest.Size(m) -} -func (m *OrchestratorRequest) XXX_DiscardUnknown() { - xxx_messageInfo_OrchestratorRequest.DiscardUnknown(m) + +func (*OrchestratorRequest) ProtoMessage() {} + +func (x *OrchestratorRequest) ProtoReflect() protoreflect.Message { + mi := &file_net_lp_rpc_proto_msgTypes[3] + 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) } -var xxx_messageInfo_OrchestratorRequest proto.InternalMessageInfo +// Deprecated: Use OrchestratorRequest.ProtoReflect.Descriptor instead. +func (*OrchestratorRequest) Descriptor() ([]byte, []int) { + return file_net_lp_rpc_proto_rawDescGZIP(), []int{3} +} -func (m *OrchestratorRequest) GetAddress() []byte { - if m != nil { - return m.Address +func (x *OrchestratorRequest) GetAddress() []byte { + if x != nil { + return x.Address } return nil } -func (m *OrchestratorRequest) GetSig() []byte { - if m != nil { - return m.Sig +func (x *OrchestratorRequest) GetSig() []byte { + if x != nil { + return x.Sig } return nil } @@ -333,54 +469,66 @@ func (m *OrchestratorRequest) GetSig() []byte { // OSInfo needed to negotiate storages that will be used. // It carries info needed to write to the storage. type OSInfo struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + // Storage type: direct, s3, ipfs. - StorageType OSInfo_StorageType `protobuf:"varint,1,opt,name=storageType,proto3,enum=net.OSInfo_StorageType" json:"storageType,omitempty"` - S3Info *S3OSInfo `protobuf:"bytes,16,opt,name=s3info,proto3" json:"s3info,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + StorageType OSInfo_StorageType `protobuf:"varint,1,opt,name=storageType,proto3,enum=net.OSInfo_StorageType" json:"storageType,omitempty"` + S3Info *S3OSInfo `protobuf:"bytes,16,opt,name=s3info,proto3" json:"s3info,omitempty"` } -func (m *OSInfo) Reset() { *m = OSInfo{} } -func (m *OSInfo) String() string { return proto.CompactTextString(m) } -func (*OSInfo) ProtoMessage() {} -func (*OSInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_034e29c79f9ba827, []int{4} +func (x *OSInfo) Reset() { + *x = OSInfo{} + if protoimpl.UnsafeEnabled { + mi := &file_net_lp_rpc_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *OSInfo) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_OSInfo.Unmarshal(m, b) +func (x *OSInfo) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *OSInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_OSInfo.Marshal(b, m, deterministic) -} -func (m *OSInfo) XXX_Merge(src proto.Message) { - xxx_messageInfo_OSInfo.Merge(m, src) -} -func (m *OSInfo) XXX_Size() int { - return xxx_messageInfo_OSInfo.Size(m) -} -func (m *OSInfo) XXX_DiscardUnknown() { - xxx_messageInfo_OSInfo.DiscardUnknown(m) + +func (*OSInfo) ProtoMessage() {} + +func (x *OSInfo) ProtoReflect() protoreflect.Message { + mi := &file_net_lp_rpc_proto_msgTypes[4] + 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) } -var xxx_messageInfo_OSInfo proto.InternalMessageInfo +// Deprecated: Use OSInfo.ProtoReflect.Descriptor instead. +func (*OSInfo) Descriptor() ([]byte, []int) { + return file_net_lp_rpc_proto_rawDescGZIP(), []int{4} +} -func (m *OSInfo) GetStorageType() OSInfo_StorageType { - if m != nil { - return m.StorageType +func (x *OSInfo) GetStorageType() OSInfo_StorageType { + if x != nil { + return x.StorageType } return OSInfo_DIRECT } -func (m *OSInfo) GetS3Info() *S3OSInfo { - if m != nil { - return m.S3Info +func (x *OSInfo) GetS3Info() *S3OSInfo { + if x != nil { + return x.S3Info } return nil } type S3OSInfo struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + // Host to use to connect to S3 Host string `protobuf:"bytes,1,opt,name=host,proto3" json:"host,omitempty"` // Key (prefix) to use when uploading the object. @@ -392,247 +540,231 @@ type S3OSInfo struct { // Needed for POST policy. Credential string `protobuf:"bytes,5,opt,name=credential,proto3" json:"credential,omitempty"` // Needed for POST policy. - XAmzDate string `protobuf:"bytes,6,opt,name=xAmzDate,proto3" json:"xAmzDate,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + XAmzDate string `protobuf:"bytes,6,opt,name=xAmzDate,proto3" json:"xAmzDate,omitempty"` } -func (m *S3OSInfo) Reset() { *m = S3OSInfo{} } -func (m *S3OSInfo) String() string { return proto.CompactTextString(m) } -func (*S3OSInfo) ProtoMessage() {} -func (*S3OSInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_034e29c79f9ba827, []int{5} +func (x *S3OSInfo) Reset() { + *x = S3OSInfo{} + if protoimpl.UnsafeEnabled { + mi := &file_net_lp_rpc_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *S3OSInfo) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_S3OSInfo.Unmarshal(m, b) -} -func (m *S3OSInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_S3OSInfo.Marshal(b, m, deterministic) +func (x *S3OSInfo) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *S3OSInfo) XXX_Merge(src proto.Message) { - xxx_messageInfo_S3OSInfo.Merge(m, src) -} -func (m *S3OSInfo) XXX_Size() int { - return xxx_messageInfo_S3OSInfo.Size(m) -} -func (m *S3OSInfo) XXX_DiscardUnknown() { - xxx_messageInfo_S3OSInfo.DiscardUnknown(m) + +func (*S3OSInfo) ProtoMessage() {} + +func (x *S3OSInfo) ProtoReflect() protoreflect.Message { + mi := &file_net_lp_rpc_proto_msgTypes[5] + 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) } -var xxx_messageInfo_S3OSInfo proto.InternalMessageInfo +// Deprecated: Use S3OSInfo.ProtoReflect.Descriptor instead. +func (*S3OSInfo) Descriptor() ([]byte, []int) { + return file_net_lp_rpc_proto_rawDescGZIP(), []int{5} +} -func (m *S3OSInfo) GetHost() string { - if m != nil { - return m.Host +func (x *S3OSInfo) GetHost() string { + if x != nil { + return x.Host } return "" } -func (m *S3OSInfo) GetKey() string { - if m != nil { - return m.Key +func (x *S3OSInfo) GetKey() string { + if x != nil { + return x.Key } return "" } -func (m *S3OSInfo) GetPolicy() string { - if m != nil { - return m.Policy +func (x *S3OSInfo) GetPolicy() string { + if x != nil { + return x.Policy } return "" } -func (m *S3OSInfo) GetSignature() string { - if m != nil { - return m.Signature +func (x *S3OSInfo) GetSignature() string { + if x != nil { + return x.Signature } return "" } -func (m *S3OSInfo) GetCredential() string { - if m != nil { - return m.Credential +func (x *S3OSInfo) GetCredential() string { + if x != nil { + return x.Credential } return "" } -func (m *S3OSInfo) GetXAmzDate() string { - if m != nil { - return m.XAmzDate +func (x *S3OSInfo) GetXAmzDate() string { + if x != nil { + return x.XAmzDate } return "" } // PriceInfo conveys pricing info for transcoding services type PriceInfo struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + // price in wei PricePerUnit int64 `protobuf:"varint,1,opt,name=pricePerUnit,proto3" json:"pricePerUnit,omitempty"` // Pixels covered in the price // Set price to 1 wei and pixelsPerUnit > 1 to have a smaller price granularity per pixel than 1 wei - PixelsPerUnit int64 `protobuf:"varint,2,opt,name=pixelsPerUnit,proto3" json:"pixelsPerUnit,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + PixelsPerUnit int64 `protobuf:"varint,2,opt,name=pixelsPerUnit,proto3" json:"pixelsPerUnit,omitempty"` } -func (m *PriceInfo) Reset() { *m = PriceInfo{} } -func (m *PriceInfo) String() string { return proto.CompactTextString(m) } -func (*PriceInfo) ProtoMessage() {} -func (*PriceInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_034e29c79f9ba827, []int{6} +func (x *PriceInfo) Reset() { + *x = PriceInfo{} + if protoimpl.UnsafeEnabled { + mi := &file_net_lp_rpc_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *PriceInfo) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_PriceInfo.Unmarshal(m, b) -} -func (m *PriceInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_PriceInfo.Marshal(b, m, deterministic) -} -func (m *PriceInfo) XXX_Merge(src proto.Message) { - xxx_messageInfo_PriceInfo.Merge(m, src) -} -func (m *PriceInfo) XXX_Size() int { - return xxx_messageInfo_PriceInfo.Size(m) +func (x *PriceInfo) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *PriceInfo) XXX_DiscardUnknown() { - xxx_messageInfo_PriceInfo.DiscardUnknown(m) + +func (*PriceInfo) ProtoMessage() {} + +func (x *PriceInfo) ProtoReflect() protoreflect.Message { + mi := &file_net_lp_rpc_proto_msgTypes[6] + 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) } -var xxx_messageInfo_PriceInfo proto.InternalMessageInfo +// Deprecated: Use PriceInfo.ProtoReflect.Descriptor instead. +func (*PriceInfo) Descriptor() ([]byte, []int) { + return file_net_lp_rpc_proto_rawDescGZIP(), []int{6} +} -func (m *PriceInfo) GetPricePerUnit() int64 { - if m != nil { - return m.PricePerUnit +func (x *PriceInfo) GetPricePerUnit() int64 { + if x != nil { + return x.PricePerUnit } return 0 } -func (m *PriceInfo) GetPixelsPerUnit() int64 { - if m != nil { - return m.PixelsPerUnit +func (x *PriceInfo) GetPixelsPerUnit() int64 { + if x != nil { + return x.PixelsPerUnit } return 0 } type Capabilities struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + // Bit string of supported features - one bit per feature Bitstring []uint64 `protobuf:"varint,1,rep,packed,name=bitstring,proto3" json:"bitstring,omitempty"` // Bit string of features that are required to be supported Mandatories []uint64 `protobuf:"varint,2,rep,packed,name=mandatories,proto3" json:"mandatories,omitempty"` // Capacity corresponding to each capability - Capacities map[uint32]uint32 `protobuf:"bytes,3,rep,name=capacities,proto3" json:"capacities,omitempty" protobuf_key:"varint,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"` - Version string `protobuf:"bytes,4,opt,name=version,proto3" json:"version,omitempty"` - Constraints *Capabilities_Constraints `protobuf:"bytes,5,opt,name=constraints,proto3" json:"constraints,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + Capacities map[uint32]uint32 `protobuf:"bytes,3,rep,name=capacities,proto3" json:"capacities,omitempty" protobuf_key:"varint,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"` + Version string `protobuf:"bytes,4,opt,name=version,proto3" json:"version,omitempty"` + Constraints *Capabilities_Constraints `protobuf:"bytes,5,opt,name=constraints,proto3" json:"constraints,omitempty"` } -func (m *Capabilities) Reset() { *m = Capabilities{} } -func (m *Capabilities) String() string { return proto.CompactTextString(m) } -func (*Capabilities) ProtoMessage() {} -func (*Capabilities) Descriptor() ([]byte, []int) { - return fileDescriptor_034e29c79f9ba827, []int{7} +func (x *Capabilities) Reset() { + *x = Capabilities{} + if protoimpl.UnsafeEnabled { + mi := &file_net_lp_rpc_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *Capabilities) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Capabilities.Unmarshal(m, b) -} -func (m *Capabilities) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Capabilities.Marshal(b, m, deterministic) -} -func (m *Capabilities) XXX_Merge(src proto.Message) { - xxx_messageInfo_Capabilities.Merge(m, src) -} -func (m *Capabilities) XXX_Size() int { - return xxx_messageInfo_Capabilities.Size(m) -} -func (m *Capabilities) XXX_DiscardUnknown() { - xxx_messageInfo_Capabilities.DiscardUnknown(m) +func (x *Capabilities) String() string { + return protoimpl.X.MessageStringOf(x) } -var xxx_messageInfo_Capabilities proto.InternalMessageInfo +func (*Capabilities) ProtoMessage() {} -func (m *Capabilities) GetBitstring() []uint64 { - if m != nil { - return m.Bitstring +func (x *Capabilities) ProtoReflect() protoreflect.Message { + mi := &file_net_lp_rpc_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms } - return nil + return mi.MessageOf(x) } -func (m *Capabilities) GetMandatories() []uint64 { - if m != nil { - return m.Mandatories - } - return nil +// Deprecated: Use Capabilities.ProtoReflect.Descriptor instead. +func (*Capabilities) Descriptor() ([]byte, []int) { + return file_net_lp_rpc_proto_rawDescGZIP(), []int{7} } -func (m *Capabilities) GetCapacities() map[uint32]uint32 { - if m != nil { - return m.Capacities +func (x *Capabilities) GetBitstring() []uint64 { + if x != nil { + return x.Bitstring } return nil } -func (m *Capabilities) GetVersion() string { - if m != nil { - return m.Version +func (x *Capabilities) GetMandatories() []uint64 { + if x != nil { + return x.Mandatories } - return "" + return nil } -func (m *Capabilities) GetConstraints() *Capabilities_Constraints { - if m != nil { - return m.Constraints +func (x *Capabilities) GetCapacities() map[uint32]uint32 { + if x != nil { + return x.Capacities } return nil } -// Non-binary capability constraints, such as supported ranges. -type Capabilities_Constraints struct { - MinVersion string `protobuf:"bytes,1,opt,name=minVersion,proto3" json:"minVersion,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *Capabilities_Constraints) Reset() { *m = Capabilities_Constraints{} } -func (m *Capabilities_Constraints) String() string { return proto.CompactTextString(m) } -func (*Capabilities_Constraints) ProtoMessage() {} -func (*Capabilities_Constraints) Descriptor() ([]byte, []int) { - return fileDescriptor_034e29c79f9ba827, []int{7, 1} -} - -func (m *Capabilities_Constraints) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Capabilities_Constraints.Unmarshal(m, b) -} -func (m *Capabilities_Constraints) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Capabilities_Constraints.Marshal(b, m, deterministic) -} -func (m *Capabilities_Constraints) XXX_Merge(src proto.Message) { - xxx_messageInfo_Capabilities_Constraints.Merge(m, src) -} -func (m *Capabilities_Constraints) XXX_Size() int { - return xxx_messageInfo_Capabilities_Constraints.Size(m) -} -func (m *Capabilities_Constraints) XXX_DiscardUnknown() { - xxx_messageInfo_Capabilities_Constraints.DiscardUnknown(m) +func (x *Capabilities) GetVersion() string { + if x != nil { + return x.Version + } + return "" } -var xxx_messageInfo_Capabilities_Constraints proto.InternalMessageInfo - -func (m *Capabilities_Constraints) GetMinVersion() string { - if m != nil { - return m.MinVersion +func (x *Capabilities) GetConstraints() *Capabilities_Constraints { + if x != nil { + return x.Constraints } - return "" + return nil } // The orchestrator sends this in response to `GetOrchestrator`, containing // miscellaneous data related to the job. type OrchestratorInfo struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + // URI of the transcoder to use for submitting segments. Transcoder string `protobuf:"bytes,1,opt,name=transcoder,proto3" json:"transcoder,omitempty"` // Parameters for probabilistic micropayment tickets @@ -646,148 +778,164 @@ type OrchestratorInfo struct { // Data for transcoding authentication AuthToken *AuthToken `protobuf:"bytes,6,opt,name=auth_token,json=authToken,proto3" json:"auth_token,omitempty"` // Orchestrator returns info about own input object storage, if it wants it to be used. - Storage []*OSInfo `protobuf:"bytes,32,rep,name=storage,proto3" json:"storage,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + Storage []*OSInfo `protobuf:"bytes,32,rep,name=storage,proto3" json:"storage,omitempty"` } -func (m *OrchestratorInfo) Reset() { *m = OrchestratorInfo{} } -func (m *OrchestratorInfo) String() string { return proto.CompactTextString(m) } -func (*OrchestratorInfo) ProtoMessage() {} -func (*OrchestratorInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_034e29c79f9ba827, []int{8} +func (x *OrchestratorInfo) Reset() { + *x = OrchestratorInfo{} + if protoimpl.UnsafeEnabled { + mi := &file_net_lp_rpc_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *OrchestratorInfo) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_OrchestratorInfo.Unmarshal(m, b) -} -func (m *OrchestratorInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_OrchestratorInfo.Marshal(b, m, deterministic) +func (x *OrchestratorInfo) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *OrchestratorInfo) XXX_Merge(src proto.Message) { - xxx_messageInfo_OrchestratorInfo.Merge(m, src) -} -func (m *OrchestratorInfo) XXX_Size() int { - return xxx_messageInfo_OrchestratorInfo.Size(m) -} -func (m *OrchestratorInfo) XXX_DiscardUnknown() { - xxx_messageInfo_OrchestratorInfo.DiscardUnknown(m) + +func (*OrchestratorInfo) ProtoMessage() {} + +func (x *OrchestratorInfo) ProtoReflect() protoreflect.Message { + mi := &file_net_lp_rpc_proto_msgTypes[8] + 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) } -var xxx_messageInfo_OrchestratorInfo proto.InternalMessageInfo +// Deprecated: Use OrchestratorInfo.ProtoReflect.Descriptor instead. +func (*OrchestratorInfo) Descriptor() ([]byte, []int) { + return file_net_lp_rpc_proto_rawDescGZIP(), []int{8} +} -func (m *OrchestratorInfo) GetTranscoder() string { - if m != nil { - return m.Transcoder +func (x *OrchestratorInfo) GetTranscoder() string { + if x != nil { + return x.Transcoder } return "" } -func (m *OrchestratorInfo) GetTicketParams() *TicketParams { - if m != nil { - return m.TicketParams +func (x *OrchestratorInfo) GetTicketParams() *TicketParams { + if x != nil { + return x.TicketParams } return nil } -func (m *OrchestratorInfo) GetPriceInfo() *PriceInfo { - if m != nil { - return m.PriceInfo +func (x *OrchestratorInfo) GetPriceInfo() *PriceInfo { + if x != nil { + return x.PriceInfo } return nil } -func (m *OrchestratorInfo) GetAddress() []byte { - if m != nil { - return m.Address +func (x *OrchestratorInfo) GetAddress() []byte { + if x != nil { + return x.Address } return nil } -func (m *OrchestratorInfo) GetCapabilities() *Capabilities { - if m != nil { - return m.Capabilities +func (x *OrchestratorInfo) GetCapabilities() *Capabilities { + if x != nil { + return x.Capabilities } return nil } -func (m *OrchestratorInfo) GetAuthToken() *AuthToken { - if m != nil { - return m.AuthToken +func (x *OrchestratorInfo) GetAuthToken() *AuthToken { + if x != nil { + return x.AuthToken } return nil } -func (m *OrchestratorInfo) GetStorage() []*OSInfo { - if m != nil { - return m.Storage +func (x *OrchestratorInfo) GetStorage() []*OSInfo { + if x != nil { + return x.Storage } return nil } // Data for transcoding authentication that is included in the OrchestratorInfo message during discovery type AuthToken struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + // Record used to authenticate for a transcode session // Opaque to the receiver Token []byte `protobuf:"bytes,1,opt,name=token,proto3" json:"token,omitempty"` // ID of the transcode session that the token is authenticating for SessionId string `protobuf:"bytes,2,opt,name=session_id,json=sessionId,proto3" json:"session_id,omitempty"` // Timestamp when the token expires - Expiration int64 `protobuf:"varint,3,opt,name=expiration,proto3" json:"expiration,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + Expiration int64 `protobuf:"varint,3,opt,name=expiration,proto3" json:"expiration,omitempty"` } -func (m *AuthToken) Reset() { *m = AuthToken{} } -func (m *AuthToken) String() string { return proto.CompactTextString(m) } -func (*AuthToken) ProtoMessage() {} -func (*AuthToken) Descriptor() ([]byte, []int) { - return fileDescriptor_034e29c79f9ba827, []int{9} +func (x *AuthToken) Reset() { + *x = AuthToken{} + if protoimpl.UnsafeEnabled { + mi := &file_net_lp_rpc_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *AuthToken) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_AuthToken.Unmarshal(m, b) -} -func (m *AuthToken) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_AuthToken.Marshal(b, m, deterministic) +func (x *AuthToken) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *AuthToken) XXX_Merge(src proto.Message) { - xxx_messageInfo_AuthToken.Merge(m, src) -} -func (m *AuthToken) XXX_Size() int { - return xxx_messageInfo_AuthToken.Size(m) -} -func (m *AuthToken) XXX_DiscardUnknown() { - xxx_messageInfo_AuthToken.DiscardUnknown(m) + +func (*AuthToken) ProtoMessage() {} + +func (x *AuthToken) ProtoReflect() protoreflect.Message { + mi := &file_net_lp_rpc_proto_msgTypes[9] + 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) } -var xxx_messageInfo_AuthToken proto.InternalMessageInfo +// Deprecated: Use AuthToken.ProtoReflect.Descriptor instead. +func (*AuthToken) Descriptor() ([]byte, []int) { + return file_net_lp_rpc_proto_rawDescGZIP(), []int{9} +} -func (m *AuthToken) GetToken() []byte { - if m != nil { - return m.Token +func (x *AuthToken) GetToken() []byte { + if x != nil { + return x.Token } return nil } -func (m *AuthToken) GetSessionId() string { - if m != nil { - return m.SessionId +func (x *AuthToken) GetSessionId() string { + if x != nil { + return x.SessionId } return "" } -func (m *AuthToken) GetExpiration() int64 { - if m != nil { - return m.Expiration +func (x *AuthToken) GetExpiration() int64 { + if x != nil { + return x.Expiration } return 0 } // Data included by the broadcaster when submitting a segment for transcoding. type SegData struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + // Manifest ID this segment belongs to ManifestId []byte `protobuf:"bytes,1,opt,name=manifestId,proto3" json:"manifestId,omitempty"` // Sequence number of the segment to be transcoded @@ -821,194 +969,210 @@ type SegData struct { // Transcoding parameters specific to this segment SegmentParameters *SegParameters `protobuf:"bytes,37,opt,name=segment_parameters,json=segmentParameters,proto3" json:"segment_parameters,omitempty"` // Force HW Session Reinit - ForceSessionReinit bool `protobuf:"varint,38,opt,name=ForceSessionReinit,proto3" json:"ForceSessionReinit,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + ForceSessionReinit bool `protobuf:"varint,38,opt,name=ForceSessionReinit,proto3" json:"ForceSessionReinit,omitempty"` } -func (m *SegData) Reset() { *m = SegData{} } -func (m *SegData) String() string { return proto.CompactTextString(m) } -func (*SegData) ProtoMessage() {} -func (*SegData) Descriptor() ([]byte, []int) { - return fileDescriptor_034e29c79f9ba827, []int{10} +func (x *SegData) Reset() { + *x = SegData{} + if protoimpl.UnsafeEnabled { + mi := &file_net_lp_rpc_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *SegData) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_SegData.Unmarshal(m, b) -} -func (m *SegData) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_SegData.Marshal(b, m, deterministic) +func (x *SegData) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *SegData) XXX_Merge(src proto.Message) { - xxx_messageInfo_SegData.Merge(m, src) -} -func (m *SegData) XXX_Size() int { - return xxx_messageInfo_SegData.Size(m) -} -func (m *SegData) XXX_DiscardUnknown() { - xxx_messageInfo_SegData.DiscardUnknown(m) + +func (*SegData) ProtoMessage() {} + +func (x *SegData) ProtoReflect() protoreflect.Message { + mi := &file_net_lp_rpc_proto_msgTypes[10] + 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) } -var xxx_messageInfo_SegData proto.InternalMessageInfo +// Deprecated: Use SegData.ProtoReflect.Descriptor instead. +func (*SegData) Descriptor() ([]byte, []int) { + return file_net_lp_rpc_proto_rawDescGZIP(), []int{10} +} -func (m *SegData) GetManifestId() []byte { - if m != nil { - return m.ManifestId +func (x *SegData) GetManifestId() []byte { + if x != nil { + return x.ManifestId } return nil } -func (m *SegData) GetSeq() int64 { - if m != nil { - return m.Seq +func (x *SegData) GetSeq() int64 { + if x != nil { + return x.Seq } return 0 } -func (m *SegData) GetHash() []byte { - if m != nil { - return m.Hash +func (x *SegData) GetHash() []byte { + if x != nil { + return x.Hash } return nil } -func (m *SegData) GetProfiles() []byte { - if m != nil { - return m.Profiles +func (x *SegData) GetProfiles() []byte { + if x != nil { + return x.Profiles } return nil } -func (m *SegData) GetSig() []byte { - if m != nil { - return m.Sig +func (x *SegData) GetSig() []byte { + if x != nil { + return x.Sig } return nil } -func (m *SegData) GetDuration() int32 { - if m != nil { - return m.Duration +func (x *SegData) GetDuration() int32 { + if x != nil { + return x.Duration } return 0 } -func (m *SegData) GetCapabilities() *Capabilities { - if m != nil { - return m.Capabilities +func (x *SegData) GetCapabilities() *Capabilities { + if x != nil { + return x.Capabilities } return nil } -func (m *SegData) GetAuthToken() *AuthToken { - if m != nil { - return m.AuthToken +func (x *SegData) GetAuthToken() *AuthToken { + if x != nil { + return x.AuthToken } return nil } -func (m *SegData) GetCalcPerceptualHash() bool { - if m != nil { - return m.CalcPerceptualHash +func (x *SegData) GetCalcPerceptualHash() bool { + if x != nil { + return x.CalcPerceptualHash } return false } -func (m *SegData) GetStorage() []*OSInfo { - if m != nil { - return m.Storage +func (x *SegData) GetStorage() []*OSInfo { + if x != nil { + return x.Storage } return nil } -func (m *SegData) GetFullProfiles() []*VideoProfile { - if m != nil { - return m.FullProfiles +func (x *SegData) GetFullProfiles() []*VideoProfile { + if x != nil { + return x.FullProfiles } return nil } -func (m *SegData) GetFullProfiles2() []*VideoProfile { - if m != nil { - return m.FullProfiles2 +func (x *SegData) GetFullProfiles2() []*VideoProfile { + if x != nil { + return x.FullProfiles2 } return nil } -func (m *SegData) GetFullProfiles3() []*VideoProfile { - if m != nil { - return m.FullProfiles3 +func (x *SegData) GetFullProfiles3() []*VideoProfile { + if x != nil { + return x.FullProfiles3 } return nil } -func (m *SegData) GetSegmentParameters() *SegParameters { - if m != nil { - return m.SegmentParameters +func (x *SegData) GetSegmentParameters() *SegParameters { + if x != nil { + return x.SegmentParameters } return nil } -func (m *SegData) GetForceSessionReinit() bool { - if m != nil { - return m.ForceSessionReinit +func (x *SegData) GetForceSessionReinit() bool { + if x != nil { + return x.ForceSessionReinit } return false } type SegParameters struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + // Start timestamp from which to start encoding // Milliseconds, from start of the file From uint64 `protobuf:"varint,1,opt,name=from,proto3" json:"from,omitempty"` // Skip all frames after that timestamp // Milliseconds, from start of the file - To uint64 `protobuf:"varint,2,opt,name=to,proto3" json:"to,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + To uint64 `protobuf:"varint,2,opt,name=to,proto3" json:"to,omitempty"` } -func (m *SegParameters) Reset() { *m = SegParameters{} } -func (m *SegParameters) String() string { return proto.CompactTextString(m) } -func (*SegParameters) ProtoMessage() {} -func (*SegParameters) Descriptor() ([]byte, []int) { - return fileDescriptor_034e29c79f9ba827, []int{11} +func (x *SegParameters) Reset() { + *x = SegParameters{} + if protoimpl.UnsafeEnabled { + mi := &file_net_lp_rpc_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *SegParameters) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_SegParameters.Unmarshal(m, b) +func (x *SegParameters) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *SegParameters) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_SegParameters.Marshal(b, m, deterministic) -} -func (m *SegParameters) XXX_Merge(src proto.Message) { - xxx_messageInfo_SegParameters.Merge(m, src) -} -func (m *SegParameters) XXX_Size() int { - return xxx_messageInfo_SegParameters.Size(m) -} -func (m *SegParameters) XXX_DiscardUnknown() { - xxx_messageInfo_SegParameters.DiscardUnknown(m) + +func (*SegParameters) ProtoMessage() {} + +func (x *SegParameters) ProtoReflect() protoreflect.Message { + mi := &file_net_lp_rpc_proto_msgTypes[11] + 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) } -var xxx_messageInfo_SegParameters proto.InternalMessageInfo +// Deprecated: Use SegParameters.ProtoReflect.Descriptor instead. +func (*SegParameters) Descriptor() ([]byte, []int) { + return file_net_lp_rpc_proto_rawDescGZIP(), []int{11} +} -func (m *SegParameters) GetFrom() uint64 { - if m != nil { - return m.From +func (x *SegParameters) GetFrom() uint64 { + if x != nil { + return x.From } return 0 } -func (m *SegParameters) GetTo() uint64 { - if m != nil { - return m.To +func (x *SegParameters) GetTo() uint64 { + if x != nil { + return x.To } return 0 } type VideoProfile struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + // Name of VideoProfile Name string `protobuf:"bytes,16,opt,name=name,proto3" json:"name,omitempty"` // Width of VideoProfile @@ -1027,306 +1191,318 @@ type VideoProfile struct { // GOP interval Gop int32 `protobuf:"varint,24,opt,name=gop,proto3" json:"gop,omitempty"` // Encoder (video codec) - Encoder VideoProfile_VideoCodec `protobuf:"varint,25,opt,name=encoder,proto3,enum=net.VideoProfile_VideoCodec" json:"encoder,omitempty"` - ColorDepth int32 `protobuf:"varint,26,opt,name=colorDepth,proto3" json:"colorDepth,omitempty"` - ChromaFormat VideoProfile_ChromaSubsampling `protobuf:"varint,27,opt,name=chromaFormat,proto3,enum=net.VideoProfile_ChromaSubsampling" json:"chromaFormat,omitempty"` - Quality uint32 `protobuf:"varint,28,opt,name=quality,proto3" json:"quality,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *VideoProfile) Reset() { *m = VideoProfile{} } -func (m *VideoProfile) String() string { return proto.CompactTextString(m) } -func (*VideoProfile) ProtoMessage() {} -func (*VideoProfile) Descriptor() ([]byte, []int) { - return fileDescriptor_034e29c79f9ba827, []int{12} + Encoder VideoProfile_VideoCodec `protobuf:"varint,25,opt,name=encoder,proto3,enum=net.VideoProfile_VideoCodec" json:"encoder,omitempty"` + ColorDepth int32 `protobuf:"varint,26,opt,name=colorDepth,proto3" json:"colorDepth,omitempty"` + ChromaFormat VideoProfile_ChromaSubsampling `protobuf:"varint,27,opt,name=chromaFormat,proto3,enum=net.VideoProfile_ChromaSubsampling" json:"chromaFormat,omitempty"` + Quality uint32 `protobuf:"varint,28,opt,name=quality,proto3" json:"quality,omitempty"` } -func (m *VideoProfile) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_VideoProfile.Unmarshal(m, b) -} -func (m *VideoProfile) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_VideoProfile.Marshal(b, m, deterministic) -} -func (m *VideoProfile) XXX_Merge(src proto.Message) { - xxx_messageInfo_VideoProfile.Merge(m, src) +func (x *VideoProfile) Reset() { + *x = VideoProfile{} + if protoimpl.UnsafeEnabled { + mi := &file_net_lp_rpc_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *VideoProfile) XXX_Size() int { - return xxx_messageInfo_VideoProfile.Size(m) + +func (x *VideoProfile) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *VideoProfile) XXX_DiscardUnknown() { - xxx_messageInfo_VideoProfile.DiscardUnknown(m) + +func (*VideoProfile) ProtoMessage() {} + +func (x *VideoProfile) ProtoReflect() protoreflect.Message { + mi := &file_net_lp_rpc_proto_msgTypes[12] + 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) } -var xxx_messageInfo_VideoProfile proto.InternalMessageInfo +// Deprecated: Use VideoProfile.ProtoReflect.Descriptor instead. +func (*VideoProfile) Descriptor() ([]byte, []int) { + return file_net_lp_rpc_proto_rawDescGZIP(), []int{12} +} -func (m *VideoProfile) GetName() string { - if m != nil { - return m.Name +func (x *VideoProfile) GetName() string { + if x != nil { + return x.Name } return "" } -func (m *VideoProfile) GetWidth() int32 { - if m != nil { - return m.Width +func (x *VideoProfile) GetWidth() int32 { + if x != nil { + return x.Width } return 0 } -func (m *VideoProfile) GetHeight() int32 { - if m != nil { - return m.Height +func (x *VideoProfile) GetHeight() int32 { + if x != nil { + return x.Height } return 0 } -func (m *VideoProfile) GetBitrate() int32 { - if m != nil { - return m.Bitrate +func (x *VideoProfile) GetBitrate() int32 { + if x != nil { + return x.Bitrate } return 0 } -func (m *VideoProfile) GetFps() uint32 { - if m != nil { - return m.Fps +func (x *VideoProfile) GetFps() uint32 { + if x != nil { + return x.Fps } return 0 } -func (m *VideoProfile) GetFormat() VideoProfile_Format { - if m != nil { - return m.Format +func (x *VideoProfile) GetFormat() VideoProfile_Format { + if x != nil { + return x.Format } return VideoProfile_MPEGTS } -func (m *VideoProfile) GetFpsDen() uint32 { - if m != nil { - return m.FpsDen +func (x *VideoProfile) GetFpsDen() uint32 { + if x != nil { + return x.FpsDen } return 0 } -func (m *VideoProfile) GetProfile() VideoProfile_Profile { - if m != nil { - return m.Profile +func (x *VideoProfile) GetProfile() VideoProfile_Profile { + if x != nil { + return x.Profile } return VideoProfile_ENCODER_DEFAULT } -func (m *VideoProfile) GetGop() int32 { - if m != nil { - return m.Gop +func (x *VideoProfile) GetGop() int32 { + if x != nil { + return x.Gop } return 0 } -func (m *VideoProfile) GetEncoder() VideoProfile_VideoCodec { - if m != nil { - return m.Encoder +func (x *VideoProfile) GetEncoder() VideoProfile_VideoCodec { + if x != nil { + return x.Encoder } return VideoProfile_H264 } -func (m *VideoProfile) GetColorDepth() int32 { - if m != nil { - return m.ColorDepth +func (x *VideoProfile) GetColorDepth() int32 { + if x != nil { + return x.ColorDepth } return 0 } -func (m *VideoProfile) GetChromaFormat() VideoProfile_ChromaSubsampling { - if m != nil { - return m.ChromaFormat +func (x *VideoProfile) GetChromaFormat() VideoProfile_ChromaSubsampling { + if x != nil { + return x.ChromaFormat } return VideoProfile_CHROMA_420 } -func (m *VideoProfile) GetQuality() uint32 { - if m != nil { - return m.Quality +func (x *VideoProfile) GetQuality() uint32 { + if x != nil { + return x.Quality } return 0 } // Individual transcoded segment data. type TranscodedSegmentData struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + // URL where the transcoded data can be downloaded from. Url string `protobuf:"bytes,1,opt,name=url,proto3" json:"url,omitempty"` // Amount of pixels processed (output pixels) Pixels int64 `protobuf:"varint,2,opt,name=pixels,proto3" json:"pixels,omitempty"` // URL where the perceptual hash data can be downloaded from (can be empty) - PerceptualHashUrl string `protobuf:"bytes,3,opt,name=perceptual_hash_url,json=perceptualHashUrl,proto3" json:"perceptual_hash_url,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + PerceptualHashUrl string `protobuf:"bytes,3,opt,name=perceptual_hash_url,json=perceptualHashUrl,proto3" json:"perceptual_hash_url,omitempty"` } -func (m *TranscodedSegmentData) Reset() { *m = TranscodedSegmentData{} } -func (m *TranscodedSegmentData) String() string { return proto.CompactTextString(m) } -func (*TranscodedSegmentData) ProtoMessage() {} -func (*TranscodedSegmentData) Descriptor() ([]byte, []int) { - return fileDescriptor_034e29c79f9ba827, []int{13} +func (x *TranscodedSegmentData) Reset() { + *x = TranscodedSegmentData{} + if protoimpl.UnsafeEnabled { + mi := &file_net_lp_rpc_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *TranscodedSegmentData) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_TranscodedSegmentData.Unmarshal(m, b) -} -func (m *TranscodedSegmentData) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_TranscodedSegmentData.Marshal(b, m, deterministic) -} -func (m *TranscodedSegmentData) XXX_Merge(src proto.Message) { - xxx_messageInfo_TranscodedSegmentData.Merge(m, src) -} -func (m *TranscodedSegmentData) XXX_Size() int { - return xxx_messageInfo_TranscodedSegmentData.Size(m) +func (x *TranscodedSegmentData) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *TranscodedSegmentData) XXX_DiscardUnknown() { - xxx_messageInfo_TranscodedSegmentData.DiscardUnknown(m) + +func (*TranscodedSegmentData) ProtoMessage() {} + +func (x *TranscodedSegmentData) ProtoReflect() protoreflect.Message { + mi := &file_net_lp_rpc_proto_msgTypes[13] + 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) } -var xxx_messageInfo_TranscodedSegmentData proto.InternalMessageInfo +// Deprecated: Use TranscodedSegmentData.ProtoReflect.Descriptor instead. +func (*TranscodedSegmentData) Descriptor() ([]byte, []int) { + return file_net_lp_rpc_proto_rawDescGZIP(), []int{13} +} -func (m *TranscodedSegmentData) GetUrl() string { - if m != nil { - return m.Url +func (x *TranscodedSegmentData) GetUrl() string { + if x != nil { + return x.Url } return "" } -func (m *TranscodedSegmentData) GetPixels() int64 { - if m != nil { - return m.Pixels +func (x *TranscodedSegmentData) GetPixels() int64 { + if x != nil { + return x.Pixels } return 0 } -func (m *TranscodedSegmentData) GetPerceptualHashUrl() string { - if m != nil { - return m.PerceptualHashUrl +func (x *TranscodedSegmentData) GetPerceptualHashUrl() string { + if x != nil { + return x.PerceptualHashUrl } return "" } // A set of transcoded segments following the profiles specified in the job. type TranscodeData struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + // Transcoded data, in the order specified in the job options Segments []*TranscodedSegmentData `protobuf:"bytes,1,rep,name=segments,proto3" json:"segments,omitempty"` // Signature of the hash of the concatenated hashes - Sig []byte `protobuf:"bytes,2,opt,name=sig,proto3" json:"sig,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + Sig []byte `protobuf:"bytes,2,opt,name=sig,proto3" json:"sig,omitempty"` } -func (m *TranscodeData) Reset() { *m = TranscodeData{} } -func (m *TranscodeData) String() string { return proto.CompactTextString(m) } -func (*TranscodeData) ProtoMessage() {} -func (*TranscodeData) Descriptor() ([]byte, []int) { - return fileDescriptor_034e29c79f9ba827, []int{14} +func (x *TranscodeData) Reset() { + *x = TranscodeData{} + if protoimpl.UnsafeEnabled { + mi := &file_net_lp_rpc_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *TranscodeData) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_TranscodeData.Unmarshal(m, b) -} -func (m *TranscodeData) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_TranscodeData.Marshal(b, m, deterministic) -} -func (m *TranscodeData) XXX_Merge(src proto.Message) { - xxx_messageInfo_TranscodeData.Merge(m, src) -} -func (m *TranscodeData) XXX_Size() int { - return xxx_messageInfo_TranscodeData.Size(m) +func (x *TranscodeData) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *TranscodeData) XXX_DiscardUnknown() { - xxx_messageInfo_TranscodeData.DiscardUnknown(m) + +func (*TranscodeData) ProtoMessage() {} + +func (x *TranscodeData) ProtoReflect() protoreflect.Message { + mi := &file_net_lp_rpc_proto_msgTypes[14] + 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) } -var xxx_messageInfo_TranscodeData proto.InternalMessageInfo +// Deprecated: Use TranscodeData.ProtoReflect.Descriptor instead. +func (*TranscodeData) Descriptor() ([]byte, []int) { + return file_net_lp_rpc_proto_rawDescGZIP(), []int{14} +} -func (m *TranscodeData) GetSegments() []*TranscodedSegmentData { - if m != nil { - return m.Segments +func (x *TranscodeData) GetSegments() []*TranscodedSegmentData { + if x != nil { + return x.Segments } return nil } -func (m *TranscodeData) GetSig() []byte { - if m != nil { - return m.Sig +func (x *TranscodeData) GetSig() []byte { + if x != nil { + return x.Sig } return nil } // Response that a transcoder sends after transcoding a segment. type TranscodeResult struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + // Sequence number of the transcoded results. Seq int64 `protobuf:"varint,1,opt,name=seq,proto3" json:"seq,omitempty"` // Result of transcoding can be an error, or successful with more info // - // Types that are valid to be assigned to Result: + // Types that are assignable to Result: // // *TranscodeResult_Error // *TranscodeResult_Data Result isTranscodeResult_Result `protobuf_oneof:"result"` // Used to notify a broadcaster of updated orchestrator information - Info *OrchestratorInfo `protobuf:"bytes,16,opt,name=info,proto3" json:"info,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + Info *OrchestratorInfo `protobuf:"bytes,16,opt,name=info,proto3" json:"info,omitempty"` } -func (m *TranscodeResult) Reset() { *m = TranscodeResult{} } -func (m *TranscodeResult) String() string { return proto.CompactTextString(m) } -func (*TranscodeResult) ProtoMessage() {} -func (*TranscodeResult) Descriptor() ([]byte, []int) { - return fileDescriptor_034e29c79f9ba827, []int{15} +func (x *TranscodeResult) Reset() { + *x = TranscodeResult{} + if protoimpl.UnsafeEnabled { + mi := &file_net_lp_rpc_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *TranscodeResult) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_TranscodeResult.Unmarshal(m, b) -} -func (m *TranscodeResult) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_TranscodeResult.Marshal(b, m, deterministic) -} -func (m *TranscodeResult) XXX_Merge(src proto.Message) { - xxx_messageInfo_TranscodeResult.Merge(m, src) -} -func (m *TranscodeResult) XXX_Size() int { - return xxx_messageInfo_TranscodeResult.Size(m) -} -func (m *TranscodeResult) XXX_DiscardUnknown() { - xxx_messageInfo_TranscodeResult.DiscardUnknown(m) +func (x *TranscodeResult) String() string { + return protoimpl.X.MessageStringOf(x) } -var xxx_messageInfo_TranscodeResult proto.InternalMessageInfo +func (*TranscodeResult) ProtoMessage() {} -func (m *TranscodeResult) GetSeq() int64 { - if m != nil { - return m.Seq +func (x *TranscodeResult) ProtoReflect() protoreflect.Message { + mi := &file_net_lp_rpc_proto_msgTypes[15] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms } - return 0 -} - -type isTranscodeResult_Result interface { - isTranscodeResult_Result() + return mi.MessageOf(x) } -type TranscodeResult_Error struct { - Error string `protobuf:"bytes,2,opt,name=error,proto3,oneof"` +// Deprecated: Use TranscodeResult.ProtoReflect.Descriptor instead. +func (*TranscodeResult) Descriptor() ([]byte, []int) { + return file_net_lp_rpc_proto_rawDescGZIP(), []int{15} } -type TranscodeResult_Data struct { - Data *TranscodeData `protobuf:"bytes,3,opt,name=data,proto3,oneof"` +func (x *TranscodeResult) GetSeq() int64 { + if x != nil { + return x.Seq + } + return 0 } -func (*TranscodeResult_Error) isTranscodeResult_Result() {} - -func (*TranscodeResult_Data) isTranscodeResult_Result() {} - func (m *TranscodeResult) GetResult() isTranscodeResult_Result { if m != nil { return m.Result @@ -1334,165 +1510,202 @@ func (m *TranscodeResult) GetResult() isTranscodeResult_Result { return nil } -func (m *TranscodeResult) GetError() string { - if x, ok := m.GetResult().(*TranscodeResult_Error); ok { +func (x *TranscodeResult) GetError() string { + if x, ok := x.GetResult().(*TranscodeResult_Error); ok { return x.Error } return "" } -func (m *TranscodeResult) GetData() *TranscodeData { - if x, ok := m.GetResult().(*TranscodeResult_Data); ok { +func (x *TranscodeResult) GetData() *TranscodeData { + if x, ok := x.GetResult().(*TranscodeResult_Data); ok { return x.Data } return nil } -func (m *TranscodeResult) GetInfo() *OrchestratorInfo { - if m != nil { - return m.Info +func (x *TranscodeResult) GetInfo() *OrchestratorInfo { + if x != nil { + return x.Info } return nil } -// XXX_OneofWrappers is for the internal use of the proto package. -func (*TranscodeResult) XXX_OneofWrappers() []interface{} { - return []interface{}{ - (*TranscodeResult_Error)(nil), - (*TranscodeResult_Data)(nil), - } +type isTranscodeResult_Result interface { + isTranscodeResult_Result() +} + +type TranscodeResult_Error struct { + Error string `protobuf:"bytes,2,opt,name=error,proto3,oneof"` } +type TranscodeResult_Data struct { + Data *TranscodeData `protobuf:"bytes,3,opt,name=data,proto3,oneof"` +} + +func (*TranscodeResult_Error) isTranscodeResult_Result() {} + +func (*TranscodeResult_Data) isTranscodeResult_Result() {} + // Sent by the transcoder to register itself to the orchestrator. type RegisterRequest 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"` // Transcoder capacity Capacity int64 `protobuf:"varint,2,opt,name=capacity,proto3" json:"capacity,omitempty"` // Transcoder capabilities - Capabilities *Capabilities `protobuf:"bytes,3,opt,name=capabilities,proto3" json:"capabilities,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + Capabilities *Capabilities `protobuf:"bytes,3,opt,name=capabilities,proto3" json:"capabilities,omitempty"` } -func (m *RegisterRequest) Reset() { *m = RegisterRequest{} } -func (m *RegisterRequest) String() string { return proto.CompactTextString(m) } -func (*RegisterRequest) ProtoMessage() {} -func (*RegisterRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_034e29c79f9ba827, []int{16} +func (x *RegisterRequest) Reset() { + *x = RegisterRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_net_lp_rpc_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *RegisterRequest) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_RegisterRequest.Unmarshal(m, b) -} -func (m *RegisterRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_RegisterRequest.Marshal(b, m, deterministic) +func (x *RegisterRequest) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *RegisterRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_RegisterRequest.Merge(m, src) -} -func (m *RegisterRequest) XXX_Size() int { - return xxx_messageInfo_RegisterRequest.Size(m) -} -func (m *RegisterRequest) XXX_DiscardUnknown() { - xxx_messageInfo_RegisterRequest.DiscardUnknown(m) + +func (*RegisterRequest) ProtoMessage() {} + +func (x *RegisterRequest) 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) } -var xxx_messageInfo_RegisterRequest proto.InternalMessageInfo +// Deprecated: Use RegisterRequest.ProtoReflect.Descriptor instead. +func (*RegisterRequest) Descriptor() ([]byte, []int) { + return file_net_lp_rpc_proto_rawDescGZIP(), []int{16} +} -func (m *RegisterRequest) GetSecret() string { - if m != nil { - return m.Secret +func (x *RegisterRequest) GetSecret() string { + if x != nil { + return x.Secret } return "" } -func (m *RegisterRequest) GetCapacity() int64 { - if m != nil { - return m.Capacity +func (x *RegisterRequest) GetCapacity() int64 { + if x != nil { + return x.Capacity } return 0 } -func (m *RegisterRequest) GetCapabilities() *Capabilities { - if m != nil { - return m.Capabilities +func (x *RegisterRequest) GetCapabilities() *Capabilities { + if x != nil { + return x.Capabilities } return nil } // Sent by the orchestrator to the transcoder type NotifySegment struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + // URL of the segment to transcode. Url string `protobuf:"bytes,1,opt,name=url,proto3" json:"url,omitempty"` // Configuration for the transcoding job SegData *SegData `protobuf:"bytes,3,opt,name=segData,proto3" json:"segData,omitempty"` // ID for this particular transcoding task. TaskId int64 `protobuf:"varint,16,opt,name=taskId,proto3" json:"taskId,omitempty"` + // Orchestrator identifier for segment metadata + OrchId string `protobuf:"bytes,18,opt,name=orchId,proto3" json:"orchId,omitempty"` // Deprecated by fullProfiles. Set of presets to transcode into. // Should be set to an invalid value to induce failures - Profiles []byte `protobuf:"bytes,17,opt,name=profiles,proto3" json:"profiles,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + Profiles []byte `protobuf:"bytes,17,opt,name=profiles,proto3" json:"profiles,omitempty"` } -func (m *NotifySegment) Reset() { *m = NotifySegment{} } -func (m *NotifySegment) String() string { return proto.CompactTextString(m) } -func (*NotifySegment) ProtoMessage() {} -func (*NotifySegment) Descriptor() ([]byte, []int) { - return fileDescriptor_034e29c79f9ba827, []int{17} +func (x *NotifySegment) Reset() { + *x = NotifySegment{} + if protoimpl.UnsafeEnabled { + mi := &file_net_lp_rpc_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *NotifySegment) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_NotifySegment.Unmarshal(m, b) -} -func (m *NotifySegment) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_NotifySegment.Marshal(b, m, deterministic) -} -func (m *NotifySegment) XXX_Merge(src proto.Message) { - xxx_messageInfo_NotifySegment.Merge(m, src) +func (x *NotifySegment) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *NotifySegment) XXX_Size() int { - return xxx_messageInfo_NotifySegment.Size(m) -} -func (m *NotifySegment) XXX_DiscardUnknown() { - xxx_messageInfo_NotifySegment.DiscardUnknown(m) + +func (*NotifySegment) ProtoMessage() {} + +func (x *NotifySegment) ProtoReflect() protoreflect.Message { + mi := &file_net_lp_rpc_proto_msgTypes[17] + 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) } -var xxx_messageInfo_NotifySegment proto.InternalMessageInfo +// Deprecated: Use NotifySegment.ProtoReflect.Descriptor instead. +func (*NotifySegment) Descriptor() ([]byte, []int) { + return file_net_lp_rpc_proto_rawDescGZIP(), []int{17} +} -func (m *NotifySegment) GetUrl() string { - if m != nil { - return m.Url +func (x *NotifySegment) GetUrl() string { + if x != nil { + return x.Url } return "" } -func (m *NotifySegment) GetSegData() *SegData { - if m != nil { - return m.SegData +func (x *NotifySegment) GetSegData() *SegData { + if x != nil { + return x.SegData } return nil } -func (m *NotifySegment) GetTaskId() int64 { - if m != nil { - return m.TaskId +func (x *NotifySegment) GetTaskId() int64 { + if x != nil { + return x.TaskId } return 0 } -func (m *NotifySegment) GetProfiles() []byte { - if m != nil { - return m.Profiles +func (x *NotifySegment) GetOrchId() string { + if x != nil { + return x.OrchId + } + return "" +} + +func (x *NotifySegment) GetProfiles() []byte { + if x != nil { + return x.Profiles } return nil } // Required parameters for probabilistic micropayment tickets type TicketParams struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + // ETH address of the recipient Recipient []byte `protobuf:"bytes,1,opt,name=recipient,proto3" json:"recipient,omitempty"` // Pay out (in Wei) to the recipient if the ticket wins @@ -1508,183 +1721,203 @@ type TicketParams struct { // Block number at which the current set of advertised TicketParams is no longer valid ExpirationBlock []byte `protobuf:"bytes,6,opt,name=expiration_block,json=expirationBlock,proto3" json:"expiration_block,omitempty"` // Expected ticket expiration params - ExpirationParams *TicketExpirationParams `protobuf:"bytes,7,opt,name=expiration_params,json=expirationParams,proto3" json:"expiration_params,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + ExpirationParams *TicketExpirationParams `protobuf:"bytes,7,opt,name=expiration_params,json=expirationParams,proto3" json:"expiration_params,omitempty"` } -func (m *TicketParams) Reset() { *m = TicketParams{} } -func (m *TicketParams) String() string { return proto.CompactTextString(m) } -func (*TicketParams) ProtoMessage() {} -func (*TicketParams) Descriptor() ([]byte, []int) { - return fileDescriptor_034e29c79f9ba827, []int{18} +func (x *TicketParams) Reset() { + *x = TicketParams{} + if protoimpl.UnsafeEnabled { + mi := &file_net_lp_rpc_proto_msgTypes[18] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *TicketParams) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_TicketParams.Unmarshal(m, b) -} -func (m *TicketParams) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_TicketParams.Marshal(b, m, deterministic) +func (x *TicketParams) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *TicketParams) XXX_Merge(src proto.Message) { - xxx_messageInfo_TicketParams.Merge(m, src) -} -func (m *TicketParams) XXX_Size() int { - return xxx_messageInfo_TicketParams.Size(m) -} -func (m *TicketParams) XXX_DiscardUnknown() { - xxx_messageInfo_TicketParams.DiscardUnknown(m) + +func (*TicketParams) ProtoMessage() {} + +func (x *TicketParams) ProtoReflect() protoreflect.Message { + mi := &file_net_lp_rpc_proto_msgTypes[18] + 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) } -var xxx_messageInfo_TicketParams proto.InternalMessageInfo +// Deprecated: Use TicketParams.ProtoReflect.Descriptor instead. +func (*TicketParams) Descriptor() ([]byte, []int) { + return file_net_lp_rpc_proto_rawDescGZIP(), []int{18} +} -func (m *TicketParams) GetRecipient() []byte { - if m != nil { - return m.Recipient +func (x *TicketParams) GetRecipient() []byte { + if x != nil { + return x.Recipient } return nil } -func (m *TicketParams) GetFaceValue() []byte { - if m != nil { - return m.FaceValue +func (x *TicketParams) GetFaceValue() []byte { + if x != nil { + return x.FaceValue } return nil } -func (m *TicketParams) GetWinProb() []byte { - if m != nil { - return m.WinProb +func (x *TicketParams) GetWinProb() []byte { + if x != nil { + return x.WinProb } return nil } -func (m *TicketParams) GetRecipientRandHash() []byte { - if m != nil { - return m.RecipientRandHash +func (x *TicketParams) GetRecipientRandHash() []byte { + if x != nil { + return x.RecipientRandHash } return nil } -func (m *TicketParams) GetSeed() []byte { - if m != nil { - return m.Seed +func (x *TicketParams) GetSeed() []byte { + if x != nil { + return x.Seed } return nil } -func (m *TicketParams) GetExpirationBlock() []byte { - if m != nil { - return m.ExpirationBlock +func (x *TicketParams) GetExpirationBlock() []byte { + if x != nil { + return x.ExpirationBlock } return nil } -func (m *TicketParams) GetExpirationParams() *TicketExpirationParams { - if m != nil { - return m.ExpirationParams +func (x *TicketParams) GetExpirationParams() *TicketExpirationParams { + if x != nil { + return x.ExpirationParams } return nil } // Sender Params (nonces and signatures) type TicketSenderParams struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + // Monotonically increasing counter that makes the ticket // unique relative to a particular hash commitment to a recipient's random number SenderNonce uint32 `protobuf:"varint,1,opt,name=sender_nonce,json=senderNonce,proto3" json:"sender_nonce,omitempty"` // Sender signature over the ticket - Sig []byte `protobuf:"bytes,2,opt,name=sig,proto3" json:"sig,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + Sig []byte `protobuf:"bytes,2,opt,name=sig,proto3" json:"sig,omitempty"` } -func (m *TicketSenderParams) Reset() { *m = TicketSenderParams{} } -func (m *TicketSenderParams) String() string { return proto.CompactTextString(m) } -func (*TicketSenderParams) ProtoMessage() {} -func (*TicketSenderParams) Descriptor() ([]byte, []int) { - return fileDescriptor_034e29c79f9ba827, []int{19} +func (x *TicketSenderParams) Reset() { + *x = TicketSenderParams{} + if protoimpl.UnsafeEnabled { + mi := &file_net_lp_rpc_proto_msgTypes[19] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *TicketSenderParams) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_TicketSenderParams.Unmarshal(m, b) -} -func (m *TicketSenderParams) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_TicketSenderParams.Marshal(b, m, deterministic) +func (x *TicketSenderParams) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *TicketSenderParams) XXX_Merge(src proto.Message) { - xxx_messageInfo_TicketSenderParams.Merge(m, src) -} -func (m *TicketSenderParams) XXX_Size() int { - return xxx_messageInfo_TicketSenderParams.Size(m) -} -func (m *TicketSenderParams) XXX_DiscardUnknown() { - xxx_messageInfo_TicketSenderParams.DiscardUnknown(m) + +func (*TicketSenderParams) ProtoMessage() {} + +func (x *TicketSenderParams) 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) } -var xxx_messageInfo_TicketSenderParams proto.InternalMessageInfo +// Deprecated: Use TicketSenderParams.ProtoReflect.Descriptor instead. +func (*TicketSenderParams) Descriptor() ([]byte, []int) { + return file_net_lp_rpc_proto_rawDescGZIP(), []int{19} +} -func (m *TicketSenderParams) GetSenderNonce() uint32 { - if m != nil { - return m.SenderNonce +func (x *TicketSenderParams) GetSenderNonce() uint32 { + if x != nil { + return x.SenderNonce } return 0 } -func (m *TicketSenderParams) GetSig() []byte { - if m != nil { - return m.Sig +func (x *TicketSenderParams) GetSig() []byte { + if x != nil { + return x.Sig } return nil } // Ticket params for expiration related validation type TicketExpirationParams struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + // Round during which tickets are created CreationRound int64 `protobuf:"varint,1,opt,name=creation_round,json=creationRound,proto3" json:"creation_round,omitempty"` // Block hash associated with creation_round - CreationRoundBlockHash []byte `protobuf:"bytes,2,opt,name=creation_round_block_hash,json=creationRoundBlockHash,proto3" json:"creation_round_block_hash,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + CreationRoundBlockHash []byte `protobuf:"bytes,2,opt,name=creation_round_block_hash,json=creationRoundBlockHash,proto3" json:"creation_round_block_hash,omitempty"` } -func (m *TicketExpirationParams) Reset() { *m = TicketExpirationParams{} } -func (m *TicketExpirationParams) String() string { return proto.CompactTextString(m) } -func (*TicketExpirationParams) ProtoMessage() {} -func (*TicketExpirationParams) Descriptor() ([]byte, []int) { - return fileDescriptor_034e29c79f9ba827, []int{20} +func (x *TicketExpirationParams) Reset() { + *x = TicketExpirationParams{} + if protoimpl.UnsafeEnabled { + mi := &file_net_lp_rpc_proto_msgTypes[20] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *TicketExpirationParams) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_TicketExpirationParams.Unmarshal(m, b) -} -func (m *TicketExpirationParams) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_TicketExpirationParams.Marshal(b, m, deterministic) -} -func (m *TicketExpirationParams) XXX_Merge(src proto.Message) { - xxx_messageInfo_TicketExpirationParams.Merge(m, src) -} -func (m *TicketExpirationParams) XXX_Size() int { - return xxx_messageInfo_TicketExpirationParams.Size(m) +func (x *TicketExpirationParams) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *TicketExpirationParams) XXX_DiscardUnknown() { - xxx_messageInfo_TicketExpirationParams.DiscardUnknown(m) + +func (*TicketExpirationParams) ProtoMessage() {} + +func (x *TicketExpirationParams) 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) } -var xxx_messageInfo_TicketExpirationParams proto.InternalMessageInfo +// Deprecated: Use TicketExpirationParams.ProtoReflect.Descriptor instead. +func (*TicketExpirationParams) Descriptor() ([]byte, []int) { + return file_net_lp_rpc_proto_rawDescGZIP(), []int{20} +} -func (m *TicketExpirationParams) GetCreationRound() int64 { - if m != nil { - return m.CreationRound +func (x *TicketExpirationParams) GetCreationRound() int64 { + if x != nil { + return x.CreationRound } return 0 } -func (m *TicketExpirationParams) GetCreationRoundBlockHash() []byte { - if m != nil { - return m.CreationRoundBlockHash +func (x *TicketExpirationParams) GetCreationRoundBlockHash() []byte { + if x != nil { + return x.CreationRoundBlockHash } return nil } @@ -1693,6 +1926,10 @@ func (m *TicketExpirationParams) GetCreationRoundBlockHash() []byte { // A payment can constitute of multiple tickets // A broadcaster might need to send multiple tickets to top up his credit with an Orchestrator type Payment struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + // Probabilistic micropayment ticket parameters // These remain the same even when sending multiple tickets TicketParams *TicketParams `protobuf:"bytes,1,opt,name=ticket_params,json=ticketParams,proto3" json:"ticket_params,omitempty"` @@ -1702,228 +1939,811 @@ type Payment struct { ExpirationParams *TicketExpirationParams `protobuf:"bytes,3,opt,name=expiration_params,json=expirationParams,proto3" json:"expiration_params,omitempty"` TicketSenderParams []*TicketSenderParams `protobuf:"bytes,4,rep,name=ticket_sender_params,json=ticketSenderParams,proto3" json:"ticket_sender_params,omitempty"` // O's last known price - ExpectedPrice *PriceInfo `protobuf:"bytes,5,opt,name=expected_price,json=expectedPrice,proto3" json:"expected_price,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + ExpectedPrice *PriceInfo `protobuf:"bytes,5,opt,name=expected_price,json=expectedPrice,proto3" json:"expected_price,omitempty"` } -func (m *Payment) Reset() { *m = Payment{} } -func (m *Payment) String() string { return proto.CompactTextString(m) } -func (*Payment) ProtoMessage() {} -func (*Payment) Descriptor() ([]byte, []int) { - return fileDescriptor_034e29c79f9ba827, []int{21} +func (x *Payment) Reset() { + *x = Payment{} + if protoimpl.UnsafeEnabled { + mi := &file_net_lp_rpc_proto_msgTypes[21] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *Payment) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Payment.Unmarshal(m, b) -} -func (m *Payment) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Payment.Marshal(b, m, deterministic) +func (x *Payment) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *Payment) XXX_Merge(src proto.Message) { - xxx_messageInfo_Payment.Merge(m, src) -} -func (m *Payment) XXX_Size() int { - return xxx_messageInfo_Payment.Size(m) -} -func (m *Payment) XXX_DiscardUnknown() { - xxx_messageInfo_Payment.DiscardUnknown(m) + +func (*Payment) ProtoMessage() {} + +func (x *Payment) 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) } -var xxx_messageInfo_Payment proto.InternalMessageInfo +// Deprecated: Use Payment.ProtoReflect.Descriptor instead. +func (*Payment) Descriptor() ([]byte, []int) { + return file_net_lp_rpc_proto_rawDescGZIP(), []int{21} +} -func (m *Payment) GetTicketParams() *TicketParams { - if m != nil { - return m.TicketParams +func (x *Payment) GetTicketParams() *TicketParams { + if x != nil { + return x.TicketParams } return nil } -func (m *Payment) GetSender() []byte { - if m != nil { - return m.Sender +func (x *Payment) GetSender() []byte { + if x != nil { + return x.Sender } return nil } -func (m *Payment) GetExpirationParams() *TicketExpirationParams { - if m != nil { - return m.ExpirationParams +func (x *Payment) GetExpirationParams() *TicketExpirationParams { + if x != nil { + return x.ExpirationParams } return nil } -func (m *Payment) GetTicketSenderParams() []*TicketSenderParams { - if m != nil { - return m.TicketSenderParams +func (x *Payment) GetTicketSenderParams() []*TicketSenderParams { + if x != nil { + return x.TicketSenderParams } return nil } -func (m *Payment) GetExpectedPrice() *PriceInfo { - if m != nil { - return m.ExpectedPrice +func (x *Payment) GetExpectedPrice() *PriceInfo { + if x != nil { + return x.ExpectedPrice } return nil } -func init() { - proto.RegisterEnum("net.OSInfo_StorageType", OSInfo_StorageType_name, OSInfo_StorageType_value) - proto.RegisterEnum("net.VideoProfile_Format", VideoProfile_Format_name, VideoProfile_Format_value) - proto.RegisterEnum("net.VideoProfile_Profile", VideoProfile_Profile_name, VideoProfile_Profile_value) - proto.RegisterEnum("net.VideoProfile_VideoCodec", VideoProfile_VideoCodec_name, VideoProfile_VideoCodec_value) - proto.RegisterEnum("net.VideoProfile_ChromaSubsampling", VideoProfile_ChromaSubsampling_name, VideoProfile_ChromaSubsampling_value) - proto.RegisterType((*PingPong)(nil), "net.PingPong") - proto.RegisterType((*EndTranscodingSessionRequest)(nil), "net.EndTranscodingSessionRequest") - proto.RegisterType((*EndTranscodingSessionResponse)(nil), "net.EndTranscodingSessionResponse") - proto.RegisterType((*OrchestratorRequest)(nil), "net.OrchestratorRequest") - proto.RegisterType((*OSInfo)(nil), "net.OSInfo") - proto.RegisterType((*S3OSInfo)(nil), "net.S3OSInfo") - proto.RegisterType((*PriceInfo)(nil), "net.PriceInfo") - proto.RegisterType((*Capabilities)(nil), "net.Capabilities") - proto.RegisterMapType((map[uint32]uint32)(nil), "net.Capabilities.CapacitiesEntry") - proto.RegisterType((*Capabilities_Constraints)(nil), "net.Capabilities.Constraints") - proto.RegisterType((*OrchestratorInfo)(nil), "net.OrchestratorInfo") - proto.RegisterType((*AuthToken)(nil), "net.AuthToken") - proto.RegisterType((*SegData)(nil), "net.SegData") - proto.RegisterType((*SegParameters)(nil), "net.SegParameters") - proto.RegisterType((*VideoProfile)(nil), "net.VideoProfile") - proto.RegisterType((*TranscodedSegmentData)(nil), "net.TranscodedSegmentData") - proto.RegisterType((*TranscodeData)(nil), "net.TranscodeData") - proto.RegisterType((*TranscodeResult)(nil), "net.TranscodeResult") - proto.RegisterType((*RegisterRequest)(nil), "net.RegisterRequest") - proto.RegisterType((*NotifySegment)(nil), "net.NotifySegment") - proto.RegisterType((*TicketParams)(nil), "net.TicketParams") - proto.RegisterType((*TicketSenderParams)(nil), "net.TicketSenderParams") - proto.RegisterType((*TicketExpirationParams)(nil), "net.TicketExpirationParams") - proto.RegisterType((*Payment)(nil), "net.Payment") -} - -func init() { - proto.RegisterFile("net/lp_rpc.proto", fileDescriptor_034e29c79f9ba827) -} - -var fileDescriptor_034e29c79f9ba827 = []byte{ - // 1911 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x58, 0xef, 0x6e, 0x1b, 0xc7, - 0x11, 0x17, 0xff, 0x88, 0x7f, 0x86, 0xa4, 0x74, 0x5c, 0x4b, 0xca, 0x49, 0xb1, 0x53, 0xf9, 0x12, - 0x07, 0xca, 0x07, 0x2b, 0x06, 0x25, 0xbb, 0x71, 0x81, 0xa2, 0xa5, 0x24, 0x5a, 0x62, 0x60, 0x49, - 0xc4, 0x52, 0x36, 0xd0, 0x7e, 0x28, 0x7b, 0xba, 0x5b, 0x92, 0x57, 0x91, 0x7b, 0xe7, 0xbd, 0x65, - 0x6c, 0x05, 0x7d, 0x81, 0x3e, 0x42, 0xfb, 0xa5, 0x40, 0x81, 0xbe, 0x47, 0x1f, 0xa0, 0x0f, 0x50, - 0xf4, 0x39, 0xfa, 0x00, 0xc5, 0xce, 0xee, 0x1d, 0x8f, 0xa2, 0x92, 0x18, 0xf9, 0xb6, 0xf3, 0x9b, - 0xd9, 0xd9, 0xd9, 0x99, 0x9d, 0x3f, 0x77, 0x60, 0x71, 0x26, 0xbf, 0x9e, 0x44, 0x03, 0x11, 0x79, - 0xfb, 0x91, 0x08, 0x65, 0x48, 0x0a, 0x9c, 0x49, 0x67, 0x17, 0x2a, 0xbd, 0x80, 0x8f, 0x7a, 0x21, - 0x1f, 0x91, 0x0d, 0x58, 0xfd, 0xce, 0x9d, 0xcc, 0x98, 0x9d, 0xdb, 0xcd, 0xed, 0xd5, 0xa9, 0x26, - 0x9c, 0x73, 0x78, 0xd8, 0xe1, 0xfe, 0x95, 0x70, 0x79, 0xec, 0x85, 0x7e, 0xc0, 0x47, 0x7d, 0x16, - 0xc7, 0x41, 0xc8, 0x29, 0x7b, 0x37, 0x63, 0xb1, 0x24, 0x4f, 0x01, 0xdc, 0x99, 0x1c, 0x0f, 0x64, - 0x78, 0xc3, 0x38, 0x6e, 0xad, 0xb5, 0xd6, 0xf6, 0x39, 0x93, 0xfb, 0xed, 0x99, 0x1c, 0x5f, 0x29, - 0x94, 0x56, 0xdd, 0x64, 0xe9, 0xfc, 0x02, 0x1e, 0xfd, 0x80, 0xba, 0x38, 0x0a, 0x79, 0xcc, 0x9c, - 0x36, 0x3c, 0xb8, 0x14, 0xde, 0x98, 0xc5, 0x52, 0xb8, 0x32, 0x14, 0xc9, 0x31, 0x36, 0x94, 0x5d, - 0xdf, 0x17, 0x2c, 0x8e, 0x8d, 0x79, 0x09, 0x49, 0x2c, 0x28, 0xc4, 0xc1, 0xc8, 0xce, 0x23, 0xaa, - 0x96, 0xce, 0x5f, 0x73, 0x50, 0xba, 0xec, 0x77, 0xf9, 0x30, 0x24, 0x2f, 0xa1, 0x16, 0xcb, 0x50, - 0xb8, 0x23, 0x76, 0x75, 0x1b, 0xe9, 0x9b, 0xad, 0xb5, 0x3e, 0x41, 0xf3, 0xb4, 0xc4, 0x7e, 0x7f, - 0xce, 0xa6, 0x59, 0x59, 0xf2, 0x04, 0x4a, 0xf1, 0x41, 0xc0, 0x87, 0xa1, 0x6d, 0xe1, 0xa5, 0x1a, - 0xb8, 0xab, 0x7f, 0xa0, 0xf7, 0x51, 0xc3, 0x74, 0x9e, 0x42, 0x2d, 0xa3, 0x82, 0x00, 0x94, 0x4e, - 0xba, 0xb4, 0x73, 0x7c, 0x65, 0xad, 0x90, 0x12, 0xe4, 0xfb, 0x07, 0x56, 0x4e, 0x61, 0xa7, 0x97, - 0x97, 0xa7, 0xaf, 0x3b, 0x56, 0xde, 0xf9, 0x47, 0x0e, 0x2a, 0x89, 0x0e, 0x42, 0xa0, 0x38, 0x0e, - 0x63, 0x89, 0x66, 0x55, 0x29, 0xae, 0xd5, 0x75, 0x6e, 0xd8, 0x2d, 0x5e, 0xa7, 0x4a, 0xd5, 0x92, - 0x6c, 0x41, 0x29, 0x0a, 0x27, 0x81, 0x77, 0x6b, 0x17, 0x10, 0x34, 0x14, 0x79, 0x08, 0xd5, 0x38, - 0x18, 0x71, 0x57, 0xce, 0x04, 0xb3, 0x8b, 0xc8, 0x9a, 0x03, 0xe4, 0x33, 0x00, 0x4f, 0x30, 0x9f, - 0x71, 0x19, 0xb8, 0x13, 0x7b, 0x15, 0xd9, 0x19, 0x84, 0xec, 0x40, 0xe5, 0x43, 0x7b, 0xfa, 0xfd, - 0x89, 0x2b, 0x99, 0x5d, 0x42, 0x6e, 0x4a, 0x3b, 0x6f, 0xa0, 0xda, 0x13, 0x81, 0xc7, 0xd0, 0x48, - 0x07, 0xea, 0x91, 0x22, 0x7a, 0x4c, 0xbc, 0xe1, 0x81, 0x36, 0xb6, 0x40, 0x17, 0x30, 0xf2, 0x05, - 0x34, 0xa2, 0xe0, 0x03, 0x9b, 0xc4, 0x89, 0x50, 0x1e, 0x85, 0x16, 0x41, 0xe7, 0xbf, 0x79, 0xa8, - 0x1f, 0xbb, 0x91, 0x7b, 0x1d, 0x4c, 0x02, 0x19, 0xb0, 0x58, 0xdd, 0xe0, 0x3a, 0x90, 0xb1, 0x14, - 0x01, 0x1f, 0xd9, 0xb9, 0xdd, 0xc2, 0x5e, 0x91, 0xce, 0x01, 0xb2, 0x0b, 0xb5, 0xa9, 0xcb, 0x7d, - 0xf5, 0x0a, 0x02, 0x16, 0xdb, 0x79, 0xe4, 0x67, 0x21, 0xd2, 0x06, 0xf0, 0xdc, 0xc8, 0xf5, 0x50, - 0x9b, 0x5d, 0xd8, 0x2d, 0xec, 0xd5, 0x5a, 0x8f, 0x31, 0x4c, 0xd9, 0x63, 0x90, 0xd0, 0x32, 0x1d, - 0x2e, 0xc5, 0x2d, 0xcd, 0x6c, 0x52, 0xef, 0xea, 0x3b, 0x26, 0xd4, 0x0b, 0x34, 0x2e, 0x4c, 0x48, - 0xf2, 0x1b, 0xa8, 0x79, 0x21, 0x57, 0xcf, 0x30, 0xe0, 0x32, 0x46, 0x0f, 0xd6, 0x5a, 0x8f, 0xee, - 0xd1, 0x3e, 0x17, 0xa2, 0xd9, 0x1d, 0x3b, 0xbf, 0x86, 0xf5, 0x3b, 0x27, 0x27, 0xc1, 0x55, 0x2e, - 0x6c, 0xe8, 0xe0, 0xa6, 0x49, 0x97, 0x47, 0x4c, 0x13, 0xbf, 0xca, 0x7f, 0x93, 0xdb, 0x79, 0x0a, - 0xb5, 0x8c, 0x6a, 0x15, 0xcf, 0x69, 0xc0, 0xdf, 0x1a, 0x5b, 0xf5, 0x8b, 0xc9, 0x20, 0xce, 0xbf, - 0xf2, 0x60, 0x65, 0x13, 0x07, 0x63, 0xf7, 0x19, 0x80, 0x34, 0xa9, 0xc6, 0x44, 0xb2, 0x69, 0x8e, - 0x90, 0x17, 0xd0, 0x90, 0x81, 0x77, 0xc3, 0xe4, 0x20, 0x72, 0x85, 0x3b, 0x8d, 0xd1, 0x8a, 0x5a, - 0xab, 0x89, 0xb7, 0xbc, 0x42, 0x4e, 0x0f, 0x19, 0xb4, 0x2e, 0x33, 0x94, 0x4a, 0x7a, 0x8c, 0xff, - 0x00, 0xf3, 0xa3, 0x90, 0x49, 0xfa, 0xf4, 0xdd, 0xd0, 0x6a, 0x94, 0x3e, 0xa1, 0x4c, 0xf2, 0x16, - 0x17, 0x93, 0xf7, 0x39, 0xd4, 0xbd, 0x8c, 0x33, 0x8d, 0x97, 0x9b, 0x4b, 0x5e, 0xa6, 0x0b, 0x62, - 0x77, 0x8a, 0x4e, 0xe9, 0x27, 0x8a, 0x0e, 0x79, 0x02, 0x65, 0x93, 0xd9, 0xf6, 0x2e, 0x3e, 0x92, - 0x5a, 0xa6, 0x02, 0xd0, 0x84, 0xe7, 0xfc, 0x11, 0xaa, 0xe9, 0x76, 0x15, 0x98, 0x79, 0x49, 0xab, - 0x53, 0x4d, 0x90, 0x47, 0x00, 0xb1, 0x2e, 0x58, 0x83, 0xc0, 0x37, 0x49, 0x5a, 0x35, 0x48, 0xd7, - 0x57, 0xfe, 0x66, 0x1f, 0xa2, 0x40, 0xb8, 0x52, 0x05, 0xa9, 0x80, 0x49, 0x90, 0x41, 0x9c, 0xff, - 0x15, 0xa1, 0xdc, 0x67, 0xa3, 0x13, 0x57, 0xba, 0x18, 0x50, 0x97, 0x07, 0x43, 0x16, 0xcb, 0xae, - 0x6f, 0x4e, 0xc9, 0x20, 0x58, 0xd7, 0xd8, 0x3b, 0x93, 0x49, 0x6a, 0x89, 0xe5, 0xc2, 0x8d, 0xc7, - 0xa8, 0xb7, 0x4e, 0x71, 0xad, 0xd2, 0x38, 0x12, 0xe1, 0x30, 0x98, 0xb0, 0xc4, 0xb7, 0x29, 0x9d, - 0x54, 0xc6, 0xd5, 0xb4, 0x32, 0x2a, 0x69, 0x7f, 0x66, 0xac, 0x53, 0x5e, 0x5b, 0xa5, 0x29, 0xbd, - 0x14, 0x8a, 0xf2, 0xcf, 0x09, 0x45, 0xe5, 0xa7, 0x42, 0xf1, 0x0c, 0x36, 0x3c, 0x77, 0xe2, 0x0d, - 0x22, 0x26, 0x3c, 0x16, 0xc9, 0x99, 0x3b, 0x19, 0xe0, 0x9d, 0x60, 0x37, 0xb7, 0x57, 0xa1, 0x44, - 0xf1, 0x7a, 0x29, 0xeb, 0x4c, 0xdd, 0xf0, 0xe3, 0x82, 0xa7, 0xcc, 0x1f, 0xce, 0x26, 0x93, 0x5e, - 0xe2, 0x8c, 0xc7, 0x28, 0xab, 0xcd, 0x7f, 0x1b, 0xf8, 0x2c, 0x34, 0x1c, 0xba, 0x20, 0x46, 0x7e, - 0x09, 0x8d, 0x2c, 0xdd, 0xb2, 0x9d, 0x1f, 0xda, 0xb7, 0x28, 0x77, 0x77, 0xe3, 0x81, 0xfd, 0xf9, - 0x47, 0x6d, 0x3c, 0x20, 0x6d, 0x20, 0x31, 0x1b, 0x4d, 0x19, 0x37, 0x49, 0xc7, 0x24, 0x13, 0xb1, - 0xfd, 0x04, 0x1d, 0x47, 0x74, 0x8f, 0x61, 0xa3, 0x5e, 0xca, 0xa1, 0x4d, 0x23, 0x3d, 0x87, 0xc8, - 0x3e, 0x90, 0x57, 0xa1, 0xf0, 0x58, 0xda, 0x3b, 0x03, 0x55, 0x73, 0xbf, 0xd4, 0x2e, 0x5c, 0xe6, - 0x38, 0x07, 0xd0, 0x58, 0xd0, 0xa9, 0x5e, 0xd2, 0x50, 0x84, 0x53, 0x7c, 0x75, 0x45, 0x8a, 0x6b, - 0xb2, 0x06, 0x79, 0x19, 0xe2, 0x73, 0x2b, 0xd2, 0xbc, 0x0c, 0x9d, 0x7f, 0xaf, 0x42, 0x3d, 0x7b, - 0x0f, 0xb5, 0x89, 0xbb, 0x53, 0x86, 0xed, 0xb0, 0x4a, 0x71, 0xad, 0xb2, 0xe4, 0x7d, 0xe0, 0xcb, - 0xb1, 0xdd, 0xc4, 0xd7, 0xa4, 0x09, 0xd5, 0xb1, 0xc6, 0x2c, 0x18, 0x8d, 0xa5, 0x4d, 0x10, 0x36, - 0x94, 0xaa, 0x03, 0xd7, 0x81, 0x2a, 0x4f, 0xcc, 0x7e, 0x80, 0x8c, 0x84, 0x54, 0x4f, 0x75, 0x18, - 0xc5, 0xf6, 0x86, 0x2e, 0x8c, 0xc3, 0x28, 0x26, 0xcf, 0xa0, 0x34, 0x0c, 0xc5, 0xd4, 0x95, 0xf6, - 0x26, 0x36, 0x6d, 0x7b, 0xc9, 0xb1, 0xfb, 0xaf, 0x90, 0x4f, 0x8d, 0x9c, 0x3a, 0x75, 0x18, 0xc5, - 0x27, 0x8c, 0xdb, 0x5b, 0xa8, 0xc6, 0x50, 0xe4, 0x00, 0xca, 0x26, 0x25, 0xec, 0x4f, 0x50, 0xd5, - 0xf6, 0xb2, 0xaa, 0x24, 0x56, 0x89, 0xa4, 0x32, 0x68, 0x14, 0x46, 0xb6, 0x8d, 0x66, 0xaa, 0x25, - 0x79, 0x01, 0x65, 0xc6, 0x75, 0x21, 0xdd, 0x46, 0x35, 0x0f, 0x97, 0xd5, 0x20, 0x71, 0x1c, 0xfa, - 0xcc, 0xa3, 0x89, 0x30, 0x36, 0xe2, 0x70, 0x12, 0x8a, 0x13, 0x16, 0xc9, 0xb1, 0xbd, 0x83, 0x0a, - 0x33, 0x08, 0x39, 0x85, 0xba, 0x37, 0x16, 0xe1, 0xd4, 0xd5, 0xd7, 0xb1, 0x3f, 0x45, 0xe5, 0x9f, - 0x2f, 0x2b, 0x3f, 0x46, 0xa9, 0xfe, 0xec, 0x3a, 0x76, 0xa7, 0xd1, 0x24, 0xe0, 0x23, 0xba, 0xb0, - 0x51, 0x79, 0xf7, 0xdd, 0xcc, 0x9d, 0x04, 0xf2, 0xd6, 0x7e, 0x88, 0x0e, 0x48, 0x48, 0xe7, 0x11, - 0x94, 0x8c, 0x0c, 0x40, 0xe9, 0xbc, 0xd7, 0x39, 0xbd, 0xea, 0x5b, 0x2b, 0xa4, 0x0c, 0x85, 0xf3, - 0xde, 0xa1, 0x95, 0x73, 0xfe, 0x04, 0xe5, 0x24, 0xc6, 0x0f, 0x60, 0xbd, 0x73, 0x71, 0x7c, 0x79, - 0xd2, 0xa1, 0x83, 0x93, 0xce, 0xab, 0xf6, 0x9b, 0xd7, 0x6a, 0x8e, 0x69, 0x42, 0xe3, 0xac, 0xf5, - 0xe2, 0x70, 0x70, 0xd4, 0xee, 0x77, 0x5e, 0x77, 0x2f, 0x3a, 0x56, 0x8e, 0x34, 0xa0, 0x8a, 0xd0, - 0x79, 0xbb, 0x7b, 0x61, 0xe5, 0x53, 0xf2, 0xac, 0x7b, 0x7a, 0x66, 0x15, 0xc8, 0x36, 0x6c, 0x22, - 0x79, 0x7c, 0x79, 0xd1, 0xbf, 0xa2, 0xed, 0xee, 0x45, 0xe7, 0x44, 0xb3, 0x8a, 0x4e, 0x0b, 0x60, - 0xee, 0x24, 0x52, 0x81, 0xa2, 0x12, 0xb4, 0x56, 0xcc, 0xea, 0xb9, 0x95, 0x53, 0x66, 0xbd, 0xed, - 0x7d, 0x63, 0xe5, 0xf5, 0xe2, 0xa5, 0x55, 0x70, 0x8e, 0xa1, 0xb9, 0x74, 0x77, 0xb2, 0x06, 0x70, - 0x7c, 0x46, 0x2f, 0xcf, 0xdb, 0x83, 0xc3, 0xd6, 0x33, 0x6b, 0x65, 0x81, 0x6e, 0x59, 0xb9, 0x2c, - 0x7d, 0x78, 0x68, 0xe5, 0x9d, 0x77, 0xb0, 0x99, 0x4c, 0x9d, 0xcc, 0xef, 0xeb, 0x94, 0xc2, 0x3a, - 0x6c, 0x41, 0x61, 0x26, 0x26, 0xa6, 0x39, 0xaa, 0x25, 0x0e, 0x5c, 0x38, 0xb8, 0x98, 0xe2, 0x6b, - 0x28, 0xb2, 0x0f, 0x0f, 0xee, 0x94, 0xad, 0x81, 0xda, 0xa9, 0xa7, 0xb2, 0x66, 0xb4, 0x50, 0xb6, - 0xde, 0x88, 0x89, 0xf3, 0x3b, 0x68, 0xa4, 0x47, 0xe2, 0x51, 0x2f, 0xa0, 0x62, 0x92, 0x39, 0xc6, - 0x71, 0xa7, 0xd6, 0xda, 0xd1, 0x9d, 0xf6, 0x3e, 0xc3, 0x68, 0x2a, 0x7b, 0xcf, 0x88, 0xfb, 0xb7, - 0x1c, 0xac, 0xa7, 0xbb, 0x28, 0x8b, 0x67, 0x13, 0x99, 0x34, 0x8c, 0xdc, 0xbc, 0x61, 0x6c, 0xc1, - 0x2a, 0x13, 0x22, 0x14, 0xba, 0x51, 0x9d, 0xad, 0x50, 0x4d, 0x92, 0x3d, 0x28, 0xfa, 0xae, 0x74, - 0x4d, 0xe3, 0x26, 0x8b, 0x36, 0xa8, 0xb3, 0xcf, 0x56, 0x28, 0x4a, 0x90, 0xaf, 0xa0, 0x98, 0x19, - 0x81, 0x37, 0x75, 0xe5, 0xbd, 0x33, 0x65, 0x50, 0x14, 0x39, 0xaa, 0x40, 0x49, 0xa0, 0x21, 0xce, - 0x9f, 0x61, 0x9d, 0xb2, 0x51, 0x10, 0x4b, 0x96, 0x8e, 0xef, 0x5b, 0x50, 0x8a, 0x99, 0x27, 0x58, - 0x32, 0xeb, 0x1a, 0x4a, 0x35, 0x24, 0x33, 0x8c, 0xdd, 0x1a, 0x67, 0xa7, 0xf4, 0x52, 0x43, 0x2a, - 0x7c, 0x54, 0x43, 0x72, 0xfe, 0x92, 0x83, 0xc6, 0x45, 0x28, 0x83, 0xe1, 0xad, 0x71, 0xe6, 0x3d, - 0x11, 0xfe, 0x12, 0xca, 0xb1, 0x6e, 0xc3, 0x46, 0x6b, 0x3d, 0x29, 0xbc, 0xe8, 0xf9, 0x84, 0xa9, - 0xcc, 0x96, 0x6e, 0x7c, 0xd3, 0xf5, 0xd1, 0x01, 0x05, 0x6a, 0xa8, 0x85, 0xae, 0xdb, 0x5c, 0xec, - 0xba, 0xdf, 0x16, 0x2b, 0x79, 0xab, 0xf0, 0x6d, 0xb1, 0xf2, 0xd8, 0x72, 0x9c, 0xbf, 0xe7, 0xa1, - 0x9e, 0x1d, 0xa3, 0xd4, 0xc4, 0x2b, 0x98, 0x17, 0x44, 0x01, 0xe3, 0xd2, 0xf4, 0xfc, 0x39, 0xa0, - 0xa6, 0x8b, 0xa1, 0xeb, 0xb1, 0xc1, 0x7c, 0x22, 0xac, 0xd3, 0xaa, 0x42, 0xde, 0x2a, 0x80, 0x6c, - 0x43, 0xe5, 0x7d, 0xc0, 0x07, 0x91, 0x08, 0xaf, 0xcd, 0x0c, 0x50, 0x7e, 0x1f, 0xf0, 0x9e, 0x08, - 0xaf, 0xd5, 0xd3, 0x4c, 0xd5, 0x0c, 0x84, 0xcb, 0x7d, 0xdd, 0x55, 0xf5, 0x44, 0xd0, 0x4c, 0x59, - 0xd4, 0xe5, 0x3e, 0x36, 0x55, 0x02, 0xc5, 0x98, 0x31, 0xdf, 0xcc, 0x06, 0xb8, 0x26, 0x5f, 0x81, - 0x35, 0x1f, 0x55, 0x06, 0xd7, 0x93, 0xd0, 0xbb, 0xc1, 0x21, 0xa1, 0x4e, 0xd7, 0xe7, 0xf8, 0x91, - 0x82, 0xc9, 0x19, 0x34, 0x33, 0xa2, 0x66, 0x76, 0xd4, 0x03, 0xc3, 0xa7, 0x99, 0xd9, 0xb1, 0x93, - 0xca, 0x98, 0x29, 0x32, 0x73, 0x80, 0x46, 0x9c, 0x2e, 0x10, 0x2d, 0xdb, 0x67, 0xdc, 0x67, 0xc2, - 0xb8, 0xe9, 0x31, 0xd4, 0x63, 0xa4, 0x07, 0x3c, 0xe4, 0x1e, 0x33, 0x03, 0x73, 0x4d, 0x63, 0x17, - 0x0a, 0xba, 0x27, 0x27, 0xbe, 0x87, 0xad, 0xfb, 0x8f, 0x25, 0x4f, 0x60, 0xcd, 0x13, 0x4c, 0x1b, - 0x2b, 0xc2, 0x19, 0xf7, 0x4d, 0x92, 0x34, 0x12, 0x94, 0x2a, 0x90, 0xbc, 0x84, 0xed, 0x45, 0x31, - 0xed, 0x04, 0xed, 0x4a, 0x7d, 0xd0, 0xd6, 0xc2, 0x0e, 0x74, 0x86, 0xf2, 0xa7, 0xf3, 0xcf, 0x3c, - 0x94, 0x7b, 0xee, 0x2d, 0x3e, 0xb7, 0xa5, 0xa1, 0x3a, 0xf7, 0x71, 0x43, 0x35, 0xe6, 0x88, 0xba, - 0xa0, 0x39, 0xcb, 0x50, 0xf7, 0x3b, 0xbb, 0xf0, 0x33, 0x9c, 0x4d, 0xba, 0xb0, 0x61, 0x2c, 0x33, - 0xde, 0x35, 0xca, 0x8a, 0x58, 0x8b, 0x3e, 0xc9, 0x28, 0xcb, 0x46, 0x83, 0x12, 0xb9, 0x1c, 0xa1, - 0xe7, 0xb0, 0xc6, 0x3e, 0x44, 0xcc, 0x93, 0xcc, 0x1f, 0xe0, 0xa0, 0x6f, 0x46, 0xf7, 0xbb, 0x5f, - 0x01, 0x8d, 0x44, 0x0a, 0xa1, 0xd6, 0x7f, 0x72, 0x50, 0xcf, 0xd6, 0x0f, 0x72, 0x04, 0xeb, 0xa7, - 0x4c, 0x2e, 0x40, 0xf6, 0x52, 0x95, 0x31, 0x55, 0x64, 0xe7, 0xfe, 0xfa, 0x43, 0xfe, 0x00, 0x9b, - 0xf7, 0xfe, 0x53, 0x20, 0xfa, 0x5b, 0xf0, 0xc7, 0x7e, 0x5f, 0xec, 0x38, 0x3f, 0x26, 0xa2, 0x7f, - 0x49, 0x90, 0x2f, 0xa0, 0xd8, 0x53, 0x2d, 0x47, 0xff, 0x01, 0x48, 0xfe, 0x97, 0xec, 0x2c, 0x92, - 0xad, 0x0b, 0x80, 0xab, 0xf9, 0x97, 0xd5, 0x6f, 0x81, 0x24, 0x35, 0x30, 0x83, 0x6e, 0xe0, 0x96, - 0x3b, 0xc5, 0x71, 0x47, 0x17, 0xe0, 0x85, 0x9a, 0xf5, 0x2c, 0x77, 0x54, 0xfe, 0xfd, 0xea, 0xfe, - 0xd7, 0x9c, 0xc9, 0xeb, 0x12, 0xfe, 0xaf, 0x39, 0xf8, 0x7f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x8c, - 0x55, 0x8b, 0x9a, 0xc3, 0x11, 0x00, 0x00, +// Non-binary capability constraints, such as supported ranges. +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"` +} + +func (x *Capabilities_Constraints) Reset() { + *x = Capabilities_Constraints{} + if protoimpl.UnsafeEnabled { + mi := &file_net_lp_rpc_proto_msgTypes[23] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Capabilities_Constraints) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Capabilities_Constraints) ProtoMessage() {} + +func (x *Capabilities_Constraints) ProtoReflect() protoreflect.Message { + mi := &file_net_lp_rpc_proto_msgTypes[23] + 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_Constraints.ProtoReflect.Descriptor instead. +func (*Capabilities_Constraints) Descriptor() ([]byte, []int) { + return file_net_lp_rpc_proto_rawDescGZIP(), []int{7, 1} +} + +func (x *Capabilities_Constraints) GetMinVersion() string { + if x != nil { + return x.MinVersion + } + return "" +} + +var File_net_lp_rpc_proto protoreflect.FileDescriptor + +var file_net_lp_rpc_proto_rawDesc = []byte{ + 0x0a, 0x10, 0x6e, 0x65, 0x74, 0x2f, 0x6c, 0x70, 0x5f, 0x72, 0x70, 0x63, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x12, 0x03, 0x6e, 0x65, 0x74, 0x22, 0x20, 0x0a, 0x08, 0x50, 0x69, 0x6e, 0x67, 0x50, + 0x6f, 0x6e, 0x67, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x4d, 0x0a, 0x1c, 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, 0x12, 0x2d, 0x0a, 0x0a, 0x61, 0x75, 0x74, + 0x68, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 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, 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, + 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, + 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, 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, + 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, +} + +var ( + file_net_lp_rpc_proto_rawDescOnce sync.Once + file_net_lp_rpc_proto_rawDescData = file_net_lp_rpc_proto_rawDesc +) + +func file_net_lp_rpc_proto_rawDescGZIP() []byte { + file_net_lp_rpc_proto_rawDescOnce.Do(func() { + file_net_lp_rpc_proto_rawDescData = protoimpl.X.CompressGZIP(file_net_lp_rpc_proto_rawDescData) + }) + return file_net_lp_rpc_proto_rawDescData +} + +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_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 +} +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 +} + +func init() { file_net_lp_rpc_proto_init() } +func file_net_lp_rpc_proto_init() { + if File_net_lp_rpc_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_net_lp_rpc_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PingPong); 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[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*EndTranscodingSessionRequest); 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[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*EndTranscodingSessionResponse); 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[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*OrchestratorRequest); 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[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*OSInfo); 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[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*S3OSInfo); 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[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PriceInfo); 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[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Capabilities); 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[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*OrchestratorInfo); 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[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AuthToken); 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[10].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SegData); 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[11].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SegParameters); 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[12].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*VideoProfile); 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[13].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*TranscodedSegmentData); 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[14].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*TranscodeData); 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].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*TranscodeResult); 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[16].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RegisterRequest); 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[17].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*NotifySegment); 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[18].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*TicketParams); 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[19].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[20].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[21].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[23].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Capabilities_Constraints); 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), + (*TranscodeResult_Data)(nil), + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_net_lp_rpc_proto_rawDesc, + NumEnums: 5, + NumMessages: 24, + NumExtensions: 0, + NumServices: 2, + }, + GoTypes: file_net_lp_rpc_proto_goTypes, + DependencyIndexes: file_net_lp_rpc_proto_depIdxs, + EnumInfos: file_net_lp_rpc_proto_enumTypes, + MessageInfos: file_net_lp_rpc_proto_msgTypes, + }.Build() + File_net_lp_rpc_proto = out.File + file_net_lp_rpc_proto_rawDesc = nil + file_net_lp_rpc_proto_goTypes = nil + file_net_lp_rpc_proto_depIdxs = nil } diff --git a/net/lp_rpc.proto b/net/lp_rpc.proto index e53a594fcf..b14f45db5e 100644 --- a/net/lp_rpc.proto +++ b/net/lp_rpc.proto @@ -340,6 +340,9 @@ message NotifySegment { // ID for this particular transcoding task. int64 taskId = 16; + // Orchestrator identifier for segment metadata + string orchId = 18; + // All fields below are deprecated. May still be populated if necessary // Deprecated by segData. Job the segment belongs to. diff --git a/net/lp_rpc_grpc.pb.go b/net/lp_rpc_grpc.pb.go index 64a0935463..d998fd9a94 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.4 +// - protoc v3.21.12 // source: net/lp_rpc.proto package net diff --git a/pm/sender.go b/pm/sender.go index 6f6acf0fd4..ebeb09e2c6 100644 --- a/pm/sender.go +++ b/pm/sender.go @@ -22,6 +22,9 @@ type Sender interface { // for creating new tickets StartSession(ticketParams TicketParams) string + // CleanupSession deletes session from the internal map + CleanupSession(sessionID string) + // CreateTicketBatch returns a ticket batch of the specified size CreateTicketBatch(sessionID string, size int) (*TicketBatch, error) @@ -82,6 +85,10 @@ func (s *sender) EV(sessionID string) (*big.Rat, error) { return ticketEV(session.ticketParams.FaceValue, session.ticketParams.WinProb), nil } +func (s *sender) CleanupSession(sessionID string) { + s.sessions.Delete(sessionID) +} + func (s *sender) validateSender(info *SenderInfo) error { maxWithdrawRound := new(big.Int).Add(s.timeManager.LastInitializedRound(), big.NewInt(1)) if info.WithdrawRound.Int64() != 0 && info.WithdrawRound.Cmp(maxWithdrawRound) != 1 { diff --git a/pm/stub.go b/pm/stub.go index a3e0f7f224..549f386472 100644 --- a/pm/stub.go +++ b/pm/stub.go @@ -511,6 +511,11 @@ func (m *MockSender) StartSession(ticketParams TicketParams) string { return args.String(0) } +// CleanupSession deletes session from the internal ma +func (m *MockSender) CleanupSession(sessionID string) { + m.Called(sessionID) +} + // EV returns the ticket EV for a session func (m *MockSender) EV(sessionID string) (*big.Rat, error) { args := m.Called(sessionID) diff --git a/server/broadcast.go b/server/broadcast.go index bcd0a54658..a3e8cf64b9 100755 --- a/server/broadcast.go +++ b/server/broadcast.go @@ -85,6 +85,7 @@ func (cfg *BroadcastConfig) SetMaxPrice(price *core.AutoConvertedPrice) { } type sessionsCreator func() ([]*BroadcastSession, error) +type sessionsCleanup func(sessionId string) type SessionPool struct { mid core.ManifestID @@ -101,10 +102,11 @@ type SessionPool struct { finished bool // set at stream end createSessions sessionsCreator + cleanupSession sessionsCleanup sus *suspender } -func NewSessionPool(mid core.ManifestID, poolSize, numOrchs int, sus *suspender, createSession sessionsCreator, +func NewSessionPool(mid core.ManifestID, poolSize, numOrchs int, sus *suspender, createSession sessionsCreator, cleanupSession sessionsCleanup, sel BroadcastSessionsSelector) *SessionPool { return &SessionPool{ @@ -114,6 +116,7 @@ func NewSessionPool(mid core.ManifestID, poolSize, numOrchs int, sus *suspender, sessMap: make(map[string]*BroadcastSession), sel: sel, createSessions: createSession, + cleanupSession: cleanupSession, sus: sus, } } @@ -378,6 +381,7 @@ func (sp *SessionPool) removeSession(session *BroadcastSession) { sp.lock.Lock() defer sp.lock.Unlock() + sp.cleanupSession(session.PMSessionID) delete(sp.sessMap, session.Transcoder()) } @@ -463,11 +467,14 @@ func NewSessionManager(ctx context.Context, node *core.LivepeerNode, params *cor untrustedNumOrchs := int(untrustedPoolSize) susTrusted := newSuspender() susUntrusted := newSuspender() + cleanupSession := func(sessionID string) { + node.Sender.CleanupSession(sessionID) + } createSessionsTrusted := func() ([]*BroadcastSession, error) { - return selectOrchestrator(ctx, node, params, trustedNumOrchs, susTrusted, common.ScoreAtLeast(common.Score_Trusted)) + return selectOrchestrator(ctx, node, params, trustedNumOrchs, susTrusted, common.ScoreAtLeast(common.Score_Trusted), cleanupSession) } createSessionsUntrusted := func() ([]*BroadcastSession, error) { - return selectOrchestrator(ctx, node, params, untrustedNumOrchs, susUntrusted, common.ScoreEqualTo(common.Score_Untrusted)) + return selectOrchestrator(ctx, node, params, untrustedNumOrchs, susUntrusted, common.ScoreEqualTo(common.Score_Untrusted), cleanupSession) } var stakeRdr stakeReader if node.Eth != nil { @@ -476,8 +483,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, NewMinLSSelector(stakeRdr, 1.0, node.SelectionAlgorithm, node.OrchPerfScore)), - untrustedPool: NewSessionPool(params.ManifestID, int(untrustedPoolSize), untrustedNumOrchs, susUntrusted, createSessionsUntrusted, 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)), + untrustedPool: NewSessionPool(params.ManifestID, int(untrustedPoolSize), untrustedNumOrchs, susUntrusted, createSessionsUntrusted, cleanupSession, NewMinLSSelector(stakeRdr, 1.0, node.SelectionAlgorithm, node.OrchPerfScore)), } bsm.trustedPool.refreshSessions(ctx) bsm.untrustedPool.refreshSessions(ctx) @@ -768,7 +775,7 @@ func (bsm *BroadcastSessionsManager) usingVerified() bool { } func selectOrchestrator(ctx context.Context, n *core.LivepeerNode, params *core.StreamParameters, count int, sus *suspender, - scorePred common.ScorePred) ([]*BroadcastSession, error) { + scorePred common.ScorePred, cleanupSession sessionsCleanup) ([]*BroadcastSession, error) { if n.OrchestratorPool == nil { clog.Infof(ctx, "No orchestrators specified; not transcoding") @@ -836,6 +843,7 @@ func selectOrchestrator(ctx context.Context, n *core.LivepeerNode, params *core. OrchestratorOS: orchOS, BroadcasterOS: bcastOS, Sender: n.Sender, + CleanupSession: cleanupSession, PMSessionID: sessionID, Balances: n.Balances, Balance: balance, @@ -1470,7 +1478,9 @@ func updateSession(sess *BroadcastSession, res *ReceivedTranscodeResult) { // and the next time this BroadcastSession is used, the ticket params will be validated // during ticket creation in genPayment(). If ticket params validation during ticket // creation fails, then this BroadcastSession will be removed + oldSession := sess.PMSessionID sess.PMSessionID = sess.Sender.StartSession(*pmTicketParams(oInfo.TicketParams)) + sess.CleanupSession(oldSession) // Session ID changed so we need to make sure the balance tracks the new session ID if oldInfo.AuthToken.SessionId != oInfo.AuthToken.SessionId { diff --git a/server/broadcast_test.go b/server/broadcast_test.go index 669ff06313..372d25205a 100644 --- a/server/broadcast_test.go +++ b/server/broadcast_test.go @@ -61,16 +61,10 @@ func StubBroadcastSession(transcoder string) *BroadcastSession { }, OrchestratorScore: common.Score_Trusted, lock: &sync.RWMutex{}, + CleanupSession: func(sessionId string) {}, } } -func StubBroadcastSessionsManager() *BroadcastSessionsManager { - sess1 := StubBroadcastSession("transcoder1") - sess2 := StubBroadcastSession("transcoder2") - - return bsmWithSessList([]*BroadcastSession{sess1, sess2}) -} - func selFactoryEmpty() BroadcastSessionsSelector { return &LIFOSelector{} } @@ -101,6 +95,8 @@ func bsmWithSessListExt(sessList, untrustedSessList []*BroadcastSession, noRefre return cloneSessions(sessList), nil } + var deleteSessions = func(sessionID string) {} + untrustedSessMap := make(map[string]*BroadcastSession) for _, sess := range untrustedSessList { untrustedSessMap[sess.OrchestratorInfo.Transcoder] = sess @@ -118,11 +114,10 @@ func bsmWithSessListExt(sessList, untrustedSessList []*BroadcastSession, noRefre if noRefresh { createSessions = createSessionsEmpty createSessionsUntrusted = createSessionsEmpty - } - trustedPool := NewSessionPool("test", len(sessList), 1, newSuspender(), createSessions, sel) + trustedPool := NewSessionPool("test", len(sessList), 1, newSuspender(), createSessions, deleteSessions, sel) trustedPool.sessMap = sessMap - untrustedPool := NewSessionPool("test", len(untrustedSessList), 1, newSuspender(), createSessionsUntrusted, unsel) + untrustedPool := NewSessionPool("test", len(untrustedSessList), 1, newSuspender(), createSessionsUntrusted, deleteSessions, unsel) untrustedPool.sessMap = untrustedSessMap return &BroadcastSessionsManager{ @@ -393,6 +388,7 @@ func TestSelectSession_MultipleInFlight2(t *testing.T) { sess := StubBroadcastSession(ts.URL) sender := &pm.MockSender{} sender.On("StartSession", mock.Anything).Return("foo").Times(3) + 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) @@ -1125,7 +1121,9 @@ func TestUpdateSession(t *testing.T) { balances := core.NewAddressBalances(5 * time.Minute) defer balances.StopCleanup() - sess := &BroadcastSession{PMSessionID: "foo", LatencyScore: 1.1, Balances: balances, lock: &sync.RWMutex{}} + sess := &BroadcastSession{PMSessionID: "foo", LatencyScore: 1.1, Balances: balances, lock: &sync.RWMutex{}, CleanupSession: func(sessionID string) { + + }} res := &ReceivedTranscodeResult{ LatencyScore: 2.1, } diff --git a/server/handlers.go b/server/handlers.go index 22116079e6..5e9cc62d8c 100644 --- a/server/handlers.go +++ b/server/handlers.go @@ -526,6 +526,12 @@ func (s *LivepeerServer) setServiceURI(client eth.LivepeerEthClient, serviceURI return err } + if !common.ValidateServiceURI(parsedURI) { + err = errors.New("service address must be a public IP address or hostname") + glog.Error(err) + return err + } + glog.Infof("Storing service URI %v in service registry...", serviceURI) tx, err := client.SetServiceURI(serviceURI) diff --git a/server/handlers_test.go b/server/handlers_test.go index d191d0a75e..528282972e 100644 --- a/server/handlers_test.go +++ b/server/handlers_test.go @@ -15,6 +15,7 @@ import ( "github.com/ethereum/go-ethereum/accounts" ethcommon "github.com/ethereum/go-ethereum/common" + ethtypes "github.com/ethereum/go-ethereum/core/types" "github.com/livepeer/go-livepeer/core" "github.com/livepeer/go-livepeer/eth" "github.com/livepeer/go-livepeer/eth/types" @@ -1570,7 +1571,29 @@ func TestMustHaveDb_Success(t *testing.T) { assert.Equal(http.StatusOK, status) assert.Equal("success", body) } +func TestSetServiceURI(t *testing.T) { + s := stubServer() + client := ð.MockClient{} + serviceURI := "https://8.8.8.8:8935" + + t.Run("Valid Service URI", func(t *testing.T) { + client.On("SetServiceURI", serviceURI).Return(ðtypes.Transaction{}, nil) + client.On("CheckTx", mock.Anything).Return(nil) + + err := s.setServiceURI(client, serviceURI) + + assert.NoError(t, err) + }) + t.Run("Invalid Service URI", func(t *testing.T) { + invalidServiceURI := "https://0.0.0.0:8935" + + err := s.setServiceURI(client, invalidServiceURI) + + assert.Error(t, err) + }) + +} func dummyHandler() http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) diff --git a/server/mediaserver.go b/server/mediaserver.go index e24bf1edbe..975aef7fb2 100644 --- a/server/mediaserver.go +++ b/server/mediaserver.go @@ -989,7 +989,7 @@ func (s *LivepeerServer) HandlePush(w http.ResponseWriter, r *http.Request) { cxn.mu.Lock() if cxn.mediaFormat == (ffmpeg.MediaFormatInfo{}) { cxn.mediaFormat = mediaFormat - } else if cxn.mediaFormat != mediaFormat { + } else if !mediaCompatible(cxn.mediaFormat, mediaFormat) { cxn.mediaFormat = mediaFormat segPar.ForceSessionReinit = true } @@ -1649,3 +1649,15 @@ func getRemoteAddr(r *http.Request) string { } return strings.Split(addr, ":")[0] } + +func mediaCompatible(a, b ffmpeg.MediaFormatInfo) bool { + return a.Acodec == b.Acodec && + a.Vcodec == b.Vcodec && + a.PixFormat == b.PixFormat && + a.Width == b.Width && + a.Height == b.Height + + // NB: there is also a Format field but that does + // not need to match since transcoder will reopen + // a new demuxer each time +} diff --git a/server/mediaserver_test.go b/server/mediaserver_test.go index 595c4e29ab..09f4f53370 100644 --- a/server/mediaserver_test.go +++ b/server/mediaserver_test.go @@ -115,31 +115,6 @@ func setupServerWithCancel() (*LivepeerServer, context.CancelFunc) { return S, cancel } -func setupServerWithCancelAndPorts() (*LivepeerServer, context.CancelFunc) { - drivers.NodeStorage = drivers.NewMemoryDriver(nil) - ctx, cancel := context.WithCancel(context.Background()) - var S *LivepeerServer - if S == nil { - httpPushResetTimer = func() (context.Context, context.CancelFunc) { - ctx, cancel := context.WithCancel(context.Background()) - pushResetWg.Add(1) - wrapCancel := func() { - cancel() - pushResetWg.Done() - } - return ctx, wrapCancel - } - n, _ := core.NewLivepeerNode(nil, "./tmp", nil) - S, _ = NewLivepeerServer("127.0.0.1:2938", n, true, "") - go S.StartMediaServer(ctx, "127.0.0.1:9080") - go func() { - srv := &http.Server{Addr: "127.0.0.1:9938"} - S.StartCliWebserver(srv) - }() - } - return S, cancel -} - // since we have test that checks that there is no goroutine // left running after using RTMP connection - we have to properly // close connections in all the tests that are using them @@ -171,6 +146,8 @@ func (d *stubDiscovery) GetInfos() []common.OrchestratorLocalInfo { return nil } +var cleanupSessions = func(sessionID string) {} + func (d *stubDiscovery) GetOrchestrators(ctx context.Context, num int, sus common.Suspender, caps common.CapabilityComparator, scorePred common.ScorePred) (common.OrchestratorDescriptors, error) { @@ -237,14 +214,14 @@ func TestSelectOrchestrator(t *testing.T) { mid := core.RandomManifestID() storage := drivers.NodeStorage.NewSession(string(mid)) sp := &core.StreamParameters{ManifestID: mid, Profiles: []ffmpeg.VideoProfile{ffmpeg.P360p30fps16x9}, OS: storage} - if _, err := selectOrchestrator(context.TODO(), s.LivepeerNode, sp, 4, newSuspender(), common.ScoreAtLeast(0)); err != errDiscovery { + if _, err := selectOrchestrator(context.TODO(), s.LivepeerNode, sp, 4, newSuspender(), common.ScoreAtLeast(0), cleanupSessions); err != errDiscovery { t.Error("Expected error with discovery") } sd := &stubDiscovery{} // Discovery returned no orchestrators s.LivepeerNode.OrchestratorPool = sd - if sess, err := selectOrchestrator(context.TODO(), s.LivepeerNode, sp, 4, newSuspender(), common.ScoreAtLeast(0)); sess != nil || err != errNoOrchs { + if sess, err := selectOrchestrator(context.TODO(), s.LivepeerNode, sp, 4, newSuspender(), common.ScoreAtLeast(0), cleanupSessions); sess != nil || err != errNoOrchs { t.Error("Expected nil session") } @@ -255,7 +232,7 @@ func TestSelectOrchestrator(t *testing.T) { {PriceInfo: &net.PriceInfo{PricePerUnit: 1, PixelsPerUnit: 1}, TicketParams: &net.TicketParams{}, AuthToken: authToken0}, {PriceInfo: &net.PriceInfo{PricePerUnit: 1, PixelsPerUnit: 1}, TicketParams: &net.TicketParams{}, AuthToken: authToken1}, } - sess, _ := selectOrchestrator(context.TODO(), s.LivepeerNode, sp, 4, newSuspender(), common.ScoreAtLeast(0)) + sess, _ := selectOrchestrator(context.TODO(), s.LivepeerNode, sp, 4, newSuspender(), common.ScoreAtLeast(0), cleanupSessions) if len(sess) != len(sd.infos) { t.Error("Expected session length of 2") @@ -290,7 +267,7 @@ func TestSelectOrchestrator(t *testing.T) { externalStorage := drivers.NodeStorage.NewSession(string(mid)) sp.OS = externalStorage - sess, err := selectOrchestrator(context.TODO(), s.LivepeerNode, sp, 4, newSuspender(), common.ScoreAtLeast(0)) + sess, err := selectOrchestrator(context.TODO(), s.LivepeerNode, sp, 4, newSuspender(), common.ScoreAtLeast(0), cleanupSessions) assert.Nil(err) // B should initialize new OS session using auth token sessionID @@ -378,7 +355,7 @@ func TestSelectOrchestrator(t *testing.T) { expSessionID2 := "bar" sender.On("StartSession", mock.Anything).Return(expSessionID2).Once() - sess, err = selectOrchestrator(context.TODO(), s.LivepeerNode, sp, 4, newSuspender(), common.ScoreAtLeast(0)) + sess, err = selectOrchestrator(context.TODO(), s.LivepeerNode, sp, 4, newSuspender(), common.ScoreAtLeast(0), cleanupSessions) require.Nil(err) assert.Len(sess, 2) @@ -407,7 +384,7 @@ func TestSelectOrchestrator(t *testing.T) { // Skip orchestrator if missing auth token sd.infos[0].AuthToken = nil - sess, err = selectOrchestrator(context.TODO(), s.LivepeerNode, sp, 4, newSuspender(), func(float32) bool { return true }) + sess, err = selectOrchestrator(context.TODO(), s.LivepeerNode, sp, 4, newSuspender(), func(float32) bool { return true }, cleanupSessions) require.Nil(err) assert.Len(sess, 1) @@ -417,7 +394,7 @@ func TestSelectOrchestrator(t *testing.T) { sd.infos[0].AuthToken = &net.AuthToken{} sd.infos[0].TicketParams = nil - sess, err = selectOrchestrator(context.TODO(), s.LivepeerNode, sp, 4, newSuspender(), func(float32) bool { return true }) + sess, err = selectOrchestrator(context.TODO(), s.LivepeerNode, sp, 4, newSuspender(), func(float32) bool { return true }, cleanupSessions) require.Nil(err) assert.Len(sess, 1) @@ -1494,6 +1471,101 @@ func TestJsonProfileToVideoProfiles(t *testing.T) { assert.Equal("unable to parse the H264 encoder profile: unknown VideoProfile profile name", err.Error()) } +func TestMediaCompatible(t *testing.T) { + empty := ffmpeg.MediaFormatInfo{} + normal := ffmpeg.MediaFormatInfo{ + Acodec: "aac", + Vcodec: "h264", + PixFormat: ffmpeg.PixelFormat{RawValue: ffmpeg.PixelFormatNV12}, + Format: "mpegts", + Width: 100, + Height: 200, + AudioBitrate: 300, + DurSecs: 5, + } + tests := []struct { + name string + a ffmpeg.MediaFormatInfo + b ffmpeg.MediaFormatInfo + match bool + }{{ + name: "empty", + a: empty, + match: true, + }, { + name: "normal", + match: true, + a: normal, + b: ffmpeg.MediaFormatInfo{ + Format: "mp4", + DurSecs: 10, + AudioBitrate: 400, + Acodec: normal.Acodec, + Vcodec: normal.Vcodec, + PixFormat: normal.PixFormat, + Width: normal.Width, + Height: normal.Height, + }, + }, { + name: "w", + a: normal, + b: ffmpeg.MediaFormatInfo{ + Width: normal.Width + 1, + Acodec: normal.Acodec, + Vcodec: normal.Vcodec, + PixFormat: normal.PixFormat, + Height: normal.Height, + }, + }, { + name: "h", + a: normal, + b: ffmpeg.MediaFormatInfo{ + Height: normal.Height + 1, + Acodec: normal.Acodec, + Vcodec: normal.Vcodec, + PixFormat: normal.PixFormat, + Width: normal.Width, + }, + }, { + name: "pixfmt", + a: normal, + b: ffmpeg.MediaFormatInfo{ + Width: normal.Width, + Acodec: normal.Acodec, + Vcodec: normal.Vcodec, + PixFormat: ffmpeg.PixelFormat{RawValue: ffmpeg.PixelFormatYUV420P}, + Height: normal.Height, + }, + }, { + name: "video codec", + a: normal, + b: ffmpeg.MediaFormatInfo{ + Vcodec: "flv", + Acodec: normal.Acodec, + Format: normal.Format, + PixFormat: normal.PixFormat, + Width: normal.Width, + Height: normal.Height, + }, + }, { + name: "audio codec", + a: normal, + b: ffmpeg.MediaFormatInfo{ + Acodec: "opus", + Vcodec: normal.Vcodec, + Format: normal.Format, + PixFormat: normal.PixFormat, + Width: normal.Width, + Height: normal.Height, + }, + }} + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + assert.Equal(t, tt.match, mediaCompatible(tt.a, tt.b)) + }) + } +} + func mustParseUrl(t *testing.T, str string) *url.URL { url, err := url.Parse(str) if err != nil { diff --git a/server/ot_rpc.go b/server/ot_rpc.go index a4ceb8045d..62502ce256 100644 --- a/server/ot_rpc.go +++ b/server/ot_rpc.go @@ -190,6 +190,7 @@ func runTranscode(n *core.LivepeerNode, orchAddr string, httpc *http.Client, not } defer os.Remove(fname) md.Fname = fname + md.Metadata = core.MakeMetadata(notify.OrchId) clog.V(common.DEBUG).Infof(ctx, "Segment from taskId=%d url=%s saved to file=%s", notify.TaskId, notify.Url, fname) start := time.Now() diff --git a/server/rpc.go b/server/rpc.go index 097c61e709..6c5d24637c 100644 --- a/server/rpc.go +++ b/server/rpc.go @@ -117,6 +117,7 @@ type BroadcastSession struct { OrchestratorInfo *net.OrchestratorInfo OrchestratorOS drivers.OSSession PMSessionID string + CleanupSession sessionsCleanup Balance Balance InitialPrice *net.PriceInfo } diff --git a/server/selection.go b/server/selection.go index c827034db6..985f2d2546 100644 --- a/server/selection.go +++ b/server/selection.go @@ -135,12 +135,15 @@ func (s *MinLSSelector) Select(ctx context.Context) *BroadcastSession { return s.selectUnknownSession(ctx) } - minSess := sess.(*BroadcastSession) - if minSess.LatencyScore > s.minLS && len(s.unknownSessions) > 0 { - 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 } - return heap.Pop(s.knownSessions).(*BroadcastSession) + // known session does not have good enough latency score, clear the heap and use unknown session + s.knownSessions = &sessHeap{} + return s.selectUnknownSession(ctx) } // Size returns the number of sessions stored by the selector diff --git a/server/selection_algorithm.go b/server/selection_algorithm.go index 050b459283..8ea304002b 100644 --- a/server/selection_algorithm.go +++ b/server/selection_algorithm.go @@ -20,7 +20,8 @@ type ProbabilitySelectionAlgorithm struct { PriceWeight float64 RandWeight float64 - PriceExpFactor float64 + PriceExpFactor float64 + IgnoreMaxPriceIfNeeded bool } func (sa ProbabilitySelectionAlgorithm) Select(ctx context.Context, addrs []ethcommon.Address, stakes map[ethcommon.Address]int64, maxPrice *big.Rat, prices map[ethcommon.Address]*big.Rat, perfScores map[ethcommon.Address]float64) ethcommon.Address { @@ -70,7 +71,7 @@ func (sa ProbabilitySelectionAlgorithm) filterByMaxPrice(ctx context.Context, ad } } - if len(res) == 0 { + if len(res) == 0 && sa.IgnoreMaxPriceIfNeeded { // If no orchestrators pass the filter, return all Orchestrators // It means that no orchestrators are below the max price clog.Warningf(ctx, "No Orchestrators passed max price filter, not using the filter, numAddrs=%d, maxPrice=%v, prices=%v, addrs=%v", len(addrs), maxPrice, prices, addrs) diff --git a/server/selection_algorithm_test.go b/server/selection_algorithm_test.go index ffae12de39..61b966b42e 100644 --- a/server/selection_algorithm_test.go +++ b/server/selection_algorithm_test.go @@ -13,13 +13,14 @@ const testPriceExpFactor = 100 func TestFilter(t *testing.T) { tests := []struct { - name string - orchMinPerfScore float64 - maxPrice float64 - prices map[string]float64 - orchPerfScores map[string]float64 - orchestrators []string - want []string + name string + orchMinPerfScore float64 + maxPrice float64 + prices map[string]float64 + orchPerfScores map[string]float64 + orchestrators []string + want []string + ignoreMaxPriceIfNeeded bool }{ { name: "Some Orchestrators pass the filter", @@ -91,7 +92,7 @@ func TestFilter(t *testing.T) { }, }, { - name: "All prices below max price", + orchMinPerfScore: 0.7, maxPrice: 2000, prices: map[string]float64{ @@ -115,9 +116,10 @@ func TestFilter(t *testing.T) { }, }, { - name: "All prices above max price", - orchMinPerfScore: 0.7, - maxPrice: 100, + name: "All prices above max price and ignoreMaxPriceIfNeeded enabled", + orchMinPerfScore: 0.7, + maxPrice: 100, + ignoreMaxPriceIfNeeded: true, prices: map[string]float64{ "0x0000000000000000000000000000000000000001": 500, "0x0000000000000000000000000000000000000002": 1500, @@ -138,6 +140,27 @@ func TestFilter(t *testing.T) { "0x0000000000000000000000000000000000000003", }, }, + { + name: "All prices below max price", + orchMinPerfScore: 0.7, + maxPrice: 100, + prices: map[string]float64{ + "0x0000000000000000000000000000000000000001": 500, + "0x0000000000000000000000000000000000000002": 1500, + "0x0000000000000000000000000000000000000003": 1000, + }, + orchPerfScores: map[string]float64{ + "0x0000000000000000000000000000000000000001": 0.6, + "0x0000000000000000000000000000000000000002": 0.8, + "0x0000000000000000000000000000000000000003": 0.9, + }, + orchestrators: []string{ + "0x0000000000000000000000000000000000000001", + "0x0000000000000000000000000000000000000002", + "0x0000000000000000000000000000000000000003", + }, + want: []string{}, + }, { name: "Mix of prices relative to max price", orchMinPerfScore: 0.7, @@ -206,7 +229,8 @@ func TestFilter(t *testing.T) { maxPrice = new(big.Rat).SetFloat64(tt.maxPrice) } sa := &ProbabilitySelectionAlgorithm{ - MinPerfScore: tt.orchMinPerfScore, + MinPerfScore: tt.orchMinPerfScore, + IgnoreMaxPriceIfNeeded: tt.ignoreMaxPriceIfNeeded, } res := sa.filter(context.Background(), addrs, maxPrice, prices, perfScores) diff --git a/server/selection_test.go b/server/selection_test.go index aa936ddb04..9699bb7af5 100644 --- a/server/selection_test.go +++ b/server/selection_test.go @@ -183,48 +183,39 @@ func TestMinLSSelector(t *testing.T) { assert.Equal(sel.Size(), 2) assert.Equal(len(sel.unknownSessions), 2) - // Set sess1.LatencyScore to not be good enough - sess1.LatencyScore = 1.1 + // Set sess1.LatencyScore to good enough + sess1.LatencyScore = 0.9 sel.Complete(sess1) assert.Equal(sel.Size(), 3) assert.Equal(len(sel.unknownSessions), 2) assert.Equal(sel.knownSessions.Len(), 1) - // Select from unknownSessions - sess2 := sel.Select(context.TODO()) + // Select sess1 because it's a known session with good enough latency score + sess := sel.Select(context.TODO()) assert.Equal(sel.Size(), 2) - assert.Equal(len(sel.unknownSessions), 1) - assert.Equal(sel.knownSessions.Len(), 1) + assert.Equal(len(sel.unknownSessions), 2) + assert.Equal(sel.knownSessions.Len(), 0) - // Set sess2.LatencyScore to be good enough - sess2.LatencyScore = .9 - sel.Complete(sess2) + // Set sess.LatencyScore to not be good enough + sess.LatencyScore = 1.1 + sel.Complete(sess) assert.Equal(sel.Size(), 3) - assert.Equal(len(sel.unknownSessions), 1) - assert.Equal(sel.knownSessions.Len(), 2) + assert.Equal(len(sel.unknownSessions), 2) + assert.Equal(sel.knownSessions.Len(), 1) - // Select from knownSessions - knownSess := sel.Select(context.TODO()) + // 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) assert.Equal(sel.Size(), 2) assert.Equal(len(sel.unknownSessions), 1) assert.Equal(sel.knownSessions.Len(), 1) - assert.Equal(knownSess, sess2) - // 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) + // Select the last unknown session + sess = sel.Select(context.TODO()) + assert.Equal(sel.Size(), 0) assert.Equal(len(sel.unknownSessions), 0) - assert.Equal(sel.knownSessions.Len(), 2) + assert.Equal(sel.knownSessions.Len(), 0) sel.Clear() assert.Zero(sel.Size()) diff --git a/server/sessionpool_test.go b/server/sessionpool_test.go index 49a9f4f44b..832f7016d3 100644 --- a/server/sessionpool_test.go +++ b/server/sessionpool_test.go @@ -51,7 +51,8 @@ func poolWithSessList(sessList []*BroadcastSession) *sessionPoolLIFO { // return sessList, nil return nil, nil } - pool := NewSessionPool("test", len(sessList), 1, newSuspender(), createSessions, sel) + var deleteSessions = func(sessionID string) {} + pool := NewSessionPool("test", len(sessList), 1, newSuspender(), createSessions, deleteSessions, sel) pool.sessMap = sessMap return newSessionPoolLIFO(pool) } diff --git a/upload_build.sh b/upload_build.sh deleted file mode 100755 index 891dbd1042..0000000000 --- a/upload_build.sh +++ /dev/null @@ -1,136 +0,0 @@ -#!/bin/bash - -# CI script for uploading builds. - -set -e -set -o nounset - -BASE_DIR="$(realpath $(dirname "$0"))" - -cd "$BASE_DIR" -RELEASES_DIR="${BASE_DIR}/${RELEASES_DIR:-releases}/" - -mkdir -p "$RELEASES_DIR" - -if [[ "${GOOS:-}" != "" ]]; then - PLATFORM="$GOOS" -elif [[ $(uname) == *"MSYS"* ]]; then - PLATFORM="windows" -else - PLATFORM=$(uname | tr '[:upper:]' '[:lower:]') -fi - -EXT="" -if [[ "$PLATFORM" == "windows" ]]; then - EXT=".exe" -fi -if [[ "$PLATFORM" != "linux" ]] && [[ "$PLATFORM" != "darwin" ]] && [[ "$PLATFORM" != "windows" ]]; then - echo "Unknown/unsupported platform: $PLATFORM" - exit 1 -fi - -if [[ -n "${RELEASE_TAG:-}" ]]; then - PLATFORM="$PLATFORM-$RELEASE_TAG" -fi - -ARCH="$(uname -m)" - -if [[ "${GOARCH:-}" != "" ]]; then - ARCH="$GOARCH" -fi -if [[ "$ARCH" == "x86_64" ]]; then - ARCH="amd64" -fi -if [[ "$ARCH" == "aarch64" ]]; then - ARCH="arm64" -fi -if [[ "$ARCH" != "amd64" ]] && [[ "$ARCH" != "arm64" ]]; then - echo "Unknown/unsupported architecture: $ARCH" - exit 1 -fi - -BASE="livepeer-$PLATFORM-$ARCH" -BRANCH="${TRAVIS_BRANCH:-unknown}" -if [[ "${GHA_REF:-}" != "" ]]; then - BRANCH="$(echo $GHA_REF | sed 's:refs/heads/::')" -fi -VERSION="$(./print_version.sh)" -if echo $VERSION | grep dirty; then - echo "Error: git state dirty, refusing to upload build" - git diff | cat - git status - exit 1 -fi - -# If we want to build with branch --> network support for any other networks, add them here! -NETWORK_BRANCHES="rinkeby mainnet" -# If the binaries are built off a network branch then the resource path should include the network branch name i.e. X.Y.Z/rinkeby or X.Y.Z/mainnet -# If the binaries are not built off a network then the resource path should only include the version i.e. X.Y.Z -VERSION_AND_NETWORK=$VERSION -for networkBranch in $NETWORK_BRANCHES; do - if [[ $BRANCH == "$networkBranch" ]]; then - VERSION_AND_NETWORK="$VERSION/$BRANCH" - fi -done - -NODE="./livepeer${EXT}" -CLI="./livepeer_cli${EXT}" -BENCH="./livepeer_bench${EXT}" -ROUTER="./livepeer_router${EXT}" - -mkdir -p "${BASE_DIR}/$BASE" - -# Optionally step into build directory, if set anywhere -cd "${GO_BUILD_DIR:-./}" -cp "$NODE" "$CLI" "$BENCH" "$ROUTER" "${BASE_DIR}/$BASE" -cd - - -# do a basic upload so we know if stuff's working prior to doing everything else -if [[ $PLATFORM == "windows" ]]; then - FILE="$BASE.zip" - zip -r "${RELEASES_DIR}/$FILE" ./$BASE -else - FILE="$BASE.tar.gz" - tar -czvf "${RELEASES_DIR}/$FILE" ./$BASE -fi - -cd "$RELEASES_DIR" - -FILE_SHA256=$(shasum -a 256 ${FILE}) - -if [[ "${GCLOUD_KEY:-}" == "" ]]; then - echo "GCLOUD_KEY not found, not uploading to Google Cloud." - exit 0 -fi - -# https://stackoverflow.com/a/44751929/990590 -BUCKET="build.livepeer.live" -PROJECT="go-livepeer" -BUCKET_PATH="${PROJECT}/${VERSION_AND_NETWORK}/${FILE}" -resource="/${BUCKET}/${BUCKET_PATH}" -contentType="application/x-compressed-tar" -dateValue="$(date -R)" -stringToSign="PUT\n\n${contentType}\n${dateValue}\n${resource}" -signature="$(echo -en ${stringToSign} | openssl sha1 -hmac ${GCLOUD_SECRET} -binary | base64)" -fullUrl="https://storage.googleapis.com${resource}" - -# Failsafe - don't overwrite existing uploads! -if curl --head --fail $fullUrl 2>/dev/null; then - echo "$fullUrl already exists, not overwriting!" - exit 0 -fi - -curl -X PUT -T "${FILE}" \ - -H "Host: storage.googleapis.com" \ - -H "Date: ${dateValue}" \ - -H "Content-Type: ${contentType}" \ - -H "Authorization: AWS ${GCLOUD_KEY}:${signature}" \ - $fullUrl - -echo "upload done" - -curl -X POST --fail -s \ - -H "Content-Type: application/json" \ - -d "{\"content\": \"Build succeeded ✅\nBranch: $BRANCH\nPlatform: $PLATFORM-$ARCH\nLast commit: $(git log -1 --pretty=format:'%s by %an')\nhttps://build.livepeer.live/${BUCKET_PATH}\nSHA256:\n${FILE_SHA256}\"}" \ - $DISCORD_URL -echo "done" diff --git a/verification/verify_test.go b/verification/verify_test.go index 18b8e055f1..c815e175ba 100644 --- a/verification/verify_test.go +++ b/verification/verify_test.go @@ -310,8 +310,7 @@ func TestPixels(t *testing.T) { p, err := pixels("foo") // Early codec check didn't find video in missing input file so - // we get `TranscoderInvalidVideo` err instead of `No such file or directory` - assert.EqualError(err, "TranscoderInvalidVideo") + assert.EqualError(err, "No such file or directory") assert.Equal(int64(0), p) // Assume that ffmpeg.Transcode3() returns the correct pixel count so we just