diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index eb65e4498..65bdd6655 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -4,12 +4,14 @@ on: push: branches: - 'main' + - '*-staging' pull_request: branches: - '*' merge_group: branches: - 'main' + - '*-staging' defaults: run: diff --git a/address/event.go b/address/event.go index a1ef2317b..79b674dc2 100644 --- a/address/event.go +++ b/address/event.go @@ -41,6 +41,33 @@ const ( StatusCompleted Status = 3 ) +// SortDirection is an enum used to specify the order of returned events. +type SortDirection uint8 + +const ( + // UndefinedSortDirection indicates that the sort direction + // is not specified. + UndefinedSortDirection SortDirection = iota + + // DescSortDirection indicates that the sort should be in + // descending order. + DescSortDirection + + // AscSortDirection indicates that the sort should be in + // ascending order. + AscSortDirection +) + +const ( + // DefaultEventQueryLimit is the number of events returned + // when no limit is provided. + DefaultEventQueryLimit = 512 + + // MaxEventQueryLimit is the maximum number of events that can be + // returned in a single query. + MaxEventQueryLimit = 16384 +) + // EventQueryParams holds the set of query params for address events. type EventQueryParams struct { // AddrTaprootOutputKey is the optional 32-byte x-only serialized @@ -65,6 +92,17 @@ type EventQueryParams struct { // (inclusive). Can be set to nil to return events of all creation // times. CreationTimeTo *time.Time + + // Offset is the offset into the result set to start returning events. + Offset int32 + + // Limit is the max number of events that should be returned. If zero, + // then DefaultEventQueryLimit will be used. + Limit int32 + + // SortDirection is the sort direction to use when returning the + // events. The default zero value sorts the events in ascending order. + SortDirection SortDirection } // AssetOutput holds the information about a single asset output that was sent diff --git a/cmd/commands/addrs.go b/cmd/commands/addrs.go index 0a17a1ca4..fcaf3d541 100644 --- a/cmd/commands/addrs.go +++ b/cmd/commands/addrs.go @@ -158,6 +158,8 @@ const ( limitName = "limit" offsetName = "offset" + + directionName = "direction" ) var queryAddrsCommand = cli.Command{ @@ -293,6 +295,20 @@ var receivesAddrCommand = cli.Command{ Usage: "filter transfers created before this + " + "unix timestamp (seconds)", }, + cli.Int64Flag{ + Name: limitName, + Usage: "the max number of events returned", + }, + cli.Int64Flag{ + Name: offsetName, + Usage: "the number of events to skip", + }, + cli.StringFlag{ + Name: directionName, + Usage: "the sort direction for events (asc or desc). " + + "Defaults to desc.", + Value: "desc", + }, }, Action: addrReceives, } @@ -311,10 +327,18 @@ func addrReceives(ctx *cli.Context) error { addr = ctx.Args().First() } + direction := taprpc.SortDirection_SORT_DIRECTION_DESC + if ctx.String(directionName) == "asc" { + direction = taprpc.SortDirection_SORT_DIRECTION_ASC + } + resp, err := client.AddrReceives(ctxc, &taprpc.AddrReceivesRequest{ FilterAddr: addr, StartTimestamp: ctx.Uint64("start_timestamp"), EndTimestamp: ctx.Uint64("end_timestamp"), + Limit: int32(ctx.Int64(limitName)), + Offset: int32(ctx.Int64(offsetName)), + Direction: direction, }) if err != nil { return fmt.Errorf("unable to query addr receives: %w", err) diff --git a/cmd/commands/assets.go b/cmd/commands/assets.go index fef730c02..9a5eb26ad 100644 --- a/cmd/commands/assets.go +++ b/cmd/commands/assets.go @@ -8,9 +8,11 @@ import ( "strconv" "strings" + "github.com/btcsuite/btcd/btcec/v2" "github.com/btcsuite/btcd/wire" taprootassets "github.com/lightninglabs/taproot-assets" "github.com/lightninglabs/taproot-assets/address" + "github.com/lightninglabs/taproot-assets/asset" "github.com/lightninglabs/taproot-assets/tapcfg" "github.com/lightninglabs/taproot-assets/taprpc" wrpc "github.com/lightninglabs/taproot-assets/taprpc/assetwalletrpc" @@ -1092,6 +1094,10 @@ var burnAssetsCommand = cli.Command{ Name: assetIDName, Usage: "the asset ID to burn units from", }, + cli.StringFlag{ + Name: assetGroupKeyName, + Usage: "the group key to burn units from", + }, cli.Uint64Flag{ Name: assetAmountName, Usage: "the amount of units to burn/destroy", @@ -1106,15 +1112,66 @@ var burnAssetsCommand = cli.Command{ Action: burnAssets, } +// buildAssetSpecifier validates and constructs an asset.Specifier from +// CLI context +func buildAssetSpecifier(ctx *cli.Context) (*asset.Specifier, error) { + assetIDHex := ctx.String(assetIDName) + groupKeyHex := ctx.String(assetGroupKeyName) + + // At least one of asset ID or group key must be provided. + if assetIDHex == "" && groupKeyHex == "" { + return nil, fmt.Errorf("either asset ID or " + + "group key must be specified") + } + + var ( + assetID *asset.ID + groupKey *btcec.PublicKey + err error + ) + + // Parse asset ID if provided. + if assetIDHex != "" { + assetIDBytes, err := hex.DecodeString(assetIDHex) + if err != nil { + return nil, fmt.Errorf("invalid asset ID: %w", err) + } + + var id asset.ID + copy(id[:], assetIDBytes) + assetID = &id + } + + // Parse group key if provided. + if groupKeyHex != "" { + groupKeyBytes, err := hex.DecodeString(groupKeyHex) + if err != nil { + return nil, fmt.Errorf("invalid group key: %w", err) + } + + groupKey, err = btcec.ParsePubKey(groupKeyBytes) + if err != nil { + return nil, fmt.Errorf("invalid group key: %w", err) + } + } + + // Construct the asset specifier. + assetSpecifier, err := asset.NewSpecifier(assetID, groupKey, nil, true) + if err != nil { + return nil, fmt.Errorf("invalid asset specifier: %w", err) + } + + return &assetSpecifier, nil +} + func burnAssets(ctx *cli.Context) error { if ctx.NArg() != 0 || ctx.NumFlags() == 0 { return cli.ShowSubcommandHelp(ctx) } - assetIDHex := ctx.String(assetIDName) - assetIDBytes, err := hex.DecodeString(assetIDHex) + assetSpecifier, err := buildAssetSpecifier(ctx) if err != nil { - return fmt.Errorf("invalid asset ID") + return fmt.Errorf("invalid asset specifier: %w", err) } burnAmount := ctx.Uint64(assetAmountName) @@ -1126,33 +1183,72 @@ func burnAssets(ctx *cli.Context) error { client, cleanUp := getClient(ctx) defer cleanUp() + assetIDBytes, groupKeyBytes := assetSpecifier.AsBytes() + if !ctx.Bool(burnOverrideConfirmationName) { - balance, err := client.ListBalances( - ctxc, &taprpc.ListBalancesRequest{ - GroupBy: &taprpc.ListBalancesRequest_AssetId{ - AssetId: true, + var currBalance uint64 + + // When both asset ID and group key are provided, + // prioritize asset ID for balance checking since + // it's more specific. + switch { + case len(assetIDBytes) > 0: + // nolint: lll + balance, err := client.ListBalances(ctxc, + &taprpc.ListBalancesRequest{ + GroupBy: &taprpc.ListBalancesRequest_AssetId{ + AssetId: true, + }, + AssetFilter: assetIDBytes, }, - AssetFilter: assetIDBytes, - }, - ) - if err != nil { - return fmt.Errorf("unable to list current asset "+ - "balances: %w", err) - } + ) + if err != nil { + return fmt.Errorf("unable to list current "+ + "asset balances: %w", err) + } + + idHex := hex.EncodeToString(assetIDBytes) + assetBalance, ok := balance.AssetBalances[idHex] + if !ok { + return fmt.Errorf("couldn't fetch balance for "+ + "asset ID %x", assetIDBytes) + } + + currBalance = assetBalance.Balance + + case len(groupKeyBytes) > 0: + // nolint: lll + balance, err := client.ListBalances(ctxc, + &taprpc.ListBalancesRequest{ + GroupBy: &taprpc.ListBalancesRequest_GroupKey{ + GroupKey: true, + }, + AssetFilter: groupKeyBytes, + }, + ) + if err != nil { + return fmt.Errorf("unable to list current "+ + "asset balances: %w", err) + } - assetBalance, ok := balance.AssetBalances[assetIDHex] - if !ok { - return fmt.Errorf("couldn't fetch balance for asset %x", - assetIDBytes) + gkHex := hex.EncodeToString(groupKeyBytes) + groupBalance, ok := balance.AssetGroupBalances[gkHex] + if !ok { + return fmt.Errorf("couldn't fetch balance for "+ + "group key %x", groupKeyBytes) + } + + currBalance = groupBalance.Balance } msg := fmt.Sprintf("Please confirm destructive action.\n"+ - "Asset ID: %x\nCurrent available balance: %d\n"+ + "%s\nCurrent available balance: %d\n"+ "Amount to burn: %d\n Are you sure you want to "+ "irreversibly burn (destroy, remove from circulation) "+ "the specified amount of assets?\nPlease answer 'yes' "+ - "or 'no' and press enter: ", assetIDBytes, - assetBalance.Balance, burnAmount) + "or 'no' and press enter: ", + assetSpecifier.String(), currBalance, burnAmount, + ) if !promptForConfirmation(msg) { return nil @@ -1160,8 +1256,9 @@ func burnAssets(ctx *cli.Context) error { } resp, err := client.BurnAsset(ctxc, &taprpc.BurnAssetRequest{ - Asset: &taprpc.BurnAssetRequest_AssetId{ - AssetId: assetIDBytes, + AssetSpecifier: &taprpc.AssetSpecifier{ + Id: assetIDBytes, + GroupKey: groupKeyBytes, }, AmountToBurn: burnAmount, ConfirmationText: taprootassets.AssetBurnConfirmationText, diff --git a/docs/release-notes/release-notes-0.7.0.md b/docs/release-notes/release-notes-0.7.0.md index bc79dd095..46d5615f9 100644 --- a/docs/release-notes/release-notes-0.7.0.md +++ b/docs/release-notes/release-notes-0.7.0.md @@ -218,6 +218,9 @@ information directly from the RPC response without performing separate blockchain queries. +- The `AddrReceives` RPC has new fields `limit`, `offset` and `direction` that + allows pagination and sorting. [See PR](https://github.com/lightninglabs/taproot-assets/pull/1813). + ## tapcli Additions - [Rename](https://github.com/lightninglabs/taproot-assets/pull/1682) the mint @@ -239,6 +242,9 @@ - The `tapcli addrs receives` command now supports [new `--start_timestamp` and `--end_timestamp` flags](https://github.com/lightninglabs/taproot-assets/pull/1794). +- The `tapcli addrs receives` command now has new flags `--limit`, `--offset` and + `--direction` that allows pagination and sorting. [See PR](https://github.com/lightninglabs/taproot-assets/pull/1813). + - The `fetchsupplycommit` command [now supports](https://github.com/lightninglabs/taproot-assets/pull/1823) a `--first` flag to fetch the very first supply commitment; if no flag is provided, it defaults to fetching the latest. Only one of `--first`, diff --git a/docs/release-notes/release-notes-0.8.0.md b/docs/release-notes/release-notes-0.8.0.md new file mode 100644 index 000000000..9661926c4 --- /dev/null +++ b/docs/release-notes/release-notes-0.8.0.md @@ -0,0 +1,87 @@ +# Release Notes +- [Bug Fixes](#bug-fixes) +- [New Features](#new-features) + - [Functional Enhancements](#functional-enhancements) + - [RPC Additions](#rpc-additions) + - [tapcli Additions](#tapcli-additions) +- [Improvements](#improvements) + - [Functional Updates](#functional-updates) + - [RPC Updates](#rpc-updates) + - [tapcli Updates](#tapcli-updates) + - [Config Changes](#config-changes) + - [Breaking Changes](#breaking-changes) + - [Performance Improvements](#performance-improvements) + - [Deprecations](#deprecations) +- [Technical and Architectural Updates](#technical-and-architectural-updates) + - [BIP/bLIP Spec Updates](#bipblip-spec-updates) + - [Testing](#testing) + - [Database](#database) + - [Code Health](#code-health) + - [Tooling and Documentation](#tooling-and-documentation) + +# Bug Fixes + +# New Features + +## Functional Enhancements + +## RPC Additions + +- The `BurnAsset` RPC now supports a + [new `AssetSpecifier` field](https://github.com/lightninglabs/taproot-assets/pull/1812) + that allows the user to specify the asset to burn by ID or GroupKey. + The `asset` field is now deprecated. + +## tapcli Additions + +# Improvements + +## Functional Updates + +## RPC Updates + +- [PR#1841](https://github.com/lightninglabs/taproot-assets/pull/1841): Remove + the defaultMacaroonWhitelist map and inline its entries directly + into the conditional logic within MacaroonWhitelist. This ensures that + access to previously always-available endpoints is now governed by + explicit user configuration (read/write/courier), improving permission + control and aligning with expected access restrictions. + +- [PR#1841](https://github.com/lightninglabs/taproot-assets/pull/1841): Add + default RPC permissions for RPC endpoints universerpc.Universe/Info and + /authmailboxrpc.Mailbox/MailboxInfo. + +## tapcli Updates + +- The `tapcli assets burn` command now has a + [new `--group_key` flag](https://github.com/lightninglabs/taproot-assets/pull/1812) + that allows users to burn assets by group key. + +## Config Changes + +- [PR#1870](https://github.com/lightninglabs/taproot-assets/pull/1870) + The `proofs-per-universe` configuration option is removed. New option + `max-proof-cache-size` sets the proof cache limit in bytes and accepts + human-readable values such as `32MB`. + +## Code Health + +## Breaking Changes + +## Performance Improvements + +## Deprecations + +# Technical and Architectural Updates + +## BIP/bLIP Spec Updates + +## Testing + +## Database + +## Code Health + +## Tooling and Documentation + +# Contributors (Alphabetical Order) diff --git a/docs/release-notes/release-notes-template.md b/docs/release-notes/release-notes-template.md index 0fca27d94..e46aedc41 100644 --- a/docs/release-notes/release-notes-template.md +++ b/docs/release-notes/release-notes-template.md @@ -8,6 +8,7 @@ - [Functional Updates](#functional-updates) - [RPC Updates](#rpc-updates) - [tapcli Updates](#tapcli-updates) + - [Config Changes](#config-changes) - [Breaking Changes](#breaking-changes) - [Performance Improvements](#performance-improvements) - [Deprecations](#deprecations) @@ -36,6 +37,8 @@ ## tapcli Updates +## Config Changes + ## Code Health ## Breaking Changes diff --git a/fn/memory.go b/fn/memory.go index 4c56497f3..5fbdb96a4 100644 --- a/fn/memory.go +++ b/fn/memory.go @@ -1,6 +1,10 @@ package fn -import "errors" +import ( + "errors" + "reflect" + "unsafe" +) var ( // ErrNilPointerDeference is returned when a nil pointer is @@ -8,6 +12,14 @@ var ( ErrNilPointerDeference = errors.New("nil pointer dereference") ) +var ( + // sliceHeaderSize is the size of a slice header. + sliceHeaderSize = uint64(unsafe.Sizeof([]byte(nil))) + + // stringHeaderSize is the size of a string header. + stringHeaderSize = uint64(unsafe.Sizeof("")) +) + // Ptr returns the pointer of the given value. This is useful in instances // where a function returns the value, but a pointer is wanted. Without this, // then an intermediate variable is needed. @@ -68,3 +80,146 @@ func DerefPanic[T any](ptr *T) T { return *ptr } + +// LowerBoundByteSize returns a conservative deep-size estimate in bytes. +// +// Notes: +// - Pointer-recursive and cycle safe; each heap allocation is counted once +// using its data pointer. +// - Lower bound: ignores allocator overhead, GC metadata, unused slice +// capacity, map buckets/overflow, evacuation, rounding, and runtime +// internals (chan/func). +func LowerBoundByteSize(x any) uint64 { + // seen is a map of heap object identities which have already been + // counted. + seen := make(map[uintptr]struct{}) + return byteSizeVisit(reflect.ValueOf(x), true, seen) +} + +// byteSizeVisit returns a conservative lower-bound byte count for `subject`. +// +// Notes: +// - addSelf: include subject’s inline bytes when true. Parents pass false. +// - seen: set of heap data pointers to avoid double counting and break +// cycles. +// +// Lower bound: ignores allocator overhead, GC metadata, unused capacity, and +// runtime internals. +func byteSizeVisit(subject reflect.Value, addSelf bool, + seen map[uintptr]struct{}) uint64 { + + if !subject.IsValid() { + return 0 + } + + subjectType := subject.Type() + subjectTypeKind := subjectType.Kind() + + if subjectTypeKind == reflect.Interface { + n := uint64(unsafe.Sizeof(subject.Interface())) + if !subject.IsNil() { + n += byteSizeVisit(subject.Elem(), true, seen) + } + return n + } + + switch subjectTypeKind { + case reflect.Ptr: + if subject.IsNil() { + return 0 + } + + ptr := subject.Pointer() + if markSeen(ptr, seen) { + return 0 + } + + return byteSizeVisit(subject.Elem(), true, seen) + + case reflect.Struct: + n := uint64(0) + if addSelf { + n += uint64(subjectType.Size()) + } + + for i := 0; i < subject.NumField(); i++ { + n += byteSizeVisit(subject.Field(i), false, seen) + } + + return n + + case reflect.Array: + n := uint64(0) + if addSelf { + n += uint64(subjectType.Size()) + } + + for i := 0; i < subject.Len(); i++ { + n += byteSizeVisit(subject.Index(i), false, seen) + } + + return n + + case reflect.Slice: + if subject.IsNil() { + return 0 + } + + n := sliceHeaderSize + dataPtr := subject.Pointer() + if dataPtr != 0 && !markSeen(dataPtr, seen) { + elem := subjectType.Elem() + n += uint64(subject.Len()) * uint64(elem.Size()) + } + + for i := 0; i < subject.Len(); i++ { + n += byteSizeVisit(subject.Index(i), false, seen) + } + + return n + + case reflect.String: + n := stringHeaderSize + dataPtr := subject.Pointer() + if dataPtr != 0 && markSeen(dataPtr, seen) { + return n + } + + return n + uint64(subject.Len()) + + case reflect.Map: + n := uint64(unsafe.Sizeof(subject.Interface())) + if subject.IsNil() { + return n + } + + it := subject.MapRange() + for it.Next() { + n += byteSizeVisit(it.Key(), false, seen) + n += byteSizeVisit(it.Value(), false, seen) + } + + return n + + case reflect.Chan, reflect.Func, reflect.UnsafePointer: + return uint64(unsafe.Sizeof(subject.Interface())) + + default: + if addSelf { + return uint64(subjectType.Size()) + } + + return 0 + } +} + +// markSeen marks the given pointer as seen and returns true if it was already +// seen. +func markSeen(ptr uintptr, seen map[uintptr]struct{}) bool { + if _, ok := seen[ptr]; ok { + return true + } + + seen[ptr] = struct{}{} + return false +} diff --git a/fn/memory_test.go b/fn/memory_test.go new file mode 100644 index 000000000..15e9b9db0 --- /dev/null +++ b/fn/memory_test.go @@ -0,0 +1,131 @@ +package fn + +import ( + "testing" + "unsafe" + + "github.com/stretchr/testify/require" +) + +// TestLowerBoundByteSizeNilAndPrimitives ensures the byte estimator handles nil +// interfaces and primitive concrete values using their inline sizes. +func TestLowerBoundByteSizeNilAndPrimitives(t *testing.T) { + actualNil := LowerBoundByteSize(nil) + require.Zero( + t, actualNil, "nil interface bytes: expected 0, actual %d", + actualNil, + ) + + var num int64 = 99 + expectedInt := uint64(unsafe.Sizeof(num)) + actualInt := LowerBoundByteSize(num) + require.Equal( + t, expectedInt, actualInt, + "int64 bytes mismatch: expected %d, actual %d", + expectedInt, actualInt, + ) + + const str = "taproot-assets" + expectedString := stringHeaderSize + uint64(len(str)) + actualString := LowerBoundByteSize(str) + require.Equal( + t, expectedString, actualString, + "string bytes mismatch: expected %d, actual %d", + expectedString, actualString, + ) +} + +// TestLowerBoundByteSizeStructsAndSlices covers structs that embed slices +// and validates shared backing arrays are only counted once via the seen set. +func TestLowerBoundByteSizeStructsAndSlices(t *testing.T) { + type structWithSlice struct { + Count uint16 + Data []byte + } + + t.Run("structWithSlice", func(t *testing.T) { + payload := []byte{1, 2, 3, 4} + value := structWithSlice{ + Count: 42, + Data: payload, + } + + expected := uint64(unsafe.Sizeof(structWithSlice{})) + expected += sliceHeaderSize + expected += uint64(len(payload)) + actual := LowerBoundByteSize(value) + + require.Equal( + t, expected, actual, + "struct with slice size mismatch: expected %d, "+ + "actual %d", + expected, actual, + ) + }) + + t.Run("sharedBackingArrayCountedOnce", func(t *testing.T) { + payload := []byte{5, 6, 7} + + type twoSlices struct { + Left []byte + Right []byte + } + + value := twoSlices{ + Left: payload, + Right: payload, + } + + expected := uint64(unsafe.Sizeof(twoSlices{})) + expected += 2 * sliceHeaderSize + expected += uint64(len(payload)) + actual := LowerBoundByteSize(value) + + require.Equal( + t, expected, actual, + "shared backing array size mismatch: expected %d, "+ + "actual %d", + expected, actual, + ) + }) +} + +// TestLowerBoundByteSizePointerCycle confirms pointer cycles do not blow up the +// traversal and only count the struct once. +func TestLowerBoundByteSizePointerCycle(t *testing.T) { + type node struct { + Value uint32 + Next *node + } + + root := &node{Value: 1} + root.Next = root + + expected := uint64(unsafe.Sizeof(node{})) + actual := LowerBoundByteSize(root) + require.Equal( + t, expected, actual, + "pointer cycle size mismatch: expected %d, actual %d", + expected, actual, + ) +} + +// TestLowerBoundByteSizeMap verifies map headers and key/value payloads are +// included in the lower bound calculation. +func TestLowerBoundByteSizeMap(t *testing.T) { + payload := []byte{9, 8, 7} + value := map[string][]byte{ + "alpha": payload, + } + + expected := uint64(unsafe.Sizeof(any(value))) + expected += stringHeaderSize + uint64(len("alpha")) + expected += sliceHeaderSize + uint64(len(payload)) + actual := LowerBoundByteSize(value) + + require.Equal( + t, expected, actual, + "map size mismatch: expected %d, actual %d", + expected, actual, + ) +} diff --git a/go.mod b/go.mod index 281cc3057..13fa4a3b9 100644 --- a/go.mod +++ b/go.mod @@ -16,6 +16,7 @@ require ( github.com/caddyserver/certmagic v0.17.2 github.com/davecgh/go-spew v1.1.1 github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 + github.com/dustin/go-humanize v1.0.1 github.com/go-errors/errors v1.0.1 github.com/golang-migrate/migrate/v4 v4.17.0 github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 @@ -28,7 +29,7 @@ require ( github.com/lightninglabs/aperture v0.3.13-beta github.com/lightninglabs/lightning-node-connect/hashmailrpc v1.0.3 github.com/lightninglabs/lndclient v0.20.0-1 - github.com/lightninglabs/neutrino/cache v1.1.2 + github.com/lightninglabs/neutrino/cache v1.1.3 github.com/lightninglabs/taproot-assets/taprpc v1.0.9 github.com/lightningnetwork/lnd v0.19.0-beta.rc5.0.20250925062351-f293566849f2 github.com/lightningnetwork/lnd/cert v1.2.2 @@ -85,7 +86,6 @@ require ( github.com/docker/docker v28.1.1+incompatible // indirect github.com/docker/go-connections v0.5.0 // indirect github.com/docker/go-units v0.5.0 // indirect - github.com/dustin/go-humanize v1.0.1 // indirect github.com/fergusstrange/embedded-postgres v1.25.0 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect diff --git a/go.sum b/go.sum index 67fca15da..998b95db2 100644 --- a/go.sum +++ b/go.sum @@ -1146,8 +1146,8 @@ github.com/lightninglabs/migrate/v4 v4.18.2-9023d66a-fork-pr-2 h1:eFjp1dIB2BhhQp github.com/lightninglabs/migrate/v4 v4.18.2-9023d66a-fork-pr-2/go.mod h1:99BKpIi6ruaaXRM1A77eqZ+FWPQ3cfRa+ZVy5bmWMaY= github.com/lightninglabs/neutrino v0.16.1 h1:5Kz4ToxncEVkpKC6fwUjXKtFKJhuxlG3sBB3MdJTJjs= github.com/lightninglabs/neutrino v0.16.1/go.mod h1:L+5UAccpUdyM7yDgmQySgixf7xmwBgJtOfs/IP26jCs= -github.com/lightninglabs/neutrino/cache v1.1.2 h1:C9DY/DAPaPxbFC+xNNEI/z1SJY9GS3shmlu5hIQ798g= -github.com/lightninglabs/neutrino/cache v1.1.2/go.mod h1:XJNcgdOw1LQnanGjw8Vj44CvguYA25IMKjWFZczwZuo= +github.com/lightninglabs/neutrino/cache v1.1.3 h1:rgnabC41W+XaPuBTQrdeFjFCCAVKh1yctAgmb3Se9zA= +github.com/lightninglabs/neutrino/cache v1.1.3/go.mod h1:qxkJb+pUxR5p84jl5uIGFCR4dGdFkhNUwMSxw3EUWls= github.com/lightninglabs/protobuf-go-hex-display v1.34.2-hex-display h1:w7FM5LH9Z6CpKxl13mS48idsu6F+cEZf0lkyiV+Dq9g= github.com/lightninglabs/protobuf-go-hex-display v1.34.2-hex-display/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= github.com/lightningnetwork/lightning-onion v1.2.1-0.20240815225420-8b40adf04ab9 h1:6D3LrdagJweLLdFm1JNodZsBk6iU4TTsBBFLQ4yiXfI= diff --git a/itest/addrs_test.go b/itest/addrs_test.go index 0a40edf11..d24d5b5f3 100644 --- a/itest/addrs_test.go +++ b/itest/addrs_test.go @@ -881,134 +881,213 @@ func testUnknownTlvType(t *harnessTest) { // testAddrReceives tests the fetching of address events. func testAddrReceives(t *harnessTest) { - // First, mint an asset so we have something to create addresses for. + // First, mint a few assets, so we have some to create addresses for. rpcAssets := MintAssetsConfirmBatch( t.t, t.lndHarness.Miner().Client, t.tapd, []*mintrpc.MintAssetRequest{ - simpleAssets[0], + simpleAssets[0], issuableAssets[0], }, ) - asset := rpcAssets[0] ctxb := context.Background() ctxt, cancel := context.WithTimeout(ctxb, defaultWaitTimeout) defer cancel() - // Create a second node that'll be the receiver. + // We'll make a second node now that'll be the receiver of all the + // assets made above. bobLnd := t.lndHarness.NewNodeWithCoins("Bob", nil) bob := setupTapdHarness(t.t, t, bobLnd, t.universeServer) defer func() { require.NoError(t.t, bob.stop(!*noDelete)) }() - // Create an address and send assets to it. - addr, events := NewAddrWithEventStream( - t.t, bob, &taprpc.NewAddrRequest{ - AssetId: asset.AssetGenesis.AssetId, - Amt: asset.Amount - 1, - AssetVersion: asset.Version, - }, - ) + timeBeforeSend := time.Now() - AssertAddrCreated(t.t, bob, asset, addr) + const numAddresses = 6 + for i := range numAddresses { + // Use different assets for variety. + assetIdx := i % len(rpcAssets) + asset := rpcAssets[assetIdx] - // Record the time before sending. - timeBeforeSend := time.Now() + addr, events := NewAddrWithEventStream( + t.t, bob, &taprpc.NewAddrRequest{ + AssetId: asset.AssetGenesis.AssetId, + Amt: uint64(10), + AssetVersion: asset.Version, + }, + ) - // Send assets to the address. - sendResp, sendEvents := sendAssetsToAddr(t, t.tapd, addr) - require.NotNil(t.t, sendResp) + AssertAddrCreated(t.t, bob, asset, addr) - // Wait for the event to be detected. - AssertAddrEvent(t.t, bob, addr, 1, statusDetected) + // Send assets to the address. + _, sendEvents := sendAssetsToAddr(t, t.tapd, addr) - // Mine a block to confirm the transaction. - MineBlocks(t.t, t.lndHarness.Miner().Client, 1, 1) + AssertAddrEvent(t.t, bob, addr, 1, statusDetected) - // Wait for the event to be confirmed. - AssertAddrEvent(t.t, bob, addr, 1, statusConfirmed) + // Mine a block to make sure the events are marked as confirmed. + MineBlocks(t.t, t.lndHarness.Miner().Client, 1, 1) - // Record the time after sending. - timeAfterSend := time.Now() + // Eventually the event should be marked as confirmed. + AssertAddrEvent(t.t, bob, addr, 1, statusConfirmed) - // Wait for the receive to complete. - AssertNonInteractiveRecvComplete(t.t, bob, 1) - AssertSendEventsComplete(t.t, addr.ScriptKey, sendEvents) - AssertReceiveEvents(t.t, addr, events) + // Make sure we have imported and finalized all proofs. + AssertNonInteractiveRecvComplete(t.t, bob, i+1) + AssertSendEventsComplete(t.t, addr.ScriptKey, sendEvents) - // Test 1: Get all events without timestamp filtering. + // Make sure the receiver has received all events in order for + // the address. + AssertReceiveEvents(t.t, addr, events) + } + + timeAfterSend := time.Now() + + // Test all events. resp, err := bob.AddrReceives( ctxt, &taprpc.AddrReceivesRequest{}, ) require.NoError(t.t, err) - require.Len(t.t, resp.Events, 1) + require.Len(t.t, resp.Events, numAddresses) - // Test 2: Filter by start timestamp before the send - // (should return events). - resp, err = bob.AddrReceives( - ctxt, &taprpc.AddrReceivesRequest{ - StartTimestamp: uint64(timeBeforeSend.Unix()), + // Test limit. + resp, err = bob.AddrReceives(ctxt, &taprpc.AddrReceivesRequest{ + Limit: 3, + }) + require.NoError(t.t, err) + require.Len(t.t, resp.Events, 3) + + // Test offset. + resp, err = bob.AddrReceives(ctxt, &taprpc.AddrReceivesRequest{ + Offset: 2, + Limit: 3, + }) + require.NoError(t.t, err) + require.Len(t.t, resp.Events, 3) + + // Test descending direction (default). + resp, err = bob.AddrReceives(ctxt, &taprpc.AddrReceivesRequest{ + Limit: 5, + }) + require.NoError(t.t, err) + require.Len(t.t, resp.Events, 5) + + // Verify descending order by checking creation times. + for i := 1; i < len(resp.Events); i++ { + require.GreaterOrEqual(t.t, + resp.Events[i-1].CreationTimeUnixSeconds, + resp.Events[i].CreationTimeUnixSeconds, + ) + } + + // Test ascending direction. + resp, err = bob.AddrReceives(ctxt, &taprpc.AddrReceivesRequest{ + Limit: 5, + Direction: taprpc.SortDirection_SORT_DIRECTION_ASC, + }) + require.NoError(t.t, err) + require.Len(t.t, resp.Events, 5) + + // Verify ascending order by checking creation times. + for i := 1; i < len(resp.Events); i++ { + require.LessOrEqual(t.t, + resp.Events[i-1].CreationTimeUnixSeconds, + resp.Events[i].CreationTimeUnixSeconds, + ) + } + + // Test offset out of bounds. + resp, err = bob.AddrReceives(ctxt, + &taprpc.AddrReceivesRequest{ + Offset: 100, + Limit: 10, }, ) require.NoError(t.t, err) - require.Len(t.t, resp.Events, 1) + require.Len(t.t, resp.Events, 0) - // Test 3: Filter by start timestamp exactly at the send time - // (should return the event). - resp, err = bob.AddrReceives( - ctxt, &taprpc.AddrReceivesRequest{ - StartTimestamp: uint64(timeBeforeSend.Unix()), + // Test pagination through all results. + var allPaginatedEvents []*taprpc.AddrEvent + offset := int32(0) + limit := int32(3) + + for { + resp, err := bob.AddrReceives(ctxt, + &taprpc.AddrReceivesRequest{ + Offset: offset, + Limit: limit, + }, + ) + require.NoError(t.t, err) + + if len(resp.Events) == 0 { + break + } + + allPaginatedEvents = append(allPaginatedEvents, resp.Events...) + offset += limit + } + + // Should have collected all events. + require.Len(t.t, allPaginatedEvents, numAddresses) + + // Test negative offset and limit error. + _, err = bob.AddrReceives(ctxt, + &taprpc.AddrReceivesRequest{ + Offset: -5, }, ) - require.NoError(t.t, err) - require.Len(t.t, resp.Events, 1) + require.Error(t.t, err) + require.Contains(t.t, err.Error(), "offset must be non-negative") - // Test 4: Filter by address and start timestamp. + _, err = bob.AddrReceives(ctxt, + &taprpc.AddrReceivesRequest{ + Limit: -5, + }, + ) + require.Error(t.t, err) + require.Contains(t.t, err.Error(), "limit must be non-negative") + + // Test filter by start timestamp before the send + // (should return events). resp, err = bob.AddrReceives( ctxt, &taprpc.AddrReceivesRequest{ - FilterAddr: addr.Encoded, - StartTimestamp: uint64(timeBeforeSend.Unix()), + StartTimestamp: uint64(timeBeforeSend.Unix() - 1), }, ) require.NoError(t.t, err) - require.Len(t.t, resp.Events, 1) - require.Equal( - t.t, addr.Encoded, resp.Events[0].Addr.Encoded, - ) + require.Len(t.t, resp.Events, numAddresses) - // Test 5: Filter by address and start timestamp after send - // (should return no events). + // Test filter by start timestamp exactly at the send time + // (should return all events). resp, err = bob.AddrReceives( ctxt, &taprpc.AddrReceivesRequest{ - FilterAddr: addr.Encoded, - StartTimestamp: uint64(timeAfterSend.Unix() + 1), + StartTimestamp: uint64(timeBeforeSend.Unix()), }, ) require.NoError(t.t, err) - require.Len(t.t, resp.Events, 0) + require.Len(t.t, resp.Events, numAddresses) - // Test 6: Filter by end timestamp before the send + // Test filter by end timestamp before the send // (should return no events). resp, err = bob.AddrReceives( ctxt, &taprpc.AddrReceivesRequest{ - EndTimestamp: uint64(timeBeforeSend.Unix()), + EndTimestamp: uint64(timeBeforeSend.Unix() - 1), }, ) require.NoError(t.t, err) require.Len(t.t, resp.Events, 0) - // Test 7: Filter by end timestamp after the send - // (should return the event). + // Test filter by end timestamp after the send + // (should return all events). resp, err = bob.AddrReceives( ctxt, &taprpc.AddrReceivesRequest{ EndTimestamp: uint64(timeAfterSend.Unix() + 1), }, ) require.NoError(t.t, err) - require.Len(t.t, resp.Events, 1) + require.Len(t.t, resp.Events, numAddresses) - // Test 8: Filter by both start and end timestamp - // (should return the event). + // Test filter by both start and end timestamp + // (should return all events). resp, err = bob.AddrReceives( ctxt, &taprpc.AddrReceivesRequest{ StartTimestamp: uint64(timeBeforeSend.Unix()), @@ -1016,7 +1095,7 @@ func testAddrReceives(t *harnessTest) { }, ) require.NoError(t.t, err) - require.Len(t.t, resp.Events, 1) + require.Len(t.t, resp.Events, numAddresses) } // sendProof manually exports a proof from the given source node and imports it diff --git a/itest/burn_test.go b/itest/burn_test.go index e983451d7..5d96f33a4 100644 --- a/itest/burn_test.go +++ b/itest/burn_test.go @@ -120,8 +120,8 @@ func testBurnAssets(t *harnessTest) { ) burnResp, err := t.tapd.BurnAsset(ctxt, &taprpc.BurnAssetRequest{ - Asset: &taprpc.BurnAssetRequest_AssetId{ - AssetId: simpleAssetID[:], + AssetSpecifier: &taprpc.AssetSpecifier{ + Id: simpleAssetID[:], }, AmountToBurn: burnAmt, Note: burnNote, @@ -129,10 +129,6 @@ func testBurnAssets(t *harnessTest) { }) require.NoError(t.t, err) - burnRespJSON, err := formatProtoJSON(burnResp) - require.NoError(t.t, err) - t.Logf("Got response from burning %d units: %v", burnAmt, burnRespJSON) - AssertAssetOutboundTransferWithOutputs( t.t, minerClient, t.tapd, burnResp.BurnTransfer, [][]byte{simpleAssetGen.AssetId}, @@ -140,7 +136,7 @@ func testBurnAssets(t *harnessTest) { ) // We'll now assert that the burned asset has the correct state. - burnedAsset := burnResp.BurnProof.Asset + burnedAsset := burnResp.BurnProofs[0].Asset allAssets, err := t.tapd.ListAssets(ctxt, &taprpc.ListAssetRequest{ IncludeSpent: true, ScriptKeyType: allScriptKeysQuery, @@ -196,18 +192,14 @@ func testBurnAssets(t *harnessTest) { // collectible from the original mint TX), while there are other, // passive assets in the anchor output. burnResp, err = t.tapd.BurnAsset(ctxt, &taprpc.BurnAssetRequest{ - Asset: &taprpc.BurnAssetRequest_AssetId{ - AssetId: simpleCollectibleGen.AssetId, + AssetSpecifier: &taprpc.AssetSpecifier{ + Id: simpleCollectibleGen.AssetId, }, AmountToBurn: simpleCollectible.Amount, ConfirmationText: taprootassets.AssetBurnConfirmationText, }) require.NoError(t.t, err) - burnRespJSON, err = formatProtoJSON(burnResp) - require.NoError(t.t, err) - t.Logf("Got response from burning all units: %v", burnRespJSON) - AssertAssetOutboundTransferWithOutputs( t.t, minerClient, t.tapd, burnResp.BurnTransfer, [][]byte{simpleCollectibleGen.AssetId}, []uint64{1}, 3, 4, 1, @@ -227,19 +219,14 @@ func testBurnAssets(t *harnessTest) { const changeAmt = 300 multiBurnAmt := outputAmounts[2] + secondSendAmt - changeAmt burnResp, err = t.tapd.BurnAsset(ctxt, &taprpc.BurnAssetRequest{ - Asset: &taprpc.BurnAssetRequest_AssetId{ - AssetId: simpleAssetGen.AssetId, + AssetSpecifier: &taprpc.AssetSpecifier{ + Id: simpleAssetGen.AssetId, }, AmountToBurn: multiBurnAmt, ConfirmationText: taprootassets.AssetBurnConfirmationText, }) require.NoError(t.t, err) - burnRespJSON, err = formatProtoJSON(burnResp) - require.NoError(t.t, err) - t.Logf("Got response from burning units from multiple inputs: %v", - burnRespJSON) - AssertAssetOutboundTransferWithOutputs( t.t, minerClient, t.tapd, burnResp.BurnTransfer, [][]byte{simpleAssetGen.AssetId}, @@ -259,13 +246,10 @@ func testBurnAssets(t *harnessTest) { WithScriptKeyType(asset.ScriptKeyBurn), ) - resp, err := t.tapd.ListAssets(ctxt, &taprpc.ListAssetRequest{ + _, err = t.tapd.ListAssets(ctxt, &taprpc.ListAssetRequest{ IncludeSpent: true, }) require.NoError(t.t, err) - assets, err := formatProtoJSON(resp) - require.NoError(t.t, err) - t.Logf("All assets before last burn: %v", assets) // Test case 4: Burn some units of a grouped asset. We start by making // sure we still have the full balance before burning. @@ -273,19 +257,14 @@ func testBurnAssets(t *harnessTest) { t.t, t.tapd, simpleGroupGen.AssetId, simpleGroup.Amount, ) burnResp, err = t.tapd.BurnAsset(ctxt, &taprpc.BurnAssetRequest{ - Asset: &taprpc.BurnAssetRequest_AssetId{ - AssetId: simpleGroupGen.AssetId, + AssetSpecifier: &taprpc.AssetSpecifier{ + Id: simpleGroupGen.AssetId, }, AmountToBurn: burnAmt, ConfirmationText: taprootassets.AssetBurnConfirmationText, }) require.NoError(t.t, err) - burnRespJSON, err = formatProtoJSON(burnResp) - require.NoError(t.t, err) - t.Logf("Got response from burning units from grouped asset: %v", - burnRespJSON) - AssertAssetOutboundTransferWithOutputs( t.t, minerClient, t.tapd, burnResp.BurnTransfer, [][]byte{simpleGroupGen.AssetId}, @@ -295,10 +274,12 @@ func testBurnAssets(t *harnessTest) { t.t, t.tapd, simpleGroupGen.AssetId, simpleGroup.Amount-burnAmt, ) + // Depending on passive re-anchoring behavior, earlier burn outputs + // might become spent when inputs are consolidated. We assert only + // currently unspent burn outputs here. AssertBalances( t.t, t.tapd, - burnAmt+simpleCollectible.Amount+multiBurnAmt+burnAmt, - WithNumUtxos(4), WithNumAnchorUtxos(4), + burnAmt+multiBurnAmt+burnAmt, WithScriptKeyType(asset.ScriptKeyBurn), ) @@ -335,19 +316,14 @@ func testBurnAssets(t *harnessTest) { simpleGroupCollect.Amount, ) burnResp, err = t.tapd.BurnAsset(ctxt, &taprpc.BurnAssetRequest{ - Asset: &taprpc.BurnAssetRequest_AssetId{ - AssetId: simpleGroupCollectGen.AssetId, + AssetSpecifier: &taprpc.AssetSpecifier{ + Id: simpleGroupCollectGen.AssetId, }, AmountToBurn: 1, ConfirmationText: taprootassets.AssetBurnConfirmationText, }) require.NoError(t.t, err) - burnRespJSON, err = formatProtoJSON(burnResp) - require.NoError(t.t, err) - t.Logf("Got response from burning units from grouped asset: %v", - burnRespJSON) - AssertAssetOutboundTransferWithOutputs( t.t, minerClient, t.tapd, burnResp.BurnTransfer, [][]byte{simpleGroupCollectGen.AssetId}, []uint64{1}, 6, 7, 1, @@ -357,8 +333,7 @@ func testBurnAssets(t *harnessTest) { AssertBalances( t.t, t.tapd, - burnAmt+simpleCollectible.Amount+multiBurnAmt+burnAmt+1, - WithNumUtxos(5), WithNumAnchorUtxos(5), + burnAmt+multiBurnAmt+burnAmt+1, WithScriptKeyType(asset.ScriptKeyBurn), ) @@ -406,6 +381,7 @@ func testBurnGroupedAssets(t *harnessTest) { var ( firstMintResp = firstMintResponses[0] + burnAssetID1 = firstMintResp.AssetGenesis.AssetId assetGroupKey = firstMintResp.AssetGroup.TweakedGroupKey ) @@ -440,9 +416,12 @@ func testBurnGroupedAssets(t *harnessTest) { assetGroup := assetGroups.Groups[encodedGroupKey] require.Len(t.t, assetGroup.Assets, 2) - // Burn some amount of the second asset. + totalAmt := firstMintResp.Amount + secondMintResp.Amount + AssertBalanceByGroup(t.t, t.tapd, encodedGroupKey, totalAmt) + + // Test case 1: Burn by asset id. var ( - burnAssetID = secondMintResp.AssetGenesis.AssetId + burnAssetID2 = secondMintResp.AssetGenesis.AssetId preBurnAmt = secondMintResp.Amount burnAmt = uint64(10) @@ -450,8 +429,8 @@ func testBurnGroupedAssets(t *harnessTest) { ) burnResp, err := t.tapd.BurnAsset(ctxb, &taprpc.BurnAssetRequest{ - Asset: &taprpc.BurnAssetRequest_AssetId{ - AssetId: burnAssetID, + AssetSpecifier: &taprpc.AssetSpecifier{ + Id: burnAssetID2, }, AmountToBurn: burnAmt, Note: burnNote, @@ -459,19 +438,15 @@ func testBurnGroupedAssets(t *harnessTest) { }) require.NoError(t.t, err) - burnRespJSON, err := formatProtoJSON(burnResp) - require.NoError(t.t, err) - t.Logf("Got response from burning %d units: %v", burnAmt, burnRespJSON) - // Assert that the asset burn transfer occurred correctly. AssertAssetOutboundTransferWithOutputs( t.t, miner, t.tapd, burnResp.BurnTransfer, - [][]byte{burnAssetID}, []uint64{postBurnAmt, burnAmt}, 0, 1, 2, + [][]byte{burnAssetID2}, []uint64{postBurnAmt, burnAmt}, 0, 1, 2, true, ) // Ensure that the burnt asset has the correct state. - burnedAsset := burnResp.BurnProof.Asset + burnedAsset := burnResp.BurnProofs[0].Asset allAssets, err := t.tapd.ListAssets(ctxb, &taprpc.ListAssetRequest{ IncludeSpent: true, ScriptKeyType: allScriptKeysQuery, @@ -486,7 +461,7 @@ func testBurnGroupedAssets(t *harnessTest) { ) // Our asset balance should have been decreased by the burned amount. - AssertBalanceByID(t.t, t.tapd, burnAssetID, postBurnAmt) + AssertBalanceByID(t.t, t.tapd, burnAssetID2, postBurnAmt) // Confirm that the minted asset group still contains two assets. assetGroups, err = t.tapd.ListGroups(ctxb, &taprpc.ListGroupsRequest{}) @@ -507,6 +482,40 @@ func testBurnGroupedAssets(t *harnessTest) { require.Equal(t.t, burnAmt, burn.Amount) require.Equal(t.t, burnNote, burn.Note) require.Equal(t.t, assetGroupKey, burn.TweakedGroupKey) + + // Test case 2: Burn by group key to we select multiple inputs. + // We burn the full amount. + burnResp, err = t.tapd.BurnAsset(ctxb, &taprpc.BurnAssetRequest{ + AssetSpecifier: &taprpc.AssetSpecifier{ + GroupKey: assetGroupKey, + }, + AmountToBurn: totalAmt - burnAmt, + ConfirmationText: taprootassets.AssetBurnConfirmationText, + }) + require.NoError(t.t, err) + + // When burning by group key with multiple inputs, + // the coin selection can vary. We verify that: + // - There are 2 outputs total + // - We burn all remaining balance. + amounts := make([]uint64, len(burnResp.BurnTransfer.Outputs)) + for i, out := range burnResp.BurnTransfer.Outputs { + amounts[i] = out.Amount + } + require.Len(t.t, amounts, 2) + + actualSum := uint64(0) + for _, amt := range amounts { + actualSum += amt + } + require.Equal(t.t, totalAmt-burnAmt, actualSum) + + AssertAssetOutboundTransferWithOutputs( + t.t, miner, t.tapd, burnResp.BurnTransfer, + [][]byte{burnAssetID1, burnAssetID2}, + amounts, 1, 2, 2, true, + ) + AssertBalanceByGroup(t.t, t.tapd, encodedGroupKey, 0) } // testFullBurnUTXO tests that we can burn the full amount of an asset UTXO. @@ -534,8 +543,8 @@ func testFullBurnUTXO(t *harnessTest) { // Perform a full burn of the asset. fullBurnAmt := simpleAsset.Amount burnResp, err := t.tapd.BurnAsset(ctxt, &taprpc.BurnAssetRequest{ - Asset: &taprpc.BurnAssetRequest_AssetId{ - AssetId: simpleAssetID[:], + AssetSpecifier: &taprpc.AssetSpecifier{ + Id: simpleAssetID[:], }, AmountToBurn: fullBurnAmt, ConfirmationText: taprootassets.AssetBurnConfirmationText, @@ -558,8 +567,8 @@ func testFullBurnUTXO(t *harnessTest) { proofResp := ExportProofFile( t.t, t.tapd, - burnResp.BurnProof.Asset.AssetGenesis.AssetId, - burnResp.BurnProof.Asset.ScriptKey, + burnResp.BurnProofs[0].Asset.AssetGenesis.AssetId, + burnResp.BurnProofs[0].Asset.ScriptKey, outpoint, ) verifyResp, err := t.tapd.VerifyProof(ctxt, &taprpc.ProofFile{ @@ -586,8 +595,8 @@ func testFullBurnUTXO(t *harnessTest) { fullBurnAmt = collectibleAsset.Amount burnResp, err = t.tapd.BurnAsset(ctxt, &taprpc.BurnAssetRequest{ - Asset: &taprpc.BurnAssetRequest_AssetId{ - AssetId: collectibleAssetID[:], + AssetSpecifier: &taprpc.AssetSpecifier{ + Id: collectibleAssetID[:], }, AmountToBurn: fullBurnAmt, ConfirmationText: taprootassets.AssetBurnConfirmationText, @@ -610,8 +619,8 @@ func testFullBurnUTXO(t *harnessTest) { proofResp = ExportProofFile( t.t, t.tapd, - burnResp.BurnProof.Asset.AssetGenesis.AssetId, - burnResp.BurnProof.Asset.ScriptKey, + burnResp.BurnProofs[0].Asset.AssetGenesis.AssetId, + burnResp.BurnProofs[0].Asset.ScriptKey, outpoint, ) verifyResp, err = t.tapd.VerifyProof(ctxt, &taprpc.ProofFile{ diff --git a/itest/rfq_test.go b/itest/rfq_test.go index ff7ecc3eb..e13c17aca 100644 --- a/itest/rfq_test.go +++ b/itest/rfq_test.go @@ -689,7 +689,7 @@ func testRfqNegotiationGroupKey(t *harnessTest) { require.True(t.t, ok, "unexpected event: %v", event) quote := e.PeerAcceptedSellQuote.PeerAcceptedSellQuote - actualGroupKeyBytes := quote.AssetSpec.GroupPubKey + actualGroupKeyBytes := quote.AssetSpec.GetGroupKey() expectedGroupKeyBytes := schnorr.SerializePubKey(groupKey) require.Equal(t.t, expectedGroupKeyBytes, actualGroupKeyBytes) }, rfqTimeout) @@ -730,7 +730,7 @@ func testRfqNegotiationGroupKey(t *harnessTest) { require.True(t.t, ok, "unexpected event: %v", event) quote := e.PeerAcceptedBuyQuote.PeerAcceptedBuyQuote - actualGroupKeyBytes := quote.AssetSpec.GroupPubKey + actualGroupKeyBytes := quote.AssetSpec.GetGroupKey() expectedGroupKeyBytes := schnorr.SerializePubKey(groupKey) require.Equal(t.t, expectedGroupKeyBytes, actualGroupKeyBytes) }, rfqTimeout) diff --git a/itest/supply_commit_test.go b/itest/supply_commit_test.go index ff8b4cf19..7e4af90eb 100644 --- a/itest/supply_commit_test.go +++ b/itest/supply_commit_test.go @@ -900,8 +900,8 @@ func testSupplyCommitMintBurn(t *harnessTest) { ) burnResp, err := t.tapd.BurnAsset(ctxb, &taprpc.BurnAssetRequest{ - Asset: &taprpc.BurnAssetRequest_AssetId{ - AssetId: rpcFirstAsset.AssetGenesis.AssetId, + AssetSpecifier: &taprpc.AssetSpecifier{ + Id: rpcFirstAsset.AssetGenesis.AssetId, }, AmountToBurn: burnAmt, Note: burnNote, diff --git a/lndservices/block_header_cache.go b/lndservices/block_header_cache.go new file mode 100644 index 000000000..0e056318c --- /dev/null +++ b/lndservices/block_header_cache.go @@ -0,0 +1,322 @@ +package lndservices + +import ( + "fmt" + "sync" + + "github.com/btcsuite/btcd/chaincfg/chainhash" + "github.com/btcsuite/btcd/wire" +) + +const ( + // DefaultHeaderCacheSize is the default maximum number of block + // headers to cache. + DefaultHeaderCacheSize = 100_000 + + // DefaultPurgePercentage is the default percentage of entries to purge + // when the cache reaches capacity (from 1 to 100). + DefaultPurgePercentage = 10 + + // DefaultMinSettledBlockDepth is the default minimum block depth + // required before a block header is considered settled. + DefaultMinSettledBlockDepth = 6 +) + +// BlockHeaderCacheConfig holds configuration parameters for the block header +// cache. +type BlockHeaderCacheConfig struct { + // MaxSize is the maximum number of block headers to cache. + MaxSize uint32 + + // PurgePercentage is the percentage of entries to purge when the cache + // reaches capacity (from 1 to 100, inclusive). + PurgePercentage uint32 + + // MinSettledBlockDepth is the minimum block depth required before a + // block header is considered settled. + MinSettledBlockDepth uint32 +} + +// DefaultBlockHeaderCacheConfig returns a BlockHeaderCacheConfig with default +// values. +func DefaultBlockHeaderCacheConfig() BlockHeaderCacheConfig { + return BlockHeaderCacheConfig{ + MaxSize: DefaultHeaderCacheSize, + PurgePercentage: DefaultPurgePercentage, + MinSettledBlockDepth: DefaultMinSettledBlockDepth, + } +} + +// Validate checks that the configuration parameters are valid. +func (c *BlockHeaderCacheConfig) Validate() error { + if c.PurgePercentage == 0 || c.PurgePercentage > 100 { + return fmt.Errorf("invalid PurgePercentage: %d, must "+ + "be > 0 and <= 100", c.PurgePercentage) + } + + return nil +} + +// headerEntry represents a cached block header with metadata. +type headerEntry struct { + // header is the cached block header. + header wire.BlockHeader + + // hash is the cached block hash. + hash chainhash.Hash + + // height is the block height of this header. + height uint32 +} + +// BlockHeaderCache is a reorg-aware cache of block headers. +// +// TODO(ffranr): Once this component is stable, consider moving btcd repo. +type BlockHeaderCache struct { + // cfg is the cache configuration. + cfg BlockHeaderCacheConfig + + // mu protects concurrent access to the cache. + mu sync.RWMutex + + // byHeight maps block height to header entry. + byHeight map[uint32]*headerEntry + + // byHash maps block hash to header entry. + byHash map[chainhash.Hash]*headerEntry + + // maxHeight tracks the highest block height we've seen. + maxHeight uint32 +} + +// NewBlockHeaderCache creates a new block header cache with the given +// configuration. +func NewBlockHeaderCache(cfg BlockHeaderCacheConfig) (*BlockHeaderCache, + error) { + + if err := cfg.Validate(); err != nil { + return nil, err + } + + return &BlockHeaderCache{ + cfg: cfg, + byHeight: make(map[uint32]*headerEntry), + byHash: make(map[chainhash.Hash]*headerEntry), + }, nil +} + +// isSettled returns whether an entry is considered settled based on +// block depth. +func (c *BlockHeaderCache) isSettled(height uint32) bool { + settledHeight := height + c.cfg.MinSettledBlockDepth + + // If the maximum height among all seen block headers meets or exceeds + // the settled height, this entry is considered settled. + return settledHeight <= c.maxHeight +} + +// Put adds a block header to the cache at the given height. +// +// If the insertion exceeded capacity, entries are purged first. If a +// conflicting header exists at this height, a reorg is detected and all headers +// at or above this height are invalidated. +func (c *BlockHeaderCache) Put(height uint32, header wire.BlockHeader) error { + c.mu.Lock() + defer c.mu.Unlock() + + hash := header.BlockHash() + + // Check if there's already an entry at this height. + if existing, exists := c.byHeight[height]; exists { + existingHash := existing.hash + + // If the hashes match, this is a duplicate insertion. + if existingHash == hash { + return nil + } + + // The hashes do not match, indicating a reorg. Invalidate + // all known headers at or above this height. + c.invalidateFromHeight(height) + } + + // Check capacity and purge if needed. + if uint32(len(c.byHeight)) >= c.cfg.MaxSize { + c.purge() + } + + // Create the new entry and store in the cache. + entry := &headerEntry{ + header: header, + hash: hash, + height: height, + } + + c.byHeight[height] = entry + c.byHash[hash] = entry + + // Update max height seen. + if height > c.maxHeight { + c.maxHeight = height + } + + return nil +} + +// GetByHeight retrieves a block header by height. Returns ok=false if not found +// or if the entry is unsettled (to force external lookup). +func (c *BlockHeaderCache) GetByHeight(height uint32) (wire.BlockHeader, bool) { + c.mu.RLock() + defer c.mu.RUnlock() + + var zero wire.BlockHeader + + entry, exists := c.byHeight[height] + if !exists || !c.isSettled(height) { + return zero, false + } + + return entry.header, true +} + +// GetByHash retrieves a block header by hash. Returns ok=false if not found or +// if the entry is unsettled (to force external lookup). +func (c *BlockHeaderCache) GetByHash(hash chainhash.Hash) (wire.BlockHeader, + bool) { + + c.mu.RLock() + defer c.mu.RUnlock() + + var zero wire.BlockHeader + + entry, exists := c.byHash[hash] + if !exists || !c.isSettled(entry.height) { + return zero, false + } + + return entry.header, true +} + +// invalidateFromHeight removes all entries at or above the given height, +// effectively invalidating the orphaned chain. +func (c *BlockHeaderCache) invalidateFromHeight(heightLowerBound uint32) { + // Track new max height after entries are removed. + var newMaxHeight uint32 + + // Iterate over all entries and remove those at or above the lower + // bound. + for height, entry := range c.byHeight { + // Skip entries below the lower bound. + if height < heightLowerBound { + // Update new max height if needed. + if height > newMaxHeight { + newMaxHeight = height + } + + continue + } + + // Remove the entry which is at or above the lower bound. + hash := entry.hash + delete(c.byHeight, height) + delete(c.byHash, hash) + } + + c.maxHeight = newMaxHeight +} + +// purge removes a random set of entries from the cache at the configured +// purge percentage. +func (c *BlockHeaderCache) purge() { + numToPurge := len(c.byHeight) * int(c.cfg.PurgePercentage) / 100 + if numToPurge == 0 { + numToPurge = 1 + } + + // Remove entries directly from the map iteration (already random + // order). + maxHeightDeleted := false + count := 0 + for height, entry := range c.byHeight { + if count >= numToPurge { + break + } + + if height == c.maxHeight { + maxHeightDeleted = true + } + + hash := entry.hash + delete(c.byHeight, height) + delete(c.byHash, hash) + count++ + } + + if !maxHeightDeleted { + return + } + + // Recalculate max height only if it was deleted. + c.maxHeight = 0 + for height := range c.byHeight { + if height > c.maxHeight { + c.maxHeight = height + } + } +} + +// Size returns the current number of entries in the cache. +func (c *BlockHeaderCache) Size() int { + c.mu.RLock() + defer c.mu.RUnlock() + + return len(c.byHeight) +} + +// Clear removes all entries from the cache. +func (c *BlockHeaderCache) Clear() { + c.mu.Lock() + defer c.mu.Unlock() + + c.byHeight = make(map[uint32]*headerEntry) + c.byHash = make(map[chainhash.Hash]*headerEntry) + c.maxHeight = 0 +} + +// Stats returns statistics about the cache. +func (c *BlockHeaderCache) Stats() CacheStats { + c.mu.RLock() + defer c.mu.RUnlock() + + settled := 0 + for height := range c.byHeight { + if c.isSettled(height) { + settled++ + } + } + + return CacheStats{ + TotalEntries: len(c.byHeight), + SettledEntries: settled, + MaxHeight: c.maxHeight, + } +} + +// CacheStats holds statistics about the block header cache. +type CacheStats struct { + // TotalEntries is the total number of entries in the cache. + TotalEntries int + + // SettledEntries is the number of settled entries in the cache. + SettledEntries int + + // MaxHeight is the highest block height seen. + MaxHeight uint32 +} + +// String returns a string representation of the cache stats. +func (s CacheStats) String() string { + return fmt.Sprintf("BlockHeaderCacheStats(total=%d, settled=%d, "+ + "max_height=%d)", s.TotalEntries, s.SettledEntries, + s.MaxHeight) +} diff --git a/lndservices/block_header_cache_test.go b/lndservices/block_header_cache_test.go new file mode 100644 index 000000000..3960f1973 --- /dev/null +++ b/lndservices/block_header_cache_test.go @@ -0,0 +1,457 @@ +package lndservices + +import ( + "testing" + "time" + + "github.com/btcsuite/btcd/chaincfg/chainhash" + "github.com/btcsuite/btcd/wire" + "github.com/stretchr/testify/require" +) + +// makeHeader creates a test block header with a unique hash based on the +// provided nonce. +func makeHeader(nonce uint32, timestamp time.Time) wire.BlockHeader { + return wire.BlockHeader{ + Version: 1, + PrevBlock: chainhash.Hash{}, + MerkleRoot: chainhash.Hash{ + byte(nonce), byte(nonce >> 8), byte(nonce >> 16), + byte(nonce >> 24), + }, + Timestamp: timestamp, + Bits: 0x1d00ffff, + Nonce: nonce, + } +} + +// makeConsecutiveHeaders creates a set of consecutive block headers where each +// header's PrevBlock points to the previous header's hash. +func makeConsecutiveHeaders(startHeight uint32, count int, + baseTime time.Time) []wire.BlockHeader { + + headers := make([]wire.BlockHeader, count) + var prevHash chainhash.Hash + + for i := 0; i < count; i++ { + timestamp := baseTime.Add(time.Duration(i) * 10 * time.Minute) + header := wire.BlockHeader{ + Version: 1, + PrevBlock: prevHash, + MerkleRoot: chainhash.Hash{byte(i)}, + Timestamp: timestamp, + Bits: 0x1d00ffff, + Nonce: startHeight + uint32(i), + } + headers[i] = header + prevHash = header.BlockHash() + } + + return headers +} + +// TestBlockHeaderCacheBasicPutGet tests basic put and get operations by +// height and hash. +func TestBlockHeaderCacheBasicPutGet(t *testing.T) { + t.Parallel() + + cfg := BlockHeaderCacheConfig{ + MaxSize: 100, + PurgePercentage: 10, + MinSettledBlockDepth: 6, + } + cache, err := NewBlockHeaderCache(cfg) + require.NoError(t, err) + + now := time.Now().UTC() + header1 := makeHeader(1, now) + header2 := makeHeader(2, now.Add(10*time.Minute)) + + // Put headers at height 100 and 106 (so 100 becomes settled). + err = cache.Put(100, header1) + require.NoError(t, err) + + err = cache.Put(106, header2) + require.NoError(t, err) + + // Height 100 should now be settled (106 - 100 >= 6). + retrieved, ok := cache.GetByHeight(100) + require.True(t, ok) + require.Equal(t, header1.BlockHash(), retrieved.BlockHash()) + + // Get by hash should also work. + hash1 := header1.BlockHash() + retrievedByHash, ok := cache.GetByHash(hash1) + require.True(t, ok) + require.Equal(t, header1.BlockHash(), retrievedByHash.BlockHash()) + + // Height 106 should not be settled yet (no blocks after it). + retrieved, ok = cache.GetByHeight(106) + require.False(t, ok, "unsettled block should return false") + + // Now add a block at height 112 to settle height 106. + header3 := makeHeader(3, now.Add(20*time.Minute)) + err = cache.Put(112, header3) + require.NoError(t, err) + + // Now height 106 should be settled. + retrieved, ok = cache.GetByHeight(106) + require.True(t, ok) + require.Equal(t, header2.BlockHash(), retrieved.BlockHash()) +} + +// TestBlockHeaderCacheCapacity tests that the cache purges entries when it +// reaches capacity. +func TestBlockHeaderCacheCapacity(t *testing.T) { + t.Parallel() + + cfg := BlockHeaderCacheConfig{ + MaxSize: 10, + PurgePercentage: 30, + MinSettledBlockDepth: 1, + } + cache, err := NewBlockHeaderCache(cfg) + require.NoError(t, err) + + now := time.Now().UTC() + + // Fill the cache to capacity. + for i := uint32(0); i < 10; i++ { + header := makeHeader(i, now.Add(time.Duration(i)*time.Minute)) + err := cache.Put(i, header) + require.NoError(t, err) + } + + require.Equal(t, 10, cache.Size()) + + // Add one more entry, which should trigger a purge. + header := makeHeader(100, now.Add(100*time.Minute)) + err = cache.Put(100, header) + require.NoError(t, err) + + // Cache should have purged ~3 entries (30% of 10), then added 1. + // So we should have around 8 entries. + size := cache.Size() + require.LessOrEqual(t, size, 10, "cache should not exceed max size") + require.GreaterOrEqual(t, size, 7, "cache should have purged entries") +} + +// TestBlockHeaderCacheUnsettledVsSettled tests the unsettled vs settled +// semantics with confirmation depth. +func TestBlockHeaderCacheUnsettledVsSettled(t *testing.T) { + t.Parallel() + + cfg := BlockHeaderCacheConfig{ + MaxSize: 100, + PurgePercentage: 10, + MinSettledBlockDepth: 6, + } + cache, err := NewBlockHeaderCache(cfg) + require.NoError(t, err) + + now := time.Now().UTC() + headers := makeConsecutiveHeaders(100, 20, now) + + // Add headers 100-119. + for i, header := range headers { + err := cache.Put(uint32(100+i), header) + require.NoError(t, err) + } + + // Headers 100-113 should be settled (119 - 6 = 113). + for i := uint32(100); i <= 113; i++ { + _, ok := cache.GetByHeight(i) + require.True(t, ok, "height %d should be settled", i) + } + + // Headers 114-119 should be unsettled. + for i := uint32(114); i <= 119; i++ { + _, ok := cache.GetByHeight(i) + require.False(t, ok, "height %d should be unsettled", i) + } + + // Check stats. + stats := cache.Stats() + require.Equal(t, 20, stats.TotalEntries) + require.Equal(t, 14, stats.SettledEntries) // 100-113 + require.Equal(t, uint32(119), stats.MaxHeight) +} + +// TestBlockHeaderCacheReorg tests reorg detection and orphaned branch +// invalidation. +func TestBlockHeaderCacheReorg(t *testing.T) { + t.Parallel() + + cfg := BlockHeaderCacheConfig{ + MaxSize: 100, + PurgePercentage: 10, + MinSettledBlockDepth: 6, + } + cache, err := NewBlockHeaderCache(cfg) + require.NoError(t, err) + + now := time.Now().UTC() + + // Create initial chain: headers at heights 100-110. + originalChain := makeConsecutiveHeaders(100, 11, now) + for i, header := range originalChain { + err := cache.Put(uint32(100+i), header) + require.NoError(t, err) + } + + // Verify heights 100-104 are settled (110 - 6 = 104). + for i := uint32(100); i <= 104; i++ { + _, ok := cache.GetByHeight(i) + require.True(t, ok, "height %d should be settled", i) + } + + // Verify we have 11 entries. + require.Equal(t, 11, cache.Size()) + + // Simulate a reorg at height 105 by inserting a different header. + reorgHeader := makeHeader(9999, now.Add(50*time.Minute)) + err = cache.Put(105, reorgHeader) + require.NoError(t, err) + + // Heights 105-110 should have been invalidated. + // Only heights 100-104 should remain (5 entries) plus the new 105. + require.Equal(t, 6, cache.Size()) + + // Heights 100-104 should be unsettled as the new highest block height + // is 105 (which is not enough to settle them). + for i := uint32(100); i <= 104; i++ { + _, ok := cache.GetByHeight(i) + require.False(t, ok, "height %d should not be settled", i) + } + + // The new header at 105 should be unsettled (no blocks after it). + _, ok := cache.GetByHeight(105) + require.False(t, ok, "new height 105 should be unsettled") + + // Old headers at 106-110 should be gone. + for i := uint32(106); i <= 110; i++ { + _, ok := cache.GetByHeight(i) + require.False(t, ok, "height %d should be invalidated", i) + } + + // Verify the hash at 105 is the new one. + cache.mu.RLock() + entry := cache.byHeight[105] + cache.mu.RUnlock() + require.NotNil(t, entry) + require.Equal(t, reorgHeader.BlockHash(), entry.header.BlockHash()) +} + +// TestBlockHeaderCacheDuplicateInsert tests that inserting the same header +// twice doesn't cause issues. +func TestBlockHeaderCacheDuplicateInsert(t *testing.T) { + t.Parallel() + + cfg := DefaultBlockHeaderCacheConfig() + cache, err := NewBlockHeaderCache(cfg) + require.NoError(t, err) + + now := time.Now().UTC() + header := makeHeader(42, now) + + err = cache.Put(100, header) + require.NoError(t, err) + + // Insert again at same height with same header. + err = cache.Put(100, header) + require.NoError(t, err) + + // Should still have just 1 entry. + require.Equal(t, 1, cache.Size()) +} + +// TestBlockHeaderCacheClear tests the Clear method. +func TestBlockHeaderCacheClear(t *testing.T) { + t.Parallel() + + cfg := DefaultBlockHeaderCacheConfig() + cache, err := NewBlockHeaderCache(cfg) + require.NoError(t, err) + + now := time.Now().UTC() + + // Add some entries. + for i := uint32(0); i < 10; i++ { + header := makeHeader(i, now.Add(time.Duration(i)*time.Minute)) + err := cache.Put(i*10, header) + require.NoError(t, err) + } + + require.Equal(t, 10, cache.Size()) + + // Clear the cache. + cache.Clear() + + require.Equal(t, 0, cache.Size()) + + stats := cache.Stats() + require.Equal(t, 0, stats.TotalEntries) + require.Equal(t, 0, stats.SettledEntries) + require.Equal(t, uint32(0), stats.MaxHeight) +} + +// TestBlockHeaderCacheStats tests the Stats method. +func TestBlockHeaderCacheStats(t *testing.T) { + t.Parallel() + + cfg := BlockHeaderCacheConfig{ + MaxSize: 100, + PurgePercentage: 10, + MinSettledBlockDepth: 5, + } + cache, err := NewBlockHeaderCache(cfg) + require.NoError(t, err) + + now := time.Now().UTC() + + // Add 15 headers starting at height 100. + for i := uint32(0); i < 15; i++ { + header := makeHeader(i, now.Add(time.Duration(i)*time.Minute)) + err := cache.Put(100+i, header) + require.NoError(t, err) + } + + stats := cache.Stats() + + // Should have 15 total entries. + require.Equal(t, 15, stats.TotalEntries) + + // Heights 100-109 should be settled (114 - 5 = 109), that's 10 entries. + require.Equal(t, 10, stats.SettledEntries) + + // Highest settled should be 114. + require.Equal(t, uint32(114), stats.MaxHeight) + + // Test String method. + statsStr := stats.String() + require.Contains(t, statsStr, "total=15") + require.Contains(t, statsStr, "settled=10") + require.Contains(t, statsStr, "max_height=114") +} + +// TestBlockHeaderCacheEdgeCases tests various edge cases. +func TestBlockHeaderCacheEdgeCases(t *testing.T) { + t.Parallel() + + cfg := BlockHeaderCacheConfig{ + MaxSize: 10, + PurgePercentage: 10, + MinSettledBlockDepth: 6, + } + cache, err := NewBlockHeaderCache(cfg) + require.NoError(t, err) + + // Get from empty cache. + _, ok := cache.GetByHeight(100) + require.False(t, ok) + + hash := chainhash.Hash{} + _, ok = cache.GetByHash(hash) + require.False(t, ok) + + // Add a single header. + now := time.Now().UTC() + header := makeHeader(1, now) + err = cache.Put(100, header) + require.NoError(t, err) + + // Should be unsettled (no confirmations). + _, ok = cache.GetByHeight(100) + require.False(t, ok) + + // Add header far enough ahead to settle the first one. + header2 := makeHeader(2, now.Add(10*time.Minute)) + err = cache.Put(107, header2) + require.NoError(t, err) + + // Now first header should be settled. + retrieved, ok := cache.GetByHeight(100) + require.True(t, ok) + require.Equal(t, header.BlockHash(), retrieved.BlockHash()) +} + +// TestBlockHeaderCacheHeaderEntryHashField verifies that the headerEntry.hash +// field is set and used correctly, especially during invalidation and purge. +func TestBlockHeaderCacheHeaderEntryHashField(t *testing.T) { + t.Parallel() + + cfg := BlockHeaderCacheConfig{ + MaxSize: 10, + PurgePercentage: 50, + MinSettledBlockDepth: 1, + } + cache, err := NewBlockHeaderCache(cfg) + require.NoError(t, err) + + now := time.Now().UTC() + header := makeHeader(123, now) + height := uint32(5) + + // Insert header and check hash field. + err = cache.Put(height, header) + require.NoError(t, err) + + cache.mu.RLock() + entry, exists := cache.byHeight[height] + cache.mu.RUnlock() + require.True(t, exists, "entry should exist") + require.Equal( + t, header.BlockHash(), entry.hash, + "headerEntry.hash should match header.BlockHash()", + ) + + // Insert a different header at the same height to trigger + // reorg/invalidation. + altHeader := makeHeader(999, now.Add(1*time.Minute)) + err = cache.Put(height, altHeader) + require.NoError(t, err) + + cache.mu.RLock() + entry, exists = cache.byHeight[height] + cache.mu.RUnlock() + require.True(t, exists, "entry should exist after reorg") + require.Equal( + t, altHeader.BlockHash(), entry.hash, + "headerEntry.hash should update after reorg", + ) +} + +// TestBlockHeaderCacheInvalidConfig tests that invalid configurations return +// errors. +func TestBlockHeaderCacheInvalidConfig(t *testing.T) { + t.Parallel() + + // Test PurgePercentage = 0. + cfg := BlockHeaderCacheConfig{ + MaxSize: 100, + PurgePercentage: 0, + MinSettledBlockDepth: 6, + } + cache, err := NewBlockHeaderCache(cfg) + require.Error(t, err) + require.Nil(t, cache) + require.Contains(t, err.Error(), "invalid PurgePercentage") + + // Test PurgePercentage > 100. + cfg.PurgePercentage = 101 + cache, err = NewBlockHeaderCache(cfg) + require.Error(t, err) + require.Nil(t, cache) + require.Contains(t, err.Error(), "invalid PurgePercentage") + + // Test valid edge cases. + cfg.PurgePercentage = 1 + cache, err = NewBlockHeaderCache(cfg) + require.NoError(t, err) + require.NotNil(t, cache) + + cfg.PurgePercentage = 100 + cache, err = NewBlockHeaderCache(cfg) + require.NoError(t, err) + require.NotNil(t, cache) +} diff --git a/lndservices/chain_bridge.go b/lndservices/chain_bridge.go index 122bce3e4..181a1a1df 100644 --- a/lndservices/chain_bridge.go +++ b/lndservices/chain_bridge.go @@ -10,7 +10,6 @@ import ( "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/btcsuite/btcd/wire" "github.com/lightninglabs/lndclient" - "github.com/lightninglabs/neutrino/cache/lru" "github.com/lightninglabs/taproot-assets/asset" "github.com/lightninglabs/taproot-assets/fn" "github.com/lightninglabs/taproot-assets/proof" @@ -21,12 +20,6 @@ import ( ) const ( - // maxNumBlocksInCache is the maximum number of blocks we'll cache - // timestamps for. With 400k blocks we should only take up approximately - // 3200kB of memory (4 bytes for the block height and 4 bytes for the - // timestamp, not including any map/cache overhead). - maxNumBlocksInCache = 400_000 - // medianTimeBlocks is the number of previous blocks which should be // used to calculate the median time used to validate block timestamps. medianTimeBlocks = 11 @@ -38,40 +31,33 @@ var ( errTxNotFound = fmt.Errorf("transaction not found in proof file") ) -// cacheableTimestamp is a wrapper around an uint32 that can be used as a value -// in an LRU cache. -type cacheableTimestamp uint32 - -// Size returns the size of the cacheable timestamp. Since we scale the cache by -// the number of items and not the total memory size, we can simply return 1 -// here to count each timestamp as 1 item. -func (c cacheableTimestamp) Size() (uint64, error) { - return 1, nil -} - // LndRpcChainBridge is an implementation of the tapgarden.ChainBridge // interface backed by an active remote lnd node. type LndRpcChainBridge struct { + // lnd is the active lnd services client. lnd *lndclient.LndServices - blockTimestampCache *lru.Cache[uint32, cacheableTimestamp] - retryConfig fn.RetryConfig + // retryConfig is the configuration used for retrying operations. + retryConfig fn.RetryConfig + // assetStore is a handle to the asset store. assetStore *tapdb.AssetStore + + // headerCache is a cache for block headers to reduce RPC calls. + headerCache *BlockHeaderCache } // NewLndRpcChainBridge creates a new chain bridge from an active lnd services // client. func NewLndRpcChainBridge(lnd *lndclient.LndServices, - assetStore *tapdb.AssetStore) *LndRpcChainBridge { + assetStore *tapdb.AssetStore, + headerCache *BlockHeaderCache) *LndRpcChainBridge { return &LndRpcChainBridge{ - lnd: lnd, - blockTimestampCache: lru.NewCache[uint32, cacheableTimestamp]( - maxNumBlocksInCache, - ), + lnd: lnd, retryConfig: fn.DefaultRetryConfig(), assetStore: assetStore, + headerCache: headerCache, } } @@ -137,6 +123,11 @@ func (l *LndRpcChainBridge) GetBlock(ctx context.Context, func (l *LndRpcChainBridge) GetBlockHeader(ctx context.Context, hash chainhash.Hash) (*wire.BlockHeader, error) { + // First, check the cache for the requested block header. + if header, ok := l.headerCache.GetByHash(hash); ok { + return &header, nil + } + return fn.RetryFuncN( ctx, l.retryConfig, func() (*wire.BlockHeader, error) { header, err := l.lnd.ChainKit.GetBlockHeader(ctx, hash) @@ -155,6 +146,14 @@ func (l *LndRpcChainBridge) GetBlockHeader(ctx context.Context, func (l *LndRpcChainBridge) GetBlockHeaderByHeight(ctx context.Context, blockHeight int64) (*wire.BlockHeader, error) { + // Convert to uint32 for cache operations. + height := uint32(blockHeight) + + // First, check the cache for the requested block header by height. + if header, ok := l.headerCache.GetByHeight(height); ok { + return &header, nil + } + // First, we need to resolve the block hash at the given height. blockHash, err := fn.RetryFuncN( ctx, l.retryConfig, func() (chainhash.Hash, error) { @@ -190,6 +189,13 @@ func (l *LndRpcChainBridge) GetBlockHeaderByHeight(ctx context.Context, ) } + // Store the retrieved header in the cache. + err = l.headerCache.Put(height, *header) + if err != nil { + return nil, fmt.Errorf("failed to cache block "+ + "header: %w", err) + } + return header, nil }, ) @@ -268,38 +274,20 @@ func (l *LndRpcChainBridge) CurrentHeight(ctx context.Context) (uint32, error) { // GetBlockTimestamp returns the timestamp of the block at the given height. func (l *LndRpcChainBridge) GetBlockTimestamp(ctx context.Context, - height uint32) int64 { + height uint32) (int64, error) { // Shortcut any lookup in case we don't have a valid height in the first // place. if height == 0 { - return 0 + return 0, nil } - cacheTS, err := l.blockTimestampCache.Get(height) - if err == nil { - return int64(cacheTS) - } - - hash, err := fn.RetryFuncN( - ctx, l.retryConfig, func() (chainhash.Hash, error) { - return l.lnd.ChainKit.GetBlockHash(ctx, int64(height)) - }, - ) - if err != nil { - return 0 - } - - // Get block header. - header, err := l.GetBlockHeader(ctx, hash) + blockHeader, err := l.GetBlockHeaderByHeight(ctx, int64(height)) if err != nil { - return 0 + return 0, fmt.Errorf("unable to fetch block header: %w", err) } - ts := uint32(header.Timestamp.Unix()) - _, _ = l.blockTimestampCache.Put(height, cacheableTimestamp(ts)) - - return int64(ts) + return blockHeader.Timestamp.Unix(), nil } // PublishTransaction attempts to publish a new transaction to the @@ -472,7 +460,14 @@ func (l *ProofChainLookup) MeanBlockTimestamp(ctx context.Context, break } - unixTs := l.chainBridge.GetBlockTimestamp(ctx, blockHeight-i) + unixTs, err := l.chainBridge.GetBlockTimestamp( + ctx, blockHeight-i, + ) + if err != nil { + return time.Time{}, fmt.Errorf("unable to fetch block "+ + "header timestamp: %w", err) + } + if unixTs == 0 { return time.Time{}, fmt.Errorf("couldn't find "+ "timestamp for block height %d", blockHeight) diff --git a/lndservices/daemon_adapters.go b/lndservices/daemon_adapters.go index 585ac864c..3386ca16d 100644 --- a/lndservices/daemon_adapters.go +++ b/lndservices/daemon_adapters.go @@ -51,14 +51,16 @@ type LndFsmDaemonAdapters struct { } // NewLndFsmDaemonAdapters creates a new instance of LndFsmDaemonAdapters. -func NewLndFsmDaemonAdapters(lnd *lndclient.LndServices) *LndFsmDaemonAdapters { +func NewLndFsmDaemonAdapters(lnd *lndclient.LndServices, + headerCache *BlockHeaderCache) *LndFsmDaemonAdapters { + retryConfig := fn.DefaultRetryConfig() msgTransport := NewLndMsgTransportClient(lnd) // Initialize the chain bridge without the asset store, as it is not // needed for the FSM adapters. - chainBridge := NewLndRpcChainBridge(lnd, nil) + chainBridge := NewLndRpcChainBridge(lnd, nil, headerCache) chainBridge.retryConfig = retryConfig return &LndFsmDaemonAdapters{ diff --git a/proof/courier.go b/proof/courier.go index 7e463fa25..58d6c249b 100644 --- a/proof/courier.go +++ b/proof/courier.go @@ -1316,9 +1316,9 @@ func (c *UniverseRpcCourier) ensureConnect(ctx context.Context) error { c.mboxClient = mboxrpc.NewMailboxClient(conn) c.rawConn = conn - // Make sure we initiate the connection. The GetInfo RPC method is in - // the base macaroon white list, so it doesn't require any - // authentication, independent of the universe's configuration. + // Ensure the connection is established by calling the `Info` RPC + // endpoint. This endpoint does not require authentication when the + // universe server is configured to act as a proof courier. _, err = c.client.Info(ctx, &unirpc.InfoRequest{}) if err != nil { // If we fail to connect, we'll close the connection and return diff --git a/rfq/marshal.go b/rfq/marshal.go index a554533ad..316430d24 100644 --- a/rfq/marshal.go +++ b/rfq/marshal.go @@ -9,6 +9,7 @@ import ( "github.com/lightninglabs/taproot-assets/fn" "github.com/lightninglabs/taproot-assets/rfqmath" "github.com/lightninglabs/taproot-assets/rfqmsg" + "github.com/lightninglabs/taproot-assets/taprpc" "github.com/lightninglabs/taproot-assets/taprpc/rfqrpc" ) @@ -54,7 +55,7 @@ func MarshalAcceptedSellQuote( // Populate asset ID and/or group key based on the asset specifier. accept.Request.AssetSpecifier.WhenId(func(assetId asset.ID) { if quote.AssetSpec == nil { - quote.AssetSpec = &rfqrpc.AssetSpec{} + quote.AssetSpec = &taprpc.AssetSpecifier{} } quote.AssetSpec.Id = assetId[:] @@ -63,10 +64,10 @@ func MarshalAcceptedSellQuote( accept.Request.AssetSpecifier.WhenGroupPubKey( func(groupKey btcec.PublicKey) { if quote.AssetSpec == nil { - quote.AssetSpec = &rfqrpc.AssetSpec{} + quote.AssetSpec = &taprpc.AssetSpecifier{} } - quote.AssetSpec.GroupPubKey = + quote.AssetSpec.GroupKey = schnorr.SerializePubKey(&groupKey) }, ) @@ -101,7 +102,7 @@ func MarshalAcceptedBuyQuote(q rfqmsg.BuyAccept) *rfqrpc.PeerAcceptedBuyQuote { // Populate asset ID and/or group key based on the asset specifier. q.Request.AssetSpecifier.WhenId(func(assetId asset.ID) { if quote.AssetSpec == nil { - quote.AssetSpec = &rfqrpc.AssetSpec{} + quote.AssetSpec = &taprpc.AssetSpecifier{} } quote.AssetSpec.Id = assetId[:] @@ -110,10 +111,10 @@ func MarshalAcceptedBuyQuote(q rfqmsg.BuyAccept) *rfqrpc.PeerAcceptedBuyQuote { q.Request.AssetSpecifier.WhenGroupPubKey( func(groupKey btcec.PublicKey) { if quote.AssetSpec == nil { - quote.AssetSpec = &rfqrpc.AssetSpec{} + quote.AssetSpec = &taprpc.AssetSpecifier{} } - quote.AssetSpec.GroupPubKey = + quote.AssetSpec.GroupKey = schnorr.SerializePubKey(&groupKey) }, ) diff --git a/rpcserver.go b/rpcserver.go index 5cf08abeb..9e3ec2fbe 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -1259,9 +1259,15 @@ func (r *rpcServer) MarshalChainAsset(ctx context.Context, a asset.ChainAsset, // Ensure the block timestamp is set if a block height is set. if a.AnchorBlockTimestamp == 0 && a.AnchorBlockHeight > 0 { - a.AnchorBlockTimestamp = r.cfg.ChainBridge.GetBlockTimestamp( + timestamp, err := r.cfg.ChainBridge.GetBlockTimestamp( ctx, a.AnchorBlockHeight, ) + if err != nil { + return nil, fmt.Errorf("unable to fetch block header "+ + "timestamp: %w", err) + } + + a.AnchorBlockTimestamp = timestamp } return rpcutils.MarshalChainAsset( @@ -2242,6 +2248,33 @@ func (r *rpcServer) AddrReceives(ctx context.Context, var sqlQuery address.EventQueryParams + if req.Offset < 0 { + return nil, fmt.Errorf("offset must be non-negative") + } + if req.Limit < 0 { + return nil, fmt.Errorf("limit must be non-negative") + } + if req.Limit > address.MaxEventQueryLimit { + return nil, fmt.Errorf("limit must be less than %d", + address.MaxEventQueryLimit) + } + + sqlQuery.Offset = req.Offset + sqlQuery.Limit = req.Limit + sqlQuery.SortDirection = address.DescSortDirection + + switch req.GetDirection() { + case taprpc.SortDirection_SORT_DIRECTION_DESC: + sqlQuery.SortDirection = address.DescSortDirection + + case taprpc.SortDirection_SORT_DIRECTION_ASC: + sqlQuery.SortDirection = address.AscSortDirection + + default: + return nil, fmt.Errorf("invalid sort direction: %v", + req.GetDirection()) + } + if len(req.FilterAddr) > 0 { addr, err := address.DecodeAddress( req.FilterAddr, &r.cfg.ChainParams, @@ -3669,24 +3702,6 @@ func (r *rpcServer) BurnAsset(ctx context.Context, rpcsLog.Debug("Executing asset burn") - var assetID asset.ID - switch { - case len(in.GetAssetId()) > 0: - copy(assetID[:], in.GetAssetId()) - - case len(in.GetAssetIdStr()) > 0: - assetIDBytes, err := hex.DecodeString(in.GetAssetIdStr()) - if err != nil { - return nil, fmt.Errorf("error decoding asset ID: %w", - err) - } - - copy(assetID[:], assetIDBytes) - - default: - return nil, fmt.Errorf("asset ID must be specified") - } - if in.AmountToBurn == 0 { return nil, fmt.Errorf("amount to burn must be specified") } @@ -3696,36 +3711,120 @@ func (r *rpcServer) BurnAsset(ctx context.Context, "accidental asset burns") } - var groupKey *btcec.PublicKey - assetGroup, err := r.cfg.TapAddrBook.QueryAssetGroupByID(ctx, assetID) + var ( + assetID *asset.ID + groupKey *btcec.PublicKey + err error + ) + + // TODO(darioAnongba): Remove this switch once the deprecated asset + // field is removed. Keep only the AssetSpecifier case. + // Added in v0.8.0. switch { - case err == nil && assetGroup.GroupKey != nil: - // We found the asset group, so we can use the group key to - // burn the asset. - groupKey = &assetGroup.GroupPubKey + case in.Asset != nil: + rpcsLog.Warnf("using deprecated asset field, please use " + + "asset_specifier instead") - case errors.Is(err, address.ErrAssetGroupUnknown): - // We don't know the asset group, so we'll try to burn the - // asset using the asset ID only. - rpcsLog.Debug("Asset group key not found, asset may not be " + - "part of a group") + switch { + case len(in.GetAssetId()) > 0: + var assetIdBytes [32]byte + copy(assetIdBytes[:], in.GetAssetId()) + id := asset.ID(assetIdBytes) + assetID = &id + + case len(in.GetAssetIdStr()) > 0: + assetIDBytes, err := hex.DecodeString( + in.GetAssetIdStr(), + ) + if err != nil { + return nil, fmt.Errorf("error decoding "+ + "asset ID: %w", + err) + } - case err != nil: - return nil, fmt.Errorf("error querying asset group: %w", err) - } + var id asset.ID + copy(id[:], assetIDBytes) + assetID = &id + + default: + return nil, fmt.Errorf("asset ID must be specified") + } + + case in.AssetSpecifier != nil: + assetID, groupKey, err = parseAssetSpecifier( + in.AssetSpecifier.GetId(), + "", + in.AssetSpecifier.GetGroupKey(), + "", + ) + if err != nil { + return nil, fmt.Errorf("unable to parse asset "+ + "specifier: %w", err) + } - var serializedGroupKey []byte - if groupKey != nil { - serializedGroupKey = groupKey.SerializeCompressed() + default: + return nil, fmt.Errorf("asset_specifier field unset") } - rpcsLog.Infof("Burning asset (asset_id=%x, group_key=%x, "+ - "burn_amount=%d)", assetID[:], serializedGroupKey, - in.AmountToBurn) + // Handle different scenarios based on what was provided: + // 1. If only assetID is provided, look up the group key. + // 2. If only groupKey is provided, use it directly + // 3. If both are provided, validate consistency. + switch { + case assetID != nil && groupKey == nil: + assetGroup, err := r.cfg.TapAddrBook.QueryAssetGroupByID( + ctx, *assetID, + ) + switch { + case err == nil && assetGroup.GroupKey != nil: + groupKey = &assetGroup.GroupPubKey - assetSpecifier := asset.NewSpecifierOptionalGroupPubKey( - assetID, groupKey, + case errors.Is(err, address.ErrAssetGroupUnknown): + rpcsLog.Trace("Asset group key not found, asset " + + "may not be part of a group") + + case err != nil: + return nil, fmt.Errorf("error querying asset "+ + "group: %w", err) + } + + case assetID != nil && groupKey != nil: + assetGroup, err := r.cfg.TapAddrBook.QueryAssetGroupByID( + ctx, *assetID, + ) + switch { + case err == nil && assetGroup.GroupKey != nil: + if !groupKey.IsEqual(&assetGroup.GroupPubKey) { + return nil, fmt.Errorf("inconsistent asset " + + "ID for given group key") + } + + case errors.Is(err, address.ErrAssetGroupUnknown): + return nil, fmt.Errorf("asset is not part of a group") + + case err != nil: + return nil, fmt.Errorf("error querying asset "+ + "group: %w", err) + } + + case assetID == nil && groupKey != nil: + // Only group key provided - use it directly + + default: + // Should be unreachable by assertion. + return nil, fmt.Errorf("invalid asset specifier state") + } + + assetSpecifier, err := asset.NewSpecifier( + assetID, groupKey, nil, true, ) + if err != nil { + return nil, fmt.Errorf("unable to create asset specifier: %w", + err) + } + + rpcsLog.Infof("Burning asset (asset_specifier=%v, burn_amount=%d)", + assetSpecifier, in.AmountToBurn) fundResp, err := r.cfg.AssetWallet.FundBurn( ctx, &tapsend.FundingDescriptor{ @@ -3737,17 +3836,13 @@ func (r *rpcServer) BurnAsset(ctx context.Context, return nil, fmt.Errorf("error funding burn: %w", err) } - // We don't support burning by group key yet, so we only expect a single - // vPacket (which implies a single asset ID is involved). - if len(fundResp.VPackets) > 1 { - return nil, fmt.Errorf("only one packet supported") - } - - // Now we can sign the packet and send it to the chain. - vPkt := fundResp.VPackets[0] - _, err = r.cfg.AssetWallet.SignVirtualPacket(ctx, vPkt) - if err != nil { - return nil, fmt.Errorf("error signing packet: %w", err) + // Sign all virtual packets created for this burn + // (may be more than one when burning by group key). + for _, vPkt := range fundResp.VPackets { + _, err = r.cfg.AssetWallet.SignVirtualPacket(ctx, vPkt) + if err != nil { + return nil, fmt.Errorf("error signing packet: %w", err) + } } resp, err := r.cfg.ChainPorter.RequestShipment( @@ -3765,28 +3860,29 @@ func (r *rpcServer) BurnAsset(ctx context.Context, err) } - var burnProof *taprpc.DecodedProof - for idx := range resp.Outputs { - vOut := vPkt.Outputs[idx] - tOut := resp.Outputs[idx] - if vOut.Asset.IsBurn() { - p, err := proof.Decode(tOut.ProofSuffix) - if err != nil { - return nil, fmt.Errorf("error decoding "+ - "burn proof: %w", err) - } + var burnProofs []*taprpc.DecodedProof + for _, tOut := range resp.Outputs { + p, err := proof.Decode(tOut.ProofSuffix) + if err != nil { + return nil, fmt.Errorf("error decoding burn proof: %w", + err) + } - burnProof, err = r.marshalProof(ctx, p, true, false) - if err != nil { - return nil, fmt.Errorf("error decoding "+ - "burn proof: %w", err) - } + if !p.Asset.IsBurn() { + continue } + + burnProof, err := r.marshalProof(ctx, p, true, false) + if err != nil { + return nil, fmt.Errorf("error decoding burn proof: %w", + err) + } + burnProofs = append(burnProofs, burnProof) } return &taprpc.BurnAssetResponse{ BurnTransfer: parcel, - BurnProof: burnProof, + BurnProofs: burnProofs, }, nil } @@ -7734,24 +7830,31 @@ func (r *rpcServer) UniverseStats(ctx context.Context, // marshalAssetSyncSnapshot maps a universe asset sync stat snapshot to the RPC // counterpart. func (r *rpcServer) marshalAssetSyncSnapshot(ctx context.Context, - a universe.AssetSyncSnapshot) *unirpc.AssetStatsSnapshot { + a universe.AssetSyncSnapshot) (*unirpc.AssetStatsSnapshot, error) { resp := &unirpc.AssetStatsSnapshot{ TotalSyncs: int64(a.TotalSyncs), TotalProofs: int64(a.TotalProofs), GroupSupply: int64(a.GroupSupply), } + + blockTimestamp, err := r.cfg.ChainBridge.GetBlockTimestamp( + ctx, a.GenesisHeight, + ) + if err != nil { + return nil, fmt.Errorf("failed to query block header "+ + "timestamp for genesis height: %w", err) + } + rpcAsset := &unirpc.AssetStatsAsset{ - AssetId: a.AssetID[:], - GenesisPoint: a.GenesisPoint.String(), - AssetName: a.AssetName, - AssetType: taprpc.AssetType(a.AssetType), - TotalSupply: int64(a.TotalSupply), - GenesisHeight: int32(a.GenesisHeight), - GenesisTimestamp: r.cfg.ChainBridge.GetBlockTimestamp( - ctx, a.GenesisHeight, - ), - AnchorPoint: a.AnchorPoint.String(), + AssetId: a.AssetID[:], + GenesisPoint: a.GenesisPoint.String(), + AssetName: a.AssetName, + AssetType: taprpc.AssetType(a.AssetType), + TotalSupply: int64(a.TotalSupply), + GenesisHeight: int32(a.GenesisHeight), + GenesisTimestamp: blockTimestamp, + AnchorPoint: a.AnchorPoint.String(), } decDisplay, err := r.cfg.AddrBook.DecDisplayForAssetID(ctx, a.AssetID) @@ -7768,7 +7871,7 @@ func (r *rpcServer) marshalAssetSyncSnapshot(ctx context.Context, resp.Asset = rpcAsset } - return resp + return resp, nil } // QueryAssetStats returns a set of statistics for a given set of assets. @@ -7812,7 +7915,13 @@ func (r *rpcServer) QueryAssetStats(ctx context.Context, ), } for idx, snapshot := range assetStats.SyncStats { - resp.AssetStats[idx] = r.marshalAssetSyncSnapshot(ctx, snapshot) + rpcSnapshot, err := r.marshalAssetSyncSnapshot(ctx, snapshot) + if err != nil { + return nil, fmt.Errorf("failed to marshal asset "+ + "snapshot: %w", err) + } + + resp.AssetStats[idx] = rpcSnapshot } return resp, nil @@ -7956,19 +8065,14 @@ func parseAssetSpecifier(reqAssetID []byte, reqAssetIDStr string, reqGroupKey []byte, reqGroupKeyStr string) (*asset.ID, *btcec.PublicKey, error) { - // Attempt to decode the asset specifier from the RPC request. In cases - // where both the asset ID and asset group key are provided, we will - // give precedence to the asset ID due to its higher level of - // specificity. var ( assetID *asset.ID groupKey *btcec.PublicKey err error ) - switch { - // Parse the asset ID if it's set. - case len(reqAssetID) > 0: + // Parse the asset ID if it's set (either as bytes or string). + if len(reqAssetID) > 0 { if len(reqAssetID) != sha256.Size { return nil, nil, fmt.Errorf("asset ID must be 32 bytes") } @@ -7977,35 +8081,30 @@ func parseAssetSpecifier(reqAssetID []byte, reqAssetIDStr string, copy(assetIdBytes[:], reqAssetID) id := asset.ID(assetIdBytes) assetID = &id - - case len(reqAssetIDStr) > 0: + } else if len(reqAssetIDStr) > 0 { assetIDBytes, err := hex.DecodeString(reqAssetIDStr) if err != nil { - return nil, nil, fmt.Errorf("error decoding asset "+ - "ID: %w", err) - } - - if len(assetIDBytes) != sha256.Size { - return nil, nil, fmt.Errorf("asset ID must be 32 bytes") + return nil, nil, fmt.Errorf("error decoding "+ + "asset ID: %w", err) } var id asset.ID copy(id[:], assetIDBytes) assetID = &id + } - // Parse the group key if it's set. - case len(reqGroupKey) > 0: + // Parse the group key if it's set (either as bytes or string). + if len(reqGroupKey) > 0 { groupKey, err = btcec.ParsePubKey(reqGroupKey) if err != nil { return nil, nil, fmt.Errorf("error parsing group "+ "key: %w", err) } - - case len(reqGroupKeyStr) > 0: + } else if len(reqGroupKeyStr) > 0 { groupKeyBytes, err := hex.DecodeString(reqGroupKeyStr) if err != nil { - return nil, nil, fmt.Errorf("error decoding group "+ - "key: %w", err) + return nil, nil, fmt.Errorf("error decoding "+ + "group key: %w", err) } groupKey, err = btcec.ParsePubKey(groupKeyBytes) @@ -8013,10 +8112,10 @@ func parseAssetSpecifier(reqAssetID []byte, reqAssetIDStr string, return nil, nil, fmt.Errorf("error parsing group "+ "key: %w", err) } + } - default: - // At this point, we know that neither the asset ID nor the - // group key are specified. Return an error. + // Validate that at least one is specified. + if assetID == nil && groupKey == nil { return nil, nil, fmt.Errorf("either asset ID or asset group " + "key must be specified") } diff --git a/sample-tapd.conf b/sample-tapd.conf index 862184396..dc9f04d11 100644 --- a/sample-tapd.conf +++ b/sample-tapd.conf @@ -388,8 +388,9 @@ [multiverse-caches] -; The number of proofs that are cached per universe. (default: 5) -; universe.multiverse-caches.proofs-per-universe=5 +; The maximum total size of the cached proofs. Accepts human readable values +; such as 32MB or 1GB. (default: 32MB) +; universe.multiverse-caches.max-proof-cache-size=32MB ; The number of universes that can have a cache of leaf keys. (default: 2000) ; universe.multiverse-caches.leaves-num-cached-universes=2000 diff --git a/tapcfg/server.go b/tapcfg/server.go index ef4b51ba7..80fd8ab7f 100644 --- a/tapcfg/server.go +++ b/tapcfg/server.go @@ -113,14 +113,30 @@ func genServerConfig(cfg *Config, cfgLogger btclog.Logger, lndServices, lndservices.WithPsbtMaxFeeRatio(cfg.Wallet.PsbtMaxFeeRatio), ) - chainBridge := lndservices.NewLndRpcChainBridge(lndServices, assetStore) + + // Create a block header cache with default configuration. + headerCache, err := lndservices.NewBlockHeaderCache( + lndservices.DefaultBlockHeaderCacheConfig(), + ) + if err != nil { + return nil, fmt.Errorf("failed to create block header cache: "+ + "%w", err) + } + + chainBridge := lndservices.NewLndRpcChainBridge( + lndServices, assetStore, headerCache, + ) + msgTransportClient := lndservices.NewLndMsgTransportClient(lndServices) lndRouterClient := lndservices.NewLndRouterClient(lndServices) lndInvoicesClient := lndservices.NewLndInvoicesClient(lndServices) lndFeatureBitsVerifier := lndservices.NewLndFeatureBitVerifier( lndServices, ) - lndFsmDaemonAdapters := lndservices.NewLndFsmDaemonAdapters(lndServices) + + lndFsmDaemonAdapters := lndservices.NewLndFsmDaemonAdapters( + lndServices, headerCache, + ) uniDB := tapdb.NewTransactionExecutor( db, func(tx *sql.Tx) tapdb.BaseUniverseStore { @@ -136,11 +152,14 @@ func genServerConfig(cfg *Config, cfgLogger btclog.Logger, cfgLogger.Debugf("multiverse_cache=%v", spew.Sdump(cfg.Universe.MultiverseCaches)) - multiverse := tapdb.NewMultiverseStore( + multiverse, err := tapdb.NewMultiverseStore( multiverseDB, &tapdb.MultiverseStoreConfig{ Caches: *cfg.Universe.MultiverseCaches, }, ) + if err != nil { + return nil, fmt.Errorf("create multiverse store: %w", err) + } uniStatsDB := tapdb.NewTransactionExecutor( db, func(tx *sql.Tx) tapdb.UniverseStatsStore { diff --git a/tapdb/addrs.go b/tapdb/addrs.go index 31fc48e0c..f619a8799 100644 --- a/tapdb/addrs.go +++ b/tapdb/addrs.go @@ -995,6 +995,9 @@ func (t *TapAddressBook) QueryAddrEvents( StatusTo: int16(address.StatusCompleted), CreatedAfter: time.Unix(0, 0).UTC(), CreatedBefore: now, + NumLimit: params.Limit, + NumOffset: params.Offset, + SortDirection: sqlInt16(params.SortDirection), } if len(params.AddrTaprootOutputKey) > 0 { @@ -1019,6 +1022,9 @@ func (t *TapAddressBook) QueryAddrEvents( return nil, fmt.Errorf("created after time after " + "created before time") } + if params.Limit == 0 { + sqlQuery.NumLimit = int32(address.DefaultEventQueryLimit) + } var ( readTxOpts = NewAssetStoreReadTx() diff --git a/tapdb/addrs_test.go b/tapdb/addrs_test.go index 7ddf562f8..ecbda6d7b 100644 --- a/tapdb/addrs_test.go +++ b/tapdb/addrs_test.go @@ -935,6 +935,102 @@ func TestQueryAddrEvents(t *testing.T) { require.Equal(t, event.Outpoint, events[0].Outpoint) } +// TestQueryAddrEventsPagination tests that query parameters for pagination are +// applied when listing address events. +func TestQueryAddrEventsPagination(t *testing.T) { + t.Parallel() + + // First, make a new addr book instance we'll use in the test below. + testClock := clock.NewTestClock(time.Now()) + addrBook, _ := newAddrBook(t, testClock) + + ctx := context.Background() + + // Insert a test address. + addrVersion := test.RandFlip(address.V0, address.V1) + proofCourierAddr := address.RandProofCourierAddrForVersion( + t, addrVersion, + ) + addr, assetGen, assetGroup := address.RandAddrWithVersion( + t, chainParams, proofCourierAddr, addrVersion, + ) + err := addrBook.db.ExecTx( + ctx, WriteTxOption(), + insertFullAssetGen(ctx, assetGen, assetGroup), + ) + require.NoError(t, err) + require.NoError(t, addrBook.InsertAddrs(ctx, *addr)) + + // Insert events. + const numEvents = 3 + events := make([]*address.Event, numEvents) + baseTime := testClock.Now().Add(-time.Duration(numEvents) * time.Second) + for i := range numEvents { + testClock.SetTime(baseTime.Add(time.Duration(i) * time.Second)) + tx := randWalletTx() + event, err := addrBook.GetOrCreateEvent( + ctx, address.StatusTransactionDetected, + newTransfer(t, addr, tx, 0), + ) + require.NoError(t, err) + events[i] = event + } + + testCases := []struct { + testName string + params address.EventQueryParams + expectedEvents []*address.Event + }{ + { + testName: "all events", + params: address.EventQueryParams{}, + expectedEvents: events, + }, + { + testName: "limit", + params: address.EventQueryParams{ + Limit: 2, + }, + expectedEvents: events[:2], + }, + { + testName: "offset and limit", + params: address.EventQueryParams{ + Limit: 2, + Offset: 2, + }, + expectedEvents: events[2:3], + }, + { + testName: "ordering asc", + params: address.EventQueryParams{ + SortDirection: address.AscSortDirection, + }, + expectedEvents: events, + }, + { + testName: "ordering desc", + params: address.EventQueryParams{ + SortDirection: address.DescSortDirection, + }, + expectedEvents: []*address.Event{ + events[2], events[1], events[0], + }, + }, + } + + for _, tc := range testCases { + t.Run(tc.testName, func(t *testing.T) { + dbEvents, err := addrBook.QueryAddrEvents( + ctx, tc.params, + ) + require.NoError(t, err) + + assertEqualAddrEvents(t, tc.expectedEvents, dbEvents) + }) + } +} + // TestAddrByScriptKeyAndVersion tests that we can retrieve an address by its // script key and version. func TestAddrByScriptKeyAndVersion(t *testing.T) { diff --git a/tapdb/asset_minting_test.go b/tapdb/asset_minting_test.go index 4d6e3acbe..54a0211c8 100644 --- a/tapdb/asset_minting_test.go +++ b/tapdb/asset_minting_test.go @@ -5,6 +5,7 @@ import ( "context" "crypto/sha256" "database/sql" + "fmt" "math/rand" "os" "testing" @@ -503,7 +504,9 @@ func TestCommitMintingBatchSeedlings(t *testing.T) { // First, we'll write a new minting batch to disk, including an // internal key and a set of seedlings. One random seedling will // be a reissuance into a specific group. - mintingBatch := tapgarden.RandSeedlingMintingBatch(t, numSeedlings) + mintingBatch := tapgarden.RandMintingBatch( + t, tapgarden.WithTotalSeedlings(numSeedlings), + ) _, randGroup, _ := addRandGroupToBatch( t, assetStore, ctx, mintingBatch.Seedlings, ) @@ -604,7 +607,9 @@ func TestCommitMintingBatchSeedlings(t *testing.T) { // Insert another normal batch into the database. We should get this // batch back if we query for the set of non-final batches. - mintingBatch = tapgarden.RandSeedlingMintingBatch(t, numSeedlings) + mintingBatch = tapgarden.RandMintingBatch( + t, tapgarden.WithTotalSeedlings(numSeedlings), + ) err = assetStore.CommitMintingBatch(ctx, mintingBatch) require.NoError(t, err) mintingBatches = noError1(t, assetStore.FetchNonFinalBatches, ctx) @@ -851,7 +856,9 @@ func TestAddSproutsToBatch(t *testing.T) { // First, we'll create a new batch, then add some sample seedlings. // One random seedling will be a reissuance into a specific group. - mintingBatch := tapgarden.RandSeedlingMintingBatch(t, numSeedlings) + mintingBatch := tapgarden.RandMintingBatch( + t, tapgarden.WithTotalSeedlings(numSeedlings), + ) _, seedlingGroups, _ := addRandGroupToBatch( t, assetStore, ctx, mintingBatch.Seedlings, ) @@ -949,7 +956,9 @@ type randAssetCtx struct { func addRandAssets(t *testing.T, ctx context.Context, assetStore *AssetMintingStore, numAssets int) randAssetCtx { - mintingBatch := tapgarden.RandSeedlingMintingBatch(t, numAssets) + mintingBatch := tapgarden.RandMintingBatch( + t, tapgarden.WithTotalSeedlings(numAssets), + ) genAmt, seedlingGroups, group := addRandGroupToBatch( t, assetStore, ctx, mintingBatch.Seedlings, ) @@ -1463,7 +1472,9 @@ func TestGroupAnchors(t *testing.T) { // internal key and a set of seedlings. One random seedling will // be a reissuance into a specific group. Two other seedlings will form // a multi-asset group. - mintingBatch := tapgarden.RandSeedlingMintingBatch(t, numSeedlings) + mintingBatch := tapgarden.RandMintingBatch( + t, tapgarden.WithTotalSeedlings(numSeedlings), + ) _, seedlingGroups, _ := addRandGroupToBatch( t, assetStore, ctx, mintingBatch.Seedlings, ) @@ -1839,7 +1850,7 @@ func TestTapscriptTreeManager(t *testing.T) { // storeMintSupplyPreCommit stores a mint anchor supply pre-commitment in the // DB. func storeMintSupplyPreCommit(t *testing.T, assetStore AssetMintingStore, - batchKey []byte, txOutputIndex int32, + batchKey []byte, txOutputIndex uint32, taprootInternalKey keychain.KeyDescriptor, groupKey []byte, outpoint wire.OutPoint) { @@ -1863,7 +1874,7 @@ func storeMintSupplyPreCommit(t *testing.T, assetStore AssetMintingStore, _, err = q.UpsertMintSupplyPreCommit( ctx, UpsertBatchPreCommitParams{ BatchKey: batchKey, - TxOutputIndex: txOutputIndex, + TxOutputIndex: int32(txOutputIndex), TaprootInternalKeyID: internalKeyID, GroupKey: groupKey, Outpoint: opBytes, @@ -1880,7 +1891,7 @@ func storeMintSupplyPreCommit(t *testing.T, assetStore AssetMintingStore, // supply pre-commitment from the DB and asserts that it matches the expected // values. func assertMintSupplyPreCommit(t *testing.T, assetStore AssetMintingStore, - batchKey []byte, txOutputIndex int32, + batchKey []byte, txOutputIndex uint32, preCommitInternalKey keychain.KeyDescriptor, groupPubKeyBytes []byte, outpoint wire.OutPoint) { @@ -1906,7 +1917,7 @@ func assertMintSupplyPreCommit(t *testing.T, assetStore AssetMintingStore, // Ensure the mint anchor commitment matches the one we inserted. require.NotNil(t, preCommit) require.Equal(t, batchKey, preCommit.BatchKey) - require.Equal(t, txOutputIndex, preCommit.TxOutputIndex) + require.EqualValues(t, txOutputIndex, preCommit.TxOutputIndex) rawInternalKey := preCommitInternalKey.PubKey.SerializeCompressed() require.Equal( @@ -1927,6 +1938,39 @@ func assertMintSupplyPreCommit(t *testing.T, assetStore AssetMintingStore, require.Equal(t, opBytes, preCommit.Outpoint) } +// storeSeedlingGroupGenesis stores the group genesis and an initial asset +// associated with the given seedling in the DB. This is necessary before we can +// commit a minting batch that contains the seedling. +func storeSeedlingGroupGenesis(t *testing.T, ctx context.Context, + assetStore *AssetMintingStore, seedling tapgarden.Seedling) { + + genesis := seedling.GroupInfo.Genesis + groupKey := seedling.GroupInfo.GroupKey + initialAsset := asset.RandAssetWithValues( + t, *genesis, groupKey, asset.RandScriptKey(t), + ) + + upsertAsset := func(q PendingAssetStore) error { + _, err := maybeUpsertAssetMeta(ctx, q, genesis, nil) + require.NoError(t, err) + + // Insert a random managed UTXO. + utxoID := addRandomManagedUTXO(t, ctx, q, initialAsset) + + _, _, err = upsertAssetsWithGenesis( + ctx, q, genesis.FirstPrevOut, + []*asset.Asset{initialAsset}, + []sql.NullInt64{sqlInt64(utxoID)}, + ) + require.NoError(t, err) + return nil + } + + var writeTxOpts AssetStoreTxOptions + err := assetStore.db.ExecTx(ctx, &writeTxOpts, upsertAsset) + require.NoError(t, err) +} + // TestUpsertMintSupplyPreCommit tests the UpsertMintSupplyPreCommit and // FetchSupplyPreCommits SQL queries. In particular, it tests that upsert works // correctly. @@ -1937,13 +1981,21 @@ func TestUpsertMintSupplyPreCommit(t *testing.T) { assetStore, _, _ := newAssetStore(t) // Create a new batch with one asset group seedling. - mintingBatch := tapgarden.RandSeedlingMintingBatch(t, 1) - mintingBatch.SupplyCommitments = true - - _, _, group := addRandGroupToBatch( - t, assetStore, ctx, mintingBatch.Seedlings, + mintingBatch := tapgarden.RandMintingBatch( + t, tapgarden.WithTotalGroups([]int{1}), + tapgarden.WithUniverseCommitments(true), ) + // Store group genesis associated with seedling. This is necessary + // before we can commit the batch. + require.Len(t, mintingBatch.Seedlings, 1) + var seedling tapgarden.Seedling + for _, s := range mintingBatch.Seedlings { + seedling = *s + break + } + storeSeedlingGroupGenesis(t, ctx, assetStore, seedling) + // Commit batch. require.NoError(t, assetStore.CommitMintingBatch(ctx, mintingBatch)) @@ -1962,32 +2014,34 @@ func TestUpsertMintSupplyPreCommit(t *testing.T) { ) // Define pre-commit outpoint for the batch mint anchor tx. - txOutputIndex := int32(2) - txidStr := mintingBatch.GenesisPacket.FundedPsbt.Pkt.UnsignedTx.TxID() + genesisPkt := mintingBatch.GenesisPacket + require.NotNil(t, genesisPkt) + + preCommitOut, err := genesisPkt.PreCommitmentOutput.UnwrapOrErr( + fmt.Errorf("no pre-commitment output"), + ) + require.NoError(t, err) + txidStr := genesisPkt.FundedPsbt.Pkt.UnsignedTx.TxID() txid, err := chainhash.NewHashFromStr(txidStr) require.NoError(t, err) preCommitOutpoint := wire.OutPoint{ Hash: *txid, - Index: uint32(txOutputIndex), + Index: preCommitOut.OutIdx, } // Serialize keys into bytes for easier handling. - preCommitInternalKey, _ := test.RandKeyDesc(t) - - groupPubKeyBytes := schnorr.SerializePubKey(&group.GroupPubKey) - - // Upsert a mint anchor commitment for the batch. - storeMintSupplyPreCommit( - t, *assetStore, batchKey, txOutputIndex, - preCommitInternalKey, groupPubKeyBytes, preCommitOutpoint, + preCommitGroupKey, err := preCommitOut.GroupPubKey.UnwrapOrErr( + fmt.Errorf("no group key"), ) + require.NoError(t, err) + groupPubKeyBytes := schnorr.SerializePubKey(&preCommitGroupKey) // Retrieve and inspect the mint anchor commitment we just inserted. assertMintSupplyPreCommit( - t, *assetStore, batchKey, txOutputIndex, - preCommitInternalKey, groupPubKeyBytes, preCommitOutpoint, + t, *assetStore, batchKey, preCommitOut.OutIdx, + preCommitOut.InternalKey, groupPubKeyBytes, preCommitOutpoint, ) // Upsert-ing a new taproot internal key for the same pre-commit @@ -1995,12 +2049,12 @@ func TestUpsertMintSupplyPreCommit(t *testing.T) { internalKey2, _ := test.RandKeyDesc(t) storeMintSupplyPreCommit( - t, *assetStore, batchKey, txOutputIndex, internalKey2, + t, *assetStore, batchKey, preCommitOut.OutIdx, internalKey2, groupPubKeyBytes, preCommitOutpoint, ) assertMintSupplyPreCommit( - t, *assetStore, batchKey, txOutputIndex, internalKey2, + t, *assetStore, batchKey, preCommitOut.OutIdx, internalKey2, groupPubKeyBytes, preCommitOutpoint, ) @@ -2010,12 +2064,12 @@ func TestUpsertMintSupplyPreCommit(t *testing.T) { groupPubKey2Bytes := schnorr.SerializePubKey(groupPubKey2) storeMintSupplyPreCommit( - t, *assetStore, batchKey, txOutputIndex, internalKey2, + t, *assetStore, batchKey, preCommitOut.OutIdx, internalKey2, groupPubKey2Bytes, preCommitOutpoint, ) assertMintSupplyPreCommit( - t, *assetStore, batchKey, txOutputIndex, internalKey2, + t, *assetStore, batchKey, preCommitOut.OutIdx, internalKey2, groupPubKey2Bytes, preCommitOutpoint, ) } diff --git a/tapdb/cache_logger.go b/tapdb/cache_logger.go index fa1468c79..5043184b8 100644 --- a/tapdb/cache_logger.go +++ b/tapdb/cache_logger.go @@ -11,13 +11,34 @@ type cacheLogger struct { hit atomic.Int64 miss atomic.Int64 + + // cacheSize is a callback that returns the cache size as a + // human-readable string. + cacheSize func() string +} + +// cacheLoggerOption defines a functional option for configuring a cacheLogger. +type cacheLoggerOption func(*cacheLogger) + +// withCacheSizeFunc sets a callback that returns the cache size as a human +// readable string. +func withCacheSizeFunc(sizeFunc func() string) cacheLoggerOption { + return func(c *cacheLogger) { + c.cacheSize = sizeFunc + } } // newCacheLogger returns a new cacheLogger with the given name. -func newCacheLogger(name string) *cacheLogger { - return &cacheLogger{ +func newCacheLogger(name string, opts ...cacheLoggerOption) *cacheLogger { + logger := &cacheLogger{ name: name, } + + for _, opt := range opts { + opt(logger) + } + + return logger } // Hit increments the hit counter for the cacheLogger. Every 100th call to this @@ -46,6 +67,11 @@ func (c *cacheLogger) log() { total := hit + miss ratio := float64(hit) / float64(total) * 100 - log.Infof("db cache %s: %d hits, %d misses, %.2f%% hit ratio", - c.name, hit, miss, ratio) + size := "" + if c.cacheSize != nil { + size = c.cacheSize() + } + + log.Infof("cacheLogger(name=%s, hits=%d, misses=%d, "+ + "hit_ratio=%.2f%%, size=%s)", c.name, hit, miss, ratio, size) } diff --git a/tapdb/multiverse.go b/tapdb/multiverse.go index fae413ae5..02bef1d9b 100644 --- a/tapdb/multiverse.go +++ b/tapdb/multiverse.go @@ -142,7 +142,12 @@ type MultiverseStore struct { // NewMultiverseStore creates a new multiverse DB store handle. func NewMultiverseStore(db BatchedMultiverse, - cfg *MultiverseStoreConfig) *MultiverseStore { + cfg *MultiverseStoreConfig) (*MultiverseStore, error) { + + proofCacheSize, err := cfg.Caches.maxProofCacheSizeBytes() + if err != nil { + return nil, fmt.Errorf("parse max proof cache size: %w", err) + } return &MultiverseStore{ db: db, @@ -154,15 +159,13 @@ func NewMultiverseStore(db BatchedMultiverse, rootNodeCache: newRootNodeCache( cfg.Caches.RootNodePageCacheSize, ), - proofCache: newUniverseProofCache( - cfg.Caches.ProofsPerUniverse, - ), + proofCache: newUniverseProofCache(proofCacheSize), leafKeysCache: newUniverseLeafPageCache( cfg.Caches.LeavesNumCachedUniverses, cfg.Caches.LeavesPerUniverse, ), transferProofDistributor: fn.NewEventDistributor[proof.Blob](), - } + }, nil } // namespaceForProof returns the multiverse namespace used for the given proof @@ -834,7 +837,7 @@ func (b *MultiverseStore) UpsertProofLeaf(ctx context.Context, // Invalidate the cache since we just updated the root. b.rootNodeCache.wipeCache() - b.proofCache.delProofsForAsset(id) + b.proofCache.RemoveLeafKeyProofs(id, key) b.leafKeysCache.wipeCache(id.String()) b.syncerCache.addOrReplace(universe.Root{ ID: id, @@ -952,10 +955,14 @@ func (b *MultiverseStore) UpsertProofLeafBatch(ctx context.Context, ) for id := range idsToDelete { - b.proofCache.Delete(id) b.leafKeysCache.wipeCache(id) } + for idx := range items { + item := items[idx] + b.proofCache.RemoveLeafKeyProofs(item.ID, item.Key) + } + return nil } @@ -990,7 +997,7 @@ func (b *MultiverseStore) DeleteUniverse(ctx context.Context, // Wipe the cache items from this node. b.rootNodeCache.wipeCache() - b.proofCache.Delete(id.String()) + b.proofCache.RemoveUniverseProofs(id) b.leafKeysCache.wipeCache(id.String()) b.syncerCache.remove(id.Key()) diff --git a/tapdb/multiverse_cache.go b/tapdb/multiverse_cache.go index 8c6d48449..487268bfa 100644 --- a/tapdb/multiverse_cache.go +++ b/tapdb/multiverse_cache.go @@ -2,29 +2,33 @@ package tapdb import ( "bytes" - "crypto/sha256" + "fmt" "slices" "sort" "sync" "sync/atomic" + "github.com/dustin/go-humanize" "github.com/lightninglabs/neutrino/cache/lru" - "github.com/lightninglabs/taproot-assets/fn" "github.com/lightninglabs/taproot-assets/universe" "github.com/lightningnetwork/lnd/lnutils" ) +const ( + // defaultMaxProofCacheSize is the default maximum size of the proof + // cache expressed as a human-readable string type so that we can + // present it directly to CLI users. + defaultMaxProofCacheSize = "32MB" +) + // MultiverseCacheConfig is the configuration for the different multiverse // caches that exist. // //nolint:lll type MultiverseCacheConfig struct { - // ProofsPerUniverse is the number of proofs that are cached per - // universe. This number needs to be multiplied by the total number of - // universes to get the total number of proofs that are cached. There is - // no limit to the number of universes that can hold cached keys, so a - // cache is created for each universe that receives a request. - ProofsPerUniverse uint64 `long:"proofs-per-universe" description:"The number of proofs that are cached per universe."` + // MaxProofCacheSize is the maximum size of the proof cache expressed + // as a human-readable string, for example, "32MB" or "1GB". + MaxProofCacheSize string `long:"max-proof-cache-size" description:"The maximum total size of the cached proofs. Accepts human readable values such as 32MB or 1GB."` // LeavesNumCachedUniverses is the number of universes that can have a // cache of leaf keys. Each cached universe can have up to @@ -58,7 +62,7 @@ type MultiverseCacheConfig struct { // multiverse cache. func DefaultMultiverseCacheConfig() MultiverseCacheConfig { return MultiverseCacheConfig{ - ProofsPerUniverse: 5, + MaxProofCacheSize: defaultMaxProofCacheSize, LeavesNumCachedUniverses: 2_000, LeavesPerUniverse: 50, SyncerCacheEnabled: false, @@ -67,63 +71,105 @@ func DefaultMultiverseCacheConfig() MultiverseCacheConfig { } } -// ProofKey is used to uniquely identify a proof within a universe. This is -// used for the LRU cache for the proofs themselves, which are considered to be -// immutable. -type ProofKey [32]byte - -// NewProofKey takes a universe identifier and leaf key, and returns a proof -// key. -func NewProofKey(id universe.Identifier, key universe.LeafKey) ProofKey { - idBytes := id.Bytes() - leafKeyBytes := key.UniverseKey() +// maxProofCacheSizeBytes returns the parsed byte representation of the proof +// cache size limit. +func (c MultiverseCacheConfig) maxProofCacheSizeBytes() (uint64, error) { + sizeStr := c.MaxProofCacheSize + if sizeStr == "" { + sizeStr = defaultMaxProofCacheSize + } - // The proof key maps down the ID and the leaf key into a single - // 32-byte value: sha256(id || leaf_key).. - h := sha256.New() - h.Write(idBytes[:]) - h.Write(leafKeyBytes[:]) + sizeBytes, err := humanize.ParseBytes(sizeStr) + if err != nil { + return 0, fmt.Errorf("parse max proof cache size: %w", err) + } - return fn.ToArray[ProofKey](h.Sum(nil)) + return sizeBytes, nil } // cachedProofs is a list of cached proof leaves. type cachedProofs []*universe.Proof -// Size just returns 1 as we're limiting based on the total number different -// leaf keys we query by. So we might store more than one proof per cache entry -// if the universe key's script key isn't set. But we only want a certain number -// of different keys stored in the cache. +// Size returns the total byte size of all cached proofs. func (c *cachedProofs) Size() (uint64, error) { - return 1, nil + if c == nil { + return 0, nil + } + + totalBytes := uint64(0) + for _, proof := range *c { + if proof == nil { + continue + } + + totalBytes += proof.LowerBoundByteSize() + } + + return totalBytes, nil } // newProofCache creates a new leaf proof cache. -func newProofCache(proofCacheSize uint64) *lru.Cache[ProofKey, *cachedProofs] { - return lru.NewCache[ProofKey, *cachedProofs](proofCacheSize) +// +// nolint: lll +func newProofCache(totalCacheBytesSize uint64) *lru.Cache[UniverseProofKey, *cachedProofs] { + return lru.NewCache[UniverseProofKey, *cachedProofs]( + totalCacheBytesSize, + ) } -// universeIDKey is a cache key that is used to uniquely identify a universe -// within a multiverse tree cache. +// universeIDKey is a cache key used to uniquely identify a universe within a +// multiverse tree cache. type universeIDKey = string +// UniverseProofKey houses the components of a universe proof key. All fields +// must be comparable. +type UniverseProofKey struct { + // uniIDKey is the universe ID key to which the proof belongs. + uniIDKey universe.IdentifierKey + + // leafKey is the leaf key of the proof. + leafKeyBytes [32]byte +} + +// NewUniverseProofKey creates a new universe proof key. +func NewUniverseProofKey(uniID universe.Identifier, + leafKey universe.LeafKey) UniverseProofKey { + + return UniverseProofKey{ + uniIDKey: uniID.Key(), + leafKeyBytes: leafKey.UniverseKey(), + } +} + // universeProofCache a map of proof caches for each proof type. type universeProofCache struct { - proofsPerUniverse uint64 + // maxCacheByteSize is the maximum size of the cache in bytes. + maxCacheByteSize uint64 - lnutils.SyncMap[universeIDKey, *lru.Cache[ProofKey, *cachedProofs]] + // cache is the LRU cache for the proofs themselves. + cache *lru.Cache[UniverseProofKey, *cachedProofs] *cacheLogger } // newUniverseProofCache creates a new proof cache. -func newUniverseProofCache(proofsPerUniverse uint64) *universeProofCache { +func newUniverseProofCache(maxCacheByteSize uint64) *universeProofCache { + cache := newProofCache(maxCacheByteSize) + + // Formulate a callback function that returns the cache size in a + // human-readable format. This will be called by the cache logger to get + // the current cache size. + cacheSizeLogStr := func() string { + return humanize.Bytes(cache.Size()) + } + cacheLogger := newCacheLogger( + "universe_proofs", withCacheSizeFunc(cacheSizeLogStr), + ) + return &universeProofCache{ - proofsPerUniverse: proofsPerUniverse, - SyncMap: lnutils.SyncMap[ - universeIDKey, *lru.Cache[ProofKey, *cachedProofs], - ]{}, - cacheLogger: newCacheLogger("universe_proofs"), + maxCacheByteSize: maxCacheByteSize, + cache: cache, + cacheLogger: cacheLogger, } } @@ -131,16 +177,8 @@ func newUniverseProofCache(proofsPerUniverse uint64) *universeProofCache { func (p *universeProofCache) fetchProof(id universe.Identifier, leafKey universe.LeafKey) []*universe.Proof { - // First, get the sub-cache for this universe ID from the map of - // caches. - assetProofCache, _ := p.LoadOrStore( - id.String(), newProofCache(p.proofsPerUniverse), - ) - - // With that lower level cache obtained, we can check to see if we have - // a hit or not. - proofKey := NewProofKey(id, leafKey) - proofFromCache, err := assetProofCache.Get(proofKey) + uniProofKey := NewUniverseProofKey(id, leafKey) + proofFromCache, err := p.cache.Get(uniProofKey) if err == nil { p.Hit() return *proofFromCache @@ -153,28 +191,54 @@ func (p *universeProofCache) fetchProof(id universe.Identifier, // insertProofs inserts the given proofs into the cache. func (p *universeProofCache) insertProofs(id universe.Identifier, - leafKey universe.LeafKey, proof []*universe.Proof) { - - assetProofCache, _ := p.LoadOrStore( - id.String(), newProofCache(p.proofsPerUniverse), - ) + leafKey universe.LeafKey, proofs []*universe.Proof) { - proofKey := NewProofKey(id, leafKey) + uniProofKey := NewUniverseProofKey(id, leafKey) - log.Debugf("storing proof for %v+%v in cache, key=%x", - id.StringForLog(), leafKey, proofKey[:]) + log.Debugf("Storing proof(s) in cache (universe_id=%v, leaf_key=%v, "+ + "count=%d)", id.StringForLog(), leafKey, len(proofs)) - proofVal := cachedProofs(proof) - if _, err := assetProofCache.Put(proofKey, &proofVal); err != nil { - log.Errorf("unable to insert into proof cache: %v", err) + proofVal := cachedProofs(proofs) + if _, err := p.cache.Put(uniProofKey, &proofVal); err != nil { + log.Errorf("Unable to insert proof into universe proof "+ + "cache: %v", err) } } -// delProofsForAsset deletes all the proofs for the given asset. -func (p *universeProofCache) delProofsForAsset(id universe.Identifier) { - log.Debugf("wiping proofs for %v from cache", id) +// RemoveUniverseProofs deletes all the proofs for the given universe ID. +func (p *universeProofCache) RemoveUniverseProofs(id universe.Identifier) { + log.Debugf("Removing universe proofs (universe_id=%s)", + id.StringForLog()) - p.Delete(id.String()) + targetIDKey := id.Key() + p.cache.Range( + func(key UniverseProofKey, proofs *cachedProofs) bool { + if key.uniIDKey == targetIDKey { + p.cache.Delete(key) + } + return true + }, + ) +} + +// RemoveLeafKeyProofs deletes all the proofs for the given universe ID and leaf +// key. +func (p *universeProofCache) RemoveLeafKeyProofs(id universe.Identifier, + leafKey universe.LeafKey) { + + log.Debugf("Removing leaf key proofs (universe_id=%s, leaf_key=%v)", + id.StringForLog(), leafKey) + + targetCacheKey := NewUniverseProofKey(id, leafKey) + + p.cache.Range( + func(key UniverseProofKey, proofs *cachedProofs) bool { + if key == targetCacheKey { + p.cache.Delete(key) + } + return true + }, + ) } // rootPageQueryKey is a cache key that wraps around a query to fetch all the @@ -374,8 +438,8 @@ func (r *syncerRootNodeCache) fetchRoots(q universe.RootNodesQuery, if !ok { // This should never happen, the two maps should be in // sync. - log.Errorf("Root key %x found in cache list but not "+ - "in map", id[:]) + log.Errorf("Root key found in cache list but not "+ + "in map (key=%x)", id[:]) r.Miss() return nil, false @@ -558,7 +622,7 @@ func (r *rootNodeCache) fetchRoots(q universe.RootNodesQuery, func (r *rootNodeCache) cacheRoots(q universe.RootNodesQuery, rootNodes []universe.Root) { - log.Debugf("caching num_roots=%v", len(rootNodes)) + log.Debugf("Caching root node (count=%v)", len(rootNodes)) // Store the main root pointer, then update the root index. rootPageCache := r.allRoots.Load() @@ -576,7 +640,7 @@ func (r *rootNodeCache) cacheRoots(q universe.RootNodesQuery, // wipeCache wipes all the cached roots. func (r *rootNodeCache) wipeCache() { - log.Debugf("wiping universe cache") + log.Debugf("Wiping universe root node cache") r.allRoots.wipe(r.cacheSize) r.rootIndex.wipe() @@ -653,8 +717,8 @@ func (u *universeLeafPageCache) fetchLeafKeys( leafKeys, err := leafPageCache.Get(newLeafQuery(q)) if err == nil { u.Hit() - log.Tracef("read leaf keys for %v from cache", - q.Id.StringForLog()) + log.Tracef("Read leaf keys from page cache "+ + "(universe_id=%v)", q.Id.StringForLog()) return *leafKeys } } @@ -672,7 +736,8 @@ func (u *universeLeafPageCache) cacheLeafKeys(q universe.UniverseLeafKeysQuery, idStr := q.Id.String() - log.Debugf("storing leaf keys for %v in cache", q.Id.StringForLog()) + log.Debugf("Storing leaf key(s) in cache (universe_id=%v)", + q.Id.StringForLog()) pageCache, err := u.leafCache.Get(idStr) if err != nil { @@ -687,21 +752,21 @@ func (u *universeLeafPageCache) cacheLeafKeys(q universe.UniverseLeafKeysQuery, if _, err := u.leafCache.Put(idStr, pageCache); err != nil { // If we encounter an error here, we'll exit to avoid a // panic below. - log.Errorf("unable to store entry in page cache: %v", + log.Errorf("Unable to store entry in page cache: %v", err) return } } - // Add the to the page cache. + // Add the cached keys to the page cache. if _, err := pageCache.Put(newLeafQuery(q), &cachedKeys); err != nil { - log.Errorf("unable to store leaf resp: %v", err) + log.Errorf("Unable to store leaf resp: %v", err) } } // wipeCache wipes the cache of leaf keys for a given universe ID. func (u *universeLeafPageCache) wipeCache(id universeIDKey) { - log.Debugf("wiping leaf keys for %s in cache", id) + log.Debugf("Wiping leaf keys from page cache (universe_id=%s)", id) u.leafCache.Delete(id) } diff --git a/tapdb/multiverse_cache_test.go b/tapdb/multiverse_cache_test.go index dd3e9bd13..083d9a123 100644 --- a/tapdb/multiverse_cache_test.go +++ b/tapdb/multiverse_cache_test.go @@ -6,6 +6,7 @@ import ( "testing" "time" + "github.com/dustin/go-humanize" "github.com/lightninglabs/taproot-assets/asset" "github.com/lightninglabs/taproot-assets/internal/test" "github.com/lightninglabs/taproot-assets/mssmt" @@ -230,6 +231,111 @@ func TestSyncerCacheMemoryUsage(t *testing.T) { } } +// TestUniverseProofCache exercises the basic behaviors of the universe proof +// cache to ensure inserts, fetches, evictions, and removals behave as +// expected. +func TestUniverseProofCache(t *testing.T) { + t.Parallel() + + // 1 MiB cache for most subtests. + const testCacheSizeBytes = 1 << 20 + + t.Run("insert and fetch", func(t *testing.T) { + cache := newUniverseProofCache(testCacheSizeBytes) + + id := randUniverseID(t, false) + leafKey := randLeafKey(t) + proofs := newTestUniverseProofs(t, 1) + + // The cache should miss until an entry is inserted. + require.Nil(t, cache.fetchProof(id, leafKey)) + require.EqualValues(t, 0, cache.hit.Load()) + require.EqualValues(t, 1, cache.miss.Load()) + + cache.insertProofs(id, leafKey, proofs) + + cached := cache.fetchProof(id, leafKey) + require.Equal(t, proofs, cached) + require.EqualValues(t, 1, cache.hit.Load()) + require.EqualValues(t, 1, cache.miss.Load()) + }) + + t.Run("eviction respects capacity", func(t *testing.T) { + // Configure the cache to hold only two entries worth of data so + // the eviction order is deterministic once a third entry + // arrives. + baseProofs := newTestUniverseProofs(t, 1) + proofSize := proofCacheEntrySize(t, baseProofs) + maxBytes := proofSize * 2 + cache := newUniverseProofCache(maxBytes) + + id := randUniverseID(t, false) + keys := []universe.LeafKey{ + randLeafKey(t), + randLeafKey(t), + randLeafKey(t), + } + + for _, key := range keys { + cache.insertProofs(id, key, cloneProofSlice(baseProofs)) + } + + require.Equal(t, 2, cache.cache.Len()) + require.LessOrEqual(t, cache.cache.Size(), maxBytes) + + // The oldest entry should have been evicted while the most + // recently inserted entries remain. + require.Nil(t, cache.fetchProof(id, keys[0])) + require.NotNil(t, cache.fetchProof(id, keys[1])) + require.NotNil(t, cache.fetchProof(id, keys[2])) + }) + + t.Run("removals", func(t *testing.T) { + cache := newUniverseProofCache(testCacheSizeBytes) + + id1 := randUniverseID(t, false) + id2 := randUniverseID(t, false) + + leaf1 := randLeafKey(t) + leaf2 := randLeafKey(t) + + cache.insertProofs(id1, leaf1, newTestUniverseProofs(t, 1)) + cache.insertProofs(id1, leaf2, newTestUniverseProofs(t, 1)) + cache.insertProofs(id2, leaf1, newTestUniverseProofs(t, 1)) + + cache.RemoveLeafKeyProofs(id1, leaf1) + require.Nil(t, cache.fetchProof(id1, leaf1)) + require.NotNil(t, cache.fetchProof(id1, leaf2)) + require.NotNil(t, cache.fetchProof(id2, leaf1)) + + cache.RemoveUniverseProofs(id1) + require.Nil(t, cache.fetchProof(id1, leaf2)) + require.NotNil(t, cache.fetchProof(id2, leaf1)) + }) + + t.Run("cache logger default size formatting", func(t *testing.T) { + cache := newUniverseProofCache(testCacheSizeBytes) + + require.NotNil(t, cache.cacheLogger.cacheSize) + require.Equal( + t, humanize.Bytes(0), cache.cacheLogger.cacheSize(), + ) + + id := randUniverseID(t, false) + leafKey := randLeafKey(t) + proofs := newTestUniverseProofs(t, 1) + + cache.insertProofs(id, leafKey, proofs) + require.Equal(t, humanize.Bytes(cache.cache.Size()), + cache.cacheLogger.cacheSize()) + + cache.RemoveLeafKeyProofs(id, leafKey) + require.Equal( + t, humanize.Bytes(0), cache.cacheLogger.cacheSize(), + ) + }) +} + func queryRoots(t *testing.T, multiverse *MultiverseStore, pageSize int32) []universe.Root { @@ -275,3 +381,49 @@ func assertAllLeavesInRoots(t *testing.T, allLeaves []*universe.Item, "idx %d", leaf.ID.StringForLog(), idx) } } + +// newTestUniverseProofs returns a slice of random universe proofs for use in +// cache tests. +func newTestUniverseProofs(t *testing.T, count int) []*universe.Proof { + t.Helper() + + proofs := make([]*universe.Proof, count) + for i := 0; i < count; i++ { + leaf := randMintingLeaf( + t, asset.RandGenesis(t, asset.Normal), nil, + ) + leafCopy := leaf + + proofs[i] = &universe.Proof{ + Leaf: &leafCopy, + LeafKey: randLeafKey(t), + UniverseRoot: leafCopy.SmtLeafNode(), + UniverseInclusionProof: &mssmt.Proof{}, + MultiverseRoot: leafCopy.SmtLeafNode(), + MultiverseInclusionProof: &mssmt.Proof{}, + } + } + + return proofs +} + +// proofCacheEntrySize returns the computed cache size for a single cache entry. +func proofCacheEntrySize(t *testing.T, proofs []*universe.Proof) uint64 { + t.Helper() + + cached := cachedProofs(proofs) + size, err := (&cached).Size() + require.NoError(t, err) + require.NotZero(t, size) + + return size +} + +// cloneProofSlice returns a shallow copy of the provided proof slice so that +// callers can reuse deterministic proof fixtures without sharing slice headers. +func cloneProofSlice(proofs []*universe.Proof) []*universe.Proof { + cloned := make([]*universe.Proof, len(proofs)) + copy(cloned, proofs) + + return cloned +} diff --git a/tapdb/sqlc/addrs.sql.go b/tapdb/sqlc/addrs.sql.go index f5a51d9dc..cd9a554b5 100644 --- a/tapdb/sqlc/addrs.sql.go +++ b/tapdb/sqlc/addrs.sql.go @@ -408,12 +408,15 @@ SELECT FROM addr_events JOIN addrs ON addr_events.addr_id = addrs.id -WHERE addr_events.status >= $1 +WHERE addr_events.status >= $1 AND addr_events.status <= $2 AND COALESCE($3, addrs.taproot_output_key) = addrs.taproot_output_key AND addr_events.creation_time >= $4 AND addr_events.creation_time <= $5 -ORDER by addr_events.creation_time +ORDER BY + CASE WHEN $6 = 1 THEN addr_events.creation_time END DESC, + CASE WHEN $6 != 1 THEN addr_events.creation_time END ASC +LIMIT $8 OFFSET $7 ` type QueryEventIDsParams struct { @@ -422,6 +425,9 @@ type QueryEventIDsParams struct { AddrTaprootKey []byte CreatedAfter time.Time CreatedBefore time.Time + SortDirection interface{} + NumOffset int32 + NumLimit int32 } type QueryEventIDsRow struct { @@ -436,6 +442,9 @@ func (q *Queries) QueryEventIDs(ctx context.Context, arg QueryEventIDsParams) ([ arg.AddrTaprootKey, arg.CreatedAfter, arg.CreatedBefore, + arg.SortDirection, + arg.NumOffset, + arg.NumLimit, ) if err != nil { return nil, err diff --git a/tapdb/sqlc/queries/addrs.sql b/tapdb/sqlc/queries/addrs.sql index 6e8167238..b5310ccd2 100644 --- a/tapdb/sqlc/queries/addrs.sql +++ b/tapdb/sqlc/queries/addrs.sql @@ -222,12 +222,15 @@ SELECT FROM addr_events JOIN addrs ON addr_events.addr_id = addrs.id -WHERE addr_events.status >= @status_from +WHERE addr_events.status >= @status_from AND addr_events.status <= @status_to AND COALESCE(@addr_taproot_key, addrs.taproot_output_key) = addrs.taproot_output_key AND addr_events.creation_time >= @created_after AND addr_events.creation_time <= @created_before -ORDER by addr_events.creation_time; +ORDER BY + CASE WHEN sqlc.narg('sort_direction') = 1 THEN addr_events.creation_time END DESC, + CASE WHEN sqlc.narg('sort_direction') != 1 THEN addr_events.creation_time END ASC +LIMIT @num_limit OFFSET @num_offset; -- name: QueryLastEventHeight :one SELECT cast(coalesce(max(chain_txns.block_height), 0) AS BIGINT) AS last_height diff --git a/tapdb/sqlutils_test.go b/tapdb/sqlutils_test.go index 5d8c5c7d5..16320b18e 100644 --- a/tapdb/sqlutils_test.go +++ b/tapdb/sqlutils_test.go @@ -241,7 +241,7 @@ func (d *DbHandler) AddRandomServerAddrs(t *testing.T, } // newDbHandleFromDb creates a new database store handle given a database store. -func newDbHandleFromDb(db *BaseDB) *DbHandler { +func newDbHandleFromDb(t *testing.T, db *BaseDB) *DbHandler { testClock := clock.NewTestClock(time.Now()) // Gain a handle to the pending (minting) universe federation store. @@ -258,9 +258,10 @@ func newDbHandleFromDb(db *BaseDB) *DbHandler { return db.WithTx(tx) }, ) - multiverseStore := NewMultiverseStore( + multiverseStore, err := NewMultiverseStore( multiverseTxCreator, DefaultMultiverseStoreConfig(), ) + require.NoError(t, err) // Gain a handle to the pending (minting) assets store. assetMintingDB := NewTransactionExecutor( @@ -301,12 +302,12 @@ func newDbHandleFromDb(db *BaseDB) *DbHandler { // path. func NewDbHandleFromPath(t *testing.T, dbPath string) *DbHandler { db := NewTestDbHandleFromPath(t, dbPath) - return newDbHandleFromDb(db.BaseDB) + return newDbHandleFromDb(t, db.BaseDB) } // NewDbHandle creates a new database store handle. func NewDbHandle(t *testing.T) *DbHandler { // Create a new test database with the default database file path. db := NewTestDB(t) - return newDbHandleFromDb(db.BaseDB) + return newDbHandleFromDb(t, db.BaseDB) } diff --git a/tapdb/universe_test.go b/tapdb/universe_test.go index 87b26b03b..0b3f2ef6a 100644 --- a/tapdb/universe_test.go +++ b/tapdb/universe_test.go @@ -93,17 +93,29 @@ func newTestMultiverse(t testing.TB) (*MultiverseStore, sqlc.Querier) { }, ) - return NewMultiverseStore(dbTxer, DefaultMultiverseStoreConfig()), db + multiverseStore, err := NewMultiverseStore( + dbTxer, DefaultMultiverseStoreConfig(), + ) + require.NoError(t, err) + + return multiverseStore, db } -func newTestMultiverseWithDb(db *BaseDB) (*MultiverseStore, sqlc.Querier) { +func newTestMultiverseWithDb(t *testing.T, db *BaseDB) (*MultiverseStore, + sqlc.Querier) { + dbTxer := NewTransactionExecutor( db, func(tx *sql.Tx) BaseMultiverseStore { return db.WithTx(tx) }, ) - return NewMultiverseStore(dbTxer, DefaultMultiverseStoreConfig()), db + multiverseStore, err := NewMultiverseStore( + dbTxer, DefaultMultiverseStoreConfig(), + ) + require.NoError(t, err) + + return multiverseStore, db } func newTestUniverseWithDb(db *BaseDB, @@ -262,7 +274,7 @@ func TestUniverseIssuanceProofs(t *testing.T) { ) db := NewTestDB(t) baseUniverse, _ := newTestUniverseWithDb(db.BaseDB, id) - multiverse, _ := newTestMultiverseWithDb(db.BaseDB) + multiverse, _ := newTestMultiverseWithDb(t, db.BaseDB) const numLeaves = 4 @@ -558,9 +570,10 @@ func TestUniverseTreeIsolation(t *testing.T) { return db.WithTx(tx) }, ) - multiverse := NewMultiverseStore( + multiverse, err := NewMultiverseStore( multiverseDB, DefaultMultiverseStoreConfig(), ) + require.NoError(t, err) rootNodes, err := multiverse.RootNodes( ctx, universe.RootNodesQuery{ @@ -620,7 +633,7 @@ func TestUniverseTreeIsolation(t *testing.T) { // TODO(roasbeef): need base universe -> universe cache // invalidation or delete thru multiverse multiverse.rootNodeCache.wipeCache() - multiverse.proofCache.delProofsForAsset(rootNode.ID) + multiverse.proofCache.RemoveUniverseProofs(rootNode.ID) } // The deleted universe should not be present in the multiverse. diff --git a/tapfreighter/fund.go b/tapfreighter/fund.go index 8926c0bad..b9dbee61f 100644 --- a/tapfreighter/fund.go +++ b/tapfreighter/fund.go @@ -138,15 +138,6 @@ func createFundedPacketWithInputs(ctx context.Context, exporter proof.Exporter, "internal keys: %w", err) } - for _, vPkt := range allPackets { - if err := tapsend.PrepareOutputAssets(ctx, vPkt); err != nil { - log.Errorf("Error preparing output assets: %v, "+ - "packets: %v", err, limitSpewer.Sdump(vPkt)) - return nil, fmt.Errorf("unable to prepare outputs: %w", - err) - } - } - // Extract just the TAP commitments by input from the selected anchored // commitments. inputCommitments := make( diff --git a/tapfreighter/wallet.go b/tapfreighter/wallet.go index 13da9efdc..aeeec1868 100644 --- a/tapfreighter/wallet.go +++ b/tapfreighter/wallet.go @@ -5,7 +5,6 @@ import ( "errors" "fmt" "net/url" - "slices" "time" "github.com/btcsuite/btcd/blockchain" @@ -684,6 +683,16 @@ func (f *AssetWallet) FundPacket(ctx context.Context, return nil, err } + for _, vPkt := range pkt.VPackets { + if err := tapsend.PrepareOutputAssets(ctx, vPkt); err != nil { + log.Errorf("Error preparing output assets: %v, "+ + "packets: %v", err, limitSpewer.Sdump(vPkt)) + + return nil, fmt.Errorf("unable to prepare outputs: %w", + err) + } + } + success = true return pkt, nil } @@ -693,12 +702,6 @@ func (f *AssetWallet) FundPacket(ctx context.Context, func (f *AssetWallet) FundBurn(ctx context.Context, fundDesc *tapsend.FundingDescriptor) (*FundedVPacket, error) { - // Extract the asset ID and group key from the funding descriptor. - assetId, err := fundDesc.AssetSpecifier.UnwrapIdOrErr() - if err != nil { - return nil, err - } - // We need to find a commitment that has enough assets to satisfy this // send request. We'll map the address to a set of constraints, so we // can use that to do Taproot asset coin selection. @@ -733,11 +736,10 @@ func (f *AssetWallet) FundBurn(ctx context.Context, } }() - activeAssets := fn.Filter( - selectedCommitments, func(c *AnchoredCommitment) bool { - return c.Asset.ID() == assetId - }, - ) + // Determine the highest asset version across all selected inputs. We'll + // use this as a default for the output version; we'll refine per packet + // later once inputs are assigned. + activeAssets := selectedCommitments maxVersion := asset.V0 for _, activeAsset := range activeAssets { @@ -746,52 +748,23 @@ func (f *AssetWallet) FundBurn(ctx context.Context, } } - // Now that we know what inputs we're going to spend, we know that by - // definition, we use the first input's info as the burn's PrevID. But - // to know which input will actually be assigned as the first input in - // the allocated virtual packet, we first apply the same sorting that - // the allocation code will also apply. - slices.SortFunc(activeAssets, func(a, b *AnchoredCommitment) int { - return tapsend.AssetSortForInputs(*a.Asset, *b.Asset) - }) - firstInput := activeAssets[0] - firstPrevID := asset.PrevID{ - OutPoint: firstInput.AnchorPoint, - ID: firstInput.Asset.ID(), - ScriptKey: asset.ToSerialized( - firstInput.Asset.ScriptKey.PubKey, - ), - } - burnKey := asset.NewScriptKey(asset.DeriveBurnKey(firstPrevID)) - newInternalKey, err := f.cfg.KeyRing.DeriveNextKey( - ctx, asset.TaprootAssetsKeyFamily, - ) - if err != nil { - return nil, err - } - // We want both the burn output and the change to be in the same anchor // output, that's why we create the packet manually. vPkt := &tappsbt.VPacket{ - Inputs: []*tappsbt.VInput{{ - PrevID: asset.PrevID{ - ID: assetId, - }, - }}, + // No inputs are set here; they'll be populated during funding. Outputs: []*tappsbt.VOutput{{ Amount: fundDesc.Amount, Type: tappsbt.TypeSimple, Interactive: true, AnchorOutputIndex: 0, AssetVersion: maxVersion, - ScriptKey: burnKey, + // We'll set the burn script key per packet after + // inputs are selected so we use a placeholder here. + ScriptKey: asset.NUMSScriptKey, }}, ChainParams: f.cfg.ChainParams, Version: tappsbt.V1, } - vPkt.Outputs[0].SetAnchorInternalKey( - newInternalKey, f.cfg.ChainParams.HDCoinType, - ) // The virtual transaction is now ready to be further enriched with the // split commitment and other data. @@ -803,11 +776,41 @@ func (f *AssetWallet) FundBurn(ctx context.Context, return nil, err } - // We don't support burning by group key yet, so we only expect a single - // vPacket (which implies a single asset ID is involved). - if len(fundedPkt.VPackets) != 1 { - return nil, fmt.Errorf("expected a single vPacket, got %d", - len(fundedPkt.VPackets)) + // Now that inputs are assigned, set the proper burn script key and + // output versions per virtual packet, and build the outputs. + for _, pkt := range fundedPkt.VPackets { + if len(pkt.Inputs) == 0 { + return nil, fmt.Errorf("no inputs in funded burn +" + + "packet") + } + + // Determine the per-packet max asset version from its inputs. + pktMaxVersion := asset.V0 + for _, in := range pkt.Inputs { + if in.Asset().Version > pktMaxVersion { + pktMaxVersion = in.Asset().Version + } + } + + // The burn output is the interactive, non-split output. + for _, out := range pkt.Outputs { + if out.Type.IsSplitRoot() || !out.Interactive { + continue + } + + // Compute burn key from the first input's PrevID. + firstPrevID := pkt.Inputs[0].PrevID + burnKey := asset.NewScriptKey( + asset.DeriveBurnKey(firstPrevID), + ) + out.ScriptKey = burnKey + out.AssetVersion = pktMaxVersion + } + + if err := tapsend.PrepareOutputAssets(ctx, pkt); err != nil { + return nil, fmt.Errorf("unable to prepare burn + "+ + "outputs: %w", err) + } } // Don't release the coins we've selected, as so far we've been diff --git a/tapgarden/batch_test.go b/tapgarden/batch_test.go index 1cf277dfc..096e61370 100644 --- a/tapgarden/batch_test.go +++ b/tapgarden/batch_test.go @@ -110,13 +110,13 @@ func TestValidateUniCommitment(t *testing.T) { // Ensures that a group anchor candidate seedling // with universe commitments can be added to an empty // batch. - name: "empty batch; candidate seedling is group " + - "anchor; is valid", + name: "empty unfunded batch; candidate seedling is " + + "group anchor; is valid", candidateSeedling: RandGroupAnchorSeedling( t, "some-anchor-name", true, ), - batch: RandMintingBatch(t), + batch: RandMintingBatch(t, WithSkipFunding()), expectErr: false, }, } diff --git a/tapgarden/custodian_test.go b/tapgarden/custodian_test.go index 5f77fa03e..f9a9d0c0f 100644 --- a/tapgarden/custodian_test.go +++ b/tapgarden/custodian_test.go @@ -136,9 +136,10 @@ func newProofArchiveForDB(t *testing.T, db *tapdb.BaseDB) (*proof.MultiArchiver, return db.WithTx(tx) }, ) - multiverse := tapdb.NewMultiverseStore( + multiverse, err := tapdb.NewMultiverseStore( multiverseDB, tapdb.DefaultMultiverseStoreConfig(), ) + require.NoError(t, err) return proofArchive, assetStore, multiverse } diff --git a/tapgarden/interface.go b/tapgarden/interface.go index bea9618f3..9f07369b3 100644 --- a/tapgarden/interface.go +++ b/tapgarden/interface.go @@ -348,7 +348,7 @@ type ChainBridge interface { // GetBlockTimestamp returns the timestamp of the block at the given // height. - GetBlockTimestamp(context.Context, uint32) int64 + GetBlockTimestamp(context.Context, uint32) (int64, error) // GetBlockHeaderByHeight returns a block header given the block height. GetBlockHeaderByHeight(ctx context.Context, diff --git a/tapgarden/mock.go b/tapgarden/mock.go index 1b228dae1..7c06340a2 100644 --- a/tapgarden/mock.go +++ b/tapgarden/mock.go @@ -22,6 +22,7 @@ import ( "github.com/btcsuite/btcd/wire" "github.com/btcsuite/btcwallet/waddrmgr" "github.com/lightninglabs/lndclient" + "github.com/lightninglabs/taproot-assets/address" "github.com/lightninglabs/taproot-assets/asset" "github.com/lightninglabs/taproot-assets/fn" "github.com/lightninglabs/taproot-assets/internal/test" @@ -163,6 +164,9 @@ type MintBatchOptions struct { // universeCommitments specifies whether to generate universe // commitments for the asset groups in this minting batch. universeCommitments bool + + // skipFunding specifies whether to skip funding the genesis PSBT. + skipFunding bool } // MintBatchOption is a functional option for creating a new minting batch. @@ -198,6 +202,13 @@ func WithUniverseCommitments(enabled bool) MintBatchOption { } } +// WithSkipFunding specifies whether to skip funding the genesis PSBT. +func WithSkipFunding() MintBatchOption { + return func(options *MintBatchOptions) { + options.skipFunding = true + } +} + // RandMintingBatch creates a new minting batch with only random seedlings // populated for testing. func RandMintingBatch(t testing.TB, opts ...MintBatchOption) *MintingBatch { @@ -259,6 +270,32 @@ func RandMintingBatch(t testing.TB, opts ...MintBatchOption) *MintingBatch { // requested amount. This check might help debug flakes in tests. require.Equal(t, options.totalSeedlings, len(batch.Seedlings)) + // Return early if funding is to be skipped. + if options.skipFunding { + return batch + } + + walletFundPsbt := func(ctx context.Context, + anchorPkt psbt.Packet) (tapsend.FundedPsbt, error) { + + changeOutputIdx := FundGenesisTx( + &anchorPkt, chainfee.FeePerKwFloor, + ) + + return tapsend.FundedPsbt{ + Pkt: &anchorPkt, + ChangeOutputIndex: int32(changeOutputIdx), + }, nil + } + + // Fund genesis packet. + ctx := context.Background() + fundedPsbt, err := fundGenesisPsbt( + ctx, address.TestNet3Tap, batch, walletFundPsbt, + ) + require.NoError(t, err) + batch.GenesisPacket = &fundedPsbt + return batch } @@ -286,29 +323,6 @@ func RandSeedlings(t testing.TB, numSeedlings int) map[string]*Seedling { return seedlings } -// RandSeedlingMintingBatch creates a new minting batch with only random -// seedlings populated for testing. -// -// TODO(ffranr): Replace this function with RandMintingBatch. Note also function -// addRandGroupToBatch. -func RandSeedlingMintingBatch(t testing.TB, numSeedlings int) *MintingBatch { - genesisTx := NewGenesisTx(t, chainfee.FeePerKwFloor) - BatchKey, _ := test.RandKeyDesc(t) - return &MintingBatch{ - BatchKey: BatchKey, - Seedlings: RandSeedlings(t, numSeedlings), - HeightHint: test.RandInt[uint32](), - CreationTime: time.Now(), - GenesisPacket: &FundedMintAnchorPsbt{ - FundedPsbt: tapsend.FundedPsbt{ - Pkt: &genesisTx, - ChangeOutputIndex: 1, - }, - AssetAnchorOutIdx: 0, - }, - } -} - type MockWalletAnchor struct { FundPsbtSignal chan *tapsend.FundedPsbt SignPsbtSignal chan struct{} @@ -345,8 +359,9 @@ func NewGenesisTx(t testing.TB, feeRate chainfee.SatPerKWeight) psbt.Packet { return *genesisPkt } -// FundGenesisTx add a genesis input and change output to a 1-output TX. -func FundGenesisTx(packet *psbt.Packet, feeRate chainfee.SatPerKWeight) { +// FundGenesisTx add a genesis input and change output to a 1-output TX and +// returns the index of the change output. +func FundGenesisTx(packet *psbt.Packet, feeRate chainfee.SatPerKWeight) uint32 { const anchorBalance = int64(100000) // Take the PSBT packet and add an additional input and output to @@ -382,7 +397,10 @@ func FundGenesisTx(packet *psbt.Packet, feeRate chainfee.SatPerKWeight) { [][]byte{tapsend.GenesisDummyScript}, packet.UnsignedTx.TxOut, feeRate, ) - packet.UnsignedTx.TxOut[1].Value -= int64(fee) + changeOutputIdx := len(packet.UnsignedTx.TxOut) - 1 + packet.UnsignedTx.TxOut[changeOutputIdx].Value -= int64(fee) + + return uint32(changeOutputIdx) } // FundPsbt funds a PSBT. @@ -716,8 +734,10 @@ func (m *MockChainBridge) CurrentHeight(_ context.Context) (uint32, error) { return 0, nil } -func (m *MockChainBridge) GetBlockTimestamp(_ context.Context, _ uint32) int64 { - return 0 +func (m *MockChainBridge) GetBlockTimestamp(_ context.Context, _ uint32) (int64, + error) { + + return 0, nil } func (m *MockChainBridge) PublishTransaction(_ context.Context, diff --git a/tapgarden/planter.go b/tapgarden/planter.go index 6a5a414da..ca3366495 100644 --- a/tapgarden/planter.go +++ b/tapgarden/planter.go @@ -921,24 +921,101 @@ func fetchPreCommitGroupKey( return fn.Some(groupAnchorSeedling.GroupInfo.GroupPubKey), nil } +// anchorTxFeeRate computes the fee rate for the anchor transaction. If a fee +// rate is manually assigned for the batch, it is used. Otherwise, the fee rate +// is estimated based on the current network conditions. +func (c *ChainPlanter) anchorTxFeeRate(ctx context.Context, + manualFeeRateOpt fn.Option[chainfee.SatPerKWeight]) ( + chainfee.SatPerKWeight, error) { + + var zero chainfee.SatPerKWeight + + // First, we'll fetch the minimum relay fee for the target chain. + // We'll use this to ensure that the fee rate we use meets the + // minimum requirements. + minRelayFee, err := c.cfg.Wallet.MinRelayFee(ctx) + if err != nil { + return zero, fmt.Errorf("unable to obtain min relay fee: %w", + err) + } + + // If provided and valid, use the manual fee rate. + if manualFeeRateOpt.IsSome() { + manualFeeRate, err := manualFeeRateOpt.UnwrapOrErr( + fmt.Errorf("code error: no manual fee rate"), + ) + if err != nil { + return zero, err + } + + log.Debug("Manual fee rate specified for batch anchor tx: %s", + manualFeeRate.String()) + + // Ensure that the manual fee rate is above the minimum relay + // fee. + if manualFeeRate < minRelayFee { + return zero, fmt.Errorf("manual fee rate less than "+ + "min relay fee: (manual_fee_rate=%s, "+ + "min_relay_fee=%s)", manualFeeRate.String(), + minRelayFee.String()) + } + + return manualFeeRate, nil + } + + log.Debug("No manual fee rate specified for batch, " + + "querying chain backend for fee rate") + + // We'll ask the chain backend to estimate a fee rate that should get + // the batch anchor tx into the next block. + chainFeeRate, err := c.cfg.ChainBridge.EstimateFee( + ctx, GenesisConfTarget, + ) + if err != nil { + return zero, fmt.Errorf("failed to call chain backend for "+ + "fee estimate: %w", err) + } + + log.Debugf("Chain backend returned fee rate: %s", chainFeeRate.String()) + + // If the chain backend provided fee rate is less than the minimum relay + // fee, we'll use the min relay fee instead. + if chainFeeRate < minRelayFee { + log.Debugf("Chain backend provided fee rate less than min "+ + "relay fee, using min relay fee "+ + "(chain_backend_fee_rate=%s, min_relay_fee=%s)", + chainFeeRate.String(), minRelayFee.String()) + return minRelayFee, nil + } + + // Otherwise, we'll use the fee rate as provided by the chain + // backend. + log.Debugf("Using fee rate from chain backend: %s", + chainFeeRate.String()) + return chainFeeRate, nil +} + +// WalletFundPsbt is a function that funds a PSBT packet. +type WalletFundPsbt = func(ctx context.Context, + anchorPkt psbt.Packet) (tapsend.FundedPsbt, error) + // fundGenesisPsbt generates a PSBT packet we'll use to create an asset. In // order to be able to create an asset, we need an initial genesis outpoint. To // obtain this we'll ask the wallet to fund a PSBT template for GenesisAmtSats // (all outputs need to hold some BTC to not be dust), and with a dummy script. // We need to use a dummy script as we can't know the actual script key since // that's dependent on the genesis outpoint. -func (c *ChainPlanter) fundGenesisPsbt(ctx context.Context, - batchKey asset.SerializedKey, - manualFeeRate *chainfee.SatPerKWeight) (FundedMintAnchorPsbt, error) { +func fundGenesisPsbt(ctx context.Context, chainParams address.ChainParams, + pendingBatch *MintingBatch, + walletFundPsbt WalletFundPsbt) (FundedMintAnchorPsbt, error) { var zero FundedMintAnchorPsbt - log.Infof("Attempting to fund batch: %x", batchKey) // If universe commitments are enabled, we formulate a pre-commitment // output. This output is spent by the universe commitment transaction. var delegationKey fn.Option[DelegationKey] - if c.pendingBatch != nil && c.pendingBatch.SupplyCommitments { - delegationK, err := fetchDelegationKey(c.pendingBatch) + if pendingBatch != nil && pendingBatch.SupplyCommitments { + delegationK, err := fetchDelegationKey(pendingBatch) if err != nil { return zero, fmt.Errorf("unable to create "+ "pre-commitment output: %w", err) @@ -975,59 +1052,7 @@ func (c *ChainPlanter) fundGenesisPsbt(ctx context.Context, } log.Tracef("Unfunded batch anchor PSBT: %v", spew.Sdump(genesisPkt)) - // Compute the anchor transaction fee rate. - var feeRate chainfee.SatPerKWeight - switch { - // If a fee rate was manually assigned for this batch, use that instead - // of a fee rate estimate. - case manualFeeRate != nil: - feeRate = *manualFeeRate - log.Infof("using manual fee rate for batch: %x, %s, %d sat/vB", - batchKey[:], feeRate.String(), - feeRate.FeePerKVByte()/1000) - - default: - feeRate, err = c.cfg.ChainBridge.EstimateFee( - ctx, GenesisConfTarget, - ) - if err != nil { - return zero, fmt.Errorf("unable to estimate fee: %w", - err) - } - - log.Infof("estimated fee rate for batch: %x, %s", - batchKey[:], feeRate.FeePerKVByte().String()) - } - - minRelayFee, err := c.cfg.Wallet.MinRelayFee(ctx) - if err != nil { - return zero, fmt.Errorf("unable to obtain minrelayfee: %w", err) - } - - // If the fee rate is below the minimum relay fee, we'll - // bump it up. - if feeRate < minRelayFee { - switch { - // If a fee rate was manually assigned for this batch, we err - // out, otherwise we silently bump the feerate. - case manualFeeRate != nil: - // This case should already have been handled by the - // `checkFeeRateSanity` of `rpcserver.go`. We check here - // again to be safe. - return zero, fmt.Errorf("feerate does not meet "+ - "minrelayfee: (fee_rate=%s, minrelayfee=%s)", - feeRate.String(), minRelayFee.String()) - default: - log.Infof("Bump fee rate for batch %x to meet "+ - "minrelayfee from %s to %s", batchKey[:], - feeRate.String(), minRelayFee.String()) - feeRate = minRelayFee - } - } - - fundedGenesisPkt, err := c.cfg.Wallet.FundPsbt( - ctx, &genesisPkt, 1, feeRate, -1, - ) + fundedGenesisPkt, err := walletFundPsbt(ctx, genesisPkt) if err != nil { return zero, fmt.Errorf("unable to fund psbt: %w", err) } @@ -1038,12 +1063,11 @@ func (c *ChainPlanter) fundGenesisPsbt(ctx context.Context, "funded anchor transaction") } - log.Infof("Funded GenesisPacket for batch: %x", batchKey) log.Tracef("GenesisPacket: %v", spew.Sdump(fundedGenesisPkt)) // Classify anchor transaction output indexes. anchorOutIndexes, err := anchorTxOutputIndexes( - *fundedGenesisPkt, preCommitmentTxOut, + fundedGenesisPkt, preCommitmentTxOut, ) if err != nil { return zero, fmt.Errorf("unable to determine output indexes: "+ @@ -1076,7 +1100,7 @@ func (c *ChainPlanter) fundGenesisPsbt(ctx context.Context, // If there is a group pub key to associate with the pre-commitment // output, fetch it now. - preCommitGroupPubKey, err := fetchPreCommitGroupKey(c.pendingBatch) + preCommitGroupPubKey, err := fetchPreCommitGroupKey(pendingBatch) if err != nil { return zero, fmt.Errorf("unable to fetch pre-commitment "+ "group key: %w", err) @@ -1110,7 +1134,7 @@ func (c *ChainPlanter) fundGenesisPsbt(ctx context.Context, // we just need to set the corresponding fields in the PSBT. bip32Derivation, trBip32Derivation := tappsbt.Bip32DerivationFromKeyDesc( - dKey, c.cfg.ChainParams.HDCoinType, + dKey, chainParams.HDCoinType, ) pOut := &fundedGenesisPkt.Pkt.Outputs[outIdx] @@ -1124,7 +1148,7 @@ func (c *ChainPlanter) fundGenesisPsbt(ctx context.Context, // Formulate a funded minting anchor PSBT from the funded PSBT. fundedMintAnchorPsbt, err := NewFundedMintAnchorPsbt( - *fundedGenesisPkt, anchorOutIndexes, preCommitOut, + fundedGenesisPkt, anchorOutIndexes, preCommitOut, ) if err != nil { return zero, fmt.Errorf("unable to create funded minting "+ @@ -2104,7 +2128,6 @@ func (c *ChainPlanter) fundBatch(ctx context.Context, params FundParams, workingBatch *MintingBatch) error { var ( - feeRate *chainfee.SatPerKWeight rootHash *chainhash.Hash err error ) @@ -2112,7 +2135,6 @@ func (c *ChainPlanter) fundBatch(ctx context.Context, params FundParams, // If a tapscript tree was specified for this batch, we'll store it on // disk. The caretaker we start for this batch will use it when deriving // the final Taproot output key. - feeRate = params.FeeRate.UnwrapToPtr() params.SiblingTapTree.WhenSome(func(tn asset.TapscriptTreeNodes) { rootHash, err = c.cfg.TreeStore.StoreTapscriptTree(ctx, tn) }) @@ -2130,13 +2152,42 @@ func (c *ChainPlanter) fundBatch(ctx context.Context, params FundParams, } // Fund the batch with the specified fee rate. + feeRate, err := c.anchorTxFeeRate(ctx, params.FeeRate) + if err != nil { + return fmt.Errorf("unable to determine anchor TX "+ + "fee rate: %w", err) + } + batchKey := asset.ToSerialized(batch.BatchKey.PubKey) - mintAnchorTx, err := c.fundGenesisPsbt(ctx, batchKey, feeRate) + + // walletFundPsbt is a closure that will be used to fund the + // batch with the specified fee rate. + walletFundPsbt := func(ctx context.Context, + anchorPkt psbt.Packet) (tapsend.FundedPsbt, error) { + + var zero tapsend.FundedPsbt + + fundedPkt, err := c.cfg.Wallet.FundPsbt( + ctx, &anchorPkt, 1, feeRate, -1, + ) + if err != nil { + return zero, err + } + + return *fundedPkt, nil + } + + log.Infof("Attempting to fund batch: %x", batchKey) + mintAnchorTx, err := fundGenesisPsbt( + ctx, c.cfg.ChainParams, c.pendingBatch, + walletFundPsbt, + ) if err != nil { return fmt.Errorf("unable to fund minting PSBT for "+ "batch: %x %w", batchKey[:], err) } + log.Infof("Funded GenesisPacket for batch: %x", batchKey) batch.GenesisPacket = &mintAnchorTx return nil diff --git a/tapgarden/planter_test.go b/tapgarden/planter_test.go index 87a8e5932..fda87662e 100644 --- a/tapgarden/planter_test.go +++ b/tapgarden/planter_test.go @@ -1484,7 +1484,7 @@ func testFinalizeBatch(t *mintingTestHarness) { t.assertNoPendingBatch() t.assertNumCaretakersActive(caretakerCount) t.assertLastBatchState(batchCount, tapgarden.BatchStateFrozen) - t.assertFinalizeBatch(&wg, respChan, "unable to estimate fee") + t.assertFinalizeBatch(&wg, respChan, "failed to estimate fee") // Queue another batch, reset fee estimation behavior, and set TX // confirmation registration to fail. diff --git a/taprpc/perms.go b/taprpc/perms.go index 056ad0ecf..e4e891c23 100644 --- a/taprpc/perms.go +++ b/taprpc/perms.go @@ -183,6 +183,10 @@ var ( Entity: "mint", Action: "read", }}, + "/universerpc.Universe/Info": {{ + Entity: "universe", + Action: "read", + }}, "/universerpc.Universe/MultiverseRoot": {{ Entity: "universe", Action: "read", @@ -339,22 +343,10 @@ var ( Entity: "mailbox", Action: "read", }}, - "/authmailboxrpc.Mailbox/MailboxInfo": {{}}, - } - - // defaultMacaroonWhitelist defines a default set of RPC endpoints that - // don't require macaroons authentication. - // - // For now, these are the Universe related read/write methods. We permit - // InsertProof as a valid proof requires an on-chain transaction, so we - // gain a layer of DoS defense. - defaultMacaroonWhitelist = map[string]struct{}{ - "/universerpc.Universe/AssetRoots": {}, - "/universerpc.Universe/QueryAssetRoots": {}, - "/universerpc.Universe/AssetLeafKeys": {}, - "/universerpc.Universe/AssetLeaves": {}, - "/universerpc.Universe/Info": {}, - "/authmailboxrpc.Mailbox/MailboxInfo": {}, + "/authmailboxrpc.Mailbox/MailboxInfo": {{ + Entity: "mailbox", + Action: "read", + }}, } ) @@ -364,34 +356,63 @@ func MacaroonWhitelist(allowUniPublicAccessRead bool, allowUniPublicAccessWrite bool, allowPublicUniProofCourier bool, allowPublicStats bool) map[string]struct{} { - // Make a copy of the default whitelist. whitelist := make(map[string]struct{}) - for k, v := range defaultMacaroonWhitelist { - whitelist[k] = v + + // addEndpoints adds the given endpoints to the whitelist map. + addEndpoints := func(endpoints ...string) { + for _, endpoint := range endpoints { + whitelist[endpoint] = struct{}{} + } } // Conditionally whitelist universe server read methods. - // nolint: lll - if allowUniPublicAccessRead || allowPublicUniProofCourier { - whitelist["/universerpc.Universe/QueryProof"] = struct{}{} - whitelist["/universerpc.Universe/FetchSupplyCommit"] = struct{}{} - whitelist["/universerpc.Universe/FetchSupplyLeaves"] = struct{}{} - whitelist["/authmailboxrpc.Mailbox/ReceiveMessages"] = struct{}{} + if allowUniPublicAccessRead { + addEndpoints( + "/universerpc.Universe/Info", + + "/universerpc.Universe/AssetRoots", + "/universerpc.Universe/QueryAssetRoots", + "/universerpc.Universe/AssetLeafKeys", + "/universerpc.Universe/AssetLeaves", + "/universerpc.Universe/QueryProof", + + "/universerpc.Universe/FetchSupplyCommit", + "/universerpc.Universe/FetchSupplyLeaves", + + "/authmailboxrpc.Mailbox/MailboxInfo", + "/authmailboxrpc.Mailbox/ReceiveMessages", + ) } // Conditionally whitelist universe server write methods. - // nolint: lll - if allowUniPublicAccessWrite || allowPublicUniProofCourier { - whitelist["/universerpc.Universe/InsertProof"] = struct{}{} - whitelist["/universerpc.Universe/InsertSupplyCommit"] = struct{}{} - whitelist["/authmailboxrpc.Mailbox/SendMessage"] = struct{}{} + if allowUniPublicAccessWrite { + addEndpoints( + "/universerpc.Universe/InsertProof", + "/universerpc.Universe/InsertSupplyCommit", + "/authmailboxrpc.Mailbox/SendMessage", + ) } // Conditionally add public stats RPC endpoints to the whitelist. if allowPublicStats { - whitelist["/universerpc.Universe/QueryAssetStats"] = struct{}{} - whitelist["/universerpc.Universe/UniverseStats"] = struct{}{} - whitelist["/universerpc.Universe/QueryEvents"] = struct{}{} + addEndpoints( + "/universerpc.Universe/QueryAssetStats", + "/universerpc.Universe/UniverseStats", + "/universerpc.Universe/QueryEvents", + ) + } + + // Conditionally whitelist public universe server proof courier methods. + if allowPublicUniProofCourier { + addEndpoints( + "/universerpc.Universe/Info", + "/universerpc.Universe/InsertProof", + "/universerpc.Universe/QueryProof", + + "/authmailboxrpc.Mailbox/MailboxInfo", + "/authmailboxrpc.Mailbox/SendMessage", + "/authmailboxrpc.Mailbox/ReceiveMessages", + ) } return whitelist diff --git a/taprpc/rfqrpc/rfq.pb.go b/taprpc/rfqrpc/rfq.pb.go index 74ba018c4..3f48c001c 100644 --- a/taprpc/rfqrpc/rfq.pb.go +++ b/taprpc/rfqrpc/rfq.pb.go @@ -7,6 +7,7 @@ package rfqrpc import ( + taprpc "github.com/lightninglabs/taproot-assets/taprpc" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" reflect "reflect" @@ -930,65 +931,6 @@ func (*QueryPeerAcceptedQuotesRequest) Descriptor() ([]byte, []int) { return file_rfqrpc_rfq_proto_rawDescGZIP(), []int{10} } -type AssetSpec struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // The 32-byte asset ID specified as raw bytes. - Id []byte `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - // The 32-byte asset group public key, serialized in BIP340 format. - // BIP340 defines a canonical encoding for Schnorr public keys. - // This field is serialized using schnorr.SerializePubKey. - GroupPubKey []byte `protobuf:"bytes,2,opt,name=group_pub_key,json=groupPubKey,proto3" json:"group_pub_key,omitempty"` -} - -func (x *AssetSpec) Reset() { - *x = AssetSpec{} - if protoimpl.UnsafeEnabled { - mi := &file_rfqrpc_rfq_proto_msgTypes[11] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *AssetSpec) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*AssetSpec) ProtoMessage() {} - -func (x *AssetSpec) ProtoReflect() protoreflect.Message { - mi := &file_rfqrpc_rfq_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) -} - -// Deprecated: Use AssetSpec.ProtoReflect.Descriptor instead. -func (*AssetSpec) Descriptor() ([]byte, []int) { - return file_rfqrpc_rfq_proto_rawDescGZIP(), []int{11} -} - -func (x *AssetSpec) GetId() []byte { - if x != nil { - return x.Id - } - return nil -} - -func (x *AssetSpec) GetGroupPubKey() []byte { - if x != nil { - return x.GroupPubKey - } - return nil -} - type PeerAcceptedBuyQuote struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1023,13 +965,13 @@ type PeerAcceptedBuyQuote struct { // more accurate (or discount) asset rate. PriceOracleMetadata string `protobuf:"bytes,8,opt,name=price_oracle_metadata,json=priceOracleMetadata,proto3" json:"price_oracle_metadata,omitempty"` // The subject asset specifier. - AssetSpec *AssetSpec `protobuf:"bytes,9,opt,name=asset_spec,json=assetSpec,proto3" json:"asset_spec,omitempty"` + AssetSpec *taprpc.AssetSpecifier `protobuf:"bytes,9,opt,name=asset_spec,json=assetSpec,proto3" json:"asset_spec,omitempty"` } func (x *PeerAcceptedBuyQuote) Reset() { *x = PeerAcceptedBuyQuote{} if protoimpl.UnsafeEnabled { - mi := &file_rfqrpc_rfq_proto_msgTypes[12] + mi := &file_rfqrpc_rfq_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1042,7 +984,7 @@ func (x *PeerAcceptedBuyQuote) String() string { func (*PeerAcceptedBuyQuote) ProtoMessage() {} func (x *PeerAcceptedBuyQuote) ProtoReflect() protoreflect.Message { - mi := &file_rfqrpc_rfq_proto_msgTypes[12] + mi := &file_rfqrpc_rfq_proto_msgTypes[11] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1055,7 +997,7 @@ func (x *PeerAcceptedBuyQuote) ProtoReflect() protoreflect.Message { // Deprecated: Use PeerAcceptedBuyQuote.ProtoReflect.Descriptor instead. func (*PeerAcceptedBuyQuote) Descriptor() ([]byte, []int) { - return file_rfqrpc_rfq_proto_rawDescGZIP(), []int{12} + return file_rfqrpc_rfq_proto_rawDescGZIP(), []int{11} } func (x *PeerAcceptedBuyQuote) GetPeer() string { @@ -1114,7 +1056,7 @@ func (x *PeerAcceptedBuyQuote) GetPriceOracleMetadata() string { return "" } -func (x *PeerAcceptedBuyQuote) GetAssetSpec() *AssetSpec { +func (x *PeerAcceptedBuyQuote) GetAssetSpec() *taprpc.AssetSpecifier { if x != nil { return x.AssetSpec } @@ -1153,13 +1095,13 @@ type PeerAcceptedSellQuote struct { // more accurate (or discount) asset rate. PriceOracleMetadata string `protobuf:"bytes,8,opt,name=price_oracle_metadata,json=priceOracleMetadata,proto3" json:"price_oracle_metadata,omitempty"` // The subject asset specifier. - AssetSpec *AssetSpec `protobuf:"bytes,9,opt,name=asset_spec,json=assetSpec,proto3" json:"asset_spec,omitempty"` + AssetSpec *taprpc.AssetSpecifier `protobuf:"bytes,9,opt,name=asset_spec,json=assetSpec,proto3" json:"asset_spec,omitempty"` } func (x *PeerAcceptedSellQuote) Reset() { *x = PeerAcceptedSellQuote{} if protoimpl.UnsafeEnabled { - mi := &file_rfqrpc_rfq_proto_msgTypes[13] + mi := &file_rfqrpc_rfq_proto_msgTypes[12] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1172,7 +1114,7 @@ func (x *PeerAcceptedSellQuote) String() string { func (*PeerAcceptedSellQuote) ProtoMessage() {} func (x *PeerAcceptedSellQuote) ProtoReflect() protoreflect.Message { - mi := &file_rfqrpc_rfq_proto_msgTypes[13] + mi := &file_rfqrpc_rfq_proto_msgTypes[12] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1185,7 +1127,7 @@ func (x *PeerAcceptedSellQuote) ProtoReflect() protoreflect.Message { // Deprecated: Use PeerAcceptedSellQuote.ProtoReflect.Descriptor instead. func (*PeerAcceptedSellQuote) Descriptor() ([]byte, []int) { - return file_rfqrpc_rfq_proto_rawDescGZIP(), []int{13} + return file_rfqrpc_rfq_proto_rawDescGZIP(), []int{12} } func (x *PeerAcceptedSellQuote) GetPeer() string { @@ -1244,7 +1186,7 @@ func (x *PeerAcceptedSellQuote) GetPriceOracleMetadata() string { return "" } -func (x *PeerAcceptedSellQuote) GetAssetSpec() *AssetSpec { +func (x *PeerAcceptedSellQuote) GetAssetSpec() *taprpc.AssetSpecifier { if x != nil { return x.AssetSpec } @@ -1269,7 +1211,7 @@ type InvalidQuoteResponse struct { func (x *InvalidQuoteResponse) Reset() { *x = InvalidQuoteResponse{} if protoimpl.UnsafeEnabled { - mi := &file_rfqrpc_rfq_proto_msgTypes[14] + mi := &file_rfqrpc_rfq_proto_msgTypes[13] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1282,7 +1224,7 @@ func (x *InvalidQuoteResponse) String() string { func (*InvalidQuoteResponse) ProtoMessage() {} func (x *InvalidQuoteResponse) ProtoReflect() protoreflect.Message { - mi := &file_rfqrpc_rfq_proto_msgTypes[14] + mi := &file_rfqrpc_rfq_proto_msgTypes[13] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1295,7 +1237,7 @@ func (x *InvalidQuoteResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use InvalidQuoteResponse.ProtoReflect.Descriptor instead. func (*InvalidQuoteResponse) Descriptor() ([]byte, []int) { - return file_rfqrpc_rfq_proto_rawDescGZIP(), []int{14} + return file_rfqrpc_rfq_proto_rawDescGZIP(), []int{13} } func (x *InvalidQuoteResponse) GetStatus() QuoteRespStatus { @@ -1339,7 +1281,7 @@ type RejectedQuoteResponse struct { func (x *RejectedQuoteResponse) Reset() { *x = RejectedQuoteResponse{} if protoimpl.UnsafeEnabled { - mi := &file_rfqrpc_rfq_proto_msgTypes[15] + mi := &file_rfqrpc_rfq_proto_msgTypes[14] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1352,7 +1294,7 @@ func (x *RejectedQuoteResponse) String() string { func (*RejectedQuoteResponse) ProtoMessage() {} func (x *RejectedQuoteResponse) ProtoReflect() protoreflect.Message { - mi := &file_rfqrpc_rfq_proto_msgTypes[15] + mi := &file_rfqrpc_rfq_proto_msgTypes[14] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1365,7 +1307,7 @@ func (x *RejectedQuoteResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RejectedQuoteResponse.ProtoReflect.Descriptor instead. func (*RejectedQuoteResponse) Descriptor() ([]byte, []int) { - return file_rfqrpc_rfq_proto_rawDescGZIP(), []int{15} + return file_rfqrpc_rfq_proto_rawDescGZIP(), []int{14} } func (x *RejectedQuoteResponse) GetPeer() string { @@ -1412,7 +1354,7 @@ type QueryPeerAcceptedQuotesResponse struct { func (x *QueryPeerAcceptedQuotesResponse) Reset() { *x = QueryPeerAcceptedQuotesResponse{} if protoimpl.UnsafeEnabled { - mi := &file_rfqrpc_rfq_proto_msgTypes[16] + mi := &file_rfqrpc_rfq_proto_msgTypes[15] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1425,7 +1367,7 @@ func (x *QueryPeerAcceptedQuotesResponse) String() string { func (*QueryPeerAcceptedQuotesResponse) ProtoMessage() {} func (x *QueryPeerAcceptedQuotesResponse) ProtoReflect() protoreflect.Message { - mi := &file_rfqrpc_rfq_proto_msgTypes[16] + mi := &file_rfqrpc_rfq_proto_msgTypes[15] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1438,7 +1380,7 @@ func (x *QueryPeerAcceptedQuotesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use QueryPeerAcceptedQuotesResponse.ProtoReflect.Descriptor instead. func (*QueryPeerAcceptedQuotesResponse) Descriptor() ([]byte, []int) { - return file_rfqrpc_rfq_proto_rawDescGZIP(), []int{16} + return file_rfqrpc_rfq_proto_rawDescGZIP(), []int{15} } func (x *QueryPeerAcceptedQuotesResponse) GetBuyQuotes() []*PeerAcceptedBuyQuote { @@ -1464,7 +1406,7 @@ type SubscribeRfqEventNtfnsRequest struct { func (x *SubscribeRfqEventNtfnsRequest) Reset() { *x = SubscribeRfqEventNtfnsRequest{} if protoimpl.UnsafeEnabled { - mi := &file_rfqrpc_rfq_proto_msgTypes[17] + mi := &file_rfqrpc_rfq_proto_msgTypes[16] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1477,7 +1419,7 @@ func (x *SubscribeRfqEventNtfnsRequest) String() string { func (*SubscribeRfqEventNtfnsRequest) ProtoMessage() {} func (x *SubscribeRfqEventNtfnsRequest) ProtoReflect() protoreflect.Message { - mi := &file_rfqrpc_rfq_proto_msgTypes[17] + mi := &file_rfqrpc_rfq_proto_msgTypes[16] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1490,7 +1432,7 @@ func (x *SubscribeRfqEventNtfnsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use SubscribeRfqEventNtfnsRequest.ProtoReflect.Descriptor instead. func (*SubscribeRfqEventNtfnsRequest) Descriptor() ([]byte, []int) { - return file_rfqrpc_rfq_proto_rawDescGZIP(), []int{17} + return file_rfqrpc_rfq_proto_rawDescGZIP(), []int{16} } type PeerAcceptedBuyQuoteEvent struct { @@ -1507,7 +1449,7 @@ type PeerAcceptedBuyQuoteEvent struct { func (x *PeerAcceptedBuyQuoteEvent) Reset() { *x = PeerAcceptedBuyQuoteEvent{} if protoimpl.UnsafeEnabled { - mi := &file_rfqrpc_rfq_proto_msgTypes[18] + mi := &file_rfqrpc_rfq_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1520,7 +1462,7 @@ func (x *PeerAcceptedBuyQuoteEvent) String() string { func (*PeerAcceptedBuyQuoteEvent) ProtoMessage() {} func (x *PeerAcceptedBuyQuoteEvent) ProtoReflect() protoreflect.Message { - mi := &file_rfqrpc_rfq_proto_msgTypes[18] + mi := &file_rfqrpc_rfq_proto_msgTypes[17] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1533,7 +1475,7 @@ func (x *PeerAcceptedBuyQuoteEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use PeerAcceptedBuyQuoteEvent.ProtoReflect.Descriptor instead. func (*PeerAcceptedBuyQuoteEvent) Descriptor() ([]byte, []int) { - return file_rfqrpc_rfq_proto_rawDescGZIP(), []int{18} + return file_rfqrpc_rfq_proto_rawDescGZIP(), []int{17} } func (x *PeerAcceptedBuyQuoteEvent) GetTimestamp() uint64 { @@ -1564,7 +1506,7 @@ type PeerAcceptedSellQuoteEvent struct { func (x *PeerAcceptedSellQuoteEvent) Reset() { *x = PeerAcceptedSellQuoteEvent{} if protoimpl.UnsafeEnabled { - mi := &file_rfqrpc_rfq_proto_msgTypes[19] + mi := &file_rfqrpc_rfq_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1577,7 +1519,7 @@ func (x *PeerAcceptedSellQuoteEvent) String() string { func (*PeerAcceptedSellQuoteEvent) ProtoMessage() {} func (x *PeerAcceptedSellQuoteEvent) ProtoReflect() protoreflect.Message { - mi := &file_rfqrpc_rfq_proto_msgTypes[19] + mi := &file_rfqrpc_rfq_proto_msgTypes[18] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1590,7 +1532,7 @@ func (x *PeerAcceptedSellQuoteEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use PeerAcceptedSellQuoteEvent.ProtoReflect.Descriptor instead. func (*PeerAcceptedSellQuoteEvent) Descriptor() ([]byte, []int) { - return file_rfqrpc_rfq_proto_rawDescGZIP(), []int{19} + return file_rfqrpc_rfq_proto_rawDescGZIP(), []int{18} } func (x *PeerAcceptedSellQuoteEvent) GetTimestamp() uint64 { @@ -1622,7 +1564,7 @@ type AcceptHtlcEvent struct { func (x *AcceptHtlcEvent) Reset() { *x = AcceptHtlcEvent{} if protoimpl.UnsafeEnabled { - mi := &file_rfqrpc_rfq_proto_msgTypes[20] + mi := &file_rfqrpc_rfq_proto_msgTypes[19] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1635,7 +1577,7 @@ func (x *AcceptHtlcEvent) String() string { func (*AcceptHtlcEvent) ProtoMessage() {} func (x *AcceptHtlcEvent) ProtoReflect() protoreflect.Message { - mi := &file_rfqrpc_rfq_proto_msgTypes[20] + mi := &file_rfqrpc_rfq_proto_msgTypes[19] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1648,7 +1590,7 @@ func (x *AcceptHtlcEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use AcceptHtlcEvent.ProtoReflect.Descriptor instead. func (*AcceptHtlcEvent) Descriptor() ([]byte, []int) { - return file_rfqrpc_rfq_proto_rawDescGZIP(), []int{20} + return file_rfqrpc_rfq_proto_rawDescGZIP(), []int{19} } func (x *AcceptHtlcEvent) GetTimestamp() uint64 { @@ -1681,7 +1623,7 @@ type RfqEvent struct { func (x *RfqEvent) Reset() { *x = RfqEvent{} if protoimpl.UnsafeEnabled { - mi := &file_rfqrpc_rfq_proto_msgTypes[21] + mi := &file_rfqrpc_rfq_proto_msgTypes[20] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1694,7 +1636,7 @@ func (x *RfqEvent) String() string { func (*RfqEvent) ProtoMessage() {} func (x *RfqEvent) ProtoReflect() protoreflect.Message { - mi := &file_rfqrpc_rfq_proto_msgTypes[21] + mi := &file_rfqrpc_rfq_proto_msgTypes[20] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1707,7 +1649,7 @@ func (x *RfqEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use RfqEvent.ProtoReflect.Descriptor instead. func (*RfqEvent) Descriptor() ([]byte, []int) { - return file_rfqrpc_rfq_proto_rawDescGZIP(), []int{21} + return file_rfqrpc_rfq_proto_rawDescGZIP(), []int{20} } func (m *RfqEvent) GetEvent() isRfqEvent_Event { @@ -1770,121 +1712,118 @@ var File_rfqrpc_rfq_proto protoreflect.FileDescriptor var file_rfqrpc_rfq_proto_rawDesc = []byte{ 0x0a, 0x10, 0x72, 0x66, 0x71, 0x72, 0x70, 0x63, 0x2f, 0x72, 0x66, 0x71, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x12, 0x06, 0x72, 0x66, 0x71, 0x72, 0x70, 0x63, 0x22, 0x9c, 0x01, 0x0a, 0x0e, 0x41, - 0x73, 0x73, 0x65, 0x74, 0x53, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x72, 0x12, 0x1b, 0x0a, - 0x08, 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x48, - 0x00, 0x52, 0x07, 0x61, 0x73, 0x73, 0x65, 0x74, 0x49, 0x64, 0x12, 0x22, 0x0a, 0x0c, 0x61, 0x73, - 0x73, 0x65, 0x74, 0x5f, 0x69, 0x64, 0x5f, 0x73, 0x74, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x48, 0x00, 0x52, 0x0a, 0x61, 0x73, 0x73, 0x65, 0x74, 0x49, 0x64, 0x53, 0x74, 0x72, 0x12, 0x1d, - 0x0a, 0x09, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x0c, 0x48, 0x00, 0x52, 0x08, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x4b, 0x65, 0x79, 0x12, 0x24, 0x0a, - 0x0d, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x73, 0x74, 0x72, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0b, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x4b, 0x65, 0x79, - 0x53, 0x74, 0x72, 0x42, 0x04, 0x0a, 0x02, 0x69, 0x64, 0x22, 0x44, 0x0a, 0x0a, 0x46, 0x69, 0x78, - 0x65, 0x64, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x6f, 0x65, 0x66, 0x66, - 0x69, 0x63, 0x69, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, - 0x65, 0x66, 0x66, 0x69, 0x63, 0x69, 0x65, 0x6e, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x63, 0x61, - 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x22, - 0xce, 0x02, 0x0a, 0x17, 0x41, 0x64, 0x64, 0x41, 0x73, 0x73, 0x65, 0x74, 0x42, 0x75, 0x79, 0x4f, + 0x74, 0x6f, 0x12, 0x06, 0x72, 0x66, 0x71, 0x72, 0x70, 0x63, 0x1a, 0x0f, 0x74, 0x61, 0x70, 0x63, + 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x9c, 0x01, 0x0a, 0x0e, + 0x41, 0x73, 0x73, 0x65, 0x74, 0x53, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x72, 0x12, 0x1b, + 0x0a, 0x08, 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, + 0x48, 0x00, 0x52, 0x07, 0x61, 0x73, 0x73, 0x65, 0x74, 0x49, 0x64, 0x12, 0x22, 0x0a, 0x0c, 0x61, + 0x73, 0x73, 0x65, 0x74, 0x5f, 0x69, 0x64, 0x5f, 0x73, 0x74, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x48, 0x00, 0x52, 0x0a, 0x61, 0x73, 0x73, 0x65, 0x74, 0x49, 0x64, 0x53, 0x74, 0x72, 0x12, + 0x1d, 0x0a, 0x09, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0c, 0x48, 0x00, 0x52, 0x08, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x4b, 0x65, 0x79, 0x12, 0x24, + 0x0a, 0x0d, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x73, 0x74, 0x72, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0b, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x4b, 0x65, + 0x79, 0x53, 0x74, 0x72, 0x42, 0x04, 0x0a, 0x02, 0x69, 0x64, 0x22, 0x44, 0x0a, 0x0a, 0x46, 0x69, + 0x78, 0x65, 0x64, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x6f, 0x65, 0x66, + 0x66, 0x69, 0x63, 0x69, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, + 0x6f, 0x65, 0x66, 0x66, 0x69, 0x63, 0x69, 0x65, 0x6e, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x63, + 0x61, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x73, 0x63, 0x61, 0x6c, 0x65, + 0x22, 0xce, 0x02, 0x0a, 0x17, 0x41, 0x64, 0x64, 0x41, 0x73, 0x73, 0x65, 0x74, 0x42, 0x75, 0x79, + 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x0f, + 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x72, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x72, 0x66, 0x71, 0x72, 0x70, 0x63, 0x2e, 0x41, + 0x73, 0x73, 0x65, 0x74, 0x53, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x72, 0x52, 0x0e, 0x61, + 0x73, 0x73, 0x65, 0x74, 0x53, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x72, 0x12, 0x22, 0x0a, + 0x0d, 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x6d, 0x61, 0x78, 0x5f, 0x61, 0x6d, 0x74, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x61, 0x73, 0x73, 0x65, 0x74, 0x4d, 0x61, 0x78, 0x41, 0x6d, + 0x74, 0x12, 0x16, 0x0a, 0x06, 0x65, 0x78, 0x70, 0x69, 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x04, 0x52, 0x06, 0x65, 0x78, 0x70, 0x69, 0x72, 0x79, 0x12, 0x20, 0x0a, 0x0c, 0x70, 0x65, 0x65, + 0x72, 0x5f, 0x70, 0x75, 0x62, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x0a, 0x70, 0x65, 0x65, 0x72, 0x50, 0x75, 0x62, 0x4b, 0x65, 0x79, 0x12, 0x27, 0x0a, 0x0f, 0x74, + 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0e, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x53, 0x65, 0x63, + 0x6f, 0x6e, 0x64, 0x73, 0x12, 0x37, 0x0a, 0x18, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x61, 0x73, 0x73, + 0x65, 0x74, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, + 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x15, 0x73, 0x6b, 0x69, 0x70, 0x41, 0x73, 0x73, 0x65, + 0x74, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x12, 0x32, 0x0a, + 0x15, 0x70, 0x72, 0x69, 0x63, 0x65, 0x5f, 0x6f, 0x72, 0x61, 0x63, 0x6c, 0x65, 0x5f, 0x6d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x70, 0x72, + 0x69, 0x63, 0x65, 0x4f, 0x72, 0x61, 0x63, 0x6c, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0x22, 0xfa, 0x01, 0x0a, 0x18, 0x41, 0x64, 0x64, 0x41, 0x73, 0x73, 0x65, 0x74, 0x42, 0x75, + 0x79, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x45, + 0x0a, 0x0e, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x5f, 0x71, 0x75, 0x6f, 0x74, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x72, 0x66, 0x71, 0x72, 0x70, 0x63, 0x2e, + 0x50, 0x65, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x42, 0x75, 0x79, 0x51, + 0x75, 0x6f, 0x74, 0x65, 0x48, 0x00, 0x52, 0x0d, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, + 0x51, 0x75, 0x6f, 0x74, 0x65, 0x12, 0x43, 0x0a, 0x0d, 0x69, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, + 0x5f, 0x71, 0x75, 0x6f, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x72, + 0x66, 0x71, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x51, 0x75, 0x6f, + 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x00, 0x52, 0x0c, 0x69, 0x6e, + 0x76, 0x61, 0x6c, 0x69, 0x64, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x12, 0x46, 0x0a, 0x0e, 0x72, 0x65, + 0x6a, 0x65, 0x63, 0x74, 0x65, 0x64, 0x5f, 0x71, 0x75, 0x6f, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x72, 0x66, 0x71, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x65, 0x6a, 0x65, + 0x63, 0x74, 0x65, 0x64, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x48, 0x00, 0x52, 0x0d, 0x72, 0x65, 0x6a, 0x65, 0x63, 0x74, 0x65, 0x64, 0x51, 0x75, 0x6f, + 0x74, 0x65, 0x42, 0x0a, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xd3, + 0x02, 0x0a, 0x18, 0x41, 0x64, 0x64, 0x41, 0x73, 0x73, 0x65, 0x74, 0x53, 0x65, 0x6c, 0x6c, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x0f, 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x72, 0x66, 0x71, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x73, 0x73, 0x65, 0x74, 0x53, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x72, 0x52, 0x0e, 0x61, 0x73, - 0x73, 0x65, 0x74, 0x53, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x72, 0x12, 0x22, 0x0a, 0x0d, - 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x6d, 0x61, 0x78, 0x5f, 0x61, 0x6d, 0x74, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x04, 0x52, 0x0b, 0x61, 0x73, 0x73, 0x65, 0x74, 0x4d, 0x61, 0x78, 0x41, 0x6d, 0x74, - 0x12, 0x16, 0x0a, 0x06, 0x65, 0x78, 0x70, 0x69, 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, - 0x52, 0x06, 0x65, 0x78, 0x70, 0x69, 0x72, 0x79, 0x12, 0x20, 0x0a, 0x0c, 0x70, 0x65, 0x65, 0x72, - 0x5f, 0x70, 0x75, 0x62, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, - 0x70, 0x65, 0x65, 0x72, 0x50, 0x75, 0x62, 0x4b, 0x65, 0x79, 0x12, 0x27, 0x0a, 0x0f, 0x74, 0x69, - 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x18, 0x05, 0x20, - 0x01, 0x28, 0x0d, 0x52, 0x0e, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x53, 0x65, 0x63, 0x6f, - 0x6e, 0x64, 0x73, 0x12, 0x37, 0x0a, 0x18, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x61, 0x73, 0x73, 0x65, - 0x74, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x18, - 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x15, 0x73, 0x6b, 0x69, 0x70, 0x41, 0x73, 0x73, 0x65, 0x74, - 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x12, 0x32, 0x0a, 0x15, - 0x70, 0x72, 0x69, 0x63, 0x65, 0x5f, 0x6f, 0x72, 0x61, 0x63, 0x6c, 0x65, 0x5f, 0x6d, 0x65, 0x74, - 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x70, 0x72, 0x69, - 0x63, 0x65, 0x4f, 0x72, 0x61, 0x63, 0x6c, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, - 0x22, 0xfa, 0x01, 0x0a, 0x18, 0x41, 0x64, 0x64, 0x41, 0x73, 0x73, 0x65, 0x74, 0x42, 0x75, 0x79, - 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x45, 0x0a, - 0x0e, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x5f, 0x71, 0x75, 0x6f, 0x74, 0x65, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x72, 0x66, 0x71, 0x72, 0x70, 0x63, 0x2e, 0x50, - 0x65, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x42, 0x75, 0x79, 0x51, 0x75, - 0x6f, 0x74, 0x65, 0x48, 0x00, 0x52, 0x0d, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x51, - 0x75, 0x6f, 0x74, 0x65, 0x12, 0x43, 0x0a, 0x0d, 0x69, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x5f, - 0x71, 0x75, 0x6f, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x72, 0x66, - 0x71, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x51, 0x75, 0x6f, 0x74, - 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x00, 0x52, 0x0c, 0x69, 0x6e, 0x76, - 0x61, 0x6c, 0x69, 0x64, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x12, 0x46, 0x0a, 0x0e, 0x72, 0x65, 0x6a, - 0x65, 0x63, 0x74, 0x65, 0x64, 0x5f, 0x71, 0x75, 0x6f, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x1d, 0x2e, 0x72, 0x66, 0x71, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x65, 0x6a, 0x65, 0x63, - 0x74, 0x65, 0x64, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x48, 0x00, 0x52, 0x0d, 0x72, 0x65, 0x6a, 0x65, 0x63, 0x74, 0x65, 0x64, 0x51, 0x75, 0x6f, 0x74, - 0x65, 0x42, 0x0a, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xd3, 0x02, - 0x0a, 0x18, 0x41, 0x64, 0x64, 0x41, 0x73, 0x73, 0x65, 0x74, 0x53, 0x65, 0x6c, 0x6c, 0x4f, 0x72, - 0x64, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x0f, 0x61, 0x73, - 0x73, 0x65, 0x74, 0x5f, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x72, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x72, 0x66, 0x71, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x73, 0x73, - 0x65, 0x74, 0x53, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x72, 0x52, 0x0e, 0x61, 0x73, 0x73, - 0x65, 0x74, 0x53, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x72, 0x12, 0x26, 0x0a, 0x0f, 0x70, - 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x6d, 0x61, 0x78, 0x5f, 0x61, 0x6d, 0x74, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x70, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x4d, 0x61, 0x78, - 0x41, 0x6d, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x65, 0x78, 0x70, 0x69, 0x72, 0x79, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x04, 0x52, 0x06, 0x65, 0x78, 0x70, 0x69, 0x72, 0x79, 0x12, 0x20, 0x0a, 0x0c, 0x70, - 0x65, 0x65, 0x72, 0x5f, 0x70, 0x75, 0x62, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x0a, 0x70, 0x65, 0x65, 0x72, 0x50, 0x75, 0x62, 0x4b, 0x65, 0x79, 0x12, 0x27, 0x0a, - 0x0f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0e, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x53, - 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x12, 0x37, 0x0a, 0x18, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x61, - 0x73, 0x73, 0x65, 0x74, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x63, 0x68, 0x65, - 0x63, 0x6b, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x15, 0x73, 0x6b, 0x69, 0x70, 0x41, 0x73, - 0x73, 0x65, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x12, - 0x32, 0x0a, 0x15, 0x70, 0x72, 0x69, 0x63, 0x65, 0x5f, 0x6f, 0x72, 0x61, 0x63, 0x6c, 0x65, 0x5f, - 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, - 0x70, 0x72, 0x69, 0x63, 0x65, 0x4f, 0x72, 0x61, 0x63, 0x6c, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, - 0x61, 0x74, 0x61, 0x22, 0xfc, 0x01, 0x0a, 0x19, 0x41, 0x64, 0x64, 0x41, 0x73, 0x73, 0x65, 0x74, - 0x53, 0x65, 0x6c, 0x6c, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x46, 0x0a, 0x0e, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x5f, 0x71, 0x75, - 0x6f, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x72, 0x66, 0x71, 0x72, - 0x70, 0x63, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x53, - 0x65, 0x6c, 0x6c, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x48, 0x00, 0x52, 0x0d, 0x61, 0x63, 0x63, 0x65, - 0x70, 0x74, 0x65, 0x64, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x12, 0x43, 0x0a, 0x0d, 0x69, 0x6e, 0x76, - 0x61, 0x6c, 0x69, 0x64, 0x5f, 0x71, 0x75, 0x6f, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x1c, 0x2e, 0x72, 0x66, 0x71, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, - 0x64, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x00, - 0x52, 0x0c, 0x69, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x12, 0x46, - 0x0a, 0x0e, 0x72, 0x65, 0x6a, 0x65, 0x63, 0x74, 0x65, 0x64, 0x5f, 0x71, 0x75, 0x6f, 0x74, 0x65, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x72, 0x66, 0x71, 0x72, 0x70, 0x63, 0x2e, - 0x52, 0x65, 0x6a, 0x65, 0x63, 0x74, 0x65, 0x64, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x00, 0x52, 0x0d, 0x72, 0x65, 0x6a, 0x65, 0x63, 0x74, 0x65, - 0x64, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x42, 0x0a, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x78, 0x0a, 0x18, 0x41, 0x64, 0x64, 0x41, 0x73, 0x73, 0x65, 0x74, 0x53, 0x65, - 0x6c, 0x6c, 0x4f, 0x66, 0x66, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, - 0x0a, 0x0f, 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, - 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x72, 0x66, 0x71, 0x72, 0x70, 0x63, - 0x2e, 0x41, 0x73, 0x73, 0x65, 0x74, 0x53, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x72, 0x52, - 0x0e, 0x61, 0x73, 0x73, 0x65, 0x74, 0x53, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x72, 0x12, - 0x1b, 0x0a, 0x09, 0x6d, 0x61, 0x78, 0x5f, 0x75, 0x6e, 0x69, 0x74, 0x73, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x04, 0x52, 0x08, 0x6d, 0x61, 0x78, 0x55, 0x6e, 0x69, 0x74, 0x73, 0x22, 0x1b, 0x0a, 0x19, - 0x41, 0x64, 0x64, 0x41, 0x73, 0x73, 0x65, 0x74, 0x53, 0x65, 0x6c, 0x6c, 0x4f, 0x66, 0x66, 0x65, - 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x77, 0x0a, 0x17, 0x41, 0x64, 0x64, - 0x41, 0x73, 0x73, 0x65, 0x74, 0x42, 0x75, 0x79, 0x4f, 0x66, 0x66, 0x65, 0x72, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x0f, 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x73, 0x70, - 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, - 0x72, 0x66, 0x71, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x73, 0x73, 0x65, 0x74, 0x53, 0x70, 0x65, 0x63, - 0x69, 0x66, 0x69, 0x65, 0x72, 0x52, 0x0e, 0x61, 0x73, 0x73, 0x65, 0x74, 0x53, 0x70, 0x65, 0x63, - 0x69, 0x66, 0x69, 0x65, 0x72, 0x12, 0x1b, 0x0a, 0x09, 0x6d, 0x61, 0x78, 0x5f, 0x75, 0x6e, 0x69, - 0x74, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x6d, 0x61, 0x78, 0x55, 0x6e, 0x69, - 0x74, 0x73, 0x22, 0x1a, 0x0a, 0x18, 0x41, 0x64, 0x64, 0x41, 0x73, 0x73, 0x65, 0x74, 0x42, 0x75, - 0x79, 0x4f, 0x66, 0x66, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x20, - 0x0a, 0x1e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x65, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x70, - 0x74, 0x65, 0x64, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x22, 0x3f, 0x0a, 0x09, 0x41, 0x73, 0x73, 0x65, 0x74, 0x53, 0x70, 0x65, 0x63, 0x12, 0x0e, 0x0a, - 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x69, 0x64, 0x12, 0x22, 0x0a, - 0x0d, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x70, 0x75, 0x62, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x50, 0x75, 0x62, 0x4b, 0x65, - 0x79, 0x22, 0xe8, 0x02, 0x0a, 0x14, 0x50, 0x65, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, + 0x73, 0x65, 0x74, 0x53, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x72, 0x12, 0x26, 0x0a, 0x0f, + 0x70, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x6d, 0x61, 0x78, 0x5f, 0x61, 0x6d, 0x74, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x70, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x4d, 0x61, + 0x78, 0x41, 0x6d, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x65, 0x78, 0x70, 0x69, 0x72, 0x79, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x65, 0x78, 0x70, 0x69, 0x72, 0x79, 0x12, 0x20, 0x0a, 0x0c, + 0x70, 0x65, 0x65, 0x72, 0x5f, 0x70, 0x75, 0x62, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x0a, 0x70, 0x65, 0x65, 0x72, 0x50, 0x75, 0x62, 0x4b, 0x65, 0x79, 0x12, 0x27, + 0x0a, 0x0f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, + 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0e, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, + 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x12, 0x37, 0x0a, 0x18, 0x73, 0x6b, 0x69, 0x70, 0x5f, + 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x63, 0x68, + 0x65, 0x63, 0x6b, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x15, 0x73, 0x6b, 0x69, 0x70, 0x41, + 0x73, 0x73, 0x65, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x43, 0x68, 0x65, 0x63, 0x6b, + 0x12, 0x32, 0x0a, 0x15, 0x70, 0x72, 0x69, 0x63, 0x65, 0x5f, 0x6f, 0x72, 0x61, 0x63, 0x6c, 0x65, + 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x13, 0x70, 0x72, 0x69, 0x63, 0x65, 0x4f, 0x72, 0x61, 0x63, 0x6c, 0x65, 0x4d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0x22, 0xfc, 0x01, 0x0a, 0x19, 0x41, 0x64, 0x64, 0x41, 0x73, 0x73, 0x65, + 0x74, 0x53, 0x65, 0x6c, 0x6c, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x46, 0x0a, 0x0e, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x5f, 0x71, + 0x75, 0x6f, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x72, 0x66, 0x71, + 0x72, 0x70, 0x63, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, + 0x53, 0x65, 0x6c, 0x6c, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x48, 0x00, 0x52, 0x0d, 0x61, 0x63, 0x63, + 0x65, 0x70, 0x74, 0x65, 0x64, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x12, 0x43, 0x0a, 0x0d, 0x69, 0x6e, + 0x76, 0x61, 0x6c, 0x69, 0x64, 0x5f, 0x71, 0x75, 0x6f, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1c, 0x2e, 0x72, 0x66, 0x71, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x6e, 0x76, 0x61, 0x6c, + 0x69, 0x64, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, + 0x00, 0x52, 0x0c, 0x69, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x12, + 0x46, 0x0a, 0x0e, 0x72, 0x65, 0x6a, 0x65, 0x63, 0x74, 0x65, 0x64, 0x5f, 0x71, 0x75, 0x6f, 0x74, + 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x72, 0x66, 0x71, 0x72, 0x70, 0x63, + 0x2e, 0x52, 0x65, 0x6a, 0x65, 0x63, 0x74, 0x65, 0x64, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x00, 0x52, 0x0d, 0x72, 0x65, 0x6a, 0x65, 0x63, 0x74, + 0x65, 0x64, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x42, 0x0a, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x78, 0x0a, 0x18, 0x41, 0x64, 0x64, 0x41, 0x73, 0x73, 0x65, 0x74, 0x53, + 0x65, 0x6c, 0x6c, 0x4f, 0x66, 0x66, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x3f, 0x0a, 0x0f, 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, + 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x72, 0x66, 0x71, 0x72, 0x70, + 0x63, 0x2e, 0x41, 0x73, 0x73, 0x65, 0x74, 0x53, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x72, + 0x52, 0x0e, 0x61, 0x73, 0x73, 0x65, 0x74, 0x53, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x72, + 0x12, 0x1b, 0x0a, 0x09, 0x6d, 0x61, 0x78, 0x5f, 0x75, 0x6e, 0x69, 0x74, 0x73, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x04, 0x52, 0x08, 0x6d, 0x61, 0x78, 0x55, 0x6e, 0x69, 0x74, 0x73, 0x22, 0x1b, 0x0a, + 0x19, 0x41, 0x64, 0x64, 0x41, 0x73, 0x73, 0x65, 0x74, 0x53, 0x65, 0x6c, 0x6c, 0x4f, 0x66, 0x66, + 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x77, 0x0a, 0x17, 0x41, 0x64, + 0x64, 0x41, 0x73, 0x73, 0x65, 0x74, 0x42, 0x75, 0x79, 0x4f, 0x66, 0x66, 0x65, 0x72, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x0f, 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x73, + 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, + 0x2e, 0x72, 0x66, 0x71, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x73, 0x73, 0x65, 0x74, 0x53, 0x70, 0x65, + 0x63, 0x69, 0x66, 0x69, 0x65, 0x72, 0x52, 0x0e, 0x61, 0x73, 0x73, 0x65, 0x74, 0x53, 0x70, 0x65, + 0x63, 0x69, 0x66, 0x69, 0x65, 0x72, 0x12, 0x1b, 0x0a, 0x09, 0x6d, 0x61, 0x78, 0x5f, 0x75, 0x6e, + 0x69, 0x74, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x6d, 0x61, 0x78, 0x55, 0x6e, + 0x69, 0x74, 0x73, 0x22, 0x1a, 0x0a, 0x18, 0x41, 0x64, 0x64, 0x41, 0x73, 0x73, 0x65, 0x74, 0x42, + 0x75, 0x79, 0x4f, 0x66, 0x66, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x20, 0x0a, 0x1e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x65, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, + 0x70, 0x74, 0x65, 0x64, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x22, 0xed, 0x02, 0x0a, 0x14, 0x50, 0x65, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x42, 0x75, 0x79, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x65, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x65, 0x65, 0x72, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, @@ -1903,143 +1842,144 @@ var file_rfqrpc_rfq_proto_rawDesc = []byte{ 0x65, 0x55, 0x6e, 0x69, 0x74, 0x73, 0x12, 0x32, 0x0a, 0x15, 0x70, 0x72, 0x69, 0x63, 0x65, 0x5f, 0x6f, 0x72, 0x61, 0x63, 0x6c, 0x65, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x70, 0x72, 0x69, 0x63, 0x65, 0x4f, 0x72, 0x61, 0x63, - 0x6c, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x30, 0x0a, 0x0a, 0x61, 0x73, - 0x73, 0x65, 0x74, 0x5f, 0x73, 0x70, 0x65, 0x63, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, - 0x2e, 0x72, 0x66, 0x71, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x73, 0x73, 0x65, 0x74, 0x53, 0x70, 0x65, - 0x63, 0x52, 0x09, 0x61, 0x73, 0x73, 0x65, 0x74, 0x53, 0x70, 0x65, 0x63, 0x22, 0xe0, 0x02, 0x0a, - 0x15, 0x50, 0x65, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x53, 0x65, 0x6c, - 0x6c, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x65, 0x65, 0x72, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x65, 0x65, 0x72, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x63, - 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x73, 0x63, 0x69, 0x64, 0x12, 0x21, - 0x0a, 0x0c, 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x61, 0x73, 0x73, 0x65, 0x74, 0x41, 0x6d, 0x6f, 0x75, 0x6e, - 0x74, 0x12, 0x38, 0x0a, 0x0e, 0x62, 0x69, 0x64, 0x5f, 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x72, - 0x61, 0x74, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x72, 0x66, 0x71, 0x72, - 0x70, 0x63, 0x2e, 0x46, 0x69, 0x78, 0x65, 0x64, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x0c, 0x62, - 0x69, 0x64, 0x41, 0x73, 0x73, 0x65, 0x74, 0x52, 0x61, 0x74, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x65, - 0x78, 0x70, 0x69, 0x72, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x65, 0x78, 0x70, - 0x69, 0x72, 0x79, 0x12, 0x34, 0x0a, 0x16, 0x6d, 0x69, 0x6e, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, - 0x70, 0x6f, 0x72, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6d, 0x73, 0x61, 0x74, 0x18, 0x07, 0x20, - 0x01, 0x28, 0x04, 0x52, 0x14, 0x6d, 0x69, 0x6e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, - 0x74, 0x61, 0x62, 0x6c, 0x65, 0x4d, 0x73, 0x61, 0x74, 0x12, 0x32, 0x0a, 0x15, 0x70, 0x72, 0x69, - 0x63, 0x65, 0x5f, 0x6f, 0x72, 0x61, 0x63, 0x6c, 0x65, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, - 0x74, 0x61, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x70, 0x72, 0x69, 0x63, 0x65, 0x4f, - 0x72, 0x61, 0x63, 0x6c, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x30, 0x0a, - 0x0a, 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x73, 0x70, 0x65, 0x63, 0x18, 0x09, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x11, 0x2e, 0x72, 0x66, 0x71, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x73, 0x73, 0x65, 0x74, - 0x53, 0x70, 0x65, 0x63, 0x52, 0x09, 0x61, 0x73, 0x73, 0x65, 0x74, 0x53, 0x70, 0x65, 0x63, 0x22, - 0x6b, 0x0a, 0x14, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x17, 0x2e, 0x72, 0x66, 0x71, 0x72, 0x70, 0x63, - 0x2e, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x65, 0x65, 0x72, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x65, 0x65, 0x72, 0x12, 0x0e, 0x0a, 0x02, - 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x69, 0x64, 0x22, 0x7f, 0x0a, 0x15, - 0x52, 0x65, 0x6a, 0x65, 0x63, 0x74, 0x65, 0x64, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x65, 0x65, 0x72, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x65, 0x65, 0x72, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x69, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x72, 0x72, - 0x6f, 0x72, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0c, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1d, - 0x0a, 0x0a, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x0d, 0x52, 0x09, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x22, 0x9e, 0x01, - 0x0a, 0x1f, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x65, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x70, - 0x74, 0x65, 0x64, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x3b, 0x0a, 0x0a, 0x62, 0x75, 0x79, 0x5f, 0x71, 0x75, 0x6f, 0x74, 0x65, 0x73, 0x18, - 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x72, 0x66, 0x71, 0x72, 0x70, 0x63, 0x2e, 0x50, - 0x65, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x42, 0x75, 0x79, 0x51, 0x75, - 0x6f, 0x74, 0x65, 0x52, 0x09, 0x62, 0x75, 0x79, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x73, 0x12, 0x3e, - 0x0a, 0x0b, 0x73, 0x65, 0x6c, 0x6c, 0x5f, 0x71, 0x75, 0x6f, 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x72, 0x66, 0x71, 0x72, 0x70, 0x63, 0x2e, 0x50, 0x65, 0x65, - 0x72, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x53, 0x65, 0x6c, 0x6c, 0x51, 0x75, 0x6f, - 0x74, 0x65, 0x52, 0x0a, 0x73, 0x65, 0x6c, 0x6c, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x73, 0x22, 0x1f, - 0x0a, 0x1d, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x52, 0x66, 0x71, 0x45, 0x76, - 0x65, 0x6e, 0x74, 0x4e, 0x74, 0x66, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, - 0x8e, 0x01, 0x0a, 0x19, 0x50, 0x65, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, - 0x42, 0x75, 0x79, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1c, 0x0a, - 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, - 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x53, 0x0a, 0x17, 0x70, - 0x65, 0x65, 0x72, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x75, 0x79, - 0x5f, 0x71, 0x75, 0x6f, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x72, - 0x66, 0x71, 0x72, 0x70, 0x63, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, - 0x65, 0x64, 0x42, 0x75, 0x79, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x52, 0x14, 0x70, 0x65, 0x65, 0x72, + 0x6c, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x35, 0x0a, 0x0a, 0x61, 0x73, + 0x73, 0x65, 0x74, 0x5f, 0x73, 0x70, 0x65, 0x63, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, + 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x73, 0x73, 0x65, 0x74, 0x53, 0x70, 0x65, + 0x63, 0x69, 0x66, 0x69, 0x65, 0x72, 0x52, 0x09, 0x61, 0x73, 0x73, 0x65, 0x74, 0x53, 0x70, 0x65, + 0x63, 0x22, 0xe5, 0x02, 0x0a, 0x15, 0x50, 0x65, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, + 0x65, 0x64, 0x53, 0x65, 0x6c, 0x6c, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x70, + 0x65, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x65, 0x65, 0x72, 0x12, + 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x69, 0x64, 0x12, + 0x12, 0x0a, 0x04, 0x73, 0x63, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x73, + 0x63, 0x69, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x61, 0x6d, 0x6f, + 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x61, 0x73, 0x73, 0x65, 0x74, + 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x38, 0x0a, 0x0e, 0x62, 0x69, 0x64, 0x5f, 0x61, 0x73, + 0x73, 0x65, 0x74, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, + 0x2e, 0x72, 0x66, 0x71, 0x72, 0x70, 0x63, 0x2e, 0x46, 0x69, 0x78, 0x65, 0x64, 0x50, 0x6f, 0x69, + 0x6e, 0x74, 0x52, 0x0c, 0x62, 0x69, 0x64, 0x41, 0x73, 0x73, 0x65, 0x74, 0x52, 0x61, 0x74, 0x65, + 0x12, 0x16, 0x0a, 0x06, 0x65, 0x78, 0x70, 0x69, 0x72, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, + 0x52, 0x06, 0x65, 0x78, 0x70, 0x69, 0x72, 0x79, 0x12, 0x34, 0x0a, 0x16, 0x6d, 0x69, 0x6e, 0x5f, + 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6d, 0x73, + 0x61, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x04, 0x52, 0x14, 0x6d, 0x69, 0x6e, 0x54, 0x72, 0x61, + 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x4d, 0x73, 0x61, 0x74, 0x12, 0x32, + 0x0a, 0x15, 0x70, 0x72, 0x69, 0x63, 0x65, 0x5f, 0x6f, 0x72, 0x61, 0x63, 0x6c, 0x65, 0x5f, 0x6d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x70, + 0x72, 0x69, 0x63, 0x65, 0x4f, 0x72, 0x61, 0x63, 0x6c, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, + 0x74, 0x61, 0x12, 0x35, 0x0a, 0x0a, 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x73, 0x70, 0x65, 0x63, + 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, + 0x41, 0x73, 0x73, 0x65, 0x74, 0x53, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x72, 0x52, 0x09, + 0x61, 0x73, 0x73, 0x65, 0x74, 0x53, 0x70, 0x65, 0x63, 0x22, 0x6b, 0x0a, 0x14, 0x49, 0x6e, 0x76, + 0x61, 0x6c, 0x69, 0x64, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x2f, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0e, 0x32, 0x17, 0x2e, 0x72, 0x66, 0x71, 0x72, 0x70, 0x63, 0x2e, 0x51, 0x75, 0x6f, 0x74, 0x65, + 0x52, 0x65, 0x73, 0x70, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x65, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x70, 0x65, 0x65, 0x72, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x02, 0x69, 0x64, 0x22, 0x7f, 0x0a, 0x15, 0x52, 0x65, 0x6a, 0x65, 0x63, 0x74, + 0x65, 0x64, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x12, 0x0a, 0x04, 0x70, 0x65, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, + 0x65, 0x65, 0x72, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x02, 0x69, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x65, 0x72, 0x72, 0x6f, + 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x65, 0x72, 0x72, 0x6f, + 0x72, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x65, 0x72, + 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x22, 0x9e, 0x01, 0x0a, 0x1f, 0x51, 0x75, 0x65, 0x72, + 0x79, 0x50, 0x65, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x51, 0x75, 0x6f, + 0x74, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x0a, 0x62, + 0x75, 0x79, 0x5f, 0x71, 0x75, 0x6f, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x1c, 0x2e, 0x72, 0x66, 0x71, 0x72, 0x70, 0x63, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x41, 0x63, 0x63, + 0x65, 0x70, 0x74, 0x65, 0x64, 0x42, 0x75, 0x79, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x52, 0x09, 0x62, + 0x75, 0x79, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x73, 0x12, 0x3e, 0x0a, 0x0b, 0x73, 0x65, 0x6c, 0x6c, + 0x5f, 0x71, 0x75, 0x6f, 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, + 0x72, 0x66, 0x71, 0x72, 0x70, 0x63, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x70, + 0x74, 0x65, 0x64, 0x53, 0x65, 0x6c, 0x6c, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x52, 0x0a, 0x73, 0x65, + 0x6c, 0x6c, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x73, 0x22, 0x1f, 0x0a, 0x1d, 0x53, 0x75, 0x62, 0x73, + 0x63, 0x72, 0x69, 0x62, 0x65, 0x52, 0x66, 0x71, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4e, 0x74, 0x66, + 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x8e, 0x01, 0x0a, 0x19, 0x50, 0x65, + 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x42, 0x75, 0x79, 0x51, 0x75, 0x6f, + 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, + 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, + 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x53, 0x0a, 0x17, 0x70, 0x65, 0x65, 0x72, 0x5f, 0x61, 0x63, + 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x75, 0x79, 0x5f, 0x71, 0x75, 0x6f, 0x74, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x72, 0x66, 0x71, 0x72, 0x70, 0x63, 0x2e, + 0x50, 0x65, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x42, 0x75, 0x79, 0x51, + 0x75, 0x6f, 0x74, 0x65, 0x52, 0x14, 0x70, 0x65, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, + 0x65, 0x64, 0x42, 0x75, 0x79, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x22, 0x92, 0x01, 0x0a, 0x1a, 0x50, + 0x65, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x53, 0x65, 0x6c, 0x6c, 0x51, + 0x75, 0x6f, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, + 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, 0x69, + 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x56, 0x0a, 0x18, 0x70, 0x65, 0x65, 0x72, 0x5f, + 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x5f, 0x73, 0x65, 0x6c, 0x6c, 0x5f, 0x71, 0x75, + 0x6f, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x72, 0x66, 0x71, 0x72, + 0x70, 0x63, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x53, + 0x65, 0x6c, 0x6c, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x52, 0x15, 0x70, 0x65, 0x65, 0x72, 0x41, 0x63, + 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x53, 0x65, 0x6c, 0x6c, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x22, + 0x43, 0x0a, 0x0f, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x48, 0x74, 0x6c, 0x63, 0x45, 0x76, 0x65, + 0x6e, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, + 0x12, 0x12, 0x0a, 0x04, 0x73, 0x63, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, + 0x73, 0x63, 0x69, 0x64, 0x22, 0x8a, 0x02, 0x0a, 0x08, 0x52, 0x66, 0x71, 0x45, 0x76, 0x65, 0x6e, + 0x74, 0x12, 0x5a, 0x0a, 0x17, 0x70, 0x65, 0x65, 0x72, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, + 0x65, 0x64, 0x5f, 0x62, 0x75, 0x79, 0x5f, 0x71, 0x75, 0x6f, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x72, 0x66, 0x71, 0x72, 0x70, 0x63, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x42, 0x75, 0x79, 0x51, 0x75, 0x6f, 0x74, 0x65, - 0x22, 0x92, 0x01, 0x0a, 0x1a, 0x50, 0x65, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, - 0x64, 0x53, 0x65, 0x6c, 0x6c, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, - 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x04, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x56, 0x0a, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x14, 0x70, 0x65, 0x65, 0x72, 0x41, 0x63, 0x63, + 0x65, 0x70, 0x74, 0x65, 0x64, 0x42, 0x75, 0x79, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x12, 0x5d, 0x0a, 0x18, 0x70, 0x65, 0x65, 0x72, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x5f, 0x73, 0x65, 0x6c, 0x6c, 0x5f, 0x71, 0x75, 0x6f, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x1d, 0x2e, 0x72, 0x66, 0x71, 0x72, 0x70, 0x63, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x41, 0x63, 0x63, - 0x65, 0x70, 0x74, 0x65, 0x64, 0x53, 0x65, 0x6c, 0x6c, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x52, 0x15, - 0x70, 0x65, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x53, 0x65, 0x6c, 0x6c, - 0x51, 0x75, 0x6f, 0x74, 0x65, 0x22, 0x43, 0x0a, 0x0f, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x48, - 0x74, 0x6c, 0x63, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, - 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, 0x69, 0x6d, - 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x63, 0x69, 0x64, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x73, 0x63, 0x69, 0x64, 0x22, 0x8a, 0x02, 0x0a, 0x08, 0x52, - 0x66, 0x71, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x5a, 0x0a, 0x17, 0x70, 0x65, 0x65, 0x72, 0x5f, - 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x75, 0x79, 0x5f, 0x71, 0x75, 0x6f, - 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x72, 0x66, 0x71, 0x72, 0x70, - 0x63, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x42, 0x75, - 0x79, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x14, 0x70, - 0x65, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x42, 0x75, 0x79, 0x51, 0x75, - 0x6f, 0x74, 0x65, 0x12, 0x5d, 0x0a, 0x18, 0x70, 0x65, 0x65, 0x72, 0x5f, 0x61, 0x63, 0x63, 0x65, - 0x70, 0x74, 0x65, 0x64, 0x5f, 0x73, 0x65, 0x6c, 0x6c, 0x5f, 0x71, 0x75, 0x6f, 0x74, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x72, 0x66, 0x71, 0x72, 0x70, 0x63, 0x2e, 0x50, - 0x65, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x53, 0x65, 0x6c, 0x6c, 0x51, - 0x75, 0x6f, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x15, 0x70, 0x65, 0x65, - 0x72, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x53, 0x65, 0x6c, 0x6c, 0x51, 0x75, 0x6f, - 0x74, 0x65, 0x12, 0x3a, 0x0a, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x5f, 0x68, 0x74, 0x6c, - 0x63, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x72, 0x66, 0x71, 0x72, 0x70, 0x63, - 0x2e, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x48, 0x74, 0x6c, 0x63, 0x45, 0x76, 0x65, 0x6e, 0x74, - 0x48, 0x00, 0x52, 0x0a, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x48, 0x74, 0x6c, 0x63, 0x42, 0x07, - 0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x2a, 0x5a, 0x0a, 0x0f, 0x51, 0x75, 0x6f, 0x74, 0x65, - 0x52, 0x65, 0x73, 0x70, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x17, 0x0a, 0x13, 0x49, 0x4e, - 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x41, 0x53, 0x53, 0x45, 0x54, 0x5f, 0x52, 0x41, 0x54, 0x45, - 0x53, 0x10, 0x00, 0x12, 0x12, 0x0a, 0x0e, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x45, - 0x58, 0x50, 0x49, 0x52, 0x59, 0x10, 0x01, 0x12, 0x1a, 0x0a, 0x16, 0x50, 0x52, 0x49, 0x43, 0x45, - 0x5f, 0x4f, 0x52, 0x41, 0x43, 0x4c, 0x45, 0x5f, 0x51, 0x55, 0x45, 0x52, 0x59, 0x5f, 0x45, 0x52, - 0x52, 0x10, 0x02, 0x32, 0xa8, 0x04, 0x0a, 0x03, 0x52, 0x66, 0x71, 0x12, 0x55, 0x0a, 0x10, 0x41, - 0x64, 0x64, 0x41, 0x73, 0x73, 0x65, 0x74, 0x42, 0x75, 0x79, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x12, - 0x1f, 0x2e, 0x72, 0x66, 0x71, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x64, 0x64, 0x41, 0x73, 0x73, 0x65, - 0x74, 0x42, 0x75, 0x79, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x20, 0x2e, 0x72, 0x66, 0x71, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x64, 0x64, 0x41, 0x73, 0x73, - 0x65, 0x74, 0x42, 0x75, 0x79, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x58, 0x0a, 0x11, 0x41, 0x64, 0x64, 0x41, 0x73, 0x73, 0x65, 0x74, 0x53, 0x65, - 0x6c, 0x6c, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x12, 0x20, 0x2e, 0x72, 0x66, 0x71, 0x72, 0x70, 0x63, - 0x2e, 0x41, 0x64, 0x64, 0x41, 0x73, 0x73, 0x65, 0x74, 0x53, 0x65, 0x6c, 0x6c, 0x4f, 0x72, 0x64, - 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x72, 0x66, 0x71, 0x72, - 0x70, 0x63, 0x2e, 0x41, 0x64, 0x64, 0x41, 0x73, 0x73, 0x65, 0x74, 0x53, 0x65, 0x6c, 0x6c, 0x4f, + 0x22, 0x2e, 0x72, 0x66, 0x71, 0x72, 0x70, 0x63, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x41, 0x63, 0x63, + 0x65, 0x70, 0x74, 0x65, 0x64, 0x53, 0x65, 0x6c, 0x6c, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x45, 0x76, + 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x15, 0x70, 0x65, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x70, + 0x74, 0x65, 0x64, 0x53, 0x65, 0x6c, 0x6c, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x12, 0x3a, 0x0a, 0x0b, + 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x5f, 0x68, 0x74, 0x6c, 0x63, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x17, 0x2e, 0x72, 0x66, 0x71, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x70, + 0x74, 0x48, 0x74, 0x6c, 0x63, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x0a, 0x61, 0x63, + 0x63, 0x65, 0x70, 0x74, 0x48, 0x74, 0x6c, 0x63, 0x42, 0x07, 0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e, + 0x74, 0x2a, 0x5a, 0x0a, 0x0f, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x53, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x12, 0x17, 0x0a, 0x13, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, + 0x41, 0x53, 0x53, 0x45, 0x54, 0x5f, 0x52, 0x41, 0x54, 0x45, 0x53, 0x10, 0x00, 0x12, 0x12, 0x0a, + 0x0e, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x45, 0x58, 0x50, 0x49, 0x52, 0x59, 0x10, + 0x01, 0x12, 0x1a, 0x0a, 0x16, 0x50, 0x52, 0x49, 0x43, 0x45, 0x5f, 0x4f, 0x52, 0x41, 0x43, 0x4c, + 0x45, 0x5f, 0x51, 0x55, 0x45, 0x52, 0x59, 0x5f, 0x45, 0x52, 0x52, 0x10, 0x02, 0x32, 0xa8, 0x04, + 0x0a, 0x03, 0x52, 0x66, 0x71, 0x12, 0x55, 0x0a, 0x10, 0x41, 0x64, 0x64, 0x41, 0x73, 0x73, 0x65, + 0x74, 0x42, 0x75, 0x79, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x12, 0x1f, 0x2e, 0x72, 0x66, 0x71, 0x72, + 0x70, 0x63, 0x2e, 0x41, 0x64, 0x64, 0x41, 0x73, 0x73, 0x65, 0x74, 0x42, 0x75, 0x79, 0x4f, 0x72, + 0x64, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x72, 0x66, 0x71, + 0x72, 0x70, 0x63, 0x2e, 0x41, 0x64, 0x64, 0x41, 0x73, 0x73, 0x65, 0x74, 0x42, 0x75, 0x79, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x58, 0x0a, 0x11, - 0x41, 0x64, 0x64, 0x41, 0x73, 0x73, 0x65, 0x74, 0x53, 0x65, 0x6c, 0x6c, 0x4f, 0x66, 0x66, 0x65, + 0x41, 0x64, 0x64, 0x41, 0x73, 0x73, 0x65, 0x74, 0x53, 0x65, 0x6c, 0x6c, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x12, 0x20, 0x2e, 0x72, 0x66, 0x71, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x64, 0x64, 0x41, 0x73, - 0x73, 0x65, 0x74, 0x53, 0x65, 0x6c, 0x6c, 0x4f, 0x66, 0x66, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, + 0x73, 0x65, 0x74, 0x53, 0x65, 0x6c, 0x6c, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x72, 0x66, 0x71, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x64, 0x64, - 0x41, 0x73, 0x73, 0x65, 0x74, 0x53, 0x65, 0x6c, 0x6c, 0x4f, 0x66, 0x66, 0x65, 0x72, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x55, 0x0a, 0x10, 0x41, 0x64, 0x64, 0x41, 0x73, 0x73, - 0x65, 0x74, 0x42, 0x75, 0x79, 0x4f, 0x66, 0x66, 0x65, 0x72, 0x12, 0x1f, 0x2e, 0x72, 0x66, 0x71, - 0x72, 0x70, 0x63, 0x2e, 0x41, 0x64, 0x64, 0x41, 0x73, 0x73, 0x65, 0x74, 0x42, 0x75, 0x79, 0x4f, - 0x66, 0x66, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x72, 0x66, - 0x71, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x64, 0x64, 0x41, 0x73, 0x73, 0x65, 0x74, 0x42, 0x75, 0x79, - 0x4f, 0x66, 0x66, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6a, 0x0a, - 0x17, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x65, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, - 0x65, 0x64, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x73, 0x12, 0x26, 0x2e, 0x72, 0x66, 0x71, 0x72, 0x70, - 0x63, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x65, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x70, - 0x74, 0x65, 0x64, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x27, 0x2e, 0x72, 0x66, 0x71, 0x72, 0x70, 0x63, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, - 0x65, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x51, 0x75, 0x6f, 0x74, 0x65, - 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x53, 0x0a, 0x16, 0x53, 0x75, 0x62, - 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x52, 0x66, 0x71, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4e, 0x74, - 0x66, 0x6e, 0x73, 0x12, 0x25, 0x2e, 0x72, 0x66, 0x71, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x75, 0x62, - 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x52, 0x66, 0x71, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4e, 0x74, - 0x66, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x10, 0x2e, 0x72, 0x66, 0x71, - 0x72, 0x70, 0x63, 0x2e, 0x52, 0x66, 0x71, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x30, 0x01, 0x42, 0x37, - 0x5a, 0x35, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6c, 0x69, 0x67, - 0x68, 0x74, 0x6e, 0x69, 0x6e, 0x67, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x74, 0x61, 0x70, 0x72, 0x6f, - 0x6f, 0x74, 0x2d, 0x61, 0x73, 0x73, 0x65, 0x74, 0x73, 0x2f, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, - 0x2f, 0x72, 0x66, 0x71, 0x72, 0x70, 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x41, 0x73, 0x73, 0x65, 0x74, 0x53, 0x65, 0x6c, 0x6c, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x58, 0x0a, 0x11, 0x41, 0x64, 0x64, 0x41, 0x73, 0x73, + 0x65, 0x74, 0x53, 0x65, 0x6c, 0x6c, 0x4f, 0x66, 0x66, 0x65, 0x72, 0x12, 0x20, 0x2e, 0x72, 0x66, + 0x71, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x64, 0x64, 0x41, 0x73, 0x73, 0x65, 0x74, 0x53, 0x65, 0x6c, + 0x6c, 0x4f, 0x66, 0x66, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, + 0x72, 0x66, 0x71, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x64, 0x64, 0x41, 0x73, 0x73, 0x65, 0x74, 0x53, + 0x65, 0x6c, 0x6c, 0x4f, 0x66, 0x66, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x55, 0x0a, 0x10, 0x41, 0x64, 0x64, 0x41, 0x73, 0x73, 0x65, 0x74, 0x42, 0x75, 0x79, 0x4f, + 0x66, 0x66, 0x65, 0x72, 0x12, 0x1f, 0x2e, 0x72, 0x66, 0x71, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x64, + 0x64, 0x41, 0x73, 0x73, 0x65, 0x74, 0x42, 0x75, 0x79, 0x4f, 0x66, 0x66, 0x65, 0x72, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x72, 0x66, 0x71, 0x72, 0x70, 0x63, 0x2e, 0x41, + 0x64, 0x64, 0x41, 0x73, 0x73, 0x65, 0x74, 0x42, 0x75, 0x79, 0x4f, 0x66, 0x66, 0x65, 0x72, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6a, 0x0a, 0x17, 0x51, 0x75, 0x65, 0x72, 0x79, + 0x50, 0x65, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x51, 0x75, 0x6f, 0x74, + 0x65, 0x73, 0x12, 0x26, 0x2e, 0x72, 0x66, 0x71, 0x72, 0x70, 0x63, 0x2e, 0x51, 0x75, 0x65, 0x72, + 0x79, 0x50, 0x65, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x51, 0x75, 0x6f, + 0x74, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x72, 0x66, 0x71, + 0x72, 0x70, 0x63, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x65, 0x65, 0x72, 0x41, 0x63, 0x63, + 0x65, 0x70, 0x74, 0x65, 0x64, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x53, 0x0a, 0x16, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, + 0x52, 0x66, 0x71, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4e, 0x74, 0x66, 0x6e, 0x73, 0x12, 0x25, 0x2e, + 0x72, 0x66, 0x71, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, + 0x52, 0x66, 0x71, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4e, 0x74, 0x66, 0x6e, 0x73, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x10, 0x2e, 0x72, 0x66, 0x71, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x66, + 0x71, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x30, 0x01, 0x42, 0x37, 0x5a, 0x35, 0x67, 0x69, 0x74, 0x68, + 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x6e, 0x69, 0x6e, 0x67, + 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x74, 0x61, 0x70, 0x72, 0x6f, 0x6f, 0x74, 0x2d, 0x61, 0x73, 0x73, + 0x65, 0x74, 0x73, 0x2f, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2f, 0x72, 0x66, 0x71, 0x72, 0x70, + 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -2055,7 +1995,7 @@ func file_rfqrpc_rfq_proto_rawDescGZIP() []byte { } var file_rfqrpc_rfq_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_rfqrpc_rfq_proto_msgTypes = make([]protoimpl.MessageInfo, 22) +var file_rfqrpc_rfq_proto_msgTypes = make([]protoimpl.MessageInfo, 21) var file_rfqrpc_rfq_proto_goTypes = []any{ (QuoteRespStatus)(0), // 0: rfqrpc.QuoteRespStatus (*AssetSpecifier)(nil), // 1: rfqrpc.AssetSpecifier @@ -2069,53 +2009,53 @@ var file_rfqrpc_rfq_proto_goTypes = []any{ (*AddAssetBuyOfferRequest)(nil), // 9: rfqrpc.AddAssetBuyOfferRequest (*AddAssetBuyOfferResponse)(nil), // 10: rfqrpc.AddAssetBuyOfferResponse (*QueryPeerAcceptedQuotesRequest)(nil), // 11: rfqrpc.QueryPeerAcceptedQuotesRequest - (*AssetSpec)(nil), // 12: rfqrpc.AssetSpec - (*PeerAcceptedBuyQuote)(nil), // 13: rfqrpc.PeerAcceptedBuyQuote - (*PeerAcceptedSellQuote)(nil), // 14: rfqrpc.PeerAcceptedSellQuote - (*InvalidQuoteResponse)(nil), // 15: rfqrpc.InvalidQuoteResponse - (*RejectedQuoteResponse)(nil), // 16: rfqrpc.RejectedQuoteResponse - (*QueryPeerAcceptedQuotesResponse)(nil), // 17: rfqrpc.QueryPeerAcceptedQuotesResponse - (*SubscribeRfqEventNtfnsRequest)(nil), // 18: rfqrpc.SubscribeRfqEventNtfnsRequest - (*PeerAcceptedBuyQuoteEvent)(nil), // 19: rfqrpc.PeerAcceptedBuyQuoteEvent - (*PeerAcceptedSellQuoteEvent)(nil), // 20: rfqrpc.PeerAcceptedSellQuoteEvent - (*AcceptHtlcEvent)(nil), // 21: rfqrpc.AcceptHtlcEvent - (*RfqEvent)(nil), // 22: rfqrpc.RfqEvent + (*PeerAcceptedBuyQuote)(nil), // 12: rfqrpc.PeerAcceptedBuyQuote + (*PeerAcceptedSellQuote)(nil), // 13: rfqrpc.PeerAcceptedSellQuote + (*InvalidQuoteResponse)(nil), // 14: rfqrpc.InvalidQuoteResponse + (*RejectedQuoteResponse)(nil), // 15: rfqrpc.RejectedQuoteResponse + (*QueryPeerAcceptedQuotesResponse)(nil), // 16: rfqrpc.QueryPeerAcceptedQuotesResponse + (*SubscribeRfqEventNtfnsRequest)(nil), // 17: rfqrpc.SubscribeRfqEventNtfnsRequest + (*PeerAcceptedBuyQuoteEvent)(nil), // 18: rfqrpc.PeerAcceptedBuyQuoteEvent + (*PeerAcceptedSellQuoteEvent)(nil), // 19: rfqrpc.PeerAcceptedSellQuoteEvent + (*AcceptHtlcEvent)(nil), // 20: rfqrpc.AcceptHtlcEvent + (*RfqEvent)(nil), // 21: rfqrpc.RfqEvent + (*taprpc.AssetSpecifier)(nil), // 22: taprpc.AssetSpecifier } var file_rfqrpc_rfq_proto_depIdxs = []int32{ 1, // 0: rfqrpc.AddAssetBuyOrderRequest.asset_specifier:type_name -> rfqrpc.AssetSpecifier - 13, // 1: rfqrpc.AddAssetBuyOrderResponse.accepted_quote:type_name -> rfqrpc.PeerAcceptedBuyQuote - 15, // 2: rfqrpc.AddAssetBuyOrderResponse.invalid_quote:type_name -> rfqrpc.InvalidQuoteResponse - 16, // 3: rfqrpc.AddAssetBuyOrderResponse.rejected_quote:type_name -> rfqrpc.RejectedQuoteResponse + 12, // 1: rfqrpc.AddAssetBuyOrderResponse.accepted_quote:type_name -> rfqrpc.PeerAcceptedBuyQuote + 14, // 2: rfqrpc.AddAssetBuyOrderResponse.invalid_quote:type_name -> rfqrpc.InvalidQuoteResponse + 15, // 3: rfqrpc.AddAssetBuyOrderResponse.rejected_quote:type_name -> rfqrpc.RejectedQuoteResponse 1, // 4: rfqrpc.AddAssetSellOrderRequest.asset_specifier:type_name -> rfqrpc.AssetSpecifier - 14, // 5: rfqrpc.AddAssetSellOrderResponse.accepted_quote:type_name -> rfqrpc.PeerAcceptedSellQuote - 15, // 6: rfqrpc.AddAssetSellOrderResponse.invalid_quote:type_name -> rfqrpc.InvalidQuoteResponse - 16, // 7: rfqrpc.AddAssetSellOrderResponse.rejected_quote:type_name -> rfqrpc.RejectedQuoteResponse + 13, // 5: rfqrpc.AddAssetSellOrderResponse.accepted_quote:type_name -> rfqrpc.PeerAcceptedSellQuote + 14, // 6: rfqrpc.AddAssetSellOrderResponse.invalid_quote:type_name -> rfqrpc.InvalidQuoteResponse + 15, // 7: rfqrpc.AddAssetSellOrderResponse.rejected_quote:type_name -> rfqrpc.RejectedQuoteResponse 1, // 8: rfqrpc.AddAssetSellOfferRequest.asset_specifier:type_name -> rfqrpc.AssetSpecifier 1, // 9: rfqrpc.AddAssetBuyOfferRequest.asset_specifier:type_name -> rfqrpc.AssetSpecifier 2, // 10: rfqrpc.PeerAcceptedBuyQuote.ask_asset_rate:type_name -> rfqrpc.FixedPoint - 12, // 11: rfqrpc.PeerAcceptedBuyQuote.asset_spec:type_name -> rfqrpc.AssetSpec + 22, // 11: rfqrpc.PeerAcceptedBuyQuote.asset_spec:type_name -> taprpc.AssetSpecifier 2, // 12: rfqrpc.PeerAcceptedSellQuote.bid_asset_rate:type_name -> rfqrpc.FixedPoint - 12, // 13: rfqrpc.PeerAcceptedSellQuote.asset_spec:type_name -> rfqrpc.AssetSpec + 22, // 13: rfqrpc.PeerAcceptedSellQuote.asset_spec:type_name -> taprpc.AssetSpecifier 0, // 14: rfqrpc.InvalidQuoteResponse.status:type_name -> rfqrpc.QuoteRespStatus - 13, // 15: rfqrpc.QueryPeerAcceptedQuotesResponse.buy_quotes:type_name -> rfqrpc.PeerAcceptedBuyQuote - 14, // 16: rfqrpc.QueryPeerAcceptedQuotesResponse.sell_quotes:type_name -> rfqrpc.PeerAcceptedSellQuote - 13, // 17: rfqrpc.PeerAcceptedBuyQuoteEvent.peer_accepted_buy_quote:type_name -> rfqrpc.PeerAcceptedBuyQuote - 14, // 18: rfqrpc.PeerAcceptedSellQuoteEvent.peer_accepted_sell_quote:type_name -> rfqrpc.PeerAcceptedSellQuote - 19, // 19: rfqrpc.RfqEvent.peer_accepted_buy_quote:type_name -> rfqrpc.PeerAcceptedBuyQuoteEvent - 20, // 20: rfqrpc.RfqEvent.peer_accepted_sell_quote:type_name -> rfqrpc.PeerAcceptedSellQuoteEvent - 21, // 21: rfqrpc.RfqEvent.accept_htlc:type_name -> rfqrpc.AcceptHtlcEvent + 12, // 15: rfqrpc.QueryPeerAcceptedQuotesResponse.buy_quotes:type_name -> rfqrpc.PeerAcceptedBuyQuote + 13, // 16: rfqrpc.QueryPeerAcceptedQuotesResponse.sell_quotes:type_name -> rfqrpc.PeerAcceptedSellQuote + 12, // 17: rfqrpc.PeerAcceptedBuyQuoteEvent.peer_accepted_buy_quote:type_name -> rfqrpc.PeerAcceptedBuyQuote + 13, // 18: rfqrpc.PeerAcceptedSellQuoteEvent.peer_accepted_sell_quote:type_name -> rfqrpc.PeerAcceptedSellQuote + 18, // 19: rfqrpc.RfqEvent.peer_accepted_buy_quote:type_name -> rfqrpc.PeerAcceptedBuyQuoteEvent + 19, // 20: rfqrpc.RfqEvent.peer_accepted_sell_quote:type_name -> rfqrpc.PeerAcceptedSellQuoteEvent + 20, // 21: rfqrpc.RfqEvent.accept_htlc:type_name -> rfqrpc.AcceptHtlcEvent 3, // 22: rfqrpc.Rfq.AddAssetBuyOrder:input_type -> rfqrpc.AddAssetBuyOrderRequest 5, // 23: rfqrpc.Rfq.AddAssetSellOrder:input_type -> rfqrpc.AddAssetSellOrderRequest 7, // 24: rfqrpc.Rfq.AddAssetSellOffer:input_type -> rfqrpc.AddAssetSellOfferRequest 9, // 25: rfqrpc.Rfq.AddAssetBuyOffer:input_type -> rfqrpc.AddAssetBuyOfferRequest 11, // 26: rfqrpc.Rfq.QueryPeerAcceptedQuotes:input_type -> rfqrpc.QueryPeerAcceptedQuotesRequest - 18, // 27: rfqrpc.Rfq.SubscribeRfqEventNtfns:input_type -> rfqrpc.SubscribeRfqEventNtfnsRequest + 17, // 27: rfqrpc.Rfq.SubscribeRfqEventNtfns:input_type -> rfqrpc.SubscribeRfqEventNtfnsRequest 4, // 28: rfqrpc.Rfq.AddAssetBuyOrder:output_type -> rfqrpc.AddAssetBuyOrderResponse 6, // 29: rfqrpc.Rfq.AddAssetSellOrder:output_type -> rfqrpc.AddAssetSellOrderResponse 8, // 30: rfqrpc.Rfq.AddAssetSellOffer:output_type -> rfqrpc.AddAssetSellOfferResponse 10, // 31: rfqrpc.Rfq.AddAssetBuyOffer:output_type -> rfqrpc.AddAssetBuyOfferResponse - 17, // 32: rfqrpc.Rfq.QueryPeerAcceptedQuotes:output_type -> rfqrpc.QueryPeerAcceptedQuotesResponse - 22, // 33: rfqrpc.Rfq.SubscribeRfqEventNtfns:output_type -> rfqrpc.RfqEvent + 16, // 32: rfqrpc.Rfq.QueryPeerAcceptedQuotes:output_type -> rfqrpc.QueryPeerAcceptedQuotesResponse + 21, // 33: rfqrpc.Rfq.SubscribeRfqEventNtfns:output_type -> rfqrpc.RfqEvent 28, // [28:34] is the sub-list for method output_type 22, // [22:28] is the sub-list for method input_type 22, // [22:22] is the sub-list for extension type_name @@ -2262,18 +2202,6 @@ func file_rfqrpc_rfq_proto_init() { } } file_rfqrpc_rfq_proto_msgTypes[11].Exporter = func(v any, i int) any { - switch v := v.(*AssetSpec); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_rfqrpc_rfq_proto_msgTypes[12].Exporter = func(v any, i int) any { switch v := v.(*PeerAcceptedBuyQuote); i { case 0: return &v.state @@ -2285,7 +2213,7 @@ func file_rfqrpc_rfq_proto_init() { return nil } } - file_rfqrpc_rfq_proto_msgTypes[13].Exporter = func(v any, i int) any { + file_rfqrpc_rfq_proto_msgTypes[12].Exporter = func(v any, i int) any { switch v := v.(*PeerAcceptedSellQuote); i { case 0: return &v.state @@ -2297,7 +2225,7 @@ func file_rfqrpc_rfq_proto_init() { return nil } } - file_rfqrpc_rfq_proto_msgTypes[14].Exporter = func(v any, i int) any { + file_rfqrpc_rfq_proto_msgTypes[13].Exporter = func(v any, i int) any { switch v := v.(*InvalidQuoteResponse); i { case 0: return &v.state @@ -2309,7 +2237,7 @@ func file_rfqrpc_rfq_proto_init() { return nil } } - file_rfqrpc_rfq_proto_msgTypes[15].Exporter = func(v any, i int) any { + file_rfqrpc_rfq_proto_msgTypes[14].Exporter = func(v any, i int) any { switch v := v.(*RejectedQuoteResponse); i { case 0: return &v.state @@ -2321,7 +2249,7 @@ func file_rfqrpc_rfq_proto_init() { return nil } } - file_rfqrpc_rfq_proto_msgTypes[16].Exporter = func(v any, i int) any { + file_rfqrpc_rfq_proto_msgTypes[15].Exporter = func(v any, i int) any { switch v := v.(*QueryPeerAcceptedQuotesResponse); i { case 0: return &v.state @@ -2333,7 +2261,7 @@ func file_rfqrpc_rfq_proto_init() { return nil } } - file_rfqrpc_rfq_proto_msgTypes[17].Exporter = func(v any, i int) any { + file_rfqrpc_rfq_proto_msgTypes[16].Exporter = func(v any, i int) any { switch v := v.(*SubscribeRfqEventNtfnsRequest); i { case 0: return &v.state @@ -2345,7 +2273,7 @@ func file_rfqrpc_rfq_proto_init() { return nil } } - file_rfqrpc_rfq_proto_msgTypes[18].Exporter = func(v any, i int) any { + file_rfqrpc_rfq_proto_msgTypes[17].Exporter = func(v any, i int) any { switch v := v.(*PeerAcceptedBuyQuoteEvent); i { case 0: return &v.state @@ -2357,7 +2285,7 @@ func file_rfqrpc_rfq_proto_init() { return nil } } - file_rfqrpc_rfq_proto_msgTypes[19].Exporter = func(v any, i int) any { + file_rfqrpc_rfq_proto_msgTypes[18].Exporter = func(v any, i int) any { switch v := v.(*PeerAcceptedSellQuoteEvent); i { case 0: return &v.state @@ -2369,7 +2297,7 @@ func file_rfqrpc_rfq_proto_init() { return nil } } - file_rfqrpc_rfq_proto_msgTypes[20].Exporter = func(v any, i int) any { + file_rfqrpc_rfq_proto_msgTypes[19].Exporter = func(v any, i int) any { switch v := v.(*AcceptHtlcEvent); i { case 0: return &v.state @@ -2381,7 +2309,7 @@ func file_rfqrpc_rfq_proto_init() { return nil } } - file_rfqrpc_rfq_proto_msgTypes[21].Exporter = func(v any, i int) any { + file_rfqrpc_rfq_proto_msgTypes[20].Exporter = func(v any, i int) any { switch v := v.(*RfqEvent); i { case 0: return &v.state @@ -2410,7 +2338,7 @@ func file_rfqrpc_rfq_proto_init() { (*AddAssetSellOrderResponse_InvalidQuote)(nil), (*AddAssetSellOrderResponse_RejectedQuote)(nil), } - file_rfqrpc_rfq_proto_msgTypes[21].OneofWrappers = []any{ + file_rfqrpc_rfq_proto_msgTypes[20].OneofWrappers = []any{ (*RfqEvent_PeerAcceptedBuyQuote)(nil), (*RfqEvent_PeerAcceptedSellQuote)(nil), (*RfqEvent_AcceptHtlc)(nil), @@ -2421,7 +2349,7 @@ func file_rfqrpc_rfq_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_rfqrpc_rfq_proto_rawDesc, NumEnums: 1, - NumMessages: 22, + NumMessages: 21, NumExtensions: 0, NumServices: 1, }, diff --git a/taprpc/rfqrpc/rfq.proto b/taprpc/rfqrpc/rfq.proto index 0d472c268..f31489250 100644 --- a/taprpc/rfqrpc/rfq.proto +++ b/taprpc/rfqrpc/rfq.proto @@ -2,6 +2,8 @@ syntax = "proto3"; package rfqrpc; +import "tapcommon.proto"; + option go_package = "github.com/lightninglabs/taproot-assets/taprpc/rfqrpc"; service Rfq { @@ -247,16 +249,6 @@ message AddAssetBuyOfferResponse { message QueryPeerAcceptedQuotesRequest { } -message AssetSpec { - // The 32-byte asset ID specified as raw bytes. - bytes id = 1; - - // The 32-byte asset group public key, serialized in BIP340 format. - // BIP340 defines a canonical encoding for Schnorr public keys. - // This field is serialized using schnorr.SerializePubKey. - bytes group_pub_key = 2; -} - message PeerAcceptedBuyQuote { // Quote counterparty peer. string peer = 1; @@ -295,7 +287,7 @@ message PeerAcceptedBuyQuote { string price_oracle_metadata = 8; // The subject asset specifier. - AssetSpec asset_spec = 9; + taprpc.AssetSpecifier asset_spec = 9; } message PeerAcceptedSellQuote { @@ -334,7 +326,7 @@ message PeerAcceptedSellQuote { string price_oracle_metadata = 8; // The subject asset specifier. - AssetSpec asset_spec = 9; + taprpc.AssetSpecifier asset_spec = 9; } // QuoteRespStatus is an enum that represents the status of a quote response. diff --git a/taprpc/rfqrpc/rfq.swagger.json b/taprpc/rfqrpc/rfq.swagger.json index 71636f8f7..ac36a7ad5 100644 --- a/taprpc/rfqrpc/rfq.swagger.json +++ b/taprpc/rfqrpc/rfq.swagger.json @@ -641,21 +641,6 @@ } } }, - "rfqrpcAssetSpec": { - "type": "object", - "properties": { - "id": { - "type": "string", - "format": "byte", - "description": "The 32-byte asset ID specified as raw bytes." - }, - "group_pub_key": { - "type": "string", - "format": "byte", - "description": "The 32-byte asset group public key, serialized in BIP340 format.\nBIP340 defines a canonical encoding for Schnorr public keys.\nThis field is serialized using schnorr.SerializePubKey." - } - } - }, "rfqrpcAssetSpecifier": { "type": "object", "properties": { @@ -754,7 +739,7 @@ "description": "An optional user-provided text field used to provide additional metadata\nabout the buy order to the price oracle. This can include information\nabout the wallet end user that initiated the transaction, or any\nauthentication information that the price oracle can use to give out a\nmore accurate (or discount) asset rate." }, "asset_spec": { - "$ref": "#/definitions/rfqrpcAssetSpec", + "$ref": "#/definitions/taprpcAssetSpecifier", "description": "The subject asset specifier." } } @@ -814,7 +799,7 @@ "description": "An optional user-provided text field used to provide additional metadata\nabout the sell order to the price oracle. This can include information\nabout the wallet end user that initiated the transaction, or any\nauthentication information that the price oracle can use to give out a\nmore accurate (or discount) asset rate." }, "asset_spec": { - "$ref": "#/definitions/rfqrpcAssetSpec", + "$ref": "#/definitions/taprpcAssetSpecifier", "description": "The subject asset specifier." } } @@ -926,6 +911,21 @@ } } } + }, + "taprpcAssetSpecifier": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "byte", + "description": "The 32-byte asset ID specified." + }, + "group_key": { + "type": "string", + "format": "byte", + "description": "The 32-byte asset group key specified." + } + } } } } diff --git a/taprpc/tapchannelrpc/tapchannel.swagger.json b/taprpc/tapchannelrpc/tapchannel.swagger.json index 5649a69c1..da60e637f 100644 --- a/taprpc/tapchannelrpc/tapchannel.swagger.json +++ b/taprpc/tapchannelrpc/tapchannel.swagger.json @@ -1238,21 +1238,6 @@ }, "additionalProperties": {} }, - "rfqrpcAssetSpec": { - "type": "object", - "properties": { - "id": { - "type": "string", - "format": "byte", - "description": "The 32-byte asset ID specified as raw bytes." - }, - "group_pub_key": { - "type": "string", - "format": "byte", - "description": "The 32-byte asset group public key, serialized in BIP340 format.\nBIP340 defines a canonical encoding for Schnorr public keys.\nThis field is serialized using schnorr.SerializePubKey." - } - } - }, "rfqrpcFixedPoint": { "type": "object", "properties": { @@ -1309,7 +1294,7 @@ "description": "An optional user-provided text field used to provide additional metadata\nabout the buy order to the price oracle. This can include information\nabout the wallet end user that initiated the transaction, or any\nauthentication information that the price oracle can use to give out a\nmore accurate (or discount) asset rate." }, "asset_spec": { - "$ref": "#/definitions/rfqrpcAssetSpec", + "$ref": "#/definitions/taprpcAssetSpecifier", "description": "The subject asset specifier." } } @@ -1355,7 +1340,7 @@ "description": "An optional user-provided text field used to provide additional metadata\nabout the sell order to the price oracle. This can include information\nabout the wallet end user that initiated the transaction, or any\nauthentication information that the price oracle can use to give out a\nmore accurate (or discount) asset rate." }, "asset_spec": { - "$ref": "#/definitions/rfqrpcAssetSpec", + "$ref": "#/definitions/taprpcAssetSpecifier", "description": "The subject asset specifier." } } @@ -1813,6 +1798,21 @@ } } }, + "taprpcAssetSpecifier": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "byte", + "description": "The 32-byte asset ID specified." + }, + "group_key": { + "type": "string", + "format": "byte", + "description": "The 32-byte asset group key specified." + } + } + }, "taprpcAssetType": { "type": "string", "enum": [ diff --git a/taprpc/tapcommon.pb.go b/taprpc/tapcommon.pb.go index a91d9305c..1405c2b2a 100644 --- a/taprpc/tapcommon.pb.go +++ b/taprpc/tapcommon.pb.go @@ -20,6 +20,54 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) +type SortDirection int32 + +const ( + // Sort results in descending order. + SortDirection_SORT_DIRECTION_DESC SortDirection = 0 + // Sort results in ascending order. + SortDirection_SORT_DIRECTION_ASC SortDirection = 1 +) + +// Enum value maps for SortDirection. +var ( + SortDirection_name = map[int32]string{ + 0: "SORT_DIRECTION_DESC", + 1: "SORT_DIRECTION_ASC", + } + SortDirection_value = map[string]int32{ + "SORT_DIRECTION_DESC": 0, + "SORT_DIRECTION_ASC": 1, + } +) + +func (x SortDirection) Enum() *SortDirection { + p := new(SortDirection) + *p = x + return p +} + +func (x SortDirection) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (SortDirection) Descriptor() protoreflect.EnumDescriptor { + return file_tapcommon_proto_enumTypes[0].Descriptor() +} + +func (SortDirection) Type() protoreflect.EnumType { + return &file_tapcommon_proto_enumTypes[0] +} + +func (x SortDirection) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use SortDirection.Descriptor instead. +func (SortDirection) EnumDescriptor() ([]byte, []int) { + return file_tapcommon_proto_rawDescGZIP(), []int{0} +} + // Represents a Bitcoin transaction outpoint. type OutPoint struct { state protoimpl.MessageState @@ -151,6 +199,63 @@ func (x *AssetOutPoint) GetScriptKey() []byte { return nil } +type AssetSpecifier struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The 32-byte asset ID specified. + Id []byte `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + // The 32-byte asset group key specified. + GroupKey []byte `protobuf:"bytes,2,opt,name=group_key,json=groupKey,proto3" json:"group_key,omitempty"` +} + +func (x *AssetSpecifier) Reset() { + *x = AssetSpecifier{} + if protoimpl.UnsafeEnabled { + mi := &file_tapcommon_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AssetSpecifier) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AssetSpecifier) ProtoMessage() {} + +func (x *AssetSpecifier) ProtoReflect() protoreflect.Message { + mi := &file_tapcommon_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) +} + +// Deprecated: Use AssetSpecifier.ProtoReflect.Descriptor instead. +func (*AssetSpecifier) Descriptor() ([]byte, []int) { + return file_tapcommon_proto_rawDescGZIP(), []int{2} +} + +func (x *AssetSpecifier) GetId() []byte { + if x != nil { + return x.Id + } + return nil +} + +func (x *AssetSpecifier) GetGroupKey() []byte { + if x != nil { + return x.GroupKey + } + return nil +} + var File_tapcommon_proto protoreflect.FileDescriptor var file_tapcommon_proto_rawDesc = []byte{ @@ -167,10 +272,18 @@ var file_tapcommon_proto_rawDesc = []byte{ 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x61, 0x73, 0x73, 0x65, 0x74, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x4b, 0x65, - 0x79, 0x42, 0x30, 0x5a, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, - 0x6c, 0x69, 0x67, 0x68, 0x74, 0x6e, 0x69, 0x6e, 0x67, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x74, 0x61, - 0x70, 0x72, 0x6f, 0x6f, 0x74, 0x2d, 0x61, 0x73, 0x73, 0x65, 0x74, 0x73, 0x2f, 0x74, 0x61, 0x70, - 0x72, 0x70, 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x79, 0x22, 0x3d, 0x0a, 0x0e, 0x41, 0x73, 0x73, 0x65, 0x74, 0x53, 0x70, 0x65, 0x63, 0x69, 0x66, + 0x69, 0x65, 0x72, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x02, 0x69, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x6b, 0x65, 0x79, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x4b, 0x65, 0x79, + 0x2a, 0x40, 0x0a, 0x0d, 0x53, 0x6f, 0x72, 0x74, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x12, 0x17, 0x0a, 0x13, 0x53, 0x4f, 0x52, 0x54, 0x5f, 0x44, 0x49, 0x52, 0x45, 0x43, 0x54, + 0x49, 0x4f, 0x4e, 0x5f, 0x44, 0x45, 0x53, 0x43, 0x10, 0x00, 0x12, 0x16, 0x0a, 0x12, 0x53, 0x4f, + 0x52, 0x54, 0x5f, 0x44, 0x49, 0x52, 0x45, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x41, 0x53, 0x43, + 0x10, 0x01, 0x42, 0x30, 0x5a, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, + 0x2f, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x6e, 0x69, 0x6e, 0x67, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x74, + 0x61, 0x70, 0x72, 0x6f, 0x6f, 0x74, 0x2d, 0x61, 0x73, 0x73, 0x65, 0x74, 0x73, 0x2f, 0x74, 0x61, + 0x70, 0x72, 0x70, 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -185,10 +298,13 @@ func file_tapcommon_proto_rawDescGZIP() []byte { return file_tapcommon_proto_rawDescData } -var file_tapcommon_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_tapcommon_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_tapcommon_proto_msgTypes = make([]protoimpl.MessageInfo, 3) var file_tapcommon_proto_goTypes = []any{ - (*OutPoint)(nil), // 0: taprpc.OutPoint - (*AssetOutPoint)(nil), // 1: taprpc.AssetOutPoint + (SortDirection)(0), // 0: taprpc.SortDirection + (*OutPoint)(nil), // 1: taprpc.OutPoint + (*AssetOutPoint)(nil), // 2: taprpc.AssetOutPoint + (*AssetSpecifier)(nil), // 3: taprpc.AssetSpecifier } var file_tapcommon_proto_depIdxs = []int32{ 0, // [0:0] is the sub-list for method output_type @@ -228,19 +344,32 @@ func file_tapcommon_proto_init() { return nil } } + file_tapcommon_proto_msgTypes[2].Exporter = func(v any, i int) any { + switch v := v.(*AssetSpecifier); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_tapcommon_proto_rawDesc, - NumEnums: 0, - NumMessages: 2, + NumEnums: 1, + NumMessages: 3, NumExtensions: 0, NumServices: 0, }, GoTypes: file_tapcommon_proto_goTypes, DependencyIndexes: file_tapcommon_proto_depIdxs, + EnumInfos: file_tapcommon_proto_enumTypes, MessageInfos: file_tapcommon_proto_msgTypes, }.Build() File_tapcommon_proto = out.File diff --git a/taprpc/tapcommon.proto b/taprpc/tapcommon.proto index c7613711d..8880bca12 100644 --- a/taprpc/tapcommon.proto +++ b/taprpc/tapcommon.proto @@ -34,3 +34,19 @@ message AssetOutPoint { // asset is locked to. bytes script_key = 3; } + +enum SortDirection { + // Sort results in descending order. + SORT_DIRECTION_DESC = 0; + + // Sort results in ascending order. + SORT_DIRECTION_ASC = 1; +} + +message AssetSpecifier { + // The 32-byte asset ID specified. + bytes id = 1; + + // The 32-byte asset group key specified. + bytes group_key = 2; +} diff --git a/taprpc/taprootassets.pb.go b/taprpc/taprootassets.pb.go index db185d3c4..a3bbf4119 100644 --- a/taprpc/taprootassets.pb.go +++ b/taprpc/taprootassets.pb.go @@ -5394,6 +5394,12 @@ type AddrReceivesRequest struct { // Filter receives by creation time less than or equal to this timestamp. // If not set, no end time filtering is applied. EndTimestamp uint64 `protobuf:"varint,4,opt,name=end_timestamp,json=endTimestamp,proto3" json:"end_timestamp,omitempty"` + // The number of events to skip. + Offset int32 `protobuf:"varint,5,opt,name=offset,proto3" json:"offset,omitempty"` + // The max number of events returned. + Limit int32 `protobuf:"varint,6,opt,name=limit,proto3" json:"limit,omitempty"` + // The direction of the page. Sorted by creation time. + Direction SortDirection `protobuf:"varint,7,opt,name=direction,proto3,enum=taprpc.SortDirection" json:"direction,omitempty"` } func (x *AddrReceivesRequest) Reset() { @@ -5456,6 +5462,27 @@ func (x *AddrReceivesRequest) GetEndTimestamp() uint64 { return 0 } +func (x *AddrReceivesRequest) GetOffset() int32 { + if x != nil { + return x.Offset + } + return 0 +} + +func (x *AddrReceivesRequest) GetLimit() int32 { + if x != nil { + return x.Limit + } + return 0 +} + +func (x *AddrReceivesRequest) GetDirection() SortDirection { + if x != nil { + return x.Direction + } + return SortDirection_SORT_DIRECTION_DESC +} + type AddrReceivesResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -6191,6 +6218,8 @@ type BurnAssetRequest struct { ConfirmationText string `protobuf:"bytes,4,opt,name=confirmation_text,json=confirmationText,proto3" json:"confirmation_text,omitempty"` // A note that may contain user defined metadata related to this burn. Note string `protobuf:"bytes,5,opt,name=note,proto3" json:"note,omitempty"` + // The asset to burn units of. + AssetSpecifier *AssetSpecifier `protobuf:"bytes,6,opt,name=asset_specifier,json=assetSpecifier,proto3" json:"asset_specifier,omitempty"` } func (x *BurnAssetRequest) Reset() { @@ -6232,6 +6261,7 @@ func (m *BurnAssetRequest) GetAsset() isBurnAssetRequest_Asset { return nil } +// Deprecated: Marked as deprecated in taprootassets.proto. func (x *BurnAssetRequest) GetAssetId() []byte { if x, ok := x.GetAsset().(*BurnAssetRequest_AssetId); ok { return x.AssetId @@ -6239,6 +6269,7 @@ func (x *BurnAssetRequest) GetAssetId() []byte { return nil } +// Deprecated: Marked as deprecated in taprootassets.proto. func (x *BurnAssetRequest) GetAssetIdStr() string { if x, ok := x.GetAsset().(*BurnAssetRequest_AssetIdStr); ok { return x.AssetIdStr @@ -6267,17 +6298,30 @@ func (x *BurnAssetRequest) GetNote() string { return "" } +func (x *BurnAssetRequest) GetAssetSpecifier() *AssetSpecifier { + if x != nil { + return x.AssetSpecifier + } + return nil +} + type isBurnAssetRequest_Asset interface { isBurnAssetRequest_Asset() } type BurnAssetRequest_AssetId struct { - // The asset ID of the asset to burn units of. + // Deprecated, the asset ID of the asset to burn units of. + // Use asset_specifier instead + // + // Deprecated: Marked as deprecated in taprootassets.proto. AssetId []byte `protobuf:"bytes,1,opt,name=asset_id,json=assetId,proto3,oneof"` } type BurnAssetRequest_AssetIdStr struct { - // The hex encoded asset ID of the asset to burn units of. + // Deprecated, the hex encoded asset ID of the asset to burn units of. + // Use asset_specifier instead + // + // Deprecated: Marked as deprecated in taprootassets.proto. AssetIdStr string `protobuf:"bytes,2,opt,name=asset_id_str,json=assetIdStr,proto3,oneof"` } @@ -6292,8 +6336,8 @@ type BurnAssetResponse struct { // The asset transfer that contains the asset burn as an output. BurnTransfer *AssetTransfer `protobuf:"bytes,1,opt,name=burn_transfer,json=burnTransfer,proto3" json:"burn_transfer,omitempty"` - // The burn transition proof for the asset burn output. - BurnProof *DecodedProof `protobuf:"bytes,2,opt,name=burn_proof,json=burnProof,proto3" json:"burn_proof,omitempty"` + // The burn transition proofs for the asset burn output. + BurnProofs []*DecodedProof `protobuf:"bytes,3,rep,name=burn_proofs,json=burnProofs,proto3" json:"burn_proofs,omitempty"` } func (x *BurnAssetResponse) Reset() { @@ -6335,9 +6379,9 @@ func (x *BurnAssetResponse) GetBurnTransfer() *AssetTransfer { return nil } -func (x *BurnAssetResponse) GetBurnProof() *DecodedProof { +func (x *BurnAssetResponse) GetBurnProofs() []*DecodedProof { if x != nil { - return x.BurnProof + return x.BurnProofs } return nil } @@ -7820,7 +7864,7 @@ var file_taprootassets_proto_rawDesc = []byte{ 0x0d, 0x52, 0x12, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x68, 0x61, 0x73, 0x5f, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x68, 0x61, 0x73, 0x50, 0x72, 0x6f, - 0x6f, 0x66, 0x22, 0xc2, 0x01, 0x0a, 0x13, 0x41, 0x64, 0x64, 0x72, 0x52, 0x65, 0x63, 0x65, 0x69, + 0x6f, 0x66, 0x22, 0xa5, 0x02, 0x0a, 0x13, 0x41, 0x64, 0x64, 0x72, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x41, 0x64, 0x64, 0x72, 0x12, 0x3c, 0x0a, 0x0d, 0x66, @@ -7832,427 +7876,439 @@ var file_taprootassets_proto_rawDesc = []byte{ 0x28, 0x04, 0x52, 0x0e, 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x6e, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x65, 0x6e, 0x64, 0x54, 0x69, - 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0x41, 0x0a, 0x14, 0x41, 0x64, 0x64, 0x72, 0x52, - 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x29, 0x0a, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x11, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x45, 0x76, 0x65, - 0x6e, 0x74, 0x52, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x22, 0xf3, 0x01, 0x0a, 0x10, 0x53, - 0x65, 0x6e, 0x64, 0x41, 0x73, 0x73, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x1b, 0x0a, 0x09, 0x74, 0x61, 0x70, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, - 0x28, 0x09, 0x52, 0x08, 0x74, 0x61, 0x70, 0x41, 0x64, 0x64, 0x72, 0x73, 0x12, 0x19, 0x0a, 0x08, - 0x66, 0x65, 0x65, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, - 0x66, 0x65, 0x65, 0x52, 0x61, 0x74, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x40, 0x0a, - 0x1d, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x5f, 0x63, 0x6f, 0x75, 0x72, - 0x69, 0x65, 0x72, 0x5f, 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x19, 0x73, 0x6b, 0x69, 0x70, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x43, - 0x6f, 0x75, 0x72, 0x69, 0x65, 0x72, 0x50, 0x69, 0x6e, 0x67, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x12, - 0x4f, 0x0a, 0x16, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x5f, 0x77, 0x69, 0x74, - 0x68, 0x5f, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x19, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, - 0x57, 0x69, 0x74, 0x68, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x14, 0x61, 0x64, 0x64, 0x72, - 0x65, 0x73, 0x73, 0x65, 0x73, 0x57, 0x69, 0x74, 0x68, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x73, - 0x22, 0x46, 0x0a, 0x11, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x57, 0x69, 0x74, 0x68, 0x41, - 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x74, 0x61, 0x70, 0x5f, 0x61, 0x64, 0x64, - 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x74, 0x61, 0x70, 0x41, 0x64, 0x64, 0x72, - 0x12, 0x16, 0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, - 0x52, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x85, 0x01, 0x0a, 0x0e, 0x50, 0x72, 0x65, - 0x76, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x41, 0x73, 0x73, 0x65, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x61, - 0x6e, 0x63, 0x68, 0x6f, 0x72, 0x5f, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0b, 0x61, 0x6e, 0x63, 0x68, 0x6f, 0x72, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x19, - 0x0a, 0x08, 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x07, 0x61, 0x73, 0x73, 0x65, 0x74, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x63, 0x72, - 0x69, 0x70, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, - 0x63, 0x72, 0x69, 0x70, 0x74, 0x4b, 0x65, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75, - 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, - 0x22, 0x46, 0x0a, 0x11, 0x53, 0x65, 0x6e, 0x64, 0x41, 0x73, 0x73, 0x65, 0x74, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x31, 0x0a, 0x08, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, + 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, + 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, + 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, + 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x33, 0x0a, 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, + 0x63, 0x2e, 0x53, 0x6f, 0x72, 0x74, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, + 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x41, 0x0a, 0x14, 0x41, 0x64, + 0x64, 0x72, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x29, 0x0a, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x64, 0x64, 0x72, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x22, 0xf3, 0x01, + 0x0a, 0x10, 0x53, 0x65, 0x6e, 0x64, 0x41, 0x73, 0x73, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x61, 0x70, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x73, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x74, 0x61, 0x70, 0x41, 0x64, 0x64, 0x72, 0x73, 0x12, + 0x19, 0x0a, 0x08, 0x66, 0x65, 0x65, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0d, 0x52, 0x07, 0x66, 0x65, 0x65, 0x52, 0x61, 0x74, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x61, + 0x62, 0x65, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, + 0x12, 0x40, 0x0a, 0x1d, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x5f, 0x63, + 0x6f, 0x75, 0x72, 0x69, 0x65, 0x72, 0x5f, 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x63, 0x68, 0x65, 0x63, + 0x6b, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x19, 0x73, 0x6b, 0x69, 0x70, 0x50, 0x72, 0x6f, + 0x6f, 0x66, 0x43, 0x6f, 0x75, 0x72, 0x69, 0x65, 0x72, 0x50, 0x69, 0x6e, 0x67, 0x43, 0x68, 0x65, + 0x63, 0x6b, 0x12, 0x4f, 0x0a, 0x16, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x5f, + 0x77, 0x69, 0x74, 0x68, 0x5f, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x18, 0x05, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x64, 0x64, 0x72, + 0x65, 0x73, 0x73, 0x57, 0x69, 0x74, 0x68, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x14, 0x61, + 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x57, 0x69, 0x74, 0x68, 0x41, 0x6d, 0x6f, 0x75, + 0x6e, 0x74, 0x73, 0x22, 0x46, 0x0a, 0x11, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x57, 0x69, + 0x74, 0x68, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x74, 0x61, 0x70, 0x5f, + 0x61, 0x64, 0x64, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x74, 0x61, 0x70, 0x41, + 0x64, 0x64, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x04, 0x52, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x85, 0x01, 0x0a, 0x0e, + 0x50, 0x72, 0x65, 0x76, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x41, 0x73, 0x73, 0x65, 0x74, 0x12, 0x21, + 0x0a, 0x0c, 0x61, 0x6e, 0x63, 0x68, 0x6f, 0x72, 0x5f, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x61, 0x6e, 0x63, 0x68, 0x6f, 0x72, 0x50, 0x6f, 0x69, 0x6e, + 0x74, 0x12, 0x19, 0x0a, 0x08, 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x07, 0x61, 0x73, 0x73, 0x65, 0x74, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, + 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x09, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x4b, 0x65, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x61, + 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x61, 0x6d, 0x6f, + 0x75, 0x6e, 0x74, 0x22, 0x46, 0x0a, 0x11, 0x53, 0x65, 0x6e, 0x64, 0x41, 0x73, 0x73, 0x65, 0x74, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x31, 0x0a, 0x08, 0x74, 0x72, 0x61, 0x6e, + 0x73, 0x66, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x61, 0x70, + 0x72, 0x70, 0x63, 0x2e, 0x41, 0x73, 0x73, 0x65, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, + 0x72, 0x52, 0x08, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x22, 0x10, 0x0a, 0x0e, 0x47, + 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x9b, 0x02, + 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1f, 0x0a, 0x0b, 0x6c, + 0x6e, 0x64, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0a, 0x6c, 0x6e, 0x64, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, + 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6e, + 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x12, 0x2e, 0x0a, 0x13, 0x6c, 0x6e, 0x64, 0x5f, 0x69, 0x64, + 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x11, 0x6c, 0x6e, 0x64, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, + 0x50, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x12, 0x1d, 0x0a, 0x0a, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x61, + 0x6c, 0x69, 0x61, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x6f, 0x64, 0x65, + 0x41, 0x6c, 0x69, 0x61, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, + 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x62, 0x6c, 0x6f, + 0x63, 0x6b, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x6c, 0x6f, 0x63, + 0x6b, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x62, 0x6c, + 0x6f, 0x63, 0x6b, 0x48, 0x61, 0x73, 0x68, 0x12, 0x22, 0x0a, 0x0d, 0x73, 0x79, 0x6e, 0x63, 0x5f, + 0x74, 0x6f, 0x5f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, + 0x73, 0x79, 0x6e, 0x63, 0x54, 0x6f, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x22, 0xa6, 0x01, 0x0a, 0x15, + 0x46, 0x65, 0x74, 0x63, 0x68, 0x41, 0x73, 0x73, 0x65, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x08, 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x69, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x07, 0x61, 0x73, 0x73, 0x65, 0x74, + 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x09, 0x6d, 0x65, 0x74, 0x61, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x48, 0x61, 0x73, + 0x68, 0x12, 0x22, 0x0a, 0x0c, 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x69, 0x64, 0x5f, 0x73, 0x74, + 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0a, 0x61, 0x73, 0x73, 0x65, 0x74, + 0x49, 0x64, 0x53, 0x74, 0x72, 0x12, 0x24, 0x0a, 0x0d, 0x6d, 0x65, 0x74, 0x61, 0x5f, 0x68, 0x61, + 0x73, 0x68, 0x5f, 0x73, 0x74, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0b, + 0x6d, 0x65, 0x74, 0x61, 0x48, 0x61, 0x73, 0x68, 0x53, 0x74, 0x72, 0x42, 0x07, 0x0a, 0x05, 0x61, + 0x73, 0x73, 0x65, 0x74, 0x22, 0xd4, 0x03, 0x0a, 0x16, 0x46, 0x65, 0x74, 0x63, 0x68, 0x41, 0x73, + 0x73, 0x65, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, + 0x61, 0x74, 0x61, 0x12, 0x29, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0e, 0x32, 0x15, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x73, 0x73, 0x65, 0x74, + 0x4d, 0x65, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x1b, + 0x0a, 0x09, 0x6d, 0x65, 0x74, 0x61, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x48, 0x61, 0x73, 0x68, 0x12, 0x5f, 0x0a, 0x11, 0x75, + 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x5f, 0x6f, 0x64, 0x64, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, + 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, + 0x46, 0x65, 0x74, 0x63, 0x68, 0x41, 0x73, 0x73, 0x65, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x4f, 0x64, + 0x64, 0x54, 0x79, 0x70, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0f, 0x75, 0x6e, 0x6b, + 0x6e, 0x6f, 0x77, 0x6e, 0x4f, 0x64, 0x64, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x27, 0x0a, 0x0f, + 0x64, 0x65, 0x63, 0x69, 0x6d, 0x61, 0x6c, 0x5f, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0e, 0x64, 0x65, 0x63, 0x69, 0x6d, 0x61, 0x6c, 0x44, 0x69, + 0x73, 0x70, 0x6c, 0x61, 0x79, 0x12, 0x31, 0x0a, 0x14, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, + 0x65, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x13, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x43, 0x6f, 0x6d, + 0x6d, 0x69, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x36, 0x0a, 0x17, 0x63, 0x61, 0x6e, 0x6f, + 0x6e, 0x69, 0x63, 0x61, 0x6c, 0x5f, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x5f, 0x75, + 0x72, 0x6c, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x15, 0x63, 0x61, 0x6e, 0x6f, 0x6e, + 0x69, 0x63, 0x61, 0x6c, 0x55, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x55, 0x72, 0x6c, 0x73, + 0x12, 0x25, 0x0a, 0x0e, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6b, + 0x65, 0x79, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x1a, 0x42, 0x0a, 0x14, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, + 0x77, 0x6e, 0x4f, 0x64, 0x64, 0x54, 0x79, 0x70, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, + 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x03, 0x6b, 0x65, + 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x8c, 0x02, 0x0a, 0x10, + 0x42, 0x75, 0x72, 0x6e, 0x41, 0x73, 0x73, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x1f, 0x0a, 0x08, 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0c, 0x42, 0x02, 0x18, 0x01, 0x48, 0x00, 0x52, 0x07, 0x61, 0x73, 0x73, 0x65, 0x74, 0x49, + 0x64, 0x12, 0x26, 0x0a, 0x0c, 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x69, 0x64, 0x5f, 0x73, 0x74, + 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x02, 0x18, 0x01, 0x48, 0x00, 0x52, 0x0a, 0x61, + 0x73, 0x73, 0x65, 0x74, 0x49, 0x64, 0x53, 0x74, 0x72, 0x12, 0x24, 0x0a, 0x0e, 0x61, 0x6d, 0x6f, + 0x75, 0x6e, 0x74, 0x5f, 0x74, 0x6f, 0x5f, 0x62, 0x75, 0x72, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x04, 0x52, 0x0c, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x54, 0x6f, 0x42, 0x75, 0x72, 0x6e, 0x12, + 0x2b, 0x0a, 0x11, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, + 0x74, 0x65, 0x78, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x63, 0x6f, 0x6e, 0x66, + 0x69, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x65, 0x78, 0x74, 0x12, 0x12, 0x0a, 0x04, + 0x6e, 0x6f, 0x74, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x6f, 0x74, 0x65, + 0x12, 0x3f, 0x0a, 0x0f, 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, + 0x69, 0x65, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x74, 0x61, 0x70, 0x72, + 0x70, 0x63, 0x2e, 0x41, 0x73, 0x73, 0x65, 0x74, 0x53, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, + 0x72, 0x52, 0x0e, 0x61, 0x73, 0x73, 0x65, 0x74, 0x53, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, + 0x72, 0x42, 0x07, 0x0a, 0x05, 0x61, 0x73, 0x73, 0x65, 0x74, 0x22, 0x8c, 0x01, 0x0a, 0x11, 0x42, + 0x75, 0x72, 0x6e, 0x41, 0x73, 0x73, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x3a, 0x0a, 0x0d, 0x62, 0x75, 0x72, 0x6e, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, - 0x2e, 0x41, 0x73, 0x73, 0x65, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x52, 0x08, - 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x22, 0x10, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x49, - 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x9b, 0x02, 0x0a, 0x0f, 0x47, - 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, - 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1f, 0x0a, 0x0b, 0x6c, 0x6e, 0x64, 0x5f, - 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6c, - 0x6e, 0x64, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x6e, 0x65, 0x74, - 0x77, 0x6f, 0x72, 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6e, 0x65, 0x74, 0x77, - 0x6f, 0x72, 0x6b, 0x12, 0x2e, 0x0a, 0x13, 0x6c, 0x6e, 0x64, 0x5f, 0x69, 0x64, 0x65, 0x6e, 0x74, - 0x69, 0x74, 0x79, 0x5f, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x11, 0x6c, 0x6e, 0x64, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x50, 0x75, 0x62, - 0x6b, 0x65, 0x79, 0x12, 0x1d, 0x0a, 0x0a, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x61, 0x6c, 0x69, 0x61, - 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x6f, 0x64, 0x65, 0x41, 0x6c, 0x69, - 0x61, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x65, 0x69, 0x67, - 0x68, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, - 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, - 0x61, 0x73, 0x68, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x62, 0x6c, 0x6f, 0x63, 0x6b, - 0x48, 0x61, 0x73, 0x68, 0x12, 0x22, 0x0a, 0x0d, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x74, 0x6f, 0x5f, - 0x63, 0x68, 0x61, 0x69, 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x73, 0x79, 0x6e, - 0x63, 0x54, 0x6f, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x22, 0xa6, 0x01, 0x0a, 0x15, 0x46, 0x65, 0x74, - 0x63, 0x68, 0x41, 0x73, 0x73, 0x65, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x08, 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x07, 0x61, 0x73, 0x73, 0x65, 0x74, 0x49, 0x64, 0x12, - 0x1d, 0x0a, 0x09, 0x6d, 0x65, 0x74, 0x61, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0c, 0x48, 0x00, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x48, 0x61, 0x73, 0x68, 0x12, 0x22, - 0x0a, 0x0c, 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x69, 0x64, 0x5f, 0x73, 0x74, 0x72, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0a, 0x61, 0x73, 0x73, 0x65, 0x74, 0x49, 0x64, 0x53, - 0x74, 0x72, 0x12, 0x24, 0x0a, 0x0d, 0x6d, 0x65, 0x74, 0x61, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x5f, - 0x73, 0x74, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0b, 0x6d, 0x65, 0x74, - 0x61, 0x48, 0x61, 0x73, 0x68, 0x53, 0x74, 0x72, 0x42, 0x07, 0x0a, 0x05, 0x61, 0x73, 0x73, 0x65, - 0x74, 0x22, 0xd4, 0x03, 0x0a, 0x16, 0x46, 0x65, 0x74, 0x63, 0x68, 0x41, 0x73, 0x73, 0x65, 0x74, - 0x4d, 0x65, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, - 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, - 0x12, 0x29, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, - 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x73, 0x73, 0x65, 0x74, 0x4d, 0x65, 0x74, - 0x61, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x6d, - 0x65, 0x74, 0x61, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, - 0x6d, 0x65, 0x74, 0x61, 0x48, 0x61, 0x73, 0x68, 0x12, 0x5f, 0x0a, 0x11, 0x75, 0x6e, 0x6b, 0x6e, - 0x6f, 0x77, 0x6e, 0x5f, 0x6f, 0x64, 0x64, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x04, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x46, 0x65, 0x74, - 0x63, 0x68, 0x41, 0x73, 0x73, 0x65, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x2e, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x4f, 0x64, 0x64, 0x54, 0x79, - 0x70, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0f, 0x75, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, - 0x6e, 0x4f, 0x64, 0x64, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x27, 0x0a, 0x0f, 0x64, 0x65, 0x63, - 0x69, 0x6d, 0x61, 0x6c, 0x5f, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x18, 0x05, 0x20, 0x01, - 0x28, 0x0d, 0x52, 0x0e, 0x64, 0x65, 0x63, 0x69, 0x6d, 0x61, 0x6c, 0x44, 0x69, 0x73, 0x70, 0x6c, - 0x61, 0x79, 0x12, 0x31, 0x0a, 0x14, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x5f, 0x63, - 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x13, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, - 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x36, 0x0a, 0x17, 0x63, 0x61, 0x6e, 0x6f, 0x6e, 0x69, 0x63, - 0x61, 0x6c, 0x5f, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x5f, 0x75, 0x72, 0x6c, 0x73, - 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x15, 0x63, 0x61, 0x6e, 0x6f, 0x6e, 0x69, 0x63, 0x61, - 0x6c, 0x55, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x55, 0x72, 0x6c, 0x73, 0x12, 0x25, 0x0a, - 0x0e, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6b, 0x65, 0x79, 0x18, - 0x08, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x4b, 0x65, 0x79, 0x1a, 0x42, 0x0a, 0x14, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x4f, - 0x64, 0x64, 0x54, 0x79, 0x70, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, - 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, - 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xc3, 0x01, 0x0a, 0x10, 0x42, 0x75, 0x72, - 0x6e, 0x41, 0x73, 0x73, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, - 0x08, 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x48, - 0x00, 0x52, 0x07, 0x61, 0x73, 0x73, 0x65, 0x74, 0x49, 0x64, 0x12, 0x22, 0x0a, 0x0c, 0x61, 0x73, - 0x73, 0x65, 0x74, 0x5f, 0x69, 0x64, 0x5f, 0x73, 0x74, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x48, 0x00, 0x52, 0x0a, 0x61, 0x73, 0x73, 0x65, 0x74, 0x49, 0x64, 0x53, 0x74, 0x72, 0x12, 0x24, - 0x0a, 0x0e, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x74, 0x6f, 0x5f, 0x62, 0x75, 0x72, 0x6e, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x54, 0x6f, - 0x42, 0x75, 0x72, 0x6e, 0x12, 0x2b, 0x0a, 0x11, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x65, 0x78, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x10, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x65, 0x78, - 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x6f, 0x74, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x04, 0x6e, 0x6f, 0x74, 0x65, 0x42, 0x07, 0x0a, 0x05, 0x61, 0x73, 0x73, 0x65, 0x74, 0x22, 0x84, - 0x01, 0x0a, 0x11, 0x42, 0x75, 0x72, 0x6e, 0x41, 0x73, 0x73, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3a, 0x0a, 0x0d, 0x62, 0x75, 0x72, 0x6e, 0x5f, 0x74, 0x72, 0x61, - 0x6e, 0x73, 0x66, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x61, + 0x2e, 0x41, 0x73, 0x73, 0x65, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x52, 0x0c, + 0x62, 0x75, 0x72, 0x6e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x12, 0x35, 0x0a, 0x0b, + 0x62, 0x75, 0x72, 0x6e, 0x5f, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x14, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x44, 0x65, 0x63, 0x6f, 0x64, + 0x65, 0x64, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x52, 0x0a, 0x62, 0x75, 0x72, 0x6e, 0x50, 0x72, 0x6f, + 0x6f, 0x66, 0x73, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x22, 0x7a, 0x0a, 0x10, 0x4c, 0x69, 0x73, + 0x74, 0x42, 0x75, 0x72, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x19, 0x0a, + 0x08, 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x07, 0x61, 0x73, 0x73, 0x65, 0x74, 0x49, 0x64, 0x12, 0x2a, 0x0a, 0x11, 0x74, 0x77, 0x65, 0x61, + 0x6b, 0x65, 0x64, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x0f, 0x74, 0x77, 0x65, 0x61, 0x6b, 0x65, 0x64, 0x47, 0x72, 0x6f, 0x75, + 0x70, 0x4b, 0x65, 0x79, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x6e, 0x63, 0x68, 0x6f, 0x72, 0x5f, 0x74, + 0x78, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x61, 0x6e, 0x63, 0x68, 0x6f, + 0x72, 0x54, 0x78, 0x69, 0x64, 0x22, 0x9f, 0x01, 0x0a, 0x09, 0x41, 0x73, 0x73, 0x65, 0x74, 0x42, + 0x75, 0x72, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x6f, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x6e, 0x6f, 0x74, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x61, 0x73, 0x73, 0x65, 0x74, + 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x61, 0x73, 0x73, 0x65, 0x74, + 0x49, 0x64, 0x12, 0x2a, 0x0a, 0x11, 0x74, 0x77, 0x65, 0x61, 0x6b, 0x65, 0x64, 0x5f, 0x67, 0x72, + 0x6f, 0x75, 0x70, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, 0x74, + 0x77, 0x65, 0x61, 0x6b, 0x65, 0x64, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x4b, 0x65, 0x79, 0x12, 0x16, + 0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, + 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x6e, 0x63, 0x68, 0x6f, 0x72, + 0x5f, 0x74, 0x78, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x61, 0x6e, 0x63, + 0x68, 0x6f, 0x72, 0x54, 0x78, 0x69, 0x64, 0x22, 0x3c, 0x0a, 0x11, 0x4c, 0x69, 0x73, 0x74, 0x42, + 0x75, 0x72, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x27, 0x0a, 0x05, + 0x62, 0x75, 0x72, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x61, + 0x70, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x73, 0x73, 0x65, 0x74, 0x42, 0x75, 0x72, 0x6e, 0x52, 0x05, + 0x62, 0x75, 0x72, 0x6e, 0x73, 0x22, 0x69, 0x0a, 0x1d, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, + 0x62, 0x65, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, + 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x66, 0x69, 0x6c, + 0x74, 0x65, 0x72, 0x41, 0x64, 0x64, 0x72, 0x12, 0x27, 0x0a, 0x0f, 0x73, 0x74, 0x61, 0x72, 0x74, + 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, + 0x52, 0x0e, 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, + 0x22, 0xe8, 0x01, 0x0a, 0x0c, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x45, 0x76, 0x65, 0x6e, + 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, + 0x26, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x0c, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x52, 0x07, + 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x6f, 0x75, 0x74, 0x70, 0x6f, + 0x69, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6f, 0x75, 0x74, 0x70, 0x6f, + 0x69, 0x6e, 0x74, 0x12, 0x2f, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x0e, 0x32, 0x17, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x64, 0x64, + 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x12, 0x2f, 0x0a, 0x13, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x0d, 0x52, 0x12, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, + 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x06, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x22, 0x94, 0x01, 0x0a, 0x1a, + 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x53, 0x65, 0x6e, 0x64, 0x45, 0x76, 0x65, + 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2a, 0x0a, 0x11, 0x66, 0x69, + 0x6c, 0x74, 0x65, 0x72, 0x5f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x53, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x4b, 0x65, 0x79, 0x12, 0x21, 0x0a, 0x0c, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, + 0x5f, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x66, 0x69, + 0x6c, 0x74, 0x65, 0x72, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x27, 0x0a, 0x0f, 0x73, 0x74, 0x61, + 0x72, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x03, 0x52, 0x0e, 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, + 0x6d, 0x70, 0x22, 0xec, 0x03, 0x0a, 0x09, 0x53, 0x65, 0x6e, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, + 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x1d, + 0x0a, 0x0a, 0x73, 0x65, 0x6e, 0x64, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x09, 0x73, 0x65, 0x6e, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x33, 0x0a, + 0x0b, 0x70, 0x61, 0x72, 0x63, 0x65, 0x6c, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0e, 0x32, 0x12, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x50, 0x61, 0x72, 0x63, + 0x65, 0x6c, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, 0x70, 0x61, 0x72, 0x63, 0x65, 0x6c, 0x54, 0x79, + 0x70, 0x65, 0x12, 0x2a, 0x0a, 0x09, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x18, + 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x41, + 0x64, 0x64, 0x72, 0x52, 0x09, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x12, 0x27, + 0x0a, 0x0f, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x5f, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74, + 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0e, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, + 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x12, 0x36, 0x0a, 0x17, 0x70, 0x61, 0x73, 0x73, 0x69, + 0x76, 0x65, 0x5f, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x5f, 0x70, 0x61, 0x63, 0x6b, 0x65, + 0x74, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x15, 0x70, 0x61, 0x73, 0x73, 0x69, 0x76, + 0x65, 0x56, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x12, + 0x48, 0x0a, 0x12, 0x61, 0x6e, 0x63, 0x68, 0x6f, 0x72, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x74, 0x61, + 0x70, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x6e, 0x63, 0x68, 0x6f, 0x72, 0x54, 0x72, 0x61, 0x6e, 0x73, + 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x11, 0x61, 0x6e, 0x63, 0x68, 0x6f, 0x72, 0x54, 0x72, + 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x31, 0x0a, 0x08, 0x74, 0x72, 0x61, + 0x6e, 0x73, 0x66, 0x65, 0x72, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x73, 0x73, 0x65, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, - 0x65, 0x72, 0x52, 0x0c, 0x62, 0x75, 0x72, 0x6e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, - 0x12, 0x33, 0x0a, 0x0a, 0x62, 0x75, 0x72, 0x6e, 0x5f, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x44, 0x65, - 0x63, 0x6f, 0x64, 0x65, 0x64, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x52, 0x09, 0x62, 0x75, 0x72, 0x6e, - 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x22, 0x7a, 0x0a, 0x10, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x75, 0x72, - 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x61, 0x73, 0x73, - 0x65, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x61, 0x73, 0x73, - 0x65, 0x74, 0x49, 0x64, 0x12, 0x2a, 0x0a, 0x11, 0x74, 0x77, 0x65, 0x61, 0x6b, 0x65, 0x64, 0x5f, - 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x0f, 0x74, 0x77, 0x65, 0x61, 0x6b, 0x65, 0x64, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x4b, 0x65, 0x79, - 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x6e, 0x63, 0x68, 0x6f, 0x72, 0x5f, 0x74, 0x78, 0x69, 0x64, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x61, 0x6e, 0x63, 0x68, 0x6f, 0x72, 0x54, 0x78, 0x69, - 0x64, 0x22, 0x9f, 0x01, 0x0a, 0x09, 0x41, 0x73, 0x73, 0x65, 0x74, 0x42, 0x75, 0x72, 0x6e, 0x12, - 0x12, 0x0a, 0x04, 0x6e, 0x6f, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, - 0x6f, 0x74, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x69, 0x64, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x61, 0x73, 0x73, 0x65, 0x74, 0x49, 0x64, 0x12, 0x2a, - 0x0a, 0x11, 0x74, 0x77, 0x65, 0x61, 0x6b, 0x65, 0x64, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, - 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, 0x74, 0x77, 0x65, 0x61, 0x6b, - 0x65, 0x64, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x4b, 0x65, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x6d, - 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x61, 0x6d, 0x6f, 0x75, - 0x6e, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x6e, 0x63, 0x68, 0x6f, 0x72, 0x5f, 0x74, 0x78, 0x69, - 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x61, 0x6e, 0x63, 0x68, 0x6f, 0x72, 0x54, - 0x78, 0x69, 0x64, 0x22, 0x3c, 0x0a, 0x11, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x75, 0x72, 0x6e, 0x73, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x27, 0x0a, 0x05, 0x62, 0x75, 0x72, 0x6e, - 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, - 0x2e, 0x41, 0x73, 0x73, 0x65, 0x74, 0x42, 0x75, 0x72, 0x6e, 0x52, 0x05, 0x62, 0x75, 0x72, 0x6e, - 0x73, 0x22, 0x69, 0x0a, 0x1d, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x52, 0x65, - 0x63, 0x65, 0x69, 0x76, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x5f, 0x61, 0x64, 0x64, - 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x41, - 0x64, 0x64, 0x72, 0x12, 0x27, 0x0a, 0x0f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x74, 0x69, 0x6d, - 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0e, 0x73, 0x74, - 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0xe8, 0x01, 0x0a, - 0x0c, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1c, 0x0a, - 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, - 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x26, 0x0a, 0x07, 0x61, - 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x74, - 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, - 0x65, 0x73, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x6f, 0x75, 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6f, 0x75, 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, - 0x2f, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, - 0x17, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x45, 0x76, 0x65, - 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x12, 0x2f, 0x0a, 0x13, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x12, 0x63, - 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x65, 0x69, 0x67, 0x68, - 0x74, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x22, 0x94, 0x01, 0x0a, 0x1a, 0x53, 0x75, 0x62, 0x73, - 0x63, 0x72, 0x69, 0x62, 0x65, 0x53, 0x65, 0x6e, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2a, 0x0a, 0x11, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, - 0x5f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x0f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x4b, - 0x65, 0x79, 0x12, 0x21, 0x0a, 0x0c, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x5f, 0x6c, 0x61, 0x62, - 0x65, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, - 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x27, 0x0a, 0x0f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x74, - 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0e, - 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0xec, - 0x03, 0x0a, 0x09, 0x53, 0x65, 0x6e, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1c, 0x0a, 0x09, - 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, - 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x65, - 0x6e, 0x64, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, - 0x73, 0x65, 0x6e, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x33, 0x0a, 0x0b, 0x70, 0x61, 0x72, - 0x63, 0x65, 0x6c, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x12, - 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x50, 0x61, 0x72, 0x63, 0x65, 0x6c, 0x54, 0x79, - 0x70, 0x65, 0x52, 0x0a, 0x70, 0x61, 0x72, 0x63, 0x65, 0x6c, 0x54, 0x79, 0x70, 0x65, 0x12, 0x2a, - 0x0a, 0x09, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x0c, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x52, - 0x09, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x12, 0x27, 0x0a, 0x0f, 0x76, 0x69, - 0x72, 0x74, 0x75, 0x61, 0x6c, 0x5f, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x18, 0x05, 0x20, - 0x03, 0x28, 0x0c, 0x52, 0x0e, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x50, 0x61, 0x63, 0x6b, - 0x65, 0x74, 0x73, 0x12, 0x36, 0x0a, 0x17, 0x70, 0x61, 0x73, 0x73, 0x69, 0x76, 0x65, 0x5f, 0x76, - 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x5f, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x18, 0x06, - 0x20, 0x03, 0x28, 0x0c, 0x52, 0x15, 0x70, 0x61, 0x73, 0x73, 0x69, 0x76, 0x65, 0x56, 0x69, 0x72, - 0x74, 0x75, 0x61, 0x6c, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x12, 0x48, 0x0a, 0x12, 0x61, - 0x6e, 0x63, 0x68, 0x6f, 0x72, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, - 0x2e, 0x41, 0x6e, 0x63, 0x68, 0x6f, 0x72, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x52, 0x11, 0x61, 0x6e, 0x63, 0x68, 0x6f, 0x72, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x31, 0x0a, 0x08, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, - 0x72, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, - 0x2e, 0x41, 0x73, 0x73, 0x65, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x52, 0x08, - 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, - 0x72, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x25, - 0x0a, 0x0e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x5f, 0x6c, 0x61, 0x62, 0x65, 0x6c, - 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, - 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x26, 0x0a, 0x0f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x73, 0x65, - 0x6e, 0x64, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, - 0x6e, 0x65, 0x78, 0x74, 0x53, 0x65, 0x6e, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x22, 0x97, 0x02, - 0x0a, 0x11, 0x41, 0x6e, 0x63, 0x68, 0x6f, 0x72, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x6e, 0x63, 0x68, 0x6f, 0x72, 0x5f, 0x70, 0x73, - 0x62, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x61, 0x6e, 0x63, 0x68, 0x6f, 0x72, - 0x50, 0x73, 0x62, 0x74, 0x12, 0x2e, 0x0a, 0x13, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x5f, 0x6f, - 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x05, 0x52, 0x11, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x49, - 0x6e, 0x64, 0x65, 0x78, 0x12, 0x26, 0x0a, 0x0f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x66, 0x65, - 0x65, 0x73, 0x5f, 0x73, 0x61, 0x74, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x63, - 0x68, 0x61, 0x69, 0x6e, 0x46, 0x65, 0x65, 0x73, 0x53, 0x61, 0x74, 0x73, 0x12, 0x32, 0x0a, 0x16, - 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x66, 0x65, 0x65, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x5f, - 0x73, 0x61, 0x74, 0x5f, 0x6b, 0x77, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x12, 0x74, 0x61, - 0x72, 0x67, 0x65, 0x74, 0x46, 0x65, 0x65, 0x52, 0x61, 0x74, 0x65, 0x53, 0x61, 0x74, 0x4b, 0x77, - 0x12, 0x3a, 0x0a, 0x10, 0x6c, 0x6e, 0x64, 0x5f, 0x6c, 0x6f, 0x63, 0x6b, 0x65, 0x64, 0x5f, 0x75, - 0x74, 0x78, 0x6f, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x74, 0x61, 0x70, - 0x72, 0x70, 0x63, 0x2e, 0x4f, 0x75, 0x74, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x0e, 0x6c, 0x6e, - 0x64, 0x4c, 0x6f, 0x63, 0x6b, 0x65, 0x64, 0x55, 0x74, 0x78, 0x6f, 0x73, 0x12, 0x19, 0x0a, 0x08, - 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x5f, 0x74, 0x78, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, - 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x54, 0x78, 0x22, 0x9e, 0x01, 0x0a, 0x17, 0x52, 0x65, 0x67, 0x69, - 0x73, 0x74, 0x65, 0x72, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x61, 0x73, 0x73, 0x65, 0x74, 0x49, 0x64, 0x12, 0x1b, - 0x0a, 0x09, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x08, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x4b, 0x65, 0x79, 0x12, 0x1d, 0x0a, 0x0a, 0x73, - 0x63, 0x72, 0x69, 0x70, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x09, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x4b, 0x65, 0x79, 0x12, 0x2c, 0x0a, 0x08, 0x6f, 0x75, - 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x74, - 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4f, 0x75, 0x74, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x08, - 0x6f, 0x75, 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x22, 0x54, 0x0a, 0x18, 0x52, 0x65, 0x67, 0x69, - 0x73, 0x74, 0x65, 0x72, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x38, 0x0a, 0x10, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, - 0x65, 0x64, 0x5f, 0x61, 0x73, 0x73, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, - 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x73, 0x73, 0x65, 0x74, 0x52, 0x0f, 0x72, - 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x65, 0x64, 0x41, 0x73, 0x73, 0x65, 0x74, 0x2a, 0x28, - 0x0a, 0x09, 0x41, 0x73, 0x73, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0a, 0x0a, 0x06, 0x4e, - 0x4f, 0x52, 0x4d, 0x41, 0x4c, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x43, 0x4f, 0x4c, 0x4c, 0x45, - 0x43, 0x54, 0x49, 0x42, 0x4c, 0x45, 0x10, 0x01, 0x2a, 0x39, 0x0a, 0x0d, 0x41, 0x73, 0x73, 0x65, - 0x74, 0x4d, 0x65, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x10, 0x4d, 0x45, 0x54, - 0x41, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4f, 0x50, 0x41, 0x51, 0x55, 0x45, 0x10, 0x00, 0x12, - 0x12, 0x0a, 0x0e, 0x4d, 0x45, 0x54, 0x41, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4a, 0x53, 0x4f, - 0x4e, 0x10, 0x01, 0x2a, 0x3a, 0x0a, 0x0c, 0x41, 0x73, 0x73, 0x65, 0x74, 0x56, 0x65, 0x72, 0x73, - 0x69, 0x6f, 0x6e, 0x12, 0x14, 0x0a, 0x10, 0x41, 0x53, 0x53, 0x45, 0x54, 0x5f, 0x56, 0x45, 0x52, - 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x56, 0x30, 0x10, 0x00, 0x12, 0x14, 0x0a, 0x10, 0x41, 0x53, 0x53, - 0x45, 0x54, 0x5f, 0x56, 0x45, 0x52, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x56, 0x31, 0x10, 0x01, 0x2a, - 0x52, 0x0a, 0x0a, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, - 0x12, 0x4f, 0x55, 0x54, 0x50, 0x55, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x49, 0x4d, - 0x50, 0x4c, 0x45, 0x10, 0x00, 0x12, 0x1a, 0x0a, 0x16, 0x4f, 0x55, 0x54, 0x50, 0x55, 0x54, 0x5f, - 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x50, 0x4c, 0x49, 0x54, 0x5f, 0x52, 0x4f, 0x4f, 0x54, 0x10, - 0x01, 0x22, 0x04, 0x08, 0x02, 0x10, 0x02, 0x22, 0x04, 0x08, 0x03, 0x10, 0x03, 0x22, 0x04, 0x08, - 0x04, 0x10, 0x04, 0x2a, 0x86, 0x01, 0x0a, 0x13, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x44, 0x65, 0x6c, - 0x69, 0x76, 0x65, 0x72, 0x79, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x28, 0x0a, 0x24, 0x50, - 0x52, 0x4f, 0x4f, 0x46, 0x5f, 0x44, 0x45, 0x4c, 0x49, 0x56, 0x45, 0x52, 0x59, 0x5f, 0x53, 0x54, - 0x41, 0x54, 0x55, 0x53, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, - 0x42, 0x4c, 0x45, 0x10, 0x00, 0x12, 0x22, 0x0a, 0x1e, 0x50, 0x52, 0x4f, 0x4f, 0x46, 0x5f, 0x44, - 0x45, 0x4c, 0x49, 0x56, 0x45, 0x52, 0x59, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x43, - 0x4f, 0x4d, 0x50, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x01, 0x12, 0x21, 0x0a, 0x1d, 0x50, 0x52, 0x4f, + 0x65, 0x72, 0x52, 0x08, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, + 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, + 0x6f, 0x72, 0x12, 0x25, 0x0a, 0x0e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x5f, 0x6c, + 0x61, 0x62, 0x65, 0x6c, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x74, 0x72, 0x61, 0x6e, + 0x73, 0x66, 0x65, 0x72, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x26, 0x0a, 0x0f, 0x6e, 0x65, 0x78, + 0x74, 0x5f, 0x73, 0x65, 0x6e, 0x64, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x0b, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0d, 0x6e, 0x65, 0x78, 0x74, 0x53, 0x65, 0x6e, 0x64, 0x53, 0x74, 0x61, 0x74, + 0x65, 0x22, 0x97, 0x02, 0x0a, 0x11, 0x41, 0x6e, 0x63, 0x68, 0x6f, 0x72, 0x54, 0x72, 0x61, 0x6e, + 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x6e, 0x63, 0x68, 0x6f, + 0x72, 0x5f, 0x70, 0x73, 0x62, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x61, 0x6e, + 0x63, 0x68, 0x6f, 0x72, 0x50, 0x73, 0x62, 0x74, 0x12, 0x2e, 0x0a, 0x13, 0x63, 0x68, 0x61, 0x6e, + 0x67, 0x65, 0x5f, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x11, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x4f, 0x75, 0x74, + 0x70, 0x75, 0x74, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x26, 0x0a, 0x0f, 0x63, 0x68, 0x61, 0x69, + 0x6e, 0x5f, 0x66, 0x65, 0x65, 0x73, 0x5f, 0x73, 0x61, 0x74, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x03, 0x52, 0x0d, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x46, 0x65, 0x65, 0x73, 0x53, 0x61, 0x74, 0x73, + 0x12, 0x32, 0x0a, 0x16, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x66, 0x65, 0x65, 0x5f, 0x72, + 0x61, 0x74, 0x65, 0x5f, 0x73, 0x61, 0x74, 0x5f, 0x6b, 0x77, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, + 0x52, 0x12, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x46, 0x65, 0x65, 0x52, 0x61, 0x74, 0x65, 0x53, + 0x61, 0x74, 0x4b, 0x77, 0x12, 0x3a, 0x0a, 0x10, 0x6c, 0x6e, 0x64, 0x5f, 0x6c, 0x6f, 0x63, 0x6b, + 0x65, 0x64, 0x5f, 0x75, 0x74, 0x78, 0x6f, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, + 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4f, 0x75, 0x74, 0x50, 0x6f, 0x69, 0x6e, 0x74, + 0x52, 0x0e, 0x6c, 0x6e, 0x64, 0x4c, 0x6f, 0x63, 0x6b, 0x65, 0x64, 0x55, 0x74, 0x78, 0x6f, 0x73, + 0x12, 0x19, 0x0a, 0x08, 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x5f, 0x74, 0x78, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x07, 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x54, 0x78, 0x22, 0x9e, 0x01, 0x0a, 0x17, + 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x61, 0x73, 0x73, 0x65, 0x74, + 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x61, 0x73, 0x73, 0x65, 0x74, + 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x6b, 0x65, 0x79, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x4b, 0x65, 0x79, 0x12, + 0x1d, 0x0a, 0x0a, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x4b, 0x65, 0x79, 0x12, 0x2c, + 0x0a, 0x08, 0x6f, 0x75, 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x10, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4f, 0x75, 0x74, 0x50, 0x6f, 0x69, + 0x6e, 0x74, 0x52, 0x08, 0x6f, 0x75, 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x22, 0x54, 0x0a, 0x18, + 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x38, 0x0a, 0x10, 0x72, 0x65, 0x67, 0x69, + 0x73, 0x74, 0x65, 0x72, 0x65, 0x64, 0x5f, 0x61, 0x73, 0x73, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x73, 0x73, 0x65, + 0x74, 0x52, 0x0f, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x65, 0x64, 0x41, 0x73, 0x73, + 0x65, 0x74, 0x2a, 0x28, 0x0a, 0x09, 0x41, 0x73, 0x73, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, + 0x0a, 0x0a, 0x06, 0x4e, 0x4f, 0x52, 0x4d, 0x41, 0x4c, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x43, + 0x4f, 0x4c, 0x4c, 0x45, 0x43, 0x54, 0x49, 0x42, 0x4c, 0x45, 0x10, 0x01, 0x2a, 0x39, 0x0a, 0x0d, + 0x41, 0x73, 0x73, 0x65, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, + 0x10, 0x4d, 0x45, 0x54, 0x41, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4f, 0x50, 0x41, 0x51, 0x55, + 0x45, 0x10, 0x00, 0x12, 0x12, 0x0a, 0x0e, 0x4d, 0x45, 0x54, 0x41, 0x5f, 0x54, 0x59, 0x50, 0x45, + 0x5f, 0x4a, 0x53, 0x4f, 0x4e, 0x10, 0x01, 0x2a, 0x3a, 0x0a, 0x0c, 0x41, 0x73, 0x73, 0x65, 0x74, + 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x14, 0x0a, 0x10, 0x41, 0x53, 0x53, 0x45, 0x54, + 0x5f, 0x56, 0x45, 0x52, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x56, 0x30, 0x10, 0x00, 0x12, 0x14, 0x0a, + 0x10, 0x41, 0x53, 0x53, 0x45, 0x54, 0x5f, 0x56, 0x45, 0x52, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x56, + 0x31, 0x10, 0x01, 0x2a, 0x52, 0x0a, 0x0a, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x54, 0x79, 0x70, + 0x65, 0x12, 0x16, 0x0a, 0x12, 0x4f, 0x55, 0x54, 0x50, 0x55, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, + 0x5f, 0x53, 0x49, 0x4d, 0x50, 0x4c, 0x45, 0x10, 0x00, 0x12, 0x1a, 0x0a, 0x16, 0x4f, 0x55, 0x54, + 0x50, 0x55, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x50, 0x4c, 0x49, 0x54, 0x5f, 0x52, + 0x4f, 0x4f, 0x54, 0x10, 0x01, 0x22, 0x04, 0x08, 0x02, 0x10, 0x02, 0x22, 0x04, 0x08, 0x03, 0x10, + 0x03, 0x22, 0x04, 0x08, 0x04, 0x10, 0x04, 0x2a, 0x86, 0x01, 0x0a, 0x13, 0x50, 0x72, 0x6f, 0x6f, + 0x66, 0x44, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x79, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, + 0x28, 0x0a, 0x24, 0x50, 0x52, 0x4f, 0x4f, 0x46, 0x5f, 0x44, 0x45, 0x4c, 0x49, 0x56, 0x45, 0x52, + 0x59, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x41, 0x50, 0x50, + 0x4c, 0x49, 0x43, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x00, 0x12, 0x22, 0x0a, 0x1e, 0x50, 0x52, 0x4f, 0x4f, 0x46, 0x5f, 0x44, 0x45, 0x4c, 0x49, 0x56, 0x45, 0x52, 0x59, 0x5f, 0x53, 0x54, 0x41, 0x54, - 0x55, 0x53, 0x5f, 0x50, 0x45, 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x02, 0x2a, 0x6a, 0x0a, 0x0b, - 0x41, 0x64, 0x64, 0x72, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1c, 0x0a, 0x18, 0x41, - 0x44, 0x44, 0x52, 0x5f, 0x56, 0x45, 0x52, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x53, 0x50, - 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0f, 0x41, 0x44, 0x44, - 0x52, 0x5f, 0x56, 0x45, 0x52, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x56, 0x30, 0x10, 0x01, 0x12, 0x13, - 0x0a, 0x0f, 0x41, 0x44, 0x44, 0x52, 0x5f, 0x56, 0x45, 0x52, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x56, - 0x31, 0x10, 0x02, 0x12, 0x13, 0x0a, 0x0f, 0x41, 0x44, 0x44, 0x52, 0x5f, 0x56, 0x45, 0x52, 0x53, - 0x49, 0x4f, 0x4e, 0x5f, 0x56, 0x32, 0x10, 0x03, 0x2a, 0xc9, 0x01, 0x0a, 0x0d, 0x53, 0x63, 0x72, - 0x69, 0x70, 0x74, 0x4b, 0x65, 0x79, 0x54, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x12, 0x53, 0x43, - 0x52, 0x49, 0x50, 0x54, 0x5f, 0x4b, 0x45, 0x59, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, - 0x10, 0x00, 0x12, 0x14, 0x0a, 0x10, 0x53, 0x43, 0x52, 0x49, 0x50, 0x54, 0x5f, 0x4b, 0x45, 0x59, - 0x5f, 0x42, 0x49, 0x50, 0x38, 0x36, 0x10, 0x01, 0x12, 0x23, 0x0a, 0x1f, 0x53, 0x43, 0x52, 0x49, - 0x50, 0x54, 0x5f, 0x4b, 0x45, 0x59, 0x5f, 0x53, 0x43, 0x52, 0x49, 0x50, 0x54, 0x5f, 0x50, 0x41, - 0x54, 0x48, 0x5f, 0x45, 0x58, 0x54, 0x45, 0x52, 0x4e, 0x41, 0x4c, 0x10, 0x02, 0x12, 0x13, 0x0a, - 0x0f, 0x53, 0x43, 0x52, 0x49, 0x50, 0x54, 0x5f, 0x4b, 0x45, 0x59, 0x5f, 0x42, 0x55, 0x52, 0x4e, - 0x10, 0x03, 0x12, 0x18, 0x0a, 0x14, 0x53, 0x43, 0x52, 0x49, 0x50, 0x54, 0x5f, 0x4b, 0x45, 0x59, - 0x5f, 0x54, 0x4f, 0x4d, 0x42, 0x53, 0x54, 0x4f, 0x4e, 0x45, 0x10, 0x04, 0x12, 0x16, 0x0a, 0x12, - 0x53, 0x43, 0x52, 0x49, 0x50, 0x54, 0x5f, 0x4b, 0x45, 0x59, 0x5f, 0x43, 0x48, 0x41, 0x4e, 0x4e, - 0x45, 0x4c, 0x10, 0x05, 0x12, 0x1e, 0x0a, 0x1a, 0x53, 0x43, 0x52, 0x49, 0x50, 0x54, 0x5f, 0x4b, - 0x45, 0x59, 0x5f, 0x55, 0x4e, 0x49, 0x51, 0x55, 0x45, 0x5f, 0x50, 0x45, 0x44, 0x45, 0x52, 0x53, - 0x45, 0x4e, 0x10, 0x06, 0x2a, 0xd0, 0x01, 0x0a, 0x0f, 0x41, 0x64, 0x64, 0x72, 0x45, 0x76, 0x65, - 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1d, 0x0a, 0x19, 0x41, 0x44, 0x44, 0x52, - 0x5f, 0x45, 0x56, 0x45, 0x4e, 0x54, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, 0x4e, - 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x2a, 0x0a, 0x26, 0x41, 0x44, 0x44, 0x52, 0x5f, + 0x55, 0x53, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x01, 0x12, 0x21, 0x0a, + 0x1d, 0x50, 0x52, 0x4f, 0x4f, 0x46, 0x5f, 0x44, 0x45, 0x4c, 0x49, 0x56, 0x45, 0x52, 0x59, 0x5f, + 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x50, 0x45, 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x02, + 0x2a, 0x6a, 0x0a, 0x0b, 0x41, 0x64, 0x64, 0x72, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, + 0x1c, 0x0a, 0x18, 0x41, 0x44, 0x44, 0x52, 0x5f, 0x56, 0x45, 0x52, 0x53, 0x49, 0x4f, 0x4e, 0x5f, + 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x13, 0x0a, + 0x0f, 0x41, 0x44, 0x44, 0x52, 0x5f, 0x56, 0x45, 0x52, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x56, 0x30, + 0x10, 0x01, 0x12, 0x13, 0x0a, 0x0f, 0x41, 0x44, 0x44, 0x52, 0x5f, 0x56, 0x45, 0x52, 0x53, 0x49, + 0x4f, 0x4e, 0x5f, 0x56, 0x31, 0x10, 0x02, 0x12, 0x13, 0x0a, 0x0f, 0x41, 0x44, 0x44, 0x52, 0x5f, + 0x56, 0x45, 0x52, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x56, 0x32, 0x10, 0x03, 0x2a, 0xc9, 0x01, 0x0a, + 0x0d, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x4b, 0x65, 0x79, 0x54, 0x79, 0x70, 0x65, 0x12, 0x16, + 0x0a, 0x12, 0x53, 0x43, 0x52, 0x49, 0x50, 0x54, 0x5f, 0x4b, 0x45, 0x59, 0x5f, 0x55, 0x4e, 0x4b, + 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x14, 0x0a, 0x10, 0x53, 0x43, 0x52, 0x49, 0x50, 0x54, + 0x5f, 0x4b, 0x45, 0x59, 0x5f, 0x42, 0x49, 0x50, 0x38, 0x36, 0x10, 0x01, 0x12, 0x23, 0x0a, 0x1f, + 0x53, 0x43, 0x52, 0x49, 0x50, 0x54, 0x5f, 0x4b, 0x45, 0x59, 0x5f, 0x53, 0x43, 0x52, 0x49, 0x50, + 0x54, 0x5f, 0x50, 0x41, 0x54, 0x48, 0x5f, 0x45, 0x58, 0x54, 0x45, 0x52, 0x4e, 0x41, 0x4c, 0x10, + 0x02, 0x12, 0x13, 0x0a, 0x0f, 0x53, 0x43, 0x52, 0x49, 0x50, 0x54, 0x5f, 0x4b, 0x45, 0x59, 0x5f, + 0x42, 0x55, 0x52, 0x4e, 0x10, 0x03, 0x12, 0x18, 0x0a, 0x14, 0x53, 0x43, 0x52, 0x49, 0x50, 0x54, + 0x5f, 0x4b, 0x45, 0x59, 0x5f, 0x54, 0x4f, 0x4d, 0x42, 0x53, 0x54, 0x4f, 0x4e, 0x45, 0x10, 0x04, + 0x12, 0x16, 0x0a, 0x12, 0x53, 0x43, 0x52, 0x49, 0x50, 0x54, 0x5f, 0x4b, 0x45, 0x59, 0x5f, 0x43, + 0x48, 0x41, 0x4e, 0x4e, 0x45, 0x4c, 0x10, 0x05, 0x12, 0x1e, 0x0a, 0x1a, 0x53, 0x43, 0x52, 0x49, + 0x50, 0x54, 0x5f, 0x4b, 0x45, 0x59, 0x5f, 0x55, 0x4e, 0x49, 0x51, 0x55, 0x45, 0x5f, 0x50, 0x45, + 0x44, 0x45, 0x52, 0x53, 0x45, 0x4e, 0x10, 0x06, 0x2a, 0xd0, 0x01, 0x0a, 0x0f, 0x41, 0x64, 0x64, + 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1d, 0x0a, 0x19, + 0x41, 0x44, 0x44, 0x52, 0x5f, 0x45, 0x56, 0x45, 0x4e, 0x54, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, + 0x53, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x2a, 0x0a, 0x26, 0x41, + 0x44, 0x44, 0x52, 0x5f, 0x45, 0x56, 0x45, 0x4e, 0x54, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, + 0x5f, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x44, 0x45, 0x54, + 0x45, 0x43, 0x54, 0x45, 0x44, 0x10, 0x01, 0x12, 0x2b, 0x0a, 0x27, 0x41, 0x44, 0x44, 0x52, 0x5f, 0x45, 0x56, 0x45, 0x4e, 0x54, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x54, 0x52, 0x41, - 0x4e, 0x53, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x44, 0x45, 0x54, 0x45, 0x43, 0x54, 0x45, - 0x44, 0x10, 0x01, 0x12, 0x2b, 0x0a, 0x27, 0x41, 0x44, 0x44, 0x52, 0x5f, 0x45, 0x56, 0x45, 0x4e, - 0x54, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x41, 0x43, - 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x52, 0x4d, 0x45, 0x44, 0x10, 0x02, - 0x12, 0x24, 0x0a, 0x20, 0x41, 0x44, 0x44, 0x52, 0x5f, 0x45, 0x56, 0x45, 0x4e, 0x54, 0x5f, 0x53, - 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x50, 0x52, 0x4f, 0x4f, 0x46, 0x5f, 0x52, 0x45, 0x43, 0x45, - 0x49, 0x56, 0x45, 0x44, 0x10, 0x03, 0x12, 0x1f, 0x0a, 0x1b, 0x41, 0x44, 0x44, 0x52, 0x5f, 0x45, - 0x56, 0x45, 0x4e, 0x54, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x43, 0x4f, 0x4d, 0x50, - 0x4c, 0x45, 0x54, 0x45, 0x44, 0x10, 0x04, 0x2a, 0x9b, 0x02, 0x0a, 0x09, 0x53, 0x65, 0x6e, 0x64, - 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x23, 0x0a, 0x1f, 0x53, 0x45, 0x4e, 0x44, 0x5f, 0x53, 0x54, - 0x41, 0x54, 0x45, 0x5f, 0x56, 0x49, 0x52, 0x54, 0x55, 0x41, 0x4c, 0x5f, 0x49, 0x4e, 0x50, 0x55, - 0x54, 0x5f, 0x53, 0x45, 0x4c, 0x45, 0x43, 0x54, 0x10, 0x00, 0x12, 0x1b, 0x0a, 0x17, 0x53, 0x45, - 0x4e, 0x44, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x56, 0x49, 0x52, 0x54, 0x55, 0x41, 0x4c, - 0x5f, 0x53, 0x49, 0x47, 0x4e, 0x10, 0x01, 0x12, 0x1a, 0x0a, 0x16, 0x53, 0x45, 0x4e, 0x44, 0x5f, - 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x41, 0x4e, 0x43, 0x48, 0x4f, 0x52, 0x5f, 0x53, 0x49, 0x47, - 0x4e, 0x10, 0x02, 0x12, 0x1d, 0x0a, 0x19, 0x53, 0x45, 0x4e, 0x44, 0x5f, 0x53, 0x54, 0x41, 0x54, - 0x45, 0x5f, 0x4c, 0x4f, 0x47, 0x5f, 0x43, 0x4f, 0x4d, 0x4d, 0x49, 0x54, 0x4d, 0x45, 0x4e, 0x54, - 0x10, 0x03, 0x12, 0x18, 0x0a, 0x14, 0x53, 0x45, 0x4e, 0x44, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, - 0x5f, 0x42, 0x52, 0x4f, 0x41, 0x44, 0x43, 0x41, 0x53, 0x54, 0x10, 0x04, 0x12, 0x20, 0x0a, 0x1c, - 0x53, 0x45, 0x4e, 0x44, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x57, 0x41, 0x49, 0x54, 0x5f, - 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x52, 0x4d, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x05, 0x12, 0x1b, - 0x0a, 0x17, 0x53, 0x45, 0x4e, 0x44, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x53, 0x54, 0x4f, - 0x52, 0x45, 0x5f, 0x50, 0x52, 0x4f, 0x4f, 0x46, 0x53, 0x10, 0x06, 0x12, 0x1e, 0x0a, 0x1a, 0x53, - 0x45, 0x4e, 0x44, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x46, - 0x45, 0x52, 0x5f, 0x50, 0x52, 0x4f, 0x4f, 0x46, 0x53, 0x10, 0x07, 0x12, 0x18, 0x0a, 0x14, 0x53, - 0x45, 0x4e, 0x44, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x4c, 0x45, - 0x54, 0x45, 0x44, 0x10, 0x08, 0x2a, 0x78, 0x0a, 0x0a, 0x50, 0x61, 0x72, 0x63, 0x65, 0x6c, 0x54, - 0x79, 0x70, 0x65, 0x12, 0x17, 0x0a, 0x13, 0x50, 0x41, 0x52, 0x43, 0x45, 0x4c, 0x5f, 0x54, 0x59, - 0x50, 0x45, 0x5f, 0x41, 0x44, 0x44, 0x52, 0x45, 0x53, 0x53, 0x10, 0x00, 0x12, 0x1a, 0x0a, 0x16, - 0x50, 0x41, 0x52, 0x43, 0x45, 0x4c, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x50, 0x52, 0x45, 0x5f, - 0x53, 0x49, 0x47, 0x4e, 0x45, 0x44, 0x10, 0x01, 0x12, 0x17, 0x0a, 0x13, 0x50, 0x41, 0x52, 0x43, - 0x45, 0x4c, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x50, 0x45, 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x10, - 0x02, 0x12, 0x1c, 0x0a, 0x18, 0x50, 0x41, 0x52, 0x43, 0x45, 0x4c, 0x5f, 0x54, 0x59, 0x50, 0x45, - 0x5f, 0x50, 0x52, 0x45, 0x5f, 0x41, 0x4e, 0x43, 0x48, 0x4f, 0x52, 0x45, 0x44, 0x10, 0x03, 0x32, - 0xd2, 0x0c, 0x0a, 0x0d, 0x54, 0x61, 0x70, 0x72, 0x6f, 0x6f, 0x74, 0x41, 0x73, 0x73, 0x65, 0x74, - 0x73, 0x12, 0x41, 0x0a, 0x0a, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x73, 0x73, 0x65, 0x74, 0x73, 0x12, - 0x18, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x73, 0x73, - 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x74, 0x61, 0x70, 0x72, - 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x73, 0x73, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x40, 0x0a, 0x09, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x74, 0x78, 0x6f, - 0x73, 0x12, 0x18, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x55, - 0x74, 0x78, 0x6f, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x74, 0x61, - 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x74, 0x78, 0x6f, 0x73, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x43, 0x0a, 0x0a, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x72, - 0x6f, 0x75, 0x70, 0x73, 0x12, 0x19, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, - 0x73, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x1a, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x72, 0x6f, - 0x75, 0x70, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x49, 0x0a, 0x0c, 0x4c, - 0x69, 0x73, 0x74, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x1b, 0x2e, 0x74, 0x61, - 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, - 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, - 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4c, 0x0a, 0x0d, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x72, - 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x73, 0x12, 0x1c, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, - 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, - 0x69, 0x73, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x37, 0x0a, 0x0a, 0x53, 0x74, 0x6f, 0x70, 0x44, 0x61, 0x65, 0x6d, - 0x6f, 0x6e, 0x12, 0x13, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x74, 0x6f, 0x70, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, - 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x43, 0x0a, - 0x0a, 0x44, 0x65, 0x62, 0x75, 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x19, 0x2e, 0x74, 0x61, - 0x70, 0x72, 0x70, 0x63, 0x2e, 0x44, 0x65, 0x62, 0x75, 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, - 0x44, 0x65, 0x62, 0x75, 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x41, 0x0a, 0x0a, 0x51, 0x75, 0x65, 0x72, 0x79, 0x41, 0x64, 0x64, 0x72, 0x73, - 0x12, 0x18, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x41, - 0x64, 0x64, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x74, 0x61, 0x70, - 0x72, 0x70, 0x63, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x41, 0x64, 0x64, 0x72, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x07, 0x4e, 0x65, 0x77, 0x41, 0x64, 0x64, 0x72, - 0x12, 0x16, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4e, 0x65, 0x77, 0x41, 0x64, 0x64, - 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0c, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, - 0x63, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x12, 0x35, 0x0a, 0x0a, 0x44, 0x65, 0x63, 0x6f, 0x64, 0x65, - 0x41, 0x64, 0x64, 0x72, 0x12, 0x19, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x44, 0x65, - 0x63, 0x6f, 0x64, 0x65, 0x41, 0x64, 0x64, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x0c, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x12, 0x49, 0x0a, - 0x0c, 0x41, 0x64, 0x64, 0x72, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x73, 0x12, 0x1b, 0x2e, - 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x52, 0x65, 0x63, 0x65, 0x69, - 0x76, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x74, 0x61, 0x70, - 0x72, 0x70, 0x63, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x73, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3d, 0x0a, 0x0b, 0x56, 0x65, 0x72, 0x69, - 0x66, 0x79, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x12, 0x11, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, - 0x2e, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x46, 0x69, 0x6c, 0x65, 0x1a, 0x1b, 0x2e, 0x74, 0x61, 0x70, - 0x72, 0x70, 0x63, 0x2e, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x46, 0x0a, 0x0b, 0x44, 0x65, 0x63, 0x6f, 0x64, - 0x65, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x12, 0x1a, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, - 0x44, 0x65, 0x63, 0x6f, 0x64, 0x65, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x44, 0x65, 0x63, 0x6f, - 0x64, 0x65, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x3c, 0x0a, 0x0b, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x12, 0x1a, - 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x50, 0x72, - 0x6f, 0x6f, 0x66, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x11, 0x2e, 0x74, 0x61, 0x70, - 0x72, 0x70, 0x63, 0x2e, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x52, 0x0a, - 0x0f, 0x55, 0x6e, 0x70, 0x61, 0x63, 0x6b, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x46, 0x69, 0x6c, 0x65, - 0x12, 0x1e, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x55, 0x6e, 0x70, 0x61, 0x63, 0x6b, - 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x1f, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x55, 0x6e, 0x70, 0x61, 0x63, 0x6b, - 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x40, 0x0a, 0x09, 0x53, 0x65, 0x6e, 0x64, 0x41, 0x73, 0x73, 0x65, 0x74, 0x12, 0x18, - 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x41, 0x73, 0x73, 0x65, - 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, - 0x63, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x41, 0x73, 0x73, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x40, 0x0a, 0x09, 0x42, 0x75, 0x72, 0x6e, 0x41, 0x73, 0x73, 0x65, 0x74, - 0x12, 0x18, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x42, 0x75, 0x72, 0x6e, 0x41, 0x73, - 0x73, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x74, 0x61, 0x70, - 0x72, 0x70, 0x63, 0x2e, 0x42, 0x75, 0x72, 0x6e, 0x41, 0x73, 0x73, 0x65, 0x74, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x40, 0x0a, 0x09, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x75, 0x72, - 0x6e, 0x73, 0x12, 0x18, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, - 0x42, 0x75, 0x72, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x74, - 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x75, 0x72, 0x6e, 0x73, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3a, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x49, 0x6e, - 0x66, 0x6f, 0x12, 0x16, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x49, - 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x74, 0x61, 0x70, - 0x72, 0x70, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x4f, 0x0a, 0x0e, 0x46, 0x65, 0x74, 0x63, 0x68, 0x41, 0x73, 0x73, 0x65, - 0x74, 0x4d, 0x65, 0x74, 0x61, 0x12, 0x1d, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x46, - 0x65, 0x74, 0x63, 0x68, 0x41, 0x73, 0x73, 0x65, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x46, 0x65, - 0x74, 0x63, 0x68, 0x41, 0x73, 0x73, 0x65, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x57, 0x0a, 0x16, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, - 0x65, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x25, - 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, - 0x65, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x52, - 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x30, 0x01, 0x12, 0x4e, 0x0a, - 0x13, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x53, 0x65, 0x6e, 0x64, 0x45, 0x76, - 0x65, 0x6e, 0x74, 0x73, 0x12, 0x22, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x75, - 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x53, 0x65, 0x6e, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, - 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x11, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, - 0x63, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x30, 0x01, 0x12, 0x55, 0x0a, - 0x10, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, - 0x72, 0x12, 0x1f, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, - 0x74, 0x65, 0x72, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x65, 0x67, 0x69, - 0x73, 0x74, 0x65, 0x72, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x30, 0x5a, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, - 0x6f, 0x6d, 0x2f, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x6e, 0x69, 0x6e, 0x67, 0x6c, 0x61, 0x62, 0x73, - 0x2f, 0x74, 0x61, 0x70, 0x72, 0x6f, 0x6f, 0x74, 0x2d, 0x61, 0x73, 0x73, 0x65, 0x74, 0x73, 0x2f, - 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x4e, 0x53, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x52, 0x4d, + 0x45, 0x44, 0x10, 0x02, 0x12, 0x24, 0x0a, 0x20, 0x41, 0x44, 0x44, 0x52, 0x5f, 0x45, 0x56, 0x45, + 0x4e, 0x54, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x50, 0x52, 0x4f, 0x4f, 0x46, 0x5f, + 0x52, 0x45, 0x43, 0x45, 0x49, 0x56, 0x45, 0x44, 0x10, 0x03, 0x12, 0x1f, 0x0a, 0x1b, 0x41, 0x44, + 0x44, 0x52, 0x5f, 0x45, 0x56, 0x45, 0x4e, 0x54, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, + 0x43, 0x4f, 0x4d, 0x50, 0x4c, 0x45, 0x54, 0x45, 0x44, 0x10, 0x04, 0x2a, 0x9b, 0x02, 0x0a, 0x09, + 0x53, 0x65, 0x6e, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x23, 0x0a, 0x1f, 0x53, 0x45, 0x4e, + 0x44, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x56, 0x49, 0x52, 0x54, 0x55, 0x41, 0x4c, 0x5f, + 0x49, 0x4e, 0x50, 0x55, 0x54, 0x5f, 0x53, 0x45, 0x4c, 0x45, 0x43, 0x54, 0x10, 0x00, 0x12, 0x1b, + 0x0a, 0x17, 0x53, 0x45, 0x4e, 0x44, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x56, 0x49, 0x52, + 0x54, 0x55, 0x41, 0x4c, 0x5f, 0x53, 0x49, 0x47, 0x4e, 0x10, 0x01, 0x12, 0x1a, 0x0a, 0x16, 0x53, + 0x45, 0x4e, 0x44, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x41, 0x4e, 0x43, 0x48, 0x4f, 0x52, + 0x5f, 0x53, 0x49, 0x47, 0x4e, 0x10, 0x02, 0x12, 0x1d, 0x0a, 0x19, 0x53, 0x45, 0x4e, 0x44, 0x5f, + 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x4c, 0x4f, 0x47, 0x5f, 0x43, 0x4f, 0x4d, 0x4d, 0x49, 0x54, + 0x4d, 0x45, 0x4e, 0x54, 0x10, 0x03, 0x12, 0x18, 0x0a, 0x14, 0x53, 0x45, 0x4e, 0x44, 0x5f, 0x53, + 0x54, 0x41, 0x54, 0x45, 0x5f, 0x42, 0x52, 0x4f, 0x41, 0x44, 0x43, 0x41, 0x53, 0x54, 0x10, 0x04, + 0x12, 0x20, 0x0a, 0x1c, 0x53, 0x45, 0x4e, 0x44, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x57, + 0x41, 0x49, 0x54, 0x5f, 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x52, 0x4d, 0x41, 0x54, 0x49, 0x4f, 0x4e, + 0x10, 0x05, 0x12, 0x1b, 0x0a, 0x17, 0x53, 0x45, 0x4e, 0x44, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, + 0x5f, 0x53, 0x54, 0x4f, 0x52, 0x45, 0x5f, 0x50, 0x52, 0x4f, 0x4f, 0x46, 0x53, 0x10, 0x06, 0x12, + 0x1e, 0x0a, 0x1a, 0x53, 0x45, 0x4e, 0x44, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x54, 0x52, + 0x41, 0x4e, 0x53, 0x46, 0x45, 0x52, 0x5f, 0x50, 0x52, 0x4f, 0x4f, 0x46, 0x53, 0x10, 0x07, 0x12, + 0x18, 0x0a, 0x14, 0x53, 0x45, 0x4e, 0x44, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x43, 0x4f, + 0x4d, 0x50, 0x4c, 0x45, 0x54, 0x45, 0x44, 0x10, 0x08, 0x2a, 0x78, 0x0a, 0x0a, 0x50, 0x61, 0x72, + 0x63, 0x65, 0x6c, 0x54, 0x79, 0x70, 0x65, 0x12, 0x17, 0x0a, 0x13, 0x50, 0x41, 0x52, 0x43, 0x45, + 0x4c, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x41, 0x44, 0x44, 0x52, 0x45, 0x53, 0x53, 0x10, 0x00, + 0x12, 0x1a, 0x0a, 0x16, 0x50, 0x41, 0x52, 0x43, 0x45, 0x4c, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, + 0x50, 0x52, 0x45, 0x5f, 0x53, 0x49, 0x47, 0x4e, 0x45, 0x44, 0x10, 0x01, 0x12, 0x17, 0x0a, 0x13, + 0x50, 0x41, 0x52, 0x43, 0x45, 0x4c, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x50, 0x45, 0x4e, 0x44, + 0x49, 0x4e, 0x47, 0x10, 0x02, 0x12, 0x1c, 0x0a, 0x18, 0x50, 0x41, 0x52, 0x43, 0x45, 0x4c, 0x5f, + 0x54, 0x59, 0x50, 0x45, 0x5f, 0x50, 0x52, 0x45, 0x5f, 0x41, 0x4e, 0x43, 0x48, 0x4f, 0x52, 0x45, + 0x44, 0x10, 0x03, 0x32, 0xd2, 0x0c, 0x0a, 0x0d, 0x54, 0x61, 0x70, 0x72, 0x6f, 0x6f, 0x74, 0x41, + 0x73, 0x73, 0x65, 0x74, 0x73, 0x12, 0x41, 0x0a, 0x0a, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x73, 0x73, + 0x65, 0x74, 0x73, 0x12, 0x18, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, + 0x74, 0x41, 0x73, 0x73, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, + 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x73, 0x73, 0x65, 0x74, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x40, 0x0a, 0x09, 0x4c, 0x69, 0x73, 0x74, + 0x55, 0x74, 0x78, 0x6f, 0x73, 0x12, 0x18, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, + 0x69, 0x73, 0x74, 0x55, 0x74, 0x78, 0x6f, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x19, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x74, 0x78, + 0x6f, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x43, 0x0a, 0x0a, 0x4c, 0x69, + 0x73, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x12, 0x19, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, + 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, + 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x49, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x12, + 0x1b, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x61, 0x6c, + 0x61, 0x6e, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x74, + 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, + 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4c, 0x0a, 0x0d, 0x4c, 0x69, + 0x73, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x73, 0x12, 0x1c, 0x2e, 0x74, 0x61, + 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, + 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x74, 0x61, 0x70, 0x72, + 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x37, 0x0a, 0x0a, 0x53, 0x74, 0x6f, 0x70, + 0x44, 0x61, 0x65, 0x6d, 0x6f, 0x6e, 0x12, 0x13, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, + 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x74, 0x61, + 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x43, 0x0a, 0x0a, 0x44, 0x65, 0x62, 0x75, 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x12, + 0x19, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x44, 0x65, 0x62, 0x75, 0x67, 0x4c, 0x65, + 0x76, 0x65, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x74, 0x61, 0x70, + 0x72, 0x70, 0x63, 0x2e, 0x44, 0x65, 0x62, 0x75, 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x41, 0x0a, 0x0a, 0x51, 0x75, 0x65, 0x72, 0x79, 0x41, + 0x64, 0x64, 0x72, 0x73, 0x12, 0x18, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x51, 0x75, + 0x65, 0x72, 0x79, 0x41, 0x64, 0x64, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, + 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x41, 0x64, 0x64, + 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x07, 0x4e, 0x65, 0x77, + 0x41, 0x64, 0x64, 0x72, 0x12, 0x16, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4e, 0x65, + 0x77, 0x41, 0x64, 0x64, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0c, 0x2e, 0x74, + 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x12, 0x35, 0x0a, 0x0a, 0x44, 0x65, + 0x63, 0x6f, 0x64, 0x65, 0x41, 0x64, 0x64, 0x72, 0x12, 0x19, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, + 0x63, 0x2e, 0x44, 0x65, 0x63, 0x6f, 0x64, 0x65, 0x41, 0x64, 0x64, 0x72, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x0c, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x64, 0x64, + 0x72, 0x12, 0x49, 0x0a, 0x0c, 0x41, 0x64, 0x64, 0x72, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, + 0x73, 0x12, 0x1b, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x52, + 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, + 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x52, 0x65, 0x63, 0x65, + 0x69, 0x76, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3d, 0x0a, 0x0b, + 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x12, 0x11, 0x2e, 0x74, 0x61, + 0x70, 0x72, 0x70, 0x63, 0x2e, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x46, 0x69, 0x6c, 0x65, 0x1a, 0x1b, + 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x50, 0x72, + 0x6f, 0x6f, 0x66, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x46, 0x0a, 0x0b, 0x44, + 0x65, 0x63, 0x6f, 0x64, 0x65, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x12, 0x1a, 0x2e, 0x74, 0x61, 0x70, + 0x72, 0x70, 0x63, 0x2e, 0x44, 0x65, 0x63, 0x6f, 0x64, 0x65, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, + 0x44, 0x65, 0x63, 0x6f, 0x64, 0x65, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x3c, 0x0a, 0x0b, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x50, 0x72, 0x6f, + 0x6f, 0x66, 0x12, 0x1a, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x45, 0x78, 0x70, 0x6f, + 0x72, 0x74, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x11, + 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x46, 0x69, 0x6c, + 0x65, 0x12, 0x52, 0x0a, 0x0f, 0x55, 0x6e, 0x70, 0x61, 0x63, 0x6b, 0x50, 0x72, 0x6f, 0x6f, 0x66, + 0x46, 0x69, 0x6c, 0x65, 0x12, 0x1e, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x55, 0x6e, + 0x70, 0x61, 0x63, 0x6b, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x55, 0x6e, + 0x70, 0x61, 0x63, 0x6b, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x40, 0x0a, 0x09, 0x53, 0x65, 0x6e, 0x64, 0x41, 0x73, 0x73, + 0x65, 0x74, 0x12, 0x18, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x6e, 0x64, + 0x41, 0x73, 0x73, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x74, + 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x41, 0x73, 0x73, 0x65, 0x74, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x40, 0x0a, 0x09, 0x42, 0x75, 0x72, 0x6e, 0x41, + 0x73, 0x73, 0x65, 0x74, 0x12, 0x18, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x42, 0x75, + 0x72, 0x6e, 0x41, 0x73, 0x73, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, + 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x42, 0x75, 0x72, 0x6e, 0x41, 0x73, 0x73, 0x65, + 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x40, 0x0a, 0x09, 0x4c, 0x69, 0x73, + 0x74, 0x42, 0x75, 0x72, 0x6e, 0x73, 0x12, 0x18, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, + 0x4c, 0x69, 0x73, 0x74, 0x42, 0x75, 0x72, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x19, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x75, + 0x72, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3a, 0x0a, 0x07, 0x47, + 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x16, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, + 0x47, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, + 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4f, 0x0a, 0x0e, 0x46, 0x65, 0x74, 0x63, 0x68, + 0x41, 0x73, 0x73, 0x65, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x12, 0x1d, 0x2e, 0x74, 0x61, 0x70, 0x72, + 0x70, 0x63, 0x2e, 0x46, 0x65, 0x74, 0x63, 0x68, 0x41, 0x73, 0x73, 0x65, 0x74, 0x4d, 0x65, 0x74, + 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, + 0x63, 0x2e, 0x46, 0x65, 0x74, 0x63, 0x68, 0x41, 0x73, 0x73, 0x65, 0x74, 0x4d, 0x65, 0x74, 0x61, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x57, 0x0a, 0x16, 0x53, 0x75, 0x62, 0x73, + 0x63, 0x72, 0x69, 0x62, 0x65, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x45, 0x76, 0x65, 0x6e, + 0x74, 0x73, 0x12, 0x25, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x75, 0x62, 0x73, + 0x63, 0x72, 0x69, 0x62, 0x65, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x45, 0x76, 0x65, 0x6e, + 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x74, 0x61, 0x70, 0x72, + 0x70, 0x63, 0x2e, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x30, + 0x01, 0x12, 0x4e, 0x0a, 0x13, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x53, 0x65, + 0x6e, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x22, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, + 0x63, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x53, 0x65, 0x6e, 0x64, 0x45, + 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x11, 0x2e, 0x74, + 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x30, + 0x01, 0x12, 0x55, 0x0a, 0x10, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x54, 0x72, 0x61, + 0x6e, 0x73, 0x66, 0x65, 0x72, 0x12, 0x1f, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x52, + 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, + 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x30, 0x5a, 0x2e, 0x67, 0x69, 0x74, 0x68, + 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x6e, 0x69, 0x6e, 0x67, + 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x74, 0x61, 0x70, 0x72, 0x6f, 0x6f, 0x74, 0x2d, 0x61, 0x73, 0x73, + 0x65, 0x74, 0x73, 0x2f, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, } var ( @@ -8368,6 +8424,8 @@ var file_taprootassets_proto_goTypes = []any{ nil, // 95: taprpc.ListBalancesResponse.AssetGroupBalancesEntry nil, // 96: taprpc.FetchAssetMetaResponse.UnknownOddTypesEntry (*OutPoint)(nil), // 97: taprpc.OutPoint + (SortDirection)(0), // 98: taprpc.SortDirection + (*AssetSpecifier)(nil), // 99: taprpc.AssetSpecifier } var file_taprootassets_proto_depIdxs = []int32{ 1, // 0: taprpc.AssetMeta.type:type_name -> taprpc.AssetMetaType @@ -8433,78 +8491,80 @@ var file_taprootassets_proto_depIdxs = []int32{ 49, // 60: taprpc.AddrEvent.addr:type_name -> taprpc.Addr 7, // 61: taprpc.AddrEvent.status:type_name -> taprpc.AddrEventStatus 7, // 62: taprpc.AddrReceivesRequest.filter_status:type_name -> taprpc.AddrEventStatus - 69, // 63: taprpc.AddrReceivesResponse.events:type_name -> taprpc.AddrEvent - 73, // 64: taprpc.SendAssetRequest.addresses_with_amounts:type_name -> taprpc.AddressWithAmount - 41, // 65: taprpc.SendAssetResponse.transfer:type_name -> taprpc.AssetTransfer - 1, // 66: taprpc.FetchAssetMetaResponse.type:type_name -> taprpc.AssetMetaType - 96, // 67: taprpc.FetchAssetMetaResponse.unknown_odd_types:type_name -> taprpc.FetchAssetMetaResponse.UnknownOddTypesEntry - 41, // 68: taprpc.BurnAssetResponse.burn_transfer:type_name -> taprpc.AssetTransfer - 62, // 69: taprpc.BurnAssetResponse.burn_proof:type_name -> taprpc.DecodedProof - 83, // 70: taprpc.ListBurnsResponse.burns:type_name -> taprpc.AssetBurn - 49, // 71: taprpc.ReceiveEvent.address:type_name -> taprpc.Addr - 7, // 72: taprpc.ReceiveEvent.status:type_name -> taprpc.AddrEventStatus - 9, // 73: taprpc.SendEvent.parcel_type:type_name -> taprpc.ParcelType - 49, // 74: taprpc.SendEvent.addresses:type_name -> taprpc.Addr - 89, // 75: taprpc.SendEvent.anchor_transaction:type_name -> taprpc.AnchorTransaction - 41, // 76: taprpc.SendEvent.transfer:type_name -> taprpc.AssetTransfer - 97, // 77: taprpc.AnchorTransaction.lnd_locked_utxos:type_name -> taprpc.OutPoint - 97, // 78: taprpc.RegisterTransferRequest.outpoint:type_name -> taprpc.OutPoint - 23, // 79: taprpc.RegisterTransferResponse.registered_asset:type_name -> taprpc.Asset - 28, // 80: taprpc.ListUtxosResponse.ManagedUtxosEntry.value:type_name -> taprpc.ManagedUtxo - 32, // 81: taprpc.ListGroupsResponse.GroupsEntry.value:type_name -> taprpc.GroupedAssets - 35, // 82: taprpc.ListBalancesResponse.AssetBalancesEntry.value:type_name -> taprpc.AssetBalance - 36, // 83: taprpc.ListBalancesResponse.AssetGroupBalancesEntry.value:type_name -> taprpc.AssetGroupBalance - 11, // 84: taprpc.TaprootAssets.ListAssets:input_type -> taprpc.ListAssetRequest - 27, // 85: taprpc.TaprootAssets.ListUtxos:input_type -> taprpc.ListUtxosRequest - 30, // 86: taprpc.TaprootAssets.ListGroups:input_type -> taprpc.ListGroupsRequest - 34, // 87: taprpc.TaprootAssets.ListBalances:input_type -> taprpc.ListBalancesRequest - 38, // 88: taprpc.TaprootAssets.ListTransfers:input_type -> taprpc.ListTransfersRequest - 45, // 89: taprpc.TaprootAssets.StopDaemon:input_type -> taprpc.StopRequest - 47, // 90: taprpc.TaprootAssets.DebugLevel:input_type -> taprpc.DebugLevelRequest - 50, // 91: taprpc.TaprootAssets.QueryAddrs:input_type -> taprpc.QueryAddrRequest - 52, // 92: taprpc.TaprootAssets.NewAddr:input_type -> taprpc.NewAddrRequest - 60, // 93: taprpc.TaprootAssets.DecodeAddr:input_type -> taprpc.DecodeAddrRequest - 70, // 94: taprpc.TaprootAssets.AddrReceives:input_type -> taprpc.AddrReceivesRequest - 61, // 95: taprpc.TaprootAssets.VerifyProof:input_type -> taprpc.ProofFile - 64, // 96: taprpc.TaprootAssets.DecodeProof:input_type -> taprpc.DecodeProofRequest - 66, // 97: taprpc.TaprootAssets.ExportProof:input_type -> taprpc.ExportProofRequest - 67, // 98: taprpc.TaprootAssets.UnpackProofFile:input_type -> taprpc.UnpackProofFileRequest - 72, // 99: taprpc.TaprootAssets.SendAsset:input_type -> taprpc.SendAssetRequest - 80, // 100: taprpc.TaprootAssets.BurnAsset:input_type -> taprpc.BurnAssetRequest - 82, // 101: taprpc.TaprootAssets.ListBurns:input_type -> taprpc.ListBurnsRequest - 76, // 102: taprpc.TaprootAssets.GetInfo:input_type -> taprpc.GetInfoRequest - 78, // 103: taprpc.TaprootAssets.FetchAssetMeta:input_type -> taprpc.FetchAssetMetaRequest - 85, // 104: taprpc.TaprootAssets.SubscribeReceiveEvents:input_type -> taprpc.SubscribeReceiveEventsRequest - 87, // 105: taprpc.TaprootAssets.SubscribeSendEvents:input_type -> taprpc.SubscribeSendEventsRequest - 90, // 106: taprpc.TaprootAssets.RegisterTransfer:input_type -> taprpc.RegisterTransferRequest - 26, // 107: taprpc.TaprootAssets.ListAssets:output_type -> taprpc.ListAssetResponse - 29, // 108: taprpc.TaprootAssets.ListUtxos:output_type -> taprpc.ListUtxosResponse - 33, // 109: taprpc.TaprootAssets.ListGroups:output_type -> taprpc.ListGroupsResponse - 37, // 110: taprpc.TaprootAssets.ListBalances:output_type -> taprpc.ListBalancesResponse - 39, // 111: taprpc.TaprootAssets.ListTransfers:output_type -> taprpc.ListTransfersResponse - 46, // 112: taprpc.TaprootAssets.StopDaemon:output_type -> taprpc.StopResponse - 48, // 113: taprpc.TaprootAssets.DebugLevel:output_type -> taprpc.DebugLevelResponse - 51, // 114: taprpc.TaprootAssets.QueryAddrs:output_type -> taprpc.QueryAddrResponse - 49, // 115: taprpc.TaprootAssets.NewAddr:output_type -> taprpc.Addr - 49, // 116: taprpc.TaprootAssets.DecodeAddr:output_type -> taprpc.Addr - 71, // 117: taprpc.TaprootAssets.AddrReceives:output_type -> taprpc.AddrReceivesResponse - 63, // 118: taprpc.TaprootAssets.VerifyProof:output_type -> taprpc.VerifyProofResponse - 65, // 119: taprpc.TaprootAssets.DecodeProof:output_type -> taprpc.DecodeProofResponse - 61, // 120: taprpc.TaprootAssets.ExportProof:output_type -> taprpc.ProofFile - 68, // 121: taprpc.TaprootAssets.UnpackProofFile:output_type -> taprpc.UnpackProofFileResponse - 75, // 122: taprpc.TaprootAssets.SendAsset:output_type -> taprpc.SendAssetResponse - 81, // 123: taprpc.TaprootAssets.BurnAsset:output_type -> taprpc.BurnAssetResponse - 84, // 124: taprpc.TaprootAssets.ListBurns:output_type -> taprpc.ListBurnsResponse - 77, // 125: taprpc.TaprootAssets.GetInfo:output_type -> taprpc.GetInfoResponse - 79, // 126: taprpc.TaprootAssets.FetchAssetMeta:output_type -> taprpc.FetchAssetMetaResponse - 86, // 127: taprpc.TaprootAssets.SubscribeReceiveEvents:output_type -> taprpc.ReceiveEvent - 88, // 128: taprpc.TaprootAssets.SubscribeSendEvents:output_type -> taprpc.SendEvent - 91, // 129: taprpc.TaprootAssets.RegisterTransfer:output_type -> taprpc.RegisterTransferResponse - 107, // [107:130] is the sub-list for method output_type - 84, // [84:107] is the sub-list for method input_type - 84, // [84:84] is the sub-list for extension type_name - 84, // [84:84] is the sub-list for extension extendee - 0, // [0:84] is the sub-list for field type_name + 98, // 63: taprpc.AddrReceivesRequest.direction:type_name -> taprpc.SortDirection + 69, // 64: taprpc.AddrReceivesResponse.events:type_name -> taprpc.AddrEvent + 73, // 65: taprpc.SendAssetRequest.addresses_with_amounts:type_name -> taprpc.AddressWithAmount + 41, // 66: taprpc.SendAssetResponse.transfer:type_name -> taprpc.AssetTransfer + 1, // 67: taprpc.FetchAssetMetaResponse.type:type_name -> taprpc.AssetMetaType + 96, // 68: taprpc.FetchAssetMetaResponse.unknown_odd_types:type_name -> taprpc.FetchAssetMetaResponse.UnknownOddTypesEntry + 99, // 69: taprpc.BurnAssetRequest.asset_specifier:type_name -> taprpc.AssetSpecifier + 41, // 70: taprpc.BurnAssetResponse.burn_transfer:type_name -> taprpc.AssetTransfer + 62, // 71: taprpc.BurnAssetResponse.burn_proofs:type_name -> taprpc.DecodedProof + 83, // 72: taprpc.ListBurnsResponse.burns:type_name -> taprpc.AssetBurn + 49, // 73: taprpc.ReceiveEvent.address:type_name -> taprpc.Addr + 7, // 74: taprpc.ReceiveEvent.status:type_name -> taprpc.AddrEventStatus + 9, // 75: taprpc.SendEvent.parcel_type:type_name -> taprpc.ParcelType + 49, // 76: taprpc.SendEvent.addresses:type_name -> taprpc.Addr + 89, // 77: taprpc.SendEvent.anchor_transaction:type_name -> taprpc.AnchorTransaction + 41, // 78: taprpc.SendEvent.transfer:type_name -> taprpc.AssetTransfer + 97, // 79: taprpc.AnchorTransaction.lnd_locked_utxos:type_name -> taprpc.OutPoint + 97, // 80: taprpc.RegisterTransferRequest.outpoint:type_name -> taprpc.OutPoint + 23, // 81: taprpc.RegisterTransferResponse.registered_asset:type_name -> taprpc.Asset + 28, // 82: taprpc.ListUtxosResponse.ManagedUtxosEntry.value:type_name -> taprpc.ManagedUtxo + 32, // 83: taprpc.ListGroupsResponse.GroupsEntry.value:type_name -> taprpc.GroupedAssets + 35, // 84: taprpc.ListBalancesResponse.AssetBalancesEntry.value:type_name -> taprpc.AssetBalance + 36, // 85: taprpc.ListBalancesResponse.AssetGroupBalancesEntry.value:type_name -> taprpc.AssetGroupBalance + 11, // 86: taprpc.TaprootAssets.ListAssets:input_type -> taprpc.ListAssetRequest + 27, // 87: taprpc.TaprootAssets.ListUtxos:input_type -> taprpc.ListUtxosRequest + 30, // 88: taprpc.TaprootAssets.ListGroups:input_type -> taprpc.ListGroupsRequest + 34, // 89: taprpc.TaprootAssets.ListBalances:input_type -> taprpc.ListBalancesRequest + 38, // 90: taprpc.TaprootAssets.ListTransfers:input_type -> taprpc.ListTransfersRequest + 45, // 91: taprpc.TaprootAssets.StopDaemon:input_type -> taprpc.StopRequest + 47, // 92: taprpc.TaprootAssets.DebugLevel:input_type -> taprpc.DebugLevelRequest + 50, // 93: taprpc.TaprootAssets.QueryAddrs:input_type -> taprpc.QueryAddrRequest + 52, // 94: taprpc.TaprootAssets.NewAddr:input_type -> taprpc.NewAddrRequest + 60, // 95: taprpc.TaprootAssets.DecodeAddr:input_type -> taprpc.DecodeAddrRequest + 70, // 96: taprpc.TaprootAssets.AddrReceives:input_type -> taprpc.AddrReceivesRequest + 61, // 97: taprpc.TaprootAssets.VerifyProof:input_type -> taprpc.ProofFile + 64, // 98: taprpc.TaprootAssets.DecodeProof:input_type -> taprpc.DecodeProofRequest + 66, // 99: taprpc.TaprootAssets.ExportProof:input_type -> taprpc.ExportProofRequest + 67, // 100: taprpc.TaprootAssets.UnpackProofFile:input_type -> taprpc.UnpackProofFileRequest + 72, // 101: taprpc.TaprootAssets.SendAsset:input_type -> taprpc.SendAssetRequest + 80, // 102: taprpc.TaprootAssets.BurnAsset:input_type -> taprpc.BurnAssetRequest + 82, // 103: taprpc.TaprootAssets.ListBurns:input_type -> taprpc.ListBurnsRequest + 76, // 104: taprpc.TaprootAssets.GetInfo:input_type -> taprpc.GetInfoRequest + 78, // 105: taprpc.TaprootAssets.FetchAssetMeta:input_type -> taprpc.FetchAssetMetaRequest + 85, // 106: taprpc.TaprootAssets.SubscribeReceiveEvents:input_type -> taprpc.SubscribeReceiveEventsRequest + 87, // 107: taprpc.TaprootAssets.SubscribeSendEvents:input_type -> taprpc.SubscribeSendEventsRequest + 90, // 108: taprpc.TaprootAssets.RegisterTransfer:input_type -> taprpc.RegisterTransferRequest + 26, // 109: taprpc.TaprootAssets.ListAssets:output_type -> taprpc.ListAssetResponse + 29, // 110: taprpc.TaprootAssets.ListUtxos:output_type -> taprpc.ListUtxosResponse + 33, // 111: taprpc.TaprootAssets.ListGroups:output_type -> taprpc.ListGroupsResponse + 37, // 112: taprpc.TaprootAssets.ListBalances:output_type -> taprpc.ListBalancesResponse + 39, // 113: taprpc.TaprootAssets.ListTransfers:output_type -> taprpc.ListTransfersResponse + 46, // 114: taprpc.TaprootAssets.StopDaemon:output_type -> taprpc.StopResponse + 48, // 115: taprpc.TaprootAssets.DebugLevel:output_type -> taprpc.DebugLevelResponse + 51, // 116: taprpc.TaprootAssets.QueryAddrs:output_type -> taprpc.QueryAddrResponse + 49, // 117: taprpc.TaprootAssets.NewAddr:output_type -> taprpc.Addr + 49, // 118: taprpc.TaprootAssets.DecodeAddr:output_type -> taprpc.Addr + 71, // 119: taprpc.TaprootAssets.AddrReceives:output_type -> taprpc.AddrReceivesResponse + 63, // 120: taprpc.TaprootAssets.VerifyProof:output_type -> taprpc.VerifyProofResponse + 65, // 121: taprpc.TaprootAssets.DecodeProof:output_type -> taprpc.DecodeProofResponse + 61, // 122: taprpc.TaprootAssets.ExportProof:output_type -> taprpc.ProofFile + 68, // 123: taprpc.TaprootAssets.UnpackProofFile:output_type -> taprpc.UnpackProofFileResponse + 75, // 124: taprpc.TaprootAssets.SendAsset:output_type -> taprpc.SendAssetResponse + 81, // 125: taprpc.TaprootAssets.BurnAsset:output_type -> taprpc.BurnAssetResponse + 84, // 126: taprpc.TaprootAssets.ListBurns:output_type -> taprpc.ListBurnsResponse + 77, // 127: taprpc.TaprootAssets.GetInfo:output_type -> taprpc.GetInfoResponse + 79, // 128: taprpc.TaprootAssets.FetchAssetMeta:output_type -> taprpc.FetchAssetMetaResponse + 86, // 129: taprpc.TaprootAssets.SubscribeReceiveEvents:output_type -> taprpc.ReceiveEvent + 88, // 130: taprpc.TaprootAssets.SubscribeSendEvents:output_type -> taprpc.SendEvent + 91, // 131: taprpc.TaprootAssets.RegisterTransfer:output_type -> taprpc.RegisterTransferResponse + 109, // [109:132] is the sub-list for method output_type + 86, // [86:109] is the sub-list for method input_type + 86, // [86:86] is the sub-list for extension type_name + 86, // [86:86] is the sub-list for extension extendee + 0, // [0:86] is the sub-list for field type_name } func init() { file_taprootassets_proto_init() } diff --git a/taprpc/taprootassets.proto b/taprpc/taprootassets.proto index 05309adc6..f75401827 100644 --- a/taprpc/taprootassets.proto +++ b/taprpc/taprootassets.proto @@ -1528,6 +1528,15 @@ message AddrReceivesRequest { // Filter receives by creation time less than or equal to this timestamp. // If not set, no end time filtering is applied. uint64 end_timestamp = 4; + + // The number of events to skip. + int32 offset = 5; + + // The max number of events returned. + int32 limit = 6; + + // The direction of the page. Sorted by creation time. + SortDirection direction = 7; } message AddrReceivesResponse { @@ -1698,11 +1707,13 @@ message FetchAssetMetaResponse { message BurnAssetRequest { oneof asset { - // The asset ID of the asset to burn units of. - bytes asset_id = 1; + // Deprecated, the asset ID of the asset to burn units of. + // Use asset_specifier instead + bytes asset_id = 1 [deprecated = true]; - // The hex encoded asset ID of the asset to burn units of. - string asset_id_str = 2; + // Deprecated, the hex encoded asset ID of the asset to burn units of. + // Use asset_specifier instead + string asset_id_str = 2 [deprecated = true]; } // The number of asset units to burn. This must be greater than zero. @@ -1715,14 +1726,19 @@ message BurnAssetRequest { // A note that may contain user defined metadata related to this burn. string note = 5; + + // The asset to burn units of. + AssetSpecifier asset_specifier = 6; } message BurnAssetResponse { // The asset transfer that contains the asset burn as an output. AssetTransfer burn_transfer = 1; - // The burn transition proof for the asset burn output. - DecodedProof burn_proof = 2; + reserved 2; + + // The burn transition proofs for the asset burn output. + repeated DecodedProof burn_proofs = 3; } message ListBurnsRequest { diff --git a/taprpc/taprootassets.swagger.json b/taprpc/taprootassets.swagger.json index 5579461bf..318739c26 100644 --- a/taprpc/taprootassets.swagger.json +++ b/taprpc/taprootassets.swagger.json @@ -1298,6 +1298,20 @@ "type": "string", "format": "uint64", "description": "Filter receives by creation time less than or equal to this timestamp.\nIf not set, no end time filtering is applied." + }, + "offset": { + "type": "integer", + "format": "int32", + "description": "The number of events to skip." + }, + "limit": { + "type": "integer", + "format": "int32", + "description": "The max number of events returned." + }, + "direction": { + "$ref": "#/definitions/taprpcSortDirection", + "description": "The direction of the page. Sorted by creation time." } } }, @@ -1670,6 +1684,21 @@ "default": "META_TYPE_OPAQUE", "description": " - META_TYPE_OPAQUE: Opaque is used for asset meta blobs that have no true structure and instead\nshould be interpreted as opaque blobs.\n - META_TYPE_JSON: JSON is used for asset meta blobs that are to be interpreted as valid JSON\nstrings." }, + "taprpcAssetSpecifier": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "byte", + "description": "The 32-byte asset ID specified." + }, + "group_key": { + "type": "string", + "format": "byte", + "description": "The 32-byte asset group key specified." + } + } + }, "taprpcAssetTransfer": { "type": "object", "properties": { @@ -1753,11 +1782,11 @@ "asset_id": { "type": "string", "format": "byte", - "description": "The asset ID of the asset to burn units of." + "title": "Deprecated, the asset ID of the asset to burn units of.\nUse asset_specifier instead" }, "asset_id_str": { "type": "string", - "description": "The hex encoded asset ID of the asset to burn units of." + "title": "Deprecated, the hex encoded asset ID of the asset to burn units of.\nUse asset_specifier instead" }, "amount_to_burn": { "type": "string", @@ -1771,6 +1800,10 @@ "note": { "type": "string", "description": "A note that may contain user defined metadata related to this burn." + }, + "asset_specifier": { + "$ref": "#/definitions/taprpcAssetSpecifier", + "description": "The asset to burn units of." } } }, @@ -1781,9 +1814,13 @@ "$ref": "#/definitions/taprpcAssetTransfer", "description": "The asset transfer that contains the asset burn as an output." }, - "burn_proof": { - "$ref": "#/definitions/taprpcDecodedProof", - "description": "The burn transition proof for the asset burn output." + "burn_proofs": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/taprpcDecodedProof" + }, + "description": "The burn transition proofs for the asset burn output." } } }, @@ -2683,6 +2720,15 @@ } } }, + "taprpcSortDirection": { + "type": "string", + "enum": [ + "SORT_DIRECTION_DESC", + "SORT_DIRECTION_ASC" + ], + "default": "SORT_DIRECTION_DESC", + "description": " - SORT_DIRECTION_DESC: Sort results in descending order.\n - SORT_DIRECTION_ASC: Sort results in ascending order." + }, "taprpcSplitCommitment": { "type": "object", "properties": { diff --git a/taprpc/universerpc/universe.pb.go b/taprpc/universerpc/universe.pb.go index fa656406d..76282a628 100644 --- a/taprpc/universerpc/universe.pb.go +++ b/taprpc/universerpc/universe.pb.go @@ -184,52 +184,6 @@ func (AssetQuerySort) EnumDescriptor() ([]byte, []int) { return file_universerpc_universe_proto_rawDescGZIP(), []int{2} } -type SortDirection int32 - -const ( - SortDirection_SORT_DIRECTION_ASC SortDirection = 0 - SortDirection_SORT_DIRECTION_DESC SortDirection = 1 -) - -// Enum value maps for SortDirection. -var ( - SortDirection_name = map[int32]string{ - 0: "SORT_DIRECTION_ASC", - 1: "SORT_DIRECTION_DESC", - } - SortDirection_value = map[string]int32{ - "SORT_DIRECTION_ASC": 0, - "SORT_DIRECTION_DESC": 1, - } -) - -func (x SortDirection) Enum() *SortDirection { - p := new(SortDirection) - *p = x - return p -} - -func (x SortDirection) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (SortDirection) Descriptor() protoreflect.EnumDescriptor { - return file_universerpc_universe_proto_enumTypes[3].Descriptor() -} - -func (SortDirection) Type() protoreflect.EnumType { - return &file_universerpc_universe_proto_enumTypes[3] -} - -func (x SortDirection) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Use SortDirection.Descriptor instead. -func (SortDirection) EnumDescriptor() ([]byte, []int) { - return file_universerpc_universe_proto_rawDescGZIP(), []int{3} -} - type AssetTypeFilter int32 const ( @@ -263,11 +217,11 @@ func (x AssetTypeFilter) String() string { } func (AssetTypeFilter) Descriptor() protoreflect.EnumDescriptor { - return file_universerpc_universe_proto_enumTypes[4].Descriptor() + return file_universerpc_universe_proto_enumTypes[3].Descriptor() } func (AssetTypeFilter) Type() protoreflect.EnumType { - return &file_universerpc_universe_proto_enumTypes[4] + return &file_universerpc_universe_proto_enumTypes[3] } func (x AssetTypeFilter) Number() protoreflect.EnumNumber { @@ -276,7 +230,7 @@ func (x AssetTypeFilter) Number() protoreflect.EnumNumber { // Deprecated: Use AssetTypeFilter.Descriptor instead. func (AssetTypeFilter) EnumDescriptor() ([]byte, []int) { - return file_universerpc_universe_proto_rawDescGZIP(), []int{4} + return file_universerpc_universe_proto_rawDescGZIP(), []int{3} } type MultiverseRootRequest struct { @@ -400,7 +354,7 @@ type AssetRootRequest struct { // The length limit for the page. Limit int32 `protobuf:"varint,3,opt,name=limit,proto3" json:"limit,omitempty"` // The direction of the page. - Direction SortDirection `protobuf:"varint,4,opt,name=direction,proto3,enum=universerpc.SortDirection" json:"direction,omitempty"` + Direction taprpc.SortDirection `protobuf:"varint,4,opt,name=direction,proto3,enum=taprpc.SortDirection" json:"direction,omitempty"` } func (x *AssetRootRequest) Reset() { @@ -456,11 +410,11 @@ func (x *AssetRootRequest) GetLimit() int32 { return 0 } -func (x *AssetRootRequest) GetDirection() SortDirection { +func (x *AssetRootRequest) GetDirection() taprpc.SortDirection { if x != nil { return x.Direction } - return SortDirection_SORT_DIRECTION_ASC + return taprpc.SortDirection(0) } type MerkleSumNode struct { @@ -1163,7 +1117,7 @@ type AssetLeafKeysRequest struct { // The length limit for the page. Limit int32 `protobuf:"varint,3,opt,name=limit,proto3" json:"limit,omitempty"` // The direction of the page. - Direction SortDirection `protobuf:"varint,4,opt,name=direction,proto3,enum=universerpc.SortDirection" json:"direction,omitempty"` + Direction taprpc.SortDirection `protobuf:"varint,4,opt,name=direction,proto3,enum=taprpc.SortDirection" json:"direction,omitempty"` } func (x *AssetLeafKeysRequest) Reset() { @@ -1219,11 +1173,11 @@ func (x *AssetLeafKeysRequest) GetLimit() int32 { return 0 } -func (x *AssetLeafKeysRequest) GetDirection() SortDirection { +func (x *AssetLeafKeysRequest) GetDirection() taprpc.SortDirection { if x != nil { return x.Direction } - return SortDirection_SORT_DIRECTION_ASC + return taprpc.SortDirection(0) } type AssetLeafKeyResponse struct { @@ -2543,7 +2497,7 @@ type AssetStatsQuery struct { // The direction of the sort. If this is set to SORT_DIRECTION_ASC, then // the results are sorted in ascending order. If set to // SORT_DIRECTION_DESC, then the results are sorted in descending order. - Direction SortDirection `protobuf:"varint,7,opt,name=direction,proto3,enum=universerpc.SortDirection" json:"direction,omitempty"` + Direction taprpc.SortDirection `protobuf:"varint,7,opt,name=direction,proto3,enum=taprpc.SortDirection" json:"direction,omitempty"` } func (x *AssetStatsQuery) Reset() { @@ -2620,11 +2574,11 @@ func (x *AssetStatsQuery) GetLimit() int32 { return 0 } -func (x *AssetStatsQuery) GetDirection() SortDirection { +func (x *AssetStatsQuery) GetDirection() taprpc.SortDirection { if x != nil { return x.Direction } - return SortDirection_SORT_DIRECTION_ASC + return taprpc.SortDirection(0) } type AssetStatsSnapshot struct { @@ -4848,835 +4802,830 @@ var file_universerpc_universe_proto_rawDesc = []byte{ 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x4d, 0x65, 0x72, 0x6b, 0x6c, 0x65, 0x53, 0x75, 0x6d, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x0e, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x52, - 0x6f, 0x6f, 0x74, 0x22, 0xa7, 0x01, 0x0a, 0x10, 0x41, 0x73, 0x73, 0x65, 0x74, 0x52, 0x6f, 0x6f, + 0x6f, 0x6f, 0x74, 0x22, 0xa2, 0x01, 0x0a, 0x10, 0x41, 0x73, 0x73, 0x65, 0x74, 0x52, 0x6f, 0x6f, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2b, 0x0a, 0x12, 0x77, 0x69, 0x74, 0x68, 0x5f, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x5f, 0x62, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x77, 0x69, 0x74, 0x68, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x42, 0x79, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x6c, 0x69, - 0x6d, 0x69, 0x74, 0x12, 0x38, 0x0a, 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, - 0x65, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x6f, 0x72, 0x74, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x52, 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x47, 0x0a, - 0x0d, 0x4d, 0x65, 0x72, 0x6b, 0x6c, 0x65, 0x53, 0x75, 0x6d, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x1b, - 0x0a, 0x09, 0x72, 0x6f, 0x6f, 0x74, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x08, 0x72, 0x6f, 0x6f, 0x74, 0x48, 0x61, 0x73, 0x68, 0x12, 0x19, 0x0a, 0x08, 0x72, - 0x6f, 0x6f, 0x74, 0x5f, 0x73, 0x75, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x72, - 0x6f, 0x6f, 0x74, 0x53, 0x75, 0x6d, 0x22, 0xc7, 0x01, 0x0a, 0x02, 0x49, 0x44, 0x12, 0x1b, 0x0a, - 0x08, 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x48, - 0x00, 0x52, 0x07, 0x61, 0x73, 0x73, 0x65, 0x74, 0x49, 0x64, 0x12, 0x22, 0x0a, 0x0c, 0x61, 0x73, - 0x73, 0x65, 0x74, 0x5f, 0x69, 0x64, 0x5f, 0x73, 0x74, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x48, 0x00, 0x52, 0x0a, 0x61, 0x73, 0x73, 0x65, 0x74, 0x49, 0x64, 0x53, 0x74, 0x72, 0x12, 0x1d, - 0x0a, 0x09, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x0c, 0x48, 0x00, 0x52, 0x08, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x4b, 0x65, 0x79, 0x12, 0x24, 0x0a, - 0x0d, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x73, 0x74, 0x72, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0b, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x4b, 0x65, 0x79, - 0x53, 0x74, 0x72, 0x12, 0x35, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x5f, 0x74, 0x79, 0x70, - 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, - 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x54, 0x79, 0x70, 0x65, 0x52, - 0x09, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x54, 0x79, 0x70, 0x65, 0x42, 0x04, 0x0a, 0x02, 0x69, 0x64, - 0x22, 0xae, 0x02, 0x0a, 0x0c, 0x55, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x52, 0x6f, 0x6f, - 0x74, 0x12, 0x1f, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, - 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x44, 0x52, 0x02, - 0x69, 0x64, 0x12, 0x39, 0x0a, 0x0a, 0x6d, 0x73, 0x73, 0x6d, 0x74, 0x5f, 0x72, 0x6f, 0x6f, 0x74, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, - 0x65, 0x72, 0x70, 0x63, 0x2e, 0x4d, 0x65, 0x72, 0x6b, 0x6c, 0x65, 0x53, 0x75, 0x6d, 0x4e, 0x6f, - 0x64, 0x65, 0x52, 0x09, 0x6d, 0x73, 0x73, 0x6d, 0x74, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x1d, 0x0a, - 0x0a, 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x09, 0x61, 0x73, 0x73, 0x65, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x5e, 0x0a, 0x13, - 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x5f, 0x62, 0x79, 0x5f, 0x61, 0x73, 0x73, 0x65, 0x74, - 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x75, 0x6e, 0x69, 0x76, - 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x55, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, - 0x52, 0x6f, 0x6f, 0x74, 0x2e, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x42, 0x79, 0x41, 0x73, - 0x73, 0x65, 0x74, 0x49, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x10, 0x61, 0x6d, 0x6f, 0x75, - 0x6e, 0x74, 0x73, 0x42, 0x79, 0x41, 0x73, 0x73, 0x65, 0x74, 0x49, 0x64, 0x1a, 0x43, 0x0a, 0x15, + 0x6d, 0x69, 0x74, 0x12, 0x33, 0x0a, 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, + 0x53, 0x6f, 0x72, 0x74, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x09, 0x64, + 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x47, 0x0a, 0x0d, 0x4d, 0x65, 0x72, 0x6b, + 0x6c, 0x65, 0x53, 0x75, 0x6d, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x72, 0x6f, 0x6f, + 0x74, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x72, 0x6f, + 0x6f, 0x74, 0x48, 0x61, 0x73, 0x68, 0x12, 0x19, 0x0a, 0x08, 0x72, 0x6f, 0x6f, 0x74, 0x5f, 0x73, + 0x75, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x72, 0x6f, 0x6f, 0x74, 0x53, 0x75, + 0x6d, 0x22, 0xc7, 0x01, 0x0a, 0x02, 0x49, 0x44, 0x12, 0x1b, 0x0a, 0x08, 0x61, 0x73, 0x73, 0x65, + 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x07, 0x61, 0x73, + 0x73, 0x65, 0x74, 0x49, 0x64, 0x12, 0x22, 0x0a, 0x0c, 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x69, + 0x64, 0x5f, 0x73, 0x74, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0a, 0x61, + 0x73, 0x73, 0x65, 0x74, 0x49, 0x64, 0x53, 0x74, 0x72, 0x12, 0x1d, 0x0a, 0x09, 0x67, 0x72, 0x6f, + 0x75, 0x70, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x08, + 0x67, 0x72, 0x6f, 0x75, 0x70, 0x4b, 0x65, 0x79, 0x12, 0x24, 0x0a, 0x0d, 0x67, 0x72, 0x6f, 0x75, + 0x70, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x73, 0x74, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x48, + 0x00, 0x52, 0x0b, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x4b, 0x65, 0x79, 0x53, 0x74, 0x72, 0x12, 0x35, + 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, + 0x2e, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x54, 0x79, 0x70, 0x65, 0x52, 0x09, 0x70, 0x72, 0x6f, 0x6f, + 0x66, 0x54, 0x79, 0x70, 0x65, 0x42, 0x04, 0x0a, 0x02, 0x69, 0x64, 0x22, 0xae, 0x02, 0x0a, 0x0c, + 0x55, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x1f, 0x0a, 0x02, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, + 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x44, 0x52, 0x02, 0x69, 0x64, 0x12, 0x39, 0x0a, + 0x0a, 0x6d, 0x73, 0x73, 0x6d, 0x74, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1a, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, + 0x4d, 0x65, 0x72, 0x6b, 0x6c, 0x65, 0x53, 0x75, 0x6d, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x09, 0x6d, + 0x73, 0x73, 0x6d, 0x74, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x73, 0x73, 0x65, + 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x73, + 0x73, 0x65, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x5e, 0x0a, 0x13, 0x61, 0x6d, 0x6f, 0x75, 0x6e, + 0x74, 0x73, 0x5f, 0x62, 0x79, 0x5f, 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x05, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, + 0x70, 0x63, 0x2e, 0x55, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x2e, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x42, 0x79, 0x41, 0x73, 0x73, 0x65, 0x74, 0x49, 0x64, - 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, - 0x01, 0x22, 0xca, 0x01, 0x0a, 0x11, 0x41, 0x73, 0x73, 0x65, 0x74, 0x52, 0x6f, 0x6f, 0x74, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x58, 0x0a, 0x0e, 0x75, 0x6e, 0x69, 0x76, 0x65, - 0x72, 0x73, 0x65, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x31, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x73, - 0x73, 0x65, 0x74, 0x52, 0x6f, 0x6f, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, + 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x10, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x42, 0x79, + 0x41, 0x73, 0x73, 0x65, 0x74, 0x49, 0x64, 0x1a, 0x43, 0x0a, 0x15, 0x41, 0x6d, 0x6f, 0x75, 0x6e, + 0x74, 0x73, 0x42, 0x79, 0x41, 0x73, 0x73, 0x65, 0x74, 0x49, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, + 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, + 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x04, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xca, 0x01, 0x0a, + 0x11, 0x41, 0x73, 0x73, 0x65, 0x74, 0x52, 0x6f, 0x6f, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x58, 0x0a, 0x0e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x5f, 0x72, + 0x6f, 0x6f, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x75, 0x6e, 0x69, + 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x73, 0x73, 0x65, 0x74, 0x52, 0x6f, + 0x6f, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x55, 0x6e, 0x69, 0x76, 0x65, + 0x72, 0x73, 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0d, 0x75, + 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x73, 0x1a, 0x5b, 0x0a, 0x12, 0x55, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x73, 0x45, 0x6e, 0x74, - 0x72, 0x79, 0x52, 0x0d, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x52, 0x6f, 0x6f, 0x74, - 0x73, 0x1a, 0x5b, 0x0a, 0x12, 0x55, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x52, 0x6f, 0x6f, - 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2f, 0x0a, 0x05, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, - 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x55, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x52, - 0x6f, 0x6f, 0x74, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x31, - 0x0a, 0x0e, 0x41, 0x73, 0x73, 0x65, 0x74, 0x52, 0x6f, 0x6f, 0x74, 0x51, 0x75, 0x65, 0x72, 0x79, - 0x12, 0x1f, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x75, - 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x44, 0x52, 0x02, 0x69, - 0x64, 0x22, 0x93, 0x01, 0x0a, 0x11, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x6f, 0x6f, 0x74, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3e, 0x0a, 0x0d, 0x69, 0x73, 0x73, 0x75, 0x61, - 0x6e, 0x63, 0x65, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, - 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x55, 0x6e, 0x69, - 0x76, 0x65, 0x72, 0x73, 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x52, 0x0c, 0x69, 0x73, 0x73, 0x75, 0x61, - 0x6e, 0x63, 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x3e, 0x0a, 0x0d, 0x74, 0x72, 0x61, 0x6e, 0x73, - 0x66, 0x65, 0x72, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, + 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2f, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, + 0x63, 0x2e, 0x55, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x52, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x31, 0x0a, 0x0e, 0x41, 0x73, 0x73, + 0x65, 0x74, 0x52, 0x6f, 0x6f, 0x74, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x1f, 0x0a, 0x02, 0x69, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, + 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x44, 0x52, 0x02, 0x69, 0x64, 0x22, 0x93, 0x01, 0x0a, + 0x11, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x6f, 0x6f, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x3e, 0x0a, 0x0d, 0x69, 0x73, 0x73, 0x75, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x72, + 0x6f, 0x6f, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x75, 0x6e, 0x69, 0x76, + 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x55, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, + 0x52, 0x6f, 0x6f, 0x74, 0x52, 0x0c, 0x69, 0x73, 0x73, 0x75, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x6f, + 0x6f, 0x74, 0x12, 0x3e, 0x0a, 0x0d, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x5f, 0x72, + 0x6f, 0x6f, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x75, 0x6e, 0x69, 0x76, + 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x55, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, + 0x52, 0x6f, 0x6f, 0x74, 0x52, 0x0c, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x52, 0x6f, + 0x6f, 0x74, 0x22, 0x32, 0x0a, 0x0f, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x6f, 0x6f, 0x74, + 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x1f, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x0f, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, + 0x49, 0x44, 0x52, 0x02, 0x69, 0x64, 0x22, 0x14, 0x0a, 0x12, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, + 0x52, 0x6f, 0x6f, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x3b, 0x0a, 0x08, + 0x4f, 0x75, 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x68, 0x61, 0x73, 0x68, + 0x5f, 0x73, 0x74, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x68, 0x61, 0x73, 0x68, + 0x53, 0x74, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x05, 0x52, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x22, 0xba, 0x01, 0x0a, 0x08, 0x41, 0x73, + 0x73, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x12, 0x17, 0x0a, 0x06, 0x6f, 0x70, 0x5f, 0x73, 0x74, 0x72, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x05, 0x6f, 0x70, 0x53, 0x74, 0x72, 0x12, + 0x27, 0x0a, 0x02, 0x6f, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x75, 0x6e, + 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x4f, 0x75, 0x74, 0x70, 0x6f, 0x69, + 0x6e, 0x74, 0x48, 0x00, 0x52, 0x02, 0x6f, 0x70, 0x12, 0x2a, 0x0a, 0x10, 0x73, 0x63, 0x72, 0x69, + 0x70, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0c, 0x48, 0x01, 0x52, 0x0e, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x4b, 0x65, 0x79, 0x42, + 0x79, 0x74, 0x65, 0x73, 0x12, 0x26, 0x0a, 0x0e, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x5f, 0x6b, + 0x65, 0x79, 0x5f, 0x73, 0x74, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x48, 0x01, 0x52, 0x0c, + 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x4b, 0x65, 0x79, 0x53, 0x74, 0x72, 0x42, 0x0a, 0x0a, 0x08, + 0x6f, 0x75, 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x42, 0x0c, 0x0a, 0x0a, 0x73, 0x63, 0x72, 0x69, + 0x70, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x22, 0x9a, 0x01, 0x0a, 0x14, 0x41, 0x73, 0x73, 0x65, 0x74, + 0x4c, 0x65, 0x61, 0x66, 0x4b, 0x65, 0x79, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x1f, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x75, 0x6e, + 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x44, 0x52, 0x02, 0x69, 0x64, + 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, + 0x52, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, + 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x33, + 0x0a, 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x0e, 0x32, 0x15, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x6f, 0x72, 0x74, 0x44, + 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x22, 0x4c, 0x0a, 0x14, 0x41, 0x73, 0x73, 0x65, 0x74, 0x4c, 0x65, 0x61, 0x66, + 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x34, 0x0a, 0x0a, 0x61, + 0x73, 0x73, 0x65, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x15, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x73, + 0x73, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x52, 0x09, 0x61, 0x73, 0x73, 0x65, 0x74, 0x4b, 0x65, 0x79, + 0x73, 0x22, 0x46, 0x0a, 0x09, 0x41, 0x73, 0x73, 0x65, 0x74, 0x4c, 0x65, 0x61, 0x66, 0x12, 0x23, + 0x0a, 0x05, 0x61, 0x73, 0x73, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, + 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x73, 0x73, 0x65, 0x74, 0x52, 0x05, 0x61, 0x73, + 0x73, 0x65, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x05, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x22, 0x43, 0x0a, 0x11, 0x41, 0x73, 0x73, + 0x65, 0x74, 0x4c, 0x65, 0x61, 0x66, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2e, + 0x0a, 0x06, 0x6c, 0x65, 0x61, 0x76, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, + 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x73, 0x73, + 0x65, 0x74, 0x4c, 0x65, 0x61, 0x66, 0x52, 0x06, 0x6c, 0x65, 0x61, 0x76, 0x65, 0x73, 0x22, 0x60, + 0x0a, 0x0b, 0x55, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x1f, 0x0a, + 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x75, 0x6e, 0x69, 0x76, + 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x44, 0x52, 0x02, 0x69, 0x64, 0x12, 0x30, + 0x0a, 0x08, 0x6c, 0x65, 0x61, 0x66, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x15, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x41, + 0x73, 0x73, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x52, 0x07, 0x6c, 0x65, 0x61, 0x66, 0x4b, 0x65, 0x79, + 0x22, 0xb4, 0x03, 0x0a, 0x12, 0x41, 0x73, 0x73, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2a, 0x0a, 0x03, 0x72, 0x65, 0x71, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, + 0x70, 0x63, 0x2e, 0x55, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x4b, 0x65, 0x79, 0x52, 0x03, + 0x72, 0x65, 0x71, 0x12, 0x3e, 0x0a, 0x0d, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x5f, + 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x75, 0x6e, 0x69, + 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x55, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, + 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x52, 0x0c, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x52, + 0x6f, 0x6f, 0x74, 0x12, 0x38, 0x0a, 0x18, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x5f, + 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x16, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x49, + 0x6e, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x12, 0x35, 0x0a, + 0x0a, 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x6c, 0x65, 0x61, 0x66, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x16, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, + 0x41, 0x73, 0x73, 0x65, 0x74, 0x4c, 0x65, 0x61, 0x66, 0x52, 0x09, 0x61, 0x73, 0x73, 0x65, 0x74, + 0x4c, 0x65, 0x61, 0x66, 0x12, 0x43, 0x0a, 0x0f, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x76, 0x65, 0x72, + 0x73, 0x65, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, + 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x4d, 0x65, 0x72, 0x6b, + 0x6c, 0x65, 0x53, 0x75, 0x6d, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x0e, 0x6d, 0x75, 0x6c, 0x74, 0x69, + 0x76, 0x65, 0x72, 0x73, 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x3c, 0x0a, 0x1a, 0x6d, 0x75, 0x6c, + 0x74, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x5f, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x6f, + 0x6e, 0x5f, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x18, 0x6d, + 0x75, 0x6c, 0x74, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x73, 0x69, + 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x12, 0x3e, 0x0a, 0x0d, 0x69, 0x73, 0x73, 0x75, 0x61, + 0x6e, 0x63, 0x65, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, + 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x73, 0x73, + 0x75, 0x61, 0x6e, 0x63, 0x65, 0x44, 0x61, 0x74, 0x61, 0x52, 0x0c, 0x69, 0x73, 0x73, 0x75, 0x61, + 0x6e, 0x63, 0x65, 0x44, 0x61, 0x74, 0x61, 0x22, 0xc2, 0x01, 0x0a, 0x0c, 0x49, 0x73, 0x73, 0x75, + 0x61, 0x6e, 0x63, 0x65, 0x44, 0x61, 0x74, 0x61, 0x12, 0x32, 0x0a, 0x0b, 0x6d, 0x65, 0x74, 0x61, + 0x5f, 0x72, 0x65, 0x76, 0x65, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, + 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x73, 0x73, 0x65, 0x74, 0x4d, 0x65, 0x74, 0x61, + 0x52, 0x0a, 0x6d, 0x65, 0x74, 0x61, 0x52, 0x65, 0x76, 0x65, 0x61, 0x6c, 0x12, 0x3c, 0x0a, 0x0e, + 0x67, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x5f, 0x72, 0x65, 0x76, 0x65, 0x61, 0x6c, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x65, + 0x6e, 0x65, 0x73, 0x69, 0x73, 0x52, 0x65, 0x76, 0x65, 0x61, 0x6c, 0x52, 0x0d, 0x67, 0x65, 0x6e, + 0x65, 0x73, 0x69, 0x73, 0x52, 0x65, 0x76, 0x65, 0x61, 0x6c, 0x12, 0x40, 0x0a, 0x10, 0x67, 0x72, + 0x6f, 0x75, 0x70, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x72, 0x65, 0x76, 0x65, 0x61, 0x6c, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x72, + 0x6f, 0x75, 0x70, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x76, 0x65, 0x61, 0x6c, 0x52, 0x0e, 0x67, 0x72, + 0x6f, 0x75, 0x70, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x76, 0x65, 0x61, 0x6c, 0x22, 0x6f, 0x0a, 0x0a, + 0x41, 0x73, 0x73, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x12, 0x2a, 0x0a, 0x03, 0x6b, 0x65, + 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, + 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x55, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x4b, 0x65, + 0x79, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x35, 0x0a, 0x0a, 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, + 0x6c, 0x65, 0x61, 0x66, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x75, 0x6e, 0x69, + 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x73, 0x73, 0x65, 0x74, 0x4c, 0x65, + 0x61, 0x66, 0x52, 0x09, 0x61, 0x73, 0x73, 0x65, 0x74, 0x4c, 0x65, 0x61, 0x66, 0x22, 0x7d, 0x0a, + 0x10, 0x50, 0x75, 0x73, 0x68, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x2a, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x55, 0x6e, 0x69, - 0x76, 0x65, 0x72, 0x73, 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x52, 0x0c, 0x74, 0x72, 0x61, 0x6e, 0x73, - 0x66, 0x65, 0x72, 0x52, 0x6f, 0x6f, 0x74, 0x22, 0x32, 0x0a, 0x0f, 0x44, 0x65, 0x6c, 0x65, 0x74, - 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x1f, 0x0a, 0x02, 0x69, 0x64, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, - 0x65, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x44, 0x52, 0x02, 0x69, 0x64, 0x22, 0x14, 0x0a, 0x12, 0x44, - 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x3b, 0x0a, 0x08, 0x4f, 0x75, 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x19, 0x0a, - 0x08, 0x68, 0x61, 0x73, 0x68, 0x5f, 0x73, 0x74, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x07, 0x68, 0x61, 0x73, 0x68, 0x53, 0x74, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6e, 0x64, 0x65, - 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x22, 0xba, - 0x01, 0x0a, 0x08, 0x41, 0x73, 0x73, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x12, 0x17, 0x0a, 0x06, 0x6f, - 0x70, 0x5f, 0x73, 0x74, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x05, 0x6f, - 0x70, 0x53, 0x74, 0x72, 0x12, 0x27, 0x0a, 0x02, 0x6f, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x15, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x4f, - 0x75, 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x02, 0x6f, 0x70, 0x12, 0x2a, 0x0a, - 0x10, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x62, 0x79, 0x74, 0x65, - 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x01, 0x52, 0x0e, 0x73, 0x63, 0x72, 0x69, 0x70, - 0x74, 0x4b, 0x65, 0x79, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x26, 0x0a, 0x0e, 0x73, 0x63, 0x72, - 0x69, 0x70, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x73, 0x74, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x09, 0x48, 0x01, 0x52, 0x0c, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x4b, 0x65, 0x79, 0x53, 0x74, - 0x72, 0x42, 0x0a, 0x0a, 0x08, 0x6f, 0x75, 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x42, 0x0c, 0x0a, - 0x0a, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x22, 0x9f, 0x01, 0x0a, 0x14, - 0x41, 0x73, 0x73, 0x65, 0x74, 0x4c, 0x65, 0x61, 0x66, 0x4b, 0x65, 0x79, 0x73, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x0f, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x49, - 0x44, 0x52, 0x02, 0x69, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x14, 0x0a, - 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x6c, 0x69, - 0x6d, 0x69, 0x74, 0x12, 0x38, 0x0a, 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, - 0x65, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x6f, 0x72, 0x74, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x52, 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x4c, 0x0a, - 0x14, 0x41, 0x73, 0x73, 0x65, 0x74, 0x4c, 0x65, 0x61, 0x66, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x34, 0x0a, 0x0a, 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x6b, - 0x65, 0x79, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x75, 0x6e, 0x69, 0x76, - 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x73, 0x73, 0x65, 0x74, 0x4b, 0x65, 0x79, - 0x52, 0x09, 0x61, 0x73, 0x73, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x22, 0x46, 0x0a, 0x09, 0x41, - 0x73, 0x73, 0x65, 0x74, 0x4c, 0x65, 0x61, 0x66, 0x12, 0x23, 0x0a, 0x05, 0x61, 0x73, 0x73, 0x65, - 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, - 0x2e, 0x41, 0x73, 0x73, 0x65, 0x74, 0x52, 0x05, 0x61, 0x73, 0x73, 0x65, 0x74, 0x12, 0x14, 0x0a, - 0x05, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x70, 0x72, - 0x6f, 0x6f, 0x66, 0x22, 0x43, 0x0a, 0x11, 0x41, 0x73, 0x73, 0x65, 0x74, 0x4c, 0x65, 0x61, 0x66, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2e, 0x0a, 0x06, 0x6c, 0x65, 0x61, 0x76, - 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, - 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x73, 0x73, 0x65, 0x74, 0x4c, 0x65, 0x61, 0x66, - 0x52, 0x06, 0x6c, 0x65, 0x61, 0x76, 0x65, 0x73, 0x22, 0x60, 0x0a, 0x0b, 0x55, 0x6e, 0x69, 0x76, - 0x65, 0x72, 0x73, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x1f, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, - 0x63, 0x2e, 0x49, 0x44, 0x52, 0x02, 0x69, 0x64, 0x12, 0x30, 0x0a, 0x08, 0x6c, 0x65, 0x61, 0x66, - 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x75, 0x6e, 0x69, - 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x73, 0x73, 0x65, 0x74, 0x4b, 0x65, - 0x79, 0x52, 0x07, 0x6c, 0x65, 0x61, 0x66, 0x4b, 0x65, 0x79, 0x22, 0xb4, 0x03, 0x0a, 0x12, 0x41, - 0x73, 0x73, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x2a, 0x0a, 0x03, 0x72, 0x65, 0x71, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, + 0x76, 0x65, 0x72, 0x73, 0x65, 0x4b, 0x65, 0x79, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x3d, 0x0a, + 0x06, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, + 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x55, 0x6e, 0x69, 0x76, + 0x65, 0x72, 0x73, 0x65, 0x46, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x52, 0x06, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x22, 0x3f, 0x0a, 0x11, + 0x50, 0x75, 0x73, 0x68, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x2a, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x55, 0x6e, 0x69, - 0x76, 0x65, 0x72, 0x73, 0x65, 0x4b, 0x65, 0x79, 0x52, 0x03, 0x72, 0x65, 0x71, 0x12, 0x3e, 0x0a, - 0x0d, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, - 0x70, 0x63, 0x2e, 0x55, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x52, - 0x0c, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x38, 0x0a, - 0x18, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x5f, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x73, - 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x16, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x73, 0x69, - 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x12, 0x35, 0x0a, 0x0a, 0x61, 0x73, 0x73, 0x65, 0x74, - 0x5f, 0x6c, 0x65, 0x61, 0x66, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x75, 0x6e, - 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x73, 0x73, 0x65, 0x74, 0x4c, - 0x65, 0x61, 0x66, 0x52, 0x09, 0x61, 0x73, 0x73, 0x65, 0x74, 0x4c, 0x65, 0x61, 0x66, 0x12, 0x43, - 0x0a, 0x0f, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x5f, 0x72, 0x6f, 0x6f, - 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, - 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x4d, 0x65, 0x72, 0x6b, 0x6c, 0x65, 0x53, 0x75, 0x6d, 0x4e, - 0x6f, 0x64, 0x65, 0x52, 0x0e, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x52, - 0x6f, 0x6f, 0x74, 0x12, 0x3c, 0x0a, 0x1a, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x76, 0x65, 0x72, 0x73, - 0x65, 0x5f, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x72, 0x6f, 0x6f, - 0x66, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x18, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x76, 0x65, - 0x72, 0x73, 0x65, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x6f, - 0x66, 0x12, 0x3e, 0x0a, 0x0d, 0x69, 0x73, 0x73, 0x75, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x64, 0x61, - 0x74, 0x61, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, - 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x73, 0x73, 0x75, 0x61, 0x6e, 0x63, 0x65, 0x44, - 0x61, 0x74, 0x61, 0x52, 0x0c, 0x69, 0x73, 0x73, 0x75, 0x61, 0x6e, 0x63, 0x65, 0x44, 0x61, 0x74, - 0x61, 0x22, 0xc2, 0x01, 0x0a, 0x0c, 0x49, 0x73, 0x73, 0x75, 0x61, 0x6e, 0x63, 0x65, 0x44, 0x61, - 0x74, 0x61, 0x12, 0x32, 0x0a, 0x0b, 0x6d, 0x65, 0x74, 0x61, 0x5f, 0x72, 0x65, 0x76, 0x65, 0x61, - 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, - 0x2e, 0x41, 0x73, 0x73, 0x65, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x52, 0x0a, 0x6d, 0x65, 0x74, 0x61, - 0x52, 0x65, 0x76, 0x65, 0x61, 0x6c, 0x12, 0x3c, 0x0a, 0x0e, 0x67, 0x65, 0x6e, 0x65, 0x73, 0x69, - 0x73, 0x5f, 0x72, 0x65, 0x76, 0x65, 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, - 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x52, - 0x65, 0x76, 0x65, 0x61, 0x6c, 0x52, 0x0d, 0x67, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x52, 0x65, - 0x76, 0x65, 0x61, 0x6c, 0x12, 0x40, 0x0a, 0x10, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x6b, 0x65, - 0x79, 0x5f, 0x72, 0x65, 0x76, 0x65, 0x61, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, - 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x4b, 0x65, 0x79, - 0x52, 0x65, 0x76, 0x65, 0x61, 0x6c, 0x52, 0x0e, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x4b, 0x65, 0x79, - 0x52, 0x65, 0x76, 0x65, 0x61, 0x6c, 0x22, 0x6f, 0x0a, 0x0a, 0x41, 0x73, 0x73, 0x65, 0x74, 0x50, - 0x72, 0x6f, 0x6f, 0x66, 0x12, 0x2a, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x18, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, - 0x55, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x4b, 0x65, 0x79, 0x52, 0x03, 0x6b, 0x65, 0x79, - 0x12, 0x35, 0x0a, 0x0a, 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x6c, 0x65, 0x61, 0x66, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, - 0x70, 0x63, 0x2e, 0x41, 0x73, 0x73, 0x65, 0x74, 0x4c, 0x65, 0x61, 0x66, 0x52, 0x09, 0x61, 0x73, - 0x73, 0x65, 0x74, 0x4c, 0x65, 0x61, 0x66, 0x22, 0x7d, 0x0a, 0x10, 0x50, 0x75, 0x73, 0x68, 0x50, - 0x72, 0x6f, 0x6f, 0x66, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2a, 0x0a, 0x03, 0x6b, - 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, - 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x55, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x4b, - 0x65, 0x79, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x3d, 0x0a, 0x06, 0x73, 0x65, 0x72, 0x76, 0x65, - 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x73, 0x65, 0x4b, 0x65, 0x79, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x22, 0x0d, 0x0a, + 0x0b, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x2d, 0x0a, 0x0c, + 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, + 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, + 0x52, 0x09, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x49, 0x64, 0x22, 0x2d, 0x0a, 0x0a, 0x53, + 0x79, 0x6e, 0x63, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x1f, 0x0a, 0x02, 0x69, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, + 0x72, 0x70, 0x63, 0x2e, 0x49, 0x44, 0x52, 0x02, 0x69, 0x64, 0x22, 0xaa, 0x01, 0x0a, 0x0b, 0x53, + 0x79, 0x6e, 0x63, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x23, 0x0a, 0x0d, 0x75, 0x6e, + 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x5f, 0x68, 0x6f, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0c, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x48, 0x6f, 0x73, 0x74, 0x12, + 0x3a, 0x0a, 0x09, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0e, 0x32, 0x1d, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, + 0x2e, 0x55, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x53, 0x79, 0x6e, 0x63, 0x4d, 0x6f, 0x64, + 0x65, 0x52, 0x08, 0x73, 0x79, 0x6e, 0x63, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x3a, 0x0a, 0x0c, 0x73, + 0x79, 0x6e, 0x63, 0x5f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x17, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, + 0x53, 0x79, 0x6e, 0x63, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x0b, 0x73, 0x79, 0x6e, 0x63, + 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x73, 0x22, 0xd4, 0x01, 0x0a, 0x0e, 0x53, 0x79, 0x6e, 0x63, + 0x65, 0x64, 0x55, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x12, 0x3f, 0x0a, 0x0e, 0x6f, 0x6c, + 0x64, 0x5f, 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, + 0x2e, 0x55, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x52, 0x0c, 0x6f, + 0x6c, 0x64, 0x41, 0x73, 0x73, 0x65, 0x74, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x3f, 0x0a, 0x0e, 0x6e, + 0x65, 0x77, 0x5f, 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, + 0x63, 0x2e, 0x55, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x52, 0x0c, + 0x6e, 0x65, 0x77, 0x41, 0x73, 0x73, 0x65, 0x74, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x40, 0x0a, 0x10, + 0x6e, 0x65, 0x77, 0x5f, 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x6c, 0x65, 0x61, 0x76, 0x65, 0x73, + 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, + 0x65, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x73, 0x73, 0x65, 0x74, 0x4c, 0x65, 0x61, 0x66, 0x52, 0x0e, + 0x6e, 0x65, 0x77, 0x41, 0x73, 0x73, 0x65, 0x74, 0x4c, 0x65, 0x61, 0x76, 0x65, 0x73, 0x22, 0x0e, + 0x0a, 0x0c, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x56, + 0x0a, 0x0c, 0x53, 0x79, 0x6e, 0x63, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x46, + 0x0a, 0x10, 0x73, 0x79, 0x6e, 0x63, 0x65, 0x64, 0x5f, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, + 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, + 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x65, 0x64, 0x55, 0x6e, 0x69, + 0x76, 0x65, 0x72, 0x73, 0x65, 0x52, 0x0f, 0x73, 0x79, 0x6e, 0x63, 0x65, 0x64, 0x55, 0x6e, 0x69, + 0x76, 0x65, 0x72, 0x73, 0x65, 0x73, 0x22, 0x3e, 0x0a, 0x18, 0x55, 0x6e, 0x69, 0x76, 0x65, 0x72, + 0x73, 0x65, 0x46, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x6f, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x68, 0x6f, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x05, 0x52, 0x02, 0x69, 0x64, 0x22, 0x1e, 0x0a, 0x1c, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x65, + 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x60, 0x0a, 0x1d, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x65, + 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3f, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, + 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x55, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x46, + 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, + 0x07, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x22, 0x5d, 0x0a, 0x1a, 0x41, 0x64, 0x64, 0x46, + 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x55, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x46, 0x65, - 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x06, - 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x22, 0x3f, 0x0a, 0x11, 0x50, 0x75, 0x73, 0x68, 0x50, 0x72, - 0x6f, 0x6f, 0x66, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2a, 0x0a, 0x03, 0x6b, - 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, - 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x55, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x4b, - 0x65, 0x79, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x22, 0x0d, 0x0a, 0x0b, 0x49, 0x6e, 0x66, 0x6f, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x2d, 0x0a, 0x0c, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, - 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x72, 0x75, 0x6e, 0x74, - 0x69, 0x6d, 0x65, 0x49, 0x64, 0x22, 0x2d, 0x0a, 0x0a, 0x53, 0x79, 0x6e, 0x63, 0x54, 0x61, 0x72, - 0x67, 0x65, 0x74, 0x12, 0x1f, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x0f, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x44, - 0x52, 0x02, 0x69, 0x64, 0x22, 0xaa, 0x01, 0x0a, 0x0b, 0x53, 0x79, 0x6e, 0x63, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x23, 0x0a, 0x0d, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, - 0x5f, 0x68, 0x6f, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x75, 0x6e, 0x69, - 0x76, 0x65, 0x72, 0x73, 0x65, 0x48, 0x6f, 0x73, 0x74, 0x12, 0x3a, 0x0a, 0x09, 0x73, 0x79, 0x6e, - 0x63, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1d, 0x2e, 0x75, - 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x55, 0x6e, 0x69, 0x76, 0x65, - 0x72, 0x73, 0x65, 0x53, 0x79, 0x6e, 0x63, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x08, 0x73, 0x79, 0x6e, - 0x63, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x3a, 0x0a, 0x0c, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x74, 0x61, - 0x72, 0x67, 0x65, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x75, 0x6e, - 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x54, 0x61, - 0x72, 0x67, 0x65, 0x74, 0x52, 0x0b, 0x73, 0x79, 0x6e, 0x63, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, - 0x73, 0x22, 0xd4, 0x01, 0x0a, 0x0e, 0x53, 0x79, 0x6e, 0x63, 0x65, 0x64, 0x55, 0x6e, 0x69, 0x76, - 0x65, 0x72, 0x73, 0x65, 0x12, 0x3f, 0x0a, 0x0e, 0x6f, 0x6c, 0x64, 0x5f, 0x61, 0x73, 0x73, 0x65, - 0x74, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x75, - 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x55, 0x6e, 0x69, 0x76, 0x65, - 0x72, 0x73, 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x52, 0x0c, 0x6f, 0x6c, 0x64, 0x41, 0x73, 0x73, 0x65, - 0x74, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x3f, 0x0a, 0x0e, 0x6e, 0x65, 0x77, 0x5f, 0x61, 0x73, 0x73, - 0x65, 0x74, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, - 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x55, 0x6e, 0x69, 0x76, - 0x65, 0x72, 0x73, 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x52, 0x0c, 0x6e, 0x65, 0x77, 0x41, 0x73, 0x73, - 0x65, 0x74, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x40, 0x0a, 0x10, 0x6e, 0x65, 0x77, 0x5f, 0x61, 0x73, - 0x73, 0x65, 0x74, 0x5f, 0x6c, 0x65, 0x61, 0x76, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x16, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x41, - 0x73, 0x73, 0x65, 0x74, 0x4c, 0x65, 0x61, 0x66, 0x52, 0x0e, 0x6e, 0x65, 0x77, 0x41, 0x73, 0x73, - 0x65, 0x74, 0x4c, 0x65, 0x61, 0x76, 0x65, 0x73, 0x22, 0x0e, 0x0a, 0x0c, 0x53, 0x74, 0x61, 0x74, - 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x56, 0x0a, 0x0c, 0x53, 0x79, 0x6e, 0x63, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x46, 0x0a, 0x10, 0x73, 0x79, 0x6e, 0x63, - 0x65, 0x64, 0x5f, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, - 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x65, 0x64, 0x55, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x52, - 0x0f, 0x73, 0x79, 0x6e, 0x63, 0x65, 0x64, 0x55, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x73, - 0x22, 0x3e, 0x0a, 0x18, 0x55, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x46, 0x65, 0x64, 0x65, - 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, - 0x68, 0x6f, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, 0x6f, 0x73, 0x74, - 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x69, 0x64, - 0x22, 0x1e, 0x0a, 0x1c, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x22, 0x60, 0x0a, 0x1d, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x3f, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, - 0x2e, 0x55, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x46, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x07, 0x73, 0x65, 0x72, 0x76, 0x65, - 0x72, 0x73, 0x22, 0x5d, 0x0a, 0x1a, 0x41, 0x64, 0x64, 0x46, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x3f, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x25, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, - 0x55, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x46, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x07, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x73, 0x22, 0x1d, 0x0a, 0x1b, 0x41, 0x64, 0x64, 0x46, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x60, 0x0a, 0x1d, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x46, 0x65, 0x64, 0x65, 0x72, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x3f, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, - 0x2e, 0x55, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x46, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x07, 0x73, 0x65, 0x72, 0x76, 0x65, - 0x72, 0x73, 0x22, 0x20, 0x0a, 0x1e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x46, 0x65, 0x64, 0x65, - 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xb5, 0x01, 0x0a, 0x0d, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x28, 0x0a, 0x10, 0x6e, 0x75, 0x6d, 0x5f, 0x74, 0x6f, - 0x74, 0x61, 0x6c, 0x5f, 0x61, 0x73, 0x73, 0x65, 0x74, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, - 0x52, 0x0e, 0x6e, 0x75, 0x6d, 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x41, 0x73, 0x73, 0x65, 0x74, 0x73, - 0x12, 0x28, 0x0a, 0x10, 0x6e, 0x75, 0x6d, 0x5f, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x67, 0x72, - 0x6f, 0x75, 0x70, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0e, 0x6e, 0x75, 0x6d, 0x54, - 0x6f, 0x74, 0x61, 0x6c, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x6e, 0x75, - 0x6d, 0x5f, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x73, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x03, 0x52, 0x0d, 0x6e, 0x75, 0x6d, 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x53, 0x79, 0x6e, - 0x63, 0x73, 0x12, 0x28, 0x0a, 0x10, 0x6e, 0x75, 0x6d, 0x5f, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, - 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0e, 0x6e, 0x75, - 0x6d, 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x73, 0x22, 0xcd, 0x02, 0x0a, - 0x0f, 0x41, 0x73, 0x73, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x73, 0x51, 0x75, 0x65, 0x72, 0x79, - 0x12, 0x2a, 0x0a, 0x11, 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x66, - 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x61, 0x73, 0x73, - 0x65, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x26, 0x0a, 0x0f, - 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x69, 0x64, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x61, 0x73, 0x73, 0x65, 0x74, 0x49, 0x64, 0x46, 0x69, - 0x6c, 0x74, 0x65, 0x72, 0x12, 0x48, 0x0a, 0x11, 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x74, 0x79, - 0x70, 0x65, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, - 0x1c, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x73, - 0x73, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x0f, 0x61, - 0x73, 0x73, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x34, - 0x0a, 0x07, 0x73, 0x6f, 0x72, 0x74, 0x5f, 0x62, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, - 0x1b, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x73, - 0x73, 0x65, 0x74, 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, 0x6f, 0x72, 0x74, 0x52, 0x06, 0x73, 0x6f, - 0x72, 0x74, 0x42, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x05, - 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x14, 0x0a, 0x05, - 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x6c, 0x69, 0x6d, - 0x69, 0x74, 0x12, 0x38, 0x0a, 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, - 0x07, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, - 0x72, 0x70, 0x63, 0x2e, 0x53, 0x6f, 0x72, 0x74, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x52, 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x8d, 0x02, 0x0a, - 0x12, 0x41, 0x73, 0x73, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x73, 0x53, 0x6e, 0x61, 0x70, 0x73, - 0x68, 0x6f, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x6b, 0x65, 0x79, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x4b, 0x65, 0x79, - 0x12, 0x21, 0x0a, 0x0c, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x73, 0x75, 0x70, 0x70, 0x6c, 0x79, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x75, 0x70, - 0x70, 0x6c, 0x79, 0x12, 0x3f, 0x0a, 0x0c, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x61, 0x6e, 0x63, - 0x68, 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x75, 0x6e, 0x69, 0x76, - 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x73, 0x73, 0x65, 0x74, 0x53, 0x74, 0x61, - 0x74, 0x73, 0x41, 0x73, 0x73, 0x65, 0x74, 0x52, 0x0b, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x41, 0x6e, - 0x63, 0x68, 0x6f, 0x72, 0x12, 0x32, 0x0a, 0x05, 0x61, 0x73, 0x73, 0x65, 0x74, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, - 0x63, 0x2e, 0x41, 0x73, 0x73, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x73, 0x41, 0x73, 0x73, 0x65, - 0x74, 0x52, 0x05, 0x61, 0x73, 0x73, 0x65, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x6f, 0x74, 0x61, - 0x6c, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x74, - 0x6f, 0x74, 0x61, 0x6c, 0x53, 0x79, 0x6e, 0x63, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x74, 0x6f, 0x74, - 0x61, 0x6c, 0x5f, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, - 0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x73, 0x22, 0xe5, 0x02, 0x0a, - 0x0f, 0x41, 0x73, 0x73, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x73, 0x41, 0x73, 0x73, 0x65, 0x74, - 0x12, 0x19, 0x0a, 0x08, 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x07, 0x61, 0x73, 0x73, 0x65, 0x74, 0x49, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x67, - 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x5f, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0c, 0x67, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x50, 0x6f, 0x69, 0x6e, 0x74, - 0x12, 0x21, 0x0a, 0x0c, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x73, 0x75, 0x70, 0x70, 0x6c, 0x79, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x53, 0x75, 0x70, - 0x70, 0x6c, 0x79, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x6e, 0x61, 0x6d, - 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x73, 0x73, 0x65, 0x74, 0x4e, 0x61, - 0x6d, 0x65, 0x12, 0x30, 0x0a, 0x0a, 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x11, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, - 0x41, 0x73, 0x73, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x09, 0x61, 0x73, 0x73, 0x65, 0x74, - 0x54, 0x79, 0x70, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x67, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x5f, - 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x67, 0x65, - 0x6e, 0x65, 0x73, 0x69, 0x73, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x2b, 0x0a, 0x11, 0x67, - 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, - 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x10, 0x67, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x54, - 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x21, 0x0a, 0x0c, 0x61, 0x6e, 0x63, 0x68, - 0x6f, 0x72, 0x5f, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, - 0x61, 0x6e, 0x63, 0x68, 0x6f, 0x72, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x27, 0x0a, 0x0f, 0x64, - 0x65, 0x63, 0x69, 0x6d, 0x61, 0x6c, 0x5f, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x18, 0x09, - 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0e, 0x64, 0x65, 0x63, 0x69, 0x6d, 0x61, 0x6c, 0x44, 0x69, 0x73, - 0x70, 0x6c, 0x61, 0x79, 0x22, 0x56, 0x0a, 0x12, 0x55, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, - 0x41, 0x73, 0x73, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x40, 0x0a, 0x0b, 0x61, 0x73, - 0x73, 0x65, 0x74, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x1f, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x73, - 0x73, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x73, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, - 0x52, 0x0a, 0x61, 0x73, 0x73, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x73, 0x22, 0x62, 0x0a, 0x12, - 0x51, 0x75, 0x65, 0x72, 0x79, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x27, 0x0a, 0x0f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, - 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0e, 0x73, 0x74, 0x61, - 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x23, 0x0a, 0x0d, 0x65, - 0x6e, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x03, 0x52, 0x0c, 0x65, 0x6e, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, - 0x22, 0x51, 0x0a, 0x13, 0x51, 0x75, 0x65, 0x72, 0x79, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3a, 0x0a, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, - 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, - 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x65, 0x64, 0x55, 0x6e, 0x69, - 0x76, 0x65, 0x72, 0x73, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x06, 0x65, 0x76, 0x65, - 0x6e, 0x74, 0x73, 0x22, 0x76, 0x0a, 0x15, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x65, 0x64, 0x55, 0x6e, - 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x12, 0x0a, 0x04, - 0x64, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x64, 0x61, 0x74, 0x65, - 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x73, 0x79, 0x6e, 0x63, 0x45, 0x76, 0x65, 0x6e, 0x74, - 0x73, 0x12, 0x28, 0x0a, 0x10, 0x6e, 0x65, 0x77, 0x5f, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x5f, 0x65, - 0x76, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0e, 0x6e, 0x65, 0x77, - 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x22, 0xcf, 0x01, 0x0a, 0x1e, - 0x53, 0x65, 0x74, 0x46, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x79, 0x6e, - 0x63, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x57, - 0x0a, 0x13, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x63, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x75, 0x6e, - 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, - 0x46, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x79, 0x6e, 0x63, 0x43, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x52, 0x11, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x79, 0x6e, 0x63, - 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x12, 0x54, 0x0a, 0x12, 0x61, 0x73, 0x73, 0x65, 0x74, - 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x18, 0x02, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, - 0x63, 0x2e, 0x41, 0x73, 0x73, 0x65, 0x74, 0x46, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x53, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x10, 0x61, 0x73, 0x73, - 0x65, 0x74, 0x53, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x22, 0x21, 0x0a, - 0x1f, 0x53, 0x65, 0x74, 0x46, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x79, - 0x6e, 0x63, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0xab, 0x01, 0x0a, 0x1a, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x46, 0x65, 0x64, 0x65, 0x72, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, - 0x35, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, - 0x63, 0x2e, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x54, 0x79, 0x70, 0x65, 0x52, 0x09, 0x70, 0x72, 0x6f, - 0x6f, 0x66, 0x54, 0x79, 0x70, 0x65, 0x12, 0x2a, 0x0a, 0x11, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x5f, - 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x0f, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x53, 0x79, 0x6e, 0x63, 0x49, 0x6e, 0x73, 0x65, - 0x72, 0x74, 0x12, 0x2a, 0x0a, 0x11, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x5f, 0x73, 0x79, 0x6e, 0x63, - 0x5f, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x61, - 0x6c, 0x6c, 0x6f, 0x77, 0x53, 0x79, 0x6e, 0x63, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x22, 0x94, - 0x01, 0x0a, 0x19, 0x41, 0x73, 0x73, 0x65, 0x74, 0x46, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x53, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1f, 0x0a, 0x02, - 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, - 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x44, 0x52, 0x02, 0x69, 0x64, 0x12, 0x2a, 0x0a, - 0x11, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x69, 0x6e, 0x73, 0x65, - 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x53, - 0x79, 0x6e, 0x63, 0x49, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x12, 0x2a, 0x0a, 0x11, 0x61, 0x6c, 0x6c, - 0x6f, 0x77, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x53, 0x79, 0x6e, 0x63, 0x45, - 0x78, 0x70, 0x6f, 0x72, 0x74, 0x22, 0x43, 0x0a, 0x20, 0x51, 0x75, 0x65, 0x72, 0x79, 0x46, 0x65, - 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x02, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, - 0x72, 0x70, 0x63, 0x2e, 0x49, 0x44, 0x52, 0x02, 0x69, 0x64, 0x22, 0xd2, 0x01, 0x0a, 0x21, 0x51, - 0x75, 0x65, 0x72, 0x79, 0x46, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x79, - 0x6e, 0x63, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x57, 0x0a, 0x13, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f, - 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, - 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x6c, 0x6f, 0x62, - 0x61, 0x6c, 0x46, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x79, 0x6e, 0x63, - 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x11, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x79, - 0x6e, 0x63, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x12, 0x54, 0x0a, 0x12, 0x61, 0x73, 0x73, - 0x65, 0x74, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x18, - 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, - 0x72, 0x70, 0x63, 0x2e, 0x41, 0x73, 0x73, 0x65, 0x74, 0x46, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x53, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x10, 0x61, - 0x73, 0x73, 0x65, 0x74, 0x53, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x22, - 0x73, 0x0a, 0x1a, 0x49, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x41, 0x73, 0x73, 0x65, 0x74, 0x4f, 0x75, - 0x74, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3d, 0x0a, - 0x0f, 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x6f, 0x75, 0x74, 0x5f, 0x70, 0x6f, 0x69, 0x6e, 0x74, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, - 0x41, 0x73, 0x73, 0x65, 0x74, 0x4f, 0x75, 0x74, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x0d, 0x61, - 0x73, 0x73, 0x65, 0x74, 0x4f, 0x75, 0x74, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x16, 0x0a, 0x06, - 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x61, 0x6d, - 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x68, 0x0a, 0x1b, 0x49, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x41, 0x73, - 0x73, 0x65, 0x74, 0x4f, 0x75, 0x74, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x6c, 0x65, 0x61, 0x66, 0x5f, 0x6b, 0x65, 0x79, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x6c, 0x65, 0x61, 0x66, 0x4b, 0x65, 0x79, 0x12, 0x2e, - 0x0a, 0x04, 0x6c, 0x65, 0x61, 0x66, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x75, - 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x4d, 0x65, 0x72, 0x6b, 0x6c, - 0x65, 0x53, 0x75, 0x6d, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x6c, 0x65, 0x61, 0x66, 0x22, 0x78, - 0x0a, 0x19, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6c, 0x79, 0x43, 0x6f, - 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x28, 0x0a, 0x0f, 0x67, - 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x0d, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x4b, 0x65, 0x79, - 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x24, 0x0a, 0x0d, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x6b, - 0x65, 0x79, 0x5f, 0x73, 0x74, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0b, - 0x67, 0x72, 0x6f, 0x75, 0x70, 0x4b, 0x65, 0x79, 0x53, 0x74, 0x72, 0x42, 0x0b, 0x0a, 0x09, 0x67, - 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x6b, 0x65, 0x79, 0x22, 0x1c, 0x0a, 0x1a, 0x55, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6c, 0x79, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xc2, 0x02, 0x0a, 0x18, 0x46, 0x65, 0x74, 0x63, 0x68, - 0x53, 0x75, 0x70, 0x70, 0x6c, 0x79, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x28, 0x0a, 0x0f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x6b, 0x65, 0x79, - 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x0d, - 0x67, 0x72, 0x6f, 0x75, 0x70, 0x4b, 0x65, 0x79, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x24, 0x0a, - 0x0d, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x73, 0x74, 0x72, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0b, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x4b, 0x65, 0x79, - 0x53, 0x74, 0x72, 0x12, 0x3b, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x6f, 0x75, - 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x74, - 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4f, 0x75, 0x74, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x48, 0x01, - 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x4f, 0x75, 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, - 0x12, 0x46, 0x0a, 0x15, 0x73, 0x70, 0x65, 0x6e, 0x74, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, - 0x5f, 0x6f, 0x75, 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x10, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4f, 0x75, 0x74, 0x50, 0x6f, 0x69, 0x6e, - 0x74, 0x48, 0x01, 0x52, 0x13, 0x73, 0x70, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, - 0x4f, 0x75, 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x1f, 0x0a, 0x0a, 0x76, 0x65, 0x72, 0x79, - 0x5f, 0x66, 0x69, 0x72, 0x73, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x48, 0x01, 0x52, 0x09, - 0x76, 0x65, 0x72, 0x79, 0x46, 0x69, 0x72, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x06, 0x6c, 0x61, 0x74, - 0x65, 0x73, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x48, 0x01, 0x52, 0x06, 0x6c, 0x61, 0x74, - 0x65, 0x73, 0x74, 0x42, 0x0b, 0x0a, 0x09, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x6b, 0x65, 0x79, - 0x42, 0x09, 0x0a, 0x07, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x6f, 0x72, 0x22, 0xd6, 0x01, 0x0a, 0x17, - 0x53, 0x75, 0x70, 0x70, 0x6c, 0x79, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x53, 0x75, 0x62, 0x74, - 0x72, 0x65, 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x37, 0x0a, 0x09, 0x72, - 0x6f, 0x6f, 0x74, 0x5f, 0x6e, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, - 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x4d, 0x65, 0x72, - 0x6b, 0x6c, 0x65, 0x53, 0x75, 0x6d, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x08, 0x72, 0x6f, 0x6f, 0x74, - 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x2f, 0x0a, 0x14, 0x73, 0x75, 0x70, 0x70, 0x6c, 0x79, 0x5f, 0x74, - 0x72, 0x65, 0x65, 0x5f, 0x6c, 0x65, 0x61, 0x66, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x11, 0x73, 0x75, 0x70, 0x70, 0x6c, 0x79, 0x54, 0x72, 0x65, 0x65, 0x4c, 0x65, - 0x61, 0x66, 0x4b, 0x65, 0x79, 0x12, 0x3d, 0x0a, 0x1b, 0x73, 0x75, 0x70, 0x70, 0x6c, 0x79, 0x5f, - 0x74, 0x72, 0x65, 0x65, 0x5f, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x70, - 0x72, 0x6f, 0x6f, 0x66, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x18, 0x73, 0x75, 0x70, 0x70, - 0x6c, 0x79, 0x54, 0x72, 0x65, 0x65, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x6f, 0x6e, 0x50, - 0x72, 0x6f, 0x6f, 0x66, 0x22, 0xa2, 0x07, 0x0a, 0x19, 0x46, 0x65, 0x74, 0x63, 0x68, 0x53, 0x75, - 0x70, 0x70, 0x6c, 0x79, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x41, 0x0a, 0x0a, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x64, 0x61, 0x74, 0x61, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, - 0x65, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x75, 0x70, 0x70, 0x6c, 0x79, 0x43, 0x6f, 0x6d, 0x6d, 0x69, - 0x74, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x09, 0x63, 0x68, 0x61, 0x69, - 0x6e, 0x44, 0x61, 0x74, 0x61, 0x12, 0x2b, 0x0a, 0x12, 0x74, 0x78, 0x5f, 0x63, 0x68, 0x61, 0x69, - 0x6e, 0x5f, 0x66, 0x65, 0x65, 0x73, 0x5f, 0x73, 0x61, 0x74, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x03, 0x52, 0x0f, 0x74, 0x78, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x46, 0x65, 0x65, 0x73, 0x53, 0x61, - 0x74, 0x73, 0x12, 0x58, 0x0a, 0x15, 0x69, 0x73, 0x73, 0x75, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x73, - 0x75, 0x62, 0x74, 0x72, 0x65, 0x65, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x24, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, - 0x53, 0x75, 0x70, 0x70, 0x6c, 0x79, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x53, 0x75, 0x62, 0x74, - 0x72, 0x65, 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x52, 0x13, 0x69, 0x73, 0x73, 0x75, 0x61, 0x6e, 0x63, - 0x65, 0x53, 0x75, 0x62, 0x74, 0x72, 0x65, 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x50, 0x0a, 0x11, - 0x62, 0x75, 0x72, 0x6e, 0x5f, 0x73, 0x75, 0x62, 0x74, 0x72, 0x65, 0x65, 0x5f, 0x72, 0x6f, 0x6f, - 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, + 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x07, + 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x22, 0x1d, 0x0a, 0x1b, 0x41, 0x64, 0x64, 0x46, 0x65, + 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x60, 0x0a, 0x1d, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, + 0x46, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, + 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x55, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x46, + 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, + 0x07, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x22, 0x20, 0x0a, 0x1e, 0x44, 0x65, 0x6c, 0x65, + 0x74, 0x65, 0x46, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xb5, 0x01, 0x0a, 0x0d, 0x53, + 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x28, 0x0a, 0x10, + 0x6e, 0x75, 0x6d, 0x5f, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x61, 0x73, 0x73, 0x65, 0x74, 0x73, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0e, 0x6e, 0x75, 0x6d, 0x54, 0x6f, 0x74, 0x61, 0x6c, + 0x41, 0x73, 0x73, 0x65, 0x74, 0x73, 0x12, 0x28, 0x0a, 0x10, 0x6e, 0x75, 0x6d, 0x5f, 0x74, 0x6f, + 0x74, 0x61, 0x6c, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, + 0x52, 0x0e, 0x6e, 0x75, 0x6d, 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, + 0x12, 0x26, 0x0a, 0x0f, 0x6e, 0x75, 0x6d, 0x5f, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x73, 0x79, + 0x6e, 0x63, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x6e, 0x75, 0x6d, 0x54, 0x6f, + 0x74, 0x61, 0x6c, 0x53, 0x79, 0x6e, 0x63, 0x73, 0x12, 0x28, 0x0a, 0x10, 0x6e, 0x75, 0x6d, 0x5f, + 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x73, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x03, 0x52, 0x0e, 0x6e, 0x75, 0x6d, 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x50, 0x72, 0x6f, 0x6f, + 0x66, 0x73, 0x22, 0xc8, 0x02, 0x0a, 0x0f, 0x41, 0x73, 0x73, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, + 0x73, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x2a, 0x0a, 0x11, 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, + 0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0f, 0x61, 0x73, 0x73, 0x65, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x46, 0x69, 0x6c, 0x74, + 0x65, 0x72, 0x12, 0x26, 0x0a, 0x0f, 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x69, 0x64, 0x5f, 0x66, + 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x61, 0x73, 0x73, + 0x65, 0x74, 0x49, 0x64, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x48, 0x0a, 0x11, 0x61, 0x73, + 0x73, 0x65, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, + 0x72, 0x70, 0x63, 0x2e, 0x41, 0x73, 0x73, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x46, 0x69, 0x6c, + 0x74, 0x65, 0x72, 0x52, 0x0f, 0x61, 0x73, 0x73, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x46, 0x69, + 0x6c, 0x74, 0x65, 0x72, 0x12, 0x34, 0x0a, 0x07, 0x73, 0x6f, 0x72, 0x74, 0x5f, 0x62, 0x79, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1b, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, + 0x72, 0x70, 0x63, 0x2e, 0x41, 0x73, 0x73, 0x65, 0x74, 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, 0x6f, + 0x72, 0x74, 0x52, 0x06, 0x73, 0x6f, 0x72, 0x74, 0x42, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x66, + 0x66, 0x73, 0x65, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x6f, 0x66, 0x66, 0x73, + 0x65, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, + 0x05, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x33, 0x0a, 0x09, 0x64, 0x69, 0x72, 0x65, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x74, 0x61, + 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x6f, 0x72, 0x74, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x52, 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x8d, 0x02, + 0x0a, 0x12, 0x41, 0x73, 0x73, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x73, 0x53, 0x6e, 0x61, 0x70, + 0x73, 0x68, 0x6f, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x6b, 0x65, + 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x4b, 0x65, + 0x79, 0x12, 0x21, 0x0a, 0x0c, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x73, 0x75, 0x70, 0x70, 0x6c, + 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x75, + 0x70, 0x70, 0x6c, 0x79, 0x12, 0x3f, 0x0a, 0x0c, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x61, 0x6e, + 0x63, 0x68, 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x75, 0x6e, 0x69, + 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x73, 0x73, 0x65, 0x74, 0x53, 0x74, + 0x61, 0x74, 0x73, 0x41, 0x73, 0x73, 0x65, 0x74, 0x52, 0x0b, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x41, + 0x6e, 0x63, 0x68, 0x6f, 0x72, 0x12, 0x32, 0x0a, 0x05, 0x61, 0x73, 0x73, 0x65, 0x74, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, + 0x70, 0x63, 0x2e, 0x41, 0x73, 0x73, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x73, 0x41, 0x73, 0x73, + 0x65, 0x74, 0x52, 0x05, 0x61, 0x73, 0x73, 0x65, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x6f, 0x74, + 0x61, 0x6c, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, + 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x53, 0x79, 0x6e, 0x63, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x74, 0x6f, + 0x74, 0x61, 0x6c, 0x5f, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, + 0x52, 0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x73, 0x22, 0xe5, 0x02, + 0x0a, 0x0f, 0x41, 0x73, 0x73, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x73, 0x41, 0x73, 0x73, 0x65, + 0x74, 0x12, 0x19, 0x0a, 0x08, 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x07, 0x61, 0x73, 0x73, 0x65, 0x74, 0x49, 0x64, 0x12, 0x23, 0x0a, 0x0d, + 0x67, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x5f, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0c, 0x67, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x50, 0x6f, 0x69, 0x6e, + 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x73, 0x75, 0x70, 0x70, 0x6c, + 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x53, 0x75, + 0x70, 0x70, 0x6c, 0x79, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x6e, 0x61, + 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x73, 0x73, 0x65, 0x74, 0x4e, + 0x61, 0x6d, 0x65, 0x12, 0x30, 0x0a, 0x0a, 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x74, 0x79, 0x70, + 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x11, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, + 0x2e, 0x41, 0x73, 0x73, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x09, 0x61, 0x73, 0x73, 0x65, + 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x67, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, + 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x67, + 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x2b, 0x0a, 0x11, + 0x67, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, + 0x70, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x10, 0x67, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, + 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x21, 0x0a, 0x0c, 0x61, 0x6e, 0x63, + 0x68, 0x6f, 0x72, 0x5f, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0b, 0x61, 0x6e, 0x63, 0x68, 0x6f, 0x72, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x27, 0x0a, 0x0f, + 0x64, 0x65, 0x63, 0x69, 0x6d, 0x61, 0x6c, 0x5f, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x18, + 0x09, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0e, 0x64, 0x65, 0x63, 0x69, 0x6d, 0x61, 0x6c, 0x44, 0x69, + 0x73, 0x70, 0x6c, 0x61, 0x79, 0x22, 0x56, 0x0a, 0x12, 0x55, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, + 0x65, 0x41, 0x73, 0x73, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x40, 0x0a, 0x0b, 0x61, + 0x73, 0x73, 0x65, 0x74, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x1f, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x41, + 0x73, 0x73, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x73, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, + 0x74, 0x52, 0x0a, 0x61, 0x73, 0x73, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x73, 0x22, 0x62, 0x0a, + 0x12, 0x51, 0x75, 0x65, 0x72, 0x79, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x27, 0x0a, 0x0f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x74, 0x69, 0x6d, + 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0e, 0x73, 0x74, + 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x23, 0x0a, 0x0d, + 0x65, 0x6e, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x03, 0x52, 0x0c, 0x65, 0x6e, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, + 0x70, 0x22, 0x51, 0x0a, 0x13, 0x51, 0x75, 0x65, 0x72, 0x79, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3a, 0x0a, 0x06, 0x65, 0x76, 0x65, 0x6e, + 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, + 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x65, 0x64, 0x55, 0x6e, + 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x06, 0x65, 0x76, + 0x65, 0x6e, 0x74, 0x73, 0x22, 0x76, 0x0a, 0x15, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x65, 0x64, 0x55, + 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x12, 0x0a, + 0x04, 0x64, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x64, 0x61, 0x74, + 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x73, 0x79, 0x6e, 0x63, 0x45, 0x76, 0x65, 0x6e, + 0x74, 0x73, 0x12, 0x28, 0x0a, 0x10, 0x6e, 0x65, 0x77, 0x5f, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x5f, + 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0e, 0x6e, 0x65, + 0x77, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x22, 0xcf, 0x01, 0x0a, + 0x1e, 0x53, 0x65, 0x74, 0x46, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x79, + 0x6e, 0x63, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x57, 0x0a, 0x13, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x63, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x75, + 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x6c, 0x6f, 0x62, 0x61, + 0x6c, 0x46, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x79, 0x6e, 0x63, 0x43, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x11, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x79, 0x6e, + 0x63, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x12, 0x54, 0x0a, 0x12, 0x61, 0x73, 0x73, 0x65, + 0x74, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x18, 0x02, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, + 0x70, 0x63, 0x2e, 0x41, 0x73, 0x73, 0x65, 0x74, 0x46, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x53, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x10, 0x61, 0x73, + 0x73, 0x65, 0x74, 0x53, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x22, 0x21, + 0x0a, 0x1f, 0x53, 0x65, 0x74, 0x46, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, + 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0xab, 0x01, 0x0a, 0x1a, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x46, 0x65, 0x64, 0x65, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x12, 0x35, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, + 0x70, 0x63, 0x2e, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x54, 0x79, 0x70, 0x65, 0x52, 0x09, 0x70, 0x72, + 0x6f, 0x6f, 0x66, 0x54, 0x79, 0x70, 0x65, 0x12, 0x2a, 0x0a, 0x11, 0x61, 0x6c, 0x6c, 0x6f, 0x77, + 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x0f, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x53, 0x79, 0x6e, 0x63, 0x49, 0x6e, 0x73, + 0x65, 0x72, 0x74, 0x12, 0x2a, 0x0a, 0x11, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x5f, 0x73, 0x79, 0x6e, + 0x63, 0x5f, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, + 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x53, 0x79, 0x6e, 0x63, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x22, + 0x94, 0x01, 0x0a, 0x19, 0x41, 0x73, 0x73, 0x65, 0x74, 0x46, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x53, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1f, 0x0a, + 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x75, 0x6e, 0x69, 0x76, + 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x44, 0x52, 0x02, 0x69, 0x64, 0x12, 0x2a, + 0x0a, 0x11, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x69, 0x6e, 0x73, + 0x65, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x61, 0x6c, 0x6c, 0x6f, 0x77, + 0x53, 0x79, 0x6e, 0x63, 0x49, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x12, 0x2a, 0x0a, 0x11, 0x61, 0x6c, + 0x6c, 0x6f, 0x77, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x53, 0x79, 0x6e, 0x63, + 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x22, 0x43, 0x0a, 0x20, 0x51, 0x75, 0x65, 0x72, 0x79, 0x46, + 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x02, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, + 0x65, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x44, 0x52, 0x02, 0x69, 0x64, 0x22, 0xd2, 0x01, 0x0a, 0x21, + 0x51, 0x75, 0x65, 0x72, 0x79, 0x46, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, + 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x57, 0x0a, 0x13, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x73, 0x79, 0x6e, 0x63, + 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, + 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x6c, 0x6f, + 0x62, 0x61, 0x6c, 0x46, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x79, 0x6e, + 0x63, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x11, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, + 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x12, 0x54, 0x0a, 0x12, 0x61, 0x73, + 0x73, 0x65, 0x74, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, + 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, + 0x65, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x73, 0x73, 0x65, 0x74, 0x46, 0x65, 0x64, 0x65, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x10, + 0x61, 0x73, 0x73, 0x65, 0x74, 0x53, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, + 0x22, 0x73, 0x0a, 0x1a, 0x49, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x41, 0x73, 0x73, 0x65, 0x74, 0x4f, + 0x75, 0x74, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3d, + 0x0a, 0x0f, 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x6f, 0x75, 0x74, 0x5f, 0x70, 0x6f, 0x69, 0x6e, + 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, + 0x2e, 0x41, 0x73, 0x73, 0x65, 0x74, 0x4f, 0x75, 0x74, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x0d, + 0x61, 0x73, 0x73, 0x65, 0x74, 0x4f, 0x75, 0x74, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x16, 0x0a, + 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x61, + 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x68, 0x0a, 0x1b, 0x49, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x41, + 0x73, 0x73, 0x65, 0x74, 0x4f, 0x75, 0x74, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x6c, 0x65, 0x61, 0x66, 0x5f, 0x6b, 0x65, 0x79, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x6c, 0x65, 0x61, 0x66, 0x4b, 0x65, 0x79, 0x12, + 0x2e, 0x0a, 0x04, 0x6c, 0x65, 0x61, 0x66, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, + 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x4d, 0x65, 0x72, 0x6b, + 0x6c, 0x65, 0x53, 0x75, 0x6d, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x6c, 0x65, 0x61, 0x66, 0x22, + 0x78, 0x0a, 0x19, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6c, 0x79, 0x43, + 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x28, 0x0a, 0x0f, + 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x0d, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x4b, 0x65, + 0x79, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x24, 0x0a, 0x0d, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, + 0x6b, 0x65, 0x79, 0x5f, 0x73, 0x74, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, + 0x0b, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x4b, 0x65, 0x79, 0x53, 0x74, 0x72, 0x42, 0x0b, 0x0a, 0x09, + 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x6b, 0x65, 0x79, 0x22, 0x1c, 0x0a, 0x1a, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6c, 0x79, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xc2, 0x02, 0x0a, 0x18, 0x46, 0x65, 0x74, 0x63, + 0x68, 0x53, 0x75, 0x70, 0x70, 0x6c, 0x79, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x28, 0x0a, 0x0f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x6b, 0x65, + 0x79, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, + 0x0d, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x4b, 0x65, 0x79, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x24, + 0x0a, 0x0d, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x73, 0x74, 0x72, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0b, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x4b, 0x65, + 0x79, 0x53, 0x74, 0x72, 0x12, 0x3b, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x6f, + 0x75, 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, + 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4f, 0x75, 0x74, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x48, + 0x01, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x4f, 0x75, 0x74, 0x70, 0x6f, 0x69, 0x6e, + 0x74, 0x12, 0x46, 0x0a, 0x15, 0x73, 0x70, 0x65, 0x6e, 0x74, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, + 0x74, 0x5f, 0x6f, 0x75, 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x10, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4f, 0x75, 0x74, 0x50, 0x6f, 0x69, + 0x6e, 0x74, 0x48, 0x01, 0x52, 0x13, 0x73, 0x70, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, + 0x74, 0x4f, 0x75, 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x1f, 0x0a, 0x0a, 0x76, 0x65, 0x72, + 0x79, 0x5f, 0x66, 0x69, 0x72, 0x73, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x48, 0x01, 0x52, + 0x09, 0x76, 0x65, 0x72, 0x79, 0x46, 0x69, 0x72, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x06, 0x6c, 0x61, + 0x74, 0x65, 0x73, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x48, 0x01, 0x52, 0x06, 0x6c, 0x61, + 0x74, 0x65, 0x73, 0x74, 0x42, 0x0b, 0x0a, 0x09, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x6b, 0x65, + 0x79, 0x42, 0x09, 0x0a, 0x07, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x6f, 0x72, 0x22, 0xd6, 0x01, 0x0a, + 0x17, 0x53, 0x75, 0x70, 0x70, 0x6c, 0x79, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x53, 0x75, 0x62, + 0x74, 0x72, 0x65, 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x37, 0x0a, 0x09, + 0x72, 0x6f, 0x6f, 0x74, 0x5f, 0x6e, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x1a, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x4d, 0x65, + 0x72, 0x6b, 0x6c, 0x65, 0x53, 0x75, 0x6d, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x08, 0x72, 0x6f, 0x6f, + 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x2f, 0x0a, 0x14, 0x73, 0x75, 0x70, 0x70, 0x6c, 0x79, 0x5f, + 0x74, 0x72, 0x65, 0x65, 0x5f, 0x6c, 0x65, 0x61, 0x66, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x11, 0x73, 0x75, 0x70, 0x70, 0x6c, 0x79, 0x54, 0x72, 0x65, 0x65, 0x4c, + 0x65, 0x61, 0x66, 0x4b, 0x65, 0x79, 0x12, 0x3d, 0x0a, 0x1b, 0x73, 0x75, 0x70, 0x70, 0x6c, 0x79, + 0x5f, 0x74, 0x72, 0x65, 0x65, 0x5f, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x6f, 0x6e, 0x5f, + 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x18, 0x73, 0x75, 0x70, + 0x70, 0x6c, 0x79, 0x54, 0x72, 0x65, 0x65, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x6f, 0x6e, + 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x22, 0xa2, 0x07, 0x0a, 0x19, 0x46, 0x65, 0x74, 0x63, 0x68, 0x53, + 0x75, 0x70, 0x70, 0x6c, 0x79, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x41, 0x0a, 0x0a, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x64, 0x61, 0x74, + 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x75, 0x70, 0x70, 0x6c, 0x79, 0x43, 0x6f, 0x6d, 0x6d, - 0x69, 0x74, 0x53, 0x75, 0x62, 0x74, 0x72, 0x65, 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x52, 0x0f, 0x62, - 0x75, 0x72, 0x6e, 0x53, 0x75, 0x62, 0x74, 0x72, 0x65, 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x54, - 0x0a, 0x13, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x5f, 0x73, 0x75, 0x62, 0x74, 0x72, 0x65, 0x65, - 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x75, 0x6e, - 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x75, 0x70, 0x70, 0x6c, 0x79, - 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x53, 0x75, 0x62, 0x74, 0x72, 0x65, 0x65, 0x52, 0x6f, 0x6f, - 0x74, 0x52, 0x11, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x53, 0x75, 0x62, 0x74, 0x72, 0x65, 0x65, - 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x45, 0x0a, 0x0f, 0x69, 0x73, 0x73, 0x75, 0x61, 0x6e, 0x63, 0x65, - 0x5f, 0x6c, 0x65, 0x61, 0x76, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, - 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x75, 0x70, 0x70, - 0x6c, 0x79, 0x4c, 0x65, 0x61, 0x66, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0e, 0x69, 0x73, 0x73, - 0x75, 0x61, 0x6e, 0x63, 0x65, 0x4c, 0x65, 0x61, 0x76, 0x65, 0x73, 0x12, 0x3d, 0x0a, 0x0b, 0x62, - 0x75, 0x72, 0x6e, 0x5f, 0x6c, 0x65, 0x61, 0x76, 0x65, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x1c, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x53, - 0x75, 0x70, 0x70, 0x6c, 0x79, 0x4c, 0x65, 0x61, 0x66, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0a, - 0x62, 0x75, 0x72, 0x6e, 0x4c, 0x65, 0x61, 0x76, 0x65, 0x73, 0x12, 0x41, 0x0a, 0x0d, 0x69, 0x67, - 0x6e, 0x6f, 0x72, 0x65, 0x5f, 0x6c, 0x65, 0x61, 0x76, 0x65, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, + 0x69, 0x74, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x09, 0x63, 0x68, 0x61, + 0x69, 0x6e, 0x44, 0x61, 0x74, 0x61, 0x12, 0x2b, 0x0a, 0x12, 0x74, 0x78, 0x5f, 0x63, 0x68, 0x61, + 0x69, 0x6e, 0x5f, 0x66, 0x65, 0x65, 0x73, 0x5f, 0x73, 0x61, 0x74, 0x73, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x03, 0x52, 0x0f, 0x74, 0x78, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x46, 0x65, 0x65, 0x73, 0x53, + 0x61, 0x74, 0x73, 0x12, 0x58, 0x0a, 0x15, 0x69, 0x73, 0x73, 0x75, 0x61, 0x6e, 0x63, 0x65, 0x5f, + 0x73, 0x75, 0x62, 0x74, 0x72, 0x65, 0x65, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, + 0x2e, 0x53, 0x75, 0x70, 0x70, 0x6c, 0x79, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x53, 0x75, 0x62, + 0x74, 0x72, 0x65, 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x52, 0x13, 0x69, 0x73, 0x73, 0x75, 0x61, 0x6e, + 0x63, 0x65, 0x53, 0x75, 0x62, 0x74, 0x72, 0x65, 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x50, 0x0a, + 0x11, 0x62, 0x75, 0x72, 0x6e, 0x5f, 0x73, 0x75, 0x62, 0x74, 0x72, 0x65, 0x65, 0x5f, 0x72, 0x6f, + 0x6f, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, + 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x75, 0x70, 0x70, 0x6c, 0x79, 0x43, 0x6f, 0x6d, + 0x6d, 0x69, 0x74, 0x53, 0x75, 0x62, 0x74, 0x72, 0x65, 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x52, 0x0f, + 0x62, 0x75, 0x72, 0x6e, 0x53, 0x75, 0x62, 0x74, 0x72, 0x65, 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x12, + 0x54, 0x0a, 0x13, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x5f, 0x73, 0x75, 0x62, 0x74, 0x72, 0x65, + 0x65, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x75, + 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x75, 0x70, 0x70, 0x6c, + 0x79, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x53, 0x75, 0x62, 0x74, 0x72, 0x65, 0x65, 0x52, 0x6f, + 0x6f, 0x74, 0x52, 0x11, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x53, 0x75, 0x62, 0x74, 0x72, 0x65, + 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x45, 0x0a, 0x0f, 0x69, 0x73, 0x73, 0x75, 0x61, 0x6e, 0x63, + 0x65, 0x5f, 0x6c, 0x65, 0x61, 0x76, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, + 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x75, 0x70, + 0x70, 0x6c, 0x79, 0x4c, 0x65, 0x61, 0x66, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0e, 0x69, 0x73, + 0x73, 0x75, 0x61, 0x6e, 0x63, 0x65, 0x4c, 0x65, 0x61, 0x76, 0x65, 0x73, 0x12, 0x3d, 0x0a, 0x0b, + 0x62, 0x75, 0x72, 0x6e, 0x5f, 0x6c, 0x65, 0x61, 0x76, 0x65, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x75, 0x70, 0x70, 0x6c, 0x79, 0x4c, 0x65, 0x61, 0x66, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, - 0x0c, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x4c, 0x65, 0x61, 0x76, 0x65, 0x73, 0x12, 0x38, 0x0a, - 0x18, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x6f, 0x75, 0x74, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x69, - 0x6e, 0x67, 0x5f, 0x73, 0x75, 0x70, 0x70, 0x6c, 0x79, 0x18, 0x09, 0x20, 0x01, 0x28, 0x04, 0x52, - 0x16, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x4f, 0x75, 0x74, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x69, 0x6e, - 0x67, 0x53, 0x75, 0x70, 0x70, 0x6c, 0x79, 0x12, 0x4c, 0x0a, 0x19, 0x73, 0x70, 0x65, 0x6e, 0x74, - 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x6f, 0x75, 0x74, 0x70, - 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x74, 0x61, 0x70, - 0x72, 0x70, 0x63, 0x2e, 0x4f, 0x75, 0x74, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x17, 0x73, 0x70, - 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x4f, 0x75, 0x74, - 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x5d, 0x0a, 0x0d, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, - 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x38, 0x2e, 0x75, - 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x46, 0x65, 0x74, 0x63, 0x68, - 0x53, 0x75, 0x70, 0x70, 0x6c, 0x79, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, - 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x61, - 0x64, 0x65, 0x72, 0x73, 0x1a, 0x63, 0x0a, 0x11, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x61, - 0x64, 0x65, 0x72, 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, 0x38, 0x0a, 0x05, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x75, 0x6e, 0x69, - 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x75, 0x70, 0x70, 0x6c, 0x79, 0x4c, - 0x65, 0x61, 0x66, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x52, 0x05, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xcd, 0x02, 0x0a, 0x18, 0x46, 0x65, - 0x74, 0x63, 0x68, 0x53, 0x75, 0x70, 0x70, 0x6c, 0x79, 0x4c, 0x65, 0x61, 0x76, 0x65, 0x73, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x28, 0x0a, 0x0f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, - 0x6b, 0x65, 0x79, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x48, - 0x00, 0x52, 0x0d, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x4b, 0x65, 0x79, 0x42, 0x79, 0x74, 0x65, 0x73, - 0x12, 0x24, 0x0a, 0x0d, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x73, 0x74, - 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0b, 0x67, 0x72, 0x6f, 0x75, 0x70, - 0x4b, 0x65, 0x79, 0x53, 0x74, 0x72, 0x12, 0x2c, 0x0a, 0x12, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, - 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x0d, 0x52, 0x10, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x53, - 0x74, 0x61, 0x72, 0x74, 0x12, 0x28, 0x0a, 0x10, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x65, - 0x69, 0x67, 0x68, 0x74, 0x5f, 0x65, 0x6e, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0e, - 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x45, 0x6e, 0x64, 0x12, 0x2c, - 0x0a, 0x12, 0x69, 0x73, 0x73, 0x75, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x6c, 0x65, 0x61, 0x66, 0x5f, - 0x6b, 0x65, 0x79, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x10, 0x69, 0x73, 0x73, 0x75, - 0x61, 0x6e, 0x63, 0x65, 0x4c, 0x65, 0x61, 0x66, 0x4b, 0x65, 0x79, 0x73, 0x12, 0x24, 0x0a, 0x0e, - 0x62, 0x75, 0x72, 0x6e, 0x5f, 0x6c, 0x65, 0x61, 0x66, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x06, - 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0c, 0x62, 0x75, 0x72, 0x6e, 0x4c, 0x65, 0x61, 0x66, 0x4b, 0x65, - 0x79, 0x73, 0x12, 0x28, 0x0a, 0x10, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x5f, 0x6c, 0x65, 0x61, - 0x66, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0e, 0x69, 0x67, - 0x6e, 0x6f, 0x72, 0x65, 0x4c, 0x65, 0x61, 0x66, 0x4b, 0x65, 0x79, 0x73, 0x42, 0x0b, 0x0a, 0x09, - 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x6b, 0x65, 0x79, 0x22, 0x7c, 0x0a, 0x0d, 0x53, 0x75, 0x70, - 0x70, 0x6c, 0x79, 0x4c, 0x65, 0x61, 0x66, 0x4b, 0x65, 0x79, 0x12, 0x31, 0x0a, 0x08, 0x6f, 0x75, - 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x75, - 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x4f, 0x75, 0x74, 0x70, 0x6f, - 0x69, 0x6e, 0x74, 0x52, 0x08, 0x6f, 0x75, 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x1d, 0x0a, - 0x0a, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x09, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x4b, 0x65, 0x79, 0x12, 0x19, 0x0a, 0x08, - 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, - 0x61, 0x73, 0x73, 0x65, 0x74, 0x49, 0x64, 0x22, 0xbf, 0x01, 0x0a, 0x0f, 0x53, 0x75, 0x70, 0x70, - 0x6c, 0x79, 0x4c, 0x65, 0x61, 0x66, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x35, 0x0a, 0x08, 0x6c, - 0x65, 0x61, 0x66, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, - 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x75, 0x70, 0x70, - 0x6c, 0x79, 0x4c, 0x65, 0x61, 0x66, 0x4b, 0x65, 0x79, 0x52, 0x07, 0x6c, 0x65, 0x61, 0x66, 0x4b, - 0x65, 0x79, 0x12, 0x37, 0x0a, 0x09, 0x6c, 0x65, 0x61, 0x66, 0x5f, 0x6e, 0x6f, 0x64, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, - 0x72, 0x70, 0x63, 0x2e, 0x4d, 0x65, 0x72, 0x6b, 0x6c, 0x65, 0x53, 0x75, 0x6d, 0x4e, 0x6f, 0x64, - 0x65, 0x52, 0x08, 0x6c, 0x65, 0x61, 0x66, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x62, - 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x0d, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x19, - 0x0a, 0x08, 0x72, 0x61, 0x77, 0x5f, 0x6c, 0x65, 0x61, 0x66, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x07, 0x72, 0x61, 0x77, 0x4c, 0x65, 0x61, 0x66, 0x22, 0x49, 0x0a, 0x15, 0x53, 0x75, 0x70, - 0x70, 0x6c, 0x79, 0x4c, 0x65, 0x61, 0x66, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x61, 0x64, - 0x65, 0x72, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, - 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, - 0x68, 0x61, 0x73, 0x68, 0x22, 0xeb, 0x04, 0x0a, 0x19, 0x46, 0x65, 0x74, 0x63, 0x68, 0x53, 0x75, - 0x70, 0x70, 0x6c, 0x79, 0x4c, 0x65, 0x61, 0x76, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x45, 0x0a, 0x0f, 0x69, 0x73, 0x73, 0x75, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x6c, - 0x65, 0x61, 0x76, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x75, 0x6e, + 0x0a, 0x62, 0x75, 0x72, 0x6e, 0x4c, 0x65, 0x61, 0x76, 0x65, 0x73, 0x12, 0x41, 0x0a, 0x0d, 0x69, + 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x5f, 0x6c, 0x65, 0x61, 0x76, 0x65, 0x73, 0x18, 0x08, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, + 0x2e, 0x53, 0x75, 0x70, 0x70, 0x6c, 0x79, 0x4c, 0x65, 0x61, 0x66, 0x45, 0x6e, 0x74, 0x72, 0x79, + 0x52, 0x0c, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x4c, 0x65, 0x61, 0x76, 0x65, 0x73, 0x12, 0x38, + 0x0a, 0x18, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x6f, 0x75, 0x74, 0x73, 0x74, 0x61, 0x6e, 0x64, + 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x75, 0x70, 0x70, 0x6c, 0x79, 0x18, 0x09, 0x20, 0x01, 0x28, 0x04, + 0x52, 0x16, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x4f, 0x75, 0x74, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x69, + 0x6e, 0x67, 0x53, 0x75, 0x70, 0x70, 0x6c, 0x79, 0x12, 0x4c, 0x0a, 0x19, 0x73, 0x70, 0x65, 0x6e, + 0x74, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x6f, 0x75, 0x74, + 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x74, 0x61, + 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4f, 0x75, 0x74, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x17, 0x73, + 0x70, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x4f, 0x75, + 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x5d, 0x0a, 0x0d, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, + 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x38, 0x2e, + 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x46, 0x65, 0x74, 0x63, + 0x68, 0x53, 0x75, 0x70, 0x70, 0x6c, 0x79, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x61, 0x64, 0x65, + 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, + 0x61, 0x64, 0x65, 0x72, 0x73, 0x1a, 0x63, 0x0a, 0x11, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, + 0x61, 0x64, 0x65, 0x72, 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, 0x38, 0x0a, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x75, 0x70, 0x70, 0x6c, 0x79, - 0x4c, 0x65, 0x61, 0x66, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0e, 0x69, 0x73, 0x73, 0x75, 0x61, - 0x6e, 0x63, 0x65, 0x4c, 0x65, 0x61, 0x76, 0x65, 0x73, 0x12, 0x3d, 0x0a, 0x0b, 0x62, 0x75, 0x72, - 0x6e, 0x5f, 0x6c, 0x65, 0x61, 0x76, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, + 0x4c, 0x65, 0x61, 0x66, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x52, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xcd, 0x02, 0x0a, 0x18, 0x46, + 0x65, 0x74, 0x63, 0x68, 0x53, 0x75, 0x70, 0x70, 0x6c, 0x79, 0x4c, 0x65, 0x61, 0x76, 0x65, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x28, 0x0a, 0x0f, 0x67, 0x72, 0x6f, 0x75, 0x70, + 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, + 0x48, 0x00, 0x52, 0x0d, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x4b, 0x65, 0x79, 0x42, 0x79, 0x74, 0x65, + 0x73, 0x12, 0x24, 0x0a, 0x0d, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x73, + 0x74, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0b, 0x67, 0x72, 0x6f, 0x75, + 0x70, 0x4b, 0x65, 0x79, 0x53, 0x74, 0x72, 0x12, 0x2c, 0x0a, 0x12, 0x62, 0x6c, 0x6f, 0x63, 0x6b, + 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x0d, 0x52, 0x10, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, + 0x53, 0x74, 0x61, 0x72, 0x74, 0x12, 0x28, 0x0a, 0x10, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, + 0x65, 0x69, 0x67, 0x68, 0x74, 0x5f, 0x65, 0x6e, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, + 0x0e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x45, 0x6e, 0x64, 0x12, + 0x2c, 0x0a, 0x12, 0x69, 0x73, 0x73, 0x75, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x6c, 0x65, 0x61, 0x66, + 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x10, 0x69, 0x73, 0x73, + 0x75, 0x61, 0x6e, 0x63, 0x65, 0x4c, 0x65, 0x61, 0x66, 0x4b, 0x65, 0x79, 0x73, 0x12, 0x24, 0x0a, + 0x0e, 0x62, 0x75, 0x72, 0x6e, 0x5f, 0x6c, 0x65, 0x61, 0x66, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18, + 0x06, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0c, 0x62, 0x75, 0x72, 0x6e, 0x4c, 0x65, 0x61, 0x66, 0x4b, + 0x65, 0x79, 0x73, 0x12, 0x28, 0x0a, 0x10, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x5f, 0x6c, 0x65, + 0x61, 0x66, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0e, 0x69, + 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x4c, 0x65, 0x61, 0x66, 0x4b, 0x65, 0x79, 0x73, 0x42, 0x0b, 0x0a, + 0x09, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x6b, 0x65, 0x79, 0x22, 0x7c, 0x0a, 0x0d, 0x53, 0x75, + 0x70, 0x70, 0x6c, 0x79, 0x4c, 0x65, 0x61, 0x66, 0x4b, 0x65, 0x79, 0x12, 0x31, 0x0a, 0x08, 0x6f, + 0x75, 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, + 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x4f, 0x75, 0x74, 0x70, + 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x08, 0x6f, 0x75, 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x1d, + 0x0a, 0x0a, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x09, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x4b, 0x65, 0x79, 0x12, 0x19, 0x0a, + 0x08, 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x07, 0x61, 0x73, 0x73, 0x65, 0x74, 0x49, 0x64, 0x22, 0xbf, 0x01, 0x0a, 0x0f, 0x53, 0x75, 0x70, + 0x70, 0x6c, 0x79, 0x4c, 0x65, 0x61, 0x66, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x35, 0x0a, 0x08, + 0x6c, 0x65, 0x61, 0x66, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x75, 0x70, - 0x70, 0x6c, 0x79, 0x4c, 0x65, 0x61, 0x66, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0a, 0x62, 0x75, - 0x72, 0x6e, 0x4c, 0x65, 0x61, 0x76, 0x65, 0x73, 0x12, 0x41, 0x0a, 0x0d, 0x69, 0x67, 0x6e, 0x6f, - 0x72, 0x65, 0x5f, 0x6c, 0x65, 0x61, 0x76, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x70, 0x6c, 0x79, 0x4c, 0x65, 0x61, 0x66, 0x4b, 0x65, 0x79, 0x52, 0x07, 0x6c, 0x65, 0x61, 0x66, + 0x4b, 0x65, 0x79, 0x12, 0x37, 0x0a, 0x09, 0x6c, 0x65, 0x61, 0x66, 0x5f, 0x6e, 0x6f, 0x64, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, + 0x65, 0x72, 0x70, 0x63, 0x2e, 0x4d, 0x65, 0x72, 0x6b, 0x6c, 0x65, 0x53, 0x75, 0x6d, 0x4e, 0x6f, + 0x64, 0x65, 0x52, 0x08, 0x6c, 0x65, 0x61, 0x66, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x21, 0x0a, 0x0c, + 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0d, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, + 0x19, 0x0a, 0x08, 0x72, 0x61, 0x77, 0x5f, 0x6c, 0x65, 0x61, 0x66, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x07, 0x72, 0x61, 0x77, 0x4c, 0x65, 0x61, 0x66, 0x22, 0x49, 0x0a, 0x15, 0x53, 0x75, + 0x70, 0x70, 0x6c, 0x79, 0x4c, 0x65, 0x61, 0x66, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x61, + 0x64, 0x65, 0x72, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, + 0x70, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x04, 0x68, 0x61, 0x73, 0x68, 0x22, 0xeb, 0x04, 0x0a, 0x19, 0x46, 0x65, 0x74, 0x63, 0x68, 0x53, + 0x75, 0x70, 0x70, 0x6c, 0x79, 0x4c, 0x65, 0x61, 0x76, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x45, 0x0a, 0x0f, 0x69, 0x73, 0x73, 0x75, 0x61, 0x6e, 0x63, 0x65, 0x5f, + 0x6c, 0x65, 0x61, 0x76, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x75, + 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x75, 0x70, 0x70, 0x6c, + 0x79, 0x4c, 0x65, 0x61, 0x66, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0e, 0x69, 0x73, 0x73, 0x75, + 0x61, 0x6e, 0x63, 0x65, 0x4c, 0x65, 0x61, 0x76, 0x65, 0x73, 0x12, 0x3d, 0x0a, 0x0b, 0x62, 0x75, + 0x72, 0x6e, 0x5f, 0x6c, 0x65, 0x61, 0x76, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x75, - 0x70, 0x70, 0x6c, 0x79, 0x4c, 0x65, 0x61, 0x66, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0c, 0x69, - 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x4c, 0x65, 0x61, 0x76, 0x65, 0x73, 0x12, 0x43, 0x0a, 0x1e, 0x69, - 0x73, 0x73, 0x75, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x6c, 0x65, 0x61, 0x66, 0x5f, 0x69, 0x6e, 0x63, - 0x6c, 0x75, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x73, 0x18, 0x04, 0x20, - 0x03, 0x28, 0x0c, 0x52, 0x1b, 0x69, 0x73, 0x73, 0x75, 0x61, 0x6e, 0x63, 0x65, 0x4c, 0x65, 0x61, - 0x66, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x73, - 0x12, 0x3b, 0x0a, 0x1a, 0x62, 0x75, 0x72, 0x6e, 0x5f, 0x6c, 0x65, 0x61, 0x66, 0x5f, 0x69, 0x6e, - 0x63, 0x6c, 0x75, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x73, 0x18, 0x05, - 0x20, 0x03, 0x28, 0x0c, 0x52, 0x17, 0x62, 0x75, 0x72, 0x6e, 0x4c, 0x65, 0x61, 0x66, 0x49, 0x6e, - 0x63, 0x6c, 0x75, 0x73, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x73, 0x12, 0x3f, 0x0a, - 0x1c, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x5f, 0x6c, 0x65, 0x61, 0x66, 0x5f, 0x69, 0x6e, 0x63, - 0x6c, 0x75, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x73, 0x18, 0x06, 0x20, - 0x03, 0x28, 0x0c, 0x52, 0x19, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x4c, 0x65, 0x61, 0x66, 0x49, - 0x6e, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x73, 0x12, 0x5d, - 0x0a, 0x0d, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x18, - 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x38, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, - 0x72, 0x70, 0x63, 0x2e, 0x46, 0x65, 0x74, 0x63, 0x68, 0x53, 0x75, 0x70, 0x70, 0x6c, 0x79, 0x4c, - 0x65, 0x61, 0x76, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x42, 0x6c, - 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, - 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x1a, 0x63, 0x0a, - 0x11, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 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, 0x38, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, - 0x63, 0x2e, 0x53, 0x75, 0x70, 0x70, 0x6c, 0x79, 0x4c, 0x65, 0x61, 0x66, 0x42, 0x6c, 0x6f, 0x63, - 0x6b, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, - 0x38, 0x01, 0x22, 0xb7, 0x03, 0x0a, 0x15, 0x53, 0x75, 0x70, 0x70, 0x6c, 0x79, 0x43, 0x6f, 0x6d, - 0x6d, 0x69, 0x74, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x44, 0x61, 0x74, 0x61, 0x12, 0x10, 0x0a, 0x03, - 0x74, 0x78, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x74, 0x78, 0x6e, 0x12, 0x1c, - 0x0a, 0x0a, 0x74, 0x78, 0x5f, 0x6f, 0x75, 0x74, 0x5f, 0x69, 0x64, 0x78, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0d, 0x52, 0x08, 0x74, 0x78, 0x4f, 0x75, 0x74, 0x49, 0x64, 0x78, 0x12, 0x21, 0x0a, 0x0c, - 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x0b, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x4b, 0x65, 0x79, 0x12, - 0x1d, 0x0a, 0x0a, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x4b, 0x65, 0x79, 0x12, 0x28, - 0x0a, 0x10, 0x73, 0x75, 0x70, 0x70, 0x6c, 0x79, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x5f, 0x68, 0x61, - 0x73, 0x68, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0e, 0x73, 0x75, 0x70, 0x70, 0x6c, 0x79, - 0x52, 0x6f, 0x6f, 0x74, 0x48, 0x61, 0x73, 0x68, 0x12, 0x26, 0x0a, 0x0f, 0x73, 0x75, 0x70, 0x70, - 0x6c, 0x79, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x5f, 0x73, 0x75, 0x6d, 0x18, 0x06, 0x20, 0x01, 0x28, - 0x04, 0x52, 0x0d, 0x73, 0x75, 0x70, 0x70, 0x6c, 0x79, 0x52, 0x6f, 0x6f, 0x74, 0x53, 0x75, 0x6d, - 0x12, 0x21, 0x0a, 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, - 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x61, - 0x64, 0x65, 0x72, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x61, 0x73, - 0x68, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x61, - 0x73, 0x68, 0x12, 0x21, 0x0a, 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x65, 0x69, 0x67, - 0x68, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, - 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x31, 0x0a, 0x15, 0x74, 0x78, 0x5f, 0x62, 0x6c, 0x6f, 0x63, - 0x6b, 0x5f, 0x6d, 0x65, 0x72, 0x6b, 0x6c, 0x65, 0x5f, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x18, 0x0a, - 0x20, 0x01, 0x28, 0x0c, 0x52, 0x12, 0x74, 0x78, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x4d, 0x65, 0x72, - 0x6b, 0x6c, 0x65, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x12, 0x19, 0x0a, 0x08, 0x74, 0x78, 0x5f, 0x69, - 0x6e, 0x64, 0x65, 0x78, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x74, 0x78, 0x49, 0x6e, - 0x64, 0x65, 0x78, 0x12, 0x27, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x6f, 0x75, - 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x63, 0x6f, - 0x6d, 0x6d, 0x69, 0x74, 0x4f, 0x75, 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x22, 0xd2, 0x03, 0x0a, - 0x19, 0x49, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x53, 0x75, 0x70, 0x70, 0x6c, 0x79, 0x43, 0x6f, 0x6d, - 0x6d, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x28, 0x0a, 0x0f, 0x67, 0x72, - 0x6f, 0x75, 0x70, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x0d, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x4b, 0x65, 0x79, 0x42, - 0x79, 0x74, 0x65, 0x73, 0x12, 0x24, 0x0a, 0x0d, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x6b, 0x65, - 0x79, 0x5f, 0x73, 0x74, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0b, 0x67, - 0x72, 0x6f, 0x75, 0x70, 0x4b, 0x65, 0x79, 0x53, 0x74, 0x72, 0x12, 0x41, 0x0a, 0x0a, 0x63, 0x68, - 0x61, 0x69, 0x6e, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, - 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x75, 0x70, - 0x70, 0x6c, 0x79, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x44, 0x61, - 0x74, 0x61, 0x52, 0x09, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x44, 0x61, 0x74, 0x61, 0x12, 0x4c, 0x0a, - 0x19, 0x73, 0x70, 0x65, 0x6e, 0x74, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x6d, 0x65, 0x6e, - 0x74, 0x5f, 0x6f, 0x75, 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x10, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4f, 0x75, 0x74, 0x50, 0x6f, 0x69, - 0x6e, 0x74, 0x52, 0x17, 0x73, 0x70, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x6d, - 0x65, 0x6e, 0x74, 0x4f, 0x75, 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x45, 0x0a, 0x0f, 0x69, - 0x73, 0x73, 0x75, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x6c, 0x65, 0x61, 0x76, 0x65, 0x73, 0x18, 0x05, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, - 0x70, 0x63, 0x2e, 0x53, 0x75, 0x70, 0x70, 0x6c, 0x79, 0x4c, 0x65, 0x61, 0x66, 0x45, 0x6e, 0x74, - 0x72, 0x79, 0x52, 0x0e, 0x69, 0x73, 0x73, 0x75, 0x61, 0x6e, 0x63, 0x65, 0x4c, 0x65, 0x61, 0x76, - 0x65, 0x73, 0x12, 0x3d, 0x0a, 0x0b, 0x62, 0x75, 0x72, 0x6e, 0x5f, 0x6c, 0x65, 0x61, 0x76, 0x65, - 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, - 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x75, 0x70, 0x70, 0x6c, 0x79, 0x4c, 0x65, 0x61, 0x66, - 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0a, 0x62, 0x75, 0x72, 0x6e, 0x4c, 0x65, 0x61, 0x76, 0x65, - 0x73, 0x12, 0x41, 0x0a, 0x0d, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x5f, 0x6c, 0x65, 0x61, 0x76, - 0x65, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, + 0x70, 0x70, 0x6c, 0x79, 0x4c, 0x65, 0x61, 0x66, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0a, 0x62, + 0x75, 0x72, 0x6e, 0x4c, 0x65, 0x61, 0x76, 0x65, 0x73, 0x12, 0x41, 0x0a, 0x0d, 0x69, 0x67, 0x6e, + 0x6f, 0x72, 0x65, 0x5f, 0x6c, 0x65, 0x61, 0x76, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x1c, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x53, + 0x75, 0x70, 0x70, 0x6c, 0x79, 0x4c, 0x65, 0x61, 0x66, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0c, + 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x4c, 0x65, 0x61, 0x76, 0x65, 0x73, 0x12, 0x43, 0x0a, 0x1e, + 0x69, 0x73, 0x73, 0x75, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x6c, 0x65, 0x61, 0x66, 0x5f, 0x69, 0x6e, + 0x63, 0x6c, 0x75, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x73, 0x18, 0x04, + 0x20, 0x03, 0x28, 0x0c, 0x52, 0x1b, 0x69, 0x73, 0x73, 0x75, 0x61, 0x6e, 0x63, 0x65, 0x4c, 0x65, + 0x61, 0x66, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x6f, 0x66, + 0x73, 0x12, 0x3b, 0x0a, 0x1a, 0x62, 0x75, 0x72, 0x6e, 0x5f, 0x6c, 0x65, 0x61, 0x66, 0x5f, 0x69, + 0x6e, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x73, 0x18, + 0x05, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x17, 0x62, 0x75, 0x72, 0x6e, 0x4c, 0x65, 0x61, 0x66, 0x49, + 0x6e, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x73, 0x12, 0x3f, + 0x0a, 0x1c, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x5f, 0x6c, 0x65, 0x61, 0x66, 0x5f, 0x69, 0x6e, + 0x63, 0x6c, 0x75, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x73, 0x18, 0x06, + 0x20, 0x03, 0x28, 0x0c, 0x52, 0x19, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x4c, 0x65, 0x61, 0x66, + 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x73, 0x12, + 0x5d, 0x0a, 0x0d, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, + 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x38, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, + 0x65, 0x72, 0x70, 0x63, 0x2e, 0x46, 0x65, 0x74, 0x63, 0x68, 0x53, 0x75, 0x70, 0x70, 0x6c, 0x79, + 0x4c, 0x65, 0x61, 0x76, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x42, + 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, + 0x52, 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x1a, 0x63, + 0x0a, 0x11, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 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, 0x38, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, + 0x70, 0x63, 0x2e, 0x53, 0x75, 0x70, 0x70, 0x6c, 0x79, 0x4c, 0x65, 0x61, 0x66, 0x42, 0x6c, 0x6f, + 0x63, 0x6b, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, + 0x02, 0x38, 0x01, 0x22, 0xb7, 0x03, 0x0a, 0x15, 0x53, 0x75, 0x70, 0x70, 0x6c, 0x79, 0x43, 0x6f, + 0x6d, 0x6d, 0x69, 0x74, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x44, 0x61, 0x74, 0x61, 0x12, 0x10, 0x0a, + 0x03, 0x74, 0x78, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x74, 0x78, 0x6e, 0x12, + 0x1c, 0x0a, 0x0a, 0x74, 0x78, 0x5f, 0x6f, 0x75, 0x74, 0x5f, 0x69, 0x64, 0x78, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0d, 0x52, 0x08, 0x74, 0x78, 0x4f, 0x75, 0x74, 0x49, 0x64, 0x78, 0x12, 0x21, 0x0a, + 0x0c, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x4b, 0x65, 0x79, + 0x12, 0x1d, 0x0a, 0x0a, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x4b, 0x65, 0x79, 0x12, + 0x28, 0x0a, 0x10, 0x73, 0x75, 0x70, 0x70, 0x6c, 0x79, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x5f, 0x68, + 0x61, 0x73, 0x68, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0e, 0x73, 0x75, 0x70, 0x70, 0x6c, + 0x79, 0x52, 0x6f, 0x6f, 0x74, 0x48, 0x61, 0x73, 0x68, 0x12, 0x26, 0x0a, 0x0f, 0x73, 0x75, 0x70, + 0x70, 0x6c, 0x79, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x5f, 0x73, 0x75, 0x6d, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x04, 0x52, 0x0d, 0x73, 0x75, 0x70, 0x70, 0x6c, 0x79, 0x52, 0x6f, 0x6f, 0x74, 0x53, 0x75, + 0x6d, 0x12, 0x21, 0x0a, 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x65, 0x61, 0x64, 0x65, + 0x72, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, + 0x61, 0x64, 0x65, 0x72, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x61, + 0x73, 0x68, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, + 0x61, 0x73, 0x68, 0x12, 0x21, 0x0a, 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x65, 0x69, + 0x67, 0x68, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, + 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x31, 0x0a, 0x15, 0x74, 0x78, 0x5f, 0x62, 0x6c, 0x6f, + 0x63, 0x6b, 0x5f, 0x6d, 0x65, 0x72, 0x6b, 0x6c, 0x65, 0x5f, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x18, + 0x0a, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x12, 0x74, 0x78, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x4d, 0x65, + 0x72, 0x6b, 0x6c, 0x65, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x12, 0x19, 0x0a, 0x08, 0x74, 0x78, 0x5f, + 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x74, 0x78, 0x49, + 0x6e, 0x64, 0x65, 0x78, 0x12, 0x27, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x6f, + 0x75, 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x63, + 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x4f, 0x75, 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x22, 0xd2, 0x03, + 0x0a, 0x19, 0x49, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x53, 0x75, 0x70, 0x70, 0x6c, 0x79, 0x43, 0x6f, + 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x28, 0x0a, 0x0f, 0x67, + 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x0d, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x4b, 0x65, 0x79, + 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x24, 0x0a, 0x0d, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x6b, + 0x65, 0x79, 0x5f, 0x73, 0x74, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0b, + 0x67, 0x72, 0x6f, 0x75, 0x70, 0x4b, 0x65, 0x79, 0x53, 0x74, 0x72, 0x12, 0x41, 0x0a, 0x0a, 0x63, + 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x22, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x75, + 0x70, 0x70, 0x6c, 0x79, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x44, + 0x61, 0x74, 0x61, 0x52, 0x09, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x44, 0x61, 0x74, 0x61, 0x12, 0x4c, + 0x0a, 0x19, 0x73, 0x70, 0x65, 0x6e, 0x74, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x6d, 0x65, + 0x6e, 0x74, 0x5f, 0x6f, 0x75, 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x10, 0x2e, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4f, 0x75, 0x74, 0x50, 0x6f, + 0x69, 0x6e, 0x74, 0x52, 0x17, 0x73, 0x70, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, + 0x6d, 0x65, 0x6e, 0x74, 0x4f, 0x75, 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x45, 0x0a, 0x0f, + 0x69, 0x73, 0x73, 0x75, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x6c, 0x65, 0x61, 0x76, 0x65, 0x73, 0x18, + 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, + 0x72, 0x70, 0x63, 0x2e, 0x53, 0x75, 0x70, 0x70, 0x6c, 0x79, 0x4c, 0x65, 0x61, 0x66, 0x45, 0x6e, + 0x74, 0x72, 0x79, 0x52, 0x0e, 0x69, 0x73, 0x73, 0x75, 0x61, 0x6e, 0x63, 0x65, 0x4c, 0x65, 0x61, + 0x76, 0x65, 0x73, 0x12, 0x3d, 0x0a, 0x0b, 0x62, 0x75, 0x72, 0x6e, 0x5f, 0x6c, 0x65, 0x61, 0x76, + 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x75, 0x70, 0x70, 0x6c, 0x79, 0x4c, 0x65, 0x61, - 0x66, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0c, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x4c, 0x65, - 0x61, 0x76, 0x65, 0x73, 0x42, 0x0b, 0x0a, 0x09, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x6b, 0x65, - 0x79, 0x22, 0x1c, 0x0a, 0x1a, 0x49, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x53, 0x75, 0x70, 0x70, 0x6c, - 0x79, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2a, - 0x59, 0x0a, 0x09, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1a, 0x0a, 0x16, - 0x50, 0x52, 0x4f, 0x4f, 0x46, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, - 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x17, 0x0a, 0x13, 0x50, 0x52, 0x4f, 0x4f, - 0x46, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x49, 0x53, 0x53, 0x55, 0x41, 0x4e, 0x43, 0x45, 0x10, - 0x01, 0x12, 0x17, 0x0a, 0x13, 0x50, 0x52, 0x4f, 0x4f, 0x46, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, - 0x54, 0x52, 0x41, 0x4e, 0x53, 0x46, 0x45, 0x52, 0x10, 0x02, 0x2a, 0x39, 0x0a, 0x10, 0x55, 0x6e, - 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x53, 0x79, 0x6e, 0x63, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x16, - 0x0a, 0x12, 0x53, 0x59, 0x4e, 0x43, 0x5f, 0x49, 0x53, 0x53, 0x55, 0x41, 0x4e, 0x43, 0x45, 0x5f, - 0x4f, 0x4e, 0x4c, 0x59, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x53, 0x59, 0x4e, 0x43, 0x5f, 0x46, - 0x55, 0x4c, 0x4c, 0x10, 0x01, 0x2a, 0xd1, 0x01, 0x0a, 0x0e, 0x41, 0x73, 0x73, 0x65, 0x74, 0x51, - 0x75, 0x65, 0x72, 0x79, 0x53, 0x6f, 0x72, 0x74, 0x12, 0x10, 0x0a, 0x0c, 0x53, 0x4f, 0x52, 0x54, - 0x5f, 0x42, 0x59, 0x5f, 0x4e, 0x4f, 0x4e, 0x45, 0x10, 0x00, 0x12, 0x16, 0x0a, 0x12, 0x53, 0x4f, - 0x52, 0x54, 0x5f, 0x42, 0x59, 0x5f, 0x41, 0x53, 0x53, 0x45, 0x54, 0x5f, 0x4e, 0x41, 0x4d, 0x45, - 0x10, 0x01, 0x12, 0x14, 0x0a, 0x10, 0x53, 0x4f, 0x52, 0x54, 0x5f, 0x42, 0x59, 0x5f, 0x41, 0x53, - 0x53, 0x45, 0x54, 0x5f, 0x49, 0x44, 0x10, 0x02, 0x12, 0x16, 0x0a, 0x12, 0x53, 0x4f, 0x52, 0x54, - 0x5f, 0x42, 0x59, 0x5f, 0x41, 0x53, 0x53, 0x45, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x10, 0x03, - 0x12, 0x17, 0x0a, 0x13, 0x53, 0x4f, 0x52, 0x54, 0x5f, 0x42, 0x59, 0x5f, 0x54, 0x4f, 0x54, 0x41, - 0x4c, 0x5f, 0x53, 0x59, 0x4e, 0x43, 0x53, 0x10, 0x04, 0x12, 0x18, 0x0a, 0x14, 0x53, 0x4f, 0x52, - 0x54, 0x5f, 0x42, 0x59, 0x5f, 0x54, 0x4f, 0x54, 0x41, 0x4c, 0x5f, 0x50, 0x52, 0x4f, 0x4f, 0x46, - 0x53, 0x10, 0x05, 0x12, 0x1a, 0x0a, 0x16, 0x53, 0x4f, 0x52, 0x54, 0x5f, 0x42, 0x59, 0x5f, 0x47, - 0x45, 0x4e, 0x45, 0x53, 0x49, 0x53, 0x5f, 0x48, 0x45, 0x49, 0x47, 0x48, 0x54, 0x10, 0x06, 0x12, - 0x18, 0x0a, 0x14, 0x53, 0x4f, 0x52, 0x54, 0x5f, 0x42, 0x59, 0x5f, 0x54, 0x4f, 0x54, 0x41, 0x4c, - 0x5f, 0x53, 0x55, 0x50, 0x50, 0x4c, 0x59, 0x10, 0x07, 0x2a, 0x40, 0x0a, 0x0d, 0x53, 0x6f, 0x72, - 0x74, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x12, 0x53, 0x4f, - 0x52, 0x54, 0x5f, 0x44, 0x49, 0x52, 0x45, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x41, 0x53, 0x43, - 0x10, 0x00, 0x12, 0x17, 0x0a, 0x13, 0x53, 0x4f, 0x52, 0x54, 0x5f, 0x44, 0x49, 0x52, 0x45, 0x43, - 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x44, 0x45, 0x53, 0x43, 0x10, 0x01, 0x2a, 0x5f, 0x0a, 0x0f, 0x41, - 0x73, 0x73, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x15, - 0x0a, 0x11, 0x46, 0x49, 0x4c, 0x54, 0x45, 0x52, 0x5f, 0x41, 0x53, 0x53, 0x45, 0x54, 0x5f, 0x4e, - 0x4f, 0x4e, 0x45, 0x10, 0x00, 0x12, 0x17, 0x0a, 0x13, 0x46, 0x49, 0x4c, 0x54, 0x45, 0x52, 0x5f, - 0x41, 0x53, 0x53, 0x45, 0x54, 0x5f, 0x4e, 0x4f, 0x52, 0x4d, 0x41, 0x4c, 0x10, 0x01, 0x12, 0x1c, - 0x0a, 0x18, 0x46, 0x49, 0x4c, 0x54, 0x45, 0x52, 0x5f, 0x41, 0x53, 0x53, 0x45, 0x54, 0x5f, 0x43, - 0x4f, 0x4c, 0x4c, 0x45, 0x43, 0x54, 0x49, 0x42, 0x4c, 0x45, 0x10, 0x02, 0x32, 0xf6, 0x10, 0x0a, - 0x08, 0x55, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x12, 0x59, 0x0a, 0x0e, 0x4d, 0x75, 0x6c, - 0x74, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x22, 0x2e, 0x75, 0x6e, - 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x76, - 0x65, 0x72, 0x73, 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x23, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x4d, 0x75, - 0x6c, 0x74, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4b, 0x0a, 0x0a, 0x41, 0x73, 0x73, 0x65, 0x74, 0x52, 0x6f, 0x6f, - 0x74, 0x73, 0x12, 0x1d, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, - 0x2e, 0x41, 0x73, 0x73, 0x65, 0x74, 0x52, 0x6f, 0x6f, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x1e, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, - 0x41, 0x73, 0x73, 0x65, 0x74, 0x52, 0x6f, 0x6f, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x4e, 0x0a, 0x0f, 0x51, 0x75, 0x65, 0x72, 0x79, 0x41, 0x73, 0x73, 0x65, 0x74, 0x52, - 0x6f, 0x6f, 0x74, 0x73, 0x12, 0x1b, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, - 0x70, 0x63, 0x2e, 0x41, 0x73, 0x73, 0x65, 0x74, 0x52, 0x6f, 0x6f, 0x74, 0x51, 0x75, 0x65, 0x72, - 0x79, 0x1a, 0x1e, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, - 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x6f, 0x6f, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x50, 0x0a, 0x0f, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x73, 0x73, 0x65, 0x74, - 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x1c, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, - 0x70, 0x63, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x51, 0x75, 0x65, - 0x72, 0x79, 0x1a, 0x1f, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, - 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x55, 0x0a, 0x0d, 0x41, 0x73, 0x73, 0x65, 0x74, 0x4c, 0x65, 0x61, 0x66, - 0x4b, 0x65, 0x79, 0x73, 0x12, 0x21, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, - 0x70, 0x63, 0x2e, 0x41, 0x73, 0x73, 0x65, 0x74, 0x4c, 0x65, 0x61, 0x66, 0x4b, 0x65, 0x79, 0x73, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, - 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x73, 0x73, 0x65, 0x74, 0x4c, 0x65, 0x61, 0x66, 0x4b, - 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3e, 0x0a, 0x0b, 0x41, 0x73, - 0x73, 0x65, 0x74, 0x4c, 0x65, 0x61, 0x76, 0x65, 0x73, 0x12, 0x0f, 0x2e, 0x75, 0x6e, 0x69, 0x76, - 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x44, 0x1a, 0x1e, 0x2e, 0x75, 0x6e, 0x69, - 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x73, 0x73, 0x65, 0x74, 0x4c, 0x65, - 0x61, 0x66, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x47, 0x0a, 0x0a, 0x51, 0x75, - 0x65, 0x72, 0x79, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x12, 0x18, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, - 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x55, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x4b, - 0x65, 0x79, 0x1a, 0x1f, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, - 0x2e, 0x41, 0x73, 0x73, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x47, 0x0a, 0x0b, 0x49, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x50, 0x72, 0x6f, - 0x6f, 0x66, 0x12, 0x17, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, - 0x2e, 0x41, 0x73, 0x73, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x1a, 0x1f, 0x2e, 0x75, 0x6e, - 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x73, 0x73, 0x65, 0x74, 0x50, - 0x72, 0x6f, 0x6f, 0x66, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4a, 0x0a, 0x09, - 0x50, 0x75, 0x73, 0x68, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x12, 0x1d, 0x2e, 0x75, 0x6e, 0x69, 0x76, - 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x50, 0x75, 0x73, 0x68, 0x50, 0x72, 0x6f, 0x6f, - 0x66, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, + 0x66, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0a, 0x62, 0x75, 0x72, 0x6e, 0x4c, 0x65, 0x61, 0x76, + 0x65, 0x73, 0x12, 0x41, 0x0a, 0x0d, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x5f, 0x6c, 0x65, 0x61, + 0x76, 0x65, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x75, 0x6e, 0x69, 0x76, + 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x75, 0x70, 0x70, 0x6c, 0x79, 0x4c, 0x65, + 0x61, 0x66, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0c, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x4c, + 0x65, 0x61, 0x76, 0x65, 0x73, 0x42, 0x0b, 0x0a, 0x09, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x6b, + 0x65, 0x79, 0x22, 0x1c, 0x0a, 0x1a, 0x49, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x53, 0x75, 0x70, 0x70, + 0x6c, 0x79, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x2a, 0x59, 0x0a, 0x09, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1a, 0x0a, + 0x16, 0x50, 0x52, 0x4f, 0x4f, 0x46, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, + 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x17, 0x0a, 0x13, 0x50, 0x52, 0x4f, + 0x4f, 0x46, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x49, 0x53, 0x53, 0x55, 0x41, 0x4e, 0x43, 0x45, + 0x10, 0x01, 0x12, 0x17, 0x0a, 0x13, 0x50, 0x52, 0x4f, 0x4f, 0x46, 0x5f, 0x54, 0x59, 0x50, 0x45, + 0x5f, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x46, 0x45, 0x52, 0x10, 0x02, 0x2a, 0x39, 0x0a, 0x10, 0x55, + 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x53, 0x79, 0x6e, 0x63, 0x4d, 0x6f, 0x64, 0x65, 0x12, + 0x16, 0x0a, 0x12, 0x53, 0x59, 0x4e, 0x43, 0x5f, 0x49, 0x53, 0x53, 0x55, 0x41, 0x4e, 0x43, 0x45, + 0x5f, 0x4f, 0x4e, 0x4c, 0x59, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x53, 0x59, 0x4e, 0x43, 0x5f, + 0x46, 0x55, 0x4c, 0x4c, 0x10, 0x01, 0x2a, 0xd1, 0x01, 0x0a, 0x0e, 0x41, 0x73, 0x73, 0x65, 0x74, + 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, 0x6f, 0x72, 0x74, 0x12, 0x10, 0x0a, 0x0c, 0x53, 0x4f, 0x52, + 0x54, 0x5f, 0x42, 0x59, 0x5f, 0x4e, 0x4f, 0x4e, 0x45, 0x10, 0x00, 0x12, 0x16, 0x0a, 0x12, 0x53, + 0x4f, 0x52, 0x54, 0x5f, 0x42, 0x59, 0x5f, 0x41, 0x53, 0x53, 0x45, 0x54, 0x5f, 0x4e, 0x41, 0x4d, + 0x45, 0x10, 0x01, 0x12, 0x14, 0x0a, 0x10, 0x53, 0x4f, 0x52, 0x54, 0x5f, 0x42, 0x59, 0x5f, 0x41, + 0x53, 0x53, 0x45, 0x54, 0x5f, 0x49, 0x44, 0x10, 0x02, 0x12, 0x16, 0x0a, 0x12, 0x53, 0x4f, 0x52, + 0x54, 0x5f, 0x42, 0x59, 0x5f, 0x41, 0x53, 0x53, 0x45, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x10, + 0x03, 0x12, 0x17, 0x0a, 0x13, 0x53, 0x4f, 0x52, 0x54, 0x5f, 0x42, 0x59, 0x5f, 0x54, 0x4f, 0x54, + 0x41, 0x4c, 0x5f, 0x53, 0x59, 0x4e, 0x43, 0x53, 0x10, 0x04, 0x12, 0x18, 0x0a, 0x14, 0x53, 0x4f, + 0x52, 0x54, 0x5f, 0x42, 0x59, 0x5f, 0x54, 0x4f, 0x54, 0x41, 0x4c, 0x5f, 0x50, 0x52, 0x4f, 0x4f, + 0x46, 0x53, 0x10, 0x05, 0x12, 0x1a, 0x0a, 0x16, 0x53, 0x4f, 0x52, 0x54, 0x5f, 0x42, 0x59, 0x5f, + 0x47, 0x45, 0x4e, 0x45, 0x53, 0x49, 0x53, 0x5f, 0x48, 0x45, 0x49, 0x47, 0x48, 0x54, 0x10, 0x06, + 0x12, 0x18, 0x0a, 0x14, 0x53, 0x4f, 0x52, 0x54, 0x5f, 0x42, 0x59, 0x5f, 0x54, 0x4f, 0x54, 0x41, + 0x4c, 0x5f, 0x53, 0x55, 0x50, 0x50, 0x4c, 0x59, 0x10, 0x07, 0x2a, 0x5f, 0x0a, 0x0f, 0x41, 0x73, + 0x73, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x15, 0x0a, + 0x11, 0x46, 0x49, 0x4c, 0x54, 0x45, 0x52, 0x5f, 0x41, 0x53, 0x53, 0x45, 0x54, 0x5f, 0x4e, 0x4f, + 0x4e, 0x45, 0x10, 0x00, 0x12, 0x17, 0x0a, 0x13, 0x46, 0x49, 0x4c, 0x54, 0x45, 0x52, 0x5f, 0x41, + 0x53, 0x53, 0x45, 0x54, 0x5f, 0x4e, 0x4f, 0x52, 0x4d, 0x41, 0x4c, 0x10, 0x01, 0x12, 0x1c, 0x0a, + 0x18, 0x46, 0x49, 0x4c, 0x54, 0x45, 0x52, 0x5f, 0x41, 0x53, 0x53, 0x45, 0x54, 0x5f, 0x43, 0x4f, + 0x4c, 0x4c, 0x45, 0x43, 0x54, 0x49, 0x42, 0x4c, 0x45, 0x10, 0x02, 0x32, 0xf6, 0x10, 0x0a, 0x08, + 0x55, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x12, 0x59, 0x0a, 0x0e, 0x4d, 0x75, 0x6c, 0x74, + 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x22, 0x2e, 0x75, 0x6e, 0x69, + 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x76, 0x65, + 0x72, 0x73, 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, + 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x4d, 0x75, 0x6c, + 0x74, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x4b, 0x0a, 0x0a, 0x41, 0x73, 0x73, 0x65, 0x74, 0x52, 0x6f, 0x6f, 0x74, + 0x73, 0x12, 0x1d, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, + 0x41, 0x73, 0x73, 0x65, 0x74, 0x52, 0x6f, 0x6f, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x1e, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x41, + 0x73, 0x73, 0x65, 0x74, 0x52, 0x6f, 0x6f, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x4e, 0x0a, 0x0f, 0x51, 0x75, 0x65, 0x72, 0x79, 0x41, 0x73, 0x73, 0x65, 0x74, 0x52, 0x6f, + 0x6f, 0x74, 0x73, 0x12, 0x1b, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, + 0x63, 0x2e, 0x41, 0x73, 0x73, 0x65, 0x74, 0x52, 0x6f, 0x6f, 0x74, 0x51, 0x75, 0x65, 0x72, 0x79, + 0x1a, 0x1e, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x51, + 0x75, 0x65, 0x72, 0x79, 0x52, 0x6f, 0x6f, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x50, 0x0a, 0x0f, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x73, 0x73, 0x65, 0x74, 0x52, + 0x6f, 0x6f, 0x74, 0x12, 0x1c, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, + 0x63, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x51, 0x75, 0x65, 0x72, + 0x79, 0x1a, 0x1f, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, + 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x55, 0x0a, 0x0d, 0x41, 0x73, 0x73, 0x65, 0x74, 0x4c, 0x65, 0x61, 0x66, 0x4b, + 0x65, 0x79, 0x73, 0x12, 0x21, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, + 0x63, 0x2e, 0x41, 0x73, 0x73, 0x65, 0x74, 0x4c, 0x65, 0x61, 0x66, 0x4b, 0x65, 0x79, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, + 0x65, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x73, 0x73, 0x65, 0x74, 0x4c, 0x65, 0x61, 0x66, 0x4b, 0x65, + 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3e, 0x0a, 0x0b, 0x41, 0x73, 0x73, + 0x65, 0x74, 0x4c, 0x65, 0x61, 0x76, 0x65, 0x73, 0x12, 0x0f, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, + 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x44, 0x1a, 0x1e, 0x2e, 0x75, 0x6e, 0x69, 0x76, + 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x73, 0x73, 0x65, 0x74, 0x4c, 0x65, 0x61, + 0x66, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x47, 0x0a, 0x0a, 0x51, 0x75, 0x65, + 0x72, 0x79, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x12, 0x18, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, + 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x55, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x4b, 0x65, + 0x79, 0x1a, 0x1f, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, + 0x41, 0x73, 0x73, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x47, 0x0a, 0x0b, 0x49, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x50, 0x72, 0x6f, 0x6f, + 0x66, 0x12, 0x17, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, + 0x41, 0x73, 0x73, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x1a, 0x1f, 0x2e, 0x75, 0x6e, 0x69, + 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x73, 0x73, 0x65, 0x74, 0x50, 0x72, + 0x6f, 0x6f, 0x66, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4a, 0x0a, 0x09, 0x50, + 0x75, 0x73, 0x68, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x12, 0x1d, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x50, 0x75, 0x73, 0x68, 0x50, 0x72, 0x6f, 0x6f, 0x66, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x04, 0x49, 0x6e, 0x66, 0x6f, - 0x12, 0x18, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x49, - 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x75, 0x6e, 0x69, - 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x43, 0x0a, 0x0c, 0x53, 0x79, 0x6e, 0x63, 0x55, 0x6e, 0x69, - 0x76, 0x65, 0x72, 0x73, 0x65, 0x12, 0x18, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, - 0x72, 0x70, 0x63, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x19, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x79, - 0x6e, 0x63, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6e, 0x0a, 0x15, 0x4c, 0x69, - 0x73, 0x74, 0x46, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x73, 0x12, 0x29, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, - 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, - 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, + 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x50, 0x75, 0x73, 0x68, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x04, 0x49, 0x6e, 0x66, 0x6f, 0x12, + 0x18, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x6e, + 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x75, 0x6e, 0x69, 0x76, + 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x43, 0x0a, 0x0c, 0x53, 0x79, 0x6e, 0x63, 0x55, 0x6e, 0x69, 0x76, + 0x65, 0x72, 0x73, 0x65, 0x12, 0x18, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, + 0x70, 0x63, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, + 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x79, 0x6e, + 0x63, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6e, 0x0a, 0x15, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x65, - 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x68, 0x0a, 0x13, 0x41, 0x64, - 0x64, 0x46, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x65, - 0x72, 0x12, 0x27, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, - 0x41, 0x64, 0x64, 0x46, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x75, 0x6e, 0x69, - 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x64, 0x64, 0x46, 0x65, 0x64, 0x65, - 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x71, 0x0a, 0x16, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x46, 0x65, - 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x2a, - 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x44, 0x65, 0x6c, - 0x65, 0x74, 0x65, 0x46, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x75, 0x6e, 0x69, - 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x46, - 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x46, 0x0a, 0x0d, 0x55, 0x6e, 0x69, 0x76, 0x65, - 0x72, 0x73, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x19, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, - 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, - 0x63, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x50, 0x0a, 0x0f, 0x51, 0x75, 0x65, 0x72, 0x79, 0x41, 0x73, 0x73, 0x65, 0x74, 0x53, 0x74, 0x61, - 0x74, 0x73, 0x12, 0x1c, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, - 0x2e, 0x41, 0x73, 0x73, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x73, 0x51, 0x75, 0x65, 0x72, 0x79, - 0x1a, 0x1f, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x55, - 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x41, 0x73, 0x73, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, - 0x73, 0x12, 0x50, 0x0a, 0x0b, 0x51, 0x75, 0x65, 0x72, 0x79, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, - 0x12, 0x1f, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x51, - 0x75, 0x65, 0x72, 0x79, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x20, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, - 0x51, 0x75, 0x65, 0x72, 0x79, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x74, 0x0a, 0x17, 0x53, 0x65, 0x74, 0x46, 0x65, 0x64, 0x65, 0x72, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x2b, - 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x74, - 0x46, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x79, 0x6e, 0x63, 0x43, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x75, 0x6e, - 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x74, 0x46, 0x65, 0x64, - 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7a, 0x0a, 0x19, 0x51, 0x75, 0x65, - 0x72, 0x79, 0x46, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x79, 0x6e, 0x63, - 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x2d, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, - 0x65, 0x72, 0x70, 0x63, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x46, 0x65, 0x64, 0x65, 0x72, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, + 0x72, 0x73, 0x12, 0x29, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, + 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, + 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, + 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, + 0x46, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x68, 0x0a, 0x13, 0x41, 0x64, 0x64, + 0x46, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x12, 0x27, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x41, + 0x64, 0x64, 0x46, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x75, 0x6e, 0x69, 0x76, + 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x64, 0x64, 0x46, 0x65, 0x64, 0x65, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x71, 0x0a, 0x16, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x46, 0x65, 0x64, + 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x2a, 0x2e, + 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x44, 0x65, 0x6c, 0x65, + 0x74, 0x65, 0x46, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x75, 0x6e, 0x69, 0x76, + 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x46, 0x65, + 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x46, 0x0a, 0x0d, 0x55, 0x6e, 0x69, 0x76, 0x65, 0x72, + 0x73, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x19, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, + 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, + 0x2e, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x50, + 0x0a, 0x0f, 0x51, 0x75, 0x65, 0x72, 0x79, 0x41, 0x73, 0x73, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, + 0x73, 0x12, 0x1c, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, + 0x41, 0x73, 0x73, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x73, 0x51, 0x75, 0x65, 0x72, 0x79, 0x1a, + 0x1f, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x55, 0x6e, + 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x41, 0x73, 0x73, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x73, + 0x12, 0x50, 0x0a, 0x0b, 0x51, 0x75, 0x65, 0x72, 0x79, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x12, + 0x1f, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x51, 0x75, + 0x65, 0x72, 0x79, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x20, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x51, + 0x75, 0x65, 0x72, 0x79, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x74, 0x0a, 0x17, 0x53, 0x65, 0x74, 0x46, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x53, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x2b, 0x2e, + 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x74, 0x46, + 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x75, 0x6e, 0x69, + 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x74, 0x46, 0x65, 0x64, 0x65, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7a, 0x0a, 0x19, 0x51, 0x75, 0x65, 0x72, + 0x79, 0x46, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x79, 0x6e, 0x63, 0x43, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x2d, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x46, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x53, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x68, 0x0a, 0x13, 0x49, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x41, - 0x73, 0x73, 0x65, 0x74, 0x4f, 0x75, 0x74, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x27, 0x2e, 0x75, - 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x67, 0x6e, 0x6f, 0x72, - 0x65, 0x41, 0x73, 0x73, 0x65, 0x74, 0x4f, 0x75, 0x74, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, - 0x72, 0x70, 0x63, 0x2e, 0x49, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x41, 0x73, 0x73, 0x65, 0x74, 0x4f, - 0x75, 0x74, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x65, 0x0a, 0x12, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6c, 0x79, 0x43, - 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12, 0x26, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, - 0x72, 0x70, 0x63, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6c, 0x79, - 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, - 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x55, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6c, 0x79, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x62, 0x0a, 0x11, 0x46, 0x65, 0x74, 0x63, 0x68, 0x53, - 0x75, 0x70, 0x70, 0x6c, 0x79, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12, 0x25, 0x2e, 0x75, 0x6e, - 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x46, 0x65, 0x74, 0x63, 0x68, 0x53, - 0x75, 0x70, 0x70, 0x6c, 0x79, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, - 0x2e, 0x46, 0x65, 0x74, 0x63, 0x68, 0x53, 0x75, 0x70, 0x70, 0x6c, 0x79, 0x43, 0x6f, 0x6d, 0x6d, - 0x69, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x62, 0x0a, 0x11, 0x46, 0x65, - 0x74, 0x63, 0x68, 0x53, 0x75, 0x70, 0x70, 0x6c, 0x79, 0x4c, 0x65, 0x61, 0x76, 0x65, 0x73, 0x12, - 0x25, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x46, 0x65, - 0x74, 0x63, 0x68, 0x53, 0x75, 0x70, 0x70, 0x6c, 0x79, 0x4c, 0x65, 0x61, 0x76, 0x65, 0x73, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, - 0x65, 0x72, 0x70, 0x63, 0x2e, 0x46, 0x65, 0x74, 0x63, 0x68, 0x53, 0x75, 0x70, 0x70, 0x6c, 0x79, - 0x4c, 0x65, 0x61, 0x76, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x65, - 0x0a, 0x12, 0x49, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x53, 0x75, 0x70, 0x70, 0x6c, 0x79, 0x43, 0x6f, + 0x69, 0x6f, 0x6e, 0x53, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, + 0x70, 0x63, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x46, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x53, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x68, 0x0a, 0x13, 0x49, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x41, 0x73, + 0x73, 0x65, 0x74, 0x4f, 0x75, 0x74, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x27, 0x2e, 0x75, 0x6e, + 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x67, 0x6e, 0x6f, 0x72, 0x65, + 0x41, 0x73, 0x73, 0x65, 0x74, 0x4f, 0x75, 0x74, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, + 0x70, 0x63, 0x2e, 0x49, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x41, 0x73, 0x73, 0x65, 0x74, 0x4f, 0x75, + 0x74, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x65, + 0x0a, 0x12, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6c, 0x79, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12, 0x26, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, - 0x70, 0x63, 0x2e, 0x49, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x53, 0x75, 0x70, 0x70, 0x6c, 0x79, 0x43, + 0x70, 0x63, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6c, 0x79, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x75, - 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x6e, 0x73, 0x65, 0x72, - 0x74, 0x53, 0x75, 0x70, 0x70, 0x6c, 0x79, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x3c, 0x5a, 0x3a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, - 0x63, 0x6f, 0x6d, 0x2f, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x6e, 0x69, 0x6e, 0x67, 0x6c, 0x61, 0x62, - 0x73, 0x2f, 0x74, 0x61, 0x70, 0x72, 0x6f, 0x6f, 0x74, 0x2d, 0x61, 0x73, 0x73, 0x65, 0x74, 0x73, - 0x2f, 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2f, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, - 0x72, 0x70, 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x53, 0x75, 0x70, 0x70, 0x6c, 0x79, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x62, 0x0a, 0x11, 0x46, 0x65, 0x74, 0x63, 0x68, 0x53, 0x75, + 0x70, 0x70, 0x6c, 0x79, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12, 0x25, 0x2e, 0x75, 0x6e, 0x69, + 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x46, 0x65, 0x74, 0x63, 0x68, 0x53, 0x75, + 0x70, 0x70, 0x6c, 0x79, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x26, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, + 0x46, 0x65, 0x74, 0x63, 0x68, 0x53, 0x75, 0x70, 0x70, 0x6c, 0x79, 0x43, 0x6f, 0x6d, 0x6d, 0x69, + 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x62, 0x0a, 0x11, 0x46, 0x65, 0x74, + 0x63, 0x68, 0x53, 0x75, 0x70, 0x70, 0x6c, 0x79, 0x4c, 0x65, 0x61, 0x76, 0x65, 0x73, 0x12, 0x25, + 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x46, 0x65, 0x74, + 0x63, 0x68, 0x53, 0x75, 0x70, 0x70, 0x6c, 0x79, 0x4c, 0x65, 0x61, 0x76, 0x65, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, + 0x72, 0x70, 0x63, 0x2e, 0x46, 0x65, 0x74, 0x63, 0x68, 0x53, 0x75, 0x70, 0x70, 0x6c, 0x79, 0x4c, + 0x65, 0x61, 0x76, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x65, 0x0a, + 0x12, 0x49, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x53, 0x75, 0x70, 0x70, 0x6c, 0x79, 0x43, 0x6f, 0x6d, + 0x6d, 0x69, 0x74, 0x12, 0x26, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, + 0x63, 0x2e, 0x49, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x53, 0x75, 0x70, 0x70, 0x6c, 0x79, 0x43, 0x6f, + 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x75, 0x6e, + 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x6e, 0x73, 0x65, 0x72, 0x74, + 0x53, 0x75, 0x70, 0x70, 0x6c, 0x79, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x3c, 0x5a, 0x3a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, + 0x6f, 0x6d, 0x2f, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x6e, 0x69, 0x6e, 0x67, 0x6c, 0x61, 0x62, 0x73, + 0x2f, 0x74, 0x61, 0x70, 0x72, 0x6f, 0x6f, 0x74, 0x2d, 0x61, 0x73, 0x73, 0x65, 0x74, 0x73, 0x2f, + 0x74, 0x61, 0x70, 0x72, 0x70, 0x63, 0x2f, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, + 0x70, 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -5691,84 +5640,84 @@ func file_universerpc_universe_proto_rawDescGZIP() []byte { return file_universerpc_universe_proto_rawDescData } -var file_universerpc_universe_proto_enumTypes = make([]protoimpl.EnumInfo, 5) +var file_universerpc_universe_proto_enumTypes = make([]protoimpl.EnumInfo, 4) var file_universerpc_universe_proto_msgTypes = make([]protoimpl.MessageInfo, 70) var file_universerpc_universe_proto_goTypes = []any{ (ProofType)(0), // 0: universerpc.ProofType (UniverseSyncMode)(0), // 1: universerpc.UniverseSyncMode (AssetQuerySort)(0), // 2: universerpc.AssetQuerySort - (SortDirection)(0), // 3: universerpc.SortDirection - (AssetTypeFilter)(0), // 4: universerpc.AssetTypeFilter - (*MultiverseRootRequest)(nil), // 5: universerpc.MultiverseRootRequest - (*MultiverseRootResponse)(nil), // 6: universerpc.MultiverseRootResponse - (*AssetRootRequest)(nil), // 7: universerpc.AssetRootRequest - (*MerkleSumNode)(nil), // 8: universerpc.MerkleSumNode - (*ID)(nil), // 9: universerpc.ID - (*UniverseRoot)(nil), // 10: universerpc.UniverseRoot - (*AssetRootResponse)(nil), // 11: universerpc.AssetRootResponse - (*AssetRootQuery)(nil), // 12: universerpc.AssetRootQuery - (*QueryRootResponse)(nil), // 13: universerpc.QueryRootResponse - (*DeleteRootQuery)(nil), // 14: universerpc.DeleteRootQuery - (*DeleteRootResponse)(nil), // 15: universerpc.DeleteRootResponse - (*Outpoint)(nil), // 16: universerpc.Outpoint - (*AssetKey)(nil), // 17: universerpc.AssetKey - (*AssetLeafKeysRequest)(nil), // 18: universerpc.AssetLeafKeysRequest - (*AssetLeafKeyResponse)(nil), // 19: universerpc.AssetLeafKeyResponse - (*AssetLeaf)(nil), // 20: universerpc.AssetLeaf - (*AssetLeafResponse)(nil), // 21: universerpc.AssetLeafResponse - (*UniverseKey)(nil), // 22: universerpc.UniverseKey - (*AssetProofResponse)(nil), // 23: universerpc.AssetProofResponse - (*IssuanceData)(nil), // 24: universerpc.IssuanceData - (*AssetProof)(nil), // 25: universerpc.AssetProof - (*PushProofRequest)(nil), // 26: universerpc.PushProofRequest - (*PushProofResponse)(nil), // 27: universerpc.PushProofResponse - (*InfoRequest)(nil), // 28: universerpc.InfoRequest - (*InfoResponse)(nil), // 29: universerpc.InfoResponse - (*SyncTarget)(nil), // 30: universerpc.SyncTarget - (*SyncRequest)(nil), // 31: universerpc.SyncRequest - (*SyncedUniverse)(nil), // 32: universerpc.SyncedUniverse - (*StatsRequest)(nil), // 33: universerpc.StatsRequest - (*SyncResponse)(nil), // 34: universerpc.SyncResponse - (*UniverseFederationServer)(nil), // 35: universerpc.UniverseFederationServer - (*ListFederationServersRequest)(nil), // 36: universerpc.ListFederationServersRequest - (*ListFederationServersResponse)(nil), // 37: universerpc.ListFederationServersResponse - (*AddFederationServerRequest)(nil), // 38: universerpc.AddFederationServerRequest - (*AddFederationServerResponse)(nil), // 39: universerpc.AddFederationServerResponse - (*DeleteFederationServerRequest)(nil), // 40: universerpc.DeleteFederationServerRequest - (*DeleteFederationServerResponse)(nil), // 41: universerpc.DeleteFederationServerResponse - (*StatsResponse)(nil), // 42: universerpc.StatsResponse - (*AssetStatsQuery)(nil), // 43: universerpc.AssetStatsQuery - (*AssetStatsSnapshot)(nil), // 44: universerpc.AssetStatsSnapshot - (*AssetStatsAsset)(nil), // 45: universerpc.AssetStatsAsset - (*UniverseAssetStats)(nil), // 46: universerpc.UniverseAssetStats - (*QueryEventsRequest)(nil), // 47: universerpc.QueryEventsRequest - (*QueryEventsResponse)(nil), // 48: universerpc.QueryEventsResponse - (*GroupedUniverseEvents)(nil), // 49: universerpc.GroupedUniverseEvents - (*SetFederationSyncConfigRequest)(nil), // 50: universerpc.SetFederationSyncConfigRequest - (*SetFederationSyncConfigResponse)(nil), // 51: universerpc.SetFederationSyncConfigResponse - (*GlobalFederationSyncConfig)(nil), // 52: universerpc.GlobalFederationSyncConfig - (*AssetFederationSyncConfig)(nil), // 53: universerpc.AssetFederationSyncConfig - (*QueryFederationSyncConfigRequest)(nil), // 54: universerpc.QueryFederationSyncConfigRequest - (*QueryFederationSyncConfigResponse)(nil), // 55: universerpc.QueryFederationSyncConfigResponse - (*IgnoreAssetOutPointRequest)(nil), // 56: universerpc.IgnoreAssetOutPointRequest - (*IgnoreAssetOutPointResponse)(nil), // 57: universerpc.IgnoreAssetOutPointResponse - (*UpdateSupplyCommitRequest)(nil), // 58: universerpc.UpdateSupplyCommitRequest - (*UpdateSupplyCommitResponse)(nil), // 59: universerpc.UpdateSupplyCommitResponse - (*FetchSupplyCommitRequest)(nil), // 60: universerpc.FetchSupplyCommitRequest - (*SupplyCommitSubtreeRoot)(nil), // 61: universerpc.SupplyCommitSubtreeRoot - (*FetchSupplyCommitResponse)(nil), // 62: universerpc.FetchSupplyCommitResponse - (*FetchSupplyLeavesRequest)(nil), // 63: universerpc.FetchSupplyLeavesRequest - (*SupplyLeafKey)(nil), // 64: universerpc.SupplyLeafKey - (*SupplyLeafEntry)(nil), // 65: universerpc.SupplyLeafEntry - (*SupplyLeafBlockHeader)(nil), // 66: universerpc.SupplyLeafBlockHeader - (*FetchSupplyLeavesResponse)(nil), // 67: universerpc.FetchSupplyLeavesResponse - (*SupplyCommitChainData)(nil), // 68: universerpc.SupplyCommitChainData - (*InsertSupplyCommitRequest)(nil), // 69: universerpc.InsertSupplyCommitRequest - (*InsertSupplyCommitResponse)(nil), // 70: universerpc.InsertSupplyCommitResponse - nil, // 71: universerpc.UniverseRoot.AmountsByAssetIdEntry - nil, // 72: universerpc.AssetRootResponse.UniverseRootsEntry - nil, // 73: universerpc.FetchSupplyCommitResponse.BlockHeadersEntry - nil, // 74: universerpc.FetchSupplyLeavesResponse.BlockHeadersEntry + (AssetTypeFilter)(0), // 3: universerpc.AssetTypeFilter + (*MultiverseRootRequest)(nil), // 4: universerpc.MultiverseRootRequest + (*MultiverseRootResponse)(nil), // 5: universerpc.MultiverseRootResponse + (*AssetRootRequest)(nil), // 6: universerpc.AssetRootRequest + (*MerkleSumNode)(nil), // 7: universerpc.MerkleSumNode + (*ID)(nil), // 8: universerpc.ID + (*UniverseRoot)(nil), // 9: universerpc.UniverseRoot + (*AssetRootResponse)(nil), // 10: universerpc.AssetRootResponse + (*AssetRootQuery)(nil), // 11: universerpc.AssetRootQuery + (*QueryRootResponse)(nil), // 12: universerpc.QueryRootResponse + (*DeleteRootQuery)(nil), // 13: universerpc.DeleteRootQuery + (*DeleteRootResponse)(nil), // 14: universerpc.DeleteRootResponse + (*Outpoint)(nil), // 15: universerpc.Outpoint + (*AssetKey)(nil), // 16: universerpc.AssetKey + (*AssetLeafKeysRequest)(nil), // 17: universerpc.AssetLeafKeysRequest + (*AssetLeafKeyResponse)(nil), // 18: universerpc.AssetLeafKeyResponse + (*AssetLeaf)(nil), // 19: universerpc.AssetLeaf + (*AssetLeafResponse)(nil), // 20: universerpc.AssetLeafResponse + (*UniverseKey)(nil), // 21: universerpc.UniverseKey + (*AssetProofResponse)(nil), // 22: universerpc.AssetProofResponse + (*IssuanceData)(nil), // 23: universerpc.IssuanceData + (*AssetProof)(nil), // 24: universerpc.AssetProof + (*PushProofRequest)(nil), // 25: universerpc.PushProofRequest + (*PushProofResponse)(nil), // 26: universerpc.PushProofResponse + (*InfoRequest)(nil), // 27: universerpc.InfoRequest + (*InfoResponse)(nil), // 28: universerpc.InfoResponse + (*SyncTarget)(nil), // 29: universerpc.SyncTarget + (*SyncRequest)(nil), // 30: universerpc.SyncRequest + (*SyncedUniverse)(nil), // 31: universerpc.SyncedUniverse + (*StatsRequest)(nil), // 32: universerpc.StatsRequest + (*SyncResponse)(nil), // 33: universerpc.SyncResponse + (*UniverseFederationServer)(nil), // 34: universerpc.UniverseFederationServer + (*ListFederationServersRequest)(nil), // 35: universerpc.ListFederationServersRequest + (*ListFederationServersResponse)(nil), // 36: universerpc.ListFederationServersResponse + (*AddFederationServerRequest)(nil), // 37: universerpc.AddFederationServerRequest + (*AddFederationServerResponse)(nil), // 38: universerpc.AddFederationServerResponse + (*DeleteFederationServerRequest)(nil), // 39: universerpc.DeleteFederationServerRequest + (*DeleteFederationServerResponse)(nil), // 40: universerpc.DeleteFederationServerResponse + (*StatsResponse)(nil), // 41: universerpc.StatsResponse + (*AssetStatsQuery)(nil), // 42: universerpc.AssetStatsQuery + (*AssetStatsSnapshot)(nil), // 43: universerpc.AssetStatsSnapshot + (*AssetStatsAsset)(nil), // 44: universerpc.AssetStatsAsset + (*UniverseAssetStats)(nil), // 45: universerpc.UniverseAssetStats + (*QueryEventsRequest)(nil), // 46: universerpc.QueryEventsRequest + (*QueryEventsResponse)(nil), // 47: universerpc.QueryEventsResponse + (*GroupedUniverseEvents)(nil), // 48: universerpc.GroupedUniverseEvents + (*SetFederationSyncConfigRequest)(nil), // 49: universerpc.SetFederationSyncConfigRequest + (*SetFederationSyncConfigResponse)(nil), // 50: universerpc.SetFederationSyncConfigResponse + (*GlobalFederationSyncConfig)(nil), // 51: universerpc.GlobalFederationSyncConfig + (*AssetFederationSyncConfig)(nil), // 52: universerpc.AssetFederationSyncConfig + (*QueryFederationSyncConfigRequest)(nil), // 53: universerpc.QueryFederationSyncConfigRequest + (*QueryFederationSyncConfigResponse)(nil), // 54: universerpc.QueryFederationSyncConfigResponse + (*IgnoreAssetOutPointRequest)(nil), // 55: universerpc.IgnoreAssetOutPointRequest + (*IgnoreAssetOutPointResponse)(nil), // 56: universerpc.IgnoreAssetOutPointResponse + (*UpdateSupplyCommitRequest)(nil), // 57: universerpc.UpdateSupplyCommitRequest + (*UpdateSupplyCommitResponse)(nil), // 58: universerpc.UpdateSupplyCommitResponse + (*FetchSupplyCommitRequest)(nil), // 59: universerpc.FetchSupplyCommitRequest + (*SupplyCommitSubtreeRoot)(nil), // 60: universerpc.SupplyCommitSubtreeRoot + (*FetchSupplyCommitResponse)(nil), // 61: universerpc.FetchSupplyCommitResponse + (*FetchSupplyLeavesRequest)(nil), // 62: universerpc.FetchSupplyLeavesRequest + (*SupplyLeafKey)(nil), // 63: universerpc.SupplyLeafKey + (*SupplyLeafEntry)(nil), // 64: universerpc.SupplyLeafEntry + (*SupplyLeafBlockHeader)(nil), // 65: universerpc.SupplyLeafBlockHeader + (*FetchSupplyLeavesResponse)(nil), // 66: universerpc.FetchSupplyLeavesResponse + (*SupplyCommitChainData)(nil), // 67: universerpc.SupplyCommitChainData + (*InsertSupplyCommitRequest)(nil), // 68: universerpc.InsertSupplyCommitRequest + (*InsertSupplyCommitResponse)(nil), // 69: universerpc.InsertSupplyCommitResponse + nil, // 70: universerpc.UniverseRoot.AmountsByAssetIdEntry + nil, // 71: universerpc.AssetRootResponse.UniverseRootsEntry + nil, // 72: universerpc.FetchSupplyCommitResponse.BlockHeadersEntry + nil, // 73: universerpc.FetchSupplyLeavesResponse.BlockHeadersEntry + (taprpc.SortDirection)(0), // 74: taprpc.SortDirection (*taprpc.Asset)(nil), // 75: taprpc.Asset (*taprpc.AssetMeta)(nil), // 76: taprpc.AssetMeta (*taprpc.GenesisReveal)(nil), // 77: taprpc.GenesisReveal @@ -5779,141 +5728,141 @@ var file_universerpc_universe_proto_goTypes = []any{ } var file_universerpc_universe_proto_depIdxs = []int32{ 0, // 0: universerpc.MultiverseRootRequest.proof_type:type_name -> universerpc.ProofType - 9, // 1: universerpc.MultiverseRootRequest.specific_ids:type_name -> universerpc.ID - 8, // 2: universerpc.MultiverseRootResponse.multiverse_root:type_name -> universerpc.MerkleSumNode - 3, // 3: universerpc.AssetRootRequest.direction:type_name -> universerpc.SortDirection + 8, // 1: universerpc.MultiverseRootRequest.specific_ids:type_name -> universerpc.ID + 7, // 2: universerpc.MultiverseRootResponse.multiverse_root:type_name -> universerpc.MerkleSumNode + 74, // 3: universerpc.AssetRootRequest.direction:type_name -> taprpc.SortDirection 0, // 4: universerpc.ID.proof_type:type_name -> universerpc.ProofType - 9, // 5: universerpc.UniverseRoot.id:type_name -> universerpc.ID - 8, // 6: universerpc.UniverseRoot.mssmt_root:type_name -> universerpc.MerkleSumNode - 71, // 7: universerpc.UniverseRoot.amounts_by_asset_id:type_name -> universerpc.UniverseRoot.AmountsByAssetIdEntry - 72, // 8: universerpc.AssetRootResponse.universe_roots:type_name -> universerpc.AssetRootResponse.UniverseRootsEntry - 9, // 9: universerpc.AssetRootQuery.id:type_name -> universerpc.ID - 10, // 10: universerpc.QueryRootResponse.issuance_root:type_name -> universerpc.UniverseRoot - 10, // 11: universerpc.QueryRootResponse.transfer_root:type_name -> universerpc.UniverseRoot - 9, // 12: universerpc.DeleteRootQuery.id:type_name -> universerpc.ID - 16, // 13: universerpc.AssetKey.op:type_name -> universerpc.Outpoint - 9, // 14: universerpc.AssetLeafKeysRequest.id:type_name -> universerpc.ID - 3, // 15: universerpc.AssetLeafKeysRequest.direction:type_name -> universerpc.SortDirection - 17, // 16: universerpc.AssetLeafKeyResponse.asset_keys:type_name -> universerpc.AssetKey + 8, // 5: universerpc.UniverseRoot.id:type_name -> universerpc.ID + 7, // 6: universerpc.UniverseRoot.mssmt_root:type_name -> universerpc.MerkleSumNode + 70, // 7: universerpc.UniverseRoot.amounts_by_asset_id:type_name -> universerpc.UniverseRoot.AmountsByAssetIdEntry + 71, // 8: universerpc.AssetRootResponse.universe_roots:type_name -> universerpc.AssetRootResponse.UniverseRootsEntry + 8, // 9: universerpc.AssetRootQuery.id:type_name -> universerpc.ID + 9, // 10: universerpc.QueryRootResponse.issuance_root:type_name -> universerpc.UniverseRoot + 9, // 11: universerpc.QueryRootResponse.transfer_root:type_name -> universerpc.UniverseRoot + 8, // 12: universerpc.DeleteRootQuery.id:type_name -> universerpc.ID + 15, // 13: universerpc.AssetKey.op:type_name -> universerpc.Outpoint + 8, // 14: universerpc.AssetLeafKeysRequest.id:type_name -> universerpc.ID + 74, // 15: universerpc.AssetLeafKeysRequest.direction:type_name -> taprpc.SortDirection + 16, // 16: universerpc.AssetLeafKeyResponse.asset_keys:type_name -> universerpc.AssetKey 75, // 17: universerpc.AssetLeaf.asset:type_name -> taprpc.Asset - 20, // 18: universerpc.AssetLeafResponse.leaves:type_name -> universerpc.AssetLeaf - 9, // 19: universerpc.UniverseKey.id:type_name -> universerpc.ID - 17, // 20: universerpc.UniverseKey.leaf_key:type_name -> universerpc.AssetKey - 22, // 21: universerpc.AssetProofResponse.req:type_name -> universerpc.UniverseKey - 10, // 22: universerpc.AssetProofResponse.universe_root:type_name -> universerpc.UniverseRoot - 20, // 23: universerpc.AssetProofResponse.asset_leaf:type_name -> universerpc.AssetLeaf - 8, // 24: universerpc.AssetProofResponse.multiverse_root:type_name -> universerpc.MerkleSumNode - 24, // 25: universerpc.AssetProofResponse.issuance_data:type_name -> universerpc.IssuanceData + 19, // 18: universerpc.AssetLeafResponse.leaves:type_name -> universerpc.AssetLeaf + 8, // 19: universerpc.UniverseKey.id:type_name -> universerpc.ID + 16, // 20: universerpc.UniverseKey.leaf_key:type_name -> universerpc.AssetKey + 21, // 21: universerpc.AssetProofResponse.req:type_name -> universerpc.UniverseKey + 9, // 22: universerpc.AssetProofResponse.universe_root:type_name -> universerpc.UniverseRoot + 19, // 23: universerpc.AssetProofResponse.asset_leaf:type_name -> universerpc.AssetLeaf + 7, // 24: universerpc.AssetProofResponse.multiverse_root:type_name -> universerpc.MerkleSumNode + 23, // 25: universerpc.AssetProofResponse.issuance_data:type_name -> universerpc.IssuanceData 76, // 26: universerpc.IssuanceData.meta_reveal:type_name -> taprpc.AssetMeta 77, // 27: universerpc.IssuanceData.genesis_reveal:type_name -> taprpc.GenesisReveal 78, // 28: universerpc.IssuanceData.group_key_reveal:type_name -> taprpc.GroupKeyReveal - 22, // 29: universerpc.AssetProof.key:type_name -> universerpc.UniverseKey - 20, // 30: universerpc.AssetProof.asset_leaf:type_name -> universerpc.AssetLeaf - 22, // 31: universerpc.PushProofRequest.key:type_name -> universerpc.UniverseKey - 35, // 32: universerpc.PushProofRequest.server:type_name -> universerpc.UniverseFederationServer - 22, // 33: universerpc.PushProofResponse.key:type_name -> universerpc.UniverseKey - 9, // 34: universerpc.SyncTarget.id:type_name -> universerpc.ID + 21, // 29: universerpc.AssetProof.key:type_name -> universerpc.UniverseKey + 19, // 30: universerpc.AssetProof.asset_leaf:type_name -> universerpc.AssetLeaf + 21, // 31: universerpc.PushProofRequest.key:type_name -> universerpc.UniverseKey + 34, // 32: universerpc.PushProofRequest.server:type_name -> universerpc.UniverseFederationServer + 21, // 33: universerpc.PushProofResponse.key:type_name -> universerpc.UniverseKey + 8, // 34: universerpc.SyncTarget.id:type_name -> universerpc.ID 1, // 35: universerpc.SyncRequest.sync_mode:type_name -> universerpc.UniverseSyncMode - 30, // 36: universerpc.SyncRequest.sync_targets:type_name -> universerpc.SyncTarget - 10, // 37: universerpc.SyncedUniverse.old_asset_root:type_name -> universerpc.UniverseRoot - 10, // 38: universerpc.SyncedUniverse.new_asset_root:type_name -> universerpc.UniverseRoot - 20, // 39: universerpc.SyncedUniverse.new_asset_leaves:type_name -> universerpc.AssetLeaf - 32, // 40: universerpc.SyncResponse.synced_universes:type_name -> universerpc.SyncedUniverse - 35, // 41: universerpc.ListFederationServersResponse.servers:type_name -> universerpc.UniverseFederationServer - 35, // 42: universerpc.AddFederationServerRequest.servers:type_name -> universerpc.UniverseFederationServer - 35, // 43: universerpc.DeleteFederationServerRequest.servers:type_name -> universerpc.UniverseFederationServer - 4, // 44: universerpc.AssetStatsQuery.asset_type_filter:type_name -> universerpc.AssetTypeFilter + 29, // 36: universerpc.SyncRequest.sync_targets:type_name -> universerpc.SyncTarget + 9, // 37: universerpc.SyncedUniverse.old_asset_root:type_name -> universerpc.UniverseRoot + 9, // 38: universerpc.SyncedUniverse.new_asset_root:type_name -> universerpc.UniverseRoot + 19, // 39: universerpc.SyncedUniverse.new_asset_leaves:type_name -> universerpc.AssetLeaf + 31, // 40: universerpc.SyncResponse.synced_universes:type_name -> universerpc.SyncedUniverse + 34, // 41: universerpc.ListFederationServersResponse.servers:type_name -> universerpc.UniverseFederationServer + 34, // 42: universerpc.AddFederationServerRequest.servers:type_name -> universerpc.UniverseFederationServer + 34, // 43: universerpc.DeleteFederationServerRequest.servers:type_name -> universerpc.UniverseFederationServer + 3, // 44: universerpc.AssetStatsQuery.asset_type_filter:type_name -> universerpc.AssetTypeFilter 2, // 45: universerpc.AssetStatsQuery.sort_by:type_name -> universerpc.AssetQuerySort - 3, // 46: universerpc.AssetStatsQuery.direction:type_name -> universerpc.SortDirection - 45, // 47: universerpc.AssetStatsSnapshot.group_anchor:type_name -> universerpc.AssetStatsAsset - 45, // 48: universerpc.AssetStatsSnapshot.asset:type_name -> universerpc.AssetStatsAsset + 74, // 46: universerpc.AssetStatsQuery.direction:type_name -> taprpc.SortDirection + 44, // 47: universerpc.AssetStatsSnapshot.group_anchor:type_name -> universerpc.AssetStatsAsset + 44, // 48: universerpc.AssetStatsSnapshot.asset:type_name -> universerpc.AssetStatsAsset 79, // 49: universerpc.AssetStatsAsset.asset_type:type_name -> taprpc.AssetType - 44, // 50: universerpc.UniverseAssetStats.asset_stats:type_name -> universerpc.AssetStatsSnapshot - 49, // 51: universerpc.QueryEventsResponse.events:type_name -> universerpc.GroupedUniverseEvents - 52, // 52: universerpc.SetFederationSyncConfigRequest.global_sync_configs:type_name -> universerpc.GlobalFederationSyncConfig - 53, // 53: universerpc.SetFederationSyncConfigRequest.asset_sync_configs:type_name -> universerpc.AssetFederationSyncConfig + 43, // 50: universerpc.UniverseAssetStats.asset_stats:type_name -> universerpc.AssetStatsSnapshot + 48, // 51: universerpc.QueryEventsResponse.events:type_name -> universerpc.GroupedUniverseEvents + 51, // 52: universerpc.SetFederationSyncConfigRequest.global_sync_configs:type_name -> universerpc.GlobalFederationSyncConfig + 52, // 53: universerpc.SetFederationSyncConfigRequest.asset_sync_configs:type_name -> universerpc.AssetFederationSyncConfig 0, // 54: universerpc.GlobalFederationSyncConfig.proof_type:type_name -> universerpc.ProofType - 9, // 55: universerpc.AssetFederationSyncConfig.id:type_name -> universerpc.ID - 9, // 56: universerpc.QueryFederationSyncConfigRequest.id:type_name -> universerpc.ID - 52, // 57: universerpc.QueryFederationSyncConfigResponse.global_sync_configs:type_name -> universerpc.GlobalFederationSyncConfig - 53, // 58: universerpc.QueryFederationSyncConfigResponse.asset_sync_configs:type_name -> universerpc.AssetFederationSyncConfig + 8, // 55: universerpc.AssetFederationSyncConfig.id:type_name -> universerpc.ID + 8, // 56: universerpc.QueryFederationSyncConfigRequest.id:type_name -> universerpc.ID + 51, // 57: universerpc.QueryFederationSyncConfigResponse.global_sync_configs:type_name -> universerpc.GlobalFederationSyncConfig + 52, // 58: universerpc.QueryFederationSyncConfigResponse.asset_sync_configs:type_name -> universerpc.AssetFederationSyncConfig 80, // 59: universerpc.IgnoreAssetOutPointRequest.asset_out_point:type_name -> taprpc.AssetOutPoint - 8, // 60: universerpc.IgnoreAssetOutPointResponse.leaf:type_name -> universerpc.MerkleSumNode + 7, // 60: universerpc.IgnoreAssetOutPointResponse.leaf:type_name -> universerpc.MerkleSumNode 81, // 61: universerpc.FetchSupplyCommitRequest.commit_outpoint:type_name -> taprpc.OutPoint 81, // 62: universerpc.FetchSupplyCommitRequest.spent_commit_outpoint:type_name -> taprpc.OutPoint - 8, // 63: universerpc.SupplyCommitSubtreeRoot.root_node:type_name -> universerpc.MerkleSumNode - 68, // 64: universerpc.FetchSupplyCommitResponse.chain_data:type_name -> universerpc.SupplyCommitChainData - 61, // 65: universerpc.FetchSupplyCommitResponse.issuance_subtree_root:type_name -> universerpc.SupplyCommitSubtreeRoot - 61, // 66: universerpc.FetchSupplyCommitResponse.burn_subtree_root:type_name -> universerpc.SupplyCommitSubtreeRoot - 61, // 67: universerpc.FetchSupplyCommitResponse.ignore_subtree_root:type_name -> universerpc.SupplyCommitSubtreeRoot - 65, // 68: universerpc.FetchSupplyCommitResponse.issuance_leaves:type_name -> universerpc.SupplyLeafEntry - 65, // 69: universerpc.FetchSupplyCommitResponse.burn_leaves:type_name -> universerpc.SupplyLeafEntry - 65, // 70: universerpc.FetchSupplyCommitResponse.ignore_leaves:type_name -> universerpc.SupplyLeafEntry + 7, // 63: universerpc.SupplyCommitSubtreeRoot.root_node:type_name -> universerpc.MerkleSumNode + 67, // 64: universerpc.FetchSupplyCommitResponse.chain_data:type_name -> universerpc.SupplyCommitChainData + 60, // 65: universerpc.FetchSupplyCommitResponse.issuance_subtree_root:type_name -> universerpc.SupplyCommitSubtreeRoot + 60, // 66: universerpc.FetchSupplyCommitResponse.burn_subtree_root:type_name -> universerpc.SupplyCommitSubtreeRoot + 60, // 67: universerpc.FetchSupplyCommitResponse.ignore_subtree_root:type_name -> universerpc.SupplyCommitSubtreeRoot + 64, // 68: universerpc.FetchSupplyCommitResponse.issuance_leaves:type_name -> universerpc.SupplyLeafEntry + 64, // 69: universerpc.FetchSupplyCommitResponse.burn_leaves:type_name -> universerpc.SupplyLeafEntry + 64, // 70: universerpc.FetchSupplyCommitResponse.ignore_leaves:type_name -> universerpc.SupplyLeafEntry 81, // 71: universerpc.FetchSupplyCommitResponse.spent_commitment_outpoint:type_name -> taprpc.OutPoint - 73, // 72: universerpc.FetchSupplyCommitResponse.block_headers:type_name -> universerpc.FetchSupplyCommitResponse.BlockHeadersEntry - 16, // 73: universerpc.SupplyLeafKey.outpoint:type_name -> universerpc.Outpoint - 64, // 74: universerpc.SupplyLeafEntry.leaf_key:type_name -> universerpc.SupplyLeafKey - 8, // 75: universerpc.SupplyLeafEntry.leaf_node:type_name -> universerpc.MerkleSumNode - 65, // 76: universerpc.FetchSupplyLeavesResponse.issuance_leaves:type_name -> universerpc.SupplyLeafEntry - 65, // 77: universerpc.FetchSupplyLeavesResponse.burn_leaves:type_name -> universerpc.SupplyLeafEntry - 65, // 78: universerpc.FetchSupplyLeavesResponse.ignore_leaves:type_name -> universerpc.SupplyLeafEntry - 74, // 79: universerpc.FetchSupplyLeavesResponse.block_headers:type_name -> universerpc.FetchSupplyLeavesResponse.BlockHeadersEntry - 68, // 80: universerpc.InsertSupplyCommitRequest.chain_data:type_name -> universerpc.SupplyCommitChainData + 72, // 72: universerpc.FetchSupplyCommitResponse.block_headers:type_name -> universerpc.FetchSupplyCommitResponse.BlockHeadersEntry + 15, // 73: universerpc.SupplyLeafKey.outpoint:type_name -> universerpc.Outpoint + 63, // 74: universerpc.SupplyLeafEntry.leaf_key:type_name -> universerpc.SupplyLeafKey + 7, // 75: universerpc.SupplyLeafEntry.leaf_node:type_name -> universerpc.MerkleSumNode + 64, // 76: universerpc.FetchSupplyLeavesResponse.issuance_leaves:type_name -> universerpc.SupplyLeafEntry + 64, // 77: universerpc.FetchSupplyLeavesResponse.burn_leaves:type_name -> universerpc.SupplyLeafEntry + 64, // 78: universerpc.FetchSupplyLeavesResponse.ignore_leaves:type_name -> universerpc.SupplyLeafEntry + 73, // 79: universerpc.FetchSupplyLeavesResponse.block_headers:type_name -> universerpc.FetchSupplyLeavesResponse.BlockHeadersEntry + 67, // 80: universerpc.InsertSupplyCommitRequest.chain_data:type_name -> universerpc.SupplyCommitChainData 81, // 81: universerpc.InsertSupplyCommitRequest.spent_commitment_outpoint:type_name -> taprpc.OutPoint - 65, // 82: universerpc.InsertSupplyCommitRequest.issuance_leaves:type_name -> universerpc.SupplyLeafEntry - 65, // 83: universerpc.InsertSupplyCommitRequest.burn_leaves:type_name -> universerpc.SupplyLeafEntry - 65, // 84: universerpc.InsertSupplyCommitRequest.ignore_leaves:type_name -> universerpc.SupplyLeafEntry - 10, // 85: universerpc.AssetRootResponse.UniverseRootsEntry.value:type_name -> universerpc.UniverseRoot - 66, // 86: universerpc.FetchSupplyCommitResponse.BlockHeadersEntry.value:type_name -> universerpc.SupplyLeafBlockHeader - 66, // 87: universerpc.FetchSupplyLeavesResponse.BlockHeadersEntry.value:type_name -> universerpc.SupplyLeafBlockHeader - 5, // 88: universerpc.Universe.MultiverseRoot:input_type -> universerpc.MultiverseRootRequest - 7, // 89: universerpc.Universe.AssetRoots:input_type -> universerpc.AssetRootRequest - 12, // 90: universerpc.Universe.QueryAssetRoots:input_type -> universerpc.AssetRootQuery - 14, // 91: universerpc.Universe.DeleteAssetRoot:input_type -> universerpc.DeleteRootQuery - 18, // 92: universerpc.Universe.AssetLeafKeys:input_type -> universerpc.AssetLeafKeysRequest - 9, // 93: universerpc.Universe.AssetLeaves:input_type -> universerpc.ID - 22, // 94: universerpc.Universe.QueryProof:input_type -> universerpc.UniverseKey - 25, // 95: universerpc.Universe.InsertProof:input_type -> universerpc.AssetProof - 26, // 96: universerpc.Universe.PushProof:input_type -> universerpc.PushProofRequest - 28, // 97: universerpc.Universe.Info:input_type -> universerpc.InfoRequest - 31, // 98: universerpc.Universe.SyncUniverse:input_type -> universerpc.SyncRequest - 36, // 99: universerpc.Universe.ListFederationServers:input_type -> universerpc.ListFederationServersRequest - 38, // 100: universerpc.Universe.AddFederationServer:input_type -> universerpc.AddFederationServerRequest - 40, // 101: universerpc.Universe.DeleteFederationServer:input_type -> universerpc.DeleteFederationServerRequest - 33, // 102: universerpc.Universe.UniverseStats:input_type -> universerpc.StatsRequest - 43, // 103: universerpc.Universe.QueryAssetStats:input_type -> universerpc.AssetStatsQuery - 47, // 104: universerpc.Universe.QueryEvents:input_type -> universerpc.QueryEventsRequest - 50, // 105: universerpc.Universe.SetFederationSyncConfig:input_type -> universerpc.SetFederationSyncConfigRequest - 54, // 106: universerpc.Universe.QueryFederationSyncConfig:input_type -> universerpc.QueryFederationSyncConfigRequest - 56, // 107: universerpc.Universe.IgnoreAssetOutPoint:input_type -> universerpc.IgnoreAssetOutPointRequest - 58, // 108: universerpc.Universe.UpdateSupplyCommit:input_type -> universerpc.UpdateSupplyCommitRequest - 60, // 109: universerpc.Universe.FetchSupplyCommit:input_type -> universerpc.FetchSupplyCommitRequest - 63, // 110: universerpc.Universe.FetchSupplyLeaves:input_type -> universerpc.FetchSupplyLeavesRequest - 69, // 111: universerpc.Universe.InsertSupplyCommit:input_type -> universerpc.InsertSupplyCommitRequest - 6, // 112: universerpc.Universe.MultiverseRoot:output_type -> universerpc.MultiverseRootResponse - 11, // 113: universerpc.Universe.AssetRoots:output_type -> universerpc.AssetRootResponse - 13, // 114: universerpc.Universe.QueryAssetRoots:output_type -> universerpc.QueryRootResponse - 15, // 115: universerpc.Universe.DeleteAssetRoot:output_type -> universerpc.DeleteRootResponse - 19, // 116: universerpc.Universe.AssetLeafKeys:output_type -> universerpc.AssetLeafKeyResponse - 21, // 117: universerpc.Universe.AssetLeaves:output_type -> universerpc.AssetLeafResponse - 23, // 118: universerpc.Universe.QueryProof:output_type -> universerpc.AssetProofResponse - 23, // 119: universerpc.Universe.InsertProof:output_type -> universerpc.AssetProofResponse - 27, // 120: universerpc.Universe.PushProof:output_type -> universerpc.PushProofResponse - 29, // 121: universerpc.Universe.Info:output_type -> universerpc.InfoResponse - 34, // 122: universerpc.Universe.SyncUniverse:output_type -> universerpc.SyncResponse - 37, // 123: universerpc.Universe.ListFederationServers:output_type -> universerpc.ListFederationServersResponse - 39, // 124: universerpc.Universe.AddFederationServer:output_type -> universerpc.AddFederationServerResponse - 41, // 125: universerpc.Universe.DeleteFederationServer:output_type -> universerpc.DeleteFederationServerResponse - 42, // 126: universerpc.Universe.UniverseStats:output_type -> universerpc.StatsResponse - 46, // 127: universerpc.Universe.QueryAssetStats:output_type -> universerpc.UniverseAssetStats - 48, // 128: universerpc.Universe.QueryEvents:output_type -> universerpc.QueryEventsResponse - 51, // 129: universerpc.Universe.SetFederationSyncConfig:output_type -> universerpc.SetFederationSyncConfigResponse - 55, // 130: universerpc.Universe.QueryFederationSyncConfig:output_type -> universerpc.QueryFederationSyncConfigResponse - 57, // 131: universerpc.Universe.IgnoreAssetOutPoint:output_type -> universerpc.IgnoreAssetOutPointResponse - 59, // 132: universerpc.Universe.UpdateSupplyCommit:output_type -> universerpc.UpdateSupplyCommitResponse - 62, // 133: universerpc.Universe.FetchSupplyCommit:output_type -> universerpc.FetchSupplyCommitResponse - 67, // 134: universerpc.Universe.FetchSupplyLeaves:output_type -> universerpc.FetchSupplyLeavesResponse - 70, // 135: universerpc.Universe.InsertSupplyCommit:output_type -> universerpc.InsertSupplyCommitResponse + 64, // 82: universerpc.InsertSupplyCommitRequest.issuance_leaves:type_name -> universerpc.SupplyLeafEntry + 64, // 83: universerpc.InsertSupplyCommitRequest.burn_leaves:type_name -> universerpc.SupplyLeafEntry + 64, // 84: universerpc.InsertSupplyCommitRequest.ignore_leaves:type_name -> universerpc.SupplyLeafEntry + 9, // 85: universerpc.AssetRootResponse.UniverseRootsEntry.value:type_name -> universerpc.UniverseRoot + 65, // 86: universerpc.FetchSupplyCommitResponse.BlockHeadersEntry.value:type_name -> universerpc.SupplyLeafBlockHeader + 65, // 87: universerpc.FetchSupplyLeavesResponse.BlockHeadersEntry.value:type_name -> universerpc.SupplyLeafBlockHeader + 4, // 88: universerpc.Universe.MultiverseRoot:input_type -> universerpc.MultiverseRootRequest + 6, // 89: universerpc.Universe.AssetRoots:input_type -> universerpc.AssetRootRequest + 11, // 90: universerpc.Universe.QueryAssetRoots:input_type -> universerpc.AssetRootQuery + 13, // 91: universerpc.Universe.DeleteAssetRoot:input_type -> universerpc.DeleteRootQuery + 17, // 92: universerpc.Universe.AssetLeafKeys:input_type -> universerpc.AssetLeafKeysRequest + 8, // 93: universerpc.Universe.AssetLeaves:input_type -> universerpc.ID + 21, // 94: universerpc.Universe.QueryProof:input_type -> universerpc.UniverseKey + 24, // 95: universerpc.Universe.InsertProof:input_type -> universerpc.AssetProof + 25, // 96: universerpc.Universe.PushProof:input_type -> universerpc.PushProofRequest + 27, // 97: universerpc.Universe.Info:input_type -> universerpc.InfoRequest + 30, // 98: universerpc.Universe.SyncUniverse:input_type -> universerpc.SyncRequest + 35, // 99: universerpc.Universe.ListFederationServers:input_type -> universerpc.ListFederationServersRequest + 37, // 100: universerpc.Universe.AddFederationServer:input_type -> universerpc.AddFederationServerRequest + 39, // 101: universerpc.Universe.DeleteFederationServer:input_type -> universerpc.DeleteFederationServerRequest + 32, // 102: universerpc.Universe.UniverseStats:input_type -> universerpc.StatsRequest + 42, // 103: universerpc.Universe.QueryAssetStats:input_type -> universerpc.AssetStatsQuery + 46, // 104: universerpc.Universe.QueryEvents:input_type -> universerpc.QueryEventsRequest + 49, // 105: universerpc.Universe.SetFederationSyncConfig:input_type -> universerpc.SetFederationSyncConfigRequest + 53, // 106: universerpc.Universe.QueryFederationSyncConfig:input_type -> universerpc.QueryFederationSyncConfigRequest + 55, // 107: universerpc.Universe.IgnoreAssetOutPoint:input_type -> universerpc.IgnoreAssetOutPointRequest + 57, // 108: universerpc.Universe.UpdateSupplyCommit:input_type -> universerpc.UpdateSupplyCommitRequest + 59, // 109: universerpc.Universe.FetchSupplyCommit:input_type -> universerpc.FetchSupplyCommitRequest + 62, // 110: universerpc.Universe.FetchSupplyLeaves:input_type -> universerpc.FetchSupplyLeavesRequest + 68, // 111: universerpc.Universe.InsertSupplyCommit:input_type -> universerpc.InsertSupplyCommitRequest + 5, // 112: universerpc.Universe.MultiverseRoot:output_type -> universerpc.MultiverseRootResponse + 10, // 113: universerpc.Universe.AssetRoots:output_type -> universerpc.AssetRootResponse + 12, // 114: universerpc.Universe.QueryAssetRoots:output_type -> universerpc.QueryRootResponse + 14, // 115: universerpc.Universe.DeleteAssetRoot:output_type -> universerpc.DeleteRootResponse + 18, // 116: universerpc.Universe.AssetLeafKeys:output_type -> universerpc.AssetLeafKeyResponse + 20, // 117: universerpc.Universe.AssetLeaves:output_type -> universerpc.AssetLeafResponse + 22, // 118: universerpc.Universe.QueryProof:output_type -> universerpc.AssetProofResponse + 22, // 119: universerpc.Universe.InsertProof:output_type -> universerpc.AssetProofResponse + 26, // 120: universerpc.Universe.PushProof:output_type -> universerpc.PushProofResponse + 28, // 121: universerpc.Universe.Info:output_type -> universerpc.InfoResponse + 33, // 122: universerpc.Universe.SyncUniverse:output_type -> universerpc.SyncResponse + 36, // 123: universerpc.Universe.ListFederationServers:output_type -> universerpc.ListFederationServersResponse + 38, // 124: universerpc.Universe.AddFederationServer:output_type -> universerpc.AddFederationServerResponse + 40, // 125: universerpc.Universe.DeleteFederationServer:output_type -> universerpc.DeleteFederationServerResponse + 41, // 126: universerpc.Universe.UniverseStats:output_type -> universerpc.StatsResponse + 45, // 127: universerpc.Universe.QueryAssetStats:output_type -> universerpc.UniverseAssetStats + 47, // 128: universerpc.Universe.QueryEvents:output_type -> universerpc.QueryEventsResponse + 50, // 129: universerpc.Universe.SetFederationSyncConfig:output_type -> universerpc.SetFederationSyncConfigResponse + 54, // 130: universerpc.Universe.QueryFederationSyncConfig:output_type -> universerpc.QueryFederationSyncConfigResponse + 56, // 131: universerpc.Universe.IgnoreAssetOutPoint:output_type -> universerpc.IgnoreAssetOutPointResponse + 58, // 132: universerpc.Universe.UpdateSupplyCommit:output_type -> universerpc.UpdateSupplyCommitResponse + 61, // 133: universerpc.Universe.FetchSupplyCommit:output_type -> universerpc.FetchSupplyCommitResponse + 66, // 134: universerpc.Universe.FetchSupplyLeaves:output_type -> universerpc.FetchSupplyLeavesResponse + 69, // 135: universerpc.Universe.InsertSupplyCommit:output_type -> universerpc.InsertSupplyCommitResponse 112, // [112:136] is the sub-list for method output_type 88, // [88:112] is the sub-list for method input_type 88, // [88:88] is the sub-list for extension type_name @@ -6757,7 +6706,7 @@ func file_universerpc_universe_proto_init() { File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_universerpc_universe_proto_rawDesc, - NumEnums: 5, + NumEnums: 4, NumMessages: 70, NumExtensions: 0, NumServices: 1, diff --git a/taprpc/universerpc/universe.proto b/taprpc/universerpc/universe.proto index bfe414325..0eab1ca5b 100644 --- a/taprpc/universerpc/universe.proto +++ b/taprpc/universerpc/universe.proto @@ -225,7 +225,7 @@ message AssetRootRequest { int32 limit = 3; // The direction of the page. - SortDirection direction = 4; + taprpc.SortDirection direction = 4; // TODO(roasbeef): filter by asset ID, etc? } @@ -352,7 +352,7 @@ message AssetLeafKeysRequest { int32 limit = 3; // The direction of the page. - SortDirection direction = 4; + taprpc.SortDirection direction = 4; } message AssetLeafKeyResponse { @@ -566,12 +566,6 @@ enum AssetQuerySort { SORT_BY_TOTAL_SUPPLY = 7; } -enum SortDirection { - SORT_DIRECTION_ASC = 0; - - SORT_DIRECTION_DESC = 1; -} - enum AssetTypeFilter { FILTER_ASSET_NONE = 0; @@ -606,7 +600,7 @@ message AssetStatsQuery { // The direction of the sort. If this is set to SORT_DIRECTION_ASC, then // the results are sorted in ascending order. If set to // SORT_DIRECTION_DESC, then the results are sorted in descending order. - SortDirection direction = 7; + taprpc.SortDirection direction = 7; } message AssetStatsSnapshot { diff --git a/taprpc/universerpc/universe.swagger.json b/taprpc/universerpc/universe.swagger.json index 66446797a..765b31e7b 100644 --- a/taprpc/universerpc/universe.swagger.json +++ b/taprpc/universerpc/universe.swagger.json @@ -260,15 +260,15 @@ }, { "name": "direction", - "description": "The direction of the page.", + "description": "The direction of the page.\n\n - SORT_DIRECTION_DESC: Sort results in descending order.\n - SORT_DIRECTION_ASC: Sort results in ascending order.", "in": "query", "required": false, "type": "string", "enum": [ - "SORT_DIRECTION_ASC", - "SORT_DIRECTION_DESC" + "SORT_DIRECTION_DESC", + "SORT_DIRECTION_ASC" ], - "default": "SORT_DIRECTION_ASC" + "default": "SORT_DIRECTION_DESC" } ], "tags": [ @@ -355,15 +355,15 @@ }, { "name": "direction", - "description": "The direction of the page.", + "description": "The direction of the page.\n\n - SORT_DIRECTION_DESC: Sort results in descending order.\n - SORT_DIRECTION_ASC: Sort results in ascending order.", "in": "query", "required": false, "type": "string", "enum": [ - "SORT_DIRECTION_ASC", - "SORT_DIRECTION_DESC" + "SORT_DIRECTION_DESC", + "SORT_DIRECTION_ASC" ], - "default": "SORT_DIRECTION_ASC" + "default": "SORT_DIRECTION_DESC" } ], "tags": [ @@ -1028,15 +1028,15 @@ }, { "name": "direction", - "description": "The direction of the page.", + "description": "The direction of the page.\n\n - SORT_DIRECTION_DESC: Sort results in descending order.\n - SORT_DIRECTION_ASC: Sort results in ascending order.", "in": "query", "required": false, "type": "string", "enum": [ - "SORT_DIRECTION_ASC", - "SORT_DIRECTION_DESC" + "SORT_DIRECTION_DESC", + "SORT_DIRECTION_ASC" ], - "default": "SORT_DIRECTION_ASC" + "default": "SORT_DIRECTION_DESC" } ], "tags": [ @@ -1284,15 +1284,15 @@ }, { "name": "direction", - "description": "The direction of the sort. If this is set to SORT_DIRECTION_ASC, then\nthe results are sorted in ascending order. If set to\nSORT_DIRECTION_DESC, then the results are sorted in descending order.", + "description": "The direction of the sort. If this is set to SORT_DIRECTION_ASC, then\nthe results are sorted in ascending order. If set to\nSORT_DIRECTION_DESC, then the results are sorted in descending order.\n\n - SORT_DIRECTION_DESC: Sort results in descending order.\n - SORT_DIRECTION_ASC: Sort results in ascending order.", "in": "query", "required": false, "type": "string", "enum": [ - "SORT_DIRECTION_ASC", - "SORT_DIRECTION_DESC" + "SORT_DIRECTION_DESC", + "SORT_DIRECTION_ASC" ], - "default": "SORT_DIRECTION_ASC" + "default": "SORT_DIRECTION_DESC" } ], "tags": [ @@ -2278,6 +2278,15 @@ "default": "SCRIPT_KEY_UNKNOWN", "description": " - SCRIPT_KEY_UNKNOWN: The type of script key is not known. This should only be stored for assets\nwhere we don't know the internal key of the script key (e.g. for imported\nproofs).\n - SCRIPT_KEY_BIP86: The script key is a normal BIP-86 key. This means that the internal key is\nturned into a Taproot output key by applying a BIP-86 tweak to it.\n - SCRIPT_KEY_SCRIPT_PATH_EXTERNAL: The script key is a key that contains a script path that is defined by the\nuser and is therefore external to the tapd wallet. Spending this key\nrequires providing a specific witness and must be signed through the vPSBT\nsigning flow.\n - SCRIPT_KEY_BURN: The script key is a specific un-spendable key that indicates a burnt asset.\nAssets with this key type can never be spent again, as a burn key is a\ntweaked NUMS key that nobody knows the private key for.\n - SCRIPT_KEY_TOMBSTONE: The script key is a specific un-spendable key that indicates a tombstone\noutput. This is only the case for zero-value assets that result from a\nnon-interactive (TAP address) send where no change was left over.\n - SCRIPT_KEY_CHANNEL: The script key is used for an asset that resides within a Taproot Asset\nChannel. That means the script key is either a funding key (OP_TRUE), a\ncommitment output key (to_local, to_remote, htlc), or a HTLC second-level\ntransaction output key. Keys related to channels are not shown in asset\nbalances (unless specifically requested) and are never used for coin\nselection.\n - SCRIPT_KEY_UNIQUE_PEDERSEN: The script key is derived using the asset ID and a single leaf that contains\nan un-spendable Pedersen commitment key\n`(OP_CHECKSIG \u003cNUMS_key + asset_id * G\u003e)`. This can be used to create\nunique script keys for each virtual packet in the fragment, to avoid proof\ncollisions in the universe, where the script keys should be spendable by\na hardware wallet that only supports miniscript policies for signing P2TR\noutputs." }, + "taprpcSortDirection": { + "type": "string", + "enum": [ + "SORT_DIRECTION_DESC", + "SORT_DIRECTION_ASC" + ], + "default": "SORT_DIRECTION_DESC", + "description": " - SORT_DIRECTION_DESC: Sort results in descending order.\n - SORT_DIRECTION_ASC: Sort results in ascending order." + }, "taprpcSplitCommitment": { "type": "object", "properties": { @@ -2935,14 +2944,6 @@ "universerpcSetFederationSyncConfigResponse": { "type": "object" }, - "universerpcSortDirection": { - "type": "string", - "enum": [ - "SORT_DIRECTION_ASC", - "SORT_DIRECTION_DESC" - ], - "default": "SORT_DIRECTION_ASC" - }, "universerpcStatsResponse": { "type": "object", "properties": { diff --git a/universe/interface.go b/universe/interface.go index 914d435eb..3fa37713f 100644 --- a/universe/interface.go +++ b/universe/interface.go @@ -393,17 +393,22 @@ type Proof struct { MultiverseInclusionProof *mssmt.Proof } +// LowerBoundByteSize returns the lower bound on the byte size of the proof. +func (p *Proof) LowerBoundByteSize() uint64 { + return fn.LowerBoundByteSize(p) +} + // VerifyRoot verifies that the inclusion proof for the root node matches the // specified root. This is useful for sanity checking an issuance proof against -// the purported root, and the included leaf. -func (i *Proof) VerifyRoot(expectedRoot mssmt.Node) bool { - leafNode := i.Leaf.SmtLeafNode() +// the purported root and the included leaf. +func (p *Proof) VerifyRoot(expectedRoot mssmt.Node) bool { + leafNode := p.Leaf.SmtLeafNode() - reconstructedRoot := i.UniverseInclusionProof.Root( - i.LeafKey.UniverseKey(), leafNode, + reconstructedRoot := p.UniverseInclusionProof.Root( + p.LeafKey.UniverseKey(), leafNode, ) - return mssmt.IsEqualNode(i.UniverseRoot, expectedRoot) && + return mssmt.IsEqualNode(p.UniverseRoot, expectedRoot) && mssmt.IsEqualNode(reconstructedRoot, expectedRoot) } diff --git a/universe/supplycommit/mock.go b/universe/supplycommit/mock.go index fb45158eb..c19379b54 100644 --- a/universe/supplycommit/mock.go +++ b/universe/supplycommit/mock.go @@ -14,6 +14,7 @@ import ( "github.com/lightninglabs/taproot-assets/fn" "github.com/lightninglabs/taproot-assets/mssmt" "github.com/lightninglabs/taproot-assets/proof" + "github.com/lightninglabs/taproot-assets/tapgarden" "github.com/lightninglabs/taproot-assets/tapsend" "github.com/lightningnetwork/lnd/chainntnfs" lfn "github.com/lightningnetwork/lnd/fn/v2" @@ -268,10 +269,10 @@ func (m *mockChainBridge) VerifyBlock(ctx context.Context, } func (m *mockChainBridge) GetBlockTimestamp(ctx context.Context, - height uint32) int64 { + height uint32) (int64, error) { args := m.Called(ctx, height) - return args.Get(0).(int64) + return args.Get(0).(int64), args.Error(1) } func (m *mockChainBridge) GenFileChainLookup(f *proof.File) asset.ChainLookup { @@ -289,6 +290,9 @@ func (m *mockChainBridge) GenProofChainLookup( return args.Get(0).(asset.ChainLookup), args.Error(1) } +// Ensure mockChainBridge implements the tapgarden.ChainBridge interface. +var _ tapgarden.ChainBridge = (*mockChainBridge)(nil) + // mockStateMachineStore is a mock implementation of the StateMachineStore // interface. type mockStateMachineStore struct { diff --git a/universe_rpc_diff.go b/universe_rpc_diff.go index 9ffdfe465..469253bb2 100644 --- a/universe_rpc_diff.go +++ b/universe_rpc_diff.go @@ -7,6 +7,7 @@ import ( "github.com/lightninglabs/taproot-assets/fn" "github.com/lightninglabs/taproot-assets/mssmt" + "github.com/lightninglabs/taproot-assets/taprpc" "github.com/lightninglabs/taproot-assets/taprpc/universerpc" unirpc "github.com/lightninglabs/taproot-assets/taprpc/universerpc" "github.com/lightninglabs/taproot-assets/universe" @@ -85,7 +86,7 @@ func (r *RpcUniverseDiff) RootNodes(ctx context.Context, WithAmountsById: q.WithAmountsById, Offset: q.Offset, Limit: q.Limit, - Direction: unirpc.SortDirection(q.SortDirection), + Direction: taprpc.SortDirection(q.SortDirection), }, ) if err != nil { @@ -147,7 +148,7 @@ func (r *RpcUniverseDiff) UniverseLeafKeys(ctx context.Context, assetKeys, err := r.conn.AssetLeafKeys( ctx, &unirpc.AssetLeafKeysRequest{ Id: uniID, - Direction: unirpc.SortDirection(q.SortDirection), + Direction: taprpc.SortDirection(q.SortDirection), Offset: q.Offset, Limit: q.Limit, },