From 2e55134d846a5a42bb60c45ef96418c8f7316972 Mon Sep 17 00:00:00 2001 From: Max Holland Date: Mon, 2 Sep 2024 16:44:43 +0100 Subject: [PATCH 01/21] Add a metric tag for Orchestrator version (#3158) --- monitor/census.go | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/monitor/census.go b/monitor/census.go index f6ee869231..f9dae6babb 100644 --- a/monitor/census.go +++ b/monitor/census.go @@ -112,6 +112,7 @@ type ( kClientIP tag.Key kOrchestratorURI tag.Key kOrchestratorAddress tag.Key + kOrchestratorVersion tag.Key kFVErrorType tag.Key mSegmentSourceAppeared *stats.Int64Measure mSegmentEmerged *stats.Int64Measure @@ -252,6 +253,7 @@ func InitCensus(nodeType NodeType, version string) { census.kClientIP = tag.MustNewKey("client_ip") census.kOrchestratorURI = tag.MustNewKey("orchestrator_uri") census.kOrchestratorAddress = tag.MustNewKey("orchestrator_address") + census.kOrchestratorVersion = tag.MustNewKey("orchestrator_version") census.kFVErrorType = tag.MustNewKey("fverror_type") census.kSegClassName = tag.MustNewKey("seg_class_name") census.ctx, err = tag.New(ctx, tag.Insert(census.kNodeType, string(nodeType)), tag.Insert(census.kNodeID, NodeID)) @@ -369,8 +371,8 @@ func InitCensus(nodeType NodeType, version string) { baseTagsWithManifestIDAndIP = append([]tag.Key{census.kClientIP}, baseTagsWithManifestID...) } baseTagsWithManifestIDAndOrchInfo := baseTagsWithManifestID - baseTagsWithOrchInfo = append([]tag.Key{census.kOrchestratorURI, census.kOrchestratorAddress}, baseTags...) - baseTagsWithManifestIDAndOrchInfo = append([]tag.Key{census.kOrchestratorURI, census.kOrchestratorAddress}, baseTagsWithManifestID...) + baseTagsWithOrchInfo = append([]tag.Key{census.kOrchestratorURI, census.kOrchestratorAddress, census.kOrchestratorVersion}, baseTags...) + baseTagsWithManifestIDAndOrchInfo = append([]tag.Key{census.kOrchestratorURI, census.kOrchestratorAddress, census.kOrchestratorVersion}, baseTagsWithManifestID...) views := []*view.View{ { @@ -914,6 +916,10 @@ func manifestIDTagAndOrchInfo(orchInfo *lpnet.OrchestratorInfo, ctx context.Cont tag.Insert(census.kOrchestratorURI, orchInfo.GetTranscoder()), tag.Insert(census.kOrchestratorAddress, common.BytesToAddress(orchInfo.GetAddress()).String()), ) + capabilities := orchInfo.GetCapabilities() + if capabilities != nil { + others = append(others, tag.Insert(census.kOrchestratorVersion, capabilities.Version)) + } return others } From 3316e352c8f537c5d7b374e8ea5e00ded6fe853b Mon Sep 17 00:00:00 2001 From: PSchroedl Date: Wed, 4 Sep 2024 03:28:02 -0700 Subject: [PATCH 02/21] feat(ai): add segment anything 2 pipeline image version(#3131) This commit adds support for the new [segment anything 2](https://ai.meta.com/sam2/) pipeline (SAM2) that was added to the AI-worker in [this pull request](https://github.com/livepeer/ai-worker/pull/185). While the new SAM pipeline can also do video segmentation this will be done in a subsequent pull request. Co-authored-by: John | Elite Encoder Co-authored-by: Peter Schroedl Co-authored-by: Rick Staa --- cmd/livepeer/starter/starter.go | 19 +++++- core/ai.go | 1 + core/capabilities.go | 3 + core/orchestrator.go | 8 +++ go.mod | 16 ++--- go.sum | 32 +++++----- server/ai_http.go | 45 +++++++++++++ server/ai_mediaserver.go | 54 ++++++++++++++++ server/ai_process.go | 108 ++++++++++++++++++++++++++++++++ server/rpc.go | 1 + server/rpc_test.go | 6 ++ 11 files changed, 267 insertions(+), 26 deletions(-) diff --git a/cmd/livepeer/starter/starter.go b/cmd/livepeer/starter/starter.go index 5a8bb5bb27..00c23ec3db 100755 --- a/cmd/livepeer/starter/starter.go +++ b/cmd/livepeer/starter/starter.go @@ -1227,10 +1227,11 @@ func StartLivepeer(ctx context.Context, cfg LivepeerConfig) { } } - // 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 != "" { + // Register external container endpoint if URL is provided. endpoint := worker.RunnerEndpoint{URL: config.URL, Token: config.Token} + + // Warm the AI worker container or register the endpoint. if err := n.AIWorker.Warm(ctx, config.Pipeline, config.ModelID, endpoint, config.OptimizationFlags); err != nil { glog.Errorf("Error AI worker warming %v container: %v", config.Pipeline, err) return @@ -1313,6 +1314,20 @@ func StartLivepeer(ctx context.Context, cfg LivepeerConfig) { if *cfg.Network != "offchain" { n.SetBasePriceForCap("default", core.Capability_AudioToText, config.ModelID, autoPrice) } + case "segment-anything-2": + _, ok := capabilityConstraints[core.Capability_SegmentAnything2] + if !ok { + aiCaps = append(aiCaps, core.Capability_SegmentAnything2) + capabilityConstraints[core.Capability_SegmentAnything2] = &core.CapabilityConstraints{ + Models: make(map[string]*core.ModelConstraint), + } + } + + capabilityConstraints[core.Capability_SegmentAnything2].Models[config.ModelID] = modelConstraint + + if *cfg.Network != "offchain" { + n.SetBasePriceForCap("default", core.Capability_SegmentAnything2, config.ModelID, autoPrice) + } } if len(aiCaps) > 0 { diff --git a/core/ai.go b/core/ai.go index e36260fa6b..887e1f8c8c 100644 --- a/core/ai.go +++ b/core/ai.go @@ -22,6 +22,7 @@ type AI interface { ImageToVideo(context.Context, worker.ImageToVideoMultipartRequestBody) (*worker.VideoResponse, error) Upscale(context.Context, worker.UpscaleMultipartRequestBody) (*worker.ImageResponse, error) AudioToText(context.Context, worker.AudioToTextMultipartRequestBody) (*worker.TextResponse, error) + SegmentAnything2(context.Context, worker.SegmentAnything2MultipartRequestBody) (*worker.MasksResponse, error) Warm(context.Context, string, string, worker.RunnerEndpoint, worker.OptimizationFlags) error Stop(context.Context) error HasCapacity(pipeline, modelID string) bool diff --git a/core/capabilities.go b/core/capabilities.go index b02e137801..734404ca83 100644 --- a/core/capabilities.go +++ b/core/capabilities.go @@ -78,6 +78,7 @@ const ( Capability_ImageToVideo Capability_Upscale Capability_AudioToText + Capability_SegmentAnything2 ) var CapabilityNameLookup = map[Capability]string{ @@ -114,6 +115,7 @@ var CapabilityNameLookup = map[Capability]string{ Capability_ImageToVideo: "Image to video", Capability_Upscale: "Upscale", Capability_AudioToText: "Audio to text", + Capability_SegmentAnything2: "Segment Anything 2", } var CapabilityTestLookup = map[Capability]CapabilityTest{ @@ -204,6 +206,7 @@ func OptionalCapabilities() []Capability { Capability_ImageToVideo, Capability_Upscale, Capability_AudioToText, + Capability_SegmentAnything2, } } diff --git a/core/orchestrator.go b/core/orchestrator.go index 51fb2206e4..ba9f470bd1 100644 --- a/core/orchestrator.go +++ b/core/orchestrator.go @@ -130,6 +130,10 @@ func (orch *orchestrator) AudioToText(ctx context.Context, req worker.AudioToTex return orch.node.AudioToText(ctx, req) } +func (orch *orchestrator) SegmentAnything2(ctx context.Context, req worker.SegmentAnything2MultipartRequestBody) (*worker.MasksResponse, error) { + return orch.node.SegmentAnything2(ctx, req) +} + func (orch *orchestrator) ProcessPayment(ctx context.Context, payment net.Payment, manifestID ManifestID) error { if orch.node == nil || orch.node.Recipient == nil { return nil @@ -963,6 +967,10 @@ func (n *LivepeerNode) AudioToText(ctx context.Context, req worker.AudioToTextMu return n.AIWorker.AudioToText(ctx, req) } +func (n *LivepeerNode) SegmentAnything2(ctx context.Context, req worker.SegmentAnything2MultipartRequestBody) (*worker.MasksResponse, error) { + return n.AIWorker.SegmentAnything2(ctx, req) +} + func (n *LivepeerNode) imageToVideo(ctx context.Context, req worker.ImageToVideoMultipartRequestBody) (*worker.ImageResponse, error) { // We might support generating more than one video in the future (i.e. multiple input images/prompts) numVideos := 1 diff --git a/go.mod b/go.mod index bfbe2c4941..b0fd01bd98 100644 --- a/go.mod +++ b/go.mod @@ -13,7 +13,7 @@ require ( github.com/golang/protobuf v1.5.4 github.com/jaypipes/ghw v0.10.0 github.com/jaypipes/pcidb v1.0.0 - github.com/livepeer/ai-worker v0.1.2 + github.com/livepeer/ai-worker v0.2.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-20240819180416-f87352959b85 @@ -31,7 +31,7 @@ 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 + golang.org/x/net v0.28.0 google.golang.org/grpc v1.65.0 google.golang.org/protobuf v1.34.1 pgregory.net/rapid v1.1.0 @@ -215,15 +215,15 @@ require ( 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.26.0 // indirect golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect - golang.org/x/mod v0.17.0 // indirect + golang.org/x/mod v0.20.0 // indirect golang.org/x/oauth2 v0.20.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/sync v0.8.0 // indirect + golang.org/x/sys v0.23.0 // indirect + golang.org/x/text v0.17.0 // indirect golang.org/x/time v0.5.0 // indirect - golang.org/x/tools v0.21.0 // indirect + golang.org/x/tools v0.24.0 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect google.golang.org/api v0.125.0 // indirect google.golang.org/appengine v1.6.7 // indirect diff --git a/go.sum b/go.sum index 6bcdec2fed..3299db083c 100644 --- a/go.sum +++ b/go.sum @@ -623,8 +623,8 @@ github.com/libp2p/go-netroute v0.2.0 h1:0FpsbsvuSnAhXFnCY0VLFbJOzaK0VnP0r1QT/o4n github.com/libp2p/go-netroute v0.2.0/go.mod h1:Vio7LTzZ+6hoT4CMZi5/6CpY3Snzh2vgZhWgxMNwlQI= github.com/libp2p/go-openssl v0.1.0 h1:LBkKEcUv6vtZIQLVTegAil8jbNpJErQ9AnT+bWV+Ooo= github.com/libp2p/go-openssl v0.1.0/go.mod h1:OiOxwPpL3n4xlenjx2h7AwSGaFSC/KZvf6gNdOBQMtc= -github.com/livepeer/ai-worker v0.1.2 h1:I73J4zJYad95QE1JFSrqrjKKCTqLHypDcoPq/zZM5aw= -github.com/livepeer/ai-worker v0.1.2/go.mod h1:Xlnb0nFG2VsGeMG9hZmReVQXeFt0Dv28ODiUT2ooyLE= +github.com/livepeer/ai-worker v0.2.0 h1:u6m3nVQnisqWn2nMhgTgKLQby7VDAEp5xmeHt7Res/Y= +github.com/livepeer/ai-worker v0.2.0/go.mod h1:91lMzkzVuwR9kZ0EzXwf+7yVhLaNVmYAfmBtn7t3cQA= github.com/livepeer/go-tools v0.3.6-0.20240130205227-92479de8531b h1:VQcnrqtCA2UROp7q8ljkh2XA/u0KRgVv0S1xoUvOweE= github.com/livepeer/go-tools v0.3.6-0.20240130205227-92479de8531b/go.mod h1:hwJ5DKhl+pTanFWl+EUpw1H7ukPO/H+MFpgA7jjshzw= github.com/livepeer/joy4 v0.1.2-0.20191121080656-b2fea45cbded h1:ZQlvR5RB4nfT+cOQee+WqmaDOgGtP2oDMhcVvR4L0yA= @@ -1024,8 +1024,8 @@ golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWP 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.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1060,8 +1060,8 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= -golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= +golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1108,8 +1108,8 @@ golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su 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.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= +golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1132,8 +1132,8 @@ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-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= @@ -1210,8 +1210,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.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= +golang.org/x/sys v0.23.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= @@ -1226,8 +1226,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.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= +golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1288,8 +1288,8 @@ 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.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= +golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/server/ai_http.go b/server/ai_http.go index 6b007e0c13..a11164bc9b 100644 --- a/server/ai_http.go +++ b/server/ai_http.go @@ -44,6 +44,7 @@ func startAIServer(lp lphttp) error { lp.transRPC.Handle("/image-to-video", oapiReqValidator(lp.ImageToVideo())) lp.transRPC.Handle("/upscale", oapiReqValidator(lp.Upscale())) lp.transRPC.Handle("/audio-to-text", oapiReqValidator(lp.AudioToText())) + lp.transRPC.Handle("/segment-anything-2", oapiReqValidator(lp.SegmentAnything2())) return nil } @@ -157,6 +158,29 @@ func (h *lphttp) AudioToText() http.Handler { }) } +func (h *lphttp) SegmentAnything2() http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + orch := h.orchestrator + + remoteAddr := getRemoteAddr(r) + ctx := clog.AddVal(r.Context(), clog.ClientIP, remoteAddr) + + multiRdr, err := r.MultipartReader() + if err != nil { + respondWithError(w, err.Error(), http.StatusBadRequest) + return + } + + var req worker.SegmentAnything2MultipartRequestBody + if err := runtime.BindMultipart(&req, *multiRdr); err != nil { + respondWithError(w, err.Error(), http.StatusInternalServerError) + return + } + + handleAIRequest(ctx, w, r, orch, req) + }) +} + func handleAIRequest(ctx context.Context, w http.ResponseWriter, r *http.Request, orch Orchestrator, req interface{}) { payment, err := getPayment(r.Header.Get(paymentHeader)) if err != nil { @@ -281,6 +305,25 @@ func handleAIRequest(ctx context.Context, w http.ResponseWriter, r *http.Request return } outPixels *= 1000 // Convert to milliseconds + case worker.SegmentAnything2MultipartRequestBody: + pipeline = "segment-anything-2" + cap = core.Capability_SegmentAnything2 + modelID = *v.ModelId + submitFn = func(ctx context.Context) (interface{}, error) { + return orch.SegmentAnything2(ctx, v) + } + + imageRdr, err := v.Image.Reader() + if err != nil { + respondWithError(w, err.Error(), http.StatusBadRequest) + return + } + config, _, err := image.DecodeConfig(imageRdr) + if err != nil { + respondWithError(w, err.Error(), http.StatusBadRequest) + return + } + outPixels = int64(config.Height) * int64(config.Width) default: respondWithError(w, "Unknown request type", http.StatusBadRequest) return @@ -352,6 +395,8 @@ func handleAIRequest(ctx context.Context, w http.ResponseWriter, r *http.Request if err == nil { latencyScore = CalculateAudioToTextLatencyScore(took, durationSeconds) } + case worker.SegmentAnything2MultipartRequestBody: + latencyScore = CalculateSegmentAnything2LatencyScore(took, outPixels) } var pricePerAIUnit float64 diff --git a/server/ai_mediaserver.go b/server/ai_mediaserver.go index 29d33b9fed..a600f3b176 100644 --- a/server/ai_mediaserver.go +++ b/server/ai_mediaserver.go @@ -69,6 +69,7 @@ func startAIMediaServer(ls *LivepeerServer) error { ls.HTTPMux.Handle("/image-to-video", oapiReqValidator(ls.ImageToVideo())) ls.HTTPMux.Handle("/image-to-video/result", ls.ImageToVideoResult()) ls.HTTPMux.Handle("/audio-to-text", oapiReqValidator(ls.AudioToText())) + ls.HTTPMux.Handle("/segment-anything-2", oapiReqValidator(ls.SegmentAnything2())) return nil } @@ -374,6 +375,59 @@ func (ls *LivepeerServer) AudioToText() http.Handler { }) } +func (ls *LivepeerServer) SegmentAnything2() http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + remoteAddr := getRemoteAddr(r) + ctx := clog.AddVal(r.Context(), clog.ClientIP, remoteAddr) + requestID := string(core.RandomManifestID()) + ctx = clog.AddVal(ctx, "request_id", requestID) + + multiRdr, err := r.MultipartReader() + if err != nil { + respondJsonError(ctx, w, err, http.StatusBadRequest) + return + } + + var req worker.SegmentAnything2MultipartRequestBody + if err := runtime.BindMultipart(&req, *multiRdr); err != nil { + respondJsonError(ctx, w, err, http.StatusBadRequest) + return + } + + clog.V(common.VERBOSE).Infof(ctx, "Received SegmentAnything2 request; image_size=%v model_id=%v", req.Image.FileSize(), *req.ModelId) + + params := aiRequestParams{ + node: ls.LivepeerNode, + os: drivers.NodeStorage.NewSession(requestID), + sessManager: ls.AISessionManager, + } + + start := time.Now() + resp, err := processSegmentAnything2(ctx, params, req) + if err != nil { + var serviceUnavailableErr *ServiceUnavailableError + var badRequestErr *BadRequestError + if errors.As(err, &serviceUnavailableErr) { + respondJsonError(ctx, w, err, http.StatusServiceUnavailable) + return + } + if errors.As(err, &badRequestErr) { + respondJsonError(ctx, w, err, http.StatusBadRequest) + return + } + respondJsonError(ctx, w, err, http.StatusInternalServerError) + return + } + + took := time.Since(start) + clog.V(common.VERBOSE).Infof(ctx, "Processed SegmentAnything2 request model_id=%v took=%v", *req.ModelId, took) + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + _ = json.NewEncoder(w).Encode(resp) + }) +} + func (ls *LivepeerServer) ImageToVideoResult() http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { remoteAddr := getRemoteAddr(r) diff --git a/server/ai_process.go b/server/ai_process.go index a8e884f68d..d69beb0610 100644 --- a/server/ai_process.go +++ b/server/ai_process.go @@ -31,6 +31,7 @@ const defaultImageToImageModelID = "stabilityai/sdxl-turbo" const defaultImageToVideoModelID = "stabilityai/stable-video-diffusion-img2vid-xt" const defaultUpscaleModelID = "stabilityai/stable-diffusion-x4-upscaler" const defaultAudioToTextModelID = "openai/whisper-large-v3" +const defaultSegmentAnything2ModelID = "facebook/sam2-hiera-large" type ServiceUnavailableError struct { err error @@ -586,6 +587,104 @@ func submitUpscale(ctx context.Context, params aiRequestParams, sess *AISession, return resp.JSON200, nil } +// CalculateSegmentAnything2LatencyScore computes the time taken per pixel for a segment-anything-2 request. +func CalculateSegmentAnything2LatencyScore(took time.Duration, outPixels int64) float64 { + if outPixels <= 0 { + return 0 + } + + return took.Seconds() / float64(outPixels) +} + +func processSegmentAnything2(ctx context.Context, params aiRequestParams, req worker.SegmentAnything2MultipartRequestBody) (*worker.MasksResponse, error) { + resp, err := processAIRequest(ctx, params, req) + if err != nil { + return nil, err + } + + txtResp := resp.(*worker.MasksResponse) + + return txtResp, nil +} + +func submitSegmentAnything2(ctx context.Context, params aiRequestParams, sess *AISession, req worker.BodySegmentAnything2SegmentAnything2Post) (*worker.MasksResponse, error) { + var buf bytes.Buffer + mw, err := worker.NewSegmentAnything2MultipartWriter(&buf, req) + if err != nil { + if monitor.Enabled { + monitor.AIRequestError(err.Error(), "segment anything 2", *req.ModelId, sess.OrchestratorInfo) + } + return nil, err + } + + client, err := worker.NewClientWithResponses(sess.Transcoder(), worker.WithHTTPClient(httpClient)) + if err != nil { + if monitor.Enabled { + monitor.AIRequestError(err.Error(), "segment anything 2", *req.ModelId, sess.OrchestratorInfo) + } + return nil, err + } + + imageRdr, err := req.Image.Reader() + if err != nil { + if monitor.Enabled { + monitor.AIRequestError(err.Error(), "segment anything 2", *req.ModelId, sess.OrchestratorInfo) + } + return nil, err + } + config, _, err := image.DecodeConfig(imageRdr) + if err != nil { + if monitor.Enabled { + monitor.AIRequestError(err.Error(), "segment anything 2", *req.ModelId, sess.OrchestratorInfo) + } + return nil, err + } + outPixels := int64(config.Height) * int64(config.Width) + + setHeaders, balUpdate, err := prepareAIPayment(ctx, sess, outPixels) + if err != nil { + if monitor.Enabled { + monitor.AIRequestError(err.Error(), "segment anything 2", *req.ModelId, sess.OrchestratorInfo) + } + return nil, err + } + defer completeBalanceUpdate(sess.BroadcastSession, balUpdate) + + start := time.Now() + resp, err := client.SegmentAnything2WithBodyWithResponse(ctx, mw.FormDataContentType(), &buf, setHeaders) + took := time.Since(start) + if err != nil { + if monitor.Enabled { + monitor.AIRequestError(err.Error(), "segment anything 2", *req.ModelId, sess.OrchestratorInfo) + } + return nil, err + } + + if resp.JSON200 == nil { + // TODO: Replace trim newline with better error spec from O + return nil, errors.New(strings.TrimSuffix(string(resp.Body), "\n")) + } + + // We treat a response as "receiving change" where the change is the difference between the credit and debit for the update + if balUpdate != nil { + balUpdate.Status = ReceivedChange + } + + // TODO: Refine this rough estimate in future iterations + sess.LatencyScore = CalculateSegmentAnything2LatencyScore(took, outPixels) + + if monitor.Enabled { + var pricePerAIUnit float64 + if priceInfo := sess.OrchestratorInfo.GetPriceInfo(); priceInfo != nil && priceInfo.PixelsPerUnit != 0 { + pricePerAIUnit = float64(priceInfo.PricePerUnit) / float64(priceInfo.PixelsPerUnit) + } + + monitor.AIRequestFinished(ctx, "segment anything 2", *req.ModelId, monitor.AIJobInfo{LatencyScore: sess.LatencyScore, PricePerUnit: pricePerAIUnit}, sess.OrchestratorInfo) + } + + return resp.JSON200, nil +} + // CalculateAudioToTextLatencyScore computes the time taken per second of audio for an audio-to-text request. func CalculateAudioToTextLatencyScore(took time.Duration, durationSeconds int64) float64 { if durationSeconds <= 0 { @@ -744,6 +843,15 @@ func processAIRequest(ctx context.Context, params aiRequestParams, req interface submitFn = func(ctx context.Context, params aiRequestParams, sess *AISession) (interface{}, error) { return submitAudioToText(ctx, params, sess, v) } + case worker.SegmentAnything2MultipartRequestBody: + cap = core.Capability_SegmentAnything2 + modelID = defaultSegmentAnything2ModelID + if v.ModelId != nil { + modelID = *v.ModelId + } + submitFn = func(ctx context.Context, params aiRequestParams, sess *AISession) (interface{}, error) { + return submitSegmentAnything2(ctx, params, sess, v) + } default: return nil, fmt.Errorf("unsupported request type %T", req) } diff --git a/server/rpc.go b/server/rpc.go index 0c8b9f8066..db797b9eba 100644 --- a/server/rpc.go +++ b/server/rpc.go @@ -68,6 +68,7 @@ type Orchestrator interface { ImageToVideo(ctx context.Context, req worker.ImageToVideoMultipartRequestBody) (*worker.ImageResponse, error) Upscale(ctx context.Context, req worker.UpscaleMultipartRequestBody) (*worker.ImageResponse, error) AudioToText(ctx context.Context, req worker.AudioToTextMultipartRequestBody) (*worker.TextResponse, error) + SegmentAnything2(ctx context.Context, req worker.SegmentAnything2MultipartRequestBody) (*worker.MasksResponse, error) } // Balance describes methods for a session's balance maintenance diff --git a/server/rpc_test.go b/server/rpc_test.go index 0ede88b261..197e2baa6b 100644 --- a/server/rpc_test.go +++ b/server/rpc_test.go @@ -202,6 +202,9 @@ func (r *stubOrchestrator) Upscale(ctx context.Context, req worker.UpscaleMultip func (r *stubOrchestrator) AudioToText(ctx context.Context, req worker.AudioToTextMultipartRequestBody) (*worker.TextResponse, error) { return nil, nil } +func (r *stubOrchestrator) SegmentAnything2(ctx context.Context, req worker.SegmentAnything2MultipartRequestBody) (*worker.MasksResponse, error) { + return nil, nil +} func (r *stubOrchestrator) CheckAICapacity(pipeline, modelID string) bool { return true } @@ -1385,6 +1388,9 @@ func (r *mockOrchestrator) Upscale(ctx context.Context, req worker.UpscaleMultip func (r *mockOrchestrator) AudioToText(ctx context.Context, req worker.AudioToTextMultipartRequestBody) (*worker.TextResponse, error) { return nil, nil } +func (r *mockOrchestrator) SegmentAnything2(ctx context.Context, req worker.SegmentAnything2MultipartRequestBody) (*worker.MasksResponse, error) { + return nil, nil +} func (r *mockOrchestrator) CheckAICapacity(pipeline, modelID string) bool { return true } From 1bae87ec854d875336fa42e1df1e885a54b49429 Mon Sep 17 00:00:00 2001 From: Rick Staa Date: Wed, 4 Sep 2024 12:41:25 +0200 Subject: [PATCH 03/21] chore(ai): release 0.7.8-ai.2 This commit released the new AI network software. --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 31f1463618..6bf1c77357 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.7.8-ai.1 +0.7.8-ai.2 From 384b7033085753a74a291c1de476d44b381d739d Mon Sep 17 00:00:00 2001 From: hjpotter92 Date: Thu, 5 Sep 2024 17:59:59 +0530 Subject: [PATCH 04/21] build.yaml: Skip upload step raising an error for PR from forks (#3162) We don't want our gcp buckets to get overfilled with builds from external devs. --- .github/workflows/build.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 56618fb8cf..ace2b7e8e0 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -242,6 +242,7 @@ jobs: upload: name: Upload artifacts to google bucket + if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository permissions: contents: "read" id-token: "write" From 48a92a171cfc9e2f55dc275a5d6bf293bd3589cf Mon Sep 17 00:00:00 2001 From: John | Elite Encoder Date: Thu, 5 Sep 2024 08:59:55 -0400 Subject: [PATCH 05/21] validate `-serviceAddr` on startup and cli handler (#3156) --- cmd/livepeer/starter/starter.go | 5 +++++ common/util.go | 5 +++++ common/util_test.go | 36 +++++++++++++++++++++++++++++++++ server/handlers.go | 6 ++++++ server/handlers_test.go | 23 +++++++++++++++++++++ 5 files changed, 75 insertions(+) diff --git a/cmd/livepeer/starter/starter.go b/cmd/livepeer/starter/starter.go index 1556b125df..fb153b3802 100755 --- a/cmd/livepeer/starter/starter.go +++ b/cmd/livepeer/starter/starter.go @@ -1199,6 +1199,11 @@ func StartLivepeer(ctx context.Context, cfg LivepeerConfig) { if err != nil { glog.Exit("Error getting service URI: ", err) } + + if *cfg.Network != "offchain" && !common.ValidateServiceURI(suri) { + glog.Warning("**Warning -serviceAddr is a not a public address or hostname; this is not recommended for onchain networks**") + } + n.SetServiceURI(suri) // if http addr is not provided, listen to all ifaces // take the port to listen to from the service URI diff --git a/common/util.go b/common/util.go index 639cf07ccd..b4d7396a8b 100644 --- a/common/util.go +++ b/common/util.go @@ -11,6 +11,7 @@ import ( "math/big" "math/rand" "mime" + "net/url" "regexp" "sort" "strconv" @@ -530,3 +531,7 @@ func ParseEthAddr(strJsonKey string) (string, error) { } return "", errors.New("Error parsing address from keyfile") } + +func ValidateServiceURI(serviceURI *url.URL) bool { + return !strings.Contains(serviceURI.Host, "0.0.0.0") +} diff --git a/common/util_test.go b/common/util_test.go index 9a541669d6..131631586e 100644 --- a/common/util_test.go +++ b/common/util_test.go @@ -5,6 +5,7 @@ import ( "fmt" "math" "math/big" + "net/url" "strconv" "strings" "testing" @@ -483,3 +484,38 @@ func TestParseAccelDevices_CustomSelection(t *testing.T) { assert.Equal(ids[1], "3") assert.Equal(ids[2], "1") } +func TestValidateServiceURI(t *testing.T) { + // Valid service URIs + validURIs := []string{ + "https://8.8.8.8:8935", + "https://127.0.0.1:8935", + } + + for _, uri := range validURIs { + serviceURI, err := url.Parse(uri) + if err != nil { + t.Errorf("Failed to parse valid service URI: %v", err) + } + + if !ValidateServiceURI(serviceURI) { + t.Errorf("Expected service URI to be valid, but got invalid: %v", uri) + } + } + + // Invalid service URIs + invalidURIs := []string{ + "http://0.0.0.0", + "https://0.0.0.0", + } + + for _, uri := range invalidURIs { + serviceURI, err := url.Parse(uri) + if err != nil { + t.Errorf("Failed to parse invalid service URI: %v", err) + } + + if ValidateServiceURI(serviceURI) { + t.Errorf("Expected service URI to be invalid, but got valid: %v", uri) + } + } +} diff --git a/server/handlers.go b/server/handlers.go index 22116079e6..5e9cc62d8c 100644 --- a/server/handlers.go +++ b/server/handlers.go @@ -526,6 +526,12 @@ func (s *LivepeerServer) setServiceURI(client eth.LivepeerEthClient, serviceURI return err } + if !common.ValidateServiceURI(parsedURI) { + err = errors.New("service address must be a public IP address or hostname") + glog.Error(err) + return err + } + glog.Infof("Storing service URI %v in service registry...", serviceURI) tx, err := client.SetServiceURI(serviceURI) diff --git a/server/handlers_test.go b/server/handlers_test.go index d191d0a75e..528282972e 100644 --- a/server/handlers_test.go +++ b/server/handlers_test.go @@ -15,6 +15,7 @@ import ( "github.com/ethereum/go-ethereum/accounts" ethcommon "github.com/ethereum/go-ethereum/common" + ethtypes "github.com/ethereum/go-ethereum/core/types" "github.com/livepeer/go-livepeer/core" "github.com/livepeer/go-livepeer/eth" "github.com/livepeer/go-livepeer/eth/types" @@ -1570,7 +1571,29 @@ func TestMustHaveDb_Success(t *testing.T) { assert.Equal(http.StatusOK, status) assert.Equal("success", body) } +func TestSetServiceURI(t *testing.T) { + s := stubServer() + client := ð.MockClient{} + serviceURI := "https://8.8.8.8:8935" + + t.Run("Valid Service URI", func(t *testing.T) { + client.On("SetServiceURI", serviceURI).Return(ðtypes.Transaction{}, nil) + client.On("CheckTx", mock.Anything).Return(nil) + + err := s.setServiceURI(client, serviceURI) + + assert.NoError(t, err) + }) + t.Run("Invalid Service URI", func(t *testing.T) { + invalidServiceURI := "https://0.0.0.0:8935" + + err := s.setServiceURI(client, invalidServiceURI) + + assert.Error(t, err) + }) + +} func dummyHandler() http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) From a99a6311434c68ad25ec9312578e733c819bab92 Mon Sep 17 00:00:00 2001 From: Josh Allmann Date: Mon, 9 Sep 2024 10:59:46 -0700 Subject: [PATCH 06/21] broadcaster: Fix media compatibility check (#3164) Not all fields will be identical segment-to-segment, particularly DurationSecs. This caused unnecessary transcoder re-initialization. --- server/mediaserver.go | 14 +++++- server/mediaserver_test.go | 95 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 108 insertions(+), 1 deletion(-) diff --git a/server/mediaserver.go b/server/mediaserver.go index e24bf1edbe..975aef7fb2 100644 --- a/server/mediaserver.go +++ b/server/mediaserver.go @@ -989,7 +989,7 @@ func (s *LivepeerServer) HandlePush(w http.ResponseWriter, r *http.Request) { cxn.mu.Lock() if cxn.mediaFormat == (ffmpeg.MediaFormatInfo{}) { cxn.mediaFormat = mediaFormat - } else if cxn.mediaFormat != mediaFormat { + } else if !mediaCompatible(cxn.mediaFormat, mediaFormat) { cxn.mediaFormat = mediaFormat segPar.ForceSessionReinit = true } @@ -1649,3 +1649,15 @@ func getRemoteAddr(r *http.Request) string { } return strings.Split(addr, ":")[0] } + +func mediaCompatible(a, b ffmpeg.MediaFormatInfo) bool { + return a.Acodec == b.Acodec && + a.Vcodec == b.Vcodec && + a.PixFormat == b.PixFormat && + a.Width == b.Width && + a.Height == b.Height + + // NB: there is also a Format field but that does + // not need to match since transcoder will reopen + // a new demuxer each time +} diff --git a/server/mediaserver_test.go b/server/mediaserver_test.go index 595c4e29ab..8a7db8659f 100644 --- a/server/mediaserver_test.go +++ b/server/mediaserver_test.go @@ -1494,6 +1494,101 @@ func TestJsonProfileToVideoProfiles(t *testing.T) { assert.Equal("unable to parse the H264 encoder profile: unknown VideoProfile profile name", err.Error()) } +func TestMediaCompatible(t *testing.T) { + empty := ffmpeg.MediaFormatInfo{} + normal := ffmpeg.MediaFormatInfo{ + Acodec: "aac", + Vcodec: "h264", + PixFormat: ffmpeg.PixelFormat{RawValue: ffmpeg.PixelFormatNV12}, + Format: "mpegts", + Width: 100, + Height: 200, + AudioBitrate: 300, + DurSecs: 5, + } + tests := []struct { + name string + a ffmpeg.MediaFormatInfo + b ffmpeg.MediaFormatInfo + match bool + }{{ + name: "empty", + a: empty, + match: true, + }, { + name: "normal", + match: true, + a: normal, + b: ffmpeg.MediaFormatInfo{ + Format: "mp4", + DurSecs: 10, + AudioBitrate: 400, + Acodec: normal.Acodec, + Vcodec: normal.Vcodec, + PixFormat: normal.PixFormat, + Width: normal.Width, + Height: normal.Height, + }, + }, { + name: "w", + a: normal, + b: ffmpeg.MediaFormatInfo{ + Width: normal.Width + 1, + Acodec: normal.Acodec, + Vcodec: normal.Vcodec, + PixFormat: normal.PixFormat, + Height: normal.Height, + }, + }, { + name: "h", + a: normal, + b: ffmpeg.MediaFormatInfo{ + Height: normal.Height + 1, + Acodec: normal.Acodec, + Vcodec: normal.Vcodec, + PixFormat: normal.PixFormat, + Width: normal.Width, + }, + }, { + name: "pixfmt", + a: normal, + b: ffmpeg.MediaFormatInfo{ + Width: normal.Width, + Acodec: normal.Acodec, + Vcodec: normal.Vcodec, + PixFormat: ffmpeg.PixelFormat{RawValue: ffmpeg.PixelFormatYUV420P}, + Height: normal.Height, + }, + }, { + name: "video codec", + a: normal, + b: ffmpeg.MediaFormatInfo{ + Vcodec: "flv", + Acodec: normal.Acodec, + Format: normal.Format, + PixFormat: normal.PixFormat, + Width: normal.Width, + Height: normal.Height, + }, + }, { + name: "audio codec", + a: normal, + b: ffmpeg.MediaFormatInfo{ + Acodec: "opus", + Vcodec: normal.Vcodec, + Format: normal.Format, + PixFormat: normal.PixFormat, + Width: normal.Width, + Height: normal.Height, + }, + }} + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + assert.Equal(t, tt.match, mediaCompatible(tt.a, tt.b)) + }) + } +} + func mustParseUrl(t *testing.T, str string) *url.URL { url, err := url.Parse(str) if err != nil { From eec6ed3e8614d75382deab275e0406cdcb59238f Mon Sep 17 00:00:00 2001 From: Josh Allmann Date: Mon, 9 Sep 2024 11:19:22 -0700 Subject: [PATCH 07/21] Add node version and orch addr to transcoded metadata (#3165) * Update LPMS to latest. * protoc: Regenerate --- CHANGELOG_PENDING.md | 4 + cmd/livepeer/starter/starter.go | 1 + core/livepeernode.go | 1 + core/orchestrator.go | 12 + core/streamdata.go | 9 + core/transcoder.go | 16 +- core/transcoder_test.go | 23 +- go.mod | 2 +- go.sum | 4 +- net/lp_rpc.pb.go | 2968 ++++++++++++++++++++----------- net/lp_rpc.proto | 3 + net/lp_rpc_grpc.pb.go | 2 +- server/ot_rpc.go | 1 + 13 files changed, 1958 insertions(+), 1088 deletions(-) diff --git a/CHANGELOG_PENDING.md b/CHANGELOG_PENDING.md index 22f1b28ed7..58c0bfd8d2 100644 --- a/CHANGELOG_PENDING.md +++ b/CHANGELOG_PENDING.md @@ -2,6 +2,8 @@ ## v0.X.X +- [#3165](https://github.com/livepeer/go-livepeer/pull/3165) Add node version and orch addr to transcoded metadata + ### Breaking Changes 🚨🚨 ### Features ⚒ @@ -22,6 +24,8 @@ #### Broadcaster +- [#3164](https://github.com/livepeer/go-livepeer/pull/3164) Fix video compatibility check + #### Orchestrator #### Transcoder diff --git a/cmd/livepeer/starter/starter.go b/cmd/livepeer/starter/starter.go index fb153b3802..23a7be0990 100755 --- a/cmd/livepeer/starter/starter.go +++ b/cmd/livepeer/starter/starter.go @@ -848,6 +848,7 @@ func StartLivepeer(ctx context.Context, cfg LivepeerConfig) { glog.Errorf("Error setting up orchestrator: %v", err) return } + n.RecipientAddr = recipientAddr.Hex() sigVerifier := &pm.DefaultSigVerifier{} validator := pm.NewValidator(sigVerifier, timeWatcher) diff --git a/core/livepeernode.go b/core/livepeernode.go index 19839a185b..d7b3fec041 100644 --- a/core/livepeernode.go +++ b/core/livepeernode.go @@ -75,6 +75,7 @@ type LivepeerNode struct { // Transcoder public fields SegmentChans map[ManifestID]SegmentChan Recipient pm.Recipient + RecipientAddr string SelectionAlgorithm common.SelectionAlgorithm OrchestratorPool common.OrchestratorPool OrchPerfScore *common.PerfScore diff --git a/core/orchestrator.go b/core/orchestrator.go index 50d6ea9757..3a2578c81a 100644 --- a/core/orchestrator.go +++ b/core/orchestrator.go @@ -582,6 +582,17 @@ func (n *LivepeerNode) transcodeSeg(ctx context.Context, config transcodeConfig, } md.Fname = url + orchId := "offchain" + if n.RecipientAddr != "" { + orchId = n.RecipientAddr + } + if isRemote { + // huge hack to thread the orch id down to the transcoder + md.Metadata = map[string]string{"orchId": orchId} + } else { + md.Metadata = MakeMetadata(orchId) + } + //Do the transcoding start := time.Now() tData, err := transcoder.Transcode(ctx, md) @@ -816,6 +827,7 @@ func (rt *RemoteTranscoder) Transcode(logCtx context.Context, md *SegTranscoding msg := &net.NotifySegment{ Url: fname, TaskId: taskID, + OrchId: md.Metadata["orchId"], SegData: segData, // Triggers failure on Os that don't know how to use SegData Profiles: []byte("invalid"), diff --git a/core/streamdata.go b/core/streamdata.go index 6b2909e5c5..f575cd2c83 100644 --- a/core/streamdata.go +++ b/core/streamdata.go @@ -66,6 +66,7 @@ type SegTranscodingMetadata struct { AuthToken *net.AuthToken CalcPerceptualHash bool SegmentParameters *SegmentParameters + Metadata map[string]string } func (md *SegTranscodingMetadata) Flatten() []byte { @@ -192,3 +193,11 @@ func (id StreamID) String() string { func RandomManifestID() ManifestID { return ManifestID(common.RandomIDGenerator(DefaultManifestIDLength)) } + +func MakeMetadata(id string) map[string]string { + s := fmt.Sprintf("Livepeer Transcoder %s (%s)", LivepeerVersion, id) + return map[string]string{ + "service_provider": s, // for mpegts + "comment": "Processed by " + s, // for mp4 + } +} diff --git a/core/transcoder.go b/core/transcoder.go index 79458a5b83..da1cb5d177 100644 --- a/core/transcoder.go +++ b/core/transcoder.go @@ -51,7 +51,7 @@ func (lt *LocalTranscoder) Transcode(ctx context.Context, md *SegTranscodingMeta Accel: ffmpeg.Software, } profiles := md.Profiles - opts := profilesToTranscodeOptions(lt.workDir, ffmpeg.Software, profiles, md.CalcPerceptualHash, md.SegmentParameters) + opts := profilesToTranscodeOptions(lt.workDir, ffmpeg.Software, md) _, seqNo, parseErr := parseURI(md.Fname) start := time.Now() @@ -100,7 +100,7 @@ func (nv *NetintTranscoder) Transcode(ctx context.Context, md *SegTranscodingMet Device: nv.device, } profiles := md.Profiles - out := profilesToTranscodeOptions(WorkDir, ffmpeg.Netint, profiles, md.CalcPerceptualHash, md.SegmentParameters) + out := profilesToTranscodeOptions(WorkDir, ffmpeg.Netint, md) _, seqNo, parseErr := parseURI(md.Fname) start := time.Now() @@ -135,7 +135,7 @@ func (nv *NvidiaTranscoder) Transcode(ctx context.Context, md *SegTranscodingMet Device: nv.device, } profiles := md.Profiles - out := profilesToTranscodeOptions(WorkDir, ffmpeg.Nvidia, profiles, md.CalcPerceptualHash, md.SegmentParameters) + out := profilesToTranscodeOptions(WorkDir, ffmpeg.Nvidia, md) _, seqNo, parseErr := parseURI(md.Fname) start := time.Now() @@ -429,8 +429,13 @@ func resToTranscodeData(ctx context.Context, res *ffmpeg.TranscodeResults, opts }, nil } -func profilesToTranscodeOptions(workDir string, accel ffmpeg.Acceleration, profiles []ffmpeg.VideoProfile, calcPHash bool, - segPar *SegmentParameters) []ffmpeg.TranscodeOptions { +func profilesToTranscodeOptions(workDir string, accel ffmpeg.Acceleration, md *SegTranscodingMetadata) []ffmpeg.TranscodeOptions { + var ( + profiles []ffmpeg.VideoProfile = md.Profiles + calcPHash bool = md.CalcPerceptualHash + segPar *SegmentParameters = md.SegmentParameters + metadata map[string]string = md.Metadata + ) opts := make([]ffmpeg.TranscodeOptions, len(profiles)) for i := range profiles { @@ -440,6 +445,7 @@ func profilesToTranscodeOptions(workDir string, accel ffmpeg.Acceleration, profi Accel: accel, AudioEncoder: ffmpeg.ComponentOptions{Name: "copy"}, CalcSign: calcPHash, + Metadata: metadata, } if segPar != nil && segPar.Clip != nil { o.From = segPar.Clip.From diff --git a/core/transcoder_test.go b/core/transcoder_test.go index 25e19c5818..a6d687504e 100644 --- a/core/transcoder_test.go +++ b/core/transcoder_test.go @@ -178,14 +178,24 @@ func TestProfilesToTranscodeOptions(t *testing.T) { } defer func() { common.RandomIDGenerator = oldRandIDFunc }() + makeMeta := func(p []ffmpeg.VideoProfile, c bool) *SegTranscodingMetadata { + return &SegTranscodingMetadata{ + Profiles: p, + CalcPerceptualHash: c, + Metadata: map[string]string{ + "meta": "data", + }, + } + } + // Test 0 profiles profiles := []ffmpeg.VideoProfile{} - opts := profilesToTranscodeOptions(workDir, ffmpeg.Software, profiles, false, nil) + opts := profilesToTranscodeOptions(workDir, ffmpeg.Software, makeMeta(profiles, false)) assert.Equal(0, len(opts)) // Test 1 profile profiles = []ffmpeg.VideoProfile{ffmpeg.P144p30fps16x9} - opts = profilesToTranscodeOptions(workDir, ffmpeg.Software, profiles, false, nil) + opts = profilesToTranscodeOptions(workDir, ffmpeg.Software, makeMeta(profiles, false)) assert.Equal(1, len(opts)) assert.Equal("foo/out_bar.tempfile", opts[0].Oname) assert.Equal(ffmpeg.Software, opts[0].Accel) @@ -194,7 +204,7 @@ func TestProfilesToTranscodeOptions(t *testing.T) { // Test > 1 profile profiles = []ffmpeg.VideoProfile{ffmpeg.P144p30fps16x9, ffmpeg.P240p30fps16x9} - opts = profilesToTranscodeOptions(workDir, ffmpeg.Software, profiles, false, nil) + opts = profilesToTranscodeOptions(workDir, ffmpeg.Software, makeMeta(profiles, false)) assert.Equal(2, len(opts)) for i, p := range profiles { @@ -202,14 +212,17 @@ func TestProfilesToTranscodeOptions(t *testing.T) { assert.Equal(ffmpeg.Software, opts[i].Accel) assert.Equal(p, opts[i].Profile) assert.Equal("copy", opts[i].AudioEncoder.Name) + assert.Equal(opts[i].Metadata, map[string]string{ + "meta": "data", + }) } // Test different acceleration value - opts = profilesToTranscodeOptions(workDir, ffmpeg.Nvidia, profiles, false, nil) + opts = profilesToTranscodeOptions(workDir, ffmpeg.Nvidia, makeMeta(profiles, false)) assert.Equal(2, len(opts)) // Test signature calculation - opts = profilesToTranscodeOptions(workDir, ffmpeg.Nvidia, profiles, true, nil) + opts = profilesToTranscodeOptions(workDir, ffmpeg.Nvidia, makeMeta(profiles, true)) assert.True(opts[0].CalcSign) assert.True(opts[1].CalcSign) diff --git a/go.mod b/go.mod index e5f7834168..4a40dbc93e 100644 --- a/go.mod +++ b/go.mod @@ -14,7 +14,7 @@ require ( github.com/jaypipes/pcidb v1.0.0 github.com/livepeer/go-tools v0.0.0-20220805063103-76df6beb6506 github.com/livepeer/livepeer-data v0.7.5-0.20231004073737-06f1f383fb18 - github.com/livepeer/lpms v0.0.0-20240819180416-f87352959b85 + github.com/livepeer/lpms v0.0.0-20240909171057-fe5aff1fa6a2 github.com/livepeer/m3u8 v0.11.1 github.com/mattn/go-sqlite3 v1.14.18 github.com/olekukonko/tablewriter v0.0.5 diff --git a/go.sum b/go.sum index 57cb8ab204..b29ad7eb76 100644 --- a/go.sum +++ b/go.sum @@ -446,8 +446,8 @@ github.com/livepeer/joy4 v0.1.2-0.20191121080656-b2fea45cbded h1:ZQlvR5RB4nfT+cO github.com/livepeer/joy4 v0.1.2-0.20191121080656-b2fea45cbded/go.mod h1:xkDdm+akniYxVT9KW1Y2Y7Hso6aW+rZObz3nrA9yTHw= github.com/livepeer/livepeer-data v0.7.5-0.20231004073737-06f1f383fb18 h1:4oH3NqV0NvcdS44Ld3zK2tO8IUiNozIggm74yobQeZg= github.com/livepeer/livepeer-data v0.7.5-0.20231004073737-06f1f383fb18/go.mod h1:Jpf4jHK+fbWioBHRDRM1WadNT1qmY27g2YicTdO0Rtc= -github.com/livepeer/lpms v0.0.0-20240819180416-f87352959b85 h1:E8hJhT1nEW1jneK+Re3KyJcsITFYS9oa0vgyA6bLmKE= -github.com/livepeer/lpms v0.0.0-20240819180416-f87352959b85/go.mod h1:z5ROP1l5OzAKSoqVRLc34MjUdueil6wHSecQYV7llIw= +github.com/livepeer/lpms v0.0.0-20240909171057-fe5aff1fa6a2 h1:UYVfhBuJ2h6eYOCBaCzjoWoj3onhZ+6wFhXNllELYDA= +github.com/livepeer/lpms v0.0.0-20240909171057-fe5aff1fa6a2/go.mod h1:z5ROP1l5OzAKSoqVRLc34MjUdueil6wHSecQYV7llIw= github.com/livepeer/m3u8 v0.11.1 h1:VkUJzfNTyjy9mqsgp5JPvouwna8wGZMvd/gAfT5FinU= github.com/livepeer/m3u8 v0.11.1/go.mod h1:IUqAtwWPAG2CblfQa4SVzTQoDcEMPyfNOaBSxqHMS04= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4= diff --git a/net/lp_rpc.pb.go b/net/lp_rpc.pb.go index d5102d77c5..5f1f72c83d 100644 --- a/net/lp_rpc.pb.go +++ b/net/lp_rpc.pb.go @@ -1,24 +1,24 @@ // Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.28.1 +// protoc v3.21.12 // source: net/lp_rpc.proto package net import ( - fmt "fmt" - proto "github.com/golang/protobuf/proto" - math "math" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" ) -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) type OSInfo_StorageType int32 @@ -28,24 +28,45 @@ const ( OSInfo_GOOGLE OSInfo_StorageType = 2 ) -var OSInfo_StorageType_name = map[int32]string{ - 0: "DIRECT", - 1: "S3", - 2: "GOOGLE", -} +// Enum value maps for OSInfo_StorageType. +var ( + OSInfo_StorageType_name = map[int32]string{ + 0: "DIRECT", + 1: "S3", + 2: "GOOGLE", + } + OSInfo_StorageType_value = map[string]int32{ + "DIRECT": 0, + "S3": 1, + "GOOGLE": 2, + } +) -var OSInfo_StorageType_value = map[string]int32{ - "DIRECT": 0, - "S3": 1, - "GOOGLE": 2, +func (x OSInfo_StorageType) Enum() *OSInfo_StorageType { + p := new(OSInfo_StorageType) + *p = x + return p } func (x OSInfo_StorageType) String() string { - return proto.EnumName(OSInfo_StorageType_name, int32(x)) + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) } +func (OSInfo_StorageType) Descriptor() protoreflect.EnumDescriptor { + return file_net_lp_rpc_proto_enumTypes[0].Descriptor() +} + +func (OSInfo_StorageType) Type() protoreflect.EnumType { + return &file_net_lp_rpc_proto_enumTypes[0] +} + +func (x OSInfo_StorageType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use OSInfo_StorageType.Descriptor instead. func (OSInfo_StorageType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_034e29c79f9ba827, []int{4, 0} + return file_net_lp_rpc_proto_rawDescGZIP(), []int{4, 0} } // Desired output format @@ -56,22 +77,43 @@ const ( VideoProfile_MP4 VideoProfile_Format = 1 ) -var VideoProfile_Format_name = map[int32]string{ - 0: "MPEGTS", - 1: "MP4", -} +// Enum value maps for VideoProfile_Format. +var ( + VideoProfile_Format_name = map[int32]string{ + 0: "MPEGTS", + 1: "MP4", + } + VideoProfile_Format_value = map[string]int32{ + "MPEGTS": 0, + "MP4": 1, + } +) -var VideoProfile_Format_value = map[string]int32{ - "MPEGTS": 0, - "MP4": 1, +func (x VideoProfile_Format) Enum() *VideoProfile_Format { + p := new(VideoProfile_Format) + *p = x + return p } func (x VideoProfile_Format) String() string { - return proto.EnumName(VideoProfile_Format_name, int32(x)) + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (VideoProfile_Format) Descriptor() protoreflect.EnumDescriptor { + return file_net_lp_rpc_proto_enumTypes[1].Descriptor() +} + +func (VideoProfile_Format) Type() protoreflect.EnumType { + return &file_net_lp_rpc_proto_enumTypes[1] +} + +func (x VideoProfile_Format) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) } +// Deprecated: Use VideoProfile_Format.Descriptor instead. func (VideoProfile_Format) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_034e29c79f9ba827, []int{12, 0} + return file_net_lp_rpc_proto_rawDescGZIP(), []int{12, 0} } type VideoProfile_Profile int32 @@ -84,28 +126,49 @@ const ( VideoProfile_H264_CONSTRAINED_HIGH VideoProfile_Profile = 4 ) -var VideoProfile_Profile_name = map[int32]string{ - 0: "ENCODER_DEFAULT", - 1: "H264_BASELINE", - 2: "H264_MAIN", - 3: "H264_HIGH", - 4: "H264_CONSTRAINED_HIGH", -} +// Enum value maps for VideoProfile_Profile. +var ( + VideoProfile_Profile_name = map[int32]string{ + 0: "ENCODER_DEFAULT", + 1: "H264_BASELINE", + 2: "H264_MAIN", + 3: "H264_HIGH", + 4: "H264_CONSTRAINED_HIGH", + } + VideoProfile_Profile_value = map[string]int32{ + "ENCODER_DEFAULT": 0, + "H264_BASELINE": 1, + "H264_MAIN": 2, + "H264_HIGH": 3, + "H264_CONSTRAINED_HIGH": 4, + } +) -var VideoProfile_Profile_value = map[string]int32{ - "ENCODER_DEFAULT": 0, - "H264_BASELINE": 1, - "H264_MAIN": 2, - "H264_HIGH": 3, - "H264_CONSTRAINED_HIGH": 4, +func (x VideoProfile_Profile) Enum() *VideoProfile_Profile { + p := new(VideoProfile_Profile) + *p = x + return p } func (x VideoProfile_Profile) String() string { - return proto.EnumName(VideoProfile_Profile_name, int32(x)) + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (VideoProfile_Profile) Descriptor() protoreflect.EnumDescriptor { + return file_net_lp_rpc_proto_enumTypes[2].Descriptor() +} + +func (VideoProfile_Profile) Type() protoreflect.EnumType { + return &file_net_lp_rpc_proto_enumTypes[2] +} + +func (x VideoProfile_Profile) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) } +// Deprecated: Use VideoProfile_Profile.Descriptor instead. func (VideoProfile_Profile) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_034e29c79f9ba827, []int{12, 1} + return file_net_lp_rpc_proto_rawDescGZIP(), []int{12, 1} } type VideoProfile_VideoCodec int32 @@ -117,26 +180,47 @@ const ( VideoProfile_VP9 VideoProfile_VideoCodec = 3 ) -var VideoProfile_VideoCodec_name = map[int32]string{ - 0: "H264", - 1: "H265", - 2: "VP8", - 3: "VP9", -} +// Enum value maps for VideoProfile_VideoCodec. +var ( + VideoProfile_VideoCodec_name = map[int32]string{ + 0: "H264", + 1: "H265", + 2: "VP8", + 3: "VP9", + } + VideoProfile_VideoCodec_value = map[string]int32{ + "H264": 0, + "H265": 1, + "VP8": 2, + "VP9": 3, + } +) -var VideoProfile_VideoCodec_value = map[string]int32{ - "H264": 0, - "H265": 1, - "VP8": 2, - "VP9": 3, +func (x VideoProfile_VideoCodec) Enum() *VideoProfile_VideoCodec { + p := new(VideoProfile_VideoCodec) + *p = x + return p } func (x VideoProfile_VideoCodec) String() string { - return proto.EnumName(VideoProfile_VideoCodec_name, int32(x)) + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) } +func (VideoProfile_VideoCodec) Descriptor() protoreflect.EnumDescriptor { + return file_net_lp_rpc_proto_enumTypes[3].Descriptor() +} + +func (VideoProfile_VideoCodec) Type() protoreflect.EnumType { + return &file_net_lp_rpc_proto_enumTypes[3] +} + +func (x VideoProfile_VideoCodec) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use VideoProfile_VideoCodec.Descriptor instead. func (VideoProfile_VideoCodec) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_034e29c79f9ba827, []int{12, 2} + return file_net_lp_rpc_proto_rawDescGZIP(), []int{12, 2} } type VideoProfile_ChromaSubsampling int32 @@ -147,185 +231,237 @@ const ( VideoProfile_CHROMA_444 VideoProfile_ChromaSubsampling = 2 ) -var VideoProfile_ChromaSubsampling_name = map[int32]string{ - 0: "CHROMA_420", - 1: "CHROMA_422", - 2: "CHROMA_444", -} +// Enum value maps for VideoProfile_ChromaSubsampling. +var ( + VideoProfile_ChromaSubsampling_name = map[int32]string{ + 0: "CHROMA_420", + 1: "CHROMA_422", + 2: "CHROMA_444", + } + VideoProfile_ChromaSubsampling_value = map[string]int32{ + "CHROMA_420": 0, + "CHROMA_422": 1, + "CHROMA_444": 2, + } +) -var VideoProfile_ChromaSubsampling_value = map[string]int32{ - "CHROMA_420": 0, - "CHROMA_422": 1, - "CHROMA_444": 2, +func (x VideoProfile_ChromaSubsampling) Enum() *VideoProfile_ChromaSubsampling { + p := new(VideoProfile_ChromaSubsampling) + *p = x + return p } func (x VideoProfile_ChromaSubsampling) String() string { - return proto.EnumName(VideoProfile_ChromaSubsampling_name, int32(x)) + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) } -func (VideoProfile_ChromaSubsampling) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_034e29c79f9ba827, []int{12, 3} +func (VideoProfile_ChromaSubsampling) Descriptor() protoreflect.EnumDescriptor { + return file_net_lp_rpc_proto_enumTypes[4].Descriptor() } -type PingPong struct { - // Implementation defined - Value []byte `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` +func (VideoProfile_ChromaSubsampling) Type() protoreflect.EnumType { + return &file_net_lp_rpc_proto_enumTypes[4] } -func (m *PingPong) Reset() { *m = PingPong{} } -func (m *PingPong) String() string { return proto.CompactTextString(m) } -func (*PingPong) ProtoMessage() {} -func (*PingPong) Descriptor() ([]byte, []int) { - return fileDescriptor_034e29c79f9ba827, []int{0} +func (x VideoProfile_ChromaSubsampling) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) } -func (m *PingPong) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_PingPong.Unmarshal(m, b) +// Deprecated: Use VideoProfile_ChromaSubsampling.Descriptor instead. +func (VideoProfile_ChromaSubsampling) EnumDescriptor() ([]byte, []int) { + return file_net_lp_rpc_proto_rawDescGZIP(), []int{12, 3} } -func (m *PingPong) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_PingPong.Marshal(b, m, deterministic) + +type PingPong struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Implementation defined + Value []byte `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"` } -func (m *PingPong) XXX_Merge(src proto.Message) { - xxx_messageInfo_PingPong.Merge(m, src) + +func (x *PingPong) Reset() { + *x = PingPong{} + if protoimpl.UnsafeEnabled { + mi := &file_net_lp_rpc_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *PingPong) XXX_Size() int { - return xxx_messageInfo_PingPong.Size(m) + +func (x *PingPong) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *PingPong) XXX_DiscardUnknown() { - xxx_messageInfo_PingPong.DiscardUnknown(m) + +func (*PingPong) ProtoMessage() {} + +func (x *PingPong) ProtoReflect() protoreflect.Message { + mi := &file_net_lp_rpc_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var xxx_messageInfo_PingPong proto.InternalMessageInfo +// Deprecated: Use PingPong.ProtoReflect.Descriptor instead. +func (*PingPong) Descriptor() ([]byte, []int) { + return file_net_lp_rpc_proto_rawDescGZIP(), []int{0} +} -func (m *PingPong) GetValue() []byte { - if m != nil { - return m.Value +func (x *PingPong) GetValue() []byte { + if x != nil { + return x.Value } return nil } // sent by Broadcaster to Orchestrator to terminate the transcoding session and free resources (used for verification sessions) type EndTranscodingSessionRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + // Data for transcoding authentication - AuthToken *AuthToken `protobuf:"bytes,1,opt,name=auth_token,json=authToken,proto3" json:"auth_token,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + AuthToken *AuthToken `protobuf:"bytes,1,opt,name=auth_token,json=authToken,proto3" json:"auth_token,omitempty"` } -func (m *EndTranscodingSessionRequest) Reset() { *m = EndTranscodingSessionRequest{} } -func (m *EndTranscodingSessionRequest) String() string { return proto.CompactTextString(m) } -func (*EndTranscodingSessionRequest) ProtoMessage() {} -func (*EndTranscodingSessionRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_034e29c79f9ba827, []int{1} +func (x *EndTranscodingSessionRequest) Reset() { + *x = EndTranscodingSessionRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_net_lp_rpc_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *EndTranscodingSessionRequest) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_EndTranscodingSessionRequest.Unmarshal(m, b) -} -func (m *EndTranscodingSessionRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_EndTranscodingSessionRequest.Marshal(b, m, deterministic) -} -func (m *EndTranscodingSessionRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_EndTranscodingSessionRequest.Merge(m, src) -} -func (m *EndTranscodingSessionRequest) XXX_Size() int { - return xxx_messageInfo_EndTranscodingSessionRequest.Size(m) +func (x *EndTranscodingSessionRequest) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *EndTranscodingSessionRequest) XXX_DiscardUnknown() { - xxx_messageInfo_EndTranscodingSessionRequest.DiscardUnknown(m) + +func (*EndTranscodingSessionRequest) ProtoMessage() {} + +func (x *EndTranscodingSessionRequest) ProtoReflect() protoreflect.Message { + mi := &file_net_lp_rpc_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var xxx_messageInfo_EndTranscodingSessionRequest proto.InternalMessageInfo +// Deprecated: Use EndTranscodingSessionRequest.ProtoReflect.Descriptor instead. +func (*EndTranscodingSessionRequest) Descriptor() ([]byte, []int) { + return file_net_lp_rpc_proto_rawDescGZIP(), []int{1} +} -func (m *EndTranscodingSessionRequest) GetAuthToken() *AuthToken { - if m != nil { - return m.AuthToken +func (x *EndTranscodingSessionRequest) GetAuthToken() *AuthToken { + if x != nil { + return x.AuthToken } return nil } type EndTranscodingSessionResponse struct { - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields } -func (m *EndTranscodingSessionResponse) Reset() { *m = EndTranscodingSessionResponse{} } -func (m *EndTranscodingSessionResponse) String() string { return proto.CompactTextString(m) } -func (*EndTranscodingSessionResponse) ProtoMessage() {} -func (*EndTranscodingSessionResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_034e29c79f9ba827, []int{2} +func (x *EndTranscodingSessionResponse) Reset() { + *x = EndTranscodingSessionResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_net_lp_rpc_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *EndTranscodingSessionResponse) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_EndTranscodingSessionResponse.Unmarshal(m, b) -} -func (m *EndTranscodingSessionResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_EndTranscodingSessionResponse.Marshal(b, m, deterministic) -} -func (m *EndTranscodingSessionResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_EndTranscodingSessionResponse.Merge(m, src) +func (x *EndTranscodingSessionResponse) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *EndTranscodingSessionResponse) XXX_Size() int { - return xxx_messageInfo_EndTranscodingSessionResponse.Size(m) -} -func (m *EndTranscodingSessionResponse) XXX_DiscardUnknown() { - xxx_messageInfo_EndTranscodingSessionResponse.DiscardUnknown(m) + +func (*EndTranscodingSessionResponse) ProtoMessage() {} + +func (x *EndTranscodingSessionResponse) ProtoReflect() protoreflect.Message { + mi := &file_net_lp_rpc_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var xxx_messageInfo_EndTranscodingSessionResponse proto.InternalMessageInfo +// Deprecated: Use EndTranscodingSessionResponse.ProtoReflect.Descriptor instead. +func (*EndTranscodingSessionResponse) Descriptor() ([]byte, []int) { + return file_net_lp_rpc_proto_rawDescGZIP(), []int{2} +} // This request is sent by the broadcaster in `GetTranscoder` to request // information on which transcoder to use. type OrchestratorRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + // Ethereum address of the broadcaster Address []byte `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` // Broadcaster's signature over its address - Sig []byte `protobuf:"bytes,2,opt,name=sig,proto3" json:"sig,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + Sig []byte `protobuf:"bytes,2,opt,name=sig,proto3" json:"sig,omitempty"` } -func (m *OrchestratorRequest) Reset() { *m = OrchestratorRequest{} } -func (m *OrchestratorRequest) String() string { return proto.CompactTextString(m) } -func (*OrchestratorRequest) ProtoMessage() {} -func (*OrchestratorRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_034e29c79f9ba827, []int{3} +func (x *OrchestratorRequest) Reset() { + *x = OrchestratorRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_net_lp_rpc_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *OrchestratorRequest) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_OrchestratorRequest.Unmarshal(m, b) -} -func (m *OrchestratorRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_OrchestratorRequest.Marshal(b, m, deterministic) -} -func (m *OrchestratorRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_OrchestratorRequest.Merge(m, src) +func (x *OrchestratorRequest) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *OrchestratorRequest) XXX_Size() int { - return xxx_messageInfo_OrchestratorRequest.Size(m) -} -func (m *OrchestratorRequest) XXX_DiscardUnknown() { - xxx_messageInfo_OrchestratorRequest.DiscardUnknown(m) + +func (*OrchestratorRequest) ProtoMessage() {} + +func (x *OrchestratorRequest) ProtoReflect() protoreflect.Message { + mi := &file_net_lp_rpc_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var xxx_messageInfo_OrchestratorRequest proto.InternalMessageInfo +// Deprecated: Use OrchestratorRequest.ProtoReflect.Descriptor instead. +func (*OrchestratorRequest) Descriptor() ([]byte, []int) { + return file_net_lp_rpc_proto_rawDescGZIP(), []int{3} +} -func (m *OrchestratorRequest) GetAddress() []byte { - if m != nil { - return m.Address +func (x *OrchestratorRequest) GetAddress() []byte { + if x != nil { + return x.Address } return nil } -func (m *OrchestratorRequest) GetSig() []byte { - if m != nil { - return m.Sig +func (x *OrchestratorRequest) GetSig() []byte { + if x != nil { + return x.Sig } return nil } @@ -333,54 +469,66 @@ func (m *OrchestratorRequest) GetSig() []byte { // OSInfo needed to negotiate storages that will be used. // It carries info needed to write to the storage. type OSInfo struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + // Storage type: direct, s3, ipfs. - StorageType OSInfo_StorageType `protobuf:"varint,1,opt,name=storageType,proto3,enum=net.OSInfo_StorageType" json:"storageType,omitempty"` - S3Info *S3OSInfo `protobuf:"bytes,16,opt,name=s3info,proto3" json:"s3info,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + StorageType OSInfo_StorageType `protobuf:"varint,1,opt,name=storageType,proto3,enum=net.OSInfo_StorageType" json:"storageType,omitempty"` + S3Info *S3OSInfo `protobuf:"bytes,16,opt,name=s3info,proto3" json:"s3info,omitempty"` } -func (m *OSInfo) Reset() { *m = OSInfo{} } -func (m *OSInfo) String() string { return proto.CompactTextString(m) } -func (*OSInfo) ProtoMessage() {} -func (*OSInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_034e29c79f9ba827, []int{4} +func (x *OSInfo) Reset() { + *x = OSInfo{} + if protoimpl.UnsafeEnabled { + mi := &file_net_lp_rpc_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *OSInfo) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_OSInfo.Unmarshal(m, b) +func (x *OSInfo) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *OSInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_OSInfo.Marshal(b, m, deterministic) -} -func (m *OSInfo) XXX_Merge(src proto.Message) { - xxx_messageInfo_OSInfo.Merge(m, src) -} -func (m *OSInfo) XXX_Size() int { - return xxx_messageInfo_OSInfo.Size(m) -} -func (m *OSInfo) XXX_DiscardUnknown() { - xxx_messageInfo_OSInfo.DiscardUnknown(m) + +func (*OSInfo) ProtoMessage() {} + +func (x *OSInfo) ProtoReflect() protoreflect.Message { + mi := &file_net_lp_rpc_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var xxx_messageInfo_OSInfo proto.InternalMessageInfo +// Deprecated: Use OSInfo.ProtoReflect.Descriptor instead. +func (*OSInfo) Descriptor() ([]byte, []int) { + return file_net_lp_rpc_proto_rawDescGZIP(), []int{4} +} -func (m *OSInfo) GetStorageType() OSInfo_StorageType { - if m != nil { - return m.StorageType +func (x *OSInfo) GetStorageType() OSInfo_StorageType { + if x != nil { + return x.StorageType } return OSInfo_DIRECT } -func (m *OSInfo) GetS3Info() *S3OSInfo { - if m != nil { - return m.S3Info +func (x *OSInfo) GetS3Info() *S3OSInfo { + if x != nil { + return x.S3Info } return nil } type S3OSInfo struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + // Host to use to connect to S3 Host string `protobuf:"bytes,1,opt,name=host,proto3" json:"host,omitempty"` // Key (prefix) to use when uploading the object. @@ -392,247 +540,231 @@ type S3OSInfo struct { // Needed for POST policy. Credential string `protobuf:"bytes,5,opt,name=credential,proto3" json:"credential,omitempty"` // Needed for POST policy. - XAmzDate string `protobuf:"bytes,6,opt,name=xAmzDate,proto3" json:"xAmzDate,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + XAmzDate string `protobuf:"bytes,6,opt,name=xAmzDate,proto3" json:"xAmzDate,omitempty"` } -func (m *S3OSInfo) Reset() { *m = S3OSInfo{} } -func (m *S3OSInfo) String() string { return proto.CompactTextString(m) } -func (*S3OSInfo) ProtoMessage() {} -func (*S3OSInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_034e29c79f9ba827, []int{5} +func (x *S3OSInfo) Reset() { + *x = S3OSInfo{} + if protoimpl.UnsafeEnabled { + mi := &file_net_lp_rpc_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *S3OSInfo) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_S3OSInfo.Unmarshal(m, b) -} -func (m *S3OSInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_S3OSInfo.Marshal(b, m, deterministic) +func (x *S3OSInfo) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *S3OSInfo) XXX_Merge(src proto.Message) { - xxx_messageInfo_S3OSInfo.Merge(m, src) -} -func (m *S3OSInfo) XXX_Size() int { - return xxx_messageInfo_S3OSInfo.Size(m) -} -func (m *S3OSInfo) XXX_DiscardUnknown() { - xxx_messageInfo_S3OSInfo.DiscardUnknown(m) + +func (*S3OSInfo) ProtoMessage() {} + +func (x *S3OSInfo) ProtoReflect() protoreflect.Message { + mi := &file_net_lp_rpc_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var xxx_messageInfo_S3OSInfo proto.InternalMessageInfo +// Deprecated: Use S3OSInfo.ProtoReflect.Descriptor instead. +func (*S3OSInfo) Descriptor() ([]byte, []int) { + return file_net_lp_rpc_proto_rawDescGZIP(), []int{5} +} -func (m *S3OSInfo) GetHost() string { - if m != nil { - return m.Host +func (x *S3OSInfo) GetHost() string { + if x != nil { + return x.Host } return "" } -func (m *S3OSInfo) GetKey() string { - if m != nil { - return m.Key +func (x *S3OSInfo) GetKey() string { + if x != nil { + return x.Key } return "" } -func (m *S3OSInfo) GetPolicy() string { - if m != nil { - return m.Policy +func (x *S3OSInfo) GetPolicy() string { + if x != nil { + return x.Policy } return "" } -func (m *S3OSInfo) GetSignature() string { - if m != nil { - return m.Signature +func (x *S3OSInfo) GetSignature() string { + if x != nil { + return x.Signature } return "" } -func (m *S3OSInfo) GetCredential() string { - if m != nil { - return m.Credential +func (x *S3OSInfo) GetCredential() string { + if x != nil { + return x.Credential } return "" } -func (m *S3OSInfo) GetXAmzDate() string { - if m != nil { - return m.XAmzDate +func (x *S3OSInfo) GetXAmzDate() string { + if x != nil { + return x.XAmzDate } return "" } // PriceInfo conveys pricing info for transcoding services type PriceInfo struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + // price in wei PricePerUnit int64 `protobuf:"varint,1,opt,name=pricePerUnit,proto3" json:"pricePerUnit,omitempty"` // Pixels covered in the price // Set price to 1 wei and pixelsPerUnit > 1 to have a smaller price granularity per pixel than 1 wei - PixelsPerUnit int64 `protobuf:"varint,2,opt,name=pixelsPerUnit,proto3" json:"pixelsPerUnit,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + PixelsPerUnit int64 `protobuf:"varint,2,opt,name=pixelsPerUnit,proto3" json:"pixelsPerUnit,omitempty"` } -func (m *PriceInfo) Reset() { *m = PriceInfo{} } -func (m *PriceInfo) String() string { return proto.CompactTextString(m) } -func (*PriceInfo) ProtoMessage() {} -func (*PriceInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_034e29c79f9ba827, []int{6} +func (x *PriceInfo) Reset() { + *x = PriceInfo{} + if protoimpl.UnsafeEnabled { + mi := &file_net_lp_rpc_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *PriceInfo) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_PriceInfo.Unmarshal(m, b) -} -func (m *PriceInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_PriceInfo.Marshal(b, m, deterministic) -} -func (m *PriceInfo) XXX_Merge(src proto.Message) { - xxx_messageInfo_PriceInfo.Merge(m, src) -} -func (m *PriceInfo) XXX_Size() int { - return xxx_messageInfo_PriceInfo.Size(m) +func (x *PriceInfo) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *PriceInfo) XXX_DiscardUnknown() { - xxx_messageInfo_PriceInfo.DiscardUnknown(m) + +func (*PriceInfo) ProtoMessage() {} + +func (x *PriceInfo) ProtoReflect() protoreflect.Message { + mi := &file_net_lp_rpc_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var xxx_messageInfo_PriceInfo proto.InternalMessageInfo +// Deprecated: Use PriceInfo.ProtoReflect.Descriptor instead. +func (*PriceInfo) Descriptor() ([]byte, []int) { + return file_net_lp_rpc_proto_rawDescGZIP(), []int{6} +} -func (m *PriceInfo) GetPricePerUnit() int64 { - if m != nil { - return m.PricePerUnit +func (x *PriceInfo) GetPricePerUnit() int64 { + if x != nil { + return x.PricePerUnit } return 0 } -func (m *PriceInfo) GetPixelsPerUnit() int64 { - if m != nil { - return m.PixelsPerUnit +func (x *PriceInfo) GetPixelsPerUnit() int64 { + if x != nil { + return x.PixelsPerUnit } return 0 } type Capabilities struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + // Bit string of supported features - one bit per feature Bitstring []uint64 `protobuf:"varint,1,rep,packed,name=bitstring,proto3" json:"bitstring,omitempty"` // Bit string of features that are required to be supported Mandatories []uint64 `protobuf:"varint,2,rep,packed,name=mandatories,proto3" json:"mandatories,omitempty"` // Capacity corresponding to each capability - Capacities map[uint32]uint32 `protobuf:"bytes,3,rep,name=capacities,proto3" json:"capacities,omitempty" protobuf_key:"varint,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"` - Version string `protobuf:"bytes,4,opt,name=version,proto3" json:"version,omitempty"` - Constraints *Capabilities_Constraints `protobuf:"bytes,5,opt,name=constraints,proto3" json:"constraints,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + Capacities map[uint32]uint32 `protobuf:"bytes,3,rep,name=capacities,proto3" json:"capacities,omitempty" protobuf_key:"varint,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"` + Version string `protobuf:"bytes,4,opt,name=version,proto3" json:"version,omitempty"` + Constraints *Capabilities_Constraints `protobuf:"bytes,5,opt,name=constraints,proto3" json:"constraints,omitempty"` } -func (m *Capabilities) Reset() { *m = Capabilities{} } -func (m *Capabilities) String() string { return proto.CompactTextString(m) } -func (*Capabilities) ProtoMessage() {} -func (*Capabilities) Descriptor() ([]byte, []int) { - return fileDescriptor_034e29c79f9ba827, []int{7} +func (x *Capabilities) Reset() { + *x = Capabilities{} + if protoimpl.UnsafeEnabled { + mi := &file_net_lp_rpc_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *Capabilities) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Capabilities.Unmarshal(m, b) -} -func (m *Capabilities) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Capabilities.Marshal(b, m, deterministic) -} -func (m *Capabilities) XXX_Merge(src proto.Message) { - xxx_messageInfo_Capabilities.Merge(m, src) -} -func (m *Capabilities) XXX_Size() int { - return xxx_messageInfo_Capabilities.Size(m) -} -func (m *Capabilities) XXX_DiscardUnknown() { - xxx_messageInfo_Capabilities.DiscardUnknown(m) +func (x *Capabilities) String() string { + return protoimpl.X.MessageStringOf(x) } -var xxx_messageInfo_Capabilities proto.InternalMessageInfo +func (*Capabilities) ProtoMessage() {} -func (m *Capabilities) GetBitstring() []uint64 { - if m != nil { - return m.Bitstring +func (x *Capabilities) ProtoReflect() protoreflect.Message { + mi := &file_net_lp_rpc_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms } - return nil + return mi.MessageOf(x) } -func (m *Capabilities) GetMandatories() []uint64 { - if m != nil { - return m.Mandatories - } - return nil +// Deprecated: Use Capabilities.ProtoReflect.Descriptor instead. +func (*Capabilities) Descriptor() ([]byte, []int) { + return file_net_lp_rpc_proto_rawDescGZIP(), []int{7} } -func (m *Capabilities) GetCapacities() map[uint32]uint32 { - if m != nil { - return m.Capacities +func (x *Capabilities) GetBitstring() []uint64 { + if x != nil { + return x.Bitstring } return nil } -func (m *Capabilities) GetVersion() string { - if m != nil { - return m.Version +func (x *Capabilities) GetMandatories() []uint64 { + if x != nil { + return x.Mandatories } - return "" + return nil } -func (m *Capabilities) GetConstraints() *Capabilities_Constraints { - if m != nil { - return m.Constraints +func (x *Capabilities) GetCapacities() map[uint32]uint32 { + if x != nil { + return x.Capacities } return nil } -// Non-binary capability constraints, such as supported ranges. -type Capabilities_Constraints struct { - MinVersion string `protobuf:"bytes,1,opt,name=minVersion,proto3" json:"minVersion,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *Capabilities_Constraints) Reset() { *m = Capabilities_Constraints{} } -func (m *Capabilities_Constraints) String() string { return proto.CompactTextString(m) } -func (*Capabilities_Constraints) ProtoMessage() {} -func (*Capabilities_Constraints) Descriptor() ([]byte, []int) { - return fileDescriptor_034e29c79f9ba827, []int{7, 1} -} - -func (m *Capabilities_Constraints) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Capabilities_Constraints.Unmarshal(m, b) -} -func (m *Capabilities_Constraints) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Capabilities_Constraints.Marshal(b, m, deterministic) -} -func (m *Capabilities_Constraints) XXX_Merge(src proto.Message) { - xxx_messageInfo_Capabilities_Constraints.Merge(m, src) -} -func (m *Capabilities_Constraints) XXX_Size() int { - return xxx_messageInfo_Capabilities_Constraints.Size(m) -} -func (m *Capabilities_Constraints) XXX_DiscardUnknown() { - xxx_messageInfo_Capabilities_Constraints.DiscardUnknown(m) +func (x *Capabilities) GetVersion() string { + if x != nil { + return x.Version + } + return "" } -var xxx_messageInfo_Capabilities_Constraints proto.InternalMessageInfo - -func (m *Capabilities_Constraints) GetMinVersion() string { - if m != nil { - return m.MinVersion +func (x *Capabilities) GetConstraints() *Capabilities_Constraints { + if x != nil { + return x.Constraints } - return "" + return nil } // The orchestrator sends this in response to `GetOrchestrator`, containing // miscellaneous data related to the job. type OrchestratorInfo struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + // URI of the transcoder to use for submitting segments. Transcoder string `protobuf:"bytes,1,opt,name=transcoder,proto3" json:"transcoder,omitempty"` // Parameters for probabilistic micropayment tickets @@ -646,148 +778,164 @@ type OrchestratorInfo struct { // Data for transcoding authentication AuthToken *AuthToken `protobuf:"bytes,6,opt,name=auth_token,json=authToken,proto3" json:"auth_token,omitempty"` // Orchestrator returns info about own input object storage, if it wants it to be used. - Storage []*OSInfo `protobuf:"bytes,32,rep,name=storage,proto3" json:"storage,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + Storage []*OSInfo `protobuf:"bytes,32,rep,name=storage,proto3" json:"storage,omitempty"` } -func (m *OrchestratorInfo) Reset() { *m = OrchestratorInfo{} } -func (m *OrchestratorInfo) String() string { return proto.CompactTextString(m) } -func (*OrchestratorInfo) ProtoMessage() {} -func (*OrchestratorInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_034e29c79f9ba827, []int{8} +func (x *OrchestratorInfo) Reset() { + *x = OrchestratorInfo{} + if protoimpl.UnsafeEnabled { + mi := &file_net_lp_rpc_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *OrchestratorInfo) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_OrchestratorInfo.Unmarshal(m, b) -} -func (m *OrchestratorInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_OrchestratorInfo.Marshal(b, m, deterministic) +func (x *OrchestratorInfo) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *OrchestratorInfo) XXX_Merge(src proto.Message) { - xxx_messageInfo_OrchestratorInfo.Merge(m, src) -} -func (m *OrchestratorInfo) XXX_Size() int { - return xxx_messageInfo_OrchestratorInfo.Size(m) -} -func (m *OrchestratorInfo) XXX_DiscardUnknown() { - xxx_messageInfo_OrchestratorInfo.DiscardUnknown(m) + +func (*OrchestratorInfo) ProtoMessage() {} + +func (x *OrchestratorInfo) ProtoReflect() protoreflect.Message { + mi := &file_net_lp_rpc_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var xxx_messageInfo_OrchestratorInfo proto.InternalMessageInfo +// Deprecated: Use OrchestratorInfo.ProtoReflect.Descriptor instead. +func (*OrchestratorInfo) Descriptor() ([]byte, []int) { + return file_net_lp_rpc_proto_rawDescGZIP(), []int{8} +} -func (m *OrchestratorInfo) GetTranscoder() string { - if m != nil { - return m.Transcoder +func (x *OrchestratorInfo) GetTranscoder() string { + if x != nil { + return x.Transcoder } return "" } -func (m *OrchestratorInfo) GetTicketParams() *TicketParams { - if m != nil { - return m.TicketParams +func (x *OrchestratorInfo) GetTicketParams() *TicketParams { + if x != nil { + return x.TicketParams } return nil } -func (m *OrchestratorInfo) GetPriceInfo() *PriceInfo { - if m != nil { - return m.PriceInfo +func (x *OrchestratorInfo) GetPriceInfo() *PriceInfo { + if x != nil { + return x.PriceInfo } return nil } -func (m *OrchestratorInfo) GetAddress() []byte { - if m != nil { - return m.Address +func (x *OrchestratorInfo) GetAddress() []byte { + if x != nil { + return x.Address } return nil } -func (m *OrchestratorInfo) GetCapabilities() *Capabilities { - if m != nil { - return m.Capabilities +func (x *OrchestratorInfo) GetCapabilities() *Capabilities { + if x != nil { + return x.Capabilities } return nil } -func (m *OrchestratorInfo) GetAuthToken() *AuthToken { - if m != nil { - return m.AuthToken +func (x *OrchestratorInfo) GetAuthToken() *AuthToken { + if x != nil { + return x.AuthToken } return nil } -func (m *OrchestratorInfo) GetStorage() []*OSInfo { - if m != nil { - return m.Storage +func (x *OrchestratorInfo) GetStorage() []*OSInfo { + if x != nil { + return x.Storage } return nil } // Data for transcoding authentication that is included in the OrchestratorInfo message during discovery type AuthToken struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + // Record used to authenticate for a transcode session // Opaque to the receiver Token []byte `protobuf:"bytes,1,opt,name=token,proto3" json:"token,omitempty"` // ID of the transcode session that the token is authenticating for SessionId string `protobuf:"bytes,2,opt,name=session_id,json=sessionId,proto3" json:"session_id,omitempty"` // Timestamp when the token expires - Expiration int64 `protobuf:"varint,3,opt,name=expiration,proto3" json:"expiration,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + Expiration int64 `protobuf:"varint,3,opt,name=expiration,proto3" json:"expiration,omitempty"` } -func (m *AuthToken) Reset() { *m = AuthToken{} } -func (m *AuthToken) String() string { return proto.CompactTextString(m) } -func (*AuthToken) ProtoMessage() {} -func (*AuthToken) Descriptor() ([]byte, []int) { - return fileDescriptor_034e29c79f9ba827, []int{9} +func (x *AuthToken) Reset() { + *x = AuthToken{} + if protoimpl.UnsafeEnabled { + mi := &file_net_lp_rpc_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *AuthToken) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_AuthToken.Unmarshal(m, b) -} -func (m *AuthToken) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_AuthToken.Marshal(b, m, deterministic) +func (x *AuthToken) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *AuthToken) XXX_Merge(src proto.Message) { - xxx_messageInfo_AuthToken.Merge(m, src) -} -func (m *AuthToken) XXX_Size() int { - return xxx_messageInfo_AuthToken.Size(m) -} -func (m *AuthToken) XXX_DiscardUnknown() { - xxx_messageInfo_AuthToken.DiscardUnknown(m) + +func (*AuthToken) ProtoMessage() {} + +func (x *AuthToken) ProtoReflect() protoreflect.Message { + mi := &file_net_lp_rpc_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var xxx_messageInfo_AuthToken proto.InternalMessageInfo +// Deprecated: Use AuthToken.ProtoReflect.Descriptor instead. +func (*AuthToken) Descriptor() ([]byte, []int) { + return file_net_lp_rpc_proto_rawDescGZIP(), []int{9} +} -func (m *AuthToken) GetToken() []byte { - if m != nil { - return m.Token +func (x *AuthToken) GetToken() []byte { + if x != nil { + return x.Token } return nil } -func (m *AuthToken) GetSessionId() string { - if m != nil { - return m.SessionId +func (x *AuthToken) GetSessionId() string { + if x != nil { + return x.SessionId } return "" } -func (m *AuthToken) GetExpiration() int64 { - if m != nil { - return m.Expiration +func (x *AuthToken) GetExpiration() int64 { + if x != nil { + return x.Expiration } return 0 } // Data included by the broadcaster when submitting a segment for transcoding. type SegData struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + // Manifest ID this segment belongs to ManifestId []byte `protobuf:"bytes,1,opt,name=manifestId,proto3" json:"manifestId,omitempty"` // Sequence number of the segment to be transcoded @@ -821,194 +969,210 @@ type SegData struct { // Transcoding parameters specific to this segment SegmentParameters *SegParameters `protobuf:"bytes,37,opt,name=segment_parameters,json=segmentParameters,proto3" json:"segment_parameters,omitempty"` // Force HW Session Reinit - ForceSessionReinit bool `protobuf:"varint,38,opt,name=ForceSessionReinit,proto3" json:"ForceSessionReinit,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + ForceSessionReinit bool `protobuf:"varint,38,opt,name=ForceSessionReinit,proto3" json:"ForceSessionReinit,omitempty"` } -func (m *SegData) Reset() { *m = SegData{} } -func (m *SegData) String() string { return proto.CompactTextString(m) } -func (*SegData) ProtoMessage() {} -func (*SegData) Descriptor() ([]byte, []int) { - return fileDescriptor_034e29c79f9ba827, []int{10} +func (x *SegData) Reset() { + *x = SegData{} + if protoimpl.UnsafeEnabled { + mi := &file_net_lp_rpc_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *SegData) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_SegData.Unmarshal(m, b) -} -func (m *SegData) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_SegData.Marshal(b, m, deterministic) +func (x *SegData) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *SegData) XXX_Merge(src proto.Message) { - xxx_messageInfo_SegData.Merge(m, src) -} -func (m *SegData) XXX_Size() int { - return xxx_messageInfo_SegData.Size(m) -} -func (m *SegData) XXX_DiscardUnknown() { - xxx_messageInfo_SegData.DiscardUnknown(m) + +func (*SegData) ProtoMessage() {} + +func (x *SegData) ProtoReflect() protoreflect.Message { + mi := &file_net_lp_rpc_proto_msgTypes[10] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var xxx_messageInfo_SegData proto.InternalMessageInfo +// Deprecated: Use SegData.ProtoReflect.Descriptor instead. +func (*SegData) Descriptor() ([]byte, []int) { + return file_net_lp_rpc_proto_rawDescGZIP(), []int{10} +} -func (m *SegData) GetManifestId() []byte { - if m != nil { - return m.ManifestId +func (x *SegData) GetManifestId() []byte { + if x != nil { + return x.ManifestId } return nil } -func (m *SegData) GetSeq() int64 { - if m != nil { - return m.Seq +func (x *SegData) GetSeq() int64 { + if x != nil { + return x.Seq } return 0 } -func (m *SegData) GetHash() []byte { - if m != nil { - return m.Hash +func (x *SegData) GetHash() []byte { + if x != nil { + return x.Hash } return nil } -func (m *SegData) GetProfiles() []byte { - if m != nil { - return m.Profiles +func (x *SegData) GetProfiles() []byte { + if x != nil { + return x.Profiles } return nil } -func (m *SegData) GetSig() []byte { - if m != nil { - return m.Sig +func (x *SegData) GetSig() []byte { + if x != nil { + return x.Sig } return nil } -func (m *SegData) GetDuration() int32 { - if m != nil { - return m.Duration +func (x *SegData) GetDuration() int32 { + if x != nil { + return x.Duration } return 0 } -func (m *SegData) GetCapabilities() *Capabilities { - if m != nil { - return m.Capabilities +func (x *SegData) GetCapabilities() *Capabilities { + if x != nil { + return x.Capabilities } return nil } -func (m *SegData) GetAuthToken() *AuthToken { - if m != nil { - return m.AuthToken +func (x *SegData) GetAuthToken() *AuthToken { + if x != nil { + return x.AuthToken } return nil } -func (m *SegData) GetCalcPerceptualHash() bool { - if m != nil { - return m.CalcPerceptualHash +func (x *SegData) GetCalcPerceptualHash() bool { + if x != nil { + return x.CalcPerceptualHash } return false } -func (m *SegData) GetStorage() []*OSInfo { - if m != nil { - return m.Storage +func (x *SegData) GetStorage() []*OSInfo { + if x != nil { + return x.Storage } return nil } -func (m *SegData) GetFullProfiles() []*VideoProfile { - if m != nil { - return m.FullProfiles +func (x *SegData) GetFullProfiles() []*VideoProfile { + if x != nil { + return x.FullProfiles } return nil } -func (m *SegData) GetFullProfiles2() []*VideoProfile { - if m != nil { - return m.FullProfiles2 +func (x *SegData) GetFullProfiles2() []*VideoProfile { + if x != nil { + return x.FullProfiles2 } return nil } -func (m *SegData) GetFullProfiles3() []*VideoProfile { - if m != nil { - return m.FullProfiles3 +func (x *SegData) GetFullProfiles3() []*VideoProfile { + if x != nil { + return x.FullProfiles3 } return nil } -func (m *SegData) GetSegmentParameters() *SegParameters { - if m != nil { - return m.SegmentParameters +func (x *SegData) GetSegmentParameters() *SegParameters { + if x != nil { + return x.SegmentParameters } return nil } -func (m *SegData) GetForceSessionReinit() bool { - if m != nil { - return m.ForceSessionReinit +func (x *SegData) GetForceSessionReinit() bool { + if x != nil { + return x.ForceSessionReinit } return false } type SegParameters struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + // Start timestamp from which to start encoding // Milliseconds, from start of the file From uint64 `protobuf:"varint,1,opt,name=from,proto3" json:"from,omitempty"` // Skip all frames after that timestamp // Milliseconds, from start of the file - To uint64 `protobuf:"varint,2,opt,name=to,proto3" json:"to,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + To uint64 `protobuf:"varint,2,opt,name=to,proto3" json:"to,omitempty"` } -func (m *SegParameters) Reset() { *m = SegParameters{} } -func (m *SegParameters) String() string { return proto.CompactTextString(m) } -func (*SegParameters) ProtoMessage() {} -func (*SegParameters) Descriptor() ([]byte, []int) { - return fileDescriptor_034e29c79f9ba827, []int{11} +func (x *SegParameters) Reset() { + *x = SegParameters{} + if protoimpl.UnsafeEnabled { + mi := &file_net_lp_rpc_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *SegParameters) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_SegParameters.Unmarshal(m, b) +func (x *SegParameters) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *SegParameters) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_SegParameters.Marshal(b, m, deterministic) -} -func (m *SegParameters) XXX_Merge(src proto.Message) { - xxx_messageInfo_SegParameters.Merge(m, src) -} -func (m *SegParameters) XXX_Size() int { - return xxx_messageInfo_SegParameters.Size(m) -} -func (m *SegParameters) XXX_DiscardUnknown() { - xxx_messageInfo_SegParameters.DiscardUnknown(m) + +func (*SegParameters) ProtoMessage() {} + +func (x *SegParameters) ProtoReflect() protoreflect.Message { + mi := &file_net_lp_rpc_proto_msgTypes[11] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var xxx_messageInfo_SegParameters proto.InternalMessageInfo +// Deprecated: Use SegParameters.ProtoReflect.Descriptor instead. +func (*SegParameters) Descriptor() ([]byte, []int) { + return file_net_lp_rpc_proto_rawDescGZIP(), []int{11} +} -func (m *SegParameters) GetFrom() uint64 { - if m != nil { - return m.From +func (x *SegParameters) GetFrom() uint64 { + if x != nil { + return x.From } return 0 } -func (m *SegParameters) GetTo() uint64 { - if m != nil { - return m.To +func (x *SegParameters) GetTo() uint64 { + if x != nil { + return x.To } return 0 } type VideoProfile struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + // Name of VideoProfile Name string `protobuf:"bytes,16,opt,name=name,proto3" json:"name,omitempty"` // Width of VideoProfile @@ -1027,306 +1191,318 @@ type VideoProfile struct { // GOP interval Gop int32 `protobuf:"varint,24,opt,name=gop,proto3" json:"gop,omitempty"` // Encoder (video codec) - Encoder VideoProfile_VideoCodec `protobuf:"varint,25,opt,name=encoder,proto3,enum=net.VideoProfile_VideoCodec" json:"encoder,omitempty"` - ColorDepth int32 `protobuf:"varint,26,opt,name=colorDepth,proto3" json:"colorDepth,omitempty"` - ChromaFormat VideoProfile_ChromaSubsampling `protobuf:"varint,27,opt,name=chromaFormat,proto3,enum=net.VideoProfile_ChromaSubsampling" json:"chromaFormat,omitempty"` - Quality uint32 `protobuf:"varint,28,opt,name=quality,proto3" json:"quality,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *VideoProfile) Reset() { *m = VideoProfile{} } -func (m *VideoProfile) String() string { return proto.CompactTextString(m) } -func (*VideoProfile) ProtoMessage() {} -func (*VideoProfile) Descriptor() ([]byte, []int) { - return fileDescriptor_034e29c79f9ba827, []int{12} + Encoder VideoProfile_VideoCodec `protobuf:"varint,25,opt,name=encoder,proto3,enum=net.VideoProfile_VideoCodec" json:"encoder,omitempty"` + ColorDepth int32 `protobuf:"varint,26,opt,name=colorDepth,proto3" json:"colorDepth,omitempty"` + ChromaFormat VideoProfile_ChromaSubsampling `protobuf:"varint,27,opt,name=chromaFormat,proto3,enum=net.VideoProfile_ChromaSubsampling" json:"chromaFormat,omitempty"` + Quality uint32 `protobuf:"varint,28,opt,name=quality,proto3" json:"quality,omitempty"` } -func (m *VideoProfile) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_VideoProfile.Unmarshal(m, b) -} -func (m *VideoProfile) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_VideoProfile.Marshal(b, m, deterministic) -} -func (m *VideoProfile) XXX_Merge(src proto.Message) { - xxx_messageInfo_VideoProfile.Merge(m, src) +func (x *VideoProfile) Reset() { + *x = VideoProfile{} + if protoimpl.UnsafeEnabled { + mi := &file_net_lp_rpc_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *VideoProfile) XXX_Size() int { - return xxx_messageInfo_VideoProfile.Size(m) + +func (x *VideoProfile) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *VideoProfile) XXX_DiscardUnknown() { - xxx_messageInfo_VideoProfile.DiscardUnknown(m) + +func (*VideoProfile) ProtoMessage() {} + +func (x *VideoProfile) ProtoReflect() protoreflect.Message { + mi := &file_net_lp_rpc_proto_msgTypes[12] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var xxx_messageInfo_VideoProfile proto.InternalMessageInfo +// Deprecated: Use VideoProfile.ProtoReflect.Descriptor instead. +func (*VideoProfile) Descriptor() ([]byte, []int) { + return file_net_lp_rpc_proto_rawDescGZIP(), []int{12} +} -func (m *VideoProfile) GetName() string { - if m != nil { - return m.Name +func (x *VideoProfile) GetName() string { + if x != nil { + return x.Name } return "" } -func (m *VideoProfile) GetWidth() int32 { - if m != nil { - return m.Width +func (x *VideoProfile) GetWidth() int32 { + if x != nil { + return x.Width } return 0 } -func (m *VideoProfile) GetHeight() int32 { - if m != nil { - return m.Height +func (x *VideoProfile) GetHeight() int32 { + if x != nil { + return x.Height } return 0 } -func (m *VideoProfile) GetBitrate() int32 { - if m != nil { - return m.Bitrate +func (x *VideoProfile) GetBitrate() int32 { + if x != nil { + return x.Bitrate } return 0 } -func (m *VideoProfile) GetFps() uint32 { - if m != nil { - return m.Fps +func (x *VideoProfile) GetFps() uint32 { + if x != nil { + return x.Fps } return 0 } -func (m *VideoProfile) GetFormat() VideoProfile_Format { - if m != nil { - return m.Format +func (x *VideoProfile) GetFormat() VideoProfile_Format { + if x != nil { + return x.Format } return VideoProfile_MPEGTS } -func (m *VideoProfile) GetFpsDen() uint32 { - if m != nil { - return m.FpsDen +func (x *VideoProfile) GetFpsDen() uint32 { + if x != nil { + return x.FpsDen } return 0 } -func (m *VideoProfile) GetProfile() VideoProfile_Profile { - if m != nil { - return m.Profile +func (x *VideoProfile) GetProfile() VideoProfile_Profile { + if x != nil { + return x.Profile } return VideoProfile_ENCODER_DEFAULT } -func (m *VideoProfile) GetGop() int32 { - if m != nil { - return m.Gop +func (x *VideoProfile) GetGop() int32 { + if x != nil { + return x.Gop } return 0 } -func (m *VideoProfile) GetEncoder() VideoProfile_VideoCodec { - if m != nil { - return m.Encoder +func (x *VideoProfile) GetEncoder() VideoProfile_VideoCodec { + if x != nil { + return x.Encoder } return VideoProfile_H264 } -func (m *VideoProfile) GetColorDepth() int32 { - if m != nil { - return m.ColorDepth +func (x *VideoProfile) GetColorDepth() int32 { + if x != nil { + return x.ColorDepth } return 0 } -func (m *VideoProfile) GetChromaFormat() VideoProfile_ChromaSubsampling { - if m != nil { - return m.ChromaFormat +func (x *VideoProfile) GetChromaFormat() VideoProfile_ChromaSubsampling { + if x != nil { + return x.ChromaFormat } return VideoProfile_CHROMA_420 } -func (m *VideoProfile) GetQuality() uint32 { - if m != nil { - return m.Quality +func (x *VideoProfile) GetQuality() uint32 { + if x != nil { + return x.Quality } return 0 } // Individual transcoded segment data. type TranscodedSegmentData struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + // URL where the transcoded data can be downloaded from. Url string `protobuf:"bytes,1,opt,name=url,proto3" json:"url,omitempty"` // Amount of pixels processed (output pixels) Pixels int64 `protobuf:"varint,2,opt,name=pixels,proto3" json:"pixels,omitempty"` // URL where the perceptual hash data can be downloaded from (can be empty) - PerceptualHashUrl string `protobuf:"bytes,3,opt,name=perceptual_hash_url,json=perceptualHashUrl,proto3" json:"perceptual_hash_url,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + PerceptualHashUrl string `protobuf:"bytes,3,opt,name=perceptual_hash_url,json=perceptualHashUrl,proto3" json:"perceptual_hash_url,omitempty"` } -func (m *TranscodedSegmentData) Reset() { *m = TranscodedSegmentData{} } -func (m *TranscodedSegmentData) String() string { return proto.CompactTextString(m) } -func (*TranscodedSegmentData) ProtoMessage() {} -func (*TranscodedSegmentData) Descriptor() ([]byte, []int) { - return fileDescriptor_034e29c79f9ba827, []int{13} +func (x *TranscodedSegmentData) Reset() { + *x = TranscodedSegmentData{} + if protoimpl.UnsafeEnabled { + mi := &file_net_lp_rpc_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *TranscodedSegmentData) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_TranscodedSegmentData.Unmarshal(m, b) -} -func (m *TranscodedSegmentData) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_TranscodedSegmentData.Marshal(b, m, deterministic) -} -func (m *TranscodedSegmentData) XXX_Merge(src proto.Message) { - xxx_messageInfo_TranscodedSegmentData.Merge(m, src) -} -func (m *TranscodedSegmentData) XXX_Size() int { - return xxx_messageInfo_TranscodedSegmentData.Size(m) +func (x *TranscodedSegmentData) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *TranscodedSegmentData) XXX_DiscardUnknown() { - xxx_messageInfo_TranscodedSegmentData.DiscardUnknown(m) + +func (*TranscodedSegmentData) ProtoMessage() {} + +func (x *TranscodedSegmentData) ProtoReflect() protoreflect.Message { + mi := &file_net_lp_rpc_proto_msgTypes[13] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var xxx_messageInfo_TranscodedSegmentData proto.InternalMessageInfo +// Deprecated: Use TranscodedSegmentData.ProtoReflect.Descriptor instead. +func (*TranscodedSegmentData) Descriptor() ([]byte, []int) { + return file_net_lp_rpc_proto_rawDescGZIP(), []int{13} +} -func (m *TranscodedSegmentData) GetUrl() string { - if m != nil { - return m.Url +func (x *TranscodedSegmentData) GetUrl() string { + if x != nil { + return x.Url } return "" } -func (m *TranscodedSegmentData) GetPixels() int64 { - if m != nil { - return m.Pixels +func (x *TranscodedSegmentData) GetPixels() int64 { + if x != nil { + return x.Pixels } return 0 } -func (m *TranscodedSegmentData) GetPerceptualHashUrl() string { - if m != nil { - return m.PerceptualHashUrl +func (x *TranscodedSegmentData) GetPerceptualHashUrl() string { + if x != nil { + return x.PerceptualHashUrl } return "" } // A set of transcoded segments following the profiles specified in the job. type TranscodeData struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + // Transcoded data, in the order specified in the job options Segments []*TranscodedSegmentData `protobuf:"bytes,1,rep,name=segments,proto3" json:"segments,omitempty"` // Signature of the hash of the concatenated hashes - Sig []byte `protobuf:"bytes,2,opt,name=sig,proto3" json:"sig,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + Sig []byte `protobuf:"bytes,2,opt,name=sig,proto3" json:"sig,omitempty"` } -func (m *TranscodeData) Reset() { *m = TranscodeData{} } -func (m *TranscodeData) String() string { return proto.CompactTextString(m) } -func (*TranscodeData) ProtoMessage() {} -func (*TranscodeData) Descriptor() ([]byte, []int) { - return fileDescriptor_034e29c79f9ba827, []int{14} +func (x *TranscodeData) Reset() { + *x = TranscodeData{} + if protoimpl.UnsafeEnabled { + mi := &file_net_lp_rpc_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *TranscodeData) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_TranscodeData.Unmarshal(m, b) -} -func (m *TranscodeData) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_TranscodeData.Marshal(b, m, deterministic) -} -func (m *TranscodeData) XXX_Merge(src proto.Message) { - xxx_messageInfo_TranscodeData.Merge(m, src) -} -func (m *TranscodeData) XXX_Size() int { - return xxx_messageInfo_TranscodeData.Size(m) +func (x *TranscodeData) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *TranscodeData) XXX_DiscardUnknown() { - xxx_messageInfo_TranscodeData.DiscardUnknown(m) + +func (*TranscodeData) ProtoMessage() {} + +func (x *TranscodeData) ProtoReflect() protoreflect.Message { + mi := &file_net_lp_rpc_proto_msgTypes[14] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var xxx_messageInfo_TranscodeData proto.InternalMessageInfo +// Deprecated: Use TranscodeData.ProtoReflect.Descriptor instead. +func (*TranscodeData) Descriptor() ([]byte, []int) { + return file_net_lp_rpc_proto_rawDescGZIP(), []int{14} +} -func (m *TranscodeData) GetSegments() []*TranscodedSegmentData { - if m != nil { - return m.Segments +func (x *TranscodeData) GetSegments() []*TranscodedSegmentData { + if x != nil { + return x.Segments } return nil } -func (m *TranscodeData) GetSig() []byte { - if m != nil { - return m.Sig +func (x *TranscodeData) GetSig() []byte { + if x != nil { + return x.Sig } return nil } // Response that a transcoder sends after transcoding a segment. type TranscodeResult struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + // Sequence number of the transcoded results. Seq int64 `protobuf:"varint,1,opt,name=seq,proto3" json:"seq,omitempty"` // Result of transcoding can be an error, or successful with more info // - // Types that are valid to be assigned to Result: + // Types that are assignable to Result: // // *TranscodeResult_Error // *TranscodeResult_Data Result isTranscodeResult_Result `protobuf_oneof:"result"` // Used to notify a broadcaster of updated orchestrator information - Info *OrchestratorInfo `protobuf:"bytes,16,opt,name=info,proto3" json:"info,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + Info *OrchestratorInfo `protobuf:"bytes,16,opt,name=info,proto3" json:"info,omitempty"` } -func (m *TranscodeResult) Reset() { *m = TranscodeResult{} } -func (m *TranscodeResult) String() string { return proto.CompactTextString(m) } -func (*TranscodeResult) ProtoMessage() {} -func (*TranscodeResult) Descriptor() ([]byte, []int) { - return fileDescriptor_034e29c79f9ba827, []int{15} +func (x *TranscodeResult) Reset() { + *x = TranscodeResult{} + if protoimpl.UnsafeEnabled { + mi := &file_net_lp_rpc_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *TranscodeResult) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_TranscodeResult.Unmarshal(m, b) -} -func (m *TranscodeResult) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_TranscodeResult.Marshal(b, m, deterministic) -} -func (m *TranscodeResult) XXX_Merge(src proto.Message) { - xxx_messageInfo_TranscodeResult.Merge(m, src) -} -func (m *TranscodeResult) XXX_Size() int { - return xxx_messageInfo_TranscodeResult.Size(m) -} -func (m *TranscodeResult) XXX_DiscardUnknown() { - xxx_messageInfo_TranscodeResult.DiscardUnknown(m) +func (x *TranscodeResult) String() string { + return protoimpl.X.MessageStringOf(x) } -var xxx_messageInfo_TranscodeResult proto.InternalMessageInfo +func (*TranscodeResult) ProtoMessage() {} -func (m *TranscodeResult) GetSeq() int64 { - if m != nil { - return m.Seq +func (x *TranscodeResult) ProtoReflect() protoreflect.Message { + mi := &file_net_lp_rpc_proto_msgTypes[15] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms } - return 0 -} - -type isTranscodeResult_Result interface { - isTranscodeResult_Result() + return mi.MessageOf(x) } -type TranscodeResult_Error struct { - Error string `protobuf:"bytes,2,opt,name=error,proto3,oneof"` +// Deprecated: Use TranscodeResult.ProtoReflect.Descriptor instead. +func (*TranscodeResult) Descriptor() ([]byte, []int) { + return file_net_lp_rpc_proto_rawDescGZIP(), []int{15} } -type TranscodeResult_Data struct { - Data *TranscodeData `protobuf:"bytes,3,opt,name=data,proto3,oneof"` +func (x *TranscodeResult) GetSeq() int64 { + if x != nil { + return x.Seq + } + return 0 } -func (*TranscodeResult_Error) isTranscodeResult_Result() {} - -func (*TranscodeResult_Data) isTranscodeResult_Result() {} - func (m *TranscodeResult) GetResult() isTranscodeResult_Result { if m != nil { return m.Result @@ -1334,165 +1510,202 @@ func (m *TranscodeResult) GetResult() isTranscodeResult_Result { return nil } -func (m *TranscodeResult) GetError() string { - if x, ok := m.GetResult().(*TranscodeResult_Error); ok { +func (x *TranscodeResult) GetError() string { + if x, ok := x.GetResult().(*TranscodeResult_Error); ok { return x.Error } return "" } -func (m *TranscodeResult) GetData() *TranscodeData { - if x, ok := m.GetResult().(*TranscodeResult_Data); ok { +func (x *TranscodeResult) GetData() *TranscodeData { + if x, ok := x.GetResult().(*TranscodeResult_Data); ok { return x.Data } return nil } -func (m *TranscodeResult) GetInfo() *OrchestratorInfo { - if m != nil { - return m.Info +func (x *TranscodeResult) GetInfo() *OrchestratorInfo { + if x != nil { + return x.Info } return nil } -// XXX_OneofWrappers is for the internal use of the proto package. -func (*TranscodeResult) XXX_OneofWrappers() []interface{} { - return []interface{}{ - (*TranscodeResult_Error)(nil), - (*TranscodeResult_Data)(nil), - } +type isTranscodeResult_Result interface { + isTranscodeResult_Result() +} + +type TranscodeResult_Error struct { + Error string `protobuf:"bytes,2,opt,name=error,proto3,oneof"` } +type TranscodeResult_Data struct { + Data *TranscodeData `protobuf:"bytes,3,opt,name=data,proto3,oneof"` +} + +func (*TranscodeResult_Error) isTranscodeResult_Result() {} + +func (*TranscodeResult_Data) isTranscodeResult_Result() {} + // Sent by the transcoder to register itself to the orchestrator. type RegisterRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + // Shared secret for auth Secret string `protobuf:"bytes,1,opt,name=secret,proto3" json:"secret,omitempty"` // Transcoder capacity Capacity int64 `protobuf:"varint,2,opt,name=capacity,proto3" json:"capacity,omitempty"` // Transcoder capabilities - Capabilities *Capabilities `protobuf:"bytes,3,opt,name=capabilities,proto3" json:"capabilities,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + Capabilities *Capabilities `protobuf:"bytes,3,opt,name=capabilities,proto3" json:"capabilities,omitempty"` } -func (m *RegisterRequest) Reset() { *m = RegisterRequest{} } -func (m *RegisterRequest) String() string { return proto.CompactTextString(m) } -func (*RegisterRequest) ProtoMessage() {} -func (*RegisterRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_034e29c79f9ba827, []int{16} +func (x *RegisterRequest) Reset() { + *x = RegisterRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_net_lp_rpc_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *RegisterRequest) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_RegisterRequest.Unmarshal(m, b) -} -func (m *RegisterRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_RegisterRequest.Marshal(b, m, deterministic) +func (x *RegisterRequest) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *RegisterRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_RegisterRequest.Merge(m, src) -} -func (m *RegisterRequest) XXX_Size() int { - return xxx_messageInfo_RegisterRequest.Size(m) -} -func (m *RegisterRequest) XXX_DiscardUnknown() { - xxx_messageInfo_RegisterRequest.DiscardUnknown(m) + +func (*RegisterRequest) ProtoMessage() {} + +func (x *RegisterRequest) ProtoReflect() protoreflect.Message { + mi := &file_net_lp_rpc_proto_msgTypes[16] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var xxx_messageInfo_RegisterRequest proto.InternalMessageInfo +// Deprecated: Use RegisterRequest.ProtoReflect.Descriptor instead. +func (*RegisterRequest) Descriptor() ([]byte, []int) { + return file_net_lp_rpc_proto_rawDescGZIP(), []int{16} +} -func (m *RegisterRequest) GetSecret() string { - if m != nil { - return m.Secret +func (x *RegisterRequest) GetSecret() string { + if x != nil { + return x.Secret } return "" } -func (m *RegisterRequest) GetCapacity() int64 { - if m != nil { - return m.Capacity +func (x *RegisterRequest) GetCapacity() int64 { + if x != nil { + return x.Capacity } return 0 } -func (m *RegisterRequest) GetCapabilities() *Capabilities { - if m != nil { - return m.Capabilities +func (x *RegisterRequest) GetCapabilities() *Capabilities { + if x != nil { + return x.Capabilities } return nil } // Sent by the orchestrator to the transcoder type NotifySegment struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + // URL of the segment to transcode. Url string `protobuf:"bytes,1,opt,name=url,proto3" json:"url,omitempty"` // Configuration for the transcoding job SegData *SegData `protobuf:"bytes,3,opt,name=segData,proto3" json:"segData,omitempty"` // ID for this particular transcoding task. TaskId int64 `protobuf:"varint,16,opt,name=taskId,proto3" json:"taskId,omitempty"` + // Orchestrator identifier for segment metadata + OrchId string `protobuf:"bytes,18,opt,name=orchId,proto3" json:"orchId,omitempty"` // Deprecated by fullProfiles. Set of presets to transcode into. // Should be set to an invalid value to induce failures - Profiles []byte `protobuf:"bytes,17,opt,name=profiles,proto3" json:"profiles,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + Profiles []byte `protobuf:"bytes,17,opt,name=profiles,proto3" json:"profiles,omitempty"` } -func (m *NotifySegment) Reset() { *m = NotifySegment{} } -func (m *NotifySegment) String() string { return proto.CompactTextString(m) } -func (*NotifySegment) ProtoMessage() {} -func (*NotifySegment) Descriptor() ([]byte, []int) { - return fileDescriptor_034e29c79f9ba827, []int{17} +func (x *NotifySegment) Reset() { + *x = NotifySegment{} + if protoimpl.UnsafeEnabled { + mi := &file_net_lp_rpc_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *NotifySegment) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_NotifySegment.Unmarshal(m, b) -} -func (m *NotifySegment) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_NotifySegment.Marshal(b, m, deterministic) -} -func (m *NotifySegment) XXX_Merge(src proto.Message) { - xxx_messageInfo_NotifySegment.Merge(m, src) +func (x *NotifySegment) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *NotifySegment) XXX_Size() int { - return xxx_messageInfo_NotifySegment.Size(m) -} -func (m *NotifySegment) XXX_DiscardUnknown() { - xxx_messageInfo_NotifySegment.DiscardUnknown(m) + +func (*NotifySegment) ProtoMessage() {} + +func (x *NotifySegment) ProtoReflect() protoreflect.Message { + mi := &file_net_lp_rpc_proto_msgTypes[17] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var xxx_messageInfo_NotifySegment proto.InternalMessageInfo +// Deprecated: Use NotifySegment.ProtoReflect.Descriptor instead. +func (*NotifySegment) Descriptor() ([]byte, []int) { + return file_net_lp_rpc_proto_rawDescGZIP(), []int{17} +} -func (m *NotifySegment) GetUrl() string { - if m != nil { - return m.Url +func (x *NotifySegment) GetUrl() string { + if x != nil { + return x.Url } return "" } -func (m *NotifySegment) GetSegData() *SegData { - if m != nil { - return m.SegData +func (x *NotifySegment) GetSegData() *SegData { + if x != nil { + return x.SegData } return nil } -func (m *NotifySegment) GetTaskId() int64 { - if m != nil { - return m.TaskId +func (x *NotifySegment) GetTaskId() int64 { + if x != nil { + return x.TaskId } return 0 } -func (m *NotifySegment) GetProfiles() []byte { - if m != nil { - return m.Profiles +func (x *NotifySegment) GetOrchId() string { + if x != nil { + return x.OrchId + } + return "" +} + +func (x *NotifySegment) GetProfiles() []byte { + if x != nil { + return x.Profiles } return nil } // Required parameters for probabilistic micropayment tickets type TicketParams struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + // ETH address of the recipient Recipient []byte `protobuf:"bytes,1,opt,name=recipient,proto3" json:"recipient,omitempty"` // Pay out (in Wei) to the recipient if the ticket wins @@ -1508,183 +1721,203 @@ type TicketParams struct { // Block number at which the current set of advertised TicketParams is no longer valid ExpirationBlock []byte `protobuf:"bytes,6,opt,name=expiration_block,json=expirationBlock,proto3" json:"expiration_block,omitempty"` // Expected ticket expiration params - ExpirationParams *TicketExpirationParams `protobuf:"bytes,7,opt,name=expiration_params,json=expirationParams,proto3" json:"expiration_params,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + ExpirationParams *TicketExpirationParams `protobuf:"bytes,7,opt,name=expiration_params,json=expirationParams,proto3" json:"expiration_params,omitempty"` } -func (m *TicketParams) Reset() { *m = TicketParams{} } -func (m *TicketParams) String() string { return proto.CompactTextString(m) } -func (*TicketParams) ProtoMessage() {} -func (*TicketParams) Descriptor() ([]byte, []int) { - return fileDescriptor_034e29c79f9ba827, []int{18} +func (x *TicketParams) Reset() { + *x = TicketParams{} + if protoimpl.UnsafeEnabled { + mi := &file_net_lp_rpc_proto_msgTypes[18] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *TicketParams) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_TicketParams.Unmarshal(m, b) -} -func (m *TicketParams) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_TicketParams.Marshal(b, m, deterministic) +func (x *TicketParams) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *TicketParams) XXX_Merge(src proto.Message) { - xxx_messageInfo_TicketParams.Merge(m, src) -} -func (m *TicketParams) XXX_Size() int { - return xxx_messageInfo_TicketParams.Size(m) -} -func (m *TicketParams) XXX_DiscardUnknown() { - xxx_messageInfo_TicketParams.DiscardUnknown(m) + +func (*TicketParams) ProtoMessage() {} + +func (x *TicketParams) ProtoReflect() protoreflect.Message { + mi := &file_net_lp_rpc_proto_msgTypes[18] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var xxx_messageInfo_TicketParams proto.InternalMessageInfo +// Deprecated: Use TicketParams.ProtoReflect.Descriptor instead. +func (*TicketParams) Descriptor() ([]byte, []int) { + return file_net_lp_rpc_proto_rawDescGZIP(), []int{18} +} -func (m *TicketParams) GetRecipient() []byte { - if m != nil { - return m.Recipient +func (x *TicketParams) GetRecipient() []byte { + if x != nil { + return x.Recipient } return nil } -func (m *TicketParams) GetFaceValue() []byte { - if m != nil { - return m.FaceValue +func (x *TicketParams) GetFaceValue() []byte { + if x != nil { + return x.FaceValue } return nil } -func (m *TicketParams) GetWinProb() []byte { - if m != nil { - return m.WinProb +func (x *TicketParams) GetWinProb() []byte { + if x != nil { + return x.WinProb } return nil } -func (m *TicketParams) GetRecipientRandHash() []byte { - if m != nil { - return m.RecipientRandHash +func (x *TicketParams) GetRecipientRandHash() []byte { + if x != nil { + return x.RecipientRandHash } return nil } -func (m *TicketParams) GetSeed() []byte { - if m != nil { - return m.Seed +func (x *TicketParams) GetSeed() []byte { + if x != nil { + return x.Seed } return nil } -func (m *TicketParams) GetExpirationBlock() []byte { - if m != nil { - return m.ExpirationBlock +func (x *TicketParams) GetExpirationBlock() []byte { + if x != nil { + return x.ExpirationBlock } return nil } -func (m *TicketParams) GetExpirationParams() *TicketExpirationParams { - if m != nil { - return m.ExpirationParams +func (x *TicketParams) GetExpirationParams() *TicketExpirationParams { + if x != nil { + return x.ExpirationParams } return nil } // Sender Params (nonces and signatures) type TicketSenderParams struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + // Monotonically increasing counter that makes the ticket // unique relative to a particular hash commitment to a recipient's random number SenderNonce uint32 `protobuf:"varint,1,opt,name=sender_nonce,json=senderNonce,proto3" json:"sender_nonce,omitempty"` // Sender signature over the ticket - Sig []byte `protobuf:"bytes,2,opt,name=sig,proto3" json:"sig,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + Sig []byte `protobuf:"bytes,2,opt,name=sig,proto3" json:"sig,omitempty"` } -func (m *TicketSenderParams) Reset() { *m = TicketSenderParams{} } -func (m *TicketSenderParams) String() string { return proto.CompactTextString(m) } -func (*TicketSenderParams) ProtoMessage() {} -func (*TicketSenderParams) Descriptor() ([]byte, []int) { - return fileDescriptor_034e29c79f9ba827, []int{19} +func (x *TicketSenderParams) Reset() { + *x = TicketSenderParams{} + if protoimpl.UnsafeEnabled { + mi := &file_net_lp_rpc_proto_msgTypes[19] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *TicketSenderParams) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_TicketSenderParams.Unmarshal(m, b) -} -func (m *TicketSenderParams) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_TicketSenderParams.Marshal(b, m, deterministic) +func (x *TicketSenderParams) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *TicketSenderParams) XXX_Merge(src proto.Message) { - xxx_messageInfo_TicketSenderParams.Merge(m, src) -} -func (m *TicketSenderParams) XXX_Size() int { - return xxx_messageInfo_TicketSenderParams.Size(m) -} -func (m *TicketSenderParams) XXX_DiscardUnknown() { - xxx_messageInfo_TicketSenderParams.DiscardUnknown(m) + +func (*TicketSenderParams) ProtoMessage() {} + +func (x *TicketSenderParams) ProtoReflect() protoreflect.Message { + mi := &file_net_lp_rpc_proto_msgTypes[19] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var xxx_messageInfo_TicketSenderParams proto.InternalMessageInfo +// Deprecated: Use TicketSenderParams.ProtoReflect.Descriptor instead. +func (*TicketSenderParams) Descriptor() ([]byte, []int) { + return file_net_lp_rpc_proto_rawDescGZIP(), []int{19} +} -func (m *TicketSenderParams) GetSenderNonce() uint32 { - if m != nil { - return m.SenderNonce +func (x *TicketSenderParams) GetSenderNonce() uint32 { + if x != nil { + return x.SenderNonce } return 0 } -func (m *TicketSenderParams) GetSig() []byte { - if m != nil { - return m.Sig +func (x *TicketSenderParams) GetSig() []byte { + if x != nil { + return x.Sig } return nil } // Ticket params for expiration related validation type TicketExpirationParams struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + // Round during which tickets are created CreationRound int64 `protobuf:"varint,1,opt,name=creation_round,json=creationRound,proto3" json:"creation_round,omitempty"` // Block hash associated with creation_round - CreationRoundBlockHash []byte `protobuf:"bytes,2,opt,name=creation_round_block_hash,json=creationRoundBlockHash,proto3" json:"creation_round_block_hash,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + CreationRoundBlockHash []byte `protobuf:"bytes,2,opt,name=creation_round_block_hash,json=creationRoundBlockHash,proto3" json:"creation_round_block_hash,omitempty"` } -func (m *TicketExpirationParams) Reset() { *m = TicketExpirationParams{} } -func (m *TicketExpirationParams) String() string { return proto.CompactTextString(m) } -func (*TicketExpirationParams) ProtoMessage() {} -func (*TicketExpirationParams) Descriptor() ([]byte, []int) { - return fileDescriptor_034e29c79f9ba827, []int{20} +func (x *TicketExpirationParams) Reset() { + *x = TicketExpirationParams{} + if protoimpl.UnsafeEnabled { + mi := &file_net_lp_rpc_proto_msgTypes[20] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *TicketExpirationParams) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_TicketExpirationParams.Unmarshal(m, b) -} -func (m *TicketExpirationParams) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_TicketExpirationParams.Marshal(b, m, deterministic) -} -func (m *TicketExpirationParams) XXX_Merge(src proto.Message) { - xxx_messageInfo_TicketExpirationParams.Merge(m, src) -} -func (m *TicketExpirationParams) XXX_Size() int { - return xxx_messageInfo_TicketExpirationParams.Size(m) +func (x *TicketExpirationParams) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *TicketExpirationParams) XXX_DiscardUnknown() { - xxx_messageInfo_TicketExpirationParams.DiscardUnknown(m) + +func (*TicketExpirationParams) ProtoMessage() {} + +func (x *TicketExpirationParams) ProtoReflect() protoreflect.Message { + mi := &file_net_lp_rpc_proto_msgTypes[20] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var xxx_messageInfo_TicketExpirationParams proto.InternalMessageInfo +// Deprecated: Use TicketExpirationParams.ProtoReflect.Descriptor instead. +func (*TicketExpirationParams) Descriptor() ([]byte, []int) { + return file_net_lp_rpc_proto_rawDescGZIP(), []int{20} +} -func (m *TicketExpirationParams) GetCreationRound() int64 { - if m != nil { - return m.CreationRound +func (x *TicketExpirationParams) GetCreationRound() int64 { + if x != nil { + return x.CreationRound } return 0 } -func (m *TicketExpirationParams) GetCreationRoundBlockHash() []byte { - if m != nil { - return m.CreationRoundBlockHash +func (x *TicketExpirationParams) GetCreationRoundBlockHash() []byte { + if x != nil { + return x.CreationRoundBlockHash } return nil } @@ -1693,6 +1926,10 @@ func (m *TicketExpirationParams) GetCreationRoundBlockHash() []byte { // A payment can constitute of multiple tickets // A broadcaster might need to send multiple tickets to top up his credit with an Orchestrator type Payment struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + // Probabilistic micropayment ticket parameters // These remain the same even when sending multiple tickets TicketParams *TicketParams `protobuf:"bytes,1,opt,name=ticket_params,json=ticketParams,proto3" json:"ticket_params,omitempty"` @@ -1702,228 +1939,811 @@ type Payment struct { ExpirationParams *TicketExpirationParams `protobuf:"bytes,3,opt,name=expiration_params,json=expirationParams,proto3" json:"expiration_params,omitempty"` TicketSenderParams []*TicketSenderParams `protobuf:"bytes,4,rep,name=ticket_sender_params,json=ticketSenderParams,proto3" json:"ticket_sender_params,omitempty"` // O's last known price - ExpectedPrice *PriceInfo `protobuf:"bytes,5,opt,name=expected_price,json=expectedPrice,proto3" json:"expected_price,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + ExpectedPrice *PriceInfo `protobuf:"bytes,5,opt,name=expected_price,json=expectedPrice,proto3" json:"expected_price,omitempty"` } -func (m *Payment) Reset() { *m = Payment{} } -func (m *Payment) String() string { return proto.CompactTextString(m) } -func (*Payment) ProtoMessage() {} -func (*Payment) Descriptor() ([]byte, []int) { - return fileDescriptor_034e29c79f9ba827, []int{21} +func (x *Payment) Reset() { + *x = Payment{} + if protoimpl.UnsafeEnabled { + mi := &file_net_lp_rpc_proto_msgTypes[21] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *Payment) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Payment.Unmarshal(m, b) -} -func (m *Payment) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Payment.Marshal(b, m, deterministic) +func (x *Payment) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *Payment) XXX_Merge(src proto.Message) { - xxx_messageInfo_Payment.Merge(m, src) -} -func (m *Payment) XXX_Size() int { - return xxx_messageInfo_Payment.Size(m) -} -func (m *Payment) XXX_DiscardUnknown() { - xxx_messageInfo_Payment.DiscardUnknown(m) + +func (*Payment) ProtoMessage() {} + +func (x *Payment) ProtoReflect() protoreflect.Message { + mi := &file_net_lp_rpc_proto_msgTypes[21] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var xxx_messageInfo_Payment proto.InternalMessageInfo +// Deprecated: Use Payment.ProtoReflect.Descriptor instead. +func (*Payment) Descriptor() ([]byte, []int) { + return file_net_lp_rpc_proto_rawDescGZIP(), []int{21} +} -func (m *Payment) GetTicketParams() *TicketParams { - if m != nil { - return m.TicketParams +func (x *Payment) GetTicketParams() *TicketParams { + if x != nil { + return x.TicketParams } return nil } -func (m *Payment) GetSender() []byte { - if m != nil { - return m.Sender +func (x *Payment) GetSender() []byte { + if x != nil { + return x.Sender } return nil } -func (m *Payment) GetExpirationParams() *TicketExpirationParams { - if m != nil { - return m.ExpirationParams +func (x *Payment) GetExpirationParams() *TicketExpirationParams { + if x != nil { + return x.ExpirationParams } return nil } -func (m *Payment) GetTicketSenderParams() []*TicketSenderParams { - if m != nil { - return m.TicketSenderParams +func (x *Payment) GetTicketSenderParams() []*TicketSenderParams { + if x != nil { + return x.TicketSenderParams } return nil } -func (m *Payment) GetExpectedPrice() *PriceInfo { - if m != nil { - return m.ExpectedPrice +func (x *Payment) GetExpectedPrice() *PriceInfo { + if x != nil { + return x.ExpectedPrice } return nil } -func init() { - proto.RegisterEnum("net.OSInfo_StorageType", OSInfo_StorageType_name, OSInfo_StorageType_value) - proto.RegisterEnum("net.VideoProfile_Format", VideoProfile_Format_name, VideoProfile_Format_value) - proto.RegisterEnum("net.VideoProfile_Profile", VideoProfile_Profile_name, VideoProfile_Profile_value) - proto.RegisterEnum("net.VideoProfile_VideoCodec", VideoProfile_VideoCodec_name, VideoProfile_VideoCodec_value) - proto.RegisterEnum("net.VideoProfile_ChromaSubsampling", VideoProfile_ChromaSubsampling_name, VideoProfile_ChromaSubsampling_value) - proto.RegisterType((*PingPong)(nil), "net.PingPong") - proto.RegisterType((*EndTranscodingSessionRequest)(nil), "net.EndTranscodingSessionRequest") - proto.RegisterType((*EndTranscodingSessionResponse)(nil), "net.EndTranscodingSessionResponse") - proto.RegisterType((*OrchestratorRequest)(nil), "net.OrchestratorRequest") - proto.RegisterType((*OSInfo)(nil), "net.OSInfo") - proto.RegisterType((*S3OSInfo)(nil), "net.S3OSInfo") - proto.RegisterType((*PriceInfo)(nil), "net.PriceInfo") - proto.RegisterType((*Capabilities)(nil), "net.Capabilities") - proto.RegisterMapType((map[uint32]uint32)(nil), "net.Capabilities.CapacitiesEntry") - proto.RegisterType((*Capabilities_Constraints)(nil), "net.Capabilities.Constraints") - proto.RegisterType((*OrchestratorInfo)(nil), "net.OrchestratorInfo") - proto.RegisterType((*AuthToken)(nil), "net.AuthToken") - proto.RegisterType((*SegData)(nil), "net.SegData") - proto.RegisterType((*SegParameters)(nil), "net.SegParameters") - proto.RegisterType((*VideoProfile)(nil), "net.VideoProfile") - proto.RegisterType((*TranscodedSegmentData)(nil), "net.TranscodedSegmentData") - proto.RegisterType((*TranscodeData)(nil), "net.TranscodeData") - proto.RegisterType((*TranscodeResult)(nil), "net.TranscodeResult") - proto.RegisterType((*RegisterRequest)(nil), "net.RegisterRequest") - proto.RegisterType((*NotifySegment)(nil), "net.NotifySegment") - proto.RegisterType((*TicketParams)(nil), "net.TicketParams") - proto.RegisterType((*TicketSenderParams)(nil), "net.TicketSenderParams") - proto.RegisterType((*TicketExpirationParams)(nil), "net.TicketExpirationParams") - proto.RegisterType((*Payment)(nil), "net.Payment") -} - -func init() { - proto.RegisterFile("net/lp_rpc.proto", fileDescriptor_034e29c79f9ba827) -} - -var fileDescriptor_034e29c79f9ba827 = []byte{ - // 1911 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x58, 0xef, 0x6e, 0x1b, 0xc7, - 0x11, 0x17, 0xff, 0x88, 0x7f, 0x86, 0xa4, 0x74, 0x5c, 0x4b, 0xca, 0x49, 0xb1, 0x53, 0xf9, 0x12, - 0x07, 0xca, 0x07, 0x2b, 0x06, 0x25, 0xbb, 0x71, 0x81, 0xa2, 0xa5, 0x24, 0x5a, 0x62, 0x60, 0x49, - 0xc4, 0x52, 0x36, 0xd0, 0x7e, 0x28, 0x7b, 0xba, 0x5b, 0x92, 0x57, 0x91, 0x7b, 0xe7, 0xbd, 0x65, - 0x6c, 0x05, 0x7d, 0x81, 0x3e, 0x42, 0xfb, 0xa5, 0x40, 0x81, 0xbe, 0x47, 0x1f, 0xa0, 0x0f, 0x50, - 0xf4, 0x39, 0xfa, 0x00, 0xc5, 0xce, 0xee, 0x1d, 0x8f, 0xa2, 0x92, 0x18, 0xf9, 0xb6, 0xf3, 0x9b, - 0xd9, 0xd9, 0xd9, 0x99, 0x9d, 0x3f, 0x77, 0x60, 0x71, 0x26, 0xbf, 0x9e, 0x44, 0x03, 0x11, 0x79, - 0xfb, 0x91, 0x08, 0x65, 0x48, 0x0a, 0x9c, 0x49, 0x67, 0x17, 0x2a, 0xbd, 0x80, 0x8f, 0x7a, 0x21, - 0x1f, 0x91, 0x0d, 0x58, 0xfd, 0xce, 0x9d, 0xcc, 0x98, 0x9d, 0xdb, 0xcd, 0xed, 0xd5, 0xa9, 0x26, - 0x9c, 0x73, 0x78, 0xd8, 0xe1, 0xfe, 0x95, 0x70, 0x79, 0xec, 0x85, 0x7e, 0xc0, 0x47, 0x7d, 0x16, - 0xc7, 0x41, 0xc8, 0x29, 0x7b, 0x37, 0x63, 0xb1, 0x24, 0x4f, 0x01, 0xdc, 0x99, 0x1c, 0x0f, 0x64, - 0x78, 0xc3, 0x38, 0x6e, 0xad, 0xb5, 0xd6, 0xf6, 0x39, 0x93, 0xfb, 0xed, 0x99, 0x1c, 0x5f, 0x29, - 0x94, 0x56, 0xdd, 0x64, 0xe9, 0xfc, 0x02, 0x1e, 0xfd, 0x80, 0xba, 0x38, 0x0a, 0x79, 0xcc, 0x9c, - 0x36, 0x3c, 0xb8, 0x14, 0xde, 0x98, 0xc5, 0x52, 0xb8, 0x32, 0x14, 0xc9, 0x31, 0x36, 0x94, 0x5d, - 0xdf, 0x17, 0x2c, 0x8e, 0x8d, 0x79, 0x09, 0x49, 0x2c, 0x28, 0xc4, 0xc1, 0xc8, 0xce, 0x23, 0xaa, - 0x96, 0xce, 0x5f, 0x73, 0x50, 0xba, 0xec, 0x77, 0xf9, 0x30, 0x24, 0x2f, 0xa1, 0x16, 0xcb, 0x50, - 0xb8, 0x23, 0x76, 0x75, 0x1b, 0xe9, 0x9b, 0xad, 0xb5, 0x3e, 0x41, 0xf3, 0xb4, 0xc4, 0x7e, 0x7f, - 0xce, 0xa6, 0x59, 0x59, 0xf2, 0x04, 0x4a, 0xf1, 0x41, 0xc0, 0x87, 0xa1, 0x6d, 0xe1, 0xa5, 0x1a, - 0xb8, 0xab, 0x7f, 0xa0, 0xf7, 0x51, 0xc3, 0x74, 0x9e, 0x42, 0x2d, 0xa3, 0x82, 0x00, 0x94, 0x4e, - 0xba, 0xb4, 0x73, 0x7c, 0x65, 0xad, 0x90, 0x12, 0xe4, 0xfb, 0x07, 0x56, 0x4e, 0x61, 0xa7, 0x97, - 0x97, 0xa7, 0xaf, 0x3b, 0x56, 0xde, 0xf9, 0x47, 0x0e, 0x2a, 0x89, 0x0e, 0x42, 0xa0, 0x38, 0x0e, - 0x63, 0x89, 0x66, 0x55, 0x29, 0xae, 0xd5, 0x75, 0x6e, 0xd8, 0x2d, 0x5e, 0xa7, 0x4a, 0xd5, 0x92, - 0x6c, 0x41, 0x29, 0x0a, 0x27, 0x81, 0x77, 0x6b, 0x17, 0x10, 0x34, 0x14, 0x79, 0x08, 0xd5, 0x38, - 0x18, 0x71, 0x57, 0xce, 0x04, 0xb3, 0x8b, 0xc8, 0x9a, 0x03, 0xe4, 0x33, 0x00, 0x4f, 0x30, 0x9f, - 0x71, 0x19, 0xb8, 0x13, 0x7b, 0x15, 0xd9, 0x19, 0x84, 0xec, 0x40, 0xe5, 0x43, 0x7b, 0xfa, 0xfd, - 0x89, 0x2b, 0x99, 0x5d, 0x42, 0x6e, 0x4a, 0x3b, 0x6f, 0xa0, 0xda, 0x13, 0x81, 0xc7, 0xd0, 0x48, - 0x07, 0xea, 0x91, 0x22, 0x7a, 0x4c, 0xbc, 0xe1, 0x81, 0x36, 0xb6, 0x40, 0x17, 0x30, 0xf2, 0x05, - 0x34, 0xa2, 0xe0, 0x03, 0x9b, 0xc4, 0x89, 0x50, 0x1e, 0x85, 0x16, 0x41, 0xe7, 0xbf, 0x79, 0xa8, - 0x1f, 0xbb, 0x91, 0x7b, 0x1d, 0x4c, 0x02, 0x19, 0xb0, 0x58, 0xdd, 0xe0, 0x3a, 0x90, 0xb1, 0x14, - 0x01, 0x1f, 0xd9, 0xb9, 0xdd, 0xc2, 0x5e, 0x91, 0xce, 0x01, 0xb2, 0x0b, 0xb5, 0xa9, 0xcb, 0x7d, - 0xf5, 0x0a, 0x02, 0x16, 0xdb, 0x79, 0xe4, 0x67, 0x21, 0xd2, 0x06, 0xf0, 0xdc, 0xc8, 0xf5, 0x50, - 0x9b, 0x5d, 0xd8, 0x2d, 0xec, 0xd5, 0x5a, 0x8f, 0x31, 0x4c, 0xd9, 0x63, 0x90, 0xd0, 0x32, 0x1d, - 0x2e, 0xc5, 0x2d, 0xcd, 0x6c, 0x52, 0xef, 0xea, 0x3b, 0x26, 0xd4, 0x0b, 0x34, 0x2e, 0x4c, 0x48, - 0xf2, 0x1b, 0xa8, 0x79, 0x21, 0x57, 0xcf, 0x30, 0xe0, 0x32, 0x46, 0x0f, 0xd6, 0x5a, 0x8f, 0xee, - 0xd1, 0x3e, 0x17, 0xa2, 0xd9, 0x1d, 0x3b, 0xbf, 0x86, 0xf5, 0x3b, 0x27, 0x27, 0xc1, 0x55, 0x2e, - 0x6c, 0xe8, 0xe0, 0xa6, 0x49, 0x97, 0x47, 0x4c, 0x13, 0xbf, 0xca, 0x7f, 0x93, 0xdb, 0x79, 0x0a, - 0xb5, 0x8c, 0x6a, 0x15, 0xcf, 0x69, 0xc0, 0xdf, 0x1a, 0x5b, 0xf5, 0x8b, 0xc9, 0x20, 0xce, 0xbf, - 0xf2, 0x60, 0x65, 0x13, 0x07, 0x63, 0xf7, 0x19, 0x80, 0x34, 0xa9, 0xc6, 0x44, 0xb2, 0x69, 0x8e, - 0x90, 0x17, 0xd0, 0x90, 0x81, 0x77, 0xc3, 0xe4, 0x20, 0x72, 0x85, 0x3b, 0x8d, 0xd1, 0x8a, 0x5a, - 0xab, 0x89, 0xb7, 0xbc, 0x42, 0x4e, 0x0f, 0x19, 0xb4, 0x2e, 0x33, 0x94, 0x4a, 0x7a, 0x8c, 0xff, - 0x00, 0xf3, 0xa3, 0x90, 0x49, 0xfa, 0xf4, 0xdd, 0xd0, 0x6a, 0x94, 0x3e, 0xa1, 0x4c, 0xf2, 0x16, - 0x17, 0x93, 0xf7, 0x39, 0xd4, 0xbd, 0x8c, 0x33, 0x8d, 0x97, 0x9b, 0x4b, 0x5e, 0xa6, 0x0b, 0x62, - 0x77, 0x8a, 0x4e, 0xe9, 0x27, 0x8a, 0x0e, 0x79, 0x02, 0x65, 0x93, 0xd9, 0xf6, 0x2e, 0x3e, 0x92, - 0x5a, 0xa6, 0x02, 0xd0, 0x84, 0xe7, 0xfc, 0x11, 0xaa, 0xe9, 0x76, 0x15, 0x98, 0x79, 0x49, 0xab, - 0x53, 0x4d, 0x90, 0x47, 0x00, 0xb1, 0x2e, 0x58, 0x83, 0xc0, 0x37, 0x49, 0x5a, 0x35, 0x48, 0xd7, - 0x57, 0xfe, 0x66, 0x1f, 0xa2, 0x40, 0xb8, 0x52, 0x05, 0xa9, 0x80, 0x49, 0x90, 0x41, 0x9c, 0xff, - 0x15, 0xa1, 0xdc, 0x67, 0xa3, 0x13, 0x57, 0xba, 0x18, 0x50, 0x97, 0x07, 0x43, 0x16, 0xcb, 0xae, - 0x6f, 0x4e, 0xc9, 0x20, 0x58, 0xd7, 0xd8, 0x3b, 0x93, 0x49, 0x6a, 0x89, 0xe5, 0xc2, 0x8d, 0xc7, - 0xa8, 0xb7, 0x4e, 0x71, 0xad, 0xd2, 0x38, 0x12, 0xe1, 0x30, 0x98, 0xb0, 0xc4, 0xb7, 0x29, 0x9d, - 0x54, 0xc6, 0xd5, 0xb4, 0x32, 0x2a, 0x69, 0x7f, 0x66, 0xac, 0x53, 0x5e, 0x5b, 0xa5, 0x29, 0xbd, - 0x14, 0x8a, 0xf2, 0xcf, 0x09, 0x45, 0xe5, 0xa7, 0x42, 0xf1, 0x0c, 0x36, 0x3c, 0x77, 0xe2, 0x0d, - 0x22, 0x26, 0x3c, 0x16, 0xc9, 0x99, 0x3b, 0x19, 0xe0, 0x9d, 0x60, 0x37, 0xb7, 0x57, 0xa1, 0x44, - 0xf1, 0x7a, 0x29, 0xeb, 0x4c, 0xdd, 0xf0, 0xe3, 0x82, 0xa7, 0xcc, 0x1f, 0xce, 0x26, 0x93, 0x5e, - 0xe2, 0x8c, 0xc7, 0x28, 0xab, 0xcd, 0x7f, 0x1b, 0xf8, 0x2c, 0x34, 0x1c, 0xba, 0x20, 0x46, 0x7e, - 0x09, 0x8d, 0x2c, 0xdd, 0xb2, 0x9d, 0x1f, 0xda, 0xb7, 0x28, 0x77, 0x77, 0xe3, 0x81, 0xfd, 0xf9, - 0x47, 0x6d, 0x3c, 0x20, 0x6d, 0x20, 0x31, 0x1b, 0x4d, 0x19, 0x37, 0x49, 0xc7, 0x24, 0x13, 0xb1, - 0xfd, 0x04, 0x1d, 0x47, 0x74, 0x8f, 0x61, 0xa3, 0x5e, 0xca, 0xa1, 0x4d, 0x23, 0x3d, 0x87, 0xc8, - 0x3e, 0x90, 0x57, 0xa1, 0xf0, 0x58, 0xda, 0x3b, 0x03, 0x55, 0x73, 0xbf, 0xd4, 0x2e, 0x5c, 0xe6, - 0x38, 0x07, 0xd0, 0x58, 0xd0, 0xa9, 0x5e, 0xd2, 0x50, 0x84, 0x53, 0x7c, 0x75, 0x45, 0x8a, 0x6b, - 0xb2, 0x06, 0x79, 0x19, 0xe2, 0x73, 0x2b, 0xd2, 0xbc, 0x0c, 0x9d, 0x7f, 0xaf, 0x42, 0x3d, 0x7b, - 0x0f, 0xb5, 0x89, 0xbb, 0x53, 0x86, 0xed, 0xb0, 0x4a, 0x71, 0xad, 0xb2, 0xe4, 0x7d, 0xe0, 0xcb, - 0xb1, 0xdd, 0xc4, 0xd7, 0xa4, 0x09, 0xd5, 0xb1, 0xc6, 0x2c, 0x18, 0x8d, 0xa5, 0x4d, 0x10, 0x36, - 0x94, 0xaa, 0x03, 0xd7, 0x81, 0x2a, 0x4f, 0xcc, 0x7e, 0x80, 0x8c, 0x84, 0x54, 0x4f, 0x75, 0x18, - 0xc5, 0xf6, 0x86, 0x2e, 0x8c, 0xc3, 0x28, 0x26, 0xcf, 0xa0, 0x34, 0x0c, 0xc5, 0xd4, 0x95, 0xf6, - 0x26, 0x36, 0x6d, 0x7b, 0xc9, 0xb1, 0xfb, 0xaf, 0x90, 0x4f, 0x8d, 0x9c, 0x3a, 0x75, 0x18, 0xc5, - 0x27, 0x8c, 0xdb, 0x5b, 0xa8, 0xc6, 0x50, 0xe4, 0x00, 0xca, 0x26, 0x25, 0xec, 0x4f, 0x50, 0xd5, - 0xf6, 0xb2, 0xaa, 0x24, 0x56, 0x89, 0xa4, 0x32, 0x68, 0x14, 0x46, 0xb6, 0x8d, 0x66, 0xaa, 0x25, - 0x79, 0x01, 0x65, 0xc6, 0x75, 0x21, 0xdd, 0x46, 0x35, 0x0f, 0x97, 0xd5, 0x20, 0x71, 0x1c, 0xfa, - 0xcc, 0xa3, 0x89, 0x30, 0x36, 0xe2, 0x70, 0x12, 0x8a, 0x13, 0x16, 0xc9, 0xb1, 0xbd, 0x83, 0x0a, - 0x33, 0x08, 0x39, 0x85, 0xba, 0x37, 0x16, 0xe1, 0xd4, 0xd5, 0xd7, 0xb1, 0x3f, 0x45, 0xe5, 0x9f, - 0x2f, 0x2b, 0x3f, 0x46, 0xa9, 0xfe, 0xec, 0x3a, 0x76, 0xa7, 0xd1, 0x24, 0xe0, 0x23, 0xba, 0xb0, - 0x51, 0x79, 0xf7, 0xdd, 0xcc, 0x9d, 0x04, 0xf2, 0xd6, 0x7e, 0x88, 0x0e, 0x48, 0x48, 0xe7, 0x11, - 0x94, 0x8c, 0x0c, 0x40, 0xe9, 0xbc, 0xd7, 0x39, 0xbd, 0xea, 0x5b, 0x2b, 0xa4, 0x0c, 0x85, 0xf3, - 0xde, 0xa1, 0x95, 0x73, 0xfe, 0x04, 0xe5, 0x24, 0xc6, 0x0f, 0x60, 0xbd, 0x73, 0x71, 0x7c, 0x79, - 0xd2, 0xa1, 0x83, 0x93, 0xce, 0xab, 0xf6, 0x9b, 0xd7, 0x6a, 0x8e, 0x69, 0x42, 0xe3, 0xac, 0xf5, - 0xe2, 0x70, 0x70, 0xd4, 0xee, 0x77, 0x5e, 0x77, 0x2f, 0x3a, 0x56, 0x8e, 0x34, 0xa0, 0x8a, 0xd0, - 0x79, 0xbb, 0x7b, 0x61, 0xe5, 0x53, 0xf2, 0xac, 0x7b, 0x7a, 0x66, 0x15, 0xc8, 0x36, 0x6c, 0x22, - 0x79, 0x7c, 0x79, 0xd1, 0xbf, 0xa2, 0xed, 0xee, 0x45, 0xe7, 0x44, 0xb3, 0x8a, 0x4e, 0x0b, 0x60, - 0xee, 0x24, 0x52, 0x81, 0xa2, 0x12, 0xb4, 0x56, 0xcc, 0xea, 0xb9, 0x95, 0x53, 0x66, 0xbd, 0xed, - 0x7d, 0x63, 0xe5, 0xf5, 0xe2, 0xa5, 0x55, 0x70, 0x8e, 0xa1, 0xb9, 0x74, 0x77, 0xb2, 0x06, 0x70, - 0x7c, 0x46, 0x2f, 0xcf, 0xdb, 0x83, 0xc3, 0xd6, 0x33, 0x6b, 0x65, 0x81, 0x6e, 0x59, 0xb9, 0x2c, - 0x7d, 0x78, 0x68, 0xe5, 0x9d, 0x77, 0xb0, 0x99, 0x4c, 0x9d, 0xcc, 0xef, 0xeb, 0x94, 0xc2, 0x3a, - 0x6c, 0x41, 0x61, 0x26, 0x26, 0xa6, 0x39, 0xaa, 0x25, 0x0e, 0x5c, 0x38, 0xb8, 0x98, 0xe2, 0x6b, - 0x28, 0xb2, 0x0f, 0x0f, 0xee, 0x94, 0xad, 0x81, 0xda, 0xa9, 0xa7, 0xb2, 0x66, 0xb4, 0x50, 0xb6, - 0xde, 0x88, 0x89, 0xf3, 0x3b, 0x68, 0xa4, 0x47, 0xe2, 0x51, 0x2f, 0xa0, 0x62, 0x92, 0x39, 0xc6, - 0x71, 0xa7, 0xd6, 0xda, 0xd1, 0x9d, 0xf6, 0x3e, 0xc3, 0x68, 0x2a, 0x7b, 0xcf, 0x88, 0xfb, 0xb7, - 0x1c, 0xac, 0xa7, 0xbb, 0x28, 0x8b, 0x67, 0x13, 0x99, 0x34, 0x8c, 0xdc, 0xbc, 0x61, 0x6c, 0xc1, - 0x2a, 0x13, 0x22, 0x14, 0xba, 0x51, 0x9d, 0xad, 0x50, 0x4d, 0x92, 0x3d, 0x28, 0xfa, 0xae, 0x74, - 0x4d, 0xe3, 0x26, 0x8b, 0x36, 0xa8, 0xb3, 0xcf, 0x56, 0x28, 0x4a, 0x90, 0xaf, 0xa0, 0x98, 0x19, - 0x81, 0x37, 0x75, 0xe5, 0xbd, 0x33, 0x65, 0x50, 0x14, 0x39, 0xaa, 0x40, 0x49, 0xa0, 0x21, 0xce, - 0x9f, 0x61, 0x9d, 0xb2, 0x51, 0x10, 0x4b, 0x96, 0x8e, 0xef, 0x5b, 0x50, 0x8a, 0x99, 0x27, 0x58, - 0x32, 0xeb, 0x1a, 0x4a, 0x35, 0x24, 0x33, 0x8c, 0xdd, 0x1a, 0x67, 0xa7, 0xf4, 0x52, 0x43, 0x2a, - 0x7c, 0x54, 0x43, 0x72, 0xfe, 0x92, 0x83, 0xc6, 0x45, 0x28, 0x83, 0xe1, 0xad, 0x71, 0xe6, 0x3d, - 0x11, 0xfe, 0x12, 0xca, 0xb1, 0x6e, 0xc3, 0x46, 0x6b, 0x3d, 0x29, 0xbc, 0xe8, 0xf9, 0x84, 0xa9, - 0xcc, 0x96, 0x6e, 0x7c, 0xd3, 0xf5, 0xd1, 0x01, 0x05, 0x6a, 0xa8, 0x85, 0xae, 0xdb, 0x5c, 0xec, - 0xba, 0xdf, 0x16, 0x2b, 0x79, 0xab, 0xf0, 0x6d, 0xb1, 0xf2, 0xd8, 0x72, 0x9c, 0xbf, 0xe7, 0xa1, - 0x9e, 0x1d, 0xa3, 0xd4, 0xc4, 0x2b, 0x98, 0x17, 0x44, 0x01, 0xe3, 0xd2, 0xf4, 0xfc, 0x39, 0xa0, - 0xa6, 0x8b, 0xa1, 0xeb, 0xb1, 0xc1, 0x7c, 0x22, 0xac, 0xd3, 0xaa, 0x42, 0xde, 0x2a, 0x80, 0x6c, - 0x43, 0xe5, 0x7d, 0xc0, 0x07, 0x91, 0x08, 0xaf, 0xcd, 0x0c, 0x50, 0x7e, 0x1f, 0xf0, 0x9e, 0x08, - 0xaf, 0xd5, 0xd3, 0x4c, 0xd5, 0x0c, 0x84, 0xcb, 0x7d, 0xdd, 0x55, 0xf5, 0x44, 0xd0, 0x4c, 0x59, - 0xd4, 0xe5, 0x3e, 0x36, 0x55, 0x02, 0xc5, 0x98, 0x31, 0xdf, 0xcc, 0x06, 0xb8, 0x26, 0x5f, 0x81, - 0x35, 0x1f, 0x55, 0x06, 0xd7, 0x93, 0xd0, 0xbb, 0xc1, 0x21, 0xa1, 0x4e, 0xd7, 0xe7, 0xf8, 0x91, - 0x82, 0xc9, 0x19, 0x34, 0x33, 0xa2, 0x66, 0x76, 0xd4, 0x03, 0xc3, 0xa7, 0x99, 0xd9, 0xb1, 0x93, - 0xca, 0x98, 0x29, 0x32, 0x73, 0x80, 0x46, 0x9c, 0x2e, 0x10, 0x2d, 0xdb, 0x67, 0xdc, 0x67, 0xc2, - 0xb8, 0xe9, 0x31, 0xd4, 0x63, 0xa4, 0x07, 0x3c, 0xe4, 0x1e, 0x33, 0x03, 0x73, 0x4d, 0x63, 0x17, - 0x0a, 0xba, 0x27, 0x27, 0xbe, 0x87, 0xad, 0xfb, 0x8f, 0x25, 0x4f, 0x60, 0xcd, 0x13, 0x4c, 0x1b, - 0x2b, 0xc2, 0x19, 0xf7, 0x4d, 0x92, 0x34, 0x12, 0x94, 0x2a, 0x90, 0xbc, 0x84, 0xed, 0x45, 0x31, - 0xed, 0x04, 0xed, 0x4a, 0x7d, 0xd0, 0xd6, 0xc2, 0x0e, 0x74, 0x86, 0xf2, 0xa7, 0xf3, 0xcf, 0x3c, - 0x94, 0x7b, 0xee, 0x2d, 0x3e, 0xb7, 0xa5, 0xa1, 0x3a, 0xf7, 0x71, 0x43, 0x35, 0xe6, 0x88, 0xba, - 0xa0, 0x39, 0xcb, 0x50, 0xf7, 0x3b, 0xbb, 0xf0, 0x33, 0x9c, 0x4d, 0xba, 0xb0, 0x61, 0x2c, 0x33, - 0xde, 0x35, 0xca, 0x8a, 0x58, 0x8b, 0x3e, 0xc9, 0x28, 0xcb, 0x46, 0x83, 0x12, 0xb9, 0x1c, 0xa1, - 0xe7, 0xb0, 0xc6, 0x3e, 0x44, 0xcc, 0x93, 0xcc, 0x1f, 0xe0, 0xa0, 0x6f, 0x46, 0xf7, 0xbb, 0x5f, - 0x01, 0x8d, 0x44, 0x0a, 0xa1, 0xd6, 0x7f, 0x72, 0x50, 0xcf, 0xd6, 0x0f, 0x72, 0x04, 0xeb, 0xa7, - 0x4c, 0x2e, 0x40, 0xf6, 0x52, 0x95, 0x31, 0x55, 0x64, 0xe7, 0xfe, 0xfa, 0x43, 0xfe, 0x00, 0x9b, - 0xf7, 0xfe, 0x53, 0x20, 0xfa, 0x5b, 0xf0, 0xc7, 0x7e, 0x5f, 0xec, 0x38, 0x3f, 0x26, 0xa2, 0x7f, - 0x49, 0x90, 0x2f, 0xa0, 0xd8, 0x53, 0x2d, 0x47, 0xff, 0x01, 0x48, 0xfe, 0x97, 0xec, 0x2c, 0x92, - 0xad, 0x0b, 0x80, 0xab, 0xf9, 0x97, 0xd5, 0x6f, 0x81, 0x24, 0x35, 0x30, 0x83, 0x6e, 0xe0, 0x96, - 0x3b, 0xc5, 0x71, 0x47, 0x17, 0xe0, 0x85, 0x9a, 0xf5, 0x2c, 0x77, 0x54, 0xfe, 0xfd, 0xea, 0xfe, - 0xd7, 0x9c, 0xc9, 0xeb, 0x12, 0xfe, 0xaf, 0x39, 0xf8, 0x7f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x8c, - 0x55, 0x8b, 0x9a, 0xc3, 0x11, 0x00, 0x00, +// Non-binary capability constraints, such as supported ranges. +type Capabilities_Constraints struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + MinVersion string `protobuf:"bytes,1,opt,name=minVersion,proto3" json:"minVersion,omitempty"` +} + +func (x *Capabilities_Constraints) Reset() { + *x = Capabilities_Constraints{} + if protoimpl.UnsafeEnabled { + mi := &file_net_lp_rpc_proto_msgTypes[23] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Capabilities_Constraints) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Capabilities_Constraints) ProtoMessage() {} + +func (x *Capabilities_Constraints) ProtoReflect() protoreflect.Message { + mi := &file_net_lp_rpc_proto_msgTypes[23] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Capabilities_Constraints.ProtoReflect.Descriptor instead. +func (*Capabilities_Constraints) Descriptor() ([]byte, []int) { + return file_net_lp_rpc_proto_rawDescGZIP(), []int{7, 1} +} + +func (x *Capabilities_Constraints) GetMinVersion() string { + if x != nil { + return x.MinVersion + } + return "" +} + +var File_net_lp_rpc_proto protoreflect.FileDescriptor + +var file_net_lp_rpc_proto_rawDesc = []byte{ + 0x0a, 0x10, 0x6e, 0x65, 0x74, 0x2f, 0x6c, 0x70, 0x5f, 0x72, 0x70, 0x63, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x12, 0x03, 0x6e, 0x65, 0x74, 0x22, 0x20, 0x0a, 0x08, 0x50, 0x69, 0x6e, 0x67, 0x50, + 0x6f, 0x6e, 0x67, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x4d, 0x0a, 0x1c, 0x45, 0x6e, 0x64, + 0x54, 0x72, 0x61, 0x6e, 0x73, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x53, 0x65, 0x73, 0x73, 0x69, + 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2d, 0x0a, 0x0a, 0x61, 0x75, 0x74, + 0x68, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, + 0x6e, 0x65, 0x74, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x09, 0x61, + 0x75, 0x74, 0x68, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x1f, 0x0a, 0x1d, 0x45, 0x6e, 0x64, 0x54, + 0x72, 0x61, 0x6e, 0x73, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, + 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x41, 0x0a, 0x13, 0x4f, 0x72, 0x63, + 0x68, 0x65, 0x73, 0x74, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x69, + 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x73, 0x69, 0x67, 0x22, 0x99, 0x01, 0x0a, + 0x06, 0x4f, 0x53, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x39, 0x0a, 0x0b, 0x73, 0x74, 0x6f, 0x72, 0x61, + 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x17, 0x2e, 0x6e, + 0x65, 0x74, 0x2e, 0x4f, 0x53, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, + 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0b, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x54, 0x79, + 0x70, 0x65, 0x12, 0x25, 0x0a, 0x06, 0x73, 0x33, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x10, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x53, 0x33, 0x4f, 0x53, 0x49, 0x6e, 0x66, + 0x6f, 0x52, 0x06, 0x73, 0x33, 0x69, 0x6e, 0x66, 0x6f, 0x22, 0x2d, 0x0a, 0x0b, 0x53, 0x74, 0x6f, + 0x72, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0a, 0x0a, 0x06, 0x44, 0x49, 0x52, 0x45, + 0x43, 0x54, 0x10, 0x00, 0x12, 0x06, 0x0a, 0x02, 0x53, 0x33, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, + 0x47, 0x4f, 0x4f, 0x47, 0x4c, 0x45, 0x10, 0x02, 0x22, 0xa2, 0x01, 0x0a, 0x08, 0x53, 0x33, 0x4f, + 0x53, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x6f, 0x73, 0x74, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, 0x6f, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x70, + 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, 0x6f, 0x6c, + 0x69, 0x63, 0x79, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, + 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, + 0x6c, 0x12, 0x1a, 0x0a, 0x08, 0x78, 0x41, 0x6d, 0x7a, 0x44, 0x61, 0x74, 0x65, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x08, 0x78, 0x41, 0x6d, 0x7a, 0x44, 0x61, 0x74, 0x65, 0x22, 0x55, 0x0a, + 0x09, 0x50, 0x72, 0x69, 0x63, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x22, 0x0a, 0x0c, 0x70, 0x72, + 0x69, 0x63, 0x65, 0x50, 0x65, 0x72, 0x55, 0x6e, 0x69, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, + 0x52, 0x0c, 0x70, 0x72, 0x69, 0x63, 0x65, 0x50, 0x65, 0x72, 0x55, 0x6e, 0x69, 0x74, 0x12, 0x24, + 0x0a, 0x0d, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x73, 0x50, 0x65, 0x72, 0x55, 0x6e, 0x69, 0x74, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x73, 0x50, 0x65, 0x72, + 0x55, 0x6e, 0x69, 0x74, 0x22, 0xda, 0x02, 0x0a, 0x0c, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, + 0x69, 0x74, 0x69, 0x65, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x62, 0x69, 0x74, 0x73, 0x74, 0x72, 0x69, + 0x6e, 0x67, 0x18, 0x01, 0x20, 0x03, 0x28, 0x04, 0x52, 0x09, 0x62, 0x69, 0x74, 0x73, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x12, 0x20, 0x0a, 0x0b, 0x6d, 0x61, 0x6e, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x69, + 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x04, 0x52, 0x0b, 0x6d, 0x61, 0x6e, 0x64, 0x61, 0x74, + 0x6f, 0x72, 0x69, 0x65, 0x73, 0x12, 0x41, 0x0a, 0x0a, 0x63, 0x61, 0x70, 0x61, 0x63, 0x69, 0x74, + 0x69, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x6e, 0x65, 0x74, 0x2e, + 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x2e, 0x43, 0x61, 0x70, + 0x61, 0x63, 0x69, 0x74, 0x69, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0a, 0x63, 0x61, + 0x70, 0x61, 0x63, 0x69, 0x74, 0x69, 0x65, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x12, 0x3f, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x74, + 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x43, 0x61, + 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x74, + 0x72, 0x61, 0x69, 0x6e, 0x74, 0x73, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x61, 0x69, + 0x6e, 0x74, 0x73, 0x1a, 0x3d, 0x0a, 0x0f, 0x43, 0x61, 0x70, 0x61, 0x63, 0x69, 0x74, 0x69, 0x65, + 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0d, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, + 0x38, 0x01, 0x1a, 0x2d, 0x0a, 0x0b, 0x43, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x74, + 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x6d, 0x69, 0x6e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6d, 0x69, 0x6e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, + 0x6e, 0x22, 0xc0, 0x02, 0x0a, 0x10, 0x4f, 0x72, 0x63, 0x68, 0x65, 0x73, 0x74, 0x72, 0x61, 0x74, + 0x6f, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1e, 0x0a, 0x0a, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x63, + 0x6f, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x74, 0x72, 0x61, 0x6e, + 0x73, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x12, 0x36, 0x0a, 0x0d, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x74, + 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, + 0x6e, 0x65, 0x74, 0x2e, 0x54, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, + 0x52, 0x0c, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x2d, + 0x0a, 0x0a, 0x70, 0x72, 0x69, 0x63, 0x65, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x50, 0x72, 0x69, 0x63, 0x65, 0x49, 0x6e, + 0x66, 0x6f, 0x52, 0x09, 0x70, 0x72, 0x69, 0x63, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x18, 0x0a, + 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, + 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x35, 0x0a, 0x0c, 0x63, 0x61, 0x70, 0x61, 0x62, + 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, + 0x6e, 0x65, 0x74, 0x2e, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, + 0x52, 0x0c, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x12, 0x2d, + 0x0a, 0x0a, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x54, 0x6f, 0x6b, + 0x65, 0x6e, 0x52, 0x09, 0x61, 0x75, 0x74, 0x68, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x25, 0x0a, + 0x07, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x18, 0x20, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0b, + 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x4f, 0x53, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x07, 0x73, 0x74, 0x6f, + 0x72, 0x61, 0x67, 0x65, 0x22, 0x60, 0x0a, 0x09, 0x41, 0x75, 0x74, 0x68, 0x54, 0x6f, 0x6b, 0x65, + 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x65, 0x73, 0x73, 0x69, + 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x65, 0x73, + 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x65, 0x78, 0x70, 0x69, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x65, 0x78, 0x70, 0x69, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xf4, 0x04, 0x0a, 0x07, 0x53, 0x65, 0x67, 0x44, 0x61, + 0x74, 0x61, 0x12, 0x1e, 0x0a, 0x0a, 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x49, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, + 0x49, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x65, 0x71, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, + 0x03, 0x73, 0x65, 0x71, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x66, + 0x69, 0x6c, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x66, + 0x69, 0x6c, 0x65, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x69, 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x03, 0x73, 0x69, 0x67, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x12, 0x35, 0x0a, 0x0c, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, + 0x65, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x43, + 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x52, 0x0c, 0x63, 0x61, 0x70, + 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x12, 0x2d, 0x0a, 0x0a, 0x61, 0x75, 0x74, + 0x68, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, + 0x6e, 0x65, 0x74, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x09, 0x61, + 0x75, 0x74, 0x68, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x30, 0x0a, 0x14, 0x63, 0x61, 0x6c, 0x63, + 0x5f, 0x70, 0x65, 0x72, 0x63, 0x65, 0x70, 0x74, 0x75, 0x61, 0x6c, 0x5f, 0x68, 0x61, 0x73, 0x68, + 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x63, 0x61, 0x6c, 0x63, 0x50, 0x65, 0x72, 0x63, + 0x65, 0x70, 0x74, 0x75, 0x61, 0x6c, 0x48, 0x61, 0x73, 0x68, 0x12, 0x25, 0x0a, 0x07, 0x73, 0x74, + 0x6f, 0x72, 0x61, 0x67, 0x65, 0x18, 0x20, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x6e, 0x65, + 0x74, 0x2e, 0x4f, 0x53, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x07, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, + 0x65, 0x12, 0x35, 0x0a, 0x0c, 0x66, 0x75, 0x6c, 0x6c, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, + 0x73, 0x18, 0x21, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x56, 0x69, + 0x64, 0x65, 0x6f, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x52, 0x0c, 0x66, 0x75, 0x6c, 0x6c, + 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x37, 0x0a, 0x0d, 0x66, 0x75, 0x6c, 0x6c, + 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x32, 0x18, 0x22, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x11, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x56, 0x69, 0x64, 0x65, 0x6f, 0x50, 0x72, 0x6f, 0x66, 0x69, + 0x6c, 0x65, 0x52, 0x0d, 0x66, 0x75, 0x6c, 0x6c, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, + 0x32, 0x12, 0x37, 0x0a, 0x0d, 0x66, 0x75, 0x6c, 0x6c, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, + 0x73, 0x33, 0x18, 0x23, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x56, + 0x69, 0x64, 0x65, 0x6f, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x52, 0x0d, 0x66, 0x75, 0x6c, + 0x6c, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x33, 0x12, 0x41, 0x0a, 0x12, 0x73, 0x65, + 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, + 0x18, 0x25, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x53, 0x65, 0x67, + 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x52, 0x11, 0x73, 0x65, 0x67, 0x6d, + 0x65, 0x6e, 0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x12, 0x2e, 0x0a, + 0x12, 0x46, 0x6f, 0x72, 0x63, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x69, + 0x6e, 0x69, 0x74, 0x18, 0x26, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x46, 0x6f, 0x72, 0x63, 0x65, + 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x69, 0x6e, 0x69, 0x74, 0x22, 0x33, 0x0a, + 0x0d, 0x53, 0x65, 0x67, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x12, 0x12, + 0x0a, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x66, 0x72, + 0x6f, 0x6d, 0x12, 0x0e, 0x0a, 0x02, 0x74, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x02, + 0x74, 0x6f, 0x22, 0xcc, 0x05, 0x0a, 0x0c, 0x56, 0x69, 0x64, 0x65, 0x6f, 0x50, 0x72, 0x6f, 0x66, + 0x69, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x10, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x77, 0x69, 0x64, 0x74, 0x68, + 0x18, 0x11, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x77, 0x69, 0x64, 0x74, 0x68, 0x12, 0x16, 0x0a, + 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x12, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x68, + 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x62, 0x69, 0x74, 0x72, 0x61, 0x74, 0x65, + 0x18, 0x13, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x62, 0x69, 0x74, 0x72, 0x61, 0x74, 0x65, 0x12, + 0x10, 0x0a, 0x03, 0x66, 0x70, 0x73, 0x18, 0x14, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x03, 0x66, 0x70, + 0x73, 0x12, 0x30, 0x0a, 0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, 0x15, 0x20, 0x01, 0x28, + 0x0e, 0x32, 0x18, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x56, 0x69, 0x64, 0x65, 0x6f, 0x50, 0x72, 0x6f, + 0x66, 0x69, 0x6c, 0x65, 0x2e, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x52, 0x06, 0x66, 0x6f, 0x72, + 0x6d, 0x61, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x70, 0x73, 0x44, 0x65, 0x6e, 0x18, 0x16, 0x20, + 0x01, 0x28, 0x0d, 0x52, 0x06, 0x66, 0x70, 0x73, 0x44, 0x65, 0x6e, 0x12, 0x33, 0x0a, 0x07, 0x70, + 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x17, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x6e, + 0x65, 0x74, 0x2e, 0x56, 0x69, 0x64, 0x65, 0x6f, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x2e, + 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, + 0x12, 0x10, 0x0a, 0x03, 0x67, 0x6f, 0x70, 0x18, 0x18, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x67, + 0x6f, 0x70, 0x12, 0x36, 0x0a, 0x07, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x18, 0x19, 0x20, + 0x01, 0x28, 0x0e, 0x32, 0x1c, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x56, 0x69, 0x64, 0x65, 0x6f, 0x50, + 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x2e, 0x56, 0x69, 0x64, 0x65, 0x6f, 0x43, 0x6f, 0x64, 0x65, + 0x63, 0x52, 0x07, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x6f, + 0x6c, 0x6f, 0x72, 0x44, 0x65, 0x70, 0x74, 0x68, 0x18, 0x1a, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, + 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x44, 0x65, 0x70, 0x74, 0x68, 0x12, 0x47, 0x0a, 0x0c, 0x63, 0x68, + 0x72, 0x6f, 0x6d, 0x61, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, 0x1b, 0x20, 0x01, 0x28, 0x0e, + 0x32, 0x23, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x56, 0x69, 0x64, 0x65, 0x6f, 0x50, 0x72, 0x6f, 0x66, + 0x69, 0x6c, 0x65, 0x2e, 0x43, 0x68, 0x72, 0x6f, 0x6d, 0x61, 0x53, 0x75, 0x62, 0x73, 0x61, 0x6d, + 0x70, 0x6c, 0x69, 0x6e, 0x67, 0x52, 0x0c, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x61, 0x46, 0x6f, 0x72, + 0x6d, 0x61, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x71, 0x75, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x18, 0x1c, + 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x71, 0x75, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x22, 0x1d, 0x0a, + 0x06, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0x0a, 0x0a, 0x06, 0x4d, 0x50, 0x45, 0x47, 0x54, + 0x53, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x4d, 0x50, 0x34, 0x10, 0x01, 0x22, 0x6a, 0x0a, 0x07, + 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x13, 0x0a, 0x0f, 0x45, 0x4e, 0x43, 0x4f, 0x44, + 0x45, 0x52, 0x5f, 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x10, 0x00, 0x12, 0x11, 0x0a, 0x0d, + 0x48, 0x32, 0x36, 0x34, 0x5f, 0x42, 0x41, 0x53, 0x45, 0x4c, 0x49, 0x4e, 0x45, 0x10, 0x01, 0x12, + 0x0d, 0x0a, 0x09, 0x48, 0x32, 0x36, 0x34, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x10, 0x02, 0x12, 0x0d, + 0x0a, 0x09, 0x48, 0x32, 0x36, 0x34, 0x5f, 0x48, 0x49, 0x47, 0x48, 0x10, 0x03, 0x12, 0x19, 0x0a, + 0x15, 0x48, 0x32, 0x36, 0x34, 0x5f, 0x43, 0x4f, 0x4e, 0x53, 0x54, 0x52, 0x41, 0x49, 0x4e, 0x45, + 0x44, 0x5f, 0x48, 0x49, 0x47, 0x48, 0x10, 0x04, 0x22, 0x32, 0x0a, 0x0a, 0x56, 0x69, 0x64, 0x65, + 0x6f, 0x43, 0x6f, 0x64, 0x65, 0x63, 0x12, 0x08, 0x0a, 0x04, 0x48, 0x32, 0x36, 0x34, 0x10, 0x00, + 0x12, 0x08, 0x0a, 0x04, 0x48, 0x32, 0x36, 0x35, 0x10, 0x01, 0x12, 0x07, 0x0a, 0x03, 0x56, 0x50, + 0x38, 0x10, 0x02, 0x12, 0x07, 0x0a, 0x03, 0x56, 0x50, 0x39, 0x10, 0x03, 0x22, 0x43, 0x0a, 0x11, + 0x43, 0x68, 0x72, 0x6f, 0x6d, 0x61, 0x53, 0x75, 0x62, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x69, 0x6e, + 0x67, 0x12, 0x0e, 0x0a, 0x0a, 0x43, 0x48, 0x52, 0x4f, 0x4d, 0x41, 0x5f, 0x34, 0x32, 0x30, 0x10, + 0x00, 0x12, 0x0e, 0x0a, 0x0a, 0x43, 0x48, 0x52, 0x4f, 0x4d, 0x41, 0x5f, 0x34, 0x32, 0x32, 0x10, + 0x01, 0x12, 0x0e, 0x0a, 0x0a, 0x43, 0x48, 0x52, 0x4f, 0x4d, 0x41, 0x5f, 0x34, 0x34, 0x34, 0x10, + 0x02, 0x22, 0x71, 0x0a, 0x15, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x63, 0x6f, 0x64, 0x65, 0x64, 0x53, + 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x44, 0x61, 0x74, 0x61, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, + 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, 0x16, 0x0a, 0x06, + 0x70, 0x69, 0x78, 0x65, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x70, 0x69, + 0x78, 0x65, 0x6c, 0x73, 0x12, 0x2e, 0x0a, 0x13, 0x70, 0x65, 0x72, 0x63, 0x65, 0x70, 0x74, 0x75, + 0x61, 0x6c, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x11, 0x70, 0x65, 0x72, 0x63, 0x65, 0x70, 0x74, 0x75, 0x61, 0x6c, 0x48, 0x61, 0x73, + 0x68, 0x55, 0x72, 0x6c, 0x22, 0x59, 0x0a, 0x0d, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x63, 0x6f, 0x64, + 0x65, 0x44, 0x61, 0x74, 0x61, 0x12, 0x36, 0x0a, 0x08, 0x73, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, + 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x54, 0x72, + 0x61, 0x6e, 0x73, 0x63, 0x6f, 0x64, 0x65, 0x64, 0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x44, + 0x61, 0x74, 0x61, 0x52, 0x08, 0x73, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x10, 0x0a, + 0x03, 0x73, 0x69, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x73, 0x69, 0x67, 0x22, + 0x9a, 0x01, 0x0a, 0x0f, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x63, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x73, + 0x75, 0x6c, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x65, 0x71, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, + 0x52, 0x03, 0x73, 0x65, 0x71, 0x12, 0x16, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x28, 0x0a, + 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6e, 0x65, + 0x74, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x63, 0x6f, 0x64, 0x65, 0x44, 0x61, 0x74, 0x61, 0x48, + 0x00, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x29, 0x0a, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x18, + 0x10, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x4f, 0x72, 0x63, 0x68, + 0x65, 0x73, 0x74, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x04, 0x69, 0x6e, + 0x66, 0x6f, 0x42, 0x08, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x7c, 0x0a, 0x0f, + 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x16, 0x0a, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x61, 0x70, 0x61, 0x63, + 0x69, 0x74, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x63, 0x61, 0x70, 0x61, 0x63, + 0x69, 0x74, 0x79, 0x12, 0x35, 0x0a, 0x0c, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, + 0x69, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x6e, 0x65, 0x74, 0x2e, + 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x52, 0x0c, 0x63, 0x61, + 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x22, 0xa1, 0x01, 0x0a, 0x0d, 0x4e, + 0x6f, 0x74, 0x69, 0x66, 0x79, 0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x10, 0x0a, 0x03, + 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, 0x26, + 0x0a, 0x07, 0x73, 0x65, 0x67, 0x44, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x0c, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x53, 0x65, 0x67, 0x44, 0x61, 0x74, 0x61, 0x52, 0x07, 0x73, + 0x65, 0x67, 0x44, 0x61, 0x74, 0x61, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x61, 0x73, 0x6b, 0x49, 0x64, + 0x18, 0x10, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x74, 0x61, 0x73, 0x6b, 0x49, 0x64, 0x12, 0x16, + 0x0a, 0x06, 0x6f, 0x72, 0x63, 0x68, 0x49, 0x64, 0x18, 0x12, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, + 0x6f, 0x72, 0x63, 0x68, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, + 0x65, 0x73, 0x18, 0x11, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, + 0x65, 0x73, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x4a, 0x04, 0x08, 0x21, 0x10, 0x22, 0x22, 0x9f, + 0x02, 0x0a, 0x0c, 0x54, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, + 0x1c, 0x0a, 0x09, 0x72, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x12, 0x1d, 0x0a, + 0x0a, 0x66, 0x61, 0x63, 0x65, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x09, 0x66, 0x61, 0x63, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x19, 0x0a, 0x08, + 0x77, 0x69, 0x6e, 0x5f, 0x70, 0x72, 0x6f, 0x62, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, + 0x77, 0x69, 0x6e, 0x50, 0x72, 0x6f, 0x62, 0x12, 0x2e, 0x0a, 0x13, 0x72, 0x65, 0x63, 0x69, 0x70, + 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x72, 0x61, 0x6e, 0x64, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x11, 0x72, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x52, + 0x61, 0x6e, 0x64, 0x48, 0x61, 0x73, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x65, 0x65, 0x64, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x73, 0x65, 0x65, 0x64, 0x12, 0x29, 0x0a, 0x10, 0x65, + 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x18, + 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, 0x65, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x48, 0x0a, 0x11, 0x65, 0x78, 0x70, 0x69, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1b, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x54, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x45, 0x78, + 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x10, + 0x65, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, + 0x22, 0x49, 0x0a, 0x12, 0x54, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x53, 0x65, 0x6e, 0x64, 0x65, 0x72, + 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, + 0x5f, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x73, 0x65, + 0x6e, 0x64, 0x65, 0x72, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x69, 0x67, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x73, 0x69, 0x67, 0x22, 0x7a, 0x0a, 0x16, 0x54, + 0x69, 0x63, 0x6b, 0x65, 0x74, 0x45, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, + 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x5f, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x63, + 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x12, 0x39, 0x0a, 0x19, + 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x62, + 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x16, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x42, 0x6c, + 0x6f, 0x63, 0x6b, 0x48, 0x61, 0x73, 0x68, 0x22, 0xa5, 0x02, 0x0a, 0x07, 0x50, 0x61, 0x79, 0x6d, + 0x65, 0x6e, 0x74, 0x12, 0x36, 0x0a, 0x0d, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x5f, 0x70, 0x61, + 0x72, 0x61, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x6e, 0x65, 0x74, + 0x2e, 0x54, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x0c, 0x74, + 0x69, 0x63, 0x6b, 0x65, 0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x73, + 0x65, 0x6e, 0x64, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x73, 0x65, 0x6e, + 0x64, 0x65, 0x72, 0x12, 0x48, 0x0a, 0x11, 0x65, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, + 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x54, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x45, 0x78, 0x70, 0x69, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x10, 0x65, 0x78, 0x70, + 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x49, 0x0a, + 0x14, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x5f, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x5f, 0x70, + 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x6e, 0x65, + 0x74, 0x2e, 0x54, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x53, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x50, 0x61, + 0x72, 0x61, 0x6d, 0x73, 0x52, 0x12, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x53, 0x65, 0x6e, 0x64, + 0x65, 0x72, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x35, 0x0a, 0x0e, 0x65, 0x78, 0x70, 0x65, + 0x63, 0x74, 0x65, 0x64, 0x5f, 0x70, 0x72, 0x69, 0x63, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x0e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x50, 0x72, 0x69, 0x63, 0x65, 0x49, 0x6e, 0x66, 0x6f, + 0x52, 0x0d, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x50, 0x72, 0x69, 0x63, 0x65, 0x32, + 0xd8, 0x01, 0x0a, 0x0c, 0x4f, 0x72, 0x63, 0x68, 0x65, 0x73, 0x74, 0x72, 0x61, 0x74, 0x6f, 0x72, + 0x12, 0x42, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x4f, 0x72, 0x63, 0x68, 0x65, 0x73, 0x74, 0x72, 0x61, + 0x74, 0x6f, 0x72, 0x12, 0x18, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x4f, 0x72, 0x63, 0x68, 0x65, 0x73, + 0x74, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, + 0x6e, 0x65, 0x74, 0x2e, 0x4f, 0x72, 0x63, 0x68, 0x65, 0x73, 0x74, 0x72, 0x61, 0x74, 0x6f, 0x72, + 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x5e, 0x0a, 0x15, 0x45, 0x6e, 0x64, 0x54, 0x72, 0x61, 0x6e, 0x73, + 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x21, 0x2e, + 0x6e, 0x65, 0x74, 0x2e, 0x45, 0x6e, 0x64, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x63, 0x6f, 0x64, 0x69, + 0x6e, 0x67, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x22, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x45, 0x6e, 0x64, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x63, + 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x24, 0x0a, 0x04, 0x50, 0x69, 0x6e, 0x67, 0x12, 0x0d, 0x2e, 0x6e, + 0x65, 0x74, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x6e, 0x67, 0x1a, 0x0d, 0x2e, 0x6e, 0x65, + 0x74, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x6e, 0x67, 0x32, 0x4e, 0x0a, 0x0a, 0x54, 0x72, + 0x61, 0x6e, 0x73, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x12, 0x40, 0x0a, 0x12, 0x52, 0x65, 0x67, 0x69, + 0x73, 0x74, 0x65, 0x72, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x12, 0x14, + 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x4e, 0x6f, 0x74, 0x69, 0x66, + 0x79, 0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x30, 0x01, 0x42, 0x07, 0x5a, 0x05, 0x2e, 0x2f, + 0x6e, 0x65, 0x74, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_net_lp_rpc_proto_rawDescOnce sync.Once + file_net_lp_rpc_proto_rawDescData = file_net_lp_rpc_proto_rawDesc +) + +func file_net_lp_rpc_proto_rawDescGZIP() []byte { + file_net_lp_rpc_proto_rawDescOnce.Do(func() { + file_net_lp_rpc_proto_rawDescData = protoimpl.X.CompressGZIP(file_net_lp_rpc_proto_rawDescData) + }) + return file_net_lp_rpc_proto_rawDescData +} + +var file_net_lp_rpc_proto_enumTypes = make([]protoimpl.EnumInfo, 5) +var file_net_lp_rpc_proto_msgTypes = make([]protoimpl.MessageInfo, 24) +var file_net_lp_rpc_proto_goTypes = []interface{}{ + (OSInfo_StorageType)(0), // 0: net.OSInfo.StorageType + (VideoProfile_Format)(0), // 1: net.VideoProfile.Format + (VideoProfile_Profile)(0), // 2: net.VideoProfile.Profile + (VideoProfile_VideoCodec)(0), // 3: net.VideoProfile.VideoCodec + (VideoProfile_ChromaSubsampling)(0), // 4: net.VideoProfile.ChromaSubsampling + (*PingPong)(nil), // 5: net.PingPong + (*EndTranscodingSessionRequest)(nil), // 6: net.EndTranscodingSessionRequest + (*EndTranscodingSessionResponse)(nil), // 7: net.EndTranscodingSessionResponse + (*OrchestratorRequest)(nil), // 8: net.OrchestratorRequest + (*OSInfo)(nil), // 9: net.OSInfo + (*S3OSInfo)(nil), // 10: net.S3OSInfo + (*PriceInfo)(nil), // 11: net.PriceInfo + (*Capabilities)(nil), // 12: net.Capabilities + (*OrchestratorInfo)(nil), // 13: net.OrchestratorInfo + (*AuthToken)(nil), // 14: net.AuthToken + (*SegData)(nil), // 15: net.SegData + (*SegParameters)(nil), // 16: net.SegParameters + (*VideoProfile)(nil), // 17: net.VideoProfile + (*TranscodedSegmentData)(nil), // 18: net.TranscodedSegmentData + (*TranscodeData)(nil), // 19: net.TranscodeData + (*TranscodeResult)(nil), // 20: net.TranscodeResult + (*RegisterRequest)(nil), // 21: net.RegisterRequest + (*NotifySegment)(nil), // 22: net.NotifySegment + (*TicketParams)(nil), // 23: net.TicketParams + (*TicketSenderParams)(nil), // 24: net.TicketSenderParams + (*TicketExpirationParams)(nil), // 25: net.TicketExpirationParams + (*Payment)(nil), // 26: net.Payment + nil, // 27: net.Capabilities.CapacitiesEntry + (*Capabilities_Constraints)(nil), // 28: net.Capabilities.Constraints +} +var file_net_lp_rpc_proto_depIdxs = []int32{ + 14, // 0: net.EndTranscodingSessionRequest.auth_token:type_name -> net.AuthToken + 0, // 1: net.OSInfo.storageType:type_name -> net.OSInfo.StorageType + 10, // 2: net.OSInfo.s3info:type_name -> net.S3OSInfo + 27, // 3: net.Capabilities.capacities:type_name -> net.Capabilities.CapacitiesEntry + 28, // 4: net.Capabilities.constraints:type_name -> net.Capabilities.Constraints + 23, // 5: net.OrchestratorInfo.ticket_params:type_name -> net.TicketParams + 11, // 6: net.OrchestratorInfo.price_info:type_name -> net.PriceInfo + 12, // 7: net.OrchestratorInfo.capabilities:type_name -> net.Capabilities + 14, // 8: net.OrchestratorInfo.auth_token:type_name -> net.AuthToken + 9, // 9: net.OrchestratorInfo.storage:type_name -> net.OSInfo + 12, // 10: net.SegData.capabilities:type_name -> net.Capabilities + 14, // 11: net.SegData.auth_token:type_name -> net.AuthToken + 9, // 12: net.SegData.storage:type_name -> net.OSInfo + 17, // 13: net.SegData.fullProfiles:type_name -> net.VideoProfile + 17, // 14: net.SegData.fullProfiles2:type_name -> net.VideoProfile + 17, // 15: net.SegData.fullProfiles3:type_name -> net.VideoProfile + 16, // 16: net.SegData.segment_parameters:type_name -> net.SegParameters + 1, // 17: net.VideoProfile.format:type_name -> net.VideoProfile.Format + 2, // 18: net.VideoProfile.profile:type_name -> net.VideoProfile.Profile + 3, // 19: net.VideoProfile.encoder:type_name -> net.VideoProfile.VideoCodec + 4, // 20: net.VideoProfile.chromaFormat:type_name -> net.VideoProfile.ChromaSubsampling + 18, // 21: net.TranscodeData.segments:type_name -> net.TranscodedSegmentData + 19, // 22: net.TranscodeResult.data:type_name -> net.TranscodeData + 13, // 23: net.TranscodeResult.info:type_name -> net.OrchestratorInfo + 12, // 24: net.RegisterRequest.capabilities:type_name -> net.Capabilities + 15, // 25: net.NotifySegment.segData:type_name -> net.SegData + 25, // 26: net.TicketParams.expiration_params:type_name -> net.TicketExpirationParams + 23, // 27: net.Payment.ticket_params:type_name -> net.TicketParams + 25, // 28: net.Payment.expiration_params:type_name -> net.TicketExpirationParams + 24, // 29: net.Payment.ticket_sender_params:type_name -> net.TicketSenderParams + 11, // 30: net.Payment.expected_price:type_name -> net.PriceInfo + 8, // 31: net.Orchestrator.GetOrchestrator:input_type -> net.OrchestratorRequest + 6, // 32: net.Orchestrator.EndTranscodingSession:input_type -> net.EndTranscodingSessionRequest + 5, // 33: net.Orchestrator.Ping:input_type -> net.PingPong + 21, // 34: net.Transcoder.RegisterTranscoder:input_type -> net.RegisterRequest + 13, // 35: net.Orchestrator.GetOrchestrator:output_type -> net.OrchestratorInfo + 7, // 36: net.Orchestrator.EndTranscodingSession:output_type -> net.EndTranscodingSessionResponse + 5, // 37: net.Orchestrator.Ping:output_type -> net.PingPong + 22, // 38: net.Transcoder.RegisterTranscoder:output_type -> net.NotifySegment + 35, // [35:39] is the sub-list for method output_type + 31, // [31:35] is the sub-list for method input_type + 31, // [31:31] is the sub-list for extension type_name + 31, // [31:31] is the sub-list for extension extendee + 0, // [0:31] is the sub-list for field type_name +} + +func init() { file_net_lp_rpc_proto_init() } +func file_net_lp_rpc_proto_init() { + if File_net_lp_rpc_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_net_lp_rpc_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PingPong); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_net_lp_rpc_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*EndTranscodingSessionRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_net_lp_rpc_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*EndTranscodingSessionResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_net_lp_rpc_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*OrchestratorRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_net_lp_rpc_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*OSInfo); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_net_lp_rpc_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*S3OSInfo); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_net_lp_rpc_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PriceInfo); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_net_lp_rpc_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Capabilities); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_net_lp_rpc_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*OrchestratorInfo); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_net_lp_rpc_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AuthToken); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_net_lp_rpc_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SegData); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_net_lp_rpc_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SegParameters); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_net_lp_rpc_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*VideoProfile); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_net_lp_rpc_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*TranscodedSegmentData); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_net_lp_rpc_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*TranscodeData); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_net_lp_rpc_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*TranscodeResult); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_net_lp_rpc_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RegisterRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_net_lp_rpc_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*NotifySegment); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_net_lp_rpc_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*TicketParams); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_net_lp_rpc_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*TicketSenderParams); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_net_lp_rpc_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*TicketExpirationParams); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_net_lp_rpc_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Payment); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_net_lp_rpc_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Capabilities_Constraints); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + file_net_lp_rpc_proto_msgTypes[15].OneofWrappers = []interface{}{ + (*TranscodeResult_Error)(nil), + (*TranscodeResult_Data)(nil), + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_net_lp_rpc_proto_rawDesc, + NumEnums: 5, + NumMessages: 24, + NumExtensions: 0, + NumServices: 2, + }, + GoTypes: file_net_lp_rpc_proto_goTypes, + DependencyIndexes: file_net_lp_rpc_proto_depIdxs, + EnumInfos: file_net_lp_rpc_proto_enumTypes, + MessageInfos: file_net_lp_rpc_proto_msgTypes, + }.Build() + File_net_lp_rpc_proto = out.File + file_net_lp_rpc_proto_rawDesc = nil + file_net_lp_rpc_proto_goTypes = nil + file_net_lp_rpc_proto_depIdxs = nil } diff --git a/net/lp_rpc.proto b/net/lp_rpc.proto index e53a594fcf..b14f45db5e 100644 --- a/net/lp_rpc.proto +++ b/net/lp_rpc.proto @@ -340,6 +340,9 @@ message NotifySegment { // ID for this particular transcoding task. int64 taskId = 16; + // Orchestrator identifier for segment metadata + string orchId = 18; + // All fields below are deprecated. May still be populated if necessary // Deprecated by segData. Job the segment belongs to. diff --git a/net/lp_rpc_grpc.pb.go b/net/lp_rpc_grpc.pb.go index 64a0935463..d998fd9a94 100644 --- a/net/lp_rpc_grpc.pb.go +++ b/net/lp_rpc_grpc.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. // versions: // - protoc-gen-go-grpc v1.2.0 -// - protoc v3.21.4 +// - protoc v3.21.12 // source: net/lp_rpc.proto package net diff --git a/server/ot_rpc.go b/server/ot_rpc.go index a4ceb8045d..62502ce256 100644 --- a/server/ot_rpc.go +++ b/server/ot_rpc.go @@ -190,6 +190,7 @@ func runTranscode(n *core.LivepeerNode, orchAddr string, httpc *http.Client, not } defer os.Remove(fname) md.Fname = fname + md.Metadata = core.MakeMetadata(notify.OrchId) clog.V(common.DEBUG).Infof(ctx, "Segment from taskId=%d url=%s saved to file=%s", notify.TaskId, notify.Url, fname) start := time.Now() From 45652c468438d89cc881297e8401246e3e5a61c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Leszko?= Date: Tue, 10 Sep 2024 15:35:11 +0200 Subject: [PATCH 08/21] Clean up inactive sessions (#3166) * Clean up inactive sessions Not cleaning up the sessions causes quite a big memory leak which in effect causes OOMKilled * Clean up inactive sessions Not cleaning up the sessions causes quite a big memory leak which in effect causes OOMKilled --- pm/sender.go | 7 +++++++ pm/stub.go | 5 +++++ server/broadcast.go | 22 ++++++++++++++------ server/broadcast_test.go | 20 +++++++++---------- server/mediaserver_test.go | 41 +++++++++----------------------------- server/rpc.go | 1 + server/sessionpool_test.go | 3 ++- 7 files changed, 49 insertions(+), 50 deletions(-) diff --git a/pm/sender.go b/pm/sender.go index 6f6acf0fd4..ebeb09e2c6 100644 --- a/pm/sender.go +++ b/pm/sender.go @@ -22,6 +22,9 @@ type Sender interface { // for creating new tickets StartSession(ticketParams TicketParams) string + // CleanupSession deletes session from the internal map + CleanupSession(sessionID string) + // CreateTicketBatch returns a ticket batch of the specified size CreateTicketBatch(sessionID string, size int) (*TicketBatch, error) @@ -82,6 +85,10 @@ func (s *sender) EV(sessionID string) (*big.Rat, error) { return ticketEV(session.ticketParams.FaceValue, session.ticketParams.WinProb), nil } +func (s *sender) CleanupSession(sessionID string) { + s.sessions.Delete(sessionID) +} + func (s *sender) validateSender(info *SenderInfo) error { maxWithdrawRound := new(big.Int).Add(s.timeManager.LastInitializedRound(), big.NewInt(1)) if info.WithdrawRound.Int64() != 0 && info.WithdrawRound.Cmp(maxWithdrawRound) != 1 { diff --git a/pm/stub.go b/pm/stub.go index a3e0f7f224..549f386472 100644 --- a/pm/stub.go +++ b/pm/stub.go @@ -511,6 +511,11 @@ func (m *MockSender) StartSession(ticketParams TicketParams) string { return args.String(0) } +// CleanupSession deletes session from the internal ma +func (m *MockSender) CleanupSession(sessionID string) { + m.Called(sessionID) +} + // EV returns the ticket EV for a session func (m *MockSender) EV(sessionID string) (*big.Rat, error) { args := m.Called(sessionID) diff --git a/server/broadcast.go b/server/broadcast.go index bcd0a54658..a3e8cf64b9 100755 --- a/server/broadcast.go +++ b/server/broadcast.go @@ -85,6 +85,7 @@ func (cfg *BroadcastConfig) SetMaxPrice(price *core.AutoConvertedPrice) { } type sessionsCreator func() ([]*BroadcastSession, error) +type sessionsCleanup func(sessionId string) type SessionPool struct { mid core.ManifestID @@ -101,10 +102,11 @@ type SessionPool struct { finished bool // set at stream end createSessions sessionsCreator + cleanupSession sessionsCleanup sus *suspender } -func NewSessionPool(mid core.ManifestID, poolSize, numOrchs int, sus *suspender, createSession sessionsCreator, +func NewSessionPool(mid core.ManifestID, poolSize, numOrchs int, sus *suspender, createSession sessionsCreator, cleanupSession sessionsCleanup, sel BroadcastSessionsSelector) *SessionPool { return &SessionPool{ @@ -114,6 +116,7 @@ func NewSessionPool(mid core.ManifestID, poolSize, numOrchs int, sus *suspender, sessMap: make(map[string]*BroadcastSession), sel: sel, createSessions: createSession, + cleanupSession: cleanupSession, sus: sus, } } @@ -378,6 +381,7 @@ func (sp *SessionPool) removeSession(session *BroadcastSession) { sp.lock.Lock() defer sp.lock.Unlock() + sp.cleanupSession(session.PMSessionID) delete(sp.sessMap, session.Transcoder()) } @@ -463,11 +467,14 @@ func NewSessionManager(ctx context.Context, node *core.LivepeerNode, params *cor untrustedNumOrchs := int(untrustedPoolSize) susTrusted := newSuspender() susUntrusted := newSuspender() + cleanupSession := func(sessionID string) { + node.Sender.CleanupSession(sessionID) + } createSessionsTrusted := func() ([]*BroadcastSession, error) { - return selectOrchestrator(ctx, node, params, trustedNumOrchs, susTrusted, common.ScoreAtLeast(common.Score_Trusted)) + return selectOrchestrator(ctx, node, params, trustedNumOrchs, susTrusted, common.ScoreAtLeast(common.Score_Trusted), cleanupSession) } createSessionsUntrusted := func() ([]*BroadcastSession, error) { - return selectOrchestrator(ctx, node, params, untrustedNumOrchs, susUntrusted, common.ScoreEqualTo(common.Score_Untrusted)) + return selectOrchestrator(ctx, node, params, untrustedNumOrchs, susUntrusted, common.ScoreEqualTo(common.Score_Untrusted), cleanupSession) } var stakeRdr stakeReader if node.Eth != nil { @@ -476,8 +483,8 @@ func NewSessionManager(ctx context.Context, node *core.LivepeerNode, params *cor bsm := &BroadcastSessionsManager{ mid: params.ManifestID, VerificationFreq: params.VerificationFreq, - trustedPool: NewSessionPool(params.ManifestID, int(trustedPoolSize), trustedNumOrchs, susTrusted, createSessionsTrusted, NewMinLSSelector(stakeRdr, 1.0, node.SelectionAlgorithm, node.OrchPerfScore)), - untrustedPool: NewSessionPool(params.ManifestID, int(untrustedPoolSize), untrustedNumOrchs, susUntrusted, createSessionsUntrusted, NewMinLSSelector(stakeRdr, 1.0, node.SelectionAlgorithm, node.OrchPerfScore)), + trustedPool: NewSessionPool(params.ManifestID, int(trustedPoolSize), trustedNumOrchs, susTrusted, createSessionsTrusted, cleanupSession, NewMinLSSelector(stakeRdr, 1.0, node.SelectionAlgorithm, node.OrchPerfScore)), + untrustedPool: NewSessionPool(params.ManifestID, int(untrustedPoolSize), untrustedNumOrchs, susUntrusted, createSessionsUntrusted, cleanupSession, NewMinLSSelector(stakeRdr, 1.0, node.SelectionAlgorithm, node.OrchPerfScore)), } bsm.trustedPool.refreshSessions(ctx) bsm.untrustedPool.refreshSessions(ctx) @@ -768,7 +775,7 @@ func (bsm *BroadcastSessionsManager) usingVerified() bool { } func selectOrchestrator(ctx context.Context, n *core.LivepeerNode, params *core.StreamParameters, count int, sus *suspender, - scorePred common.ScorePred) ([]*BroadcastSession, error) { + scorePred common.ScorePred, cleanupSession sessionsCleanup) ([]*BroadcastSession, error) { if n.OrchestratorPool == nil { clog.Infof(ctx, "No orchestrators specified; not transcoding") @@ -836,6 +843,7 @@ func selectOrchestrator(ctx context.Context, n *core.LivepeerNode, params *core. OrchestratorOS: orchOS, BroadcasterOS: bcastOS, Sender: n.Sender, + CleanupSession: cleanupSession, PMSessionID: sessionID, Balances: n.Balances, Balance: balance, @@ -1470,7 +1478,9 @@ func updateSession(sess *BroadcastSession, res *ReceivedTranscodeResult) { // and the next time this BroadcastSession is used, the ticket params will be validated // during ticket creation in genPayment(). If ticket params validation during ticket // creation fails, then this BroadcastSession will be removed + oldSession := sess.PMSessionID sess.PMSessionID = sess.Sender.StartSession(*pmTicketParams(oInfo.TicketParams)) + sess.CleanupSession(oldSession) // Session ID changed so we need to make sure the balance tracks the new session ID if oldInfo.AuthToken.SessionId != oInfo.AuthToken.SessionId { diff --git a/server/broadcast_test.go b/server/broadcast_test.go index 669ff06313..372d25205a 100644 --- a/server/broadcast_test.go +++ b/server/broadcast_test.go @@ -61,16 +61,10 @@ func StubBroadcastSession(transcoder string) *BroadcastSession { }, OrchestratorScore: common.Score_Trusted, lock: &sync.RWMutex{}, + CleanupSession: func(sessionId string) {}, } } -func StubBroadcastSessionsManager() *BroadcastSessionsManager { - sess1 := StubBroadcastSession("transcoder1") - sess2 := StubBroadcastSession("transcoder2") - - return bsmWithSessList([]*BroadcastSession{sess1, sess2}) -} - func selFactoryEmpty() BroadcastSessionsSelector { return &LIFOSelector{} } @@ -101,6 +95,8 @@ func bsmWithSessListExt(sessList, untrustedSessList []*BroadcastSession, noRefre return cloneSessions(sessList), nil } + var deleteSessions = func(sessionID string) {} + untrustedSessMap := make(map[string]*BroadcastSession) for _, sess := range untrustedSessList { untrustedSessMap[sess.OrchestratorInfo.Transcoder] = sess @@ -118,11 +114,10 @@ func bsmWithSessListExt(sessList, untrustedSessList []*BroadcastSession, noRefre if noRefresh { createSessions = createSessionsEmpty createSessionsUntrusted = createSessionsEmpty - } - trustedPool := NewSessionPool("test", len(sessList), 1, newSuspender(), createSessions, sel) + trustedPool := NewSessionPool("test", len(sessList), 1, newSuspender(), createSessions, deleteSessions, sel) trustedPool.sessMap = sessMap - untrustedPool := NewSessionPool("test", len(untrustedSessList), 1, newSuspender(), createSessionsUntrusted, unsel) + untrustedPool := NewSessionPool("test", len(untrustedSessList), 1, newSuspender(), createSessionsUntrusted, deleteSessions, unsel) untrustedPool.sessMap = untrustedSessMap return &BroadcastSessionsManager{ @@ -393,6 +388,7 @@ func TestSelectSession_MultipleInFlight2(t *testing.T) { sess := StubBroadcastSession(ts.URL) sender := &pm.MockSender{} sender.On("StartSession", mock.Anything).Return("foo").Times(3) + sender.On("StopSession", mock.Anything).Times(3) sender.On("EV", mock.Anything).Return(big.NewRat(1000000, 1), nil) sender.On("CreateTicketBatch", mock.Anything, mock.Anything).Return(defaultTicketBatch(), nil) sender.On("ValidateTicketParams", mock.Anything).Return(nil) @@ -1125,7 +1121,9 @@ func TestUpdateSession(t *testing.T) { balances := core.NewAddressBalances(5 * time.Minute) defer balances.StopCleanup() - sess := &BroadcastSession{PMSessionID: "foo", LatencyScore: 1.1, Balances: balances, lock: &sync.RWMutex{}} + sess := &BroadcastSession{PMSessionID: "foo", LatencyScore: 1.1, Balances: balances, lock: &sync.RWMutex{}, CleanupSession: func(sessionID string) { + + }} res := &ReceivedTranscodeResult{ LatencyScore: 2.1, } diff --git a/server/mediaserver_test.go b/server/mediaserver_test.go index 8a7db8659f..09f4f53370 100644 --- a/server/mediaserver_test.go +++ b/server/mediaserver_test.go @@ -115,31 +115,6 @@ func setupServerWithCancel() (*LivepeerServer, context.CancelFunc) { return S, cancel } -func setupServerWithCancelAndPorts() (*LivepeerServer, context.CancelFunc) { - drivers.NodeStorage = drivers.NewMemoryDriver(nil) - ctx, cancel := context.WithCancel(context.Background()) - var S *LivepeerServer - if S == nil { - httpPushResetTimer = func() (context.Context, context.CancelFunc) { - ctx, cancel := context.WithCancel(context.Background()) - pushResetWg.Add(1) - wrapCancel := func() { - cancel() - pushResetWg.Done() - } - return ctx, wrapCancel - } - n, _ := core.NewLivepeerNode(nil, "./tmp", nil) - S, _ = NewLivepeerServer("127.0.0.1:2938", n, true, "") - go S.StartMediaServer(ctx, "127.0.0.1:9080") - go func() { - srv := &http.Server{Addr: "127.0.0.1:9938"} - S.StartCliWebserver(srv) - }() - } - return S, cancel -} - // since we have test that checks that there is no goroutine // left running after using RTMP connection - we have to properly // close connections in all the tests that are using them @@ -171,6 +146,8 @@ func (d *stubDiscovery) GetInfos() []common.OrchestratorLocalInfo { return nil } +var cleanupSessions = func(sessionID string) {} + func (d *stubDiscovery) GetOrchestrators(ctx context.Context, num int, sus common.Suspender, caps common.CapabilityComparator, scorePred common.ScorePred) (common.OrchestratorDescriptors, error) { @@ -237,14 +214,14 @@ func TestSelectOrchestrator(t *testing.T) { mid := core.RandomManifestID() storage := drivers.NodeStorage.NewSession(string(mid)) sp := &core.StreamParameters{ManifestID: mid, Profiles: []ffmpeg.VideoProfile{ffmpeg.P360p30fps16x9}, OS: storage} - if _, err := selectOrchestrator(context.TODO(), s.LivepeerNode, sp, 4, newSuspender(), common.ScoreAtLeast(0)); err != errDiscovery { + if _, err := selectOrchestrator(context.TODO(), s.LivepeerNode, sp, 4, newSuspender(), common.ScoreAtLeast(0), cleanupSessions); err != errDiscovery { t.Error("Expected error with discovery") } sd := &stubDiscovery{} // Discovery returned no orchestrators s.LivepeerNode.OrchestratorPool = sd - if sess, err := selectOrchestrator(context.TODO(), s.LivepeerNode, sp, 4, newSuspender(), common.ScoreAtLeast(0)); sess != nil || err != errNoOrchs { + if sess, err := selectOrchestrator(context.TODO(), s.LivepeerNode, sp, 4, newSuspender(), common.ScoreAtLeast(0), cleanupSessions); sess != nil || err != errNoOrchs { t.Error("Expected nil session") } @@ -255,7 +232,7 @@ func TestSelectOrchestrator(t *testing.T) { {PriceInfo: &net.PriceInfo{PricePerUnit: 1, PixelsPerUnit: 1}, TicketParams: &net.TicketParams{}, AuthToken: authToken0}, {PriceInfo: &net.PriceInfo{PricePerUnit: 1, PixelsPerUnit: 1}, TicketParams: &net.TicketParams{}, AuthToken: authToken1}, } - sess, _ := selectOrchestrator(context.TODO(), s.LivepeerNode, sp, 4, newSuspender(), common.ScoreAtLeast(0)) + sess, _ := selectOrchestrator(context.TODO(), s.LivepeerNode, sp, 4, newSuspender(), common.ScoreAtLeast(0), cleanupSessions) if len(sess) != len(sd.infos) { t.Error("Expected session length of 2") @@ -290,7 +267,7 @@ func TestSelectOrchestrator(t *testing.T) { externalStorage := drivers.NodeStorage.NewSession(string(mid)) sp.OS = externalStorage - sess, err := selectOrchestrator(context.TODO(), s.LivepeerNode, sp, 4, newSuspender(), common.ScoreAtLeast(0)) + sess, err := selectOrchestrator(context.TODO(), s.LivepeerNode, sp, 4, newSuspender(), common.ScoreAtLeast(0), cleanupSessions) assert.Nil(err) // B should initialize new OS session using auth token sessionID @@ -378,7 +355,7 @@ func TestSelectOrchestrator(t *testing.T) { expSessionID2 := "bar" sender.On("StartSession", mock.Anything).Return(expSessionID2).Once() - sess, err = selectOrchestrator(context.TODO(), s.LivepeerNode, sp, 4, newSuspender(), common.ScoreAtLeast(0)) + sess, err = selectOrchestrator(context.TODO(), s.LivepeerNode, sp, 4, newSuspender(), common.ScoreAtLeast(0), cleanupSessions) require.Nil(err) assert.Len(sess, 2) @@ -407,7 +384,7 @@ func TestSelectOrchestrator(t *testing.T) { // Skip orchestrator if missing auth token sd.infos[0].AuthToken = nil - sess, err = selectOrchestrator(context.TODO(), s.LivepeerNode, sp, 4, newSuspender(), func(float32) bool { return true }) + sess, err = selectOrchestrator(context.TODO(), s.LivepeerNode, sp, 4, newSuspender(), func(float32) bool { return true }, cleanupSessions) require.Nil(err) assert.Len(sess, 1) @@ -417,7 +394,7 @@ func TestSelectOrchestrator(t *testing.T) { sd.infos[0].AuthToken = &net.AuthToken{} sd.infos[0].TicketParams = nil - sess, err = selectOrchestrator(context.TODO(), s.LivepeerNode, sp, 4, newSuspender(), func(float32) bool { return true }) + sess, err = selectOrchestrator(context.TODO(), s.LivepeerNode, sp, 4, newSuspender(), func(float32) bool { return true }, cleanupSessions) require.Nil(err) assert.Len(sess, 1) diff --git a/server/rpc.go b/server/rpc.go index 097c61e709..6c5d24637c 100644 --- a/server/rpc.go +++ b/server/rpc.go @@ -117,6 +117,7 @@ type BroadcastSession struct { OrchestratorInfo *net.OrchestratorInfo OrchestratorOS drivers.OSSession PMSessionID string + CleanupSession sessionsCleanup Balance Balance InitialPrice *net.PriceInfo } diff --git a/server/sessionpool_test.go b/server/sessionpool_test.go index 49a9f4f44b..832f7016d3 100644 --- a/server/sessionpool_test.go +++ b/server/sessionpool_test.go @@ -51,7 +51,8 @@ func poolWithSessList(sessList []*BroadcastSession) *sessionPoolLIFO { // return sessList, nil return nil, nil } - pool := NewSessionPool("test", len(sessList), 1, newSuspender(), createSessions, sel) + var deleteSessions = func(sessionID string) {} + pool := NewSessionPool("test", len(sessList), 1, newSuspender(), createSessions, deleteSessions, sel) pool.sessMap = sessMap return newSessionPoolLIFO(pool) } From 834a9c622b1b4b9b4b4edda3294338da4f72888b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Leszko?= Date: Tue, 10 Sep 2024 15:47:40 +0200 Subject: [PATCH 09/21] selection: Clear known sessions if none of them has good enough latency score (#3086) Problem: We never cleaned the known sessions, even if all of them had too low latency score to use; example of what sometimes happens: 1) Broadcaster accumulated 8 known sessions, but all had too low latency score 2) Session refresh was not triggered because we had a lot of knows session in the pool 3) At the same time, we didn't have sessions in unknown session pool 4) Selection checked that it cannot use the known session and tried to select from unknown sessions (but the pool was empty or there were no sessions fulfilling the condition of max price or perf score) Co-authored-by: Thom Shutt --- server/selection.go | 11 ++++++---- server/selection_test.go | 47 ++++++++++++++++------------------------ 2 files changed, 26 insertions(+), 32 deletions(-) diff --git a/server/selection.go b/server/selection.go index c827034db6..985f2d2546 100644 --- a/server/selection.go +++ b/server/selection.go @@ -135,12 +135,15 @@ func (s *MinLSSelector) Select(ctx context.Context) *BroadcastSession { return s.selectUnknownSession(ctx) } - minSess := sess.(*BroadcastSession) - if minSess.LatencyScore > s.minLS && len(s.unknownSessions) > 0 { - return s.selectUnknownSession(ctx) + lowestLatencyScoreKnownSession := heap.Pop(s.knownSessions).(*BroadcastSession) + if lowestLatencyScoreKnownSession.LatencyScore <= s.minLS { + // known session has good enough latency score, use it + return lowestLatencyScoreKnownSession } - return heap.Pop(s.knownSessions).(*BroadcastSession) + // known session does not have good enough latency score, clear the heap and use unknown session + s.knownSessions = &sessHeap{} + return s.selectUnknownSession(ctx) } // Size returns the number of sessions stored by the selector diff --git a/server/selection_test.go b/server/selection_test.go index aa936ddb04..9699bb7af5 100644 --- a/server/selection_test.go +++ b/server/selection_test.go @@ -183,48 +183,39 @@ func TestMinLSSelector(t *testing.T) { assert.Equal(sel.Size(), 2) assert.Equal(len(sel.unknownSessions), 2) - // Set sess1.LatencyScore to not be good enough - sess1.LatencyScore = 1.1 + // Set sess1.LatencyScore to good enough + sess1.LatencyScore = 0.9 sel.Complete(sess1) assert.Equal(sel.Size(), 3) assert.Equal(len(sel.unknownSessions), 2) assert.Equal(sel.knownSessions.Len(), 1) - // Select from unknownSessions - sess2 := sel.Select(context.TODO()) + // Select sess1 because it's a known session with good enough latency score + sess := sel.Select(context.TODO()) assert.Equal(sel.Size(), 2) - assert.Equal(len(sel.unknownSessions), 1) - assert.Equal(sel.knownSessions.Len(), 1) + assert.Equal(len(sel.unknownSessions), 2) + assert.Equal(sel.knownSessions.Len(), 0) - // Set sess2.LatencyScore to be good enough - sess2.LatencyScore = .9 - sel.Complete(sess2) + // Set sess.LatencyScore to not be good enough + sess.LatencyScore = 1.1 + sel.Complete(sess) assert.Equal(sel.Size(), 3) - assert.Equal(len(sel.unknownSessions), 1) - assert.Equal(sel.knownSessions.Len(), 2) + assert.Equal(len(sel.unknownSessions), 2) + assert.Equal(sel.knownSessions.Len(), 1) - // Select from knownSessions - knownSess := sel.Select(context.TODO()) + // Select from unknownSessions, because sess2 does not have a good enough latency score + sess = sel.Select(context.TODO()) + sess.LatencyScore = 1.1 + sel.Complete(sess) assert.Equal(sel.Size(), 2) assert.Equal(len(sel.unknownSessions), 1) assert.Equal(sel.knownSessions.Len(), 1) - assert.Equal(knownSess, sess2) - // Set knownSess.LatencyScore to not be good enough - knownSess.LatencyScore = 1.1 - sel.Complete(knownSess) - // Clear unknownSessions - sess := sel.Select(context.TODO()) - sess.LatencyScore = 2.1 - sel.Complete(sess) - assert.Equal(len(sel.unknownSessions), 0) - assert.Equal(sel.knownSessions.Len(), 3) - - // Select from knownSessions - knownSess = sel.Select(context.TODO()) - assert.Equal(sel.Size(), 2) + // Select the last unknown session + sess = sel.Select(context.TODO()) + assert.Equal(sel.Size(), 0) assert.Equal(len(sel.unknownSessions), 0) - assert.Equal(sel.knownSessions.Len(), 2) + assert.Equal(sel.knownSessions.Len(), 0) sel.Clear() assert.Zero(sel.Size()) From 56a8a88be25456329eb8e2b4176974e99984a583 Mon Sep 17 00:00:00 2001 From: Josh Allmann Date: Tue, 10 Sep 2024 08:31:13 -0700 Subject: [PATCH 10/21] release v0.7.9 (#3167) --- CHANGELOG.md | 18 ++++++++++++++++++ CHANGELOG_PENDING.md | 4 ---- VERSION | 2 +- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a05b0885c7..29f376fbaf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,23 @@ # Changelog +## v0.7.9 + +- [#3165](https://github.com/livepeer/go-livepeer/pull/3165) Add node version and orch addr to transcoded metadata + +### Features ⚒ + +#### Broadcaster + +- [#3158](https://github.com/livepeer/go-livepeer/pull/3158) Add a metric tag for Orchestrator version + +### Bug Fixes 🐞 + +#### Broadcaster + +- [#3164](https://github.com/livepeer/go-livepeer/pull/3164) Fix media compatibility check +- [#3166](https://github.com/livepeer/go-livepeer/pull/3166) Clean up inactive sessions +- [#3086](https://github.com/livepeer/go-livepeer/pull/3086) Clear known sessions with inadequate latency scores + ## v0.7.8 ### Features ⚒ diff --git a/CHANGELOG_PENDING.md b/CHANGELOG_PENDING.md index 58c0bfd8d2..22f1b28ed7 100644 --- a/CHANGELOG_PENDING.md +++ b/CHANGELOG_PENDING.md @@ -2,8 +2,6 @@ ## v0.X.X -- [#3165](https://github.com/livepeer/go-livepeer/pull/3165) Add node version and orch addr to transcoded metadata - ### Breaking Changes 🚨🚨 ### Features ⚒ @@ -24,8 +22,6 @@ #### Broadcaster -- [#3164](https://github.com/livepeer/go-livepeer/pull/3164) Fix video compatibility check - #### Orchestrator #### Transcoder diff --git a/VERSION b/VERSION index e7c7d3cc3c..1451d481e2 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.7.8 +0.7.9 \ No newline at end of file From c5f5a1177148ef78f933d46bd1fc2823a7665f91 Mon Sep 17 00:00:00 2001 From: ad-astra-video <99882368+ad-astra-video@users.noreply.github.com> Date: Wed, 11 Sep 2024 17:14:21 -0500 Subject: [PATCH 11/21] fix(ai): update SAM2 capability description to only upper case first letter (#3170) --- core/capabilities.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/capabilities.go b/core/capabilities.go index 734404ca83..fc9e5217ba 100644 --- a/core/capabilities.go +++ b/core/capabilities.go @@ -115,7 +115,7 @@ var CapabilityNameLookup = map[Capability]string{ Capability_ImageToVideo: "Image to video", Capability_Upscale: "Upscale", Capability_AudioToText: "Audio to text", - Capability_SegmentAnything2: "Segment Anything 2", + Capability_SegmentAnything2: "Segment anything 2", } var CapabilityTestLookup = map[Capability]CapabilityTest{ From e01daa22d565a1652653ff802b861421661ac84e Mon Sep 17 00:00:00 2001 From: Rick Staa Date: Fri, 13 Sep 2024 17:09:27 +0200 Subject: [PATCH 12/21] chore(ai): update ai-worker This commit updates the ai-worker to the one with the changed worker types. --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index b0fd01bd98..6e5a284e68 100644 --- a/go.mod +++ b/go.mod @@ -13,7 +13,7 @@ require ( github.com/golang/protobuf v1.5.4 github.com/jaypipes/ghw v0.10.0 github.com/jaypipes/pcidb v1.0.0 - github.com/livepeer/ai-worker v0.2.0 + github.com/livepeer/ai-worker v0.3.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-20240819180416-f87352959b85 diff --git a/go.sum b/go.sum index 3299db083c..70fa5c13f9 100644 --- a/go.sum +++ b/go.sum @@ -623,8 +623,8 @@ github.com/libp2p/go-netroute v0.2.0 h1:0FpsbsvuSnAhXFnCY0VLFbJOzaK0VnP0r1QT/o4n github.com/libp2p/go-netroute v0.2.0/go.mod h1:Vio7LTzZ+6hoT4CMZi5/6CpY3Snzh2vgZhWgxMNwlQI= github.com/libp2p/go-openssl v0.1.0 h1:LBkKEcUv6vtZIQLVTegAil8jbNpJErQ9AnT+bWV+Ooo= github.com/libp2p/go-openssl v0.1.0/go.mod h1:OiOxwPpL3n4xlenjx2h7AwSGaFSC/KZvf6gNdOBQMtc= -github.com/livepeer/ai-worker v0.2.0 h1:u6m3nVQnisqWn2nMhgTgKLQby7VDAEp5xmeHt7Res/Y= -github.com/livepeer/ai-worker v0.2.0/go.mod h1:91lMzkzVuwR9kZ0EzXwf+7yVhLaNVmYAfmBtn7t3cQA= +github.com/livepeer/ai-worker v0.3.0 h1:fdxsHPO6/5CpTmqcyJoeWL4MCqxJVnLiDFCZYGCfxOs= +github.com/livepeer/ai-worker v0.3.0/go.mod h1:91lMzkzVuwR9kZ0EzXwf+7yVhLaNVmYAfmBtn7t3cQA= github.com/livepeer/go-tools v0.3.6-0.20240130205227-92479de8531b h1:VQcnrqtCA2UROp7q8ljkh2XA/u0KRgVv0S1xoUvOweE= github.com/livepeer/go-tools v0.3.6-0.20240130205227-92479de8531b/go.mod h1:hwJ5DKhl+pTanFWl+EUpw1H7ukPO/H+MFpgA7jjshzw= github.com/livepeer/joy4 v0.1.2-0.20191121080656-b2fea45cbded h1:ZQlvR5RB4nfT+cOQee+WqmaDOgGtP2oDMhcVvR4L0yA= From 14f77830417eab9ade3394aa697e2a02c5b18263 Mon Sep 17 00:00:00 2001 From: Rick Staa Date: Fri, 13 Sep 2024 17:20:12 +0200 Subject: [PATCH 13/21] Revert "chore(ai): update ai-worker" This reverts commit e01daa22d565a1652653ff802b861421661ac84e. --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 6e5a284e68..b0fd01bd98 100644 --- a/go.mod +++ b/go.mod @@ -13,7 +13,7 @@ require ( github.com/golang/protobuf v1.5.4 github.com/jaypipes/ghw v0.10.0 github.com/jaypipes/pcidb v1.0.0 - github.com/livepeer/ai-worker v0.3.0 + github.com/livepeer/ai-worker v0.2.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-20240819180416-f87352959b85 diff --git a/go.sum b/go.sum index 70fa5c13f9..3299db083c 100644 --- a/go.sum +++ b/go.sum @@ -623,8 +623,8 @@ github.com/libp2p/go-netroute v0.2.0 h1:0FpsbsvuSnAhXFnCY0VLFbJOzaK0VnP0r1QT/o4n github.com/libp2p/go-netroute v0.2.0/go.mod h1:Vio7LTzZ+6hoT4CMZi5/6CpY3Snzh2vgZhWgxMNwlQI= github.com/libp2p/go-openssl v0.1.0 h1:LBkKEcUv6vtZIQLVTegAil8jbNpJErQ9AnT+bWV+Ooo= github.com/libp2p/go-openssl v0.1.0/go.mod h1:OiOxwPpL3n4xlenjx2h7AwSGaFSC/KZvf6gNdOBQMtc= -github.com/livepeer/ai-worker v0.3.0 h1:fdxsHPO6/5CpTmqcyJoeWL4MCqxJVnLiDFCZYGCfxOs= -github.com/livepeer/ai-worker v0.3.0/go.mod h1:91lMzkzVuwR9kZ0EzXwf+7yVhLaNVmYAfmBtn7t3cQA= +github.com/livepeer/ai-worker v0.2.0 h1:u6m3nVQnisqWn2nMhgTgKLQby7VDAEp5xmeHt7Res/Y= +github.com/livepeer/ai-worker v0.2.0/go.mod h1:91lMzkzVuwR9kZ0EzXwf+7yVhLaNVmYAfmBtn7t3cQA= github.com/livepeer/go-tools v0.3.6-0.20240130205227-92479de8531b h1:VQcnrqtCA2UROp7q8ljkh2XA/u0KRgVv0S1xoUvOweE= github.com/livepeer/go-tools v0.3.6-0.20240130205227-92479de8531b/go.mod h1:hwJ5DKhl+pTanFWl+EUpw1H7ukPO/H+MFpgA7jjshzw= github.com/livepeer/joy4 v0.1.2-0.20191121080656-b2fea45cbded h1:ZQlvR5RB4nfT+cOQee+WqmaDOgGtP2oDMhcVvR4L0yA= From ffb1922d4a26a47b189c20e811de5fa67f9ebc66 Mon Sep 17 00:00:00 2001 From: Rick Staa Date: Fri, 13 Sep 2024 18:01:14 +0200 Subject: [PATCH 14/21] refactor: update worker classes (#3171) This commit ensures that the go-livepeer code uses the new worker classes that were defined in https://github.com/livepeer/ai-worker/pull/191. --- ai/file_worker.go | 8 +++--- core/ai.go | 12 ++++----- core/orchestrator.go | 24 ++++++++--------- go.mod | 2 +- go.sum | 4 +-- server/ai_http.go | 36 +++++++++++++------------- server/ai_mediaserver.go | 12 ++++----- server/ai_process.go | 56 ++++++++++++++++++++-------------------- server/rpc.go | 12 ++++----- server/rpc_test.go | 24 ++++++++--------- 10 files changed, 95 insertions(+), 95 deletions(-) diff --git a/ai/file_worker.go b/ai/file_worker.go index e9eb85c641..1ce5478204 100644 --- a/ai/file_worker.go +++ b/ai/file_worker.go @@ -17,7 +17,7 @@ func NewFileWorker(files map[string]string) *FileWorker { return &FileWorker{files: files} } -func (w *FileWorker) TextToImage(ctx context.Context, req worker.TextToImageJSONRequestBody) (*worker.ImageResponse, error) { +func (w *FileWorker) TextToImage(ctx context.Context, req worker.GenTextToImageJSONRequestBody) (*worker.ImageResponse, error) { fname, ok := w.files["text-to-image"] if !ok { return nil, errors.New("text-to-image response file not found") @@ -36,7 +36,7 @@ func (w *FileWorker) TextToImage(ctx context.Context, req worker.TextToImageJSON return &resp, nil } -func (w *FileWorker) ImageToImage(ctx context.Context, req worker.ImageToImageMultipartRequestBody) (*worker.ImageResponse, error) { +func (w *FileWorker) ImageToImage(ctx context.Context, req worker.GenImageToImageMultipartRequestBody) (*worker.ImageResponse, error) { fname, ok := w.files["image-to-image"] if !ok { return nil, errors.New("image-to-image response file not found") @@ -55,7 +55,7 @@ func (w *FileWorker) ImageToImage(ctx context.Context, req worker.ImageToImageMu return &resp, nil } -func (w *FileWorker) ImageToVideo(ctx context.Context, req worker.ImageToVideoMultipartRequestBody) (*worker.VideoResponse, error) { +func (w *FileWorker) ImageToVideo(ctx context.Context, req worker.GenImageToVideoMultipartRequestBody) (*worker.VideoResponse, error) { fname, ok := w.files["image-to-video"] if !ok { return nil, errors.New("image-to-video response file not found") @@ -74,7 +74,7 @@ func (w *FileWorker) ImageToVideo(ctx context.Context, req worker.ImageToVideoMu return &resp, nil } -func (w *FileWorker) Upscale(ctx context.Context, req worker.UpscaleMultipartRequestBody) (*worker.ImageResponse, error) { +func (w *FileWorker) Upscale(ctx context.Context, req worker.GenUpscaleMultipartRequestBody) (*worker.ImageResponse, error) { fname, ok := w.files["upscale"] if !ok { return nil, errors.New("upscale response file not found") diff --git a/core/ai.go b/core/ai.go index 887e1f8c8c..31f331e49e 100644 --- a/core/ai.go +++ b/core/ai.go @@ -17,12 +17,12 @@ import ( var errPipelineNotAvailable = errors.New("pipeline not available") type AI interface { - TextToImage(context.Context, worker.TextToImageJSONRequestBody) (*worker.ImageResponse, error) - ImageToImage(context.Context, worker.ImageToImageMultipartRequestBody) (*worker.ImageResponse, error) - ImageToVideo(context.Context, worker.ImageToVideoMultipartRequestBody) (*worker.VideoResponse, error) - Upscale(context.Context, worker.UpscaleMultipartRequestBody) (*worker.ImageResponse, error) - AudioToText(context.Context, worker.AudioToTextMultipartRequestBody) (*worker.TextResponse, error) - SegmentAnything2(context.Context, worker.SegmentAnything2MultipartRequestBody) (*worker.MasksResponse, error) + TextToImage(context.Context, worker.GenTextToImageJSONRequestBody) (*worker.ImageResponse, error) + ImageToImage(context.Context, worker.GenImageToImageMultipartRequestBody) (*worker.ImageResponse, error) + ImageToVideo(context.Context, worker.GenImageToVideoMultipartRequestBody) (*worker.VideoResponse, error) + Upscale(context.Context, worker.GenUpscaleMultipartRequestBody) (*worker.ImageResponse, error) + AudioToText(context.Context, worker.GenAudioToTextMultipartRequestBody) (*worker.TextResponse, error) + SegmentAnything2(context.Context, worker.GenSegmentAnything2MultipartRequestBody) (*worker.MasksResponse, error) Warm(context.Context, string, string, worker.RunnerEndpoint, worker.OptimizationFlags) error Stop(context.Context) error HasCapacity(pipeline, modelID string) bool diff --git a/core/orchestrator.go b/core/orchestrator.go index ba9f470bd1..f8e343ae32 100644 --- a/core/orchestrator.go +++ b/core/orchestrator.go @@ -110,27 +110,27 @@ func (orch *orchestrator) TranscoderResults(tcID int64, res *RemoteTranscoderRes orch.node.TranscoderManager.transcoderResults(tcID, res) } -func (orch *orchestrator) TextToImage(ctx context.Context, req worker.TextToImageJSONRequestBody) (*worker.ImageResponse, error) { +func (orch *orchestrator) TextToImage(ctx context.Context, req worker.GenTextToImageJSONRequestBody) (*worker.ImageResponse, error) { return orch.node.textToImage(ctx, req) } -func (orch *orchestrator) ImageToImage(ctx context.Context, req worker.ImageToImageMultipartRequestBody) (*worker.ImageResponse, error) { +func (orch *orchestrator) ImageToImage(ctx context.Context, req worker.GenImageToImageMultipartRequestBody) (*worker.ImageResponse, error) { return orch.node.imageToImage(ctx, req) } -func (orch *orchestrator) ImageToVideo(ctx context.Context, req worker.ImageToVideoMultipartRequestBody) (*worker.ImageResponse, error) { +func (orch *orchestrator) ImageToVideo(ctx context.Context, req worker.GenImageToVideoMultipartRequestBody) (*worker.ImageResponse, error) { return orch.node.imageToVideo(ctx, req) } -func (orch *orchestrator) Upscale(ctx context.Context, req worker.UpscaleMultipartRequestBody) (*worker.ImageResponse, error) { +func (orch *orchestrator) Upscale(ctx context.Context, req worker.GenUpscaleMultipartRequestBody) (*worker.ImageResponse, error) { return orch.node.upscale(ctx, req) } -func (orch *orchestrator) AudioToText(ctx context.Context, req worker.AudioToTextMultipartRequestBody) (*worker.TextResponse, error) { +func (orch *orchestrator) AudioToText(ctx context.Context, req worker.GenAudioToTextMultipartRequestBody) (*worker.TextResponse, error) { return orch.node.AudioToText(ctx, req) } -func (orch *orchestrator) SegmentAnything2(ctx context.Context, req worker.SegmentAnything2MultipartRequestBody) (*worker.MasksResponse, error) { +func (orch *orchestrator) SegmentAnything2(ctx context.Context, req worker.GenSegmentAnything2MultipartRequestBody) (*worker.MasksResponse, error) { return orch.node.SegmentAnything2(ctx, req) } @@ -951,27 +951,27 @@ func (n *LivepeerNode) serveTranscoder(stream net.Transcoder_RegisterTranscoderS } } -func (n *LivepeerNode) textToImage(ctx context.Context, req worker.TextToImageJSONRequestBody) (*worker.ImageResponse, error) { +func (n *LivepeerNode) textToImage(ctx context.Context, req worker.GenTextToImageJSONRequestBody) (*worker.ImageResponse, error) { return n.AIWorker.TextToImage(ctx, req) } -func (n *LivepeerNode) imageToImage(ctx context.Context, req worker.ImageToImageMultipartRequestBody) (*worker.ImageResponse, error) { +func (n *LivepeerNode) imageToImage(ctx context.Context, req worker.GenImageToImageMultipartRequestBody) (*worker.ImageResponse, error) { return n.AIWorker.ImageToImage(ctx, req) } -func (n *LivepeerNode) upscale(ctx context.Context, req worker.UpscaleMultipartRequestBody) (*worker.ImageResponse, error) { +func (n *LivepeerNode) upscale(ctx context.Context, req worker.GenUpscaleMultipartRequestBody) (*worker.ImageResponse, error) { return n.AIWorker.Upscale(ctx, req) } -func (n *LivepeerNode) AudioToText(ctx context.Context, req worker.AudioToTextMultipartRequestBody) (*worker.TextResponse, error) { +func (n *LivepeerNode) AudioToText(ctx context.Context, req worker.GenAudioToTextMultipartRequestBody) (*worker.TextResponse, error) { return n.AIWorker.AudioToText(ctx, req) } -func (n *LivepeerNode) SegmentAnything2(ctx context.Context, req worker.SegmentAnything2MultipartRequestBody) (*worker.MasksResponse, error) { +func (n *LivepeerNode) SegmentAnything2(ctx context.Context, req worker.GenSegmentAnything2MultipartRequestBody) (*worker.MasksResponse, error) { return n.AIWorker.SegmentAnything2(ctx, req) } -func (n *LivepeerNode) imageToVideo(ctx context.Context, req worker.ImageToVideoMultipartRequestBody) (*worker.ImageResponse, error) { +func (n *LivepeerNode) imageToVideo(ctx context.Context, req worker.GenImageToVideoMultipartRequestBody) (*worker.ImageResponse, error) { // We might support generating more than one video in the future (i.e. multiple input images/prompts) numVideos := 1 diff --git a/go.mod b/go.mod index b0fd01bd98..f84f4a6b37 100644 --- a/go.mod +++ b/go.mod @@ -13,7 +13,7 @@ require ( github.com/golang/protobuf v1.5.4 github.com/jaypipes/ghw v0.10.0 github.com/jaypipes/pcidb v1.0.0 - github.com/livepeer/ai-worker v0.2.0 + github.com/livepeer/ai-worker v0.5.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-20240819180416-f87352959b85 diff --git a/go.sum b/go.sum index 3299db083c..8c7b8cd8cb 100644 --- a/go.sum +++ b/go.sum @@ -623,8 +623,8 @@ github.com/libp2p/go-netroute v0.2.0 h1:0FpsbsvuSnAhXFnCY0VLFbJOzaK0VnP0r1QT/o4n github.com/libp2p/go-netroute v0.2.0/go.mod h1:Vio7LTzZ+6hoT4CMZi5/6CpY3Snzh2vgZhWgxMNwlQI= github.com/libp2p/go-openssl v0.1.0 h1:LBkKEcUv6vtZIQLVTegAil8jbNpJErQ9AnT+bWV+Ooo= github.com/libp2p/go-openssl v0.1.0/go.mod h1:OiOxwPpL3n4xlenjx2h7AwSGaFSC/KZvf6gNdOBQMtc= -github.com/livepeer/ai-worker v0.2.0 h1:u6m3nVQnisqWn2nMhgTgKLQby7VDAEp5xmeHt7Res/Y= -github.com/livepeer/ai-worker v0.2.0/go.mod h1:91lMzkzVuwR9kZ0EzXwf+7yVhLaNVmYAfmBtn7t3cQA= +github.com/livepeer/ai-worker v0.5.0 h1:dgO6j9QVFPOq9omIcgB1YmgVSlhV94BMb6QO4WUocX8= +github.com/livepeer/ai-worker v0.5.0/go.mod h1:91lMzkzVuwR9kZ0EzXwf+7yVhLaNVmYAfmBtn7t3cQA= github.com/livepeer/go-tools v0.3.6-0.20240130205227-92479de8531b h1:VQcnrqtCA2UROp7q8ljkh2XA/u0KRgVv0S1xoUvOweE= github.com/livepeer/go-tools v0.3.6-0.20240130205227-92479de8531b/go.mod h1:hwJ5DKhl+pTanFWl+EUpw1H7ukPO/H+MFpgA7jjshzw= github.com/livepeer/joy4 v0.1.2-0.20191121080656-b2fea45cbded h1:ZQlvR5RB4nfT+cOQee+WqmaDOgGtP2oDMhcVvR4L0yA= diff --git a/server/ai_http.go b/server/ai_http.go index a11164bc9b..3f0bb97d9e 100644 --- a/server/ai_http.go +++ b/server/ai_http.go @@ -56,7 +56,7 @@ func (h *lphttp) TextToImage() http.Handler { remoteAddr := getRemoteAddr(r) ctx := clog.AddVal(r.Context(), clog.ClientIP, remoteAddr) - var req worker.TextToImageJSONRequestBody + var req worker.GenTextToImageJSONRequestBody if err := json.NewDecoder(r.Body).Decode(&req); err != nil { respondWithError(w, err.Error(), http.StatusBadRequest) return @@ -79,7 +79,7 @@ func (h *lphttp) ImageToImage() http.Handler { return } - var req worker.ImageToImageMultipartRequestBody + var req worker.GenImageToImageMultipartRequestBody if err := runtime.BindMultipart(&req, *multiRdr); err != nil { respondWithError(w, err.Error(), http.StatusInternalServerError) return @@ -102,7 +102,7 @@ func (h *lphttp) ImageToVideo() http.Handler { return } - var req worker.ImageToVideoMultipartRequestBody + var req worker.GenImageToVideoMultipartRequestBody if err := runtime.BindMultipart(&req, *multiRdr); err != nil { respondWithError(w, err.Error(), http.StatusInternalServerError) return @@ -125,7 +125,7 @@ func (h *lphttp) Upscale() http.Handler { return } - var req worker.UpscaleMultipartRequestBody + var req worker.GenUpscaleMultipartRequestBody if err := runtime.BindMultipart(&req, *multiRdr); err != nil { respondWithError(w, err.Error(), http.StatusInternalServerError) return @@ -148,7 +148,7 @@ func (h *lphttp) AudioToText() http.Handler { return } - var req worker.AudioToTextMultipartRequestBody + var req worker.GenAudioToTextMultipartRequestBody if err := runtime.BindMultipart(&req, *multiRdr); err != nil { respondWithError(w, err.Error(), http.StatusInternalServerError) return @@ -171,7 +171,7 @@ func (h *lphttp) SegmentAnything2() http.Handler { return } - var req worker.SegmentAnything2MultipartRequestBody + var req worker.GenSegmentAnything2MultipartRequestBody if err := runtime.BindMultipart(&req, *multiRdr); err != nil { respondWithError(w, err.Error(), http.StatusInternalServerError) return @@ -202,7 +202,7 @@ func handleAIRequest(ctx context.Context, w http.ResponseWriter, r *http.Request var outPixels int64 switch v := req.(type) { - case worker.TextToImageJSONRequestBody: + case worker.GenTextToImageJSONRequestBody: pipeline = "text-to-image" cap = core.Capability_TextToImage modelID = *v.ModelId @@ -226,7 +226,7 @@ func handleAIRequest(ctx context.Context, w http.ResponseWriter, r *http.Request } outPixels = height * width * numImages - case worker.ImageToImageMultipartRequestBody: + case worker.GenImageToImageMultipartRequestBody: pipeline = "image-to-image" cap = core.Capability_ImageToImage modelID = *v.ModelId @@ -251,7 +251,7 @@ func handleAIRequest(ctx context.Context, w http.ResponseWriter, r *http.Request } outPixels = int64(config.Height) * int64(config.Width) * numImages - case worker.UpscaleMultipartRequestBody: + case worker.GenUpscaleMultipartRequestBody: pipeline = "upscale" cap = core.Capability_Upscale modelID = *v.ModelId @@ -270,7 +270,7 @@ func handleAIRequest(ctx context.Context, w http.ResponseWriter, r *http.Request return } outPixels = int64(config.Height) * int64(config.Width) - case worker.ImageToVideoMultipartRequestBody: + case worker.GenImageToVideoMultipartRequestBody: pipeline = "image-to-video" cap = core.Capability_ImageToVideo modelID = *v.ModelId @@ -291,7 +291,7 @@ func handleAIRequest(ctx context.Context, w http.ResponseWriter, r *http.Request frames := int64(25) outPixels = height * width * int64(frames) - case worker.AudioToTextMultipartRequestBody: + case worker.GenAudioToTextMultipartRequestBody: pipeline = "audio-to-text" cap = core.Capability_AudioToText modelID = *v.ModelId @@ -305,7 +305,7 @@ func handleAIRequest(ctx context.Context, w http.ResponseWriter, r *http.Request return } outPixels *= 1000 // Convert to milliseconds - case worker.SegmentAnything2MultipartRequestBody: + case worker.GenSegmentAnything2MultipartRequestBody: pipeline = "segment-anything-2" cap = core.Capability_SegmentAnything2 modelID = *v.ModelId @@ -382,20 +382,20 @@ func handleAIRequest(ctx context.Context, w http.ResponseWriter, r *http.Request if monitor.Enabled { var latencyScore float64 switch v := req.(type) { - case worker.TextToImageJSONRequestBody: + case worker.GenTextToImageJSONRequestBody: latencyScore = CalculateTextToImageLatencyScore(took, v, outPixels) - case worker.ImageToImageMultipartRequestBody: + case worker.GenImageToImageMultipartRequestBody: latencyScore = CalculateImageToImageLatencyScore(took, v, outPixels) - case worker.ImageToVideoMultipartRequestBody: + case worker.GenImageToVideoMultipartRequestBody: latencyScore = CalculateImageToVideoLatencyScore(took, v, outPixels) - case worker.UpscaleMultipartRequestBody: + case worker.GenUpscaleMultipartRequestBody: latencyScore = CalculateUpscaleLatencyScore(took, v, outPixels) - case worker.AudioToTextMultipartRequestBody: + case worker.GenAudioToTextMultipartRequestBody: durationSeconds, err := common.CalculateAudioDuration(v.Audio) if err == nil { latencyScore = CalculateAudioToTextLatencyScore(took, durationSeconds) } - case worker.SegmentAnything2MultipartRequestBody: + case worker.GenSegmentAnything2MultipartRequestBody: latencyScore = CalculateSegmentAnything2LatencyScore(took, outPixels) } diff --git a/server/ai_mediaserver.go b/server/ai_mediaserver.go index a600f3b176..078fa05ee9 100644 --- a/server/ai_mediaserver.go +++ b/server/ai_mediaserver.go @@ -81,7 +81,7 @@ func (ls *LivepeerServer) TextToImage() http.Handler { requestID := string(core.RandomManifestID()) ctx = clog.AddVal(ctx, "request_id", requestID) - var req worker.TextToImageJSONRequestBody + var req worker.GenTextToImageJSONRequestBody if err := json.NewDecoder(r.Body).Decode(&req); err != nil { respondJsonError(ctx, w, err, http.StatusBadRequest) return @@ -129,7 +129,7 @@ func (ls *LivepeerServer) ImageToImage() http.Handler { return } - var req worker.ImageToImageMultipartRequestBody + var req worker.GenImageToImageMultipartRequestBody if err := runtime.BindMultipart(&req, *multiRdr); err != nil { respondJsonError(ctx, w, err, http.StatusBadRequest) return @@ -177,7 +177,7 @@ func (ls *LivepeerServer) ImageToVideo() http.Handler { return } - var req worker.ImageToVideoMultipartRequestBody + var req worker.GenImageToVideoMultipartRequestBody if err := runtime.BindMultipart(&req, *multiRdr); err != nil { respondJsonError(ctx, w, err, http.StatusBadRequest) return @@ -287,7 +287,7 @@ func (ls *LivepeerServer) Upscale() http.Handler { return } - var req worker.UpscaleMultipartRequestBody + var req worker.GenUpscaleMultipartRequestBody if err := runtime.BindMultipart(&req, *multiRdr); err != nil { respondJsonError(ctx, w, err, http.StatusBadRequest) return @@ -335,7 +335,7 @@ func (ls *LivepeerServer) AudioToText() http.Handler { return } - var req worker.AudioToTextMultipartRequestBody + var req worker.GenAudioToTextMultipartRequestBody if err := runtime.BindMultipart(&req, *multiRdr); err != nil { respondJsonError(ctx, w, err, http.StatusBadRequest) return @@ -388,7 +388,7 @@ func (ls *LivepeerServer) SegmentAnything2() http.Handler { return } - var req worker.SegmentAnything2MultipartRequestBody + var req worker.GenSegmentAnything2MultipartRequestBody if err := runtime.BindMultipart(&req, *multiRdr); err != nil { respondJsonError(ctx, w, err, http.StatusBadRequest) return diff --git a/server/ai_process.go b/server/ai_process.go index d69beb0610..249cc506b6 100644 --- a/server/ai_process.go +++ b/server/ai_process.go @@ -56,7 +56,7 @@ type aiRequestParams struct { } // CalculateTextToImageLatencyScore computes the time taken per pixel for an text-to-image request. -func CalculateTextToImageLatencyScore(took time.Duration, req worker.TextToImageJSONRequestBody, outPixels int64) float64 { +func CalculateTextToImageLatencyScore(took time.Duration, req worker.GenTextToImageJSONRequestBody, outPixels int64) float64 { if outPixels <= 0 { return 0 } @@ -75,7 +75,7 @@ func CalculateTextToImageLatencyScore(took time.Duration, req worker.TextToImage return took.Seconds() / float64(outPixels) / numInferenceSteps } -func processTextToImage(ctx context.Context, params aiRequestParams, req worker.TextToImageJSONRequestBody) (*worker.ImageResponse, error) { +func processTextToImage(ctx context.Context, params aiRequestParams, req worker.GenTextToImageJSONRequestBody) (*worker.ImageResponse, error) { resp, err := processAIRequest(ctx, params, req) if err != nil { return nil, err @@ -106,7 +106,7 @@ func processTextToImage(ctx context.Context, params aiRequestParams, req worker. return imgResp, nil } -func submitTextToImage(ctx context.Context, params aiRequestParams, sess *AISession, req worker.TextToImageJSONRequestBody) (*worker.ImageResponse, error) { +func submitTextToImage(ctx context.Context, params aiRequestParams, sess *AISession, req worker.GenTextToImageJSONRequestBody) (*worker.ImageResponse, error) { client, err := worker.NewClientWithResponses(sess.Transcoder(), worker.WithHTTPClient(httpClient)) if err != nil { @@ -146,7 +146,7 @@ func submitTextToImage(ctx context.Context, params aiRequestParams, sess *AISess defer completeBalanceUpdate(sess.BroadcastSession, balUpdate) start := time.Now() - resp, err := client.TextToImageWithResponse(ctx, req, setHeaders) + resp, err := client.GenTextToImageWithResponse(ctx, req, setHeaders) took := time.Since(start) // TODO: Refine this rough estimate in future iterations. @@ -182,7 +182,7 @@ func submitTextToImage(ctx context.Context, params aiRequestParams, sess *AISess } // CalculateImageToImageLatencyScore computes the time taken per pixel for an image-to-image request. -func CalculateImageToImageLatencyScore(took time.Duration, req worker.ImageToImageMultipartRequestBody, outPixels int64) float64 { +func CalculateImageToImageLatencyScore(took time.Duration, req worker.GenImageToImageMultipartRequestBody, outPixels int64) float64 { if outPixels <= 0 { return 0 } @@ -201,7 +201,7 @@ func CalculateImageToImageLatencyScore(took time.Duration, req worker.ImageToIma return took.Seconds() / float64(outPixels) / numInferenceSteps } -func processImageToImage(ctx context.Context, params aiRequestParams, req worker.ImageToImageMultipartRequestBody) (*worker.ImageResponse, error) { +func processImageToImage(ctx context.Context, params aiRequestParams, req worker.GenImageToImageMultipartRequestBody) (*worker.ImageResponse, error) { resp, err := processAIRequest(ctx, params, req) if err != nil { return nil, err @@ -232,7 +232,7 @@ func processImageToImage(ctx context.Context, params aiRequestParams, req worker return imgResp, nil } -func submitImageToImage(ctx context.Context, params aiRequestParams, sess *AISession, req worker.ImageToImageMultipartRequestBody) (*worker.ImageResponse, error) { +func submitImageToImage(ctx context.Context, params aiRequestParams, sess *AISession, req worker.GenImageToImageMultipartRequestBody) (*worker.ImageResponse, error) { // TODO: Default values for the number of images is currently hardcoded. // These should be managed by the nethttpmiddleware. Refer to issue LIV-412 for more details. defaultNumImages := 1 @@ -286,7 +286,7 @@ func submitImageToImage(ctx context.Context, params aiRequestParams, sess *AISes defer completeBalanceUpdate(sess.BroadcastSession, balUpdate) start := time.Now() - resp, err := client.ImageToImageWithBodyWithResponse(ctx, mw.FormDataContentType(), &buf, setHeaders) + resp, err := client.GenImageToImageWithBodyWithResponse(ctx, mw.FormDataContentType(), &buf, setHeaders) took := time.Since(start) // TODO: Refine this rough estimate in future iterations. @@ -322,7 +322,7 @@ func submitImageToImage(ctx context.Context, params aiRequestParams, sess *AISes } // CalculateImageToVideoLatencyScore computes the time taken per pixel for an image-to-video request. -func CalculateImageToVideoLatencyScore(took time.Duration, req worker.ImageToVideoMultipartRequestBody, outPixels int64) float64 { +func CalculateImageToVideoLatencyScore(took time.Duration, req worker.GenImageToVideoMultipartRequestBody, outPixels int64) float64 { if outPixels <= 0 { return 0 } @@ -337,7 +337,7 @@ func CalculateImageToVideoLatencyScore(took time.Duration, req worker.ImageToVid return took.Seconds() / float64(outPixels) / numInferenceSteps } -func processImageToVideo(ctx context.Context, params aiRequestParams, req worker.ImageToVideoMultipartRequestBody) (*worker.ImageResponse, error) { +func processImageToVideo(ctx context.Context, params aiRequestParams, req worker.GenImageToVideoMultipartRequestBody) (*worker.ImageResponse, error) { resp, err := processAIRequest(ctx, params, req) if err != nil { return nil, err @@ -373,7 +373,7 @@ func processImageToVideo(ctx context.Context, params aiRequestParams, req worker return imgResp, nil } -func submitImageToVideo(ctx context.Context, params aiRequestParams, sess *AISession, req worker.ImageToVideoMultipartRequestBody) (*worker.ImageResponse, error) { +func submitImageToVideo(ctx context.Context, params aiRequestParams, sess *AISession, req worker.GenImageToVideoMultipartRequestBody) (*worker.ImageResponse, error) { var buf bytes.Buffer mw, err := worker.NewImageToVideoMultipartWriter(&buf, req) if err != nil { @@ -412,7 +412,7 @@ func submitImageToVideo(ctx context.Context, params aiRequestParams, sess *AISes defer completeBalanceUpdate(sess.BroadcastSession, balUpdate) start := time.Now() - resp, err := client.ImageToVideoWithBody(ctx, mw.FormDataContentType(), &buf, setHeaders) + resp, err := client.GenImageToVideoWithBody(ctx, mw.FormDataContentType(), &buf, setHeaders) took := time.Since(start) if err != nil { if monitor.Enabled { @@ -463,7 +463,7 @@ func submitImageToVideo(ctx context.Context, params aiRequestParams, sess *AISes } // CalculateUpscaleLatencyScore computes the time taken per pixel for an upscale request. -func CalculateUpscaleLatencyScore(took time.Duration, req worker.UpscaleMultipartRequestBody, outPixels int64) float64 { +func CalculateUpscaleLatencyScore(took time.Duration, req worker.GenUpscaleMultipartRequestBody, outPixels int64) float64 { if outPixels <= 0 { return 0 } @@ -478,7 +478,7 @@ func CalculateUpscaleLatencyScore(took time.Duration, req worker.UpscaleMultipar return took.Seconds() / float64(outPixels) / numInferenceSteps } -func processUpscale(ctx context.Context, params aiRequestParams, req worker.UpscaleMultipartRequestBody) (*worker.ImageResponse, error) { +func processUpscale(ctx context.Context, params aiRequestParams, req worker.GenUpscaleMultipartRequestBody) (*worker.ImageResponse, error) { resp, err := processAIRequest(ctx, params, req) if err != nil { return nil, err @@ -509,7 +509,7 @@ func processUpscale(ctx context.Context, params aiRequestParams, req worker.Upsc return imgResp, nil } -func submitUpscale(ctx context.Context, params aiRequestParams, sess *AISession, req worker.UpscaleMultipartRequestBody) (*worker.ImageResponse, error) { +func submitUpscale(ctx context.Context, params aiRequestParams, sess *AISession, req worker.GenUpscaleMultipartRequestBody) (*worker.ImageResponse, error) { var buf bytes.Buffer mw, err := worker.NewUpscaleMultipartWriter(&buf, req) if err != nil { @@ -553,7 +553,7 @@ func submitUpscale(ctx context.Context, params aiRequestParams, sess *AISession, defer completeBalanceUpdate(sess.BroadcastSession, balUpdate) start := time.Now() - resp, err := client.UpscaleWithBodyWithResponse(ctx, mw.FormDataContentType(), &buf, setHeaders) + resp, err := client.GenUpscaleWithBodyWithResponse(ctx, mw.FormDataContentType(), &buf, setHeaders) took := time.Since(start) if err != nil { if monitor.Enabled { @@ -596,7 +596,7 @@ func CalculateSegmentAnything2LatencyScore(took time.Duration, outPixels int64) return took.Seconds() / float64(outPixels) } -func processSegmentAnything2(ctx context.Context, params aiRequestParams, req worker.SegmentAnything2MultipartRequestBody) (*worker.MasksResponse, error) { +func processSegmentAnything2(ctx context.Context, params aiRequestParams, req worker.GenSegmentAnything2MultipartRequestBody) (*worker.MasksResponse, error) { resp, err := processAIRequest(ctx, params, req) if err != nil { return nil, err @@ -607,7 +607,7 @@ func processSegmentAnything2(ctx context.Context, params aiRequestParams, req wo return txtResp, nil } -func submitSegmentAnything2(ctx context.Context, params aiRequestParams, sess *AISession, req worker.BodySegmentAnything2SegmentAnything2Post) (*worker.MasksResponse, error) { +func submitSegmentAnything2(ctx context.Context, params aiRequestParams, sess *AISession, req worker.GenSegmentAnything2MultipartRequestBody) (*worker.MasksResponse, error) { var buf bytes.Buffer mw, err := worker.NewSegmentAnything2MultipartWriter(&buf, req) if err != nil { @@ -651,7 +651,7 @@ func submitSegmentAnything2(ctx context.Context, params aiRequestParams, sess *A defer completeBalanceUpdate(sess.BroadcastSession, balUpdate) start := time.Now() - resp, err := client.SegmentAnything2WithBodyWithResponse(ctx, mw.FormDataContentType(), &buf, setHeaders) + resp, err := client.GenSegmentAnything2WithBodyWithResponse(ctx, mw.FormDataContentType(), &buf, setHeaders) took := time.Since(start) if err != nil { if monitor.Enabled { @@ -694,7 +694,7 @@ func CalculateAudioToTextLatencyScore(took time.Duration, durationSeconds int64) return took.Seconds() / float64(durationSeconds) } -func processAudioToText(ctx context.Context, params aiRequestParams, req worker.AudioToTextMultipartRequestBody) (*worker.TextResponse, error) { +func processAudioToText(ctx context.Context, params aiRequestParams, req worker.GenAudioToTextMultipartRequestBody) (*worker.TextResponse, error) { resp, err := processAIRequest(ctx, params, req) if err != nil { return nil, err @@ -705,7 +705,7 @@ func processAudioToText(ctx context.Context, params aiRequestParams, req worker. return txtResp, nil } -func submitAudioToText(ctx context.Context, params aiRequestParams, sess *AISession, req worker.AudioToTextMultipartRequestBody) (*worker.TextResponse, error) { +func submitAudioToText(ctx context.Context, params aiRequestParams, sess *AISession, req worker.GenAudioToTextMultipartRequestBody) (*worker.TextResponse, error) { var buf bytes.Buffer mw, err := worker.NewAudioToTextMultipartWriter(&buf, req) if err != nil { @@ -742,7 +742,7 @@ func submitAudioToText(ctx context.Context, params aiRequestParams, sess *AISess defer completeBalanceUpdate(sess.BroadcastSession, balUpdate) start := time.Now() - resp, err := client.AudioToTextWithBody(ctx, mw.FormDataContentType(), &buf, setHeaders) + resp, err := client.GenAudioToTextWithBody(ctx, mw.FormDataContentType(), &buf, setHeaders) took := time.Since(start) if err != nil { if monitor.Enabled { @@ -798,7 +798,7 @@ func processAIRequest(ctx context.Context, params aiRequestParams, req interface var submitFn func(context.Context, aiRequestParams, *AISession) (interface{}, error) switch v := req.(type) { - case worker.TextToImageJSONRequestBody: + case worker.GenTextToImageJSONRequestBody: cap = core.Capability_TextToImage modelID = defaultTextToImageModelID if v.ModelId != nil { @@ -807,7 +807,7 @@ func processAIRequest(ctx context.Context, params aiRequestParams, req interface submitFn = func(ctx context.Context, params aiRequestParams, sess *AISession) (interface{}, error) { return submitTextToImage(ctx, params, sess, v) } - case worker.ImageToImageMultipartRequestBody: + case worker.GenImageToImageMultipartRequestBody: cap = core.Capability_ImageToImage modelID = defaultImageToImageModelID if v.ModelId != nil { @@ -816,7 +816,7 @@ func processAIRequest(ctx context.Context, params aiRequestParams, req interface submitFn = func(ctx context.Context, params aiRequestParams, sess *AISession) (interface{}, error) { return submitImageToImage(ctx, params, sess, v) } - case worker.ImageToVideoMultipartRequestBody: + case worker.GenImageToVideoMultipartRequestBody: cap = core.Capability_ImageToVideo modelID = defaultImageToVideoModelID if v.ModelId != nil { @@ -825,7 +825,7 @@ func processAIRequest(ctx context.Context, params aiRequestParams, req interface submitFn = func(ctx context.Context, params aiRequestParams, sess *AISession) (interface{}, error) { return submitImageToVideo(ctx, params, sess, v) } - case worker.UpscaleMultipartRequestBody: + case worker.GenUpscaleMultipartRequestBody: cap = core.Capability_Upscale modelID = defaultUpscaleModelID if v.ModelId != nil { @@ -834,7 +834,7 @@ func processAIRequest(ctx context.Context, params aiRequestParams, req interface submitFn = func(ctx context.Context, params aiRequestParams, sess *AISession) (interface{}, error) { return submitUpscale(ctx, params, sess, v) } - case worker.AudioToTextMultipartRequestBody: + case worker.GenAudioToTextMultipartRequestBody: cap = core.Capability_AudioToText modelID = defaultAudioToTextModelID if v.ModelId != nil { @@ -843,7 +843,7 @@ func processAIRequest(ctx context.Context, params aiRequestParams, req interface submitFn = func(ctx context.Context, params aiRequestParams, sess *AISession) (interface{}, error) { return submitAudioToText(ctx, params, sess, v) } - case worker.SegmentAnything2MultipartRequestBody: + case worker.GenSegmentAnything2MultipartRequestBody: cap = core.Capability_SegmentAnything2 modelID = defaultSegmentAnything2ModelID if v.ModelId != nil { diff --git a/server/rpc.go b/server/rpc.go index db797b9eba..6c1365ccd6 100644 --- a/server/rpc.go +++ b/server/rpc.go @@ -63,12 +63,12 @@ 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 - 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) - Upscale(ctx context.Context, req worker.UpscaleMultipartRequestBody) (*worker.ImageResponse, error) - AudioToText(ctx context.Context, req worker.AudioToTextMultipartRequestBody) (*worker.TextResponse, error) - SegmentAnything2(ctx context.Context, req worker.SegmentAnything2MultipartRequestBody) (*worker.MasksResponse, error) + TextToImage(ctx context.Context, req worker.GenTextToImageJSONRequestBody) (*worker.ImageResponse, error) + ImageToImage(ctx context.Context, req worker.GenImageToImageMultipartRequestBody) (*worker.ImageResponse, error) + ImageToVideo(ctx context.Context, req worker.GenImageToVideoMultipartRequestBody) (*worker.ImageResponse, error) + Upscale(ctx context.Context, req worker.GenUpscaleMultipartRequestBody) (*worker.ImageResponse, error) + AudioToText(ctx context.Context, req worker.GenAudioToTextMultipartRequestBody) (*worker.TextResponse, error) + SegmentAnything2(ctx context.Context, req worker.GenSegmentAnything2MultipartRequestBody) (*worker.MasksResponse, error) } // Balance describes methods for a session's balance maintenance diff --git a/server/rpc_test.go b/server/rpc_test.go index 197e2baa6b..6f710a319d 100644 --- a/server/rpc_test.go +++ b/server/rpc_test.go @@ -187,22 +187,22 @@ func (r *stubOrchestrator) TranscoderSecret() string { func (r *stubOrchestrator) PriceInfoForCaps(sender ethcommon.Address, manifestID core.ManifestID, caps *net.Capabilities) (*net.PriceInfo, error) { return &net.PriceInfo{PricePerUnit: 4, PixelsPerUnit: 1}, nil } -func (r *stubOrchestrator) TextToImage(ctx context.Context, req worker.TextToImageJSONRequestBody) (*worker.ImageResponse, error) { +func (r *stubOrchestrator) TextToImage(ctx context.Context, req worker.GenTextToImageJSONRequestBody) (*worker.ImageResponse, error) { return nil, nil } -func (r *stubOrchestrator) ImageToImage(ctx context.Context, req worker.ImageToImageMultipartRequestBody) (*worker.ImageResponse, error) { +func (r *stubOrchestrator) ImageToImage(ctx context.Context, req worker.GenImageToImageMultipartRequestBody) (*worker.ImageResponse, error) { return nil, nil } -func (r *stubOrchestrator) ImageToVideo(ctx context.Context, req worker.ImageToVideoMultipartRequestBody) (*worker.ImageResponse, error) { +func (r *stubOrchestrator) ImageToVideo(ctx context.Context, req worker.GenImageToVideoMultipartRequestBody) (*worker.ImageResponse, error) { return nil, nil } -func (r *stubOrchestrator) Upscale(ctx context.Context, req worker.UpscaleMultipartRequestBody) (*worker.ImageResponse, error) { +func (r *stubOrchestrator) Upscale(ctx context.Context, req worker.GenUpscaleMultipartRequestBody) (*worker.ImageResponse, error) { return nil, nil } -func (r *stubOrchestrator) AudioToText(ctx context.Context, req worker.AudioToTextMultipartRequestBody) (*worker.TextResponse, error) { +func (r *stubOrchestrator) AudioToText(ctx context.Context, req worker.GenAudioToTextMultipartRequestBody) (*worker.TextResponse, error) { return nil, nil } -func (r *stubOrchestrator) SegmentAnything2(ctx context.Context, req worker.SegmentAnything2MultipartRequestBody) (*worker.MasksResponse, error) { +func (r *stubOrchestrator) SegmentAnything2(ctx context.Context, req worker.GenSegmentAnything2MultipartRequestBody) (*worker.MasksResponse, error) { return nil, nil } func (r *stubOrchestrator) CheckAICapacity(pipeline, modelID string) bool { @@ -1373,22 +1373,22 @@ func (o *mockOrchestrator) AuthToken(sessionID string, expiration int64) *net.Au func (r *mockOrchestrator) PriceInfoForCaps(sender ethcommon.Address, manifestID core.ManifestID, caps *net.Capabilities) (*net.PriceInfo, error) { return &net.PriceInfo{PricePerUnit: 4, PixelsPerUnit: 1}, nil } -func (r *mockOrchestrator) TextToImage(ctx context.Context, req worker.TextToImageJSONRequestBody) (*worker.ImageResponse, error) { +func (r *mockOrchestrator) TextToImage(ctx context.Context, req worker.GenTextToImageJSONRequestBody) (*worker.ImageResponse, error) { return nil, nil } -func (r *mockOrchestrator) ImageToImage(ctx context.Context, req worker.ImageToImageMultipartRequestBody) (*worker.ImageResponse, error) { +func (r *mockOrchestrator) ImageToImage(ctx context.Context, req worker.GenImageToImageMultipartRequestBody) (*worker.ImageResponse, error) { return nil, nil } -func (r *mockOrchestrator) ImageToVideo(ctx context.Context, req worker.ImageToVideoMultipartRequestBody) (*worker.ImageResponse, error) { +func (r *mockOrchestrator) ImageToVideo(ctx context.Context, req worker.GenImageToVideoMultipartRequestBody) (*worker.ImageResponse, error) { return nil, nil } -func (r *mockOrchestrator) Upscale(ctx context.Context, req worker.UpscaleMultipartRequestBody) (*worker.ImageResponse, error) { +func (r *mockOrchestrator) Upscale(ctx context.Context, req worker.GenUpscaleMultipartRequestBody) (*worker.ImageResponse, error) { return nil, nil } -func (r *mockOrchestrator) AudioToText(ctx context.Context, req worker.AudioToTextMultipartRequestBody) (*worker.TextResponse, error) { +func (r *mockOrchestrator) AudioToText(ctx context.Context, req worker.GenAudioToTextMultipartRequestBody) (*worker.TextResponse, error) { return nil, nil } -func (r *mockOrchestrator) SegmentAnything2(ctx context.Context, req worker.SegmentAnything2MultipartRequestBody) (*worker.MasksResponse, error) { +func (r *mockOrchestrator) SegmentAnything2(ctx context.Context, req worker.GenSegmentAnything2MultipartRequestBody) (*worker.MasksResponse, error) { return nil, nil } func (r *mockOrchestrator) CheckAICapacity(pipeline, modelID string) bool { From 81bc9e505a5675b3672d5bf294a1b07b4cc1ce2b Mon Sep 17 00:00:00 2001 From: ad-astra-video <99882368+ad-astra-video@users.noreply.github.com> Date: Thu, 19 Sep 2024 15:35:09 -0500 Subject: [PATCH 15/21] feat: enable changing GetOrchestrator discovery timeout (#3150) This commit introduces a mechanism for gateways to configure the timeout during the discovery process. It adds the `DiscoveryTimeout` CLI argument, with a default value of 500ms, consistent with the previous codebase. --- cmd/livepeer/livepeer.go | 1 + cmd/livepeer/starter/starter.go | 9 ++-- discovery/db_discovery.go | 12 +++-- discovery/discovery.go | 22 ++++----- discovery/discovery_test.go | 86 ++++++++++++++++++++------------- discovery/wh_discovery.go | 24 ++++----- 6 files changed, 92 insertions(+), 62 deletions(-) diff --git a/cmd/livepeer/livepeer.go b/cmd/livepeer/livepeer.go index d28b579a32..446bbe5f20 100755 --- a/cmd/livepeer/livepeer.go +++ b/cmd/livepeer/livepeer.go @@ -137,6 +137,7 @@ func parseLivepeerConfig() starter.LivepeerConfig { cfg.MaxPricePerUnit = flag.String("maxPricePerUnit", *cfg.MaxPricePerUnit, "The maximum transcoding price per 'pixelsPerUnit' a broadcaster is willing to accept. If not set explicitly, broadcaster is willing to accept ANY price. Can be specified in wei or a custom currency in the format (e.g. 0.50USD). When using a custom currency, a corresponding price feed must be configured with -priceFeedAddr") cfg.IgnoreMaxPriceIfNeeded = flag.Bool("ignoreMaxPriceIfNeeded", *cfg.IgnoreMaxPriceIfNeeded, "Set to true to allow exceeding max price condition if there is no O that meets this requirement") cfg.MinPerfScore = flag.Float64("minPerfScore", *cfg.MinPerfScore, "The minimum orchestrator's performance score a broadcaster is willing to accept") + cfg.DiscoveryTimeout = flag.Duration("discoveryTimeout", *cfg.DiscoveryTimeout, "Time to wait for orchestrators to return info to be included in transcoding sessions for manifest (default = 500ms)") // Transcoding: cfg.Orchestrator = flag.Bool("orchestrator", *cfg.Orchestrator, "Set to true to be an orchestrator") diff --git a/cmd/livepeer/starter/starter.go b/cmd/livepeer/starter/starter.go index 23a7be0990..92ba9079bb 100755 --- a/cmd/livepeer/starter/starter.go +++ b/cmd/livepeer/starter/starter.go @@ -101,6 +101,7 @@ type LivepeerConfig struct { MaxPricePerUnit *string IgnoreMaxPriceIfNeeded *bool MinPerfScore *float64 + DiscoveryTimeout *time.Duration MaxSessions *string CurrentManifest *bool Nvidia *string @@ -180,6 +181,7 @@ func DefaultLivepeerConfig() LivepeerConfig { defaultOrchPerfStatsURL := "" defaultRegion := "" defaultMinPerfScore := 0.0 + defaultDiscoveryTimeout := 500 * time.Millisecond defaultCurrentManifest := false defaultNvidia := "" defaultNetint := "" @@ -271,6 +273,7 @@ func DefaultLivepeerConfig() LivepeerConfig { OrchPerfStatsURL: &defaultOrchPerfStatsURL, Region: &defaultRegion, MinPerfScore: &defaultMinPerfScore, + DiscoveryTimeout: &defaultDiscoveryTimeout, CurrentManifest: &defaultCurrentManifest, Nvidia: &defaultNvidia, Netint: &defaultNetint, @@ -1123,7 +1126,7 @@ func StartLivepeer(ctx context.Context, cfg LivepeerConfig) { if *cfg.Network != "offchain" { ctx, cancel := context.WithCancel(ctx) defer cancel() - dbOrchPoolCache, err := discovery.NewDBOrchestratorPoolCache(ctx, n, timeWatcher, orchBlacklist) + dbOrchPoolCache, err := discovery.NewDBOrchestratorPoolCache(ctx, n, timeWatcher, orchBlacklist, *cfg.DiscoveryTimeout) if err != nil { exit("Could not create orchestrator pool with DB cache: %v", err) } @@ -1138,9 +1141,9 @@ func StartLivepeer(ctx context.Context, cfg LivepeerConfig) { glog.Exit("Error setting orch webhook URL ", err) } glog.Info("Using orchestrator webhook URL ", whurl) - n.OrchestratorPool = discovery.NewWebhookPool(bcast, whurl) + n.OrchestratorPool = discovery.NewWebhookPool(bcast, whurl, *cfg.DiscoveryTimeout) } else if len(orchURLs) > 0 { - n.OrchestratorPool = discovery.NewOrchestratorPool(bcast, orchURLs, common.Score_Trusted, orchBlacklist) + n.OrchestratorPool = discovery.NewOrchestratorPool(bcast, orchURLs, common.Score_Trusted, orchBlacklist, *cfg.DiscoveryTimeout) } if n.OrchestratorPool == nil { diff --git a/discovery/db_discovery.go b/discovery/db_discovery.go index 7747be9b72..36f9162aae 100644 --- a/discovery/db_discovery.go +++ b/discovery/db_discovery.go @@ -36,9 +36,10 @@ type DBOrchestratorPoolCache struct { rm common.RoundsManager bcast common.Broadcaster orchBlacklist []string + discoveryTimeout time.Duration } -func NewDBOrchestratorPoolCache(ctx context.Context, node *core.LivepeerNode, rm common.RoundsManager, orchBlacklist []string) (*DBOrchestratorPoolCache, error) { +func NewDBOrchestratorPoolCache(ctx context.Context, node *core.LivepeerNode, rm common.RoundsManager, orchBlacklist []string, discoveryTimeout time.Duration) (*DBOrchestratorPoolCache, error) { if node.Eth == nil { return nil, fmt.Errorf("could not create DBOrchestratorPoolCache: LivepeerEthClient is nil") } @@ -50,6 +51,7 @@ func NewDBOrchestratorPoolCache(ctx context.Context, node *core.LivepeerNode, rm rm: rm, bcast: core.NewBroadcaster(node), orchBlacklist: orchBlacklist, + discoveryTimeout: discoveryTimeout, } if err := dbo.cacheTranscoderPool(); err != nil { @@ -135,7 +137,7 @@ func (dbo *DBOrchestratorPoolCache) GetOrchestrators(ctx context.Context, numOrc return true } - orchPool := NewOrchestratorPoolWithPred(dbo.bcast, uris, pred, common.Score_Untrusted, dbo.orchBlacklist) + orchPool := NewOrchestratorPoolWithPred(dbo.bcast, uris, pred, common.Score_Untrusted, dbo.orchBlacklist, dbo.discoveryTimeout) orchInfos, err := orchPool.GetOrchestrators(ctx, numOrchestrators, suspender, caps, scorePred) if err != nil || len(orchInfos) <= 0 { return nil, err @@ -187,7 +189,8 @@ func (dbo *DBOrchestratorPoolCache) cacheOrchestratorStake() error { } resc, errc := make(chan *common.DBOrch, len(orchs)), make(chan error, len(orchs)) - ctx, cancel := context.WithTimeout(context.Background(), getOrchestratorsTimeoutLoop) + timeout := getOrchestratorTimeoutLoop //needs to be same or longer than GRPCConnectTimeout in server/rpc.go + ctx, cancel := context.WithTimeout(context.Background(), timeout) defer cancel() currentRound := dbo.rm.LastInitializedRound() @@ -263,7 +266,8 @@ func (dbo *DBOrchestratorPoolCache) cacheDBOrchs() error { } resc, errc := make(chan *common.DBOrch, len(orchs)), make(chan error, len(orchs)) - ctx, cancel := context.WithTimeout(context.Background(), getOrchestratorsTimeoutLoop) + timeout := getOrchestratorTimeoutLoop //needs to be same or longer than GRPCConnectTimeout in server/rpc.go + ctx, cancel := context.WithTimeout(context.Background(), timeout) defer cancel() getOrchInfo := func(dbOrch *common.DBOrch) { diff --git a/discovery/discovery.go b/discovery/discovery.go index 4b37b9c934..bc488274cc 100644 --- a/discovery/discovery.go +++ b/discovery/discovery.go @@ -20,20 +20,20 @@ import ( "github.com/golang/glog" ) -var getOrchestratorsTimeoutLoop = 3 * time.Second -var getOrchestratorsCutoffTimeout = 500 * time.Millisecond +var getOrchestratorTimeoutLoop = 3 * time.Second var maxGetOrchestratorCutoffTimeout = 6 * time.Second var serverGetOrchInfo = server.GetOrchestratorInfo type orchestratorPool struct { - infos []common.OrchestratorLocalInfo - pred func(info *net.OrchestratorInfo) bool - bcast common.Broadcaster - orchBlacklist []string + infos []common.OrchestratorLocalInfo + pred func(info *net.OrchestratorInfo) bool + bcast common.Broadcaster + orchBlacklist []string + discoveryTimeout time.Duration } -func NewOrchestratorPool(bcast common.Broadcaster, uris []*url.URL, score float32, orchBlacklist []string) *orchestratorPool { +func NewOrchestratorPool(bcast common.Broadcaster, uris []*url.URL, score float32, orchBlacklist []string, discoveryTimeout time.Duration) *orchestratorPool { if len(uris) <= 0 { // Should we return here? glog.Error("Orchestrator pool does not have any URIs") @@ -42,13 +42,13 @@ func NewOrchestratorPool(bcast common.Broadcaster, uris []*url.URL, score float3 for _, uri := range uris { infos = append(infos, common.OrchestratorLocalInfo{URL: uri, Score: score}) } - return &orchestratorPool{infos: infos, bcast: bcast, orchBlacklist: orchBlacklist} + return &orchestratorPool{infos: infos, bcast: bcast, orchBlacklist: orchBlacklist, discoveryTimeout: discoveryTimeout} } func NewOrchestratorPoolWithPred(bcast common.Broadcaster, addresses []*url.URL, - pred func(*net.OrchestratorInfo) bool, score float32, orchBlacklist []string) *orchestratorPool { + pred func(*net.OrchestratorInfo) bool, score float32, orchBlacklist []string, discoveryTimeout time.Duration) *orchestratorPool { - pool := NewOrchestratorPool(bcast, addresses, score, orchBlacklist) + pool := NewOrchestratorPool(bcast, addresses, score, orchBlacklist, discoveryTimeout) pool.pred = pred return pool } @@ -136,7 +136,7 @@ func (o *orchestratorPool) GetOrchestrators(ctx context.Context, numOrchestrator } // try to wait for orchestrators until at least 1 is found (with the exponential backoff timout) - timeout := getOrchestratorsCutoffTimeout + timeout := o.discoveryTimeout timer := time.NewTimer(timeout) for nbResp < numAvailableOrchs && len(ods) < numOrchestrators && !timedOut { diff --git a/discovery/discovery_test.go b/discovery/discovery_test.go index 33e20e5b79..dccf8dab5c 100644 --- a/discovery/discovery_test.go +++ b/discovery/discovery_test.go @@ -43,7 +43,7 @@ func TestNewDBOrchestratorPoolCache_NilEthClient_ReturnsError(t *testing.T) { } ctx, cancel := context.WithCancel(context.Background()) defer cancel() - pool, err := NewDBOrchestratorPoolCache(ctx, node, &stubRoundsManager{}, []string{}) + pool, err := NewDBOrchestratorPoolCache(ctx, node, &stubRoundsManager{}, []string{}, 500*time.Millisecond) assert.Nil(pool) assert.EqualError(err, "could not create DBOrchestratorPoolCache: LivepeerEthClient is nil") } @@ -73,7 +73,7 @@ func TestDeadLock(t *testing.T) { uris := stringsToURIs(addresses) assert := assert.New(t) wg.Add(len(uris)) - pool := NewOrchestratorPool(nil, uris, common.Score_Trusted, []string{}) + pool := NewOrchestratorPool(nil, uris, common.Score_Trusted, []string{}, 50*time.Millisecond) infos, err := pool.GetOrchestrators(context.TODO(), 1, newStubSuspender(), newStubCapabilities(), common.ScoreAtLeast(0)) assert.Nil(err, "Should not be error") assert.Len(infos, 1, "Should return one orchestrator") @@ -120,7 +120,7 @@ func TestDeadLock_NewOrchestratorPoolWithPred(t *testing.T) { } wg.Add(len(uris)) - pool := NewOrchestratorPoolWithPred(nil, uris, pred, common.Score_Trusted, []string{}) + pool := NewOrchestratorPoolWithPred(nil, uris, pred, common.Score_Trusted, []string{}, 50*time.Millisecond) infos, err := pool.GetOrchestrators(context.TODO(), 1, newStubSuspender(), newStubCapabilities(), common.ScoreAtLeast(0)) assert.Nil(err, "Should not be error") @@ -132,12 +132,12 @@ func TestPoolSize(t *testing.T) { addresses := stringsToURIs([]string{"https://127.0.0.1:8936", "https://127.0.0.1:8937", "https://127.0.0.1:8938"}) assert := assert.New(t) - pool := NewOrchestratorPool(nil, addresses, common.Score_Trusted, []string{}) + pool := NewOrchestratorPool(nil, addresses, common.Score_Trusted, []string{}, 50*time.Millisecond) assert.Equal(3, pool.Size()) // will results in len(uris) <= 0 -> log Error errorLogsBefore := glog.Stats.Error.Lines() - pool = NewOrchestratorPool(nil, nil, common.Score_Trusted, []string{}) + pool = NewOrchestratorPool(nil, nil, common.Score_Trusted, []string{}, 50*time.Millisecond) errorLogsAfter := glog.Stats.Error.Lines() assert.Equal(0, pool.Size()) assert.NotZero(t, errorLogsAfter-errorLogsBefore) @@ -163,7 +163,7 @@ func TestDBOrchestratorPoolCacheSize(t *testing.T) { goleak.VerifyNone(t, common.IgnoreRoutines()...) }() - emptyPool, err := NewDBOrchestratorPoolCache(ctx, node, &stubRoundsManager{}, []string{}) + emptyPool, err := NewDBOrchestratorPoolCache(ctx, node, &stubRoundsManager{}, []string{}, 500*time.Millisecond) require.NoError(err) require.NotNil(emptyPool) assert.Equal(0, emptyPool.Size()) @@ -174,7 +174,7 @@ func TestDBOrchestratorPoolCacheSize(t *testing.T) { dbh.UpdateOrch(ethOrchToDBOrch(o)) } - nonEmptyPool, err := NewDBOrchestratorPoolCache(ctx, node, &stubRoundsManager{}, []string{}) + nonEmptyPool, err := NewDBOrchestratorPoolCache(ctx, node, &stubRoundsManager{}, []string{}, 500*time.Millisecond) require.NoError(err) require.NotNil(nonEmptyPool) assert.Equal(len(addresses), nonEmptyPool.Size()) @@ -218,7 +218,7 @@ func TestNewDBOrchestorPoolCache_NoEthAddress(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - pool, err := NewDBOrchestratorPoolCache(ctx, node, rm, []string{}) + pool, err := NewDBOrchestratorPoolCache(ctx, node, rm, []string{}, 500*time.Millisecond) require.Nil(err) // Check that serverGetOrchInfo returns early and the orchestrator isn't updated @@ -272,7 +272,7 @@ func TestNewDBOrchestratorPoolCache_InvalidPrices(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - pool, err := NewDBOrchestratorPoolCache(ctx, node, rm, []string{}) + pool, err := NewDBOrchestratorPoolCache(ctx, node, rm, []string{}, 500*time.Millisecond) require.Nil(err) // priceInfo.PixelsPerUnit = 0 @@ -343,7 +343,7 @@ func TestNewDBOrchestratorPoolCache_GivenListOfOrchs_CreatesPoolCacheCorrectly(t sender.On("ValidateTicketParams", mock.Anything).Return(nil).Times(3) - pool, err := NewDBOrchestratorPoolCache(ctx, node, &stubRoundsManager{}, []string{}) + pool, err := NewDBOrchestratorPoolCache(ctx, node, &stubRoundsManager{}, []string{}, 500*time.Millisecond) require.NoError(err) assert.Equal(pool.Size(), 3) orchs, err := pool.GetOrchestrators(context.TODO(), pool.Size(), newStubSuspender(), newStubCapabilities(), common.ScoreAtLeast(0)) @@ -413,7 +413,7 @@ func TestNewDBOrchestratorPoolCache_TestURLs(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - pool, err := NewDBOrchestratorPoolCache(ctx, node, &stubRoundsManager{}, []string{}) + pool, err := NewDBOrchestratorPoolCache(ctx, node, &stubRoundsManager{}, []string{}, 500*time.Millisecond) require.NoError(err) // bad URLs are inserted in the database but are not included in the working set, as there is no returnable query for getting their priceInfo // And if URL is updated it won't be picked up until next cache update @@ -446,7 +446,7 @@ func TestNewDBOrchestratorPoolCache_TestURLs_Empty(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - pool, err := NewDBOrchestratorPoolCache(ctx, node, &stubRoundsManager{}, []string{}) + pool, err := NewDBOrchestratorPoolCache(ctx, node, &stubRoundsManager{}, []string{}, 500*time.Millisecond) require.NoError(err) assert.Equal(0, pool.Size()) infos := pool.GetInfos() @@ -531,7 +531,7 @@ func TestNewDBOrchestorPoolCache_PollOrchestratorInfo(t *testing.T) { origCacheRefreshInterval := cacheRefreshInterval cacheRefreshInterval = 200 * time.Millisecond defer func() { cacheRefreshInterval = origCacheRefreshInterval }() - pool, err := NewDBOrchestratorPoolCache(ctx, node, &stubRoundsManager{}, []string{}) + pool, err := NewDBOrchestratorPoolCache(ctx, node, &stubRoundsManager{}, []string{}, 500*time.Millisecond) require.NoError(err) // Ensure orchestrators exist in DB @@ -569,7 +569,7 @@ func TestNewOrchestratorPoolCache_GivenListOfOrchs_CreatesPoolCacheCorrectly(t * assert := assert.New(t) // creating NewOrchestratorPool with orch addresses - offchainOrch := NewOrchestratorPool(nil, addresses, common.Score_Trusted, []string{}) + offchainOrch := NewOrchestratorPool(nil, addresses, common.Score_Trusted, []string{}, 50*time.Millisecond) for i, info := range offchainOrch.infos { assert.Equal(info.URL.String(), addresses[i].String()) @@ -595,7 +595,7 @@ func TestNewOrchestratorPoolWithPred_TestPredicate(t *testing.T) { } uris := stringsToURIs(addresses) - pool := NewOrchestratorPoolWithPred(nil, uris, pred, common.Score_Trusted, []string{}) + pool := NewOrchestratorPoolWithPred(nil, uris, pred, common.Score_Trusted, []string{}, 50*time.Millisecond) oInfo := &net.OrchestratorInfo{ PriceInfo: &net.PriceInfo{ @@ -685,7 +685,7 @@ func TestCachedPool_AllOrchestratorsTooExpensive_ReturnsAllOrchestrators(t *test sender.On("ValidateTicketParams", mock.Anything).Return(nil) - pool, err := NewDBOrchestratorPoolCache(ctx, node, &stubRoundsManager{}, []string{}) + pool, err := NewDBOrchestratorPoolCache(ctx, node, &stubRoundsManager{}, []string{}, 500*time.Millisecond) require.NoError(err) // ensuring orchs exist in DB @@ -775,7 +775,7 @@ func TestCachedPool_GetOrchestrators_MaxBroadcastPriceNotSet(t *testing.T) { sender.On("ValidateTicketParams", mock.Anything).Return(nil) - pool, err := NewDBOrchestratorPoolCache(ctx, node, &stubRoundsManager{}, []string{}) + pool, err := NewDBOrchestratorPoolCache(ctx, node, &stubRoundsManager{}, []string{}, 500*time.Millisecond) require.NoError(err) // ensuring orchs exist in DB @@ -881,7 +881,7 @@ func TestCachedPool_N_OrchestratorsGoodPricing_ReturnsNOrchestrators(t *testing. sender.On("ValidateTicketParams", mock.Anything).Return(nil) - pool, err := NewDBOrchestratorPoolCache(ctx, node, &stubRoundsManager{}, []string{}) + pool, err := NewDBOrchestratorPoolCache(ctx, node, &stubRoundsManager{}, []string{}, 500*time.Millisecond) require.NoError(err) // ensuring orchs exist in DB @@ -928,7 +928,7 @@ func TestCachedPool_GetOrchestrators_TicketParamsValidation(t *testing.T) { gmp := runtime.GOMAXPROCS(50) defer runtime.GOMAXPROCS(gmp) // Disable retrying discovery with extended timeout - maxGetOrchestratorCutoffTimeout = getOrchestratorsCutoffTimeout + maxGetOrchestratorCutoffTimeout = 500 * time.Millisecond server.BroadcastCfg.SetMaxPrice(nil) @@ -971,7 +971,7 @@ func TestCachedPool_GetOrchestrators_TicketParamsValidation(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - pool, err := NewDBOrchestratorPoolCache(ctx, node, &stubRoundsManager{}, []string{}) + pool, err := NewDBOrchestratorPoolCache(ctx, node, &stubRoundsManager{}, []string{}, 500*time.Millisecond) require.NoError(err) // Test 25 out of 50 orchs pass ticket params validation @@ -1065,7 +1065,7 @@ func TestCachedPool_GetOrchestrators_OnlyActiveOrchestrators(t *testing.T) { sender.On("ValidateTicketParams", mock.Anything).Return(nil) - pool, err := NewDBOrchestratorPoolCache(ctx, node, &stubRoundsManager{round: big.NewInt(24)}, []string{}) + pool, err := NewDBOrchestratorPoolCache(ctx, node, &stubRoundsManager{round: big.NewInt(24)}, []string{}, 500*time.Millisecond) require.NoError(err) // ensuring orchs exist in DB @@ -1120,7 +1120,7 @@ func TestNewWHOrchestratorPoolCache(t *testing.T) { // assert created webhook pool is correct length whURL, _ := url.ParseRequestURI("https://livepeer.live/api/orchestrator") - whpool := NewWebhookPool(nil, whURL) + whpool := NewWebhookPool(nil, whURL, 500*time.Millisecond) assert.Equal(3, whpool.Size()) // assert that list is not refreshed if lastRequest is less than 1 min ago and hash is the same @@ -1270,6 +1270,7 @@ func TestOrchestratorPool_GetOrchestrators(t *testing.T) { assert := assert.New(t) addresses := stringsToURIs([]string{"https://127.0.0.1:8936", "https://127.0.0.1:8937", "https://127.0.0.1:8938"}) + orchTimeout := 500 * time.Millisecond wg := sync.WaitGroup{} orchCb := func() error { return nil } @@ -1283,7 +1284,7 @@ func TestOrchestratorPool_GetOrchestrators(t *testing.T) { }, err } - pool := NewOrchestratorPool(nil, addresses, common.Score_Trusted, []string{}) + pool := NewOrchestratorPool(nil, addresses, common.Score_Trusted, []string{}, orchTimeout) // Check that we receive everything wg.Add(len(addresses)) @@ -1326,7 +1327,7 @@ func TestOrchestratorPool_GetOrchestrators(t *testing.T) { assert.Len(res, len(addresses)-1) // Ensure that the timeout did not fire assert.Less(end.Sub(start).Milliseconds(), - getOrchestratorsTimeoutLoop.Milliseconds()) + pool.discoveryTimeout.Milliseconds()) } @@ -1348,7 +1349,7 @@ func TestOrchestratorPool_GetOrchestrators_SuspendedOrchs(t *testing.T) { }, err } - pool := NewOrchestratorPool(nil, addresses, common.Score_Trusted, []string{}) + pool := NewOrchestratorPool(nil, addresses, common.Score_Trusted, []string{}, 50*time.Millisecond) // suspend https://127.0.0.1:8938 sus := newStubSuspender() @@ -1417,7 +1418,7 @@ func TestOrchestratorPool_ShuffleGetOrchestrators(t *testing.T) { return &net.OrchestratorInfo{Transcoder: server.String()}, nil } - pool := NewOrchestratorPool(nil, addresses, common.Score_Trusted, []string{}) + pool := NewOrchestratorPool(nil, addresses, common.Score_Trusted, []string{}, 50*time.Millisecond) // Check that randomization happens: check for elements in a different order // Could fail sometimes due to scheduling; the order of execution is undefined @@ -1480,14 +1481,12 @@ func TestOrchestratorPool_GetOrchestratorTimeout(t *testing.T) { return &net.OrchestratorInfo{}, nil } - oldTimeout := getOrchestratorsTimeoutLoop - getOrchestratorsTimeoutLoop = 1 * time.Millisecond - defer func() { getOrchestratorsTimeoutLoop = oldTimeout }() + timeout := 1 * time.Millisecond - pool := NewOrchestratorPool(nil, addresses, common.Score_Trusted, []string{}) + pool := NewOrchestratorPool(nil, addresses, common.Score_Trusted, []string{}, timeout) timedOut := func(start, end time.Time) bool { - return end.Sub(start).Milliseconds() >= getOrchestratorsTimeoutLoop.Milliseconds() + return end.Sub(start).Milliseconds() >= pool.discoveryTimeout.Milliseconds() } // We may only return a subset of responses for a given test @@ -1529,7 +1528,7 @@ func TestOrchestratorPool_GetOrchestratorTimeout(t *testing.T) { assert.True(responsesDrained(), "Did not drain responses in time") // Sanity check we get addresses with a reasonable timeout and no forced delay - getOrchestratorsTimeoutLoop = 25 * time.Millisecond + pool.discoveryTimeout = 25 * time.Millisecond go drainOrchResponses(len(addresses)) start = time.Now() res, err = getOrchestrators(len(addresses)) @@ -1579,7 +1578,7 @@ func TestOrchestratorPool_Capabilities(t *testing.T) { responses := []*net.OrchestratorInfo{i1, i2, i3, i4, i5} addresses := stringsToURIs([]string{"a://b", "a://b", "a://b", "a://b", "a://b"}) - pool := NewOrchestratorPool(nil, addresses, common.Score_Trusted, []string{hex.EncodeToString(address)}) + pool := NewOrchestratorPool(nil, addresses, common.Score_Trusted, []string{hex.EncodeToString(address)}, 50*time.Millisecond) // some sanity checks assert.Len(addresses, len(responses)) @@ -1629,3 +1628,24 @@ func TestOrchestratorPool_Capabilities(t *testing.T) { assert.Len(infos, 1) assert.Equal(i4, infos[0].RemoteInfo) } + +func TestSetGetOrchestratorTimeout(t *testing.T) { + assert := assert.New(t) + dbh, _, err := common.TempDB(t) + require := require.New(t) + require.Nil(err) + + sender := &pm.MockSender{} + node := &core.LivepeerNode{ + Database: dbh, + Eth: ð.StubClient{TotalStake: big.NewInt(0)}, + Sender: sender, + } + + //set timeout to 1000ms + poolCache, err := NewDBOrchestratorPoolCache(context.TODO(), node, &stubRoundsManager{}, []string{}, 1000*time.Millisecond) + assert.Nil(err) + //confirm the timeout is now 1000ms + assert.Equal(poolCache.discoveryTimeout, 1000*time.Millisecond) + +} diff --git a/discovery/wh_discovery.go b/discovery/wh_discovery.go index 1c4c8539f3..7e552dfcce 100644 --- a/discovery/wh_discovery.go +++ b/discovery/wh_discovery.go @@ -21,19 +21,21 @@ type webhookResponse struct { } type webhookPool struct { - pool *orchestratorPool - callback *url.URL - responseHash ethcommon.Hash - lastRequest time.Time - mu *sync.RWMutex - bcast common.Broadcaster + pool *orchestratorPool + callback *url.URL + responseHash ethcommon.Hash + lastRequest time.Time + mu *sync.RWMutex + bcast common.Broadcaster + discoveryTimeout time.Duration } -func NewWebhookPool(bcast common.Broadcaster, callback *url.URL) *webhookPool { +func NewWebhookPool(bcast common.Broadcaster, callback *url.URL, discoveryTimeout time.Duration) *webhookPool { p := &webhookPool{ - callback: callback, - mu: &sync.RWMutex{}, - bcast: bcast, + callback: callback, + mu: &sync.RWMutex{}, + bcast: bcast, + discoveryTimeout: discoveryTimeout, } go p.getInfos() return p @@ -71,7 +73,7 @@ func (w *webhookPool) getInfos() ([]common.OrchestratorLocalInfo, error) { } // pool = NewOrchestratorPool(w.bcast, addrs) - pool = &orchestratorPool{infos: infos, bcast: w.bcast} + pool = &orchestratorPool{infos: infos, bcast: w.bcast, discoveryTimeout: w.discoveryTimeout} w.mu.Lock() w.responseHash = hash From 71a2dcf8391a49662950ea34b8b05af7ba1b8c92 Mon Sep 17 00:00:00 2001 From: John | Elite Encoder Date: Sun, 22 Sep 2024 20:28:43 -0400 Subject: [PATCH 16/21] print error message on gateway for bad request lora errors (#3154) This commit updates the AI error handling behavoir so that BadRequest errors are forwarded to the user. Co-authored-by: Rick Staa --- go.mod | 2 +- go.sum | 4 ++-- server/ai_mediaserver.go | 37 ++++++++++++++++++++++++++++--------- server/ai_process.go | 24 ++++++++++++++++++++++++ 4 files changed, 55 insertions(+), 12 deletions(-) diff --git a/go.mod b/go.mod index f84f4a6b37..b2823c22da 100644 --- a/go.mod +++ b/go.mod @@ -13,7 +13,7 @@ require ( github.com/golang/protobuf v1.5.4 github.com/jaypipes/ghw v0.10.0 github.com/jaypipes/pcidb v1.0.0 - github.com/livepeer/ai-worker v0.5.0 + github.com/livepeer/ai-worker v0.6.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-20240819180416-f87352959b85 diff --git a/go.sum b/go.sum index 8c7b8cd8cb..a136521425 100644 --- a/go.sum +++ b/go.sum @@ -623,8 +623,8 @@ github.com/libp2p/go-netroute v0.2.0 h1:0FpsbsvuSnAhXFnCY0VLFbJOzaK0VnP0r1QT/o4n github.com/libp2p/go-netroute v0.2.0/go.mod h1:Vio7LTzZ+6hoT4CMZi5/6CpY3Snzh2vgZhWgxMNwlQI= github.com/libp2p/go-openssl v0.1.0 h1:LBkKEcUv6vtZIQLVTegAil8jbNpJErQ9AnT+bWV+Ooo= github.com/libp2p/go-openssl v0.1.0/go.mod h1:OiOxwPpL3n4xlenjx2h7AwSGaFSC/KZvf6gNdOBQMtc= -github.com/livepeer/ai-worker v0.5.0 h1:dgO6j9QVFPOq9omIcgB1YmgVSlhV94BMb6QO4WUocX8= -github.com/livepeer/ai-worker v0.5.0/go.mod h1:91lMzkzVuwR9kZ0EzXwf+7yVhLaNVmYAfmBtn7t3cQA= +github.com/livepeer/ai-worker v0.6.0 h1:sGldUavfbTXPQDKc1a80/zgK8G1VdYRAxiuFTP0YyOU= +github.com/livepeer/ai-worker v0.6.0/go.mod h1:91lMzkzVuwR9kZ0EzXwf+7yVhLaNVmYAfmBtn7t3cQA= github.com/livepeer/go-tools v0.3.6-0.20240130205227-92479de8531b h1:VQcnrqtCA2UROp7q8ljkh2XA/u0KRgVv0S1xoUvOweE= github.com/livepeer/go-tools v0.3.6-0.20240130205227-92479de8531b/go.mod h1:hwJ5DKhl+pTanFWl+EUpw1H7ukPO/H+MFpgA7jjshzw= github.com/livepeer/joy4 v0.1.2-0.20191121080656-b2fea45cbded h1:ZQlvR5RB4nfT+cOQee+WqmaDOgGtP2oDMhcVvR4L0yA= diff --git a/server/ai_mediaserver.go b/server/ai_mediaserver.go index 078fa05ee9..0571eaf68c 100644 --- a/server/ai_mediaserver.go +++ b/server/ai_mediaserver.go @@ -98,11 +98,16 @@ func (ls *LivepeerServer) TextToImage() http.Handler { start := time.Now() resp, err := processTextToImage(ctx, params, req) if err != nil { - var e *ServiceUnavailableError - if errors.As(err, &e) { + var serviceUnavailableErr *ServiceUnavailableError + var badRequestErr *BadRequestError + if errors.As(err, &serviceUnavailableErr) { respondJsonError(ctx, w, err, http.StatusServiceUnavailable) return } + if errors.As(err, &badRequestErr) { + respondJsonError(ctx, w, err, http.StatusBadRequest) + return + } respondJsonError(ctx, w, err, http.StatusInternalServerError) return } @@ -146,11 +151,16 @@ func (ls *LivepeerServer) ImageToImage() http.Handler { start := time.Now() resp, err := processImageToImage(ctx, params, req) if err != nil { - var e *ServiceUnavailableError - if errors.As(err, &e) { + var serviceUnavailableErr *ServiceUnavailableError + var badRequestErr *BadRequestError + if errors.As(err, &serviceUnavailableErr) { respondJsonError(ctx, w, err, http.StatusServiceUnavailable) return } + if errors.As(err, &badRequestErr) { + respondJsonError(ctx, w, err, http.StatusBadRequest) + return + } respondJsonError(ctx, w, err, http.StatusInternalServerError) return } @@ -202,12 +212,16 @@ func (ls *LivepeerServer) ImageToVideo() http.Handler { resp, err := processImageToVideo(ctx, params, req) if err != nil { - var e *ServiceUnavailableError - if errors.As(err, &e) { + var serviceUnavailableErr *ServiceUnavailableError + var badRequestErr *BadRequestError + if errors.As(err, &serviceUnavailableErr) { respondJsonError(ctx, w, err, http.StatusServiceUnavailable) return } - + if errors.As(err, &badRequestErr) { + respondJsonError(ctx, w, err, http.StatusBadRequest) + return + } respondJsonError(ctx, w, err, http.StatusInternalServerError) return } @@ -304,11 +318,16 @@ func (ls *LivepeerServer) Upscale() http.Handler { start := time.Now() resp, err := processUpscale(ctx, params, req) if err != nil { - var e *ServiceUnavailableError - if errors.As(err, &e) { + var serviceUnavailableErr *ServiceUnavailableError + var badRequestErr *BadRequestError + if errors.As(err, &serviceUnavailableErr) { respondJsonError(ctx, w, err, http.StatusServiceUnavailable) return } + if errors.As(err, &badRequestErr) { + respondJsonError(ctx, w, err, http.StatusBadRequest) + return + } respondJsonError(ctx, w, err, http.StatusInternalServerError) return } diff --git a/server/ai_process.go b/server/ai_process.go index 249cc506b6..cce4595aa5 100644 --- a/server/ai_process.go +++ b/server/ai_process.go @@ -49,6 +49,26 @@ func (e *BadRequestError) Error() string { return e.err.Error() } +// parseBadRequestError checks if the error is a bad request error and returns a BadRequestError. +func parseBadRequestError(err error) *BadRequestError { + if err == nil { + return nil + } + + const errorCode = "returned 400" + if !strings.Contains(err.Error(), errorCode) { + return nil + } + + parts := strings.SplitN(err.Error(), errorCode, 2) + detail := strings.TrimSpace(parts[1]) + if detail == "" { + detail = "bad request" + } + + return &BadRequestError{err: errors.New(detail)} +} + type aiRequestParams struct { node *core.LivepeerNode os drivers.OSSession @@ -897,6 +917,10 @@ func processAIRequest(ctx context.Context, params aiRequestParams, req interface if errors.Is(err, common.ErrAudioDurationCalculation) { return nil, &BadRequestError{err} } + + if badRequestErr := parseBadRequestError(err); badRequestErr != nil { + return nil, badRequestErr + } } if resp == nil { From aad1a230a3c1ff3ef722a96bd2093d985b517ce2 Mon Sep 17 00:00:00 2001 From: Rick Staa Date: Mon, 23 Sep 2024 12:23:04 +0200 Subject: [PATCH 17/21] refactor: remove unused selection factory (#3180) This commit cleansup the broadcaster and NewSessionManager code by removing the selection factory that has been unused since https://github.com/livepeer/go-livepeer/commit/fea5673d253dd9ba44e0ac01a752e9aa94319be7. --- server/broadcast.go | 2 +- server/broadcast_test.go | 8 ++------ server/mediaserver.go | 11 +---------- 3 files changed, 4 insertions(+), 17 deletions(-) diff --git a/server/broadcast.go b/server/broadcast.go index a3e8cf64b9..5e9c134685 100755 --- a/server/broadcast.go +++ b/server/broadcast.go @@ -453,7 +453,7 @@ func (bsm *BroadcastSessionsManager) shouldSkipVerification(sessions []*Broadcas return common.RandomUintUnder(bsm.VerificationFreq) != 0 } -func NewSessionManager(ctx context.Context, node *core.LivepeerNode, params *core.StreamParameters, sel BroadcastSessionsSelectorFactory) *BroadcastSessionsManager { +func NewSessionManager(ctx context.Context, node *core.LivepeerNode, params *core.StreamParameters) *BroadcastSessionsManager { if node.Capabilities != nil { params.Capabilities.SetMinVersionConstraint(node.Capabilities.MinVersionConstraint()) } diff --git a/server/broadcast_test.go b/server/broadcast_test.go index 372d25205a..21f11cb18d 100644 --- a/server/broadcast_test.go +++ b/server/broadcast_test.go @@ -65,10 +65,6 @@ func StubBroadcastSession(transcoder string) *BroadcastSession { } } -func selFactoryEmpty() BroadcastSessionsSelector { - return &LIFOSelector{} -} - func bsmWithSessList(sessList []*BroadcastSession) *BroadcastSessionsManager { return bsmWithSessListExt(sessList, nil, false) } @@ -299,7 +295,7 @@ func TestNewSessionManager(t *testing.T) { // Check empty pool produces expected numOrchs - sess := NewSessionManager(context.TODO(), n, params, selFactoryEmpty) + sess := NewSessionManager(context.TODO(), n, params) assert.Equal(0, sess.trustedPool.numOrchs) assert.Equal(0, sess.untrustedPool.numOrchs) @@ -308,7 +304,7 @@ func TestNewSessionManager(t *testing.T) { n.OrchestratorPool = sd max := int(common.HTTPTimeout.Seconds()/SegLen.Seconds()) * 2 for i := 0; i < 10; i++ { - sess = NewSessionManager(context.TODO(), n, params, selFactoryEmpty) + sess = NewSessionManager(context.TODO(), n, params) if i < max { assert.Equal(i, sess.trustedPool.numOrchs) } else { diff --git a/server/mediaserver.go b/server/mediaserver.go index 975aef7fb2..6b1b5ea69a 100644 --- a/server/mediaserver.go +++ b/server/mediaserver.go @@ -524,17 +524,8 @@ func (s *LivepeerServer) registerConnection(ctx context.Context, rtmpStrm stream // do not obtain this lock again while initializing channel is open, it will cause deadlock if other goroutine already obtained the lock and called getActiveRtmpConnectionUnsafe() s.connectionLock.Unlock() - // initialize session manager - var stakeRdr stakeReader - if s.LivepeerNode.Eth != nil { - stakeRdr = &storeStakeReader{store: s.LivepeerNode.Database} - } - selFactory := func() BroadcastSessionsSelector { - return NewMinLSSelector(stakeRdr, SELECTOR_LATENCY_SCORE_THRESHOLD, s.LivepeerNode.SelectionAlgorithm, s.LivepeerNode.OrchPerfScore) - } - // safe, because other goroutines should be waiting on initializing channel - cxn.sessManager = NewSessionManager(ctx, s.LivepeerNode, params, selFactory) + cxn.sessManager = NewSessionManager(ctx, s.LivepeerNode, params) // populate fields and signal initializing channel s.serverLock.Lock() From d1b4dec9cccfc56edb6a522ef9bc0cbd29aa1876 Mon Sep 17 00:00:00 2001 From: Rick Staa Date: Mon, 23 Sep 2024 14:26:53 +0200 Subject: [PATCH 18/21] fix(ai): selection algorithm transcoding conflict patch (#3181) While merging the main branch into the AI branch, the fragile AI selection algorithm broke due to changes in the transcoding selection logic, which the AI algorithm relies on. This commit provides a temporary patch to ensure the selection process continues to function while we work on improving the AI selection algorithm. --- server/selection.go | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/server/selection.go b/server/selection.go index f3a80a4819..f13b094b82 100644 --- a/server/selection.go +++ b/server/selection.go @@ -137,15 +137,23 @@ func (s *MinLSSelector) Select(ctx context.Context) *BroadcastSession { return s.selectUnknownSession(ctx) } - lowestLatencyScoreKnownSession := heap.Pop(s.knownSessions).(*BroadcastSession) - if lowestLatencyScoreKnownSession.LatencyScore <= s.minLS { - // known session has good enough latency score, use it - return lowestLatencyScoreKnownSession + minSess := sess.(*BroadcastSession) + if minSess.LatencyScore > s.minLS && len(s.unknownSessions) > 0 { + return s.selectUnknownSession(ctx) } - // known session does not have good enough latency score, clear the heap and use unknown session - s.knownSessions = &sessHeap{} - return s.selectUnknownSession(ctx) + return heap.Pop(s.knownSessions).(*BroadcastSession) + + // TODO: Fix AI selection logic, remove above code and uncomment transcoding logic below. + // lowestLatencyScoreKnownSession := heap.Pop(s.knownSessions).(*BroadcastSession) + // if lowestLatencyScoreKnownSession.LatencyScore <= s.minLS { + // // known session has good enough latency score, use it + // return lowestLatencyScoreKnownSession + // } + + // // known session does not have good enough latency score, clear the heap and use unknown session + // s.knownSessions = &sessHeap{} + // return s.selectUnknownSession(ctx) } // Size returns the number of sessions stored by the selector From 277935b7b1e170c4d20625ca4dc55535aaf1f2a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Wilczy=C5=84ski?= Date: Thu, 26 Sep 2024 11:08:59 +0200 Subject: [PATCH 19/21] Add ochestrator_version tag to ai_request_latency_score and ai_request_errors metrics --- monitor/census.go | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/monitor/census.go b/monitor/census.go index b69bddc43e..d0f76e5449 100644 --- a/monitor/census.go +++ b/monitor/census.go @@ -1815,9 +1815,13 @@ func (cen *censusMetricsCounter) recordAIRequestLatencyScore(Pipeline string, Mo cen.lock.Lock() defer cen.lock.Unlock() - if err := stats.RecordWithTags(cen.ctx, - []tag.Mutator{tag.Insert(cen.kPipeline, Pipeline), tag.Insert(cen.kModelName, Model), tag.Insert(cen.kOrchestratorURI, orchInfo.GetTranscoder()), tag.Insert(cen.kOrchestratorAddress, common.BytesToAddress(orchInfo.GetAddress()).String())}, - cen.mAIRequestLatencyScore.M(latencyScore)); err != nil { + tags := []tag.Mutator{tag.Insert(cen.kPipeline, Pipeline), tag.Insert(cen.kModelName, Model), tag.Insert(cen.kOrchestratorURI, orchInfo.GetTranscoder()), tag.Insert(cen.kOrchestratorAddress, common.BytesToAddress(orchInfo.GetAddress()).String())} + capabilities := orchInfo.GetCapabilities() + if capabilities != nil { + tags = append(tags, tag.Insert(cen.kOrchestratorVersion, orchInfo.GetCapabilities().GetVersion())) + } + + if err := stats.RecordWithTags(cen.ctx, tags, cen.mAIRequestLatencyScore.M(latencyScore)); err != nil { glog.Errorf("Error recording metrics err=%q", err) } } @@ -1841,9 +1845,13 @@ func AIRequestError(code string, Pipeline string, Model string, orchInfo *lpnet. orchAddr = common.BytesToAddress(addr).String() } - if err := stats.RecordWithTags(census.ctx, - []tag.Mutator{tag.Insert(census.kErrorCode, code), tag.Insert(census.kPipeline, Pipeline), tag.Insert(census.kModelName, Model), tag.Insert(census.kOrchestratorURI, orchInfo.GetTranscoder()), tag.Insert(census.kOrchestratorAddress, orchAddr)}, - census.mAIRequestError.M(1)); err != nil { + tags := []tag.Mutator{tag.Insert(census.kErrorCode, code), tag.Insert(census.kPipeline, Pipeline), tag.Insert(census.kModelName, Model), tag.Insert(census.kOrchestratorURI, orchInfo.GetTranscoder()), tag.Insert(census.kOrchestratorAddress, orchAddr)} + capabilities := orchInfo.GetCapabilities() + if capabilities != nil { + tags = append(tags, tag.Insert(census.kOrchestratorVersion, orchInfo.GetCapabilities().GetVersion())) + } + + if err := stats.RecordWithTags(census.ctx, tags, census.mAIRequestError.M(1)); err != nil { glog.Errorf("Error recording metrics err=%q", err) } } From 2cd552f7937b0aa6a96c92fc7f373e22163f38d6 Mon Sep 17 00:00:00 2001 From: Max Holland Date: Fri, 27 Sep 2024 09:39:27 +0100 Subject: [PATCH 20/21] Better messages for objectStore errors (#3183) --- core/capabilities.go | 8 ++++++++ core/capabilities_test.go | 25 +++++++++++++++++++++++++ server/ai_mediaserver.go | 2 +- server/ai_process.go | 15 ++++++++------- 4 files changed, 42 insertions(+), 8 deletions(-) diff --git a/core/capabilities.go b/core/capabilities.go index fc9e5217ba..1ac674a9ed 100644 --- a/core/capabilities.go +++ b/core/capabilities.go @@ -623,6 +623,14 @@ func CapabilityToName(capability Capability) (string, error) { return capName, nil } +func (c Capability) String() string { + name, err := CapabilityToName(c) + if err != nil { + return fmt.Sprintf("%d", int(c)) + } + return name +} + func HasCapability(caps []Capability, capability Capability) bool { for _, c := range caps { if capability == c { diff --git a/core/capabilities_test.go b/core/capabilities_test.go index cf9eabf40f..70cea1c869 100644 --- a/core/capabilities_test.go +++ b/core/capabilities_test.go @@ -714,3 +714,28 @@ func TestLiveeerVersionCompatibleWith(t *testing.T) { }) } } + +func TestCapability_String(t *testing.T) { + var unknownCap Capability = -100 + tests := []struct { + name string + c Capability + want string + }{ + { + name: "Capability_TextToImage", + c: Capability_TextToImage, + want: "Text to image", + }, + { + name: "Unknown", + c: unknownCap, + want: "-100", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + assert.Equal(t, tt.want, tt.c.String()) + }) + } +} diff --git a/server/ai_mediaserver.go b/server/ai_mediaserver.go index 0571eaf68c..8190348aa4 100644 --- a/server/ai_mediaserver.go +++ b/server/ai_mediaserver.go @@ -87,7 +87,7 @@ func (ls *LivepeerServer) TextToImage() http.Handler { return } - clog.V(common.VERBOSE).Infof(r.Context(), "Received TextToImage request prompt=%v model_id=%v", req.Prompt, *req.ModelId) + clog.V(common.VERBOSE).Infof(ctx, "Received TextToImage request prompt=%v model_id=%v", req.Prompt, *req.ModelId) params := aiRequestParams{ node: ls.LivepeerNode, diff --git a/server/ai_process.go b/server/ai_process.go index cce4595aa5..a244b82cc6 100644 --- a/server/ai_process.go +++ b/server/ai_process.go @@ -115,7 +115,7 @@ func processTextToImage(ctx context.Context, params aiRequestParams, req worker. name := string(core.RandomManifestID()) + ".png" newUrl, err := params.os.SaveData(ctx, name, bytes.NewReader(data.Bytes()), nil, 0) if err != nil { - return nil, err + return nil, fmt.Errorf("error saving image to objectStore: %w", err) } newMedia[i] = worker.Media{Nsfw: media.Nsfw, Seed: media.Seed, Url: newUrl} @@ -241,7 +241,7 @@ func processImageToImage(ctx context.Context, params aiRequestParams, req worker name := string(core.RandomManifestID()) + ".png" newUrl, err := params.os.SaveData(ctx, name, bytes.NewReader(data.Bytes()), nil, 0) if err != nil { - return nil, err + return nil, fmt.Errorf("error saving image to objectStore: %w", err) } newMedia[i] = worker.Media{Nsfw: media.Nsfw, Seed: media.Seed, Url: newUrl} @@ -377,7 +377,7 @@ func processImageToVideo(ctx context.Context, params aiRequestParams, req worker name := filepath.Base(media.Url) newUrl, err := params.os.SaveData(ctx, name, bytes.NewReader(data), nil, 0) if err != nil { - return nil, err + return nil, fmt.Errorf("error saving video to objectStore: %w", err) } videos[i] = worker.Media{ @@ -518,7 +518,7 @@ func processUpscale(ctx context.Context, params aiRequestParams, req worker.GenU name := string(core.RandomManifestID()) + ".png" newUrl, err := params.os.SaveData(ctx, name, bytes.NewReader(data.Bytes()), nil, 0) if err != nil { - return nil, err + return nil, fmt.Errorf("error saving image to objectStore: %w", err) } newMedia[i] = worker.Media{Nsfw: media.Nsfw, Seed: media.Seed, Url: newUrl} @@ -875,7 +875,8 @@ func processAIRequest(ctx context.Context, params aiRequestParams, req interface default: return nil, fmt.Errorf("unsupported request type %T", req) } - capName, _ := core.CapabilityToName(cap) + capName := cap.String() + ctx = clog.AddVal(ctx, "capability", capName) var resp interface{} @@ -897,7 +898,7 @@ func processAIRequest(ctx context.Context, params aiRequestParams, req interface tries++ sess, err := params.sessManager.Select(ctx, cap, modelID) if err != nil { - clog.Infof(ctx, "Error selecting session cap=%v modelID=%v err=%v", cap, modelID, err) + clog.Infof(ctx, "Error selecting session modelID=%v err=%v", modelID, err) continue } @@ -911,7 +912,7 @@ func processAIRequest(ctx context.Context, params aiRequestParams, req interface break } - clog.Infof(ctx, "Error submitting request cap=%v modelID=%v try=%v orch=%v err=%v", cap, modelID, tries, sess.Transcoder(), err) + clog.Infof(ctx, "Error submitting request modelID=%v try=%v orch=%v err=%v", modelID, tries, sess.Transcoder(), err) params.sessManager.Remove(ctx, sess) if errors.Is(err, common.ErrAudioDurationCalculation) { From a49cd1b9c723bff22757ac011d695491b0a1c382 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Leszko?= Date: Tue, 1 Oct 2024 09:03:20 +0200 Subject: [PATCH 21/21] Small cleanup (#3187) --- ..._RoundTrip_Net-20240729130524-3824236.fail | 828 ------------------ 1 file changed, 828 deletions(-) delete mode 100644 core/testdata/rapid/TestCapability_RoundTrip_Net/TestCapability_RoundTrip_Net-20240729130524-3824236.fail 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 deleted file mode 100644 index bfa48715a7..0000000000 --- a/core/testdata/rapid/TestCapability_RoundTrip_Net/TestCapability_RoundTrip_Net-20240729130524-3824236.fail +++ /dev/null @@ -1,828 +0,0 @@ -# 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