From ef5d78922e08d8b815814df419d03e0561c1e974 Mon Sep 17 00:00:00 2001 From: Victor Elias Date: Wed, 27 Mar 2024 15:57:51 -0300 Subject: [PATCH 01/88] eth,eth/watcher: Create Chainlink price feed watcher (#2972) * eth/watchers: Create PriceFeed watcher Makefile: Use mockgen binary from tool dependencies eth/contracts: Add chainlink interfaces source Makefile: Generate Chainlink contracts ABI tools: Add abigen tool to repo eth/contracts: Generate chainlink bindings Makefile: Fix abigen bindings generation Revert everything abigen Turns out there's already bindings exported from the Chainlink lib. go.mod: Add chainlink library eth/watchers: Add pricefeed watcher eth/watchers: Clean-up event watching code eth/watchers: Improve price tracking Revert "go.mod: Add chainlink library" This reverts commit ac415bd8fb210088874e7fdea8d37ac4dad81dab. Revert "Revert everything abigen" This reverts commit b7c40b1e936c885aad973f28d87d42b0d85cb0e4. eth/contracts: Gen bindings for proxy iface eth/watchers: Use local bindings for contracts eth/watchers: Simplify event subs logic eth/watchers: Simplify&optimize truncated ticker eth/watchers: Update decimals on fetch eth/watchers: Improve handling of decimals eth/watchers: Fix price rat creation eth/watchers: Make sure we use UTC on truncated timer eth/contracts/chainlink: Generate only V3 contract bindings eth/watchers: Watch PriceFeed only with polling eth/watchers: Add a retry logic on price update eth/watchers: Use clog instead of fmt.Printf * eth: Create separate pricefeed client unit This will make the code more testable. * eth: Add tests for pricefeed client * eth/watchers: Add tests to the truncated ticker Gosh that was much harder than I thought * eth/watchers: Add tests for pricefeedwatcher * eth: Add comments to the new components * go fmt * eth: Address minor review comments * eth,eth/watchers: Improve pricefeed watcher interface * eth/watchers: Remove truncated ticker tests --- Makefile | 18 +- .../chainlink/AggregatorV3Interface.abi | 1 + .../chainlink/AggregatorV3Interface.go | 394 ++++++++++++++++++ .../chainlink/AggregatorV3Interface.sol | 36 ++ eth/pricefeed.go | 78 ++++ eth/pricefeed_test.go | 51 +++ eth/watchers/pricefeedwatcher.go | 182 ++++++++ eth/watchers/pricefeedwatcher_test.go | 216 ++++++++++ go.mod | 36 +- go.sum | 225 +++++++++- tools.go | 9 + 11 files changed, 1240 insertions(+), 6 deletions(-) create mode 100644 eth/contracts/chainlink/AggregatorV3Interface.abi create mode 100644 eth/contracts/chainlink/AggregatorV3Interface.go create mode 100644 eth/contracts/chainlink/AggregatorV3Interface.sol create mode 100644 eth/pricefeed.go create mode 100644 eth/pricefeed_test.go create mode 100644 eth/watchers/pricefeedwatcher.go create mode 100644 eth/watchers/pricefeedwatcher_test.go create mode 100644 tools.go diff --git a/Makefile b/Makefile index db8026968a..d57d7ffc96 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,10 @@ SHELL=/bin/bash GO_BUILD_DIR?="./" -all: net/lp_rpc.pb.go net/redeemer.pb.go net/redeemer_mock.pb.go core/test_segment.go livepeer livepeer_cli livepeer_router livepeer_bench +MOCKGEN=go run github.com/golang/mock/mockgen +ABIGEN=go run github.com/ethereum/go-ethereum/cmd/abigen + +all: net/lp_rpc.pb.go net/redeemer.pb.go net/redeemer_mock.pb.go core/test_segment.go eth/contracts/chainlink/AggregatorV3Interface.go livepeer livepeer_cli livepeer_router livepeer_bench net/lp_rpc.pb.go: net/lp_rpc.proto protoc -I=. --go_out=. --go-grpc_out=. $^ @@ -10,12 +13,21 @@ net/redeemer.pb.go: net/redeemer.proto protoc -I=. --go_out=. --go-grpc_out=. $^ net/redeemer_mock.pb.go net/redeemer_grpc_mock.pb.go: net/redeemer.pb.go net/redeemer_grpc.pb.go - @mockgen -source net/redeemer.pb.go -destination net/redeemer_mock.pb.go -package net - @mockgen -source net/redeemer_grpc.pb.go -destination net/redeemer_grpc_mock.pb.go -package net + @$(MOCKGEN) -source net/redeemer.pb.go -destination net/redeemer_mock.pb.go -package net + @$(MOCKGEN) -source net/redeemer_grpc.pb.go -destination net/redeemer_grpc_mock.pb.go -package net core/test_segment.go: core/test_segment.sh core/test_segment.go +eth/contracts/chainlink/AggregatorV3Interface.go: + solc --version | grep 0.7.6+commit.7338295f + @set -ex; \ + for sol_file in eth/contracts/chainlink/*.sol; do \ + contract_name=$$(basename "$$sol_file" .sol); \ + solc --abi --optimize --overwrite -o $$(dirname "$$sol_file") $$sol_file; \ + $(ABIGEN) --abi=$${sol_file%.sol}.abi --pkg=chainlink --type=$$contract_name --out=$${sol_file%.sol}.go; \ + done + version=$(shell cat VERSION) ldflags := -X github.com/livepeer/go-livepeer/core.LivepeerVersion=$(shell ./print_version.sh) diff --git a/eth/contracts/chainlink/AggregatorV3Interface.abi b/eth/contracts/chainlink/AggregatorV3Interface.abi new file mode 100644 index 0000000000..106c4a7bcb --- /dev/null +++ b/eth/contracts/chainlink/AggregatorV3Interface.abi @@ -0,0 +1 @@ +[{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"description","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint80","name":"_roundId","type":"uint80"}],"name":"getRoundData","outputs":[{"internalType":"uint80","name":"roundId","type":"uint80"},{"internalType":"int256","name":"answer","type":"int256"},{"internalType":"uint256","name":"startedAt","type":"uint256"},{"internalType":"uint256","name":"updatedAt","type":"uint256"},{"internalType":"uint80","name":"answeredInRound","type":"uint80"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"latestRoundData","outputs":[{"internalType":"uint80","name":"roundId","type":"uint80"},{"internalType":"int256","name":"answer","type":"int256"},{"internalType":"uint256","name":"startedAt","type":"uint256"},{"internalType":"uint256","name":"updatedAt","type":"uint256"},{"internalType":"uint80","name":"answeredInRound","type":"uint80"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"version","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}] diff --git a/eth/contracts/chainlink/AggregatorV3Interface.go b/eth/contracts/chainlink/AggregatorV3Interface.go new file mode 100644 index 0000000000..2b0c1c9587 --- /dev/null +++ b/eth/contracts/chainlink/AggregatorV3Interface.go @@ -0,0 +1,394 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package chainlink + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// AggregatorV3InterfaceMetaData contains all meta data concerning the AggregatorV3Interface contract. +var AggregatorV3InterfaceMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"description\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint80\",\"name\":\"_roundId\",\"type\":\"uint80\"}],\"name\":\"getRoundData\",\"outputs\":[{\"internalType\":\"uint80\",\"name\":\"roundId\",\"type\":\"uint80\"},{\"internalType\":\"int256\",\"name\":\"answer\",\"type\":\"int256\"},{\"internalType\":\"uint256\",\"name\":\"startedAt\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"updatedAt\",\"type\":\"uint256\"},{\"internalType\":\"uint80\",\"name\":\"answeredInRound\",\"type\":\"uint80\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestRoundData\",\"outputs\":[{\"internalType\":\"uint80\",\"name\":\"roundId\",\"type\":\"uint80\"},{\"internalType\":\"int256\",\"name\":\"answer\",\"type\":\"int256\"},{\"internalType\":\"uint256\",\"name\":\"startedAt\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"updatedAt\",\"type\":\"uint256\"},{\"internalType\":\"uint80\",\"name\":\"answeredInRound\",\"type\":\"uint80\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", +} + +// AggregatorV3InterfaceABI is the input ABI used to generate the binding from. +// Deprecated: Use AggregatorV3InterfaceMetaData.ABI instead. +var AggregatorV3InterfaceABI = AggregatorV3InterfaceMetaData.ABI + +// AggregatorV3Interface is an auto generated Go binding around an Ethereum contract. +type AggregatorV3Interface struct { + AggregatorV3InterfaceCaller // Read-only binding to the contract + AggregatorV3InterfaceTransactor // Write-only binding to the contract + AggregatorV3InterfaceFilterer // Log filterer for contract events +} + +// AggregatorV3InterfaceCaller is an auto generated read-only Go binding around an Ethereum contract. +type AggregatorV3InterfaceCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// AggregatorV3InterfaceTransactor is an auto generated write-only Go binding around an Ethereum contract. +type AggregatorV3InterfaceTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// AggregatorV3InterfaceFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type AggregatorV3InterfaceFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// AggregatorV3InterfaceSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type AggregatorV3InterfaceSession struct { + Contract *AggregatorV3Interface // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// AggregatorV3InterfaceCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type AggregatorV3InterfaceCallerSession struct { + Contract *AggregatorV3InterfaceCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// AggregatorV3InterfaceTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type AggregatorV3InterfaceTransactorSession struct { + Contract *AggregatorV3InterfaceTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// AggregatorV3InterfaceRaw is an auto generated low-level Go binding around an Ethereum contract. +type AggregatorV3InterfaceRaw struct { + Contract *AggregatorV3Interface // Generic contract binding to access the raw methods on +} + +// AggregatorV3InterfaceCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type AggregatorV3InterfaceCallerRaw struct { + Contract *AggregatorV3InterfaceCaller // Generic read-only contract binding to access the raw methods on +} + +// AggregatorV3InterfaceTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type AggregatorV3InterfaceTransactorRaw struct { + Contract *AggregatorV3InterfaceTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewAggregatorV3Interface creates a new instance of AggregatorV3Interface, bound to a specific deployed contract. +func NewAggregatorV3Interface(address common.Address, backend bind.ContractBackend) (*AggregatorV3Interface, error) { + contract, err := bindAggregatorV3Interface(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &AggregatorV3Interface{AggregatorV3InterfaceCaller: AggregatorV3InterfaceCaller{contract: contract}, AggregatorV3InterfaceTransactor: AggregatorV3InterfaceTransactor{contract: contract}, AggregatorV3InterfaceFilterer: AggregatorV3InterfaceFilterer{contract: contract}}, nil +} + +// NewAggregatorV3InterfaceCaller creates a new read-only instance of AggregatorV3Interface, bound to a specific deployed contract. +func NewAggregatorV3InterfaceCaller(address common.Address, caller bind.ContractCaller) (*AggregatorV3InterfaceCaller, error) { + contract, err := bindAggregatorV3Interface(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &AggregatorV3InterfaceCaller{contract: contract}, nil +} + +// NewAggregatorV3InterfaceTransactor creates a new write-only instance of AggregatorV3Interface, bound to a specific deployed contract. +func NewAggregatorV3InterfaceTransactor(address common.Address, transactor bind.ContractTransactor) (*AggregatorV3InterfaceTransactor, error) { + contract, err := bindAggregatorV3Interface(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &AggregatorV3InterfaceTransactor{contract: contract}, nil +} + +// NewAggregatorV3InterfaceFilterer creates a new log filterer instance of AggregatorV3Interface, bound to a specific deployed contract. +func NewAggregatorV3InterfaceFilterer(address common.Address, filterer bind.ContractFilterer) (*AggregatorV3InterfaceFilterer, error) { + contract, err := bindAggregatorV3Interface(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &AggregatorV3InterfaceFilterer{contract: contract}, nil +} + +// bindAggregatorV3Interface binds a generic wrapper to an already deployed contract. +func bindAggregatorV3Interface(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := AggregatorV3InterfaceMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_AggregatorV3Interface *AggregatorV3InterfaceRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _AggregatorV3Interface.Contract.AggregatorV3InterfaceCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_AggregatorV3Interface *AggregatorV3InterfaceRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _AggregatorV3Interface.Contract.AggregatorV3InterfaceTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_AggregatorV3Interface *AggregatorV3InterfaceRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _AggregatorV3Interface.Contract.AggregatorV3InterfaceTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_AggregatorV3Interface *AggregatorV3InterfaceCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _AggregatorV3Interface.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_AggregatorV3Interface *AggregatorV3InterfaceTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _AggregatorV3Interface.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_AggregatorV3Interface *AggregatorV3InterfaceTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _AggregatorV3Interface.Contract.contract.Transact(opts, method, params...) +} + +// Decimals is a free data retrieval call binding the contract method 0x313ce567. +// +// Solidity: function decimals() view returns(uint8) +func (_AggregatorV3Interface *AggregatorV3InterfaceCaller) Decimals(opts *bind.CallOpts) (uint8, error) { + var out []interface{} + err := _AggregatorV3Interface.contract.Call(opts, &out, "decimals") + + if err != nil { + return *new(uint8), err + } + + out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + + return out0, err + +} + +// Decimals is a free data retrieval call binding the contract method 0x313ce567. +// +// Solidity: function decimals() view returns(uint8) +func (_AggregatorV3Interface *AggregatorV3InterfaceSession) Decimals() (uint8, error) { + return _AggregatorV3Interface.Contract.Decimals(&_AggregatorV3Interface.CallOpts) +} + +// Decimals is a free data retrieval call binding the contract method 0x313ce567. +// +// Solidity: function decimals() view returns(uint8) +func (_AggregatorV3Interface *AggregatorV3InterfaceCallerSession) Decimals() (uint8, error) { + return _AggregatorV3Interface.Contract.Decimals(&_AggregatorV3Interface.CallOpts) +} + +// Description is a free data retrieval call binding the contract method 0x7284e416. +// +// Solidity: function description() view returns(string) +func (_AggregatorV3Interface *AggregatorV3InterfaceCaller) Description(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _AggregatorV3Interface.contract.Call(opts, &out, "description") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +// Description is a free data retrieval call binding the contract method 0x7284e416. +// +// Solidity: function description() view returns(string) +func (_AggregatorV3Interface *AggregatorV3InterfaceSession) Description() (string, error) { + return _AggregatorV3Interface.Contract.Description(&_AggregatorV3Interface.CallOpts) +} + +// Description is a free data retrieval call binding the contract method 0x7284e416. +// +// Solidity: function description() view returns(string) +func (_AggregatorV3Interface *AggregatorV3InterfaceCallerSession) Description() (string, error) { + return _AggregatorV3Interface.Contract.Description(&_AggregatorV3Interface.CallOpts) +} + +// GetRoundData is a free data retrieval call binding the contract method 0x9a6fc8f5. +// +// Solidity: function getRoundData(uint80 _roundId) view returns(uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound) +func (_AggregatorV3Interface *AggregatorV3InterfaceCaller) GetRoundData(opts *bind.CallOpts, _roundId *big.Int) (struct { + RoundId *big.Int + Answer *big.Int + StartedAt *big.Int + UpdatedAt *big.Int + AnsweredInRound *big.Int +}, error) { + var out []interface{} + err := _AggregatorV3Interface.contract.Call(opts, &out, "getRoundData", _roundId) + + outstruct := new(struct { + RoundId *big.Int + Answer *big.Int + StartedAt *big.Int + UpdatedAt *big.Int + AnsweredInRound *big.Int + }) + if err != nil { + return *outstruct, err + } + + outstruct.RoundId = *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + outstruct.Answer = *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) + outstruct.StartedAt = *abi.ConvertType(out[2], new(*big.Int)).(**big.Int) + outstruct.UpdatedAt = *abi.ConvertType(out[3], new(*big.Int)).(**big.Int) + outstruct.AnsweredInRound = *abi.ConvertType(out[4], new(*big.Int)).(**big.Int) + + return *outstruct, err + +} + +// GetRoundData is a free data retrieval call binding the contract method 0x9a6fc8f5. +// +// Solidity: function getRoundData(uint80 _roundId) view returns(uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound) +func (_AggregatorV3Interface *AggregatorV3InterfaceSession) GetRoundData(_roundId *big.Int) (struct { + RoundId *big.Int + Answer *big.Int + StartedAt *big.Int + UpdatedAt *big.Int + AnsweredInRound *big.Int +}, error) { + return _AggregatorV3Interface.Contract.GetRoundData(&_AggregatorV3Interface.CallOpts, _roundId) +} + +// GetRoundData is a free data retrieval call binding the contract method 0x9a6fc8f5. +// +// Solidity: function getRoundData(uint80 _roundId) view returns(uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound) +func (_AggregatorV3Interface *AggregatorV3InterfaceCallerSession) GetRoundData(_roundId *big.Int) (struct { + RoundId *big.Int + Answer *big.Int + StartedAt *big.Int + UpdatedAt *big.Int + AnsweredInRound *big.Int +}, error) { + return _AggregatorV3Interface.Contract.GetRoundData(&_AggregatorV3Interface.CallOpts, _roundId) +} + +// LatestRoundData is a free data retrieval call binding the contract method 0xfeaf968c. +// +// Solidity: function latestRoundData() view returns(uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound) +func (_AggregatorV3Interface *AggregatorV3InterfaceCaller) LatestRoundData(opts *bind.CallOpts) (struct { + RoundId *big.Int + Answer *big.Int + StartedAt *big.Int + UpdatedAt *big.Int + AnsweredInRound *big.Int +}, error) { + var out []interface{} + err := _AggregatorV3Interface.contract.Call(opts, &out, "latestRoundData") + + outstruct := new(struct { + RoundId *big.Int + Answer *big.Int + StartedAt *big.Int + UpdatedAt *big.Int + AnsweredInRound *big.Int + }) + if err != nil { + return *outstruct, err + } + + outstruct.RoundId = *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + outstruct.Answer = *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) + outstruct.StartedAt = *abi.ConvertType(out[2], new(*big.Int)).(**big.Int) + outstruct.UpdatedAt = *abi.ConvertType(out[3], new(*big.Int)).(**big.Int) + outstruct.AnsweredInRound = *abi.ConvertType(out[4], new(*big.Int)).(**big.Int) + + return *outstruct, err + +} + +// LatestRoundData is a free data retrieval call binding the contract method 0xfeaf968c. +// +// Solidity: function latestRoundData() view returns(uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound) +func (_AggregatorV3Interface *AggregatorV3InterfaceSession) LatestRoundData() (struct { + RoundId *big.Int + Answer *big.Int + StartedAt *big.Int + UpdatedAt *big.Int + AnsweredInRound *big.Int +}, error) { + return _AggregatorV3Interface.Contract.LatestRoundData(&_AggregatorV3Interface.CallOpts) +} + +// LatestRoundData is a free data retrieval call binding the contract method 0xfeaf968c. +// +// Solidity: function latestRoundData() view returns(uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound) +func (_AggregatorV3Interface *AggregatorV3InterfaceCallerSession) LatestRoundData() (struct { + RoundId *big.Int + Answer *big.Int + StartedAt *big.Int + UpdatedAt *big.Int + AnsweredInRound *big.Int +}, error) { + return _AggregatorV3Interface.Contract.LatestRoundData(&_AggregatorV3Interface.CallOpts) +} + +// Version is a free data retrieval call binding the contract method 0x54fd4d50. +// +// Solidity: function version() view returns(uint256) +func (_AggregatorV3Interface *AggregatorV3InterfaceCaller) Version(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _AggregatorV3Interface.contract.Call(opts, &out, "version") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Version is a free data retrieval call binding the contract method 0x54fd4d50. +// +// Solidity: function version() view returns(uint256) +func (_AggregatorV3Interface *AggregatorV3InterfaceSession) Version() (*big.Int, error) { + return _AggregatorV3Interface.Contract.Version(&_AggregatorV3Interface.CallOpts) +} + +// Version is a free data retrieval call binding the contract method 0x54fd4d50. +// +// Solidity: function version() view returns(uint256) +func (_AggregatorV3Interface *AggregatorV3InterfaceCallerSession) Version() (*big.Int, error) { + return _AggregatorV3Interface.Contract.Version(&_AggregatorV3Interface.CallOpts) +} diff --git a/eth/contracts/chainlink/AggregatorV3Interface.sol b/eth/contracts/chainlink/AggregatorV3Interface.sol new file mode 100644 index 0000000000..1bedfce214 --- /dev/null +++ b/eth/contracts/chainlink/AggregatorV3Interface.sol @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: MIT +// https://github.com/smartcontractkit/chainlink/blob/v2.9.1/contracts/src/v0.7/interfaces/AggregatorV3Interface.sol +pragma solidity ^0.7.0; + +interface AggregatorV3Interface { + function decimals() external view returns (uint8); + + function description() external view returns (string memory); + + function version() external view returns (uint256); + + // getRoundData and latestRoundData should both raise "No data present" + // if they do not have data to report, instead of returning unset values + // which could be misinterpreted as actual reported values. + function getRoundData(uint80 _roundId) + external + view + returns ( + uint80 roundId, + int256 answer, + uint256 startedAt, + uint256 updatedAt, + uint80 answeredInRound + ); + + function latestRoundData() + external + view + returns ( + uint80 roundId, + int256 answer, + uint256 startedAt, + uint256 updatedAt, + uint80 answeredInRound + ); +} diff --git a/eth/pricefeed.go b/eth/pricefeed.go new file mode 100644 index 0000000000..a9f51d0122 --- /dev/null +++ b/eth/pricefeed.go @@ -0,0 +1,78 @@ +package eth + +import ( + "errors" + "fmt" + "math/big" + "time" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/ethclient" + "github.com/livepeer/go-livepeer/eth/contracts/chainlink" +) + +type PriceData struct { + RoundID int64 + Price *big.Rat + UpdatedAt time.Time +} + +// PriceFeedEthClient is an interface for fetching price data from a Chainlink +// PriceFeed contract. +type PriceFeedEthClient interface { + Description() (string, error) + FetchPriceData() (PriceData, error) +} + +func NewPriceFeedEthClient(ethClient *ethclient.Client, priceFeedAddr string) (PriceFeedEthClient, error) { + addr := common.HexToAddress(priceFeedAddr) + priceFeed, err := chainlink.NewAggregatorV3Interface(addr, ethClient) + if err != nil { + return nil, fmt.Errorf("failed to create aggregator proxy: %w", err) + } + + return &priceFeedClient{ + client: ethClient, + priceFeed: priceFeed, + }, nil +} + +type priceFeedClient struct { + client *ethclient.Client + priceFeed *chainlink.AggregatorV3Interface +} + +func (c *priceFeedClient) Description() (string, error) { + return c.priceFeed.Description(&bind.CallOpts{}) +} + +func (c *priceFeedClient) FetchPriceData() (PriceData, error) { + data, err := c.priceFeed.LatestRoundData(&bind.CallOpts{}) + if err != nil { + return PriceData{}, errors.New("failed to get latest round data: " + err.Error()) + } + + decimals, err := c.priceFeed.Decimals(&bind.CallOpts{}) + if err != nil { + return PriceData{}, errors.New("failed to get decimals: " + err.Error()) + } + + return computePriceData(data.RoundId, data.UpdatedAt, data.Answer, decimals), nil +} + +// computePriceData transforms the raw data from the PriceFeed into the higher +// level PriceData struct, more easily usable by the rest of the system. +func computePriceData(roundID, updatedAt, answer *big.Int, decimals uint8) PriceData { + // Compute a big.int which is 10^decimals. + divisor := new(big.Int).Exp( + big.NewInt(10), + big.NewInt(int64(decimals)), + nil) + + return PriceData{ + RoundID: roundID.Int64(), + Price: new(big.Rat).SetFrac(answer, divisor), + UpdatedAt: time.Unix(updatedAt.Int64(), 0), + } +} diff --git a/eth/pricefeed_test.go b/eth/pricefeed_test.go new file mode 100644 index 0000000000..981a158e75 --- /dev/null +++ b/eth/pricefeed_test.go @@ -0,0 +1,51 @@ +package eth + +import ( + "math/big" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestComputePriceData(t *testing.T) { + assert := assert.New(t) + + t.Run("valid data", func(t *testing.T) { + roundID := big.NewInt(1) + updatedAt := big.NewInt(1626192000) + answer := big.NewInt(420666000) + decimals := uint8(6) + + data := computePriceData(roundID, updatedAt, answer, decimals) + + assert.EqualValues(int64(1), data.RoundID, "Round ID didn't match") + assert.Equal("210333/500", data.Price.RatString(), "The Price Rat didn't match") + assert.Equal("2021-07-13 16:00:00 +0000 UTC", data.UpdatedAt.UTC().String(), "The updated at time did not match") + }) + + t.Run("zero answer", func(t *testing.T) { + roundID := big.NewInt(2) + updatedAt := big.NewInt(1626192000) + answer := big.NewInt(0) + decimals := uint8(18) + + data := computePriceData(roundID, updatedAt, answer, decimals) + + assert.EqualValues(int64(2), data.RoundID, "Round ID didn't match") + assert.Equal("0", data.Price.RatString(), "The Price Rat didn't match") + assert.Equal("2021-07-13 16:00:00 +0000 UTC", data.UpdatedAt.UTC().String(), "The updated at time did not match") + }) + + t.Run("zero decimals", func(t *testing.T) { + roundID := big.NewInt(3) + updatedAt := big.NewInt(1626192000) + answer := big.NewInt(13) + decimals := uint8(0) + + data := computePriceData(roundID, updatedAt, answer, decimals) + + assert.EqualValues(int64(3), data.RoundID, "Round ID didn't match") + assert.Equal("13", data.Price.RatString(), "The Price Rat didn't match") + assert.Equal("2021-07-13 16:00:00 +0000 UTC", data.UpdatedAt.UTC().String(), "The updated at time did not match") + }) +} diff --git a/eth/watchers/pricefeedwatcher.go b/eth/watchers/pricefeedwatcher.go new file mode 100644 index 0000000000..ec7a81f2f3 --- /dev/null +++ b/eth/watchers/pricefeedwatcher.go @@ -0,0 +1,182 @@ +package watchers + +import ( + "context" + "fmt" + "strings" + "sync" + "time" + + "github.com/ethereum/go-ethereum/ethclient" + "github.com/ethereum/go-ethereum/event" + "github.com/livepeer/go-livepeer/clog" + "github.com/livepeer/go-livepeer/eth" +) + +const ( + priceUpdateMaxRetries = 5 + priceUpdateBaseRetryDelay = 30 * time.Second + priceUpdatePeriod = 1 * time.Hour +) + +// PriceFeedWatcher monitors a Chainlink PriceFeed for updated pricing info. It +// allows fetching the current price as well as listening for updates on the +// PriceUpdated channel. +type PriceFeedWatcher struct { + baseRetryDelay time.Duration + + priceFeed eth.PriceFeedEthClient + currencyBase, currencyQuote string + + mu sync.RWMutex + current eth.PriceData + priceEventFeed event.Feed +} + +// NewPriceFeedWatcher creates a new PriceFeedWatcher instance. It will already +// fetch the current price and start a goroutine to watch for updates. +func NewPriceFeedWatcher(ethClient *ethclient.Client, priceFeedAddr string) (*PriceFeedWatcher, error) { + priceFeed, err := eth.NewPriceFeedEthClient(ethClient, priceFeedAddr) + if err != nil { + return nil, fmt.Errorf("failed to create price feed client: %w", err) + } + + description, err := priceFeed.Description() + if err != nil { + return nil, fmt.Errorf("failed to get description: %w", err) + } + + currencyFrom, currencyTo, err := parseCurrencies(description) + if err != nil { + return nil, err + } + + w := &PriceFeedWatcher{ + baseRetryDelay: priceUpdateBaseRetryDelay, + priceFeed: priceFeed, + currencyBase: currencyFrom, + currencyQuote: currencyTo, + } + + err = w.updatePrice() + if err != nil { + return nil, fmt.Errorf("failed to update price: %w", err) + } + + return w, nil +} + +// Currencies returns the base and quote currencies of the price feed. +// i.e. base = CurrentPrice() * quote +func (w *PriceFeedWatcher) Currencies() (base string, quote string) { + return w.currencyBase, w.currencyQuote +} + +// Current returns the latest fetched price data. +func (w *PriceFeedWatcher) Current() eth.PriceData { + w.mu.RLock() + defer w.mu.RUnlock() + return w.current +} + +// Subscribe allows one to subscribe to price updates emitted by the Watcher. +// To unsubscribe, simply call `Unsubscribe` on the returned subscription. +// The sink channel should have ample buffer space to avoid blocking other +// subscribers. Slow subscribers are not dropped. +func (w *PriceFeedWatcher) Subscribe(sub chan<- eth.PriceData) event.Subscription { + return w.priceEventFeed.Subscribe(sub) +} + +func (w *PriceFeedWatcher) updatePrice() error { + newPrice, err := w.priceFeed.FetchPriceData() + if err != nil { + return fmt.Errorf("failed to fetch price data: %w", err) + } + + if newPrice.UpdatedAt.After(w.current.UpdatedAt) { + w.mu.Lock() + w.current = newPrice + w.mu.Unlock() + w.priceEventFeed.Send(newPrice) + } + + return nil +} + +// Watch starts the watch process. It will periodically poll the price feed for +// price updates until the given context is canceled. Typically, you want to +// call Watch inside a goroutine. +func (w *PriceFeedWatcher) Watch(ctx context.Context) { + ticker := newTruncatedTicker(ctx, priceUpdatePeriod) + w.watchTicker(ctx, ticker) +} + +func (w *PriceFeedWatcher) watchTicker(ctx context.Context, ticker <-chan time.Time) { + for { + select { + case <-ctx.Done(): + return + case <-ticker: + attempt, retryDelay := 1, w.baseRetryDelay + for { + err := w.updatePrice() + if err == nil { + break + } else if attempt >= priceUpdateMaxRetries { + clog.Errorf(ctx, "Failed to fetch updated price from PriceFeed attempts=%d err=%q", attempt, err) + break + } + + clog.Warningf(ctx, "Failed to fetch updated price from PriceFeed, retrying after retryDelay=%d attempt=%d err=%q", retryDelay, attempt, err) + select { + case <-ctx.Done(): + return + case <-time.After(retryDelay): + } + attempt, retryDelay = attempt+1, retryDelay*2 + } + } + } +} + +// parseCurrencies parses the base and quote currencies from a price feed based +// on Chainlink PriceFeed description pattern "FROM / TO". +func parseCurrencies(description string) (currencyBase string, currencyQuote string, err error) { + currencies := strings.Split(description, "/") + if len(currencies) != 2 { + return "", "", fmt.Errorf("aggregator description must be in the format 'FROM / TO' but got: %s", description) + } + + currencyBase = strings.TrimSpace(currencies[0]) + currencyQuote = strings.TrimSpace(currencies[1]) + return +} + +// newTruncatedTicker creates a ticker that ticks at the next time that is a +// multiple of d, starting from the current time. This is a best-effort approach +// to ensure that nodes update their prices around the same time to avoid too +// big price discrepancies. +func newTruncatedTicker(ctx context.Context, d time.Duration) <-chan time.Time { + ch := make(chan time.Time, 1) + go func() { + defer close(ch) + + nextTick := time.Now().UTC().Truncate(d) + for { + nextTick = nextTick.Add(d) + untilNextTick := nextTick.Sub(time.Now().UTC()) + if untilNextTick <= 0 { + continue + } + + select { + case <-ctx.Done(): + return + case t := <-time.After(untilNextTick): + ch <- t + } + } + }() + + return ch +} diff --git a/eth/watchers/pricefeedwatcher_test.go b/eth/watchers/pricefeedwatcher_test.go new file mode 100644 index 0000000000..20e09578e1 --- /dev/null +++ b/eth/watchers/pricefeedwatcher_test.go @@ -0,0 +1,216 @@ +package watchers + +import ( + "context" + "errors" + "math/big" + "testing" + "time" + + "github.com/livepeer/go-livepeer/eth" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" +) + +type mockPriceFeedEthClient struct { + mock.Mock +} + +func (m *mockPriceFeedEthClient) FetchPriceData() (eth.PriceData, error) { + args := m.Called() + return args.Get(0).(eth.PriceData), args.Error(1) +} + +func (m *mockPriceFeedEthClient) Description() (string, error) { + args := m.Called() + return args.String(0), args.Error(1) +} + +func TestPriceFeedWatcher_UpdatePrice(t *testing.T) { + priceFeedMock := new(mockPriceFeedEthClient) + defer priceFeedMock.AssertExpectations(t) + + priceData := eth.PriceData{ + RoundID: 10, + Price: big.NewRat(3, 2), + UpdatedAt: time.Now(), + } + priceFeedMock.On("FetchPriceData").Return(priceData, nil).Once() + + w := &PriceFeedWatcher{ + priceFeed: priceFeedMock, + currencyBase: "ETH", + currencyQuote: "USD", + } + + priceUpdated := make(chan eth.PriceData, 1) + sub := w.Subscribe(priceUpdated) + defer sub.Unsubscribe() + + require.NoError(t, w.updatePrice()) + require.Equal(t, priceData, w.current) + + select { + case updatedPrice := <-priceUpdated: + require.Equal(t, priceData, updatedPrice) + case <-time.After(2 * time.Second): + t.Error("Updated price hasn't been received on channel") + } +} + +func TestPriceFeedWatcher_Watch(t *testing.T) { + require := require.New(t) + priceFeedMock := new(mockPriceFeedEthClient) + defer priceFeedMock.AssertExpectations(t) + + w := &PriceFeedWatcher{ + priceFeed: priceFeedMock, + currencyBase: "ETH", + currencyQuote: "USD", + } + + priceUpdated := make(chan eth.PriceData, 1) + sub := w.Subscribe(priceUpdated) + defer sub.Unsubscribe() + + priceData := eth.PriceData{ + RoundID: 10, + Price: big.NewRat(9, 2), + UpdatedAt: time.Now(), + } + checkPriceUpdated := func() { + select { + case updatedPrice := <-priceUpdated: + require.Equal(priceData, updatedPrice) + require.Equal(priceData, w.current) + case <-time.After(1 * time.Second): + require.Fail("Updated price hasn't been received on channel in a timely manner") + } + priceFeedMock.AssertExpectations(t) + } + checkNoPriceUpdate := func() { + select { + case <-priceUpdated: + require.Fail("Unexpected price update given it hasn't changed") + case <-time.After(1 * time.Second): + // all good + } + priceFeedMock.AssertExpectations(t) + } + + // Start the watch loop + fakeTicker := make(chan time.Time, 10) + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + go func() { + w.watchTicker(ctx, fakeTicker) + }() + + // First time should trigger an update + priceFeedMock.On("FetchPriceData").Return(priceData, nil).Once() + fakeTicker <- time.Now() + checkPriceUpdated() + + // Trigger a dummy update given price hasn't changed + priceFeedMock.On("FetchPriceData").Return(priceData, nil).Once() + fakeTicker <- time.Now() + checkNoPriceUpdate() + + // still shouldn't update given UpdatedAt stayed the same + priceData.Price = big.NewRat(1, 1) + priceFeedMock.On("FetchPriceData").Return(priceData, nil).Once() + fakeTicker <- time.Now() + checkNoPriceUpdate() + + // bump the UpdatedAt time to trigger an update + priceData.UpdatedAt = priceData.UpdatedAt.Add(1 * time.Minute) + priceFeedMock.On("FetchPriceData").Return(priceData, nil).Once() + fakeTicker <- time.Now() + checkPriceUpdated() + + priceData.UpdatedAt = priceData.UpdatedAt.Add(1 * time.Hour) + priceData.Price = big.NewRat(3, 2) + priceFeedMock.On("FetchPriceData").Return(priceData, nil).Once() + fakeTicker <- time.Now() + checkPriceUpdated() +} + +func TestPriceFeedWatcher_WatchErrorRetries(t *testing.T) { + priceFeedMock := new(mockPriceFeedEthClient) + defer priceFeedMock.AssertExpectations(t) + + // First 4 calls should fail then succeed on the 5th + for i := 0; i < 4; i++ { + priceFeedMock.On("FetchPriceData").Return(eth.PriceData{}, errors.New("error")).Once() + } + priceData := eth.PriceData{ + RoundID: 10, + Price: big.NewRat(3, 2), + UpdatedAt: time.Now(), + } + priceFeedMock.On("FetchPriceData").Return(priceData, nil) + + w := &PriceFeedWatcher{ + baseRetryDelay: 5 * time.Millisecond, + priceFeed: priceFeedMock, + currencyBase: "ETH", + currencyQuote: "USD", + } + + priceUpdated := make(chan eth.PriceData, 1) + sub := w.Subscribe(priceUpdated) + defer sub.Unsubscribe() + + // Start watch loop + fakeTicker := make(chan time.Time, 10) + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + go func() { + w.watchTicker(ctx, fakeTicker) + }() + + fakeTicker <- time.Now() + select { + case updatedPrice := <-priceUpdated: + require.Equal(t, priceData, updatedPrice) + case <-time.After(2 * time.Second): + t.Error("Updated price hasn't been received on channel") + } +} + +func TestParseCurrencies(t *testing.T) { + t.Run("Valid currencies", func(t *testing.T) { + description := "ETH / USD" + currencyBase, currencyQuote, err := parseCurrencies(description) + + require.NoError(t, err) + require.Equal(t, "ETH", currencyBase) + require.Equal(t, "USD", currencyQuote) + }) + + t.Run("Missing separator", func(t *testing.T) { + description := "ETHUSD" + _, _, err := parseCurrencies(description) + + require.Error(t, err) + require.Contains(t, err.Error(), "aggregator description must be in the format 'FROM / TO'") + }) + + t.Run("Extra spaces", func(t *testing.T) { + description := " ETH / USD " + currencyBase, currencyQuote, err := parseCurrencies(description) + + require.NoError(t, err) + require.Equal(t, "ETH", currencyBase) + require.Equal(t, "USD", currencyQuote) + }) + + t.Run("Lowercase currency", func(t *testing.T) { + description := "eth / usd" + currencyBase, currencyQuote, err := parseCurrencies(description) + + require.NoError(t, err) + require.Equal(t, "eth", currencyBase) + require.Equal(t, "usd", currencyQuote) + }) +} diff --git a/go.mod b/go.mod index ed9e2f3715..675f75b480 100644 --- a/go.mod +++ b/go.mod @@ -28,6 +28,7 @@ require ( go.uber.org/goleak v1.3.0 golang.org/x/net v0.17.0 google.golang.org/grpc v1.57.1 + google.golang.org/protobuf v1.30.0 pgregory.net/rapid v1.1.0 ) @@ -39,9 +40,11 @@ require ( cloud.google.com/go/storage v1.28.1 // indirect dario.cat/mergo v1.0.0 // indirect github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect + github.com/DataDog/zstd v1.4.5 // indirect github.com/Microsoft/go-winio v0.6.1 // indirect github.com/Microsoft/hcsshim v0.11.1 // indirect github.com/StackExchange/wmi v1.2.1 // indirect + github.com/VictoriaMetrics/fastcache v1.12.1 // indirect github.com/aws/aws-sdk-go v1.44.64 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bits-and-blooms/bitset v1.7.0 // indirect @@ -49,6 +52,12 @@ require ( github.com/cenkalti/backoff/v4 v4.2.1 // indirect github.com/cespare/cp v1.1.1 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/cockroachdb/errors v1.8.1 // indirect + github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f // indirect + github.com/cockroachdb/pebble v0.0.0-20230928194634-aa077af62593 // indirect + github.com/cockroachdb/redact v1.0.8 // indirect + github.com/cockroachdb/sentry-go v0.6.1-cockroachdb.2 // indirect + github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect github.com/consensys/bavard v0.1.13 // indirect github.com/consensys/gnark-crypto v0.12.1 // indirect github.com/containerd/containerd v1.7.7 // indirect @@ -59,6 +68,7 @@ require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/deckarep/golang-set/v2 v2.1.0 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect + github.com/deepmap/oapi-codegen v1.6.0 // indirect github.com/dlclark/regexp2 v1.7.0 // indirect github.com/docker/distribution v2.8.2+incompatible // indirect github.com/docker/docker v24.0.6+incompatible // indirect @@ -67,6 +77,7 @@ require ( github.com/dop251/goja v0.0.0-20230806174421-c933cf95e127 // indirect github.com/ethereum/c-kzg-4844 v0.4.0 // indirect github.com/fatih/color v1.13.0 // indirect + github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff // indirect github.com/ghodss/yaml v1.0.0 // indirect @@ -75,7 +86,9 @@ require ( github.com/go-ole/go-ole v1.2.6 // indirect github.com/go-sourcemap/sourcemap v2.1.3+incompatible // indirect github.com/go-stack/stack v1.8.1 // indirect + github.com/gofrs/flock v0.8.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang-jwt/jwt/v4 v4.5.0 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect github.com/google/go-cmp v0.5.9 // indirect @@ -84,10 +97,21 @@ require ( github.com/googleapis/enterprise-certificate-proxy v0.2.3 // indirect github.com/googleapis/gax-go/v2 v2.7.1 // indirect github.com/gorilla/websocket v1.4.2 // indirect + github.com/graph-gophers/graphql-go v1.3.0 // indirect + github.com/hashicorp/go-bexpr v0.1.10 // indirect + github.com/holiman/billy v0.0.0-20230718173358-1c7e68d277a7 // indirect + github.com/holiman/bloomfilter/v2 v2.0.3 // indirect github.com/holiman/uint256 v1.2.3 // indirect + github.com/huin/goupnp v1.3.0 // indirect + github.com/influxdata/influxdb-client-go/v2 v2.4.0 // indirect + github.com/influxdata/influxdb1-client v0.0.0-20220302092344-a9ab5670611c // indirect + github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839 // indirect + github.com/jackpal/go-nat-pmp v1.0.2 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/karalabe/usb v0.0.2 // indirect github.com/klauspost/compress v1.16.3 // indirect + github.com/kr/pretty v0.3.1 // indirect + github.com/kr/text v0.2.0 // indirect github.com/livepeer/joy4 v0.1.2-0.20191121080656-b2fea45cbded // indirect github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect github.com/magiconair/properties v1.8.7 // indirect @@ -96,6 +120,8 @@ require ( github.com/mattn/go-runewidth v0.0.13 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect + github.com/mitchellh/mapstructure v1.4.1 // indirect + github.com/mitchellh/pointerstructure v1.2.0 // indirect github.com/mmcloughlin/addchain v0.4.0 // indirect github.com/moby/patternmatcher v0.6.0 // indirect github.com/moby/sys/sequential v0.5.0 // indirect @@ -104,6 +130,7 @@ require ( github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/image-spec v1.1.0-rc5 // indirect github.com/opencontainers/runc v1.1.5 // indirect + github.com/opentracing/opentracing-go v1.1.0 // indirect github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7 // indirect github.com/pierrec/lz4 v2.6.1+incompatible // indirect github.com/pmezard/go-difflib v1.0.0 // indirect @@ -115,6 +142,8 @@ require ( github.com/rabbitmq/amqp091-go v1.8.0 // indirect github.com/rabbitmq/rabbitmq-stream-go-client v1.1.1 // indirect github.com/rivo/uniseg v0.2.0 // indirect + github.com/rogpeppe/go-internal v1.9.0 // indirect + github.com/rs/cors v1.7.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible // indirect github.com/shirou/gopsutil/v3 v3.23.9 // indirect @@ -123,8 +152,12 @@ require ( github.com/status-im/keycard-go v0.2.0 // indirect github.com/stretchr/objx v0.5.0 // indirect github.com/supranational/blst v0.3.11 // indirect + github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // indirect github.com/tklauser/go-sysconf v0.3.12 // indirect github.com/tklauser/numcpus v0.6.1 // indirect + github.com/tyler-smith/go-bip39 v1.1.0 // indirect + github.com/urfave/cli/v2 v2.25.7 // indirect + github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect github.com/yusufpapurcu/wmi v1.2.3 // indirect golang.org/x/crypto v0.14.0 // indirect golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect @@ -133,6 +166,7 @@ require ( golang.org/x/sync v0.3.0 // indirect golang.org/x/sys v0.13.0 // indirect golang.org/x/text v0.13.0 // indirect + golang.org/x/time v0.3.0 // indirect golang.org/x/tools v0.13.0 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect google.golang.org/api v0.114.0 // indirect @@ -140,7 +174,7 @@ require ( google.golang.org/genproto v0.0.0-20230526161137-0005af68ea54 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20230525234035-dd9d682886f9 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19 // indirect - google.golang.org/protobuf v1.30.0 // indirect + gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect howett.net/plist v1.0.0 // indirect diff --git a/go.sum b/go.sum index 5f01dac8e5..02fdd1f23e 100644 --- a/go.sum +++ b/go.sum @@ -47,27 +47,41 @@ dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 h1:bvDV9vkmnHYOMsOr4WLk+Vo07yKIzd94sVoIqshQ4bU= +github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/CloudyKit/fastprinter v0.0.0-20170127035650-74b38d55f37a/go.mod h1:EFZQ978U7x8IRnstaskI3IysnWY5Ao3QgZUKOXlsAdw= +github.com/CloudyKit/jet v2.1.3-0.20180809161101-62edd43e4f88+incompatible/go.mod h1:HPYO+50pSWkPoj9Q/eq0aRGByCL6ScRlUmiEX5Zgm+w= github.com/DataDog/zstd v1.4.5 h1:EndNeuB0l9syBZhut0wns3gV1hL8zX8LIu6ZiVHWLIQ= +github.com/DataDog/zstd v1.4.5/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= +github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY= +github.com/Joker/jade v1.0.1-0.20190614124447-d475f43051e7/go.mod h1:6E6s8o2AE4KhCrqr6GRJjdC/gNfTdxkIXvuGZZda2VM= github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= github.com/Microsoft/hcsshim v0.11.1 h1:hJ3s7GbWlGK4YVV92sO88BQSyF4ZLVy7/awqOlPxFbA= github.com/Microsoft/hcsshim v0.11.1/go.mod h1:nFJmaO4Zr5Y7eADdFOpYswDDlNVbvcIJJNJLECr5JQg= +github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0= github.com/StackExchange/wmi v1.2.1 h1:VIkavFPXSjcnS+O8yTq7NI32k0R5Aj+v39y29VYDOSA= github.com/StackExchange/wmi v1.2.1/go.mod h1:rcmrprowKIVzvc+NUiLncP2uuArMWLCbu9SBzvHz7e8= github.com/VictoriaMetrics/fastcache v1.12.1 h1:i0mICQuojGDL3KblA7wUNlY5lOK6a4bwt3uRKnkZU40= +github.com/VictoriaMetrics/fastcache v1.12.1/go.mod h1:tX04vaqcNoQeGLD+ra5pU5sWkuxnzWhEzLwhP9w653o= +github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= +github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah4HI848JfFxHt+iPb26b4zyfspmqY0/8= +github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= +github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/aws/aws-sdk-go v1.44.64 h1:DuDZSBDkFBWW5H8q6i80RJDkBaaa/53KA6Jreqwjlqw= github.com/aws/aws-sdk-go v1.44.64/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= +github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -98,12 +112,22 @@ github.com/chzyer/test v0.0.0-20210722231415-061457976a23/go.mod h1:Q3SI9o4m/ZMn github.com/cilium/ebpf v0.7.0/go.mod h1:/oI2+1shJiTGAMgl6/RgJr36Eo1jzrRcAWbcXO2usCA= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cockroachdb/datadriven v1.0.0/go.mod h1:5Ib8Meh+jk1RlHIXej6Pzevx/NLlNvQB9pmSBZErGA4= +github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f h1:otljaYPt5hWxV3MUfO5dFPFiOXg9CyG5/kCfayTqsJ4= +github.com/cockroachdb/errors v1.6.1/go.mod h1:tm6FTP5G81vwJ5lC0SizQo374JNCOPrHyXGitRJoDqM= github.com/cockroachdb/errors v1.8.1 h1:A5+txlVZfOqFBDa4mGz2bUWSp0aHElvHX2bKkdbQu+Y= +github.com/cockroachdb/errors v1.8.1/go.mod h1:qGwQn6JmZ+oMjuLwjWzUNqblqk0xl4CVV3SQbGwK7Ac= github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f h1:o/kfcElHqOiXqcou5a3rIlMc7oJbMQkeLk0VQJ7zgqY= +github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI= github.com/cockroachdb/pebble v0.0.0-20230928194634-aa077af62593 h1:aPEJyR4rPBvDmeyi+l/FS/VtA00IWvjeFvjen1m1l1A= +github.com/cockroachdb/pebble v0.0.0-20230928194634-aa077af62593/go.mod h1:6hk1eMY/u5t+Cf18q5lFMUA1Rc+Sm5I6Ra1QuPyxXCo= github.com/cockroachdb/redact v1.0.8 h1:8QG/764wK+vmEYoOlfobpe12EQcS81ukx/a4hdVMxNw= +github.com/cockroachdb/redact v1.0.8/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= github.com/cockroachdb/sentry-go v0.6.1-cockroachdb.2 h1:IKgmqgMQlVJIZj19CdocBeSfSaiCbEBZGKODaixqtHM= +github.com/cockroachdb/sentry-go v0.6.1-cockroachdb.2/go.mod h1:8BT+cPK6xvFOcRlk0R8eg+OTkcqI6baNH4xAkpiYVvQ= github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 h1:zuQyyAKVxetITBuuhv3BI9cMrmStnpT18zmgmTxunpo= +github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06/go.mod h1:7nc4anLGjupUW/PeY5qiNYsdNXj7zopG+eqsS7To5IQ= +github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM= github.com/consensys/bavard v0.1.13 h1:oLhMLOFGTLdlda/kma4VOJazblc7IM5y5QPd2A/YjhQ= github.com/consensys/bavard v0.1.13/go.mod h1:9ItSMtA/dXMAiL7BG6bqW2m3NdSEObYWoH223nGHukI= github.com/consensys/gnark-crypto v0.12.1 h1:lHH39WuuFgVHONRl3J0LRBtuYdQTumFSDtJF7HpyG8M= @@ -113,9 +137,13 @@ github.com/containerd/containerd v1.7.7 h1:QOC2K4A42RQpcrZyptP6z9EJZnlHfHJUfZrAA github.com/containerd/containerd v1.7.7/go.mod h1:3c4XZv6VeT9qgf9GMTxNTMFxGJrGpI2vz1yk4ye+YY8= github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= +github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= +github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/cpuguy83/dockercfg v0.3.1 h1:/FpZ+JaygUR/lZP2NlFI2DVfrOEMAIKP5wWEJdoYe9E= github.com/cpuguy83/dockercfg v0.3.1/go.mod h1:sugsbF4//dDlL/i+S+rtpIWp+5h0BHJHfjj5/jFyUJc= +github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= @@ -123,6 +151,7 @@ github.com/crate-crypto/go-kzg-4844 v0.7.0 h1:C0vgZRk4q4EZ/JgPfzuSoxdCq3C3mOZMBS github.com/crate-crypto/go-kzg-4844 v0.7.0/go.mod h1:1kMhvPgI0Ky3yIa+9lFySEBUBXkYxeOi8ZF1sYioxhc= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= +github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4= github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= @@ -133,6 +162,11 @@ github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 h1:YLtO71vCjJRCBcrPMtQ9nqBsqpA1m5sE92cU+pd5Mcc= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs= +github.com/deepmap/oapi-codegen v1.6.0 h1:w/d1ntwh91XI0b/8ja7+u5SvA4IFfM0UNNLmiDR1gg0= +github.com/deepmap/oapi-codegen v1.6.0/go.mod h1:ryDa9AgbELGeB+YEXE1dR53yAjHwFvE9iAUlWl9Al3M= +github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= +github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= github.com/dlclark/regexp2 v1.7.0 h1:7lJfhqlPssTb1WQx4yvTHN0uElPEv52sbaECrAQxjAo= github.com/dlclark/regexp2 v1.7.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= @@ -150,25 +184,42 @@ github.com/dop251/goja v0.0.0-20230806174421-c933cf95e127 h1:qwcF+vdFrvPSEUDSX5R github.com/dop251/goja v0.0.0-20230806174421-c933cf95e127/go.mod h1:QMWlm50DNe14hD7t24KEqZuUdC9sOTy8W6XbCU1mlw4= github.com/dop251/goja_nodejs v0.0.0-20210225215109-d91c329300e7/go.mod h1:hn7BA7c8pLvoGndExHudxTDKZ84Pyvv+90pbBjbTz0Y= github.com/dop251/goja_nodejs v0.0.0-20211022123610-8dd9abb0616d/go.mod h1:DngW8aVqWbuLRMHItjPUyqdj+HWPvnQe8V8y1nDpIbM= +github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw= github.com/ethereum/c-kzg-4844 v0.4.0 h1:3MS1s4JtA868KpJxroZoepdV0ZKBp3u/O5HcZ7R3nlY= github.com/ethereum/c-kzg-4844 v0.4.0/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1aQputP83wc0= github.com/ethereum/go-ethereum v1.13.5 h1:U6TCRciCqZRe4FPXmy1sMGxTfuk8P7u2UoinF3VbaFk= github.com/ethereum/go-ethereum v1.13.5/go.mod h1:yMTu38GSuyxaYzQMViqNmQ1s3cE84abZexQmTgenWk0= +github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8= github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= +github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 h1:FtmdgXiUlNeRsoNMFlKLDt+S+6hbjVMEW6RGQ7aUf7c= +github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= +github.com/flosch/pongo2 v0.0.0-20190707114632-bbf5a6c351f4/go.mod h1:T9YF2M40nIgbVgp3rreNmTged+9HrbNTIQf1PsaIiTA= github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= github.com/frankban/quicktest v1.14.2 h1:SPb1KFFmM+ybpEjPUhCCkZOM5xlovT5UbrMvWnXyBns= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= +github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc= github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff h1:tY80oXqGNY4FhTFhk+o9oFHGINQ/+vhlm8HFzi6znCI= github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= +github.com/getkin/kin-openapi v0.53.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4= github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s= +github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM= +github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= +github.com/go-chi/chi/v5 v5.0.0/go.mod h1:BBug9lr0cqtdAhsu6R4AAdvufI0/XBzAQSsUqJpoZOs= +github.com/go-errors/errors v1.0.1 h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w= +github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= @@ -184,21 +235,33 @@ github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG github.com/go-logfmt/logfmt v0.5.1 h1:otpy5pqBCBZ1ng9RQ0dPu4PN7ba75Y/aA+UpowDyNVA= github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= +github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= +github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-sourcemap/sourcemap v2.1.3+incompatible h1:W1iEw64niKVGogNgBN3ePyLFfuisuzeidWPMPWmECqU= github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-stack/stack v1.8.1 h1:ntEHSVwIt7PNXNpgPmVfMrNhLtgjlmnZha2kOpuRiDw= github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4= +github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= +github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= +github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.0.6/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= +github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= +github.com/gogo/googleapis v0.0.0-20180223154316-0cd9801be74a/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/gogo/status v1.1.0/go.mod h1:BFv9nrluPLmrS0EmGVvLaPNmRosr9KapBYd5/hpY1WM= github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= +github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/glog v1.1.1 h1:jxpi2eWoU84wbX9iIEyAeeoac3FLuifZpY9tcNUD9kw= github.com/golang/glog v1.1.1/go.mod h1:zR+okUeTbrL6EL3xHUDxZuEtGv04p5shwip1+mL/rLQ= @@ -234,8 +297,11 @@ github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaS github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb h1:PBC98N2aIaM3XXiurYmW7fx4GZkL8feAMVq7nEjURHk= github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golangci/lint-1 v0.0.0-20181222135242-d2cdd8c08219/go.mod h1:/X8TswGSh1pIozq4ZwCfxS0WA5JGXguxk94ar/4c87Y= +github.com/gomodule/redigo v1.7.1-0.20190724094224-574c33c3df38/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= @@ -252,6 +318,7 @@ github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= @@ -277,19 +344,45 @@ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+ github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/gax-go/v2 v2.7.1 h1:gF4c0zjUP2H/s/hEGyLA3I0fA2ZWjzYiONAD6cvPr8A= github.com/googleapis/gax-go/v2 v2.7.1/go.mod h1:4orTrqY6hXxxaUL4LHIPl6lGo8vAE38/qKbhSAKP6QI= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= +github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/graph-gophers/graphql-go v1.3.0 h1:Eb9x/q6MFpCLz7jBCiP/WTxjSDrYLR1QY41SORZyNJ0= +github.com/graph-gophers/graphql-go v1.3.0/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc= github.com/hashicorp/go-bexpr v0.1.10 h1:9kuI5PFotCboP3dkDYFr/wi0gg0QVbSNz5oFRpxn4uE= +github.com/hashicorp/go-bexpr v0.1.10/go.mod h1:oxlubA2vC/gFVfX1A6JGp7ls7uCDlfJn732ehYYg+g0= +github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/holiman/billy v0.0.0-20230718173358-1c7e68d277a7 h1:3JQNjnMRil1yD0IfZKHF9GxxWKDJGj8I0IqOUol//sw= +github.com/holiman/billy v0.0.0-20230718173358-1c7e68d277a7/go.mod h1:5GuXa7vkL8u9FkFuWdVvfR5ix8hRB7DbOAaYULamFpc= github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao= +github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA= github.com/holiman/uint256 v1.2.3 h1:K8UWO1HUJpRMXBxbmaY1Y8IAMZC/RsKB+ArEnnK4l5o= github.com/holiman/uint256 v1.2.3/go.mod h1:SC8Ryt4n+UBbPbIBKaG9zbbDlp4jOru9xFZmPzLUTxw= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc= +github.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= +github.com/hydrogen18/memlistener v0.0.0-20141126152155-54553eb933fb/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20220319035150-800ac71e25c2/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w= +github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/influxdata/influxdb-client-go/v2 v2.4.0 h1:HGBfZYStlx3Kqvsv1h2pJixbCl/jhnFtxpKFAv9Tu5k= +github.com/influxdata/influxdb-client-go/v2 v2.4.0/go.mod h1:vLNHdxTJkIf2mSLvGrpj8TCcISApPoXkaxP8g9uRlW8= +github.com/influxdata/influxdb1-client v0.0.0-20220302092344-a9ab5670611c h1:qSHzRbhzK8RdXOsAdfDgO49TtqC1oZ+acxPrkfTxcCs= +github.com/influxdata/influxdb1-client v0.0.0-20220302092344-a9ab5670611c/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= +github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839 h1:W9WBk7wlPfJLvMCdtV4zPulc4uCPrlywQOmbFOhgQNU= +github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839/go.mod h1:xaLFMmpvUxqXtVkUJfg9QmT88cDaCJ3ZKgdZ78oO8Qo= +github.com/iris-contrib/blackfriday v2.0.0+incompatible/go.mod h1:UzZ2bDEoaSGPbkg6SAB4att1aAwTmVIx/5gCVqeyUdI= +github.com/iris-contrib/go.uuid v2.0.0+incompatible/go.mod h1:iz2lgM/1UnEf1kP0L/+fafWORmlnuysV2EMP8MW+qe0= +github.com/iris-contrib/i18n v0.0.0-20171121225848-987a633949d0/go.mod h1:pMCz62A0xJL6I+umB2YTlFRwWXaDFA0jy+5HzGiJjqI= +github.com/iris-contrib/schema v0.0.1/go.mod h1:urYA3uvUNG1TIIjOSCzHr9/LmbQo8LrOcOqfqxa4hXw= github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= +github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= github.com/jaypipes/ghw v0.10.0 h1:UHu9UX08Py315iPojADFPOkmjTsNzHj4g4adsNKKteY= github.com/jaypipes/ghw v0.10.0/go.mod h1:jeJGbkRB2lL3/gxYzNYzEDETV1ZJ56OKr+CSeSEym+g= github.com/jaypipes/pcidb v1.0.0 h1:vtZIfkiCUE42oYbJS0TAq9XSfSmcsgo9IdxSm9qzYU8= @@ -306,14 +399,28 @@ github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/ github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= +github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/juju/errors v0.0.0-20181118221551-089d3ea4e4d5/go.mod h1:W54LbzXuIE0boCoNJfwqpmkKJ1O4TCTZMetAt6jGk7Q= +github.com/juju/loggo v0.0.0-20180524022052-584905176618/go.mod h1:vgyd7OREkbtVEN/8IXZe5Ooef3LQePvuBm9UWj6ZL8U= +github.com/juju/testing v0.0.0-20180920084828-472a3e8b2073/go.mod h1:63prj8cnj0tU0S9OHjGJn+b1h0ZghCndfnbQolrYTwA= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= +github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k= github.com/karalabe/usb v0.0.2 h1:M6QQBNxF+CQ8OFvxrT90BA0qBOXymndZnk5q235mFc4= github.com/karalabe/usb v0.0.2/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU= +github.com/kataras/golog v0.0.9/go.mod h1:12HJgwBIZFNGL0EJnMRhmvGA0PQGx8VFwrZtM4CqbAk= +github.com/kataras/iris/v12 v12.0.1/go.mod h1:udK4vLQKkdDqMGJJVd/msuMtN6hpYJhg/lSzuxjhO+U= +github.com/kataras/neffos v0.0.10/go.mod h1:ZYmJC07hQPW67eKuzlfY7SO3bC0mw83A3j6im82hfqw= +github.com/kataras/pio v0.0.0-20190103105442-ea782b38602d/go.mod h1:NV88laa9UiiDuX9AhMbDPkGYSPugBOV6yTZB1l2K9Z0= +github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= +github.com/klauspost/compress v1.9.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.16.3 h1:XuJt9zzcnaz6a16/OU53ZjWp/v7/42WcR5t2a0PcNQY= github.com/klauspost/compress v1.16.3/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= @@ -321,11 +428,15 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= +github.com/labstack/echo/v4 v4.1.11/go.mod h1:i541M3Fj6f76NZtHSj7TXnyM8n2gaodfvfxNnFqi74g= +github.com/labstack/echo/v4 v4.2.1/go.mod h1:AA49e0DZ8kk5jTOOCKNuPR6oTnBS0dYiM4FW1e6jwpg= +github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= github.com/livepeer/go-tools v0.0.0-20220805063103-76df6beb6506 h1:qKon23c1RQPvL5Oya/hkImbaXNMkt6VdYtnh5jcIhoY= github.com/livepeer/go-tools v0.0.0-20220805063103-76df6beb6506/go.mod h1:aLVS1DT0ur9kpr0IlNI4DNcm9vVjRRUjDnwuEUm0BdQ= @@ -333,19 +444,27 @@ 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-20231002131146-663c62246a3c h1:qxmMX/j6Yp0xFR17nhGktbHwEVqIjLK5lh2TiiENzY8= -github.com/livepeer/lpms v0.0.0-20231002131146-663c62246a3c/go.mod h1:Hr/JhxxPDipOVd4ZrGYWrdJfpVF8/SEI0nNr2ctAlkM= github.com/livepeer/lpms v0.0.0-20240115103113-98566e26c007 h1:0xr1TeIanBDdzI3sE2Zgf2yEV3s+6cPo3lJeyOHKmtM= github.com/livepeer/lpms v0.0.0-20240115103113-98566e26c007/go.mod h1:Hr/JhxxPDipOVd4ZrGYWrdJfpVF8/SEI0nNr2ctAlkM= 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= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= +github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= +github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/matryer/moq v0.0.0-20190312154309-6cfb0558e1bd/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ= +github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= @@ -357,13 +476,20 @@ github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4 github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-sqlite3 v1.14.18 h1:JL0eqdCOq6DJVNPSvArO/bIV9/P7fbGrV00LZHc+5aI= github.com/mattn/go-sqlite3 v1.14.18/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= +github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= +github.com/mediocregopher/mediocre-go-lib v0.0.0-20181029021733-cb65787f37ed/go.mod h1:dSsfyI2zABAdhcbvkXqgxOxrCsbYeHCPgrZkku60dSg= +github.com/mediocregopher/radix/v3 v3.3.0/go.mod h1:EmfVyvspXz1uZEyPBMyGK+kjWiKQGvsUt6O3Pj+LDCQ= +github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag= +github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/pointerstructure v1.2.0 h1:O+i9nHnXS3l/9Wu7r4NrEdwA2VFTicjUEN1uBnDo34A= +github.com/mitchellh/pointerstructure v1.2.0/go.mod h1:BRAsLI5zgXmw97Lf6s25bs8ohIXc3tViBH44KcwB2g4= github.com/mmcloughlin/addchain v0.4.0 h1:SobOdjm2xLj1KkXN5/n0xTIWyZA2+s99UCY1iPfkHRY= github.com/mmcloughlin/addchain v0.4.0/go.mod h1:A86O+tHqZLMNO4w6ZZ4FlVQEadcoqkyU72HC5wJ4RlU= github.com/mmcloughlin/profile v0.1.1/go.mod h1:IhHD7q1ooxgwTgjxQYkACGA77oFTDdFVejUS1/tS/qU= @@ -381,12 +507,25 @@ github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3Rllmb github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= +github.com/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ= github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/nats-io/nats.go v1.8.1/go.mod h1:BrFz9vVn0fU3AcH9Vn4Kd7W0NpJ651tD5omQ3M8LwxM= +github.com/nats-io/nkeys v0.0.2/go.mod h1:dab7URMsZm6Z/jp9Z5UGa87Uutgc2mVpXLC4B7TDb/4= +github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= +github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.13.0/go.mod h1:+REjRxOmWfHCjfv9TTWB1jD1Frx4XydAD3zm1lskyM0= +github.com/onsi/ginkgo v1.14.0 h1:2mOpI4JVVPBN+WQRa0WKH2eXR+Ey+uK4n7Zj0aYpIQA= +github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/ginkgo/v2 v2.4.0 h1:+Ig9nvqgS5OBSACXNk15PLdp0U9XPYROt9CFzVdFGIs= +github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.22.1 h1:pY8O4lBfsHKZHM/6nrxkhVPUznOlIu3quZcKP/M20KI= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= @@ -396,14 +535,20 @@ github.com/opencontainers/runc v1.1.5 h1:L44KXEpKmfWDcS02aeGm8QNTFXTo2D+8MYGDIJ/ github.com/opencontainers/runc v1.1.5/go.mod h1:1J5XiS+vdZ3wCyZybsuxXZWGrgSr8fFJHLXuG2PsnNg= github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/selinux v1.10.0/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI= +github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU= +github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc= github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= +github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/peterbourgon/ff/v3 v3.4.0 h1:QBvM/rizZM1cB0p0lGMdmR7HxZeI/ZrBWB4DqLkMUBc= github.com/peterbourgon/ff/v3 v3.4.0/go.mod h1:zjJVUhx+twciwfDl0zBcFzl4dW8axCRyXE/eKY9RztQ= github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7 h1:oYW+YCJ1pachXTQmzR3rNLYGGz4g/UgFcjb28p/viDM= github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7/go.mod h1:CRroGNssyjTd/qIG2FyxByd2S8JEAZXBl4qUrZf8GS0= github.com/pierrec/lz4 v2.6.1+incompatible h1:9UY3+iC23yxF0UfGaYrGplQ+79Rg+h/q9FV9ix19jjM= github.com/pierrec/lz4 v2.6.1+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= +github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -453,11 +598,17 @@ github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJ github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik= +github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= +github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/sclevine/agouti v3.0.0+incompatible/go.mod h1:b4WX9W9L1sfQKXeJf1mUTLZKJ48R1S7H23Ji7oFO5Bw= github.com/seccomp/libseccomp-golang v0.9.2-0.20220502022130-f33da4d89646/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg= +github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible h1:Bn1aCHHRnjv4Bl16T8rcaFjYSrGrIZvpiGO6P3Q4GpU= github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= github.com/shirou/gopsutil/v3 v3.23.9 h1:ZI5bWVeu2ep4/DIxB4U9okeYJ7zp/QLTO4auRb/ty/E= @@ -473,6 +624,14 @@ github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrf github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= +github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/status-im/keycard-go v0.2.0 h1:QDLFswOQu1r5jsycloeQh3bVU8n/NatHHaZobtDnDzA= github.com/status-im/keycard-go v0.2.0/go.mod h1:wlp8ZLbsmrF6g6WjugPAx+IzoLrkdf9+mHxBEeo3Hbg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -483,6 +642,7 @@ github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpE github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= @@ -495,6 +655,7 @@ github.com/supranational/blst v0.3.11 h1:LyU6FolezeWAhvQk0k6O/d49jqgO52MSDDfYgbe github.com/supranational/blst v0.3.11/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= +github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= github.com/testcontainers/testcontainers-go v0.26.0 h1:uqcYdoOHBy1ca7gKODfBd9uTHVK3a7UL848z09MVZ0c= github.com/testcontainers/testcontainers-go v0.26.0/go.mod h1:ICriE9bLX5CLxL9OFQ2N+2N+f+803LNJ1utJb1+Inx0= github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU= @@ -502,13 +663,32 @@ github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0h github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk= github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY= github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8= +github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U= +github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= +github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli v1.22.12 h1:igJgVw1JdKH+trcLWLeLwZjU9fEfPesQ+9/e4MQ44S8= github.com/urfave/cli v1.22.12/go.mod h1:sSBEIC79qR6OvcmsD4U3KABeOTxDqQtdDnaFuUN30b8= github.com/urfave/cli/v2 v2.25.7 h1:VAzn5oq403l5pHjc4OhD54+XGO9cdKVL/7lDjF+iKUs= +github.com/urfave/cli/v2 v2.25.7/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ= +github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4= +github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w= +github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= +github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= +github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE= github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU= +github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= +github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= +github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= +github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= +github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= +github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI= +github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= +github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= +github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -529,11 +709,15 @@ go.uber.org/goleak v1.2.1/go.mod h1:qlT2yGI9QafXHhZZLxlSuNsMw3FFLxBr+tBRlmO1xH4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= @@ -575,10 +759,13 @@ golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190327091125-710a502c58a2/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -587,6 +774,7 @@ golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -597,13 +785,16 @@ golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/ golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= @@ -638,8 +829,11 @@ golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -648,11 +842,16 @@ golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -668,10 +867,13 @@ golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200826173525-f9321e4c35a6/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -695,11 +897,13 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -707,6 +911,7 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= @@ -715,13 +920,20 @@ golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= +golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181221001348-537d06c36207/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190327201419-c70d86f8b7cf/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= @@ -794,6 +1006,7 @@ google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCID google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/genproto v0.0.0-20180518175338-11a468237815/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= @@ -829,6 +1042,7 @@ google.golang.org/genproto/googleapis/api v0.0.0-20230525234035-dd9d682886f9 h1: google.golang.org/genproto/googleapis/api v0.0.0-20230525234035-dd9d682886f9/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig= google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19 h1:0nDDozoAU19Qb2HwhXadU8OcsiO/09cnTqhUtq2MEOM= google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= +google.golang.org/grpc v1.12.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -868,7 +1082,14 @@ gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= +gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y= +gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8= +gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0/go.mod h1:WDnlLJ4WF5VGsH/HVa3CI79GS0ol3YnhVnKP89i0kNg= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/tools.go b/tools.go new file mode 100644 index 0000000000..6bc191ddd2 --- /dev/null +++ b/tools.go @@ -0,0 +1,9 @@ +//go:build tools +// +build tools + +package tools + +import ( + _ "github.com/ethereum/go-ethereum/cmd/abigen" + _ "github.com/golang/mock/mockgen" +) From 706ec33286344613ec37c4f0ac4d4f3d17657049 Mon Sep 17 00:00:00 2001 From: Victor Elias Date: Wed, 27 Mar 2024 20:58:52 -0300 Subject: [PATCH 02/88] cmd/livepeer: Use price feed watcher for dynamic pricePerPixel (#2981) * eth/watchers: Create PriceFeed watcher Makefile: Use mockgen binary from tool dependencies eth/contracts: Add chainlink interfaces source Makefile: Generate Chainlink contracts ABI tools: Add abigen tool to repo eth/contracts: Generate chainlink bindings Makefile: Fix abigen bindings generation Revert everything abigen Turns out there's already bindings exported from the Chainlink lib. go.mod: Add chainlink library eth/watchers: Add pricefeed watcher eth/watchers: Clean-up event watching code eth/watchers: Improve price tracking Revert "go.mod: Add chainlink library" This reverts commit ac415bd8fb210088874e7fdea8d37ac4dad81dab. Revert "Revert everything abigen" This reverts commit b7c40b1e936c885aad973f28d87d42b0d85cb0e4. eth/contracts: Gen bindings for proxy iface eth/watchers: Use local bindings for contracts eth/watchers: Simplify event subs logic eth/watchers: Simplify&optimize truncated ticker eth/watchers: Update decimals on fetch eth/watchers: Improve handling of decimals eth/watchers: Fix price rat creation eth/watchers: Make sure we use UTC on truncated timer eth/contracts/chainlink: Generate only V3 contract bindings eth/watchers: Watch PriceFeed only with polling eth/watchers: Add a retry logic on price update eth/watchers: Use clog instead of fmt.Printf * eth: Create separate pricefeed client unit This will make the code more testable. * eth: Add tests for pricefeed client * eth/watchers: Add tests to the truncated ticker Gosh that was much harder than I thought * eth/watchers: Add tests for pricefeedwatcher * eth: Add comments to the new components * go fmt * cmd: make pricePerUnit flags strings * cmd: Allow price per unit to be speficied with a currency Currently ignoring the currency value. * cmd: Add logic to start price update loop * cmd: Add flag for specifying price feed address * cmd: Add a lil test to priceDataToWei * TODO: Reminder for something I noticed is missing * cmd/starter: Support currencies for custom broadcaster prices * eth: Address minor review comments * eth,eth/watchers: Improve pricefeed watcher interface * eth/watchers: Fix pricefeed watcher after merge * cmd,core,server: Support dynamic updates to price in USD * eth/watchers: Remove truncated ticker tests * eth/watchers: Finalize pricefeedwatcher docs/tests * cmd: Address review comment * core: Create tests for autoconvertedprice * cmd,core: Move wei default to AutoConvertedPrice * Address review comments * cmd: Fix the e2e flow for setting/updating configs * CHANGELOG * cmd: Make sure pricePerPixel can be specified with e notation Parse it directlty as a big.Rat from a raw string, like I was doing for pricePerUnit in some places. * Fix tests Turns out tests were not running on my branch due to base branch * go fmt * core: Fix typo in comment * cmd,server: Use 3 decimal points when logging PPP Found out that's officially supported precision on the discovery logic, so let's reflect that here. --- CHANGELOG_PENDING.md | 2 + cmd/livepeer/livepeer.go | 11 +- cmd/livepeer/starter/starter.go | 163 ++++++++++++---- cmd/livepeer/starter/starter_test.go | 92 ++++++++- cmd/livepeer_cli/wizard_broadcast.go | 22 ++- cmd/livepeer_cli/wizard_stats.go | 30 +-- cmd/livepeer_cli/wizard_transcoder.go | 49 ++--- core/autoconvertedprice.go | 139 ++++++++++++++ core/autoconvertedprice_test.go | 258 ++++++++++++++++++++++++++ core/livepeernode.go | 22 ++- core/livepeernode_test.go | 12 +- core/orch_test.go | 44 ++--- discovery/discovery_test.go | 8 +- eth/watchers/pricefeedwatcher.go | 146 ++++++++++----- eth/watchers/pricefeedwatcher_test.go | 83 ++++++--- server/broadcast.go | 15 +- server/handlers.go | 103 +++++----- server/handlers_test.go | 29 +-- server/rpc_test.go | 8 +- server/segment_rpc_test.go | 2 +- test/e2e/e2e.go | 2 +- 21 files changed, 976 insertions(+), 264 deletions(-) create mode 100644 core/autoconvertedprice.go create mode 100644 core/autoconvertedprice_test.go diff --git a/CHANGELOG_PENDING.md b/CHANGELOG_PENDING.md index 3ca5044811..df9d710ef8 100644 --- a/CHANGELOG_PENDING.md +++ b/CHANGELOG_PENDING.md @@ -8,6 +8,8 @@ #### General +- [#2981](https://github.com/livepeer/go-livepeer/pull/2981) Add support for prices in custom currencies like USD (@victorges) + #### Broadcaster #### Orchestrator diff --git a/cmd/livepeer/livepeer.go b/cmd/livepeer/livepeer.go index b9ed7a907d..d875a079f8 100755 --- a/cmd/livepeer/livepeer.go +++ b/cmd/livepeer/livepeer.go @@ -133,7 +133,7 @@ func parseLivepeerConfig() starter.LivepeerConfig { cfg.SelectPriceExpFactor = flag.Float64("selectPriceExpFactor", *cfg.SelectPriceExpFactor, "Expresses how significant a small change of price is for the selection algorithm; default 100") 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.Int("maxPricePerUnit", *cfg.MaxPricePerUnit, "The maximum transcoding price (in wei) per 'pixelsPerUnit' a broadcaster is willing to accept. If not set explicitly, broadcaster is willing to accept ANY price") + 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.MinPerfScore = flag.Float64("minPerfScore", *cfg.MinPerfScore, "The minimum orchestrator's performance score a broadcaster is willing to accept") // Transcoding: @@ -171,11 +171,12 @@ func parseLivepeerConfig() starter.LivepeerConfig { // Broadcaster deposit multiplier to determine max acceptable ticket faceValue cfg.DepositMultiplier = flag.Int("depositMultiplier", *cfg.DepositMultiplier, "The deposit multiplier used to determine max acceptable faceValue for PM tickets") // Orchestrator base pricing info - cfg.PricePerUnit = flag.Int("pricePerUnit", 0, "The price per 'pixelsPerUnit' amount pixels") - // Unit of pixels for both O's basePriceInfo and B's MaxBroadcastPrice - cfg.PixelsPerUnit = flag.Int("pixelsPerUnit", *cfg.PixelsPerUnit, "Amount of pixels per unit. Set to '> 1' to have smaller price granularity than 1 wei / pixel") + cfg.PricePerUnit = flag.String("pricePerUnit", "0", "The price per 'pixelsPerUnit' amount pixels. 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") + // Unit of pixels for both O's pricePerUnit and B's maxPricePerUnit + cfg.PixelsPerUnit = flag.String("pixelsPerUnit", *cfg.PixelsPerUnit, "Amount of pixels per unit. Set to '> 1' to have smaller price granularity than 1 wei / pixel") + cfg.PriceFeedAddr = flag.String("priceFeedAddr", *cfg.PriceFeedAddr, "ETH address of the Chainlink price feed contract. Used for custom currencies conversion on -pricePerUnit or -maxPricePerUnit") cfg.AutoAdjustPrice = flag.Bool("autoAdjustPrice", *cfg.AutoAdjustPrice, "Enable/disable automatic price adjustments based on the overhead for redeeming tickets") - cfg.PricePerBroadcaster = flag.String("pricePerBroadcaster", *cfg.PricePerBroadcaster, `json list of price per broadcaster or path to json config file. Example: {"broadcasters":[{"ethaddress":"address1","priceperunit":1000,"pixelsperunit":1},{"ethaddress":"address2","priceperunit":1200,"pixelsperunit":1}]}`) + cfg.PricePerBroadcaster = flag.String("pricePerBroadcaster", *cfg.PricePerBroadcaster, `json list of price per broadcaster or path to json config file. Example: {"broadcasters":[{"ethaddress":"address1","priceperunit":0.5,"currency":"USD","pixelsperunit":1000000000000},{"ethaddress":"address2","priceperunit":0.3,"currency":"USD","pixelsperunit":1000000000000}]}`) // Interval to poll for blocks cfg.BlockPollingInterval = flag.Int("blockPollingInterval", *cfg.BlockPollingInterval, "Interval in seconds at which different blockchain event services poll for blocks") // Redemption service diff --git a/cmd/livepeer/starter/starter.go b/cmd/livepeer/starter/starter.go index 8c5da0bf2a..2896d95431 100755 --- a/cmd/livepeer/starter/starter.go +++ b/cmd/livepeer/starter/starter.go @@ -15,6 +15,7 @@ import ( "os" "os/user" "path/filepath" + "regexp" "strconv" "strings" "time" @@ -32,6 +33,7 @@ import ( "github.com/livepeer/go-livepeer/eth" "github.com/livepeer/go-livepeer/eth/blockwatch" "github.com/livepeer/go-livepeer/eth/watchers" + "github.com/livepeer/go-livepeer/monitor" lpmon "github.com/livepeer/go-livepeer/monitor" "github.com/livepeer/go-livepeer/pm" "github.com/livepeer/go-livepeer/server" @@ -95,7 +97,7 @@ type LivepeerConfig struct { SelectPriceExpFactor *float64 OrchPerfStatsURL *string Region *string - MaxPricePerUnit *int + MaxPricePerUnit *string MinPerfScore *float64 MaxSessions *string CurrentManifest *bool @@ -118,8 +120,9 @@ type LivepeerConfig struct { MaxTicketEV *string MaxTotalEV *string DepositMultiplier *int - PricePerUnit *int - PixelsPerUnit *int + PricePerUnit *string + PixelsPerUnit *string + PriceFeedAddr *string AutoAdjustPrice *bool PricePerBroadcaster *string BlockPollingInterval *int @@ -192,8 +195,9 @@ func DefaultLivepeerConfig() LivepeerConfig { defaultMaxTicketEV := "3000000000000" defaultMaxTotalEV := "20000000000000" defaultDepositMultiplier := 1 - defaultMaxPricePerUnit := 0 - defaultPixelsPerUnit := 1 + defaultMaxPricePerUnit := "0" + defaultPixelsPerUnit := "1" + defaultPriceFeedAddr := "0x639Fe6ab55C921f74e7fac1ee960C0B6293ba612" // ETH / USD price feed address on Arbitrum Mainnet defaultAutoAdjustPrice := true defaultPricePerBroadcaster := "" defaultBlockPollingInterval := 5 @@ -278,6 +282,7 @@ func DefaultLivepeerConfig() LivepeerConfig { DepositMultiplier: &defaultDepositMultiplier, MaxPricePerUnit: &defaultMaxPricePerUnit, PixelsPerUnit: &defaultPixelsPerUnit, + PriceFeedAddr: &defaultPriceFeedAddr, AutoAdjustPrice: &defaultAutoAdjustPrice, PricePerBroadcaster: &defaultPricePerBroadcaster, BlockPollingInterval: &defaultBlockPollingInterval, @@ -712,6 +717,13 @@ func StartLivepeer(ctx context.Context, cfg LivepeerConfig) { go serviceRegistryWatcher.Watch() defer serviceRegistryWatcher.Stop() + core.PriceFeedWatcher, err = watchers.NewPriceFeedWatcher(backend, *cfg.PriceFeedAddr) + // The price feed watch loop is started on demand on first subscribe. + if err != nil { + glog.Errorf("Failed to set up price feed watcher: %v", err) + return + } + n.Balances = core.NewAddressBalances(cleanupInterval) defer n.Balances.StopCleanup() @@ -733,27 +745,44 @@ func StartLivepeer(ctx context.Context, cfg LivepeerConfig) { if *cfg.Orchestrator { // Set price per pixel base info - if *cfg.PixelsPerUnit <= 0 { + pixelsPerUnit, ok := new(big.Rat).SetString(*cfg.PixelsPerUnit) + if !ok || !pixelsPerUnit.IsInt() { + panic(fmt.Errorf("-pixelsPerUnit must be a valid integer, provided %v", *cfg.PixelsPerUnit)) + } + if pixelsPerUnit.Sign() <= 0 { // Can't divide by 0 - panic(fmt.Errorf("-pixelsPerUnit must be > 0, provided %d", *cfg.PixelsPerUnit)) + panic(fmt.Errorf("-pixelsPerUnit must be > 0, provided %v", *cfg.PixelsPerUnit)) } if cfg.PricePerUnit == nil { // Prevent orchestrators from unknowingly providing free transcoding panic(fmt.Errorf("-pricePerUnit must be set")) } - if *cfg.PricePerUnit < 0 { - panic(fmt.Errorf("-pricePerUnit must be >= 0, provided %d", *cfg.PricePerUnit)) + pricePerUnit, currency, err := parsePricePerUnit(*cfg.PricePerUnit) + if err != nil { + panic(fmt.Errorf("-pricePerUnit must be a valid integer with an optional currency, provided %v", *cfg.PricePerUnit)) + } else if pricePerUnit.Sign() < 0 { + panic(fmt.Errorf("-pricePerUnit must be >= 0, provided %s", pricePerUnit)) + } + pricePerPixel := new(big.Rat).Quo(pricePerUnit, pixelsPerUnit) + autoPrice, err := core.NewAutoConvertedPrice(currency, pricePerPixel, func(price *big.Rat) { + glog.Infof("Price: %v wei per pixel\n ", price.FloatString(3)) + }) + if err != nil { + panic(fmt.Errorf("Error converting price: %v", err)) } - n.SetBasePrice("default", big.NewRat(int64(*cfg.PricePerUnit), int64(*cfg.PixelsPerUnit))) - glog.Infof("Price: %d wei for %d pixels\n ", *cfg.PricePerUnit, *cfg.PixelsPerUnit) - - if *cfg.PricePerBroadcaster != "" { - ppb := getBroadcasterPrices(*cfg.PricePerBroadcaster) - for _, p := range ppb { - price := big.NewRat(p.PricePerUnit, p.PixelsPerUnit) - n.SetBasePrice(p.EthAddress, price) - glog.Infof("Price: %v set for broadcaster %v", price.RatString(), p.EthAddress) + n.SetBasePrice("default", autoPrice) + + broadcasterPrices := getBroadcasterPrices(*cfg.PricePerBroadcaster) + for _, p := range broadcasterPrices { + p := p + pricePerPixel := new(big.Rat).Quo(p.PricePerUnit, p.PixelsPerUnit) + autoPrice, err := core.NewAutoConvertedPrice(p.Currency, pricePerPixel, func(price *big.Rat) { + glog.Infof("Price: %v wei per pixel for broadcaster %v", price.FloatString(3), p.EthAddress) + }) + if err != nil { + panic(fmt.Errorf("Error converting price for broadcaster %s: %v", p.EthAddress, err)) } + n.SetBasePrice(p.EthAddress, autoPrice) } n.AutoSessionLimit = *cfg.MaxSessions == "auto" @@ -850,12 +879,30 @@ func StartLivepeer(ctx context.Context, cfg LivepeerConfig) { n.Sender = pm.NewSender(n.Eth, timeWatcher, senderWatcher, maxEV, maxTotalEV, *cfg.DepositMultiplier) - if *cfg.PixelsPerUnit <= 0 { + pixelsPerUnit, ok := new(big.Rat).SetString(*cfg.PixelsPerUnit) + if !ok || !pixelsPerUnit.IsInt() { + panic(fmt.Errorf("-pixelsPerUnit must be a valid integer, provided %v", *cfg.PixelsPerUnit)) + } + if pixelsPerUnit.Sign() <= 0 { // Can't divide by 0 - panic(fmt.Errorf("The amount of pixels per unit must be greater than 0, provided %d instead\n", *cfg.PixelsPerUnit)) + panic(fmt.Errorf("-pixelsPerUnit must be > 0, provided %v", *cfg.PixelsPerUnit)) + } + maxPricePerUnit, currency, err := parsePricePerUnit(*cfg.MaxPricePerUnit) + if err != nil { + panic(fmt.Errorf("The maximum price per unit must be a valid integer with an optional currency, provided %v instead\n", *cfg.MaxPricePerUnit)) } - if *cfg.MaxPricePerUnit > 0 { - server.BroadcastCfg.SetMaxPrice(big.NewRat(int64(*cfg.MaxPricePerUnit), int64(*cfg.PixelsPerUnit))) + if maxPricePerUnit.Sign() > 0 { + pricePerPixel := new(big.Rat).Quo(maxPricePerUnit, pixelsPerUnit) + autoPrice, err := core.NewAutoConvertedPrice(currency, pricePerPixel, func(price *big.Rat) { + if monitor.Enabled { + monitor.MaxTranscodingPrice(price) + } + glog.Infof("Maximum transcoding price: %v wei per pixel\n ", price.FloatString(3)) + }) + if err != nil { + panic(fmt.Errorf("Error converting price: %v", err)) + } + server.BroadcastCfg.SetMaxPrice(autoPrice) } else { glog.Infof("Maximum transcoding price per pixel is not greater than 0: %v, broadcaster is currently set to accept ANY price.\n", *cfg.MaxPricePerUnit) glog.Infoln("To update the broadcaster's maximum acceptable transcoding price per pixel, use the CLI or restart the broadcaster with the appropriate 'maxPricePerUnit' and 'pixelsPerUnit' values") @@ -1420,29 +1467,59 @@ func checkOrStoreChainID(dbh *common.DB, chainID *big.Int) error { return nil } -// Format of broadcasterPrices json -// {"broadcasters":[{"ethaddress":"address1","priceperunit":1000,"pixelsperunit":1}, {"ethaddress":"address2","priceperunit":2000,"pixelsperunit":3}]} -type BroadcasterPrices struct { - Prices []BroadcasterPrice `json:"broadcasters"` -} - type BroadcasterPrice struct { - EthAddress string `json:"ethaddress"` - PricePerUnit int64 `json:"priceperunit"` - PixelsPerUnit int64 `json:"pixelsperunit"` + EthAddress string + PricePerUnit *big.Rat + Currency string + PixelsPerUnit *big.Rat } func getBroadcasterPrices(broadcasterPrices string) []BroadcasterPrice { - var pricesSet BroadcasterPrices - prices, _ := common.ReadFromFile(broadcasterPrices) + if broadcasterPrices == "" { + return nil + } + + // Format of broadcasterPrices json + // {"broadcasters":[{"ethaddress":"address1","priceperunit":0.5,"currency":"USD","pixelsperunit":1}, {"ethaddress":"address2","priceperunit":0.3,"currency":"USD","pixelsperunit":3}]} + var pricesSet struct { + Broadcasters []struct { + EthAddress string `json:"ethaddress"` + // The fields below are specified as a number in the JSON, but we don't want to lose precision so we store the raw characters here and parse as a big.Rat. + // This also allows support for exponential notation for numbers, which is helpful for pricePerUnit which could be a value like 1e12. + PixelsPerUnit json.RawMessage `json:"pixelsperunit"` + PricePerUnit json.RawMessage `json:"priceperunit"` + Currency string `json:"currency"` + } `json:"broadcasters"` + } + pricesFileContent, _ := common.ReadFromFile(broadcasterPrices) - err := json.Unmarshal([]byte(prices), &pricesSet) + err := json.Unmarshal([]byte(pricesFileContent), &pricesSet) if err != nil { glog.Errorf("broadcaster prices could not be parsed: %s", err) return nil } - return pricesSet.Prices + prices := make([]BroadcasterPrice, len(pricesSet.Broadcasters)) + for i, p := range pricesSet.Broadcasters { + pixelsPerUnit, ok := new(big.Rat).SetString(string(p.PixelsPerUnit)) + if !ok { + glog.Errorf("Pixels per unit could not be parsed for broadcaster %v. must be a valid number, provided %s", p.EthAddress, p.PixelsPerUnit) + continue + } + pricePerUnit, ok := new(big.Rat).SetString(string(p.PricePerUnit)) + if !ok { + glog.Errorf("Price per unit could not be parsed for broadcaster %v. must be a valid number, provided %s", p.EthAddress, p.PricePerUnit) + continue + } + prices[i] = BroadcasterPrice{ + EthAddress: p.EthAddress, + Currency: p.Currency, + PricePerUnit: pricePerUnit, + PixelsPerUnit: pixelsPerUnit, + } + } + + return prices } func createSelectionAlgorithm(cfg LivepeerConfig) (common.SelectionAlgorithm, error) { @@ -1494,6 +1571,22 @@ func parseEthKeystorePath(ethKeystorePath string) (keystorePath, error) { return keystore, nil } +func parsePricePerUnit(pricePerUnitStr string) (*big.Rat, string, error) { + pricePerUnitRex := regexp.MustCompile(`^(\d+(\.\d+)?)([A-z][A-z0-9]*)?$`) + match := pricePerUnitRex.FindStringSubmatch(pricePerUnitStr) + if match == nil { + return nil, "", fmt.Errorf("price must be in the format of , provided %v", pricePerUnitStr) + } + price, currency := match[1], match[3] + + pricePerUnit, ok := new(big.Rat).SetString(price) + if !ok { + return nil, "", fmt.Errorf("price must be a valid number, provided %v", match[1]) + } + + return pricePerUnit, currency, nil +} + func refreshOrchPerfScoreLoop(ctx context.Context, region string, orchPerfScoreURL string, score *common.PerfScore) { for { refreshOrchPerfScore(region, orchPerfScoreURL, score) diff --git a/cmd/livepeer/starter/starter_test.go b/cmd/livepeer/starter/starter_test.go index 18a08633a2..45d3620b8e 100644 --- a/cmd/livepeer/starter/starter_test.go +++ b/cmd/livepeer/starter/starter_test.go @@ -96,8 +96,8 @@ func TestParseGetBroadcasterPrices(t *testing.T) { assert.NotNil(prices) assert.Equal(2, len(prices)) - price1 := big.NewRat(prices[0].PricePerUnit, prices[0].PixelsPerUnit) - price2 := big.NewRat(prices[1].PricePerUnit, prices[1].PixelsPerUnit) + price1 := new(big.Rat).Quo(prices[0].PricePerUnit, prices[0].PixelsPerUnit) + price2 := new(big.Rat).Quo(prices[1].PricePerUnit, prices[1].PixelsPerUnit) assert.Equal(big.NewRat(1000, 1), price1) assert.Equal(big.NewRat(2000, 3), price2) } @@ -295,3 +295,91 @@ func TestUpdatePerfScore(t *testing.T) { } require.Equal(t, expScores, scores.Scores) } + +func TestParsePricePerUnit(t *testing.T) { + tests := []struct { + name string + pricePerUnitStr string + expectedPrice *big.Rat + expectedCurrency string + expectError bool + }{ + { + name: "Valid input with integer price", + pricePerUnitStr: "100USD", + expectedPrice: big.NewRat(100, 1), + expectedCurrency: "USD", + expectError: false, + }, + { + name: "Valid input with fractional price", + pricePerUnitStr: "0.13USD", + expectedPrice: big.NewRat(13, 100), + expectedCurrency: "USD", + expectError: false, + }, + { + name: "Valid input with decimal price", + pricePerUnitStr: "99.99EUR", + expectedPrice: big.NewRat(9999, 100), + expectedCurrency: "EUR", + expectError: false, + }, + { + name: "Lower case currency", + pricePerUnitStr: "99.99eur", + expectedPrice: big.NewRat(9999, 100), + expectedCurrency: "eur", + expectError: false, + }, + { + name: "Currency with numbers", + pricePerUnitStr: "420DOG3", + expectedPrice: big.NewRat(420, 1), + expectedCurrency: "DOG3", + expectError: false, + }, + { + name: "No specified currency, empty currency", + pricePerUnitStr: "100", + expectedPrice: big.NewRat(100, 1), + expectedCurrency: "", + expectError: false, + }, + { + name: "Explicit wei currency", + pricePerUnitStr: "100wei", + expectedPrice: big.NewRat(100, 1), + expectedCurrency: "wei", + expectError: false, + }, + { + name: "Invalid number", + pricePerUnitStr: "abcUSD", + expectedPrice: nil, + expectedCurrency: "", + expectError: true, + }, + { + name: "Negative price", + pricePerUnitStr: "-100USD", + expectedPrice: nil, + expectedCurrency: "", + expectError: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + price, currency, err := parsePricePerUnit(tt.pricePerUnitStr) + + if tt.expectError { + assert.Error(t, err) + } else { + require.NoError(t, err) + assert.True(t, tt.expectedPrice.Cmp(price) == 0) + assert.Equal(t, tt.expectedCurrency, currency) + } + }) + } +} diff --git a/cmd/livepeer_cli/wizard_broadcast.go b/cmd/livepeer_cli/wizard_broadcast.go index b7967b0dd6..8f2c59e917 100644 --- a/cmd/livepeer_cli/wizard_broadcast.go +++ b/cmd/livepeer_cli/wizard_broadcast.go @@ -57,10 +57,14 @@ func (w *wizard) setBroadcastConfig() { fmt.Printf("eg. 1 wei / 10 pixels = 0,1 wei per pixel \n") fmt.Printf("\n") fmt.Printf("Enter amount of pixels that make up a single unit (default: 1 pixel) - ") - pixelsPerUnit := w.readDefaultInt(1) + // Read numbers as strings not to lose precision and support big numbers + pixelsPerUnit := w.readDefaultString("1") fmt.Printf("\n") - fmt.Printf("Enter the maximum price to pay for %d pixels in Wei (required) - ", pixelsPerUnit) - maxPricePerUnit := w.readDefaultInt(0) + fmt.Printf("Enter the currency for the price per unit (default: Wei) - ") + currency := w.readDefaultString("Wei") + fmt.Printf("\n") + fmt.Printf("Enter the maximum price to pay for %s pixels in %s (default: 0) - ", pixelsPerUnit, currency) + maxPricePerUnit := w.readDefaultString("0") opts := w.allTranscodingOptions() if opts == nil { @@ -77,12 +81,18 @@ func (w *wizard) setBroadcastConfig() { } val := url.Values{ - "pixelsPerUnit": {fmt.Sprintf("%v", strconv.Itoa(pixelsPerUnit))}, - "maxPricePerUnit": {fmt.Sprintf("%v", strconv.Itoa(maxPricePerUnit))}, + "pixelsPerUnit": {fmt.Sprintf("%v", pixelsPerUnit)}, + "currency": {fmt.Sprintf("%v", currency)}, + "maxPricePerUnit": {fmt.Sprintf("%v", maxPricePerUnit)}, "transcodingOptions": {fmt.Sprintf("%v", transOpts)}, } - httpPostWithParams(fmt.Sprintf("http://%v:%v/setBroadcastConfig", w.host, w.httpPort), val) + result, ok := httpPostWithParams(fmt.Sprintf("http://%v:%v/setBroadcastConfig", w.host, w.httpPort), val) + if !ok { + fmt.Printf("Error applying configuration: %s\n", result) + } else { + fmt.Printf("Configuration applied successfully\n") + } } func (w *wizard) idListToVideoProfileList(idList string, opts map[int]string) (string, error) { diff --git a/cmd/livepeer_cli/wizard_stats.go b/cmd/livepeer_cli/wizard_stats.go index 8a251fc9a4..bea3b07908 100644 --- a/cmd/livepeer_cli/wizard_stats.go +++ b/cmd/livepeer_cli/wizard_stats.go @@ -171,14 +171,10 @@ func (w *wizard) broadcastStats() { } price, transcodingOptions := w.getBroadcastConfig() - priceString := "n/a" - if price != nil { - priceString = fmt.Sprintf("%v wei / %v pixels", price.Num().Int64(), price.Denom().Int64()) - } table := tablewriter.NewWriter(os.Stdout) data := [][]string{ - {"Max Price Per Pixel", priceString}, + {"Max Price Per Pixel", formatPricePerPixel(price)}, {"Broadcast Transcoding Options", transcodingOptions}, {"Deposit", eth.FormatUnits(sender.Deposit, "ETH")}, {"Reserve", eth.FormatUnits(sender.Reserve.FundsRemaining, "ETH")}, @@ -227,7 +223,7 @@ func (w *wizard) orchestratorStats() { {"Reward Cut (%)", eth.FormatPerc(t.RewardCut)}, {"Fee Cut (%)", eth.FormatPerc(flipPerc(t.FeeShare))}, {"Last Reward Round", t.LastRewardRound.String()}, - {"Base price per pixel", fmt.Sprintf("%v wei / %v pixels", priceInfo.Num(), priceInfo.Denom())}, + {"Base price per pixel", formatPricePerPixel(priceInfo)}, {"Base price for broadcasters", b_prices}, } @@ -488,7 +484,9 @@ func (w *wizard) getBroadcasterPrices() (string, error) { return "", err } - var status map[string]interface{} + var status struct { + BroadcasterPrices map[string]*big.Rat `json:"BroadcasterPrices"` + } err = json.Unmarshal(result, &status) if err != nil { return "", err @@ -496,13 +494,21 @@ func (w *wizard) getBroadcasterPrices() (string, error) { prices := new(bytes.Buffer) - if broadcasterPrices, ok := status["BroadcasterPrices"]; ok { - for b, p := range broadcasterPrices.(map[string]interface{}) { - if b != "default" { - fmt.Fprintf(prices, "%s: %s per pixel\n", b, p) - } + for b, p := range status.BroadcasterPrices { + if b != "default" { + fmt.Fprintf(prices, "%s: %s\n", b, formatPricePerPixel(p)) } } return prices.String(), nil } + +func formatPricePerPixel(price *big.Rat) string { + if price == nil { + return "n/a" + } + if price.IsInt() { + return fmt.Sprintf("%v wei/pixel", price.RatString()) + } + return fmt.Sprintf("%v wei/pixel (%v/%v)", price.FloatString(3), price.Num(), price.Denom()) +} diff --git a/cmd/livepeer_cli/wizard_transcoder.go b/cmd/livepeer_cli/wizard_transcoder.go index b25644a744..2416aadbd0 100644 --- a/cmd/livepeer_cli/wizard_transcoder.go +++ b/cmd/livepeer_cli/wizard_transcoder.go @@ -43,13 +43,7 @@ func myHostPort() string { return "https://" + ip + ":" + defaultRPCPort } -func (w *wizard) promptOrchestratorConfig() (float64, float64, int, int, string) { - var ( - blockRewardCut float64 - feeCut float64 - addr string - ) - +func (w *wizard) promptOrchestratorConfig() (blockRewardCut, feeCut float64, pricePerUnit, currency, pixelsPerUnit, serviceURI string) { orch, _, err := w.getOrchestratorInfo() if err != nil || orch == nil { fmt.Println("unable to get current reward cut and fee cut") @@ -68,17 +62,23 @@ func (w *wizard) promptOrchestratorConfig() (float64, float64, int, int, string) fmt.Println("eg. 1 wei / 10 pixels = 0,1 wei per pixel") fmt.Println() fmt.Printf("Enter amount of pixels that make up a single unit (default: 1 pixel) ") - pixelsPerUnit := w.readDefaultInt(1) - fmt.Printf("Enter the price for %d pixels in Wei (required) ", pixelsPerUnit) - pricePerUnit := w.readDefaultInt(0) + // Read numbers as strings not to lose precision and support big numbers + pixelsPerUnit = w.readDefaultString("1") + fmt.Println() + fmt.Printf("Enter the currency for the price per unit (default: Wei) ") + currency = w.readDefaultString("Wei") + fmt.Println() + fmt.Printf("Enter the price for %s pixels in %s (default: 0) ", pixelsPerUnit, currency) + pricePerUnit = w.readDefaultString("0") + var addr string if orch.ServiceURI == "" { addr = myHostPort() } else { addr = orch.ServiceURI } fmt.Printf("Enter the public host:port of node (default: %v)", addr) - serviceURI := w.readStringAndValidate(func(in string) (string, error) { + serviceURI = w.readStringAndValidate(func(in string) (string, error) { if "" == in { in = addr } @@ -92,7 +92,7 @@ func (w *wizard) promptOrchestratorConfig() (float64, float64, int, int, string) return in, nil }) - return blockRewardCut, 100 - feeCut, pricePerUnit, pixelsPerUnit, serviceURI + return blockRewardCut, 100 - feeCut, pricePerUnit, currency, pixelsPerUnit, serviceURI } func (w *wizard) activateOrchestrator() { @@ -196,13 +196,14 @@ func (w *wizard) setOrchestratorConfig() { } func (w *wizard) getOrchestratorConfigFormValues() url.Values { - blockRewardCut, feeShare, pricePerUnit, pixelsPerUnit, serviceURI := w.promptOrchestratorConfig() + blockRewardCut, feeShare, pricePerUnit, currency, pixelsPerUnit, serviceURI := w.promptOrchestratorConfig() return url.Values{ "blockRewardCut": {fmt.Sprintf("%v", blockRewardCut)}, "feeShare": {fmt.Sprintf("%v", feeShare)}, - "pricePerUnit": {fmt.Sprintf("%v", strconv.Itoa(pricePerUnit))}, - "pixelsPerUnit": {fmt.Sprintf("%v", strconv.Itoa(pixelsPerUnit))}, + "pricePerUnit": {fmt.Sprintf("%v", pricePerUnit)}, + "currency": {fmt.Sprintf("%v", currency)}, + "pixelsPerUnit": {fmt.Sprintf("%v", pixelsPerUnit)}, "serviceURI": {fmt.Sprintf("%v", serviceURI)}, } } @@ -319,18 +320,22 @@ func (w *wizard) setPriceForBroadcaster() { return in, nil }) - fmt.Println("Enter price per unit:") - price := w.readDefaultInt(0) - fmt.Println("Enter pixels per unit:") - pixels := w.readDefaultInt(1) + fmt.Println("Enter pixels per unit (default: 1 pixel)") + // Read numbers as strings not to lose precision and support big numbers + pixels := w.readDefaultString("1") + fmt.Println("Enter currency for the price per unit (default: Wei)") + currency := w.readDefaultString("Wei") + fmt.Println("Enter price per unit (default: 0)") + price := w.readDefaultString("0") data := url.Values{ - "pricePerUnit": {fmt.Sprintf("%v", strconv.Itoa(price))}, - "pixelsPerUnit": {fmt.Sprintf("%v", strconv.Itoa(pixels))}, + "pricePerUnit": {fmt.Sprintf("%v", price)}, + "currency": {fmt.Sprintf("%v", currency)}, + "pixelsPerUnit": {fmt.Sprintf("%v", pixels)}, "broadcasterEthAddr": {fmt.Sprintf("%v", ethaddr)}, } result, ok := httpPostWithParams(fmt.Sprintf("http://%v:%v/setPriceForBroadcaster", w.host, w.httpPort), data) if ok { - fmt.Printf("Price for broadcaster %v set to %v gwei per %v pixels", ethaddr, price, pixels) + fmt.Printf("Price for broadcaster %v set to %v %v per %v pixels", ethaddr, price, currency, pixels) return } else { fmt.Printf("Error setting price for broadcaster: %v", result) diff --git a/core/autoconvertedprice.go b/core/autoconvertedprice.go new file mode 100644 index 0000000000..b248937db1 --- /dev/null +++ b/core/autoconvertedprice.go @@ -0,0 +1,139 @@ +package core + +import ( + "context" + "fmt" + "math/big" + "strings" + "sync" + + "github.com/livepeer/go-livepeer/eth" + "github.com/livepeer/go-livepeer/eth/watchers" +) + +// PriceFeedWatcher is a global instance of a PriceFeedWatcher. It must be +// initialized before creating an AutoConvertedPrice instance. +var PriceFeedWatcher watchers.PriceFeedWatcher + +// Number of wei in 1 ETH +var weiPerETH = big.NewRat(1e18, 1) + +// AutoConvertedPrice represents a price that is automatically converted to wei +// based on the current price of ETH in a given currency. It uses the static +// PriceFeedWatcher that must be configured before creating an instance. +type AutoConvertedPrice struct { + cancelSubscription func() + onUpdate func(*big.Rat) + basePrice *big.Rat + + mu sync.RWMutex + current *big.Rat +} + +// NewFixedPrice creates a new AutoConvertedPrice with a fixed price in wei. +func NewFixedPrice(price *big.Rat) *AutoConvertedPrice { + return &AutoConvertedPrice{current: price} +} + +// NewAutoConvertedPrice creates a new AutoConvertedPrice instance with the given +// currency and base price. The onUpdate function is optional and gets called +// whenever the price is updated (also with the initial price). The Stop function +// must be called to free resources when the price is no longer needed. +func NewAutoConvertedPrice(currency string, basePrice *big.Rat, onUpdate func(*big.Rat)) (*AutoConvertedPrice, error) { + if onUpdate == nil { + onUpdate = func(*big.Rat) {} + } + + // Default currency (wei/eth) doesn't need the conversion loop + if lcurr := strings.ToLower(currency); lcurr == "" || lcurr == "wei" || lcurr == "eth" { + price := basePrice + if lcurr == "eth" { + price = new(big.Rat).Mul(basePrice, weiPerETH) + } + onUpdate(price) + return NewFixedPrice(price), nil + } + + if PriceFeedWatcher == nil { + return nil, fmt.Errorf("PriceFeedWatcher is not initialized") + } + + base, quote, err := PriceFeedWatcher.Currencies() + if err != nil { + return nil, fmt.Errorf("error getting price feed currencies: %v", err) + } + base, quote, currency = strings.ToUpper(base), strings.ToUpper(quote), strings.ToUpper(currency) + if base != "ETH" && quote != "ETH" { + return nil, fmt.Errorf("price feed does not have ETH as a currency (%v/%v)", base, quote) + } + if base != currency && quote != currency { + return nil, fmt.Errorf("price feed does not have %v as a currency (%v/%v)", currency, base, quote) + } + + currencyPrice, err := PriceFeedWatcher.Current() + if err != nil { + return nil, fmt.Errorf("error getting current price data: %v", err) + } + + ctx, cancel := context.WithCancel(context.Background()) + price := &AutoConvertedPrice{ + cancelSubscription: cancel, + onUpdate: onUpdate, + basePrice: basePrice, + current: new(big.Rat).Mul(basePrice, currencyToWeiMultiplier(currencyPrice, base)), + } + // Trigger the initial update with the current price + onUpdate(price.current) + + price.startAutoConvertLoop(ctx, base) + + return price, nil +} + +// Value returns the current price in wei. +func (a *AutoConvertedPrice) Value() *big.Rat { + a.mu.RLock() + defer a.mu.RUnlock() + return a.current +} + +// Stop unsubscribes from the price feed and frees resources from the +// auto-conversion loop. +func (a *AutoConvertedPrice) Stop() { + a.mu.Lock() + defer a.mu.Unlock() + if a.cancelSubscription != nil { + a.cancelSubscription() + a.cancelSubscription = nil + } +} + +func (a *AutoConvertedPrice) startAutoConvertLoop(ctx context.Context, baseCurrency string) { + priceUpdated := make(chan eth.PriceData, 1) + PriceFeedWatcher.Subscribe(ctx, priceUpdated) + go func() { + for { + select { + case <-ctx.Done(): + return + case currencyPrice := <-priceUpdated: + a.mu.Lock() + a.current = new(big.Rat).Mul(a.basePrice, currencyToWeiMultiplier(currencyPrice, baseCurrency)) + a.mu.Unlock() + + a.onUpdate(a.current) + } + } + }() +} + +// currencyToWeiMultiplier calculates the multiplier to convert the value +// specified in the custom currency to wei. +func currencyToWeiMultiplier(data eth.PriceData, baseCurrency string) *big.Rat { + ethMultipler := data.Price + if baseCurrency == "ETH" { + // Invert the multiplier if the quote is in the form ETH / X + ethMultipler = new(big.Rat).Inv(ethMultipler) + } + return new(big.Rat).Mul(ethMultipler, weiPerETH) +} diff --git a/core/autoconvertedprice_test.go b/core/autoconvertedprice_test.go new file mode 100644 index 0000000000..54db6cfde0 --- /dev/null +++ b/core/autoconvertedprice_test.go @@ -0,0 +1,258 @@ +package core + +import ( + "context" + "math/big" + "testing" + "time" + + "github.com/livepeer/go-livepeer/eth" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" +) + +func TestNewAutoConvertedPrice(t *testing.T) { + t.Run("PriceFeedWatcher not initialized", func(t *testing.T) { + _, err := NewAutoConvertedPrice("USD", big.NewRat(1, 1), nil) + require.Error(t, err) + }) + + watcherMock := NewPriceFeedWatcherMock(t) + PriceFeedWatcher = watcherMock + watcherMock.On("Currencies").Return("ETH", "USD", nil) + + t.Run("Fixed price for wei", func(t *testing.T) { + price, err := NewAutoConvertedPrice("wei", big.NewRat(1, 1), nil) + require.NoError(t, err) + require.Equal(t, big.NewRat(1, 1), price.Value()) + require.Nil(t, price.cancelSubscription) + }) + + t.Run("Auto-converted price for ETH", func(t *testing.T) { + price, err := NewAutoConvertedPrice("ETH", big.NewRat(2, 1), nil) + require.NoError(t, err) + require.Equal(t, big.NewRat(2e18, 1), price.Value()) // 2 ETH in wei + require.Nil(t, price.cancelSubscription) + }) + + t.Run("Auto-converted price for USD", func(t *testing.T) { + watcherMock.On("Current").Return(eth.PriceData{Price: big.NewRat(100, 1)}, nil) + watcherMock.On("Subscribe", mock.Anything, mock.Anything).Once() + price, err := NewAutoConvertedPrice("USD", big.NewRat(2, 1), nil) + require.NoError(t, err) + require.Equal(t, big.NewRat(2e16, 1), price.Value()) // 2 USD * 1/100 ETH/USD + require.NotNil(t, price.cancelSubscription) + price.Stop() + }) + + t.Run("Currency not supported by feed", func(t *testing.T) { + _, err := NewAutoConvertedPrice("GBP", big.NewRat(1, 1), nil) + require.Error(t, err) + }) + + t.Run("Currency ETH not supported by feed", func(t *testing.T) { + // set up a new mock to change the currencies returned + watcherMock := NewPriceFeedWatcherMock(t) + PriceFeedWatcher = watcherMock + watcherMock.On("Currencies").Return("wei", "USD", nil) + + _, err := NewAutoConvertedPrice("USD", big.NewRat(1, 1), nil) + require.Error(t, err) + }) + + t.Run("Auto-converted price for inverted quote", func(t *testing.T) { + // set up a new mock to change the currencies returned + watcherMock := NewPriceFeedWatcherMock(t) + PriceFeedWatcher = watcherMock + watcherMock.On("Currencies").Return("USD", "ETH", nil) + watcherMock.On("Current").Return(eth.PriceData{Price: big.NewRat(1, 420)}, nil) + watcherMock.On("Subscribe", mock.Anything, mock.Anything).Once() + price, err := NewAutoConvertedPrice("USD", big.NewRat(66, 1), nil) + require.NoError(t, err) + require.Equal(t, big.NewRat(11e17, 7), price.Value()) // 66 USD * 1/420 ETH/USD + require.NotNil(t, price.cancelSubscription) + price.Stop() + }) +} + +func TestAutoConvertedPrice_Update(t *testing.T) { + require := require.New(t) + watcherMock := NewPriceFeedWatcherMock(t) + PriceFeedWatcher = watcherMock + + watcherMock.On("Currencies").Return("ETH", "USD", nil) + watcherMock.On("Current").Return(eth.PriceData{Price: big.NewRat(3000, 1)}, nil) + + priceUpdatedChan := make(chan *big.Rat, 1) + onUpdate := func(price *big.Rat) { + priceUpdatedChan <- price + } + + var sink chan<- eth.PriceData + watcherMock.On("Subscribe", mock.Anything, mock.Anything).Run(func(args mock.Arguments) { + sink = args.Get(1).(chan<- eth.PriceData) + }).Once() + + price, err := NewAutoConvertedPrice("USD", big.NewRat(50, 1), onUpdate) + require.NoError(err) + require.NotNil(t, price.cancelSubscription) + defer price.Stop() + watcherMock.AssertExpectations(t) + + require.Equal(big.NewRat(5e16, 3), price.Value()) // 50 USD * 1/3000 ETH/USD + require.Equal(big.NewRat(5e16, 3), <-priceUpdatedChan) // initial update must be sent + + // Simulate a price update + sink <- eth.PriceData{Price: big.NewRat(6000, 1)} + + select { + case updatedPrice := <-priceUpdatedChan: + require.Equal(big.NewRat(5e16, 6), updatedPrice) // 50 USD * 1/6000 USD/ETH + require.Equal(big.NewRat(5e16, 6), price.Value()) // must also udpate current value + case <-time.After(time.Second): + t.Fatal("Expected price update not received") + } +} + +func TestAutoConvertedPrice_Stop(t *testing.T) { + require := require.New(t) + watcherMock := NewPriceFeedWatcherMock(t) + PriceFeedWatcher = watcherMock + + watcherMock.On("Currencies").Return("ETH", "USD", nil) + watcherMock.On("Current").Return(eth.PriceData{Price: big.NewRat(100, 1)}, nil) + + var subsCtx context.Context + watcherMock.On("Subscribe", mock.Anything, mock.Anything).Run(func(args mock.Arguments) { + subsCtx = args.Get(0).(context.Context) + }).Once() + + price, err := NewAutoConvertedPrice("USD", big.NewRat(50, 1), nil) + require.NoError(err) + require.NotNil(t, price.cancelSubscription) + + price.Stop() + require.Nil(price.cancelSubscription) + require.Error(subsCtx.Err()) +} + +func TestCurrencyToWeiMultiplier(t *testing.T) { + tests := []struct { + name string + data eth.PriceData + baseCurrency string + expectedWei *big.Rat + }{ + { + name: "Base currency is ETH", + data: eth.PriceData{Price: big.NewRat(500, 1)}, // 500 USD per ETH + baseCurrency: "ETH", + expectedWei: big.NewRat(1e18, 500), // (1 / 500 USD/ETH) * 1e18 wei/ETH + }, + { + name: "Base currency is not ETH", + data: eth.PriceData{Price: big.NewRat(1, 2000)}, // 1/2000 ETH per USD + baseCurrency: "USD", + expectedWei: big.NewRat(5e14, 1), // (1 * 1/2000 ETH/USD) * 1e18 wei/ETH + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result := currencyToWeiMultiplier(tt.data, tt.baseCurrency) + assert.Equal(t, 0, tt.expectedWei.Cmp(result)) + }) + } +} + +// Auto-generated code from here down. +// +// Code generated by mockery v2.42.1. DO NOT EDIT. + +// PriceFeedWatcherMock is an autogenerated mock type for the PriceFeedWatcher type +type PriceFeedWatcherMock struct { + mock.Mock +} + +// Currencies provides a mock function with given fields: +func (_m *PriceFeedWatcherMock) Currencies() (string, string, error) { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Currencies") + } + + var r0 string + var r1 string + var r2 error + if rf, ok := ret.Get(0).(func() (string, string, error)); ok { + return rf() + } + if rf, ok := ret.Get(0).(func() string); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(string) + } + + if rf, ok := ret.Get(1).(func() string); ok { + r1 = rf() + } else { + r1 = ret.Get(1).(string) + } + + if rf, ok := ret.Get(2).(func() error); ok { + r2 = rf() + } else { + r2 = ret.Error(2) + } + + return r0, r1, r2 +} + +// Current provides a mock function with given fields: +func (_m *PriceFeedWatcherMock) Current() (eth.PriceData, error) { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Current") + } + + var r0 eth.PriceData + var r1 error + if rf, ok := ret.Get(0).(func() (eth.PriceData, error)); ok { + return rf() + } + if rf, ok := ret.Get(0).(func() eth.PriceData); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(eth.PriceData) + } + + if rf, ok := ret.Get(1).(func() error); ok { + r1 = rf() + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// Subscribe provides a mock function with given fields: ctx, sink +func (_m *PriceFeedWatcherMock) Subscribe(ctx context.Context, sink chan<- eth.PriceData) { + _m.Called(ctx, sink) +} + +// NewPriceFeedWatcherMock creates a new instance of PriceFeedWatcherMock. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewPriceFeedWatcherMock(t interface { + mock.TestingT + Cleanup(func()) +}) *PriceFeedWatcherMock { + mock := &PriceFeedWatcherMock{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/livepeernode.go b/core/livepeernode.go index 57b1055e39..f4741aae93 100644 --- a/core/livepeernode.go +++ b/core/livepeernode.go @@ -93,7 +93,7 @@ type LivepeerNode struct { StorageConfigs map[string]*transcodeConfig storageMutex *sync.RWMutex // Transcoder private fields - priceInfo map[string]*big.Rat + priceInfo map[string]*AutoConvertedPrice serviceURI url.URL segmentMutex *sync.RWMutex } @@ -109,7 +109,7 @@ func NewLivepeerNode(e eth.LivepeerEthClient, wd string, dbh *common.DB) (*Livep SegmentChans: make(map[ManifestID]SegmentChan), segmentMutex: &sync.RWMutex{}, Capabilities: &Capabilities{capacities: map[Capability]int{}}, - priceInfo: make(map[string]*big.Rat), + priceInfo: make(map[string]*AutoConvertedPrice), StorageConfigs: make(map[string]*transcodeConfig), storageMutex: &sync.RWMutex{}, }, nil @@ -128,12 +128,16 @@ func (n *LivepeerNode) SetServiceURI(newUrl *url.URL) { } // SetBasePrice sets the base price for an orchestrator on the node -func (n *LivepeerNode) SetBasePrice(b_eth_addr string, price *big.Rat) { +func (n *LivepeerNode) SetBasePrice(b_eth_addr string, price *AutoConvertedPrice) { addr := strings.ToLower(b_eth_addr) n.mu.Lock() defer n.mu.Unlock() + prevPrice := n.priceInfo[addr] n.priceInfo[addr] = price + if prevPrice != nil { + prevPrice.Stop() + } } // GetBasePrice gets the base price for an orchestrator @@ -142,14 +146,22 @@ func (n *LivepeerNode) GetBasePrice(b_eth_addr string) *big.Rat { n.mu.RLock() defer n.mu.RUnlock() - return n.priceInfo[addr] + price := n.priceInfo[addr] + if price == nil { + return nil + } + return price.Value() } func (n *LivepeerNode) GetBasePrices() map[string]*big.Rat { n.mu.RLock() defer n.mu.RUnlock() - return n.priceInfo + prices := make(map[string]*big.Rat) + for addr, price := range n.priceInfo { + prices[addr] = price.Value() + } + return prices } // SetMaxFaceValue sets the faceValue upper limit for tickets received diff --git a/core/livepeernode_test.go b/core/livepeernode_test.go index 259992f892..230f8dd421 100644 --- a/core/livepeernode_test.go +++ b/core/livepeernode_test.go @@ -162,8 +162,8 @@ func TestSetAndGetBasePrice(t *testing.T) { price := big.NewRat(1, 1) - n.SetBasePrice("default", price) - assert.Zero(n.priceInfo["default"].Cmp(price)) + n.SetBasePrice("default", NewFixedPrice(price)) + assert.Zero(n.priceInfo["default"].Value().Cmp(price)) assert.Zero(n.GetBasePrice("default").Cmp(price)) assert.Zero(n.GetBasePrices()["default"].Cmp(price)) @@ -172,10 +172,10 @@ func TestSetAndGetBasePrice(t *testing.T) { price1 := big.NewRat(2, 1) price2 := big.NewRat(3, 1) - n.SetBasePrice(addr1, price1) - n.SetBasePrice(addr2, price2) - assert.Zero(n.priceInfo[addr1].Cmp(price1)) - assert.Zero(n.priceInfo[addr2].Cmp(price2)) + n.SetBasePrice(addr1, NewFixedPrice(price1)) + n.SetBasePrice(addr2, NewFixedPrice(price2)) + assert.Zero(n.priceInfo[addr1].Value().Cmp(price1)) + assert.Zero(n.priceInfo[addr2].Value().Cmp(price2)) assert.Zero(n.GetBasePrices()[addr1].Cmp(price1)) assert.Zero(n.GetBasePrices()[addr2].Cmp(price2)) } diff --git a/core/orch_test.go b/core/orch_test.go index 981661433d..dcc8a6c2d9 100644 --- a/core/orch_test.go +++ b/core/orch_test.go @@ -704,7 +704,7 @@ func TestProcessPayment_GivenRecipientError_ReturnsNil(t *testing.T) { } orch := NewOrchestrator(n, rm) orch.address = addr - orch.node.SetBasePrice("default", big.NewRat(0, 1)) + orch.node.SetBasePrice("default", NewFixedPrice(big.NewRat(0, 1))) recipient.On("TxCostMultiplier", mock.Anything).Return(big.NewRat(1, 1), nil) recipient.On("ReceiveTicket", mock.Anything, mock.Anything, mock.Anything).Return("", false, nil) @@ -785,7 +785,7 @@ func TestProcessPayment_ActiveOrchestrator(t *testing.T) { } orch := NewOrchestrator(n, rm) orch.address = addr - orch.node.SetBasePrice("default", big.NewRat(0, 1)) + orch.node.SetBasePrice("default", NewFixedPrice(big.NewRat(0, 1))) // orchestrator inactive -> error err := orch.ProcessPayment(context.Background(), defaultPayment(t), ManifestID("some manifest")) @@ -856,7 +856,7 @@ func TestProcessPayment_GivenLosingTicket_DoesNotRedeem(t *testing.T) { } orch := NewOrchestrator(n, rm) orch.address = addr - orch.node.SetBasePrice("default", big.NewRat(0, 1)) + orch.node.SetBasePrice("default", NewFixedPrice(big.NewRat(0, 1))) recipient.On("TxCostMultiplier", mock.Anything).Return(big.NewRat(1, 1), nil) recipient.On("ReceiveTicket", mock.Anything, mock.Anything, mock.Anything).Return("some sessionID", false, nil) @@ -888,7 +888,7 @@ func TestProcessPayment_GivenWinningTicket_RedeemError(t *testing.T) { } orch := NewOrchestrator(n, rm) orch.address = addr - orch.node.SetBasePrice("default", big.NewRat(0, 1)) + orch.node.SetBasePrice("default", NewFixedPrice(big.NewRat(0, 1))) manifestID := ManifestID("some manifest") sessionID := "some sessionID" @@ -928,7 +928,7 @@ func TestProcessPayment_GivenWinningTicket_Redeems(t *testing.T) { } orch := NewOrchestrator(n, rm) orch.address = addr - orch.node.SetBasePrice("default", big.NewRat(0, 1)) + orch.node.SetBasePrice("default", NewFixedPrice(big.NewRat(0, 1))) manifestID := ManifestID("some manifest") sessionID := "some sessionID" @@ -968,7 +968,7 @@ func TestProcessPayment_GivenMultipleWinningTickets_RedeemsAll(t *testing.T) { } orch := NewOrchestrator(n, rm) orch.address = addr - orch.node.SetBasePrice("default", big.NewRat(0, 1)) + orch.node.SetBasePrice("default", NewFixedPrice(big.NewRat(0, 1))) manifestID := ManifestID("some manifest") sessionID := "some sessionID" @@ -1038,7 +1038,7 @@ func TestProcessPayment_GivenConcurrentWinningTickets_RedeemsAll(t *testing.T) { } orch := NewOrchestrator(n, rm) orch.address = addr - orch.node.SetBasePrice("default", big.NewRat(0, 1)) + orch.node.SetBasePrice("default", NewFixedPrice(big.NewRat(0, 1))) manifestIDs := make([]string, 5) @@ -1097,7 +1097,7 @@ func TestProcessPayment_GivenReceiveTicketError_ReturnsError(t *testing.T) { } orch := NewOrchestrator(n, rm) orch.address = addr - orch.node.SetBasePrice("default", big.NewRat(0, 1)) + orch.node.SetBasePrice("default", NewFixedPrice(big.NewRat(0, 1))) manifestID := ManifestID("some manifest") @@ -1165,7 +1165,7 @@ func TestProcessPayment_PaymentError_DoesNotIncreaseCreditBalance(t *testing.T) } orch := NewOrchestrator(n, rm) orch.address = addr - orch.node.SetBasePrice("default", big.NewRat(0, 1)) + orch.node.SetBasePrice("default", NewFixedPrice(big.NewRat(0, 1))) manifestID := ManifestID("some manifest") paymentError := errors.New("ReceiveTicket error") @@ -1227,7 +1227,7 @@ func TestSufficientBalance_IsSufficient_ReturnsTrue(t *testing.T) { } orch := NewOrchestrator(n, rm) orch.address = addr - orch.node.SetBasePrice("default", big.NewRat(0, 1)) + orch.node.SetBasePrice("default", NewFixedPrice(big.NewRat(0, 1))) manifestID := ManifestID("some manifest") @@ -1265,7 +1265,7 @@ func TestSufficientBalance_IsNotSufficient_ReturnsFalse(t *testing.T) { } orch := NewOrchestrator(n, rm) orch.address = addr - orch.node.SetBasePrice("default", big.NewRat(0, 1)) + orch.node.SetBasePrice("default", NewFixedPrice(big.NewRat(0, 1))) manifestID := ManifestID("some manifest") @@ -1307,7 +1307,7 @@ func TestSufficientBalance_OffChainMode_ReturnsTrue(t *testing.T) { func TestTicketParams(t *testing.T) { n, _ := NewLivepeerNode(nil, "", nil) - n.priceInfo["default"] = big.NewRat(1, 1) + n.priceInfo["default"] = NewFixedPrice(big.NewRat(1, 1)) priceInfo := &net.PriceInfo{PricePerUnit: 1, PixelsPerUnit: 1} recipient := new(pm.MockRecipient) n.Recipient = recipient @@ -1388,7 +1388,7 @@ func TestPriceInfo(t *testing.T) { expPricePerPixel := big.NewRat(101, 100) n, _ := NewLivepeerNode(nil, "", nil) - n.SetBasePrice("default", basePrice) + n.SetBasePrice("default", NewFixedPrice(basePrice)) recipient := new(pm.MockRecipient) n.Recipient = recipient @@ -1406,7 +1406,7 @@ func TestPriceInfo(t *testing.T) { // basePrice = 10/1, txMultiplier = 100/1 => expPricePerPixel = 1010/100 basePrice = big.NewRat(10, 1) - n.SetBasePrice("default", basePrice) + n.SetBasePrice("default", NewFixedPrice(basePrice)) orch = NewOrchestrator(n, nil) expPricePerPixel = big.NewRat(1010, 100) @@ -1421,7 +1421,7 @@ func TestPriceInfo(t *testing.T) { // basePrice = 1/10, txMultiplier = 100 => expPricePerPixel = 101/1000 basePrice = big.NewRat(1, 10) - n.SetBasePrice("default", basePrice) + n.SetBasePrice("default", NewFixedPrice(basePrice)) orch = NewOrchestrator(n, nil) expPricePerPixel = big.NewRat(101, 1000) @@ -1435,7 +1435,7 @@ func TestPriceInfo(t *testing.T) { assert.Equal(priceInfo.PixelsPerUnit, expPrice.Denom().Int64()) // basePrice = 25/10 , txMultiplier = 100 => expPricePerPixel = 2525/1000 basePrice = big.NewRat(25, 10) - n.SetBasePrice("default", basePrice) + n.SetBasePrice("default", NewFixedPrice(basePrice)) orch = NewOrchestrator(n, nil) expPricePerPixel = big.NewRat(2525, 1000) @@ -1451,7 +1451,7 @@ func TestPriceInfo(t *testing.T) { // basePrice = 10/1 , txMultiplier = 100/10 => expPricePerPixel = 11 basePrice = big.NewRat(10, 1) txMultiplier = big.NewRat(100, 10) - n.SetBasePrice("default", basePrice) + n.SetBasePrice("default", NewFixedPrice(basePrice)) recipient = new(pm.MockRecipient) n.Recipient = recipient recipient.On("TxCostMultiplier", mock.Anything).Return(txMultiplier, nil) @@ -1470,7 +1470,7 @@ func TestPriceInfo(t *testing.T) { // basePrice = 10/1 , txMultiplier = 1/10 => expPricePerPixel = 110 basePrice = big.NewRat(10, 1) txMultiplier = big.NewRat(1, 10) - n.SetBasePrice("default", basePrice) + n.SetBasePrice("default", NewFixedPrice(basePrice)) recipient = new(pm.MockRecipient) n.Recipient = recipient recipient.On("TxCostMultiplier", mock.Anything).Return(txMultiplier, nil) @@ -1489,7 +1489,7 @@ func TestPriceInfo(t *testing.T) { // basePrice = 10, txMultiplier = 1 => expPricePerPixel = 20 basePrice = big.NewRat(10, 1) txMultiplier = big.NewRat(1, 1) - n.SetBasePrice("default", basePrice) + n.SetBasePrice("default", NewFixedPrice(basePrice)) recipient = new(pm.MockRecipient) n.Recipient = recipient recipient.On("TxCostMultiplier", mock.Anything).Return(txMultiplier, nil) @@ -1506,7 +1506,7 @@ func TestPriceInfo(t *testing.T) { assert.Equal(priceInfo.PixelsPerUnit, expPrice.Denom().Int64()) // basePrice = 0 => expPricePerPixel = 0 - n.SetBasePrice("default", big.NewRat(0, 1)) + n.SetBasePrice("default", NewFixedPrice(big.NewRat(0, 1))) orch = NewOrchestrator(n, nil) priceInfo, err = orch.PriceInfo(ethcommon.Address{}, "") @@ -1516,7 +1516,7 @@ func TestPriceInfo(t *testing.T) { // test no overflows basePrice = big.NewRat(25000, 1) - n.SetBasePrice("default", basePrice) + n.SetBasePrice("default", NewFixedPrice(basePrice)) faceValue, _ := new(big.Int).SetString("22245599237119512", 10) txCost := new(big.Int).Mul(big.NewInt(100000), big.NewInt(7500000000)) txMultiplier = new(big.Rat).SetFrac(faceValue, txCost) // 926899968213313/31250000000000 @@ -1572,7 +1572,7 @@ func TestPriceInfo_TxMultiplierError_ReturnsError(t *testing.T) { expError := errors.New("TxMultiplier Error") n, _ := NewLivepeerNode(nil, "", nil) - n.SetBasePrice("default", big.NewRat(1, 1)) + n.SetBasePrice("default", NewFixedPrice(big.NewRat(1, 1))) recipient := new(pm.MockRecipient) n.Recipient = recipient recipient.On("TxCostMultiplier", mock.Anything).Return(nil, expError) diff --git a/discovery/discovery_test.go b/discovery/discovery_test.go index c52ce7ce61..c7e2b1d3ac 100644 --- a/discovery/discovery_test.go +++ b/discovery/discovery_test.go @@ -608,11 +608,11 @@ func TestNewOrchestratorPoolWithPred_TestPredicate(t *testing.T) { assert.True(t, pool.pred(oInfo)) // Set server.BroadcastCfg.maxPrice higher than PriceInfo , should return true - server.BroadcastCfg.SetMaxPrice(big.NewRat(10, 1)) + server.BroadcastCfg.SetMaxPrice(core.NewFixedPrice(big.NewRat(10, 1))) assert.True(t, pool.pred(oInfo)) // Set MaxBroadcastPrice lower than PriceInfo, should return false - server.BroadcastCfg.SetMaxPrice(big.NewRat(1, 1)) + server.BroadcastCfg.SetMaxPrice(core.NewFixedPrice(big.NewRat(1, 1))) assert.False(t, pool.pred(oInfo)) // PixelsPerUnit is 0 , return false @@ -629,7 +629,7 @@ func TestCachedPool_AllOrchestratorsTooExpensive_ReturnsEmptyList(t *testing.T) expTranscoder := "transcoderFromTest" expPricePerPixel, _ := common.PriceToFixed(big.NewRat(999, 1)) - server.BroadcastCfg.SetMaxPrice(big.NewRat(1, 1)) + server.BroadcastCfg.SetMaxPrice(core.NewFixedPrice(big.NewRat(1, 1))) gmp := runtime.GOMAXPROCS(50) defer runtime.GOMAXPROCS(gmp) var mu sync.Mutex @@ -823,7 +823,7 @@ func TestCachedPool_N_OrchestratorsGoodPricing_ReturnsNOrchestrators(t *testing. }, } - server.BroadcastCfg.SetMaxPrice(big.NewRat(10, 1)) + server.BroadcastCfg.SetMaxPrice(core.NewFixedPrice(big.NewRat(10, 1))) gmp := runtime.GOMAXPROCS(50) defer runtime.GOMAXPROCS(gmp) var mu sync.Mutex diff --git a/eth/watchers/pricefeedwatcher.go b/eth/watchers/pricefeedwatcher.go index ec7a81f2f3..1bab9dc130 100644 --- a/eth/watchers/pricefeedwatcher.go +++ b/eth/watchers/pricefeedwatcher.go @@ -19,78 +19,93 @@ const ( priceUpdatePeriod = 1 * time.Hour ) +type PriceFeedWatcher interface { + Currencies() (base string, quote string, err error) + Current() (eth.PriceData, error) + Subscribe(ctx context.Context, sink chan<- eth.PriceData) +} + // PriceFeedWatcher monitors a Chainlink PriceFeed for updated pricing info. It // allows fetching the current price as well as listening for updates on the // PriceUpdated channel. -type PriceFeedWatcher struct { +type priceFeedWatcher struct { baseRetryDelay time.Duration - priceFeed eth.PriceFeedEthClient - currencyBase, currencyQuote string + priceFeed eth.PriceFeedEthClient + + mu sync.RWMutex + current eth.PriceData + cancelWatch func() - mu sync.RWMutex - current eth.PriceData priceEventFeed event.Feed + subscriptions event.SubscriptionScope } // NewPriceFeedWatcher creates a new PriceFeedWatcher instance. It will already // fetch the current price and start a goroutine to watch for updates. -func NewPriceFeedWatcher(ethClient *ethclient.Client, priceFeedAddr string) (*PriceFeedWatcher, error) { +func NewPriceFeedWatcher(ethClient *ethclient.Client, priceFeedAddr string) (PriceFeedWatcher, error) { priceFeed, err := eth.NewPriceFeedEthClient(ethClient, priceFeedAddr) if err != nil { return nil, fmt.Errorf("failed to create price feed client: %w", err) } - - description, err := priceFeed.Description() - if err != nil { - return nil, fmt.Errorf("failed to get description: %w", err) - } - - currencyFrom, currencyTo, err := parseCurrencies(description) - if err != nil { - return nil, err - } - - w := &PriceFeedWatcher{ + w := &priceFeedWatcher{ baseRetryDelay: priceUpdateBaseRetryDelay, priceFeed: priceFeed, - currencyBase: currencyFrom, - currencyQuote: currencyTo, - } - - err = w.updatePrice() - if err != nil { - return nil, fmt.Errorf("failed to update price: %w", err) } - return w, nil } // Currencies returns the base and quote currencies of the price feed. // i.e. base = CurrentPrice() * quote -func (w *PriceFeedWatcher) Currencies() (base string, quote string) { - return w.currencyBase, w.currencyQuote +func (w *priceFeedWatcher) Currencies() (base string, quote string, err error) { + description, err := w.priceFeed.Description() + if err != nil { + return "", "", fmt.Errorf("failed to get description: %w", err) + } + + base, quote, err = parseCurrencies(description) + if err != nil { + return "", "", err + } + return } -// Current returns the latest fetched price data. -func (w *PriceFeedWatcher) Current() eth.PriceData { +// Current returns the latest fetched price data, or fetches it in case it has +// not been fetched yet. +func (w *priceFeedWatcher) Current() (eth.PriceData, error) { w.mu.RLock() - defer w.mu.RUnlock() - return w.current + current := w.current + w.mu.RUnlock() + if current.UpdatedAt.IsZero() { + return w.updatePrice() + } + return current, nil } // Subscribe allows one to subscribe to price updates emitted by the Watcher. -// To unsubscribe, simply call `Unsubscribe` on the returned subscription. // The sink channel should have ample buffer space to avoid blocking other -// subscribers. Slow subscribers are not dropped. -func (w *PriceFeedWatcher) Subscribe(sub chan<- eth.PriceData) event.Subscription { - return w.priceEventFeed.Subscribe(sub) +// subscribers. Slow subscribers are not dropped. The subscription is kept alive +// until the passed Context is cancelled. +// +// The watch loop is run automatically while there are active subscriptions. It +// will be started when the first subscription is made and is automatically +// stopped when the last subscription is closed. +func (w *priceFeedWatcher) Subscribe(ctx context.Context, sink chan<- eth.PriceData) { + w.mu.Lock() + defer w.mu.Unlock() + w.ensureWatchLocked() + + sub := w.subscriptions.Track(w.priceEventFeed.Subscribe(sink)) + go w.handleUnsubscribe(ctx, sub) } -func (w *PriceFeedWatcher) updatePrice() error { +// updatePrice fetches the latest price data from the price feed and updates the +// current price if it is newer. If the price is updated, it will also send the +// updated price to the price event feed. +func (w *priceFeedWatcher) updatePrice() (eth.PriceData, error) { newPrice, err := w.priceFeed.FetchPriceData() if err != nil { - return fmt.Errorf("failed to fetch price data: %w", err) + return eth.PriceData{}, fmt.Errorf("failed to fetch price data: %w", err) } if newPrice.UpdatedAt.After(w.current.UpdatedAt) { @@ -100,26 +115,62 @@ func (w *PriceFeedWatcher) updatePrice() error { w.priceEventFeed.Send(newPrice) } - return nil + return newPrice, nil } -// Watch starts the watch process. It will periodically poll the price feed for -// price updates until the given context is canceled. Typically, you want to -// call Watch inside a goroutine. -func (w *PriceFeedWatcher) Watch(ctx context.Context) { +// ensureWatchLocked makes sure that the watch process is running. It assumes it +// is already running in a locked context (w.mu). The watch process itself will +// run in background and periodically poll the price feed for updates until the +// `w.cancelWatch` function is called. +func (w *priceFeedWatcher) ensureWatchLocked() { + if w.cancelWatch != nil { + // already running + return + } + ctx, cancel := context.WithCancel(context.Background()) + w.cancelWatch = cancel + ticker := newTruncatedTicker(ctx, priceUpdatePeriod) - w.watchTicker(ctx, ticker) + go w.watchTicker(ctx, ticker) +} + +// handleUnsubscribe waits for the provided Context to be done and then closes +// the given subscription. It then stops the watch process if there are no more +// active subscriptions. +func (w *priceFeedWatcher) handleUnsubscribe(ctx context.Context, sub event.Subscription) { +loop: + for { + select { + case <-ctx.Done(): + break loop + case <-sub.Err(): + clog.Errorf(ctx, "PriceFeedWatcher subscription error: %v", sub.Err()) + } + } + w.mu.Lock() + defer w.mu.Unlock() + + sub.Unsubscribe() + if w.subscriptions.Count() == 0 && w.cancelWatch != nil { + w.cancelWatch() + w.cancelWatch = nil + } } -func (w *PriceFeedWatcher) watchTicker(ctx context.Context, ticker <-chan time.Time) { +// watchTicker is the main loop that periodically fetches the latest price data +// from the price feed. It's lifecycle is handled through the ensureWatch and +// handleUnsubscribe functions. +func (w *priceFeedWatcher) watchTicker(ctx context.Context, ticker <-chan time.Time) { + clog.V(6).Infof(ctx, "Starting PriceFeed watch loop") for { select { case <-ctx.Done(): + clog.V(6).Infof(ctx, "Stopping PriceFeed watch loop") return case <-ticker: attempt, retryDelay := 1, w.baseRetryDelay for { - err := w.updatePrice() + _, err := w.updatePrice() if err == nil { break } else if attempt >= priceUpdateMaxRetries { @@ -159,7 +210,8 @@ func parseCurrencies(description string) (currencyBase string, currencyQuote str func newTruncatedTicker(ctx context.Context, d time.Duration) <-chan time.Time { ch := make(chan time.Time, 1) go func() { - defer close(ch) + // Do not close the channel, to prevent a concurrent goroutine reading from + // the channel from seeing an erroneous "tick" after its closed. nextTick := time.Now().UTC().Truncate(d) for { diff --git a/eth/watchers/pricefeedwatcher_test.go b/eth/watchers/pricefeedwatcher_test.go index 20e09578e1..27eb5d24d0 100644 --- a/eth/watchers/pricefeedwatcher_test.go +++ b/eth/watchers/pricefeedwatcher_test.go @@ -4,6 +4,7 @@ import ( "context" "errors" "math/big" + "reflect" "testing" "time" @@ -37,18 +38,16 @@ func TestPriceFeedWatcher_UpdatePrice(t *testing.T) { } priceFeedMock.On("FetchPriceData").Return(priceData, nil).Once() - w := &PriceFeedWatcher{ - priceFeed: priceFeedMock, - currencyBase: "ETH", - currencyQuote: "USD", - } + w := &priceFeedWatcher{priceFeed: priceFeedMock} + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() priceUpdated := make(chan eth.PriceData, 1) - sub := w.Subscribe(priceUpdated) - defer sub.Unsubscribe() + w.Subscribe(ctx, priceUpdated) - require.NoError(t, w.updatePrice()) - require.Equal(t, priceData, w.current) + newPrice, err := w.updatePrice() + require.NoError(t, err) + require.Equal(t, priceData, newPrice) select { case updatedPrice := <-priceUpdated: @@ -58,20 +57,59 @@ func TestPriceFeedWatcher_UpdatePrice(t *testing.T) { } } -func TestPriceFeedWatcher_Watch(t *testing.T) { +func TestPriceFeedWatcher_Subscribe(t *testing.T) { require := require.New(t) priceFeedMock := new(mockPriceFeedEthClient) defer priceFeedMock.AssertExpectations(t) - w := &PriceFeedWatcher{ - priceFeed: priceFeedMock, - currencyBase: "ETH", - currencyQuote: "USD", + w := &priceFeedWatcher{priceFeed: priceFeedMock} + + // Start a bunch of subscriptions and make sure only 1 watch loop gets started + observedCancelWatch := []context.CancelFunc{} + cancelSub := []context.CancelFunc{} + for i := 0; i < 5; i++ { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + w.Subscribe(ctx, make(chan eth.PriceData, 1)) + + observedCancelWatch = append(observedCancelWatch, w.cancelWatch) + cancelSub = append(cancelSub, cancel) + } + + require.NotNil(w.cancelWatch) + for i := range observedCancelWatch { + require.Equal(reflect.ValueOf(w.cancelWatch).Pointer(), reflect.ValueOf(observedCancelWatch[i]).Pointer()) } + // Stop all but the last subscription and ensure watch loop stays running + for i := 0; i < 4; i++ { + cancelSub[i]() + require.NotNil(w.cancelWatch) + } + + // Now stop the last subscription and ensure watch loop gets stopped + cancelSub[4]() + time.Sleep(1 * time.Second) + require.Nil(w.cancelWatch) + + // Finally, just make sure it can be started again after having been stopped + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + w.Subscribe(ctx, make(chan eth.PriceData, 1)) + require.NotNil(w.cancelWatch) +} + +func TestPriceFeedWatcher_Watch(t *testing.T) { + require := require.New(t) + priceFeedMock := new(mockPriceFeedEthClient) + defer priceFeedMock.AssertExpectations(t) + + w := &priceFeedWatcher{priceFeed: priceFeedMock} + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() priceUpdated := make(chan eth.PriceData, 1) - sub := w.Subscribe(priceUpdated) - defer sub.Unsubscribe() + w.Subscribe(ctx, priceUpdated) priceData := eth.PriceData{ RoundID: 10, @@ -100,8 +138,6 @@ func TestPriceFeedWatcher_Watch(t *testing.T) { // Start the watch loop fakeTicker := make(chan time.Time, 10) - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() go func() { w.watchTicker(ctx, fakeTicker) }() @@ -150,21 +186,18 @@ func TestPriceFeedWatcher_WatchErrorRetries(t *testing.T) { } priceFeedMock.On("FetchPriceData").Return(priceData, nil) - w := &PriceFeedWatcher{ + w := &priceFeedWatcher{ baseRetryDelay: 5 * time.Millisecond, priceFeed: priceFeedMock, - currencyBase: "ETH", - currencyQuote: "USD", } + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() priceUpdated := make(chan eth.PriceData, 1) - sub := w.Subscribe(priceUpdated) - defer sub.Unsubscribe() + w.Subscribe(ctx, priceUpdated) // Start watch loop fakeTicker := make(chan time.Time, 10) - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() go func() { w.watchTicker(ctx, fakeTicker) }() diff --git a/server/broadcast.go b/server/broadcast.go index 5658f0cda6..2edcd4f58d 100755 --- a/server/broadcast.go +++ b/server/broadcast.go @@ -56,7 +56,7 @@ var submitMultiSession = func(ctx context.Context, sess *BroadcastSession, seg * var maxTranscodeAttempts = errors.New("hit max transcode attempts") type BroadcastConfig struct { - maxPrice *big.Rat + maxPrice *core.AutoConvertedPrice mu sync.RWMutex } @@ -68,16 +68,19 @@ type SegFlightMetadata struct { func (cfg *BroadcastConfig) MaxPrice() *big.Rat { cfg.mu.RLock() defer cfg.mu.RUnlock() - return cfg.maxPrice + if cfg.maxPrice == nil { + return nil + } + return cfg.maxPrice.Value() } -func (cfg *BroadcastConfig) SetMaxPrice(price *big.Rat) { +func (cfg *BroadcastConfig) SetMaxPrice(price *core.AutoConvertedPrice) { cfg.mu.Lock() defer cfg.mu.Unlock() + prevPrice := cfg.maxPrice cfg.maxPrice = price - - if monitor.Enabled { - monitor.MaxTranscodingPrice(price) + if prevPrice != nil { + prevPrice.Stop() } } diff --git a/server/handlers.go b/server/handlers.go index 7461065fc1..7514de56ff 100644 --- a/server/handlers.go +++ b/server/handlers.go @@ -20,6 +20,7 @@ import ( "github.com/livepeer/go-livepeer/core" "github.com/livepeer/go-livepeer/eth" "github.com/livepeer/go-livepeer/eth/types" + "github.com/livepeer/go-livepeer/monitor" "github.com/livepeer/go-livepeer/pm" "github.com/livepeer/lpms/ffmpeg" "github.com/pkg/errors" @@ -125,6 +126,7 @@ func setBroadcastConfigHandler() http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { pricePerUnit := r.FormValue("maxPricePerUnit") pixelsPerUnit := r.FormValue("pixelsPerUnit") + currency := r.FormValue("currency") transcodingOptions := r.FormValue("transcodingOptions") if (pricePerUnit == "" || pixelsPerUnit == "") && transcodingOptions == "" { @@ -134,28 +136,38 @@ func setBroadcastConfigHandler() http.Handler { // set max price if pricePerUnit != "" && pixelsPerUnit != "" { - pr, err := strconv.ParseInt(pricePerUnit, 10, 64) - if err != nil { - respond400(w, errors.Wrapf(err, "Error converting string to int64").Error()) + pr, ok := new(big.Rat).SetString(pricePerUnit) + if !ok { + respond400(w, fmt.Sprintf("Error parsing pricePerUnit value: %s", pricePerUnit)) return } - px, err := strconv.ParseInt(pixelsPerUnit, 10, 64) - if err != nil { - respond400(w, errors.Wrapf(err, "Error converting string to int64").Error()) + px, ok := new(big.Rat).SetString(pixelsPerUnit) + if !ok { + respond400(w, fmt.Sprintf("Error parsing pixelsPerUnit value: %s", pixelsPerUnit)) return } - if px <= 0 { - respond400(w, fmt.Sprintf("pixels per unit must be greater than 0, provided %d", px)) + if px.Sign() <= 0 { + respond400(w, fmt.Sprintf("pixels per unit must be greater than 0, provided %v", pixelsPerUnit)) return } - - var price *big.Rat - if pr > 0 { - price = big.NewRat(pr, px) + pricePerPixel := new(big.Rat).Quo(pr, px) + + var autoPrice *core.AutoConvertedPrice + if pricePerPixel.Sign() > 0 { + var err error + autoPrice, err = core.NewAutoConvertedPrice(currency, pricePerPixel, func(price *big.Rat) { + if monitor.Enabled { + monitor.MaxTranscodingPrice(price) + } + glog.Infof("Maximum transcoding price: %v wei per pixel\n", price.FloatString(3)) + }) + if err != nil { + respond400(w, errors.Wrap(err, "error converting price").Error()) + return + } } - BroadcastCfg.SetMaxPrice(price) - glog.Infof("Maximum transcoding price: %d per %q pixels\n", pr, px) + BroadcastCfg.SetMaxPrice(autoPrice) } // set broadcast profiles @@ -291,7 +303,8 @@ func (s *LivepeerServer) activateOrchestratorHandler(client eth.LivepeerEthClien return } - if err := s.setOrchestratorPriceInfo("default", r.FormValue("pricePerUnit"), r.FormValue("pixelsPerUnit")); err != nil { + pricePerUnit, pixelsPerUnit, currency := r.FormValue("pricePerUnit"), r.FormValue("pixelsPerUnit"), r.FormValue("currency") + if err := s.setOrchestratorPriceInfo("default", pricePerUnit, pixelsPerUnit, currency); err != nil { respond400(w, err.Error()) return } @@ -385,8 +398,9 @@ func (s *LivepeerServer) setOrchestratorConfigHandler(client eth.LivepeerEthClie return mustHaveClient(client, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { pixels := r.FormValue("pixelsPerUnit") price := r.FormValue("pricePerUnit") + currency := r.FormValue("currency") if pixels != "" && price != "" { - if err := s.setOrchestratorPriceInfo("default", price, pixels); err != nil { + if err := s.setOrchestratorPriceInfo("default", price, pixels, currency); err != nil { respond400(w, err.Error()) return } @@ -458,53 +472,43 @@ func (s *LivepeerServer) setOrchestratorConfigHandler(client eth.LivepeerEthClie })) } -func (s *LivepeerServer) setOrchestratorPriceInfo(broadcasterEthAddr, pricePerUnitStr, pixelsPerUnitStr string) error { - ok, err := regexp.MatchString("^[0-9]+$", pricePerUnitStr) +func (s *LivepeerServer) setOrchestratorPriceInfo(broadcasterEthAddr, pricePerUnitStr, pixelsPerUnitStr, currency string) error { + ok, err := regexp.MatchString("^0x[0-9a-fA-F]{40}|default$", broadcasterEthAddr) if err != nil { return err } if !ok { - return fmt.Errorf("pricePerUnit is not a valid integer, provided %v", pricePerUnitStr) + return fmt.Errorf("broadcasterEthAddr is not a valid eth address, provided %v", broadcasterEthAddr) } - ok, err = regexp.MatchString("^[0-9]+$", pixelsPerUnitStr) - if err != nil { - return err - } + pricePerUnit, ok := new(big.Rat).SetString(pricePerUnitStr) if !ok { - return fmt.Errorf("pixelsPerUnit is not a valid integer, provided %v", pixelsPerUnitStr) + return fmt.Errorf("error parsing pricePerUnit value: %s", pricePerUnitStr) } - - ok, err = regexp.MatchString("^0x[0-9a-fA-F]{40}|default$", broadcasterEthAddr) - if err != nil { - return err - } - if !ok { - return fmt.Errorf("broadcasterEthAddr is not a valid eth address, provided %v", broadcasterEthAddr) + if pricePerUnit.Sign() < 0 { + return fmt.Errorf("price unit must be greater than or equal to 0, provided %s", pricePerUnitStr) } - pricePerUnit, err := strconv.ParseInt(pricePerUnitStr, 10, 64) - if err != nil { - return fmt.Errorf("error converting pricePerUnit string to int64: %v", err) + pixelsPerUnit, ok := new(big.Rat).SetString(pixelsPerUnitStr) + if !ok { + return fmt.Errorf("error parsing pixelsPerUnit value: %v", pixelsPerUnitStr) } - if pricePerUnit < 0 { - return fmt.Errorf("price unit must be greater than or equal to 0, provided %d", pricePerUnit) + if pixelsPerUnit.Sign() <= 0 { + return fmt.Errorf("pixels per unit must be greater than 0, provided %s", pixelsPerUnitStr) } - pixelsPerUnit, err := strconv.ParseInt(pixelsPerUnitStr, 10, 64) + pricePerPixel := new(big.Rat).Quo(pricePerUnit, pixelsPerUnit) + autoPrice, err := core.NewAutoConvertedPrice(currency, pricePerPixel, func(price *big.Rat) { + if broadcasterEthAddr == "default" { + glog.Infof("Price: %v wei per pixel\n ", price.FloatString(3)) + } else { + glog.Infof("Price: %v wei per pixel for broadcaster %v", price.FloatString(3), broadcasterEthAddr) + } + }) if err != nil { - return fmt.Errorf("error converting pixelsPerUnit string to int64: %v", err) - } - if pixelsPerUnit <= 0 { - return fmt.Errorf("pixels per unit must be greater than 0, provided %d", pixelsPerUnit) - } - - s.LivepeerNode.SetBasePrice(broadcasterEthAddr, big.NewRat(pricePerUnit, pixelsPerUnit)) - if broadcasterEthAddr == "default" { - glog.Infof("Price per pixel set to %d wei for %d pixels\n", pricePerUnit, pixelsPerUnit) - } else { - glog.Infof("Price per pixel set to %d wei for %d pixels for broadcaster %s\n", pricePerUnit, pixelsPerUnit, broadcasterEthAddr) + return fmt.Errorf("error converting price: %v", err) } + s.LivepeerNode.SetBasePrice(broadcasterEthAddr, autoPrice) return nil } @@ -564,9 +568,10 @@ func (s *LivepeerServer) setPriceForBroadcaster() http.Handler { if s.LivepeerNode.NodeType == core.OrchestratorNode { pricePerUnitStr := r.FormValue("pricePerUnit") pixelsPerUnitStr := r.FormValue("pixelsPerUnit") + currency := r.FormValue("currency") broadcasterEthAddr := r.FormValue("broadcasterEthAddr") - err := s.setOrchestratorPriceInfo(broadcasterEthAddr, pricePerUnitStr, pixelsPerUnitStr) + err := s.setOrchestratorPriceInfo(broadcasterEthAddr, pricePerUnitStr, pixelsPerUnitStr, currency) if err == nil { respondOk(w, []byte(fmt.Sprintf("Price per pixel set to %s wei for %s pixels for broadcaster %s\n", pricePerUnitStr, pixelsPerUnitStr, broadcasterEthAddr))) } else { diff --git a/server/handlers_test.go b/server/handlers_test.go index aa01fe88cc..f7852e3d46 100644 --- a/server/handlers_test.go +++ b/server/handlers_test.go @@ -116,7 +116,7 @@ func TestOrchestratorInfoHandler_Success(t *testing.T) { s := &LivepeerServer{LivepeerNode: n} price := big.NewRat(1, 2) - s.LivepeerNode.SetBasePrice("default", price) + s.LivepeerNode.SetBasePrice("default", core.NewFixedPrice(price)) trans := &types.Transcoder{ ServiceURI: "127.0.0.1:8935", @@ -196,7 +196,7 @@ func TestSetBroadcastConfigHandler_ConvertPricePerUnitError(t *testing.T) { }) assert.Equal(http.StatusBadRequest, status) - assert.Contains(body, "Error converting string to int64") + assert.Contains(body, "Error parsing pricePerUnit value") } func TestSetBroadcastConfigHandler_ConvertPixelsPerUnitError(t *testing.T) { @@ -209,7 +209,7 @@ func TestSetBroadcastConfigHandler_ConvertPixelsPerUnitError(t *testing.T) { }) assert.Equal(http.StatusBadRequest, status) - assert.Contains(body, "Error converting string to int64") + assert.Contains(body, "Error parsing pixelsPerUnit value") } func TestSetBroadcastConfigHandler_NegativePixelPerUnitError(t *testing.T) { @@ -259,7 +259,7 @@ func TestSetBroadcastConfigHandler_Success(t *testing.T) { func TestGetBroadcastConfigHandler(t *testing.T) { assert := assert.New(t) - BroadcastCfg.maxPrice = big.NewRat(1, 2) + BroadcastCfg.maxPrice = core.NewFixedPrice(big.NewRat(1, 2)) BroadcastJobVideoProfiles = []ffmpeg.VideoProfile{ ffmpeg.VideoProfileLookup["P240p25fps16x9"], } @@ -501,26 +501,31 @@ func TestSetOrchestratorPriceInfo(t *testing.T) { s := stubServer() // pricePerUnit is not an integer - err := s.setOrchestratorPriceInfo("default", "nil", "1") + err := s.setOrchestratorPriceInfo("default", "nil", "1", "") assert.Error(t, err) - assert.True(t, strings.Contains(err.Error(), "pricePerUnit is not a valid integer")) + assert.Contains(t, err.Error(), "error parsing pricePerUnit value") // pixelsPerUnit is not an integer - err = s.setOrchestratorPriceInfo("default", "1", "nil") + err = s.setOrchestratorPriceInfo("default", "1", "nil", "") assert.Error(t, err) - assert.True(t, strings.Contains(err.Error(), "pixelsPerUnit is not a valid integer")) + assert.Contains(t, err.Error(), "error parsing pixelsPerUnit value") - err = s.setOrchestratorPriceInfo("default", "1", "1") + // price feed watcher is not initialized and one attempts a custom currency + err = s.setOrchestratorPriceInfo("default", "1e12", "0.7", "USD") + assert.Error(t, err) + assert.Contains(t, err.Error(), "PriceFeedWatcher is not initialized") + + err = s.setOrchestratorPriceInfo("default", "1", "1", "") assert.Nil(t, err) assert.Zero(t, s.LivepeerNode.GetBasePrice("default").Cmp(big.NewRat(1, 1))) - err = s.setOrchestratorPriceInfo("default", "-5", "1") + err = s.setOrchestratorPriceInfo("default", "-5", "1", "") assert.EqualErrorf(t, err, err.Error(), "price unit must be greater than or equal to 0, provided %d\n", -5) // pixels per unit <= 0 - err = s.setOrchestratorPriceInfo("default", "1", "0") + err = s.setOrchestratorPriceInfo("default", "1", "0", "") assert.EqualErrorf(t, err, err.Error(), "pixels per unit must be greater than 0, provided %d\n", 0) - err = s.setOrchestratorPriceInfo("default", "1", "-5") + err = s.setOrchestratorPriceInfo("default", "1", "-5", "") assert.EqualErrorf(t, err, err.Error(), "pixels per unit must be greater than 0, provided %d\n", -5) } diff --git a/server/rpc_test.go b/server/rpc_test.go index 712568c20d..ab35bb0875 100644 --- a/server/rpc_test.go +++ b/server/rpc_test.go @@ -550,7 +550,7 @@ func TestGenPayment(t *testing.T) { s.Sender = sender // Test invalid price - BroadcastCfg.SetMaxPrice(big.NewRat(1, 5)) + BroadcastCfg.SetMaxPrice(core.NewFixedPrice(big.NewRat(1, 5))) payment, err = genPayment(context.TODO(), s, 1) assert.Equal("", payment) assert.Errorf(err, err.Error(), "Orchestrator price higher than the set maximum price of %v wei per %v pixels", int64(1), int64(5)) @@ -687,12 +687,12 @@ func TestValidatePrice(t *testing.T) { defer BroadcastCfg.SetMaxPrice(nil) // B MaxPrice > O Price - BroadcastCfg.SetMaxPrice(big.NewRat(5, 1)) + BroadcastCfg.SetMaxPrice(core.NewFixedPrice(big.NewRat(5, 1))) err = validatePrice(s) assert.Nil(err) // B MaxPrice == O Price - BroadcastCfg.SetMaxPrice(big.NewRat(1, 3)) + BroadcastCfg.SetMaxPrice(core.NewFixedPrice(big.NewRat(1, 3))) err = validatePrice(s) assert.Nil(err) @@ -713,7 +713,7 @@ func TestValidatePrice(t *testing.T) { // B MaxPrice < O Price s.InitialPrice = nil - BroadcastCfg.SetMaxPrice(big.NewRat(1, 5)) + BroadcastCfg.SetMaxPrice(core.NewFixedPrice(big.NewRat(1, 5))) err = validatePrice(s) assert.EqualError(err, fmt.Sprintf("Orchestrator price higher than the set maximum price of %v wei per %v pixels", int64(1), int64(5))) diff --git a/server/segment_rpc_test.go b/server/segment_rpc_test.go index 6feb1a5ba8..f8786202cd 100644 --- a/server/segment_rpc_test.go +++ b/server/segment_rpc_test.go @@ -1679,7 +1679,7 @@ func TestSubmitSegment_GenPaymentError_ValidatePriceError(t *testing.T) { OrchestratorInfo: oinfo, } - BroadcastCfg.SetMaxPrice(big.NewRat(1, 5)) + BroadcastCfg.SetMaxPrice(core.NewFixedPrice(big.NewRat(1, 5))) defer BroadcastCfg.SetMaxPrice(nil) _, err := SubmitSegment(context.TODO(), s, &stream.HLSSegment{}, nil, 0, false, true) diff --git a/test/e2e/e2e.go b/test/e2e/e2e.go index 59a77b5c88..efc723d602 100644 --- a/test/e2e/e2e.go +++ b/test/e2e/e2e.go @@ -122,7 +122,7 @@ func lpCfg() starter.LivepeerConfig { ethPassword := "" network := "devnet" blockPollingInterval := 1 - pricePerUnit := 1 + pricePerUnit := "1" initializeRound := true cfg := starter.DefaultLivepeerConfig() From 2572d97ec8be0d11ed6aef9d072971d4b6b96c4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Leszko?= Date: Fri, 29 Mar 2024 17:35:23 +0100 Subject: [PATCH 03/88] Release 0.7.3 (#2988) * release v0.7.3 * release v0.7.3 --- CHANGELOG.md | 32 +++++++++++++++++++++++++++++++- CHANGELOG_PENDING.md | 2 -- VERSION | 2 +- 3 files changed, 32 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8bebd6eff2..3c86a0649c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,35 @@ # Changelog +## v0.7.3 + +### Breaking Changes 🚨🚨 + +### Features ⚒ + +#### General + +- [#2978](https://github.com/livepeer/go-livepeer/pull/2978) Update CUDA version from 11.x to 12.x (@leszko) +- [#2973](https://github.com/livepeer/go-livepeer/pull/2973) Update ffmpeg version (@thomshutt) +- [#2981](https://github.com/livepeer/go-livepeer/pull/2981) Add support for prices in custom currencies like USD (@victorges) + +#### Broadcaster + +#### Orchestrator + +#### Transcoder + +### Bug Fixes 🐞 + +#### CLI + +#### General + +#### Broadcaster + +#### Orchestrator + +#### Transcoder + ## v0.7.2 ### Breaking Changes 🚨🚨 @@ -562,7 +592,7 @@ Additional highlights of this release: - Support for EIP-1559 (otherwise known as type 2) Ethereum transactions which results in more predictable transaction confirmation times, reduces the chance of stuck pending transactions and avoids overpaying in gas fees. If you are interested in additional details on the implications of EIP-1559 transactions refer to this [resource](https://hackmd.io/@timbeiko/1559-resources). - An improvement in ticket parameter generation for orchestrators to prevent short lived gas price spikes on the Ethereum network from disrupting streams. - The node will automatically detect if the GPU enters an unrecoverable state and crash. The reason for crashing upon detecting an unrecoverable GPU state is that no transcoding will -be possible in this scenario until the node is restarted. We recommend node operators to setup a process for monitoring if their node is still up and starting the node if it has crashed. For reference, a bash script similar to [this one](https://gist.github.com/jailuthra/03c3d65d0bbff457cae8f9a14b4c04b7) can be used to automate restarts of the node in the event of a crash. + be possible in this scenario until the node is restarted. We recommend node operators to setup a process for monitoring if their node is still up and starting the node if it has crashed. For reference, a bash script similar to [this one](https://gist.github.com/jailuthra/03c3d65d0bbff457cae8f9a14b4c04b7) can be used to automate restarts of the node in the event of a crash. Thanks to everyone that submitted bug reports and assisted in testing! diff --git a/CHANGELOG_PENDING.md b/CHANGELOG_PENDING.md index df9d710ef8..3ca5044811 100644 --- a/CHANGELOG_PENDING.md +++ b/CHANGELOG_PENDING.md @@ -8,8 +8,6 @@ #### General -- [#2981](https://github.com/livepeer/go-livepeer/pull/2981) Add support for prices in custom currencies like USD (@victorges) - #### Broadcaster #### Orchestrator diff --git a/VERSION b/VERSION index d5cc44d1d3..b09a54cb9b 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.7.2 \ No newline at end of file +0.7.3 \ No newline at end of file From 8c243abfc2ed877aef121e9c208857c0d1ad5c18 Mon Sep 17 00:00:00 2001 From: Thom Shutt Date: Tue, 2 Apr 2024 11:11:26 +0100 Subject: [PATCH 04/88] Revert "Bump ffmpeg version and nv-codec-headers" (#2989) * Revert "Bump ffmpeg version and nv-codec-headers (#2973)" This reverts commit cad6713174fc351850ae5a2f82b0f6ab306fc133. * Revert "Update CUDA build version from 11.7.1 to 12.0.0 (#2978)" This reverts commit 6c09a9f00682d7ed404257bba9f485dc0c4041ad. * Reapply "Update CUDA build version from 11.7.1 to 12.0.0 (#2978)" This reverts commit ebbf2102b8f6420a02439554fbe4992ab1113749. * Force ffmpeg reinstall * Revert "Force ffmpeg reinstall" This reverts commit 5adb9a598b14b3d12f038201d7d8374fac5e2f8c. --------- Co-authored-by: Victor Elias --- install_ffmpeg.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/install_ffmpeg.sh b/install_ffmpeg.sh index 03b4e0b301..af66bd0b88 100755 --- a/install_ffmpeg.sh +++ b/install_ffmpeg.sh @@ -116,7 +116,7 @@ if [[ "$GOOS" != "darwin" ]]; then if [[ ! -e "$ROOT/nv-codec-headers" ]]; then git clone https://git.videolan.org/git/ffmpeg/nv-codec-headers.git "$ROOT/nv-codec-headers" cd $ROOT/nv-codec-headers - git checkout n12.1.14.0 + git checkout n9.1.23.1 make -e PREFIX="$ROOT/compiled" make install -e PREFIX="$ROOT/compiled" fi @@ -203,8 +203,9 @@ else fi if [[ ! -e "$ROOT/ffmpeg/libavcodec/libavcodec.a" ]]; then - git clone https://github.com/livepeer/FFmpeg-6.1.1.git "$ROOT/ffmpeg" || echo "FFmpeg dir already exists" + git clone https://github.com/livepeer/FFmpeg.git "$ROOT/ffmpeg" || echo "FFmpeg dir already exists" cd "$ROOT/ffmpeg" + git checkout 2e18d069668c143f3c251067abd25389e411d022 ./configure ${TARGET_OS:-} $DISABLE_FFMPEG_COMPONENTS --fatal-warnings \ --enable-libx264 --enable-gpl \ --enable-protocol=rtmp,file,pipe \ From f55d6058e0c57a77b63963422db277954bd6ec04 Mon Sep 17 00:00:00 2001 From: Thom Shutt Date: Tue, 2 Apr 2024 12:01:26 +0100 Subject: [PATCH 05/88] Bump LPMS (#2992) --- go.mod | 6 +++--- go.sum | 6 ++++++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 675f75b480..fd1a55b99f 100644 --- a/go.mod +++ b/go.mod @@ -8,12 +8,12 @@ require ( github.com/ethereum/go-ethereum v1.13.5 github.com/golang/glog v1.1.1 github.com/golang/mock v1.6.0 - github.com/golang/protobuf v1.5.3 + github.com/golang/protobuf v1.5.4 github.com/jaypipes/ghw v0.10.0 github.com/jaypipes/pcidb v1.0.0 github.com/livepeer/go-tools v0.0.0-20220805063103-76df6beb6506 github.com/livepeer/livepeer-data v0.7.5-0.20231004073737-06f1f383fb18 - github.com/livepeer/lpms v0.0.0-20240115103113-98566e26c007 + github.com/livepeer/lpms v0.0.0-20240402101153-ced71c476bd0 github.com/livepeer/m3u8 v0.11.1 github.com/mattn/go-sqlite3 v1.14.18 github.com/olekukonko/tablewriter v0.0.5 @@ -28,7 +28,7 @@ require ( go.uber.org/goleak v1.3.0 golang.org/x/net v0.17.0 google.golang.org/grpc v1.57.1 - google.golang.org/protobuf v1.30.0 + google.golang.org/protobuf v1.33.0 pgregory.net/rapid v1.1.0 ) diff --git a/go.sum b/go.sum index 02fdd1f23e..984557a611 100644 --- a/go.sum +++ b/go.sum @@ -297,6 +297,8 @@ github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaS github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb h1:PBC98N2aIaM3XXiurYmW7fx4GZkL8feAMVq7nEjURHk= github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= @@ -446,6 +448,8 @@ github.com/livepeer/livepeer-data v0.7.5-0.20231004073737-06f1f383fb18 h1:4oH3Nq github.com/livepeer/livepeer-data v0.7.5-0.20231004073737-06f1f383fb18/go.mod h1:Jpf4jHK+fbWioBHRDRM1WadNT1qmY27g2YicTdO0Rtc= github.com/livepeer/lpms v0.0.0-20240115103113-98566e26c007 h1:0xr1TeIanBDdzI3sE2Zgf2yEV3s+6cPo3lJeyOHKmtM= github.com/livepeer/lpms v0.0.0-20240115103113-98566e26c007/go.mod h1:Hr/JhxxPDipOVd4ZrGYWrdJfpVF8/SEI0nNr2ctAlkM= +github.com/livepeer/lpms v0.0.0-20240402101153-ced71c476bd0 h1:Ch+HRjVJHpNo3kySGJgyDqb+l0KPWehyqZfA1wOafgY= +github.com/livepeer/lpms v0.0.0-20240402101153-ced71c476bd0/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= @@ -1075,6 +1079,8 @@ google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqw google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= +google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= From 85bea861061b8931f60e3b30e9af1d9300ef040f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Leszko?= Date: Tue, 2 Apr 2024 16:11:01 +0200 Subject: [PATCH 06/88] release v0.7.4 (#2993) --- CHANGELOG.md | 28 ++++++++++++++++++++++++++++ VERSION | 2 +- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3c86a0649c..ea7f99c11a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,33 @@ # Changelog +## v0.7.4 + +### Breaking Changes 🚨🚨 + +### Features ⚒ + +#### General + +- [#2989](https://github.com/livepeer/go-livepeer/pull/2989) Revert "Update ffmpeg version" (@thomshutt) + +#### Broadcaster + +#### Orchestrator + +#### Transcoder + +### Bug Fixes 🐞 + +#### CLI + +#### General + +#### Broadcaster + +#### Orchestrator + +#### Transcoder + ## v0.7.3 ### Breaking Changes 🚨🚨 diff --git a/VERSION b/VERSION index b09a54cb9b..ef090a6c47 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.7.3 \ No newline at end of file +0.7.4 \ No newline at end of file From 07fed97ca250dfe61ba87043bae9ac5672364fed Mon Sep 17 00:00:00 2001 From: Victor Elias Date: Wed, 3 Apr 2024 08:44:49 -0300 Subject: [PATCH 07/88] server: Skip redundant maxPrice check in ongoing session (#2994) * server: Remove maxPrice check mid-session * server: Fix tests * server: Fix erroneous usage of assert.EqualErrorf When I was writing the tests for validatePrice I found out we were using that function wrong in a couple places and never checking any error. We were sending err.Error() to check the error from err. * server: Fix error checks after fixing assertion * CHANGELOG --- CHANGELOG_PENDING.md | 2 ++ server/handlers_test.go | 6 +++--- server/rpc_test.go | 28 +++++----------------------- server/segment_rpc.go | 4 ---- server/segment_rpc_test.go | 9 +++++---- 5 files changed, 15 insertions(+), 34 deletions(-) diff --git a/CHANGELOG_PENDING.md b/CHANGELOG_PENDING.md index 3ca5044811..cb662d0568 100644 --- a/CHANGELOG_PENDING.md +++ b/CHANGELOG_PENDING.md @@ -22,6 +22,8 @@ #### Broadcaster +- [#2994](https://github.com/livepeer/go-livepeer/pull/2994) server: Skip redundant maxPrice check in ongoing session (@victorges) + #### Orchestrator #### Transcoder diff --git a/server/handlers_test.go b/server/handlers_test.go index f7852e3d46..d191d0a75e 100644 --- a/server/handlers_test.go +++ b/server/handlers_test.go @@ -520,13 +520,13 @@ func TestSetOrchestratorPriceInfo(t *testing.T) { assert.Zero(t, s.LivepeerNode.GetBasePrice("default").Cmp(big.NewRat(1, 1))) err = s.setOrchestratorPriceInfo("default", "-5", "1", "") - assert.EqualErrorf(t, err, err.Error(), "price unit must be greater than or equal to 0, provided %d\n", -5) + assert.EqualError(t, err, fmt.Sprintf("price unit must be greater than or equal to 0, provided %d", -5)) // pixels per unit <= 0 err = s.setOrchestratorPriceInfo("default", "1", "0", "") - assert.EqualErrorf(t, err, err.Error(), "pixels per unit must be greater than 0, provided %d\n", 0) + assert.EqualError(t, err, fmt.Sprintf("pixels per unit must be greater than 0, provided %d", 0)) err = s.setOrchestratorPriceInfo("default", "1", "-5", "") - assert.EqualErrorf(t, err, err.Error(), "pixels per unit must be greater than 0, provided %d\n", -5) + assert.EqualError(t, err, fmt.Sprintf("pixels per unit must be greater than 0, provided %d", -5)) } func TestSetPriceForBroadcasterHandler(t *testing.T) { diff --git a/server/rpc_test.go b/server/rpc_test.go index ab35bb0875..93c776f456 100644 --- a/server/rpc_test.go +++ b/server/rpc_test.go @@ -549,13 +549,13 @@ func TestGenPayment(t *testing.T) { sender := &pm.MockSender{} s.Sender = sender - // Test invalid price - BroadcastCfg.SetMaxPrice(core.NewFixedPrice(big.NewRat(1, 5))) + // Test changing O price + s.InitialPrice = &net.PriceInfo{PricePerUnit: 1, PixelsPerUnit: 5} payment, err = genPayment(context.TODO(), s, 1) assert.Equal("", payment) - assert.Errorf(err, err.Error(), "Orchestrator price higher than the set maximum price of %v wei per %v pixels", int64(1), int64(5)) + assert.Errorf(err, "Orchestrator price has changed, Orchestrator price: %v, Orchestrator initial price: %v", "1/3", "1/5") - BroadcastCfg.SetMaxPrice(nil) + s.InitialPrice = nil // Test CreateTicketBatch error sender.On("CreateTicketBatch", mock.Anything, mock.Anything).Return(nil, errors.New("CreateTicketBatch error")).Once() @@ -680,22 +680,10 @@ func TestValidatePrice(t *testing.T) { PMSessionID: "foo", } - // B's MaxPrice is nil + // O's Initial Price is nil err := validatePrice(s) assert.Nil(err) - defer BroadcastCfg.SetMaxPrice(nil) - - // B MaxPrice > O Price - BroadcastCfg.SetMaxPrice(core.NewFixedPrice(big.NewRat(5, 1))) - err = validatePrice(s) - assert.Nil(err) - - // B MaxPrice == O Price - BroadcastCfg.SetMaxPrice(core.NewFixedPrice(big.NewRat(1, 3))) - err = validatePrice(s) - assert.Nil(err) - // O Initial Price == O Price s.InitialPrice = oinfo.PriceInfo err = validatePrice(s) @@ -711,12 +699,6 @@ func TestValidatePrice(t *testing.T) { err = validatePrice(s) assert.ErrorContains(err, "price has changed") - // B MaxPrice < O Price - s.InitialPrice = nil - BroadcastCfg.SetMaxPrice(core.NewFixedPrice(big.NewRat(1, 5))) - err = validatePrice(s) - assert.EqualError(err, fmt.Sprintf("Orchestrator price higher than the set maximum price of %v wei per %v pixels", int64(1), int64(5))) - // O.PriceInfo is nil s.OrchestratorInfo.PriceInfo = nil err = validatePrice(s) diff --git a/server/segment_rpc.go b/server/segment_rpc.go index 7f81999f7b..3472222e27 100644 --- a/server/segment_rpc.go +++ b/server/segment_rpc.go @@ -826,10 +826,6 @@ func validatePrice(sess *BroadcastSession) error { return errors.New("missing orchestrator price") } - maxPrice := BroadcastCfg.MaxPrice() - if maxPrice != nil && oPrice.Cmp(maxPrice) == 1 { - return fmt.Errorf("Orchestrator price higher than the set maximum price of %v wei per %v pixels", maxPrice.Num().Int64(), maxPrice.Denom().Int64()) - } iPrice, err := common.RatPriceInfo(sess.InitialPrice) if err == nil && iPrice != nil && oPrice.Cmp(iPrice) == 1 { return fmt.Errorf("Orchestrator price has changed, Orchestrator price: %v, Orchestrator initial price: %v", oPrice, iPrice) diff --git a/server/segment_rpc_test.go b/server/segment_rpc_test.go index f8786202cd..01c37f903c 100644 --- a/server/segment_rpc_test.go +++ b/server/segment_rpc_test.go @@ -1677,14 +1677,15 @@ func TestSubmitSegment_GenPaymentError_ValidatePriceError(t *testing.T) { Sender: sender, Balance: balance, OrchestratorInfo: oinfo, + InitialPrice: &net.PriceInfo{ + PricePerUnit: 1, + PixelsPerUnit: 5, + }, } - BroadcastCfg.SetMaxPrice(core.NewFixedPrice(big.NewRat(1, 5))) - defer BroadcastCfg.SetMaxPrice(nil) - _, err := SubmitSegment(context.TODO(), s, &stream.HLSSegment{}, nil, 0, false, true) - assert.EqualErrorf(t, err, err.Error(), "Orchestrator price higher than the set maximum price of %v wei per %v pixels", int64(1), int64(5)) + assert.EqualError(t, err, fmt.Sprintf("Orchestrator price has changed, Orchestrator price: %v, Orchestrator initial price: %v", "1/3", "1/5")) balance.AssertCalled(t, "Credit", existingCredit) } From 119f346c3835cfa5f77e23344b102462a52b78be Mon Sep 17 00:00:00 2001 From: Victor Elias Date: Wed, 3 Apr 2024 08:49:47 -0300 Subject: [PATCH 08/88] server: Allow Os price to increase up to 2x mid-session (#2995) * server: Allow dynamic (and sometimes >max) prices for Os * CHANGELOG --- CHANGELOG_PENDING.md | 2 ++ server/rpc_test.go | 15 ++++++++++----- server/segment_rpc.go | 18 +++++++++++++++--- server/segment_rpc_test.go | 4 ++-- 4 files changed, 29 insertions(+), 10 deletions(-) diff --git a/CHANGELOG_PENDING.md b/CHANGELOG_PENDING.md index cb662d0568..f5e99d64c6 100644 --- a/CHANGELOG_PENDING.md +++ b/CHANGELOG_PENDING.md @@ -10,6 +10,8 @@ #### Broadcaster +- [#2995](https://github.com/livepeer/go-livepeer/pull/2995) server: Allow Os price to increase up to 2x mid-session (@victorges) + #### Orchestrator #### Transcoder diff --git a/server/rpc_test.go b/server/rpc_test.go index 93c776f456..c0832a0c46 100644 --- a/server/rpc_test.go +++ b/server/rpc_test.go @@ -550,10 +550,10 @@ func TestGenPayment(t *testing.T) { s.Sender = sender // Test changing O price - s.InitialPrice = &net.PriceInfo{PricePerUnit: 1, PixelsPerUnit: 5} + s.InitialPrice = &net.PriceInfo{PricePerUnit: 1, PixelsPerUnit: 7} payment, err = genPayment(context.TODO(), s, 1) assert.Equal("", payment) - assert.Errorf(err, "Orchestrator price has changed, Orchestrator price: %v, Orchestrator initial price: %v", "1/3", "1/5") + assert.Errorf(err, "Orchestrator price has more than doubled, Orchestrator price: %v, Orchestrator initial price: %v", "1/3", "1/7") s.InitialPrice = nil @@ -694,10 +694,15 @@ func TestValidatePrice(t *testing.T) { err = validatePrice(s) assert.Nil(err) - // O Initial Price lower than O Price - s.InitialPrice = &net.PriceInfo{PricePerUnit: 1, PixelsPerUnit: 10} + // O Price higher but up to 2x Initial Price + s.InitialPrice = &net.PriceInfo{PricePerUnit: 1, PixelsPerUnit: 6} err = validatePrice(s) - assert.ErrorContains(err, "price has changed") + assert.Nil(err) + + // O Price higher than 2x Initial Price + s.InitialPrice = &net.PriceInfo{PricePerUnit: 1000, PixelsPerUnit: 6001} + err = validatePrice(s) + assert.ErrorContains(err, "price has more than doubled") // O.PriceInfo is nil s.OrchestratorInfo.PriceInfo = nil diff --git a/server/segment_rpc.go b/server/segment_rpc.go index 3472222e27..b7a948b5f0 100644 --- a/server/segment_rpc.go +++ b/server/segment_rpc.go @@ -36,6 +36,9 @@ const segmentHeader = "Livepeer-Segment" const pixelEstimateMultiplier = 1.02 +// Maximum price change allowed in orchestrator pricing before the session is swapped. +var priceIncreaseThreshold = big.NewRat(2, 1) + var errSegEncoding = errors.New("ErrorSegEncoding") var errSegSig = errors.New("ErrSegSig") var errFormat = errors.New("unrecognized profile output format") @@ -826,9 +829,18 @@ func validatePrice(sess *BroadcastSession) error { return errors.New("missing orchestrator price") } - iPrice, err := common.RatPriceInfo(sess.InitialPrice) - if err == nil && iPrice != nil && oPrice.Cmp(iPrice) == 1 { - return fmt.Errorf("Orchestrator price has changed, Orchestrator price: %v, Orchestrator initial price: %v", oPrice, iPrice) + initPrice, err := common.RatPriceInfo(sess.InitialPrice) + if err != nil { + glog.Warningf("Error parsing session initial price (%d / %d): %v", + sess.InitialPrice.PricePerUnit, sess.InitialPrice.PixelsPerUnit, err) + } + if initPrice != nil { + // Prices are dynamic if configured with a custom currency, so we need to allow some change during the session. + // TODO: Make sure prices stay the same during a session so we can make this logic more strict, disallowing any price changes. + maxIncreasedPrice := new(big.Rat).Mul(initPrice, priceIncreaseThreshold) + if oPrice.Cmp(maxIncreasedPrice) > 0 { + return fmt.Errorf("Orchestrator price has more than doubled, Orchestrator price: %v, Orchestrator initial price: %v", oPrice.RatString(), initPrice.RatString()) + } } return nil diff --git a/server/segment_rpc_test.go b/server/segment_rpc_test.go index 01c37f903c..282e3187dc 100644 --- a/server/segment_rpc_test.go +++ b/server/segment_rpc_test.go @@ -1679,13 +1679,13 @@ func TestSubmitSegment_GenPaymentError_ValidatePriceError(t *testing.T) { OrchestratorInfo: oinfo, InitialPrice: &net.PriceInfo{ PricePerUnit: 1, - PixelsPerUnit: 5, + PixelsPerUnit: 7, }, } _, err := SubmitSegment(context.TODO(), s, &stream.HLSSegment{}, nil, 0, false, true) - assert.EqualError(t, err, fmt.Sprintf("Orchestrator price has changed, Orchestrator price: %v, Orchestrator initial price: %v", "1/3", "1/5")) + assert.EqualError(t, err, fmt.Sprintf("Orchestrator price has more than doubled, Orchestrator price: %v, Orchestrator initial price: %v", "1/3", "1/7")) balance.AssertCalled(t, "Credit", existingCredit) } From eb25467f56d8288aadffe9592a299e37c43aa1e9 Mon Sep 17 00:00:00 2001 From: Victor Elias Date: Fri, 5 Apr 2024 15:57:33 -0300 Subject: [PATCH 09/88] server,discovery: Allow B to use any O in case none match maxPrice (#2999) * discovery: Ignore maxPrice on db_discovery queries Still kept the feature on the db as it had all the tests already implemented and could still be useful in the future. I can remove it if preferred though. * server: Get prices as big rats for selection While this may not seem useful now since we just convert them to floats on the probability calculation, it will be useful later when comparing prices to max price. * server: Add maxPrice filter logic on selection algorithm * CHANGELOG * server: Break filter in 2 functions --- CHANGELOG_PENDING.md | 1 + common/types.go | 9 ++- discovery/db_discovery.go | 14 +--- discovery/discovery_test.go | 26 ++++--- server/selection.go | 9 ++- server/selection_algorithm.go | 48 +++++++++--- server/selection_algorithm_test.go | 121 +++++++++++++++++++++++++++-- server/selection_test.go | 8 +- 8 files changed, 190 insertions(+), 46 deletions(-) diff --git a/CHANGELOG_PENDING.md b/CHANGELOG_PENDING.md index f5e99d64c6..1015174350 100644 --- a/CHANGELOG_PENDING.md +++ b/CHANGELOG_PENDING.md @@ -11,6 +11,7 @@ #### Broadcaster - [#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 diff --git a/common/types.go b/common/types.go index 0dc4e7445b..4535e24e36 100644 --- a/common/types.go +++ b/common/types.go @@ -3,12 +3,13 @@ package common import ( "context" "encoding/json" - ethcommon "github.com/ethereum/go-ethereum/common" - "github.com/livepeer/go-livepeer/net" - "github.com/livepeer/m3u8" "math/big" "net/url" "sync" + + ethcommon "github.com/ethereum/go-ethereum/common" + "github.com/livepeer/go-livepeer/net" + "github.com/livepeer/m3u8" ) type RemoteTranscoderInfo struct { @@ -104,7 +105,7 @@ type OrchestratorPool interface { } type SelectionAlgorithm interface { - Select(addrs []ethcommon.Address, stakes map[ethcommon.Address]int64, prices map[ethcommon.Address]float64, perfScores map[ethcommon.Address]float64) ethcommon.Address + Select(addrs []ethcommon.Address, stakes map[ethcommon.Address]int64, maxPrice *big.Rat, prices map[ethcommon.Address]*big.Rat, perfScores map[ethcommon.Address]float64) ethcommon.Address } type PerfScore struct { diff --git a/discovery/db_discovery.go b/discovery/db_discovery.go index f75a9cdb01..7747be9b72 100644 --- a/discovery/db_discovery.go +++ b/discovery/db_discovery.go @@ -16,7 +16,6 @@ import ( lpTypes "github.com/livepeer/go-livepeer/eth/types" "github.com/livepeer/go-livepeer/net" "github.com/livepeer/go-livepeer/pm" - "github.com/livepeer/go-livepeer/server" "github.com/golang/glog" ) @@ -71,7 +70,6 @@ func NewDBOrchestratorPoolCache(ctx context.Context, node *core.LivepeerNode, rm func (dbo *DBOrchestratorPoolCache) getURLs() ([]*url.URL, error) { orchs, err := dbo.store.SelectOrchs( &common.DBOrchFilter{ - MaxPrice: server.BroadcastCfg.MaxPrice(), CurrentRound: dbo.rm.LastInitializedRound(), UpdatedLastDay: true, }, @@ -120,8 +118,7 @@ func (dbo *DBOrchestratorPoolCache) GetOrchestrators(ctx context.Context, numOrc return false } - // check if O's price is below B's max price - maxPrice := server.BroadcastCfg.MaxPrice() + // check if O has a valid price price, err := common.RatPriceInfo(info.PriceInfo) if err != nil { clog.V(common.DEBUG).Infof(ctx, "invalid price info orch=%v err=%q", info.GetTranscoder(), err) @@ -131,12 +128,8 @@ func (dbo *DBOrchestratorPoolCache) GetOrchestrators(ctx context.Context, numOrc clog.V(common.DEBUG).Infof(ctx, "no price info received for orch=%v", info.GetTranscoder()) return false } - if maxPrice != nil && price.Cmp(maxPrice) > 0 { - clog.V(common.DEBUG).Infof(ctx, "orchestrator's price is too high orch=%v price=%v wei/pixel maxPrice=%v wei/pixel", - info.GetTranscoder(), - price.FloatString(3), - maxPrice.FloatString(3), - ) + if price.Sign() < 0 { + clog.V(common.DEBUG).Infof(ctx, "invalid price received for orch=%v price=%v", info.GetTranscoder(), price.RatString()) return false } return true @@ -154,7 +147,6 @@ func (dbo *DBOrchestratorPoolCache) GetOrchestrators(ctx context.Context, numOrc func (dbo *DBOrchestratorPoolCache) Size() int { count, _ := dbo.store.OrchCount( &common.DBOrchFilter{ - MaxPrice: server.BroadcastCfg.MaxPrice(), CurrentRound: dbo.rm.LastInitializedRound(), UpdatedLastDay: true, }, diff --git a/discovery/discovery_test.go b/discovery/discovery_test.go index c7e2b1d3ac..33e20e5b79 100644 --- a/discovery/discovery_test.go +++ b/discovery/discovery_test.go @@ -620,7 +620,7 @@ func TestNewOrchestratorPoolWithPred_TestPredicate(t *testing.T) { assert.False(t, pool.pred(oInfo)) } -func TestCachedPool_AllOrchestratorsTooExpensive_ReturnsEmptyList(t *testing.T) { +func TestCachedPool_AllOrchestratorsTooExpensive_ReturnsAllOrchestrators(t *testing.T) { // Test setup expPriceInfo := &net.PriceInfo{ PricePerUnit: 999, @@ -698,14 +698,15 @@ func TestCachedPool_AllOrchestratorsTooExpensive_ReturnsEmptyList(t *testing.T) } // check size - assert.Equal(0, pool.Size()) + assert.Equal(50, pool.Size()) urls := pool.GetInfos() - assert.Len(urls, 0) + assert.Len(urls, 50) + infos, err := pool.GetOrchestrators(context.TODO(), len(addresses), newStubSuspender(), newStubCapabilities(), common.ScoreAtLeast(0)) assert.Nil(err, "Should not be error") - assert.Len(infos, 0) + assert.Len(infos, 50) } func TestCachedPool_GetOrchestrators_MaxBroadcastPriceNotSet(t *testing.T) { @@ -899,22 +900,27 @@ func TestCachedPool_N_OrchestratorsGoodPricing_ReturnsNOrchestrators(t *testing. assert.Contains(testOrchs[25:], toOrchTest(o.EthereumAddr, o.ServiceURI, o.PricePerPixel)) } - // check size - assert.Equal(25, pool.Size()) + // check pool returns all Os, not filtering by max price + assert.Equal(50, pool.Size()) infos := pool.GetInfos() - assert.Len(infos, 25) + assert.Len(infos, 50) for _, info := range infos { - assert.Contains(addresses[25:], info.URL.String()) + assert.Contains(addresses, info.URL.String()) } oinfos, err := pool.GetOrchestrators(context.TODO(), len(orchestrators), newStubSuspender(), newStubCapabilities(), common.ScoreAtLeast(0)) assert.Nil(err, "Should not be error") - assert.Len(oinfos, 25) + assert.Len(oinfos, 50) + + seenAddrs := make(map[string]bool) for _, info := range oinfos { - assert.Equal(info.RemoteInfo.Transcoder, "goodPriceTranscoder") + addr := info.LocalInfo.URL.String() + assert.Contains(addresses, addr) + seenAddrs[addr] = true } + assert.Len(seenAddrs, 50) } func TestCachedPool_GetOrchestrators_TicketParamsValidation(t *testing.T) { diff --git a/server/selection.go b/server/selection.go index c7187c79e1..e9b9103247 100644 --- a/server/selection.go +++ b/server/selection.go @@ -3,6 +3,8 @@ package server import ( "container/heap" "context" + "math/big" + ethcommon "github.com/ethereum/go-ethereum/common" "github.com/livepeer/go-livepeer/clog" "github.com/livepeer/go-livepeer/common" @@ -167,7 +169,7 @@ func (s *MinLSSelector) selectUnknownSession(ctx context.Context) *BroadcastSess } var addrs []ethcommon.Address - prices := map[ethcommon.Address]float64{} + prices := map[ethcommon.Address]*big.Rat{} addrCount := make(map[ethcommon.Address]int) for _, sess := range s.unknownSessions { if sess.OrchestratorInfo.GetTicketParams() == nil { @@ -180,9 +182,10 @@ func (s *MinLSSelector) selectUnknownSession(ctx context.Context) *BroadcastSess addrCount[addr]++ pi := sess.OrchestratorInfo.PriceInfo if pi != nil && pi.PixelsPerUnit != 0 { - prices[addr] = float64(pi.PricePerUnit) / float64(pi.PixelsPerUnit) + prices[addr] = big.NewRat(pi.PricePerUnit, pi.PixelsPerUnit) } } + maxPrice := BroadcastCfg.MaxPrice() stakes, err := s.stakeRdr.Stakes(addrs) if err != nil { @@ -199,7 +202,7 @@ func (s *MinLSSelector) selectUnknownSession(ctx context.Context) *BroadcastSess s.perfScore.Mu.Unlock() } - selected := s.selectionAlgorithm.Select(addrs, stakes, prices, perfScores) + selected := s.selectionAlgorithm.Select(addrs, stakes, maxPrice, prices, perfScores) for i, sess := range s.unknownSessions { if sess.OrchestratorInfo.GetTicketParams() == nil { diff --git a/server/selection_algorithm.go b/server/selection_algorithm.go index 72bc2a663b..54aebb0e65 100644 --- a/server/selection_algorithm.go +++ b/server/selection_algorithm.go @@ -1,11 +1,13 @@ package server import ( - ethcommon "github.com/ethereum/go-ethereum/common" - "github.com/golang/glog" "math" + "math/big" "math/rand" "time" + + ethcommon "github.com/ethereum/go-ethereum/common" + "github.com/golang/glog" ) var random = rand.New(rand.NewSource(time.Now().UnixNano())) @@ -20,14 +22,19 @@ type ProbabilitySelectionAlgorithm struct { PriceExpFactor float64 } -func (sa ProbabilitySelectionAlgorithm) Select(addrs []ethcommon.Address, stakes map[ethcommon.Address]int64, prices map[ethcommon.Address]float64, perfScores map[ethcommon.Address]float64) ethcommon.Address { - filtered := sa.filter(addrs, perfScores) +func (sa ProbabilitySelectionAlgorithm) Select(addrs []ethcommon.Address, stakes map[ethcommon.Address]int64, maxPrice *big.Rat, prices map[ethcommon.Address]*big.Rat, perfScores map[ethcommon.Address]float64) ethcommon.Address { + filtered := sa.filter(addrs, maxPrice, prices, perfScores) probabilities := sa.calculateProbabilities(filtered, stakes, prices) return selectBy(probabilities) } -func (sa ProbabilitySelectionAlgorithm) filter(addrs []ethcommon.Address, scores map[ethcommon.Address]float64) []ethcommon.Address { - if sa.MinPerfScore <= 0 || scores == nil || len(scores) == 0 { +func (sa ProbabilitySelectionAlgorithm) filter(addrs []ethcommon.Address, maxPrice *big.Rat, prices map[ethcommon.Address]*big.Rat, perfScores map[ethcommon.Address]float64) []ethcommon.Address { + filteredByPerfScore := sa.filterByPerfScore(addrs, perfScores) + return sa.filterByMaxPrice(filteredByPerfScore, maxPrice, prices) +} + +func (sa ProbabilitySelectionAlgorithm) filterByPerfScore(addrs []ethcommon.Address, scores map[ethcommon.Address]float64) []ethcommon.Address { + if sa.MinPerfScore <= 0 || len(scores) == 0 { // Performance Score filter not defined, return all Orchestrators return addrs } @@ -40,7 +47,7 @@ func (sa ProbabilitySelectionAlgorithm) filter(addrs []ethcommon.Address, scores } if len(res) == 0 { - // If no orchestrators pass the filter, then returns all Orchestrators + // If no orchestrators pass the perf filter, return all Orchestrators. // That may mean some issues with the PerfScore service. glog.Warning("No Orchestrators passed min performance score filter, not using the filter") return addrs @@ -48,10 +55,33 @@ func (sa ProbabilitySelectionAlgorithm) filter(addrs []ethcommon.Address, scores return res } -func (sa ProbabilitySelectionAlgorithm) calculateProbabilities(addrs []ethcommon.Address, stakes map[ethcommon.Address]int64, prices map[ethcommon.Address]float64) map[ethcommon.Address]float64 { +func (sa ProbabilitySelectionAlgorithm) filterByMaxPrice(addrs []ethcommon.Address, maxPrice *big.Rat, prices map[ethcommon.Address]*big.Rat) []ethcommon.Address { + if maxPrice == nil || len(prices) == 0 { + // Max price filter not defined, return all Orchestrators + return addrs + } + + var res []ethcommon.Address + for _, addr := range addrs { + price := prices[addr] + if price != nil && price.Cmp(maxPrice) <= 0 { + res = append(res, addr) + } + } + + if len(res) == 0 { + // If no orchestrators pass the filter, return all Orchestrators + // It means that no orchestrators are below the max price + glog.Warning("No Orchestrators passed max price filter, not using the filter") + return addrs + } + return res +} + +func (sa ProbabilitySelectionAlgorithm) calculateProbabilities(addrs []ethcommon.Address, stakes map[ethcommon.Address]int64, prices map[ethcommon.Address]*big.Rat) map[ethcommon.Address]float64 { pricesNorm := map[ethcommon.Address]float64{} for _, addr := range addrs { - p := prices[addr] + p, _ := prices[addr].Float64() pricesNorm[addr] = math.Exp(-1 * p / sa.PriceExpFactor) } diff --git a/server/selection_algorithm_test.go b/server/selection_algorithm_test.go index 96ef58f0a4..85e677a6ba 100644 --- a/server/selection_algorithm_test.go +++ b/server/selection_algorithm_test.go @@ -1,9 +1,11 @@ package server import ( + "math/big" + "testing" + ethcommon "github.com/ethereum/go-ethereum/common" "github.com/stretchr/testify/require" - "testing" ) const testPriceExpFactor = 100 @@ -12,6 +14,8 @@ 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 @@ -85,21 +89,126 @@ func TestFilter(t *testing.T) { "0x0000000000000000000000000000000000000004", }, }, + { + name: "All prices below max price", + orchMinPerfScore: 0.7, + maxPrice: 2000, + 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{ + "0x0000000000000000000000000000000000000002", + "0x0000000000000000000000000000000000000003", + }, + }, + { + name: "All prices above 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{ + "0x0000000000000000000000000000000000000002", + "0x0000000000000000000000000000000000000003", + }, + }, + { + name: "Mix of prices relative to max price", + orchMinPerfScore: 0.7, + maxPrice: 750, + prices: map[string]float64{ + "0x0000000000000000000000000000000000000001": 500, + "0x0000000000000000000000000000000000000002": 1500, + "0x0000000000000000000000000000000000000003": 700, + }, + orchPerfScores: map[string]float64{ + "0x0000000000000000000000000000000000000001": 0.8, + "0x0000000000000000000000000000000000000002": 0.6, + "0x0000000000000000000000000000000000000003": 0.9, + }, + orchestrators: []string{ + "0x0000000000000000000000000000000000000001", + "0x0000000000000000000000000000000000000002", + "0x0000000000000000000000000000000000000003", + }, + want: []string{ + "0x0000000000000000000000000000000000000001", + "0x0000000000000000000000000000000000000003", + }, + }, + { + name: "Exact match with max price", + orchMinPerfScore: 0.7, + maxPrice: 1000, + prices: map[string]float64{ + "0x0000000000000000000000000000000000000001": 500, + "0x0000000000000000000000000000000000000002": 1000, // exactly max + "0x0000000000000000000000000000000000000003": 1500, + }, + orchPerfScores: map[string]float64{ + "0x0000000000000000000000000000000000000001": 0.8, + "0x0000000000000000000000000000000000000002": 0.9, + "0x0000000000000000000000000000000000000003": 0.6, + }, + orchestrators: []string{ + "0x0000000000000000000000000000000000000001", + "0x0000000000000000000000000000000000000002", + "0x0000000000000000000000000000000000000003", + }, + want: []string{ + "0x0000000000000000000000000000000000000001", + "0x0000000000000000000000000000000000000002", + }, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { var addrs []ethcommon.Address + var maxPrice *big.Rat + prices := map[ethcommon.Address]*big.Rat{} perfScores := map[ethcommon.Address]float64{} for _, o := range tt.orchestrators { - perfScores[ethcommon.HexToAddress(o)] = tt.orchPerfScores[o] - addrs = append(addrs, ethcommon.HexToAddress(o)) + addr := ethcommon.HexToAddress(o) + addrs = append(addrs, addr) + perfScores[addr] = tt.orchPerfScores[o] + if price, ok := tt.prices[o]; ok { + prices[addr] = new(big.Rat).SetFloat64(price) + } + } + if tt.maxPrice > 0 { + maxPrice = new(big.Rat).SetFloat64(tt.maxPrice) } sa := &ProbabilitySelectionAlgorithm{ MinPerfScore: tt.orchMinPerfScore, } - res := sa.filter(addrs, perfScores) + res := sa.filter(addrs, maxPrice, prices, perfScores) var exp []ethcommon.Address for _, o := range tt.want { @@ -160,13 +269,13 @@ func TestCalculateProbabilities(t *testing.T) { t.Run(tt.name, func(t *testing.T) { var orchs []ethcommon.Address stakes := map[ethcommon.Address]int64{} - prices := map[ethcommon.Address]float64{} + prices := map[ethcommon.Address]*big.Rat{} expProbs := map[ethcommon.Address]float64{} for i, addrStr := range tt.addrs { addr := ethcommon.HexToAddress(addrStr) orchs = append(orchs, addr) stakes[addr] = tt.stakes[i] - prices[addr] = tt.prices[i] + prices[addr] = new(big.Rat).SetFloat64(tt.prices[i]) expProbs[addr] = tt.want[i] } diff --git a/server/selection_test.go b/server/selection_test.go index 716c780d06..b7d6958ab3 100644 --- a/server/selection_test.go +++ b/server/selection_test.go @@ -4,10 +4,12 @@ import ( "container/heap" "context" "errors" + "math/big" + "testing" + "github.com/livepeer/go-livepeer/core" "github.com/livepeer/go-livepeer/net" "github.com/stretchr/testify/require" - "testing" ethcommon "github.com/ethereum/go-ethereum/common" "github.com/livepeer/go-livepeer/common" @@ -89,7 +91,7 @@ func (r *stubStakeReader) SetStakes(stakes map[ethcommon.Address]int64) { type stubSelectionAlgorithm struct{} -func (sa stubSelectionAlgorithm) Select(addrs []ethcommon.Address, stakes map[ethcommon.Address]int64, prices map[ethcommon.Address]float64, perfScores map[ethcommon.Address]float64) ethcommon.Address { +func (sa stubSelectionAlgorithm) Select(addrs []ethcommon.Address, stakes map[ethcommon.Address]int64, maxPrice *big.Rat, prices map[ethcommon.Address]*big.Rat, perfScores map[ethcommon.Address]float64) ethcommon.Address { if len(addrs) == 0 { return ethcommon.Address{} } @@ -98,7 +100,7 @@ func (sa stubSelectionAlgorithm) Select(addrs []ethcommon.Address, stakes map[et // select lowest price lowest := prices[addr] for _, a := range addrs { - if prices[a] < lowest { + if prices[a].Cmp(lowest) < 0 { addr = a lowest = prices[a] } From 52186d7c1d7dd8508b9eec9e840f88f3762257b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Leszko?= Date: Wed, 10 Apr 2024 14:46:07 +0200 Subject: [PATCH 10/88] Fix transcoding price metrics (#3001) --- monitor/census.go | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/monitor/census.go b/monitor/census.go index 3381a92d7f..8c80459bc7 100644 --- a/monitor/census.go +++ b/monitor/census.go @@ -1551,14 +1551,12 @@ func Reserve(sender string, reserve *big.Int) { } func MaxTranscodingPrice(maxPrice *big.Rat) { - floatWei, ok := maxPrice.Float64() - if ok { - if err := stats.RecordWithTags(census.ctx, - []tag.Mutator{tag.Insert(census.kSender, "max")}, - census.mTranscodingPrice.M(floatWei)); err != nil { + floatWei, _ := maxPrice.Float64() + if err := stats.RecordWithTags(census.ctx, + []tag.Mutator{tag.Insert(census.kSender, "max")}, + census.mTranscodingPrice.M(floatWei)); err != nil { - glog.Errorf("Error recording metrics err=%q", err) - } + glog.Errorf("Error recording metrics err=%q", err) } } @@ -1672,15 +1670,13 @@ func MaxGasPrice(maxGasPrice *big.Int) { // TranscodingPrice records the last transcoding price func TranscodingPrice(sender string, price *big.Rat) { - floatWei, ok := price.Float64() - if ok { - stats.Record(census.ctx, census.mTranscodingPrice.M(floatWei)) - if err := stats.RecordWithTags(census.ctx, - []tag.Mutator{tag.Insert(census.kSender, sender)}, - census.mTranscodingPrice.M(floatWei)); err != nil { + floatWei, _ := price.Float64() + stats.Record(census.ctx, census.mTranscodingPrice.M(floatWei)) + if err := stats.RecordWithTags(census.ctx, + []tag.Mutator{tag.Insert(census.kSender, sender)}, + census.mTranscodingPrice.M(floatWei)); err != nil { - glog.Errorf("Error recording metrics err=%q", err) - } + glog.Errorf("Error recording metrics err=%q", err) } } From 44c95d093d7cd61fcbd53628d7c44d83b156a593 Mon Sep 17 00:00:00 2001 From: Rick Staa Date: Sat, 13 Apr 2024 10:47:55 +0200 Subject: [PATCH 11/88] ci(ai): add AI issue templates This commit introduces two new AI-specific issue templates, aiming to streamline the routing of AI subnet-related issues and feature requests to the appropriate team. --- .github/ISSUE_TEMPLATE/ai_bug_report.yml | 76 +++++++++++++++++++ .github/ISSUE_TEMPLATE/ai_feature_request.yml | 45 +++++++++++ .github/ISSUE_TEMPLATE/config.yml | 8 ++ 3 files changed, 129 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/ai_bug_report.yml create mode 100644 .github/ISSUE_TEMPLATE/ai_feature_request.yml create mode 100644 .github/ISSUE_TEMPLATE/config.yml diff --git a/.github/ISSUE_TEMPLATE/ai_bug_report.yml b/.github/ISSUE_TEMPLATE/ai_bug_report.yml new file mode 100644 index 0000000000..b992554a2e --- /dev/null +++ b/.github/ISSUE_TEMPLATE/ai_bug_report.yml @@ -0,0 +1,76 @@ +name: AI Bug report +description: Create a report to help us improve. +labels: + - "bug" + - "ai" +body: + - type: markdown + attributes: + value: | + ## Bug report + Please fill out the following information to help us understand your issue. + + > [!IMPORTANT] + > This repository is only related to the core bugs with the AI branch of the go-livepeer software (i.e. `ai-video`). It does not cover bugs related to running AI pipelines and AI models used on the AI subnet. For these issues, please refer to the [AI-worker repository](https://github.com/livepeer/ai-worker/issues/new/choose) + - type: textarea + attributes: + label: Describe the bug + description: A clear and concise description of what the bug is. + validations: + required: true + - type: textarea + attributes: + label: Reproduction steps + description: "How do you trigger this bug? Please walk us through it step by step." + value: | + 1. Go to '...' + 2. Click on '....' + 3. Scroll down to '....' + 4. See error + - type: textarea + attributes: + label: Expected behaviour + description: A clear and concise description of what you expected to happen. + - type: dropdown + id: severity + attributes: + label: Severity + description: "How severe is this bug?" + options: + - Minor + - Major + - Critical + - type: textarea + attributes: + label: Screenshots / Live demo link + description: If applicable, add screenshots to help explain your problem. + placeholder: Paste the image link as markdown image + - type: dropdown + id: os + attributes: + label: OS + description: "What operating system are you using?" + options: + - Windows + - Mac + - Linux + - type: dropdown + id: running_on + attributes: + label: Running on + description: "Where are you running the application?" + options: + - Local + - Docker + - type: input + attributes: + label: AI go-livepeer version + description: "What version of the AI-worker are you using?" + - type: input + attributes: + label: AI go-livepeer commit hash + description: "Could you please provide the commit hash of the `ai-video` branch that you are currently using?" + - type: textarea + attributes: + label: Additional context + description: Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/ai_feature_request.yml b/.github/ISSUE_TEMPLATE/ai_feature_request.yml new file mode 100644 index 0000000000..22ddfa71f4 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/ai_feature_request.yml @@ -0,0 +1,45 @@ +name: AI Feature request +description: Suggest an idea for this project. +labels: + - "enhancement" + - "ai" +body: + - type: markdown + attributes: + value: | + ## Feature Request + Please fill out the following information to help us understand your request. + + > [!IMPORTANT] + > This repository is only related to feature requests related to the the AI branch of the go-livepeer software (i.e. `ai-video`). It does not cover feature requests related to the addition of new AI pipelines and AI models used on the AI subnet. For these issues, please refer to the [AI-worker repository](https://github.com/livepeer/ai-worker/issues/new/choose). + - type: textarea + attributes: + label: Is your feature request related to a problem? Please describe. + description: + A clear and concise description of what the problem is. Ex. I'm always + frustrated when [...] + validations: + required: true + - type: textarea + attributes: + label: Describe the solution you'd like + description: A clear and concise description of what you want to happen. + - type: textarea + attributes: + label: Describe alternatives you've considered + description: + A clear and concise description of any alternative solutions or features + you've considered. + - type: textarea + attributes: + label: Use Case + description: "Please describe why you want this feature to be added. This will help us prioritize your request." + - type: textarea + attributes: + label: Expected Outcome + description: "What do you expect to happen once this feature is implemented?" + - type: textarea + attributes: + label: Additional context + description: + Add any other context or screenshots about the feature request here. diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000000..4ee3f97db0 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,8 @@ +blank_issues_enabled: true +contact_links: + - name: Go-livepeer Question + url: https://github.com/livepeer/go-livepeer/discussions + about: Please ask and answer questions related to the go-livepeer software here. + - name: Livepeer Question + url: https://discord.gg/livepeer + about: "Have a general Livepeer question? Join us in the Livepeer Discord server. We're here to help!" From c822b132d790e89fc6601a3052990cea3faeb85b Mon Sep 17 00:00:00 2001 From: Rick Staa Date: Sat, 13 Apr 2024 11:13:08 +0200 Subject: [PATCH 12/88] ci(ai): add AI pull request labeler This commit adds a pull request labeler action that automatically attaches the `ai` label when a pull request is created to the `ai-video` branch. --- .github/workflows/issue-labeler.yml | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/.github/workflows/issue-labeler.yml b/.github/workflows/issue-labeler.yml index b647014f3c..92a7186661 100644 --- a/.github/workflows/issue-labeler.yml +++ b/.github/workflows/issue-labeler.yml @@ -1,11 +1,13 @@ -name: Label issues +name: Label issues and pull requests on: issues: - types: - - reopened - - opened + types: [opened, reopened] + pull_request: + types: [opened, reopened] + jobs: label_issues: + if: ${{ github.event_name == 'issues' }} runs-on: ubuntu-latest permissions: issues: write @@ -16,3 +18,12 @@ jobs: add-labels: "status: triage" repo-token: ${{ secrets.GITHUB_TOKEN }} ignore-if-assigned: false + + label_pull_requests: + if: ${{ github.event_name == 'pull_request' }} + runs-on: ubuntu-latest + permissions: + contents: read + pull-requests: write + steps: + - uses: actions/labeler@v5 From 8d378fd3b36d53a6a1acdc4ba694ef42d360bcc7 Mon Sep 17 00:00:00 2001 From: Rick Staa Date: Mon, 15 Apr 2024 14:28:45 +0200 Subject: [PATCH 13/88] ci: change issue template order and add PR labeler config (#3006) * ci: change issue template order This commit ensures that the main branch issue templates are put above the AI related issue templates. * ci(ai): add PR labeler config file This commmit adds a https://github.com/actions/labeler configuration file so that all PRs on the `ai-video` branch will be correctly labeled with the `ai` label. --- .github/ISSUE_TEMPLATE/{bug_report.md => 01-bug_report.md} | 0 .../{feature_request.md => 02-feature_request.md} | 0 .github/ISSUE_TEMPLATE/{spec.md => 03-spec.md} | 0 .../{ai_bug_report.yml => bug_report_ai_video.yml} | 0 .../{ai_feature_request.yml => feature_request_ai.yml} | 0 .github/labeler.yml | 2 ++ 6 files changed, 2 insertions(+) rename .github/ISSUE_TEMPLATE/{bug_report.md => 01-bug_report.md} (100%) rename .github/ISSUE_TEMPLATE/{feature_request.md => 02-feature_request.md} (100%) rename .github/ISSUE_TEMPLATE/{spec.md => 03-spec.md} (100%) rename .github/ISSUE_TEMPLATE/{ai_bug_report.yml => bug_report_ai_video.yml} (100%) rename .github/ISSUE_TEMPLATE/{ai_feature_request.yml => feature_request_ai.yml} (100%) create mode 100644 .github/labeler.yml diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/01-bug_report.md similarity index 100% rename from .github/ISSUE_TEMPLATE/bug_report.md rename to .github/ISSUE_TEMPLATE/01-bug_report.md diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/02-feature_request.md similarity index 100% rename from .github/ISSUE_TEMPLATE/feature_request.md rename to .github/ISSUE_TEMPLATE/02-feature_request.md diff --git a/.github/ISSUE_TEMPLATE/spec.md b/.github/ISSUE_TEMPLATE/03-spec.md similarity index 100% rename from .github/ISSUE_TEMPLATE/spec.md rename to .github/ISSUE_TEMPLATE/03-spec.md diff --git a/.github/ISSUE_TEMPLATE/ai_bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report_ai_video.yml similarity index 100% rename from .github/ISSUE_TEMPLATE/ai_bug_report.yml rename to .github/ISSUE_TEMPLATE/bug_report_ai_video.yml diff --git a/.github/ISSUE_TEMPLATE/ai_feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request_ai.yml similarity index 100% rename from .github/ISSUE_TEMPLATE/ai_feature_request.yml rename to .github/ISSUE_TEMPLATE/feature_request_ai.yml diff --git a/.github/labeler.yml b/.github/labeler.yml new file mode 100644 index 0000000000..4e219d6f45 --- /dev/null +++ b/.github/labeler.yml @@ -0,0 +1,2 @@ +ai: + - base-branch: "ai-video" From bc726a81358e625399f13a68039b2c7e02efb495 Mon Sep 17 00:00:00 2001 From: Rick Staa Date: Tue, 16 Apr 2024 08:01:45 +0200 Subject: [PATCH 14/88] ci(ai): fix incorrect labels (#3012) * ci(ai): fix incorrect labels This commit fixed the labels that were specified in the Issue Templates to the one found in the repository. * ci: rename labeler and remove trailing whitespace --- .github/ISSUE_TEMPLATE/bug_report_ai_video.yml | 4 ++-- .github/ISSUE_TEMPLATE/feature_request_ai.yml | 4 ++-- .github/labeler.yml | 2 +- .github/workflows/{issue-labeler.yml => labeler.yml} | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) rename .github/workflows/{issue-labeler.yml => labeler.yml} (95%) diff --git a/.github/ISSUE_TEMPLATE/bug_report_ai_video.yml b/.github/ISSUE_TEMPLATE/bug_report_ai_video.yml index b992554a2e..b8a7c25dd0 100644 --- a/.github/ISSUE_TEMPLATE/bug_report_ai_video.yml +++ b/.github/ISSUE_TEMPLATE/bug_report_ai_video.yml @@ -1,8 +1,8 @@ name: AI Bug report description: Create a report to help us improve. labels: - - "bug" - - "ai" + - "type: bug" + - "AI" body: - type: markdown attributes: diff --git a/.github/ISSUE_TEMPLATE/feature_request_ai.yml b/.github/ISSUE_TEMPLATE/feature_request_ai.yml index 22ddfa71f4..0c708f1100 100644 --- a/.github/ISSUE_TEMPLATE/feature_request_ai.yml +++ b/.github/ISSUE_TEMPLATE/feature_request_ai.yml @@ -1,8 +1,8 @@ name: AI Feature request description: Suggest an idea for this project. labels: - - "enhancement" - - "ai" + - "type: feature" + - "AI" body: - type: markdown attributes: diff --git a/.github/labeler.yml b/.github/labeler.yml index 4e219d6f45..2e2c7b2861 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -1,2 +1,2 @@ -ai: +AI: - base-branch: "ai-video" diff --git a/.github/workflows/issue-labeler.yml b/.github/workflows/labeler.yml similarity index 95% rename from .github/workflows/issue-labeler.yml rename to .github/workflows/labeler.yml index 92a7186661..0c45d7086b 100644 --- a/.github/workflows/issue-labeler.yml +++ b/.github/workflows/labeler.yml @@ -18,7 +18,7 @@ jobs: add-labels: "status: triage" repo-token: ${{ secrets.GITHUB_TOKEN }} ignore-if-assigned: false - + label_pull_requests: if: ${{ github.event_name == 'pull_request' }} runs-on: ubuntu-latest @@ -26,4 +26,4 @@ jobs: contents: read pull-requests: write steps: - - uses: actions/labeler@v5 + - uses: actions/labeler@v5 From 930533388e62d21b339cccd8d6f4348dc14c5e75 Mon Sep 17 00:00:00 2001 From: Rick Staa Date: Fri, 19 Apr 2024 08:59:20 +0200 Subject: [PATCH 15/88] ci(ai): fix pull request config warning (#3018) (#3019) * ci(ai): fix pull request config warning (#3018) This commit gets rid of the Pull request labeler configuration file warning. * ci(ai): auto assign AI issues This commit auto assigns the AI issues to the right member of the AI team. * ci(ai): cleanup labeler actions This commit cleans up the labeler actions and ensure they run on the right triggers. --- .github/ISSUE_TEMPLATE/bug_report_ai_video.yml | 2 ++ .github/ISSUE_TEMPLATE/feature_request_ai.yml | 2 ++ .../workflows/{labeler.yml => issue-labeler.yml} | 13 +------------ .github/workflows/pr-labeler.yml | 14 ++++++++++++++ 4 files changed, 19 insertions(+), 12 deletions(-) rename .github/workflows/{labeler.yml => issue-labeler.yml} (57%) create mode 100644 .github/workflows/pr-labeler.yml diff --git a/.github/ISSUE_TEMPLATE/bug_report_ai_video.yml b/.github/ISSUE_TEMPLATE/bug_report_ai_video.yml index b8a7c25dd0..bd8565982e 100644 --- a/.github/ISSUE_TEMPLATE/bug_report_ai_video.yml +++ b/.github/ISSUE_TEMPLATE/bug_report_ai_video.yml @@ -3,6 +3,8 @@ description: Create a report to help us improve. labels: - "type: bug" - "AI" +assignees: + - rickstaa body: - type: markdown attributes: diff --git a/.github/ISSUE_TEMPLATE/feature_request_ai.yml b/.github/ISSUE_TEMPLATE/feature_request_ai.yml index 0c708f1100..648117fa78 100644 --- a/.github/ISSUE_TEMPLATE/feature_request_ai.yml +++ b/.github/ISSUE_TEMPLATE/feature_request_ai.yml @@ -3,6 +3,8 @@ description: Suggest an idea for this project. labels: - "type: feature" - "AI" +assignees: + - rickstaa body: - type: markdown attributes: diff --git a/.github/workflows/labeler.yml b/.github/workflows/issue-labeler.yml similarity index 57% rename from .github/workflows/labeler.yml rename to .github/workflows/issue-labeler.yml index 0c45d7086b..390535f95c 100644 --- a/.github/workflows/labeler.yml +++ b/.github/workflows/issue-labeler.yml @@ -1,9 +1,7 @@ -name: Label issues and pull requests +name: Label issues on: issues: types: [opened, reopened] - pull_request: - types: [opened, reopened] jobs: label_issues: @@ -18,12 +16,3 @@ jobs: add-labels: "status: triage" repo-token: ${{ secrets.GITHUB_TOKEN }} ignore-if-assigned: false - - label_pull_requests: - if: ${{ github.event_name == 'pull_request' }} - runs-on: ubuntu-latest - permissions: - contents: read - pull-requests: write - steps: - - uses: actions/labeler@v5 diff --git a/.github/workflows/pr-labeler.yml b/.github/workflows/pr-labeler.yml new file mode 100644 index 0000000000..26bade1dfc --- /dev/null +++ b/.github/workflows/pr-labeler.yml @@ -0,0 +1,14 @@ +name: Label PRs +on: + pull_request_target: + types: [opened, reopened] + +jobs: + label_pull_requests: + runs-on: ubuntu-latest + permissions: + contents: read + pull-requests: write + steps: + - uses: actions/checkout@v4 + - uses: actions/labeler@v5 From e9cbadbee54abe1e29393065a9c048b11ba9a215 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Leszko?= Date: Wed, 24 Apr 2024 14:49:05 +0200 Subject: [PATCH 16/88] Initialize round by any B/O who has the initializeRound flag set to true (#3029) --- cmd/livepeer/livepeer.go | 1 + cmd/livepeer/starter/starter.go | 205 ++++++++++++++++---------------- eth/roundinitializer.go | 95 ++++----------- eth/roundinitializer_test.go | 112 +---------------- 4 files changed, 131 insertions(+), 282 deletions(-) diff --git a/cmd/livepeer/livepeer.go b/cmd/livepeer/livepeer.go index d875a079f8..030d897957 100755 --- a/cmd/livepeer/livepeer.go +++ b/cmd/livepeer/livepeer.go @@ -162,6 +162,7 @@ func parseLivepeerConfig() starter.LivepeerConfig { cfg.MaxGasPrice = flag.Int("maxGasPrice", *cfg.MaxGasPrice, "Maximum gas price (priority fee + base fee) for ETH transactions in wei, 40 Gwei = 40000000000") cfg.EthController = flag.String("ethController", *cfg.EthController, "Protocol smart contract address") cfg.InitializeRound = flag.Bool("initializeRound", *cfg.InitializeRound, "Set to true if running as a transcoder and the node should automatically initialize new rounds") + cfg.InitializeRoundMaxDelay = flag.Duration("initializeRoundMaxDelay", *cfg.InitializeRoundMaxDelay, "Maximum delay to wait before initializing a round") cfg.TicketEV = flag.String("ticketEV", *cfg.TicketEV, "The expected value for PM tickets") cfg.MaxFaceValue = flag.String("maxFaceValue", *cfg.MaxFaceValue, "set max ticket face value in WEI") // Broadcaster max acceptable ticket EV diff --git a/cmd/livepeer/starter/starter.go b/cmd/livepeer/starter/starter.go index 2896d95431..f9296abfa6 100755 --- a/cmd/livepeer/starter/starter.go +++ b/cmd/livepeer/starter/starter.go @@ -74,76 +74,77 @@ const ( ) type LivepeerConfig struct { - Network *string - RtmpAddr *string - CliAddr *string - HttpAddr *string - ServiceAddr *string - OrchAddr *string - VerifierURL *string - EthController *string - VerifierPath *string - LocalVerify *bool - HttpIngest *bool - Orchestrator *bool - Transcoder *bool - Broadcaster *bool - OrchSecret *string - TranscodingOptions *string - MaxAttempts *int - SelectRandWeight *float64 - SelectStakeWeight *float64 - SelectPriceWeight *float64 - SelectPriceExpFactor *float64 - OrchPerfStatsURL *string - Region *string - MaxPricePerUnit *string - MinPerfScore *float64 - MaxSessions *string - CurrentManifest *bool - Nvidia *string - Netint *string - TestTranscoder *bool - EthAcctAddr *string - EthPassword *string - EthKeystorePath *string - EthOrchAddr *string - EthUrl *string - TxTimeout *time.Duration - MaxTxReplacements *int - GasLimit *int - MinGasPrice *int64 - MaxGasPrice *int - InitializeRound *bool - TicketEV *string - MaxFaceValue *string - MaxTicketEV *string - MaxTotalEV *string - DepositMultiplier *int - PricePerUnit *string - PixelsPerUnit *string - PriceFeedAddr *string - AutoAdjustPrice *bool - PricePerBroadcaster *string - BlockPollingInterval *int - Redeemer *bool - RedeemerAddr *string - Reward *bool - Monitor *bool - MetricsPerStream *bool - MetricsExposeClientIP *bool - MetadataQueueUri *string - MetadataAmqpExchange *string - MetadataPublishTimeout *time.Duration - Datadir *string - Objectstore *string - Recordstore *string - FVfailGsBucket *string - FVfailGsKey *string - AuthWebhookURL *string - OrchWebhookURL *string - OrchBlacklist *string - TestOrchAvail *bool + Network *string + RtmpAddr *string + CliAddr *string + HttpAddr *string + ServiceAddr *string + OrchAddr *string + VerifierURL *string + EthController *string + VerifierPath *string + LocalVerify *bool + HttpIngest *bool + Orchestrator *bool + Transcoder *bool + Broadcaster *bool + OrchSecret *string + TranscodingOptions *string + MaxAttempts *int + SelectRandWeight *float64 + SelectStakeWeight *float64 + SelectPriceWeight *float64 + SelectPriceExpFactor *float64 + OrchPerfStatsURL *string + Region *string + MaxPricePerUnit *string + MinPerfScore *float64 + MaxSessions *string + CurrentManifest *bool + Nvidia *string + Netint *string + TestTranscoder *bool + EthAcctAddr *string + EthPassword *string + EthKeystorePath *string + EthOrchAddr *string + EthUrl *string + TxTimeout *time.Duration + MaxTxReplacements *int + GasLimit *int + MinGasPrice *int64 + MaxGasPrice *int + InitializeRound *bool + InitializeRoundMaxDelay *time.Duration + TicketEV *string + MaxFaceValue *string + MaxTicketEV *string + MaxTotalEV *string + DepositMultiplier *int + PricePerUnit *string + PixelsPerUnit *string + PriceFeedAddr *string + AutoAdjustPrice *bool + PricePerBroadcaster *string + BlockPollingInterval *int + Redeemer *bool + RedeemerAddr *string + Reward *bool + Monitor *bool + MetricsPerStream *bool + MetricsExposeClientIP *bool + MetadataQueueUri *string + MetadataAmqpExchange *string + MetadataPublishTimeout *time.Duration + Datadir *string + Objectstore *string + Recordstore *string + FVfailGsBucket *string + FVfailGsKey *string + AuthWebhookURL *string + OrchWebhookURL *string + OrchBlacklist *string + TestOrchAvail *bool } // DefaultLivepeerConfig creates LivepeerConfig exactly the same as when no flags are passed to the livepeer process. @@ -190,6 +191,7 @@ func DefaultLivepeerConfig() LivepeerConfig { defaultMaxGasPrice := 0 defaultEthController := "" defaultInitializeRound := false + defaultInitializeRoundMaxDelay := 30 * time.Second defaultTicketEV := "8000000000" defaultMaxFaceValue := "0" defaultMaxTicketEV := "3000000000000" @@ -264,36 +266,37 @@ func DefaultLivepeerConfig() LivepeerConfig { TestTranscoder: &defaultTestTranscoder, // Onchain: - EthAcctAddr: &defaultEthAcctAddr, - EthPassword: &defaultEthPassword, - EthKeystorePath: &defaultEthKeystorePath, - EthOrchAddr: &defaultEthOrchAddr, - EthUrl: &defaultEthUrl, - TxTimeout: &defaultTxTimeout, - MaxTxReplacements: &defaultMaxTxReplacements, - GasLimit: &defaultGasLimit, - MaxGasPrice: &defaultMaxGasPrice, - EthController: &defaultEthController, - InitializeRound: &defaultInitializeRound, - TicketEV: &defaultTicketEV, - MaxFaceValue: &defaultMaxFaceValue, - MaxTicketEV: &defaultMaxTicketEV, - MaxTotalEV: &defaultMaxTotalEV, - DepositMultiplier: &defaultDepositMultiplier, - MaxPricePerUnit: &defaultMaxPricePerUnit, - PixelsPerUnit: &defaultPixelsPerUnit, - PriceFeedAddr: &defaultPriceFeedAddr, - AutoAdjustPrice: &defaultAutoAdjustPrice, - PricePerBroadcaster: &defaultPricePerBroadcaster, - BlockPollingInterval: &defaultBlockPollingInterval, - Redeemer: &defaultRedeemer, - RedeemerAddr: &defaultRedeemerAddr, - Monitor: &defaultMonitor, - MetricsPerStream: &defaultMetricsPerStream, - MetricsExposeClientIP: &defaultMetricsExposeClientIP, - MetadataQueueUri: &defaultMetadataQueueUri, - MetadataAmqpExchange: &defaultMetadataAmqpExchange, - MetadataPublishTimeout: &defaultMetadataPublishTimeout, + EthAcctAddr: &defaultEthAcctAddr, + EthPassword: &defaultEthPassword, + EthKeystorePath: &defaultEthKeystorePath, + EthOrchAddr: &defaultEthOrchAddr, + EthUrl: &defaultEthUrl, + TxTimeout: &defaultTxTimeout, + MaxTxReplacements: &defaultMaxTxReplacements, + GasLimit: &defaultGasLimit, + MaxGasPrice: &defaultMaxGasPrice, + EthController: &defaultEthController, + InitializeRound: &defaultInitializeRound, + InitializeRoundMaxDelay: &defaultInitializeRoundMaxDelay, + TicketEV: &defaultTicketEV, + MaxFaceValue: &defaultMaxFaceValue, + MaxTicketEV: &defaultMaxTicketEV, + MaxTotalEV: &defaultMaxTotalEV, + DepositMultiplier: &defaultDepositMultiplier, + MaxPricePerUnit: &defaultMaxPricePerUnit, + PixelsPerUnit: &defaultPixelsPerUnit, + PriceFeedAddr: &defaultPriceFeedAddr, + AutoAdjustPrice: &defaultAutoAdjustPrice, + PricePerBroadcaster: &defaultPricePerBroadcaster, + BlockPollingInterval: &defaultBlockPollingInterval, + Redeemer: &defaultRedeemer, + RedeemerAddr: &defaultRedeemerAddr, + Monitor: &defaultMonitor, + MetricsPerStream: &defaultMetricsPerStream, + MetricsExposeClientIP: &defaultMetricsExposeClientIP, + MetadataQueueUri: &defaultMetadataQueueUri, + MetadataAmqpExchange: &defaultMetadataAmqpExchange, + MetadataPublishTimeout: &defaultMetadataPublishTimeout, // Ingest: HttpIngest: &defaultHttpIngest, @@ -975,7 +978,7 @@ func StartLivepeer(ctx context.Context, cfg LivepeerConfig) { if *cfg.InitializeRound { // Start round initializer // The node will only initialize rounds if it in the upcoming active set for the round - initializer := eth.NewRoundInitializer(n.Eth, timeWatcher) + initializer := eth.NewRoundInitializer(n.Eth, timeWatcher, *cfg.InitializeRoundMaxDelay) go func() { if err := initializer.Start(); err != nil { serviceErr <- err diff --git a/eth/roundinitializer.go b/eth/roundinitializer.go index d3f2cbeeee..a7aaff6667 100644 --- a/eth/roundinitializer.go +++ b/eth/roundinitializer.go @@ -2,10 +2,11 @@ package eth import ( "math/big" + "math/rand" "sync" + "time" "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/event" "github.com/golang/glog" ) @@ -29,20 +30,22 @@ type timeWatcher interface { // This selection process is purely a client side implementation that attempts to minimize on-chain transaction collisions, but // collisions are still possible if initialization transactions are submitted by parties that are not using this selection process type RoundInitializer struct { - client LivepeerEthClient - tw timeWatcher - quit chan struct{} + maxDelay time.Duration + client LivepeerEthClient + tw timeWatcher + quit chan struct{} nextRoundStartL1Block *big.Int mu sync.Mutex } // NewRoundInitializer creates a RoundInitializer instance -func NewRoundInitializer(client LivepeerEthClient, tw timeWatcher) *RoundInitializer { +func NewRoundInitializer(client LivepeerEthClient, tw timeWatcher, maxDelay time.Duration) *RoundInitializer { return &RoundInitializer{ - client: client, - tw: tw, - quit: make(chan struct{}), + maxDelay: maxDelay, + client: client, + tw: tw, + quit: make(chan struct{}), } } @@ -104,23 +107,23 @@ func (r *RoundInitializer) tryInitialize() error { r.mu.Lock() defer r.mu.Unlock() - currentL1Blk := r.tw.LastSeenL1Block() - lastInitializedL1BlkHash := r.tw.LastInitializedL1BlockHash() - - epochSeed := r.currentEpochSeed(currentL1Blk, r.nextRoundStartL1Block, lastInitializedL1BlkHash) - - ok, err := r.shouldInitialize(epochSeed) - if err != nil { - return err + if r.tw.LastSeenL1Block().Cmp(r.nextRoundStartL1Block) < 0 { + // Round already initialized + return nil } - // Noop if the caller should not initialize the round - if !ok { - return nil + if r.maxDelay > 0 { + randDelay := time.Duration(rand.Int63n(int64(r.maxDelay))) + glog.Infof("Waiting %v before attempting to initialize round", randDelay) + time.Sleep(randDelay) + + if r.tw.LastSeenL1Block().Cmp(r.nextRoundStartL1Block) < 0 { + glog.Infof("Round is already initialized, not initializing") + return nil + } } currentRound := new(big.Int).Add(r.tw.LastInitializedRound(), big.NewInt(1)) - glog.Infof("New round - preparing to initialize round to join active set, current round is %d", currentRound) tx, err := r.client.InitializeRound() @@ -136,55 +139,3 @@ func (r *RoundInitializer) tryInitialize() error { return nil } - -func (r *RoundInitializer) shouldInitialize(epochSeed *big.Int) (bool, error) { - transcoders, err := r.client.TranscoderPool() - if err != nil { - return false, err - } - - numActive := big.NewInt(int64(len(transcoders))) - - // Should not initialize if the upcoming active set is empty - if numActive.Cmp(big.NewInt(0)) == 0 { - return false, nil - } - - // Find the caller's rank in the upcoming active set - rank := int64(-1) - maxRank := numActive.Int64() - caller := r.client.Account().Address - for i := int64(0); i < maxRank; i++ { - if transcoders[i].Address == caller { - rank = i - break - } - } - - // Should not initialize if the caller is not in the upcoming active set - if rank == -1 { - return false, nil - } - - // Use the seed to select a position within the active set - selection := new(big.Int).Mod(epochSeed, numActive) - // Should not initialize if the selection does not match the caller's rank in the active set - if selection.Int64() != int64(rank) { - return false, nil - } - - // If the selection matches the caller's rank the caller should initialize the round - return true, nil -} - -// Returns the seed used to select a round initializer in the current epoch for the current round -// This seed is not meant to be unpredictable. The only requirement for the seed is that it is calculated the same way for each -// party running the round initializer -func (r *RoundInitializer) currentEpochSeed(currentL1Block, roundStartL1Block *big.Int, lastInitializedL1BlkHash [32]byte) *big.Int { - epochNum := new(big.Int).Sub(currentL1Block, roundStartL1Block) - epochNum.Div(epochNum, epochL1Blocks) - - // The seed for the current epoch is calculated as: - // keccak256(lastInitializedL1BlkHash | epochNum) - return crypto.Keccak256Hash(append(lastInitializedL1BlkHash[:], epochNum.Bytes()...)).Big() -} diff --git a/eth/roundinitializer_test.go b/eth/roundinitializer_test.go index 25e60205a0..a96cb3b2f2 100644 --- a/eth/roundinitializer_test.go +++ b/eth/roundinitializer_test.go @@ -16,84 +16,6 @@ import ( "github.com/stretchr/testify/mock" ) -func TestRoundInitializer_CurrentEpochSeed(t *testing.T) { - initializer := NewRoundInitializer(nil, nil) - - assert := assert.New(t) - - // Test epochNum = 0 - blkHash := [32]byte{123} - - epochSeed := initializer.currentEpochSeed(big.NewInt(5), big.NewInt(5), blkHash) - // epochNum = (5 - 5) / 5 = 0 - // epochSeed = keccak256(blkHash | 0) = 53205358842179480591542570540016728811976439286094436690881169143335261643310 - expEpochSeed, _ := new(big.Int).SetString("53205358842179480591542570540016728811976439286094436690881169143335261643310", 10) - assert.Equal(expEpochSeed, epochSeed) - - // Test epochNum > 0 - epochSeed = initializer.currentEpochSeed(big.NewInt(20), big.NewInt(5), blkHash) - // epochNum = (20 - 5) / 5 = 3 - // epochSeed = keccak256(blkHash | 3) = 42541119854153860846042329644941941146216657514071318786342840580076059276721 - expEpochSeed.SetString("42541119854153860846042329644941941146216657514071318786342840580076059276721", 10) - assert.Equal(expEpochSeed, epochSeed) - - // Test epochNum > 0 with some # of blocks into the epoch - epochSeed = initializer.currentEpochSeed(big.NewInt(20), big.NewInt(4), blkHash) - // epochNum = (20 - 4) / 5 = 3.2 -> 3 - assert.Equal(expEpochSeed, epochSeed) -} - -func TestRoundInitializer_ShouldInitialize(t *testing.T) { - client := &MockClient{} - tw := &stubTimeWatcher{} - initializer := NewRoundInitializer(client, tw) - - assert := assert.New(t) - - // Test error getting transcoders - expErr := errors.New("TranscoderPool error") - client.On("TranscoderPool").Return(nil, expErr).Once() - - ok, err := initializer.shouldInitialize(nil) - assert.EqualError(err, expErr.Error()) - assert.False(ok) - - // Test active set is empty because no registered transcoders - client.On("TranscoderPool").Return([]*lpTypes.Transcoder{}, nil).Once() - ok, err = initializer.shouldInitialize(nil) - assert.Nil(err) - assert.False(ok) - - // Test that caller is not in active set because it is not registered - caller := ethcommon.BytesToAddress([]byte("foo")) - client.On("Account").Return(accounts.Account{Address: caller}) - - registered := []*lpTypes.Transcoder{ - {Address: ethcommon.BytesToAddress([]byte("jar"))}, - {Address: ethcommon.BytesToAddress([]byte("bar"))}, - } - client.On("TranscoderPool").Return(registered, nil).Once() - - ok, err = initializer.shouldInitialize(nil) - assert.Nil(err) - assert.False(ok) - - // Test not selected - registered = append(registered, &lpTypes.Transcoder{Address: caller}) - client.On("TranscoderPool").Return(registered, nil) - - seed := big.NewInt(3) - ok, err = initializer.shouldInitialize(seed) - assert.Nil(err) - assert.False(ok) - - // Test caller selected - seed = big.NewInt(5) - ok, err = initializer.shouldInitialize(seed) - assert.Nil(err) - assert.True(ok) -} - func TestRoundInitializer_TryInitialize(t *testing.T) { client := &MockClient{} tw := &stubTimeWatcher{ @@ -101,45 +23,17 @@ func TestRoundInitializer_TryInitialize(t *testing.T) { lastInitializedRound: big.NewInt(100), lastInitializedBlockHash: [32]byte{123}, } - initializer := NewRoundInitializer(client, tw) + initializer := NewRoundInitializer(client, tw, 0) initializer.nextRoundStartL1Block = big.NewInt(5) assert := assert.New(t) - // Test error checking should initialize - expErr := errors.New("shouldInitialize error") - client.On("TranscoderPool").Return(nil, expErr).Once() - - err := initializer.tryInitialize() - assert.EqualError(err, expErr.Error()) - - // Test should not initialize - caller := ethcommon.BytesToAddress([]byte("foo")) - client.On("Account").Return(accounts.Account{Address: caller}) - - registered := []*lpTypes.Transcoder{ - {Address: ethcommon.BytesToAddress([]byte("jar"))}, - } - client.On("TranscoderPool").Return(registered, nil).Once() - - err = initializer.tryInitialize() - assert.Nil(err) - - // Test error when submitting initialization tx - registered = []*lpTypes.Transcoder{{Address: caller}} - client.On("TranscoderPool").Return(registered, nil) - expErr = errors.New("InitializeRound error") - client.On("InitializeRound").Return(nil, expErr).Once() - - err = initializer.tryInitialize() - assert.EqualError(err, expErr.Error()) - // Test error checking initialization tx tx := &types.Transaction{} client.On("InitializeRound").Return(tx, nil) - expErr = errors.New("CheckTx error") + expErr := errors.New("CheckTx error") client.On("CheckTx", mock.Anything).Return(expErr).Once() - err = initializer.tryInitialize() + err := initializer.tryInitialize() assert.EqualError(err, expErr.Error()) // Test success From b1b2c030ad39638ca3f1dead504ec2f1cdc516de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Leszko?= Date: Wed, 8 May 2024 16:32:17 +0200 Subject: [PATCH 17/88] Fix CI Darwin Build (#3049) * Fix CI * Fix CI --- .github/workflows/build.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index cb2d590e43..6e93599485 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -157,7 +157,7 @@ jobs: target: - GOOS: darwin GOARCH: amd64 - runner: macos-latest + runner: macos-14-large - GOOS: darwin GOARCH: arm64 From 6e49ae205367d9d0729c962a8492aa097e45b200 Mon Sep 17 00:00:00 2001 From: kevincatty <168698033+kevincatty@users.noreply.github.com> Date: Thu, 9 May 2024 22:14:42 +0800 Subject: [PATCH 18/88] chore: fix function names (#3040) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: kevincatty Co-authored-by: Rafał Leszko --- cmd/livepeer_cli/wizard.go | 2 +- core/orchestrator.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/livepeer_cli/wizard.go b/cmd/livepeer_cli/wizard.go index 01801e4fd6..27ba130174 100644 --- a/cmd/livepeer_cli/wizard.go +++ b/cmd/livepeer_cli/wizard.go @@ -76,7 +76,7 @@ func (w *wizard) readStringAndValidate(validate func(in string) (string, error)) } } -// readStringYesOrNot reads a single line from stdin, trims spaces and +// readStringYesOrNo reads a single line from stdin, trims spaces and // checks that the string is either y or n func (w *wizard) readStringYesOrNo() string { return w.readStringAndValidate(func(in string) (string, error) { diff --git a/core/orchestrator.go b/core/orchestrator.go index f5eeb121c4..d7314a4581 100644 --- a/core/orchestrator.go +++ b/core/orchestrator.go @@ -1033,7 +1033,7 @@ func (node *RemoteTranscoderManager) EndTranscodingSession(sessionId string) { panic("shouldn't be called on RemoteTranscoderManager") } -// completeStreamSessions end a stream session for a remote transcoder and decrements its load +// completeStreamSession end a stream session for a remote transcoder and decrements its load // caller should hold the mutex lock func (rtm *RemoteTranscoderManager) completeStreamSession(sessionId string) { t, ok := rtm.streamSessions[sessionId] From 133ca8bd0141275b9717328bf6369a576190fa01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Leszko?= Date: Mon, 13 May 2024 18:28:09 +0200 Subject: [PATCH 19/88] Create option to filter Os by min livepeer version used (#3050) --- cmd/livepeer/livepeer.go | 1 + cmd/livepeer/starter/starter.go | 10 +- core/capabilities.go | 58 +- core/capabilities_test.go | 103 ++ core/livepeernode.go | 2 +- core/orch_test.go | 19 +- core/orchestrator.go | 4 +- go.mod | 1 + go.sum | 2 + net/lp_rpc.pb.go | 2934 ++++++++++++------------------- net/lp_rpc.proto | 6 +- net/lp_rpc_grpc.pb.go | 2 +- net/redeemer.pb.go | 1 - server/broadcast.go | 3 + server/mediaserver.go | 1 + 15 files changed, 1280 insertions(+), 1867 deletions(-) diff --git a/cmd/livepeer/livepeer.go b/cmd/livepeer/livepeer.go index 030d897957..b25472f7fa 100755 --- a/cmd/livepeer/livepeer.go +++ b/cmd/livepeer/livepeer.go @@ -127,6 +127,7 @@ func parseLivepeerConfig() starter.LivepeerConfig { cfg.OrchAddr = flag.String("orchAddr", *cfg.OrchAddr, "Comma-separated list of orchestrators to connect to") cfg.OrchWebhookURL = flag.String("orchWebhookUrl", *cfg.OrchWebhookURL, "Orchestrator discovery callback URL") cfg.OrchBlacklist = flag.String("orchBlocklist", "", "Comma-separated list of blocklisted orchestrators") + cfg.OrchMinLivepeerVersion = flag.String("orchMinLivepeerVersion", *cfg.OrchMinLivepeerVersion, "Minimal go-livepeer version orchestrator should have to be selected") cfg.SelectRandWeight = flag.Float64("selectRandFreq", *cfg.SelectRandWeight, "Weight of the random factor in the orchestrator selection algorithm") cfg.SelectStakeWeight = flag.Float64("selectStakeWeight", *cfg.SelectStakeWeight, "Weight of the stake factor in the orchestrator selection algorithm") cfg.SelectPriceWeight = flag.Float64("selectPriceWeight", *cfg.SelectPriceWeight, "Weight of the price factor in the orchestrator selection algorithm") diff --git a/cmd/livepeer/starter/starter.go b/cmd/livepeer/starter/starter.go index f9296abfa6..84ff08c330 100755 --- a/cmd/livepeer/starter/starter.go +++ b/cmd/livepeer/starter/starter.go @@ -144,6 +144,7 @@ type LivepeerConfig struct { AuthWebhookURL *string OrchWebhookURL *string OrchBlacklist *string + OrchMinLivepeerVersion *string TestOrchAvail *bool } @@ -230,6 +231,7 @@ func DefaultLivepeerConfig() LivepeerConfig { // API defaultAuthWebhookURL := "" defaultOrchWebhookURL := "" + defaultMinLivepeerVersion := "" // Flags defaultTestOrchAvail := true @@ -314,8 +316,9 @@ func DefaultLivepeerConfig() LivepeerConfig { FVfailGsKey: &defaultFVfailGsKey, // API - AuthWebhookURL: &defaultAuthWebhookURL, - OrchWebhookURL: &defaultOrchWebhookURL, + AuthWebhookURL: &defaultAuthWebhookURL, + OrchWebhookURL: &defaultOrchWebhookURL, + OrchMinLivepeerVersion: &defaultMinLivepeerVersion, // Flags TestOrchAvail: &defaultTestOrchAvail, @@ -1169,6 +1172,9 @@ func StartLivepeer(ctx context.Context, cfg LivepeerConfig) { } n.Capabilities = core.NewCapabilities(transcoderCaps, core.MandatoryOCapabilities()) + if cfg.OrchMinLivepeerVersion != nil { + n.Capabilities.SetMinVersionConstraint(*cfg.OrchMinLivepeerVersion) + } if drivers.NodeStorage == nil { // base URI will be empty for broadcasters; that's OK diff --git a/core/capabilities.go b/core/capabilities.go index 9d54c41e16..7bd4f00f5f 100644 --- a/core/capabilities.go +++ b/core/capabilities.go @@ -3,9 +3,10 @@ package core import ( "errors" "fmt" - "sync" + "github.com/Masterminds/semver/v3" + "github.com/golang/glog" "github.com/livepeer/go-livepeer/net" "github.com/livepeer/go-tools/drivers" "github.com/livepeer/lpms/ffmpeg" @@ -13,10 +14,13 @@ import ( type Capability int type CapabilityString []uint64 -type Constraints struct{} +type Constraints struct { + minVersion string +} type Capabilities struct { bitstring CapabilityString mandatories CapabilityString + version string constraints Constraints capacities map[Capability]int mutex sync.Mutex @@ -316,6 +320,34 @@ func JobCapabilities(params *StreamParameters, segPar *SegmentParameters) (*Capa return &Capabilities{bitstring: NewCapabilityString(capList)}, nil } +func (bcast *Capabilities) LivepeerVersionCompatibleWith(orch *net.Capabilities) bool { + if bcast == nil || orch == nil || bcast.constraints.minVersion == "" { + // should not happen, but just in case, return true by default + return true + } + if orch.Version == "" || orch.Version == "undefined" { + // Orchestrator/Transcoder version is not set, so it's incompatible + return false + } + + minVer, err := semver.NewVersion(bcast.constraints.minVersion) + if err != nil { + glog.Warningf("error while parsing minVersion: %v", err) + return true + } + ver, err := semver.NewVersion(orch.Version) + if err != nil { + glog.Warningf("error while parsing version: %v", err) + return false + } + + // Ignore prerelease versions as in go-livepeer we actually define post-release suffixes + minVerNoSuffix, _ := minVer.SetPrerelease("") + verNoSuffix, _ := ver.SetPrerelease("") + + return !verNoSuffix.LessThan(&minVerNoSuffix) +} + func (bcast *Capabilities) CompatibleWith(orch *net.Capabilities) bool { // Ensure bcast and orch are compatible with one another. @@ -325,6 +357,9 @@ func (bcast *Capabilities) CompatibleWith(orch *net.Capabilities) bool { // cf. common.CapabilityComparator return false } + if !bcast.LivepeerVersionCompatibleWith(orch) { + return false + } // For now, check this: // ( orch.mandatories AND bcast.bitstring ) == orch.mandatories && @@ -346,7 +381,7 @@ func (c *Capabilities) ToNetCapabilities() *net.Capabilities { } c.mutex.Lock() defer c.mutex.Unlock() - netCaps := &net.Capabilities{Bitstring: c.bitstring, Mandatories: c.mandatories, Capacities: make(map[uint32]uint32)} + netCaps := &net.Capabilities{Bitstring: c.bitstring, Mandatories: c.mandatories, Version: c.version, Capacities: make(map[uint32]uint32), Constraints: &net.Capabilities_Constraints{MinVersion: c.constraints.minVersion}} for capability, capacity := range c.capacities { netCaps.Capacities[uint32(capability)] = uint32(capacity) } @@ -361,6 +396,8 @@ func CapabilitiesFromNetCapabilities(caps *net.Capabilities) *Capabilities { bitstring: caps.Bitstring, mandatories: caps.Mandatories, capacities: make(map[Capability]int), + version: caps.Version, + constraints: Constraints{minVersion: caps.Constraints.GetMinVersion()}, } if caps.Capacities == nil || len(caps.Capacities) == 0 { // build capacities map if not present (struct received from previous versions) @@ -381,7 +418,7 @@ func CapabilitiesFromNetCapabilities(caps *net.Capabilities) *Capabilities { } func NewCapabilities(caps []Capability, m []Capability) *Capabilities { - c := &Capabilities{capacities: make(map[Capability]int)} + c := &Capabilities{capacities: make(map[Capability]int), version: LivepeerVersion} if len(caps) > 0 { c.bitstring = NewCapabilityString(caps) // initialize capacities to 1 by default, mandatory capabilities doesn't have capacities @@ -567,3 +604,16 @@ func (bcast *Capabilities) LegacyOnly() bool { } return bcast.bitstring.CompatibleWith(legacyCapabilityString) } + +func (bcast *Capabilities) SetMinVersionConstraint(minVersionConstraint string) { + if bcast != nil { + bcast.constraints.minVersion = minVersionConstraint + } +} + +func (bcast *Capabilities) MinVersionConstraint() string { + if bcast != nil { + return bcast.constraints.minVersion + } + return "" +} diff --git a/core/capabilities_test.go b/core/capabilities_test.go index c9c1ee319f..b165a3d9ca 100644 --- a/core/capabilities_test.go +++ b/core/capabilities_test.go @@ -331,6 +331,20 @@ func TestCapability_CompatibleWithNetCap(t *testing.T) { orch = NewCapabilities(nil, nil) bcast = NewCapabilities(nil, []Capability{1}) assert.True(bcast.CompatibleWith(orch.ToNetCapabilities())) + + // broadcaster is not compatible with orchestrator - old O's version + orch = NewCapabilities(nil, nil) + bcast = NewCapabilities(nil, nil) + bcast.constraints.minVersion = "0.4.1" + orch.version = "0.4.0" + assert.False(bcast.CompatibleWith(orch.ToNetCapabilities())) + + // broadcaster is not compatible with orchestrator - the same version + orch = NewCapabilities(nil, nil) + bcast = NewCapabilities(nil, nil) + bcast.constraints.minVersion = "0.4.1" + orch.version = "0.4.1" + assert.True(bcast.CompatibleWith(orch.ToNetCapabilities())) } func TestCapability_RoundTrip_Net(t *testing.T) { @@ -474,3 +488,92 @@ func TestCapabilities_LegacyCheck(t *testing.T) { assert.Len(legacyCapabilities, legacyLen) // sanity check no modifications } + +func TestLiveeerVersionCompatibleWith(t *testing.T) { + tests := []struct { + name string + broadcasterMinVersion string + transcoderVersion string + expected bool + }{ + { + name: "broadcaster required version is the same as the transcoder version", + broadcasterMinVersion: "0.4.1", + transcoderVersion: "0.4.1", + expected: true, + }, + { + name: "broadcaster required version is less than the transcoder version", + broadcasterMinVersion: "0.4.0", + transcoderVersion: "0.4.1", + expected: true, + }, + { + name: "broadcaster required version is more than the transcoder version", + broadcasterMinVersion: "0.4.2", + transcoderVersion: "0.4.1", + expected: false, + }, + { + name: "broadcaster required version is the same as the transcoder dirty version", + broadcasterMinVersion: "0.4.1", + transcoderVersion: "0.4.1-b3278dce-dirty", + expected: true, + }, + { + name: "broadcaster required version is before the transcoder dirty version", + broadcasterMinVersion: "0.4.0", + transcoderVersion: "0.4.1-b3278dce-dirty", + expected: true, + }, + { + name: "broadcaster required version is after the transcoder dirty version", + broadcasterMinVersion: "0.4.2", + transcoderVersion: "0.4.1-b3278dce-dirty", + expected: false, + }, + { + name: "broadcaster required version is empty", + broadcasterMinVersion: "", + transcoderVersion: "0.4.1", + expected: true, + }, + { + name: "both versions are undefined", + broadcasterMinVersion: "", + transcoderVersion: "", + expected: true, + }, + { + name: "transcoder version is empty", + broadcasterMinVersion: "0.4.0", + transcoderVersion: "", + expected: false, + }, + { + name: "transcoder version is undefined", + broadcasterMinVersion: "0.4.0", + transcoderVersion: "undefined", + expected: false, + }, + { + name: "unparsable broadcaster's min version", + broadcasterMinVersion: "nonparsablesemversion", + transcoderVersion: "0.4.1", + expected: true, + }, + { + name: "unparsable transcoder's version", + broadcasterMinVersion: "0.4.1", + transcoderVersion: "nonparsablesemversion", + expected: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + bCapabilities := &Capabilities{constraints: Constraints{minVersion: tt.broadcasterMinVersion}} + tCapabilities := &Capabilities{version: tt.transcoderVersion} + assert.Equal(t, tt.expected, bCapabilities.LivepeerVersionCompatibleWith(tCapabilities.ToNetCapabilities())) + }) + } +} diff --git a/core/livepeernode.go b/core/livepeernode.go index f4741aae93..19839a185b 100644 --- a/core/livepeernode.go +++ b/core/livepeernode.go @@ -108,7 +108,7 @@ func NewLivepeerNode(e eth.LivepeerEthClient, wd string, dbh *common.DB) (*Livep AutoAdjustPrice: true, SegmentChans: make(map[ManifestID]SegmentChan), segmentMutex: &sync.RWMutex{}, - Capabilities: &Capabilities{capacities: map[Capability]int{}}, + Capabilities: &Capabilities{capacities: map[Capability]int{}, version: LivepeerVersion}, priceInfo: make(map[string]*AutoConvertedPrice), StorageConfigs: make(map[string]*transcodeConfig), storageMutex: &sync.RWMutex{}, diff --git a/core/orch_test.go b/core/orch_test.go index dcc8a6c2d9..72aa9cb8bb 100644 --- a/core/orch_test.go +++ b/core/orch_test.go @@ -245,7 +245,10 @@ func TestSelectTranscoder(t *testing.T) { strm := &StubTranscoderServer{manager: m, WithholdResults: false} strm2 := &StubTranscoderServer{manager: m} + LivepeerVersion = "0.4.1" capabilities := NewCapabilities(DefaultCapabilities(), []Capability{}) + LivepeerVersion = "undefined" + richCapabilities := NewCapabilities(append(DefaultCapabilities(), Capability_HEVC_Encode), []Capability{}) allCapabilities := NewCapabilities(append(DefaultCapabilities(), OptionalCapabilities()...), []Capability{}) @@ -259,7 +262,7 @@ func TestSelectTranscoder(t *testing.T) { go func() { m.Manage(strm, 1, capabilities.ToNetCapabilities()) }() time.Sleep(1 * time.Millisecond) // allow time for first stream to register go func() { m.Manage(strm2, 1, richCapabilities.ToNetCapabilities()); wg.Done() }() - time.Sleep(1 * time.Millisecond) // allow time for second stream to register + time.Sleep(1 * time.Millisecond) // allow time for second stream to register e for third stream to register assert.NotNil(m.liveTranscoders[strm]) assert.NotNil(m.liveTranscoders[strm2]) @@ -341,6 +344,20 @@ func TestSelectTranscoder(t *testing.T) { assert.Equal(1, t1.load) m.completeStreamSession(testSessionId) assert.Equal(0, t1.load) + + // assert one transcoder with the correct Livepeer version is selected + minVersionCapabilities := NewCapabilities(DefaultCapabilities(), []Capability{}) + minVersionCapabilities.SetMinVersionConstraint("0.4.0") + currentTranscoder, err = m.selectTranscoder(testSessionId, minVersionCapabilities) + assert.Nil(err) + m.completeStreamSession(testSessionId) + + // assert no transcoders available for min version higher than any transcoder + minVersionHighCapabilities := NewCapabilities(DefaultCapabilities(), []Capability{}) + minVersionHighCapabilities.SetMinVersionConstraint("0.4.2") + currentTranscoder, err = m.selectTranscoder(testSessionId, minVersionHighCapabilities) + assert.NotNil(err) + m.completeStreamSession(testSessionId) } func TestCompleteStreamSession(t *testing.T) { diff --git a/core/orchestrator.go b/core/orchestrator.go index d7314a4581..50d6ea9757 100644 --- a/core/orchestrator.go +++ b/core/orchestrator.go @@ -981,7 +981,9 @@ func (rtm *RemoteTranscoderManager) selectTranscoder(sessionId string, caps *Cap findCompatibleTranscoder := func(rtm *RemoteTranscoderManager) int { for i := len(rtm.remoteTranscoders) - 1; i >= 0; i-- { // no capabilities = default capabilities, all transcoders must support them - if caps == nil || caps.bitstring.CompatibleWith(rtm.remoteTranscoders[i].capabilities.bitstring) { + if caps == nil || + (caps.bitstring.CompatibleWith(rtm.remoteTranscoders[i].capabilities.bitstring) && + caps.LivepeerVersionCompatibleWith(rtm.remoteTranscoders[i].capabilities.ToNetCapabilities())) { return i } } diff --git a/go.mod b/go.mod index fd1a55b99f..e4837beb3b 100644 --- a/go.mod +++ b/go.mod @@ -41,6 +41,7 @@ require ( dario.cat/mergo v1.0.0 // indirect github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect github.com/DataDog/zstd v1.4.5 // indirect + github.com/Masterminds/semver/v3 v3.2.1 // indirect github.com/Microsoft/go-winio v0.6.1 // indirect github.com/Microsoft/hcsshim v0.11.1 // indirect github.com/StackExchange/wmi v1.2.1 // indirect diff --git a/go.sum b/go.sum index 984557a611..cad66eecff 100644 --- a/go.sum +++ b/go.sum @@ -60,6 +60,8 @@ github.com/DataDog/zstd v1.4.5 h1:EndNeuB0l9syBZhut0wns3gV1hL8zX8LIu6ZiVHWLIQ= github.com/DataDog/zstd v1.4.5/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY= github.com/Joker/jade v1.0.1-0.20190614124447-d475f43051e7/go.mod h1:6E6s8o2AE4KhCrqr6GRJjdC/gNfTdxkIXvuGZZda2VM= +github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0= +github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= github.com/Microsoft/hcsshim v0.11.1 h1:hJ3s7GbWlGK4YVV92sO88BQSyF4ZLVy7/awqOlPxFbA= diff --git a/net/lp_rpc.pb.go b/net/lp_rpc.pb.go index 5e6ac70297..d5102d77c5 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 v4.25.2 // source: net/lp_rpc.proto package net import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" + fmt "fmt" + proto "github.com/golang/protobuf/proto" + math "math" ) -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) -) +// 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 type OSInfo_StorageType int32 @@ -28,45 +28,24 @@ const ( OSInfo_GOOGLE OSInfo_StorageType = 2 ) -// 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, - } -) - -func (x OSInfo_StorageType) Enum() *OSInfo_StorageType { - p := new(OSInfo_StorageType) - *p = x - return p +var OSInfo_StorageType_name = map[int32]string{ + 0: "DIRECT", + 1: "S3", + 2: "GOOGLE", } -func (x OSInfo_StorageType) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +var OSInfo_StorageType_value = map[string]int32{ + "DIRECT": 0, + "S3": 1, + "GOOGLE": 2, } -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) +func (x OSInfo_StorageType) String() string { + return proto.EnumName(OSInfo_StorageType_name, int32(x)) } -// Deprecated: Use OSInfo_StorageType.Descriptor instead. func (OSInfo_StorageType) EnumDescriptor() ([]byte, []int) { - return file_net_lp_rpc_proto_rawDescGZIP(), []int{4, 0} + return fileDescriptor_034e29c79f9ba827, []int{4, 0} } // Desired output format @@ -77,43 +56,22 @@ const ( VideoProfile_MP4 VideoProfile_Format = 1 ) -// 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, - } -) - -func (x VideoProfile_Format) Enum() *VideoProfile_Format { - p := new(VideoProfile_Format) - *p = x - return p -} - -func (x VideoProfile_Format) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (VideoProfile_Format) Descriptor() protoreflect.EnumDescriptor { - return file_net_lp_rpc_proto_enumTypes[1].Descriptor() +var VideoProfile_Format_name = map[int32]string{ + 0: "MPEGTS", + 1: "MP4", } -func (VideoProfile_Format) Type() protoreflect.EnumType { - return &file_net_lp_rpc_proto_enumTypes[1] +var VideoProfile_Format_value = map[string]int32{ + "MPEGTS": 0, + "MP4": 1, } -func (x VideoProfile_Format) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) +func (x VideoProfile_Format) String() string { + return proto.EnumName(VideoProfile_Format_name, int32(x)) } -// Deprecated: Use VideoProfile_Format.Descriptor instead. func (VideoProfile_Format) EnumDescriptor() ([]byte, []int) { - return file_net_lp_rpc_proto_rawDescGZIP(), []int{12, 0} + return fileDescriptor_034e29c79f9ba827, []int{12, 0} } type VideoProfile_Profile int32 @@ -126,49 +84,28 @@ const ( VideoProfile_H264_CONSTRAINED_HIGH VideoProfile_Profile = 4 ) -// 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, - } -) - -func (x VideoProfile_Profile) Enum() *VideoProfile_Profile { - p := new(VideoProfile_Profile) - *p = x - return p -} - -func (x VideoProfile_Profile) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +var VideoProfile_Profile_name = map[int32]string{ + 0: "ENCODER_DEFAULT", + 1: "H264_BASELINE", + 2: "H264_MAIN", + 3: "H264_HIGH", + 4: "H264_CONSTRAINED_HIGH", } -func (VideoProfile_Profile) Descriptor() protoreflect.EnumDescriptor { - return file_net_lp_rpc_proto_enumTypes[2].Descriptor() +var VideoProfile_Profile_value = map[string]int32{ + "ENCODER_DEFAULT": 0, + "H264_BASELINE": 1, + "H264_MAIN": 2, + "H264_HIGH": 3, + "H264_CONSTRAINED_HIGH": 4, } -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) +func (x VideoProfile_Profile) String() string { + return proto.EnumName(VideoProfile_Profile_name, int32(x)) } -// Deprecated: Use VideoProfile_Profile.Descriptor instead. func (VideoProfile_Profile) EnumDescriptor() ([]byte, []int) { - return file_net_lp_rpc_proto_rawDescGZIP(), []int{12, 1} + return fileDescriptor_034e29c79f9ba827, []int{12, 1} } type VideoProfile_VideoCodec int32 @@ -180,47 +117,26 @@ const ( VideoProfile_VP9 VideoProfile_VideoCodec = 3 ) -// 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, - } -) - -func (x VideoProfile_VideoCodec) Enum() *VideoProfile_VideoCodec { - p := new(VideoProfile_VideoCodec) - *p = x - return p +var VideoProfile_VideoCodec_name = map[int32]string{ + 0: "H264", + 1: "H265", + 2: "VP8", + 3: "VP9", } -func (x VideoProfile_VideoCodec) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (VideoProfile_VideoCodec) Descriptor() protoreflect.EnumDescriptor { - return file_net_lp_rpc_proto_enumTypes[3].Descriptor() +var VideoProfile_VideoCodec_value = map[string]int32{ + "H264": 0, + "H265": 1, + "VP8": 2, + "VP9": 3, } -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) +func (x VideoProfile_VideoCodec) String() string { + return proto.EnumName(VideoProfile_VideoCodec_name, int32(x)) } -// Deprecated: Use VideoProfile_VideoCodec.Descriptor instead. func (VideoProfile_VideoCodec) EnumDescriptor() ([]byte, []int) { - return file_net_lp_rpc_proto_rawDescGZIP(), []int{12, 2} + return fileDescriptor_034e29c79f9ba827, []int{12, 2} } type VideoProfile_ChromaSubsampling int32 @@ -231,237 +147,185 @@ const ( VideoProfile_CHROMA_444 VideoProfile_ChromaSubsampling = 2 ) -// 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, - } -) - -func (x VideoProfile_ChromaSubsampling) Enum() *VideoProfile_ChromaSubsampling { - p := new(VideoProfile_ChromaSubsampling) - *p = x - return p -} - -func (x VideoProfile_ChromaSubsampling) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (VideoProfile_ChromaSubsampling) Descriptor() protoreflect.EnumDescriptor { - return file_net_lp_rpc_proto_enumTypes[4].Descriptor() +var VideoProfile_ChromaSubsampling_name = map[int32]string{ + 0: "CHROMA_420", + 1: "CHROMA_422", + 2: "CHROMA_444", } -func (VideoProfile_ChromaSubsampling) Type() protoreflect.EnumType { - return &file_net_lp_rpc_proto_enumTypes[4] +var VideoProfile_ChromaSubsampling_value = map[string]int32{ + "CHROMA_420": 0, + "CHROMA_422": 1, + "CHROMA_444": 2, } -func (x VideoProfile_ChromaSubsampling) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) +func (x VideoProfile_ChromaSubsampling) String() string { + return proto.EnumName(VideoProfile_ChromaSubsampling_name, int32(x)) } -// Deprecated: Use VideoProfile_ChromaSubsampling.Descriptor instead. func (VideoProfile_ChromaSubsampling) EnumDescriptor() ([]byte, []int) { - return file_net_lp_rpc_proto_rawDescGZIP(), []int{12, 3} + return fileDescriptor_034e29c79f9ba827, []int{12, 3} } 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"` + 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 (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) 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 *PingPong) String() string { - return protoimpl.X.MessageStringOf(x) +func (m *PingPong) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_PingPong.Unmarshal(m, b) } - -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) +func (m *PingPong) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_PingPong.Marshal(b, m, deterministic) } - -// Deprecated: Use PingPong.ProtoReflect.Descriptor instead. -func (*PingPong) Descriptor() ([]byte, []int) { - return file_net_lp_rpc_proto_rawDescGZIP(), []int{0} +func (m *PingPong) XXX_Merge(src proto.Message) { + xxx_messageInfo_PingPong.Merge(m, src) +} +func (m *PingPong) XXX_Size() int { + return xxx_messageInfo_PingPong.Size(m) } +func (m *PingPong) XXX_DiscardUnknown() { + xxx_messageInfo_PingPong.DiscardUnknown(m) +} + +var xxx_messageInfo_PingPong proto.InternalMessageInfo -func (x *PingPong) GetValue() []byte { - if x != nil { - return x.Value +func (m *PingPong) GetValue() []byte { + if m != nil { + return m.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"` + 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:"-"` } -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) 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) String() string { - return protoimpl.X.MessageStringOf(x) +func (m *EndTranscodingSessionRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_EndTranscodingSessionRequest.Unmarshal(m, b) } - -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) +func (m *EndTranscodingSessionRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_EndTranscodingSessionRequest.Marshal(b, m, deterministic) } - -// Deprecated: Use EndTranscodingSessionRequest.ProtoReflect.Descriptor instead. -func (*EndTranscodingSessionRequest) Descriptor() ([]byte, []int) { - return file_net_lp_rpc_proto_rawDescGZIP(), []int{1} +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 (m *EndTranscodingSessionRequest) XXX_DiscardUnknown() { + xxx_messageInfo_EndTranscodingSessionRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_EndTranscodingSessionRequest proto.InternalMessageInfo -func (x *EndTranscodingSessionRequest) GetAuthToken() *AuthToken { - if x != nil { - return x.AuthToken +func (m *EndTranscodingSessionRequest) GetAuthToken() *AuthToken { + if m != nil { + return m.AuthToken } return nil } type EndTranscodingSessionResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } -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) 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) String() string { - return protoimpl.X.MessageStringOf(x) +func (m *EndTranscodingSessionResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_EndTranscodingSessionResponse.Unmarshal(m, b) } - -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) +func (m *EndTranscodingSessionResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_EndTranscodingSessionResponse.Marshal(b, m, deterministic) } - -// Deprecated: Use EndTranscodingSessionResponse.ProtoReflect.Descriptor instead. -func (*EndTranscodingSessionResponse) Descriptor() ([]byte, []int) { - return file_net_lp_rpc_proto_rawDescGZIP(), []int{2} +func (m *EndTranscodingSessionResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_EndTranscodingSessionResponse.Merge(m, src) +} +func (m *EndTranscodingSessionResponse) XXX_Size() int { + return xxx_messageInfo_EndTranscodingSessionResponse.Size(m) +} +func (m *EndTranscodingSessionResponse) XXX_DiscardUnknown() { + xxx_messageInfo_EndTranscodingSessionResponse.DiscardUnknown(m) } +var xxx_messageInfo_EndTranscodingSessionResponse proto.InternalMessageInfo + // 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"` + Sig []byte `protobuf:"bytes,2,opt,name=sig,proto3" json:"sig,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } -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) 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) String() string { - return protoimpl.X.MessageStringOf(x) +func (m *OrchestratorRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_OrchestratorRequest.Unmarshal(m, b) } - -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) +func (m *OrchestratorRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_OrchestratorRequest.Marshal(b, m, deterministic) } - -// Deprecated: Use OrchestratorRequest.ProtoReflect.Descriptor instead. -func (*OrchestratorRequest) Descriptor() ([]byte, []int) { - return file_net_lp_rpc_proto_rawDescGZIP(), []int{3} +func (m *OrchestratorRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_OrchestratorRequest.Merge(m, src) +} +func (m *OrchestratorRequest) XXX_Size() int { + return xxx_messageInfo_OrchestratorRequest.Size(m) +} +func (m *OrchestratorRequest) XXX_DiscardUnknown() { + xxx_messageInfo_OrchestratorRequest.DiscardUnknown(m) } -func (x *OrchestratorRequest) GetAddress() []byte { - if x != nil { - return x.Address +var xxx_messageInfo_OrchestratorRequest proto.InternalMessageInfo + +func (m *OrchestratorRequest) GetAddress() []byte { + if m != nil { + return m.Address } return nil } -func (x *OrchestratorRequest) GetSig() []byte { - if x != nil { - return x.Sig +func (m *OrchestratorRequest) GetSig() []byte { + if m != nil { + return m.Sig } return nil } @@ -469,66 +333,54 @@ func (x *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"` + 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:"-"` } -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) 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) String() string { - return protoimpl.X.MessageStringOf(x) +func (m *OSInfo) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_OSInfo.Unmarshal(m, b) } - -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) +func (m *OSInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_OSInfo.Marshal(b, m, deterministic) } - -// Deprecated: Use OSInfo.ProtoReflect.Descriptor instead. -func (*OSInfo) Descriptor() ([]byte, []int) { - return file_net_lp_rpc_proto_rawDescGZIP(), []int{4} +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) +} + +var xxx_messageInfo_OSInfo proto.InternalMessageInfo -func (x *OSInfo) GetStorageType() OSInfo_StorageType { - if x != nil { - return x.StorageType +func (m *OSInfo) GetStorageType() OSInfo_StorageType { + if m != nil { + return m.StorageType } return OSInfo_DIRECT } -func (x *OSInfo) GetS3Info() *S3OSInfo { - if x != nil { - return x.S3Info +func (m *OSInfo) GetS3Info() *S3OSInfo { + if m != nil { + return m.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. @@ -540,215 +392,247 @@ 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"` + XAmzDate string `protobuf:"bytes,6,opt,name=xAmzDate,proto3" json:"xAmzDate,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } -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) 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) String() string { - return protoimpl.X.MessageStringOf(x) +func (m *S3OSInfo) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_S3OSInfo.Unmarshal(m, b) } - -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) +func (m *S3OSInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_S3OSInfo.Marshal(b, m, deterministic) } - -// Deprecated: Use S3OSInfo.ProtoReflect.Descriptor instead. -func (*S3OSInfo) Descriptor() ([]byte, []int) { - return file_net_lp_rpc_proto_rawDescGZIP(), []int{5} +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) +} + +var xxx_messageInfo_S3OSInfo proto.InternalMessageInfo -func (x *S3OSInfo) GetHost() string { - if x != nil { - return x.Host +func (m *S3OSInfo) GetHost() string { + if m != nil { + return m.Host } return "" } -func (x *S3OSInfo) GetKey() string { - if x != nil { - return x.Key +func (m *S3OSInfo) GetKey() string { + if m != nil { + return m.Key } return "" } -func (x *S3OSInfo) GetPolicy() string { - if x != nil { - return x.Policy +func (m *S3OSInfo) GetPolicy() string { + if m != nil { + return m.Policy } return "" } -func (x *S3OSInfo) GetSignature() string { - if x != nil { - return x.Signature +func (m *S3OSInfo) GetSignature() string { + if m != nil { + return m.Signature } return "" } -func (x *S3OSInfo) GetCredential() string { - if x != nil { - return x.Credential +func (m *S3OSInfo) GetCredential() string { + if m != nil { + return m.Credential } return "" } -func (x *S3OSInfo) GetXAmzDate() string { - if x != nil { - return x.XAmzDate +func (m *S3OSInfo) GetXAmzDate() string { + if m != nil { + return m.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"` + PixelsPerUnit int64 `protobuf:"varint,2,opt,name=pixelsPerUnit,proto3" json:"pixelsPerUnit,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } -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) 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) String() string { - return protoimpl.X.MessageStringOf(x) +func (m *PriceInfo) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_PriceInfo.Unmarshal(m, b) } - -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) +func (m *PriceInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_PriceInfo.Marshal(b, m, deterministic) } - -// Deprecated: Use PriceInfo.ProtoReflect.Descriptor instead. -func (*PriceInfo) Descriptor() ([]byte, []int) { - return file_net_lp_rpc_proto_rawDescGZIP(), []int{6} +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 (m *PriceInfo) XXX_DiscardUnknown() { + xxx_messageInfo_PriceInfo.DiscardUnknown(m) } -func (x *PriceInfo) GetPricePerUnit() int64 { - if x != nil { - return x.PricePerUnit +var xxx_messageInfo_PriceInfo proto.InternalMessageInfo + +func (m *PriceInfo) GetPricePerUnit() int64 { + if m != nil { + return m.PricePerUnit } return 0 } -func (x *PriceInfo) GetPixelsPerUnit() int64 { - if x != nil { - return x.PixelsPerUnit +func (m *PriceInfo) GetPixelsPerUnit() int64 { + if m != nil { + return m.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"` + 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:"-"` } -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) 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) String() string { - return protoimpl.X.MessageStringOf(x) +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 (*Capabilities) ProtoMessage() {} +var xxx_messageInfo_Capabilities proto.InternalMessageInfo -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 +func (m *Capabilities) GetBitstring() []uint64 { + if m != nil { + return m.Bitstring } - return mi.MessageOf(x) + 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) GetMandatories() []uint64 { + if m != nil { + return m.Mandatories + } + return nil } -func (x *Capabilities) GetBitstring() []uint64 { - if x != nil { - return x.Bitstring +func (m *Capabilities) GetCapacities() map[uint32]uint32 { + if m != nil { + return m.Capacities } return nil } -func (x *Capabilities) GetMandatories() []uint64 { - if x != nil { - return x.Mandatories +func (m *Capabilities) GetVersion() string { + if m != nil { + return m.Version } - return nil + return "" } -func (x *Capabilities) GetCapacities() map[uint32]uint32 { - if x != nil { - return x.Capacities +func (m *Capabilities) GetConstraints() *Capabilities_Constraints { + if m != nil { + return m.Constraints } 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) +} + +var xxx_messageInfo_Capabilities_Constraints proto.InternalMessageInfo + +func (m *Capabilities_Constraints) GetMinVersion() string { + if m != nil { + return m.MinVersion + } + return "" +} + // 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 @@ -762,164 +646,148 @@ 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"` + Storage []*OSInfo `protobuf:"bytes,32,rep,name=storage,proto3" json:"storage,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } -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) 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) String() string { - return protoimpl.X.MessageStringOf(x) +func (m *OrchestratorInfo) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_OrchestratorInfo.Unmarshal(m, b) } - -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) +func (m *OrchestratorInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_OrchestratorInfo.Marshal(b, m, deterministic) } - -// Deprecated: Use OrchestratorInfo.ProtoReflect.Descriptor instead. -func (*OrchestratorInfo) Descriptor() ([]byte, []int) { - return file_net_lp_rpc_proto_rawDescGZIP(), []int{8} +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) +} + +var xxx_messageInfo_OrchestratorInfo proto.InternalMessageInfo -func (x *OrchestratorInfo) GetTranscoder() string { - if x != nil { - return x.Transcoder +func (m *OrchestratorInfo) GetTranscoder() string { + if m != nil { + return m.Transcoder } return "" } -func (x *OrchestratorInfo) GetTicketParams() *TicketParams { - if x != nil { - return x.TicketParams +func (m *OrchestratorInfo) GetTicketParams() *TicketParams { + if m != nil { + return m.TicketParams } return nil } -func (x *OrchestratorInfo) GetPriceInfo() *PriceInfo { - if x != nil { - return x.PriceInfo +func (m *OrchestratorInfo) GetPriceInfo() *PriceInfo { + if m != nil { + return m.PriceInfo } return nil } -func (x *OrchestratorInfo) GetAddress() []byte { - if x != nil { - return x.Address +func (m *OrchestratorInfo) GetAddress() []byte { + if m != nil { + return m.Address } return nil } -func (x *OrchestratorInfo) GetCapabilities() *Capabilities { - if x != nil { - return x.Capabilities +func (m *OrchestratorInfo) GetCapabilities() *Capabilities { + if m != nil { + return m.Capabilities } return nil } -func (x *OrchestratorInfo) GetAuthToken() *AuthToken { - if x != nil { - return x.AuthToken +func (m *OrchestratorInfo) GetAuthToken() *AuthToken { + if m != nil { + return m.AuthToken } return nil } -func (x *OrchestratorInfo) GetStorage() []*OSInfo { - if x != nil { - return x.Storage +func (m *OrchestratorInfo) GetStorage() []*OSInfo { + if m != nil { + return m.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"` + Expiration int64 `protobuf:"varint,3,opt,name=expiration,proto3" json:"expiration,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } -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) 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) String() string { - return protoimpl.X.MessageStringOf(x) +func (m *AuthToken) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_AuthToken.Unmarshal(m, b) } - -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) +func (m *AuthToken) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_AuthToken.Marshal(b, m, deterministic) } - -// Deprecated: Use AuthToken.ProtoReflect.Descriptor instead. -func (*AuthToken) Descriptor() ([]byte, []int) { - return file_net_lp_rpc_proto_rawDescGZIP(), []int{9} +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) +} + +var xxx_messageInfo_AuthToken proto.InternalMessageInfo -func (x *AuthToken) GetToken() []byte { - if x != nil { - return x.Token +func (m *AuthToken) GetToken() []byte { + if m != nil { + return m.Token } return nil } -func (x *AuthToken) GetSessionId() string { - if x != nil { - return x.SessionId +func (m *AuthToken) GetSessionId() string { + if m != nil { + return m.SessionId } return "" } -func (x *AuthToken) GetExpiration() int64 { - if x != nil { - return x.Expiration +func (m *AuthToken) GetExpiration() int64 { + if m != nil { + return m.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 @@ -953,210 +821,194 @@ 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"` + ForceSessionReinit bool `protobuf:"varint,38,opt,name=ForceSessionReinit,proto3" json:"ForceSessionReinit,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } -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) 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) String() string { - return protoimpl.X.MessageStringOf(x) +func (m *SegData) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_SegData.Unmarshal(m, b) } - -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) +func (m *SegData) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_SegData.Marshal(b, m, deterministic) } - -// Deprecated: Use SegData.ProtoReflect.Descriptor instead. -func (*SegData) Descriptor() ([]byte, []int) { - return file_net_lp_rpc_proto_rawDescGZIP(), []int{10} +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) +} + +var xxx_messageInfo_SegData proto.InternalMessageInfo -func (x *SegData) GetManifestId() []byte { - if x != nil { - return x.ManifestId +func (m *SegData) GetManifestId() []byte { + if m != nil { + return m.ManifestId } return nil } -func (x *SegData) GetSeq() int64 { - if x != nil { - return x.Seq +func (m *SegData) GetSeq() int64 { + if m != nil { + return m.Seq } return 0 } -func (x *SegData) GetHash() []byte { - if x != nil { - return x.Hash +func (m *SegData) GetHash() []byte { + if m != nil { + return m.Hash } return nil } -func (x *SegData) GetProfiles() []byte { - if x != nil { - return x.Profiles +func (m *SegData) GetProfiles() []byte { + if m != nil { + return m.Profiles } return nil } -func (x *SegData) GetSig() []byte { - if x != nil { - return x.Sig +func (m *SegData) GetSig() []byte { + if m != nil { + return m.Sig } return nil } -func (x *SegData) GetDuration() int32 { - if x != nil { - return x.Duration +func (m *SegData) GetDuration() int32 { + if m != nil { + return m.Duration } return 0 } -func (x *SegData) GetCapabilities() *Capabilities { - if x != nil { - return x.Capabilities +func (m *SegData) GetCapabilities() *Capabilities { + if m != nil { + return m.Capabilities } return nil } -func (x *SegData) GetAuthToken() *AuthToken { - if x != nil { - return x.AuthToken +func (m *SegData) GetAuthToken() *AuthToken { + if m != nil { + return m.AuthToken } return nil } -func (x *SegData) GetCalcPerceptualHash() bool { - if x != nil { - return x.CalcPerceptualHash +func (m *SegData) GetCalcPerceptualHash() bool { + if m != nil { + return m.CalcPerceptualHash } return false } -func (x *SegData) GetStorage() []*OSInfo { - if x != nil { - return x.Storage +func (m *SegData) GetStorage() []*OSInfo { + if m != nil { + return m.Storage } return nil } -func (x *SegData) GetFullProfiles() []*VideoProfile { - if x != nil { - return x.FullProfiles +func (m *SegData) GetFullProfiles() []*VideoProfile { + if m != nil { + return m.FullProfiles } return nil } -func (x *SegData) GetFullProfiles2() []*VideoProfile { - if x != nil { - return x.FullProfiles2 +func (m *SegData) GetFullProfiles2() []*VideoProfile { + if m != nil { + return m.FullProfiles2 } return nil } -func (x *SegData) GetFullProfiles3() []*VideoProfile { - if x != nil { - return x.FullProfiles3 +func (m *SegData) GetFullProfiles3() []*VideoProfile { + if m != nil { + return m.FullProfiles3 } return nil } -func (x *SegData) GetSegmentParameters() *SegParameters { - if x != nil { - return x.SegmentParameters +func (m *SegData) GetSegmentParameters() *SegParameters { + if m != nil { + return m.SegmentParameters } return nil } -func (x *SegData) GetForceSessionReinit() bool { - if x != nil { - return x.ForceSessionReinit +func (m *SegData) GetForceSessionReinit() bool { + if m != nil { + return m.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"` + To uint64 `protobuf:"varint,2,opt,name=to,proto3" json:"to,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } -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) 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) String() string { - return protoimpl.X.MessageStringOf(x) +func (m *SegParameters) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_SegParameters.Unmarshal(m, b) } - -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) +func (m *SegParameters) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_SegParameters.Marshal(b, m, deterministic) } - -// Deprecated: Use SegParameters.ProtoReflect.Descriptor instead. -func (*SegParameters) Descriptor() ([]byte, []int) { - return file_net_lp_rpc_proto_rawDescGZIP(), []int{11} +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 (x *SegParameters) GetFrom() uint64 { - if x != nil { - return x.From +var xxx_messageInfo_SegParameters proto.InternalMessageInfo + +func (m *SegParameters) GetFrom() uint64 { + if m != nil { + return m.From } return 0 } -func (x *SegParameters) GetTo() uint64 { - if x != nil { - return x.To +func (m *SegParameters) GetTo() uint64 { + if m != nil { + return m.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 @@ -1175,318 +1027,306 @@ 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"` + 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} } -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_Unmarshal(b []byte) error { + return xxx_messageInfo_VideoProfile.Unmarshal(m, b) } - -func (x *VideoProfile) String() string { - return protoimpl.X.MessageStringOf(x) +func (m *VideoProfile) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_VideoProfile.Marshal(b, m, deterministic) } - -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) +func (m *VideoProfile) XXX_Merge(src proto.Message) { + xxx_messageInfo_VideoProfile.Merge(m, src) } - -// Deprecated: Use VideoProfile.ProtoReflect.Descriptor instead. -func (*VideoProfile) Descriptor() ([]byte, []int) { - return file_net_lp_rpc_proto_rawDescGZIP(), []int{12} +func (m *VideoProfile) XXX_Size() int { + return xxx_messageInfo_VideoProfile.Size(m) +} +func (m *VideoProfile) XXX_DiscardUnknown() { + xxx_messageInfo_VideoProfile.DiscardUnknown(m) } -func (x *VideoProfile) GetName() string { - if x != nil { - return x.Name +var xxx_messageInfo_VideoProfile proto.InternalMessageInfo + +func (m *VideoProfile) GetName() string { + if m != nil { + return m.Name } return "" } -func (x *VideoProfile) GetWidth() int32 { - if x != nil { - return x.Width +func (m *VideoProfile) GetWidth() int32 { + if m != nil { + return m.Width } return 0 } -func (x *VideoProfile) GetHeight() int32 { - if x != nil { - return x.Height +func (m *VideoProfile) GetHeight() int32 { + if m != nil { + return m.Height } return 0 } -func (x *VideoProfile) GetBitrate() int32 { - if x != nil { - return x.Bitrate +func (m *VideoProfile) GetBitrate() int32 { + if m != nil { + return m.Bitrate } return 0 } -func (x *VideoProfile) GetFps() uint32 { - if x != nil { - return x.Fps +func (m *VideoProfile) GetFps() uint32 { + if m != nil { + return m.Fps } return 0 } -func (x *VideoProfile) GetFormat() VideoProfile_Format { - if x != nil { - return x.Format +func (m *VideoProfile) GetFormat() VideoProfile_Format { + if m != nil { + return m.Format } return VideoProfile_MPEGTS } -func (x *VideoProfile) GetFpsDen() uint32 { - if x != nil { - return x.FpsDen +func (m *VideoProfile) GetFpsDen() uint32 { + if m != nil { + return m.FpsDen } return 0 } -func (x *VideoProfile) GetProfile() VideoProfile_Profile { - if x != nil { - return x.Profile +func (m *VideoProfile) GetProfile() VideoProfile_Profile { + if m != nil { + return m.Profile } return VideoProfile_ENCODER_DEFAULT } -func (x *VideoProfile) GetGop() int32 { - if x != nil { - return x.Gop +func (m *VideoProfile) GetGop() int32 { + if m != nil { + return m.Gop } return 0 } -func (x *VideoProfile) GetEncoder() VideoProfile_VideoCodec { - if x != nil { - return x.Encoder +func (m *VideoProfile) GetEncoder() VideoProfile_VideoCodec { + if m != nil { + return m.Encoder } return VideoProfile_H264 } -func (x *VideoProfile) GetColorDepth() int32 { - if x != nil { - return x.ColorDepth +func (m *VideoProfile) GetColorDepth() int32 { + if m != nil { + return m.ColorDepth } return 0 } -func (x *VideoProfile) GetChromaFormat() VideoProfile_ChromaSubsampling { - if x != nil { - return x.ChromaFormat +func (m *VideoProfile) GetChromaFormat() VideoProfile_ChromaSubsampling { + if m != nil { + return m.ChromaFormat } return VideoProfile_CHROMA_420 } -func (x *VideoProfile) GetQuality() uint32 { - if x != nil { - return x.Quality +func (m *VideoProfile) GetQuality() uint32 { + if m != nil { + return m.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"` + 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:"-"` } -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) 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) String() string { - return protoimpl.X.MessageStringOf(x) +func (m *TranscodedSegmentData) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_TranscodedSegmentData.Unmarshal(m, b) } - -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) +func (m *TranscodedSegmentData) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_TranscodedSegmentData.Marshal(b, m, deterministic) } - -// Deprecated: Use TranscodedSegmentData.ProtoReflect.Descriptor instead. -func (*TranscodedSegmentData) Descriptor() ([]byte, []int) { - return file_net_lp_rpc_proto_rawDescGZIP(), []int{13} +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 (m *TranscodedSegmentData) XXX_DiscardUnknown() { + xxx_messageInfo_TranscodedSegmentData.DiscardUnknown(m) } -func (x *TranscodedSegmentData) GetUrl() string { - if x != nil { - return x.Url +var xxx_messageInfo_TranscodedSegmentData proto.InternalMessageInfo + +func (m *TranscodedSegmentData) GetUrl() string { + if m != nil { + return m.Url } return "" } -func (x *TranscodedSegmentData) GetPixels() int64 { - if x != nil { - return x.Pixels +func (m *TranscodedSegmentData) GetPixels() int64 { + if m != nil { + return m.Pixels } return 0 } -func (x *TranscodedSegmentData) GetPerceptualHashUrl() string { - if x != nil { - return x.PerceptualHashUrl +func (m *TranscodedSegmentData) GetPerceptualHashUrl() string { + if m != nil { + return m.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"` + Sig []byte `protobuf:"bytes,2,opt,name=sig,proto3" json:"sig,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } -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) 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) String() string { - return protoimpl.X.MessageStringOf(x) +func (m *TranscodeData) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_TranscodeData.Unmarshal(m, b) } - -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) +func (m *TranscodeData) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_TranscodeData.Marshal(b, m, deterministic) } - -// Deprecated: Use TranscodeData.ProtoReflect.Descriptor instead. -func (*TranscodeData) Descriptor() ([]byte, []int) { - return file_net_lp_rpc_proto_rawDescGZIP(), []int{14} +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 (m *TranscodeData) XXX_DiscardUnknown() { + xxx_messageInfo_TranscodeData.DiscardUnknown(m) } -func (x *TranscodeData) GetSegments() []*TranscodedSegmentData { - if x != nil { - return x.Segments +var xxx_messageInfo_TranscodeData proto.InternalMessageInfo + +func (m *TranscodeData) GetSegments() []*TranscodedSegmentData { + if m != nil { + return m.Segments } return nil } -func (x *TranscodeData) GetSig() []byte { - if x != nil { - return x.Sig +func (m *TranscodeData) GetSig() []byte { + if m != nil { + return m.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 assignable to Result: + // Types that are valid to be assigned 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"` + Info *OrchestratorInfo `protobuf:"bytes,16,opt,name=info,proto3" json:"info,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } -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) 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) String() string { - return protoimpl.X.MessageStringOf(x) +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 (*TranscodeResult) ProtoMessage() {} +var xxx_messageInfo_TranscodeResult proto.InternalMessageInfo -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 +func (m *TranscodeResult) GetSeq() int64 { + if m != nil { + return m.Seq } - return mi.MessageOf(x) + return 0 } -// Deprecated: Use TranscodeResult.ProtoReflect.Descriptor instead. -func (*TranscodeResult) Descriptor() ([]byte, []int) { - return file_net_lp_rpc_proto_rawDescGZIP(), []int{15} +type isTranscodeResult_Result interface { + isTranscodeResult_Result() } -func (x *TranscodeResult) GetSeq() int64 { - if x != nil { - return x.Seq - } - return 0 +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() {} + func (m *TranscodeResult) GetResult() isTranscodeResult_Result { if m != nil { return m.Result @@ -1494,116 +1334,96 @@ func (m *TranscodeResult) GetResult() isTranscodeResult_Result { return nil } -func (x *TranscodeResult) GetError() string { - if x, ok := x.GetResult().(*TranscodeResult_Error); ok { +func (m *TranscodeResult) GetError() string { + if x, ok := m.GetResult().(*TranscodeResult_Error); ok { return x.Error } return "" } -func (x *TranscodeResult) GetData() *TranscodeData { - if x, ok := x.GetResult().(*TranscodeResult_Data); ok { +func (m *TranscodeResult) GetData() *TranscodeData { + if x, ok := m.GetResult().(*TranscodeResult_Data); ok { return x.Data } return nil } -func (x *TranscodeResult) GetInfo() *OrchestratorInfo { - if x != nil { - return x.Info +func (m *TranscodeResult) GetInfo() *OrchestratorInfo { + if m != nil { + return m.Info } return 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"` +// XXX_OneofWrappers is for the internal use of the proto package. +func (*TranscodeResult) XXX_OneofWrappers() []interface{} { + return []interface{}{ + (*TranscodeResult_Error)(nil), + (*TranscodeResult_Data)(nil), + } } -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"` + Capabilities *Capabilities `protobuf:"bytes,3,opt,name=capabilities,proto3" json:"capabilities,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } -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) 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) String() string { - return protoimpl.X.MessageStringOf(x) +func (m *RegisterRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_RegisterRequest.Unmarshal(m, b) } - -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) +func (m *RegisterRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_RegisterRequest.Marshal(b, m, deterministic) } - -// Deprecated: Use RegisterRequest.ProtoReflect.Descriptor instead. -func (*RegisterRequest) Descriptor() ([]byte, []int) { - return file_net_lp_rpc_proto_rawDescGZIP(), []int{16} +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 (x *RegisterRequest) GetSecret() string { - if x != nil { - return x.Secret +var xxx_messageInfo_RegisterRequest proto.InternalMessageInfo + +func (m *RegisterRequest) GetSecret() string { + if m != nil { + return m.Secret } return "" } -func (x *RegisterRequest) GetCapacity() int64 { - if x != nil { - return x.Capacity +func (m *RegisterRequest) GetCapacity() int64 { + if m != nil { + return m.Capacity } return 0 } -func (x *RegisterRequest) GetCapabilities() *Capabilities { - if x != nil { - return x.Capabilities +func (m *RegisterRequest) GetCapabilities() *Capabilities { + if m != nil { + return m.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 @@ -1612,75 +1432,67 @@ type NotifySegment struct { TaskId int64 `protobuf:"varint,16,opt,name=taskId,proto3" json:"taskId,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"` + Profiles []byte `protobuf:"bytes,17,opt,name=profiles,proto3" json:"profiles,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } -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) 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) String() string { - return protoimpl.X.MessageStringOf(x) +func (m *NotifySegment) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_NotifySegment.Unmarshal(m, b) } - -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) +func (m *NotifySegment) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_NotifySegment.Marshal(b, m, deterministic) } - -// Deprecated: Use NotifySegment.ProtoReflect.Descriptor instead. -func (*NotifySegment) Descriptor() ([]byte, []int) { - return file_net_lp_rpc_proto_rawDescGZIP(), []int{17} +func (m *NotifySegment) XXX_Merge(src proto.Message) { + xxx_messageInfo_NotifySegment.Merge(m, src) +} +func (m *NotifySegment) XXX_Size() int { + return xxx_messageInfo_NotifySegment.Size(m) +} +func (m *NotifySegment) XXX_DiscardUnknown() { + xxx_messageInfo_NotifySegment.DiscardUnknown(m) } -func (x *NotifySegment) GetUrl() string { - if x != nil { - return x.Url +var xxx_messageInfo_NotifySegment proto.InternalMessageInfo + +func (m *NotifySegment) GetUrl() string { + if m != nil { + return m.Url } return "" } -func (x *NotifySegment) GetSegData() *SegData { - if x != nil { - return x.SegData +func (m *NotifySegment) GetSegData() *SegData { + if m != nil { + return m.SegData } return nil } -func (x *NotifySegment) GetTaskId() int64 { - if x != nil { - return x.TaskId +func (m *NotifySegment) GetTaskId() int64 { + if m != nil { + return m.TaskId } return 0 } -func (x *NotifySegment) GetProfiles() []byte { - if x != nil { - return x.Profiles +func (m *NotifySegment) GetProfiles() []byte { + if m != nil { + return m.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 @@ -1696,203 +1508,183 @@ 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"` + 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:"-"` } -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) 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) String() string { - return protoimpl.X.MessageStringOf(x) +func (m *TicketParams) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_TicketParams.Unmarshal(m, b) } - -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) +func (m *TicketParams) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_TicketParams.Marshal(b, m, deterministic) } - -// Deprecated: Use TicketParams.ProtoReflect.Descriptor instead. -func (*TicketParams) Descriptor() ([]byte, []int) { - return file_net_lp_rpc_proto_rawDescGZIP(), []int{18} +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) +} + +var xxx_messageInfo_TicketParams proto.InternalMessageInfo -func (x *TicketParams) GetRecipient() []byte { - if x != nil { - return x.Recipient +func (m *TicketParams) GetRecipient() []byte { + if m != nil { + return m.Recipient } return nil } -func (x *TicketParams) GetFaceValue() []byte { - if x != nil { - return x.FaceValue +func (m *TicketParams) GetFaceValue() []byte { + if m != nil { + return m.FaceValue } return nil } -func (x *TicketParams) GetWinProb() []byte { - if x != nil { - return x.WinProb +func (m *TicketParams) GetWinProb() []byte { + if m != nil { + return m.WinProb } return nil } -func (x *TicketParams) GetRecipientRandHash() []byte { - if x != nil { - return x.RecipientRandHash +func (m *TicketParams) GetRecipientRandHash() []byte { + if m != nil { + return m.RecipientRandHash } return nil } -func (x *TicketParams) GetSeed() []byte { - if x != nil { - return x.Seed +func (m *TicketParams) GetSeed() []byte { + if m != nil { + return m.Seed } return nil } -func (x *TicketParams) GetExpirationBlock() []byte { - if x != nil { - return x.ExpirationBlock +func (m *TicketParams) GetExpirationBlock() []byte { + if m != nil { + return m.ExpirationBlock } return nil } -func (x *TicketParams) GetExpirationParams() *TicketExpirationParams { - if x != nil { - return x.ExpirationParams +func (m *TicketParams) GetExpirationParams() *TicketExpirationParams { + if m != nil { + return m.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"` + Sig []byte `protobuf:"bytes,2,opt,name=sig,proto3" json:"sig,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } -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) 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) String() string { - return protoimpl.X.MessageStringOf(x) +func (m *TicketSenderParams) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_TicketSenderParams.Unmarshal(m, b) } - -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) +func (m *TicketSenderParams) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_TicketSenderParams.Marshal(b, m, deterministic) } - -// Deprecated: Use TicketSenderParams.ProtoReflect.Descriptor instead. -func (*TicketSenderParams) Descriptor() ([]byte, []int) { - return file_net_lp_rpc_proto_rawDescGZIP(), []int{19} +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) +} + +var xxx_messageInfo_TicketSenderParams proto.InternalMessageInfo -func (x *TicketSenderParams) GetSenderNonce() uint32 { - if x != nil { - return x.SenderNonce +func (m *TicketSenderParams) GetSenderNonce() uint32 { + if m != nil { + return m.SenderNonce } return 0 } -func (x *TicketSenderParams) GetSig() []byte { - if x != nil { - return x.Sig +func (m *TicketSenderParams) GetSig() []byte { + if m != nil { + return m.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"` + 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:"-"` } -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) 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) String() string { - return protoimpl.X.MessageStringOf(x) +func (m *TicketExpirationParams) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_TicketExpirationParams.Unmarshal(m, b) } - -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) +func (m *TicketExpirationParams) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_TicketExpirationParams.Marshal(b, m, deterministic) } - -// Deprecated: Use TicketExpirationParams.ProtoReflect.Descriptor instead. -func (*TicketExpirationParams) Descriptor() ([]byte, []int) { - return file_net_lp_rpc_proto_rawDescGZIP(), []int{20} +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 (m *TicketExpirationParams) XXX_DiscardUnknown() { + xxx_messageInfo_TicketExpirationParams.DiscardUnknown(m) } -func (x *TicketExpirationParams) GetCreationRound() int64 { - if x != nil { - return x.CreationRound +var xxx_messageInfo_TicketExpirationParams proto.InternalMessageInfo + +func (m *TicketExpirationParams) GetCreationRound() int64 { + if m != nil { + return m.CreationRound } return 0 } -func (x *TicketExpirationParams) GetCreationRoundBlockHash() []byte { - if x != nil { - return x.CreationRoundBlockHash +func (m *TicketExpirationParams) GetCreationRoundBlockHash() []byte { + if m != nil { + return m.CreationRoundBlockHash } return nil } @@ -1901,10 +1693,6 @@ func (x *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"` @@ -1914,792 +1702,228 @@ 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"` + 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:"-"` } -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) 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) String() string { - return protoimpl.X.MessageStringOf(x) +func (m *Payment) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Payment.Unmarshal(m, b) } - -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) +func (m *Payment) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Payment.Marshal(b, m, deterministic) } - -// Deprecated: Use Payment.ProtoReflect.Descriptor instead. -func (*Payment) Descriptor() ([]byte, []int) { - return file_net_lp_rpc_proto_rawDescGZIP(), []int{21} +func (m *Payment) XXX_Merge(src proto.Message) { + xxx_messageInfo_Payment.Merge(m, src) } - -func (x *Payment) GetTicketParams() *TicketParams { - if x != nil { - return x.TicketParams - } - return nil +func (m *Payment) XXX_Size() int { + return xxx_messageInfo_Payment.Size(m) } - -func (x *Payment) GetSender() []byte { - if x != nil { - return x.Sender - } - return nil +func (m *Payment) XXX_DiscardUnknown() { + xxx_messageInfo_Payment.DiscardUnknown(m) } -func (x *Payment) GetExpirationParams() *TicketExpirationParams { - if x != nil { - return x.ExpirationParams +var xxx_messageInfo_Payment proto.InternalMessageInfo + +func (m *Payment) GetTicketParams() *TicketParams { + if m != nil { + return m.TicketParams } return nil } -func (x *Payment) GetTicketSenderParams() []*TicketSenderParams { - if x != nil { - return x.TicketSenderParams +func (m *Payment) GetSender() []byte { + if m != nil { + return m.Sender } return nil } -func (x *Payment) GetExpectedPrice() *PriceInfo { - if x != nil { - return x.ExpectedPrice +func (m *Payment) GetExpirationParams() *TicketExpirationParams { + if m != nil { + return m.ExpirationParams } return nil } -// Non-binary capability constraints, such as supported ranges. -type Capabilities_Constraints struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields -} - -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 (m *Payment) GetTicketSenderParams() []*TicketSenderParams { + if m != nil { + return m.TicketSenderParams } + return nil } -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 +func (m *Payment) GetExpectedPrice() *PriceInfo { + if m != nil { + return m.ExpectedPrice } - return mi.MessageOf(x) + return nil } -// Deprecated: Use Capabilities_Constraints.ProtoReflect.Descriptor instead. -func (*Capabilities_Constraints) Descriptor() ([]byte, []int) { - return file_net_lp_rpc_proto_rawDescGZIP(), []int{7, 1} -} - -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, 0xdf, 0x01, 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, 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, 0x0d, 0x0a, 0x0b, 0x43, 0x6f, 0x6e, 0x73, 0x74, - 0x72, 0x61, 0x69, 0x6e, 0x74, 0x73, 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, - 0x89, 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, 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 - 23, // 4: net.OrchestratorInfo.ticket_params:type_name -> net.TicketParams - 11, // 5: net.OrchestratorInfo.price_info:type_name -> net.PriceInfo - 12, // 6: net.OrchestratorInfo.capabilities:type_name -> net.Capabilities - 14, // 7: net.OrchestratorInfo.auth_token:type_name -> net.AuthToken - 9, // 8: net.OrchestratorInfo.storage:type_name -> net.OSInfo - 12, // 9: net.SegData.capabilities:type_name -> net.Capabilities - 14, // 10: net.SegData.auth_token:type_name -> net.AuthToken - 9, // 11: net.SegData.storage:type_name -> net.OSInfo - 17, // 12: net.SegData.fullProfiles:type_name -> net.VideoProfile - 17, // 13: net.SegData.fullProfiles2:type_name -> net.VideoProfile - 17, // 14: net.SegData.fullProfiles3:type_name -> net.VideoProfile - 16, // 15: net.SegData.segment_parameters:type_name -> net.SegParameters - 1, // 16: net.VideoProfile.format:type_name -> net.VideoProfile.Format - 2, // 17: net.VideoProfile.profile:type_name -> net.VideoProfile.Profile - 3, // 18: net.VideoProfile.encoder:type_name -> net.VideoProfile.VideoCodec - 4, // 19: net.VideoProfile.chromaFormat:type_name -> net.VideoProfile.ChromaSubsampling - 18, // 20: net.TranscodeData.segments:type_name -> net.TranscodedSegmentData - 19, // 21: net.TranscodeResult.data:type_name -> net.TranscodeData - 13, // 22: net.TranscodeResult.info:type_name -> net.OrchestratorInfo - 12, // 23: net.RegisterRequest.capabilities:type_name -> net.Capabilities - 15, // 24: net.NotifySegment.segData:type_name -> net.SegData - 25, // 25: net.TicketParams.expiration_params:type_name -> net.TicketExpirationParams - 23, // 26: net.Payment.ticket_params:type_name -> net.TicketParams - 25, // 27: net.Payment.expiration_params:type_name -> net.TicketExpirationParams - 24, // 28: net.Payment.ticket_sender_params:type_name -> net.TicketSenderParams - 11, // 29: net.Payment.expected_price:type_name -> net.PriceInfo - 8, // 30: net.Orchestrator.GetOrchestrator:input_type -> net.OrchestratorRequest - 6, // 31: net.Orchestrator.EndTranscodingSession:input_type -> net.EndTranscodingSessionRequest - 5, // 32: net.Orchestrator.Ping:input_type -> net.PingPong - 21, // 33: net.Transcoder.RegisterTranscoder:input_type -> net.RegisterRequest - 13, // 34: net.Orchestrator.GetOrchestrator:output_type -> net.OrchestratorInfo - 7, // 35: net.Orchestrator.EndTranscodingSession:output_type -> net.EndTranscodingSessionResponse - 5, // 36: net.Orchestrator.Ping:output_type -> net.PingPong - 22, // 37: net.Transcoder.RegisterTranscoder:output_type -> net.NotifySegment - 34, // [34:38] is the sub-list for method output_type - 30, // [30:34] is the sub-list for method input_type - 30, // [30:30] is the sub-list for extension type_name - 30, // [30:30] is the sub-list for extension extendee - 0, // [0:30] 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 +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, } diff --git a/net/lp_rpc.proto b/net/lp_rpc.proto index c7854f5980..e53a594fcf 100644 --- a/net/lp_rpc.proto +++ b/net/lp_rpc.proto @@ -105,9 +105,13 @@ message Capabilities { // Capacity corresponding to each capability map capacities = 3; + string version = 4; + + Constraints constraints = 5; + // Non-binary capability constraints, such as supported ranges. message Constraints { - // Empty for now + string minVersion = 1; } } diff --git a/net/lp_rpc_grpc.pb.go b/net/lp_rpc_grpc.pb.go index 3743d79756..64a0935463 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 v4.25.2 +// - protoc v3.21.4 // source: net/lp_rpc.proto package net diff --git a/net/redeemer.pb.go b/net/redeemer.pb.go index 132a70cf49..87d1869b4d 100644 --- a/net/redeemer.pb.go +++ b/net/redeemer.pb.go @@ -319,7 +319,6 @@ func file_net_redeemer_proto_init() { if File_net_redeemer_proto != nil { return } - file_net_lp_rpc_proto_init() if !protoimpl.UnsafeEnabled { file_net_redeemer_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Ticket); i { diff --git a/server/broadcast.go b/server/broadcast.go index 2edcd4f58d..150d66ea86 100755 --- a/server/broadcast.go +++ b/server/broadcast.go @@ -448,6 +448,9 @@ func (bsm *BroadcastSessionsManager) shouldSkipVerification(sessions []*Broadcas } func NewSessionManager(ctx context.Context, node *core.LivepeerNode, params *core.StreamParameters, sel BroadcastSessionsSelectorFactory) *BroadcastSessionsManager { + if node.Capabilities != nil { + params.Capabilities.SetMinVersionConstraint(node.Capabilities.MinVersionConstraint()) + } var trustedPoolSize, untrustedPoolSize float64 if node.OrchestratorPool != nil { trustedPoolSize = float64(node.OrchestratorPool.SizeWith(common.ScoreAtLeast(common.Score_Trusted))) diff --git a/server/mediaserver.go b/server/mediaserver.go index c123c578a9..7f57e6b823 100644 --- a/server/mediaserver.go +++ b/server/mediaserver.go @@ -433,6 +433,7 @@ func gotRTMPStreamHandler(s *LivepeerServer) func(url *url.URL, rtmpStrm stream. func endRTMPStreamHandler(s *LivepeerServer) func(url *url.URL, rtmpStrm stream.RTMPVideoStream) error { return func(url *url.URL, rtmpStrm stream.RTMPVideoStream) error { params := streamParams(rtmpStrm.AppData()) + params.Capabilities.SetMinVersionConstraint(s.LivepeerNode.Capabilities.MinVersionConstraint()) if params == nil { return errMismatchedParams } From 5f8bc5549879880a03c9e48f731e786b58a2b67c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Leszko?= Date: Mon, 13 May 2024 18:57:12 +0200 Subject: [PATCH 20/88] Update LPMS with the mobile transcoding fix (#3003) --- core/core_test.go | 4 ++-- core/transcoder_test.go | 4 ++-- go.mod | 2 +- go.sum | 2 ++ 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/core/core_test.go b/core/core_test.go index 671c56c916..5346e2a3d3 100644 --- a/core/core_test.go +++ b/core/core_test.go @@ -78,10 +78,10 @@ func TestTranscode(t *testing.T) { } // Check transcode result - if Over1Pct(len(tr.TranscodeData.Segments[0].Data), 218268) { // 144p + if Over1Pct(len(tr.TranscodeData.Segments[0].Data), 273352) { // 144p t.Error("Unexpected transcode result ", len(tr.TranscodeData.Segments[0].Data)) } - if Over1Pct(len(tr.TranscodeData.Segments[1].Data), 302868) { // 240p + if Over1Pct(len(tr.TranscodeData.Segments[1].Data), 378068) { // 240p t.Error("Unexpected transcode result ", len(tr.TranscodeData.Segments[1].Data)) } diff --git a/core/transcoder_test.go b/core/transcoder_test.go index 8b8061ffc8..25e19c5818 100644 --- a/core/transcoder_test.go +++ b/core/transcoder_test.go @@ -32,10 +32,10 @@ func TestLocalTranscoder(t *testing.T) { if len(res.Segments) != len(videoProfiles) { t.Error("Mismatched results") } - if Over1Pct(len(res.Segments[0].Data), 522264) { + if Over1Pct(len(res.Segments[0].Data), 585620) { t.Errorf("Wrong data %v", len(res.Segments[0].Data)) } - if Over1Pct(len(res.Segments[1].Data), 715528) { + if Over1Pct(len(res.Segments[1].Data), 813100) { t.Errorf("Wrong data %v", len(res.Segments[1].Data)) } } diff --git a/go.mod b/go.mod index e4837beb3b..42eef47297 100644 --- a/go.mod +++ b/go.mod @@ -13,7 +13,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-20240402101153-ced71c476bd0 + github.com/livepeer/lpms v0.0.0-20240513161533-11a5584d691d 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 cad66eecff..6a79bae3e1 100644 --- a/go.sum +++ b/go.sum @@ -452,6 +452,8 @@ github.com/livepeer/lpms v0.0.0-20240115103113-98566e26c007 h1:0xr1TeIanBDdzI3sE github.com/livepeer/lpms v0.0.0-20240115103113-98566e26c007/go.mod h1:Hr/JhxxPDipOVd4ZrGYWrdJfpVF8/SEI0nNr2ctAlkM= github.com/livepeer/lpms v0.0.0-20240402101153-ced71c476bd0 h1:Ch+HRjVJHpNo3kySGJgyDqb+l0KPWehyqZfA1wOafgY= github.com/livepeer/lpms v0.0.0-20240402101153-ced71c476bd0/go.mod h1:z5ROP1l5OzAKSoqVRLc34MjUdueil6wHSecQYV7llIw= +github.com/livepeer/lpms v0.0.0-20240513161533-11a5584d691d h1:RehRsei/f2mv1RCWD1e3FWRkPl/+eKlHq6syU9c4WJE= +github.com/livepeer/lpms v0.0.0-20240513161533-11a5584d691d/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= From 7599f7fe79174d8541305fe79aeb5d0bac078afc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Leszko?= Date: Tue, 14 May 2024 17:17:17 +0200 Subject: [PATCH 21/88] Release 0.7.5 (#3051) --- CHANGELOG.md | 41 ++++++++++++++++++++++++++++++++++++++++- CHANGELOG_PENDING.md | 5 ----- VERSION | 2 +- 3 files changed, 41 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ea7f99c11a..49545e9b2c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,44 @@ # Changelog +## v0.7.5 + +### Breaking Changes 🚨🚨 + +### Features ⚒ + +#### General + +- [#3050](https://github.com/livepeer/go-livepeer/pull/3050) Create option to filter Os by min livepeer version used (@leszko) +- [#3029](https://github.com/livepeer/go-livepeer/pull/3029) Initialize round by any B/O who has the initializeRound flag set to true (@leszko) +- [#3040](https://github.com/livepeer/go-livepeer/pull/3040) Fix function names (@kevincatty) + +#### Broadcaster + +- [#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) + +#### Orchestrator + +- [#3001](https://github.com/livepeer/go-livepeer/pull/3001) Fix transcoding price metrics (@leszko) + +#### Transcoder + +- [#3003](https://github.com/livepeer/go-livepeer/pull/3003) Fix issue in the transcoding layer for WebRTC input (@j0sh) + ## v0.7.4 ### Breaking Changes 🚨🚨 @@ -946,4 +985,4 @@ Thanks everyone that submitted bug reports and assisted in testing! - [#1775](https://github.com/livepeer/go-livepeer/pull/1775) Fix transcoder load balancer race condition around session cleanup (@jailuthra) - [#1784](https://github.com/livepeer/go-livepeer/pull/1784) Use auth token sessionID to index into sessions map in transcoder load balancer (@jailuthra) -[Full list of changes](https://github.com/livepeer/go-livepeer/compare/v0.5.14...v0.5.15) \ No newline at end of file +[Full list of changes](https://github.com/livepeer/go-livepeer/compare/v0.5.14...v0.5.15) diff --git a/CHANGELOG_PENDING.md b/CHANGELOG_PENDING.md index 1015174350..3ca5044811 100644 --- a/CHANGELOG_PENDING.md +++ b/CHANGELOG_PENDING.md @@ -10,9 +10,6 @@ #### Broadcaster -- [#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 @@ -25,8 +22,6 @@ #### Broadcaster -- [#2994](https://github.com/livepeer/go-livepeer/pull/2994) server: Skip redundant maxPrice check in ongoing session (@victorges) - #### Orchestrator #### Transcoder diff --git a/VERSION b/VERSION index ef090a6c47..da2ac9c7e6 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.7.4 \ No newline at end of file +0.7.5 \ No newline at end of file From 19f1cf62293a76d050567e4d7edc018c274901a9 Mon Sep 17 00:00:00 2001 From: Rick Staa Date: Thu, 16 May 2024 18:46:20 +0200 Subject: [PATCH 22/88] refactor: add -gateway and deprecate -broadcaster (#3053) * refactor: add -gateway and deprecate -broadcaster This commit adds the `gateway` flag and deprecates the `broadcaster` flag per core team decision (details: https://discord.com/channels/423160867534929930/1051963444598943784/1210356864643109004). * chore: update pending changelog --------- Co-authored-by: John | Elite Encoder --- CHANGELOG_PENDING.md | 2 ++ cmd/livepeer/livepeer.go | 3 ++- cmd/livepeer/starter/starter.go | 8 +++++++- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/CHANGELOG_PENDING.md b/CHANGELOG_PENDING.md index 3ca5044811..fa297c5552 100644 --- a/CHANGELOG_PENDING.md +++ b/CHANGELOG_PENDING.md @@ -2,6 +2,8 @@ ## vX.X +- [#3053](https://github.com/livepeer/go-livepeer/pull/3053) cli: add `-gateway` flag and deprecate `-broadcaster` flag. + ### Breaking Changes 🚨🚨 ### Features ⚒ diff --git a/cmd/livepeer/livepeer.go b/cmd/livepeer/livepeer.go index b25472f7fa..0568b70836 100755 --- a/cmd/livepeer/livepeer.go +++ b/cmd/livepeer/livepeer.go @@ -140,7 +140,8 @@ func parseLivepeerConfig() starter.LivepeerConfig { // Transcoding: cfg.Orchestrator = flag.Bool("orchestrator", *cfg.Orchestrator, "Set to true to be an orchestrator") cfg.Transcoder = flag.Bool("transcoder", *cfg.Transcoder, "Set to true to be a transcoder") - cfg.Broadcaster = flag.Bool("broadcaster", *cfg.Broadcaster, "Set to true to be a broadcaster") + cfg.Gateway = flag.Bool("gateway", *cfg.Broadcaster, "Set to true to be a gateway") + cfg.Broadcaster = flag.Bool("broadcaster", *cfg.Broadcaster, "Set to true to be a broadcaster (**Deprecated**, use -gateway)") cfg.OrchSecret = flag.String("orchSecret", *cfg.OrchSecret, "Shared secret with the orchestrator as a standalone transcoder or path to file") cfg.TranscodingOptions = flag.String("transcodingOptions", *cfg.TranscodingOptions, "Transcoding options for broadcast job, or path to json config") cfg.MaxAttempts = flag.Int("maxAttempts", *cfg.MaxAttempts, "Maximum transcode attempts") diff --git a/cmd/livepeer/starter/starter.go b/cmd/livepeer/starter/starter.go index 84ff08c330..3ed6edfaa0 100755 --- a/cmd/livepeer/starter/starter.go +++ b/cmd/livepeer/starter/starter.go @@ -87,6 +87,7 @@ type LivepeerConfig struct { HttpIngest *bool Orchestrator *bool Transcoder *bool + Gateway *bool Broadcaster *bool OrchSecret *string TranscodingOptions *string @@ -164,6 +165,7 @@ func DefaultLivepeerConfig() LivepeerConfig { defaultOrchestrator := false defaultTranscoder := false defaultBroadcaster := false + defaultGateway := false defaultOrchSecret := "" defaultTranscodingOptions := "P240p30fps16x9,P360p30fps16x9" defaultMaxAttempts := 3 @@ -250,6 +252,7 @@ func DefaultLivepeerConfig() LivepeerConfig { // Transcoding: Orchestrator: &defaultOrchestrator, Transcoder: &defaultTranscoder, + Gateway: &defaultGateway, Broadcaster: &defaultBroadcaster, OrchSecret: &defaultOrchSecret, TranscodingOptions: &defaultTranscodingOptions, @@ -501,6 +504,9 @@ func StartLivepeer(ctx context.Context, cfg LivepeerConfig) { n.NodeType = core.TranscoderNode } else if *cfg.Broadcaster { n.NodeType = core.BroadcasterNode + glog.Warning("-broadcaster flag is deprecated and will be removed in a future release. Please use -gateway instead") + } else if *cfg.Gateway { + n.NodeType = core.BroadcasterNode } else if (cfg.Reward == nil || !*cfg.Reward) && !*cfg.InitializeRound { exit("No services enabled; must be at least one of -broadcaster, -transcoder, -orchestrator, -redeemer, -reward or -initializeRound") } @@ -1273,7 +1279,7 @@ func StartLivepeer(ctx context.Context, cfg LivepeerConfig) { case core.OrchestratorNode: glog.Infof("***Livepeer Running in Orchestrator Mode***") case core.BroadcasterNode: - glog.Infof("***Livepeer Running in Broadcaster Mode***") + glog.Infof("***Livepeer Running in Gateway Mode***") glog.Infof("Video Ingest Endpoint - rtmp://%v", *cfg.RtmpAddr) case core.TranscoderNode: glog.Infof("**Liveepeer Running in Transcoder Mode***") From 304e47f12e805aa25a51968b7ddf00a87ed54172 Mon Sep 17 00:00:00 2001 From: Rick Staa Date: Thu, 16 May 2024 20:06:18 +0200 Subject: [PATCH 23/88] refactor(census): rename Broadcaster metrics to Gateway (#3055) * refactor(census): rename Broadcaster metrics to Gateway This commit renames the metrics related to Broadcaster to Gateway, following a team decision. More details can be found in the discussion here: [Team Discussion Link](.com/channels/423160867534929930/1051963444598943784/1210356864643109004). * chore: update pending changelog --- CHANGELOG_PENDING.md | 3 ++- monitor/census.go | 25 ++++++++++++++++++++----- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/CHANGELOG_PENDING.md b/CHANGELOG_PENDING.md index fa297c5552..bd4caf70d2 100644 --- a/CHANGELOG_PENDING.md +++ b/CHANGELOG_PENDING.md @@ -2,7 +2,8 @@ ## vX.X -- [#3053](https://github.com/livepeer/go-livepeer/pull/3053) cli: add `-gateway` flag and deprecate `-broadcaster` flag. +- [#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. ### Breaking Changes 🚨🚨 diff --git a/monitor/census.go b/monitor/census.go index 8c80459bc7..f6ee869231 100644 --- a/monitor/census.go +++ b/monitor/census.go @@ -306,8 +306,8 @@ func InitCensus(nodeType NodeType, version string) { census.mTicketValueSent = stats.Float64("ticket_value_sent", "TicketValueSent", "gwei") census.mTicketsSent = stats.Int64("tickets_sent", "TicketsSent", "tot") census.mPaymentCreateError = stats.Int64("payment_create_errors", "PaymentCreateError", "tot") - census.mDeposit = stats.Float64("broadcaster_deposit", "Current remaining deposit for the broadcaster node", "gwei") - census.mReserve = stats.Float64("broadcaster_reserve", "Current remaining reserve for the broadcaster node", "gwei") + census.mDeposit = stats.Float64("gateway_deposit", "Current remaining deposit for the gateway node", "gwei") + census.mReserve = stats.Float64("gateway_reserve", "Current remaining reserve for the gateway node", "gwei") // Metrics for receiving payments census.mTicketValueRecv = stats.Float64("ticket_value_recv", "TicketValueRecv", "gwei") @@ -690,17 +690,32 @@ func InitCensus(nodeType NodeType, version string) { TagKeys: baseTagsWithManifestID, Aggregation: view.Sum(), }, + { + Name: "gateway_deposit", + Measure: census.mDeposit, + Description: "Current remaining deposit for the gateway node", + TagKeys: baseTagsWithEthAddr, + Aggregation: view.LastValue(), + }, + { + Name: "gateway_reserve", + Measure: census.mReserve, + Description: "Current remaining reserve for the gateway node", + TagKeys: baseTagsWithEthAddr, + Aggregation: view.LastValue(), + }, + // TODO: Keep the old names for backwards compatibility, remove in the future { Name: "broadcaster_deposit", Measure: census.mDeposit, - Description: "Current remaining deposit for the broadcaster node", + Description: "Current remaining deposit for the gateway node", TagKeys: baseTagsWithEthAddr, Aggregation: view.LastValue(), }, { Name: "broadcaster_reserve", Measure: census.mReserve, - Description: "Current remaining reserve for the broadcaster node", + Description: "Current remaining reserve for the gateway node", TagKeys: baseTagsWithEthAddr, Aggregation: view.LastValue(), }, @@ -1533,7 +1548,7 @@ func PaymentCreateError(ctx context.Context) { } } -// Deposit records the current deposit for the broadcaster +// Deposit records the current deposit for the gateway func Deposit(sender string, deposit *big.Int) { if err := stats.RecordWithTags(census.ctx, []tag.Mutator{tag.Insert(census.kSender, sender)}, census.mDeposit.M(wei2gwei(deposit))); err != nil { From b739f354ce42d20d51c0778156999932dd8c2ae8 Mon Sep 17 00:00:00 2001 From: Rick Staa Date: Sun, 19 May 2024 23:12:03 +0200 Subject: [PATCH 24/88] refactor: add -pricePerGateway and deprecate -pricePerBroadcaster (#3056) * refactor: add -pricePerGateway and deprecate -pricePerBroadcaster This commit adds the `pricePerGateway` flag and deprecates the `pricePerBroadcaster` flag per core team decision (details: https://discord.com/channels/423160867534929930/1051963444598943784/1210356864643109004). * chore: update pending changelog * refactor: remove redundant deprecation comment This commit removes the `PricePerBroadcaster` deprecation comment since this is already clear from the glog warning below. * fix: correct the `pricePerBroadcaster` flag check This commit ensures that the deprecation condition for the `pricePerBroadcaster` flag properly handles the default empty string value. * fix: ensure 'pricePerGateway' is used This commit ensures that the `pricePerGateway` is correctly used instead of the `pricePerBroadcaster` when it is set. * refactor: deprecate 'pricePerGateway' broadcasters property in favor of 'gateways' This commit updates the configuration to replace the `broadcasters` property specified under the `pricePerGateway` flag with `gateways`. Additionally, it ensures that a warning is issued when the deprecated property is still used. * test: fix TestParseGetBroadcasterPrices test This commit ensures that the TestParseGetBroadcasterPrices function uses the new getGatewayPrices function. * test: rename TestParseGetBroadcasterPrices to reflect Gateway naming This commit updates the `TestParseGetBroadcasterPrices` function to `TestParseGetGatewayPrices` to align with the new node naming convention. --- CHANGELOG_PENDING.md | 1 + cmd/livepeer/livepeer.go | 1 + cmd/livepeer/starter/starter.go | 50 +++++++++++++++++++--------- cmd/livepeer/starter/starter_test.go | 25 +++++++++----- 4 files changed, 53 insertions(+), 24 deletions(-) diff --git a/CHANGELOG_PENDING.md b/CHANGELOG_PENDING.md index bd4caf70d2..cd86a5c596 100644 --- a/CHANGELOG_PENDING.md +++ b/CHANGELOG_PENDING.md @@ -4,6 +4,7 @@ - [#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. ### Breaking Changes 🚨🚨 diff --git a/cmd/livepeer/livepeer.go b/cmd/livepeer/livepeer.go index 0568b70836..0bf119b7bb 100755 --- a/cmd/livepeer/livepeer.go +++ b/cmd/livepeer/livepeer.go @@ -179,6 +179,7 @@ func parseLivepeerConfig() starter.LivepeerConfig { cfg.PixelsPerUnit = flag.String("pixelsPerUnit", *cfg.PixelsPerUnit, "Amount of pixels per unit. Set to '> 1' to have smaller price granularity than 1 wei / pixel") cfg.PriceFeedAddr = flag.String("priceFeedAddr", *cfg.PriceFeedAddr, "ETH address of the Chainlink price feed contract. Used for custom currencies conversion on -pricePerUnit or -maxPricePerUnit") cfg.AutoAdjustPrice = flag.Bool("autoAdjustPrice", *cfg.AutoAdjustPrice, "Enable/disable automatic price adjustments based on the overhead for redeeming tickets") + cfg.PricePerGateway = flag.String("pricePerGateway", *cfg.PricePerGateway, `json list of price per gateway or path to json config file. Example: {"broadcasters":[{"ethaddress":"address1","priceperunit":0.5,"currency":"USD","pixelsperunit":1000000000000},{"ethaddress":"address2","priceperunit":0.3,"currency":"USD","pixelsperunit":1000000000000}]}`) cfg.PricePerBroadcaster = flag.String("pricePerBroadcaster", *cfg.PricePerBroadcaster, `json list of price per broadcaster or path to json config file. Example: {"broadcasters":[{"ethaddress":"address1","priceperunit":0.5,"currency":"USD","pixelsperunit":1000000000000},{"ethaddress":"address2","priceperunit":0.3,"currency":"USD","pixelsperunit":1000000000000}]}`) // Interval to poll for blocks cfg.BlockPollingInterval = flag.Int("blockPollingInterval", *cfg.BlockPollingInterval, "Interval in seconds at which different blockchain event services poll for blocks") diff --git a/cmd/livepeer/starter/starter.go b/cmd/livepeer/starter/starter.go index 3ed6edfaa0..1053506bda 100755 --- a/cmd/livepeer/starter/starter.go +++ b/cmd/livepeer/starter/starter.go @@ -126,6 +126,7 @@ type LivepeerConfig struct { PixelsPerUnit *string PriceFeedAddr *string AutoAdjustPrice *bool + PricePerGateway *string PricePerBroadcaster *string BlockPollingInterval *int Redeemer *bool @@ -204,6 +205,7 @@ func DefaultLivepeerConfig() LivepeerConfig { defaultPixelsPerUnit := "1" defaultPriceFeedAddr := "0x639Fe6ab55C921f74e7fac1ee960C0B6293ba612" // ETH / USD price feed address on Arbitrum Mainnet defaultAutoAdjustPrice := true + defaultPricePerGateway := "" defaultPricePerBroadcaster := "" defaultBlockPollingInterval := 5 defaultRedeemer := false @@ -292,6 +294,7 @@ func DefaultLivepeerConfig() LivepeerConfig { PixelsPerUnit: &defaultPixelsPerUnit, PriceFeedAddr: &defaultPriceFeedAddr, AutoAdjustPrice: &defaultAutoAdjustPrice, + PricePerGateway: &defaultPricePerGateway, PricePerBroadcaster: &defaultPricePerBroadcaster, BlockPollingInterval: &defaultBlockPollingInterval, Redeemer: &defaultRedeemer, @@ -784,7 +787,11 @@ func StartLivepeer(ctx context.Context, cfg LivepeerConfig) { } n.SetBasePrice("default", autoPrice) - broadcasterPrices := getBroadcasterPrices(*cfg.PricePerBroadcaster) + if *cfg.PricePerBroadcaster != "" { + glog.Warning("-PricePerBroadcaster flag is deprecated and will be removed in a future release. Please use -PricePerGateway instead") + cfg.PricePerGateway = cfg.PricePerBroadcaster + } + broadcasterPrices := getGatewayPrices(*cfg.PricePerGateway) for _, p := range broadcasterPrices { p := p pricePerPixel := new(big.Rat).Quo(p.PricePerUnit, p.PixelsPerUnit) @@ -1482,51 +1489,64 @@ func checkOrStoreChainID(dbh *common.DB, chainID *big.Int) error { return nil } -type BroadcasterPrice struct { +type GatewayPrice struct { EthAddress string PricePerUnit *big.Rat Currency string PixelsPerUnit *big.Rat } -func getBroadcasterPrices(broadcasterPrices string) []BroadcasterPrice { - if broadcasterPrices == "" { +func getGatewayPrices(gatewayPrices string) []GatewayPrice { + if gatewayPrices == "" { return nil } // Format of broadcasterPrices json - // {"broadcasters":[{"ethaddress":"address1","priceperunit":0.5,"currency":"USD","pixelsperunit":1}, {"ethaddress":"address2","priceperunit":0.3,"currency":"USD","pixelsperunit":3}]} + // {"gateways":[{"ethaddress":"address1","priceperunit":0.5,"currency":"USD","pixelsperunit":1}, {"ethaddress":"address2","priceperunit":0.3,"currency":"USD","pixelsperunit":3}]} var pricesSet struct { + Gateways []struct { + EthAddress string `json:"ethaddress"` + PixelsPerUnit json.RawMessage `json:"pixelsperunit"` + PricePerUnit json.RawMessage `json:"priceperunit"` + Currency string `json:"currency"` + } `json:"gateways"` + // TODO: Keep the old name for backwards compatibility, remove in the future Broadcasters []struct { - EthAddress string `json:"ethaddress"` - // The fields below are specified as a number in the JSON, but we don't want to lose precision so we store the raw characters here and parse as a big.Rat. - // This also allows support for exponential notation for numbers, which is helpful for pricePerUnit which could be a value like 1e12. + EthAddress string `json:"ethaddress"` PixelsPerUnit json.RawMessage `json:"pixelsperunit"` PricePerUnit json.RawMessage `json:"priceperunit"` Currency string `json:"currency"` } `json:"broadcasters"` } - pricesFileContent, _ := common.ReadFromFile(broadcasterPrices) + pricesFileContent, _ := common.ReadFromFile(gatewayPrices) err := json.Unmarshal([]byte(pricesFileContent), &pricesSet) if err != nil { - glog.Errorf("broadcaster prices could not be parsed: %s", err) + glog.Errorf("gateway prices could not be parsed: %s", err) return nil } - prices := make([]BroadcasterPrice, len(pricesSet.Broadcasters)) - for i, p := range pricesSet.Broadcasters { + // Check if broadcasters field is used and display a warning + if len(pricesSet.Broadcasters) > 0 { + glog.Warning("The 'broadcaster' property in the 'pricePerGateway' config is deprecated and will be removed in a future release. Please use 'gateways' instead.") + } + + // Combine broadcasters and gateways into a single slice + allGateways := append(pricesSet.Broadcasters, pricesSet.Gateways...) + + prices := make([]GatewayPrice, len(allGateways)) + for i, p := range allGateways { pixelsPerUnit, ok := new(big.Rat).SetString(string(p.PixelsPerUnit)) if !ok { - glog.Errorf("Pixels per unit could not be parsed for broadcaster %v. must be a valid number, provided %s", p.EthAddress, p.PixelsPerUnit) + glog.Errorf("Pixels per unit could not be parsed for gateway %v. must be a valid number, provided %s", p.EthAddress, p.PixelsPerUnit) continue } pricePerUnit, ok := new(big.Rat).SetString(string(p.PricePerUnit)) if !ok { - glog.Errorf("Price per unit could not be parsed for broadcaster %v. must be a valid number, provided %s", p.EthAddress, p.PricePerUnit) + glog.Errorf("Price per unit could not be parsed for gateway %v. must be a valid number, provided %s", p.EthAddress, p.PricePerUnit) continue } - prices[i] = BroadcasterPrice{ + prices[i] = GatewayPrice{ EthAddress: p.EthAddress, Currency: p.Currency, PricePerUnit: pricePerUnit, diff --git a/cmd/livepeer/starter/starter_test.go b/cmd/livepeer/starter/starter_test.go index 45d3620b8e..60df927897 100644 --- a/cmd/livepeer/starter/starter_test.go +++ b/cmd/livepeer/starter/starter_test.go @@ -2,6 +2,7 @@ package starter import ( "errors" + "fmt" "math/big" "os" "path/filepath" @@ -87,19 +88,25 @@ func TestIsLocalURL(t *testing.T) { assert.False(isLocal) } -func TestParseGetBroadcasterPrices(t *testing.T) { +func TestParseGetGatewayPrices(t *testing.T) { assert := assert.New(t) - j := `{"broadcasters":[{"ethaddress":"0x0000000000000000000000000000000000000000","priceperunit":1000,"pixelsperunit":1}, {"ethaddress":"0x1000000000000000000000000000000000000000","priceperunit":2000,"pixelsperunit":3}]}` + // TODO: Keep checking old field for backwards compatibility, remove in future + jsonTemplate := `{"%s":[{"ethaddress":"0x0000000000000000000000000000000000000000","priceperunit":1000,"pixelsperunit":1}, {"ethaddress":"0x1000000000000000000000000000000000000000","priceperunit":2000,"pixelsperunit":3}]}` + testCases := []string{"gateways", "broadcasters"} - prices := getBroadcasterPrices(j) - assert.NotNil(prices) - assert.Equal(2, len(prices)) + for _, tc := range testCases { + jsonStr := fmt.Sprintf(jsonTemplate, tc) - price1 := new(big.Rat).Quo(prices[0].PricePerUnit, prices[0].PixelsPerUnit) - price2 := new(big.Rat).Quo(prices[1].PricePerUnit, prices[1].PixelsPerUnit) - assert.Equal(big.NewRat(1000, 1), price1) - assert.Equal(big.NewRat(2000, 3), price2) + prices := getGatewayPrices(jsonStr) + assert.NotNil(prices) + assert.Equal(2, len(prices)) + + price1 := new(big.Rat).Quo(prices[0].PricePerUnit, prices[0].PixelsPerUnit) + price2 := new(big.Rat).Quo(prices[1].PricePerUnit, prices[1].PixelsPerUnit) + assert.Equal(big.NewRat(1000, 1), price1) + assert.Equal(big.NewRat(2000, 3), price2) + } } // Address provided to keystore file From 6cfaf1e619da499b9509c268b01a9d2dbb11516b Mon Sep 17 00:00:00 2001 From: Rick Staa Date: Tue, 21 May 2024 09:01:33 +0200 Subject: [PATCH 25/88] ci: protect Docker 'stable' tag (#3062) This commit introduces a safeguard to ensure that the Docker image tagged as 'stable' is only pushed when a new tag is created on the stable branch. This prevents unintended updates to the stable Docker image, ensuring consistency and reliability for users relying on the stable tag. --- .github/workflows/docker.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker.yaml b/.github/workflows/docker.yaml index 6661c9dc03..05b64262f1 100644 --- a/.github/workflows/docker.yaml +++ b/.github/workflows/docker.yaml @@ -81,7 +81,7 @@ jobs: type=semver,pattern={{major}}.{{minor}},prefix=v type=raw,value=latest,enable={{is_default_branch}} type=raw,value=${{ github.event.pull_request.head.ref }} - type=raw,value=stable,enable=${{ startsWith(github.event.ref, 'refs/tags/v') }} + type=raw,value=stable,enable=${{ startsWith(github.event.ref, 'refs/tags/v') && is_default_branch }} - name: Build and push livepeer docker image uses: docker/build-push-action@v5 From fbb393e3fdc899eb6d2232afa6952a52904eba75 Mon Sep 17 00:00:00 2001 From: Thom Shutt Date: Tue, 28 May 2024 11:21:47 +0100 Subject: [PATCH 26/88] Return appropriate errors when auth fails, not just 5xx (#3065) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Return appropriate errors when auth fails, not just 5xx * Fix unit tests for new signature * Fix remaining tests * Fix another test * Refactor Forbidden to error type * Refactor Forbidden to error type --------- Co-authored-by: Rafał Leszko --- go.mod | 4 +- go.sum | 12 +--- server/mediaserver.go | 61 +++++++++++-------- server/mediaserver_test.go | 118 ++++++++++++++++++++++++++----------- server/push_test.go | 2 +- 5 files changed, 126 insertions(+), 71 deletions(-) diff --git a/go.mod b/go.mod index 42eef47297..54396951d9 100644 --- a/go.mod +++ b/go.mod @@ -4,6 +4,7 @@ go 1.20 require ( contrib.go.opencensus.io/exporter/prometheus v0.4.2 + github.com/Masterminds/semver/v3 v3.2.1 github.com/cenkalti/backoff v2.2.1+incompatible github.com/ethereum/go-ethereum v1.13.5 github.com/golang/glog v1.1.1 @@ -13,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-20240513161533-11a5584d691d + github.com/livepeer/lpms v0.0.0-20240528070257-343a3ddb3748 github.com/livepeer/m3u8 v0.11.1 github.com/mattn/go-sqlite3 v1.14.18 github.com/olekukonko/tablewriter v0.0.5 @@ -41,7 +42,6 @@ require ( dario.cat/mergo v1.0.0 // indirect github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect github.com/DataDog/zstd v1.4.5 // indirect - github.com/Masterminds/semver/v3 v3.2.1 // indirect github.com/Microsoft/go-winio v0.6.1 // indirect github.com/Microsoft/hcsshim v0.11.1 // indirect github.com/StackExchange/wmi v1.2.1 // indirect diff --git a/go.sum b/go.sum index 6a79bae3e1..866e8b20bc 100644 --- a/go.sum +++ b/go.sum @@ -297,8 +297,6 @@ github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= -github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= @@ -448,12 +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-20240115103113-98566e26c007 h1:0xr1TeIanBDdzI3sE2Zgf2yEV3s+6cPo3lJeyOHKmtM= -github.com/livepeer/lpms v0.0.0-20240115103113-98566e26c007/go.mod h1:Hr/JhxxPDipOVd4ZrGYWrdJfpVF8/SEI0nNr2ctAlkM= -github.com/livepeer/lpms v0.0.0-20240402101153-ced71c476bd0 h1:Ch+HRjVJHpNo3kySGJgyDqb+l0KPWehyqZfA1wOafgY= -github.com/livepeer/lpms v0.0.0-20240402101153-ced71c476bd0/go.mod h1:z5ROP1l5OzAKSoqVRLc34MjUdueil6wHSecQYV7llIw= -github.com/livepeer/lpms v0.0.0-20240513161533-11a5584d691d h1:RehRsei/f2mv1RCWD1e3FWRkPl/+eKlHq6syU9c4WJE= -github.com/livepeer/lpms v0.0.0-20240513161533-11a5584d691d/go.mod h1:z5ROP1l5OzAKSoqVRLc34MjUdueil6wHSecQYV7llIw= +github.com/livepeer/lpms v0.0.0-20240528070257-343a3ddb3748 h1:sucdljv+Wjo24WbuHYNFFzjRFsKlSj/s9bn7qdCkG/Y= +github.com/livepeer/lpms v0.0.0-20240528070257-343a3ddb3748/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= @@ -1081,8 +1075,6 @@ google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= -google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= diff --git a/server/mediaserver.go b/server/mediaserver.go index 7f57e6b823..168686525c 100644 --- a/server/mediaserver.go +++ b/server/mediaserver.go @@ -44,12 +44,15 @@ import ( "github.com/patrickmn/go-cache" ) -var errAlreadyExists = errors.New("StreamAlreadyExists") -var errStorage = errors.New("ErrStorage") -var errDiscovery = errors.New("ErrDiscovery") -var errNoOrchs = errors.New("ErrNoOrchs") -var errUnknownStream = errors.New("ErrUnknownStream") -var errMismatchedParams = errors.New("Mismatched type for stream params") +var ( + errAlreadyExists = errors.New("StreamAlreadyExists") + errStorage = errors.New("ErrStorage") + errDiscovery = errors.New("ErrDiscovery") + errNoOrchs = errors.New("ErrNoOrchs") + errUnknownStream = errors.New("ErrUnknownStream") + errMismatchedParams = errors.New("Mismatched type for stream params") + errForbidden = errors.New("authentication denied") +) const HLSWaitInterval = time.Second const HLSBufferCap = uint(43200) //12 hrs assuming 1s segment @@ -233,8 +236,8 @@ func (s *LivepeerServer) StartMediaServer(ctx context.Context, httpAddr string) } // RTMP Publish Handlers -func createRTMPStreamIDHandler(_ctx context.Context, s *LivepeerServer, webhookResponseOverride *authWebhookResponse) func(url *url.URL) (strmID stream.AppData) { - return func(url *url.URL) (strmID stream.AppData) { +func createRTMPStreamIDHandler(_ctx context.Context, s *LivepeerServer, webhookResponseOverride *authWebhookResponse) func(url *url.URL) (strmID stream.AppData, e error) { + return func(url *url.URL) (strmID stream.AppData, e error) { //Check HTTP header for ManifestID //If ManifestID is passed in HTTP header, use that one //Else check webhook for ManifestID @@ -256,8 +259,8 @@ func createRTMPStreamIDHandler(_ctx context.Context, s *LivepeerServer, webhookR // do not replace captured _ctx variable ctx := clog.AddNonce(_ctx, nonce) if resp, err = authenticateStream(AuthWebhookURL, url.String()); err != nil { - clog.Errorf(ctx, "Authentication denied for streamID url=%s err=%q", url.String(), err) - return nil + clog.Errorf(ctx, fmt.Sprintf("Forbidden: Authentication denied for streamID url=%s err=%q", url.String(), err)) + return nil, errForbidden } // If we've received auth in header AND callback URL forms then for now, we reject cases where they're @@ -265,7 +268,7 @@ func createRTMPStreamIDHandler(_ctx context.Context, s *LivepeerServer, webhookR if resp != nil && webhookResponseOverride != nil { if !resp.areProfilesEqual(*webhookResponseOverride) { clog.Errorf(ctx, "Received auth header with profiles that don't match those in callback URL response") - return nil + return nil, fmt.Errorf("Received auth header with profiles that don't match those in callback URL response") } } @@ -287,8 +290,9 @@ func createRTMPStreamIDHandler(_ctx context.Context, s *LivepeerServer, webhookR parsedProfiles, err := ffmpeg.ParseProfilesFromJsonProfileArray(resp.Profiles) if err != nil { - clog.Errorf(ctx, "Failed to parse JSON video profile for streamID url=%s err=%q", url.String(), err) - return nil + errMsg := fmt.Sprintf("Failed to parse JSON video profile for streamID url=%s err=%q", url.String(), err) + clog.Errorf(ctx, errMsg) + return nil, fmt.Errorf(errMsg) } profiles = append(profiles, parsedProfiles...) @@ -301,16 +305,18 @@ func createRTMPStreamIDHandler(_ctx context.Context, s *LivepeerServer, webhookR if resp.ObjectStore != "" { os, err = drivers.ParseOSURL(resp.ObjectStore, false) if err != nil { - clog.Errorf(ctx, "Failed to parse object store url for streamID url=%s err=%q", url.String(), err) - return nil + errMsg := fmt.Sprintf("Failed to parse object store url for streamID url=%s err=%q", url.String(), err) + clog.Errorf(ctx, errMsg) + return nil, fmt.Errorf(errMsg) } } // set Recording OS if it was provided if resp.RecordObjectStore != "" { ros, err = drivers.ParseOSURL(resp.RecordObjectStore, true) if err != nil { - clog.Errorf(ctx, "Failed to parse recording object store url for streamID url=%s err=%q", url.String(), err) - return nil + errMsg := fmt.Sprintf("Failed to parse recording object store url for streamID url=%s err=%q", url.String(), err) + clog.Errorf(ctx, errMsg) + return nil, fmt.Errorf(errMsg) } } @@ -346,8 +352,10 @@ func createRTMPStreamIDHandler(_ctx context.Context, s *LivepeerServer, webhookR s.connectionLock.RLock() defer s.connectionLock.RUnlock() if core.MaxSessions > 0 && len(s.rtmpConnections) >= core.MaxSessions { - clog.Errorf(ctx, "Too many connections for streamID url=%s err=%q", url.String(), err) - return nil + errMsg := fmt.Sprintf("Too many connections for streamID url=%s err=%q", url.String(), err) + clog.Errorf(ctx, errMsg) + return nil, fmt.Errorf(errMsg) + } return &core.StreamParameters{ ManifestID: mid, @@ -360,7 +368,7 @@ func createRTMPStreamIDHandler(_ctx context.Context, s *LivepeerServer, webhookR RecordOS: ross, VerificationFreq: VerificationFreq, Nonce: nonce, - } + }, nil } } @@ -820,10 +828,15 @@ func (s *LivepeerServer) HandlePush(w http.ResponseWriter, r *http.Request) { // Check for presence and register if a fresh cxn if !exists { - appData := (createRTMPStreamIDHandler(ctx, s, authHeaderConfig))(r.URL) - if appData == nil { - errorOut(http.StatusInternalServerError, "Could not create stream ID: url=%s", r.URL) - return + appData, err := (createRTMPStreamIDHandler(ctx, s, authHeaderConfig))(r.URL) + if err != nil { + if errors.Is(err, errForbidden) { + errorOut(http.StatusForbidden, "Could not create stream ID: url=%s", r.URL) + return + } else { + errorOut(http.StatusInternalServerError, "Could not create stream ID: url=%s", r.URL) + return + } } params := streamParams(appData) if authHeaderConfig != nil { diff --git a/server/mediaserver_test.go b/server/mediaserver_test.go index 79b4f611fb..595c4e29ab 100644 --- a/server/mediaserver_test.go +++ b/server/mediaserver_test.go @@ -438,7 +438,9 @@ func TestCreateRTMPStreamHandlerCap(t *testing.T) { oldMaxSessions := core.MaxSessions core.MaxSessions = 1 // happy case - sid := createSid(u).(*core.StreamParameters) + id, err := createSid(u) + require.NoError(t, err) + sid := id.(*core.StreamParameters) mid := sid.ManifestID if mid != "id1" { t.Error("Stream should be allowd", sid) @@ -448,7 +450,8 @@ func TestCreateRTMPStreamHandlerCap(t *testing.T) { } s.rtmpConnections[core.ManifestID("id1")] = nil // capped case - params := createSid(u) + params, err := createSid(u) + require.Error(t, err) if params != nil { t.Error("Stream should be denied because of capacity cap") } @@ -460,7 +463,7 @@ type authWebhookReq struct { } func TestCreateRTMPStreamHandlerWebhook(t *testing.T) { - assert := assert.New(t) + assert := require.New(t) s, cancel := setupServerWithCancel() defer serverCleanup(s) defer cancel() @@ -469,7 +472,8 @@ func TestCreateRTMPStreamHandlerWebhook(t *testing.T) { AuthWebhookURL = mustParseUrl(t, "http://localhost:8938/notexisting") u := mustParseUrl(t, "http://hot/something/id1") - sid := createSid(u) + sid, err := createSid(u) + assert.Error(err) assert.Nil(sid, "Webhook auth failed") ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { @@ -486,7 +490,8 @@ func TestCreateRTMPStreamHandlerWebhook(t *testing.T) { })) defer ts.Close() AuthWebhookURL = mustParseUrl(t, ts.URL) - sid = createSid(u) + sid, err = createSid(u) + assert.NoError(err) assert.NotNil(sid, "On empty response with 200 code should pass") // local helper to reduce boilerplate @@ -503,19 +508,23 @@ func TestCreateRTMPStreamHandlerWebhook(t *testing.T) { // empty manifestID ts2 := makeServer(`{"manifestID":""}`) defer ts2.Close() - sid = createSid(u) + sid, err = createSid(u) + assert.Error(err) assert.Nil(sid, "Should not pass if returned manifest id is empty") // invalid json ts3 := makeServer(`{manifestID:"XX"}`) defer ts3.Close() - sid = createSid(u) + sid, err = createSid(u) + assert.Error(err) assert.Nil(sid, "Should not pass if returned json is invalid") // set manifestID ts4 := makeServer(`{"manifestID":"xy"}`) defer ts4.Close() - params := createSid(u).(*core.StreamParameters) + p, err := createSid(u) + assert.NoError(err) + params := p.(*core.StreamParameters) mid := params.ManifestID assert.Equal(core.ManifestID("xy"), mid, "Should set manifest id to one provided by webhook") @@ -526,7 +535,9 @@ func TestCreateRTMPStreamHandlerWebhook(t *testing.T) { // set manifestID + streamKey ts5 := makeServer(`{"manifestID":"xyz", "streamKey":"zyx"}`) defer ts5.Close() - params = createSid(u).(*core.StreamParameters) + id, err := createSid(u) + require.NoError(t, err) + params = id.(*core.StreamParameters) mid = params.ManifestID assert.Equal(core.ManifestID("xyz"), mid, "Should set manifest to one provided by webhook") assert.Equal("xyz/zyx", params.StreamID(), "Should set streamkey to one provided by webhook") @@ -535,7 +546,9 @@ func TestCreateRTMPStreamHandlerWebhook(t *testing.T) { // set presets (with some invalid) ts6 := makeServer(`{"manifestID":"a", "presets":["P240p30fps16x9", "unknown", "P720p30fps16x9"]}`) defer ts6.Close() - params = createSid(u).(*core.StreamParameters) + strmID, err := createSid(u) + require.NoError(t, err) + params = strmID.(*core.StreamParameters) assert.Len(params.Profiles, 2) assert.Equal(params.Profiles, []ffmpeg.VideoProfile{ffmpeg.P240p30fps16x9, ffmpeg.P720p30fps16x9}, "Did not have matching presets") @@ -547,7 +560,9 @@ func TestCreateRTMPStreamHandlerWebhook(t *testing.T) { {"name": "passthru_fps", "bitrate": 890, "width": 789, "height": 654, "profile": "H264ConstrainedHigh", "gop":"123"}, {"name": "gop0", "bitrate": 800, "width": 400, "height": 220, "profile": "H264ConstrainedHigh", "gop":"0.0"}]}`) defer ts7.Close() - params = createSid(u).(*core.StreamParameters) + data, err := createSid(u) + require.NoError(t, err) + params = data.(*core.StreamParameters) assert.Len(params.Profiles, 4) expectedProfiles := []ffmpeg.VideoProfile{ @@ -597,7 +612,9 @@ func TestCreateRTMPStreamHandlerWebhook(t *testing.T) { {"name": "prof1", "bitrate": 432, "fps": 560, "width": 123, "height": 456}, {"name": "prof2", "bitrate": 765, "fps": 876, "width": 456, "height": "hello"}]}`) defer ts8.Close() - params, ok := createSid(u).(*core.StreamParameters) + appData, err := createSid(u) + require.Error(t, err) + params, ok := appData.(*core.StreamParameters) assert.False(ok) assert.Nil(params) @@ -609,7 +626,9 @@ func TestCreateRTMPStreamHandlerWebhook(t *testing.T) { {"name": "gop0", "bitrate": 800, "width": 400, "height": 220, "profile": "H264ConstrainedHigh", "gop":"0.0"}]}`) defer ts9.Close() - params = createSid(u).(*core.StreamParameters) + i, err := createSid(u) + require.NoError(t, err) + params = i.(*core.StreamParameters) jointProfiles := append([]ffmpeg.VideoProfile{ffmpeg.P240p30fps16x9, ffmpeg.P720p30fps16x9}, expectedProfiles...) assert.Len(params.Profiles, 6) @@ -618,7 +637,9 @@ func TestCreateRTMPStreamHandlerWebhook(t *testing.T) { // all invalid presets in webhook should lead to empty set ts10 := makeServer(`{"manifestID":"a", "presets":["very", "unknown"]}`) defer ts10.Close() - params = createSid(u).(*core.StreamParameters) + id2, err := createSid(u) + require.NoError(t, err) + params = id2.(*core.StreamParameters) assert.Len(params.Profiles, 0, "Unexpected value in presets") // invalid gops @@ -636,25 +657,31 @@ func TestCreateRTMPStreamHandlerWebhook(t *testing.T) { // intra only gop ts14 := makeServer(`{"manifestID":"a", "profiles": [ {"gop": "intra" }]}`) defer ts14.Close() - params = createSid(u).(*core.StreamParameters) + id3, err := createSid(u) + require.NoError(t, err) + params = id3.(*core.StreamParameters) assert.Len(params.Profiles, 1) assert.Equal(ffmpeg.GOPIntraOnly, params.Profiles[0].GOP) // do not create stream if ObjectStore URL is invalid ts15 := makeServer(`{"manifestID":"a2", "objectStore": "invalid://object.store", "recordObjectStore": ""}`) defer ts15.Close() - sid = createSid(u) + sid, err = createSid(u) + require.Error(t, err) assert.Nil(sid) // do not create stream if RecordObjectStore URL is invalid ts16 := makeServer(`{"manifestID":"a2", "objectStore": "", "recordObjectStore": "invalid://object.store"}`) defer ts16.Close() - sid = createSid(u) + sid, err = createSid(u) + require.Error(t, err) assert.Nil(sid) ts17 := makeServer(`{"manifestID":"a3", "objectStore": "s3+http://us:pass@object.store/path", "recordObjectStore": "s3+http://us:pass@record.store"}`) defer ts17.Close() - params = createSid(u).(*core.StreamParameters) + id4, err := createSid(u) + require.NoError(t, err) + params = id4.(*core.StreamParameters) assert.Equal(core.ManifestID("a3"), params.ManifestID) assert.NotNil(params.OS) assert.True(params.OS.IsExternal()) @@ -689,30 +716,41 @@ func TestCreateRTMPStreamHandler(t *testing.T) { u := mustParseUrl(t, "rtmp://localhost/"+expectedSid.String()) // with key rand.Seed(123) - sid := createSid(u) + sid, err := createSid(u) + require.NoError(t, err) sap := sid.(*core.StreamParameters) assert.Equal(t, uint64(0x4a68998bed5c40f1), sap.Nonce) - if sid := createSid(u); sid.StreamID() != expectedSid.String() { + sid, err = createSid(u) + require.NoError(t, err) + if sid.StreamID() != expectedSid.String() { t.Error("Unexpected streamid", sid.StreamID()) } u = mustParseUrl(t, "rtmp://localhost/stream/"+expectedSid.String()) // with stream - if sid := createSid(u); sid.StreamID() != expectedSid.String() { + sid, err = createSid(u) + require.NoError(t, err) + if sid.StreamID() != expectedSid.String() { t.Error("Unexpected streamid") } expectedMid := "mnopq" key := common.RandomIDGenerator(StreamKeyBytes) u = mustParseUrl(t, "rtmp://localhost/"+string(expectedMid)) // without key - if sid := createSid(u); sid.StreamID() != string(expectedMid)+"/"+key { + sid, err = createSid(u) + require.NoError(t, err) + if sid.StreamID() != string(expectedMid)+"/"+key { t.Error("Unexpected streamid", sid.StreamID()) } u = mustParseUrl(t, "rtmp://localhost/stream/"+string(expectedMid)) // with stream, without key - if sid := createSid(u); sid.StreamID() != string(expectedMid)+"/"+key { + sid, err = createSid(u) + require.NoError(t, err) + if sid.StreamID() != string(expectedMid)+"/"+key { t.Error("Unexpected streamid", sid.StreamID()) } // Test normal case u = mustParseUrl(t, "rtmp://localhost") - st := stream.NewBasicRTMPVideoStream(createSid(u)) + id, err := createSid(u) + require.NoError(t, err) + st := stream.NewBasicRTMPVideoStream(id) if st.GetStreamID() == "" { t.Error("Empty streamid") } @@ -721,14 +759,18 @@ func TestCreateRTMPStreamHandler(t *testing.T) { t.Error("Handler failed ", err) } // Test collisions via stream reuse - if sid := createSid(u); sid == nil { + sid, err = createSid(u) + require.NoError(t, err) + if sid == nil { t.Error("Did not expect a failure due to naming collision") } // Ensure the stream ID is reusable after the stream ends if err := endHandler(u, st); err != nil { t.Error("Could not clean up stream") } - if sid := createSid(u); sid.StreamID() != st.GetStreamID() { + sid, err = createSid(u) + require.NoError(t, err) + if sid.StreamID() != st.GetStreamID() { t.Error("Mismatched streamid during stream reuse", sid.StreamID(), st.GetStreamID()) } @@ -739,7 +781,9 @@ func TestCreateRTMPStreamHandler(t *testing.T) { // This isn't a great test because if the query param ever changes, // this test will still pass u := mustParseUrl(t, "rtmp://localhost/"+inp) - if sid := createSid(u); sid.StreamID() != st.GetStreamID() { + sid, err = createSid(u) + require.NoError(t, err) + if sid.StreamID() != st.GetStreamID() { t.Errorf("Unexpected StreamID for '%v' ; expected '%v' for input '%v'", sid, st.GetStreamID(), inp) } } @@ -804,7 +848,8 @@ func TestCreateRTMPStreamHandlerWithAuthHeader(t *testing.T) { expectedSid := core.MakeStreamIDFromString("override-manifest-id", "abcdef") u := mustParseUrl(t, "rtmp://localhost/"+expectedSid.String()) // with key - sid := createSid(u) + sid, err := createSid(u) + require.NoError(t, err) require.NotNil(t, sid) require.Equal(t, expectedSid.String(), sid.StreamID()) @@ -874,7 +919,8 @@ func TestCreateRTMPStreamHandlerWithAuthHeader_DifferentProfilesToCallbackURL(t expectedSid := core.MakeStreamIDFromString("override-manifest-id", "abcdef") u := mustParseUrl(t, "rtmp://localhost/"+expectedSid.String()) // with key - sid := createSid(u) + sid, err := createSid(u) + require.Error(t, err) require.Nil(t, sid) } @@ -887,7 +933,8 @@ func TestEndRTMPStreamHandler(t *testing.T) { handler := gotRTMPStreamHandler(s) endHandler := endRTMPStreamHandler(s) u := mustParseUrl(t, "rtmp://localhost") - sid := createSid(u) + sid, err := createSid(u) + require.NoError(t, err) st := stream.NewBasicRTMPVideoStream(sid) // Nonexistent stream @@ -998,7 +1045,9 @@ func TestMultiStream(t *testing.T) { createSid := createRTMPStreamIDHandler(context.TODO(), s, nil) handleStream := func(i int) { - st := stream.NewBasicRTMPVideoStream(createSid(u)) + id, err := createSid(u) + require.NoError(t, err) + st := stream.NewBasicRTMPVideoStream(id) if err := handler(u, st); err != nil { t.Error("Could not handle stream ", i, err) } @@ -1229,7 +1278,8 @@ func TestBroadcastSessionManagerWithStreamStartStop(t *testing.T) { // create BasicRTMPVideoStream and extract ManifestID u := mustParseUrl(t, "rtmp://localhost") - sid := createSid(u) + sid, err := createSid(u) + assert.NoError(err) st := stream.NewBasicRTMPVideoStream(sid) mid := streamParams(st.AppData()).ManifestID @@ -1238,8 +1288,8 @@ func TestBroadcastSessionManagerWithStreamStartStop(t *testing.T) { assert.Equal(exists, false) // assert stream starts successfully - err := handler(u, st) - assert.Nil(err) + err = handler(u, st) + assert.NoError(err) // assert sessManager is running and has right number of sessions cxn, exists := s.rtmpConnections[mid] diff --git a/server/push_test.go b/server/push_test.go index b5d0817e0c..bb17ac8a11 100644 --- a/server/push_test.go +++ b/server/push_test.go @@ -1037,7 +1037,7 @@ func TestPush_ForAuthWebhookFailure(t *testing.T) { body, err := ioutil.ReadAll(resp.Body) require.Nil(t, err) - assert.Equal(http.StatusInternalServerError, resp.StatusCode) + assert.Equal(http.StatusForbidden, resp.StatusCode) assert.Contains(strings.TrimSpace(string(body)), "Could not create stream ID") } From 29732e7f879b22070b67879c14c1d815aa863e8c Mon Sep 17 00:00:00 2001 From: Rick Staa Date: Wed, 29 May 2024 16:58:11 +0200 Subject: [PATCH 27/88] ci: fix syntax error in Docker action tags (#3068) * ci: fix syntax error in Docker action tags This commit addresses a syntax error in the Docker image tag creation step. * ci(docker): ensure stable tag is created on master branch This commit ensures that the stable tag is created on the master branch. --- .github/workflows/docker.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker.yaml b/.github/workflows/docker.yaml index 05b64262f1..44dd48fa14 100644 --- a/.github/workflows/docker.yaml +++ b/.github/workflows/docker.yaml @@ -81,7 +81,7 @@ jobs: type=semver,pattern={{major}}.{{minor}},prefix=v type=raw,value=latest,enable={{is_default_branch}} type=raw,value=${{ github.event.pull_request.head.ref }} - type=raw,value=stable,enable=${{ startsWith(github.event.ref, 'refs/tags/v') && is_default_branch }} + type=raw,value=stable,enable=${{ startsWith(github.event.ref, 'refs/tags/v') && github.event.base_ref == 'refs/heads/master' }} - name: Build and push livepeer docker image uses: docker/build-push-action@v5 From e8f079e3af2464e582f93c7786b5aa0ac88944ab Mon Sep 17 00:00:00 2001 From: linghuying <1599935829@qq.com> Date: Sat, 1 Jun 2024 20:09:19 +0800 Subject: [PATCH 28/88] chore: fix some comments (#3070) Signed-off-by: linghuying <1599935829@qq.com> --- cmd/devtool/devtool.go | 2 +- pm/recipient.go | 2 +- pm/sender.go | 2 +- pm/stub.go | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cmd/devtool/devtool.go b/cmd/devtool/devtool.go index e106e30444..ffd696427e 100644 --- a/cmd/devtool/devtool.go +++ b/cmd/devtool/devtool.go @@ -61,7 +61,7 @@ func main() { if !goodToGo { fmt.Println(` Usage: go run cmd/devtool/devtool.go setup broadcaster|transcoder [nodeIndex] - It will create initilize eth account (on private testnet) to be used for broadcaster or transcoder + It will create initialize eth account (on private testnet) to be used for broadcaster or transcoder and will create shell script (run_broadcaster_ETHACC.sh or run_transcoder_ETHACC.sh) to run it. Node index indicates how much to offset node's port. Orchestrator node's index by default is 1. For example: diff --git a/pm/recipient.go b/pm/recipient.go index 1c2333a5bb..4c20281756 100644 --- a/pm/recipient.go +++ b/pm/recipient.go @@ -43,7 +43,7 @@ type Recipient interface { RedeemWinningTicket(ticket *Ticket, sig []byte, seed *big.Int) error // TicketParams returns the recipient's currently accepted ticket parameters - // for a provided sender ETH adddress + // for a provided sender ETH address TicketParams(sender ethcommon.Address, price *big.Rat) (*TicketParams, error) // TxCostMultiplier returns the tx cost multiplier for an address diff --git a/pm/sender.go b/pm/sender.go index db178bfc5b..6f6acf0fd4 100644 --- a/pm/sender.go +++ b/pm/sender.go @@ -113,7 +113,7 @@ func (s *sender) CreateTicketBatch(sessionID string, size int) (*TicketBatch, er ticketParams := &session.ticketParams expirationParams := ticketParams.ExpirationParams - // Ensure backwards compatbility + // Ensure backwards compatibility // If no expirationParams are included by O // B sets the values based upon its last seen round if expirationParams == nil || expirationParams.CreationRound == 0 || expirationParams.CreationRoundBlockHash == (ethcommon.Hash{}) { diff --git a/pm/stub.go b/pm/stub.go index 856bb9416f..a3e0f7f224 100644 --- a/pm/stub.go +++ b/pm/stub.go @@ -466,7 +466,7 @@ func (m *MockRecipient) RedeemWinningTicket(ticket *Ticket, sig []byte, seed *bi } // TicketParams returns the recipient's currently accepted ticket parameters -// for a provided sender ETH adddress +// for a provided sender ETH address func (m *MockRecipient) TicketParams(sender ethcommon.Address, price *big.Rat) (*TicketParams, error) { args := m.Called(sender, price) From 65f501ac541d1b5c0aea9e7258ba75accad538a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Leszko?= Date: Tue, 11 Jun 2024 13:33:25 +0200 Subject: [PATCH 29/88] Add logging to selection_algorithm.go (#3076) * Add logging to selection_algorithm.go * Add even more logging --- server/selection_algorithm.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/selection_algorithm.go b/server/selection_algorithm.go index 54aebb0e65..9264922046 100644 --- a/server/selection_algorithm.go +++ b/server/selection_algorithm.go @@ -49,7 +49,7 @@ func (sa ProbabilitySelectionAlgorithm) filterByPerfScore(addrs []ethcommon.Addr if len(res) == 0 { // If no orchestrators pass the perf filter, return all Orchestrators. // That may mean some issues with the PerfScore service. - glog.Warning("No Orchestrators passed min performance score filter, not using the filter") + glog.Warning("No Orchestrators passed min performance score filter, not using the filter, numAddrs=%d, minPerfScore=%v, scores=%v, addrs=%v", len(addrs), sa.MinPerfScore, scores, addrs) return addrs } return res @@ -72,7 +72,7 @@ func (sa ProbabilitySelectionAlgorithm) filterByMaxPrice(addrs []ethcommon.Addre if len(res) == 0 { // If no orchestrators pass the filter, return all Orchestrators // It means that no orchestrators are below the max price - glog.Warning("No Orchestrators passed max price filter, not using the filter") + glog.Warning("No Orchestrators passed max price filter, not using the filter, numAddrs=%d, maxPrice=%v, prices=%v, addrs=%v", len(addrs), maxPrice, prices, addrs) return addrs } return res From df4c1062f247ef6563ef1f1aea6d6710bf5b5146 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Leszko?= Date: Thu, 13 Jun 2024 09:38:49 +0200 Subject: [PATCH 30/88] Fix typo in logs (#3079) --- server/selection_algorithm.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/selection_algorithm.go b/server/selection_algorithm.go index 9264922046..e5d868c61f 100644 --- a/server/selection_algorithm.go +++ b/server/selection_algorithm.go @@ -49,7 +49,7 @@ func (sa ProbabilitySelectionAlgorithm) filterByPerfScore(addrs []ethcommon.Addr if len(res) == 0 { // If no orchestrators pass the perf filter, return all Orchestrators. // That may mean some issues with the PerfScore service. - glog.Warning("No Orchestrators passed min performance score filter, not using the filter, numAddrs=%d, minPerfScore=%v, scores=%v, addrs=%v", len(addrs), sa.MinPerfScore, scores, addrs) + glog.Warningf("No Orchestrators passed min performance score filter, not using the filter, numAddrs=%d, minPerfScore=%v, scores=%v, addrs=%v", len(addrs), sa.MinPerfScore, scores, addrs) return addrs } return res @@ -72,7 +72,7 @@ func (sa ProbabilitySelectionAlgorithm) filterByMaxPrice(addrs []ethcommon.Addre if len(res) == 0 { // If no orchestrators pass the filter, return all Orchestrators // It means that no orchestrators are below the max price - glog.Warning("No Orchestrators passed max price filter, not using the filter, numAddrs=%d, maxPrice=%v, prices=%v, addrs=%v", len(addrs), maxPrice, prices, addrs) + glog.Warningf("No Orchestrators passed max price filter, not using the filter, numAddrs=%d, maxPrice=%v, prices=%v, addrs=%v", len(addrs), maxPrice, prices, addrs) return addrs } return res From b62c60c11bcbe8486af40e29452c4e45b2bc2bba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Leszko?= Date: Fri, 14 Jun 2024 16:04:29 +0200 Subject: [PATCH 31/88] Add ctx to logging for selection algorithm (#3080) * Add ctx to logging for selection algorithm * Reorg imports * Fix unit tests --- common/types.go | 2 +- server/selection.go | 2 +- server/selection_algorithm.go | 21 +++++++++++---------- server/selection_algorithm_test.go | 3 ++- server/selection_test.go | 2 +- 5 files changed, 16 insertions(+), 14 deletions(-) diff --git a/common/types.go b/common/types.go index 4535e24e36..8dc0845a77 100644 --- a/common/types.go +++ b/common/types.go @@ -105,7 +105,7 @@ type OrchestratorPool interface { } type SelectionAlgorithm interface { - Select(addrs []ethcommon.Address, stakes map[ethcommon.Address]int64, maxPrice *big.Rat, prices map[ethcommon.Address]*big.Rat, perfScores map[ethcommon.Address]float64) ethcommon.Address + 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 } type PerfScore struct { diff --git a/server/selection.go b/server/selection.go index e9b9103247..c827034db6 100644 --- a/server/selection.go +++ b/server/selection.go @@ -202,7 +202,7 @@ func (s *MinLSSelector) selectUnknownSession(ctx context.Context) *BroadcastSess s.perfScore.Mu.Unlock() } - selected := s.selectionAlgorithm.Select(addrs, stakes, maxPrice, prices, perfScores) + selected := s.selectionAlgorithm.Select(ctx, addrs, stakes, maxPrice, prices, perfScores) for i, sess := range s.unknownSessions { if sess.OrchestratorInfo.GetTicketParams() == nil { diff --git a/server/selection_algorithm.go b/server/selection_algorithm.go index e5d868c61f..050b459283 100644 --- a/server/selection_algorithm.go +++ b/server/selection_algorithm.go @@ -1,13 +1,14 @@ package server import ( + "context" "math" "math/big" "math/rand" "time" ethcommon "github.com/ethereum/go-ethereum/common" - "github.com/golang/glog" + "github.com/livepeer/go-livepeer/clog" ) var random = rand.New(rand.NewSource(time.Now().UnixNano())) @@ -22,18 +23,18 @@ type ProbabilitySelectionAlgorithm struct { PriceExpFactor float64 } -func (sa ProbabilitySelectionAlgorithm) Select(addrs []ethcommon.Address, stakes map[ethcommon.Address]int64, maxPrice *big.Rat, prices map[ethcommon.Address]*big.Rat, perfScores map[ethcommon.Address]float64) ethcommon.Address { - filtered := sa.filter(addrs, maxPrice, prices, perfScores) +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 { + filtered := sa.filter(ctx, addrs, maxPrice, prices, perfScores) probabilities := sa.calculateProbabilities(filtered, stakes, prices) return selectBy(probabilities) } -func (sa ProbabilitySelectionAlgorithm) filter(addrs []ethcommon.Address, maxPrice *big.Rat, prices map[ethcommon.Address]*big.Rat, perfScores map[ethcommon.Address]float64) []ethcommon.Address { - filteredByPerfScore := sa.filterByPerfScore(addrs, perfScores) - return sa.filterByMaxPrice(filteredByPerfScore, maxPrice, prices) +func (sa ProbabilitySelectionAlgorithm) filter(ctx context.Context, addrs []ethcommon.Address, maxPrice *big.Rat, prices map[ethcommon.Address]*big.Rat, perfScores map[ethcommon.Address]float64) []ethcommon.Address { + filteredByPerfScore := sa.filterByPerfScore(ctx, addrs, perfScores) + return sa.filterByMaxPrice(ctx, filteredByPerfScore, maxPrice, prices) } -func (sa ProbabilitySelectionAlgorithm) filterByPerfScore(addrs []ethcommon.Address, scores map[ethcommon.Address]float64) []ethcommon.Address { +func (sa ProbabilitySelectionAlgorithm) filterByPerfScore(ctx context.Context, addrs []ethcommon.Address, scores map[ethcommon.Address]float64) []ethcommon.Address { if sa.MinPerfScore <= 0 || len(scores) == 0 { // Performance Score filter not defined, return all Orchestrators return addrs @@ -49,13 +50,13 @@ func (sa ProbabilitySelectionAlgorithm) filterByPerfScore(addrs []ethcommon.Addr if len(res) == 0 { // If no orchestrators pass the perf filter, return all Orchestrators. // That may mean some issues with the PerfScore service. - glog.Warningf("No Orchestrators passed min performance score filter, not using the filter, numAddrs=%d, minPerfScore=%v, scores=%v, addrs=%v", len(addrs), sa.MinPerfScore, scores, addrs) + clog.Warningf(ctx, "No Orchestrators passed min performance score filter, not using the filter, numAddrs=%d, minPerfScore=%v, scores=%v, addrs=%v", len(addrs), sa.MinPerfScore, scores, addrs) return addrs } return res } -func (sa ProbabilitySelectionAlgorithm) filterByMaxPrice(addrs []ethcommon.Address, maxPrice *big.Rat, prices map[ethcommon.Address]*big.Rat) []ethcommon.Address { +func (sa ProbabilitySelectionAlgorithm) filterByMaxPrice(ctx context.Context, addrs []ethcommon.Address, maxPrice *big.Rat, prices map[ethcommon.Address]*big.Rat) []ethcommon.Address { if maxPrice == nil || len(prices) == 0 { // Max price filter not defined, return all Orchestrators return addrs @@ -72,7 +73,7 @@ func (sa ProbabilitySelectionAlgorithm) filterByMaxPrice(addrs []ethcommon.Addre if len(res) == 0 { // If no orchestrators pass the filter, return all Orchestrators // It means that no orchestrators are below the max price - glog.Warningf("No Orchestrators passed max price filter, not using the filter, numAddrs=%d, maxPrice=%v, prices=%v, addrs=%v", len(addrs), maxPrice, prices, addrs) + 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) return addrs } return res diff --git a/server/selection_algorithm_test.go b/server/selection_algorithm_test.go index 85e677a6ba..ffae12de39 100644 --- a/server/selection_algorithm_test.go +++ b/server/selection_algorithm_test.go @@ -1,6 +1,7 @@ package server import ( + "context" "math/big" "testing" @@ -208,7 +209,7 @@ func TestFilter(t *testing.T) { MinPerfScore: tt.orchMinPerfScore, } - res := sa.filter(addrs, maxPrice, prices, perfScores) + res := sa.filter(context.Background(), addrs, maxPrice, prices, perfScores) var exp []ethcommon.Address for _, o := range tt.want { diff --git a/server/selection_test.go b/server/selection_test.go index b7d6958ab3..aa936ddb04 100644 --- a/server/selection_test.go +++ b/server/selection_test.go @@ -91,7 +91,7 @@ func (r *stubStakeReader) SetStakes(stakes map[ethcommon.Address]int64) { type stubSelectionAlgorithm struct{} -func (sa stubSelectionAlgorithm) Select(addrs []ethcommon.Address, stakes map[ethcommon.Address]int64, maxPrice *big.Rat, prices map[ethcommon.Address]*big.Rat, perfScores map[ethcommon.Address]float64) ethcommon.Address { +func (sa stubSelectionAlgorithm) 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 { if len(addrs) == 0 { return ethcommon.Address{} } From 0dd670f0098c456d93d8d8addc9d83f09939c842 Mon Sep 17 00:00:00 2001 From: tongjicoder Date: Mon, 17 Jun 2024 05:57:25 +0900 Subject: [PATCH 32/88] chore: make function comment match function name (#3081) Signed-off-by: tongjicoder --- server/rpc.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/rpc.go b/server/rpc.go index 4f278d06f6..097c61e709 100644 --- a/server/rpc.go +++ b/server/rpc.go @@ -268,7 +268,7 @@ func GetOrchestratorInfo(ctx context.Context, bcast common.Broadcaster, orchestr return r, nil } -// EndSession - the broadcaster calls EndTranscodingSession to tear down sessions used for verification only once +// EndTranscodingSession - the broadcaster calls EndTranscodingSession to tear down sessions used for verification only once func EndTranscodingSession(ctx context.Context, sess *BroadcastSession) error { uri, err := url.Parse(sess.Transcoder()) if err != nil { From 20e81fbba28f8e042827c71162cf7274882295cd Mon Sep 17 00:00:00 2001 From: Rick Staa Date: Tue, 18 Jun 2024 12:41:30 +0200 Subject: [PATCH 33/88] refactor: rename internal references from Broadcaster to Gateway (#3060) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * refactor: rename internal references from Broadcaster to Gateway This commit updates internal references from 'Broadcaster' to 'Gateway' in accordance with the core team’s decision. For more details, refer to the discussion: [Discord Link](https://discord.com/channels/423160867534929930/1051963444598943784/1210356864643109004). * chore: update pending changelog --- CHANGELOG_PENDING.md | 1 + cmd/livepeer/livepeer.go | 2 +- cmd/livepeer/starter/starter.go | 10 +++++----- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/CHANGELOG_PENDING.md b/CHANGELOG_PENDING.md index cd86a5c596..28d9c39c4f 100644 --- a/CHANGELOG_PENDING.md +++ b/CHANGELOG_PENDING.md @@ -5,6 +5,7 @@ - [#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 🚨🚨 diff --git a/cmd/livepeer/livepeer.go b/cmd/livepeer/livepeer.go index 0bf119b7bb..70922549c5 100755 --- a/cmd/livepeer/livepeer.go +++ b/cmd/livepeer/livepeer.go @@ -179,7 +179,7 @@ func parseLivepeerConfig() starter.LivepeerConfig { cfg.PixelsPerUnit = flag.String("pixelsPerUnit", *cfg.PixelsPerUnit, "Amount of pixels per unit. Set to '> 1' to have smaller price granularity than 1 wei / pixel") cfg.PriceFeedAddr = flag.String("priceFeedAddr", *cfg.PriceFeedAddr, "ETH address of the Chainlink price feed contract. Used for custom currencies conversion on -pricePerUnit or -maxPricePerUnit") cfg.AutoAdjustPrice = flag.Bool("autoAdjustPrice", *cfg.AutoAdjustPrice, "Enable/disable automatic price adjustments based on the overhead for redeeming tickets") - cfg.PricePerGateway = flag.String("pricePerGateway", *cfg.PricePerGateway, `json list of price per gateway or path to json config file. Example: {"broadcasters":[{"ethaddress":"address1","priceperunit":0.5,"currency":"USD","pixelsperunit":1000000000000},{"ethaddress":"address2","priceperunit":0.3,"currency":"USD","pixelsperunit":1000000000000}]}`) + cfg.PricePerGateway = flag.String("pricePerGateway", *cfg.PricePerGateway, `json list of price per gateway or path to json config file. Example: {"gateways":[{"ethaddress":"address1","priceperunit":0.5,"currency":"USD","pixelsperunit":1000000000000},{"ethaddress":"address2","priceperunit":0.3,"currency":"USD","pixelsperunit":1000000000000}]}`) cfg.PricePerBroadcaster = flag.String("pricePerBroadcaster", *cfg.PricePerBroadcaster, `json list of price per broadcaster or path to json config file. Example: {"broadcasters":[{"ethaddress":"address1","priceperunit":0.5,"currency":"USD","pixelsperunit":1000000000000},{"ethaddress":"address2","priceperunit":0.3,"currency":"USD","pixelsperunit":1000000000000}]}`) // Interval to poll for blocks cfg.BlockPollingInterval = flag.Int("blockPollingInterval", *cfg.BlockPollingInterval, "Interval in seconds at which different blockchain event services poll for blocks") diff --git a/cmd/livepeer/starter/starter.go b/cmd/livepeer/starter/starter.go index 1053506bda..384d89edf0 100755 --- a/cmd/livepeer/starter/starter.go +++ b/cmd/livepeer/starter/starter.go @@ -791,15 +791,15 @@ func StartLivepeer(ctx context.Context, cfg LivepeerConfig) { glog.Warning("-PricePerBroadcaster flag is deprecated and will be removed in a future release. Please use -PricePerGateway instead") cfg.PricePerGateway = cfg.PricePerBroadcaster } - broadcasterPrices := getGatewayPrices(*cfg.PricePerGateway) - for _, p := range broadcasterPrices { + gatewayPrices := getGatewayPrices(*cfg.PricePerGateway) + for _, p := range gatewayPrices { p := p pricePerPixel := new(big.Rat).Quo(p.PricePerUnit, p.PixelsPerUnit) autoPrice, err := core.NewAutoConvertedPrice(p.Currency, pricePerPixel, func(price *big.Rat) { - glog.Infof("Price: %v wei per pixel for broadcaster %v", price.FloatString(3), p.EthAddress) + glog.Infof("Price: %v wei per pixel for gateway %v", price.FloatString(3), p.EthAddress) }) if err != nil { - panic(fmt.Errorf("Error converting price for broadcaster %s: %v", p.EthAddress, err)) + panic(fmt.Errorf("Error converting price for gateway %s: %v", p.EthAddress, err)) } n.SetBasePrice(p.EthAddress, autoPrice) } @@ -1501,7 +1501,7 @@ func getGatewayPrices(gatewayPrices string) []GatewayPrice { return nil } - // Format of broadcasterPrices json + // Format of gatewayPrices json // {"gateways":[{"ethaddress":"address1","priceperunit":0.5,"currency":"USD","pixelsperunit":1}, {"ethaddress":"address2","priceperunit":0.3,"currency":"USD","pixelsperunit":3}]} var pricesSet struct { Gateways []struct { From 3dcdf3d57d49951276a4132466506256d9a24e23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Leszko?= Date: Fri, 21 Jun 2024 08:52:30 +0200 Subject: [PATCH 34/88] Add logging to the session refresh (#3083) --- server/broadcast.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/server/broadcast.go b/server/broadcast.go index 150d66ea86..bcd0a54658 100755 --- a/server/broadcast.go +++ b/server/broadcast.go @@ -288,7 +288,9 @@ func (sp *SessionPool) selectSessions(ctx context.Context, sessionsNum int) []*B checkSessions := func(m *SessionPool) bool { numSess := m.sel.Size() - if numSess < int(math.Min(maxRefreshSessionsThreshold, math.Ceil(float64(m.numOrchs)/2.0))) { + refreshThreshold := int(math.Min(maxRefreshSessionsThreshold, math.Ceil(float64(m.numOrchs)/2.0))) + clog.Infof(ctx, "Checking if the session refresh is needed, numSess=%v, refreshThreshold=%v", numSess, refreshThreshold) + if numSess < refreshThreshold { go m.refreshSessions(ctx) } return (numSess > 0 || len(sp.lastSess) > 0) From e6a712b130382616c899e8424bdb903393441a02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Leszko?= Date: Mon, 15 Jul 2024 09:19:45 +0200 Subject: [PATCH 35/88] Add `/healthz` endpoint (#3095) --- server/handlers.go | 6 ++++++ server/mediaserver.go | 3 +++ 2 files changed, 9 insertions(+) diff --git a/server/handlers.go b/server/handlers.go index 7514de56ff..22116079e6 100644 --- a/server/handlers.go +++ b/server/handlers.go @@ -29,6 +29,12 @@ import ( const MainnetChainId = 1 const RinkebyChainId = 4 +func (s *LivepeerServer) healthzHandler() http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + respondOk(w, nil) + }) +} + // Status func (s *LivepeerServer) statusHandler() http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { diff --git a/server/mediaserver.go b/server/mediaserver.go index 168686525c..e24bf1edbe 100644 --- a/server/mediaserver.go +++ b/server/mediaserver.go @@ -199,6 +199,9 @@ func (s *LivepeerServer) StartMediaServer(ctx context.Context, httpAddr string) // Store ctx to later use as cancel signal for watchdog goroutine s.context = ctx + // health endpoint + s.HTTPMux.Handle("/healthz", s.healthzHandler()) + //LPMS handlers for handling RTMP video s.LPMS.HandleRTMPPublish(createRTMPStreamIDHandler(ctx, s, nil), gotRTMPStreamHandler(s), endRTMPStreamHandler(s)) s.LPMS.HandleRTMPPlay(getRTMPStreamHandler(s)) From 16246943ccb5ee50b07501c36d7a23391918bd8e Mon Sep 17 00:00:00 2001 From: Josh Allmann Date: Wed, 24 Jul 2024 05:55:52 -0700 Subject: [PATCH 36/88] Update LPMS to ffmpeg 7 (#3096) * install_ffmpeg: point to LPMS * Update to use ffmpeg7 LPMS --- go.mod | 2 +- go.sum | 4 +- install_ffmpeg.sh | 232 +--------------------------------------------- 3 files changed, 5 insertions(+), 233 deletions(-) diff --git a/go.mod b/go.mod index 54396951d9..9347403796 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-20240528070257-343a3ddb3748 + github.com/livepeer/lpms v0.0.0-20240711034524-d9c78b62effd 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 866e8b20bc..92db740f3b 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-20240528070257-343a3ddb3748 h1:sucdljv+Wjo24WbuHYNFFzjRFsKlSj/s9bn7qdCkG/Y= -github.com/livepeer/lpms v0.0.0-20240528070257-343a3ddb3748/go.mod h1:z5ROP1l5OzAKSoqVRLc34MjUdueil6wHSecQYV7llIw= +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/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/install_ffmpeg.sh b/install_ffmpeg.sh index af66bd0b88..fdc111f8b0 100755 --- a/install_ffmpeg.sh +++ b/install_ffmpeg.sh @@ -1,231 +1,3 @@ #!/usr/bin/env bash - -set -exuo pipefail - -ROOT="${1:-$HOME}" -NPROC=${NPROC:-$(nproc)} -EXTRA_CFLAGS="" -EXTRA_LDFLAGS="" -EXTRA_X264_FLAGS="" -EXTRA_FFMPEG_FLAGS="" -BUILD_TAGS="${BUILD_TAGS:-}" - -# Build platform flags -BUILDOS=$(uname -s | tr '[:upper:]' '[:lower:]') -BUILDARCH=$(uname -m | tr '[:upper:]' '[:lower:]') -if [[ $BUILDARCH == "aarch64" ]]; then - BUILDARCH=arm64 -fi -if [[ $BUILDARCH == "x86_64" ]]; then - BUILDARCH=amd64 -fi - -# Override these for cross-compilation -export GOOS="${GOOS:-$BUILDOS}" -export GOARCH="${GOARCH:-$BUILDARCH}" - -echo "BUILDOS: $BUILDOS" -echo "BUILDARCH: $BUILDARCH" -echo "GOOS: $GOOS" -echo "GOARCH: $GOARCH" - -function check_sysroot() { - if ! stat $SYSROOT > /dev/null; then - echo "cross-compilation sysroot not found at $SYSROOT, try setting SYSROOT to the correct path" - exit 1 - fi -} - -if [[ "$BUILDARCH" == "amd64" && "$BUILDOS" == "linux" && "$GOARCH" == "arm64" && "$GOOS" == "linux" ]]; then - echo "cross-compiling linux-amd64 --> linux-arm64" - export CC="clang-14" - export STRIP="llvm-strip-14" - export AR="llvm-ar-14" - export RANLIB="llvm-ranlib-14" - EXTRA_CFLAGS="--target=aarch64-linux-gnu -I/usr/local/cuda_arm64/include $EXTRA_CFLAGS" - EXTRA_LDFLAGS="-fuse-ld=lld --target=aarch64-linux-gnu -L/usr/local/cuda_arm64/lib64 $EXTRA_LDFLAGS" - EXTRA_FFMPEG_FLAGS="$EXTRA_FFMPEG_FLAGS --arch=aarch64 --enable-cross-compile --cc=clang --strip=llvm-strip-14" - HOST_OS="--host=aarch64-linux-gnu" -fi - -if [[ "$BUILDARCH" == "arm64" && "$BUILDOS" == "darwin" && "$GOARCH" == "arm64" && "$GOOS" == "linux" ]]; then - SYSROOT="${SYSROOT:-"/tmp/sysroot-aarch64-linux-gnu"}" - check_sysroot - echo "cross-compiling darwin-arm64 --> linux-arm64" - LLVM_PATH="${LLVM_PATH:-/opt/homebrew/opt/llvm/bin}" - if [[ ! -f "$LLVM_PATH/ld.lld" ]]; then - echo "llvm linker not found at '$LLVM_PATH/ld.lld'. try 'brew install llvm' or set LLVM_PATH to your LLVM bin directory" - exit 1 - fi - export CC="$LLVM_PATH/clang --sysroot=$SYSROOT" - export AR="/opt/homebrew/opt/llvm/bin/llvm-ar" - export RANLIB="/opt/homebrew/opt/llvm/bin/llvm-ranlib" - EXTRA_CFLAGS="--target=aarch64-linux-gnu $EXTRA_CFLAGS" - EXTRA_LDFLAGS="--target=aarch64-linux-gnu -fuse-ld=$LLVM_PATH/ld.lld $EXTRA_LDFLAGS" - EXTRA_FFMPEG_FLAGS="$EXTRA_FFMPEG_FLAGS --arch=aarch64 --enable-cross-compile --cc=$LLVM_PATH/clang --sysroot=$SYSROOT --ar=$AR --ranlib=$RANLIB --target-os=linux" - EXTRA_X264_FLAGS="$EXTRA_X264_FLAGS --sysroot=$SYSROOT --ar=$AR --ranlib=$RANLIB" - HOST_OS="--host=aarch64-linux-gnu" -fi - -if [[ "$BUILDOS" == "linux" && "$GOARCH" == "amd64" && "$GOOS" == "windows" ]]; then - echo "cross-compiling linux-$BUILDARCH --> windows-amd64" - SYSROOT="${SYSROOT:-"/usr/x86_64-w64-mingw32"}" - check_sysroot - EXTRA_CFLAGS="-L$SYSROOT/lib -I$SYSROOT/include $EXTRA_CFLAGS" - EXTRA_LDFLAGS="-L$SYSROOT/lib $EXTRA_LDFLAGS" - EXTRA_FFMPEG_FLAGS="$EXTRA_FFMPEG_FLAGS --arch=x86_64 --enable-cross-compile --cross-prefix=x86_64-w64-mingw32- --target-os=mingw64 --sysroot=$SYSROOT" - EXTRA_X264_FLAGS="$EXTRA_X264_FLAGS --cross-prefix=x86_64-w64-mingw32- --sysroot=$SYSROOT" - HOST_OS="--host=mingw64" - # Workaround for https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=967969 - export PKG_CONFIG_LIBDIR="/usr/local/x86_64-w64-mingw32/lib/pkgconfig" - EXTRA_FFMPEG_FLAGS="$EXTRA_FFMPEG_FLAGS --pkg-config=$(which pkg-config)" -fi - -if [[ "$BUILDARCH" == "amd64" && "$BUILDOS" == "darwin" && "$GOARCH" == "arm64" && "$GOOS" == "darwin" ]]; then - echo "cross-compiling darwin-amd64 --> darwin-arm64" - EXTRA_CFLAGS="$EXTRA_CFLAGS --target=arm64-apple-macos11" - EXTRA_LDFLAGS="$EXTRA_LDFLAGS --target=arm64-apple-macos11" - HOST_OS="--host=aarch64-darwin" - EXTRA_FFMPEG_FLAGS="$EXTRA_FFMPEG_FLAGS --arch=aarch64 --enable-cross-compile" -fi - -# Windows (MSYS2) needs a few tweaks -if [[ "$BUILDOS" == *"MSYS"* ]]; then - ROOT="/build" - export PATH="$PATH:/usr/bin:/mingw64/bin" - export C_INCLUDE_PATH="${C_INCLUDE_PATH:-}:/mingw64/lib" - - export PATH="$ROOT/compiled/bin":$PATH - export PKG_CONFIG_PATH=/mingw64/lib/pkgconfig - - export TARGET_OS="--target-os=mingw64" - export HOST_OS="--host=x86_64-w64-mingw32" - export BUILD_OS="--build=x86_64-w64-mingw32 --host=x86_64-w64-mingw32 --target=x86_64-w64-mingw32" - - # Needed for mbedtls - export WINDOWS_BUILD=1 -fi - -export PATH="$ROOT/compiled/bin:${PATH}" -export PKG_CONFIG_PATH="${PKG_CONFIG_PATH:-}:$ROOT/compiled/lib/pkgconfig" - -mkdir -p "$ROOT/" - -# NVENC only works on Windows/Linux -if [[ "$GOOS" != "darwin" ]]; then - if [[ ! -e "$ROOT/nv-codec-headers" ]]; then - git clone https://git.videolan.org/git/ffmpeg/nv-codec-headers.git "$ROOT/nv-codec-headers" - cd $ROOT/nv-codec-headers - git checkout n9.1.23.1 - make -e PREFIX="$ROOT/compiled" - make install -e PREFIX="$ROOT/compiled" - fi -fi - -if [[ "$GOOS" != "windows" && "$GOARCH" == "amd64" ]]; then - if [[ ! -e "$ROOT/nasm-2.14.02" ]]; then - # sudo apt-get -y install asciidoc xmlto # this fails :( - cd "$ROOT" - curl -o nasm-2.14.02.tar.gz https://www.nasm.us/pub/nasm/releasebuilds/2.14.02/nasm-2.14.02.tar.gz - echo 'b34bae344a3f2ed93b2ca7bf25f1ed3fb12da89eeda6096e3551fd66adeae9fc nasm-2.14.02.tar.gz' >nasm-2.14.02.tar.gz.sha256 - sha256sum -c nasm-2.14.02.tar.gz.sha256 - tar xf nasm-2.14.02.tar.gz - rm nasm-2.14.02.tar.gz nasm-2.14.02.tar.gz.sha256 - cd "$ROOT/nasm-2.14.02" - ./configure --prefix="$ROOT/compiled" - make -j$NPROC - make -j$NPROC install || echo "Installing docs fails but should be OK otherwise" - fi -fi - -if [[ ! -e "$ROOT/x264" ]]; then - git clone http://git.videolan.org/git/x264.git "$ROOT/x264" - cd "$ROOT/x264" - if [[ $GOARCH == "arm64" ]]; then - # newer git master, compiles on Apple Silicon - git checkout 66a5bc1bd1563d8227d5d18440b525a09bcf17ca - else - # older git master, does not compile on Apple Silicon - git checkout 545de2ffec6ae9a80738de1b2c8cf820249a2530 - fi - ./configure --prefix="$ROOT/compiled" --enable-pic --enable-static ${HOST_OS:-} --disable-cli --extra-cflags="$EXTRA_CFLAGS" --extra-asflags="$EXTRA_CFLAGS" --extra-ldflags="$EXTRA_LDFLAGS" $EXTRA_X264_FLAGS || (cat $ROOT/x264/config.log && exit 1) - make -j$NPROC - make -j$NPROC install-lib-static -fi - -if [[ "$GOOS" == "linux" && "$BUILD_TAGS" == *"debug-video"* ]]; then - sudo apt-get install -y libnuma-dev cmake - if [[ ! -e "$ROOT/x265" ]]; then - git clone https://bitbucket.org/multicoreware/x265_git.git "$ROOT/x265" - cd "$ROOT/x265" - git checkout 17839cc0dc5a389e27810944ae2128a65ac39318 - cd build/linux/ - cmake -DCMAKE_INSTALL_PREFIX=$ROOT/compiled -G "Unix Makefiles" ../../source - make -j$NPROC - make -j$NPROC install - fi - # VP8/9 support - if [[ ! -e "$ROOT/libvpx" ]]; then - git clone https://chromium.googlesource.com/webm/libvpx.git "$ROOT/libvpx" - cd "$ROOT/libvpx" - git checkout ab35ee100a38347433af24df05a5e1578172a2ae - ./configure --prefix="$ROOT/compiled" --disable-examples --disable-unit-tests --enable-vp9-highbitdepth --enable-shared --as=nasm - make -j$NPROC - make -j$NPROC install - fi -fi - -DISABLE_FFMPEG_COMPONENTS="" -EXTRA_FFMPEG_LDFLAGS="$EXTRA_LDFLAGS" -# all flags which should be present for production build, but should be replaced/removed for debug build -DEV_FFMPEG_FLAGS="" - -if [[ "$BUILDOS" == "darwin" && "$GOOS" == "darwin" ]]; then - EXTRA_FFMPEG_LDFLAGS="$EXTRA_FFMPEG_LDFLAGS -framework CoreFoundation -framework Security" -elif [[ "$GOOS" == "windows" ]]; then - EXTRA_FFMPEG_FLAGS="$EXTRA_FFMPEG_FLAGS --enable-cuda --enable-cuda-llvm --enable-cuvid --enable-nvenc --enable-decoder=h264_cuvid,hevc_cuvid,vp8_cuvid,vp9_cuvid --enable-filter=scale_cuda,signature_cuda,hwupload_cuda --enable-encoder=h264_nvenc,hevc_nvenc" -elif [[ -e "/usr/local/cuda/lib64" ]]; then - echo "CUDA SDK detected, building with GPU support" - EXTRA_FFMPEG_FLAGS="$EXTRA_FFMPEG_FLAGS --enable-nonfree --enable-cuda-nvcc --enable-libnpp --enable-cuda --enable-cuda-llvm --enable-cuvid --enable-nvenc --enable-decoder=h264_cuvid,hevc_cuvid,vp8_cuvid,vp9_cuvid --enable-filter=scale_npp,signature_cuda,hwupload_cuda --enable-encoder=h264_nvenc,hevc_nvenc" -else - echo "No CUDA SDK detected, building without GPU support" -fi - -if [[ $BUILD_TAGS == *"debug-video"* ]]; then - echo "video debug mode, building ffmpeg with tools, debug info and additional capabilities for running tests" - DEV_FFMPEG_FLAGS="--enable-muxer=md5,flv --enable-demuxer=hls --enable-filter=ssim,tinterlace --enable-encoder=wrapped_avframe,pcm_s16le " - DEV_FFMPEG_FLAGS+="--enable-shared --enable-debug=3 --disable-stripping --disable-optimizations --enable-encoder=libx265,libvpx_vp8,libvpx_vp9 " - DEV_FFMPEG_FLAGS+="--enable-decoder=hevc,libvpx_vp8,libvpx_vp9 --enable-libx265 --enable-libvpx --enable-bsf=noise " -else - # disable all unnecessary features for production build - DISABLE_FFMPEG_COMPONENTS+=" --disable-doc --disable-sdl2 --disable-iconv --disable-muxers --disable-demuxers --disable-parsers --disable-protocols " - DISABLE_FFMPEG_COMPONENTS+=" --disable-encoders --disable-decoders --disable-filters --disable-bsfs --disable-postproc --disable-lzma " -fi - -if [[ ! -e "$ROOT/ffmpeg/libavcodec/libavcodec.a" ]]; then - git clone https://github.com/livepeer/FFmpeg.git "$ROOT/ffmpeg" || echo "FFmpeg dir already exists" - cd "$ROOT/ffmpeg" - git checkout 2e18d069668c143f3c251067abd25389e411d022 - ./configure ${TARGET_OS:-} $DISABLE_FFMPEG_COMPONENTS --fatal-warnings \ - --enable-libx264 --enable-gpl \ - --enable-protocol=rtmp,file,pipe \ - --enable-muxer=mpegts,hls,segment,mp4,hevc,matroska,webm,null --enable-demuxer=flv,mpegts,mp4,mov,webm,matroska \ - --enable-bsf=h264_mp4toannexb,aac_adtstoasc,h264_metadata,h264_redundant_pps,hevc_mp4toannexb,extract_extradata \ - --enable-parser=aac,aac_latm,h264,hevc,vp8,vp9 \ - --enable-filter=abuffer,buffer,abuffersink,buffersink,afifo,fifo,aformat,format \ - --enable-filter=aresample,asetnsamples,fps,scale,hwdownload,select,livepeer_dnn,signature \ - --enable-encoder=aac,opus,libx264 \ - --enable-decoder=aac,opus,h264 \ - --extra-cflags="${EXTRA_CFLAGS} -I${ROOT}/compiled/include -I/usr/local/cuda/include" \ - --extra-ldflags="${EXTRA_FFMPEG_LDFLAGS} -L${ROOT}/compiled/lib -L/usr/local/cuda/lib64" \ - --prefix="$ROOT/compiled" \ - $EXTRA_FFMPEG_FLAGS \ - $DEV_FFMPEG_FLAGS || (tail -100 ${ROOT}/ffmpeg/ffbuild/config.log && exit 1) - # If configure fails, then print the last 100 log lines for debugging and exit. -fi - -if [[ ! -e "$ROOT/ffmpeg/libavcodec/libavcodec.a" || $BUILD_TAGS == *"debug-video"* ]]; then - cd "$ROOT/ffmpeg" - make -j$NPROC - make -j$NPROC install -fi +echo 'WARNING: downloading and executing lpms/install_ffmpeg.sh, use it directly in case of issues' +curl https://raw.githubusercontent.com/livepeer/lpms/d9c78b62effdb4f5c8fc438b6033da1090d04a03/install_ffmpeg.sh | bash -s $1 From a5cdcc6d3719a8e0bd1618c4cfc4cd03f27cc497 Mon Sep 17 00:00:00 2001 From: Josh Allmann Date: Wed, 24 Jul 2024 20:41:38 +0000 Subject: [PATCH 37/88] release v0.7.6 --- CHANGELOG.md | 33 ++++++++++++++++++++++++++++++++- CHANGELOG_PENDING.md | 5 ----- VERSION | 2 +- 3 files changed, 33 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 49545e9b2c..fb3c5d8036 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,36 @@ # Changelog +## v0.7.6 + +- [#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 ⚒ + +#### General + +#### Broadcaster + +#### Orchestrator + +#### Transcoder + +### Bug Fixes 🐞 + +#### CLI + +#### General + +#### Broadcaster + +#### Orchestrator + +#### Transcoder + ## v0.7.5 ### Breaking Changes 🚨🚨 @@ -985,4 +1016,4 @@ Thanks everyone that submitted bug reports and assisted in testing! - [#1775](https://github.com/livepeer/go-livepeer/pull/1775) Fix transcoder load balancer race condition around session cleanup (@jailuthra) - [#1784](https://github.com/livepeer/go-livepeer/pull/1784) Use auth token sessionID to index into sessions map in transcoder load balancer (@jailuthra) -[Full list of changes](https://github.com/livepeer/go-livepeer/compare/v0.5.14...v0.5.15) +[Full list of changes](https://github.com/livepeer/go-livepeer/compare/v0.5.14...v0.5.15) \ No newline at end of file diff --git a/CHANGELOG_PENDING.md b/CHANGELOG_PENDING.md index 28d9c39c4f..3ca5044811 100644 --- a/CHANGELOG_PENDING.md +++ b/CHANGELOG_PENDING.md @@ -2,11 +2,6 @@ ## vX.X -- [#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 ⚒ diff --git a/VERSION b/VERSION index da2ac9c7e6..4d01880a7f 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.7.5 \ No newline at end of file +0.7.6 \ No newline at end of file From 21f98a504590a06009c429621ccb81c718b4d368 Mon Sep 17 00:00:00 2001 From: Rick Staa Date: Sat, 27 Jul 2024 11:31:26 +0200 Subject: [PATCH 38/88] chore(ai): ensure ai-video-rebased ffmpeg file is used Since the lpms `ai-video` and `ai-video-rebase-main` branches are not yet merged into the main branch we need to ensure the right AI install_ffmpeg.sh script is used. --- install_ffmpeg.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install_ffmpeg.sh b/install_ffmpeg.sh index fdc111f8b0..3de15fdc17 100755 --- a/install_ffmpeg.sh +++ b/install_ffmpeg.sh @@ -1,3 +1,3 @@ #!/usr/bin/env bash echo 'WARNING: downloading and executing lpms/install_ffmpeg.sh, use it directly in case of issues' -curl https://raw.githubusercontent.com/livepeer/lpms/d9c78b62effdb4f5c8fc438b6033da1090d04a03/install_ffmpeg.sh | bash -s $1 +curl https://raw.githubusercontent.com/livepeer/lpms/5b7b9f5e831f041c6cf707bbaad7b5503c2f138d/install_ffmpeg.sh | bash -s $1 From 280b4a54a9bee530e490b2b9ee73f063c83b09ee Mon Sep 17 00:00:00 2001 From: Rick Staa Date: Sat, 27 Jul 2024 11:35:29 +0200 Subject: [PATCH 39/88] chore(ai): remove local go module dependency This commit removes the local go module dependency to lpms that was accidentally commited. --- go.mod | 2 -- 1 file changed, 2 deletions(-) diff --git a/go.mod b/go.mod index 082f4b50ac..16051cab5a 100644 --- a/go.mod +++ b/go.mod @@ -240,5 +240,3 @@ require ( lukechampine.com/blake3 v1.2.1 // indirect rsc.io/tmplfunc v0.0.3 // indirect ) - -replace github.com/livepeer/lpms => /home/ricks/development/work/livepeer/ai_spe/lpms From 01fc75be2d91dd40e91ba9c41c29d07123b72a0f Mon Sep 17 00:00:00 2001 From: Rick Staa Date: Mon, 29 Jul 2024 14:42:07 +0200 Subject: [PATCH 40/88] test: fix broadcast test This commit fixes the bugs that were introduced by the AI codebas einto the broadcast test functions. --- server/broadcast_test.go | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/server/broadcast_test.go b/server/broadcast_test.go index 669ff06313..c219a192b2 100644 --- a/server/broadcast_test.go +++ b/server/broadcast_test.go @@ -182,7 +182,10 @@ type stubOSSession struct { err error } -func (s *stubOSSession) SaveData(ctx context.Context, name string, data io.Reader, meta map[string]string, timeout time.Duration) (string, error) { +func (s *stubOSSession) OS() drivers.OSDriver { + return nil +} +func (s *stubOSSession) SaveData(ctx context.Context, name string, data io.Reader, meta *drivers.FileProperties, timeout time.Duration) (string, error) { s.saved = append(s.saved, name) return "saved_" + name, s.err } @@ -200,11 +203,17 @@ func (s *stubOSSession) IsOwn(url string) bool { func (s *stubOSSession) ListFiles(ctx context.Context, prefix, delim string) (drivers.PageInfo, error) { return nil, nil } +func (os *stubOSSession) DeleteFile(ctx context.Context, name string) error { + return nil +} func (s *stubOSSession) ReadData(ctx context.Context, name string) (*drivers.FileInfoReader, error) { return nil, nil } -func (s *stubOSSession) OS() drivers.OSDriver { - return nil +func (os *stubOSSession) ReadDataRange(ctx context.Context, name, byteRange string) (*drivers.FileInfoReader, error) { + return nil, nil +} +func (os *stubOSSession) Presign(name string, expire time.Duration) (string, error) { + return "", nil } type stubPlaylistManager struct { @@ -385,7 +394,7 @@ func TestSelectSession_MultipleInFlight2(t *testing.T) { defer func() { getOrchestratorInfoRPC = oldGetOrchestratorInfoRPC }() orchInfoCalled := 0 - getOrchestratorInfoRPC = func(ctx context.Context, bcast common.Broadcaster, orchestratorServer *url.URL) (*net.OrchestratorInfo, error) { + getOrchestratorInfoRPC = func(ctx context.Context, bcast common.Broadcaster, orchestratorServer *url.URL, caps *net.Capabilities) (*net.OrchestratorInfo, error) { orchInfoCalled++ return successOrchInfoUpdate, nil } @@ -604,7 +613,7 @@ func TestTranscodeSegment_RefreshSession(t *testing.T) { oldGetOrchestratorInfoRPC := getOrchestratorInfoRPC defer func() { getOrchestratorInfoRPC = oldGetOrchestratorInfoRPC }() - getOrchestratorInfoRPC = func(ctx context.Context, bcast common.Broadcaster, orchestratorServer *url.URL) (*net.OrchestratorInfo, error) { + getOrchestratorInfoRPC = func(ctx context.Context, bcast common.Broadcaster, orchestratorServer *url.URL, caps *net.Capabilities) (*net.OrchestratorInfo, error) { return successOrchInfoUpdate, nil } @@ -1503,7 +1512,7 @@ func TestRefreshSession(t *testing.T) { assert.Contains(err.Error(), "invalid control character in URL") // trigger getOrchestratorInfo error - getOrchestratorInfoRPC = func(ctx context.Context, bcast common.Broadcaster, orchestratorServer *url.URL) (*net.OrchestratorInfo, error) { + getOrchestratorInfoRPC = func(ctx context.Context, bcast common.Broadcaster, orchestratorServer *url.URL, caps *net.Capabilities) (*net.OrchestratorInfo, error) { return nil, errors.New("some error") } sess = StubBroadcastSession("foo") @@ -1511,7 +1520,7 @@ func TestRefreshSession(t *testing.T) { assert.EqualError(err, "some error") // trigger update - getOrchestratorInfoRPC = func(ctx context.Context, bcast common.Broadcaster, orchestratorServer *url.URL) (*net.OrchestratorInfo, error) { + getOrchestratorInfoRPC = func(ctx context.Context, bcast common.Broadcaster, orchestratorServer *url.URL, caps *net.Capabilities) (*net.OrchestratorInfo, error) { return successOrchInfoUpdate, nil } err = refreshSession(context.TODO(), sess) @@ -1522,7 +1531,7 @@ func TestRefreshSession(t *testing.T) { oldRefreshTimeout := refreshTimeout defer func() { refreshTimeout = oldRefreshTimeout }() refreshTimeout = 10 * time.Millisecond - getOrchestratorInfoRPC = func(ctx context.Context, bcast common.Broadcaster, serv *url.URL) (*net.OrchestratorInfo, error) { + getOrchestratorInfoRPC = func(ctx context.Context, bcast common.Broadcaster, serv *url.URL, caps *net.Capabilities) (*net.OrchestratorInfo, error) { // Wait until the refreshTimeout has elapsed select { case <-ctx.Done(): From 6292df161f1c719e42eab42af152b0b748b32a1a Mon Sep 17 00:00:00 2001 From: Rick Staa Date: Mon, 29 Jul 2024 16:29:40 +0200 Subject: [PATCH 41/88] feat(ai): add dynamic pricePerUnit feature to AI pricing This commit ensures that Orchestrators can set their pricing in USD and the price gets updated dynamically. --- cmd/livepeer/starter/starter.go | 321 +++---- core/ai.go | 33 +- core/capabilities.go | 4 +- core/capabilities_test.go | 21 +- core/livepeernode.go | 16 +- core/livepeernode_test.go | 26 + ..._RoundTrip_Net-20240729130524-3824236.fail | 828 ++++++++++++++++++ go.mod | 2 + 8 files changed, 1084 insertions(+), 167 deletions(-) create mode 100644 core/testdata/rapid/TestCapability_RoundTrip_Net/TestCapability_RoundTrip_Net-20240729130524-3824236.fail diff --git a/cmd/livepeer/starter/starter.go b/cmd/livepeer/starter/starter.go index 29c08d246b..6f9a11e0ec 100755 --- a/cmd/livepeer/starter/starter.go +++ b/cmd/livepeer/starter/starter.go @@ -515,152 +515,6 @@ func StartLivepeer(ctx context.Context, cfg LivepeerConfig) { } } - var aiCaps []core.Capability - capabilityConstraints := make(map[core.Capability]*core.PerCapabilityConstraints) - - if *cfg.AIWorker { - gpus := []string{} - if *cfg.Nvidia != "" { - var err error - gpus, err = common.ParseAccelDevices(*cfg.Nvidia, ffmpeg.Nvidia) - if err != nil { - glog.Errorf("Error parsing -nvidia for devices: %v", err) - return - } - } - - modelsDir := *cfg.AIModelsDir - if modelsDir == "" { - var err error - modelsDir, err = filepath.Abs(path.Join(*cfg.Datadir, "models")) - if err != nil { - glog.Error("Error creating absolute path for models dir: %v", modelsDir) - return - } - } - - if err := os.MkdirAll(modelsDir, 0755); err != nil { - glog.Error("Error creating models dir %v", modelsDir) - return - } - - n.AIWorker, err = worker.NewWorker(*cfg.AIRunnerImage, gpus, modelsDir) - if err != nil { - glog.Errorf("Error starting AI worker: %v", err) - return - } - - if *cfg.AIModels != "" { - configs, err := core.ParseAIModelConfigs(*cfg.AIModels) - if err != nil { - glog.Errorf("Error parsing -aiModels: %v", err) - return - } - - for _, config := range configs { - modelConstraint := &core.ModelConstraint{Warm: config.Warm} - - // If the config contains a URL we call Warm() anyway because AIWorker will just register - // the endpoint for an external container - if config.Warm || config.URL != "" { - endpoint := worker.RunnerEndpoint{URL: config.URL, Token: config.Token} - if err := n.AIWorker.Warm(ctx, config.Pipeline, config.ModelID, endpoint, config.OptimizationFlags); err != nil { - glog.Errorf("Error AI worker warming %v container: %v", config.Pipeline, err) - return - } - } - - // Show warning if people set OptimizationFlags but not Warm. - if len(config.OptimizationFlags) > 0 && !config.Warm { - glog.Warningf("Model %v has 'optimization_flags' set without 'warm'. Optimization flags are currently only used for warm containers.", config.ModelID) - } - - switch config.Pipeline { - case "text-to-image": - _, ok := capabilityConstraints[core.Capability_TextToImage] - if !ok { - aiCaps = append(aiCaps, core.Capability_TextToImage) - capabilityConstraints[core.Capability_TextToImage] = &core.PerCapabilityConstraints{ - Models: make(map[string]*core.ModelConstraint), - } - } - - capabilityConstraints[core.Capability_TextToImage].Models[config.ModelID] = modelConstraint - - n.SetBasePriceForCap("default", core.Capability_TextToImage, config.ModelID, big.NewRat(config.PricePerUnit, config.PixelsPerUnit)) - case "image-to-image": - _, ok := capabilityConstraints[core.Capability_ImageToImage] - if !ok { - aiCaps = append(aiCaps, core.Capability_ImageToImage) - capabilityConstraints[core.Capability_ImageToImage] = &core.PerCapabilityConstraints{ - Models: make(map[string]*core.ModelConstraint), - } - } - - capabilityConstraints[core.Capability_ImageToImage].Models[config.ModelID] = modelConstraint - - n.SetBasePriceForCap("default", core.Capability_ImageToImage, config.ModelID, big.NewRat(config.PricePerUnit, config.PixelsPerUnit)) - case "image-to-video": - _, ok := capabilityConstraints[core.Capability_ImageToVideo] - if !ok { - aiCaps = append(aiCaps, core.Capability_ImageToVideo) - capabilityConstraints[core.Capability_ImageToVideo] = &core.PerCapabilityConstraints{ - Models: make(map[string]*core.ModelConstraint), - } - } - - capabilityConstraints[core.Capability_ImageToVideo].Models[config.ModelID] = modelConstraint - - n.SetBasePriceForCap("default", core.Capability_ImageToVideo, config.ModelID, big.NewRat(config.PricePerUnit, config.PixelsPerUnit)) - case "upscale": - _, ok := capabilityConstraints[core.Capability_Upscale] - if !ok { - aiCaps = append(aiCaps, core.Capability_Upscale) - capabilityConstraints[core.Capability_Upscale] = &core.PerCapabilityConstraints{ - Models: make(map[string]*core.ModelConstraint), - } - } - - capabilityConstraints[core.Capability_Upscale].Models[config.ModelID] = modelConstraint - - n.SetBasePriceForCap("default", core.Capability_Upscale, config.ModelID, big.NewRat(config.PricePerUnit, config.PixelsPerUnit)) - case "audio-to-text": - _, ok := capabilityConstraints[core.Capability_AudioToText] - if !ok { - aiCaps = append(aiCaps, core.Capability_AudioToText) - capabilityConstraints[core.Capability_AudioToText] = &core.PerCapabilityConstraints{ - Models: make(map[string]*core.ModelConstraint), - } - } - - capabilityConstraints[core.Capability_AudioToText].Models[config.ModelID] = modelConstraint - - n.SetBasePriceForCap("default", core.Capability_AudioToText, config.ModelID, big.NewRat(config.PricePerUnit, config.PixelsPerUnit)) - } - - if len(aiCaps) > 0 { - capability := aiCaps[len(aiCaps)-1] - price := n.GetBasePriceForCap("default", capability, config.ModelID) - glog.V(6).Infof("Capability %s (ID: %v) advertised with model constraint %s at price %d per %d unit", config.Pipeline, capability, config.ModelID, price.Num(), price.Denom()) - } - } - } else { - glog.Error("The '-aiModels' flag was set, but no model configuration was provided. Please specify the model configuration using the '-aiModels' flag.") - return - } - - defer func() { - ctx, cancel := context.WithTimeout(context.Background(), aiWorkerContainerStopTimeout) - defer cancel() - if err := n.AIWorker.Stop(ctx); err != nil { - glog.Errorf("Error stopping AI worker containers: %v", err) - return - } - - glog.Infof("Stopped AI worker containers") - }() - } - if *cfg.Redeemer { n.NodeType = core.RedeemerNode } else if *cfg.Orchestrator { @@ -718,7 +572,6 @@ func StartLivepeer(ctx context.Context, cfg LivepeerConfig) { glog.Error(err) return } - } else { n.SelectionAlgorithm, err = createSelectionAlgorithm(cfg) if err != nil { @@ -946,7 +799,11 @@ func StartLivepeer(ctx context.Context, cfg LivepeerConfig) { } pricePerPixel := new(big.Rat).Quo(pricePerUnit, pixelsPerUnit) autoPrice, err := core.NewAutoConvertedPrice(currency, pricePerPixel, func(price *big.Rat) { - glog.Infof("Price: %v wei per pixel\n ", price.FloatString(3)) + unit := "pixel" + if *cfg.AIWorker { + unit = "compute unit" + } + glog.Infof("Price: %v wei per %s\n", price.FloatString(3), unit) }) if err != nil { panic(fmt.Errorf("Error converting price: %v", err)) @@ -1201,6 +1058,174 @@ func StartLivepeer(ctx context.Context, cfg LivepeerConfig) { }() } + var aiCaps []core.Capability + capabilityConstraints := make(map[core.Capability]*core.PerCapabilityConstraints) + + if *cfg.AIWorker { + gpus := []string{} + if *cfg.Nvidia != "" { + var err error + gpus, err = common.ParseAccelDevices(*cfg.Nvidia, ffmpeg.Nvidia) + if err != nil { + glog.Errorf("Error parsing -nvidia for devices: %v", err) + return + } + } + + modelsDir := *cfg.AIModelsDir + if modelsDir == "" { + var err error + modelsDir, err = filepath.Abs(path.Join(*cfg.Datadir, "models")) + if err != nil { + glog.Error("Error creating absolute path for models dir: %v", modelsDir) + return + } + } + + if err := os.MkdirAll(modelsDir, 0755); err != nil { + glog.Error("Error creating models dir %v", modelsDir) + return + } + + n.AIWorker, err = worker.NewWorker(*cfg.AIRunnerImage, gpus, modelsDir) + if err != nil { + glog.Errorf("Error starting AI worker: %v", err) + return + } + + if *cfg.AIModels != "" { + configs, err := core.ParseAIModelConfigs(*cfg.AIModels) + if err != nil { + glog.Errorf("Error parsing -aiModels: %v", err) + return + } + + for _, config := range configs { + modelConstraint := &core.ModelConstraint{Warm: config.Warm} + + // Set price per unit base info. + pixelsPerUnit, ok := new(big.Rat).SetString(*cfg.PixelsPerUnit) + if !ok || !pixelsPerUnit.IsInt() { + panic(fmt.Errorf("-pixelsPerUnit must be a valid integer, provided %v", *cfg.PixelsPerUnit)) + } + if pixelsPerUnit.Sign() <= 0 { + // Can't divide by 0 + panic(fmt.Errorf("-pixelsPerUnit must be > 0, provided %v", *cfg.PixelsPerUnit)) + } + pricePerUnit, currency, err := parsePricePerUnit(config.PricePerUnit.String()) + if err != nil { + panic(fmt.Errorf("'pricePerUnit' value specified for model '%v' in pipeline '%v' must be a valid integer with an optional currency, provided %v", config.ModelID, config.Pipeline, config.PricePerUnit)) + } else if pricePerUnit.Sign() < 0 { + panic(fmt.Errorf("'pricePerUnit' value specified for model '%v' in pipeline '%v' must be >= 0, provided %v", config.ModelID, config.Pipeline, config.PricePerUnit)) + } + pricePerPixel := new(big.Rat).Quo(pricePerUnit, pixelsPerUnit) + autoPrice, err := core.NewAutoConvertedPrice(currency, pricePerPixel, nil) + if err != nil { + panic(fmt.Errorf("error converting price: %v", err)) + } + + // If the config contains a URL we call Warm() anyway because AIWorker will just register + // the endpoint for an external container + if config.Warm || config.URL != "" { + endpoint := worker.RunnerEndpoint{URL: config.URL, Token: config.Token} + if err := n.AIWorker.Warm(ctx, config.Pipeline, config.ModelID, endpoint, config.OptimizationFlags); err != nil { + glog.Errorf("Error AI worker warming %v container: %v", config.Pipeline, err) + return + } + } + + // Show warning if people set OptimizationFlags but not Warm. + if len(config.OptimizationFlags) > 0 && !config.Warm { + glog.Warningf("Model %v has 'optimization_flags' set without 'warm'. Optimization flags are currently only used for warm containers.", config.ModelID) + } + + switch config.Pipeline { + case "text-to-image": + _, ok := capabilityConstraints[core.Capability_TextToImage] + if !ok { + aiCaps = append(aiCaps, core.Capability_TextToImage) + capabilityConstraints[core.Capability_TextToImage] = &core.PerCapabilityConstraints{ + Models: make(map[string]*core.ModelConstraint), + } + } + + capabilityConstraints[core.Capability_TextToImage].Models[config.ModelID] = modelConstraint + + n.SetBasePriceForCap("default", core.Capability_TextToImage, config.ModelID, autoPrice) + case "image-to-image": + _, ok := capabilityConstraints[core.Capability_ImageToImage] + if !ok { + aiCaps = append(aiCaps, core.Capability_ImageToImage) + capabilityConstraints[core.Capability_ImageToImage] = &core.PerCapabilityConstraints{ + Models: make(map[string]*core.ModelConstraint), + } + } + + capabilityConstraints[core.Capability_ImageToImage].Models[config.ModelID] = modelConstraint + + n.SetBasePriceForCap("default", core.Capability_ImageToImage, config.ModelID, autoPrice) + case "image-to-video": + _, ok := capabilityConstraints[core.Capability_ImageToVideo] + if !ok { + aiCaps = append(aiCaps, core.Capability_ImageToVideo) + capabilityConstraints[core.Capability_ImageToVideo] = &core.PerCapabilityConstraints{ + Models: make(map[string]*core.ModelConstraint), + } + } + + capabilityConstraints[core.Capability_ImageToVideo].Models[config.ModelID] = modelConstraint + + n.SetBasePriceForCap("default", core.Capability_ImageToVideo, config.ModelID, autoPrice) + case "upscale": + _, ok := capabilityConstraints[core.Capability_Upscale] + if !ok { + aiCaps = append(aiCaps, core.Capability_Upscale) + capabilityConstraints[core.Capability_Upscale] = &core.PerCapabilityConstraints{ + Models: make(map[string]*core.ModelConstraint), + } + } + + capabilityConstraints[core.Capability_Upscale].Models[config.ModelID] = modelConstraint + + n.SetBasePriceForCap("default", core.Capability_Upscale, config.ModelID, autoPrice) + case "audio-to-text": + _, ok := capabilityConstraints[core.Capability_AudioToText] + if !ok { + aiCaps = append(aiCaps, core.Capability_AudioToText) + capabilityConstraints[core.Capability_AudioToText] = &core.PerCapabilityConstraints{ + Models: make(map[string]*core.ModelConstraint), + } + } + + capabilityConstraints[core.Capability_AudioToText].Models[config.ModelID] = modelConstraint + + n.SetBasePriceForCap("default", core.Capability_AudioToText, config.ModelID, autoPrice) + } + + if len(aiCaps) > 0 { + capability := aiCaps[len(aiCaps)-1] + price := n.GetBasePriceForCap("default", capability, config.ModelID) + pricePerUnit := price.Num().Int64() / price.Denom().Int64() + glog.V(6).Infof("Capability %s (ID: %v) advertised with model constraint %s at price %d wei per compute unit", config.Pipeline, capability, config.ModelID, pricePerUnit) + } + } + } else { + glog.Error("The '-aiModels' flag was set, but no model configuration was provided. Please specify the model configuration using the '-aiModels' flag.") + return + } + + defer func() { + ctx, cancel := context.WithTimeout(context.Background(), aiWorkerContainerStopTimeout) + defer cancel() + if err := n.AIWorker.Stop(ctx); err != nil { + glog.Errorf("Error stopping AI worker containers: %v", err) + return + } + + glog.Infof("Stopped AI worker containers") + }() + } + if *cfg.Objectstore != "" { prepared, err := drivers.PrepareOSURL(*cfg.Objectstore) if err != nil { diff --git a/core/ai.go b/core/ai.go index 772712e97c..93966bd418 100644 --- a/core/ai.go +++ b/core/ai.go @@ -4,6 +4,7 @@ import ( "context" "encoding/json" "errors" + "fmt" "os" "regexp" "strconv" @@ -23,14 +24,40 @@ type AI interface { HasCapacity(pipeline, modelID string) bool } +// Custom type to handle both string and int but store as string. +type StringInt string + +// UnmarshalJSON method to handle both string and int. +func (s *StringInt) UnmarshalJSON(data []byte) error { + // Try to unmarshal as int. + var intValue int64 + if err := json.Unmarshal(data, &intValue); err == nil { + *s = StringInt(strconv.FormatInt(intValue, 10)) + return nil + } + + var strValue string + if err := json.Unmarshal(data, &strValue); err == nil { + *s = StringInt(strValue) + return nil + } + + return fmt.Errorf("invalid value for StringInt: %s", data) +} + +// String converts the StringInt type to a string. +func (s StringInt) String() string { + return string(s) +} + type AIModelConfig struct { Pipeline string `json:"pipeline"` ModelID string `json:"model_id"` URL string `json:"url,omitempty"` Token string `json:"token,omitempty"` Warm bool `json:"warm,omitempty"` - PricePerUnit int64 `json:"price_per_unit,omitempty"` - PixelsPerUnit int64 `json:"pixels_per_unit,omitempty"` + PricePerUnit StringInt `json:"price_per_unit,omitempty"` + PixelsPerUnit StringInt `json:"pixels_per_unit,omitempty"` OptimizationFlags worker.OptimizationFlags `json:"optimization_flags,omitempty"` } @@ -39,7 +66,7 @@ func (config *AIModelConfig) UnmarshalJSON(data []byte) error { type AIModelConfigAlias AIModelConfig // Set default values for fields defaultConfig := &AIModelConfigAlias{ - PixelsPerUnit: 1, + PixelsPerUnit: "1", } if err := json.Unmarshal(data, defaultConfig); err != nil { diff --git a/core/capabilities.go b/core/capabilities.go index cfeb84046b..4f4122ec7b 100644 --- a/core/capabilities.go +++ b/core/capabilities.go @@ -479,7 +479,7 @@ func CapabilitiesFromNetCapabilities(caps *net.Capabilities) *Capabilities { capacities: make(map[Capability]int), version: caps.Version, constraints: Constraints{minVersion: caps.Constraints.GetMinVersion()}, - capabilityConstraints: make(map[Capability]*PerCapabilityConstraints), + capabilityConstraints: make(CapabilityConstraints), } if caps.Capacities == nil || len(caps.Capacities) == 0 { // build capacities map if not present (struct received from previous versions) @@ -512,7 +512,7 @@ func CapabilitiesFromNetCapabilities(caps *net.Capabilities) *Capabilities { } func NewCapabilities(caps []Capability, m []Capability) *Capabilities { - c := &Capabilities{capacities: make(map[Capability]int), version: LivepeerVersion} + c := &Capabilities{capacities: make(map[Capability]int), version: LivepeerVersion, capabilityConstraints: make(CapabilityConstraints)} if len(caps) > 0 { c.bitstring = NewCapabilityString(caps) // initialize capacities to 1 by default, mandatory capabilities doesn't have capacities diff --git a/core/capabilities_test.go b/core/capabilities_test.go index b165a3d9ca..f4a9055525 100644 --- a/core/capabilities_test.go +++ b/core/capabilities_test.go @@ -396,26 +396,35 @@ type stubOS struct { storageType int32 } +func (os *stubOS) OS() drivers.OSDriver { + return nil +} +func (os *stubOS) SaveData(context.Context, string, io.Reader, *drivers.FileProperties, time.Duration) (string, error) { + return "", nil +} +func (os *stubOS) EndSession() {} func (os *stubOS) GetInfo() *drivers.OSInfo { if os.storageType == stubOSMagic { return nil } return &drivers.OSInfo{StorageType: drivers.OSInfo_StorageType(os.storageType)} } -func (os *stubOS) EndSession() {} -func (os *stubOS) SaveData(context.Context, string, io.Reader, map[string]string, time.Duration) (string, error) { - return "", nil -} func (os *stubOS) IsExternal() bool { return false } func (os *stubOS) IsOwn(url string) bool { return true } func (os *stubOS) ListFiles(ctx context.Context, prefix, delim string) (drivers.PageInfo, error) { return nil, nil } +func (os *stubOS) DeleteFile(ctx context.Context, name string) error { + return nil +} func (os *stubOS) ReadData(ctx context.Context, name string) (*drivers.FileInfoReader, error) { return nil, nil } -func (os *stubOS) OS() drivers.OSDriver { - return nil +func (os *stubOS) ReadDataRange(ctx context.Context, name, byteRange string) (*drivers.FileInfoReader, error) { + return nil, nil +} +func (os *stubOS) Presign(name string, expire time.Duration) (string, error) { + return "", nil } func TestCapability_StorageToCapability(t *testing.T) { diff --git a/core/livepeernode.go b/core/livepeernode.go index e33c435f65..0d726ce652 100644 --- a/core/livepeernode.go +++ b/core/livepeernode.go @@ -64,20 +64,20 @@ func (t NodeType) String() string { } type CapabilityPriceMenu struct { - modelPrices map[string]*big.Rat + modelPrices map[string]*AutoConvertedPrice } func NewCapabilityPriceMenu() CapabilityPriceMenu { return CapabilityPriceMenu{ - modelPrices: make(map[string]*big.Rat), + modelPrices: make(map[string]*AutoConvertedPrice), } } -func (m CapabilityPriceMenu) SetPriceForModelID(modelID string, price *big.Rat) { +func (m CapabilityPriceMenu) SetPriceForModelID(modelID string, price *AutoConvertedPrice) { m.modelPrices[modelID] = price } -func (m CapabilityPriceMenu) PriceForModelID(modelID string) *big.Rat { +func (m CapabilityPriceMenu) PriceForModelID(modelID string) *AutoConvertedPrice { return m.modelPrices[modelID] } @@ -87,7 +87,7 @@ func NewCapabilityPrices() CapabilityPrices { return make(map[Capability]CapabilityPriceMenu) } -func (cp CapabilityPrices) SetPriceForModelID(cap Capability, modelID string, price *big.Rat) { +func (cp CapabilityPrices) SetPriceForModelID(cap Capability, modelID string, price *AutoConvertedPrice) { menu, ok := cp[cap] if !ok { menu = NewCapabilityPriceMenu() @@ -97,7 +97,7 @@ func (cp CapabilityPrices) SetPriceForModelID(cap Capability, modelID string, pr menu.SetPriceForModelID(modelID, price) } -func (cp CapabilityPrices) PriceForModelID(cap Capability, modelID string) *big.Rat { +func (cp CapabilityPrices) PriceForModelID(cap Capability, modelID string) *AutoConvertedPrice { menu, ok := cp[cap] if !ok { return nil @@ -212,7 +212,7 @@ func (n *LivepeerNode) GetBasePrices() map[string]*big.Rat { return prices } -func (n *LivepeerNode) SetBasePriceForCap(b_eth_addr string, cap Capability, modelID string, price *big.Rat) { +func (n *LivepeerNode) SetBasePriceForCap(b_eth_addr string, cap Capability, modelID string, price *AutoConvertedPrice) { addr := strings.ToLower(b_eth_addr) n.mu.Lock() defer n.mu.Unlock() @@ -236,7 +236,7 @@ func (n *LivepeerNode) GetBasePriceForCap(b_eth_addr string, cap Capability, mod return nil } - return prices.PriceForModelID(cap, modelID) + return prices.PriceForModelID(cap, modelID).Value() } // SetMaxFaceValue sets the faceValue upper limit for tickets received diff --git a/core/livepeernode_test.go b/core/livepeernode_test.go index 230f8dd421..d943086ba4 100644 --- a/core/livepeernode_test.go +++ b/core/livepeernode_test.go @@ -179,3 +179,29 @@ func TestSetAndGetBasePrice(t *testing.T) { assert.Zero(n.GetBasePrices()[addr1].Cmp(price1)) assert.Zero(n.GetBasePrices()[addr2].Cmp(price2)) } + +func TestSetAndGetCapabilityPrices(t *testing.T) { + require := require.New(t) + assert := assert.New(t) + + n, err := NewLivepeerNode(nil, "", nil) + require.Nil(err) + + price := big.NewRat(1, 1) + + n.SetBasePriceForCap("default", Capability_TextToImage, "default", NewFixedPrice(price)) + assert.Zero(n.priceInfoForCaps["default"].PriceForModelID(Capability_TextToImage, "default").Value().Cmp(price)) + assert.Zero(n.GetBasePriceForCap("default", Capability_TextToImage, "default").Cmp(price)) + + addr1 := "0x0000000000000000000000000000000000000000" + addr2 := "0x1000000000000000000000000000000000000000" + price1 := big.NewRat(2, 1) + price2 := big.NewRat(3, 1) + + n.SetBasePriceForCap(addr1, Capability_TextToImage, "default", NewFixedPrice(price1)) + n.SetBasePriceForCap(addr2, Capability_ImageToImage, "default", NewFixedPrice(price2)) + assert.Zero(n.priceInfoForCaps[addr1].PriceForModelID(Capability_TextToImage, "default").Value().Cmp(price1)) + assert.Zero(n.priceInfoForCaps[addr2].PriceForModelID(Capability_ImageToImage, "default").Value().Cmp(price2)) + assert.Zero(n.GetBasePriceForCap(addr1, Capability_TextToImage, "default").Cmp(price1)) + assert.Zero(n.GetBasePriceForCap(addr2, Capability_ImageToImage, "default").Cmp(price2)) +} diff --git a/core/testdata/rapid/TestCapability_RoundTrip_Net/TestCapability_RoundTrip_Net-20240729130524-3824236.fail b/core/testdata/rapid/TestCapability_RoundTrip_Net/TestCapability_RoundTrip_Net-20240729130524-3824236.fail new file mode 100644 index 0000000000..bfa48715a7 --- /dev/null +++ b/core/testdata/rapid/TestCapability_RoundTrip_Net/TestCapability_RoundTrip_Net-20240729130524-3824236.fail @@ -0,0 +1,828 @@ +# 2024/07/29 13:05:24.695037 [TestCapability_RoundTrip_Net] [rapid] draw capLen: 54 +# 2024/07/29 13:05:24.695039 [TestCapability_RoundTrip_Net] [rapid] draw cap: 464 +# 2024/07/29 13:05:24.695040 [TestCapability_RoundTrip_Net] [rapid] draw cap: 1 +# 2024/07/29 13:05:24.695040 [TestCapability_RoundTrip_Net] [rapid] draw cap: 461 +# 2024/07/29 13:05:24.695041 [TestCapability_RoundTrip_Net] [rapid] draw cap: 509 +# 2024/07/29 13:05:24.695041 [TestCapability_RoundTrip_Net] [rapid] draw cap: 429 +# 2024/07/29 13:05:24.695042 [TestCapability_RoundTrip_Net] [rapid] draw cap: 39 +# 2024/07/29 13:05:24.695042 [TestCapability_RoundTrip_Net] [rapid] draw cap: 0 +# 2024/07/29 13:05:24.695043 [TestCapability_RoundTrip_Net] [rapid] draw cap: 9 +# 2024/07/29 13:05:24.695043 [TestCapability_RoundTrip_Net] [rapid] draw cap: 291 +# 2024/07/29 13:05:24.695044 [TestCapability_RoundTrip_Net] [rapid] draw cap: 4 +# 2024/07/29 13:05:24.695045 [TestCapability_RoundTrip_Net] [rapid] draw cap: 1 +# 2024/07/29 13:05:24.695045 [TestCapability_RoundTrip_Net] [rapid] draw cap: 27 +# 2024/07/29 13:05:24.695045 [TestCapability_RoundTrip_Net] [rapid] draw cap: 3 +# 2024/07/29 13:05:24.695046 [TestCapability_RoundTrip_Net] [rapid] draw cap: 214 +# 2024/07/29 13:05:24.695046 [TestCapability_RoundTrip_Net] [rapid] draw cap: 192 +# 2024/07/29 13:05:24.695047 [TestCapability_RoundTrip_Net] [rapid] draw cap: 0 +# 2024/07/29 13:05:24.695047 [TestCapability_RoundTrip_Net] [rapid] draw cap: 484 +# 2024/07/29 13:05:24.695047 [TestCapability_RoundTrip_Net] [rapid] draw cap: 165 +# 2024/07/29 13:05:24.695048 [TestCapability_RoundTrip_Net] [rapid] draw cap: 177 +# 2024/07/29 13:05:24.695049 [TestCapability_RoundTrip_Net] [rapid] draw cap: 213 +# 2024/07/29 13:05:24.695049 [TestCapability_RoundTrip_Net] [rapid] draw cap: 18 +# 2024/07/29 13:05:24.695050 [TestCapability_RoundTrip_Net] [rapid] draw cap: 3 +# 2024/07/29 13:05:24.695050 [TestCapability_RoundTrip_Net] [rapid] draw cap: 9 +# 2024/07/29 13:05:24.695050 [TestCapability_RoundTrip_Net] [rapid] draw cap: 2 +# 2024/07/29 13:05:24.695051 [TestCapability_RoundTrip_Net] [rapid] draw cap: 12 +# 2024/07/29 13:05:24.695051 [TestCapability_RoundTrip_Net] [rapid] draw cap: 1 +# 2024/07/29 13:05:24.695051 [TestCapability_RoundTrip_Net] [rapid] draw cap: 437 +# 2024/07/29 13:05:24.695052 [TestCapability_RoundTrip_Net] [rapid] draw cap: 11 +# 2024/07/29 13:05:24.695052 [TestCapability_RoundTrip_Net] [rapid] draw cap: 39 +# 2024/07/29 13:05:24.695052 [TestCapability_RoundTrip_Net] [rapid] draw cap: 30 +# 2024/07/29 13:05:24.695053 [TestCapability_RoundTrip_Net] [rapid] draw cap: 12 +# 2024/07/29 13:05:24.695053 [TestCapability_RoundTrip_Net] [rapid] draw cap: 325 +# 2024/07/29 13:05:24.695053 [TestCapability_RoundTrip_Net] [rapid] draw cap: 204 +# 2024/07/29 13:05:24.695054 [TestCapability_RoundTrip_Net] [rapid] draw cap: 13 +# 2024/07/29 13:05:24.695054 [TestCapability_RoundTrip_Net] [rapid] draw cap: 403 +# 2024/07/29 13:05:24.695055 [TestCapability_RoundTrip_Net] [rapid] draw cap: 498 +# 2024/07/29 13:05:24.695055 [TestCapability_RoundTrip_Net] [rapid] draw cap: 512 +# 2024/07/29 13:05:24.695056 [TestCapability_RoundTrip_Net] [rapid] draw cap: 3 +# 2024/07/29 13:05:24.695057 [TestCapability_RoundTrip_Net] [rapid] draw cap: 0 +# 2024/07/29 13:05:24.695058 [TestCapability_RoundTrip_Net] [rapid] draw cap: 136 +# 2024/07/29 13:05:24.695058 [TestCapability_RoundTrip_Net] [rapid] draw cap: 2 +# 2024/07/29 13:05:24.695058 [TestCapability_RoundTrip_Net] [rapid] draw cap: 169 +# 2024/07/29 13:05:24.695059 [TestCapability_RoundTrip_Net] [rapid] draw cap: 1 +# 2024/07/29 13:05:24.695059 [TestCapability_RoundTrip_Net] [rapid] draw cap: 62 +# 2024/07/29 13:05:24.695059 [TestCapability_RoundTrip_Net] [rapid] draw cap: 181 +# 2024/07/29 13:05:24.695060 [TestCapability_RoundTrip_Net] [rapid] draw cap: 0 +# 2024/07/29 13:05:24.695060 [TestCapability_RoundTrip_Net] [rapid] draw cap: 6 +# 2024/07/29 13:05:24.695061 [TestCapability_RoundTrip_Net] [rapid] draw cap: 12 +# 2024/07/29 13:05:24.695061 [TestCapability_RoundTrip_Net] [rapid] draw cap: 512 +# 2024/07/29 13:05:24.695062 [TestCapability_RoundTrip_Net] [rapid] draw cap: 177 +# 2024/07/29 13:05:24.695062 [TestCapability_RoundTrip_Net] [rapid] draw cap: 7 +# 2024/07/29 13:05:24.695063 [TestCapability_RoundTrip_Net] [rapid] draw cap: 0 +# 2024/07/29 13:05:24.695064 [TestCapability_RoundTrip_Net] [rapid] draw cap: 0 +# 2024/07/29 13:05:24.695064 [TestCapability_RoundTrip_Net] [rapid] draw cap: 400 +# 2024/07/29 13:05:24.695065 [TestCapability_RoundTrip_Net] [rapid] draw capLen: 42 +# 2024/07/29 13:05:24.695066 [TestCapability_RoundTrip_Net] [rapid] draw cap: 0 +# 2024/07/29 13:05:24.695067 [TestCapability_RoundTrip_Net] [rapid] draw cap: 6 +# 2024/07/29 13:05:24.695068 [TestCapability_RoundTrip_Net] [rapid] draw cap: 368 +# 2024/07/29 13:05:24.695069 [TestCapability_RoundTrip_Net] [rapid] draw cap: 512 +# 2024/07/29 13:05:24.695069 [TestCapability_RoundTrip_Net] [rapid] draw cap: 10 +# 2024/07/29 13:05:24.695070 [TestCapability_RoundTrip_Net] [rapid] draw cap: 235 +# 2024/07/29 13:05:24.695071 [TestCapability_RoundTrip_Net] [rapid] draw cap: 1 +# 2024/07/29 13:05:24.695071 [TestCapability_RoundTrip_Net] [rapid] draw cap: 1 +# 2024/07/29 13:05:24.695071 [TestCapability_RoundTrip_Net] [rapid] draw cap: 3 +# 2024/07/29 13:05:24.695072 [TestCapability_RoundTrip_Net] [rapid] draw cap: 8 +# 2024/07/29 13:05:24.695072 [TestCapability_RoundTrip_Net] [rapid] draw cap: 263 +# 2024/07/29 13:05:24.695072 [TestCapability_RoundTrip_Net] [rapid] draw cap: 1 +# 2024/07/29 13:05:24.695073 [TestCapability_RoundTrip_Net] [rapid] draw cap: 107 +# 2024/07/29 13:05:24.695073 [TestCapability_RoundTrip_Net] [rapid] draw cap: 301 +# 2024/07/29 13:05:24.695074 [TestCapability_RoundTrip_Net] [rapid] draw cap: 13 +# 2024/07/29 13:05:24.695074 [TestCapability_RoundTrip_Net] [rapid] draw cap: 1 +# 2024/07/29 13:05:24.695074 [TestCapability_RoundTrip_Net] [rapid] draw cap: 1 +# 2024/07/29 13:05:24.695075 [TestCapability_RoundTrip_Net] [rapid] draw cap: 11 +# 2024/07/29 13:05:24.695075 [TestCapability_RoundTrip_Net] [rapid] draw cap: 289 +# 2024/07/29 13:05:24.695076 [TestCapability_RoundTrip_Net] [rapid] draw cap: 19 +# 2024/07/29 13:05:24.695076 [TestCapability_RoundTrip_Net] [rapid] draw cap: 68 +# 2024/07/29 13:05:24.695077 [TestCapability_RoundTrip_Net] [rapid] draw cap: 1 +# 2024/07/29 13:05:24.695079 [TestCapability_RoundTrip_Net] [rapid] draw cap: 102 +# 2024/07/29 13:05:24.695079 [TestCapability_RoundTrip_Net] [rapid] draw cap: 10 +# 2024/07/29 13:05:24.695079 [TestCapability_RoundTrip_Net] [rapid] draw cap: 0 +# 2024/07/29 13:05:24.695080 [TestCapability_RoundTrip_Net] [rapid] draw cap: 6 +# 2024/07/29 13:05:24.695080 [TestCapability_RoundTrip_Net] [rapid] draw cap: 1 +# 2024/07/29 13:05:24.695080 [TestCapability_RoundTrip_Net] [rapid] draw cap: 14 +# 2024/07/29 13:05:24.695081 [TestCapability_RoundTrip_Net] [rapid] draw cap: 3 +# 2024/07/29 13:05:24.695081 [TestCapability_RoundTrip_Net] [rapid] draw cap: 15 +# 2024/07/29 13:05:24.695081 [TestCapability_RoundTrip_Net] [rapid] draw cap: 54 +# 2024/07/29 13:05:24.695082 [TestCapability_RoundTrip_Net] [rapid] draw cap: 7 +# 2024/07/29 13:05:24.695082 [TestCapability_RoundTrip_Net] [rapid] draw cap: 94 +# 2024/07/29 13:05:24.695083 [TestCapability_RoundTrip_Net] [rapid] draw cap: 1 +# 2024/07/29 13:05:24.695084 [TestCapability_RoundTrip_Net] [rapid] draw cap: 1 +# 2024/07/29 13:05:24.695084 [TestCapability_RoundTrip_Net] [rapid] draw cap: 5 +# 2024/07/29 13:05:24.695084 [TestCapability_RoundTrip_Net] [rapid] draw cap: 206 +# 2024/07/29 13:05:24.695085 [TestCapability_RoundTrip_Net] [rapid] draw cap: 512 +# 2024/07/29 13:05:24.695085 [TestCapability_RoundTrip_Net] [rapid] draw cap: 2 +# 2024/07/29 13:05:24.695086 [TestCapability_RoundTrip_Net] [rapid] draw cap: 78 +# 2024/07/29 13:05:24.695086 [TestCapability_RoundTrip_Net] [rapid] draw cap: 11 +# 2024/07/29 13:05:24.695086 [TestCapability_RoundTrip_Net] [rapid] draw cap: 457 +# 2024/07/29 13:05:24.695203 [TestCapability_RoundTrip_Net] +# Error Trace: /home/ricks/development/livepeer/ai/go-livepeer/core/capabilities_test.go:371 +# /home/ricks/go/pkg/mod/pgregory.net/rapid@v1.1.0/engine.go:368 +# /home/ricks/go/pkg/mod/pgregory.net/rapid@v1.1.0/engine.go:377 +# /home/ricks/go/pkg/mod/pgregory.net/rapid@v1.1.0/engine.go:203 +# /home/ricks/go/pkg/mod/pgregory.net/rapid@v1.1.0/engine.go:118 +# /home/ricks/development/livepeer/ai/go-livepeer/core/capabilities_test.go:356 +# Error: Not equal: +# expected: &core.Capabilities{bitstring:core.CapabilityString{0x4000008048043adf, 0x0, 0x22022000000100, 0x601001, 0x800000000, 0x20, 0x20200000090000, 0x2004001000012000, 0x1}, mandatories:core.CapabilityString{0x4000000008edef, 0x84040004010, 0x0, 0x80000004000, 0x200200000080, 0x1000000000000, 0x0, 0x200, 0x1}, version:"undefined", constraints:core.Constraints{minVersion:""}, capabilityConstraints:core.CapabilityConstraints(nil), capacities:map[core.Capability]int{0:1, 1:1, 2:1, 3:1, 4:1, 6:1, 7:1, 9:1, 11:1, 12:1, 13:1, 18:1, 27:1, 30:1, 39:1, 62:1, 136:1, 165:1, 169:1, 177:1, 181:1, 192:1, 204:1, 213:1, 214:1, 291:1, 325:1, 400:1, 403:1, 429:1, 437:1, 461:1, 464:1, 484:1, 498:1, 509:1, 512:1}, mutex:sync.Mutex{state:0, sema:0x0}} +# actual : &core.Capabilities{bitstring:core.CapabilityString{0x4000008048043adf, 0x0, 0x22022000000100, 0x601001, 0x800000000, 0x20, 0x20200000090000, 0x2004001000012000, 0x1}, mandatories:core.CapabilityString{0x4000000008edef, 0x84040004010, 0x0, 0x80000004000, 0x200200000080, 0x1000000000000, 0x0, 0x200, 0x1}, version:"undefined", constraints:core.Constraints{minVersion:""}, capabilityConstraints:core.CapabilityConstraints{}, capacities:map[core.Capability]int{0:1, 1:1, 2:1, 3:1, 4:1, 6:1, 7:1, 9:1, 11:1, 12:1, 13:1, 18:1, 27:1, 30:1, 39:1, 62:1, 136:1, 165:1, 169:1, 177:1, 181:1, 192:1, 204:1, 213:1, 214:1, 291:1, 325:1, 400:1, 403:1, 429:1, 437:1, 461:1, 464:1, 484:1, 498:1, 509:1, 512:1}, mutex:sync.Mutex{state:0, sema:0x0}} +# +# Diff: +# --- Expected +# +++ Actual +# @@ -27,3 +27,4 @@ +# }, +# - capabilityConstraints: (core.CapabilityConstraints) , +# + capabilityConstraints: (core.CapabilityConstraints) { +# + }, +# capacities: (map[core.Capability]int) (len=37) { +# Test: TestCapability_RoundTrip_Net +# 2024/07/29 13:05:24.695205 [TestCapability_RoundTrip_Net] [rapid] draw capLen: 0 +# 2024/07/29 13:05:24.695206 [TestCapability_RoundTrip_Net] [rapid] draw capLen: 88 +# 2024/07/29 13:05:24.695207 [TestCapability_RoundTrip_Net] [rapid] draw cap: 4 +# 2024/07/29 13:05:24.695207 [TestCapability_RoundTrip_Net] [rapid] draw cap: 8 +# 2024/07/29 13:05:24.695208 [TestCapability_RoundTrip_Net] [rapid] draw cap: 512 +# 2024/07/29 13:05:24.695208 [TestCapability_RoundTrip_Net] [rapid] draw cap: 0 +# 2024/07/29 13:05:24.695208 [TestCapability_RoundTrip_Net] [rapid] draw cap: 3 +# 2024/07/29 13:05:24.695209 [TestCapability_RoundTrip_Net] [rapid] draw cap: 2 +# 2024/07/29 13:05:24.695210 [TestCapability_RoundTrip_Net] [rapid] draw cap: 1 +# 2024/07/29 13:05:24.695210 [TestCapability_RoundTrip_Net] [rapid] draw cap: 79 +# 2024/07/29 13:05:24.695210 [TestCapability_RoundTrip_Net] [rapid] draw cap: 0 +# 2024/07/29 13:05:24.695211 [TestCapability_RoundTrip_Net] [rapid] draw cap: 0 +# 2024/07/29 13:05:24.695211 [TestCapability_RoundTrip_Net] [rapid] draw cap: 453 +# 2024/07/29 13:05:24.695212 [TestCapability_RoundTrip_Net] [rapid] draw cap: 232 +# 2024/07/29 13:05:24.695212 [TestCapability_RoundTrip_Net] [rapid] draw cap: 8 +# 2024/07/29 13:05:24.695212 [TestCapability_RoundTrip_Net] [rapid] draw cap: 10 +# 2024/07/29 13:05:24.695213 [TestCapability_RoundTrip_Net] [rapid] draw cap: 239 +# 2024/07/29 13:05:24.695214 [TestCapability_RoundTrip_Net] [rapid] draw cap: 20 +# 2024/07/29 13:05:24.695214 [TestCapability_RoundTrip_Net] [rapid] draw cap: 5 +# 2024/07/29 13:05:24.695215 [TestCapability_RoundTrip_Net] [rapid] draw cap: 0 +# 2024/07/29 13:05:24.695216 [TestCapability_RoundTrip_Net] [rapid] draw cap: 0 +# 2024/07/29 13:05:24.695217 [TestCapability_RoundTrip_Net] [rapid] draw cap: 265 +# 2024/07/29 13:05:24.695217 [TestCapability_RoundTrip_Net] [rapid] draw cap: 150 +# 2024/07/29 13:05:24.695218 [TestCapability_RoundTrip_Net] [rapid] draw cap: 2 +# 2024/07/29 13:05:24.695219 [TestCapability_RoundTrip_Net] [rapid] draw cap: 234 +# 2024/07/29 13:05:24.695219 [TestCapability_RoundTrip_Net] [rapid] draw cap: 0 +# 2024/07/29 13:05:24.695223 [TestCapability_RoundTrip_Net] [rapid] draw cap: 0 +# 2024/07/29 13:05:24.695223 [TestCapability_RoundTrip_Net] [rapid] draw cap: 62 +# 2024/07/29 13:05:24.695223 [TestCapability_RoundTrip_Net] [rapid] draw cap: 5 +# 2024/07/29 13:05:24.695224 [TestCapability_RoundTrip_Net] [rapid] draw cap: 512 +# 2024/07/29 13:05:24.695224 [TestCapability_RoundTrip_Net] [rapid] draw cap: 0 +# 2024/07/29 13:05:24.695224 [TestCapability_RoundTrip_Net] [rapid] draw cap: 2 +# 2024/07/29 13:05:24.695225 [TestCapability_RoundTrip_Net] [rapid] draw cap: 17 +# 2024/07/29 13:05:24.695225 [TestCapability_RoundTrip_Net] [rapid] draw cap: 5 +# 2024/07/29 13:05:24.695226 [TestCapability_RoundTrip_Net] [rapid] draw cap: 75 +# 2024/07/29 13:05:24.695226 [TestCapability_RoundTrip_Net] [rapid] draw cap: 310 +# 2024/07/29 13:05:24.695226 [TestCapability_RoundTrip_Net] [rapid] draw cap: 172 +# 2024/07/29 13:05:24.695227 [TestCapability_RoundTrip_Net] [rapid] draw cap: 24 +# 2024/07/29 13:05:24.695227 [TestCapability_RoundTrip_Net] [rapid] draw cap: 88 +# 2024/07/29 13:05:24.695228 [TestCapability_RoundTrip_Net] [rapid] draw cap: 512 +# 2024/07/29 13:05:24.695228 [TestCapability_RoundTrip_Net] [rapid] draw cap: 446 +# 2024/07/29 13:05:24.695228 [TestCapability_RoundTrip_Net] [rapid] draw cap: 7 +# 2024/07/29 13:05:24.695229 [TestCapability_RoundTrip_Net] [rapid] draw cap: 3 +# 2024/07/29 13:05:24.695229 [TestCapability_RoundTrip_Net] [rapid] draw cap: 3 +# 2024/07/29 13:05:24.695229 [TestCapability_RoundTrip_Net] [rapid] draw cap: 114 +# 2024/07/29 13:05:24.695230 [TestCapability_RoundTrip_Net] [rapid] draw cap: 6 +# 2024/07/29 13:05:24.695230 [TestCapability_RoundTrip_Net] [rapid] draw cap: 2 +# 2024/07/29 13:05:24.695230 [TestCapability_RoundTrip_Net] [rapid] draw cap: 426 +# 2024/07/29 13:05:24.695231 [TestCapability_RoundTrip_Net] [rapid] draw cap: 13 +# 2024/07/29 13:05:24.695232 [TestCapability_RoundTrip_Net] [rapid] draw cap: 13 +# 2024/07/29 13:05:24.695232 [TestCapability_RoundTrip_Net] [rapid] draw cap: 6 +# 2024/07/29 13:05:24.695233 [TestCapability_RoundTrip_Net] [rapid] draw cap: 29 +# 2024/07/29 13:05:24.695233 [TestCapability_RoundTrip_Net] [rapid] draw cap: 130 +# 2024/07/29 13:05:24.695233 [TestCapability_RoundTrip_Net] [rapid] draw cap: 15 +# 2024/07/29 13:05:24.695234 [TestCapability_RoundTrip_Net] [rapid] draw cap: 196 +# 2024/07/29 13:05:24.695234 [TestCapability_RoundTrip_Net] [rapid] draw cap: 478 +# 2024/07/29 13:05:24.695234 [TestCapability_RoundTrip_Net] [rapid] draw cap: 0 +# 2024/07/29 13:05:24.695235 [TestCapability_RoundTrip_Net] [rapid] draw cap: 1 +# 2024/07/29 13:05:24.695235 [TestCapability_RoundTrip_Net] [rapid] draw cap: 10 +# 2024/07/29 13:05:24.695236 [TestCapability_RoundTrip_Net] [rapid] draw cap: 3 +# 2024/07/29 13:05:24.695236 [TestCapability_RoundTrip_Net] [rapid] draw cap: 406 +# 2024/07/29 13:05:24.695236 [TestCapability_RoundTrip_Net] [rapid] draw cap: 145 +# 2024/07/29 13:05:24.695237 [TestCapability_RoundTrip_Net] [rapid] draw cap: 241 +# 2024/07/29 13:05:24.695237 [TestCapability_RoundTrip_Net] [rapid] draw cap: 0 +# 2024/07/29 13:05:24.695237 [TestCapability_RoundTrip_Net] [rapid] draw cap: 2 +# 2024/07/29 13:05:24.695238 [TestCapability_RoundTrip_Net] [rapid] draw cap: 5 +# 2024/07/29 13:05:24.695238 [TestCapability_RoundTrip_Net] [rapid] draw cap: 229 +# 2024/07/29 13:05:24.695239 [TestCapability_RoundTrip_Net] [rapid] draw cap: 47 +# 2024/07/29 13:05:24.695239 [TestCapability_RoundTrip_Net] [rapid] draw cap: 512 +# 2024/07/29 13:05:24.695240 [TestCapability_RoundTrip_Net] [rapid] draw cap: 5 +# 2024/07/29 13:05:24.695240 [TestCapability_RoundTrip_Net] [rapid] draw cap: 270 +# 2024/07/29 13:05:24.695241 [TestCapability_RoundTrip_Net] [rapid] draw cap: 148 +# 2024/07/29 13:05:24.695241 [TestCapability_RoundTrip_Net] [rapid] draw cap: 292 +# 2024/07/29 13:05:24.695241 [TestCapability_RoundTrip_Net] [rapid] draw cap: 146 +# 2024/07/29 13:05:24.695242 [TestCapability_RoundTrip_Net] [rapid] draw cap: 411 +# 2024/07/29 13:05:24.695242 [TestCapability_RoundTrip_Net] [rapid] draw cap: 49 +# 2024/07/29 13:05:24.695242 [TestCapability_RoundTrip_Net] [rapid] draw cap: 3 +# 2024/07/29 13:05:24.695243 [TestCapability_RoundTrip_Net] [rapid] draw cap: 132 +# 2024/07/29 13:05:24.695243 [TestCapability_RoundTrip_Net] [rapid] draw cap: 9 +# 2024/07/29 13:05:24.695243 [TestCapability_RoundTrip_Net] [rapid] draw cap: 193 +# 2024/07/29 13:05:24.695244 [TestCapability_RoundTrip_Net] [rapid] draw cap: 510 +# 2024/07/29 13:05:24.695244 [TestCapability_RoundTrip_Net] [rapid] draw cap: 3 +# 2024/07/29 13:05:24.695245 [TestCapability_RoundTrip_Net] [rapid] draw cap: 1 +# 2024/07/29 13:05:24.695245 [TestCapability_RoundTrip_Net] [rapid] draw cap: 22 +# 2024/07/29 13:05:24.695245 [TestCapability_RoundTrip_Net] [rapid] draw cap: 2 +# 2024/07/29 13:05:24.695246 [TestCapability_RoundTrip_Net] [rapid] draw cap: 136 +# 2024/07/29 13:05:24.695246 [TestCapability_RoundTrip_Net] [rapid] draw cap: 408 +# 2024/07/29 13:05:24.695246 [TestCapability_RoundTrip_Net] [rapid] draw cap: 11 +# 2024/07/29 13:05:24.695247 [TestCapability_RoundTrip_Net] [rapid] draw cap: 1 +# 2024/07/29 13:05:24.695247 [TestCapability_RoundTrip_Net] [rapid] draw cap: 1 +# +v0.4.8#8355047278167994326 +0x1ffe553afdc0f7 +0xf45b3a3026fb1 +0x36 +0x19e8d3757890a9 +0x1ece3789377bd6 +0x254 +0x205 +0x1d0 +0xc696ee1730946 +0xa5bfc6000ae4 +0x1 +0x1e767e042e2f9d +0x176d810cfc0f2b +0x267 +0x1cd +0x2a57c0b86b7d2 +0x1e916bccdef442 +0x1fd +0xcf6dc68c6ae6f +0x17398c89c02dec +0x1ad +0x131c5a873b987b +0x157a8063db5cc8 +0x27 +0x1987e962a4ed1 +0x12edc22943d81 +0x0 +0x163376461fd54d +0x9ce4ce56c30ba +0x9 +0x1e5486cb3b6174 +0x16c0f7f21eb8cb +0x123 +0xf0a4d4dd1e518 +0x1ac2347bba71a3 +0x4 +0x169e45fe17b9c4 +0x5c8baba4436ce +0x1 +0x1fa586fec7e96b +0x120720f4f21290 +0x1b +0x4fb6259a712e2 +0x37f35a9300112 +0x3 +0x1935b725e9e96 +0x187a601d1528ca +0xd6 +0x7913ebe9dc13a +0x142e0f585b2dac +0xc0 +0x196f40656a41ec +0x3af286f273a5d +0x0 +0x1a2c3ac100cc8e +0x1a36899482617e +0x3a3 +0x1e4 +0x1b6b16ee1d7b0 +0x1cbffa9417a94e +0xa5 +0x6edec3d67143c +0x127c8c567c73c4 +0xb1 +0x188f8cfc3194f8 +0x15a4da498b416b +0xd5 +0x1ac94151d50f1b +0x1cbdfcfdc9aba8 +0x12 +0x4424d7c0cfd27 +0xc2c679bb08e83 +0x3 +0x13a41a68b5e7b5 +0xe824a9c93fb79 +0x9 +0x104eae942c2d3a +0x8401f4f6add60 +0x2 +0x1a85ae65d696b5 +0xd9a97b75d45a0 +0xc +0x1dcdacf4d1f538 +0x5b79db0b9ce2e +0x1 +0x105690b2cc5155 +0x160e817f276ba9 +0x1b5 +0x1aef64c8f37d26 +0xaf0d1bd20e7f0 +0xb +0x124d67659fe95 +0xef30a4d402397 +0x27 +0xea3815f25e942 +0xd3dd513625b5f +0x1e +0xa34a45d0353c0 +0x181b4b8c96b635 +0x2cf +0x390 +0xc +0x1249d6d7171e3e +0x18466e9bb7d281 +0x3c9 +0x358 +0x145 +0x99299469331c0 +0x1225c985e1f9d7 +0xcc +0x8ae4b0b2d445c +0xa0005e7ee8688 +0xd +0x156193b8049849 +0x1beecbb840472f +0x3c1 +0x318 +0x2ab +0x193 +0x14816d4d091040 +0x1e18e4ad3afb90 +0x312 +0x1f2 +0x16d98afc38a5eb +0x1ffb0857cf3f4e +0xffffffffffffffff +0x63bc8e9d1b67c +0x670439aa47cba +0x3 +0x7d862db5053c3 +0x908d39c551ddc +0x0 +0x1e5beb91ed0b7 +0x11cff49a778ef7 +0x88 +0xc149b27cdeaff +0x5ae64d015a7f1 +0x2 +0x3f1601a4584c9 +0x12b7466721c2e3 +0xa9 +0x141e20558b5b71 +0x1b482d7eb0eab +0x1 +0xfe9be41b1a7d1 +0x11fbe041d5e3a2 +0x3e +0xc05c575caa3e2 +0x12fd3f55f92749 +0xb5 +0xfef307a80649c +0x694d773b6e563 +0x0 +0x1284e54af89718 +0x8f1a506967360 +0x6 +0x1eecbbac2653a2 +0xafb39c58bdb30 +0xc +0x1397764b96e3d7 +0x1fcf6c00def779 +0xffffffffffffffff +0xd943ace824438 +0x1234ba12e2b5d9 +0xb1 +0xc079ec12eaad5 +0x7e0bf0514df4a +0x7 +0x151b5694ff1a29 +0x3699052aae4ed +0x0 +0x160ee2a3299343 +0x94725373b3b5e +0x0 +0x19762e14c2a5a5 +0x1d3d3495650207 +0x190 +0x16cfffcbf32568 +0xe62e37e3841db +0x2a +0x11079c4e5b4840 +0x54fc022a5fc28 +0x0 +0x12cb7927ef68c +0xab6a464b9bb44 +0x6 +0x1396451ba612f3 +0x15955083a4f426 +0x2c4 +0x3c2 +0x170 +0x8ad02f4160198 +0x1f2e292b02fc83 +0xffffffffffffffff +0x947f2842e50d6 +0xeaa1a5622e3a4 +0xa +0x1a1704c8278973 +0x12a05ed66f4c0a +0xeb +0x1114fdc6207cd2 +0x3bb4cfcac042b +0x1 +0x1b3b74b3d01456 +0x531f320b2531b +0x1 +0x197e4b75069d1c +0x4d8176640b92e +0x3 +0x1b012144f0fa51 +0x10fae59448f46a +0x8 +0x10539663fa4035 +0x164c0b334cded1 +0x37c +0x107 +0x125a9a06e7bba5 +0xb9b43c76717b +0x1 +0x1cf2aeb6603cb3 +0x149038ed5d9d11 +0x6b +0xf173ebe9135e5 +0x1811a49e35de09 +0x12d +0xb813b577702a +0xafe2049d3f562 +0xd +0x1ba2b7b064c255 +0x20607cec5b805 +0x1 +0x16c2154199ef32 +0x23f3c71d80c9b +0x1 +0x1106d63649cf19 +0xa2b99bca8e7ac +0xb +0xa6d34ffecd0a5 +0x159f02878e5f6d +0x2ea +0x2ba +0x31b +0x121 +0x17762d304d229e +0x1ae07bc79e4410 +0x13 +0x16520166b2318f +0x18b9eed5884993 +0x39e +0x44 +0x156a3d2e785604 +0x6de195e62fd9c +0x1 +0x357a4cb6e9746 +0x1ec3aa7ce66580 +0x2cd +0x66 +0x17ac30ce8ec31b +0x9497852492b84 +0xa +0x18ac792a689485 +0x3266d37f6731d +0x0 +0x158865b1697fc3 +0xb5ea2b426535e +0x6 +0x1db03d2d540db2 +0x48084744eebcc +0x1 +0xf03b281d81e80 +0x10b4af861d654f +0xe +0x1b54ecc34b53e2 +0x6106d8d99c88d +0x3 +0xb165bcd6cecde +0xf3ff59d242ab5 +0xf +0x340e867d1532d +0x1130568709d9e7 +0x36 +0x12d1ffb3754d5b +0xa84458eda2d0e +0x7 +0x1a64f2673adbc7 +0x18822fb55da60d +0x30c +0x230 +0x393 +0x5e +0x1249caf2fa4cc7 +0x1090841a6a3c7 +0x1 +0xbbab3008bcd4b +0x5e0cf2416db3c +0x1 +0x1ae89840ef2766 +0x8c200ba4313b8 +0x5 +0x1fee6a270f448d +0x11d30f6fb09a46 +0xce +0xe8381b8eda998 +0x1f1e4a7c6aa3ec +0xffffffffffffffff +0xf6462d88f7320 +0x49d09a27bb9f3 +0x2 +0x416e964435cca +0x1e1ff6f6b79794 +0x367 +0x2a1 +0x4e +0x2c8f3bf759265 +0xc76dc2ff2479b +0xb +0x1b474ddd26012d +0x18213ba0d029a5 +0x2c7 +0x21e +0x3cd +0x2ed +0x1c9 +0x12eeb282e67311 +0x70f801cad570 +0x0 +0xe7431464d3755 +0x1033f1de5f67a0 +0x58 +0x1535a55a6d00d +0xeec21f4e4462d +0x4 +0x74c5911718c5f +0xcde3a5429d3bf +0x8 +0x11b45fdd094ebb +0x1f167cee04ae61 +0xffffffffffffffff +0x17a28518b52445 +0x3321f47533362 +0x0 +0xdd01a125c4a4a +0x6a89a8d9ab90b +0x3 +0xe1049754f4420 +0x94c9cca847000 +0x2 +0x163568c0c286a3 +0x320875f898519 +0x1 +0xd65f1429c43f8 +0x19d7d707113edd +0x20f +0x2c9 +0x4f +0x860cd5aab781b +0x39b3c9375f97d +0x0 +0x2333e3d7ca98d +0x17a6d7616fae5 +0x0 +0x1be31c31fa1b65 +0x1e9cf0eff97714 +0x3b2 +0x1c5 +0x228d962252c1 +0x1da1342813d162 +0xe8 +0xcb52be9526514 +0xbe7715933fd26 +0x8 +0x8f1a4b72402b3 +0xd29274e087de2 +0xa +0x16eaf729826089 +0x18c0985d643ec9 +0x3eb +0x3af +0xef +0x771448beb2b60 +0xca48c76e6a43b +0x14 +0x12e8d395659fca +0x6962f0ecdd7eb +0x5 +0x1b5b9a7947347f +0x111eac80e7a6a +0x0 +0xa2f9593345b1a +0x23ab2574ece76 +0x0 +0x52bdb9f49038 +0x13c1e91774246c +0x109 +0x11678fb01f0e94 +0x1eed50c572ce61 +0x276 +0x96 +0x85293dd2b81d9 +0x46f5a55a32f21 +0x2 +0x8ea156b2403b8 +0x130c376c244b7a +0xea +0x593dbf28c8642 +0x48fb750754798 +0x0 +0x218b6e19d2ce7 +0x28667e2348614 +0x0 +0xb47c81a484822 +0xe7763abc2530e +0x3e +0x11621e6432f25e +0xb6e51a3c7540d +0x5 +0x15a8205db3e4cf +0x1f528a70225267 +0xffffffffffffffff +0x7f1a01494e0e2 +0x64a97840199f5 +0x0 +0xe8a7648610a60 +0x7814e573acea1 +0x2 +0x9f52042f72a1f +0xceeb054adc0f0 +0x11 +0x1f8e17539ad7cf +0x726edc3a875f6 +0x5 +0x14704edc0975f7 +0x118b2f49f75478 +0x4b +0x1bc318c2f02b8e +0x158d0ef586448e +0x2a1 +0x381 +0x136 +0x10bd503772dde5 +0x11f23f5e7b3f97 +0xac +0x184032fc1d0289 +0x112711dd817d83 +0x18 +0x273b20abf615c +0x1a1f72d887b0c2 +0x221 +0x58 +0x75447e86e9506 +0x1f5077c5158403 +0xffffffffffffffff +0x1484c44b895db2 +0x1a7a4cd63fe6fd +0x2d8 +0x3a7 +0x1be +0x49d80aad06826 +0xb75b3c47ca70b +0x7 +0x17b50ef6547c08 +0x61a34e6ccfe60 +0x3 +0x17c0e7eed36e10 +0x6a094e5ea11f2 +0x3 +0xe6e5d341e0f9f +0x18519b4701487e +0x3fb +0x72 +0xf64409ba1a52b +0x7c54c8de9c737 +0x6 +0x3bd3309d85dfa +0xd7c26e0c06e7f +0x2 +0x10a3874da0fe24 +0x17ee1a5fd6e736 +0x367 +0x25e +0x1aa +0xedea7935cd0ab +0xbce43cf730e22 +0xd +0x189100661f2b80 +0xbf03d117400cd +0xd +0x1940aba500afec +0xf0331a24e3663 +0x6 +0xbf51d6f2c634e +0x135a22a6c9173a +0x1d +0x6082f4e73edc4 +0x1e76c6b2e83524 +0x82 +0x23d8833c0cfd1 +0xad6c5e891d077 +0xf +0x1395753897997a +0x12a341871f9b19 +0xc4 +0x1af8256ea1b399 +0x1e023f88c2f3d1 +0x21f +0x1de +0x15e381df69a2fb +0x36dbfaad03710 +0x0 +0x1636516372e7b1 +0x2f1ee347aed69 +0x1 +0xb3da16c4564fc +0xc3cbf6936777d +0xa +0xa747baaa63b10 +0x5fd09cf3fd7ae +0x3 +0x841b987647c93 +0x14ee7c5e1c4aec +0x378 +0x310 +0x196 +0x86138cb44b38e +0x11ce7c42224c97 +0x91 +0x199672e5f8fe30 +0x19f254a45c1ad8 +0xf1 +0x93cbdc9747fab +0xd9f690e1b64d0 +0x0 +0x1ab1e9f7ba4a +0x59e57af077bea +0x2 +0x1c885e18521117 +0x81245406d707c +0x5 +0x1c09c2947a1067 +0x13215075ebb743 +0xe5 +0x1fc0b792b6c8ce +0xe9884cf04721d +0x2f +0x144617c620a489 +0x1f497e7115f5b4 +0xffffffffffffffff +0x1ae47ced5ad3a3 +0xa2c6fbd42a883 +0x5 +0xb9e9253823be +0x1bd67da246b7a6 +0x10e +0x1bb16c7f546078 +0x1edc5424565bbe +0x21c +0x305 +0x309 +0x94 +0x72cc716d0d736 +0x1e7c78aceae3e8 +0x124 +0xd0bf7d6644188 +0x133d77cb1a83e7 +0x92 +0x139da06e6cbf55 +0x1ca3de51b16a13 +0x19b +0x194a80ee239485 +0x1704d2bf665acd +0x3f4 +0x229 +0x31 +0x30bb2986d48e0 +0x6dad9af00bae1 +0x3 +0x143d3ccf72cc6a +0x1272257645e054 +0x84 +0x1124a37048f083 +0x1084ce7caad86a +0x9 +0x1cea54a09c4bb5 +0x1ab6eac00ea1cc +0xc1 +0x13c855d1666b97 +0x1da18afcac568a +0x273 +0x1fe +0x134dcf198d08d5 +0x56d7aa877e65b +0x3 +0x19c1af5ea21ea0 +0xeaca78e7822 +0x1 +0x807e8630dc7ed +0xdb91f876d1fe5 +0x16 +0xdd5c5f42f155 +0x129a02e8915eef +0x2 +0x365fdd52f9d57 +0x15660795ef0ed4 +0x217 +0x88 +0xdc1d746a07de2 +0x1e4a5c76a57b57 +0x198 +0x13b94df18444f1 +0xbb1f76a846da0 +0xb +0x17bb74a9f969e6 +0x42d5523f10d7a +0x1 +0x105046a138d532 +0x30621e8844265 +0x1 \ No newline at end of file diff --git a/go.mod b/go.mod index 16051cab5a..3f9a3a431d 100644 --- a/go.mod +++ b/go.mod @@ -240,3 +240,5 @@ require ( lukechampine.com/blake3 v1.2.1 // indirect rsc.io/tmplfunc v0.0.3 // indirect ) + +replace github.com/livepeer/lpms => /home/ricks/development/livepeer/ai/lpms From 29f93ee80d9ec673f3ba0e5943ac8bee4e99fd27 Mon Sep 17 00:00:00 2001 From: kyriediculous Date: Wed, 12 Jun 2024 11:56:36 +0200 Subject: [PATCH 42/88] [net,server]: RemoteAIWorker gRPC --- net/lp_rpc.pb.go | 1159 +++++++++++++++++++++++++++++++++++++++++ net/lp_rpc.proto | 15 + net/lp_rpc_grpc.pb.go | 67 +++ server/ot_rpc.go | 84 ++- 4 files changed, 1309 insertions(+), 16 deletions(-) diff --git a/net/lp_rpc.pb.go b/net/lp_rpc.pb.go index 70a6f4b1f4..f4879f3e8d 100644 --- a/net/lp_rpc.pb.go +++ b/net/lp_rpc.pb.go @@ -20,6 +20,55 @@ var _ = math.Inf // proto package needs to be updated. const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package +type AIRequestType int32 + +const ( + AIRequestType_TextToImage AIRequestType = 0 + AIRequestType_ImageToText AIRequestType = 1 + AIRequestType_ImageToImage AIRequestType = 2 +) + +// Enum value maps for AIRequestType. +var ( + AIRequestType_name = map[int32]string{ + 0: "TextToImage", + 1: "ImageToText", + 2: "ImageToImage", + } + AIRequestType_value = map[string]int32{ + "TextToImage": 0, + "ImageToText": 1, + "ImageToImage": 2, + } +) + +func (x AIRequestType) Enum() *AIRequestType { + p := new(AIRequestType) + *p = x + return p +} + +func (x AIRequestType) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (AIRequestType) Descriptor() protoreflect.EnumDescriptor { + return file_net_lp_rpc_proto_enumTypes[0].Descriptor() +} + +func (AIRequestType) Type() protoreflect.EnumType { + return &file_net_lp_rpc_proto_enumTypes[0] +} + +func (x AIRequestType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use AIRequestType.Descriptor instead. +func (AIRequestType) EnumDescriptor() ([]byte, []int) { + return file_net_lp_rpc_proto_rawDescGZIP(), []int{0} +} + type OSInfo_StorageType int32 const ( @@ -44,6 +93,22 @@ func (x OSInfo_StorageType) String() string { return proto.EnumName(OSInfo_StorageType_name, int32(x)) } +<<<<<<< HEAD +======= +func (OSInfo_StorageType) Descriptor() protoreflect.EnumDescriptor { + return file_net_lp_rpc_proto_enumTypes[1].Descriptor() +} + +func (OSInfo_StorageType) Type() protoreflect.EnumType { + return &file_net_lp_rpc_proto_enumTypes[1] +} + +func (x OSInfo_StorageType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use OSInfo_StorageType.Descriptor instead. +>>>>>>> 703455f1 ([net,server]: RemoteAIWorker gRPC) func (OSInfo_StorageType) EnumDescriptor() ([]byte, []int) { return fileDescriptor_034e29c79f9ba827, []int{4, 0} } @@ -70,6 +135,19 @@ func (x VideoProfile_Format) String() string { return proto.EnumName(VideoProfile_Format_name, int32(x)) } +func (VideoProfile_Format) Descriptor() protoreflect.EnumDescriptor { + return file_net_lp_rpc_proto_enumTypes[2].Descriptor() +} + +func (VideoProfile_Format) Type() protoreflect.EnumType { + return &file_net_lp_rpc_proto_enumTypes[2] +} + +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} } @@ -104,6 +182,22 @@ func (x VideoProfile_Profile) String() string { return proto.EnumName(VideoProfile_Profile_name, int32(x)) } +<<<<<<< HEAD +======= +func (VideoProfile_Profile) Descriptor() protoreflect.EnumDescriptor { + return file_net_lp_rpc_proto_enumTypes[3].Descriptor() +} + +func (VideoProfile_Profile) Type() protoreflect.EnumType { + return &file_net_lp_rpc_proto_enumTypes[3] +} + +func (x VideoProfile_Profile) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use VideoProfile_Profile.Descriptor instead. +>>>>>>> 703455f1 ([net,server]: RemoteAIWorker gRPC) func (VideoProfile_Profile) EnumDescriptor() ([]byte, []int) { return fileDescriptor_034e29c79f9ba827, []int{12, 1} } @@ -135,6 +229,22 @@ func (x VideoProfile_VideoCodec) String() string { return proto.EnumName(VideoProfile_VideoCodec_name, int32(x)) } +<<<<<<< HEAD +======= +func (VideoProfile_VideoCodec) Descriptor() protoreflect.EnumDescriptor { + return file_net_lp_rpc_proto_enumTypes[4].Descriptor() +} + +func (VideoProfile_VideoCodec) Type() protoreflect.EnumType { + return &file_net_lp_rpc_proto_enumTypes[4] +} + +func (x VideoProfile_VideoCodec) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use VideoProfile_VideoCodec.Descriptor instead. +>>>>>>> 703455f1 ([net,server]: RemoteAIWorker gRPC) func (VideoProfile_VideoCodec) EnumDescriptor() ([]byte, []int) { return fileDescriptor_034e29c79f9ba827, []int{12, 2} } @@ -163,6 +273,22 @@ func (x VideoProfile_ChromaSubsampling) String() string { return proto.EnumName(VideoProfile_ChromaSubsampling_name, int32(x)) } +<<<<<<< HEAD +======= +func (VideoProfile_ChromaSubsampling) Descriptor() protoreflect.EnumDescriptor { + return file_net_lp_rpc_proto_enumTypes[5].Descriptor() +} + +func (VideoProfile_ChromaSubsampling) Type() protoreflect.EnumType { + return &file_net_lp_rpc_proto_enumTypes[5] +} + +func (x VideoProfile_ChromaSubsampling) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use VideoProfile_ChromaSubsampling.Descriptor instead. +>>>>>>> 703455f1 ([net,server]: RemoteAIWorker gRPC) func (VideoProfile_ChromaSubsampling) EnumDescriptor() ([]byte, []int) { return fileDescriptor_034e29c79f9ba827, []int{12, 3} } @@ -1591,6 +1717,62 @@ func (m *NotifySegment) GetProfiles() []byte { return nil } +// Sent by the orchestrator to the remote AI worker +type NotifyAIJob struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Type AIRequestType `protobuf:"varint,1,opt,name=type,proto3,enum=net.AIRequestType" json:"type,omitempty"` + Data []byte `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"` // json +} + +func (x *NotifyAIJob) Reset() { + *x = NotifyAIJob{} + if protoimpl.UnsafeEnabled { + mi := &file_net_lp_rpc_proto_msgTypes[18] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *NotifyAIJob) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*NotifyAIJob) ProtoMessage() {} + +func (x *NotifyAIJob) ProtoReflect() protoreflect.Message { + mi := &file_net_lp_rpc_proto_msgTypes[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) +} + +// Deprecated: Use NotifyAIJob.ProtoReflect.Descriptor instead. +func (*NotifyAIJob) Descriptor() ([]byte, []int) { + return file_net_lp_rpc_proto_rawDescGZIP(), []int{18} +} + +func (x *NotifyAIJob) GetType() AIRequestType { + if x != nil { + return x.Type + } + return AIRequestType_TextToImage +} + +func (x *NotifyAIJob) GetData() []byte { + if x != nil { + return x.Data + } + return nil +} + // Required parameters for probabilistic micropayment tickets type TicketParams struct { // ETH address of the recipient @@ -1614,11 +1796,44 @@ type TicketParams struct { XXX_sizecache int32 `json:"-"` } +<<<<<<< HEAD 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[19] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *TicketParams) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TicketParams) ProtoMessage() {} + +func (x *TicketParams) ProtoReflect() protoreflect.Message { + mi := &file_net_lp_rpc_proto_msgTypes[19] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TicketParams.ProtoReflect.Descriptor instead. +func (*TicketParams) Descriptor() ([]byte, []int) { + return file_net_lp_rpc_proto_rawDescGZIP(), []int{19} +>>>>>>> 703455f1 ([net,server]: RemoteAIWorker gRPC) } func (m *TicketParams) XXX_Unmarshal(b []byte) error { @@ -1700,11 +1915,44 @@ type TicketSenderParams struct { XXX_sizecache int32 `json:"-"` } +<<<<<<< HEAD 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[20] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *TicketSenderParams) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TicketSenderParams) ProtoMessage() {} + +func (x *TicketSenderParams) ProtoReflect() protoreflect.Message { + mi := &file_net_lp_rpc_proto_msgTypes[20] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TicketSenderParams.ProtoReflect.Descriptor instead. +func (*TicketSenderParams) Descriptor() ([]byte, []int) { + return file_net_lp_rpc_proto_rawDescGZIP(), []int{20} +>>>>>>> 703455f1 ([net,server]: RemoteAIWorker gRPC) } func (m *TicketSenderParams) XXX_Unmarshal(b []byte) error { @@ -1750,11 +1998,44 @@ type TicketExpirationParams struct { XXX_sizecache int32 `json:"-"` } +<<<<<<< HEAD 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[21] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *TicketExpirationParams) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TicketExpirationParams) ProtoMessage() {} + +func (x *TicketExpirationParams) ProtoReflect() protoreflect.Message { + mi := &file_net_lp_rpc_proto_msgTypes[21] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TicketExpirationParams.ProtoReflect.Descriptor instead. +func (*TicketExpirationParams) Descriptor() ([]byte, []int) { + return file_net_lp_rpc_proto_rawDescGZIP(), []int{21} +>>>>>>> 703455f1 ([net,server]: RemoteAIWorker gRPC) } func (m *TicketExpirationParams) XXX_Unmarshal(b []byte) error { @@ -1808,11 +2089,44 @@ type Payment struct { XXX_sizecache int32 `json:"-"` } +<<<<<<< HEAD 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[22] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Payment) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Payment) ProtoMessage() {} + +func (x *Payment) ProtoReflect() protoreflect.Message { + mi := &file_net_lp_rpc_proto_msgTypes[22] + 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 Payment.ProtoReflect.Descriptor instead. +func (*Payment) Descriptor() ([]byte, []int) { + return file_net_lp_rpc_proto_rawDescGZIP(), []int{22} +>>>>>>> 703455f1 ([net,server]: RemoteAIWorker gRPC) } func (m *Payment) XXX_Unmarshal(b []byte) error { @@ -1904,6 +2218,7 @@ func init() { proto.RegisterType((*Payment)(nil), "net.Payment") } +<<<<<<< HEAD func init() { proto.RegisterFile("net/lp_rpc.proto", fileDescriptor_034e29c79f9ba827) } @@ -2037,4 +2352,848 @@ var fileDescriptor_034e29c79f9ba827 = []byte{ 0x38, 0x36, 0x15, 0x00, 0x67, 0x30, 0xeb, 0x79, 0x6e, 0xbf, 0xfc, 0x9b, 0xe5, 0xed, 0xaf, 0x7c, 0x26, 0x2e, 0x4a, 0xf8, 0xff, 0x6e, 0xe7, 0xbf, 0x01, 0x00, 0x00, 0xff, 0xff, 0xa2, 0xc3, 0xc1, 0x2e, 0xd3, 0x13, 0x00, 0x00, +======= +func (x *Capabilities_Constraints) Reset() { + *x = Capabilities_Constraints{} + if protoimpl.UnsafeEnabled { + mi := &file_net_lp_rpc_proto_msgTypes[24] + 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[24] + 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) GetModels() map[string]*Capabilities_Constraints_ModelConstraint { + if x != nil { + return x.Models + } + return nil +} + +type Capabilities_Constraints_ModelConstraint struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Warm bool `protobuf:"varint,1,opt,name=warm,proto3" json:"warm,omitempty"` +} + +func (x *Capabilities_Constraints_ModelConstraint) Reset() { + *x = Capabilities_Constraints_ModelConstraint{} + if protoimpl.UnsafeEnabled { + mi := &file_net_lp_rpc_proto_msgTypes[26] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Capabilities_Constraints_ModelConstraint) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Capabilities_Constraints_ModelConstraint) ProtoMessage() {} + +func (x *Capabilities_Constraints_ModelConstraint) ProtoReflect() protoreflect.Message { + mi := &file_net_lp_rpc_proto_msgTypes[26] + 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_ModelConstraint.ProtoReflect.Descriptor instead. +func (*Capabilities_Constraints_ModelConstraint) Descriptor() ([]byte, []int) { + return file_net_lp_rpc_proto_rawDescGZIP(), []int{7, 1, 0} +} + +func (x *Capabilities_Constraints_ModelConstraint) GetWarm() bool { + if x != nil { + return x.Warm + } + return false +} + +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, 0x78, 0x0a, 0x13, 0x4f, 0x72, 0x63, + 0x68, 0x65, 0x73, 0x74, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x69, + 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x73, 0x69, 0x67, 0x12, 0x35, 0x0a, 0x0c, + 0x63, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, + 0x69, 0x74, 0x69, 0x65, 0x73, 0x52, 0x0c, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, + 0x69, 0x65, 0x73, 0x22, 0x99, 0x01, 0x0a, 0x06, 0x4f, 0x53, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x39, + 0x0a, 0x0b, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0e, 0x32, 0x17, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x4f, 0x53, 0x49, 0x6e, 0x66, 0x6f, + 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0b, 0x73, 0x74, + 0x6f, 0x72, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x25, 0x0a, 0x06, 0x73, 0x33, 0x69, + 0x6e, 0x66, 0x6f, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x6e, 0x65, 0x74, 0x2e, + 0x53, 0x33, 0x4f, 0x53, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x06, 0x73, 0x33, 0x69, 0x6e, 0x66, 0x6f, + 0x22, 0x2d, 0x0a, 0x0b, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, + 0x0a, 0x0a, 0x06, 0x44, 0x49, 0x52, 0x45, 0x43, 0x54, 0x10, 0x00, 0x12, 0x06, 0x0a, 0x02, 0x53, + 0x33, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x47, 0x4f, 0x4f, 0x47, 0x4c, 0x45, 0x10, 0x02, 0x22, + 0xa2, 0x01, 0x0a, 0x08, 0x53, 0x33, 0x4f, 0x53, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x12, 0x0a, 0x04, + 0x68, 0x6f, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, 0x6f, 0x73, 0x74, + 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, + 0x65, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x06, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, + 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, + 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x64, + 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x72, + 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x12, 0x1a, 0x0a, 0x08, 0x78, 0x41, 0x6d, 0x7a, + 0x44, 0x61, 0x74, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x78, 0x41, 0x6d, 0x7a, + 0x44, 0x61, 0x74, 0x65, 0x22, 0x55, 0x0a, 0x09, 0x50, 0x72, 0x69, 0x63, 0x65, 0x49, 0x6e, 0x66, + 0x6f, 0x12, 0x22, 0x0a, 0x0c, 0x70, 0x72, 0x69, 0x63, 0x65, 0x50, 0x65, 0x72, 0x55, 0x6e, 0x69, + 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x70, 0x72, 0x69, 0x63, 0x65, 0x50, 0x65, + 0x72, 0x55, 0x6e, 0x69, 0x74, 0x12, 0x24, 0x0a, 0x0d, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x73, 0x50, + 0x65, 0x72, 0x55, 0x6e, 0x69, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x70, 0x69, + 0x78, 0x65, 0x6c, 0x73, 0x50, 0x65, 0x72, 0x55, 0x6e, 0x69, 0x74, 0x22, 0xd9, 0x04, 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, + 0x44, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x74, 0x73, 0x18, 0x04, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 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, 0x45, 0x6e, 0x74, 0x72, 0x79, 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, 0xe1, 0x01, 0x0a, 0x0b, 0x43, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x61, + 0x69, 0x6e, 0x74, 0x73, 0x12, 0x41, 0x0a, 0x06, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x73, 0x18, 0x01, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x43, 0x61, 0x70, 0x61, 0x62, + 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x61, 0x69, + 0x6e, 0x74, 0x73, 0x2e, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, + 0x06, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x73, 0x1a, 0x25, 0x0a, 0x0f, 0x4d, 0x6f, 0x64, 0x65, 0x6c, + 0x43, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x77, 0x61, + 0x72, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x77, 0x61, 0x72, 0x6d, 0x1a, 0x68, + 0x0a, 0x0b, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, + 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, + 0x43, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, + 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, + 0x73, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x74, 0x73, 0x2e, 0x4d, 0x6f, + 0x64, 0x65, 0x6c, 0x43, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x74, 0x52, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x5d, 0x0a, 0x10, 0x43, 0x6f, 0x6e, 0x73, + 0x74, 0x72, 0x61, 0x69, 0x6e, 0x74, 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, 0x33, + 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 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, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xc0, 0x02, 0x0a, 0x10, 0x4f, 0x72, 0x63, 0x68, + 0x65, 0x73, 0x74, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1e, 0x0a, 0x0a, + 0x74, 0x72, 0x61, 0x6e, 0x73, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0a, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x12, 0x36, 0x0a, 0x0d, + 0x74, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x54, 0x69, 0x63, 0x6b, 0x65, 0x74, + 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x0c, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x50, 0x61, + 0x72, 0x61, 0x6d, 0x73, 0x12, 0x2d, 0x0a, 0x0a, 0x70, 0x72, 0x69, 0x63, 0x65, 0x5f, 0x69, 0x6e, + 0x66, 0x6f, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x50, + 0x72, 0x69, 0x63, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x09, 0x70, 0x72, 0x69, 0x63, 0x65, 0x49, + 0x6e, 0x66, 0x6f, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x35, 0x0a, + 0x0c, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, + 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x52, 0x0c, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, + 0x74, 0x69, 0x65, 0x73, 0x12, 0x2d, 0x0a, 0x0a, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x74, 0x6f, 0x6b, + 0x65, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x41, + 0x75, 0x74, 0x68, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x09, 0x61, 0x75, 0x74, 0x68, 0x54, 0x6f, + 0x6b, 0x65, 0x6e, 0x12, 0x25, 0x0a, 0x07, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x18, 0x20, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x4f, 0x53, 0x49, 0x6e, 0x66, + 0x6f, 0x52, 0x07, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x22, 0x60, 0x0a, 0x09, 0x41, 0x75, + 0x74, 0x68, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x1d, 0x0a, + 0x0a, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x09, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x1e, 0x0a, 0x0a, + 0x65, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, + 0x52, 0x0a, 0x65, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xf4, 0x04, 0x0a, + 0x07, 0x53, 0x65, 0x67, 0x44, 0x61, 0x74, 0x61, 0x12, 0x1e, 0x0a, 0x0a, 0x6d, 0x61, 0x6e, 0x69, + 0x66, 0x65, 0x73, 0x74, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x6d, 0x61, + 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x65, 0x71, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x03, 0x73, 0x65, 0x71, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, + 0x73, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x12, 0x1a, + 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x08, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x69, + 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x73, 0x69, 0x67, 0x12, 0x1a, 0x0a, 0x08, + 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, + 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x35, 0x0a, 0x0c, 0x63, 0x61, 0x70, 0x61, + 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, + 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, + 0x73, 0x52, 0x0c, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x12, + 0x2d, 0x0a, 0x0a, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x08, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x54, 0x6f, + 0x6b, 0x65, 0x6e, 0x52, 0x09, 0x61, 0x75, 0x74, 0x68, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x30, + 0x0a, 0x14, 0x63, 0x61, 0x6c, 0x63, 0x5f, 0x70, 0x65, 0x72, 0x63, 0x65, 0x70, 0x74, 0x75, 0x61, + 0x6c, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x63, 0x61, + 0x6c, 0x63, 0x50, 0x65, 0x72, 0x63, 0x65, 0x70, 0x74, 0x75, 0x61, 0x6c, 0x48, 0x61, 0x73, 0x68, + 0x12, 0x25, 0x0a, 0x07, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x18, 0x20, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x0b, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x4f, 0x53, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x07, + 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x12, 0x35, 0x0a, 0x0c, 0x66, 0x75, 0x6c, 0x6c, 0x50, + 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x18, 0x21, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, + 0x6e, 0x65, 0x74, 0x2e, 0x56, 0x69, 0x64, 0x65, 0x6f, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, + 0x52, 0x0c, 0x66, 0x75, 0x6c, 0x6c, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x37, + 0x0a, 0x0d, 0x66, 0x75, 0x6c, 0x6c, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x32, 0x18, + 0x22, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x56, 0x69, 0x64, 0x65, + 0x6f, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x52, 0x0d, 0x66, 0x75, 0x6c, 0x6c, 0x50, 0x72, + 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 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, 0x89, 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, 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, 0x49, 0x0a, 0x0b, + 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x41, 0x49, 0x4a, 0x6f, 0x62, 0x12, 0x26, 0x0a, 0x04, 0x74, + 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x12, 0x2e, 0x6e, 0x65, 0x74, 0x2e, + 0x41, 0x49, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, + 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 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, 0x2a, 0x43, 0x0a, 0x0d, 0x41, 0x49, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0f, 0x0a, 0x0b, 0x54, 0x65, 0x78, + 0x74, 0x54, 0x6f, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x49, 0x6d, + 0x61, 0x67, 0x65, 0x54, 0x6f, 0x54, 0x65, 0x78, 0x74, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x49, + 0x6d, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x10, 0x02, 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, 0x8c, 0x01, 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, 0x12, 0x3c, 0x0a, 0x10, 0x52, 0x65, 0x67, + 0x69, 0x73, 0x74, 0x65, 0x72, 0x41, 0x49, 0x57, 0x6f, 0x72, 0x6b, 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, 0x10, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, + 0x41, 0x49, 0x4a, 0x6f, 0x62, 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, 6) +var file_net_lp_rpc_proto_msgTypes = make([]protoimpl.MessageInfo, 28) +var file_net_lp_rpc_proto_goTypes = []interface{}{ + (AIRequestType)(0), // 0: net.AIRequestType + (OSInfo_StorageType)(0), // 1: net.OSInfo.StorageType + (VideoProfile_Format)(0), // 2: net.VideoProfile.Format + (VideoProfile_Profile)(0), // 3: net.VideoProfile.Profile + (VideoProfile_VideoCodec)(0), // 4: net.VideoProfile.VideoCodec + (VideoProfile_ChromaSubsampling)(0), // 5: net.VideoProfile.ChromaSubsampling + (*PingPong)(nil), // 6: net.PingPong + (*EndTranscodingSessionRequest)(nil), // 7: net.EndTranscodingSessionRequest + (*EndTranscodingSessionResponse)(nil), // 8: net.EndTranscodingSessionResponse + (*OrchestratorRequest)(nil), // 9: net.OrchestratorRequest + (*OSInfo)(nil), // 10: net.OSInfo + (*S3OSInfo)(nil), // 11: net.S3OSInfo + (*PriceInfo)(nil), // 12: net.PriceInfo + (*Capabilities)(nil), // 13: net.Capabilities + (*OrchestratorInfo)(nil), // 14: net.OrchestratorInfo + (*AuthToken)(nil), // 15: net.AuthToken + (*SegData)(nil), // 16: net.SegData + (*SegParameters)(nil), // 17: net.SegParameters + (*VideoProfile)(nil), // 18: net.VideoProfile + (*TranscodedSegmentData)(nil), // 19: net.TranscodedSegmentData + (*TranscodeData)(nil), // 20: net.TranscodeData + (*TranscodeResult)(nil), // 21: net.TranscodeResult + (*RegisterRequest)(nil), // 22: net.RegisterRequest + (*NotifySegment)(nil), // 23: net.NotifySegment + (*NotifyAIJob)(nil), // 24: net.NotifyAIJob + (*TicketParams)(nil), // 25: net.TicketParams + (*TicketSenderParams)(nil), // 26: net.TicketSenderParams + (*TicketExpirationParams)(nil), // 27: net.TicketExpirationParams + (*Payment)(nil), // 28: net.Payment + nil, // 29: net.Capabilities.CapacitiesEntry + (*Capabilities_Constraints)(nil), // 30: net.Capabilities.Constraints + nil, // 31: net.Capabilities.ConstraintsEntry + (*Capabilities_Constraints_ModelConstraint)(nil), // 32: net.Capabilities.Constraints.ModelConstraint + nil, // 33: net.Capabilities.Constraints.ModelsEntry +} +var file_net_lp_rpc_proto_depIdxs = []int32{ + 15, // 0: net.EndTranscodingSessionRequest.auth_token:type_name -> net.AuthToken + 13, // 1: net.OrchestratorRequest.capabilities:type_name -> net.Capabilities + 1, // 2: net.OSInfo.storageType:type_name -> net.OSInfo.StorageType + 11, // 3: net.OSInfo.s3info:type_name -> net.S3OSInfo + 29, // 4: net.Capabilities.capacities:type_name -> net.Capabilities.CapacitiesEntry + 31, // 5: net.Capabilities.constraints:type_name -> net.Capabilities.ConstraintsEntry + 25, // 6: net.OrchestratorInfo.ticket_params:type_name -> net.TicketParams + 12, // 7: net.OrchestratorInfo.price_info:type_name -> net.PriceInfo + 13, // 8: net.OrchestratorInfo.capabilities:type_name -> net.Capabilities + 15, // 9: net.OrchestratorInfo.auth_token:type_name -> net.AuthToken + 10, // 10: net.OrchestratorInfo.storage:type_name -> net.OSInfo + 13, // 11: net.SegData.capabilities:type_name -> net.Capabilities + 15, // 12: net.SegData.auth_token:type_name -> net.AuthToken + 10, // 13: net.SegData.storage:type_name -> net.OSInfo + 18, // 14: net.SegData.fullProfiles:type_name -> net.VideoProfile + 18, // 15: net.SegData.fullProfiles2:type_name -> net.VideoProfile + 18, // 16: net.SegData.fullProfiles3:type_name -> net.VideoProfile + 17, // 17: net.SegData.segment_parameters:type_name -> net.SegParameters + 2, // 18: net.VideoProfile.format:type_name -> net.VideoProfile.Format + 3, // 19: net.VideoProfile.profile:type_name -> net.VideoProfile.Profile + 4, // 20: net.VideoProfile.encoder:type_name -> net.VideoProfile.VideoCodec + 5, // 21: net.VideoProfile.chromaFormat:type_name -> net.VideoProfile.ChromaSubsampling + 19, // 22: net.TranscodeData.segments:type_name -> net.TranscodedSegmentData + 20, // 23: net.TranscodeResult.data:type_name -> net.TranscodeData + 14, // 24: net.TranscodeResult.info:type_name -> net.OrchestratorInfo + 13, // 25: net.RegisterRequest.capabilities:type_name -> net.Capabilities + 16, // 26: net.NotifySegment.segData:type_name -> net.SegData + 0, // 27: net.NotifyAIJob.type:type_name -> net.AIRequestType + 27, // 28: net.TicketParams.expiration_params:type_name -> net.TicketExpirationParams + 25, // 29: net.Payment.ticket_params:type_name -> net.TicketParams + 27, // 30: net.Payment.expiration_params:type_name -> net.TicketExpirationParams + 26, // 31: net.Payment.ticket_sender_params:type_name -> net.TicketSenderParams + 12, // 32: net.Payment.expected_price:type_name -> net.PriceInfo + 33, // 33: net.Capabilities.Constraints.models:type_name -> net.Capabilities.Constraints.ModelsEntry + 30, // 34: net.Capabilities.ConstraintsEntry.value:type_name -> net.Capabilities.Constraints + 32, // 35: net.Capabilities.Constraints.ModelsEntry.value:type_name -> net.Capabilities.Constraints.ModelConstraint + 9, // 36: net.Orchestrator.GetOrchestrator:input_type -> net.OrchestratorRequest + 7, // 37: net.Orchestrator.EndTranscodingSession:input_type -> net.EndTranscodingSessionRequest + 6, // 38: net.Orchestrator.Ping:input_type -> net.PingPong + 22, // 39: net.Transcoder.RegisterTranscoder:input_type -> net.RegisterRequest + 22, // 40: net.Transcoder.RegisterAIWorker:input_type -> net.RegisterRequest + 14, // 41: net.Orchestrator.GetOrchestrator:output_type -> net.OrchestratorInfo + 8, // 42: net.Orchestrator.EndTranscodingSession:output_type -> net.EndTranscodingSessionResponse + 6, // 43: net.Orchestrator.Ping:output_type -> net.PingPong + 23, // 44: net.Transcoder.RegisterTranscoder:output_type -> net.NotifySegment + 24, // 45: net.Transcoder.RegisterAIWorker:output_type -> net.NotifyAIJob + 41, // [41:46] is the sub-list for method output_type + 36, // [36:41] is the sub-list for method input_type + 36, // [36:36] is the sub-list for extension type_name + 36, // [36:36] is the sub-list for extension extendee + 0, // [0:36] 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.(*NotifyAIJob); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_net_lp_rpc_proto_msgTypes[19].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[20].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[21].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[22].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[24].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[26].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Capabilities_Constraints_ModelConstraint); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + file_net_lp_rpc_proto_msgTypes[15].OneofWrappers = []interface{}{ + (*TranscodeResult_Error)(nil), + (*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: 6, + NumMessages: 28, + 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 +>>>>>>> 703455f1 ([net,server]: RemoteAIWorker gRPC) } diff --git a/net/lp_rpc.proto b/net/lp_rpc.proto index bd3e6f1efa..0d5f6a37b3 100644 --- a/net/lp_rpc.proto +++ b/net/lp_rpc.proto @@ -17,6 +17,9 @@ service Transcoder { // Called by the transcoder to register to an orchestrator. The orchestrator // notifies registered transcoders of segments as they come in. rpc RegisterTranscoder(RegisterRequest) returns (stream NotifySegment); + // Called by the transcoder to register a `RemoteAIWorker` worker to an orchestrator + // notifies the registered `RemoteAIWorker` of AI jobs as they come in. + rpc RegisterAIWorker(RegisterRequest) returns (stream NotifyAIJob); } message PingPong { @@ -367,6 +370,18 @@ message NotifySegment { reserved 33; // Formerly "repeated VideoProfile fullProfiles" } +enum AIRequestType { + TextToImage= 0; + ImageToText= 1; + ImageToImage= 2; + Upscale = 3; +} +// Sent by the orchestrator to the remote AI worker +message NotifyAIJob { + AIRequestType type = 1; + bytes data = 2; // json +} + // Required parameters for probabilistic micropayment tickets message TicketParams { // ETH address of the recipient diff --git a/net/lp_rpc_grpc.pb.go b/net/lp_rpc_grpc.pb.go index 5dd8d296ba..ff4cd7c826 100644 --- a/net/lp_rpc_grpc.pb.go +++ b/net/lp_rpc_grpc.pb.go @@ -185,6 +185,9 @@ type TranscoderClient interface { // Called by the transcoder to register to an orchestrator. The orchestrator // notifies registered transcoders of segments as they come in. RegisterTranscoder(ctx context.Context, in *RegisterRequest, opts ...grpc.CallOption) (Transcoder_RegisterTranscoderClient, error) + // Called by the transcoder to register a `RemoteAIWorker` worker to an orchestrator + // notifies the registered `RemoteAIWorker` of AI jobs as they come in. + RegisterAIWorker(ctx context.Context, in *RegisterRequest, opts ...grpc.CallOption) (Transcoder_RegisterAIWorkerClient, error) } type transcoderClient struct { @@ -227,6 +230,38 @@ func (x *transcoderRegisterTranscoderClient) Recv() (*NotifySegment, error) { return m, nil } +func (c *transcoderClient) RegisterAIWorker(ctx context.Context, in *RegisterRequest, opts ...grpc.CallOption) (Transcoder_RegisterAIWorkerClient, error) { + stream, err := c.cc.NewStream(ctx, &Transcoder_ServiceDesc.Streams[1], "/net.Transcoder/RegisterAIWorker", opts...) + if err != nil { + return nil, err + } + x := &transcoderRegisterAIWorkerClient{stream} + if err := x.ClientStream.SendMsg(in); err != nil { + return nil, err + } + if err := x.ClientStream.CloseSend(); err != nil { + return nil, err + } + return x, nil +} + +type Transcoder_RegisterAIWorkerClient interface { + Recv() (*NotifyAIJob, error) + grpc.ClientStream +} + +type transcoderRegisterAIWorkerClient struct { + grpc.ClientStream +} + +func (x *transcoderRegisterAIWorkerClient) Recv() (*NotifyAIJob, error) { + m := new(NotifyAIJob) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + // TranscoderServer is the server API for Transcoder service. // All implementations must embed UnimplementedTranscoderServer // for forward compatibility @@ -234,6 +269,9 @@ type TranscoderServer interface { // Called by the transcoder to register to an orchestrator. The orchestrator // notifies registered transcoders of segments as they come in. RegisterTranscoder(*RegisterRequest, Transcoder_RegisterTranscoderServer) error + // Called by the transcoder to register a `RemoteAIWorker` worker to an orchestrator + // notifies the registered `RemoteAIWorker` of AI jobs as they come in. + RegisterAIWorker(*RegisterRequest, Transcoder_RegisterAIWorkerServer) error mustEmbedUnimplementedTranscoderServer() } @@ -244,6 +282,9 @@ type UnimplementedTranscoderServer struct { func (UnimplementedTranscoderServer) RegisterTranscoder(*RegisterRequest, Transcoder_RegisterTranscoderServer) error { return status.Errorf(codes.Unimplemented, "method RegisterTranscoder not implemented") } +func (UnimplementedTranscoderServer) RegisterAIWorker(*RegisterRequest, Transcoder_RegisterAIWorkerServer) error { + return status.Errorf(codes.Unimplemented, "method RegisterAIWorker not implemented") +} func (UnimplementedTranscoderServer) mustEmbedUnimplementedTranscoderServer() {} // UnsafeTranscoderServer may be embedded to opt out of forward compatibility for this service. @@ -278,6 +319,27 @@ func (x *transcoderRegisterTranscoderServer) Send(m *NotifySegment) error { return x.ServerStream.SendMsg(m) } +func _Transcoder_RegisterAIWorker_Handler(srv interface{}, stream grpc.ServerStream) error { + m := new(RegisterRequest) + if err := stream.RecvMsg(m); err != nil { + return err + } + return srv.(TranscoderServer).RegisterAIWorker(m, &transcoderRegisterAIWorkerServer{stream}) +} + +type Transcoder_RegisterAIWorkerServer interface { + Send(*NotifyAIJob) error + grpc.ServerStream +} + +type transcoderRegisterAIWorkerServer struct { + grpc.ServerStream +} + +func (x *transcoderRegisterAIWorkerServer) Send(m *NotifyAIJob) error { + return x.ServerStream.SendMsg(m) +} + // Transcoder_ServiceDesc is the grpc.ServiceDesc for Transcoder service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) @@ -291,6 +353,11 @@ var Transcoder_ServiceDesc = grpc.ServiceDesc{ Handler: _Transcoder_RegisterTranscoder_Handler, ServerStreams: true, }, + { + StreamName: "RegisterAIWorker", + Handler: _Transcoder_RegisterAIWorker_Handler, + ServerStreams: true, + }, }, Metadata: "net/lp_rpc.proto", } diff --git a/server/ot_rpc.go b/server/ot_rpc.go index a4ceb8045d..e7ae5b7bab 100644 --- a/server/ot_rpc.go +++ b/server/ot_rpc.go @@ -96,13 +96,25 @@ func runTranscoder(n *core.LivepeerNode, orchAddr string, capacity int, caps []c ctx, cancel := context.WithCancel(ctx) // Silence linter defer cancel() - r, err := c.RegisterTranscoder(ctx, &net.RegisterRequest{Secret: n.OrchSecret, Capacity: int64(capacity), + + // TODO: check if transcoding capabilities are defined + + tR, err := c.RegisterTranscoder(ctx, &net.RegisterRequest{Secret: n.OrchSecret, Capacity: int64(capacity), Capabilities: core.NewCapabilities(caps, []core.Capability{}).ToNetCapabilities()}) if err := checkTranscoderError(err); err != nil { glog.Error("Could not register transcoder to orchestrator ", err) return err } + // TODO check if ai capabilities are defined + aiR, err := c.RegisterAIWorker(ctx, &net.RegisterRequest{Secret: n.OrchSecret, Capacity: int64(capacity), + Capabilities: core.NewCapabilities(caps, []core.Capability{}).ToNetCapabilities()}) + // TODO: add checking AI errors to checkTranscoderError + if err := checkTranscoderError(err); err != nil { + glog.Error("Could not register AI worker to orchestrator ", err) + return err + } + // Catch interrupt signal to shut down transcoder exitc := make(chan os.Signal) signal.Notify(exitc, os.Interrupt, syscall.SIGTERM) @@ -119,23 +131,63 @@ func runTranscoder(n *core.LivepeerNode, orchAddr string, capacity int, caps []c httpc := &http.Client{Transport: &http2.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: true}}} var wg sync.WaitGroup - for { - notify, err := r.Recv() - if err := checkTranscoderError(err); err != nil { - glog.Infof(`End of stream receive cycle because of err=%q, waiting for running transcode jobs to complete`, err) - wg.Wait() - return err + + // Channels to receive messages + tRChan := make(chan *net.NotifySegment) + aiRChan := make(chan *net.NotifyAIJob) + errChan := make(chan error) + + go func() { + for { + notify, err := tR.Recv() + if err != nil { + errChan <- err + return + } + tRChan <- notify } - if notify.SegData != nil && notify.SegData.AuthToken != nil && len(notify.SegData.AuthToken.SessionId) > 0 && len(notify.Url) == 0 { - // session teardown signal - n.Transcoder.EndTranscodingSession(notify.SegData.AuthToken.SessionId) - } else { - wg.Add(1) - go func() { - runTranscode(n, orchAddr, httpc, notify) - wg.Done() - }() + + }() + + go func() { + for { + aiJob, err := aiR.Recv() + if err != nil { + errChan <- err + return + } + aiRChan <- aiJob } + }() + + for { + select { + case notify := <-tRChan: + + if notify.SegData != nil && notify.SegData.AuthToken != nil && len(notify.SegData.AuthToken.SessionId) > 0 && len(notify.Url) == 0 { + // session teardown signal + n.Transcoder.EndTranscodingSession(notify.SegData.AuthToken.SessionId) + } else { + wg.Add(1) + go func() { + runTranscode(n, orchAddr, httpc, notify) + wg.Done() + }() + } + case aiJob := <-aiRChan: + if aiJob == nil { + glog.Error("Received nil AI job") + continue + } + case err := <-errChan: + if err := checkTranscoderError(err); err != nil { + glog.Infof(`End of stream receive cycle because of err=%q, waiting for running transcode jobs to complete`, err) + wg.Wait() + return err + } + + } + } } From 4b211a45386d642db2aced70baa77696392d2342 Mon Sep 17 00:00:00 2001 From: kyriediculous Date: Wed, 12 Jun 2024 11:56:59 +0200 Subject: [PATCH 43/88] [cmd,core]: initial RemoteAIWorkerManager setup --- cmd/livepeer/starter/starter.go | 4 +++ core/ai.go | 62 +++++++++++++++++++++++++++++++++ core/livepeernode.go | 3 +- 3 files changed, 68 insertions(+), 1 deletion(-) diff --git a/cmd/livepeer/starter/starter.go b/cmd/livepeer/starter/starter.go index 6f9a11e0ec..980671f6ac 100755 --- a/cmd/livepeer/starter/starter.go +++ b/cmd/livepeer/starter/starter.go @@ -523,6 +523,10 @@ func StartLivepeer(ctx context.Context, cfg LivepeerConfig) { n.TranscoderManager = core.NewRemoteTranscoderManager() n.Transcoder = n.TranscoderManager } + if !*cfg.AIWorker { + n.AIManager = core.NewRemoteAIWorkerManager() + n.AIWorker = n.AIManager + } } else if *cfg.Transcoder { n.NodeType = core.TranscoderNode } else if *cfg.Broadcaster { diff --git a/core/ai.go b/core/ai.go index 93966bd418..041ec86cf3 100644 --- a/core/ai.go +++ b/core/ai.go @@ -9,8 +9,10 @@ import ( "regexp" "strconv" "strings" + "sync" "github.com/livepeer/ai-worker/worker" + "github.com/livepeer/go-livepeer/net" ) type AI interface { @@ -50,6 +52,66 @@ func (s StringInt) String() string { return string(s) } +type RemoteAIWorkerManager struct { + // TODO Mapping by pipeline + remoteWorkers []*RemoteAIWorker + liveWorkers map[net.Transcoder_RegisterAIWorkerServer]*RemoteAIWorker + workersMutex sync.Mutex +} + +func NewRemoteAIWorkerManager() *RemoteAIWorkerManager { + return &RemoteAIWorkerManager{ + remoteWorkers: []*RemoteAIWorker{}, + liveWorkers: map[net.Transcoder_RegisterAIWorkerServer]*RemoteAIWorker{}, + workersMutex: sync.Mutex{}, + } +} + +func (m *RemoteAIWorkerManager) TextToImage(ctx context.Context, req worker.TextToImageJSONRequestBody) (*worker.ImageResponse, error) { + return nil, nil + +} + +func (m *RemoteAIWorkerManager) ImageToImage(ctx context.Context, req worker.ImageToImageMultipartRequestBody) (*worker.ImageResponse, error) { + return nil, nil +} + +func (m *RemoteAIWorkerManager) ImageToVideo(ctx context.Context, req worker.ImageToVideoMultipartRequestBody) (*worker.VideoResponse, error) { + return nil, nil +} + +func (m *RemoteAIWorkerManager) Upscale(ctx context.Context, req worker.UpscaleMultipartRequestBody) (*worker.ImageResponse, error) { + return nil, nil +} + +func (m *RemoteAIWorkerManager) Warm(ctx context.Context, pipeline, modelID string, endpoint worker.RunnerEndpoint, flags worker.OptimizationFlags) error { + return nil +} + +func (m *RemoteAIWorkerManager) Stop(ctx context.Context) error { + return nil +} + +func (m *RemoteAIWorkerManager) HasCapacity(pipeline, modelID string) bool { + return false +} + +type RemoteAIWorker struct { + manager *RemoteAIWorkerManager + addr string + capabilities *Capabilities // TODO: AI capabilities only + eof chan struct{} +} + +func NewRemoteAIWorker(manager *RemoteAIWorkerManager, addr string, capabilities *Capabilities) *RemoteAIWorker { + return &RemoteAIWorker{ + manager: manager, + addr: addr, + capabilities: capabilities, + eof: make(chan struct{}), + } +} + type AIModelConfig struct { Pipeline string `json:"pipeline"` ModelID string `json:"model_id"` diff --git a/core/livepeernode.go b/core/livepeernode.go index 0d726ce652..2dff73989e 100644 --- a/core/livepeernode.go +++ b/core/livepeernode.go @@ -116,7 +116,8 @@ type LivepeerNode struct { Database *common.DB // AI worker public fields - AIWorker AI + AIWorker AI + AIManager *RemoteAIWorkerManager // Transcoder public fields SegmentChans map[ManifestID]SegmentChan From 8b6916860925a9c4838cf629a6ba8c2bc9a4de2b Mon Sep 17 00:00:00 2001 From: kyriediculous Date: Wed, 12 Jun 2024 13:27:08 +0200 Subject: [PATCH 44/88] [core,server]: add ai results route and registerAiworker route for orchestrator --- core/ai.go | 45 ++++++++++++++++++++++++++++++++++++++++++++- server/ot_rpc.go | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+), 1 deletion(-) diff --git a/core/ai.go b/core/ai.go index 041ec86cf3..5a18150887 100644 --- a/core/ai.go +++ b/core/ai.go @@ -11,7 +11,9 @@ import ( "strings" "sync" + "github.com/golang/glog" "github.com/livepeer/ai-worker/worker" + "github.com/livepeer/go-livepeer/common" "github.com/livepeer/go-livepeer/net" ) @@ -57,6 +59,10 @@ type RemoteAIWorkerManager struct { remoteWorkers []*RemoteAIWorker liveWorkers map[net.Transcoder_RegisterAIWorkerServer]*RemoteAIWorker workersMutex sync.Mutex + + // tasks + // TODO: how to id tasks/sessions ? + taskMutex sync.Mutex } func NewRemoteAIWorkerManager() *RemoteAIWorkerManager { @@ -67,6 +73,33 @@ func NewRemoteAIWorkerManager() *RemoteAIWorkerManager { } } +func (m *RemoteAIWorkerManager) Manage(stream net.Transcoder_RegisterAIWorkerServer, capabilities *net.Capabilities) { + from := common.GetConnectionAddr(stream.Context()) + worker := NewRemoteAIWorker(m, stream, from, CapabilitiesFromNetCapabilities(capabilities)) + go func() { + ctx := stream.Context() + <-ctx.Done() + err := ctx.Err() + glog.Errorf("Stream closed for remote AI worker=%s err=%q", from, err) + worker.done() + }() + + m.workersMutex.Lock() + m.remoteWorkers = append(m.remoteWorkers, worker) + m.liveWorkers[stream] = worker + m.workersMutex.Unlock() + + <-worker.eof + glog.Infof("Remote AI worker=%s done, removing from live AI workers map", from) + + m.workersMutex.Lock() + delete(m.liveWorkers, stream) + // TODO: remove from remoteWorkers + m.workersMutex.Unlock() +} + +func (m *RemoteAIWorkerManager) handleAIRequest() + func (m *RemoteAIWorkerManager) TextToImage(ctx context.Context, req worker.TextToImageJSONRequestBody) (*worker.ImageResponse, error) { return nil, nil @@ -98,20 +131,30 @@ func (m *RemoteAIWorkerManager) HasCapacity(pipeline, modelID string) bool { type RemoteAIWorker struct { manager *RemoteAIWorkerManager + stream net.Transcoder_RegisterAIWorkerServer addr string capabilities *Capabilities // TODO: AI capabilities only eof chan struct{} } -func NewRemoteAIWorker(manager *RemoteAIWorkerManager, addr string, capabilities *Capabilities) *RemoteAIWorker { +func NewRemoteAIWorker(manager *RemoteAIWorkerManager, stream net.Transcoder_RegisterAIWorkerServer, addr string, capabilities *Capabilities) *RemoteAIWorker { return &RemoteAIWorker{ manager: manager, + stream: stream, addr: addr, capabilities: capabilities, eof: make(chan struct{}), } } +func (w *RemoteAIWorker) done() { + // select so we don't block indefinitely if there's no listener + select { + case w.eof <- struct{}{}: + default: + } +} + type AIModelConfig struct { Pipeline string `json:"pipeline"` ModelID string `json:"model_id"` diff --git a/server/ot_rpc.go b/server/ot_rpc.go index e7ae5b7bab..bce3bae987 100644 --- a/server/ot_rpc.go +++ b/server/ot_rpc.go @@ -367,8 +367,49 @@ func (h *lphttp) RegisterTranscoder(req *net.RegisterRequest, stream net.Transco return nil } +func (h *lphttp) RegisterRemoteAIWorker(req *net.RegisterRequest, stream net.Transcoder_RegisterAIWorkerServer) error { + from := common.GetConnectionAddr(stream.Context()) + glog.Infof("Got a RegisterAIWorker request from transcoder=%s capacity=%d", from, req.Capacity) + + if req.Secret != h.orchestrator.TranscoderSecret() { + glog.Errorf("err=%q", errSecret.Error()) + return errSecret + } + if req.Capacity <= 0 { + glog.Errorf("err=%q", errZeroCapacity.Error()) + return errZeroCapacity + } + // handle + if req.Capabilities == nil { + // TODO: return error No AI capabilities + } + // h.orchestrator.ServeRemoteAIWorker() + return nil +} + // Orchestrator HTTP +func (h *lphttp) AIWorkerResults(w http.ResponseWriter, r *http.Request) { + orch := h.orchestrator + + authType := r.Header.Get("Authorization") + creds := r.Header.Get("Credentials") + if protoVerLPT != authType { + glog.Error("Invalid auth type ", authType) + http.Error(w, "Unauthorized", http.StatusUnauthorized) + return + } + + if creds != orch.TranscoderSecret() { + glog.Error("Invalid shared secret") + http.Error(w, "Unauthorized", http.StatusUnauthorized) + return + } + + // TODO: handle results + +} + func (h *lphttp) TranscodeResults(w http.ResponseWriter, r *http.Request) { orch := h.orchestrator From 26ba3e9ddacdec6a5ecd8838f6801492a5ebe056 Mon Sep 17 00:00:00 2001 From: kyriediculous Date: Wed, 12 Jun 2024 13:27:29 +0200 Subject: [PATCH 45/88] cmd: start transcoder with full capabilities (ai + transcoder) --- cmd/livepeer/starter/starter.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/livepeer/starter/starter.go b/cmd/livepeer/starter/starter.go index 980671f6ac..d7774bb727 100755 --- a/cmd/livepeer/starter/starter.go +++ b/cmd/livepeer/starter/starter.go @@ -1475,7 +1475,7 @@ func StartLivepeer(ctx context.Context, cfg LivepeerConfig) { glog.Exit("Missing -orchAddr") } - go server.RunTranscoder(n, orchURLs[0].Host, core.MaxSessions, transcoderCaps) + go server.RunTranscoder(n, orchURLs[0].Host, core.MaxSessions, append(transcoderCaps, aiCaps...)) } switch n.NodeType { From 738c3e03d8c9e6022d06bdba011fdecbe160f02f Mon Sep 17 00:00:00 2001 From: kyriediculous Date: Wed, 12 Jun 2024 16:33:54 +0200 Subject: [PATCH 46/88] [core,server]: Orchestrator.ServeRemoteAIWorker --- core/orchestrator.go | 17 +++++++++++++++++ server/ot_rpc.go | 4 +++- server/rpc.go | 1 + 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/core/orchestrator.go b/core/orchestrator.go index 70975ff3a6..c93e92b65b 100644 --- a/core/orchestrator.go +++ b/core/orchestrator.go @@ -110,6 +110,10 @@ func (orch *orchestrator) TranscoderResults(tcID int64, res *RemoteTranscoderRes orch.node.TranscoderManager.transcoderResults(tcID, res) } +func (orch *orchestrator) ServeRemoteAIWorker(stream net.Transcoder_RegisterAIWorkerServer, capabilities *net.Capabilities) { + orch.node.serveRemoteAIWorker(stream, capabilities) +} + func (orch *orchestrator) TextToImage(ctx context.Context, req worker.TextToImageJSONRequestBody) (*worker.ImageResponse, error) { return orch.node.textToImage(ctx, req) } @@ -918,6 +922,19 @@ func (n *LivepeerNode) endTranscodingSession(sessionId string, logCtx context.Co } } +func (n *LivepeerNode) serveRemoteAIWorker(stream net.Transcoder_RegisterAIWorkerServer, capabilities *net.Capabilities) { + from := common.GetConnectionAddr(stream.Context()) + // aiCaps := CapabilitiesFromNetCapabilities(capabilities) + + // TODO: expand n.Capabilitiers with AI capabilities + // defer removing the same capabilities + + // Blocks while AIWorker is connected + n.AIManager.Manage(stream, capabilities) + glog.V(common.DEBUG).Infof("Closing AIWorker=%s channel", from) + +} + func (n *LivepeerNode) serveTranscoder(stream net.Transcoder_RegisterTranscoderServer, capacity int, capabilities *net.Capabilities) { from := common.GetConnectionAddr(stream.Context()) coreCaps := CapabilitiesFromNetCapabilities(capabilities) diff --git a/server/ot_rpc.go b/server/ot_rpc.go index bce3bae987..ef11aa292d 100644 --- a/server/ot_rpc.go +++ b/server/ot_rpc.go @@ -383,7 +383,7 @@ func (h *lphttp) RegisterRemoteAIWorker(req *net.RegisterRequest, stream net.Tra if req.Capabilities == nil { // TODO: return error No AI capabilities } - // h.orchestrator.ServeRemoteAIWorker() + h.orchestrator.ServeRemoteAIWorker(stream, req.Capabilities) return nil } @@ -407,6 +407,8 @@ func (h *lphttp) AIWorkerResults(w http.ResponseWriter, r *http.Request) { } // TODO: handle results + // Get session channel for session + // Send result over session channel } diff --git a/server/rpc.go b/server/rpc.go index 0ab18f4a19..10c3b1b11e 100644 --- a/server/rpc.go +++ b/server/rpc.go @@ -63,6 +63,7 @@ type Orchestrator interface { DebitFees(addr ethcommon.Address, manifestID core.ManifestID, price *net.PriceInfo, pixels int64) Capabilities() *net.Capabilities AuthToken(sessionID string, expiration int64) *net.AuthToken + ServeRemoteAIWorker(stream net.Transcoder_RegisterAIWorkerServer, capabilities *net.Capabilities) TextToImage(ctx context.Context, req worker.TextToImageJSONRequestBody) (*worker.ImageResponse, error) ImageToImage(ctx context.Context, req worker.ImageToImageMultipartRequestBody) (*worker.ImageResponse, error) ImageToVideo(ctx context.Context, req worker.ImageToVideoMultipartRequestBody) (*worker.ImageResponse, error) From 329f6d58c1b7cef034193a5d20bd3697fb4f4891 Mon Sep 17 00:00:00 2001 From: kyriediculous Date: Wed, 12 Jun 2024 16:34:44 +0200 Subject: [PATCH 47/88] [core,net]: RemoteAIWorkerManager task management --- core/ai.go | 39 ++++++++++- net/lp_rpc.pb.go | 177 +++++++++++++++++++++++++---------------------- net/lp_rpc.proto | 3 +- 3 files changed, 135 insertions(+), 84 deletions(-) diff --git a/core/ai.go b/core/ai.go index 5a18150887..3d452969db 100644 --- a/core/ai.go +++ b/core/ai.go @@ -54,6 +54,8 @@ func (s StringInt) String() string { return string(s) } +type RemoteAIResultChan chan interface{} + type RemoteAIWorkerManager struct { // TODO Mapping by pipeline remoteWorkers []*RemoteAIWorker @@ -62,7 +64,9 @@ type RemoteAIWorkerManager struct { // tasks // TODO: how to id tasks/sessions ? - taskMutex sync.Mutex + taskChans map[int64]RemoteAIResultChan + taskMutex sync.RWMutex + taskCount int64 } func NewRemoteAIWorkerManager() *RemoteAIWorkerManager { @@ -129,6 +133,39 @@ func (m *RemoteAIWorkerManager) HasCapacity(pipeline, modelID string) bool { return false } +func (m *RemoteAIWorkerManager) getTaskChan(taskID int64) (RemoteAIResultChan, error) { + m.taskMutex.RLock() + defer m.taskMutex.RUnlock() + if tc, ok := m.taskChans[taskID]; ok { + return tc, nil + } + return nil, fmt.Errorf("No AI job channel") +} + +func (m *RemoteAIWorkerManager) addTaskChan() (int64, RemoteAIResultChan) { + m.taskMutex.Lock() + defer m.taskMutex.Unlock() + taskID := m.taskCount + m.taskCount++ + if tc, ok := m.taskChans[taskID]; ok { + // should really never happen + glog.V(common.DEBUG).Info("AI job channel already exists for ", taskID) + return taskID, tc + } + m.taskChans[taskID] = make(RemoteAIResultChan, 1) + return taskID, m.taskChans[taskID] +} + +func (m *RemoteAIWorkerManager) removeTaskChan(taskID int64) { + m.taskMutex.Lock() + defer m.taskMutex.Unlock() + if _, ok := m.taskChans[taskID]; !ok { + glog.V(common.DEBUG).Info("Transcoder channel nonexistent for job ", taskID) + return + } + delete(m.taskChans, taskID) +} + type RemoteAIWorker struct { manager *RemoteAIWorkerManager stream net.Transcoder_RegisterAIWorkerServer diff --git a/net/lp_rpc.pb.go b/net/lp_rpc.pb.go index f4879f3e8d..eb474c6b33 100644 --- a/net/lp_rpc.pb.go +++ b/net/lp_rpc.pb.go @@ -26,6 +26,7 @@ const ( AIRequestType_TextToImage AIRequestType = 0 AIRequestType_ImageToText AIRequestType = 1 AIRequestType_ImageToImage AIRequestType = 2 + AIRequestType_Upscale AIRequestType = 3 ) // Enum value maps for AIRequestType. @@ -34,11 +35,13 @@ var ( 0: "TextToImage", 1: "ImageToText", 2: "ImageToImage", + 3: "Upscale", } AIRequestType_value = map[string]int32{ "TextToImage": 0, "ImageToText": 1, "ImageToImage": 2, + "Upscale": 3, } ) @@ -1723,8 +1726,9 @@ type NotifyAIJob struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Type AIRequestType `protobuf:"varint,1,opt,name=type,proto3,enum=net.AIRequestType" json:"type,omitempty"` - Data []byte `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"` // json + Type AIRequestType `protobuf:"varint,1,opt,name=type,proto3,enum=net.AIRequestType" json:"type,omitempty"` + TaskId int64 `protobuf:"varint,2,opt,name=taskId,proto3" json:"taskId,omitempty"` + Data []byte `protobuf:"bytes,3,opt,name=data,proto3" json:"data,omitempty"` // json } func (x *NotifyAIJob) Reset() { @@ -1766,6 +1770,13 @@ func (x *NotifyAIJob) GetType() AIRequestType { return AIRequestType_TextToImage } +func (x *NotifyAIJob) GetTaskId() int64 { + if x != nil { + return x.TaskId + } + return 0 +} + func (x *NotifyAIJob) GetData() []byte { if x != nil { return x.Data @@ -2676,89 +2687,91 @@ var file_net_lp_rpc_proto_rawDesc = []byte{ 0x74, 0x61, 0x73, 0x6b, 0x49, 0x64, 0x18, 0x10, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x74, 0x61, 0x73, 0x6b, 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, 0x49, 0x0a, 0x0b, + 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x4a, 0x04, 0x08, 0x21, 0x10, 0x22, 0x22, 0x61, 0x0a, 0x0b, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x41, 0x49, 0x4a, 0x6f, 0x62, 0x12, 0x26, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x12, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x41, 0x49, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, - 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 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, 0x2a, 0x43, 0x0a, 0x0d, 0x41, 0x49, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0f, 0x0a, 0x0b, 0x54, 0x65, 0x78, - 0x74, 0x54, 0x6f, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x49, 0x6d, - 0x61, 0x67, 0x65, 0x54, 0x6f, 0x54, 0x65, 0x78, 0x74, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x49, - 0x6d, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x10, 0x02, 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, 0x8c, 0x01, 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, 0x12, 0x3c, 0x0a, 0x10, 0x52, 0x65, 0x67, - 0x69, 0x73, 0x74, 0x65, 0x72, 0x41, 0x49, 0x57, 0x6f, 0x72, 0x6b, 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, 0x10, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, - 0x41, 0x49, 0x4a, 0x6f, 0x62, 0x30, 0x01, 0x42, 0x07, 0x5a, 0x05, 0x2e, 0x2f, 0x6e, 0x65, 0x74, - 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x61, 0x73, 0x6b, 0x49, 0x64, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x03, 0x52, 0x06, 0x74, 0x61, 0x73, 0x6b, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x64, + 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 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, + 0x2a, 0x50, 0x0a, 0x0d, 0x41, 0x49, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, + 0x65, 0x12, 0x0f, 0x0a, 0x0b, 0x54, 0x65, 0x78, 0x74, 0x54, 0x6f, 0x49, 0x6d, 0x61, 0x67, 0x65, + 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x54, 0x65, 0x78, + 0x74, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x49, 0x6d, + 0x61, 0x67, 0x65, 0x10, 0x02, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x70, 0x73, 0x63, 0x61, 0x6c, 0x65, + 0x10, 0x03, 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, 0x8c, 0x01, + 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, 0x12, 0x3c, + 0x0a, 0x10, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x41, 0x49, 0x57, 0x6f, 0x72, 0x6b, + 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, 0x10, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x4e, + 0x6f, 0x74, 0x69, 0x66, 0x79, 0x41, 0x49, 0x4a, 0x6f, 0x62, 0x30, 0x01, 0x42, 0x07, 0x5a, 0x05, + 0x2e, 0x2f, 0x6e, 0x65, 0x74, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/net/lp_rpc.proto b/net/lp_rpc.proto index 0d5f6a37b3..886918711a 100644 --- a/net/lp_rpc.proto +++ b/net/lp_rpc.proto @@ -379,7 +379,8 @@ enum AIRequestType { // Sent by the orchestrator to the remote AI worker message NotifyAIJob { AIRequestType type = 1; - bytes data = 2; // json + int64 taskId = 2; + bytes data = 3; // json } // Required parameters for probabilistic micropayment tickets From 56a4797a42180a555b39b96e9af90eef5598df5d Mon Sep 17 00:00:00 2001 From: kyriediculous Date: Wed, 12 Jun 2024 17:06:39 +0200 Subject: [PATCH 48/88] [core,server]: hander remote AI worker job results on orchestrator --- core/ai.go | 15 +++++++++++++++ core/orchestrator.go | 6 +++++- server/ot_rpc.go | 22 +++++++++++++++++++--- server/rpc.go | 1 + 4 files changed, 40 insertions(+), 4 deletions(-) diff --git a/core/ai.go b/core/ai.go index 3d452969db..db173fbf8c 100644 --- a/core/ai.go +++ b/core/ai.go @@ -68,6 +68,12 @@ type RemoteAIWorkerManager struct { taskMutex sync.RWMutex taskCount int64 } +type RemoteAIWorkerResult struct { + JobType net.AIRequestType + TaskID int64 + Bytes []byte + Err error +} func NewRemoteAIWorkerManager() *RemoteAIWorkerManager { return &RemoteAIWorkerManager{ @@ -133,6 +139,15 @@ func (m *RemoteAIWorkerManager) HasCapacity(pipeline, modelID string) bool { return false } +func (m *RemoteAIWorkerManager) aiResult(res *RemoteAIWorkerResult) { + tc, err := m.getTaskChan(res.TaskID) + if err != nil { + glog.V(common.DEBUG).Info("No AI job channel for ", res.TaskID) + return + } + tc <- res +} + func (m *RemoteAIWorkerManager) getTaskChan(taskID int64) (RemoteAIResultChan, error) { m.taskMutex.RLock() defer m.taskMutex.RUnlock() diff --git a/core/orchestrator.go b/core/orchestrator.go index c93e92b65b..ea5885c8f7 100644 --- a/core/orchestrator.go +++ b/core/orchestrator.go @@ -95,7 +95,7 @@ func (orch *orchestrator) CheckCapacity(mid ManifestID) error { // CheckAICapacity verifies if the orchestrator can process a request for a specific pipeline and modelID. func (orch *orchestrator) CheckAICapacity(pipeline, modelID string) bool { - return orch.node.AIWorker.HasCapacity(pipeline, modelID) + return true } func (orch *orchestrator) TranscodeSeg(ctx context.Context, md *SegTranscodingMetadata, seg *stream.HLSSegment) (*TranscodeResult, error) { @@ -114,6 +114,10 @@ func (orch *orchestrator) ServeRemoteAIWorker(stream net.Transcoder_RegisterAIWo orch.node.serveRemoteAIWorker(stream, capabilities) } +func (orch *orchestrator) AIResult(res *RemoteAIWorkerResult) { + orch.node.AIManager.aiResult(res) +} + func (orch *orchestrator) TextToImage(ctx context.Context, req worker.TextToImageJSONRequestBody) (*worker.ImageResponse, error) { return orch.node.textToImage(ctx, req) } diff --git a/server/ot_rpc.go b/server/ot_rpc.go index ef11aa292d..4af17b5f19 100644 --- a/server/ot_rpc.go +++ b/server/ot_rpc.go @@ -4,6 +4,7 @@ import ( "bytes" "context" "crypto/tls" + "encoding/json" "errors" "fmt" "io" @@ -389,6 +390,13 @@ func (h *lphttp) RegisterRemoteAIWorker(req *net.RegisterRequest, stream net.Tra // Orchestrator HTTP +type RemoteAIWorkerResult struct { + JobType net.AIRequestType + TaskID int64 + Bytes []byte + Err error +} + func (h *lphttp) AIWorkerResults(w http.ResponseWriter, r *http.Request) { orch := h.orchestrator @@ -406,10 +414,18 @@ func (h *lphttp) AIWorkerResults(w http.ResponseWriter, r *http.Request) { return } - // TODO: handle results - // Get session channel for session - // Send result over session channel + var req core.RemoteAIWorkerResult + if err := json.NewDecoder(r.Body).Decode(&req); err != nil { + respondWithError(w, err.Error(), http.StatusBadRequest) + return + } + + if req.Err != nil { + respondWithError(w, req.Err.Error(), http.StatusInternalServerError) + return + } + orch.AIResult(&req) } func (h *lphttp) TranscodeResults(w http.ResponseWriter, r *http.Request) { diff --git a/server/rpc.go b/server/rpc.go index 10c3b1b11e..77fdbd471a 100644 --- a/server/rpc.go +++ b/server/rpc.go @@ -64,6 +64,7 @@ type Orchestrator interface { Capabilities() *net.Capabilities AuthToken(sessionID string, expiration int64) *net.AuthToken ServeRemoteAIWorker(stream net.Transcoder_RegisterAIWorkerServer, capabilities *net.Capabilities) + AIResult(res *core.RemoteAIWorkerResult) TextToImage(ctx context.Context, req worker.TextToImageJSONRequestBody) (*worker.ImageResponse, error) ImageToImage(ctx context.Context, req worker.ImageToImageMultipartRequestBody) (*worker.ImageResponse, error) ImageToVideo(ctx context.Context, req worker.ImageToVideoMultipartRequestBody) (*worker.ImageResponse, error) From 8107959df12aa5216e914faa1d79a5369d8ffd63 Mon Sep 17 00:00:00 2001 From: kyriediculous Date: Wed, 12 Jun 2024 17:33:03 +0200 Subject: [PATCH 49/88] [core,net]: example remote AI request handling --- core/ai.go | 32 ++++++++++++++++++++++++++++++-- net/lp_rpc.pb.go | 10 +++++----- net/lp_rpc.proto | 2 +- 3 files changed, 36 insertions(+), 8 deletions(-) diff --git a/core/ai.go b/core/ai.go index db173fbf8c..a69b765bbe 100644 --- a/core/ai.go +++ b/core/ai.go @@ -54,7 +54,7 @@ func (s StringInt) String() string { return string(s) } -type RemoteAIResultChan chan interface{} +type RemoteAIResultChan chan *RemoteAIWorkerResult type RemoteAIWorkerManager struct { // TODO Mapping by pipeline @@ -108,9 +108,37 @@ func (m *RemoteAIWorkerManager) Manage(stream net.Transcoder_RegisterAIWorkerSer m.workersMutex.Unlock() } -func (m *RemoteAIWorkerManager) handleAIRequest() +func (m *RemoteAIWorkerManager) handleAIRequest(req *net.NotifyAIJob) { + // send request to selected remote worker +} func (m *RemoteAIWorkerManager) TextToImage(ctx context.Context, req worker.TextToImageJSONRequestBody) (*worker.ImageResponse, error) { + taskID, taskChan := m.addTaskChan() + defer m.removeTaskChan(taskID) + + // send request to remote worker + jsonData, err := json.Marshal(req) + if err != nil { + return nil, err + } + + remoteReq := &net.NotifyAIJob{ + Type: net.AIRequestType_TextToImage, + TaskID: taskID, + Data: jsonData, + } + m.handleAIRequest(remoteReq) // task id, pipeline + + select { + case <-ctx.Done(): + // return EOF signal + case chanData := <-taskChan: + var res worker.ImageResponse + if err := json.Unmarshal(chanData.Bytes, &res); err != nil { + return nil, err + } + return &res, nil + } return nil, nil } diff --git a/net/lp_rpc.pb.go b/net/lp_rpc.pb.go index eb474c6b33..4baca69111 100644 --- a/net/lp_rpc.pb.go +++ b/net/lp_rpc.pb.go @@ -1727,7 +1727,7 @@ type NotifyAIJob struct { unknownFields protoimpl.UnknownFields Type AIRequestType `protobuf:"varint,1,opt,name=type,proto3,enum=net.AIRequestType" json:"type,omitempty"` - TaskId int64 `protobuf:"varint,2,opt,name=taskId,proto3" json:"taskId,omitempty"` + TaskID int64 `protobuf:"varint,2,opt,name=taskID,proto3" json:"taskID,omitempty"` Data []byte `protobuf:"bytes,3,opt,name=data,proto3" json:"data,omitempty"` // json } @@ -1770,9 +1770,9 @@ func (x *NotifyAIJob) GetType() AIRequestType { return AIRequestType_TextToImage } -func (x *NotifyAIJob) GetTaskId() int64 { +func (x *NotifyAIJob) GetTaskID() int64 { if x != nil { - return x.TaskId + return x.TaskID } return 0 } @@ -2691,8 +2691,8 @@ var file_net_lp_rpc_proto_rawDesc = []byte{ 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x41, 0x49, 0x4a, 0x6f, 0x62, 0x12, 0x26, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x12, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x41, 0x49, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, - 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x61, 0x73, 0x6b, 0x49, 0x64, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x03, 0x52, 0x06, 0x74, 0x61, 0x73, 0x6b, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x64, + 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x61, 0x73, 0x6b, 0x49, 0x44, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x03, 0x52, 0x06, 0x74, 0x61, 0x73, 0x6b, 0x49, 0x44, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 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, diff --git a/net/lp_rpc.proto b/net/lp_rpc.proto index 886918711a..5147f18ea3 100644 --- a/net/lp_rpc.proto +++ b/net/lp_rpc.proto @@ -379,7 +379,7 @@ enum AIRequestType { // Sent by the orchestrator to the remote AI worker message NotifyAIJob { AIRequestType type = 1; - int64 taskId = 2; + int64 taskID = 2; bytes data = 3; // json } From 3fbdc9ac15762094996ed93164b96e929301afd5 Mon Sep 17 00:00:00 2001 From: kyriediculous Date: Wed, 12 Jun 2024 17:50:36 +0200 Subject: [PATCH 50/88] server: add aiResults route to server --- core/ai.go | 1 - server/rpc.go | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/core/ai.go b/core/ai.go index a69b765bbe..2a7f2b2dcc 100644 --- a/core/ai.go +++ b/core/ai.go @@ -63,7 +63,6 @@ type RemoteAIWorkerManager struct { workersMutex sync.Mutex // tasks - // TODO: how to id tasks/sessions ? taskChans map[int64]RemoteAIResultChan taskMutex sync.RWMutex taskCount int64 diff --git a/server/rpc.go b/server/rpc.go index 77fdbd471a..949e210ca1 100644 --- a/server/rpc.go +++ b/server/rpc.go @@ -207,6 +207,7 @@ func StartTranscodeServer(orch Orchestrator, bind string, mux *http.ServeMux, wo if acceptRemoteTranscoders { net.RegisterTranscoderServer(s, &lp) lp.transRPC.HandleFunc("/transcodeResults", lp.TranscodeResults) + lp.transRPC.HandleFunc("/aiResults", lp.AIWorkerResults) } if n.AIWorker != nil { From d2822e143e98a5a47f490959289894be2512f29d Mon Sep 17 00:00:00 2001 From: kyriediculous Date: Thu, 13 Jun 2024 14:15:56 +0200 Subject: [PATCH 51/88] [server,core]: fix RegisterAIWorker interface implementaiton --- core/ai.go | 7 +++++++ server/ot_rpc.go | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/core/ai.go b/core/ai.go index 2a7f2b2dcc..0610c8eaff 100644 --- a/core/ai.go +++ b/core/ai.go @@ -115,6 +115,9 @@ func (m *RemoteAIWorkerManager) TextToImage(ctx context.Context, req worker.Text taskID, taskChan := m.addTaskChan() defer m.removeTaskChan(taskID) + // select a remote worker + w := m.remoteWorkers[0] + // send request to remote worker jsonData, err := json.Marshal(req) if err != nil { @@ -128,6 +131,10 @@ func (m *RemoteAIWorkerManager) TextToImage(ctx context.Context, req worker.Text } m.handleAIRequest(remoteReq) // task id, pipeline + if err := w.stream.Send(remoteReq); err != nil { + return nil, err + } + select { case <-ctx.Done(): // return EOF signal diff --git a/server/ot_rpc.go b/server/ot_rpc.go index 4af17b5f19..2da3a631d5 100644 --- a/server/ot_rpc.go +++ b/server/ot_rpc.go @@ -368,7 +368,7 @@ func (h *lphttp) RegisterTranscoder(req *net.RegisterRequest, stream net.Transco return nil } -func (h *lphttp) RegisterRemoteAIWorker(req *net.RegisterRequest, stream net.Transcoder_RegisterAIWorkerServer) error { +func (h *lphttp) RegisterAIWorker(req *net.RegisterRequest, stream net.Transcoder_RegisterAIWorkerServer) error { from := common.GetConnectionAddr(stream.Context()) glog.Infof("Got a RegisterAIWorker request from transcoder=%s capacity=%d", from, req.Capacity) From ba40ec9facce1e0eece19850d7dd5777c6ccc0d4 Mon Sep 17 00:00:00 2001 From: kyriediculous Date: Fri, 21 Jun 2024 03:57:56 +0200 Subject: [PATCH 52/88] temporary models config in remote AI manager mode --- core/ai.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/ai.go b/core/ai.go index 0610c8eaff..1b41021a80 100644 --- a/core/ai.go +++ b/core/ai.go @@ -295,7 +295,7 @@ func ParseAIModelConfigs(config string) ([]AIModelConfig, error) { pipeline := parts[0] modelID := parts[1] - warm, err := strconv.ParseBool(parts[3]) + warm, err := strconv.ParseBool(parts[2]) if err != nil { return nil, err } From 28b347fe27cc4bb2b0e90515f8a97b7706210c46 Mon Sep 17 00:00:00 2001 From: kyriediculous Date: Fri, 21 Jun 2024 04:07:55 +0200 Subject: [PATCH 53/88] [core]: fix nil map error for task channels on remotee transcoder manager --- core/ai.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/core/ai.go b/core/ai.go index 1b41021a80..6f83600122 100644 --- a/core/ai.go +++ b/core/ai.go @@ -79,6 +79,10 @@ func NewRemoteAIWorkerManager() *RemoteAIWorkerManager { remoteWorkers: []*RemoteAIWorker{}, liveWorkers: map[net.Transcoder_RegisterAIWorkerServer]*RemoteAIWorker{}, workersMutex: sync.Mutex{}, + + taskChans: map[int64]RemoteAIResultChan{}, + taskMutex: sync.RWMutex{}, + taskCount: 0, } } From 8c998955675abd21c0b2efc971595e80487892e5 Mon Sep 17 00:00:00 2001 From: kyriediculous Date: Fri, 21 Jun 2024 04:16:25 +0200 Subject: [PATCH 54/88] cmd: set transcoding capabilties in remote AI mode without needing transcoder flag --- cmd/livepeer/starter/starter.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cmd/livepeer/starter/starter.go b/cmd/livepeer/starter/starter.go index d7774bb727..8aca90fd94 100755 --- a/cmd/livepeer/starter/starter.go +++ b/cmd/livepeer/starter/starter.go @@ -526,6 +526,8 @@ func StartLivepeer(ctx context.Context, cfg LivepeerConfig) { if !*cfg.AIWorker { n.AIManager = core.NewRemoteAIWorkerManager() n.AIWorker = n.AIManager + // set transcoder capabilties since we don't use transcoder flag here + transcoderCaps = append(core.DefaultCapabilities(), core.OptionalCapabilities()...) } } else if *cfg.Transcoder { n.NodeType = core.TranscoderNode From 88f8cb4f1587a96b7b39d1d8a7d94d942bc9e435 Mon Sep 17 00:00:00 2001 From: kyriediculous Date: Thu, 27 Jun 2024 12:44:53 +0200 Subject: [PATCH 55/88] wip: log received AI job on transcoder --- server/ot_rpc.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/server/ot_rpc.go b/server/ot_rpc.go index 2da3a631d5..c02174d49f 100644 --- a/server/ot_rpc.go +++ b/server/ot_rpc.go @@ -29,6 +29,7 @@ import ( "google.golang.org/grpc/credentials" "google.golang.org/grpc/status" + "github.com/livepeer/ai-worker/worker" "github.com/livepeer/go-livepeer/clog" "github.com/livepeer/go-livepeer/common" "github.com/livepeer/go-livepeer/core" @@ -153,6 +154,13 @@ func runTranscoder(n *core.LivepeerNode, orchAddr string, capacity int, caps []c go func() { for { aiJob, err := aiR.Recv() + glog.Infof("Received AI job %v type: %v", aiJob.TaskID, aiJob.Type) + var aiRequest worker.TextToImageJSONRequestBody + if err := json.Unmarshal(aiJob.Data, &aiRequest); err != nil { + glog.Errorf("Unable to unmarshal AI job data err=%q", err) + continue + } + glog.Infof("AI Job decoded model=%v prompt=%v", aiRequest.ModelId, aiRequest.Prompt) if err != nil { errChan <- err return From 69fe1feed7fe33daf7e1926ed17398c74682057a Mon Sep 17 00:00:00 2001 From: kyriediculous Date: Thu, 27 Jun 2024 13:04:39 +0200 Subject: [PATCH 56/88] wip: handle ai job on transcoder --- server/ot_rpc.go | 63 ++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 56 insertions(+), 7 deletions(-) diff --git a/server/ot_rpc.go b/server/ot_rpc.go index c02174d49f..046ada77ad 100644 --- a/server/ot_rpc.go +++ b/server/ot_rpc.go @@ -154,13 +154,7 @@ func runTranscoder(n *core.LivepeerNode, orchAddr string, capacity int, caps []c go func() { for { aiJob, err := aiR.Recv() - glog.Infof("Received AI job %v type: %v", aiJob.TaskID, aiJob.Type) - var aiRequest worker.TextToImageJSONRequestBody - if err := json.Unmarshal(aiJob.Data, &aiRequest); err != nil { - glog.Errorf("Unable to unmarshal AI job data err=%q", err) - continue - } - glog.Infof("AI Job decoded model=%v prompt=%v", aiRequest.ModelId, aiRequest.Prompt) + if err != nil { errChan <- err return @@ -188,6 +182,61 @@ func runTranscoder(n *core.LivepeerNode, orchAddr string, capacity int, caps []c glog.Error("Received nil AI job") continue } + glog.Infof("Received AI job %v type: %v", aiJob.TaskID, aiJob.Type) + var aiRequest worker.TextToImageJSONRequestBody + if err := json.Unmarshal(aiJob.Data, &aiRequest); err != nil { + glog.Errorf("Unable to unmarshal AI job data err=%q", err) + continue + } + glog.Infof("AI Job decoded model=%v prompt=%v", aiRequest.ModelId, aiRequest.Prompt) + + // Send job to worker + res, err := n.AIWorker.TextToImage(context.Background(), aiRequest) + if err != nil { + glog.Errorf("AI job failed err=%q", err) + continue + } + // marshal res to json bytes + jsonBytes, err := json.Marshal(res) + if err != nil { + glog.Errorf("Unable to marshal AI job response err=%q", err) + continue + } + + aiResult := &core.RemoteAIWorkerResult{ + JobType: aiJob.Type, + TaskID: aiJob.TaskID, + Bytes: jsonBytes, + Err: err, + } + + // Create a bytes.Buffer and write the JSON data to it + var body bytes.Buffer + jsonAiResult, err := json.Marshal(aiResult) + if err != nil { + glog.Errorf("Error marshaling JSON err=%q", err) + continue + } + body.Write(jsonAiResult) + + // Post result back to orchestrator + req, err := http.NewRequest("POST", "https://"+orchAddr+"/aiResult", &body) + if err != nil { + glog.Errorf("Error posting results to orch=%s taskId=%d type=%s err=%q", orchAddr, + aiResult.TaskID, aiResult.JobType, err) + continue + } + req.Header.Set("Authorization", protoVerLPT) + req.Header.Set("Credentials", n.OrchSecret) + req.Header.Set("Content-Type", "application/json") + + resp, err := httpc.Do(req) + if err != nil { + glog.Errorf("Error submitting results err=%q", err) + continue + } + defer resp.Body.Close() + case err := <-errChan: if err := checkTranscoderError(err); err != nil { glog.Infof(`End of stream receive cycle because of err=%q, waiting for running transcode jobs to complete`, err) From 75d57f37bf83de81eb721991e37364fb053e3bcc Mon Sep 17 00:00:00 2001 From: kyriediculous Date: Thu, 27 Jun 2024 15:24:37 +0200 Subject: [PATCH 57/88] wip: temp disable ai worker --- server/ot_rpc.go | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/server/ot_rpc.go b/server/ot_rpc.go index 046ada77ad..536ae1f797 100644 --- a/server/ot_rpc.go +++ b/server/ot_rpc.go @@ -191,11 +191,13 @@ func runTranscoder(n *core.LivepeerNode, orchAddr string, capacity int, caps []c glog.Infof("AI Job decoded model=%v prompt=%v", aiRequest.ModelId, aiRequest.Prompt) // Send job to worker - res, err := n.AIWorker.TextToImage(context.Background(), aiRequest) - if err != nil { - glog.Errorf("AI job failed err=%q", err) - continue - } + // res, err := n.AIWorker.TextToImage(context.Background(), aiRequest) + // if err != nil { + // glog.Errorf("AI job failed err=%q", err) + // continue + // } + + res := &worker.ImageResponse{} // marshal res to json bytes jsonBytes, err := json.Marshal(res) if err != nil { From 9bbbe1aec392d3652311679961a81af5a801df5b Mon Sep 17 00:00:00 2001 From: kyriediculous Date: Thu, 27 Jun 2024 15:37:02 +0200 Subject: [PATCH 58/88] wip: log ai result on orchestrator --- core/ai.go | 1 + 1 file changed, 1 insertion(+) diff --git a/core/ai.go b/core/ai.go index 6f83600122..23f87f2dc1 100644 --- a/core/ai.go +++ b/core/ai.go @@ -147,6 +147,7 @@ func (m *RemoteAIWorkerManager) TextToImage(ctx context.Context, req worker.Text if err := json.Unmarshal(chanData.Bytes, &res); err != nil { return nil, err } + glog.Infof("Received AI result for task %d images=%s", chanData.TaskID, res.Images) return &res, nil } return nil, nil From 20670449f842fd7b1b4528340c8971e18783faf1 Mon Sep 17 00:00:00 2001 From: kyriediculous Date: Thu, 27 Jun 2024 15:40:25 +0200 Subject: [PATCH 59/88] fix: post ai results to correct route --- server/ot_rpc.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/ot_rpc.go b/server/ot_rpc.go index 536ae1f797..eb6285710f 100644 --- a/server/ot_rpc.go +++ b/server/ot_rpc.go @@ -222,7 +222,7 @@ func runTranscoder(n *core.LivepeerNode, orchAddr string, capacity int, caps []c body.Write(jsonAiResult) // Post result back to orchestrator - req, err := http.NewRequest("POST", "https://"+orchAddr+"/aiResult", &body) + req, err := http.NewRequest("POST", "https://"+orchAddr+"/aiResults", &body) if err != nil { glog.Errorf("Error posting results to orch=%s taskId=%d type=%s err=%q", orchAddr, aiResult.TaskID, aiResult.JobType, err) From a8ccc5c3381d196d437b89f863cc8bf81f45b72d Mon Sep 17 00:00:00 2001 From: Reuben Rodrigues Date: Fri, 28 Jun 2024 10:56:52 +0530 Subject: [PATCH 60/88] server: image-to-image remote worker --- go.mod | 60 ++++----- go.sum | 146 +++++++++----------- net/lp_rpc.pb.go | 303 +++++++++--------------------------------- net/lp_rpc.proto | 4 +- net/lp_rpc_grpc.pb.go | 52 +++++--- server/ot_rpc.go | 64 ++++++--- 6 files changed, 239 insertions(+), 390 deletions(-) diff --git a/go.mod b/go.mod index 3f9a3a431d..bc45377d83 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ require ( github.com/cenkalti/backoff v2.2.1+incompatible github.com/ethereum/go-ethereum v1.13.5 github.com/getkin/kin-openapi v0.124.0 - github.com/golang/glog v1.1.1 + github.com/golang/glog v1.2.0 github.com/golang/mock v1.6.0 github.com/golang/protobuf v1.5.4 github.com/jaypipes/ghw v0.10.0 @@ -31,18 +31,18 @@ require ( github.com/urfave/cli v1.22.12 go.opencensus.io v0.24.0 go.uber.org/goleak v1.3.0 - golang.org/x/net v0.25.0 - google.golang.org/grpc v1.57.1 - google.golang.org/protobuf v1.33.0 + golang.org/x/net v0.26.0 + google.golang.org/grpc v1.64.0 + google.golang.org/protobuf v1.34.2 pgregory.net/rapid v1.1.0 ) require ( - cloud.google.com/go v0.110.2 // indirect - cloud.google.com/go/compute v1.20.0 // indirect + cloud.google.com/go v0.112.1 // indirect + cloud.google.com/go/compute v1.25.1 // indirect cloud.google.com/go/compute/metadata v0.2.3 // indirect - cloud.google.com/go/iam v1.1.0 // indirect - cloud.google.com/go/storage v1.30.1 // indirect + cloud.google.com/go/iam v1.1.6 // indirect + cloud.google.com/go/storage v1.38.0 // indirect github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect github.com/DataDog/zstd v1.4.5 // indirect github.com/Microsoft/go-winio v0.6.1 // indirect @@ -82,14 +82,14 @@ require ( github.com/dustin/go-humanize v1.0.1 // indirect github.com/ethereum/c-kzg-4844 v0.4.0 // indirect github.com/fatih/color v1.13.0 // indirect - github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 // indirect + github.com/felixge/httpsnoop v1.0.4 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff // indirect github.com/ghodss/yaml v1.0.0 // indirect github.com/go-chi/chi/v5 v5.0.12 // indirect github.com/go-kit/log v0.2.1 // indirect github.com/go-logfmt/logfmt v0.5.1 // indirect - github.com/go-logr/logr v1.2.4 // indirect + github.com/go-logr/logr v1.4.1 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-ole/go-ole v1.2.6 // indirect github.com/go-openapi/jsonpointer v0.20.2 // indirect @@ -102,12 +102,11 @@ require ( github.com/golang-jwt/jwt/v4 v4.5.0 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect - github.com/google/go-cmp v0.6.0 // indirect github.com/google/pprof v0.0.0-20230207041349-798e818bf904 // indirect - github.com/google/s2a-go v0.1.4 // indirect - github.com/google/uuid v1.5.0 // indirect - github.com/googleapis/enterprise-certificate-proxy v0.2.3 // indirect - github.com/googleapis/gax-go/v2 v2.10.0 // indirect + github.com/google/s2a-go v0.1.7 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect + github.com/googleapis/gax-go/v2 v2.12.2 // indirect github.com/gorilla/mux v1.8.1 // indirect github.com/gorilla/websocket v1.4.2 // indirect github.com/graph-gophers/graphql-go v1.3.0 // indirect @@ -210,28 +209,29 @@ require ( github.com/urfave/cli/v2 v2.25.7 // indirect github.com/vincent-petithory/dataurl v1.0.0 // indirect github.com/whyrusleeping/cbor-gen v0.0.0-20230418232409-daab9ece03a0 // indirect - github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect - go.opentelemetry.io/otel v1.16.0 // indirect - go.opentelemetry.io/otel/metric v1.16.0 // indirect - go.opentelemetry.io/otel/trace v1.16.0 // indirect + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 // indirect + go.opentelemetry.io/otel v1.24.0 // indirect + go.opentelemetry.io/otel/metric v1.24.0 // indirect + go.opentelemetry.io/otel/trace v1.24.0 // indirect go.uber.org/atomic v1.11.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.24.0 // indirect - golang.org/x/crypto v0.23.0 // indirect + golang.org/x/crypto v0.24.0 // indirect golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect golang.org/x/mod v0.17.0 // indirect - golang.org/x/oauth2 v0.8.0 // indirect + golang.org/x/oauth2 v0.18.0 // indirect golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.20.0 // indirect - golang.org/x/text v0.15.0 // indirect + golang.org/x/sys v0.21.0 // indirect + golang.org/x/text v0.16.0 // indirect golang.org/x/time v0.5.0 // indirect - golang.org/x/tools v0.21.0 // indirect - golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect - google.golang.org/api v0.125.0 // indirect - google.golang.org/appengine v1.6.7 // indirect - google.golang.org/genproto v0.0.0-20230530153820-e85fd2cbaebc // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20230530153820-e85fd2cbaebc // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc // indirect + golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect + golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect + google.golang.org/api v0.169.0 // indirect + google.golang.org/appengine v1.6.8 // indirect + google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240318140521-94a12d6c2237 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240624140628-dc46fd24d27d // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect diff --git a/go.sum b/go.sum index e4c680fbc8..251621f380 100644 --- a/go.sum +++ b/go.sum @@ -13,22 +13,22 @@ cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKV cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= -cloud.google.com/go v0.110.2 h1:sdFPBr6xG9/wkBbfhmUz/JmZC7X6LavQgcrVINrKiVA= -cloud.google.com/go v0.110.2/go.mod h1:k04UEeEtb6ZBRTv3dZz4CeJC3jKGxyhl0sAiVVquxiw= +cloud.google.com/go v0.112.1 h1:uJSeirPke5UNZHIb4SxfZklVSiWWVqW4oXlETwZziwM= +cloud.google.com/go v0.112.1/go.mod h1:+Vbu+Y1UU+I1rjmzeMOb/8RfkKJK2Gyxi1X6jJCZLo4= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= -cloud.google.com/go/compute v1.20.0 h1:cUOcywWuowO9It2i1KX1lIb0HH7gLv6nENKuZGnlcSo= -cloud.google.com/go/compute v1.20.0/go.mod h1:kn5BhC++qUWR/AM3Dn21myV7QbgqejW04cAOrtppaQI= +cloud.google.com/go/compute v1.25.1 h1:ZRpHJedLtTpKgr3RV1Fx23NuaAEN1Zfx9hw1u4aJdjU= +cloud.google.com/go/compute v1.25.1/go.mod h1:oopOIR53ly6viBYxaDhBfJwzUAxf1zE//uf3IB011ls= cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= -cloud.google.com/go/iam v1.1.0 h1:67gSqaPukx7O8WLLHMa0PNs3EBGd2eE4d+psbO/CO94= -cloud.google.com/go/iam v1.1.0/go.mod h1:nxdHjaKfCr7fNYx/HJMM8LgiMugmveWlkatear5gVyk= +cloud.google.com/go/iam v1.1.6 h1:bEa06k05IO4f4uJonbB5iAgKTPpABy1ayxaIZV/GHVc= +cloud.google.com/go/iam v1.1.6/go.mod h1:O0zxdPeGBoFdWW3HWmBxJsk0pfvNM/p/qa82rWOGTwI= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= @@ -38,8 +38,8 @@ cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0Zeo cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= -cloud.google.com/go/storage v1.30.1 h1:uOdMxAs8HExqBlnLtnQyP0YkvbiDpdGShGKtx6U/oNM= -cloud.google.com/go/storage v1.30.1/go.mod h1:NfxhC0UJE1aXSx7CIIbCf7y9HKT7BiccwkR7+P7gN8E= +cloud.google.com/go/storage v1.38.0 h1:Az68ZRGlnNTpIBbLjSMIV2BDcwwXYlRlQzis0llkpJg= +cloud.google.com/go/storage v1.38.0/go.mod h1:tlUADB0mAb9BgYls9lq+8MGkfzOXuLrnHXlpHmvFJoY= contrib.go.opencensus.io/exporter/prometheus v0.4.2 h1:sqfsYl5GIY/L570iT+l93ehxaWJs2/OwXtiWwew3oAg= contrib.go.opencensus.io/exporter/prometheus v0.4.2/go.mod h1:dvEHbiKmgvbr5pjaF9fpw1KeYcjrnC1J8B+JKjsZyRQ= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= @@ -81,9 +81,6 @@ github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRF github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= -github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah4HI848JfFxHt+iPb26b4zyfspmqY0/8= -github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= -github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/apapsch/go-jsonmerge/v2 v2.0.0 h1:axGnT1gRIfimI7gJifB699GoE/oq+F2MU7Dml6nw9rQ= github.com/apapsch/go-jsonmerge/v2 v2.0.0/go.mod h1:lvDnEdqiQrp0O42VQGgmlKpxL1AP2+08jFMw88y4klk= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= @@ -123,15 +120,6 @@ github.com/chzyer/test v0.0.0-20210722231415-061457976a23/go.mod h1:Q3SI9o4m/ZMn github.com/cilium/ebpf v0.7.0/go.mod h1:/oI2+1shJiTGAMgl6/RgJr36Eo1jzrRcAWbcXO2usCA= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= -github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cockroachdb/datadriven v1.0.0/go.mod h1:5Ib8Meh+jk1RlHIXej6Pzevx/NLlNvQB9pmSBZErGA4= -github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f h1:otljaYPt5hWxV3MUfO5dFPFiOXg9CyG5/kCfayTqsJ4= -github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU= -github.com/cockroachdb/errors v1.6.1/go.mod h1:tm6FTP5G81vwJ5lC0SizQo374JNCOPrHyXGitRJoDqM= github.com/cockroachdb/errors v1.8.1 h1:A5+txlVZfOqFBDa4mGz2bUWSp0aHElvHX2bKkdbQu+Y= github.com/cockroachdb/errors v1.8.1/go.mod h1:qGwQn6JmZ+oMjuLwjWzUNqblqk0xl4CVV3SQbGwK7Ac= github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f h1:o/kfcElHqOiXqcou5a3rIlMc7oJbMQkeLk0VQJ7zgqY= @@ -217,8 +205,6 @@ github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZi github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= -github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= -github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw= github.com/ethereum/c-kzg-4844 v0.4.0 h1:3MS1s4JtA868KpJxroZoepdV0ZKBp3u/O5HcZ7R3nlY= @@ -228,7 +214,8 @@ github.com/ethereum/go-ethereum v1.13.5/go.mod h1:yMTu38GSuyxaYzQMViqNmQ1s3cE84a github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8= github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= -github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= +github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= +github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 h1:FtmdgXiUlNeRsoNMFlKLDt+S+6hbjVMEW6RGQ7aUf7c= github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= github.com/flosch/pongo2 v0.0.0-20190707114632-bbf5a6c351f4/go.mod h1:T9YF2M40nIgbVgp3rreNmTged+9HrbNTIQf1PsaIiTA= @@ -272,8 +259,8 @@ github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG github.com/go-logfmt/logfmt v0.5.1 h1:otpy5pqBCBZ1ng9RQ0dPu4PN7ba75Y/aA+UpowDyNVA= github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= -github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= +github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= @@ -319,8 +306,8 @@ github.com/gogo/status v1.1.0/go.mod h1:BFv9nrluPLmrS0EmGVvLaPNmRosr9KapBYd5/hpY github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/glog v1.1.1 h1:jxpi2eWoU84wbX9iIEyAeeoac3FLuifZpY9tcNUD9kw= -github.com/golang/glog v1.1.1/go.mod h1:zR+okUeTbrL6EL3xHUDxZuEtGv04p5shwip1+mL/rLQ= +github.com/golang/glog v1.2.0 h1:uCdmnmatrKCgMBlM4rMuJZWOkPDqdbZPnrMXDY4gI68= +github.com/golang/glog v1.2.0/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -392,18 +379,18 @@ github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20230207041349-798e818bf904 h1:4/hN5RUoecvl+RmJRE2YxKWtnnQls6rQjjW5oV7qg2U= github.com/google/pprof v0.0.0-20230207041349-798e818bf904/go.mod h1:uglQLonpP8qtYCYyzA+8c/9qtqgA3qsXGYqCPKARAFg= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/s2a-go v0.1.4 h1:1kZ/sQM3srePvKs3tXAvQzo66XfcReoqFpIpIccE7Oc= -github.com/google/s2a-go v0.1.4/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A= +github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o= +github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw= github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU= -github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/googleapis/enterprise-certificate-proxy v0.2.3 h1:yk9/cqRKtT9wXZSsRH9aurXEpJX+U6FLtpYTdC3R06k= -github.com/googleapis/enterprise-certificate-proxy v0.2.3/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfFxPRy3Bf7vr3h0cechB90XaQs= +github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/googleapis/gax-go/v2 v2.10.0 h1:ebSgKfMxynOdxw8QQuFOKMgomqeLGPqNLQox2bo42zg= -github.com/googleapis/gax-go/v2 v2.10.0/go.mod h1:4UOEnMCrxsSqQ940WnTiD6qJ63le2ev3xfyagutxiPw= +github.com/googleapis/gax-go/v2 v2.12.2 h1:mhN09QQW1jEWeMF74zGR81R30z4VJzjZsfkUhuHF+DA= +github.com/googleapis/gax-go/v2 v2.12.2/go.mod h1:61M8vcyyXR2kqKFxKrfA22jaA8JGF7Dc8App1U3H6jc= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= @@ -414,9 +401,6 @@ github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWS github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/graph-gophers/graphql-go v1.3.0 h1:Eb9x/q6MFpCLz7jBCiP/WTxjSDrYLR1QY41SORZyNJ0= -github.com/graph-gophers/graphql-go v1.3.0/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc= -github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= github.com/hashicorp/go-bexpr v0.1.10 h1:9kuI5PFotCboP3dkDYFr/wi0gg0QVbSNz5oFRpxn4uE= @@ -850,7 +834,6 @@ github.com/rabbitmq/rabbitmq-stream-go-client v1.1.1 h1:Fji7RgmMggroffCyL0QtrhMx github.com/rabbitmq/rabbitmq-stream-go-client v1.1.1/go.mod h1:2pRPe6/8y2ZenIbnucUULMhfrPpzM90EPfjOkpsedVo= github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= -github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= @@ -906,7 +889,6 @@ github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= @@ -984,13 +966,18 @@ go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/otel v1.16.0 h1:Z7GVAX/UkAXPKsy94IU+i6thsQS4nb7LviLpnaNeW8s= -go.opentelemetry.io/otel v1.16.0/go.mod h1:vl0h9NUa1D5s1nv3A5vZOYWn8av4K8Ml6JDeHrT/bx4= -go.opentelemetry.io/otel/metric v1.16.0 h1:RbrpwVG1Hfv85LgnZ7+txXioPDoh6EdbZHo26Q3hqOo= -go.opentelemetry.io/otel/metric v1.16.0/go.mod h1:QE47cpOmkwipPiefDwo2wDzwJrlfxxNYodqc4xnGCo4= -go.opentelemetry.io/otel/trace v1.16.0 h1:8JRpaObFoW0pxuVPapkgH8UhHQj+bJW8jJsCZEu5MQs= -go.opentelemetry.io/otel/trace v1.16.0/go.mod h1:Yt9vYq1SdNz3xdjZZK7wcXv1qv2pwLkqr2QVwea0ef0= -go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 h1:4Pp6oUg3+e/6M4C0A/3kJ2VYa++dsWVTtGgLVj5xtHg= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0/go.mod h1:Mjt1i1INqiaoZOMGR1RIUJN+i3ChKoFRqzrRQhlkbs0= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 h1:jq9TW8u3so/bN+JPT166wjOI6/vQPF6Xe7nMNIltagk= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0/go.mod h1:p8pYQP+m5XfbZm9fxtSKAbM6oIllS7s2AfxrChvc7iw= +go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo= +go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo= +go.opentelemetry.io/otel/metric v1.24.0 h1:6EhoGWWK28x1fbpA4tYTOWBkPefTDQnb8WSGXlc88kI= +go.opentelemetry.io/otel/metric v1.24.0/go.mod h1:VYhLe1rFfxuTXLgj4CBiyz+9WYBA8pNGJgDcSFRKBco= +go.opentelemetry.io/otel/sdk v1.22.0 h1:6coWHw9xw7EfClIC/+O31R8IY3/+EiRFHevmHafB2Gw= +go.opentelemetry.io/otel/sdk v1.22.0/go.mod h1:iu7luyVGYovrRpe2fmj3CVKouQNdTOkxtLzPvPz1DOc= +go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y1YELI= +go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= @@ -1022,9 +1009,8 @@ golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= -golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= +golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI= +golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1102,13 +1088,12 @@ golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= -golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= -golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= +golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= +golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1116,8 +1101,8 @@ golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4Iltr golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= -golang.org/x/oauth2 v0.8.0 h1:6dkIjl3j3LtZ/O3sTgZTMsLKSftL/B8Zgq4huOIIUu8= -golang.org/x/oauth2 v0.8.0/go.mod h1:yr7u4HXZRm1R1kBWqr/xKNqewf0plRYoB7sla+BCIXE= +golang.org/x/oauth2 v0.18.0 h1:09qnuIAgzdx1XplqJvW6CQqMCtGZykZWcXzPMPUusvI= +golang.org/x/oauth2 v0.18.0/go.mod h1:Wf7knwG0MPoWIMMBgFlEaSUDaKskp0dCfrlJRJXbBi8= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1209,8 +1194,8 @@ golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= -golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= +golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -1225,8 +1210,8 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= -golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= +golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1287,14 +1272,14 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.21.0 h1:qc0xYgIbsSDt9EyWz05J5wfa7LOVW0YTLOXrqdLAWIw= -golang.org/x/tools v0.21.0/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= +golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg= +golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk= -golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 h1:+cNy6SZtPcJQH3LJVLOSmiC7MMxXNOb3PU/VUEz+EhU= +golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= @@ -1311,17 +1296,16 @@ google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0M google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= -google.golang.org/api v0.125.0 h1:7xGvEY4fyWbhWMHf3R2/4w7L4fXyfpRGE9g6lp8+DCk= -google.golang.org/api v0.125.0/go.mod h1:mBwVAtz+87bEN6CbA1GtZPDOqY2R5ONPqJeIlvyo4Aw= +google.golang.org/api v0.169.0 h1:QwWPy71FgMWqJN/l6jVlFHUa29a7dcUy02I8o799nPY= +google.golang.org/api v0.169.0/go.mod h1:gpNOiMA2tZ4mf5R9Iwf4rK/Dcz0fbdIgWYWVoxmsyLg= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= -google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/genproto v0.0.0-20180518175338-11a468237815/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= +google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= @@ -1345,20 +1329,18 @@ google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfG google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20230530153820-e85fd2cbaebc h1:8DyZCyvI8mE1IdLy/60bS+52xfymkE72wv1asokgtao= -google.golang.org/genproto v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:xZnkP7mREFX5MORlOPEzLMr+90PPZQ2QWzrVTWfAq64= -google.golang.org/genproto/googleapis/api v0.0.0-20230530153820-e85fd2cbaebc h1:kVKPf/IiYSBWEWtkIn6wZXwWGCnLKcC8oWfZvXjsGnM= -google.golang.org/genproto/googleapis/api v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc h1:XSJ8Vk1SWuNr8S18z1NZSziL0CPIXLCCMDOEFtHBOFc= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= -google.golang.org/grpc v1.12.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= +google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 h1:9+tzLLstTlPTRyJTh+ah5wIMsBW5c4tQwGTN3thOW9Y= +google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9/go.mod h1:mqHbVIp48Muh7Ywss/AD6I5kNVKZMmAa/QEW58Gxp2s= +google.golang.org/genproto/googleapis/api v0.0.0-20240318140521-94a12d6c2237 h1:RFiFrvy37/mpSpdySBDrUdipW/dHwsRwh3J3+A9VgT4= +google.golang.org/genproto/googleapis/api v0.0.0-20240318140521-94a12d6c2237/go.mod h1:Z5Iiy3jtmioajWHDGFk7CeugTyHtPvMHA4UTmUkyalE= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240624140628-dc46fd24d27d h1:k3zyW3BYYR30e8v3x0bTDdE9vpYFjZHK+HcyqkrppWk= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240624140628-dc46fd24d27d/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= @@ -1372,12 +1354,9 @@ google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKa google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= -google.golang.org/grpc v1.57.1 h1:upNTNqv0ES+2ZOOqACwVtS3Il8M12/+Hz41RCPzAjQg= -google.golang.org/grpc v1.57.1/go.mod h1:Sd+9RMTACXwmub0zcNY2c4arhtrbBYD1AUHI/dt16Mo= +google.golang.org/grpc v1.64.0 h1:KH3VH9y/MgNQg1dE7b3XfVK0GsPSIzJwdF617gUSbvY= +google.golang.org/grpc v1.64.0/go.mod h1:oxjF8E3FBnjp+/gVFYdWacaLDx9na1aqy9oovLpxQYg= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -1393,8 +1372,8 @@ google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= -google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= +google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -1415,7 +1394,6 @@ gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWD gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0/go.mod h1:WDnlLJ4WF5VGsH/HVa3CI79GS0ol3YnhVnKP89i0kNg= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/net/lp_rpc.pb.go b/net/lp_rpc.pb.go index 4baca69111..3fb4a54d50 100644 --- a/net/lp_rpc.pb.go +++ b/net/lp_rpc.pb.go @@ -1,4 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.34.2 +// protoc v5.27.1 // source: net/lp_rpc.proto package net @@ -24,8 +27,8 @@ type AIRequestType int32 const ( AIRequestType_TextToImage AIRequestType = 0 - AIRequestType_ImageToText AIRequestType = 1 - AIRequestType_ImageToImage AIRequestType = 2 + AIRequestType_ImageToImage AIRequestType = 1 + AIRequestType_ImageToVideo AIRequestType = 2 AIRequestType_Upscale AIRequestType = 3 ) @@ -33,14 +36,14 @@ const ( var ( AIRequestType_name = map[int32]string{ 0: "TextToImage", - 1: "ImageToText", - 2: "ImageToImage", + 1: "ImageToImage", + 2: "ImageToVideo", 3: "Upscale", } AIRequestType_value = map[string]int32{ "TextToImage": 0, - "ImageToText": 1, - "ImageToImage": 2, + "ImageToImage": 1, + "ImageToVideo": 2, "Upscale": 3, } ) @@ -96,8 +99,6 @@ func (x OSInfo_StorageType) String() string { return proto.EnumName(OSInfo_StorageType_name, int32(x)) } -<<<<<<< HEAD -======= func (OSInfo_StorageType) Descriptor() protoreflect.EnumDescriptor { return file_net_lp_rpc_proto_enumTypes[1].Descriptor() } @@ -111,7 +112,6 @@ func (x OSInfo_StorageType) Number() protoreflect.EnumNumber { } // Deprecated: Use OSInfo_StorageType.Descriptor instead. ->>>>>>> 703455f1 ([net,server]: RemoteAIWorker gRPC) func (OSInfo_StorageType) EnumDescriptor() ([]byte, []int) { return fileDescriptor_034e29c79f9ba827, []int{4, 0} } @@ -185,8 +185,6 @@ func (x VideoProfile_Profile) String() string { return proto.EnumName(VideoProfile_Profile_name, int32(x)) } -<<<<<<< HEAD -======= func (VideoProfile_Profile) Descriptor() protoreflect.EnumDescriptor { return file_net_lp_rpc_proto_enumTypes[3].Descriptor() } @@ -200,7 +198,6 @@ func (x VideoProfile_Profile) Number() protoreflect.EnumNumber { } // Deprecated: Use VideoProfile_Profile.Descriptor instead. ->>>>>>> 703455f1 ([net,server]: RemoteAIWorker gRPC) func (VideoProfile_Profile) EnumDescriptor() ([]byte, []int) { return fileDescriptor_034e29c79f9ba827, []int{12, 1} } @@ -232,8 +229,6 @@ func (x VideoProfile_VideoCodec) String() string { return proto.EnumName(VideoProfile_VideoCodec_name, int32(x)) } -<<<<<<< HEAD -======= func (VideoProfile_VideoCodec) Descriptor() protoreflect.EnumDescriptor { return file_net_lp_rpc_proto_enumTypes[4].Descriptor() } @@ -247,7 +242,6 @@ func (x VideoProfile_VideoCodec) Number() protoreflect.EnumNumber { } // Deprecated: Use VideoProfile_VideoCodec.Descriptor instead. ->>>>>>> 703455f1 ([net,server]: RemoteAIWorker gRPC) func (VideoProfile_VideoCodec) EnumDescriptor() ([]byte, []int) { return fileDescriptor_034e29c79f9ba827, []int{12, 2} } @@ -276,8 +270,6 @@ func (x VideoProfile_ChromaSubsampling) String() string { return proto.EnumName(VideoProfile_ChromaSubsampling_name, int32(x)) } -<<<<<<< HEAD -======= func (VideoProfile_ChromaSubsampling) Descriptor() protoreflect.EnumDescriptor { return file_net_lp_rpc_proto_enumTypes[5].Descriptor() } @@ -291,7 +283,6 @@ func (x VideoProfile_ChromaSubsampling) Number() protoreflect.EnumNumber { } // Deprecated: Use VideoProfile_ChromaSubsampling.Descriptor instead. ->>>>>>> 703455f1 ([net,server]: RemoteAIWorker gRPC) func (VideoProfile_ChromaSubsampling) EnumDescriptor() ([]byte, []int) { return fileDescriptor_034e29c79f9ba827, []int{12, 3} } @@ -1807,13 +1798,6 @@ type TicketParams struct { XXX_sizecache int32 `json:"-"` } -<<<<<<< HEAD -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 { @@ -1844,7 +1828,6 @@ func (x *TicketParams) ProtoReflect() protoreflect.Message { // Deprecated: Use TicketParams.ProtoReflect.Descriptor instead. func (*TicketParams) Descriptor() ([]byte, []int) { return file_net_lp_rpc_proto_rawDescGZIP(), []int{19} ->>>>>>> 703455f1 ([net,server]: RemoteAIWorker gRPC) } func (m *TicketParams) XXX_Unmarshal(b []byte) error { @@ -1926,13 +1909,6 @@ type TicketSenderParams struct { XXX_sizecache int32 `json:"-"` } -<<<<<<< HEAD -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 { @@ -1963,7 +1939,6 @@ func (x *TicketSenderParams) ProtoReflect() protoreflect.Message { // Deprecated: Use TicketSenderParams.ProtoReflect.Descriptor instead. func (*TicketSenderParams) Descriptor() ([]byte, []int) { return file_net_lp_rpc_proto_rawDescGZIP(), []int{20} ->>>>>>> 703455f1 ([net,server]: RemoteAIWorker gRPC) } func (m *TicketSenderParams) XXX_Unmarshal(b []byte) error { @@ -2009,13 +1984,6 @@ type TicketExpirationParams struct { XXX_sizecache int32 `json:"-"` } -<<<<<<< HEAD -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 { @@ -2046,7 +2014,6 @@ func (x *TicketExpirationParams) ProtoReflect() protoreflect.Message { // Deprecated: Use TicketExpirationParams.ProtoReflect.Descriptor instead. func (*TicketExpirationParams) Descriptor() ([]byte, []int) { return file_net_lp_rpc_proto_rawDescGZIP(), []int{21} ->>>>>>> 703455f1 ([net,server]: RemoteAIWorker gRPC) } func (m *TicketExpirationParams) XXX_Unmarshal(b []byte) error { @@ -2100,13 +2067,6 @@ type Payment struct { XXX_sizecache int32 `json:"-"` } -<<<<<<< HEAD -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 { @@ -2137,7 +2097,6 @@ func (x *Payment) ProtoReflect() protoreflect.Message { // Deprecated: Use Payment.ProtoReflect.Descriptor instead. func (*Payment) Descriptor() ([]byte, []int) { return file_net_lp_rpc_proto_rawDescGZIP(), []int{22} ->>>>>>> 703455f1 ([net,server]: RemoteAIWorker gRPC) } func (m *Payment) XXX_Unmarshal(b []byte) error { @@ -2229,141 +2188,6 @@ func init() { proto.RegisterType((*Payment)(nil), "net.Payment") } -<<<<<<< HEAD -func init() { - proto.RegisterFile("net/lp_rpc.proto", fileDescriptor_034e29c79f9ba827) -} - -var fileDescriptor_034e29c79f9ba827 = []byte{ - // 2021 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x58, 0xdd, 0x72, 0xdb, 0xc6, - 0xf5, 0x17, 0x3f, 0xc4, 0x8f, 0x43, 0x52, 0x82, 0xd6, 0x96, 0x0c, 0x33, 0x76, 0xfe, 0x32, 0x12, - 0xe5, 0xef, 0xcc, 0xd4, 0x8a, 0x87, 0x92, 0x9d, 0xb8, 0x33, 0x99, 0x56, 0x1f, 0xb4, 0xc4, 0xd4, - 0x92, 0x38, 0x4b, 0xd9, 0x33, 0xed, 0x45, 0x59, 0x08, 0x58, 0x92, 0xa8, 0x48, 0x00, 0x5a, 0x2c, - 0x63, 0x29, 0xd3, 0x17, 0xe8, 0x23, 0xb4, 0x37, 0x9d, 0xe9, 0x4c, 0x9f, 0xa0, 0x2f, 0xd0, 0x07, - 0xe8, 0x03, 0xf4, 0x41, 0x7a, 0xdf, 0xce, 0x9e, 0x5d, 0x80, 0x80, 0x48, 0x27, 0xaa, 0xef, 0xf6, - 0x7c, 0xee, 0xd9, 0xb3, 0x67, 0x7f, 0xe7, 0x00, 0x60, 0xf8, 0x4c, 0x7c, 0x35, 0x0e, 0xfb, 0x3c, - 0x74, 0xb6, 0x43, 0x1e, 0x88, 0x80, 0x14, 0x7c, 0x26, 0xac, 0x4d, 0xa8, 0x74, 0x3d, 0x7f, 0xd8, - 0x0d, 0xfc, 0x21, 0xb9, 0x0f, 0xcb, 0xdf, 0xdb, 0xe3, 0x29, 0x33, 0x73, 0x9b, 0xb9, 0xa7, 0x75, - 0xaa, 0x08, 0xeb, 0x04, 0x1e, 0xb5, 0x7d, 0xf7, 0x9c, 0xdb, 0x7e, 0xe4, 0x04, 0xae, 0xe7, 0x0f, - 0x7b, 0x2c, 0x8a, 0xbc, 0xc0, 0xa7, 0xec, 0x6a, 0xca, 0x22, 0x41, 0x9e, 0x01, 0xd8, 0x53, 0x31, - 0xea, 0x8b, 0xe0, 0x92, 0xf9, 0x68, 0x5a, 0x6b, 0xad, 0x6c, 0xfb, 0x4c, 0x6c, 0xef, 0x4d, 0xc5, - 0xe8, 0x5c, 0x72, 0x69, 0xd5, 0x8e, 0x97, 0xd6, 0xff, 0xc1, 0xe3, 0x0f, 0xb8, 0x8b, 0xc2, 0xc0, - 0x8f, 0x98, 0x75, 0x0d, 0xf7, 0xce, 0xb8, 0x33, 0x62, 0x91, 0xe0, 0xb6, 0x08, 0x78, 0xbc, 0x8d, - 0x09, 0x65, 0xdb, 0x75, 0x39, 0x8b, 0x22, 0x1d, 0x5e, 0x4c, 0x12, 0x03, 0x0a, 0x91, 0x37, 0x34, - 0xf3, 0xc8, 0x95, 0x4b, 0xf2, 0x02, 0xea, 0x8e, 0x1d, 0xda, 0x17, 0xde, 0xd8, 0x13, 0x1e, 0x8b, - 0xcc, 0x02, 0x06, 0xb5, 0x86, 0x41, 0x1d, 0xa4, 0x04, 0x34, 0xa3, 0x66, 0xfd, 0x29, 0x07, 0xa5, - 0xb3, 0x5e, 0xc7, 0x1f, 0x04, 0xe4, 0x15, 0xd4, 0x22, 0x11, 0x70, 0x7b, 0xc8, 0xce, 0x6f, 0x42, - 0x95, 0x90, 0x95, 0xd6, 0x03, 0x74, 0xa0, 0x34, 0xb6, 0x7b, 0x33, 0x31, 0x4d, 0xeb, 0x92, 0x2d, - 0x28, 0x45, 0x3b, 0x9e, 0x3f, 0x08, 0x4c, 0x03, 0xb7, 0x6d, 0xa0, 0x55, 0x6f, 0x47, 0xd9, 0x51, - 0x2d, 0xb4, 0x9e, 0x41, 0x2d, 0xe5, 0x82, 0x00, 0x94, 0x0e, 0x3b, 0xb4, 0x7d, 0x70, 0x6e, 0x2c, - 0x91, 0x12, 0xe4, 0x7b, 0x3b, 0x46, 0x4e, 0xf2, 0x8e, 0xce, 0xce, 0x8e, 0xde, 0xb4, 0x8d, 0xbc, - 0xf5, 0xd7, 0x1c, 0x54, 0x62, 0x1f, 0x84, 0x40, 0x71, 0x14, 0x44, 0x02, 0xc3, 0xaa, 0x52, 0x5c, - 0xcb, 0x2c, 0x5c, 0xb2, 0x1b, 0xcc, 0x42, 0x95, 0xca, 0x25, 0xd9, 0x80, 0x52, 0x18, 0x8c, 0x3d, - 0xe7, 0x06, 0xcf, 0x5f, 0xa5, 0x9a, 0x22, 0x8f, 0xa0, 0x1a, 0x79, 0x43, 0xdf, 0x16, 0x53, 0xce, - 0xcc, 0x22, 0x8a, 0x66, 0x0c, 0xf2, 0x29, 0x80, 0xc3, 0x99, 0xcb, 0x7c, 0xe1, 0xd9, 0x63, 0x73, - 0x19, 0xc5, 0x29, 0x0e, 0x69, 0x42, 0xe5, 0x7a, 0x6f, 0xf2, 0xc3, 0xa1, 0x2d, 0x98, 0x59, 0x42, - 0x69, 0x42, 0x5b, 0x6f, 0xa1, 0xda, 0xe5, 0x9e, 0xc3, 0x30, 0x48, 0x0b, 0xea, 0xa1, 0x24, 0xba, - 0x8c, 0xbf, 0xf5, 0x3d, 0x15, 0x6c, 0x81, 0x66, 0x78, 0xe4, 0x73, 0x68, 0x84, 0xde, 0x35, 0x1b, - 0x47, 0xb1, 0x52, 0x1e, 0x95, 0xb2, 0x4c, 0xeb, 0xef, 0x25, 0xa8, 0xa7, 0xaf, 0x4d, 0x9e, 0xe0, - 0xc2, 0x13, 0x91, 0xe0, 0x9e, 0x3f, 0x34, 0x73, 0x9b, 0x85, 0xa7, 0x45, 0x3a, 0x63, 0x90, 0x4d, - 0xa8, 0x4d, 0x6c, 0xdf, 0x95, 0xc5, 0x23, 0x2f, 0x3f, 0x8f, 0xf2, 0x34, 0x8b, 0xec, 0x01, 0xc8, - 0x8b, 0x77, 0xe2, 0xea, 0x28, 0x3c, 0xad, 0xb5, 0x9e, 0xcc, 0x55, 0x07, 0x12, 0x4a, 0xa7, 0xed, - 0x0b, 0x7e, 0x43, 0x53, 0x46, 0xb2, 0x1c, 0xbf, 0x67, 0x5c, 0x16, 0xae, 0x4e, 0x61, 0x4c, 0x92, - 0x5f, 0x40, 0xcd, 0x09, 0x7c, 0x59, 0xbd, 0x9e, 0x2f, 0x22, 0xcc, 0x60, 0xad, 0xf5, 0x78, 0x81, - 0xf7, 0x99, 0x12, 0x4d, 0x5b, 0x90, 0x0b, 0x58, 0x4f, 0xca, 0xf2, 0x26, 0xa5, 0x65, 0x96, 0x30, - 0xd0, 0x9f, 0x2d, 0x0e, 0x74, 0x4e, 0x5d, 0xc5, 0xbc, 0xd8, 0x55, 0xf3, 0x5b, 0x58, 0xbd, 0x75, - 0xba, 0xb8, 0x80, 0xe4, 0x35, 0x35, 0x54, 0x01, 0x25, 0x78, 0x90, 0x47, 0x9e, 0x22, 0x7e, 0x9e, - 0xff, 0x26, 0xd7, 0x7c, 0x06, 0xb5, 0x94, 0x37, 0x59, 0x33, 0x13, 0xcf, 0x7f, 0xa7, 0xf3, 0xa1, - 0xaa, 0x32, 0xc5, 0x69, 0xfe, 0x27, 0x07, 0xeb, 0x0b, 0x63, 0x24, 0xbf, 0x82, 0xd2, 0x24, 0x70, - 0xd9, 0x38, 0xc2, 0x6b, 0xac, 0xb5, 0x76, 0xee, 0x78, 0xb8, 0xed, 0x13, 0xb4, 0x52, 0x67, 0xd4, - 0x2e, 0x9a, 0x5b, 0xb0, 0x8a, 0xec, 0x99, 0x9e, 0x7c, 0x29, 0xef, 0x6d, 0x3e, 0xc1, 0x98, 0x2a, - 0x14, 0xd7, 0x4d, 0x0e, 0xb5, 0x94, 0x75, 0xfa, 0xdc, 0xfa, 0xe1, 0x9c, 0xa4, 0xcf, 0x5d, 0x6b, - 0x7d, 0xfd, 0x3f, 0xc5, 0x34, 0x63, 0xa4, 0x13, 0x76, 0x05, 0xcd, 0x0f, 0x5f, 0xd2, 0x82, 0xd4, - 0x7f, 0x9b, 0x0d, 0xe1, 0xff, 0xef, 0x18, 0x42, 0x6a, 0x4b, 0xeb, 0x1f, 0x79, 0x30, 0xd2, 0x40, - 0x8a, 0x8f, 0xf2, 0x53, 0x00, 0xa1, 0xa1, 0x97, 0xf1, 0xf8, 0xa6, 0x66, 0x1c, 0xf2, 0x12, 0x1a, - 0xc2, 0x73, 0x2e, 0x99, 0xe8, 0x87, 0x36, 0xb7, 0x27, 0x91, 0xde, 0x5f, 0x41, 0xe7, 0x39, 0x4a, - 0xba, 0x28, 0xa0, 0x75, 0x91, 0xa2, 0x64, 0x13, 0xc0, 0x87, 0xdd, 0x47, 0xe0, 0x2b, 0xa4, 0x9a, - 0x40, 0x02, 0x08, 0xb4, 0x1a, 0x26, 0xd8, 0x90, 0x02, 0xf3, 0x62, 0x16, 0xcc, 0x6f, 0x43, 0xf7, - 0xf2, 0x9d, 0xa0, 0xfb, 0x56, 0x13, 0x2a, 0xfd, 0x44, 0x13, 0x22, 0x5b, 0x50, 0xd6, 0x90, 0x6d, - 0x6e, 0x62, 0xdd, 0xd5, 0x52, 0xd0, 0x4e, 0x63, 0x99, 0xf5, 0x3b, 0xa8, 0x26, 0xe6, 0xf2, 0x35, - 0xcc, 0x5a, 0x5c, 0x9d, 0x2a, 0x82, 0x3c, 0x06, 0x88, 0x54, 0x03, 0xeb, 0x7b, 0xae, 0x46, 0xdf, - 0xaa, 0xe6, 0x74, 0x5c, 0x99, 0x6f, 0x76, 0x1d, 0x7a, 0xdc, 0x16, 0xf2, 0x65, 0x14, 0x10, 0xdd, - 0x52, 0x1c, 0xeb, 0xdf, 0x45, 0x28, 0xf7, 0xd8, 0xf0, 0xd0, 0x16, 0x36, 0xbe, 0x22, 0xdb, 0xf7, - 0x06, 0x2c, 0x12, 0x1d, 0x57, 0xef, 0x92, 0xe2, 0x60, 0x9f, 0x63, 0x57, 0x1a, 0x22, 0xe5, 0x12, - 0xfb, 0x80, 0x1d, 0x8d, 0xd0, 0x6f, 0x9d, 0xe2, 0x5a, 0xe2, 0x73, 0xc8, 0x83, 0x81, 0x37, 0x66, - 0x71, 0x6e, 0x13, 0x3a, 0xee, 0x94, 0xcb, 0xb3, 0x4e, 0xd9, 0x84, 0x8a, 0x3b, 0xd5, 0xd1, 0xc9, - 0xac, 0x2d, 0xd3, 0x84, 0x9e, 0xbb, 0x8a, 0xf2, 0xc7, 0x5c, 0x45, 0xe5, 0xa7, 0xae, 0xe2, 0x39, - 0xdc, 0x77, 0xec, 0xb1, 0xd3, 0x0f, 0x19, 0x77, 0x58, 0x28, 0xa6, 0xf6, 0xb8, 0x8f, 0x67, 0x02, - 0x7c, 0xb1, 0x44, 0xca, 0xba, 0x89, 0xe8, 0x58, 0x9e, 0xf0, 0x6e, 0x97, 0x27, 0xc3, 0x1f, 0x4c, - 0xc7, 0xe3, 0x6e, 0x9c, 0x8c, 0x27, 0xa8, 0xab, 0xc2, 0x7f, 0xe7, 0xb9, 0x2c, 0xd0, 0x12, 0x9a, - 0x51, 0x23, 0x5f, 0x43, 0x23, 0x4d, 0xb7, 0x4c, 0xeb, 0x43, 0x76, 0x59, 0xbd, 0xdb, 0x86, 0x3b, - 0xe6, 0x67, 0x77, 0x32, 0xdc, 0x21, 0x7b, 0x40, 0x22, 0x36, 0x9c, 0x30, 0x5f, 0x3f, 0x3a, 0x26, - 0x18, 0x8f, 0xcc, 0x2d, 0x4c, 0x1c, 0x51, 0xc3, 0x03, 0x1b, 0x76, 0x13, 0x09, 0x5d, 0xd3, 0xda, - 0x33, 0x16, 0xd9, 0x06, 0xf2, 0x3a, 0xe0, 0x0e, 0x4b, 0x66, 0x29, 0x4f, 0x36, 0xd3, 0x2f, 0x54, - 0x0a, 0xe7, 0x25, 0xd6, 0x0e, 0x34, 0x32, 0x3e, 0x65, 0x25, 0x0d, 0x78, 0xa0, 0x70, 0xb2, 0x48, - 0x71, 0x4d, 0x56, 0x20, 0x2f, 0x02, 0x2c, 0xb7, 0x22, 0xcd, 0x8b, 0xc0, 0xfa, 0xe7, 0x32, 0xd4, - 0xd3, 0xe7, 0x90, 0x46, 0xbe, 0x3d, 0x61, 0x38, 0xe7, 0x54, 0x29, 0xae, 0xe5, 0x2b, 0x79, 0xef, - 0xb9, 0x62, 0x64, 0xae, 0x61, 0x35, 0x29, 0x42, 0x8e, 0x22, 0x23, 0xe6, 0x0d, 0x47, 0xc2, 0x24, - 0xc8, 0xd6, 0x94, 0xc4, 0x81, 0x0b, 0x4f, 0xc2, 0x13, 0x33, 0xef, 0xa1, 0x20, 0x26, 0x65, 0xa9, - 0x0e, 0xc2, 0xc8, 0xbc, 0xaf, 0x20, 0x71, 0x10, 0x46, 0xe4, 0x39, 0x94, 0x06, 0x01, 0x9f, 0xd8, - 0xc2, 0x5c, 0xc7, 0x69, 0xcc, 0x9c, 0x4b, 0xec, 0xf6, 0x6b, 0x94, 0x53, 0xad, 0x27, 0x77, 0x1d, - 0x84, 0xd1, 0x21, 0xf3, 0xcd, 0x0d, 0x74, 0xa3, 0x29, 0xb2, 0x03, 0x65, 0xfd, 0x24, 0xcc, 0x07, - 0xe8, 0xea, 0xe1, 0xbc, 0xab, 0xf8, 0xae, 0x62, 0x4d, 0x19, 0xd0, 0x30, 0x08, 0x4d, 0x13, 0xc3, - 0x94, 0x4b, 0xf2, 0x12, 0xca, 0xcc, 0x57, 0x40, 0xfa, 0x10, 0xdd, 0x3c, 0x9a, 0x77, 0x83, 0xc4, - 0x41, 0xe0, 0x32, 0x87, 0xc6, 0xca, 0x38, 0x61, 0x05, 0xe3, 0x80, 0x1f, 0xb2, 0x50, 0x8c, 0xcc, - 0x26, 0x3a, 0x4c, 0x71, 0xc8, 0x11, 0xd4, 0x9d, 0x11, 0x0f, 0x26, 0xb6, 0x3a, 0x8e, 0xf9, 0x09, - 0x3a, 0xff, 0x6c, 0xde, 0xf9, 0x01, 0x6a, 0xf5, 0xa6, 0x17, 0x91, 0x3d, 0x09, 0xc7, 0x9e, 0x3f, - 0xa4, 0x19, 0x43, 0x99, 0xdd, 0xab, 0xa9, 0x2d, 0x5b, 0x84, 0xf9, 0x08, 0x13, 0x10, 0x93, 0xd6, - 0x63, 0x28, 0x69, 0x1d, 0x80, 0xd2, 0x49, 0xb7, 0x7d, 0x74, 0xde, 0x33, 0x96, 0x48, 0x19, 0x0a, - 0x27, 0xdd, 0x5d, 0x23, 0x67, 0xfd, 0x1e, 0xca, 0xf1, 0x1d, 0xdf, 0x83, 0xd5, 0xf6, 0xe9, 0xc1, - 0xd9, 0x61, 0x9b, 0xf6, 0x0f, 0xdb, 0xaf, 0xf7, 0xde, 0xbe, 0x91, 0x03, 0xea, 0x1a, 0x34, 0x8e, - 0x5b, 0x2f, 0x77, 0xfb, 0xfb, 0x7b, 0xbd, 0xf6, 0x9b, 0xce, 0x69, 0xdb, 0xc8, 0x91, 0x06, 0x54, - 0x91, 0x75, 0xb2, 0xd7, 0x39, 0x35, 0xf2, 0x09, 0x79, 0xdc, 0x39, 0x3a, 0x36, 0x0a, 0xe4, 0x21, - 0xac, 0x23, 0x79, 0x70, 0x76, 0xda, 0x3b, 0xa7, 0x7b, 0x9d, 0xd3, 0xf6, 0xa1, 0x12, 0x15, 0xad, - 0x16, 0xc0, 0x2c, 0x49, 0xa4, 0x02, 0x45, 0xa9, 0x68, 0x2c, 0xe9, 0xd5, 0x0b, 0x23, 0x27, 0xc3, - 0x7a, 0xd7, 0xfd, 0xc6, 0xc8, 0xab, 0xc5, 0x2b, 0xa3, 0x60, 0x1d, 0xc0, 0xda, 0xdc, 0xd9, 0xc9, - 0x0a, 0xc0, 0xc1, 0x31, 0x3d, 0x3b, 0xd9, 0xeb, 0xef, 0xb6, 0x9e, 0x1b, 0x4b, 0x19, 0xba, 0x65, - 0xe4, 0xd2, 0xf4, 0xee, 0xae, 0x91, 0xb7, 0xae, 0x60, 0x3d, 0xfe, 0x0a, 0x61, 0x6e, 0x4f, 0x3d, - 0x29, 0xc4, 0x61, 0x03, 0x0a, 0x53, 0x3e, 0x8e, 0x07, 0x82, 0x29, 0x1f, 0xe3, 0x24, 0x8d, 0x13, - 0xa9, 0x06, 0x5f, 0x4d, 0x91, 0x6d, 0xb8, 0x77, 0x0b, 0xb6, 0xfa, 0xd2, 0x52, 0x8d, 0xdb, 0x6b, - 0x61, 0x06, 0xb6, 0xde, 0xf2, 0xb1, 0xf5, 0x6b, 0x68, 0x24, 0x5b, 0xe2, 0x56, 0x2f, 0xa1, 0xa2, - 0x1f, 0x73, 0x3c, 0x00, 0x35, 0x55, 0xa7, 0x5d, 0x14, 0x18, 0x4d, 0x74, 0xe7, 0x3f, 0x79, 0xac, - 0x3f, 0xe7, 0x60, 0x35, 0xb1, 0xa2, 0x2c, 0x9a, 0x8e, 0x45, 0xdc, 0x30, 0x72, 0xb3, 0x86, 0xb1, - 0x01, 0xcb, 0x8c, 0xf3, 0x80, 0xab, 0x46, 0x75, 0xbc, 0x44, 0x15, 0x49, 0x9e, 0x42, 0xd1, 0xb5, - 0x85, 0xad, 0x1b, 0x37, 0xc9, 0xc6, 0x20, 0xf7, 0x3e, 0x5e, 0xa2, 0xa8, 0x41, 0xbe, 0x84, 0x62, - 0xea, 0xdb, 0x66, 0x5d, 0x21, 0xef, 0xad, 0x29, 0x83, 0xa2, 0xca, 0x7e, 0x05, 0x4a, 0x1c, 0x03, - 0xb1, 0xfe, 0x00, 0xab, 0x94, 0x0d, 0xbd, 0x48, 0xb0, 0xe4, 0x73, 0x6e, 0x03, 0x4a, 0x11, 0x73, - 0x38, 0x8b, 0x3f, 0x62, 0x34, 0x25, 0x1b, 0x92, 0x9e, 0xb2, 0x6f, 0x74, 0xb2, 0x13, 0xfa, 0x63, - 0x3f, 0xeb, 0xfe, 0x98, 0x83, 0xc6, 0x69, 0x20, 0xbc, 0xc1, 0x8d, 0x4e, 0xe6, 0x82, 0x1b, 0xfe, - 0x02, 0xca, 0x91, 0x6a, 0xc3, 0xda, 0x6b, 0x3d, 0x06, 0x5e, 0xcc, 0x7c, 0x2c, 0x94, 0x61, 0x0b, - 0x3b, 0xba, 0xec, 0xb8, 0x98, 0x80, 0x02, 0xd5, 0x54, 0xa6, 0xeb, 0xae, 0x65, 0xbb, 0xee, 0x77, - 0xc5, 0x4a, 0xde, 0x28, 0x7c, 0x57, 0xac, 0x3c, 0x31, 0x2c, 0xeb, 0x2f, 0x79, 0xa8, 0xa7, 0xc7, - 0x28, 0xf9, 0x29, 0xc3, 0x99, 0xe3, 0x85, 0x1e, 0xf3, 0x85, 0xee, 0xf9, 0x33, 0x86, 0x9c, 0x2e, - 0x06, 0xb6, 0xc3, 0xfa, 0xb3, 0x59, 0xb0, 0x4e, 0xab, 0x92, 0xf3, 0x4e, 0x32, 0xc8, 0x43, 0xa8, - 0xbc, 0xf7, 0xfc, 0x7e, 0xc8, 0x83, 0x0b, 0x3d, 0x03, 0x94, 0xdf, 0x7b, 0x7e, 0x97, 0x07, 0x17, - 0xb2, 0x34, 0x13, 0x37, 0x7d, 0x6e, 0xfb, 0xae, 0xea, 0xaa, 0x6a, 0x22, 0x58, 0x4b, 0x44, 0xd4, - 0xf6, 0x5d, 0x6c, 0xaa, 0x04, 0x8a, 0x11, 0x63, 0xae, 0x9e, 0x0d, 0x70, 0x4d, 0xbe, 0x04, 0x63, - 0x36, 0xaa, 0xf4, 0x2f, 0xc6, 0x81, 0x73, 0x89, 0x43, 0x42, 0x9d, 0xae, 0xce, 0xf8, 0xfb, 0x92, - 0x4d, 0x8e, 0x61, 0x2d, 0xa5, 0xaa, 0x67, 0x47, 0x35, 0x30, 0x7c, 0x92, 0x9a, 0x1d, 0xdb, 0x89, - 0x8e, 0x9e, 0x22, 0x53, 0x1b, 0x28, 0x8e, 0xd5, 0x01, 0xa2, 0x74, 0x7b, 0xcc, 0x77, 0x19, 0xd7, - 0x69, 0x7a, 0x02, 0xf5, 0x08, 0xe9, 0xbe, 0x1f, 0xf8, 0x0e, 0xd3, 0xa3, 0x72, 0x4d, 0xf1, 0x4e, - 0x25, 0x6b, 0xc1, 0x9b, 0xf8, 0x01, 0x36, 0x16, 0x6f, 0x4b, 0xb6, 0x60, 0xc5, 0xe1, 0x4c, 0x05, - 0xcb, 0x83, 0xa9, 0xef, 0xea, 0x47, 0xd2, 0x88, 0xb9, 0x54, 0x32, 0xc9, 0x2b, 0x78, 0x98, 0x55, - 0x53, 0x49, 0x50, 0xa9, 0x54, 0x1b, 0x6d, 0x64, 0x2c, 0x30, 0x19, 0x32, 0x9f, 0xd6, 0xdf, 0xf2, - 0x50, 0xee, 0xda, 0x37, 0x58, 0x6e, 0x73, 0x43, 0x75, 0xee, 0x6e, 0x43, 0x35, 0xbe, 0x11, 0x79, - 0x40, 0xbd, 0x97, 0xa6, 0x16, 0x27, 0xbb, 0xf0, 0x11, 0xc9, 0x26, 0x1d, 0xb8, 0xaf, 0x23, 0xd3, - 0xd9, 0xd5, 0xce, 0x8a, 0x88, 0x45, 0x0f, 0x52, 0xce, 0xd2, 0xb7, 0x41, 0x89, 0x98, 0xbf, 0xa1, - 0x17, 0xb0, 0xc2, 0xae, 0x43, 0xe6, 0x08, 0xe6, 0xf6, 0x71, 0xd0, 0xd7, 0xa3, 0xfb, 0xed, 0xaf, - 0x80, 0x46, 0xac, 0x85, 0xac, 0xd6, 0xbf, 0x72, 0x50, 0x4f, 0xe3, 0x07, 0xd9, 0x87, 0xd5, 0x23, - 0x26, 0x32, 0x2c, 0x73, 0x0e, 0x65, 0x34, 0x8a, 0x34, 0x17, 0xe3, 0x0f, 0xf9, 0x2d, 0xac, 0x2f, - 0xfc, 0xc7, 0x44, 0xd4, 0x47, 0xfe, 0x8f, 0xfd, 0xce, 0x6a, 0x5a, 0x3f, 0xa6, 0xa2, 0x7e, 0x51, - 0x91, 0xcf, 0xa1, 0xd8, 0x95, 0x2d, 0x47, 0xfd, 0xda, 0x89, 0xff, 0x9f, 0x35, 0xb3, 0x64, 0xeb, - 0x14, 0xe0, 0x7c, 0xf6, 0x65, 0xf5, 0x4b, 0x20, 0x31, 0x06, 0xa6, 0xb8, 0xf7, 0xd1, 0xe4, 0x16, - 0x38, 0x36, 0x15, 0x00, 0x67, 0x30, 0xeb, 0x79, 0x6e, 0xbf, 0xfc, 0x9b, 0xe5, 0xed, 0xaf, 0x7c, - 0x26, 0x2e, 0x4a, 0xf8, 0xff, 0x6e, 0xe7, 0xbf, 0x01, 0x00, 0x00, 0xff, 0xff, 0xa2, 0xc3, 0xc1, - 0x2e, 0xd3, 0x13, 0x00, 0x00, -======= func (x *Capabilities_Constraints) Reset() { *x = Capabilities_Constraints{} if protoimpl.UnsafeEnabled { @@ -2743,35 +2567,35 @@ var file_net_lp_rpc_proto_rawDesc = []byte{ 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, - 0x2a, 0x50, 0x0a, 0x0d, 0x41, 0x49, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, + 0x2a, 0x51, 0x0a, 0x0d, 0x41, 0x49, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0f, 0x0a, 0x0b, 0x54, 0x65, 0x78, 0x74, 0x54, 0x6f, 0x49, 0x6d, 0x61, 0x67, 0x65, - 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x54, 0x65, 0x78, - 0x74, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x49, 0x6d, - 0x61, 0x67, 0x65, 0x10, 0x02, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x70, 0x73, 0x63, 0x61, 0x6c, 0x65, - 0x10, 0x03, 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, + 0x10, 0x00, 0x12, 0x10, 0x0a, 0x0c, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x49, 0x6d, 0x61, + 0x67, 0x65, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x56, + 0x69, 0x64, 0x65, 0x6f, 0x10, 0x02, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x70, 0x73, 0x63, 0x61, 0x6c, + 0x65, 0x10, 0x03, 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, - 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, 0x8c, 0x01, - 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, 0x12, 0x3c, - 0x0a, 0x10, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x41, 0x49, 0x57, 0x6f, 0x72, 0x6b, - 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, 0x10, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x4e, - 0x6f, 0x74, 0x69, 0x66, 0x79, 0x41, 0x49, 0x4a, 0x6f, 0x62, 0x30, 0x01, 0x42, 0x07, 0x5a, 0x05, - 0x2e, 0x2f, 0x6e, 0x65, 0x74, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 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, 0x8c, + 0x01, 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, 0x12, + 0x3c, 0x0a, 0x10, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x41, 0x49, 0x57, 0x6f, 0x72, + 0x6b, 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, 0x10, 0x2e, 0x6e, 0x65, 0x74, 0x2e, + 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x41, 0x49, 0x4a, 0x6f, 0x62, 0x30, 0x01, 0x42, 0x07, 0x5a, + 0x05, 0x2e, 0x2f, 0x6e, 0x65, 0x74, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -2788,7 +2612,7 @@ func file_net_lp_rpc_proto_rawDescGZIP() []byte { var file_net_lp_rpc_proto_enumTypes = make([]protoimpl.EnumInfo, 6) var file_net_lp_rpc_proto_msgTypes = make([]protoimpl.MessageInfo, 28) -var file_net_lp_rpc_proto_goTypes = []interface{}{ +var file_net_lp_rpc_proto_goTypes = []any{ (AIRequestType)(0), // 0: net.AIRequestType (OSInfo_StorageType)(0), // 1: net.OSInfo.StorageType (VideoProfile_Format)(0), // 2: net.VideoProfile.Format @@ -2884,7 +2708,7 @@ func file_net_lp_rpc_proto_init() { return } if !protoimpl.UnsafeEnabled { - file_net_lp_rpc_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + file_net_lp_rpc_proto_msgTypes[0].Exporter = func(v any, i int) any { switch v := v.(*PingPong); i { case 0: return &v.state @@ -2896,7 +2720,7 @@ func file_net_lp_rpc_proto_init() { return nil } } - file_net_lp_rpc_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + file_net_lp_rpc_proto_msgTypes[1].Exporter = func(v any, i int) any { switch v := v.(*EndTranscodingSessionRequest); i { case 0: return &v.state @@ -2908,7 +2732,7 @@ func file_net_lp_rpc_proto_init() { return nil } } - file_net_lp_rpc_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + file_net_lp_rpc_proto_msgTypes[2].Exporter = func(v any, i int) any { switch v := v.(*EndTranscodingSessionResponse); i { case 0: return &v.state @@ -2920,7 +2744,7 @@ func file_net_lp_rpc_proto_init() { return nil } } - file_net_lp_rpc_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + file_net_lp_rpc_proto_msgTypes[3].Exporter = func(v any, i int) any { switch v := v.(*OrchestratorRequest); i { case 0: return &v.state @@ -2932,7 +2756,7 @@ func file_net_lp_rpc_proto_init() { return nil } } - file_net_lp_rpc_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + file_net_lp_rpc_proto_msgTypes[4].Exporter = func(v any, i int) any { switch v := v.(*OSInfo); i { case 0: return &v.state @@ -2944,7 +2768,7 @@ func file_net_lp_rpc_proto_init() { return nil } } - file_net_lp_rpc_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + file_net_lp_rpc_proto_msgTypes[5].Exporter = func(v any, i int) any { switch v := v.(*S3OSInfo); i { case 0: return &v.state @@ -2956,7 +2780,7 @@ func file_net_lp_rpc_proto_init() { return nil } } - file_net_lp_rpc_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + file_net_lp_rpc_proto_msgTypes[6].Exporter = func(v any, i int) any { switch v := v.(*PriceInfo); i { case 0: return &v.state @@ -2968,7 +2792,7 @@ func file_net_lp_rpc_proto_init() { return nil } } - file_net_lp_rpc_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + file_net_lp_rpc_proto_msgTypes[7].Exporter = func(v any, i int) any { switch v := v.(*Capabilities); i { case 0: return &v.state @@ -2980,7 +2804,7 @@ func file_net_lp_rpc_proto_init() { return nil } } - file_net_lp_rpc_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + file_net_lp_rpc_proto_msgTypes[8].Exporter = func(v any, i int) any { switch v := v.(*OrchestratorInfo); i { case 0: return &v.state @@ -2992,7 +2816,7 @@ func file_net_lp_rpc_proto_init() { return nil } } - file_net_lp_rpc_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + file_net_lp_rpc_proto_msgTypes[9].Exporter = func(v any, i int) any { switch v := v.(*AuthToken); i { case 0: return &v.state @@ -3004,7 +2828,7 @@ func file_net_lp_rpc_proto_init() { return nil } } - file_net_lp_rpc_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + file_net_lp_rpc_proto_msgTypes[10].Exporter = func(v any, i int) any { switch v := v.(*SegData); i { case 0: return &v.state @@ -3016,7 +2840,7 @@ func file_net_lp_rpc_proto_init() { return nil } } - file_net_lp_rpc_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + file_net_lp_rpc_proto_msgTypes[11].Exporter = func(v any, i int) any { switch v := v.(*SegParameters); i { case 0: return &v.state @@ -3028,7 +2852,7 @@ func file_net_lp_rpc_proto_init() { return nil } } - file_net_lp_rpc_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { + file_net_lp_rpc_proto_msgTypes[12].Exporter = func(v any, i int) any { switch v := v.(*VideoProfile); i { case 0: return &v.state @@ -3040,7 +2864,7 @@ func file_net_lp_rpc_proto_init() { return nil } } - file_net_lp_rpc_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { + file_net_lp_rpc_proto_msgTypes[13].Exporter = func(v any, i int) any { switch v := v.(*TranscodedSegmentData); i { case 0: return &v.state @@ -3052,7 +2876,7 @@ func file_net_lp_rpc_proto_init() { return nil } } - file_net_lp_rpc_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { + file_net_lp_rpc_proto_msgTypes[14].Exporter = func(v any, i int) any { switch v := v.(*TranscodeData); i { case 0: return &v.state @@ -3064,7 +2888,7 @@ func file_net_lp_rpc_proto_init() { return nil } } - file_net_lp_rpc_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { + file_net_lp_rpc_proto_msgTypes[15].Exporter = func(v any, i int) any { switch v := v.(*TranscodeResult); i { case 0: return &v.state @@ -3076,7 +2900,7 @@ func file_net_lp_rpc_proto_init() { return nil } } - file_net_lp_rpc_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { + file_net_lp_rpc_proto_msgTypes[16].Exporter = func(v any, i int) any { switch v := v.(*RegisterRequest); i { case 0: return &v.state @@ -3088,7 +2912,7 @@ func file_net_lp_rpc_proto_init() { return nil } } - file_net_lp_rpc_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { + file_net_lp_rpc_proto_msgTypes[17].Exporter = func(v any, i int) any { switch v := v.(*NotifySegment); i { case 0: return &v.state @@ -3100,7 +2924,7 @@ func file_net_lp_rpc_proto_init() { return nil } } - file_net_lp_rpc_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { + file_net_lp_rpc_proto_msgTypes[18].Exporter = func(v any, i int) any { switch v := v.(*NotifyAIJob); i { case 0: return &v.state @@ -3112,7 +2936,7 @@ func file_net_lp_rpc_proto_init() { return nil } } - file_net_lp_rpc_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { + file_net_lp_rpc_proto_msgTypes[19].Exporter = func(v any, i int) any { switch v := v.(*TicketParams); i { case 0: return &v.state @@ -3124,7 +2948,7 @@ func file_net_lp_rpc_proto_init() { return nil } } - file_net_lp_rpc_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { + file_net_lp_rpc_proto_msgTypes[20].Exporter = func(v any, i int) any { switch v := v.(*TicketSenderParams); i { case 0: return &v.state @@ -3136,7 +2960,7 @@ func file_net_lp_rpc_proto_init() { return nil } } - file_net_lp_rpc_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { + file_net_lp_rpc_proto_msgTypes[21].Exporter = func(v any, i int) any { switch v := v.(*TicketExpirationParams); i { case 0: return &v.state @@ -3148,7 +2972,7 @@ func file_net_lp_rpc_proto_init() { return nil } } - file_net_lp_rpc_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { + file_net_lp_rpc_proto_msgTypes[22].Exporter = func(v any, i int) any { switch v := v.(*Payment); i { case 0: return &v.state @@ -3160,7 +2984,7 @@ func file_net_lp_rpc_proto_init() { return nil } } - file_net_lp_rpc_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { + file_net_lp_rpc_proto_msgTypes[24].Exporter = func(v any, i int) any { switch v := v.(*Capabilities_Constraints); i { case 0: return &v.state @@ -3172,7 +2996,7 @@ func file_net_lp_rpc_proto_init() { return nil } } - file_net_lp_rpc_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} { + file_net_lp_rpc_proto_msgTypes[26].Exporter = func(v any, i int) any { switch v := v.(*Capabilities_Constraints_ModelConstraint); i { case 0: return &v.state @@ -3185,7 +3009,7 @@ func file_net_lp_rpc_proto_init() { } } } - file_net_lp_rpc_proto_msgTypes[15].OneofWrappers = []interface{}{ + file_net_lp_rpc_proto_msgTypes[15].OneofWrappers = []any{ (*TranscodeResult_Error)(nil), (*TranscodeResult_Data)(nil), } @@ -3208,5 +3032,4 @@ func file_net_lp_rpc_proto_init() { file_net_lp_rpc_proto_rawDesc = nil file_net_lp_rpc_proto_goTypes = nil file_net_lp_rpc_proto_depIdxs = nil ->>>>>>> 703455f1 ([net,server]: RemoteAIWorker gRPC) } diff --git a/net/lp_rpc.proto b/net/lp_rpc.proto index 5147f18ea3..8ab2fe1bce 100644 --- a/net/lp_rpc.proto +++ b/net/lp_rpc.proto @@ -372,8 +372,8 @@ message NotifySegment { enum AIRequestType { TextToImage= 0; - ImageToText= 1; - ImageToImage= 2; + ImageToImage= 1; + ImageToVideo= 2; Upscale = 3; } // Sent by the orchestrator to the remote AI worker diff --git a/net/lp_rpc_grpc.pb.go b/net/lp_rpc_grpc.pb.go index ff4cd7c826..6ee7f8d0dc 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.12.4 +// - protoc-gen-go-grpc v1.4.0 +// - protoc v5.27.1 // source: net/lp_rpc.proto package net @@ -15,12 +15,20 @@ import ( // This is a compile-time assertion to ensure that this generated file // is compatible with the grpc package it is being compiled against. -// Requires gRPC-Go v1.32.0 or later. -const _ = grpc.SupportPackageIsVersion7 +// Requires gRPC-Go v1.62.0 or later. +const _ = grpc.SupportPackageIsVersion8 + +const ( + Orchestrator_GetOrchestrator_FullMethodName = "/net.Orchestrator/GetOrchestrator" + Orchestrator_EndTranscodingSession_FullMethodName = "/net.Orchestrator/EndTranscodingSession" + Orchestrator_Ping_FullMethodName = "/net.Orchestrator/Ping" +) // OrchestratorClient is the client API for Orchestrator service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +// +// RPC calls implemented by the orchestrator type OrchestratorClient interface { // Called by the broadcaster to request transcoder info from an orchestrator. GetOrchestrator(ctx context.Context, in *OrchestratorRequest, opts ...grpc.CallOption) (*OrchestratorInfo, error) @@ -37,8 +45,9 @@ func NewOrchestratorClient(cc grpc.ClientConnInterface) OrchestratorClient { } func (c *orchestratorClient) GetOrchestrator(ctx context.Context, in *OrchestratorRequest, opts ...grpc.CallOption) (*OrchestratorInfo, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(OrchestratorInfo) - err := c.cc.Invoke(ctx, "/net.Orchestrator/GetOrchestrator", in, out, opts...) + err := c.cc.Invoke(ctx, Orchestrator_GetOrchestrator_FullMethodName, in, out, cOpts...) if err != nil { return nil, err } @@ -46,8 +55,9 @@ func (c *orchestratorClient) GetOrchestrator(ctx context.Context, in *Orchestrat } func (c *orchestratorClient) EndTranscodingSession(ctx context.Context, in *EndTranscodingSessionRequest, opts ...grpc.CallOption) (*EndTranscodingSessionResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(EndTranscodingSessionResponse) - err := c.cc.Invoke(ctx, "/net.Orchestrator/EndTranscodingSession", in, out, opts...) + err := c.cc.Invoke(ctx, Orchestrator_EndTranscodingSession_FullMethodName, in, out, cOpts...) if err != nil { return nil, err } @@ -55,8 +65,9 @@ func (c *orchestratorClient) EndTranscodingSession(ctx context.Context, in *EndT } func (c *orchestratorClient) Ping(ctx context.Context, in *PingPong, opts ...grpc.CallOption) (*PingPong, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(PingPong) - err := c.cc.Invoke(ctx, "/net.Orchestrator/Ping", in, out, opts...) + err := c.cc.Invoke(ctx, Orchestrator_Ping_FullMethodName, in, out, cOpts...) if err != nil { return nil, err } @@ -66,6 +77,8 @@ func (c *orchestratorClient) Ping(ctx context.Context, in *PingPong, opts ...grp // OrchestratorServer is the server API for Orchestrator service. // All implementations must embed UnimplementedOrchestratorServer // for forward compatibility +// +// RPC calls implemented by the orchestrator type OrchestratorServer interface { // Called by the broadcaster to request transcoder info from an orchestrator. GetOrchestrator(context.Context, *OrchestratorRequest) (*OrchestratorInfo, error) @@ -110,7 +123,7 @@ func _Orchestrator_GetOrchestrator_Handler(srv interface{}, ctx context.Context, } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/net.Orchestrator/GetOrchestrator", + FullMethod: Orchestrator_GetOrchestrator_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(OrchestratorServer).GetOrchestrator(ctx, req.(*OrchestratorRequest)) @@ -128,7 +141,7 @@ func _Orchestrator_EndTranscodingSession_Handler(srv interface{}, ctx context.Co } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/net.Orchestrator/EndTranscodingSession", + FullMethod: Orchestrator_EndTranscodingSession_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(OrchestratorServer).EndTranscodingSession(ctx, req.(*EndTranscodingSessionRequest)) @@ -146,7 +159,7 @@ func _Orchestrator_Ping_Handler(srv interface{}, ctx context.Context, dec func(i } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/net.Orchestrator/Ping", + FullMethod: Orchestrator_Ping_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(OrchestratorServer).Ping(ctx, req.(*PingPong)) @@ -178,6 +191,11 @@ var Orchestrator_ServiceDesc = grpc.ServiceDesc{ Metadata: "net/lp_rpc.proto", } +const ( + Transcoder_RegisterTranscoder_FullMethodName = "/net.Transcoder/RegisterTranscoder" + Transcoder_RegisterAIWorker_FullMethodName = "/net.Transcoder/RegisterAIWorker" +) + // TranscoderClient is the client API for Transcoder service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. @@ -199,11 +217,12 @@ func NewTranscoderClient(cc grpc.ClientConnInterface) TranscoderClient { } func (c *transcoderClient) RegisterTranscoder(ctx context.Context, in *RegisterRequest, opts ...grpc.CallOption) (Transcoder_RegisterTranscoderClient, error) { - stream, err := c.cc.NewStream(ctx, &Transcoder_ServiceDesc.Streams[0], "/net.Transcoder/RegisterTranscoder", opts...) + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + stream, err := c.cc.NewStream(ctx, &Transcoder_ServiceDesc.Streams[0], Transcoder_RegisterTranscoder_FullMethodName, cOpts...) if err != nil { return nil, err } - x := &transcoderRegisterTranscoderClient{stream} + x := &transcoderRegisterTranscoderClient{ClientStream: stream} if err := x.ClientStream.SendMsg(in); err != nil { return nil, err } @@ -231,11 +250,12 @@ func (x *transcoderRegisterTranscoderClient) Recv() (*NotifySegment, error) { } func (c *transcoderClient) RegisterAIWorker(ctx context.Context, in *RegisterRequest, opts ...grpc.CallOption) (Transcoder_RegisterAIWorkerClient, error) { - stream, err := c.cc.NewStream(ctx, &Transcoder_ServiceDesc.Streams[1], "/net.Transcoder/RegisterAIWorker", opts...) + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + stream, err := c.cc.NewStream(ctx, &Transcoder_ServiceDesc.Streams[1], Transcoder_RegisterAIWorker_FullMethodName, cOpts...) if err != nil { return nil, err } - x := &transcoderRegisterAIWorkerClient{stream} + x := &transcoderRegisterAIWorkerClient{ClientStream: stream} if err := x.ClientStream.SendMsg(in); err != nil { return nil, err } @@ -303,7 +323,7 @@ func _Transcoder_RegisterTranscoder_Handler(srv interface{}, stream grpc.ServerS if err := stream.RecvMsg(m); err != nil { return err } - return srv.(TranscoderServer).RegisterTranscoder(m, &transcoderRegisterTranscoderServer{stream}) + return srv.(TranscoderServer).RegisterTranscoder(m, &transcoderRegisterTranscoderServer{ServerStream: stream}) } type Transcoder_RegisterTranscoderServer interface { @@ -324,7 +344,7 @@ func _Transcoder_RegisterAIWorker_Handler(srv interface{}, stream grpc.ServerStr if err := stream.RecvMsg(m); err != nil { return err } - return srv.(TranscoderServer).RegisterAIWorker(m, &transcoderRegisterAIWorkerServer{stream}) + return srv.(TranscoderServer).RegisterAIWorker(m, &transcoderRegisterAIWorkerServer{ServerStream: stream}) } type Transcoder_RegisterAIWorkerServer interface { diff --git a/server/ot_rpc.go b/server/ot_rpc.go index eb6285710f..d7985576d0 100644 --- a/server/ot_rpc.go +++ b/server/ot_rpc.go @@ -183,32 +183,60 @@ func runTranscoder(n *core.LivepeerNode, orchAddr string, capacity int, caps []c continue } glog.Infof("Received AI job %v type: %v", aiJob.TaskID, aiJob.Type) - var aiRequest worker.TextToImageJSONRequestBody - if err := json.Unmarshal(aiJob.Data, &aiRequest); err != nil { - glog.Errorf("Unable to unmarshal AI job data err=%q", err) + + // var aiResult *core.RemoteAIWorkerResult + var aiResultBytes []byte + var unmarshalReqErr error + var unmarshalResErr error + var aiReqErr error + + switch aiJob.Type { + case net.AIRequestType_TextToImage: + var req worker.TextToImageJSONRequestBody + var res *worker.ImageResponse + if unmarshalReqErr = json.Unmarshal(aiJob.Data, &req); unmarshalReqErr == nil { + glog.Infof("Text-to-Image AI Job decoded model=%v prompt=%v", req.ModelId, req.Prompt) + // res, aiReqErr = n.AIWorker.TextToImage(context.Background(), req) + res = &worker.ImageResponse{} // mock response + if aiReqErr == nil { + aiResultBytes, unmarshalResErr = json.Marshal(res) + } + } + case net.AIRequestType_ImageToImage: + var req worker.ImageToImageMultipartRequestBody + var res *worker.ImageResponse + if unmarshalReqErr = json.Unmarshal(aiJob.Data, &req); unmarshalReqErr == nil { + glog.Infof("Image-to-Image AI Job decoded model=%v image=%v", req.ModelId, req.Image.Filename()) + // res, aiReqErr = n.AIWorker.ImageToImage(context.Background(), req) + res = &worker.ImageResponse{} // mock response + if aiReqErr == nil { + aiResultBytes, unmarshalResErr = json.Marshal(res) + } + } + default: + glog.Errorf("Invalid Job type decoded taskID=%v type=%v", aiJob.TaskID, aiJob.Type) continue } - glog.Infof("AI Job decoded model=%v prompt=%v", aiRequest.ModelId, aiRequest.Prompt) - - // Send job to worker - // res, err := n.AIWorker.TextToImage(context.Background(), aiRequest) - // if err != nil { - // glog.Errorf("AI job failed err=%q", err) - // continue - // } - - res := &worker.ImageResponse{} - // marshal res to json bytes - jsonBytes, err := json.Marshal(res) - if err != nil { - glog.Errorf("Unable to marshal AI job response err=%q", err) + + if unmarshalReqErr != nil { + glog.Errorf("Unable to unmarshal AI job data taskID=%v err=%q", aiJob.TaskID, unmarshalReqErr) + continue + } + + if aiReqErr != nil { + glog.Errorf("AI job failed ID=%v err=%v", aiJob.TaskID, aiReqErr) + continue + } + + if unmarshalResErr != nil { + glog.Errorf("Unable to marshal AI job response ID=%v err=%q", aiJob.TaskID, unmarshalResErr) continue } aiResult := &core.RemoteAIWorkerResult{ JobType: aiJob.Type, TaskID: aiJob.TaskID, - Bytes: jsonBytes, + Bytes: aiResultBytes, Err: err, } From 7810cd411def31252853a755b0910f6e1d903ff5 Mon Sep 17 00:00:00 2001 From: Reuben Rodrigues Date: Mon, 1 Jul 2024 10:59:09 +0530 Subject: [PATCH 61/88] server: handle remote upscale job --- server/ot_rpc.go | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/server/ot_rpc.go b/server/ot_rpc.go index d7985576d0..aa2c8bfb3e 100644 --- a/server/ot_rpc.go +++ b/server/ot_rpc.go @@ -213,6 +213,17 @@ func runTranscoder(n *core.LivepeerNode, orchAddr string, capacity int, caps []c aiResultBytes, unmarshalResErr = json.Marshal(res) } } + case net.AIRequestType_Upscale: + var req worker.UpscaleMultipartRequestBody + var res *worker.ImageResponse + if unmarshalReqErr = json.Unmarshal(aiJob.Data, &req); unmarshalReqErr == nil { + glog.Infof("Upscale AI Job decoded model=%v image=%v", req.ModelId, req.Image.Filename()) + // res, aiReqErr = n.AIWorker.Upscale(context.Background(), req) + res = &worker.ImageResponse{} // mock response + if aiReqErr == nil { + aiResultBytes, unmarshalResErr = json.Marshal(res) + } + } default: glog.Errorf("Invalid Job type decoded taskID=%v type=%v", aiJob.TaskID, aiJob.Type) continue From bb860306f6e977414f40b00ac1be0ffc21540bb6 Mon Sep 17 00:00:00 2001 From: Reuben Rodrigues Date: Mon, 1 Jul 2024 20:52:09 +0530 Subject: [PATCH 62/88] server: handlers for image-to-image + upscale --- core/ai.go | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/core/ai.go b/core/ai.go index 23f87f2dc1..e82cf065e5 100644 --- a/core/ai.go +++ b/core/ai.go @@ -154,7 +154,44 @@ func (m *RemoteAIWorkerManager) TextToImage(ctx context.Context, req worker.Text } +// TODO: DRY these? func (m *RemoteAIWorkerManager) ImageToImage(ctx context.Context, req worker.ImageToImageMultipartRequestBody) (*worker.ImageResponse, error) { + taskID, taskChan := m.addTaskChan() + defer m.removeTaskChan(taskID) + + // select a remote worker + w := m.remoteWorkers[0] + + // send request to remote worker + jsonData, err := json.Marshal(req) + if err != nil { + return nil, err + } + + remoteReq := &net.NotifyAIJob{ + Type: net.AIRequestType_ImageToImage, + TaskID: taskID, + Data: jsonData, + } + + m.handleAIRequest(remoteReq) // task id, pipeline + + if err := w.stream.Send(remoteReq); err != nil { + return nil, err + } + + select { + case <-ctx.Done(): + // return EOF signal + case chanData := <-taskChan: + var res worker.ImageResponse + if err := json.Unmarshal(chanData.Bytes, &res); err != nil { + return nil, err + } + glog.Infof("Received AI result for task %d images=%s", chanData.TaskID, res.Images) + return &res, nil + } + return nil, nil } @@ -163,6 +200,42 @@ func (m *RemoteAIWorkerManager) ImageToVideo(ctx context.Context, req worker.Ima } func (m *RemoteAIWorkerManager) Upscale(ctx context.Context, req worker.UpscaleMultipartRequestBody) (*worker.ImageResponse, error) { + taskID, taskChan := m.addTaskChan() + defer m.removeTaskChan(taskID) + + // select a remote worker + w := m.remoteWorkers[0] + + // send request to remote worker + jsonData, err := json.Marshal(req) + if err != nil { + return nil, err + } + + remoteReq := &net.NotifyAIJob{ + Type: net.AIRequestType_Upscale, + TaskID: taskID, + Data: jsonData, + } + + m.handleAIRequest(remoteReq) // task id, pipeline + + if err := w.stream.Send(remoteReq); err != nil { + return nil, err + } + + select { + case <-ctx.Done(): + // return EOF signal + case chanData := <-taskChan: + var res worker.ImageResponse + if err := json.Unmarshal(chanData.Bytes, &res); err != nil { + return nil, err + } + glog.Infof("Received AI result for task %d images=%s", chanData.TaskID, res.Images) + return &res, nil + } + return nil, nil } From e656a316e005d802140dcae8889c96b8ef0668a0 Mon Sep 17 00:00:00 2001 From: Reuben Rodrigues Date: Tue, 2 Jul 2024 13:32:39 +0530 Subject: [PATCH 63/88] server: advertise ai capabilities to remote O --- core/capabilities.go | 22 ++++++++++++++++++++++ core/orchestrator.go | 6 ++---- server/ot_rpc.go | 2 +- 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/core/capabilities.go b/core/capabilities.go index 4f4122ec7b..3f4e6232d2 100644 --- a/core/capabilities.go +++ b/core/capabilities.go @@ -549,6 +549,19 @@ func (cap *Capabilities) AddCapacity(newCaps *Capabilities) { } cap.bitstring[arrIdx] |= uint64(1 << bitIdx) } + + for capability, constraints := range newCaps.constraints { + if cap.constraints[capability] == nil { + cap.constraints[capability] = constraints + } else { + for modelID, modelConstraint := range constraints.Models { + if cap.constraints[capability].Models[modelID] == nil { + // TODO: this re-writes Warm; check + cap.constraints[capability].Models[modelID] = modelConstraint + } + } + } + } } func (cap *Capabilities) RemoveCapacity(goneCaps *Capabilities) { @@ -567,6 +580,15 @@ func (cap *Capabilities) RemoveCapacity(goneCaps *Capabilities) { cap.capacities[capability] = newCapacity } } + + for capability, constraints := range goneCaps.constraints { + if cap.constraints[capability] == nil { + continue + } + for modelID := range constraints.Models { + delete(cap.constraints[capability].Models, modelID) + } + } } func (capStr *CapabilityString) removeCapability(capability Capability) { diff --git a/core/orchestrator.go b/core/orchestrator.go index ea5885c8f7..83f404288c 100644 --- a/core/orchestrator.go +++ b/core/orchestrator.go @@ -928,10 +928,8 @@ func (n *LivepeerNode) endTranscodingSession(sessionId string, logCtx context.Co func (n *LivepeerNode) serveRemoteAIWorker(stream net.Transcoder_RegisterAIWorkerServer, capabilities *net.Capabilities) { from := common.GetConnectionAddr(stream.Context()) - // aiCaps := CapabilitiesFromNetCapabilities(capabilities) - - // TODO: expand n.Capabilitiers with AI capabilities - // defer removing the same capabilities + n.Capabilities.AddCapacity(CapabilitiesFromNetCapabilities(capabilities)) + defer n.Capabilities.RemoveCapacity(CapabilitiesFromNetCapabilities(capabilities)) // Blocks while AIWorker is connected n.AIManager.Manage(stream, capabilities) diff --git a/server/ot_rpc.go b/server/ot_rpc.go index aa2c8bfb3e..276937f02a 100644 --- a/server/ot_rpc.go +++ b/server/ot_rpc.go @@ -110,7 +110,7 @@ func runTranscoder(n *core.LivepeerNode, orchAddr string, capacity int, caps []c // TODO check if ai capabilities are defined aiR, err := c.RegisterAIWorker(ctx, &net.RegisterRequest{Secret: n.OrchSecret, Capacity: int64(capacity), - Capabilities: core.NewCapabilities(caps, []core.Capability{}).ToNetCapabilities()}) + Capabilities: n.Capabilities.ToNetCapabilities()}) // TODO: add checking AI errors to checkTranscoderError if err := checkTranscoderError(err); err != nil { glog.Error("Could not register AI worker to orchestrator ", err) From 417d6b789808d5d69290c7bb642939df1e8c6540 Mon Sep 17 00:00:00 2001 From: kyriediculous Date: Tue, 2 Jul 2024 17:17:15 +0200 Subject: [PATCH 64/88] fix: uncomment running actual ai worker jobs --- server/ot_rpc.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/server/ot_rpc.go b/server/ot_rpc.go index 276937f02a..cb2e714ff9 100644 --- a/server/ot_rpc.go +++ b/server/ot_rpc.go @@ -196,7 +196,7 @@ func runTranscoder(n *core.LivepeerNode, orchAddr string, capacity int, caps []c var res *worker.ImageResponse if unmarshalReqErr = json.Unmarshal(aiJob.Data, &req); unmarshalReqErr == nil { glog.Infof("Text-to-Image AI Job decoded model=%v prompt=%v", req.ModelId, req.Prompt) - // res, aiReqErr = n.AIWorker.TextToImage(context.Background(), req) + res, aiReqErr = n.AIWorker.TextToImage(context.Background(), req) res = &worker.ImageResponse{} // mock response if aiReqErr == nil { aiResultBytes, unmarshalResErr = json.Marshal(res) @@ -207,7 +207,7 @@ func runTranscoder(n *core.LivepeerNode, orchAddr string, capacity int, caps []c var res *worker.ImageResponse if unmarshalReqErr = json.Unmarshal(aiJob.Data, &req); unmarshalReqErr == nil { glog.Infof("Image-to-Image AI Job decoded model=%v image=%v", req.ModelId, req.Image.Filename()) - // res, aiReqErr = n.AIWorker.ImageToImage(context.Background(), req) + res, aiReqErr = n.AIWorker.ImageToImage(context.Background(), req) res = &worker.ImageResponse{} // mock response if aiReqErr == nil { aiResultBytes, unmarshalResErr = json.Marshal(res) @@ -218,7 +218,7 @@ func runTranscoder(n *core.LivepeerNode, orchAddr string, capacity int, caps []c var res *worker.ImageResponse if unmarshalReqErr = json.Unmarshal(aiJob.Data, &req); unmarshalReqErr == nil { glog.Infof("Upscale AI Job decoded model=%v image=%v", req.ModelId, req.Image.Filename()) - // res, aiReqErr = n.AIWorker.Upscale(context.Background(), req) + res, aiReqErr = n.AIWorker.Upscale(context.Background(), req) res = &worker.ImageResponse{} // mock response if aiReqErr == nil { aiResultBytes, unmarshalResErr = json.Marshal(res) From cfca2b7272328252a61ef905f52b4d634ce80808 Mon Sep 17 00:00:00 2001 From: kyriediculous Date: Tue, 2 Jul 2024 17:27:44 +0200 Subject: [PATCH 65/88] fix: remove mock ai responses --- server/ot_rpc.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/server/ot_rpc.go b/server/ot_rpc.go index cb2e714ff9..6080d4679f 100644 --- a/server/ot_rpc.go +++ b/server/ot_rpc.go @@ -197,7 +197,6 @@ func runTranscoder(n *core.LivepeerNode, orchAddr string, capacity int, caps []c if unmarshalReqErr = json.Unmarshal(aiJob.Data, &req); unmarshalReqErr == nil { glog.Infof("Text-to-Image AI Job decoded model=%v prompt=%v", req.ModelId, req.Prompt) res, aiReqErr = n.AIWorker.TextToImage(context.Background(), req) - res = &worker.ImageResponse{} // mock response if aiReqErr == nil { aiResultBytes, unmarshalResErr = json.Marshal(res) } @@ -208,7 +207,6 @@ func runTranscoder(n *core.LivepeerNode, orchAddr string, capacity int, caps []c if unmarshalReqErr = json.Unmarshal(aiJob.Data, &req); unmarshalReqErr == nil { glog.Infof("Image-to-Image AI Job decoded model=%v image=%v", req.ModelId, req.Image.Filename()) res, aiReqErr = n.AIWorker.ImageToImage(context.Background(), req) - res = &worker.ImageResponse{} // mock response if aiReqErr == nil { aiResultBytes, unmarshalResErr = json.Marshal(res) } @@ -219,7 +217,6 @@ func runTranscoder(n *core.LivepeerNode, orchAddr string, capacity int, caps []c if unmarshalReqErr = json.Unmarshal(aiJob.Data, &req); unmarshalReqErr == nil { glog.Infof("Upscale AI Job decoded model=%v image=%v", req.ModelId, req.Image.Filename()) res, aiReqErr = n.AIWorker.Upscale(context.Background(), req) - res = &worker.ImageResponse{} // mock response if aiReqErr == nil { aiResultBytes, unmarshalResErr = json.Marshal(res) } From cd3f4f474d85eb4dcd84d0307c8d457ea338a69b Mon Sep 17 00:00:00 2001 From: Reuben Rodrigues Date: Fri, 5 Jul 2024 14:56:49 +0530 Subject: [PATCH 66/88] wip: rotate remote ai workers by model --- core/ai.go | 46 +++++++++++++++++++++++++++++++++++++------- core/orchestrator.go | 2 +- 2 files changed, 40 insertions(+), 8 deletions(-) diff --git a/core/ai.go b/core/ai.go index e82cf065e5..8dcf643836 100644 --- a/core/ai.go +++ b/core/ai.go @@ -57,8 +57,8 @@ func (s StringInt) String() string { type RemoteAIResultChan chan *RemoteAIWorkerResult type RemoteAIWorkerManager struct { - // TODO Mapping by pipeline - remoteWorkers []*RemoteAIWorker + // TODO: account for pipeline + remoteWorkers map[string][]*RemoteAIWorker liveWorkers map[net.Transcoder_RegisterAIWorkerServer]*RemoteAIWorker workersMutex sync.Mutex @@ -76,7 +76,7 @@ type RemoteAIWorkerResult struct { func NewRemoteAIWorkerManager() *RemoteAIWorkerManager { return &RemoteAIWorkerManager{ - remoteWorkers: []*RemoteAIWorker{}, + remoteWorkers: map[string][]*RemoteAIWorker{}, liveWorkers: map[net.Transcoder_RegisterAIWorkerServer]*RemoteAIWorker{}, workersMutex: sync.Mutex{}, @@ -98,7 +98,11 @@ func (m *RemoteAIWorkerManager) Manage(stream net.Transcoder_RegisterAIWorkerSer }() m.workersMutex.Lock() - m.remoteWorkers = append(m.remoteWorkers, worker) + for _, constraints := range capabilities.Constraints { + for modelID, _ := range constraints.Models { + m.remoteWorkers[modelID] = append(m.remoteWorkers[modelID], worker) + } + } m.liveWorkers[stream] = worker m.workersMutex.Unlock() @@ -119,8 +123,17 @@ func (m *RemoteAIWorkerManager) TextToImage(ctx context.Context, req worker.Text taskID, taskChan := m.addTaskChan() defer m.removeTaskChan(taskID) + var workerCount = len(m.remoteWorkers[*req.ModelId]) + if workerCount == 0 { + return nil, ErrOrchCap + } + // select a remote worker - w := m.remoteWorkers[0] + w := m.remoteWorkers[*req.ModelId][0] + glog.Infof("Selected worker %s for model %s; Total worker count: %v", w.addr, *req.ModelId, workerCount) + if workerCount > 1 { + m.remoteWorkers[*req.ModelId] = append(m.remoteWorkers[*req.ModelId][1:], m.remoteWorkers[*req.ModelId][0]) + } // send request to remote worker jsonData, err := json.Marshal(req) @@ -159,8 +172,17 @@ func (m *RemoteAIWorkerManager) ImageToImage(ctx context.Context, req worker.Ima taskID, taskChan := m.addTaskChan() defer m.removeTaskChan(taskID) + var workerCount = len(m.remoteWorkers[*req.ModelId]) + if workerCount == 0 { + return nil, ErrOrchCap + } + // select a remote worker - w := m.remoteWorkers[0] + w := m.remoteWorkers[*req.ModelId][0] + glog.Infof("Selected worker %s for model %s; Total worker count: %v", w.addr, *req.ModelId, workerCount) + if workerCount > 1 { + m.remoteWorkers[*req.ModelId] = append(m.remoteWorkers[*req.ModelId][1:], m.remoteWorkers[*req.ModelId][0]) + } // send request to remote worker jsonData, err := json.Marshal(req) @@ -204,7 +226,17 @@ func (m *RemoteAIWorkerManager) Upscale(ctx context.Context, req worker.UpscaleM defer m.removeTaskChan(taskID) // select a remote worker - w := m.remoteWorkers[0] + var workerCount = len(m.remoteWorkers[*req.ModelId]) + if workerCount == 0 { + return nil, ErrOrchCap + } + + // select a remote worker + w := m.remoteWorkers[*req.ModelId][0] + glog.Infof("Selected worker %s for model %s; Total worker count: %v", w.addr, *req.ModelId, workerCount) + if workerCount > 1 { + m.remoteWorkers[*req.ModelId] = append(m.remoteWorkers[*req.ModelId][1:], m.remoteWorkers[*req.ModelId][0]) + } // send request to remote worker jsonData, err := json.Marshal(req) diff --git a/core/orchestrator.go b/core/orchestrator.go index 83f404288c..3567dbbf3e 100644 --- a/core/orchestrator.go +++ b/core/orchestrator.go @@ -95,7 +95,7 @@ func (orch *orchestrator) CheckCapacity(mid ManifestID) error { // CheckAICapacity verifies if the orchestrator can process a request for a specific pipeline and modelID. func (orch *orchestrator) CheckAICapacity(pipeline, modelID string) bool { - return true + return len(orch.node.AIManager.remoteWorkers[modelID]) > 0 } func (orch *orchestrator) TranscodeSeg(ctx context.Context, md *SegTranscodingMetadata, seg *stream.HLSSegment) (*TranscodeResult, error) { From ee6bbc69d99150ce4ecc90d3646fbf565151e5ae Mon Sep 17 00:00:00 2001 From: Reuben Rodrigues Date: Sat, 6 Jul 2024 12:05:56 +0530 Subject: [PATCH 67/88] ai: map remote workers by pipeline --- core/ai.go | 28 ++++++++++++++-------------- core/orchestrator.go | 15 ++++++++++++++- 2 files changed, 28 insertions(+), 15 deletions(-) diff --git a/core/ai.go b/core/ai.go index 8dcf643836..477565f8b2 100644 --- a/core/ai.go +++ b/core/ai.go @@ -57,8 +57,8 @@ func (s StringInt) String() string { type RemoteAIResultChan chan *RemoteAIWorkerResult type RemoteAIWorkerManager struct { - // TODO: account for pipeline - remoteWorkers map[string][]*RemoteAIWorker + // workers mapped by Pipeline(Capability) + ModelID + remoteWorkers map[Capability]map[string][]*RemoteAIWorker liveWorkers map[net.Transcoder_RegisterAIWorkerServer]*RemoteAIWorker workersMutex sync.Mutex @@ -76,7 +76,7 @@ type RemoteAIWorkerResult struct { func NewRemoteAIWorkerManager() *RemoteAIWorkerManager { return &RemoteAIWorkerManager{ - remoteWorkers: map[string][]*RemoteAIWorker{}, + remoteWorkers: map[Capability]map[string][]*RemoteAIWorker{}, liveWorkers: map[net.Transcoder_RegisterAIWorkerServer]*RemoteAIWorker{}, workersMutex: sync.Mutex{}, @@ -98,9 +98,9 @@ func (m *RemoteAIWorkerManager) Manage(stream net.Transcoder_RegisterAIWorkerSer }() m.workersMutex.Lock() - for _, constraints := range capabilities.Constraints { + for cap, constraints := range capabilities.Constraints { for modelID, _ := range constraints.Models { - m.remoteWorkers[modelID] = append(m.remoteWorkers[modelID], worker) + m.remoteWorkers[Capability(cap)][modelID] = append(m.remoteWorkers[Capability(cap)][modelID], worker) } } m.liveWorkers[stream] = worker @@ -123,16 +123,16 @@ func (m *RemoteAIWorkerManager) TextToImage(ctx context.Context, req worker.Text taskID, taskChan := m.addTaskChan() defer m.removeTaskChan(taskID) - var workerCount = len(m.remoteWorkers[*req.ModelId]) + var workerCount = len(m.remoteWorkers[Capability_TextToImage][*req.ModelId]) if workerCount == 0 { return nil, ErrOrchCap } // select a remote worker - w := m.remoteWorkers[*req.ModelId][0] + w := m.remoteWorkers[Capability_TextToImage][*req.ModelId][0] glog.Infof("Selected worker %s for model %s; Total worker count: %v", w.addr, *req.ModelId, workerCount) if workerCount > 1 { - m.remoteWorkers[*req.ModelId] = append(m.remoteWorkers[*req.ModelId][1:], m.remoteWorkers[*req.ModelId][0]) + m.remoteWorkers[Capability_TextToImage][*req.ModelId] = append(m.remoteWorkers[Capability_TextToImage][*req.ModelId][1:], m.remoteWorkers[Capability_TextToImage][*req.ModelId][0]) } // send request to remote worker @@ -172,16 +172,16 @@ func (m *RemoteAIWorkerManager) ImageToImage(ctx context.Context, req worker.Ima taskID, taskChan := m.addTaskChan() defer m.removeTaskChan(taskID) - var workerCount = len(m.remoteWorkers[*req.ModelId]) + var workerCount = len(m.remoteWorkers[Capability_ImageToImage][*req.ModelId]) if workerCount == 0 { return nil, ErrOrchCap } // select a remote worker - w := m.remoteWorkers[*req.ModelId][0] + w := m.remoteWorkers[Capability_ImageToImage][*req.ModelId][0] glog.Infof("Selected worker %s for model %s; Total worker count: %v", w.addr, *req.ModelId, workerCount) if workerCount > 1 { - m.remoteWorkers[*req.ModelId] = append(m.remoteWorkers[*req.ModelId][1:], m.remoteWorkers[*req.ModelId][0]) + m.remoteWorkers[Capability_ImageToImage][*req.ModelId] = append(m.remoteWorkers[Capability_ImageToImage][*req.ModelId][1:], m.remoteWorkers[Capability_ImageToImage][*req.ModelId][0]) } // send request to remote worker @@ -226,16 +226,16 @@ func (m *RemoteAIWorkerManager) Upscale(ctx context.Context, req worker.UpscaleM defer m.removeTaskChan(taskID) // select a remote worker - var workerCount = len(m.remoteWorkers[*req.ModelId]) + var workerCount = len(m.remoteWorkers[Capability_Upscale][*req.ModelId]) if workerCount == 0 { return nil, ErrOrchCap } // select a remote worker - w := m.remoteWorkers[*req.ModelId][0] + w := m.remoteWorkers[Capability_Upscale][*req.ModelId][0] glog.Infof("Selected worker %s for model %s; Total worker count: %v", w.addr, *req.ModelId, workerCount) if workerCount > 1 { - m.remoteWorkers[*req.ModelId] = append(m.remoteWorkers[*req.ModelId][1:], m.remoteWorkers[*req.ModelId][0]) + m.remoteWorkers[Capability_Upscale][*req.ModelId] = append(m.remoteWorkers[Capability_Upscale][*req.ModelId][1:], m.remoteWorkers[Capability_Upscale][*req.ModelId][0]) } // send request to remote worker diff --git a/core/orchestrator.go b/core/orchestrator.go index 3567dbbf3e..4284e987a5 100644 --- a/core/orchestrator.go +++ b/core/orchestrator.go @@ -95,7 +95,20 @@ func (orch *orchestrator) CheckCapacity(mid ManifestID) error { // CheckAICapacity verifies if the orchestrator can process a request for a specific pipeline and modelID. func (orch *orchestrator) CheckAICapacity(pipeline, modelID string) bool { - return len(orch.node.AIManager.remoteWorkers[modelID]) > 0 + // TODO: Pass cap instead? Considering it's a public function might be + // better to pass the string directly + var cap Capability + switch pipeline { + case "text-to-image": + cap = Capability_TextToImage + case "image-to-image": + cap = Capability_ImageToImage + case "upscale": + cap = Capability_Upscale + default: + return false + } + return len(orch.node.AIManager.remoteWorkers[cap][modelID]) > 0 } func (orch *orchestrator) TranscodeSeg(ctx context.Context, md *SegTranscodingMetadata, seg *stream.HLSSegment) (*TranscodeResult, error) { From f0c6902a542b829dbb4d7792ad70ed10fbe8858b Mon Sep 17 00:00:00 2001 From: kyriediculous Date: Wed, 24 Jul 2024 05:12:04 +0200 Subject: [PATCH 68/88] core,server: improve remote AI worker code, clean up --- core/ai.go | 177 +++++++++++++------------------ core/capabilities.go | 19 ++++ server/ot_rpc.go | 244 +++++++++++++++++++++++-------------------- 3 files changed, 222 insertions(+), 218 deletions(-) diff --git a/core/ai.go b/core/ai.go index 477565f8b2..e4416bc90f 100644 --- a/core/ai.go +++ b/core/ai.go @@ -111,42 +111,52 @@ func (m *RemoteAIWorkerManager) Manage(stream net.Transcoder_RegisterAIWorkerSer m.workersMutex.Lock() delete(m.liveWorkers, stream) - // TODO: remove from remoteWorkers - m.workersMutex.Unlock() -} -func (m *RemoteAIWorkerManager) handleAIRequest(req *net.NotifyAIJob) { - // send request to selected remote worker + // Remove worker from remoteWorkers + for cap, modelMap := range m.remoteWorkers { + for modelID, workers := range modelMap { + for i, w := range workers { + if w == worker { + // Remove the worker from the slice + m.remoteWorkers[cap][modelID] = append(workers[:i], workers[i+1:]...) + break + } + } + // If the worker list is empty, remove the modelID entry + if len(m.remoteWorkers[cap][modelID]) == 0 { + delete(m.remoteWorkers[cap], modelID) + } + } + // If the capability map is empty, remove the capability entry + if len(m.remoteWorkers[cap]) == 0 { + delete(m.remoteWorkers, cap) + } + } + + m.workersMutex.Unlock() } -func (m *RemoteAIWorkerManager) TextToImage(ctx context.Context, req worker.TextToImageJSONRequestBody) (*worker.ImageResponse, error) { +func (m *RemoteAIWorkerManager) processAIRequest(ctx context.Context, capability Capability, req interface{}, aiRequestType net.AIRequestType) (interface{}, error) { taskID, taskChan := m.addTaskChan() defer m.removeTaskChan(taskID) - var workerCount = len(m.remoteWorkers[Capability_TextToImage][*req.ModelId]) - if workerCount == 0 { - return nil, ErrOrchCap - } + modelID := getModelID(req) - // select a remote worker - w := m.remoteWorkers[Capability_TextToImage][*req.ModelId][0] - glog.Infof("Selected worker %s for model %s; Total worker count: %v", w.addr, *req.ModelId, workerCount) - if workerCount > 1 { - m.remoteWorkers[Capability_TextToImage][*req.ModelId] = append(m.remoteWorkers[Capability_TextToImage][*req.ModelId][1:], m.remoteWorkers[Capability_TextToImage][*req.ModelId][0]) + w, err := m.selectWorker(capability, modelID) + if err != nil { + return nil, err } - // send request to remote worker jsonData, err := json.Marshal(req) if err != nil { return nil, err } remoteReq := &net.NotifyAIJob{ - Type: net.AIRequestType_TextToImage, + Type: aiRequestType, TaskID: taskID, Data: jsonData, } - m.handleAIRequest(remoteReq) // task id, pipeline if err := w.stream.Send(remoteReq); err != nil { return nil, err @@ -154,121 +164,82 @@ func (m *RemoteAIWorkerManager) TextToImage(ctx context.Context, req worker.Text select { case <-ctx.Done(): - // return EOF signal + return nil, ctx.Err() case chanData := <-taskChan: - var res worker.ImageResponse + var res interface{} if err := json.Unmarshal(chanData.Bytes, &res); err != nil { return nil, err } - glog.Infof("Received AI result for task %d images=%s", chanData.TaskID, res.Images) - return &res, nil + glog.Infof("Received AI result for task %d", chanData.TaskID) + return res, nil } - return nil, nil - } -// TODO: DRY these? -func (m *RemoteAIWorkerManager) ImageToImage(ctx context.Context, req worker.ImageToImageMultipartRequestBody) (*worker.ImageResponse, error) { - taskID, taskChan := m.addTaskChan() - defer m.removeTaskChan(taskID) +func (m *RemoteAIWorkerManager) selectWorker(capability Capability, modelID string) (*RemoteAIWorker, error) { + m.workersMutex.Lock() + defer m.workersMutex.Unlock() + workers := m.remoteWorkers[capability][modelID] - var workerCount = len(m.remoteWorkers[Capability_ImageToImage][*req.ModelId]) - if workerCount == 0 { + if len(workers) == 0 { return nil, ErrOrchCap } - // select a remote worker - w := m.remoteWorkers[Capability_ImageToImage][*req.ModelId][0] - glog.Infof("Selected worker %s for model %s; Total worker count: %v", w.addr, *req.ModelId, workerCount) - if workerCount > 1 { - m.remoteWorkers[Capability_ImageToImage][*req.ModelId] = append(m.remoteWorkers[Capability_ImageToImage][*req.ModelId][1:], m.remoteWorkers[Capability_ImageToImage][*req.ModelId][0]) - } - - // send request to remote worker - jsonData, err := json.Marshal(req) - if err != nil { - return nil, err - } + w := workers[0] + glog.Infof("Selected worker %s for model %s; Total worker count: %v", w.addr, modelID, len(workers)) - remoteReq := &net.NotifyAIJob{ - Type: net.AIRequestType_ImageToImage, - TaskID: taskID, - Data: jsonData, + if len(workers) > 1 { + m.remoteWorkers[capability][modelID] = append(workers[1:], workers[0]) } - m.handleAIRequest(remoteReq) // task id, pipeline + return w, nil +} - if err := w.stream.Send(remoteReq); err != nil { +func (m *RemoteAIWorkerManager) TextToImage(ctx context.Context, req worker.TextToImageJSONRequestBody) (*worker.ImageResponse, error) { + res, err := m.processAIRequest(ctx, Capability_TextToImage, req, net.AIRequestType_TextToImage) + if err != nil { return nil, err } - - select { - case <-ctx.Done(): - // return EOF signal - case chanData := <-taskChan: - var res worker.ImageResponse - if err := json.Unmarshal(chanData.Bytes, &res); err != nil { - return nil, err - } - glog.Infof("Received AI result for task %d images=%s", chanData.TaskID, res.Images) - return &res, nil - } - - return nil, nil + return res.(*worker.ImageResponse), nil } -func (m *RemoteAIWorkerManager) ImageToVideo(ctx context.Context, req worker.ImageToVideoMultipartRequestBody) (*worker.VideoResponse, error) { - return nil, nil +func (m *RemoteAIWorkerManager) ImageToImage(ctx context.Context, req worker.ImageToImageMultipartRequestBody) (*worker.ImageResponse, error) { + res, err := m.processAIRequest(ctx, Capability_ImageToImage, req, net.AIRequestType_ImageToImage) + if err != nil { + return nil, err + } + return res.(*worker.ImageResponse), nil } func (m *RemoteAIWorkerManager) Upscale(ctx context.Context, req worker.UpscaleMultipartRequestBody) (*worker.ImageResponse, error) { - taskID, taskChan := m.addTaskChan() - defer m.removeTaskChan(taskID) - - // select a remote worker - var workerCount = len(m.remoteWorkers[Capability_Upscale][*req.ModelId]) - if workerCount == 0 { - return nil, ErrOrchCap - } - - // select a remote worker - w := m.remoteWorkers[Capability_Upscale][*req.ModelId][0] - glog.Infof("Selected worker %s for model %s; Total worker count: %v", w.addr, *req.ModelId, workerCount) - if workerCount > 1 { - m.remoteWorkers[Capability_Upscale][*req.ModelId] = append(m.remoteWorkers[Capability_Upscale][*req.ModelId][1:], m.remoteWorkers[Capability_Upscale][*req.ModelId][0]) - } - - // send request to remote worker - jsonData, err := json.Marshal(req) + res, err := m.processAIRequest(ctx, Capability_Upscale, req, net.AIRequestType_Upscale) if err != nil { return nil, err } + return res.(*worker.ImageResponse), nil +} - remoteReq := &net.NotifyAIJob{ - Type: net.AIRequestType_Upscale, - TaskID: taskID, - Data: jsonData, +// Helper function to get ModelId from different request types +func getModelID(req interface{}) string { + switch r := req.(type) { + case worker.TextToImageJSONRequestBody: + return *r.ModelId + case worker.ImageToImageMultipartRequestBody: + return *r.ModelId + case worker.UpscaleMultipartRequestBody: + return *r.ModelId + case worker.ImageToVideoMultipartRequestBody: + return *r.ModelId + default: + return "" } +} - m.handleAIRequest(remoteReq) // task id, pipeline - - if err := w.stream.Send(remoteReq); err != nil { +func (m *RemoteAIWorkerManager) ImageToVideo(ctx context.Context, req worker.ImageToVideoMultipartRequestBody) (*worker.VideoResponse, error) { + res, err := m.processAIRequest(ctx, Capability_ImageToVideo, req, net.AIRequestType_ImageToVideo) + if err != nil { return nil, err } - - select { - case <-ctx.Done(): - // return EOF signal - case chanData := <-taskChan: - var res worker.ImageResponse - if err := json.Unmarshal(chanData.Bytes, &res); err != nil { - return nil, err - } - glog.Infof("Received AI result for task %d images=%s", chanData.TaskID, res.Images) - return &res, nil - } - - return nil, nil + return res.(*worker.VideoResponse), nil } func (m *RemoteAIWorkerManager) Warm(ctx context.Context, pipeline, modelID string, endpoint worker.RunnerEndpoint, flags worker.OptimizationFlags) error { diff --git a/core/capabilities.go b/core/capabilities.go index 3f4e6232d2..81a60ac88f 100644 --- a/core/capabilities.go +++ b/core/capabilities.go @@ -207,6 +207,25 @@ func OptionalCapabilities() []Capability { } } +func AICapabilities() []Capability { + return []Capability{ + Capability_TextToImage, + Capability_ImageToImage, + Capability_ImageToVideo, + Capability_Upscale, + } +} + +func ContainsAICapabilities(caps []Capability) bool { + for _, c := range caps { + switch c { + case Capability_TextToImage, Capability_ImageToImage, Capability_ImageToVideo, Capability_Upscale: + return true + } + } + return false +} + func MandatoryOCapabilities() []Capability { // Add to this list as certain features become mandatory. // Use sparingly, as adding to this is a hard break with older nodes diff --git a/server/ot_rpc.go b/server/ot_rpc.go index 6080d4679f..94e2473f05 100644 --- a/server/ot_rpc.go +++ b/server/ot_rpc.go @@ -99,47 +99,42 @@ func runTranscoder(n *core.LivepeerNode, orchAddr string, capacity int, caps []c // Silence linter defer cancel() - // TODO: check if transcoding capabilities are defined - + // // TODO: check if transcoding capabilities are defined + netCaps := core.NewCapabilities(caps, []core.Capability{}).ToNetCapabilities() + // coreCaps.CompatibleWith(core.NewCapabilities(core.DefaultCapabilities(), []core.Capability{}).ToNetCapabilities()) tR, err := c.RegisterTranscoder(ctx, &net.RegisterRequest{Secret: n.OrchSecret, Capacity: int64(capacity), - Capabilities: core.NewCapabilities(caps, []core.Capability{}).ToNetCapabilities()}) + Capabilities: netCaps}) if err := checkTranscoderError(err); err != nil { glog.Error("Could not register transcoder to orchestrator ", err) return err } - // TODO check if ai capabilities are defined - aiR, err := c.RegisterAIWorker(ctx, &net.RegisterRequest{Secret: n.OrchSecret, Capacity: int64(capacity), - Capabilities: n.Capabilities.ToNetCapabilities()}) - // TODO: add checking AI errors to checkTranscoderError - if err := checkTranscoderError(err); err != nil { - glog.Error("Could not register AI worker to orchestrator ", err) - return err + var aiR net.Transcoder_RegisterAIWorkerClient + if core.ContainsAICapabilities(caps) { + aiR, err = c.RegisterAIWorker(ctx, &net.RegisterRequest{Secret: n.OrchSecret, Capacity: int64(capacity), + Capabilities: netCaps}) + // TODO: add checking AI errors to checkTranscoderError + if err := checkTranscoderError(err); err != nil { + glog.Error("Could not register AI worker to orchestrator ", err) + return err + } } // Catch interrupt signal to shut down transcoder exitc := make(chan os.Signal) signal.Notify(exitc, os.Interrupt, syscall.SIGTERM) defer signal.Stop(exitc) - go func() { - select { - case sig := <-exitc: - glog.Infof("Exiting Livepeer Transcoder: %v", sig) - // Cancelling context will close connection to orchestrator - cancel() - return - } - }() + defer close(exitc) httpc := &http.Client{Transport: &http2.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: true}}} var wg sync.WaitGroup - + errChan := make(chan error, 2) // Channels to receive messages tRChan := make(chan *net.NotifySegment) aiRChan := make(chan *net.NotifyAIJob) - errChan := make(chan error) go func() { + defer close(tRChan) for { notify, err := tR.Recv() if err != nil { @@ -152,6 +147,7 @@ func runTranscoder(n *core.LivepeerNode, orchAddr string, capacity int, caps []c }() go func() { + defer close(aiRChan) for { aiJob, err := aiR.Recv() @@ -165,8 +161,9 @@ func runTranscoder(n *core.LivepeerNode, orchAddr string, capacity int, caps []c for { select { + case <-ctx.Done(): + return ctx.Err() case notify := <-tRChan: - if notify.SegData != nil && notify.SegData.AuthToken != nil && len(notify.SegData.AuthToken.SessionId) > 0 && len(notify.Url) == 0 { // session teardown signal n.Transcoder.EndTranscodingSession(notify.SegData.AuthToken.SessionId) @@ -178,112 +175,129 @@ func runTranscoder(n *core.LivepeerNode, orchAddr string, capacity int, caps []c }() } case aiJob := <-aiRChan: - if aiJob == nil { - glog.Error("Received nil AI job") - continue - } - glog.Infof("Received AI job %v type: %v", aiJob.TaskID, aiJob.Type) - - // var aiResult *core.RemoteAIWorkerResult - var aiResultBytes []byte - var unmarshalReqErr error - var unmarshalResErr error - var aiReqErr error - - switch aiJob.Type { - case net.AIRequestType_TextToImage: - var req worker.TextToImageJSONRequestBody - var res *worker.ImageResponse - if unmarshalReqErr = json.Unmarshal(aiJob.Data, &req); unmarshalReqErr == nil { - glog.Infof("Text-to-Image AI Job decoded model=%v prompt=%v", req.ModelId, req.Prompt) - res, aiReqErr = n.AIWorker.TextToImage(context.Background(), req) - if aiReqErr == nil { - aiResultBytes, unmarshalResErr = json.Marshal(res) - } - } - case net.AIRequestType_ImageToImage: - var req worker.ImageToImageMultipartRequestBody - var res *worker.ImageResponse - if unmarshalReqErr = json.Unmarshal(aiJob.Data, &req); unmarshalReqErr == nil { - glog.Infof("Image-to-Image AI Job decoded model=%v image=%v", req.ModelId, req.Image.Filename()) - res, aiReqErr = n.AIWorker.ImageToImage(context.Background(), req) - if aiReqErr == nil { - aiResultBytes, unmarshalResErr = json.Marshal(res) - } - } - case net.AIRequestType_Upscale: - var req worker.UpscaleMultipartRequestBody - var res *worker.ImageResponse - if unmarshalReqErr = json.Unmarshal(aiJob.Data, &req); unmarshalReqErr == nil { - glog.Infof("Upscale AI Job decoded model=%v image=%v", req.ModelId, req.Image.Filename()) - res, aiReqErr = n.AIWorker.Upscale(context.Background(), req) - if aiReqErr == nil { - aiResultBytes, unmarshalResErr = json.Marshal(res) - } - } - default: - glog.Errorf("Invalid Job type decoded taskID=%v type=%v", aiJob.TaskID, aiJob.Type) - continue + wg.Add(1) + go func() { + defer wg.Done() + runAIJob(ctx, aiJob, n, orchAddr, httpc) + }() + case err := <-errChan: + if err := checkTranscoderError(err); err != nil { + glog.Infof(`End of stream receive cycle because of err=%q, waiting for running transcode and ai jobs to complete`, err) + wg.Wait() + return err } + case sig := <-exitc: + glog.Infof("Exiting Livepeer Transcoder: %v", sig) + // Cancelling context will close connection to orchestrator + cancel() + return nil + } + } +} - if unmarshalReqErr != nil { - glog.Errorf("Unable to unmarshal AI job data taskID=%v err=%q", aiJob.TaskID, unmarshalReqErr) - continue +func runAIJob(ctx context.Context, aiJob *net.NotifyAIJob, n *core.LivepeerNode, orchAddr string, httpc *http.Client) { + // Process the transcoding job + select { + case <-ctx.Done(): + glog.Info("Received cancellation signal err=%q", ctx.Err()) + return + default: + if aiJob == nil { + glog.Error("Received nil AI job") + return + } + glog.Infof("Received AI job %v type: %v", aiJob.TaskID, aiJob.Type) + + // var aiResult *core.RemoteAIWorkerResult + var aiResultBytes []byte + var unmarshalReqErr error + var unmarshalResErr error + var aiReqErr error + + switch aiJob.Type { + case net.AIRequestType_TextToImage: + var req worker.TextToImageJSONRequestBody + var res *worker.ImageResponse + if unmarshalReqErr = json.Unmarshal(aiJob.Data, &req); unmarshalReqErr == nil { + glog.Infof("Text-to-Image AI Job decoded model=%v prompt=%v", req.ModelId, req.Prompt) + res, aiReqErr = n.AIWorker.TextToImage(context.Background(), req) + if aiReqErr == nil { + aiResultBytes, unmarshalResErr = json.Marshal(res) + } } - - if aiReqErr != nil { - glog.Errorf("AI job failed ID=%v err=%v", aiJob.TaskID, aiReqErr) - continue + case net.AIRequestType_ImageToImage: + var req worker.ImageToImageMultipartRequestBody + var res *worker.ImageResponse + if unmarshalReqErr = json.Unmarshal(aiJob.Data, &req); unmarshalReqErr == nil { + glog.Infof("Image-to-Image AI Job decoded model=%v image=%v", req.ModelId, req.Image.Filename()) + res, aiReqErr = n.AIWorker.ImageToImage(context.Background(), req) + if aiReqErr == nil { + aiResultBytes, unmarshalResErr = json.Marshal(res) + } } - - if unmarshalResErr != nil { - glog.Errorf("Unable to marshal AI job response ID=%v err=%q", aiJob.TaskID, unmarshalResErr) - continue + case net.AIRequestType_Upscale: + var req worker.UpscaleMultipartRequestBody + var res *worker.ImageResponse + if unmarshalReqErr = json.Unmarshal(aiJob.Data, &req); unmarshalReqErr == nil { + glog.Infof("Upscale AI Job decoded model=%v image=%v", req.ModelId, req.Image.Filename()) + res, aiReqErr = n.AIWorker.Upscale(context.Background(), req) + if aiReqErr == nil { + aiResultBytes, unmarshalResErr = json.Marshal(res) + } } + default: + glog.Errorf("Invalid Job type decoded taskID=%v type=%v", aiJob.TaskID, aiJob.Type) + return + } - aiResult := &core.RemoteAIWorkerResult{ - JobType: aiJob.Type, - TaskID: aiJob.TaskID, - Bytes: aiResultBytes, - Err: err, - } + if unmarshalReqErr != nil { + glog.Errorf("Unable to unmarshal AI job data taskID=%v err=%q", aiJob.TaskID, unmarshalReqErr) + return + } - // Create a bytes.Buffer and write the JSON data to it - var body bytes.Buffer - jsonAiResult, err := json.Marshal(aiResult) - if err != nil { - glog.Errorf("Error marshaling JSON err=%q", err) - continue - } - body.Write(jsonAiResult) + if aiReqErr != nil { + glog.Errorf("AI job failed ID=%v err=%v", aiJob.TaskID, aiReqErr) + return + } - // Post result back to orchestrator - req, err := http.NewRequest("POST", "https://"+orchAddr+"/aiResults", &body) - if err != nil { - glog.Errorf("Error posting results to orch=%s taskId=%d type=%s err=%q", orchAddr, - aiResult.TaskID, aiResult.JobType, err) - continue - } - req.Header.Set("Authorization", protoVerLPT) - req.Header.Set("Credentials", n.OrchSecret) - req.Header.Set("Content-Type", "application/json") + if unmarshalResErr != nil { + glog.Errorf("Unable to marshal AI job response ID=%v err=%q", aiJob.TaskID, unmarshalResErr) + return + } - resp, err := httpc.Do(req) - if err != nil { - glog.Errorf("Error submitting results err=%q", err) - continue - } - defer resp.Body.Close() + aiResult := &core.RemoteAIWorkerResult{ + JobType: aiJob.Type, + TaskID: aiJob.TaskID, + Bytes: aiResultBytes, + Err: aiReqErr, + } - case err := <-errChan: - if err := checkTranscoderError(err); err != nil { - glog.Infof(`End of stream receive cycle because of err=%q, waiting for running transcode jobs to complete`, err) - wg.Wait() - return err - } + // Create a bytes.Buffer and write the JSON data to it + var body bytes.Buffer + jsonAiResult, err := json.Marshal(aiResult) + if err != nil { + glog.Errorf("Error marshaling JSON err=%q", err) + return + } + body.Write(jsonAiResult) + // Post result back to orchestrator + req, err := http.NewRequest("POST", "https://"+orchAddr+"/aiResults", &body) + if err != nil { + glog.Errorf("Error posting results to orch=%s taskId=%d type=%s err=%q", orchAddr, + aiResult.TaskID, aiResult.JobType, err) + return } + req.Header.Set("Authorization", protoVerLPT) + req.Header.Set("Credentials", n.OrchSecret) + req.Header.Set("Content-Type", "application/json") + resp, err := httpc.Do(req) + if err != nil { + glog.Errorf("Error submitting results err=%q", err) + return + } + defer resp.Body.Close() } } From b1df7a486e7a697e39a655342e491dc3cd5e0e75 Mon Sep 17 00:00:00 2001 From: kyriediculous Date: Thu, 25 Jul 2024 17:07:41 +0200 Subject: [PATCH 69/88] fix: remote transcoder selection bug fixes --- cmd/livepeer/starter/starter.go | 2 +- core/ai.go | 46 +++++++++++++++++++++++++++++---- core/capabilities.go | 6 ++--- core/orchestrator.go | 13 +--------- server/ot_rpc.go | 11 +++----- 5 files changed, 50 insertions(+), 28 deletions(-) diff --git a/cmd/livepeer/starter/starter.go b/cmd/livepeer/starter/starter.go index 8aca90fd94..2b598ce685 100755 --- a/cmd/livepeer/starter/starter.go +++ b/cmd/livepeer/starter/starter.go @@ -1477,7 +1477,7 @@ func StartLivepeer(ctx context.Context, cfg LivepeerConfig) { glog.Exit("Missing -orchAddr") } - go server.RunTranscoder(n, orchURLs[0].Host, core.MaxSessions, append(transcoderCaps, aiCaps...)) + go server.RunTranscoder(n, orchURLs[0].Host, core.MaxSessions, n.Capabilities) } switch n.NodeType { diff --git a/core/ai.go b/core/ai.go index e4416bc90f..ec2f3b9050 100644 --- a/core/ai.go +++ b/core/ai.go @@ -99,8 +99,17 @@ func (m *RemoteAIWorkerManager) Manage(stream net.Transcoder_RegisterAIWorkerSer m.workersMutex.Lock() for cap, constraints := range capabilities.Constraints { + c := Capability(cap) + // Initialize the inner map if it's nil + if m.remoteWorkers[c] == nil { + m.remoteWorkers[c] = make(map[string][]*RemoteAIWorker) + } for modelID, _ := range constraints.Models { - m.remoteWorkers[Capability(cap)][modelID] = append(m.remoteWorkers[Capability(cap)][modelID], worker) + // Initialize the remoteWorkers slice if it's nil + if m.remoteWorkers[Capability(cap)][modelID] == nil { + m.remoteWorkers[Capability(cap)][modelID] = []*RemoteAIWorker{} + } + m.remoteWorkers[c][modelID] = append(m.remoteWorkers[c][modelID], worker) } } m.liveWorkers[stream] = worker @@ -166,11 +175,22 @@ func (m *RemoteAIWorkerManager) processAIRequest(ctx context.Context, capability case <-ctx.Done(): return nil, ctx.Err() case chanData := <-taskChan: + glog.Infof("Received AI result for task %d", chanData.TaskID) var res interface{} - if err := json.Unmarshal(chanData.Bytes, &res); err != nil { - return nil, err + switch aiRequestType { + case net.AIRequestType_ImageToVideo: + var videoRes worker.VideoResponse + if err := json.Unmarshal(chanData.Bytes, &videoRes); err != nil { + return nil, err + } + res = &videoRes + default: + var imgRes worker.ImageResponse + if err := json.Unmarshal(chanData.Bytes, &imgRes); err != nil { + return nil, err + } + res = &imgRes } - glog.Infof("Received AI result for task %d", chanData.TaskID) return res, nil } } @@ -251,7 +271,23 @@ func (m *RemoteAIWorkerManager) Stop(ctx context.Context) error { } func (m *RemoteAIWorkerManager) HasCapacity(pipeline, modelID string) bool { - return false + m.workersMutex.Lock() + defer m.workersMutex.Unlock() + // TODO: Pass cap instead? Considering it's a public function might be + // better to pass the string directly + var cap Capability + switch pipeline { + case "text-to-image": + cap = Capability_TextToImage + case "image-to-image": + cap = Capability_ImageToImage + case "upscale": + cap = Capability_Upscale + default: + return false + } + + return len(m.remoteWorkers[cap][modelID]) > 0 } func (m *RemoteAIWorkerManager) aiResult(res *RemoteAIWorkerResult) { diff --git a/core/capabilities.go b/core/capabilities.go index 81a60ac88f..9f99459f12 100644 --- a/core/capabilities.go +++ b/core/capabilities.go @@ -216,9 +216,9 @@ func AICapabilities() []Capability { } } -func ContainsAICapabilities(caps []Capability) bool { - for _, c := range caps { - switch c { +func ContainsAICapabilities(caps *Capabilities) bool { + for cap, _ := range caps.capacities { + switch cap { case Capability_TextToImage, Capability_ImageToImage, Capability_ImageToVideo, Capability_Upscale: return true } diff --git a/core/orchestrator.go b/core/orchestrator.go index 4284e987a5..e3c2ac2f4c 100644 --- a/core/orchestrator.go +++ b/core/orchestrator.go @@ -97,18 +97,7 @@ func (orch *orchestrator) CheckCapacity(mid ManifestID) error { func (orch *orchestrator) CheckAICapacity(pipeline, modelID string) bool { // TODO: Pass cap instead? Considering it's a public function might be // better to pass the string directly - var cap Capability - switch pipeline { - case "text-to-image": - cap = Capability_TextToImage - case "image-to-image": - cap = Capability_ImageToImage - case "upscale": - cap = Capability_Upscale - default: - return false - } - return len(orch.node.AIManager.remoteWorkers[cap][modelID]) > 0 + return orch.node.AIWorker.HasCapacity(pipeline, modelID) } func (orch *orchestrator) TranscodeSeg(ctx context.Context, md *SegTranscodingMetadata, seg *stream.HLSSegment) (*TranscodeResult, error) { diff --git a/server/ot_rpc.go b/server/ot_rpc.go index 94e2473f05..50c014f698 100644 --- a/server/ot_rpc.go +++ b/server/ot_rpc.go @@ -49,7 +49,7 @@ var errCapabilities = errors.New("incompatible segment capabilities") // RunTranscoder is main routing of standalone transcoder // Exiting it will terminate executable -func RunTranscoder(n *core.LivepeerNode, orchAddr string, capacity int, caps []core.Capability) { +func RunTranscoder(n *core.LivepeerNode, orchAddr string, capacity int, caps *core.Capabilities) { expb := backoff.NewExponentialBackOff() expb.MaxInterval = time.Minute expb.MaxElapsedTime = 0 @@ -83,7 +83,7 @@ func checkTranscoderError(err error) error { return err } -func runTranscoder(n *core.LivepeerNode, orchAddr string, capacity int, caps []core.Capability) error { +func runTranscoder(n *core.LivepeerNode, orchAddr string, capacity int, caps *core.Capabilities) error { tlsConfig := &tls.Config{InsecureSkipVerify: true} conn, err := grpc.Dial(orchAddr, grpc.WithTransportCredentials(credentials.NewTLS(tlsConfig))) @@ -99,11 +99,8 @@ func runTranscoder(n *core.LivepeerNode, orchAddr string, capacity int, caps []c // Silence linter defer cancel() - // // TODO: check if transcoding capabilities are defined - netCaps := core.NewCapabilities(caps, []core.Capability{}).ToNetCapabilities() - // coreCaps.CompatibleWith(core.NewCapabilities(core.DefaultCapabilities(), []core.Capability{}).ToNetCapabilities()) tR, err := c.RegisterTranscoder(ctx, &net.RegisterRequest{Secret: n.OrchSecret, Capacity: int64(capacity), - Capabilities: netCaps}) + Capabilities: caps.ToNetCapabilities()}) if err := checkTranscoderError(err); err != nil { glog.Error("Could not register transcoder to orchestrator ", err) return err @@ -112,7 +109,7 @@ func runTranscoder(n *core.LivepeerNode, orchAddr string, capacity int, caps []c var aiR net.Transcoder_RegisterAIWorkerClient if core.ContainsAICapabilities(caps) { aiR, err = c.RegisterAIWorker(ctx, &net.RegisterRequest{Secret: n.OrchSecret, Capacity: int64(capacity), - Capabilities: netCaps}) + Capabilities: caps.ToNetCapabilities()}) // TODO: add checking AI errors to checkTranscoderError if err := checkTranscoderError(err); err != nil { glog.Error("Could not register AI worker to orchestrator ", err) From 0fbf3f03f7990b1d3c05f82ce41f515677502064 Mon Sep 17 00:00:00 2001 From: kyriediculous Date: Sat, 27 Jul 2024 01:31:44 +0200 Subject: [PATCH 70/88] fix: improve CheckAICapacity to have no breaking changes --- core/ai.go | 6 +++--- core/capabilities.go | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/core/ai.go b/core/ai.go index ec2f3b9050..caaa8d5e22 100644 --- a/core/ai.go +++ b/core/ai.go @@ -273,8 +273,6 @@ func (m *RemoteAIWorkerManager) Stop(ctx context.Context) error { func (m *RemoteAIWorkerManager) HasCapacity(pipeline, modelID string) bool { m.workersMutex.Lock() defer m.workersMutex.Unlock() - // TODO: Pass cap instead? Considering it's a public function might be - // better to pass the string directly var cap Capability switch pipeline { case "text-to-image": @@ -283,11 +281,13 @@ func (m *RemoteAIWorkerManager) HasCapacity(pipeline, modelID string) bool { cap = Capability_ImageToImage case "upscale": cap = Capability_Upscale + case "image-to-video": + cap = Capability_ImageToVideo default: return false } - return len(m.remoteWorkers[cap][modelID]) > 0 + } func (m *RemoteAIWorkerManager) aiResult(res *RemoteAIWorkerResult) { diff --git a/core/capabilities.go b/core/capabilities.go index 9f99459f12..3f59cae43d 100644 --- a/core/capabilities.go +++ b/core/capabilities.go @@ -559,6 +559,7 @@ func (cap *Capabilities) AddCapacity(newCaps *Capabilities) { curCapacity, e := cap.capacities[capability] if !e { cap.capacities[capability] = 0 + glog.Infof("Adding new capability %v", capability) } cap.capacities[capability] = curCapacity + capacity arrIdx := int(capability) / 64 From e2961a06f176a7d30ee1973dc7aa0d0cd3a7f2a7 Mon Sep 17 00:00:00 2001 From: kyriediculous Date: Sat, 27 Jul 2024 03:06:34 +0200 Subject: [PATCH 71/88] fix: improve ot_rpc remote ai worker error handling --- core/capabilities.go | 1 - server/ot_rpc.go | 48 +++++++++++++++++--------------------------- 2 files changed, 18 insertions(+), 31 deletions(-) diff --git a/core/capabilities.go b/core/capabilities.go index 3f59cae43d..9f99459f12 100644 --- a/core/capabilities.go +++ b/core/capabilities.go @@ -559,7 +559,6 @@ func (cap *Capabilities) AddCapacity(newCaps *Capabilities) { curCapacity, e := cap.capacities[capability] if !e { cap.capacities[capability] = 0 - glog.Infof("Adding new capability %v", capability) } cap.capacities[capability] = curCapacity + capacity arrIdx := int(capability) / 64 diff --git a/server/ot_rpc.go b/server/ot_rpc.go index 50c014f698..a9d8345722 100644 --- a/server/ot_rpc.go +++ b/server/ot_rpc.go @@ -207,66 +207,54 @@ func runAIJob(ctx context.Context, aiJob *net.NotifyAIJob, n *core.LivepeerNode, // var aiResult *core.RemoteAIWorkerResult var aiResultBytes []byte - var unmarshalReqErr error - var unmarshalResErr error - var aiReqErr error + + var err error switch aiJob.Type { case net.AIRequestType_TextToImage: var req worker.TextToImageJSONRequestBody var res *worker.ImageResponse - if unmarshalReqErr = json.Unmarshal(aiJob.Data, &req); unmarshalReqErr == nil { + if err = json.Unmarshal(aiJob.Data, &req); err == nil { glog.Infof("Text-to-Image AI Job decoded model=%v prompt=%v", req.ModelId, req.Prompt) - res, aiReqErr = n.AIWorker.TextToImage(context.Background(), req) - if aiReqErr == nil { - aiResultBytes, unmarshalResErr = json.Marshal(res) + res, err = n.AIWorker.TextToImage(context.Background(), req) + if err == nil { + aiResultBytes, err = json.Marshal(res) } } case net.AIRequestType_ImageToImage: var req worker.ImageToImageMultipartRequestBody var res *worker.ImageResponse - if unmarshalReqErr = json.Unmarshal(aiJob.Data, &req); unmarshalReqErr == nil { + if err = json.Unmarshal(aiJob.Data, &req); err == nil { glog.Infof("Image-to-Image AI Job decoded model=%v image=%v", req.ModelId, req.Image.Filename()) - res, aiReqErr = n.AIWorker.ImageToImage(context.Background(), req) - if aiReqErr == nil { - aiResultBytes, unmarshalResErr = json.Marshal(res) + res, err = n.AIWorker.ImageToImage(context.Background(), req) + if err == nil { + aiResultBytes, err = json.Marshal(res) } } case net.AIRequestType_Upscale: var req worker.UpscaleMultipartRequestBody var res *worker.ImageResponse - if unmarshalReqErr = json.Unmarshal(aiJob.Data, &req); unmarshalReqErr == nil { + if err = json.Unmarshal(aiJob.Data, &req); err == nil { glog.Infof("Upscale AI Job decoded model=%v image=%v", req.ModelId, req.Image.Filename()) - res, aiReqErr = n.AIWorker.Upscale(context.Background(), req) - if aiReqErr == nil { - aiResultBytes, unmarshalResErr = json.Marshal(res) + res, err = n.AIWorker.Upscale(context.Background(), req) + if err == nil { + aiResultBytes, err = json.Marshal(res) } } default: glog.Errorf("Invalid Job type decoded taskID=%v type=%v", aiJob.TaskID, aiJob.Type) - return - } - - if unmarshalReqErr != nil { - glog.Errorf("Unable to unmarshal AI job data taskID=%v err=%q", aiJob.TaskID, unmarshalReqErr) - return + err = fmt.Errorf("Invalid Job type decoded taskID=%v type=%v", aiJob.TaskID, aiJob.Type) } - if aiReqErr != nil { - glog.Errorf("AI job failed ID=%v err=%v", aiJob.TaskID, aiReqErr) - return - } - - if unmarshalResErr != nil { - glog.Errorf("Unable to marshal AI job response ID=%v err=%q", aiJob.TaskID, unmarshalResErr) - return + if err != nil { + glog.Errorf("AI job failed ID=%v err=%v", aiJob.TaskID, err) } aiResult := &core.RemoteAIWorkerResult{ JobType: aiJob.Type, TaskID: aiJob.TaskID, Bytes: aiResultBytes, - Err: aiReqErr, + Err: err, } // Create a bytes.Buffer and write the JSON data to it From 64e1f5eea5dca20c4e98423ee3ce7cd87c33d226 Mon Sep 17 00:00:00 2001 From: kyriediculous Date: Sat, 27 Jul 2024 03:15:03 +0200 Subject: [PATCH 72/88] fix: propagate remote AI result error properly --- core/ai.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/core/ai.go b/core/ai.go index caaa8d5e22..22f6ea9e3c 100644 --- a/core/ai.go +++ b/core/ai.go @@ -175,6 +175,9 @@ func (m *RemoteAIWorkerManager) processAIRequest(ctx context.Context, capability case <-ctx.Done(): return nil, ctx.Err() case chanData := <-taskChan: + if chanData.Err != nil { + return nil, chanData.Err + } glog.Infof("Received AI result for task %d", chanData.TaskID) var res interface{} switch aiRequestType { From aab34cbbfd8bace28681627ae65367df9581c524 Mon Sep 17 00:00:00 2001 From: kyriediculous Date: Sat, 27 Jul 2024 03:59:58 +0200 Subject: [PATCH 73/88] fix: aiErr unmarshal to json --- core/ai.go | 6 +++--- server/ot_rpc.go | 15 +++------------ 2 files changed, 6 insertions(+), 15 deletions(-) diff --git a/core/ai.go b/core/ai.go index 22f6ea9e3c..7d09c2f78d 100644 --- a/core/ai.go +++ b/core/ai.go @@ -71,7 +71,7 @@ type RemoteAIWorkerResult struct { JobType net.AIRequestType TaskID int64 Bytes []byte - Err error + Err string } func NewRemoteAIWorkerManager() *RemoteAIWorkerManager { @@ -175,8 +175,8 @@ func (m *RemoteAIWorkerManager) processAIRequest(ctx context.Context, capability case <-ctx.Done(): return nil, ctx.Err() case chanData := <-taskChan: - if chanData.Err != nil { - return nil, chanData.Err + if chanData.Err != "" { + return nil, fmt.Errorf("%v", chanData.Err) } glog.Infof("Received AI result for task %d", chanData.TaskID) var res interface{} diff --git a/server/ot_rpc.go b/server/ot_rpc.go index a9d8345722..c3fed00022 100644 --- a/server/ot_rpc.go +++ b/server/ot_rpc.go @@ -205,9 +205,7 @@ func runAIJob(ctx context.Context, aiJob *net.NotifyAIJob, n *core.LivepeerNode, } glog.Infof("Received AI job %v type: %v", aiJob.TaskID, aiJob.Type) - // var aiResult *core.RemoteAIWorkerResult var aiResultBytes []byte - var err error switch aiJob.Type { @@ -254,7 +252,7 @@ func runAIJob(ctx context.Context, aiJob *net.NotifyAIJob, n *core.LivepeerNode, JobType: aiJob.Type, TaskID: aiJob.TaskID, Bytes: aiResultBytes, - Err: err, + Err: err.Error(), } // Create a bytes.Buffer and write the JSON data to it @@ -484,13 +482,6 @@ func (h *lphttp) RegisterAIWorker(req *net.RegisterRequest, stream net.Transcode // Orchestrator HTTP -type RemoteAIWorkerResult struct { - JobType net.AIRequestType - TaskID int64 - Bytes []byte - Err error -} - func (h *lphttp) AIWorkerResults(w http.ResponseWriter, r *http.Request) { orch := h.orchestrator @@ -514,8 +505,8 @@ func (h *lphttp) AIWorkerResults(w http.ResponseWriter, r *http.Request) { return } - if req.Err != nil { - respondWithError(w, req.Err.Error(), http.StatusInternalServerError) + if req.Err != "" { + respondWithError(w, req.Err, http.StatusInternalServerError) return } From 37873b2679b3f5ab7ee650c76b0faca1ab8ecf80 Mon Sep 17 00:00:00 2001 From: kyriediculous Date: Sat, 27 Jul 2024 22:02:51 +0200 Subject: [PATCH 74/88] feat: rotate workers until timeout, success, or all fail --- core/ai.go | 94 +++++++++++++++++++++++++++++++++++------------------- 1 file changed, 62 insertions(+), 32 deletions(-) diff --git a/core/ai.go b/core/ai.go index 7d09c2f78d..e5466a00c8 100644 --- a/core/ai.go +++ b/core/ai.go @@ -10,6 +10,7 @@ import ( "strconv" "strings" "sync" + "time" "github.com/golang/glog" "github.com/livepeer/ai-worker/worker" @@ -17,6 +18,9 @@ import ( "github.com/livepeer/go-livepeer/net" ) +// TODO: seperate timeout for warm requests +const workerTimeout = 60 * time.Second // Adjust this value as needed + type AI interface { TextToImage(context.Context, worker.TextToImageJSONRequestBody) (*worker.ImageResponse, error) ImageToImage(context.Context, worker.ImageToImageMultipartRequestBody) (*worker.ImageResponse, error) @@ -116,7 +120,7 @@ func (m *RemoteAIWorkerManager) Manage(stream net.Transcoder_RegisterAIWorkerSer m.workersMutex.Unlock() <-worker.eof - glog.Infof("Remote AI worker=%s done, removing from live AI workers map", from) + glog.Infof("Remote AI worker stream closed, removing from live AI workers map worker=%s", from) m.workersMutex.Lock() delete(m.liveWorkers, stream) @@ -151,11 +155,6 @@ func (m *RemoteAIWorkerManager) processAIRequest(ctx context.Context, capability modelID := getModelID(req) - w, err := m.selectWorker(capability, modelID) - if err != nil { - return nil, err - } - jsonData, err := json.Marshal(req) if err != nil { return nil, err @@ -167,35 +166,21 @@ func (m *RemoteAIWorkerManager) processAIRequest(ctx context.Context, capability Data: jsonData, } - if err := w.stream.Send(remoteReq); err != nil { - return nil, err - } - - select { - case <-ctx.Done(): - return nil, ctx.Err() - case chanData := <-taskChan: - if chanData.Err != "" { - return nil, fmt.Errorf("%v", chanData.Err) + workerCount := m.getWorkerCount(capability, modelID) + for i := 0; i < workerCount; i++ { + w, err := m.selectWorker(capability, modelID) + if err != nil { + return nil, err } - glog.Infof("Received AI result for task %d", chanData.TaskID) - var res interface{} - switch aiRequestType { - case net.AIRequestType_ImageToVideo: - var videoRes worker.VideoResponse - if err := json.Unmarshal(chanData.Bytes, &videoRes); err != nil { - return nil, err - } - res = &videoRes - default: - var imgRes worker.ImageResponse - if err := json.Unmarshal(chanData.Bytes, &imgRes); err != nil { - return nil, err - } - res = &imgRes + + chanData, err := m.sendRequestToWorker(ctx, w, remoteReq, taskChan) + if err == nil { + return m.processWorkerResponse(chanData, aiRequestType) } - return res, nil + + glog.Warningf("Worker %s failed, retrying taskID=%v err=%v", w.addr, taskID, err) } + return nil, ErrNoTranscodersAvailable } func (m *RemoteAIWorkerManager) selectWorker(capability Capability, modelID string) (*RemoteAIWorker, error) { @@ -217,6 +202,51 @@ func (m *RemoteAIWorkerManager) selectWorker(capability Capability, modelID stri return w, nil } +func (m *RemoteAIWorkerManager) getWorkerCount(capability Capability, modelID string) int { + m.workersMutex.Lock() + defer m.workersMutex.Unlock() + return len(m.remoteWorkers[capability][modelID]) +} + +func (m *RemoteAIWorkerManager) sendRequestToWorker(ctx context.Context, w *RemoteAIWorker, remoteReq *net.NotifyAIJob, taskChan RemoteAIResultChan) (*RemoteAIWorkerResult, error) { + if err := w.stream.Send(remoteReq); err != nil { + return nil, fmt.Errorf("failed to send request: %w", err) + } + + timeoutCtx, cancel := context.WithTimeout(ctx, workerTimeout) + defer cancel() + + select { + case <-timeoutCtx.Done(): + return nil, fmt.Errorf("worker timed out") + case chanData := <-taskChan: + if chanData.Err != "" { + return nil, fmt.Errorf("worker returned error: %s", chanData.Err) + } + return chanData, nil + } +} + +func (m *RemoteAIWorkerManager) processWorkerResponse(chanData *RemoteAIWorkerResult, aiRequestType net.AIRequestType) (interface{}, error) { + glog.Infof("Received AI result for task %d", chanData.TaskID) + var res interface{} + switch aiRequestType { + case net.AIRequestType_ImageToVideo: + var videoRes worker.VideoResponse + if err := json.Unmarshal(chanData.Bytes, &videoRes); err != nil { + return nil, fmt.Errorf("failed to unmarshal video response: %w", err) + } + res = &videoRes + default: + var imgRes worker.ImageResponse + if err := json.Unmarshal(chanData.Bytes, &imgRes); err != nil { + return nil, fmt.Errorf("failed to unmarshal image response: %w", err) + } + res = &imgRes + } + return res, nil +} + func (m *RemoteAIWorkerManager) TextToImage(ctx context.Context, req worker.TextToImageJSONRequestBody) (*worker.ImageResponse, error) { res, err := m.processAIRequest(ctx, Capability_TextToImage, req, net.AIRequestType_TextToImage) if err != nil { From df648f20f49238306e440eca6e670ecefcbb5ef1 Mon Sep 17 00:00:00 2001 From: kyriediculous Date: Sat, 27 Jul 2024 22:03:26 +0200 Subject: [PATCH 75/88] feat: add image to video for remote worker --- server/ot_rpc.go | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/server/ot_rpc.go b/server/ot_rpc.go index c3fed00022..fb17154ad4 100644 --- a/server/ot_rpc.go +++ b/server/ot_rpc.go @@ -200,10 +200,8 @@ func runAIJob(ctx context.Context, aiJob *net.NotifyAIJob, n *core.LivepeerNode, return default: if aiJob == nil { - glog.Error("Received nil AI job") return } - glog.Infof("Received AI job %v type: %v", aiJob.TaskID, aiJob.Type) var aiResultBytes []byte var err error @@ -213,7 +211,7 @@ func runAIJob(ctx context.Context, aiJob *net.NotifyAIJob, n *core.LivepeerNode, var req worker.TextToImageJSONRequestBody var res *worker.ImageResponse if err = json.Unmarshal(aiJob.Data, &req); err == nil { - glog.Infof("Text-to-Image AI Job decoded model=%v prompt=%v", req.ModelId, req.Prompt) + glog.V(common.DEBUG).Infof("Text-to-Image AI Job received model=%v prompt=%v", req.ModelId, req.Prompt) res, err = n.AIWorker.TextToImage(context.Background(), req) if err == nil { aiResultBytes, err = json.Marshal(res) @@ -223,7 +221,7 @@ func runAIJob(ctx context.Context, aiJob *net.NotifyAIJob, n *core.LivepeerNode, var req worker.ImageToImageMultipartRequestBody var res *worker.ImageResponse if err = json.Unmarshal(aiJob.Data, &req); err == nil { - glog.Infof("Image-to-Image AI Job decoded model=%v image=%v", req.ModelId, req.Image.Filename()) + glog.V(common.DEBUG).Infof("Image-to-Image AI Job received model=%v image=%v", req.ModelId, req.Image.Filename()) res, err = n.AIWorker.ImageToImage(context.Background(), req) if err == nil { aiResultBytes, err = json.Marshal(res) @@ -233,15 +231,25 @@ func runAIJob(ctx context.Context, aiJob *net.NotifyAIJob, n *core.LivepeerNode, var req worker.UpscaleMultipartRequestBody var res *worker.ImageResponse if err = json.Unmarshal(aiJob.Data, &req); err == nil { - glog.Infof("Upscale AI Job decoded model=%v image=%v", req.ModelId, req.Image.Filename()) + glog.V(common.DEBUG).Infof("Upscale AI Job received model=%v image=%v", req.ModelId, req.Image.Filename()) res, err = n.AIWorker.Upscale(context.Background(), req) if err == nil { aiResultBytes, err = json.Marshal(res) } } + case net.AIRequestType_ImageToVideo: + var req worker.ImageToVideoMultipartRequestBody + var res *worker.VideoResponse + if err = json.Unmarshal(aiJob.Data, &req); err == nil { + glog.V(common.DEBUG).Infof("Image-to-Video AI Job received model=%v image=%v", req.ModelId, req.Image.Filename()) + res, err = n.AIWorker.ImageToVideo(context.Background(), req) + if err == nil { + aiResultBytes, err = json.Marshal(res) + } + } default: - glog.Errorf("Invalid Job type decoded taskID=%v type=%v", aiJob.TaskID, aiJob.Type) err = fmt.Errorf("Invalid Job type decoded taskID=%v type=%v", aiJob.TaskID, aiJob.Type) + glog.Error(err) } if err != nil { @@ -260,7 +268,6 @@ func runAIJob(ctx context.Context, aiJob *net.NotifyAIJob, n *core.LivepeerNode, jsonAiResult, err := json.Marshal(aiResult) if err != nil { glog.Errorf("Error marshaling JSON err=%q", err) - return } body.Write(jsonAiResult) From 7da83241f18406878fccb73aa4289a1bd0b22a29 Mon Sep 17 00:00:00 2001 From: kyriediculous Date: Sat, 27 Jul 2024 22:45:50 +0200 Subject: [PATCH 76/88] feat: add audio-to-text --- core/ai.go | 47 ++++++++++++------ core/orchestrator.go | 4 +- net/lp_rpc.pb.go | 110 ++++++++++++++++++++++-------------------- net/lp_rpc.proto | 1 + net/lp_rpc_grpc.pb.go | 52 ++++++-------------- server/ot_rpc.go | 11 +++++ 6 files changed, 118 insertions(+), 107 deletions(-) diff --git a/core/ai.go b/core/ai.go index e5466a00c8..59ae65e91c 100644 --- a/core/ai.go +++ b/core/ai.go @@ -237,6 +237,12 @@ func (m *RemoteAIWorkerManager) processWorkerResponse(chanData *RemoteAIWorkerRe return nil, fmt.Errorf("failed to unmarshal video response: %w", err) } res = &videoRes + case net.AIRequestType_AudioToText: + var textRes worker.TextResponse + if err := json.Unmarshal(chanData.Bytes, &textRes); err != nil { + return nil, fmt.Errorf("failed to unmarshal text response: %w", err) + } + res = &textRes default: var imgRes worker.ImageResponse if err := json.Unmarshal(chanData.Bytes, &imgRes); err != nil { @@ -271,22 +277,6 @@ func (m *RemoteAIWorkerManager) Upscale(ctx context.Context, req worker.UpscaleM return res.(*worker.ImageResponse), nil } -// Helper function to get ModelId from different request types -func getModelID(req interface{}) string { - switch r := req.(type) { - case worker.TextToImageJSONRequestBody: - return *r.ModelId - case worker.ImageToImageMultipartRequestBody: - return *r.ModelId - case worker.UpscaleMultipartRequestBody: - return *r.ModelId - case worker.ImageToVideoMultipartRequestBody: - return *r.ModelId - default: - return "" - } -} - func (m *RemoteAIWorkerManager) ImageToVideo(ctx context.Context, req worker.ImageToVideoMultipartRequestBody) (*worker.VideoResponse, error) { res, err := m.processAIRequest(ctx, Capability_ImageToVideo, req, net.AIRequestType_ImageToVideo) if err != nil { @@ -295,6 +285,14 @@ func (m *RemoteAIWorkerManager) ImageToVideo(ctx context.Context, req worker.Ima return res.(*worker.VideoResponse), nil } +func (m *RemoteAIWorkerManager) AudioToText(ctx context.Context, req worker.AudioToTextMultipartRequestBody) (*worker.TextResponse, error) { + res, err := m.processAIRequest(ctx, Capability_AudioToText, req, net.AIRequestType_AudioToText) + if err != nil { + return nil, err + } + return res.(*worker.TextResponse), nil +} + func (m *RemoteAIWorkerManager) Warm(ctx context.Context, pipeline, modelID string, endpoint worker.RunnerEndpoint, flags worker.OptimizationFlags) error { return nil } @@ -316,6 +314,8 @@ func (m *RemoteAIWorkerManager) HasCapacity(pipeline, modelID string) bool { cap = Capability_Upscale case "image-to-video": cap = Capability_ImageToVideo + case "audio-to-text": + cap = Capability_AudioToText default: return false } @@ -471,3 +471,18 @@ func ParseStepsFromModelID(modelID *string, defaultSteps float64) float64 { return numInferenceSteps } + +func getModelID(req interface{}) string { + var holder struct { + ModelId *string `json:"model_id"` + } + + b, err := json.Marshal(req) + if err == nil { + json.Unmarshal(b, &holder) + if holder.ModelId != nil { + return *holder.ModelId + } + } + return "" +} diff --git a/core/orchestrator.go b/core/orchestrator.go index e3c2ac2f4c..b6d92a7f3f 100644 --- a/core/orchestrator.go +++ b/core/orchestrator.go @@ -137,7 +137,7 @@ func (orch *orchestrator) Upscale(ctx context.Context, req worker.UpscaleMultipa } func (orch *orchestrator) AudioToText(ctx context.Context, req worker.AudioToTextMultipartRequestBody) (*worker.TextResponse, error) { - return orch.node.AudioToText(ctx, req) + return orch.node.audioToText(ctx, req) } func (orch *orchestrator) ProcessPayment(ctx context.Context, payment net.Payment, manifestID ManifestID) error { @@ -970,7 +970,7 @@ func (n *LivepeerNode) upscale(ctx context.Context, req worker.UpscaleMultipartR return n.AIWorker.Upscale(ctx, req) } -func (n *LivepeerNode) AudioToText(ctx context.Context, req worker.AudioToTextMultipartRequestBody) (*worker.TextResponse, error) { +func (n *LivepeerNode) audioToText(ctx context.Context, req worker.AudioToTextMultipartRequestBody) (*worker.TextResponse, error) { return n.AIWorker.AudioToText(ctx, req) } diff --git a/net/lp_rpc.pb.go b/net/lp_rpc.pb.go index 3fb4a54d50..8ed2d4c816 100644 --- a/net/lp_rpc.pb.go +++ b/net/lp_rpc.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.34.2 -// protoc v5.27.1 +// protoc-gen-go v1.28.1 +// protoc v4.25.2 // source: net/lp_rpc.proto package net @@ -30,6 +30,7 @@ const ( AIRequestType_ImageToImage AIRequestType = 1 AIRequestType_ImageToVideo AIRequestType = 2 AIRequestType_Upscale AIRequestType = 3 + AIRequestType_AudioToText AIRequestType = 4 ) // Enum value maps for AIRequestType. @@ -39,12 +40,14 @@ var ( 1: "ImageToImage", 2: "ImageToVideo", 3: "Upscale", + 4: "AudioToText", } AIRequestType_value = map[string]int32{ "TextToImage": 0, "ImageToImage": 1, "ImageToVideo": 2, "Upscale": 3, + "AudioToText": 4, } ) @@ -2567,35 +2570,36 @@ var file_net_lp_rpc_proto_rawDesc = []byte{ 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, - 0x2a, 0x51, 0x0a, 0x0d, 0x41, 0x49, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, + 0x2a, 0x62, 0x0a, 0x0d, 0x41, 0x49, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0f, 0x0a, 0x0b, 0x54, 0x65, 0x78, 0x74, 0x54, 0x6f, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x10, 0x00, 0x12, 0x10, 0x0a, 0x0c, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x56, 0x69, 0x64, 0x65, 0x6f, 0x10, 0x02, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x70, 0x73, 0x63, 0x61, 0x6c, - 0x65, 0x10, 0x03, 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, + 0x65, 0x10, 0x03, 0x12, 0x0f, 0x0a, 0x0b, 0x41, 0x75, 0x64, 0x69, 0x6f, 0x54, 0x6f, 0x54, 0x65, + 0x78, 0x74, 0x10, 0x04, 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, 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, 0x8c, - 0x01, 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, 0x12, - 0x3c, 0x0a, 0x10, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x41, 0x49, 0x57, 0x6f, 0x72, - 0x6b, 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, 0x10, 0x2e, 0x6e, 0x65, 0x74, 0x2e, - 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x41, 0x49, 0x4a, 0x6f, 0x62, 0x30, 0x01, 0x42, 0x07, 0x5a, - 0x05, 0x2e, 0x2f, 0x6e, 0x65, 0x74, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 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, + 0x8c, 0x01, 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, + 0x12, 0x3c, 0x0a, 0x10, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x41, 0x49, 0x57, 0x6f, + 0x72, 0x6b, 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, 0x10, 0x2e, 0x6e, 0x65, 0x74, + 0x2e, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x41, 0x49, 0x4a, 0x6f, 0x62, 0x30, 0x01, 0x42, 0x07, + 0x5a, 0x05, 0x2e, 0x2f, 0x6e, 0x65, 0x74, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -2612,7 +2616,7 @@ func file_net_lp_rpc_proto_rawDescGZIP() []byte { var file_net_lp_rpc_proto_enumTypes = make([]protoimpl.EnumInfo, 6) var file_net_lp_rpc_proto_msgTypes = make([]protoimpl.MessageInfo, 28) -var file_net_lp_rpc_proto_goTypes = []any{ +var file_net_lp_rpc_proto_goTypes = []interface{}{ (AIRequestType)(0), // 0: net.AIRequestType (OSInfo_StorageType)(0), // 1: net.OSInfo.StorageType (VideoProfile_Format)(0), // 2: net.VideoProfile.Format @@ -2708,7 +2712,7 @@ func file_net_lp_rpc_proto_init() { return } if !protoimpl.UnsafeEnabled { - file_net_lp_rpc_proto_msgTypes[0].Exporter = func(v any, i int) any { + file_net_lp_rpc_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*PingPong); i { case 0: return &v.state @@ -2720,7 +2724,7 @@ func file_net_lp_rpc_proto_init() { return nil } } - file_net_lp_rpc_proto_msgTypes[1].Exporter = func(v any, i int) any { + file_net_lp_rpc_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*EndTranscodingSessionRequest); i { case 0: return &v.state @@ -2732,7 +2736,7 @@ func file_net_lp_rpc_proto_init() { return nil } } - file_net_lp_rpc_proto_msgTypes[2].Exporter = func(v any, i int) any { + file_net_lp_rpc_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*EndTranscodingSessionResponse); i { case 0: return &v.state @@ -2744,7 +2748,7 @@ func file_net_lp_rpc_proto_init() { return nil } } - file_net_lp_rpc_proto_msgTypes[3].Exporter = func(v any, i int) any { + file_net_lp_rpc_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*OrchestratorRequest); i { case 0: return &v.state @@ -2756,7 +2760,7 @@ func file_net_lp_rpc_proto_init() { return nil } } - file_net_lp_rpc_proto_msgTypes[4].Exporter = func(v any, i int) any { + file_net_lp_rpc_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*OSInfo); i { case 0: return &v.state @@ -2768,7 +2772,7 @@ func file_net_lp_rpc_proto_init() { return nil } } - file_net_lp_rpc_proto_msgTypes[5].Exporter = func(v any, i int) any { + file_net_lp_rpc_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*S3OSInfo); i { case 0: return &v.state @@ -2780,7 +2784,7 @@ func file_net_lp_rpc_proto_init() { return nil } } - file_net_lp_rpc_proto_msgTypes[6].Exporter = func(v any, i int) any { + file_net_lp_rpc_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*PriceInfo); i { case 0: return &v.state @@ -2792,7 +2796,7 @@ func file_net_lp_rpc_proto_init() { return nil } } - file_net_lp_rpc_proto_msgTypes[7].Exporter = func(v any, i int) any { + file_net_lp_rpc_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Capabilities); i { case 0: return &v.state @@ -2804,7 +2808,7 @@ func file_net_lp_rpc_proto_init() { return nil } } - file_net_lp_rpc_proto_msgTypes[8].Exporter = func(v any, i int) any { + file_net_lp_rpc_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*OrchestratorInfo); i { case 0: return &v.state @@ -2816,7 +2820,7 @@ func file_net_lp_rpc_proto_init() { return nil } } - file_net_lp_rpc_proto_msgTypes[9].Exporter = func(v any, i int) any { + file_net_lp_rpc_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*AuthToken); i { case 0: return &v.state @@ -2828,7 +2832,7 @@ func file_net_lp_rpc_proto_init() { return nil } } - file_net_lp_rpc_proto_msgTypes[10].Exporter = func(v any, i int) any { + file_net_lp_rpc_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*SegData); i { case 0: return &v.state @@ -2840,7 +2844,7 @@ func file_net_lp_rpc_proto_init() { return nil } } - file_net_lp_rpc_proto_msgTypes[11].Exporter = func(v any, i int) any { + file_net_lp_rpc_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*SegParameters); i { case 0: return &v.state @@ -2852,7 +2856,7 @@ func file_net_lp_rpc_proto_init() { return nil } } - file_net_lp_rpc_proto_msgTypes[12].Exporter = func(v any, i int) any { + file_net_lp_rpc_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*VideoProfile); i { case 0: return &v.state @@ -2864,7 +2868,7 @@ func file_net_lp_rpc_proto_init() { return nil } } - file_net_lp_rpc_proto_msgTypes[13].Exporter = func(v any, i int) any { + file_net_lp_rpc_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*TranscodedSegmentData); i { case 0: return &v.state @@ -2876,7 +2880,7 @@ func file_net_lp_rpc_proto_init() { return nil } } - file_net_lp_rpc_proto_msgTypes[14].Exporter = func(v any, i int) any { + file_net_lp_rpc_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*TranscodeData); i { case 0: return &v.state @@ -2888,7 +2892,7 @@ func file_net_lp_rpc_proto_init() { return nil } } - file_net_lp_rpc_proto_msgTypes[15].Exporter = func(v any, i int) any { + file_net_lp_rpc_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*TranscodeResult); i { case 0: return &v.state @@ -2900,7 +2904,7 @@ func file_net_lp_rpc_proto_init() { return nil } } - file_net_lp_rpc_proto_msgTypes[16].Exporter = func(v any, i int) any { + file_net_lp_rpc_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*RegisterRequest); i { case 0: return &v.state @@ -2912,7 +2916,7 @@ func file_net_lp_rpc_proto_init() { return nil } } - file_net_lp_rpc_proto_msgTypes[17].Exporter = func(v any, i int) any { + file_net_lp_rpc_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*NotifySegment); i { case 0: return &v.state @@ -2924,7 +2928,7 @@ func file_net_lp_rpc_proto_init() { return nil } } - file_net_lp_rpc_proto_msgTypes[18].Exporter = func(v any, i int) any { + file_net_lp_rpc_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*NotifyAIJob); i { case 0: return &v.state @@ -2936,7 +2940,7 @@ func file_net_lp_rpc_proto_init() { return nil } } - file_net_lp_rpc_proto_msgTypes[19].Exporter = func(v any, i int) any { + file_net_lp_rpc_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*TicketParams); i { case 0: return &v.state @@ -2948,7 +2952,7 @@ func file_net_lp_rpc_proto_init() { return nil } } - file_net_lp_rpc_proto_msgTypes[20].Exporter = func(v any, i int) any { + file_net_lp_rpc_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*TicketSenderParams); i { case 0: return &v.state @@ -2960,7 +2964,7 @@ func file_net_lp_rpc_proto_init() { return nil } } - file_net_lp_rpc_proto_msgTypes[21].Exporter = func(v any, i int) any { + file_net_lp_rpc_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*TicketExpirationParams); i { case 0: return &v.state @@ -2972,7 +2976,7 @@ func file_net_lp_rpc_proto_init() { return nil } } - file_net_lp_rpc_proto_msgTypes[22].Exporter = func(v any, i int) any { + file_net_lp_rpc_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Payment); i { case 0: return &v.state @@ -2984,7 +2988,7 @@ func file_net_lp_rpc_proto_init() { return nil } } - file_net_lp_rpc_proto_msgTypes[24].Exporter = func(v any, i int) any { + file_net_lp_rpc_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Capabilities_Constraints); i { case 0: return &v.state @@ -2996,7 +3000,7 @@ func file_net_lp_rpc_proto_init() { return nil } } - file_net_lp_rpc_proto_msgTypes[26].Exporter = func(v any, i int) any { + file_net_lp_rpc_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Capabilities_Constraints_ModelConstraint); i { case 0: return &v.state @@ -3009,7 +3013,7 @@ func file_net_lp_rpc_proto_init() { } } } - file_net_lp_rpc_proto_msgTypes[15].OneofWrappers = []any{ + file_net_lp_rpc_proto_msgTypes[15].OneofWrappers = []interface{}{ (*TranscodeResult_Error)(nil), (*TranscodeResult_Data)(nil), } diff --git a/net/lp_rpc.proto b/net/lp_rpc.proto index 8ab2fe1bce..47b686e4b2 100644 --- a/net/lp_rpc.proto +++ b/net/lp_rpc.proto @@ -375,6 +375,7 @@ enum AIRequestType { ImageToImage= 1; ImageToVideo= 2; Upscale = 3; + AudioToText = 4; } // Sent by the orchestrator to the remote AI worker message NotifyAIJob { diff --git a/net/lp_rpc_grpc.pb.go b/net/lp_rpc_grpc.pb.go index 6ee7f8d0dc..5d723d78ac 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.4.0 -// - protoc v5.27.1 +// - protoc-gen-go-grpc v1.2.0 +// - protoc v4.25.2 // source: net/lp_rpc.proto package net @@ -15,20 +15,12 @@ import ( // This is a compile-time assertion to ensure that this generated file // is compatible with the grpc package it is being compiled against. -// Requires gRPC-Go v1.62.0 or later. -const _ = grpc.SupportPackageIsVersion8 - -const ( - Orchestrator_GetOrchestrator_FullMethodName = "/net.Orchestrator/GetOrchestrator" - Orchestrator_EndTranscodingSession_FullMethodName = "/net.Orchestrator/EndTranscodingSession" - Orchestrator_Ping_FullMethodName = "/net.Orchestrator/Ping" -) +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 // OrchestratorClient is the client API for Orchestrator service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. -// -// RPC calls implemented by the orchestrator type OrchestratorClient interface { // Called by the broadcaster to request transcoder info from an orchestrator. GetOrchestrator(ctx context.Context, in *OrchestratorRequest, opts ...grpc.CallOption) (*OrchestratorInfo, error) @@ -45,9 +37,8 @@ func NewOrchestratorClient(cc grpc.ClientConnInterface) OrchestratorClient { } func (c *orchestratorClient) GetOrchestrator(ctx context.Context, in *OrchestratorRequest, opts ...grpc.CallOption) (*OrchestratorInfo, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(OrchestratorInfo) - err := c.cc.Invoke(ctx, Orchestrator_GetOrchestrator_FullMethodName, in, out, cOpts...) + err := c.cc.Invoke(ctx, "/net.Orchestrator/GetOrchestrator", in, out, opts...) if err != nil { return nil, err } @@ -55,9 +46,8 @@ func (c *orchestratorClient) GetOrchestrator(ctx context.Context, in *Orchestrat } func (c *orchestratorClient) EndTranscodingSession(ctx context.Context, in *EndTranscodingSessionRequest, opts ...grpc.CallOption) (*EndTranscodingSessionResponse, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(EndTranscodingSessionResponse) - err := c.cc.Invoke(ctx, Orchestrator_EndTranscodingSession_FullMethodName, in, out, cOpts...) + err := c.cc.Invoke(ctx, "/net.Orchestrator/EndTranscodingSession", in, out, opts...) if err != nil { return nil, err } @@ -65,9 +55,8 @@ func (c *orchestratorClient) EndTranscodingSession(ctx context.Context, in *EndT } func (c *orchestratorClient) Ping(ctx context.Context, in *PingPong, opts ...grpc.CallOption) (*PingPong, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(PingPong) - err := c.cc.Invoke(ctx, Orchestrator_Ping_FullMethodName, in, out, cOpts...) + err := c.cc.Invoke(ctx, "/net.Orchestrator/Ping", in, out, opts...) if err != nil { return nil, err } @@ -77,8 +66,6 @@ func (c *orchestratorClient) Ping(ctx context.Context, in *PingPong, opts ...grp // OrchestratorServer is the server API for Orchestrator service. // All implementations must embed UnimplementedOrchestratorServer // for forward compatibility -// -// RPC calls implemented by the orchestrator type OrchestratorServer interface { // Called by the broadcaster to request transcoder info from an orchestrator. GetOrchestrator(context.Context, *OrchestratorRequest) (*OrchestratorInfo, error) @@ -123,7 +110,7 @@ func _Orchestrator_GetOrchestrator_Handler(srv interface{}, ctx context.Context, } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: Orchestrator_GetOrchestrator_FullMethodName, + FullMethod: "/net.Orchestrator/GetOrchestrator", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(OrchestratorServer).GetOrchestrator(ctx, req.(*OrchestratorRequest)) @@ -141,7 +128,7 @@ func _Orchestrator_EndTranscodingSession_Handler(srv interface{}, ctx context.Co } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: Orchestrator_EndTranscodingSession_FullMethodName, + FullMethod: "/net.Orchestrator/EndTranscodingSession", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(OrchestratorServer).EndTranscodingSession(ctx, req.(*EndTranscodingSessionRequest)) @@ -159,7 +146,7 @@ func _Orchestrator_Ping_Handler(srv interface{}, ctx context.Context, dec func(i } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: Orchestrator_Ping_FullMethodName, + FullMethod: "/net.Orchestrator/Ping", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(OrchestratorServer).Ping(ctx, req.(*PingPong)) @@ -191,11 +178,6 @@ var Orchestrator_ServiceDesc = grpc.ServiceDesc{ Metadata: "net/lp_rpc.proto", } -const ( - Transcoder_RegisterTranscoder_FullMethodName = "/net.Transcoder/RegisterTranscoder" - Transcoder_RegisterAIWorker_FullMethodName = "/net.Transcoder/RegisterAIWorker" -) - // TranscoderClient is the client API for Transcoder service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. @@ -217,12 +199,11 @@ func NewTranscoderClient(cc grpc.ClientConnInterface) TranscoderClient { } func (c *transcoderClient) RegisterTranscoder(ctx context.Context, in *RegisterRequest, opts ...grpc.CallOption) (Transcoder_RegisterTranscoderClient, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - stream, err := c.cc.NewStream(ctx, &Transcoder_ServiceDesc.Streams[0], Transcoder_RegisterTranscoder_FullMethodName, cOpts...) + stream, err := c.cc.NewStream(ctx, &Transcoder_ServiceDesc.Streams[0], "/net.Transcoder/RegisterTranscoder", opts...) if err != nil { return nil, err } - x := &transcoderRegisterTranscoderClient{ClientStream: stream} + x := &transcoderRegisterTranscoderClient{stream} if err := x.ClientStream.SendMsg(in); err != nil { return nil, err } @@ -250,12 +231,11 @@ func (x *transcoderRegisterTranscoderClient) Recv() (*NotifySegment, error) { } func (c *transcoderClient) RegisterAIWorker(ctx context.Context, in *RegisterRequest, opts ...grpc.CallOption) (Transcoder_RegisterAIWorkerClient, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - stream, err := c.cc.NewStream(ctx, &Transcoder_ServiceDesc.Streams[1], Transcoder_RegisterAIWorker_FullMethodName, cOpts...) + stream, err := c.cc.NewStream(ctx, &Transcoder_ServiceDesc.Streams[1], "/net.Transcoder/RegisterAIWorker", opts...) if err != nil { return nil, err } - x := &transcoderRegisterAIWorkerClient{ClientStream: stream} + x := &transcoderRegisterAIWorkerClient{stream} if err := x.ClientStream.SendMsg(in); err != nil { return nil, err } @@ -323,7 +303,7 @@ func _Transcoder_RegisterTranscoder_Handler(srv interface{}, stream grpc.ServerS if err := stream.RecvMsg(m); err != nil { return err } - return srv.(TranscoderServer).RegisterTranscoder(m, &transcoderRegisterTranscoderServer{ServerStream: stream}) + return srv.(TranscoderServer).RegisterTranscoder(m, &transcoderRegisterTranscoderServer{stream}) } type Transcoder_RegisterTranscoderServer interface { @@ -344,7 +324,7 @@ func _Transcoder_RegisterAIWorker_Handler(srv interface{}, stream grpc.ServerStr if err := stream.RecvMsg(m); err != nil { return err } - return srv.(TranscoderServer).RegisterAIWorker(m, &transcoderRegisterAIWorkerServer{ServerStream: stream}) + return srv.(TranscoderServer).RegisterAIWorker(m, &transcoderRegisterAIWorkerServer{stream}) } type Transcoder_RegisterAIWorkerServer interface { diff --git a/server/ot_rpc.go b/server/ot_rpc.go index fb17154ad4..d625624cd3 100644 --- a/server/ot_rpc.go +++ b/server/ot_rpc.go @@ -237,6 +237,7 @@ func runAIJob(ctx context.Context, aiJob *net.NotifyAIJob, n *core.LivepeerNode, aiResultBytes, err = json.Marshal(res) } } + // TODO: apparently this uses imageReponse for now (?) case net.AIRequestType_ImageToVideo: var req worker.ImageToVideoMultipartRequestBody var res *worker.VideoResponse @@ -247,6 +248,16 @@ func runAIJob(ctx context.Context, aiJob *net.NotifyAIJob, n *core.LivepeerNode, aiResultBytes, err = json.Marshal(res) } } + case net.AIRequestType_AudioToText: + var req worker.AudioToTextMultipartRequestBody + var res *worker.TextResponse + if err = json.Unmarshal(aiJob.Data, &req); err == nil { + glog.V(common.DEBUG).Infof("Audio-to-Text AI Job received model=%v audio=%v", req.ModelId, req.Audio.Filename()) + res, err = n.AIWorker.AudioToText(context.Background(), req) + if err == nil { + aiResultBytes, err = json.Marshal(res) + } + } default: err = fmt.Errorf("Invalid Job type decoded taskID=%v type=%v", aiJob.TaskID, aiJob.Type) glog.Error(err) From bdfe3a3c820c1a9e895507dc31d36e8c2afcd9ce Mon Sep 17 00:00:00 2001 From: kyriediculous Date: Sun, 28 Jul 2024 14:11:12 +0200 Subject: [PATCH 77/88] fix nil pointer on error from RemoteAIResult --- server/ot_rpc.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/server/ot_rpc.go b/server/ot_rpc.go index d625624cd3..5243ea7f41 100644 --- a/server/ot_rpc.go +++ b/server/ot_rpc.go @@ -263,15 +263,17 @@ func runAIJob(ctx context.Context, aiJob *net.NotifyAIJob, n *core.LivepeerNode, glog.Error(err) } + var errString string if err != nil { glog.Errorf("AI job failed ID=%v err=%v", aiJob.TaskID, err) + errString = err.Error() } aiResult := &core.RemoteAIWorkerResult{ JobType: aiJob.Type, TaskID: aiJob.TaskID, Bytes: aiResultBytes, - Err: err.Error(), + Err: errString, } // Create a bytes.Buffer and write the JSON data to it From 0410787ec6aa70c4b9ab64c0fb8b1b4a19200944 Mon Sep 17 00:00:00 2001 From: kyriediculous Date: Tue, 30 Jul 2024 05:13:40 +0200 Subject: [PATCH 78/88] resolve merge conflicts --- cmd/livepeer/starter/starter.go | 87 + core/ai.go | 2 +- core/capabilities.go | 19 +- net/lp_rpc.pb.go | 2814 ++++++++++++++++--------------- 4 files changed, 1520 insertions(+), 1402 deletions(-) diff --git a/cmd/livepeer/starter/starter.go b/cmd/livepeer/starter/starter.go index 2b598ce685..1e1f65934c 100755 --- a/cmd/livepeer/starter/starter.go +++ b/cmd/livepeer/starter/starter.go @@ -1232,6 +1232,93 @@ func StartLivepeer(ctx context.Context, cfg LivepeerConfig) { }() } + if !*cfg.AIWorker && *cfg.AIModels != "" { + configs, err := core.ParseAIModelConfigs(*cfg.AIModels) + if err != nil { + glog.Errorf("Error parsing -aiModels: %v", err) + return + } + + // Set price per unit base info. + pixelsPerUnit, ok := new(big.Rat).SetString(*cfg.PixelsPerUnit) + if !ok || !pixelsPerUnit.IsInt() { + panic(fmt.Errorf("-pixelsPerUnit must be a valid integer, provided %v", *cfg.PixelsPerUnit)) + } + if pixelsPerUnit.Sign() <= 0 { + // Can't divide by 0 + panic(fmt.Errorf("-pixelsPerUnit must be > 0, provided %v", *cfg.PixelsPerUnit)) + } + + for _, config := range configs { + modelConstraint := &core.ModelConstraint{Warm: config.Warm} + + pricePerUnit, currency, err := parsePricePerUnit(config.PricePerUnit.String()) + if err != nil { + panic(fmt.Errorf("'pricePerUnit' value specified for model '%v' in pipeline '%v' must be a valid integer with an optional currency, provided %v", config.ModelID, config.Pipeline, config.PricePerUnit)) + } else if pricePerUnit.Sign() < 0 { + panic(fmt.Errorf("'pricePerUnit' value specified for model '%v' in pipeline '%v' must be >= 0, provided %v", config.ModelID, config.Pipeline, config.PricePerUnit)) + } + pricePerPixel := new(big.Rat).Quo(pricePerUnit, pixelsPerUnit) + autoPrice, err := core.NewAutoConvertedPrice(currency, pricePerPixel, nil) + if err != nil { + panic(fmt.Errorf("error converting price: %v", err)) + } + + switch config.Pipeline { + case "text-to-image": + _, ok := capabilityConstraints[core.Capability_TextToImage] + if !ok { + aiCaps = append(aiCaps, core.Capability_TextToImage) + capabilityConstraints[core.Capability_TextToImage] = &core.PerCapabilityConstraints{ + Models: make(map[string]*core.ModelConstraint), + } + } + + capabilityConstraints[core.Capability_TextToImage].Models[config.ModelID] = modelConstraint + + n.SetBasePriceForCap("default", core.Capability_TextToImage, config.ModelID, autoPrice) + case "image-to-image": + _, ok := capabilityConstraints[core.Capability_ImageToImage] + if !ok { + aiCaps = append(aiCaps, core.Capability_ImageToImage) + capabilityConstraints[core.Capability_ImageToImage] = &core.PerCapabilityConstraints{ + Models: make(map[string]*core.ModelConstraint), + } + } + + n.SetBasePriceForCap("default", core.Capability_ImageToImage, config.ModelID, autoPrice) + case "image-to-video": + _, ok := capabilityConstraints[core.Capability_ImageToVideo] + if !ok { + aiCaps = append(aiCaps, core.Capability_ImageToVideo) + capabilityConstraints[core.Capability_ImageToVideo] = &core.PerCapabilityConstraints{ + Models: make(map[string]*core.ModelConstraint), + } + } + + n.SetBasePriceForCap("default", core.Capability_ImageToVideo, config.ModelID, autoPrice) + case "upscale": + _, ok := capabilityConstraints[core.Capability_Upscale] + if !ok { + aiCaps = append(aiCaps, core.Capability_Upscale) + capabilityConstraints[core.Capability_Upscale] = &core.PerCapabilityConstraints{ + Models: make(map[string]*core.ModelConstraint), + } + } + + n.SetBasePriceForCap("default", core.Capability_Upscale, config.ModelID, autoPrice) + } + + if len(aiCaps) > 0 { + capability := aiCaps[len(aiCaps)-1] + price := n.GetBasePriceForCap("default", capability, config.ModelID) + if price != nil { + glog.V(6).Infof("Capability %s (ID: %v) advertised with model constraint %s at price %d per %d unit", config.Pipeline, capability, config.ModelID, price.Num(), price.Denom()) + } + } + } + } + if *cfg.Objectstore != "" { prepared, err := drivers.PrepareOSURL(*cfg.Objectstore) if err != nil { diff --git a/core/ai.go b/core/ai.go index 59ae65e91c..94562c4133 100644 --- a/core/ai.go +++ b/core/ai.go @@ -102,7 +102,7 @@ func (m *RemoteAIWorkerManager) Manage(stream net.Transcoder_RegisterAIWorkerSer }() m.workersMutex.Lock() - for cap, constraints := range capabilities.Constraints { + for cap, constraints := range capabilities.CapabilityConstraints { c := Capability(cap) // Initialize the inner map if it's nil if m.remoteWorkers[c] == nil { diff --git a/core/capabilities.go b/core/capabilities.go index 9f99459f12..c0527d75e1 100644 --- a/core/capabilities.go +++ b/core/capabilities.go @@ -569,15 +569,16 @@ func (cap *Capabilities) AddCapacity(newCaps *Capabilities) { cap.bitstring[arrIdx] |= uint64(1 << bitIdx) } - for capability, constraints := range newCaps.constraints { - if cap.constraints[capability] == nil { - cap.constraints[capability] = constraints + for capability, constraints := range newCaps.capabilityConstraints { + if cap.capabilityConstraints[capability] == nil { + cap.capabilityConstraints[capability] = constraints } else { for modelID, modelConstraint := range constraints.Models { - if cap.constraints[capability].Models[modelID] == nil { - // TODO: this re-writes Warm; check - cap.constraints[capability].Models[modelID] = modelConstraint + if modelConstraints := cap.capabilityConstraints[capability].Models[modelID]; modelConstraints != nil && modelConstraints.Warm { + // already available warm, don't overwrite + continue } + cap.capabilityConstraints[capability].Models[modelID] = modelConstraint } } } @@ -600,12 +601,12 @@ func (cap *Capabilities) RemoveCapacity(goneCaps *Capabilities) { } } - for capability, constraints := range goneCaps.constraints { - if cap.constraints[capability] == nil { + for capability, constraints := range goneCaps.capabilityConstraints { + if cap.capabilityConstraints[capability] == nil { continue } for modelID := range constraints.Models { - delete(cap.constraints[capability].Models, modelID) + delete(cap.capabilityConstraints[capability].Models, modelID) } } } diff --git a/net/lp_rpc.pb.go b/net/lp_rpc.pb.go index 8ed2d4c816..471d381512 100644 --- a/net/lp_rpc.pb.go +++ b/net/lp_rpc.pb.go @@ -7,21 +7,18 @@ 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 AIRequestType int32 @@ -86,20 +83,28 @@ 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 { @@ -116,7 +121,7 @@ func (x OSInfo_StorageType) Number() protoreflect.EnumNumber { // 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 @@ -127,18 +132,26 @@ 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 { @@ -155,7 +168,7 @@ func (x VideoProfile_Format) Number() protoreflect.EnumNumber { // 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 @@ -168,24 +181,32 @@ 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 { @@ -202,7 +223,7 @@ func (x VideoProfile_Profile) Number() protoreflect.EnumNumber { // 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 @@ -214,22 +235,30 @@ 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 { @@ -246,7 +275,7 @@ func (x VideoProfile_VideoCodec) Number() protoreflect.EnumNumber { // 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 @@ -257,20 +286,28 @@ 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) Descriptor() protoreflect.EnumDescriptor { @@ -287,233 +324,275 @@ func (x VideoProfile_ChromaSubsampling) Number() protoreflect.EnumNumber { // Deprecated: Use VideoProfile_ChromaSubsampling.Descriptor instead. func (VideoProfile_ChromaSubsampling) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_034e29c79f9ba827, []int{12, 3} + return file_net_lp_rpc_proto_rawDescGZIP(), []int{12, 3} } 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"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + Value []byte `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"` } -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 *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_Unmarshal(b []byte) error { - return xxx_messageInfo_PingPong.Unmarshal(m, b) -} -func (m *PingPong) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_PingPong.Marshal(b, m, deterministic) -} -func (m *PingPong) XXX_Merge(src proto.Message) { - xxx_messageInfo_PingPong.Merge(m, src) -} -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 (m *EndTranscodingSessionResponse) XXX_Size() int { - return xxx_messageInfo_EndTranscodingSessionResponse.Size(m) +func (x *EndTranscodingSessionResponse) String() string { + return protoimpl.X.MessageStringOf(x) } -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"` // Features and constraints required by the broadcaster - 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 *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 (m *OrchestratorRequest) XXX_Size() int { - return xxx_messageInfo_OrchestratorRequest.Size(m) +func (x *OrchestratorRequest) String() string { + return protoimpl.X.MessageStringOf(x) } -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 } -func (m *OrchestratorRequest) GetCapabilities() *Capabilities { - if m != nil { - return m.Capabilities +func (x *OrchestratorRequest) GetCapabilities() *Capabilities { + if x != nil { + return x.Capabilities } return nil } -// -//OSInfo needed to negotiate storages that will be used. -//It carries info needed to write to the storage. +// 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 (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 (x *OSInfo) String() string { + return protoimpl.X.MessageStringOf(x) } -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. @@ -525,131 +604,147 @@ 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 (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 (x *S3OSInfo) String() string { + return protoimpl.X.MessageStringOf(x) } -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 @@ -659,204 +754,89 @@ type Capabilities struct { 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"` CapabilityConstraints map[uint32]*Capabilities_CapabilityConstraints `protobuf:"bytes,6,rep,name=capabilityConstraints,proto3" json:"capabilityConstraints,omitempty" protobuf_key:"varint,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` } -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 - } - return "" -} - -func (m *Capabilities) GetConstraints() *Capabilities_Constraints { - if m != nil { - return m.Constraints +func (x *Capabilities) GetMandatories() []uint64 { + if x != nil { + return x.Mandatories } return nil } -func (m *Capabilities) GetCapabilityConstraints() map[uint32]*Capabilities_CapabilityConstraints { - if m != nil { - return m.CapabilityConstraints +func (x *Capabilities) GetCapacities() map[uint32]uint32 { + if x != nil { + return x.Capacities } return nil } -// Non-binary general constraints. -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) -} - -var xxx_messageInfo_Capabilities_Constraints proto.InternalMessageInfo - -func (m *Capabilities_Constraints) GetMinVersion() string { - if m != nil { - return m.MinVersion +func (x *Capabilities) GetVersion() string { + if x != nil { + return x.Version } return "" } -// Non-binary capability constraints, such as supported ranges. -type Capabilities_CapabilityConstraints struct { - Models map[string]*Capabilities_CapabilityConstraints_ModelConstraint `protobuf:"bytes,1,rep,name=models,proto3" json:"models,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *Capabilities_CapabilityConstraints) Reset() { *m = Capabilities_CapabilityConstraints{} } -func (m *Capabilities_CapabilityConstraints) String() string { return proto.CompactTextString(m) } -func (*Capabilities_CapabilityConstraints) ProtoMessage() {} -func (*Capabilities_CapabilityConstraints) Descriptor() ([]byte, []int) { - return fileDescriptor_034e29c79f9ba827, []int{7, 2} -} - -func (m *Capabilities_CapabilityConstraints) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Capabilities_CapabilityConstraints.Unmarshal(m, b) -} -func (m *Capabilities_CapabilityConstraints) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Capabilities_CapabilityConstraints.Marshal(b, m, deterministic) -} -func (m *Capabilities_CapabilityConstraints) XXX_Merge(src proto.Message) { - xxx_messageInfo_Capabilities_CapabilityConstraints.Merge(m, src) -} -func (m *Capabilities_CapabilityConstraints) XXX_Size() int { - return xxx_messageInfo_Capabilities_CapabilityConstraints.Size(m) -} -func (m *Capabilities_CapabilityConstraints) XXX_DiscardUnknown() { - xxx_messageInfo_Capabilities_CapabilityConstraints.DiscardUnknown(m) -} - -var xxx_messageInfo_Capabilities_CapabilityConstraints proto.InternalMessageInfo - -func (m *Capabilities_CapabilityConstraints) GetModels() map[string]*Capabilities_CapabilityConstraints_ModelConstraint { - if m != nil { - return m.Models +func (x *Capabilities) GetConstraints() *Capabilities_Constraints { + if x != nil { + return x.Constraints } return nil } -type Capabilities_CapabilityConstraints_ModelConstraint struct { - Warm bool `protobuf:"varint,1,opt,name=warm,proto3" json:"warm,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *Capabilities_CapabilityConstraints_ModelConstraint) Reset() { - *m = Capabilities_CapabilityConstraints_ModelConstraint{} -} -func (m *Capabilities_CapabilityConstraints_ModelConstraint) String() string { - return proto.CompactTextString(m) -} -func (*Capabilities_CapabilityConstraints_ModelConstraint) ProtoMessage() {} -func (*Capabilities_CapabilityConstraints_ModelConstraint) Descriptor() ([]byte, []int) { - return fileDescriptor_034e29c79f9ba827, []int{7, 2, 0} -} - -func (m *Capabilities_CapabilityConstraints_ModelConstraint) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Capabilities_CapabilityConstraints_ModelConstraint.Unmarshal(m, b) -} -func (m *Capabilities_CapabilityConstraints_ModelConstraint) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Capabilities_CapabilityConstraints_ModelConstraint.Marshal(b, m, deterministic) -} -func (m *Capabilities_CapabilityConstraints_ModelConstraint) XXX_Merge(src proto.Message) { - xxx_messageInfo_Capabilities_CapabilityConstraints_ModelConstraint.Merge(m, src) -} -func (m *Capabilities_CapabilityConstraints_ModelConstraint) XXX_Size() int { - return xxx_messageInfo_Capabilities_CapabilityConstraints_ModelConstraint.Size(m) -} -func (m *Capabilities_CapabilityConstraints_ModelConstraint) XXX_DiscardUnknown() { - xxx_messageInfo_Capabilities_CapabilityConstraints_ModelConstraint.DiscardUnknown(m) -} - -var xxx_messageInfo_Capabilities_CapabilityConstraints_ModelConstraint proto.InternalMessageInfo - -func (m *Capabilities_CapabilityConstraints_ModelConstraint) GetWarm() bool { - if m != nil { - return m.Warm +func (x *Capabilities) GetCapabilityConstraints() map[uint32]*Capabilities_CapabilityConstraints { + if x != nil { + return x.CapabilityConstraints } - return false + 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 @@ -870,148 +850,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 (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 (x *OrchestratorInfo) String() string { + return protoimpl.X.MessageStringOf(x) } -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 (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 (x *AuthToken) String() string { + return protoimpl.X.MessageStringOf(x) } -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 @@ -1045,194 +1041,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 (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 (x *SegData) String() string { + return protoimpl.X.MessageStringOf(x) } -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 (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 (x *SegParameters) String() string { + return protoimpl.X.MessageStringOf(x) } -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 @@ -1251,305 +1263,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 @@ -1557,96 +1582,116 @@ 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 (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 (x *RegisterRequest) String() string { + return protoimpl.X.MessageStringOf(x) } -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 @@ -1655,61 +1700,65 @@ type NotifySegment struct { TaskId int64 `protobuf:"varint,16,opt,name=taskId,proto3" json:"taskId,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 (m *NotifySegment) XXX_Size() int { - return xxx_messageInfo_NotifySegment.Size(m) +func (x *NotifySegment) String() string { + return protoimpl.X.MessageStringOf(x) } -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) GetProfiles() []byte { + if x != nil { + return x.Profiles } return nil } @@ -1780,6 +1829,10 @@ func (x *NotifyAIJob) GetData() []byte { // 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 @@ -1795,10 +1848,7 @@ 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 (x *TicketParams) Reset() { @@ -1833,83 +1883,66 @@ func (*TicketParams) Descriptor() ([]byte, []int) { return file_net_lp_rpc_proto_rawDescGZIP(), []int{19} } -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 (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) -} - -var xxx_messageInfo_TicketParams proto.InternalMessageInfo - -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 (x *TicketSenderParams) Reset() { @@ -1944,47 +1977,30 @@ func (*TicketSenderParams) Descriptor() ([]byte, []int) { return file_net_lp_rpc_proto_rawDescGZIP(), []int{20} } -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 (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) -} - -var xxx_messageInfo_TicketSenderParams proto.InternalMessageInfo - -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 (x *TicketExpirationParams) Reset() { @@ -2019,34 +2035,16 @@ func (*TicketExpirationParams) Descriptor() ([]byte, []int) { return file_net_lp_rpc_proto_rawDescGZIP(), []int{21} } -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 (m *TicketExpirationParams) XXX_DiscardUnknown() { - xxx_messageInfo_TicketExpirationParams.DiscardUnknown(m) -} - -var xxx_messageInfo_TicketExpirationParams proto.InternalMessageInfo - -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 } @@ -2055,6 +2053,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"` @@ -2064,10 +2066,7 @@ 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 (x *Payment) Reset() { @@ -2102,93 +2101,48 @@ func (*Payment) Descriptor() ([]byte, []int) { return file_net_lp_rpc_proto_rawDescGZIP(), []int{22} } -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 (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) -} - -var xxx_messageInfo_Payment proto.InternalMessageInfo - -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]*Capabilities_CapabilityConstraints)(nil), "net.Capabilities.CapabilityConstraintsEntry") - proto.RegisterMapType((map[uint32]uint32)(nil), "net.Capabilities.CapacitiesEntry") - proto.RegisterType((*Capabilities_Constraints)(nil), "net.Capabilities.Constraints") - proto.RegisterType((*Capabilities_CapabilityConstraints)(nil), "net.Capabilities.CapabilityConstraints") - proto.RegisterMapType((map[string]*Capabilities_CapabilityConstraints_ModelConstraint)(nil), "net.Capabilities.CapabilityConstraints.ModelsEntry") - proto.RegisterType((*Capabilities_CapabilityConstraints_ModelConstraint)(nil), "net.Capabilities.CapabilityConstraints.ModelConstraint") - 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") +// Non-binary general constraints. +type Capabilities_Constraints struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + MinVersion string `protobuf:"bytes,1,opt,name=minVersion,proto3" json:"minVersion,omitempty"` } func (x *Capabilities_Constraints) Reset() { @@ -2223,14 +2177,62 @@ func (*Capabilities_Constraints) Descriptor() ([]byte, []int) { return file_net_lp_rpc_proto_rawDescGZIP(), []int{7, 1} } -func (x *Capabilities_Constraints) GetModels() map[string]*Capabilities_Constraints_ModelConstraint { +func (x *Capabilities_Constraints) GetMinVersion() string { + if x != nil { + return x.MinVersion + } + return "" +} + +// Non-binary capability constraints, such as supported ranges. +type Capabilities_CapabilityConstraints struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Models map[string]*Capabilities_CapabilityConstraints_ModelConstraint `protobuf:"bytes,1,rep,name=models,proto3" json:"models,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *Capabilities_CapabilityConstraints) Reset() { + *x = Capabilities_CapabilityConstraints{} + if protoimpl.UnsafeEnabled { + mi := &file_net_lp_rpc_proto_msgTypes[25] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Capabilities_CapabilityConstraints) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Capabilities_CapabilityConstraints) ProtoMessage() {} + +func (x *Capabilities_CapabilityConstraints) ProtoReflect() protoreflect.Message { + mi := &file_net_lp_rpc_proto_msgTypes[25] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Capabilities_CapabilityConstraints.ProtoReflect.Descriptor instead. +func (*Capabilities_CapabilityConstraints) Descriptor() ([]byte, []int) { + return file_net_lp_rpc_proto_rawDescGZIP(), []int{7, 2} +} + +func (x *Capabilities_CapabilityConstraints) GetModels() map[string]*Capabilities_CapabilityConstraints_ModelConstraint { if x != nil { return x.Models } return nil } -type Capabilities_Constraints_ModelConstraint struct { +type Capabilities_CapabilityConstraints_ModelConstraint struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields @@ -2238,23 +2240,23 @@ type Capabilities_Constraints_ModelConstraint struct { Warm bool `protobuf:"varint,1,opt,name=warm,proto3" json:"warm,omitempty"` } -func (x *Capabilities_Constraints_ModelConstraint) Reset() { - *x = Capabilities_Constraints_ModelConstraint{} +func (x *Capabilities_CapabilityConstraints_ModelConstraint) Reset() { + *x = Capabilities_CapabilityConstraints_ModelConstraint{} if protoimpl.UnsafeEnabled { - mi := &file_net_lp_rpc_proto_msgTypes[26] + mi := &file_net_lp_rpc_proto_msgTypes[27] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } -func (x *Capabilities_Constraints_ModelConstraint) String() string { +func (x *Capabilities_CapabilityConstraints_ModelConstraint) String() string { return protoimpl.X.MessageStringOf(x) } -func (*Capabilities_Constraints_ModelConstraint) ProtoMessage() {} +func (*Capabilities_CapabilityConstraints_ModelConstraint) ProtoMessage() {} -func (x *Capabilities_Constraints_ModelConstraint) ProtoReflect() protoreflect.Message { - mi := &file_net_lp_rpc_proto_msgTypes[26] +func (x *Capabilities_CapabilityConstraints_ModelConstraint) ProtoReflect() protoreflect.Message { + mi := &file_net_lp_rpc_proto_msgTypes[27] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2265,12 +2267,12 @@ func (x *Capabilities_Constraints_ModelConstraint) ProtoReflect() protoreflect.M return mi.MessageOf(x) } -// Deprecated: Use Capabilities_Constraints_ModelConstraint.ProtoReflect.Descriptor instead. -func (*Capabilities_Constraints_ModelConstraint) Descriptor() ([]byte, []int) { - return file_net_lp_rpc_proto_rawDescGZIP(), []int{7, 1, 0} +// Deprecated: Use Capabilities_CapabilityConstraints_ModelConstraint.ProtoReflect.Descriptor instead. +func (*Capabilities_CapabilityConstraints_ModelConstraint) Descriptor() ([]byte, []int) { + return file_net_lp_rpc_proto_rawDescGZIP(), []int{7, 2, 0} } -func (x *Capabilities_Constraints_ModelConstraint) GetWarm() bool { +func (x *Capabilities_CapabilityConstraints_ModelConstraint) GetWarm() bool { if x != nil { return x.Warm } @@ -2323,7 +2325,7 @@ var file_net_lp_rpc_proto_rawDesc = []byte{ 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, 0xd9, 0x04, 0x0a, 0x0c, + 0x78, 0x65, 0x6c, 0x73, 0x50, 0x65, 0x72, 0x55, 0x6e, 0x69, 0x74, 0x22, 0xb3, 0x06, 0x0a, 0x0c, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x62, 0x69, 0x74, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x18, 0x01, 0x20, 0x03, 0x28, 0x04, 0x52, 0x09, 0x62, 0x69, 0x74, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x12, 0x20, 0x0a, 0x0b, 0x6d, 0x61, @@ -2333,273 +2335,287 @@ var file_net_lp_rpc_proto_rawDesc = []byte{ 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, - 0x44, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x74, 0x73, 0x18, 0x04, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 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, 0x45, 0x6e, 0x74, 0x72, 0x79, 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, 0xe1, 0x01, 0x0a, 0x0b, 0x43, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x61, - 0x69, 0x6e, 0x74, 0x73, 0x12, 0x41, 0x0a, 0x06, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x73, 0x18, 0x01, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x43, 0x61, 0x70, 0x61, 0x62, - 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x61, 0x69, - 0x6e, 0x74, 0x73, 0x2e, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, - 0x06, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x73, 0x1a, 0x25, 0x0a, 0x0f, 0x4d, 0x6f, 0x64, 0x65, 0x6c, - 0x43, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x77, 0x61, - 0x72, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x77, 0x61, 0x72, 0x6d, 0x1a, 0x68, - 0x0a, 0x0b, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, - 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, - 0x43, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, + 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, 0x2e, 0x4d, 0x6f, - 0x64, 0x65, 0x6c, 0x43, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x74, 0x52, 0x05, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x5d, 0x0a, 0x10, 0x43, 0x6f, 0x6e, 0x73, + 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, 0x12, 0x62, 0x0a, 0x15, 0x63, 0x61, + 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x43, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x61, 0x69, + 0x6e, 0x74, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x6e, 0x65, 0x74, 0x2e, + 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x2e, 0x43, 0x61, 0x70, + 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x43, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x61, 0x69, 0x6e, + 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x15, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, + 0x69, 0x74, 0x79, 0x43, 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, 0x1a, 0xff, 0x01, 0x0a, + 0x15, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x43, 0x6f, 0x6e, 0x73, 0x74, + 0x72, 0x61, 0x69, 0x6e, 0x74, 0x73, 0x12, 0x4b, 0x0a, 0x06, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x73, + 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x43, 0x61, 0x70, + 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x2e, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, + 0x6c, 0x69, 0x74, 0x79, 0x43, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x74, 0x73, 0x2e, + 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x6d, 0x6f, 0x64, + 0x65, 0x6c, 0x73, 0x1a, 0x25, 0x0a, 0x0f, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x43, 0x6f, 0x6e, 0x73, + 0x74, 0x72, 0x61, 0x69, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x77, 0x61, 0x72, 0x6d, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x77, 0x61, 0x72, 0x6d, 0x1a, 0x72, 0x0a, 0x0b, 0x4d, 0x6f, + 0x64, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x4d, 0x0a, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x37, 0x2e, 0x6e, 0x65, 0x74, + 0x2e, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x2e, 0x43, 0x61, + 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x43, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x61, 0x69, + 0x6e, 0x74, 0x73, 0x2e, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x43, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x61, + 0x69, 0x6e, 0x74, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x71, + 0x0a, 0x1a, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x43, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x74, 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, 0x33, - 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, + 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x3d, + 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, - 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x74, 0x73, 0x52, 0x05, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xc0, 0x02, 0x0a, 0x10, 0x4f, 0x72, 0x63, 0x68, - 0x65, 0x73, 0x74, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1e, 0x0a, 0x0a, - 0x74, 0x72, 0x61, 0x6e, 0x73, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0a, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x12, 0x36, 0x0a, 0x0d, - 0x74, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x54, 0x69, 0x63, 0x6b, 0x65, 0x74, - 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x0c, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x50, 0x61, - 0x72, 0x61, 0x6d, 0x73, 0x12, 0x2d, 0x0a, 0x0a, 0x70, 0x72, 0x69, 0x63, 0x65, 0x5f, 0x69, 0x6e, - 0x66, 0x6f, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x50, - 0x72, 0x69, 0x63, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x09, 0x70, 0x72, 0x69, 0x63, 0x65, 0x49, - 0x6e, 0x66, 0x6f, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x35, 0x0a, - 0x0c, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x18, 0x05, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, - 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x52, 0x0c, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, - 0x74, 0x69, 0x65, 0x73, 0x12, 0x2d, 0x0a, 0x0a, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x74, 0x6f, 0x6b, - 0x65, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x41, - 0x75, 0x74, 0x68, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x09, 0x61, 0x75, 0x74, 0x68, 0x54, 0x6f, - 0x6b, 0x65, 0x6e, 0x12, 0x25, 0x0a, 0x07, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x18, 0x20, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x4f, 0x53, 0x49, 0x6e, 0x66, - 0x6f, 0x52, 0x07, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x22, 0x60, 0x0a, 0x09, 0x41, 0x75, - 0x74, 0x68, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x1d, 0x0a, - 0x0a, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x09, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x1e, 0x0a, 0x0a, - 0x65, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, - 0x52, 0x0a, 0x65, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xf4, 0x04, 0x0a, - 0x07, 0x53, 0x65, 0x67, 0x44, 0x61, 0x74, 0x61, 0x12, 0x1e, 0x0a, 0x0a, 0x6d, 0x61, 0x6e, 0x69, - 0x66, 0x65, 0x73, 0x74, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x6d, 0x61, - 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x65, 0x71, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x03, 0x73, 0x65, 0x71, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, - 0x73, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x12, 0x1a, - 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x08, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x69, - 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x73, 0x69, 0x67, 0x12, 0x1a, 0x0a, 0x08, - 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, - 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x35, 0x0a, 0x0c, 0x63, 0x61, 0x70, 0x61, - 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, - 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, - 0x73, 0x52, 0x0c, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x12, - 0x2d, 0x0a, 0x0a, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x08, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x54, 0x6f, - 0x6b, 0x65, 0x6e, 0x52, 0x09, 0x61, 0x75, 0x74, 0x68, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x30, - 0x0a, 0x14, 0x63, 0x61, 0x6c, 0x63, 0x5f, 0x70, 0x65, 0x72, 0x63, 0x65, 0x70, 0x74, 0x75, 0x61, - 0x6c, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x63, 0x61, - 0x6c, 0x63, 0x50, 0x65, 0x72, 0x63, 0x65, 0x70, 0x74, 0x75, 0x61, 0x6c, 0x48, 0x61, 0x73, 0x68, - 0x12, 0x25, 0x0a, 0x07, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x18, 0x20, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x0b, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x4f, 0x53, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x07, - 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x12, 0x35, 0x0a, 0x0c, 0x66, 0x75, 0x6c, 0x6c, 0x50, - 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x18, 0x21, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, - 0x6e, 0x65, 0x74, 0x2e, 0x56, 0x69, 0x64, 0x65, 0x6f, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, - 0x52, 0x0c, 0x66, 0x75, 0x6c, 0x6c, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x37, - 0x0a, 0x0d, 0x66, 0x75, 0x6c, 0x6c, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x32, 0x18, - 0x22, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x56, 0x69, 0x64, 0x65, - 0x6f, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x52, 0x0d, 0x66, 0x75, 0x6c, 0x6c, 0x50, 0x72, - 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 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, + 0x2e, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x43, 0x6f, 0x6e, 0x73, 0x74, + 0x72, 0x61, 0x69, 0x6e, 0x74, 0x73, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, + 0x01, 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, 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, 0x89, 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, 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, 0x61, 0x0a, 0x0b, - 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x41, 0x49, 0x4a, 0x6f, 0x62, 0x12, 0x26, 0x0a, 0x04, 0x74, - 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x12, 0x2e, 0x6e, 0x65, 0x74, 0x2e, - 0x41, 0x49, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, - 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x61, 0x73, 0x6b, 0x49, 0x44, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x03, 0x52, 0x06, 0x74, 0x61, 0x73, 0x6b, 0x49, 0x44, 0x12, 0x12, 0x0a, 0x04, 0x64, - 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 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, + 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, 0x89, 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, 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, 0x61, 0x0a, 0x0b, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, + 0x41, 0x49, 0x4a, 0x6f, 0x62, 0x12, 0x26, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0e, 0x32, 0x12, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x41, 0x49, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, + 0x06, 0x74, 0x61, 0x73, 0x6b, 0x49, 0x44, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x74, + 0x61, 0x73, 0x6b, 0x49, 0x44, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 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, 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, - 0x2a, 0x62, 0x0a, 0x0d, 0x41, 0x49, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, - 0x65, 0x12, 0x0f, 0x0a, 0x0b, 0x54, 0x65, 0x78, 0x74, 0x54, 0x6f, 0x49, 0x6d, 0x61, 0x67, 0x65, - 0x10, 0x00, 0x12, 0x10, 0x0a, 0x0c, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x49, 0x6d, 0x61, - 0x67, 0x65, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x56, - 0x69, 0x64, 0x65, 0x6f, 0x10, 0x02, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x70, 0x73, 0x63, 0x61, 0x6c, - 0x65, 0x10, 0x03, 0x12, 0x0f, 0x0a, 0x0b, 0x41, 0x75, 0x64, 0x69, 0x6f, 0x54, 0x6f, 0x54, 0x65, - 0x78, 0x74, 0x10, 0x04, 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, - 0x8c, 0x01, 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, - 0x12, 0x3c, 0x0a, 0x10, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x41, 0x49, 0x57, 0x6f, - 0x72, 0x6b, 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, 0x10, 0x2e, 0x6e, 0x65, 0x74, - 0x2e, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x41, 0x49, 0x4a, 0x6f, 0x62, 0x30, 0x01, 0x42, 0x07, - 0x5a, 0x05, 0x2e, 0x2f, 0x6e, 0x65, 0x74, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 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, 0x2a, 0x62, 0x0a, 0x0d, 0x41, 0x49, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0f, 0x0a, 0x0b, 0x54, + 0x65, 0x78, 0x74, 0x54, 0x6f, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x10, 0x00, 0x12, 0x10, 0x0a, 0x0c, + 0x49, 0x6d, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x10, 0x01, 0x12, 0x10, + 0x0a, 0x0c, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x56, 0x69, 0x64, 0x65, 0x6f, 0x10, 0x02, + 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x70, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x10, 0x03, 0x12, 0x0f, 0x0a, + 0x0b, 0x41, 0x75, 0x64, 0x69, 0x6f, 0x54, 0x6f, 0x54, 0x65, 0x78, 0x74, 0x10, 0x04, 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, 0x8c, 0x01, 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, 0x12, 0x3c, 0x0a, 0x10, 0x52, 0x65, + 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x41, 0x49, 0x57, 0x6f, 0x72, 0x6b, 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, 0x10, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x4e, 0x6f, 0x74, 0x69, 0x66, + 0x79, 0x41, 0x49, 0x4a, 0x6f, 0x62, 0x30, 0x01, 0x42, 0x07, 0x5a, 0x05, 0x2e, 0x2f, 0x6e, 0x65, + 0x74, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -2615,42 +2631,43 @@ func file_net_lp_rpc_proto_rawDescGZIP() []byte { } var file_net_lp_rpc_proto_enumTypes = make([]protoimpl.EnumInfo, 6) -var file_net_lp_rpc_proto_msgTypes = make([]protoimpl.MessageInfo, 28) +var file_net_lp_rpc_proto_msgTypes = make([]protoimpl.MessageInfo, 29) var file_net_lp_rpc_proto_goTypes = []interface{}{ - (AIRequestType)(0), // 0: net.AIRequestType - (OSInfo_StorageType)(0), // 1: net.OSInfo.StorageType - (VideoProfile_Format)(0), // 2: net.VideoProfile.Format - (VideoProfile_Profile)(0), // 3: net.VideoProfile.Profile - (VideoProfile_VideoCodec)(0), // 4: net.VideoProfile.VideoCodec - (VideoProfile_ChromaSubsampling)(0), // 5: net.VideoProfile.ChromaSubsampling - (*PingPong)(nil), // 6: net.PingPong - (*EndTranscodingSessionRequest)(nil), // 7: net.EndTranscodingSessionRequest - (*EndTranscodingSessionResponse)(nil), // 8: net.EndTranscodingSessionResponse - (*OrchestratorRequest)(nil), // 9: net.OrchestratorRequest - (*OSInfo)(nil), // 10: net.OSInfo - (*S3OSInfo)(nil), // 11: net.S3OSInfo - (*PriceInfo)(nil), // 12: net.PriceInfo - (*Capabilities)(nil), // 13: net.Capabilities - (*OrchestratorInfo)(nil), // 14: net.OrchestratorInfo - (*AuthToken)(nil), // 15: net.AuthToken - (*SegData)(nil), // 16: net.SegData - (*SegParameters)(nil), // 17: net.SegParameters - (*VideoProfile)(nil), // 18: net.VideoProfile - (*TranscodedSegmentData)(nil), // 19: net.TranscodedSegmentData - (*TranscodeData)(nil), // 20: net.TranscodeData - (*TranscodeResult)(nil), // 21: net.TranscodeResult - (*RegisterRequest)(nil), // 22: net.RegisterRequest - (*NotifySegment)(nil), // 23: net.NotifySegment - (*NotifyAIJob)(nil), // 24: net.NotifyAIJob - (*TicketParams)(nil), // 25: net.TicketParams - (*TicketSenderParams)(nil), // 26: net.TicketSenderParams - (*TicketExpirationParams)(nil), // 27: net.TicketExpirationParams - (*Payment)(nil), // 28: net.Payment - nil, // 29: net.Capabilities.CapacitiesEntry - (*Capabilities_Constraints)(nil), // 30: net.Capabilities.Constraints - nil, // 31: net.Capabilities.ConstraintsEntry - (*Capabilities_Constraints_ModelConstraint)(nil), // 32: net.Capabilities.Constraints.ModelConstraint - nil, // 33: net.Capabilities.Constraints.ModelsEntry + (AIRequestType)(0), // 0: net.AIRequestType + (OSInfo_StorageType)(0), // 1: net.OSInfo.StorageType + (VideoProfile_Format)(0), // 2: net.VideoProfile.Format + (VideoProfile_Profile)(0), // 3: net.VideoProfile.Profile + (VideoProfile_VideoCodec)(0), // 4: net.VideoProfile.VideoCodec + (VideoProfile_ChromaSubsampling)(0), // 5: net.VideoProfile.ChromaSubsampling + (*PingPong)(nil), // 6: net.PingPong + (*EndTranscodingSessionRequest)(nil), // 7: net.EndTranscodingSessionRequest + (*EndTranscodingSessionResponse)(nil), // 8: net.EndTranscodingSessionResponse + (*OrchestratorRequest)(nil), // 9: net.OrchestratorRequest + (*OSInfo)(nil), // 10: net.OSInfo + (*S3OSInfo)(nil), // 11: net.S3OSInfo + (*PriceInfo)(nil), // 12: net.PriceInfo + (*Capabilities)(nil), // 13: net.Capabilities + (*OrchestratorInfo)(nil), // 14: net.OrchestratorInfo + (*AuthToken)(nil), // 15: net.AuthToken + (*SegData)(nil), // 16: net.SegData + (*SegParameters)(nil), // 17: net.SegParameters + (*VideoProfile)(nil), // 18: net.VideoProfile + (*TranscodedSegmentData)(nil), // 19: net.TranscodedSegmentData + (*TranscodeData)(nil), // 20: net.TranscodeData + (*TranscodeResult)(nil), // 21: net.TranscodeResult + (*RegisterRequest)(nil), // 22: net.RegisterRequest + (*NotifySegment)(nil), // 23: net.NotifySegment + (*NotifyAIJob)(nil), // 24: net.NotifyAIJob + (*TicketParams)(nil), // 25: net.TicketParams + (*TicketSenderParams)(nil), // 26: net.TicketSenderParams + (*TicketExpirationParams)(nil), // 27: net.TicketExpirationParams + (*Payment)(nil), // 28: net.Payment + nil, // 29: net.Capabilities.CapacitiesEntry + (*Capabilities_Constraints)(nil), // 30: net.Capabilities.Constraints + (*Capabilities_CapabilityConstraints)(nil), // 31: net.Capabilities.CapabilityConstraints + nil, // 32: net.Capabilities.CapabilityConstraintsEntry + (*Capabilities_CapabilityConstraints_ModelConstraint)(nil), // 33: net.Capabilities.CapabilityConstraints.ModelConstraint + nil, // 34: net.Capabilities.CapabilityConstraints.ModelsEntry } var file_net_lp_rpc_proto_depIdxs = []int32{ 15, // 0: net.EndTranscodingSessionRequest.auth_token:type_name -> net.AuthToken @@ -2658,52 +2675,53 @@ var file_net_lp_rpc_proto_depIdxs = []int32{ 1, // 2: net.OSInfo.storageType:type_name -> net.OSInfo.StorageType 11, // 3: net.OSInfo.s3info:type_name -> net.S3OSInfo 29, // 4: net.Capabilities.capacities:type_name -> net.Capabilities.CapacitiesEntry - 31, // 5: net.Capabilities.constraints:type_name -> net.Capabilities.ConstraintsEntry - 25, // 6: net.OrchestratorInfo.ticket_params:type_name -> net.TicketParams - 12, // 7: net.OrchestratorInfo.price_info:type_name -> net.PriceInfo - 13, // 8: net.OrchestratorInfo.capabilities:type_name -> net.Capabilities - 15, // 9: net.OrchestratorInfo.auth_token:type_name -> net.AuthToken - 10, // 10: net.OrchestratorInfo.storage:type_name -> net.OSInfo - 13, // 11: net.SegData.capabilities:type_name -> net.Capabilities - 15, // 12: net.SegData.auth_token:type_name -> net.AuthToken - 10, // 13: net.SegData.storage:type_name -> net.OSInfo - 18, // 14: net.SegData.fullProfiles:type_name -> net.VideoProfile - 18, // 15: net.SegData.fullProfiles2:type_name -> net.VideoProfile - 18, // 16: net.SegData.fullProfiles3:type_name -> net.VideoProfile - 17, // 17: net.SegData.segment_parameters:type_name -> net.SegParameters - 2, // 18: net.VideoProfile.format:type_name -> net.VideoProfile.Format - 3, // 19: net.VideoProfile.profile:type_name -> net.VideoProfile.Profile - 4, // 20: net.VideoProfile.encoder:type_name -> net.VideoProfile.VideoCodec - 5, // 21: net.VideoProfile.chromaFormat:type_name -> net.VideoProfile.ChromaSubsampling - 19, // 22: net.TranscodeData.segments:type_name -> net.TranscodedSegmentData - 20, // 23: net.TranscodeResult.data:type_name -> net.TranscodeData - 14, // 24: net.TranscodeResult.info:type_name -> net.OrchestratorInfo - 13, // 25: net.RegisterRequest.capabilities:type_name -> net.Capabilities - 16, // 26: net.NotifySegment.segData:type_name -> net.SegData - 0, // 27: net.NotifyAIJob.type:type_name -> net.AIRequestType - 27, // 28: net.TicketParams.expiration_params:type_name -> net.TicketExpirationParams - 25, // 29: net.Payment.ticket_params:type_name -> net.TicketParams - 27, // 30: net.Payment.expiration_params:type_name -> net.TicketExpirationParams - 26, // 31: net.Payment.ticket_sender_params:type_name -> net.TicketSenderParams - 12, // 32: net.Payment.expected_price:type_name -> net.PriceInfo - 33, // 33: net.Capabilities.Constraints.models:type_name -> net.Capabilities.Constraints.ModelsEntry - 30, // 34: net.Capabilities.ConstraintsEntry.value:type_name -> net.Capabilities.Constraints - 32, // 35: net.Capabilities.Constraints.ModelsEntry.value:type_name -> net.Capabilities.Constraints.ModelConstraint - 9, // 36: net.Orchestrator.GetOrchestrator:input_type -> net.OrchestratorRequest - 7, // 37: net.Orchestrator.EndTranscodingSession:input_type -> net.EndTranscodingSessionRequest - 6, // 38: net.Orchestrator.Ping:input_type -> net.PingPong - 22, // 39: net.Transcoder.RegisterTranscoder:input_type -> net.RegisterRequest - 22, // 40: net.Transcoder.RegisterAIWorker:input_type -> net.RegisterRequest - 14, // 41: net.Orchestrator.GetOrchestrator:output_type -> net.OrchestratorInfo - 8, // 42: net.Orchestrator.EndTranscodingSession:output_type -> net.EndTranscodingSessionResponse - 6, // 43: net.Orchestrator.Ping:output_type -> net.PingPong - 23, // 44: net.Transcoder.RegisterTranscoder:output_type -> net.NotifySegment - 24, // 45: net.Transcoder.RegisterAIWorker:output_type -> net.NotifyAIJob - 41, // [41:46] is the sub-list for method output_type - 36, // [36:41] is the sub-list for method input_type - 36, // [36:36] is the sub-list for extension type_name - 36, // [36:36] is the sub-list for extension extendee - 0, // [0:36] is the sub-list for field type_name + 30, // 5: net.Capabilities.constraints:type_name -> net.Capabilities.Constraints + 32, // 6: net.Capabilities.capabilityConstraints:type_name -> net.Capabilities.CapabilityConstraintsEntry + 25, // 7: net.OrchestratorInfo.ticket_params:type_name -> net.TicketParams + 12, // 8: net.OrchestratorInfo.price_info:type_name -> net.PriceInfo + 13, // 9: net.OrchestratorInfo.capabilities:type_name -> net.Capabilities + 15, // 10: net.OrchestratorInfo.auth_token:type_name -> net.AuthToken + 10, // 11: net.OrchestratorInfo.storage:type_name -> net.OSInfo + 13, // 12: net.SegData.capabilities:type_name -> net.Capabilities + 15, // 13: net.SegData.auth_token:type_name -> net.AuthToken + 10, // 14: net.SegData.storage:type_name -> net.OSInfo + 18, // 15: net.SegData.fullProfiles:type_name -> net.VideoProfile + 18, // 16: net.SegData.fullProfiles2:type_name -> net.VideoProfile + 18, // 17: net.SegData.fullProfiles3:type_name -> net.VideoProfile + 17, // 18: net.SegData.segment_parameters:type_name -> net.SegParameters + 2, // 19: net.VideoProfile.format:type_name -> net.VideoProfile.Format + 3, // 20: net.VideoProfile.profile:type_name -> net.VideoProfile.Profile + 4, // 21: net.VideoProfile.encoder:type_name -> net.VideoProfile.VideoCodec + 5, // 22: net.VideoProfile.chromaFormat:type_name -> net.VideoProfile.ChromaSubsampling + 19, // 23: net.TranscodeData.segments:type_name -> net.TranscodedSegmentData + 20, // 24: net.TranscodeResult.data:type_name -> net.TranscodeData + 14, // 25: net.TranscodeResult.info:type_name -> net.OrchestratorInfo + 13, // 26: net.RegisterRequest.capabilities:type_name -> net.Capabilities + 16, // 27: net.NotifySegment.segData:type_name -> net.SegData + 0, // 28: net.NotifyAIJob.type:type_name -> net.AIRequestType + 27, // 29: net.TicketParams.expiration_params:type_name -> net.TicketExpirationParams + 25, // 30: net.Payment.ticket_params:type_name -> net.TicketParams + 27, // 31: net.Payment.expiration_params:type_name -> net.TicketExpirationParams + 26, // 32: net.Payment.ticket_sender_params:type_name -> net.TicketSenderParams + 12, // 33: net.Payment.expected_price:type_name -> net.PriceInfo + 34, // 34: net.Capabilities.CapabilityConstraints.models:type_name -> net.Capabilities.CapabilityConstraints.ModelsEntry + 31, // 35: net.Capabilities.CapabilityConstraintsEntry.value:type_name -> net.Capabilities.CapabilityConstraints + 33, // 36: net.Capabilities.CapabilityConstraints.ModelsEntry.value:type_name -> net.Capabilities.CapabilityConstraints.ModelConstraint + 9, // 37: net.Orchestrator.GetOrchestrator:input_type -> net.OrchestratorRequest + 7, // 38: net.Orchestrator.EndTranscodingSession:input_type -> net.EndTranscodingSessionRequest + 6, // 39: net.Orchestrator.Ping:input_type -> net.PingPong + 22, // 40: net.Transcoder.RegisterTranscoder:input_type -> net.RegisterRequest + 22, // 41: net.Transcoder.RegisterAIWorker:input_type -> net.RegisterRequest + 14, // 42: net.Orchestrator.GetOrchestrator:output_type -> net.OrchestratorInfo + 8, // 43: net.Orchestrator.EndTranscodingSession:output_type -> net.EndTranscodingSessionResponse + 6, // 44: net.Orchestrator.Ping:output_type -> net.PingPong + 23, // 45: net.Transcoder.RegisterTranscoder:output_type -> net.NotifySegment + 24, // 46: net.Transcoder.RegisterAIWorker:output_type -> net.NotifyAIJob + 42, // [42:47] is the sub-list for method output_type + 37, // [37:42] is the sub-list for method input_type + 37, // [37:37] is the sub-list for extension type_name + 37, // [37:37] is the sub-list for extension extendee + 0, // [0:37] is the sub-list for field type_name } func init() { file_net_lp_rpc_proto_init() } @@ -3000,8 +3018,20 @@ func file_net_lp_rpc_proto_init() { return nil } } - file_net_lp_rpc_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Capabilities_Constraints_ModelConstraint); i { + file_net_lp_rpc_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Capabilities_CapabilityConstraints); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_net_lp_rpc_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Capabilities_CapabilityConstraints_ModelConstraint); i { case 0: return &v.state case 1: @@ -3023,7 +3053,7 @@ func file_net_lp_rpc_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_net_lp_rpc_proto_rawDesc, NumEnums: 6, - NumMessages: 28, + NumMessages: 29, NumExtensions: 0, NumServices: 2, }, From fefd30c837078c9f679c20353aad2a1796d06b83 Mon Sep 17 00:00:00 2001 From: kyriediculous Date: Tue, 30 Jul 2024 05:16:25 +0200 Subject: [PATCH 79/88] cmd: set ai pricePerPixel outside of config loop --- cmd/livepeer/starter/starter.go | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/cmd/livepeer/starter/starter.go b/cmd/livepeer/starter/starter.go index 1e1f65934c..66a2de2291 100755 --- a/cmd/livepeer/starter/starter.go +++ b/cmd/livepeer/starter/starter.go @@ -1106,18 +1106,19 @@ func StartLivepeer(ctx context.Context, cfg LivepeerConfig) { return } + // Set price per unit base info. + pixelsPerUnit, ok := new(big.Rat).SetString(*cfg.PixelsPerUnit) + if !ok || !pixelsPerUnit.IsInt() { + panic(fmt.Errorf("-pixelsPerUnit must be a valid integer, provided %v", *cfg.PixelsPerUnit)) + } + if pixelsPerUnit.Sign() <= 0 { + // Can't divide by 0 + panic(fmt.Errorf("-pixelsPerUnit must be > 0, provided %v", *cfg.PixelsPerUnit)) + } + for _, config := range configs { modelConstraint := &core.ModelConstraint{Warm: config.Warm} - // Set price per unit base info. - pixelsPerUnit, ok := new(big.Rat).SetString(*cfg.PixelsPerUnit) - if !ok || !pixelsPerUnit.IsInt() { - panic(fmt.Errorf("-pixelsPerUnit must be a valid integer, provided %v", *cfg.PixelsPerUnit)) - } - if pixelsPerUnit.Sign() <= 0 { - // Can't divide by 0 - panic(fmt.Errorf("-pixelsPerUnit must be > 0, provided %v", *cfg.PixelsPerUnit)) - } pricePerUnit, currency, err := parsePricePerUnit(config.PricePerUnit.String()) if err != nil { panic(fmt.Errorf("'pricePerUnit' value specified for model '%v' in pipeline '%v' must be a valid integer with an optional currency, provided %v", config.ModelID, config.Pipeline, config.PricePerUnit)) From 3d7863718c0411945ac10e3fdbb093b96c99f790 Mon Sep 17 00:00:00 2001 From: kyriediculous Date: Tue, 30 Jul 2024 05:22:15 +0200 Subject: [PATCH 80/88] go mod: remove replacement for lpms --- go.mod | 4 ++-- go.sum | 14 ++++++++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/go.mod b/go.mod index bc45377d83..a5163a9f55 100644 --- a/go.mod +++ b/go.mod @@ -83,6 +83,7 @@ require ( github.com/ethereum/c-kzg-4844 v0.4.0 // indirect github.com/fatih/color v1.13.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect + github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff // indirect github.com/ghodss/yaml v1.0.0 // indirect @@ -209,6 +210,7 @@ require ( github.com/urfave/cli/v2 v2.25.7 // indirect github.com/vincent-petithory/dataurl v1.0.0 // indirect github.com/whyrusleeping/cbor-gen v0.0.0-20230418232409-daab9ece03a0 // indirect + github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 // indirect go.opentelemetry.io/otel v1.24.0 // indirect @@ -240,5 +242,3 @@ require ( lukechampine.com/blake3 v1.2.1 // indirect rsc.io/tmplfunc v0.0.3 // indirect ) - -replace github.com/livepeer/lpms => /home/ricks/development/livepeer/ai/lpms diff --git a/go.sum b/go.sum index 251621f380..8b7c9c40c3 100644 --- a/go.sum +++ b/go.sum @@ -81,6 +81,8 @@ github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRF github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= +github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah4HI848JfFxHt+iPb26b4zyfspmqY0/8= +github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= github.com/apapsch/go-jsonmerge/v2 v2.0.0 h1:axGnT1gRIfimI7gJifB699GoE/oq+F2MU7Dml6nw9rQ= github.com/apapsch/go-jsonmerge/v2 v2.0.0/go.mod h1:lvDnEdqiQrp0O42VQGgmlKpxL1AP2+08jFMw88y4klk= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= @@ -120,6 +122,10 @@ github.com/chzyer/test v0.0.0-20210722231415-061457976a23/go.mod h1:Q3SI9o4m/ZMn github.com/cilium/ebpf v0.7.0/go.mod h1:/oI2+1shJiTGAMgl6/RgJr36Eo1jzrRcAWbcXO2usCA= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cockroachdb/datadriven v1.0.0/go.mod h1:5Ib8Meh+jk1RlHIXej6Pzevx/NLlNvQB9pmSBZErGA4= +github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f h1:otljaYPt5hWxV3MUfO5dFPFiOXg9CyG5/kCfayTqsJ4= +github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU= +github.com/cockroachdb/errors v1.6.1/go.mod h1:tm6FTP5G81vwJ5lC0SizQo374JNCOPrHyXGitRJoDqM= github.com/cockroachdb/errors v1.8.1 h1:A5+txlVZfOqFBDa4mGz2bUWSp0aHElvHX2bKkdbQu+Y= github.com/cockroachdb/errors v1.8.1/go.mod h1:qGwQn6JmZ+oMjuLwjWzUNqblqk0xl4CVV3SQbGwK7Ac= github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f h1:o/kfcElHqOiXqcou5a3rIlMc7oJbMQkeLk0VQJ7zgqY= @@ -214,6 +220,7 @@ github.com/ethereum/go-ethereum v1.13.5/go.mod h1:yMTu38GSuyxaYzQMViqNmQ1s3cE84a github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8= github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= +github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 h1:FtmdgXiUlNeRsoNMFlKLDt+S+6hbjVMEW6RGQ7aUf7c= @@ -401,6 +408,8 @@ github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWS github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/graph-gophers/graphql-go v1.3.0 h1:Eb9x/q6MFpCLz7jBCiP/WTxjSDrYLR1QY41SORZyNJ0= +github.com/graph-gophers/graphql-go v1.3.0/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc= github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= github.com/hashicorp/go-bexpr v0.1.10 h1:9kuI5PFotCboP3dkDYFr/wi0gg0QVbSNz5oFRpxn4uE= @@ -616,6 +625,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-20240711175220-227325841434 h1:E7PKN6q/jMLapEV+eEwlwv87Xe5zacaVhvZ8T6AJR3c= +github.com/livepeer/lpms v0.0.0-20240711175220-227325841434/go.mod h1:Hr/JhxxPDipOVd4ZrGYWrdJfpVF8/SEI0nNr2ctAlkM= github.com/livepeer/m3u8 v0.11.1 h1:VkUJzfNTyjy9mqsgp5JPvouwna8wGZMvd/gAfT5FinU= github.com/livepeer/m3u8 v0.11.1/go.mod h1:IUqAtwWPAG2CblfQa4SVzTQoDcEMPyfNOaBSxqHMS04= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= @@ -889,6 +900,7 @@ github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= @@ -1306,6 +1318,7 @@ google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCID google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= +google.golang.org/genproto v0.0.0-20180518175338-11a468237815/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= @@ -1341,6 +1354,7 @@ google.golang.org/genproto/googleapis/api v0.0.0-20240318140521-94a12d6c2237 h1: google.golang.org/genproto/googleapis/api v0.0.0-20240318140521-94a12d6c2237/go.mod h1:Z5Iiy3jtmioajWHDGFk7CeugTyHtPvMHA4UTmUkyalE= google.golang.org/genproto/googleapis/rpc v0.0.0-20240624140628-dc46fd24d27d h1:k3zyW3BYYR30e8v3x0bTDdE9vpYFjZHK+HcyqkrppWk= google.golang.org/genproto/googleapis/rpc v0.0.0-20240624140628-dc46fd24d27d/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= +google.golang.org/grpc v1.12.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= From 600b62b9fd27070acfbb63b4c1579b4a60ee9c4c Mon Sep 17 00:00:00 2001 From: kyriediculous Date: Tue, 30 Jul 2024 15:54:52 +0200 Subject: [PATCH 81/88] change lpms version --- go.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go.mod b/go.mod index a5163a9f55..361cc8befb 100644 --- a/go.mod +++ b/go.mod @@ -16,7 +16,7 @@ require ( github.com/livepeer/ai-worker v0.1.0 github.com/livepeer/go-tools v0.3.6-0.20240130205227-92479de8531b github.com/livepeer/livepeer-data v0.7.5-0.20231004073737-06f1f383fb18 - github.com/livepeer/lpms v0.0.0-20240711175220-227325841434 + github.com/livepeer/lpms v0.0.0-20240711034524-d9c78b62effd github.com/livepeer/m3u8 v0.11.1 github.com/mattn/go-sqlite3 v1.14.18 github.com/oapi-codegen/nethttp-middleware v1.0.1 From 6d18a8c50749ee6892bbf73cacc897b3cf1c8499 Mon Sep 17 00:00:00 2001 From: kyriediculous Date: Tue, 30 Jul 2024 16:08:10 +0200 Subject: [PATCH 82/88] chore: go mod tidy --- go.sum | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/go.sum b/go.sum index 8b7c9c40c3..14590c9ef6 100644 --- a/go.sum +++ b/go.sum @@ -625,8 +625,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-20240711175220-227325841434 h1:E7PKN6q/jMLapEV+eEwlwv87Xe5zacaVhvZ8T6AJR3c= -github.com/livepeer/lpms v0.0.0-20240711175220-227325841434/go.mod h1:Hr/JhxxPDipOVd4ZrGYWrdJfpVF8/SEI0nNr2ctAlkM= +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/m3u8 v0.11.1 h1:VkUJzfNTyjy9mqsgp5JPvouwna8wGZMvd/gAfT5FinU= github.com/livepeer/m3u8 v0.11.1/go.mod h1:IUqAtwWPAG2CblfQa4SVzTQoDcEMPyfNOaBSxqHMS04= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= @@ -1386,6 +1386,7 @@ google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= From 82fcaf51f5a6a600e8b3b731e8cdd38a142fe08f Mon Sep 17 00:00:00 2001 From: kyriediculous Date: Tue, 30 Jul 2024 16:17:42 +0200 Subject: [PATCH 83/88] change lpms version --- go.mod | 2 +- go.sum | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/go.mod b/go.mod index 361cc8befb..a5163a9f55 100644 --- a/go.mod +++ b/go.mod @@ -16,7 +16,7 @@ require ( github.com/livepeer/ai-worker v0.1.0 github.com/livepeer/go-tools v0.3.6-0.20240130205227-92479de8531b github.com/livepeer/livepeer-data v0.7.5-0.20231004073737-06f1f383fb18 - github.com/livepeer/lpms v0.0.0-20240711034524-d9c78b62effd + github.com/livepeer/lpms v0.0.0-20240711175220-227325841434 github.com/livepeer/m3u8 v0.11.1 github.com/mattn/go-sqlite3 v1.14.18 github.com/oapi-codegen/nethttp-middleware v1.0.1 diff --git a/go.sum b/go.sum index 14590c9ef6..8b7c9c40c3 100644 --- a/go.sum +++ b/go.sum @@ -625,8 +625,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-20240711175220-227325841434 h1:E7PKN6q/jMLapEV+eEwlwv87Xe5zacaVhvZ8T6AJR3c= +github.com/livepeer/lpms v0.0.0-20240711175220-227325841434/go.mod h1:Hr/JhxxPDipOVd4ZrGYWrdJfpVF8/SEI0nNr2ctAlkM= github.com/livepeer/m3u8 v0.11.1 h1:VkUJzfNTyjy9mqsgp5JPvouwna8wGZMvd/gAfT5FinU= github.com/livepeer/m3u8 v0.11.1/go.mod h1:IUqAtwWPAG2CblfQa4SVzTQoDcEMPyfNOaBSxqHMS04= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= @@ -1386,7 +1386,6 @@ google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= From 59a2fd331e46b8f723bf70971de706f10a67d37d Mon Sep 17 00:00:00 2001 From: kyriediculous Date: Tue, 30 Jul 2024 16:21:19 +0200 Subject: [PATCH 84/88] change lpms version --- go.mod | 2 +- go.sum | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index a5163a9f55..361cc8befb 100644 --- a/go.mod +++ b/go.mod @@ -16,7 +16,7 @@ require ( github.com/livepeer/ai-worker v0.1.0 github.com/livepeer/go-tools v0.3.6-0.20240130205227-92479de8531b github.com/livepeer/livepeer-data v0.7.5-0.20231004073737-06f1f383fb18 - github.com/livepeer/lpms v0.0.0-20240711175220-227325841434 + github.com/livepeer/lpms v0.0.0-20240711034524-d9c78b62effd github.com/livepeer/m3u8 v0.11.1 github.com/mattn/go-sqlite3 v1.14.18 github.com/oapi-codegen/nethttp-middleware v1.0.1 diff --git a/go.sum b/go.sum index 8b7c9c40c3..14590c9ef6 100644 --- a/go.sum +++ b/go.sum @@ -625,8 +625,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-20240711175220-227325841434 h1:E7PKN6q/jMLapEV+eEwlwv87Xe5zacaVhvZ8T6AJR3c= -github.com/livepeer/lpms v0.0.0-20240711175220-227325841434/go.mod h1:Hr/JhxxPDipOVd4ZrGYWrdJfpVF8/SEI0nNr2ctAlkM= +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/m3u8 v0.11.1 h1:VkUJzfNTyjy9mqsgp5JPvouwna8wGZMvd/gAfT5FinU= github.com/livepeer/m3u8 v0.11.1/go.mod h1:IUqAtwWPAG2CblfQa4SVzTQoDcEMPyfNOaBSxqHMS04= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= @@ -1386,6 +1386,7 @@ google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= From ffc8ca030430cad9f21e82b0eee0f16326fa6b80 Mon Sep 17 00:00:00 2001 From: kyriediculous Date: Tue, 30 Jul 2024 20:29:19 +0200 Subject: [PATCH 85/88] core: remote ai worker manager tests --- core/ai.go | 2 +- core/ai_test.go | 393 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 394 insertions(+), 1 deletion(-) create mode 100644 core/ai_test.go diff --git a/core/ai.go b/core/ai.go index 94562c4133..e0bf619f69 100644 --- a/core/ai.go +++ b/core/ai.go @@ -369,7 +369,7 @@ type RemoteAIWorker struct { manager *RemoteAIWorkerManager stream net.Transcoder_RegisterAIWorkerServer addr string - capabilities *Capabilities // TODO: AI capabilities only + capabilities *Capabilities eof chan struct{} } diff --git a/core/ai_test.go b/core/ai_test.go new file mode 100644 index 0000000000..fe34ad2654 --- /dev/null +++ b/core/ai_test.go @@ -0,0 +1,393 @@ +package core + +import ( + "context" + "testing" + "time" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + aiworker "github.com/livepeer/ai-worker/worker" + "github.com/livepeer/go-livepeer/net" + openapi_types "github.com/oapi-codegen/runtime/types" +) + +// Mock interfaces +type mockStream struct { + net.Transcoder_RegisterAIWorkerServer + sendFunc func(*net.NotifyAIJob) error + ctx context.Context +} + +func (m *mockStream) Send(job *net.NotifyAIJob) error { + return m.sendFunc(job) +} + +func (m *mockStream) Context() context.Context { + if m.ctx == nil { + return context.Background() + } + return m.ctx +} + +func TestNewRemoteAIWorkerManager(t *testing.T) { + manager := NewRemoteAIWorkerManager() + require.NotNil(t, manager, "Expected non-nil manager") + assert.Empty(t, manager.remoteWorkers, "Expected empty remoteWorkers") + assert.Empty(t, manager.liveWorkers, "Expected empty liveWorkers") + assert.Empty(t, manager.taskChans, "Expected empty taskChans") + assert.Zero(t, manager.taskCount, "Expected taskCount to be 0") +} + +func TestManage(t *testing.T) { + manager := NewRemoteAIWorkerManager() + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + stream := &mockStream{ + ctx: ctx, + sendFunc: func(*net.NotifyAIJob) error { + return nil + }, + } + capabilities := &Capabilities{ + capabilityConstraints: CapabilityConstraints{ + Capability_TextToImage: &PerCapabilityConstraints{ + Models: ModelConstraints{ + "model1": &ModelConstraint{}, + }, + }, + }, + } + + manageDone := make(chan struct{}) + go func() { + manager.Manage(stream, capabilities.ToNetCapabilities()) + close(manageDone) + }() + + time.Sleep(100 * time.Millisecond) // Give some time for goroutine to execute + + assert.Len(t, manager.liveWorkers, 1, "Expected 1 live worker") + assert.Len(t, manager.remoteWorkers[Capability_TextToImage], 1, "Expected 1 remote worker for TextToImage") + assert.Len(t, manager.remoteWorkers[Capability_TextToImage]["model1"], 1, "Expected 1 remote worker for model1") + + // Simulate stream closing + cancel() + + select { + case <-manageDone: + // Manage function has finished + case <-time.After(5 * time.Second): + t.Fatal("Manage function did not finish within the expected time") + } + + assert.Empty(t, manager.liveWorkers, "Expected 0 live workers after closing") + assert.Empty(t, manager.remoteWorkers[Capability_TextToImage]["model1"], "Expected 0 remote workers after closing") +} + +func TestProcessAIRequest(t *testing.T) { + manager := NewRemoteAIWorkerManager() + stream := &mockStream{} + worker := NewRemoteAIWorker(manager, stream, "test-addr", nil) + + manager.remoteWorkers[Capability_TextToImage] = map[string][]*RemoteAIWorker{ + "model1": {worker}, + } + + req := aiworker.TextToImageParams{ + ModelId: stringPtr("model1"), + Prompt: "test prompt", + } + + stream.sendFunc = func(job *net.NotifyAIJob) error { + go func() { + manager.aiResult(&RemoteAIWorkerResult{ + JobType: job.Type, + TaskID: job.TaskID, + Bytes: []byte(`{"images": [{"url": "test-image"}]}`), + }) + }() + return nil + } + + res, err := manager.processAIRequest(context.Background(), Capability_TextToImage, req, net.AIRequestType_TextToImage) + + if err != nil { + t.Fatalf("Unexpected error: %v", err) + } + + imgRes, ok := res.(*aiworker.ImageResponse) + if !ok { + t.Fatalf("Expected *ImageResponse, got %T", res) + } + + if len(imgRes.Images) != 1 || imgRes.Images[0].Url != "test-image" { + t.Errorf("Unexpected response: %+v", imgRes) + } +} + +func TestSelectWorker(t *testing.T) { + manager := NewRemoteAIWorkerManager() + worker1 := NewRemoteAIWorker(manager, nil, "addr1", nil) + worker2 := NewRemoteAIWorker(manager, nil, "addr2", nil) + + manager.remoteWorkers[Capability_TextToImage] = map[string][]*RemoteAIWorker{ + "model1": {worker1, worker2}, + } + + // First selection + selected, err := manager.selectWorker(Capability_TextToImage, "model1") + if err != nil { + t.Fatalf("Unexpected error: %v", err) + } + if selected.addr != "addr1" { + t.Errorf("Expected addr1, got %s", selected.addr) + } + + // Second selection (should rotate) + selected, err = manager.selectWorker(Capability_TextToImage, "model1") + if err != nil { + t.Fatalf("Unexpected error: %v", err) + } + if selected.addr != "addr2" { + t.Errorf("Expected addr2, got %s", selected.addr) + } + + // Third selection (should rotate back to first) + selected, err = manager.selectWorker(Capability_TextToImage, "model1") + if err != nil { + t.Fatalf("Unexpected error: %v", err) + } + if selected.addr != "addr1" { + t.Errorf("Expected addr1, got %s", selected.addr) + } +} + +func TestHasCapacity(t *testing.T) { + manager := NewRemoteAIWorkerManager() + worker := NewRemoteAIWorker(manager, nil, "test-addr", nil) + + manager.remoteWorkers[Capability_TextToImage] = map[string][]*RemoteAIWorker{ + "model1": {worker}, + } + + if !manager.HasCapacity("text-to-image", "model1") { + t.Error("Expected HasCapacity to return true for text-to-image model1") + } + if manager.HasCapacity("text-to-image", "model2") { + t.Error("Expected HasCapacity to return false for text-to-image model2") + } + if manager.HasCapacity("image-to-image", "model1") { + t.Error("Expected HasCapacity to return false for image-to-image model1") + } +} + +func TestAddRemoveTaskChan(t *testing.T) { + manager := NewRemoteAIWorkerManager() + + taskID, taskChan := manager.addTaskChan() + if taskID != 0 { + t.Errorf("Expected taskID 0, got %d", taskID) + } + if taskChan == nil { + t.Error("Expected non-nil taskChan") + } + + retrievedChan, err := manager.getTaskChan(taskID) + if err != nil { + t.Fatalf("Unexpected error: %v", err) + } + if taskChan != retrievedChan { + t.Error("Retrieved channel does not match added channel") + } + + manager.removeTaskChan(taskID) + + _, err = manager.getTaskChan(taskID) + if err == nil { + t.Error("Expected error after removing task channel, got nil") + } +} + +func TestTextToImage(t *testing.T) { + manager := NewRemoteAIWorkerManager() + stream := &mockStream{} + worker := NewRemoteAIWorker(manager, stream, "test-addr", nil) + + manager.remoteWorkers[Capability_TextToImage] = map[string][]*RemoteAIWorker{ + "model1": {worker}, + } + + stream.sendFunc = func(job *net.NotifyAIJob) error { + go func() { + manager.aiResult(&RemoteAIWorkerResult{ + JobType: job.Type, + TaskID: job.TaskID, + Bytes: []byte(`{"images": [{"url": "test-image-url"}]}`), + }) + }() + return nil + } + + req := aiworker.TextToImageJSONRequestBody{ + ModelId: stringPtr("model1"), + Prompt: "test prompt", + } + + res, err := manager.TextToImage(context.Background(), req) + + require.NoError(t, err) + require.NotNil(t, res) + assert.Len(t, res.Images, 1) + assert.Equal(t, "test-image-url", res.Images[0].Url) +} + +func TestImageToImage(t *testing.T) { + manager := NewRemoteAIWorkerManager() + stream := &mockStream{} + worker := NewRemoteAIWorker(manager, stream, "test-addr", nil) + + manager.remoteWorkers[Capability_ImageToImage] = map[string][]*RemoteAIWorker{ + "model1": {worker}, + } + + stream.sendFunc = func(job *net.NotifyAIJob) error { + go func() { + manager.aiResult(&RemoteAIWorkerResult{ + JobType: job.Type, + TaskID: job.TaskID, + Bytes: []byte(`{"images": [{"url": "transformed-image-url"}]}`), + }) + }() + return nil + } + file := &openapi_types.File{} + file.InitFromBytes([]byte("fake image data"), "test-image.jpg") + req := aiworker.ImageToImageMultipartRequestBody{ + ModelId: stringPtr("model1"), + Image: *file, + Prompt: "transform this image", + } + + res, err := manager.ImageToImage(context.Background(), req) + + require.NoError(t, err) + require.NotNil(t, res) + assert.Len(t, res.Images, 1) + assert.Equal(t, "transformed-image-url", res.Images[0].Url) +} + +func TestAudioToText(t *testing.T) { + manager := NewRemoteAIWorkerManager() + stream := &mockStream{} + worker := NewRemoteAIWorker(manager, stream, "test-addr", nil) + + manager.remoteWorkers[Capability_AudioToText] = map[string][]*RemoteAIWorker{ + "model1": {worker}, + } + + stream.sendFunc = func(job *net.NotifyAIJob) error { + go func() { + manager.aiResult(&RemoteAIWorkerResult{ + JobType: job.Type, + TaskID: job.TaskID, + Bytes: []byte(`{"text": "transcribed text"}`), + }) + }() + return nil + } + + file := &openapi_types.File{} + file.InitFromBytes([]byte("fake audio data"), "test-audio.wav") + req := aiworker.AudioToTextMultipartRequestBody{ + ModelId: stringPtr("model1"), + Audio: *file, + } + + res, err := manager.AudioToText(context.Background(), req) + + require.NoError(t, err) + require.NotNil(t, res) + assert.Equal(t, "transcribed text", res.Text) +} + +func TestImageToVideo(t *testing.T) { + manager := NewRemoteAIWorkerManager() + stream := &mockStream{} + worker := NewRemoteAIWorker(manager, stream, "test-addr", nil) + + manager.remoteWorkers[Capability_ImageToVideo] = map[string][]*RemoteAIWorker{ + "model1": {worker}, + } + + stream.sendFunc = func(job *net.NotifyAIJob) error { + go func() { + manager.aiResult(&RemoteAIWorkerResult{ + JobType: job.Type, + TaskID: job.TaskID, + Bytes: []byte(`{"frames": [[{"url": "generated-video-url"}]]}`), + }) + }() + return nil + } + + file := &openapi_types.File{} + file.InitFromBytes([]byte("fake image data"), "test-image.jpg") + req := aiworker.ImageToVideoMultipartRequestBody{ + ModelId: stringPtr("model1"), + Image: *file, + } + + res, err := manager.ImageToVideo(context.Background(), req) + + require.NoError(t, err) + require.NotNil(t, res) + assert.Len(t, res.Frames, 1) + assert.Equal(t, "generated-video-url", res.Frames[0][0].Url) +} + +func TestUpscale(t *testing.T) { + manager := NewRemoteAIWorkerManager() + stream := &mockStream{} + worker := NewRemoteAIWorker(manager, stream, "test-addr", nil) + + manager.remoteWorkers[Capability_Upscale] = map[string][]*RemoteAIWorker{ + "model1": {worker}, + } + + stream.sendFunc = func(job *net.NotifyAIJob) error { + go func() { + manager.aiResult(&RemoteAIWorkerResult{ + JobType: job.Type, + TaskID: job.TaskID, + Bytes: []byte(`{"images": [{"url": "upscaled-image-url"}]}`), + }) + }() + return nil + } + + file := &openapi_types.File{} + file.InitFromBytes([]byte("fake image data"), "test-image.jpg") + req := aiworker.UpscaleMultipartRequestBody{ + ModelId: stringPtr("model1"), + Image: *file, + Prompt: "upscale 2x", + } + + res, err := manager.Upscale(context.Background(), req) + + require.NoError(t, err) + require.NotNil(t, res) + assert.Len(t, res.Images, 1) + assert.Equal(t, "upscaled-image-url", res.Images[0].Url) +} + +func intPtr(i int) *int { + return &i +} + +func stringPtr(s string) *string { + return &s +} From 8b1e4ee53d91ffccb745e3e2685c1e7a030e90c4 Mon Sep 17 00:00:00 2001 From: kyriediculous Date: Tue, 30 Jul 2024 20:29:25 +0200 Subject: [PATCH 86/88] udpate ffmpeg --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 361cc8befb..224eda0805 100644 --- a/go.mod +++ b/go.mod @@ -16,7 +16,7 @@ require ( github.com/livepeer/ai-worker v0.1.0 github.com/livepeer/go-tools v0.3.6-0.20240130205227-92479de8531b github.com/livepeer/livepeer-data v0.7.5-0.20231004073737-06f1f383fb18 - github.com/livepeer/lpms v0.0.0-20240711034524-d9c78b62effd + github.com/livepeer/lpms v0.0.0-20240726132931-5b7b9f5e831f github.com/livepeer/m3u8 v0.11.1 github.com/mattn/go-sqlite3 v1.14.18 github.com/oapi-codegen/nethttp-middleware v1.0.1 diff --git a/go.sum b/go.sum index 14590c9ef6..3963c2aff6 100644 --- a/go.sum +++ b/go.sum @@ -625,8 +625,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-20240726132931-5b7b9f5e831f h1:zAlqPgRkSo6zubbZS2SpOpO4oPGprr3zoabVK6tANMg= +github.com/livepeer/lpms v0.0.0-20240726132931-5b7b9f5e831f/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/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= From ff3fa3b91964a325e401c2acf395653abbc9f321 Mon Sep 17 00:00:00 2001 From: kyriediculous Date: Tue, 30 Jul 2024 20:49:58 +0200 Subject: [PATCH 87/88] aiResults route tests --- server/ot_rpc_test.go | 100 ++++++++++++++++++++++++++++++++++++++++ server/rpc_test.go | 104 ++++++++++++++++++++++++++++++++++++------ 2 files changed, 191 insertions(+), 13 deletions(-) diff --git a/server/ot_rpc_test.go b/server/ot_rpc_test.go index 241a954d37..ac4924cbad 100644 --- a/server/ot_rpc_test.go +++ b/server/ot_rpc_test.go @@ -4,6 +4,7 @@ import ( "bytes" "context" "crypto/tls" + "encoding/json" "errors" "fmt" "io" @@ -375,3 +376,102 @@ func TestRemoteTranscoder_Error(t *testing.T) { assert.Equal("some error", string(body)) assert.True(panicked) } + +func TestAIWorkerResults_ErrorsWhenAuthHeaderMissing(t *testing.T) { + var l lphttp + var w = httptest.NewRecorder() + + r, err := http.NewRequest(http.MethodPost, "/aiResults", nil) + require.NoError(t, err) + + l.AIWorkerResults(w, r) + require.Equal(t, http.StatusUnauthorized, w.Code) + require.Contains(t, w.Body.String(), "Unauthorized") +} + +func TestAIWorkerResults_ErrorsWhenCredentialsInvalid(t *testing.T) { + var l lphttp + l.orchestrator = newStubOrchestrator() + l.orchestrator.TranscoderSecret() + var w = httptest.NewRecorder() + + r, err := http.NewRequest(http.MethodPost, "/aiResults", nil) + require.NoError(t, err) + + r.Header.Set("Authorization", protoVerLPT) + r.Header.Set("Credentials", "BAD CREDENTIALS") + + l.AIWorkerResults(w, r) + require.Equal(t, http.StatusUnauthorized, w.Code) + require.Contains(t, w.Body.String(), "Unauthorized") +} + +func TestAIWorkerResults_ErrorsWhenBodyInvalid(t *testing.T) { + var l lphttp + l.orchestrator = newStubOrchestrator() + l.orchestrator.TranscoderSecret() + var w = httptest.NewRecorder() + + r, err := http.NewRequest(http.MethodPost, "/aiResults", bytes.NewBufferString("invalid json")) + require.NoError(t, err) + + r.Header.Set("Authorization", protoVerLPT) + r.Header.Set("Credentials", "") + r.Header.Set("Content-Type", "application/json") + + l.AIWorkerResults(w, r) + require.Equal(t, http.StatusBadRequest, w.Code) + require.Contains(t, w.Body.String(), "invalid character") +} + +func TestAIWorkerResults_ErrorsWhenAIResultHasError(t *testing.T) { + var l lphttp + l.orchestrator = newStubOrchestrator() + l.orchestrator.TranscoderSecret() + var w = httptest.NewRecorder() + + result := core.RemoteAIWorkerResult{ + Err: "AI processing error", + } + body, err := json.Marshal(result) + require.NoError(t, err) + + r, err := http.NewRequest(http.MethodPost, "/aiResults", bytes.NewBuffer(body)) + require.NoError(t, err) + + r.Header.Set("Authorization", protoVerLPT) + r.Header.Set("Credentials", "") + r.Header.Set("Content-Type", "application/json") + + l.AIWorkerResults(w, r) + require.Equal(t, http.StatusInternalServerError, w.Code) + require.Contains(t, w.Body.String(), "AI processing error") +} + +func TestAIWorkerResults_SuccessfulProcessing(t *testing.T) { + var l lphttp + mockOrch := newStubOrchestrator() + l.orchestrator = mockOrch + var w = httptest.NewRecorder() + + result := core.RemoteAIWorkerResult{ + JobType: 1, + TaskID: 123, + Bytes: []byte("AI result data"), + } + body, err := json.Marshal(result) + require.NoError(t, err) + + r, err := http.NewRequest(http.MethodPost, "/aiResults", bytes.NewBuffer(body)) + require.NoError(t, err) + + r.Header.Set("Authorization", protoVerLPT) + r.Header.Set("Credentials", "") + r.Header.Set("Content-Type", "application/json") + + l.AIWorkerResults(w, r) + require.Equal(t, http.StatusOK, w.Code) + assert.Equal(t, result.TaskID, mockOrch.lastAIResultPost.TaskID) + assert.Equal(t, result.JobType, mockOrch.lastAIResultPost.JobType) + assert.Equal(t, result.Bytes, mockOrch.lastAIResultPost.Bytes) +} diff --git a/server/rpc_test.go b/server/rpc_test.go index c0832a0c46..5594752363 100644 --- a/server/rpc_test.go +++ b/server/rpc_test.go @@ -25,6 +25,7 @@ import ( "github.com/golang/protobuf/proto" + "github.com/livepeer/ai-worker/worker" "github.com/livepeer/go-livepeer/common" "github.com/livepeer/go-livepeer/core" "github.com/livepeer/go-livepeer/crypto" @@ -64,17 +65,28 @@ func (m *mockBalance) Clear() { } type stubOrchestrator struct { - priv *ecdsa.PrivateKey - block *big.Int - signErr error - sessCapErr error - ticketParams *net.TicketParams - priceInfo *net.PriceInfo - serviceURI string - res *core.TranscodeResult - offchain bool - caps *core.Capabilities - authToken *net.AuthToken + priv *ecdsa.PrivateKey + block *big.Int + signErr error + sessCapErr error + ticketParams *net.TicketParams + priceInfo *net.PriceInfo + serviceURI string + res *core.TranscodeResult + offchain bool + caps *core.Capabilities + authToken *net.AuthToken + lastAIResultPost *core.RemoteAIWorkerResult +} + +// PriceInfoForCaps implements Orchestrator. +func (r *stubOrchestrator) PriceInfoForCaps(sender ethcommon.Address, manifestID core.ManifestID, caps *net.Capabilities) (*net.PriceInfo, error) { + panic("unimplemented") +} + +// ServeRemoteAIWorker implements Orchestrator. +func (r *stubOrchestrator) ServeRemoteAIWorker(stream net.Transcoder_RegisterAIWorkerServer, capabilities *net.Capabilities) { + panic("unimplemented") } func (r *stubOrchestrator) ServiceURI() *url.URL { @@ -183,6 +195,35 @@ func (r *stubOrchestrator) TranscoderResults(job int64, res *core.RemoteTranscod func (r *stubOrchestrator) TranscoderSecret() string { return "" } + +func (orch *stubOrchestrator) AIResult(res *core.RemoteAIWorkerResult) { + orch.lastAIResultPost = res +} + +func (orch *stubOrchestrator) CheckAICapacity(pipeline, modelID string) bool { + return false +} + +func (orch *stubOrchestrator) TextToImage(ctx context.Context, req worker.TextToImageJSONRequestBody) (*worker.ImageResponse, error) { + return nil, nil +} + +func (orch *stubOrchestrator) ImageToImage(ctx context.Context, req worker.ImageToImageMultipartRequestBody) (*worker.ImageResponse, error) { + return nil, nil +} + +func (orch *stubOrchestrator) ImageToVideo(ctx context.Context, req worker.ImageToVideoMultipartRequestBody) (*worker.ImageResponse, error) { + return nil, nil +} + +func (orch *stubOrchestrator) Upscale(ctx context.Context, req worker.UpscaleMultipartRequestBody) (*worker.ImageResponse, error) { + return nil, nil +} + +func (orch *stubOrchestrator) AudioToText(ctx context.Context, req worker.AudioToTextMultipartRequestBody) (*worker.TextResponse, error) { + return nil, nil +} + func stubBroadcaster2() *stubOrchestrator { return newStubOrchestrator() // lazy; leverage subtyping for interface commonalities } @@ -192,7 +233,7 @@ func TestRPCTranscoderReq(t *testing.T) { o := newStubOrchestrator() b := stubBroadcaster2() - req, err := genOrchestratorReq(b) + req, err := genOrchestratorReq(b, &net.Capabilities{}) if err != nil { t.Error("Unable to create orchestrator req ", req) } @@ -224,7 +265,7 @@ func TestRPCTranscoderReq(t *testing.T) { // error signing b.signErr = fmt.Errorf("Signing error") - _, err = genOrchestratorReq(b) + _, err = genOrchestratorReq(b, &net.Capabilities{}) if err == nil { t.Error("Did not expect to generate a orchestrator request with invalid address") } @@ -1258,6 +1299,16 @@ type mockOrchestrator struct { mock.Mock } +// PriceInfoForCaps implements Orchestrator. +func (o *mockOrchestrator) PriceInfoForCaps(sender ethcommon.Address, manifestID core.ManifestID, caps *net.Capabilities) (*net.PriceInfo, error) { + panic("unimplemented") +} + +// ServeRemoteAIWorker implements Orchestrator. +func (o *mockOrchestrator) ServeRemoteAIWorker(stream net.Transcoder_RegisterAIWorkerServer, capabilities *net.Capabilities) { + panic("unimplemented") +} + func (o *mockOrchestrator) ServiceURI() *url.URL { args := o.Called() if args.Get(0) != nil { @@ -1346,6 +1397,33 @@ func (o *mockOrchestrator) AuthToken(sessionID string, expiration int64) *net.Au return nil } +func (orch *mockOrchestrator) AIResult(res *core.RemoteAIWorkerResult) { +} + +func (orch *mockOrchestrator) TextToImage(ctx context.Context, req worker.TextToImageJSONRequestBody) (*worker.ImageResponse, error) { + return nil, nil +} + +func (orch *mockOrchestrator) ImageToImage(ctx context.Context, req worker.ImageToImageMultipartRequestBody) (*worker.ImageResponse, error) { + return nil, nil +} + +func (orch *mockOrchestrator) ImageToVideo(ctx context.Context, req worker.ImageToVideoMultipartRequestBody) (*worker.ImageResponse, error) { + return nil, nil +} + +func (orch *mockOrchestrator) Upscale(ctx context.Context, req worker.UpscaleMultipartRequestBody) (*worker.ImageResponse, error) { + return nil, nil +} + +func (orch *mockOrchestrator) AudioToText(ctx context.Context, req worker.AudioToTextMultipartRequestBody) (*worker.TextResponse, error) { + return nil, nil +} + +func (orch *mockOrchestrator) CheckAICapacity(pipeline, modelID string) bool { + return false +} + func defaultTicketParams() *net.TicketParams { return &net.TicketParams{ Recipient: pm.RandBytes(123), From 8c07ba9bf7c03f7f32899c363da576b4be1b2ef3 Mon Sep 17 00:00:00 2001 From: kyriediculous Date: Tue, 30 Jul 2024 21:34:30 +0200 Subject: [PATCH 88/88] core: improve remote ai worker tests --- core/ai_test.go | 101 ++++++++++++++++++++++-------------------------- 1 file changed, 47 insertions(+), 54 deletions(-) diff --git a/core/ai_test.go b/core/ai_test.go index fe34ad2654..31a851cf12 100644 --- a/core/ai_test.go +++ b/core/ai_test.go @@ -114,55 +114,64 @@ func TestProcessAIRequest(t *testing.T) { res, err := manager.processAIRequest(context.Background(), Capability_TextToImage, req, net.AIRequestType_TextToImage) - if err != nil { - t.Fatalf("Unexpected error: %v", err) - } + require.NoError(t, err, "Unexpected error") imgRes, ok := res.(*aiworker.ImageResponse) - if !ok { - t.Fatalf("Expected *ImageResponse, got %T", res) - } + require.True(t, ok, "Expected *ImageResponse") - if len(imgRes.Images) != 1 || imgRes.Images[0].Url != "test-image" { - t.Errorf("Unexpected response: %+v", imgRes) - } + assert.Len(t, imgRes.Images, 1, "Expected 1 image in response") + assert.Equal(t, "test-image", imgRes.Images[0].Url, "Unexpected image URL") } func TestSelectWorker(t *testing.T) { manager := NewRemoteAIWorkerManager() - worker1 := NewRemoteAIWorker(manager, nil, "addr1", nil) - worker2 := NewRemoteAIWorker(manager, nil, "addr2", nil) + cap1 := &Capabilities{ + capabilityConstraints: CapabilityConstraints{ + Capability_TextToImage: &PerCapabilityConstraints{ + Models: ModelConstraints{ + "model1": &ModelConstraint{}, + }, + }, + }, + } + cap2 := &Capabilities{ + capabilityConstraints: CapabilityConstraints{ + Capability_TextToImage: &PerCapabilityConstraints{ + Models: ModelConstraints{ + "model2": &ModelConstraint{}, + }, + }, + }, + } + + worker1 := NewRemoteAIWorker(manager, nil, "addr1", cap1) + worker2 := NewRemoteAIWorker(manager, nil, "addr2", cap2) + worker3 := NewRemoteAIWorker(manager, nil, "addr3", cap1) manager.remoteWorkers[Capability_TextToImage] = map[string][]*RemoteAIWorker{ - "model1": {worker1, worker2}, + "model1": {worker1, worker3}, + "model2": {worker2}, } // First selection selected, err := manager.selectWorker(Capability_TextToImage, "model1") - if err != nil { - t.Fatalf("Unexpected error: %v", err) - } - if selected.addr != "addr1" { - t.Errorf("Expected addr1, got %s", selected.addr) - } + require.NoError(t, err, "Unexpected error") + assert.Equal(t, "addr1", selected.addr, "Expected addr1") // Second selection (should rotate) selected, err = manager.selectWorker(Capability_TextToImage, "model1") - if err != nil { - t.Fatalf("Unexpected error: %v", err) - } - if selected.addr != "addr2" { - t.Errorf("Expected addr2, got %s", selected.addr) - } + require.NoError(t, err, "Unexpected error") + assert.Equal(t, "addr3", selected.addr, "Expected addr3") // Third selection (should rotate back to first) selected, err = manager.selectWorker(Capability_TextToImage, "model1") - if err != nil { - t.Fatalf("Unexpected error: %v", err) - } - if selected.addr != "addr1" { - t.Errorf("Expected addr1, got %s", selected.addr) - } + require.NoError(t, err, "Unexpected error") + assert.Equal(t, "addr1", selected.addr, "Expected addr1") + + // model2 + selected, err = manager.selectWorker(Capability_TextToImage, "model2") + require.NoError(t, err, "Unexpected error") + assert.Equal(t, "addr2", selected.addr, "Expected addr2") } func TestHasCapacity(t *testing.T) { @@ -173,42 +182,26 @@ func TestHasCapacity(t *testing.T) { "model1": {worker}, } - if !manager.HasCapacity("text-to-image", "model1") { - t.Error("Expected HasCapacity to return true for text-to-image model1") - } - if manager.HasCapacity("text-to-image", "model2") { - t.Error("Expected HasCapacity to return false for text-to-image model2") - } - if manager.HasCapacity("image-to-image", "model1") { - t.Error("Expected HasCapacity to return false for image-to-image model1") - } + assert.True(t, manager.HasCapacity("text-to-image", "model1"), "Expected HasCapacity to return true for text-to-image model1") + assert.False(t, manager.HasCapacity("text-to-image", "model2"), "Expected HasCapacity to return false for text-to-image model2") + assert.False(t, manager.HasCapacity("image-to-image", "model1"), "Expected HasCapacity to return false for image-to-image model1") } func TestAddRemoveTaskChan(t *testing.T) { manager := NewRemoteAIWorkerManager() taskID, taskChan := manager.addTaskChan() - if taskID != 0 { - t.Errorf("Expected taskID 0, got %d", taskID) - } - if taskChan == nil { - t.Error("Expected non-nil taskChan") - } + assert.Equal(t, int64(0), taskID, "Expected taskID 0") + assert.NotNil(t, taskChan, "Expected non-nil taskChan") retrievedChan, err := manager.getTaskChan(taskID) - if err != nil { - t.Fatalf("Unexpected error: %v", err) - } - if taskChan != retrievedChan { - t.Error("Retrieved channel does not match added channel") - } + require.NoError(t, err, "Unexpected error") + assert.Equal(t, taskChan, retrievedChan, "Retrieved channel does not match added channel") manager.removeTaskChan(taskID) _, err = manager.getTaskChan(taskID) - if err == nil { - t.Error("Expected error after removing task channel, got nil") - } + assert.Error(t, err, "Expected error after removing task channel") } func TestTextToImage(t *testing.T) {