From 7400499b0045a42be508ba80b36aa396b510ed30 Mon Sep 17 00:00:00 2001 From: Oliver Gugger Date: Thu, 26 Oct 2023 21:35:18 +0200 Subject: [PATCH 01/16] tapdb: format and reflow comments --- tapdb/universe.go | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/tapdb/universe.go b/tapdb/universe.go index e754f23bf..d5eba58c3 100644 --- a/tapdb/universe.go +++ b/tapdb/universe.go @@ -340,8 +340,7 @@ func (b *BaseUniverseTree) RegisterIssuance(ctx context.Context, // broader DB updates. func universeUpsertProofLeaf(ctx context.Context, dbTx BaseUniverseStore, id universe.Identifier, key universe.LeafKey, leaf *universe.Leaf, - metaReveal *proof.MetaReveal, -) (*universe.Proof, mssmt.Node, error) { + metaReveal *proof.MetaReveal) (*universe.Proof, mssmt.Node, error) { namespace := id.String() @@ -349,8 +348,8 @@ func universeUpsertProofLeaf(ctx context.Context, dbTx BaseUniverseStore, // the minting key, as that'll be the key in the SMT itself. smtKey := key.UniverseKey() - // The value stored in the MS-SMT will be the serialized Leaf, - // so we'll convert that into raw bytes now. + // The value stored in the MS-SMT will be the serialized Leaf, so we'll + // convert that into raw bytes now. leafNode := leaf.SmtLeafNode() var groupKeyBytes []byte @@ -368,23 +367,21 @@ func universeUpsertProofLeaf(ctx context.Context, dbTx BaseUniverseStore, universeRoot mssmt.Node ) - // First, we'll instantiate a new compact tree instance from the - // backing tree store. + // First, we'll instantiate a new compact tree instance from the backing + // tree store. universeTree := mssmt.NewCompactedTree( newTreeStoreWrapperTx(dbTx, namespace), ) - // Now that we have a tree instance linked to this DB - // transaction, we'll insert the leaf into the tree based on - // its SMT key. + // Now that we have a tree instance linked to this DB transaction, we'll + // insert the leaf into the tree based on its SMT key. _, err = universeTree.Insert(ctx, smtKey, leafNode) if err != nil { return nil, nil, err } - // Next, we'll upsert the universe root in the DB, which gives - // us the root ID that we'll use to insert the universe leaf - // overlay. + // Next, we'll upsert the universe root in the DB, which gives us the + // root ID that we'll use to insert the universe leaf overlay. universeRootID, err := dbTx.UpsertUniverseRoot(ctx, NewUniverseRoot{ NamespaceRoot: namespace, AssetID: fn.ByteSlice(leaf.ID()), @@ -395,9 +392,9 @@ func universeUpsertProofLeaf(ctx context.Context, dbTx BaseUniverseStore, return nil, nil, err } - // Before we insert the asset genesis, we'll insert the meta - // first. The reveal may or may not be populated, which'll also - // insert the opaque meta blob on disk. + // Before we insert the asset genesis, we'll insert the meta first. The + // reveal may or may not be populated, which'll also insert the opaque + // meta blob on disk. _, err = maybeUpsertAssetMeta(ctx, dbTx, &leaf.Genesis, metaReveal) if err != nil { return nil, nil, err @@ -429,8 +426,8 @@ func universeUpsertProofLeaf(ctx context.Context, dbTx BaseUniverseStore, return nil, nil, err } - // Finally, we'll obtain the merkle proof from the tree for the - // leaf we just inserted. + // Finally, we'll obtain the merkle proof from the tree for the leaf we + // just inserted. leafInclusionProof, err = universeTree.MerkleProof(ctx, smtKey) if err != nil { return nil, nil, err From 1afc90b9efa8b42f9570b67ae1a3a6bb99e95983 Mon Sep 17 00:00:00 2001 From: Oliver Gugger Date: Thu, 26 Oct 2023 21:35:19 +0200 Subject: [PATCH 02/16] tapdb: add new multiverse root overlay tables and queries This commit adds two new tables for the two multiverse trees we currently have: multiverse_roots (will currently only contain two entries, one for the issuance and one for the transfer multiverse roots) and multiverse_leaves (which will contain an entry for each issuance and proof universe we currently have). We already have all information needed to fill these tables for existing universes, so we can use conditional INSERT statements to create the entries for all existing universes. Any new universes will be added through the new upsert methods added. --- tapdb/postgres.go | 1 + .../000014_multiverse_tree.down.sql | 3 + .../migrations/000014_multiverse_tree.up.sql | 87 ++++++++++++ tapdb/sqlc/models.go | 15 +++ tapdb/sqlc/querier.go | 4 + tapdb/sqlc/queries/universe.sql | 36 ++++- tapdb/sqlc/universe.sql.go | 124 ++++++++++++++++++ 7 files changed, 269 insertions(+), 1 deletion(-) create mode 100644 tapdb/sqlc/migrations/000014_multiverse_tree.down.sql create mode 100644 tapdb/sqlc/migrations/000014_multiverse_tree.up.sql diff --git a/tapdb/postgres.go b/tapdb/postgres.go index 1d4e5b745..8dc3c01a0 100644 --- a/tapdb/postgres.go +++ b/tapdb/postgres.go @@ -39,6 +39,7 @@ var ( "INTEGER PRIMARY KEY": "SERIAL PRIMARY KEY", "BIGINT PRIMARY KEY": "BIGSERIAL PRIMARY KEY", "TIMESTAMP": "TIMESTAMP WITHOUT TIME ZONE", + "UNHEX": "DECODE", } ) diff --git a/tapdb/sqlc/migrations/000014_multiverse_tree.down.sql b/tapdb/sqlc/migrations/000014_multiverse_tree.down.sql new file mode 100644 index 000000000..1ab6273c6 --- /dev/null +++ b/tapdb/sqlc/migrations/000014_multiverse_tree.down.sql @@ -0,0 +1,3 @@ +DROP INDEX IF EXISTS multiverse_leaves_unique; +DROP TABLE IF EXISTS multiverse_leaves; +DROP TABLE IF EXISTS multiverse_roots; diff --git a/tapdb/sqlc/migrations/000014_multiverse_tree.up.sql b/tapdb/sqlc/migrations/000014_multiverse_tree.up.sql new file mode 100644 index 000000000..bf98c9716 --- /dev/null +++ b/tapdb/sqlc/migrations/000014_multiverse_tree.up.sql @@ -0,0 +1,87 @@ +CREATE TABLE IF NOT EXISTS multiverse_roots ( + id BIGINT PRIMARY KEY, + + -- For the namespace root, we set the foreign key constraint evaluation to + -- be deferred until after the database transaction ends. Otherwise, if the + -- root of the SMT is deleted temporarily before inserting a new root, then + -- this constraint is violated as there's no longer a root that this + -- universe tree can point to. + namespace_root VARCHAR UNIQUE NOT NULL REFERENCES mssmt_roots(namespace) DEFERRABLE INITIALLY DEFERRED, + + -- This field is an enum representing the proof type stored in the given + -- universe. + proof_type TEXT NOT NULL CHECK(proof_type IN ('issuance', 'transfer')) +); + +CREATE TABLE IF NOT EXISTS multiverse_leaves ( + id BIGINT PRIMARY KEY, + + multiverse_root_id BIGINT NOT NULL REFERENCES multiverse_roots(id), + + asset_id BLOB CHECK(length(asset_id) = 32), + + -- We use the 32 byte schnorr key here as this is what's used to derive the + -- top-level Taproot Asset commitment key. + group_key BLOB CHECK(LENGTH(group_key) = 32), + + leaf_node_key BLOB NOT NULL, + + leaf_node_namespace VARCHAR NOT NULL, + + -- Both the asset ID and group key cannot be null at the same time. + CHECK ( + (asset_id IS NOT NULL AND group_key IS NULL) OR + (asset_id IS NULL AND group_key IS NOT NULL) + ) +); + +CREATE UNIQUE INDEX multiverse_leaves_unique ON multiverse_leaves ( + leaf_node_key, leaf_node_namespace +); + +-- If there already is a multiverse root entry in the mssmt_roots for the +-- issuance or transfer multiverses, add them to the multiverse_roots table as +-- well. Both statements are no-ops if the root doesn't exist yet. +INSERT INTO multiverse_roots (namespace_root, proof_type) +SELECT 'multiverse-issuance', 'issuance' +WHERE EXISTS ( + SELECT 1 FROM mssmt_roots WHERE namespace = 'multiverse-issuance' +); + +INSERT INTO multiverse_roots (namespace_root, proof_type) +SELECT 'multiverse-transfer', 'transfer' +WHERE EXISTS ( + SELECT 1 FROM mssmt_roots WHERE namespace = 'multiverse-transfer' +); + +-- And now we create the multiverse_leaves entries for the multiverse roots. +-- This is a no-op if the multiverse root doesn't exist yet. +INSERT INTO multiverse_leaves ( + multiverse_root_id, asset_id, group_key, leaf_node_key, leaf_node_namespace +) SELECT + (SELECT id from multiverse_roots mr where mr.namespace_root = 'multiverse-issuance'), + CASE WHEN ur.group_key IS NULL THEN ur.asset_id ELSE NULL END, + ur.group_key, + -- UNHEX() only exists in SQLite and it doesn't take a second argument + -- (the 'hex' part). But it also doesn't complain about it, so we can + -- leave it in for the Postgres version which is replaced in-memory to + -- DECODE() which needs the 'hex' argument. + UNHEX(REPLACE(ur.namespace_root, 'issuance-', ''), 'hex'), + ur.namespace_root + FROM universe_roots ur + WHERE ur.namespace_root LIKE 'issuance-%'; + +INSERT INTO multiverse_leaves ( + multiverse_root_id, asset_id, group_key, leaf_node_key, leaf_node_namespace +) SELECT + (SELECT id from multiverse_roots mr where mr.namespace_root = 'multiverse-transfer'), + CASE WHEN ur.group_key IS NULL THEN ur.asset_id ELSE NULL END, + ur.group_key, + -- UNHEX() only exists in SQLite and it doesn't take a second argument + -- (the 'hex' part). But it also doesn't complain about it, so we can + -- leave it in for the Postgres version which is replaced in-memory to + -- DECODE() which needs the 'hex' argument. + UNHEX(REPLACE(ur.namespace_root, 'transfer-', ''), 'hex'), + ur.namespace_root +FROM universe_roots ur +WHERE ur.namespace_root LIKE 'transfer-%'; diff --git a/tapdb/sqlc/models.go b/tapdb/sqlc/models.go index 26eef9b5d..784ab41d9 100644 --- a/tapdb/sqlc/models.go +++ b/tapdb/sqlc/models.go @@ -264,6 +264,21 @@ type MssmtRoot struct { RootHash []byte } +type MultiverseLeafe struct { + ID int64 + MultiverseRootID int64 + AssetID []byte + GroupKey []byte + LeafNodeKey []byte + LeafNodeNamespace string +} + +type MultiverseRoot struct { + ID int64 + NamespaceRoot string + ProofType string +} + type PassiveAsset struct { PassiveID int64 TransferID int64 diff --git a/tapdb/sqlc/querier.go b/tapdb/sqlc/querier.go index 3a9a6b27a..dc105d7de 100644 --- a/tapdb/sqlc/querier.go +++ b/tapdb/sqlc/querier.go @@ -27,6 +27,7 @@ type Querier interface { DeleteExpiredUTXOLeases(ctx context.Context, now sql.NullTime) error DeleteFederationProofSyncLog(ctx context.Context, arg DeleteFederationProofSyncLogParams) error DeleteManagedUTXO(ctx context.Context, outpoint []byte) error + DeleteMultiverseLeaf(ctx context.Context, arg DeleteMultiverseLeafParams) error DeleteNode(ctx context.Context, arg DeleteNodeParams) (int64, error) DeleteRoot(ctx context.Context, namespace string) (int64, error) DeleteUTXOLease(ctx context.Context, outpoint []byte) error @@ -126,6 +127,7 @@ type Querier interface { // Join on genesis_info_view to get leaf related fields. QueryFederationProofSyncLog(ctx context.Context, arg QueryFederationProofSyncLogParams) ([]QueryFederationProofSyncLogRow, error) QueryFederationUniSyncConfigs(ctx context.Context) ([]FederationUniSyncConfig, error) + QueryMultiverseLeaves(ctx context.Context, arg QueryMultiverseLeavesParams) ([]QueryMultiverseLeavesRow, error) QueryPassiveAssets(ctx context.Context, transferID int64) ([]QueryPassiveAssetsRow, error) QueryProofTransferAttempts(ctx context.Context, arg QueryProofTransferAttemptsParams) ([]time.Time, error) // TODO(roasbeef): use the universe id instead for the grouping? so namespace @@ -155,6 +157,8 @@ type Querier interface { UpsertGenesisPoint(ctx context.Context, prevOut []byte) (int64, error) UpsertInternalKey(ctx context.Context, arg UpsertInternalKeyParams) (int64, error) UpsertManagedUTXO(ctx context.Context, arg UpsertManagedUTXOParams) (int64, error) + UpsertMultiverseLeaf(ctx context.Context, arg UpsertMultiverseLeafParams) (int64, error) + UpsertMultiverseRoot(ctx context.Context, arg UpsertMultiverseRootParams) (int64, error) UpsertRootNode(ctx context.Context, arg UpsertRootNodeParams) error UpsertScriptKey(ctx context.Context, arg UpsertScriptKeyParams) (int64, error) UpsertUniverseLeaf(ctx context.Context, arg UpsertUniverseLeafParams) error diff --git a/tapdb/sqlc/queries/universe.sql b/tapdb/sqlc/queries/universe.sql index 767c50f25..4e2d12835 100644 --- a/tapdb/sqlc/queries/universe.sql +++ b/tapdb/sqlc/queries/universe.sql @@ -480,4 +480,38 @@ WHERE (timestamp >= sqlc.narg('min_timestamp') OR sqlc.narg('min_timestamp') IS NULL) AND (attempt_counter >= sqlc.narg('min_attempt_counter') - OR sqlc.narg('min_attempt_counter') IS NULL); \ No newline at end of file + OR sqlc.narg('min_attempt_counter') IS NULL); + +-- name: UpsertMultiverseRoot :one +INSERT INTO multiverse_roots (namespace_root, proof_type) +VALUES (@namespace_root, @proof_type) +ON CONFLICT (namespace_root) + -- This is a no-op to allow returning the ID. + DO UPDATE SET namespace_root = EXCLUDED.namespace_root +RETURNING id; + +-- name: UpsertMultiverseLeaf :one +INSERT INTO multiverse_leaves ( + multiverse_root_id, asset_id, group_key, leaf_node_key, leaf_node_namespace +) VALUES ( + @multiverse_root_id, @asset_id, @group_key, @leaf_node_key, + @leaf_node_namespace +) +ON CONFLICT (leaf_node_key, leaf_node_namespace) + -- This is a no-op to allow returning the ID. + DO UPDATE SET leaf_node_key = EXCLUDED.leaf_node_key, + leaf_node_namespace = EXCLUDED.leaf_node_namespace +RETURNING id; + +-- name: DeleteMultiverseLeaf :exec +DELETE FROM multiverse_leaves +WHERE leaf_node_namespace = @namespace AND leaf_node_key = @leaf_node_key; + +-- name: QueryMultiverseLeaves :many +SELECT r.namespace_root, r.proof_type, l.asset_id, l.group_key, l.leaf_node_key +FROM multiverse_leaves l +JOIN multiverse_roots r + ON l.multiverse_root_id = r.id +WHERE r.proof_type = @proof_type AND + (l.asset_id = @asset_id OR @asset_id IS NULL) AND + (l.group_key = @group_key OR @group_key IS NULL); diff --git a/tapdb/sqlc/universe.sql.go b/tapdb/sqlc/universe.sql.go index b1e7b33ec..8fbb8e709 100644 --- a/tapdb/sqlc/universe.sql.go +++ b/tapdb/sqlc/universe.sql.go @@ -49,6 +49,21 @@ func (q *Queries) DeleteFederationProofSyncLog(ctx context.Context, arg DeleteFe return err } +const deleteMultiverseLeaf = `-- name: DeleteMultiverseLeaf :exec +DELETE FROM multiverse_leaves +WHERE leaf_node_namespace = $1 AND leaf_node_key = $2 +` + +type DeleteMultiverseLeafParams struct { + Namespace string + LeafNodeKey []byte +} + +func (q *Queries) DeleteMultiverseLeaf(ctx context.Context, arg DeleteMultiverseLeafParams) error { + _, err := q.db.ExecContext(ctx, deleteMultiverseLeaf, arg.Namespace, arg.LeafNodeKey) + return err +} + const deleteUniverseEvents = `-- name: DeleteUniverseEvents :exec WITH root_id AS ( SELECT id @@ -604,6 +619,59 @@ func (q *Queries) QueryFederationUniSyncConfigs(ctx context.Context) ([]Federati return items, nil } +const queryMultiverseLeaves = `-- name: QueryMultiverseLeaves :many +SELECT r.namespace_root, r.proof_type, l.asset_id, l.group_key, l.leaf_node_key +FROM multiverse_leaves l +JOIN multiverse_roots r + ON l.multiverse_root_id = r.id +WHERE r.proof_type = $1 AND + (l.asset_id = $2 OR $2 IS NULL) AND + (l.group_key = $3 OR $3 IS NULL) +` + +type QueryMultiverseLeavesParams struct { + ProofType string + AssetID []byte + GroupKey []byte +} + +type QueryMultiverseLeavesRow struct { + NamespaceRoot string + ProofType string + AssetID []byte + GroupKey []byte + LeafNodeKey []byte +} + +func (q *Queries) QueryMultiverseLeaves(ctx context.Context, arg QueryMultiverseLeavesParams) ([]QueryMultiverseLeavesRow, error) { + rows, err := q.db.QueryContext(ctx, queryMultiverseLeaves, arg.ProofType, arg.AssetID, arg.GroupKey) + if err != nil { + return nil, err + } + defer rows.Close() + var items []QueryMultiverseLeavesRow + for rows.Next() { + var i QueryMultiverseLeavesRow + if err := rows.Scan( + &i.NamespaceRoot, + &i.ProofType, + &i.AssetID, + &i.GroupKey, + &i.LeafNodeKey, + ); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + const queryUniverseAssetStats = `-- name: QueryUniverseAssetStats :many WITH asset_supply AS ( @@ -1147,6 +1215,62 @@ func (q *Queries) UpsertFederationUniSyncConfig(ctx context.Context, arg UpsertF return err } +const upsertMultiverseLeaf = `-- name: UpsertMultiverseLeaf :one +INSERT INTO multiverse_leaves ( + multiverse_root_id, asset_id, group_key, leaf_node_key, leaf_node_namespace +) VALUES ( + $1, $2, $3, $4, + $5 +) +ON CONFLICT (leaf_node_key, leaf_node_namespace) + -- This is a no-op to allow returning the ID. + DO UPDATE SET leaf_node_key = EXCLUDED.leaf_node_key, + leaf_node_namespace = EXCLUDED.leaf_node_namespace +RETURNING id +` + +type UpsertMultiverseLeafParams struct { + MultiverseRootID int64 + AssetID []byte + GroupKey []byte + LeafNodeKey []byte + LeafNodeNamespace string +} + +func (q *Queries) UpsertMultiverseLeaf(ctx context.Context, arg UpsertMultiverseLeafParams) (int64, error) { + row := q.db.QueryRowContext(ctx, upsertMultiverseLeaf, + arg.MultiverseRootID, + arg.AssetID, + arg.GroupKey, + arg.LeafNodeKey, + arg.LeafNodeNamespace, + ) + var id int64 + err := row.Scan(&id) + return id, err +} + +const upsertMultiverseRoot = `-- name: UpsertMultiverseRoot :one +INSERT INTO multiverse_roots (namespace_root, proof_type) +VALUES ($1, $2) +ON CONFLICT (namespace_root) + -- This is a no-op to allow returning the ID. + DO UPDATE SET namespace_root = EXCLUDED.namespace_root +RETURNING id +` + +type UpsertMultiverseRootParams struct { + NamespaceRoot string + ProofType string +} + +func (q *Queries) UpsertMultiverseRoot(ctx context.Context, arg UpsertMultiverseRootParams) (int64, error) { + row := q.db.QueryRowContext(ctx, upsertMultiverseRoot, arg.NamespaceRoot, arg.ProofType) + var id int64 + err := row.Scan(&id) + return id, err +} + const upsertUniverseLeaf = `-- name: UpsertUniverseLeaf :exec INSERT INTO universe_leaves ( asset_genesis_id, script_key_bytes, universe_root_id, leaf_node_key, From 94a371ac1e7838f68f4270d531ab9383e6ba1bc2 Mon Sep 17 00:00:00 2001 From: Oliver Gugger Date: Thu, 26 Oct 2023 21:35:21 +0200 Subject: [PATCH 03/16] tapdb: upsert multiverse tree --- internal/test/helpers.go | 8 ++ tapdb/multiverse.go | 156 +++++++++++----------------- tapdb/universe.go | 157 +++++++++++++++++++++++++--- tapdb/universe_test.go | 214 +++++++++++++++++++++++++++------------ 4 files changed, 360 insertions(+), 175 deletions(-) diff --git a/internal/test/helpers.go b/internal/test/helpers.go index 72e0f4c34..19dc03807 100644 --- a/internal/test/helpers.go +++ b/internal/test/helpers.go @@ -99,6 +99,14 @@ func SchnorrKey(t testing.TB, pubKey *btcec.PublicKey) *btcec.PublicKey { return key } +func SchnorrKeysEqual(t testing.TB, a, b *btcec.PublicKey) bool { + if a == nil || b == nil { + return a == b + } + + return SchnorrKey(t, a).IsEqual(SchnorrKey(t, b)) +} + func RandPubKey(t testing.TB) *btcec.PublicKey { return SchnorrPubKey(t, RandPrivKey(t)) } diff --git a/tapdb/multiverse.go b/tapdb/multiverse.go index 12bbb81b8..94acc75cf 100644 --- a/tapdb/multiverse.go +++ b/tapdb/multiverse.go @@ -10,6 +10,7 @@ import ( "sync/atomic" "time" + "github.com/btcsuite/btcd/btcec/v2" "github.com/btcsuite/btcd/btcec/v2/schnorr" "github.com/lightninglabs/neutrino/cache/lru" "github.com/lightninglabs/taproot-assets/asset" @@ -862,75 +863,18 @@ func (b *MultiverseStore) UpsertProofLeaf(ctx context.Context, issuanceProof *universe.Proof ) - multiverseNS, err := namespaceForProof(id.ProofType) - if err != nil { - return nil, err - } - execTxFunc := func(dbTx BaseMultiverseStore) error { // Register issuance in the asset (group) specific universe // tree. - var ( - universeRoot mssmt.Node - err error - ) - issuanceProof, universeRoot, err = universeUpsertProofLeaf( + var err error + issuanceProof, err = universeUpsertProofLeaf( ctx, dbTx, id, key, leaf, metaReveal, ) if err != nil { return err } - // Retrieve a handle to the multiverse tree so that we can - // update the tree by inserting a new issuance. - multiverseTree := mssmt.NewCompactedTree( - newTreeStoreWrapperTx(dbTx, multiverseNS), - ) - - // Construct a leaf node for insertion into the multiverse tree. - // The leaf node includes a reference to the lower tree via the - // lower tree root hash. - universeRootHash := universeRoot.NodeHash() - assetGroupSum := universeRoot.NodeSum() - - if id.ProofType == universe.ProofTypeIssuance { - assetGroupSum = 1 - } - - leafNode := mssmt.NewLeafNode( - universeRootHash[:], assetGroupSum, - ) - - // Use asset ID (or asset group hash) as the upper tree leaf - // node key. This is the same as the asset specific universe ID. - leafNodeKey := id.Bytes() - - _, err = multiverseTree.Insert( - ctx, leafNodeKey, leafNode, - ) - if err != nil { - return err - } - - // Retrieve the multiverse root and asset specific inclusion - // proof for the leaf node. - multiverseRoot, err := multiverseTree.Root(ctx) - if err != nil { - return err - } - - multiverseInclusionProof, err := multiverseTree.MerkleProof( - ctx, leafNodeKey, - ) - if err != nil { - return err - } - - // Add multiverse specific fields to the issuance proof. - issuanceProof.MultiverseRoot = multiverseRoot - issuanceProof.MultiverseInclusionProof = multiverseInclusionProof - - return err + return nil } dbErr := b.db.ExecTx(ctx, &writeTx, execTxFunc) if dbErr != nil { @@ -957,7 +901,7 @@ func (b *MultiverseStore) UpsertProofLeafBatch(ctx context.Context, // Upsert proof leaf into the asset (group) specific universe // tree. - _, universeRoot, err := universeUpsertProofLeaf( + _, err := universeUpsertProofLeaf( ctx, dbTx, item.ID, item.Key, item.Leaf, item.MetaReveal, ) @@ -965,40 +909,6 @@ func (b *MultiverseStore) UpsertProofLeafBatch(ctx context.Context, return err } - multiverseNS, err := namespaceForProof(item.ID.ProofType) - if err != nil { - return err - } - - // Retrieve a handle to the multiverse tree so that we can - // update the tree by inserting/updating a proof leaf. - multiverseTree := mssmt.NewCompactedTree( - newTreeStoreWrapperTx(dbTx, multiverseNS), - ) - - // Construct a leaf node for insertion into the multiverse tree. - // The leaf node includes a reference to the lower tree via the - // lower tree root hash. - universeRootHash := universeRoot.NodeHash() - assetGroupSum := universeRoot.NodeSum() - - if item.ID.ProofType == universe.ProofTypeIssuance { - assetGroupSum = 1 - } - - leafNode := mssmt.NewLeafNode( - universeRootHash[:], assetGroupSum, - ) - - // Use asset ID (or asset group hash) as the upper tree leaf - // node key. This is the same as the asset specific universe ID. - leafNodeKey := item.ID.Bytes() - - _, err = multiverseTree.Insert(ctx, leafNodeKey, leafNode) - if err != nil { - return err - } - return nil } @@ -1074,3 +984,59 @@ func (b *MultiverseStore) DeleteUniverse(ctx context.Context, return id.String(), dbErr } + +// FetchLeaves returns the set of multiverse leaves for the given proof type, +// asset ID, and group key. If both asset ID and group key is nil, all leaves +// for the given proof type will be returned. +func (b *MultiverseStore) FetchLeaves(ctx context.Context, + assetID *asset.ID, groupKey *btcec.PublicKey, + proofType universe.ProofType) ([]universe.Identifier, error) { + + var assetIDBytes, groupKeyBytes []byte + if assetID != nil { + assetIDBytes = assetID[:] + } + if groupKey != nil { + groupKeyBytes = schnorr.SerializePubKey(groupKey) + } + + var ( + readTx = NewBaseUniverseReadTx() + ids []universe.Identifier + ) + dbErr := b.db.ExecTx(ctx, &readTx, func(q BaseMultiverseStore) error { + leaves, err := q.QueryMultiverseLeaves( + ctx, QueryMultiverseLeaves{ + ProofType: proofType.String(), + AssetID: assetIDBytes, + GroupKey: groupKeyBytes, + }, + ) + if err != nil { + return err + } + + ids = make([]universe.Identifier, len(leaves)) + for i, leaf := range leaves { + ids[i].ProofType = proofType + if len(leaf.AssetID) > 0 { + copy(ids[i].AssetID[:], leaf.AssetID) + } + if len(leaf.GroupKey) > 0 { + ids[i].GroupKey, err = schnorr.ParsePubKey( + leaf.GroupKey, + ) + if err != nil { + return err + } + } + } + + return nil + }) + if dbErr != nil { + return nil, dbErr + } + + return ids, nil +} diff --git a/tapdb/universe.go b/tapdb/universe.go index d5eba58c3..15cb331d5 100644 --- a/tapdb/universe.go +++ b/tapdb/universe.go @@ -41,6 +41,22 @@ type ( // UniverseLeafKeysQuery is used to query for the set of keys that are // currently stored for a given namespace. UniverseLeafKeysQuery = sqlc.FetchUniverseKeysParams + + // UpsertMultiverseRoot is used to upsert a multiverse root. + UpsertMultiverseRoot = sqlc.UpsertMultiverseRootParams + + // UpsertMultiverseLeaf is used to upsert a multiverse leaf. + UpsertMultiverseLeaf = sqlc.UpsertMultiverseLeafParams + + // DeleteMultiverseLeaf is used to delete a multiverse leaf. + DeleteMultiverseLeaf = sqlc.DeleteMultiverseLeafParams + + // QueryMultiverseLeaves is used to query for a set of leaves based on + // the proof type and asset ID (or group key) + QueryMultiverseLeaves = sqlc.QueryMultiverseLeavesParams + + // MultiverseLeaf is a leaf in a multiverse. + MultiverseLeaf = sqlc.QueryMultiverseLeavesRow ) // BaseUniverseStore is the main interface for the Taproot Asset universe store. @@ -89,6 +105,23 @@ type BaseUniverseStore interface { // for a given namespace. FetchUniverseKeys(ctx context.Context, arg UniverseLeafKeysQuery) ([]UniverseKeys, error) + + // UpsertMultiverseRoot upserts a multiverse root in the database. + UpsertMultiverseRoot(ctx context.Context, + arg UpsertMultiverseRoot) (int64, error) + + // UpsertMultiverseLeaf upserts a multiverse leaf in the database. + UpsertMultiverseLeaf(ctx context.Context, + arg UpsertMultiverseLeaf) (int64, error) + + // DeleteMultiverseLeaf deletes a multiverse leaf from the database. + DeleteMultiverseLeaf(ctx context.Context, + arg DeleteMultiverseLeaf) error + + // QueryMultiverseLeaves is used to query for the set of leaves that + // reside in a multiverse tree. + QueryMultiverseLeaves(ctx context.Context, + arg QueryMultiverseLeaves) ([]MultiverseLeaf, error) } // BaseUniverseStoreOptions is the set of options for universe tree queries. @@ -318,7 +351,7 @@ func (b *BaseUniverseTree) RegisterIssuance(ctx context.Context, issuanceProof *universe.Proof ) dbErr := b.db.ExecTx(ctx, &writeTx, func(dbTx BaseUniverseStore) error { - issuanceProof, _, err = universeUpsertProofLeaf( + issuanceProof, err = universeUpsertProofLeaf( ctx, dbTx, b.id, key, leaf, metaReveal, ) return err @@ -340,7 +373,7 @@ func (b *BaseUniverseTree) RegisterIssuance(ctx context.Context, // broader DB updates. func universeUpsertProofLeaf(ctx context.Context, dbTx BaseUniverseStore, id universe.Identifier, key universe.LeafKey, leaf *universe.Leaf, - metaReveal *proof.MetaReveal) (*universe.Proof, mssmt.Node, error) { + metaReveal *proof.MetaReveal) (*universe.Proof, error) { namespace := id.String() @@ -359,7 +392,7 @@ func universeUpsertProofLeaf(ctx context.Context, dbTx BaseUniverseStore, mintingPointBytes, err := encodeOutpoint(key.OutPoint) if err != nil { - return nil, nil, err + return nil, err } var ( @@ -377,7 +410,7 @@ func universeUpsertProofLeaf(ctx context.Context, dbTx BaseUniverseStore, // insert the leaf into the tree based on its SMT key. _, err = universeTree.Insert(ctx, smtKey, leafNode) if err != nil { - return nil, nil, err + return nil, err } // Next, we'll upsert the universe root in the DB, which gives us the @@ -389,7 +422,7 @@ func universeUpsertProofLeaf(ctx context.Context, dbTx BaseUniverseStore, ProofType: id.ProofType.String(), }) if err != nil { - return nil, nil, err + return nil, err } // Before we insert the asset genesis, we'll insert the meta first. The @@ -397,20 +430,20 @@ func universeUpsertProofLeaf(ctx context.Context, dbTx BaseUniverseStore, // meta blob on disk. _, err = maybeUpsertAssetMeta(ctx, dbTx, &leaf.Genesis, metaReveal) if err != nil { - return nil, nil, err + return nil, err } var leafProof proof.Proof err = leafProof.Decode(bytes.NewReader(leaf.RawProof)) if err != nil { - return nil, nil, fmt.Errorf("unable to decode proof: %w", err) + return nil, fmt.Errorf("unable to decode proof: %w", err) } assetGenID, err := upsertAssetGen( ctx, dbTx, leaf.Genesis, leaf.GroupKey, &leafProof, ) if err != nil { - return nil, nil, err + return nil, err } scriptKeyBytes := schnorr.SerializePubKey(key.ScriptKey.PubKey) @@ -423,29 +456,109 @@ func universeUpsertProofLeaf(ctx context.Context, dbTx BaseUniverseStore, MintingPoint: mintingPointBytes, }) if err != nil { - return nil, nil, err + return nil, err } // Finally, we'll obtain the merkle proof from the tree for the leaf we // just inserted. leafInclusionProof, err = universeTree.MerkleProof(ctx, smtKey) if err != nil { - return nil, nil, err + return nil, err } // With the insertion complete, we'll now fetch the root of the tree as // it stands and return it to the caller. universeRoot, err = universeTree.Root(ctx) if err != nil { - return nil, nil, err + return nil, err + } + + // The next step is to insert the multiverse leaf, which is a leaf in + // the multiverse tree that points to the universe leaf we just created. + multiverseNS, err := namespaceForProof(id.ProofType) + if err != nil { + return nil, err + } + + // Retrieve a handle to the multiverse tree so that we can update the + // tree by inserting a new issuance. + multiverseTree := mssmt.NewCompactedTree( + newTreeStoreWrapperTx(dbTx, multiverseNS), + ) + + // Construct a leaf node for insertion into the multiverse tree. The + // leaf node includes a reference to the lower tree via the lower tree + // root hash. + universeRootHash := universeRoot.NodeHash() + assetGroupSum := universeRoot.NodeSum() + + if id.ProofType == universe.ProofTypeIssuance { + assetGroupSum = 1 + } + + uniLeafNode := mssmt.NewLeafNode(universeRootHash[:], assetGroupSum) + + // Use asset ID (or asset group hash) as the upper tree leaf node key. + // This is the same as the asset specific universe ID. + uniLeafNodeKey := id.Bytes() + + _, err = multiverseTree.Insert(ctx, uniLeafNodeKey, uniLeafNode) + if err != nil { + return nil, err + } + + // Now that we've inserted the leaf into the multiverse tree, we'll also + // make sure the corresponding multiverse roots and leaves are created. + multiverseRootID, err := dbTx.UpsertMultiverseRoot( + ctx, UpsertMultiverseRoot{ + NamespaceRoot: multiverseNS, + ProofType: id.ProofType.String(), + }, + ) + if err != nil { + return nil, fmt.Errorf("unable to upsert multiverse root: %w", + err) + } + + var assetIDBytes []byte + if id.GroupKey == nil { + assetIDBytes = id.AssetID[:] + } + + _, err = dbTx.UpsertMultiverseLeaf(ctx, UpsertMultiverseLeaf{ + MultiverseRootID: multiverseRootID, + AssetID: assetIDBytes, + GroupKey: groupKeyBytes, + LeafNodeKey: uniLeafNodeKey[:], + LeafNodeNamespace: multiverseNS, + }) + if err != nil { + return nil, fmt.Errorf("unable to upsert multiverse leaf: %w", + err) + } + + // Retrieve the multiverse root and asset specific inclusion proof for + // the leaf node. + multiverseRoot, err := multiverseTree.Root(ctx) + if err != nil { + return nil, err + } + + multiverseInclusionProof, err := multiverseTree.MerkleProof( + ctx, uniLeafNodeKey, + ) + if err != nil { + return nil, err } return &universe.Proof{ - LeafKey: key, - UniverseRoot: universeRoot, - UniverseInclusionProof: leafInclusionProof, - Leaf: leaf, - }, universeRoot, nil + LeafKey: key, + UniverseRoot: universeRoot, + UniverseInclusionProof: leafInclusionProof, + MultiverseRoot: multiverseRoot, + MultiverseInclusionProof: multiverseInclusionProof, + Leaf: leaf, + }, nil } // FetchIssuanceProof returns an issuance proof for the target key. If the key @@ -805,6 +918,18 @@ func deleteUniverseTree(ctx context.Context, err) } + multiverseNS, err := namespaceForProof(id.ProofType) + if err != nil { + return err + } + err = db.DeleteMultiverseLeaf(ctx, DeleteMultiverseLeaf{ + Namespace: multiverseNS, + LeafNodeKey: fn.ByteSlice(id.Bytes()), + }) + if err != nil { + return fmt.Errorf("unable to upsert multiverse leaf: %w", err) + } + return nil } diff --git a/tapdb/universe_test.go b/tapdb/universe_test.go index b82223e40..2a579ab76 100644 --- a/tapdb/universe_test.go +++ b/tapdb/universe_test.go @@ -26,7 +26,7 @@ type universeIdOptions struct { proofType universe.ProofType } -func defaultUniverseIdOptions(t *testing.T) *universeIdOptions { +func defaultUniverseIdOptions() *universeIdOptions { return &universeIdOptions{ proofType: universe.ProofTypeIssuance, } @@ -43,7 +43,7 @@ func withProofType(proofType universe.ProofType) universeIDOptFunc { func randUniverseID(t *testing.T, forceGroup bool, optFunctions ...universeIDOptFunc) universe.Identifier { - opts := defaultUniverseIdOptions(t) + opts := defaultUniverseIdOptions() for _, optFunc := range optFunctions { optFunc(opts) } @@ -73,8 +73,8 @@ func newTestUniverse(t *testing.T, db := NewTestDB(t) - dbTxer := NewTransactionExecutor(db, - func(tx *sql.Tx) BaseUniverseStore { + dbTxer := NewTransactionExecutor( + db, func(tx *sql.Tx) BaseUniverseStore { return db.WithTx(tx) }, ) @@ -85,8 +85,18 @@ func newTestUniverse(t *testing.T, func newTestMultiverse(t *testing.T) (*MultiverseStore, sqlc.Querier) { db := NewTestDB(t) - dbTxer := NewTransactionExecutor(db, - func(tx *sql.Tx) BaseMultiverseStore { + dbTxer := NewTransactionExecutor( + db, func(tx *sql.Tx) BaseMultiverseStore { + return db.WithTx(tx) + }, + ) + + return NewMultiverseStore(dbTxer), db +} + +func newTestMultiverseWithDb(db *BaseDB) (*MultiverseStore, sqlc.Querier) { + dbTxer := NewTransactionExecutor( + db, func(tx *sql.Tx) BaseMultiverseStore { return db.WithTx(tx) }, ) @@ -106,6 +116,29 @@ func newTestUniverseWithDb(db *BaseDB, return NewBaseUniverseTree(dbTxer, id), db } +func assertIDInList(t *testing.T, leaves []universe.Identifier, + id universe.Identifier) { + + require.True(t, fn.Any(leaves, func(l universe.Identifier) bool { + switch { + case l.AssetID != asset.ID{}: + return l.AssetID == id.AssetID + + case l.GroupKey != nil: + if id.GroupKey == nil { + return false + } + + return test.SchnorrKeysEqual(t, l.GroupKey, id.GroupKey) + + default: + require.Fail(t, "invalid leaf") + } + + return false + })) +} + // TestUniverseEmptyTree tests that an empty Universe tree returns the expected // error. func TestUniverseEmptyTree(t *testing.T) { @@ -122,10 +155,8 @@ func TestUniverseEmptyTree(t *testing.T) { func randLeafKey(t *testing.T) universe.LeafKey { return universe.LeafKey{ - OutPoint: test.RandOp(t), - ScriptKey: fn.Ptr( - asset.NewScriptKey(test.RandPubKey(t)), - ), + OutPoint: test.RandOp(t), + ScriptKey: fn.Ptr(asset.NewScriptKey(test.RandPubKey(t))), } } @@ -193,7 +224,7 @@ func randMintingLeaf(t *testing.T, assetGen asset.Genesis, return leaf } -// leaWithKey is a two tuple that associates universe leaf key with a leaf. +// leafWithKey is a two tuple that associates universe leaf key with a leaf. type leafWithKey struct { universe.LeafKey @@ -208,11 +239,27 @@ func TestUniverseIssuanceProofs(t *testing.T) { ctx := context.Background() - id := randUniverseID(t, false) - baseUniverse, _ := newTestUniverse(t, id) + id := randUniverseID( + t, false, withProofType(universe.ProofTypeIssuance), + ) + db := NewTestDB(t) + baseUniverse, _ := newTestUniverseWithDb(db.BaseDB, id) + multiverse, _ := newTestMultiverseWithDb(db.BaseDB) const numLeaves = 4 + // The multiverse tree should be empty at this point. + issuanceLeaves, err := multiverse.FetchLeaves( + ctx, nil, nil, universe.ProofTypeIssuance, + ) + require.NoError(t, err) + require.Len(t, issuanceLeaves, 0) + transferLeaves, err := multiverse.FetchLeaves( + ctx, nil, nil, universe.ProofTypeTransfer, + ) + require.NoError(t, err) + require.Len(t, transferLeaves, 0) + // All the leaves will be under the same base universe tree, so we want // them to have the same asset ID. assetGen := asset.RandGenesis(t, asset.Normal) @@ -287,6 +334,17 @@ func TestUniverseIssuanceProofs(t *testing.T) { ) } + // The multiverse tree should just have a single leaf, since we inserted + // proofs into the same universe. + multiverseLeaves, err := multiverse.FetchLeaves( + ctx, nil, nil, id.ProofType, + ) + require.NoError(t, err) + require.Len(t, multiverseLeaves, 1) + + // And we should actually find the leaf we just inserted. + assertIDInList(t, multiverseLeaves, id) + // Next, we'll query for all the available keys, this should match the // number of insertions we just did. mintingKeys, err := baseUniverse.MintingKeys( @@ -820,13 +878,15 @@ func TestMultiverseRootSum(t *testing.T) { sumAmt uint64 } - testCases := []struct { + type testCase struct { name string finalSum uint64 proofType universe.ProofType doubleUp bool leaves []leaf - }{ + } + + testCases := []testCase{ // If we insert two transfers into a transfer tree, then the // sum should be the sum of the leaf values. The leaf value // here is itself the root sum of an transfer tree, or the @@ -863,75 +923,101 @@ func TestMultiverseRootSum(t *testing.T) { }, }, } - for _, testCase := range testCases { - t.Run(testCase.name, func(t *testing.T) { - multiverse, _ := newTestMultiverse(t) - ctx := context.Background() + runTestCase := func(t *testing.T, tc testCase) { + multiverse, _ := newTestMultiverse(t) - leaves := make([]universe.Leaf, len(testCase.leaves)) - ids := make([]universe.Identifier, len(testCase.leaves)) - for i, testLeaf := range testCase.leaves { - id := randUniverseID( - t, false, withProofType(testCase.proofType), - ) + ctx := context.Background() - ids[i] = id + // The multiverse tree should be empty at this point. + issuanceLeaves, err := multiverse.FetchLeaves( + ctx, nil, nil, universe.ProofTypeIssuance, + ) + require.NoError(t, err) + require.Len(t, issuanceLeaves, 0) + transferLeaves, err := multiverse.FetchLeaves( + ctx, nil, nil, universe.ProofTypeTransfer, + ) + require.NoError(t, err) + require.Len(t, transferLeaves, 0) - assetGen := asset.RandGenesis(t, asset.Normal) - leaf := randMintingLeaf( - t, assetGen, id.GroupKey, - ) - leaf.Amt = testLeaf.sumAmt + leaves := make([]universe.Leaf, len(tc.leaves)) + ids := make([]universe.Identifier, len(tc.leaves)) + for i, testLeaf := range tc.leaves { + id := randUniverseID( + t, false, withProofType(tc.proofType), + ) - leaves[i] = leaf + ids[i] = id - targetKey := randLeafKey(t) + assetGen := asset.RandGenesis(t, asset.Normal) + leaf := randMintingLeaf(t, assetGen, id.GroupKey) + leaf.Amt = testLeaf.sumAmt - // For transfer proofs, we'll modify the - // witness asset proof to look more like a - // transfer. - if testCase.proofType == - universe.ProofTypeTransfer { + leaves[i] = leaf - //nolint:lll - leaf.Asset.PrevWitnesses[0].TxWitness = [][]byte{ - {1}, {1}, {1}, - } - //nolint:lll - leaf.Asset.PrevWitnesses[0].PrevID.OutPoint.Hash = [32]byte{1} + targetKey := randLeafKey(t) + + // For transfer proofs, we'll modify the witness asset + // proof to look more like a transfer. + if tc.proofType == universe.ProofTypeTransfer { + prevWitnesses := leaf.Asset.PrevWitnesses + prevWitnesses[0].TxWitness = [][]byte{ + {1}, {1}, {1}, } + prevWitnesses[0].PrevID.OutPoint.Hash = [32]byte{1} + } + + _, err := multiverse.UpsertProofLeaf( + ctx, id, targetKey, &leaf, nil, + ) + require.NoError(t, err) + + // If we should add more than one under this ID, then + // we'll generate another instance. + if tc.doubleUp { + targetKey = randLeafKey(t) _, err := multiverse.UpsertProofLeaf( ctx, id, targetKey, &leaf, nil, ) require.NoError(t, err) - - // If we should add more than one under this - // ID, then we'll generate another instance. - if testCase.doubleUp { - targetKey = randLeafKey(t) - - _, err := multiverse.UpsertProofLeaf( - ctx, id, targetKey, &leaf, nil, - ) - require.NoError(t, err) - } } - // If we fetch the root value of the tree, it should be - // the same as the finalSum. - rootNode, err := multiverse.RootNode( - ctx, testCase.proofType, + // The multiverse tree should now have one more leaf. + multiverseLeaves, err := multiverse.FetchLeaves( + ctx, nil, nil, tc.proofType, ) require.NoError(t, err) + require.Len(t, multiverseLeaves, i+1) - require.Equal( - t, int(testCase.finalSum), int(rootNode.NodeSum()), - ) + // And we should actually find the leaf we just + // inserted. + assertIDInList(t, multiverseLeaves, id) + } - // TODO(roasbeef): also check leaves, need ability to - // track them directly. + // If we fetch the root value of the tree, it should be + // the same as the finalSum. + rootNode, err := multiverse.RootNode(ctx, tc.proofType) + require.NoError(t, err) + + require.EqualValues(t, tc.finalSum, rootNode.NodeSum()) + + // We now delete the whole universe and expect the multiverse + // leave to also disappear. + _, err = multiverse.DeleteUniverse(ctx, ids[0]) + require.NoError(t, err) + + multiverseLeaves, err := multiverse.FetchLeaves( + ctx, nil, nil, tc.proofType, + ) + require.NoError(t, err) + require.Len(t, multiverseLeaves, len(ids)-1) + } + + for _, testCase := range testCases { + t.Run(testCase.name, func(t *testing.T) { + runTestCase(t, testCase) }) } } From 69072b5fe1b3e2eee1f4658db373798839da6dfd Mon Sep 17 00:00:00 2001 From: Oliver Gugger Date: Fri, 27 Oct 2023 16:53:27 +0200 Subject: [PATCH 04/16] universe: add MultiverseRoot method to archive --- universe/base.go | 64 +++++++++++++++++++++++++++++++++++++++++++ universe/interface.go | 25 +++++++++++++++++ 2 files changed, 89 insertions(+) diff --git a/universe/base.go b/universe/base.go index 07a07de28..f130238d3 100644 --- a/universe/base.go +++ b/universe/base.go @@ -12,6 +12,7 @@ import ( "github.com/davecgh/go-spew/spew" "github.com/lightninglabs/taproot-assets/asset" "github.com/lightninglabs/taproot-assets/fn" + "github.com/lightninglabs/taproot-assets/mssmt" "github.com/lightninglabs/taproot-assets/proof" ) @@ -134,6 +135,69 @@ func (a *Archive) RootNodes(ctx context.Context, return a.cfg.Multiverse.RootNodes(ctx, q) } +// MultiverseRoot returns the root node of the multiverse for the specified +// proof type. If the given list of universe IDs is non-empty, then the root +// will be calculated just for those universes. +func (a *Archive) MultiverseRoot(ctx context.Context, proofType ProofType, + filterByIDs []Identifier) (mssmt.Node, error) { + + log.Debugf("Fetching multiverse root for proof type: %v", proofType) + + leaveIDs, err := a.cfg.Multiverse.FetchLeaves(ctx, nil, nil, proofType) + if err != nil { + return nil, fmt.Errorf("unable to fetch multiverse leaves: %w", + err) + } + + // If a filter list is provided, then we'll only include the leaves + // that are in the filter list. + includeUniverse := func(id Identifier) bool { + if len(filterByIDs) == 0 { + return true + } + + for _, filterID := range filterByIDs { + if id.IsEqual(filterID) { + return true + } + } + + return false + } + + memStore := mssmt.NewDefaultStore() + tree := mssmt.NewCompactedTree(memStore) + + for _, id := range leaveIDs { + // Only include the universe if it's in the filter list (given + // the filter list is non-empty). + if !includeUniverse(id) { + continue + } + + uniRoot, err := a.cfg.Multiverse.UniverseRootNode(ctx, id) + if err != nil { + return nil, fmt.Errorf("unable to fetch universe "+ + "root: %w", err) + } + + rootHash := uniRoot.NodeHash() + rootSum := uniRoot.NodeSum() + + if id.ProofType == ProofTypeIssuance { + rootSum = 1 + } + + uniLeaf := mssmt.NewLeafNode(rootHash[:], rootSum) + _, err = tree.Insert(ctx, id.Bytes(), uniLeaf) + if err != nil { + return nil, fmt.Errorf("unable to insert leaf: %w", err) + } + } + + return tree.Root(ctx) +} + // UpsertProofLeaf attempts to upsert a proof for an asset issuance or transfer // event. This method will return an error if the passed proof is invalid. If // the leaf is already known, then no action is taken and the existing diff --git a/universe/interface.go b/universe/interface.go index 29712cc4f..2490b7e8a 100644 --- a/universe/interface.go +++ b/universe/interface.go @@ -84,6 +84,24 @@ func (i *Identifier) StringForLog() string { i.String(), i.AssetID[:], groupKey, i.ProofType) } +// IsEqual returns true if the two identifiers are equal. +func (i *Identifier) IsEqual(other Identifier) bool { + if i == nil { + return false + } + + groupKeysEqual := false + if i.GroupKey == nil || other.GroupKey == nil { + groupKeysEqual = i.GroupKey == other.GroupKey + } else { + groupKeysEqual = i.GroupKey.IsEqual(other.GroupKey) + } + + return i.AssetID == other.AssetID && + groupKeysEqual && + i.ProofType == other.ProofType +} + // NewUniIDFromAsset creates a new universe ID from an asset. func NewUniIDFromAsset(a asset.Asset) Identifier { proofType := ProofTypeTransfer @@ -393,6 +411,13 @@ type MultiverseArchive interface { // universe. UniverseLeafKeys(ctx context.Context, q UniverseLeafKeysQuery) ([]LeafKey, error) + + // FetchLeaves returns the set of multiverse leaves for the given proof + // type, asset ID, and group key. If both asset ID and group key is nil, + // all leaves for the given proof type will be returned. + FetchLeaves(ctx context.Context, assetID *asset.ID, + groupKey *btcec.PublicKey, + proofType ProofType) ([]Identifier, error) } // Registrar is an interface that allows a caller to upsert a proof leaf in a From 7da2bf5fc5d0ab927c69f007a8017ca8a115288e Mon Sep 17 00:00:00 2001 From: Oliver Gugger Date: Fri, 27 Oct 2023 16:53:55 +0200 Subject: [PATCH 05/16] multi: add MultiverseRoot RPC method --- perms/perms.go | 4 + rpcserver.go | 50 + taprpc/universerpc/universe.pb.go | 1782 ++++++++++++---------- taprpc/universerpc/universe.pb.gw.go | 81 + taprpc/universerpc/universe.pb.json.go | 25 + taprpc/universerpc/universe.proto | 23 + taprpc/universerpc/universe.swagger.json | 58 + taprpc/universerpc/universe.yaml | 4 + taprpc/universerpc/universe_grpc.pb.go | 44 + 9 files changed, 1259 insertions(+), 812 deletions(-) diff --git a/perms/perms.go b/perms/perms.go index a8fa12f75..2d7afc005 100644 --- a/perms/perms.go +++ b/perms/perms.go @@ -136,6 +136,10 @@ var ( Entity: "mint", Action: "read", }}, + "/universerpc.Universe/MultiverseRoot": {{ + Entity: "universe", + Action: "read", + }}, "/universerpc.Universe/AssetRoots": {{ Entity: "universe", Action: "read", diff --git a/rpcserver.go b/rpcserver.go index 148add54e..ea610dd20 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -2960,6 +2960,56 @@ func marshalUniverseRoot(node universe.Root) (*unirpc.UniverseRoot, error) { }, nil } +// MultiverseRoot returns the root of the multiverse tree. This is useful to +// determine the equality of two multiverse trees, since the root can directly +// be compared to another multiverse root to find out if a sync is required. +func (r *rpcServer) MultiverseRoot(ctx context.Context, + req *unirpc.MultiverseRootRequest) (*unirpc.MultiverseRootResponse, + error) { + + proofType, err := UnmarshalUniProofType(req.ProofType) + if err != nil { + return nil, fmt.Errorf("invalid proof type: %w", err) + } + + if proofType == universe.ProofTypeUnspecified { + return nil, fmt.Errorf("proof type must be specified") + } + + filterByIDs := make([]universe.Identifier, len(req.SpecificIds)) + for idx, rpcID := range req.SpecificIds { + filterByIDs[idx], err = UnmarshalUniID(rpcID) + if err != nil { + return nil, fmt.Errorf("unable to parse universe id: "+ + "%w", err) + } + + // Allow the RPC user to not specify the proof type for each ID + // individually since the outer one is mandatory. + if filterByIDs[idx].ProofType == universe.ProofTypeUnspecified { + filterByIDs[idx].ProofType = proofType + } + + if filterByIDs[idx].ProofType != proofType { + return nil, fmt.Errorf("proof type mismatch in ID "+ + "%d: %v != %v", idx, filterByIDs[idx].ProofType, + proofType) + } + } + + rootNode, err := r.cfg.UniverseArchive.MultiverseRoot( + ctx, proofType, filterByIDs, + ) + if err != nil { + return nil, fmt.Errorf("unable to fetch multiverse root: %w", + err) + } + + return &unirpc.MultiverseRootResponse{ + MultiverseRoot: marshalMssmtNode(rootNode), + }, nil +} + // AssetRoots queries for the known Universe roots associated with each known // asset. These roots represent the supply/audit state for each known asset. func (r *rpcServer) AssetRoots(ctx context.Context, diff --git a/taprpc/universerpc/universe.pb.go b/taprpc/universerpc/universe.pb.go index f99d7f6df..1d7e88149 100644 --- a/taprpc/universerpc/universe.pb.go +++ b/taprpc/universerpc/universe.pb.go @@ -279,6 +279,114 @@ func (AssetTypeFilter) EnumDescriptor() ([]byte, []int) { return file_universerpc_universe_proto_rawDescGZIP(), []int{4} } +type MultiverseRootRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The proof type to calculate the multiverse root for. + ProofType ProofType `protobuf:"varint,1,opt,name=proof_type,json=proofType,proto3,enum=universerpc.ProofType" json:"proof_type,omitempty"` + // An optional list of universe IDs to include in the multiverse root. If + // none are specified, then all known universes of the given proof type are + // included. NOTE: The proof type within the IDs must either be unspecified + // or match the proof type above. + SpecificIds []*ID `protobuf:"bytes,2,rep,name=specific_ids,json=specificIds,proto3" json:"specific_ids,omitempty"` +} + +func (x *MultiverseRootRequest) Reset() { + *x = MultiverseRootRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_universerpc_universe_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *MultiverseRootRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MultiverseRootRequest) ProtoMessage() {} + +func (x *MultiverseRootRequest) ProtoReflect() protoreflect.Message { + mi := &file_universerpc_universe_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MultiverseRootRequest.ProtoReflect.Descriptor instead. +func (*MultiverseRootRequest) Descriptor() ([]byte, []int) { + return file_universerpc_universe_proto_rawDescGZIP(), []int{0} +} + +func (x *MultiverseRootRequest) GetProofType() ProofType { + if x != nil { + return x.ProofType + } + return ProofType_PROOF_TYPE_UNSPECIFIED +} + +func (x *MultiverseRootRequest) GetSpecificIds() []*ID { + if x != nil { + return x.SpecificIds + } + return nil +} + +type MultiverseRootResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The root of the multiverse tree. + MultiverseRoot *MerkleSumNode `protobuf:"bytes,1,opt,name=multiverse_root,json=multiverseRoot,proto3" json:"multiverse_root,omitempty"` +} + +func (x *MultiverseRootResponse) Reset() { + *x = MultiverseRootResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_universerpc_universe_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *MultiverseRootResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MultiverseRootResponse) ProtoMessage() {} + +func (x *MultiverseRootResponse) ProtoReflect() protoreflect.Message { + mi := &file_universerpc_universe_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MultiverseRootResponse.ProtoReflect.Descriptor instead. +func (*MultiverseRootResponse) Descriptor() ([]byte, []int) { + return file_universerpc_universe_proto_rawDescGZIP(), []int{1} +} + +func (x *MultiverseRootResponse) GetMultiverseRoot() *MerkleSumNode { + if x != nil { + return x.MultiverseRoot + } + return nil +} + type AssetRootRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -298,7 +406,7 @@ type AssetRootRequest struct { func (x *AssetRootRequest) Reset() { *x = AssetRootRequest{} if protoimpl.UnsafeEnabled { - mi := &file_universerpc_universe_proto_msgTypes[0] + mi := &file_universerpc_universe_proto_msgTypes[2] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -311,7 +419,7 @@ func (x *AssetRootRequest) String() string { func (*AssetRootRequest) ProtoMessage() {} func (x *AssetRootRequest) ProtoReflect() protoreflect.Message { - mi := &file_universerpc_universe_proto_msgTypes[0] + mi := &file_universerpc_universe_proto_msgTypes[2] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -324,7 +432,7 @@ func (x *AssetRootRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use AssetRootRequest.ProtoReflect.Descriptor instead. func (*AssetRootRequest) Descriptor() ([]byte, []int) { - return file_universerpc_universe_proto_rawDescGZIP(), []int{0} + return file_universerpc_universe_proto_rawDescGZIP(), []int{2} } func (x *AssetRootRequest) GetWithAmountsById() bool { @@ -371,7 +479,7 @@ type MerkleSumNode struct { func (x *MerkleSumNode) Reset() { *x = MerkleSumNode{} if protoimpl.UnsafeEnabled { - mi := &file_universerpc_universe_proto_msgTypes[1] + mi := &file_universerpc_universe_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -384,7 +492,7 @@ func (x *MerkleSumNode) String() string { func (*MerkleSumNode) ProtoMessage() {} func (x *MerkleSumNode) ProtoReflect() protoreflect.Message { - mi := &file_universerpc_universe_proto_msgTypes[1] + mi := &file_universerpc_universe_proto_msgTypes[3] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -397,7 +505,7 @@ func (x *MerkleSumNode) ProtoReflect() protoreflect.Message { // Deprecated: Use MerkleSumNode.ProtoReflect.Descriptor instead. func (*MerkleSumNode) Descriptor() ([]byte, []int) { - return file_universerpc_universe_proto_rawDescGZIP(), []int{1} + return file_universerpc_universe_proto_rawDescGZIP(), []int{3} } func (x *MerkleSumNode) GetRootHash() []byte { @@ -432,7 +540,7 @@ type ID struct { func (x *ID) Reset() { *x = ID{} if protoimpl.UnsafeEnabled { - mi := &file_universerpc_universe_proto_msgTypes[2] + mi := &file_universerpc_universe_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -445,7 +553,7 @@ func (x *ID) String() string { func (*ID) ProtoMessage() {} func (x *ID) ProtoReflect() protoreflect.Message { - mi := &file_universerpc_universe_proto_msgTypes[2] + mi := &file_universerpc_universe_proto_msgTypes[4] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -458,7 +566,7 @@ func (x *ID) ProtoReflect() protoreflect.Message { // Deprecated: Use ID.ProtoReflect.Descriptor instead. func (*ID) Descriptor() ([]byte, []int) { - return file_universerpc_universe_proto_rawDescGZIP(), []int{2} + return file_universerpc_universe_proto_rawDescGZIP(), []int{4} } func (m *ID) GetId() isID_Id { @@ -560,7 +668,7 @@ type UniverseRoot struct { func (x *UniverseRoot) Reset() { *x = UniverseRoot{} if protoimpl.UnsafeEnabled { - mi := &file_universerpc_universe_proto_msgTypes[3] + mi := &file_universerpc_universe_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -573,7 +681,7 @@ func (x *UniverseRoot) String() string { func (*UniverseRoot) ProtoMessage() {} func (x *UniverseRoot) ProtoReflect() protoreflect.Message { - mi := &file_universerpc_universe_proto_msgTypes[3] + mi := &file_universerpc_universe_proto_msgTypes[5] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -586,7 +694,7 @@ func (x *UniverseRoot) ProtoReflect() protoreflect.Message { // Deprecated: Use UniverseRoot.ProtoReflect.Descriptor instead. func (*UniverseRoot) Descriptor() ([]byte, []int) { - return file_universerpc_universe_proto_rawDescGZIP(), []int{3} + return file_universerpc_universe_proto_rawDescGZIP(), []int{5} } func (x *UniverseRoot) GetId() *ID { @@ -630,7 +738,7 @@ type AssetRootResponse struct { func (x *AssetRootResponse) Reset() { *x = AssetRootResponse{} if protoimpl.UnsafeEnabled { - mi := &file_universerpc_universe_proto_msgTypes[4] + mi := &file_universerpc_universe_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -643,7 +751,7 @@ func (x *AssetRootResponse) String() string { func (*AssetRootResponse) ProtoMessage() {} func (x *AssetRootResponse) ProtoReflect() protoreflect.Message { - mi := &file_universerpc_universe_proto_msgTypes[4] + mi := &file_universerpc_universe_proto_msgTypes[6] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -656,7 +764,7 @@ func (x *AssetRootResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use AssetRootResponse.ProtoReflect.Descriptor instead. func (*AssetRootResponse) Descriptor() ([]byte, []int) { - return file_universerpc_universe_proto_rawDescGZIP(), []int{4} + return file_universerpc_universe_proto_rawDescGZIP(), []int{6} } func (x *AssetRootResponse) GetUniverseRoots() map[string]*UniverseRoot { @@ -678,7 +786,7 @@ type AssetRootQuery struct { func (x *AssetRootQuery) Reset() { *x = AssetRootQuery{} if protoimpl.UnsafeEnabled { - mi := &file_universerpc_universe_proto_msgTypes[5] + mi := &file_universerpc_universe_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -691,7 +799,7 @@ func (x *AssetRootQuery) String() string { func (*AssetRootQuery) ProtoMessage() {} func (x *AssetRootQuery) ProtoReflect() protoreflect.Message { - mi := &file_universerpc_universe_proto_msgTypes[5] + mi := &file_universerpc_universe_proto_msgTypes[7] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -704,7 +812,7 @@ func (x *AssetRootQuery) ProtoReflect() protoreflect.Message { // Deprecated: Use AssetRootQuery.ProtoReflect.Descriptor instead. func (*AssetRootQuery) Descriptor() ([]byte, []int) { - return file_universerpc_universe_proto_rawDescGZIP(), []int{5} + return file_universerpc_universe_proto_rawDescGZIP(), []int{7} } func (x *AssetRootQuery) GetId() *ID { @@ -728,7 +836,7 @@ type QueryRootResponse struct { func (x *QueryRootResponse) Reset() { *x = QueryRootResponse{} if protoimpl.UnsafeEnabled { - mi := &file_universerpc_universe_proto_msgTypes[6] + mi := &file_universerpc_universe_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -741,7 +849,7 @@ func (x *QueryRootResponse) String() string { func (*QueryRootResponse) ProtoMessage() {} func (x *QueryRootResponse) ProtoReflect() protoreflect.Message { - mi := &file_universerpc_universe_proto_msgTypes[6] + mi := &file_universerpc_universe_proto_msgTypes[8] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -754,7 +862,7 @@ func (x *QueryRootResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use QueryRootResponse.ProtoReflect.Descriptor instead. func (*QueryRootResponse) Descriptor() ([]byte, []int) { - return file_universerpc_universe_proto_rawDescGZIP(), []int{6} + return file_universerpc_universe_proto_rawDescGZIP(), []int{8} } func (x *QueryRootResponse) GetIssuanceRoot() *UniverseRoot { @@ -783,7 +891,7 @@ type DeleteRootQuery struct { func (x *DeleteRootQuery) Reset() { *x = DeleteRootQuery{} if protoimpl.UnsafeEnabled { - mi := &file_universerpc_universe_proto_msgTypes[7] + mi := &file_universerpc_universe_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -796,7 +904,7 @@ func (x *DeleteRootQuery) String() string { func (*DeleteRootQuery) ProtoMessage() {} func (x *DeleteRootQuery) ProtoReflect() protoreflect.Message { - mi := &file_universerpc_universe_proto_msgTypes[7] + mi := &file_universerpc_universe_proto_msgTypes[9] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -809,7 +917,7 @@ func (x *DeleteRootQuery) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteRootQuery.ProtoReflect.Descriptor instead. func (*DeleteRootQuery) Descriptor() ([]byte, []int) { - return file_universerpc_universe_proto_rawDescGZIP(), []int{7} + return file_universerpc_universe_proto_rawDescGZIP(), []int{9} } func (x *DeleteRootQuery) GetId() *ID { @@ -828,7 +936,7 @@ type DeleteRootResponse struct { func (x *DeleteRootResponse) Reset() { *x = DeleteRootResponse{} if protoimpl.UnsafeEnabled { - mi := &file_universerpc_universe_proto_msgTypes[8] + mi := &file_universerpc_universe_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -841,7 +949,7 @@ func (x *DeleteRootResponse) String() string { func (*DeleteRootResponse) ProtoMessage() {} func (x *DeleteRootResponse) ProtoReflect() protoreflect.Message { - mi := &file_universerpc_universe_proto_msgTypes[8] + mi := &file_universerpc_universe_proto_msgTypes[10] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -854,7 +962,7 @@ func (x *DeleteRootResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteRootResponse.ProtoReflect.Descriptor instead. func (*DeleteRootResponse) Descriptor() ([]byte, []int) { - return file_universerpc_universe_proto_rawDescGZIP(), []int{8} + return file_universerpc_universe_proto_rawDescGZIP(), []int{10} } type Outpoint struct { @@ -871,7 +979,7 @@ type Outpoint struct { func (x *Outpoint) Reset() { *x = Outpoint{} if protoimpl.UnsafeEnabled { - mi := &file_universerpc_universe_proto_msgTypes[9] + mi := &file_universerpc_universe_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -884,7 +992,7 @@ func (x *Outpoint) String() string { func (*Outpoint) ProtoMessage() {} func (x *Outpoint) ProtoReflect() protoreflect.Message { - mi := &file_universerpc_universe_proto_msgTypes[9] + mi := &file_universerpc_universe_proto_msgTypes[11] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -897,7 +1005,7 @@ func (x *Outpoint) ProtoReflect() protoreflect.Message { // Deprecated: Use Outpoint.ProtoReflect.Descriptor instead. func (*Outpoint) Descriptor() ([]byte, []int) { - return file_universerpc_universe_proto_rawDescGZIP(), []int{9} + return file_universerpc_universe_proto_rawDescGZIP(), []int{11} } func (x *Outpoint) GetHashStr() string { @@ -939,7 +1047,7 @@ type AssetKey struct { func (x *AssetKey) Reset() { *x = AssetKey{} if protoimpl.UnsafeEnabled { - mi := &file_universerpc_universe_proto_msgTypes[10] + mi := &file_universerpc_universe_proto_msgTypes[12] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -952,7 +1060,7 @@ func (x *AssetKey) String() string { func (*AssetKey) ProtoMessage() {} func (x *AssetKey) ProtoReflect() protoreflect.Message { - mi := &file_universerpc_universe_proto_msgTypes[10] + mi := &file_universerpc_universe_proto_msgTypes[12] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -965,7 +1073,7 @@ func (x *AssetKey) ProtoReflect() protoreflect.Message { // Deprecated: Use AssetKey.ProtoReflect.Descriptor instead. func (*AssetKey) Descriptor() ([]byte, []int) { - return file_universerpc_universe_proto_rawDescGZIP(), []int{10} + return file_universerpc_universe_proto_rawDescGZIP(), []int{12} } func (m *AssetKey) GetOutpoint() isAssetKey_Outpoint { @@ -1060,7 +1168,7 @@ type AssetLeafKeysRequest struct { func (x *AssetLeafKeysRequest) Reset() { *x = AssetLeafKeysRequest{} if protoimpl.UnsafeEnabled { - mi := &file_universerpc_universe_proto_msgTypes[11] + mi := &file_universerpc_universe_proto_msgTypes[13] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1073,7 +1181,7 @@ func (x *AssetLeafKeysRequest) String() string { func (*AssetLeafKeysRequest) ProtoMessage() {} func (x *AssetLeafKeysRequest) ProtoReflect() protoreflect.Message { - mi := &file_universerpc_universe_proto_msgTypes[11] + mi := &file_universerpc_universe_proto_msgTypes[13] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1086,7 +1194,7 @@ func (x *AssetLeafKeysRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use AssetLeafKeysRequest.ProtoReflect.Descriptor instead. func (*AssetLeafKeysRequest) Descriptor() ([]byte, []int) { - return file_universerpc_universe_proto_rawDescGZIP(), []int{11} + return file_universerpc_universe_proto_rawDescGZIP(), []int{13} } func (x *AssetLeafKeysRequest) GetId() *ID { @@ -1129,7 +1237,7 @@ type AssetLeafKeyResponse struct { func (x *AssetLeafKeyResponse) Reset() { *x = AssetLeafKeyResponse{} if protoimpl.UnsafeEnabled { - mi := &file_universerpc_universe_proto_msgTypes[12] + mi := &file_universerpc_universe_proto_msgTypes[14] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1142,7 +1250,7 @@ func (x *AssetLeafKeyResponse) String() string { func (*AssetLeafKeyResponse) ProtoMessage() {} func (x *AssetLeafKeyResponse) ProtoReflect() protoreflect.Message { - mi := &file_universerpc_universe_proto_msgTypes[12] + mi := &file_universerpc_universe_proto_msgTypes[14] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1155,7 +1263,7 @@ func (x *AssetLeafKeyResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use AssetLeafKeyResponse.ProtoReflect.Descriptor instead. func (*AssetLeafKeyResponse) Descriptor() ([]byte, []int) { - return file_universerpc_universe_proto_rawDescGZIP(), []int{12} + return file_universerpc_universe_proto_rawDescGZIP(), []int{14} } func (x *AssetLeafKeyResponse) GetAssetKeys() []*AssetKey { @@ -1181,7 +1289,7 @@ type AssetLeaf struct { func (x *AssetLeaf) Reset() { *x = AssetLeaf{} if protoimpl.UnsafeEnabled { - mi := &file_universerpc_universe_proto_msgTypes[13] + mi := &file_universerpc_universe_proto_msgTypes[15] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1194,7 +1302,7 @@ func (x *AssetLeaf) String() string { func (*AssetLeaf) ProtoMessage() {} func (x *AssetLeaf) ProtoReflect() protoreflect.Message { - mi := &file_universerpc_universe_proto_msgTypes[13] + mi := &file_universerpc_universe_proto_msgTypes[15] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1207,7 +1315,7 @@ func (x *AssetLeaf) ProtoReflect() protoreflect.Message { // Deprecated: Use AssetLeaf.ProtoReflect.Descriptor instead. func (*AssetLeaf) Descriptor() ([]byte, []int) { - return file_universerpc_universe_proto_rawDescGZIP(), []int{13} + return file_universerpc_universe_proto_rawDescGZIP(), []int{15} } func (x *AssetLeaf) GetAsset() *taprpc.Asset { @@ -1236,7 +1344,7 @@ type AssetLeafResponse struct { func (x *AssetLeafResponse) Reset() { *x = AssetLeafResponse{} if protoimpl.UnsafeEnabled { - mi := &file_universerpc_universe_proto_msgTypes[14] + mi := &file_universerpc_universe_proto_msgTypes[16] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1249,7 +1357,7 @@ func (x *AssetLeafResponse) String() string { func (*AssetLeafResponse) ProtoMessage() {} func (x *AssetLeafResponse) ProtoReflect() protoreflect.Message { - mi := &file_universerpc_universe_proto_msgTypes[14] + mi := &file_universerpc_universe_proto_msgTypes[16] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1262,7 +1370,7 @@ func (x *AssetLeafResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use AssetLeafResponse.ProtoReflect.Descriptor instead. func (*AssetLeafResponse) Descriptor() ([]byte, []int) { - return file_universerpc_universe_proto_rawDescGZIP(), []int{14} + return file_universerpc_universe_proto_rawDescGZIP(), []int{16} } func (x *AssetLeafResponse) GetLeaves() []*AssetLeaf { @@ -1286,7 +1394,7 @@ type UniverseKey struct { func (x *UniverseKey) Reset() { *x = UniverseKey{} if protoimpl.UnsafeEnabled { - mi := &file_universerpc_universe_proto_msgTypes[15] + mi := &file_universerpc_universe_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1299,7 +1407,7 @@ func (x *UniverseKey) String() string { func (*UniverseKey) ProtoMessage() {} func (x *UniverseKey) ProtoReflect() protoreflect.Message { - mi := &file_universerpc_universe_proto_msgTypes[15] + mi := &file_universerpc_universe_proto_msgTypes[17] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1312,7 +1420,7 @@ func (x *UniverseKey) ProtoReflect() protoreflect.Message { // Deprecated: Use UniverseKey.ProtoReflect.Descriptor instead. func (*UniverseKey) Descriptor() ([]byte, []int) { - return file_universerpc_universe_proto_rawDescGZIP(), []int{15} + return file_universerpc_universe_proto_rawDescGZIP(), []int{17} } func (x *UniverseKey) GetId() *ID { @@ -1354,7 +1462,7 @@ type AssetProofResponse struct { func (x *AssetProofResponse) Reset() { *x = AssetProofResponse{} if protoimpl.UnsafeEnabled { - mi := &file_universerpc_universe_proto_msgTypes[16] + mi := &file_universerpc_universe_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1367,7 +1475,7 @@ func (x *AssetProofResponse) String() string { func (*AssetProofResponse) ProtoMessage() {} func (x *AssetProofResponse) ProtoReflect() protoreflect.Message { - mi := &file_universerpc_universe_proto_msgTypes[16] + mi := &file_universerpc_universe_proto_msgTypes[18] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1380,7 +1488,7 @@ func (x *AssetProofResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use AssetProofResponse.ProtoReflect.Descriptor instead. func (*AssetProofResponse) Descriptor() ([]byte, []int) { - return file_universerpc_universe_proto_rawDescGZIP(), []int{16} + return file_universerpc_universe_proto_rawDescGZIP(), []int{18} } func (x *AssetProofResponse) GetReq() *UniverseKey { @@ -1439,7 +1547,7 @@ type AssetProof struct { func (x *AssetProof) Reset() { *x = AssetProof{} if protoimpl.UnsafeEnabled { - mi := &file_universerpc_universe_proto_msgTypes[17] + mi := &file_universerpc_universe_proto_msgTypes[19] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1452,7 +1560,7 @@ func (x *AssetProof) String() string { func (*AssetProof) ProtoMessage() {} func (x *AssetProof) ProtoReflect() protoreflect.Message { - mi := &file_universerpc_universe_proto_msgTypes[17] + mi := &file_universerpc_universe_proto_msgTypes[19] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1465,7 +1573,7 @@ func (x *AssetProof) ProtoReflect() protoreflect.Message { // Deprecated: Use AssetProof.ProtoReflect.Descriptor instead. func (*AssetProof) Descriptor() ([]byte, []int) { - return file_universerpc_universe_proto_rawDescGZIP(), []int{17} + return file_universerpc_universe_proto_rawDescGZIP(), []int{19} } func (x *AssetProof) GetKey() *UniverseKey { @@ -1491,7 +1599,7 @@ type InfoRequest struct { func (x *InfoRequest) Reset() { *x = InfoRequest{} if protoimpl.UnsafeEnabled { - mi := &file_universerpc_universe_proto_msgTypes[18] + mi := &file_universerpc_universe_proto_msgTypes[20] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1504,7 +1612,7 @@ func (x *InfoRequest) String() string { func (*InfoRequest) ProtoMessage() {} func (x *InfoRequest) ProtoReflect() protoreflect.Message { - mi := &file_universerpc_universe_proto_msgTypes[18] + mi := &file_universerpc_universe_proto_msgTypes[20] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1517,7 +1625,7 @@ func (x *InfoRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use InfoRequest.ProtoReflect.Descriptor instead. func (*InfoRequest) Descriptor() ([]byte, []int) { - return file_universerpc_universe_proto_rawDescGZIP(), []int{18} + return file_universerpc_universe_proto_rawDescGZIP(), []int{20} } type InfoResponse struct { @@ -1534,7 +1642,7 @@ type InfoResponse struct { func (x *InfoResponse) Reset() { *x = InfoResponse{} if protoimpl.UnsafeEnabled { - mi := &file_universerpc_universe_proto_msgTypes[19] + mi := &file_universerpc_universe_proto_msgTypes[21] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1547,7 +1655,7 @@ func (x *InfoResponse) String() string { func (*InfoResponse) ProtoMessage() {} func (x *InfoResponse) ProtoReflect() protoreflect.Message { - mi := &file_universerpc_universe_proto_msgTypes[19] + mi := &file_universerpc_universe_proto_msgTypes[21] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1560,7 +1668,7 @@ func (x *InfoResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use InfoResponse.ProtoReflect.Descriptor instead. func (*InfoResponse) Descriptor() ([]byte, []int) { - return file_universerpc_universe_proto_rawDescGZIP(), []int{19} + return file_universerpc_universe_proto_rawDescGZIP(), []int{21} } func (x *InfoResponse) GetRuntimeId() int64 { @@ -1581,7 +1689,7 @@ type SyncTarget struct { func (x *SyncTarget) Reset() { *x = SyncTarget{} if protoimpl.UnsafeEnabled { - mi := &file_universerpc_universe_proto_msgTypes[20] + mi := &file_universerpc_universe_proto_msgTypes[22] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1594,7 +1702,7 @@ func (x *SyncTarget) String() string { func (*SyncTarget) ProtoMessage() {} func (x *SyncTarget) ProtoReflect() protoreflect.Message { - mi := &file_universerpc_universe_proto_msgTypes[20] + mi := &file_universerpc_universe_proto_msgTypes[22] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1607,7 +1715,7 @@ func (x *SyncTarget) ProtoReflect() protoreflect.Message { // Deprecated: Use SyncTarget.ProtoReflect.Descriptor instead. func (*SyncTarget) Descriptor() ([]byte, []int) { - return file_universerpc_universe_proto_rawDescGZIP(), []int{20} + return file_universerpc_universe_proto_rawDescGZIP(), []int{22} } func (x *SyncTarget) GetId() *ID { @@ -1635,7 +1743,7 @@ type SyncRequest struct { func (x *SyncRequest) Reset() { *x = SyncRequest{} if protoimpl.UnsafeEnabled { - mi := &file_universerpc_universe_proto_msgTypes[21] + mi := &file_universerpc_universe_proto_msgTypes[23] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1648,7 +1756,7 @@ func (x *SyncRequest) String() string { func (*SyncRequest) ProtoMessage() {} func (x *SyncRequest) ProtoReflect() protoreflect.Message { - mi := &file_universerpc_universe_proto_msgTypes[21] + mi := &file_universerpc_universe_proto_msgTypes[23] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1661,7 +1769,7 @@ func (x *SyncRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use SyncRequest.ProtoReflect.Descriptor instead. func (*SyncRequest) Descriptor() ([]byte, []int) { - return file_universerpc_universe_proto_rawDescGZIP(), []int{21} + return file_universerpc_universe_proto_rawDescGZIP(), []int{23} } func (x *SyncRequest) GetUniverseHost() string { @@ -1701,7 +1809,7 @@ type SyncedUniverse struct { func (x *SyncedUniverse) Reset() { *x = SyncedUniverse{} if protoimpl.UnsafeEnabled { - mi := &file_universerpc_universe_proto_msgTypes[22] + mi := &file_universerpc_universe_proto_msgTypes[24] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1714,7 +1822,7 @@ func (x *SyncedUniverse) String() string { func (*SyncedUniverse) ProtoMessage() {} func (x *SyncedUniverse) ProtoReflect() protoreflect.Message { - mi := &file_universerpc_universe_proto_msgTypes[22] + mi := &file_universerpc_universe_proto_msgTypes[24] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1727,7 +1835,7 @@ func (x *SyncedUniverse) ProtoReflect() protoreflect.Message { // Deprecated: Use SyncedUniverse.ProtoReflect.Descriptor instead. func (*SyncedUniverse) Descriptor() ([]byte, []int) { - return file_universerpc_universe_proto_rawDescGZIP(), []int{22} + return file_universerpc_universe_proto_rawDescGZIP(), []int{24} } func (x *SyncedUniverse) GetOldAssetRoot() *UniverseRoot { @@ -1760,7 +1868,7 @@ type StatsRequest struct { func (x *StatsRequest) Reset() { *x = StatsRequest{} if protoimpl.UnsafeEnabled { - mi := &file_universerpc_universe_proto_msgTypes[23] + mi := &file_universerpc_universe_proto_msgTypes[25] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1773,7 +1881,7 @@ func (x *StatsRequest) String() string { func (*StatsRequest) ProtoMessage() {} func (x *StatsRequest) ProtoReflect() protoreflect.Message { - mi := &file_universerpc_universe_proto_msgTypes[23] + mi := &file_universerpc_universe_proto_msgTypes[25] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1786,7 +1894,7 @@ func (x *StatsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use StatsRequest.ProtoReflect.Descriptor instead. func (*StatsRequest) Descriptor() ([]byte, []int) { - return file_universerpc_universe_proto_rawDescGZIP(), []int{23} + return file_universerpc_universe_proto_rawDescGZIP(), []int{25} } type SyncResponse struct { @@ -1801,7 +1909,7 @@ type SyncResponse struct { func (x *SyncResponse) Reset() { *x = SyncResponse{} if protoimpl.UnsafeEnabled { - mi := &file_universerpc_universe_proto_msgTypes[24] + mi := &file_universerpc_universe_proto_msgTypes[26] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1814,7 +1922,7 @@ func (x *SyncResponse) String() string { func (*SyncResponse) ProtoMessage() {} func (x *SyncResponse) ProtoReflect() protoreflect.Message { - mi := &file_universerpc_universe_proto_msgTypes[24] + mi := &file_universerpc_universe_proto_msgTypes[26] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1827,7 +1935,7 @@ func (x *SyncResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use SyncResponse.ProtoReflect.Descriptor instead. func (*SyncResponse) Descriptor() ([]byte, []int) { - return file_universerpc_universe_proto_rawDescGZIP(), []int{24} + return file_universerpc_universe_proto_rawDescGZIP(), []int{26} } func (x *SyncResponse) GetSyncedUniverses() []*SyncedUniverse { @@ -1849,7 +1957,7 @@ type UniverseFederationServer struct { func (x *UniverseFederationServer) Reset() { *x = UniverseFederationServer{} if protoimpl.UnsafeEnabled { - mi := &file_universerpc_universe_proto_msgTypes[25] + mi := &file_universerpc_universe_proto_msgTypes[27] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1862,7 +1970,7 @@ func (x *UniverseFederationServer) String() string { func (*UniverseFederationServer) ProtoMessage() {} func (x *UniverseFederationServer) ProtoReflect() protoreflect.Message { - mi := &file_universerpc_universe_proto_msgTypes[25] + mi := &file_universerpc_universe_proto_msgTypes[27] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1875,7 +1983,7 @@ func (x *UniverseFederationServer) ProtoReflect() protoreflect.Message { // Deprecated: Use UniverseFederationServer.ProtoReflect.Descriptor instead. func (*UniverseFederationServer) Descriptor() ([]byte, []int) { - return file_universerpc_universe_proto_rawDescGZIP(), []int{25} + return file_universerpc_universe_proto_rawDescGZIP(), []int{27} } func (x *UniverseFederationServer) GetHost() string { @@ -1901,7 +2009,7 @@ type ListFederationServersRequest struct { func (x *ListFederationServersRequest) Reset() { *x = ListFederationServersRequest{} if protoimpl.UnsafeEnabled { - mi := &file_universerpc_universe_proto_msgTypes[26] + mi := &file_universerpc_universe_proto_msgTypes[28] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1914,7 +2022,7 @@ func (x *ListFederationServersRequest) String() string { func (*ListFederationServersRequest) ProtoMessage() {} func (x *ListFederationServersRequest) ProtoReflect() protoreflect.Message { - mi := &file_universerpc_universe_proto_msgTypes[26] + mi := &file_universerpc_universe_proto_msgTypes[28] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1927,7 +2035,7 @@ func (x *ListFederationServersRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListFederationServersRequest.ProtoReflect.Descriptor instead. func (*ListFederationServersRequest) Descriptor() ([]byte, []int) { - return file_universerpc_universe_proto_rawDescGZIP(), []int{26} + return file_universerpc_universe_proto_rawDescGZIP(), []int{28} } type ListFederationServersResponse struct { @@ -1941,7 +2049,7 @@ type ListFederationServersResponse struct { func (x *ListFederationServersResponse) Reset() { *x = ListFederationServersResponse{} if protoimpl.UnsafeEnabled { - mi := &file_universerpc_universe_proto_msgTypes[27] + mi := &file_universerpc_universe_proto_msgTypes[29] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1954,7 +2062,7 @@ func (x *ListFederationServersResponse) String() string { func (*ListFederationServersResponse) ProtoMessage() {} func (x *ListFederationServersResponse) ProtoReflect() protoreflect.Message { - mi := &file_universerpc_universe_proto_msgTypes[27] + mi := &file_universerpc_universe_proto_msgTypes[29] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1967,7 +2075,7 @@ func (x *ListFederationServersResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListFederationServersResponse.ProtoReflect.Descriptor instead. func (*ListFederationServersResponse) Descriptor() ([]byte, []int) { - return file_universerpc_universe_proto_rawDescGZIP(), []int{27} + return file_universerpc_universe_proto_rawDescGZIP(), []int{29} } func (x *ListFederationServersResponse) GetServers() []*UniverseFederationServer { @@ -1988,7 +2096,7 @@ type AddFederationServerRequest struct { func (x *AddFederationServerRequest) Reset() { *x = AddFederationServerRequest{} if protoimpl.UnsafeEnabled { - mi := &file_universerpc_universe_proto_msgTypes[28] + mi := &file_universerpc_universe_proto_msgTypes[30] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2001,7 +2109,7 @@ func (x *AddFederationServerRequest) String() string { func (*AddFederationServerRequest) ProtoMessage() {} func (x *AddFederationServerRequest) ProtoReflect() protoreflect.Message { - mi := &file_universerpc_universe_proto_msgTypes[28] + mi := &file_universerpc_universe_proto_msgTypes[30] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2014,7 +2122,7 @@ func (x *AddFederationServerRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use AddFederationServerRequest.ProtoReflect.Descriptor instead. func (*AddFederationServerRequest) Descriptor() ([]byte, []int) { - return file_universerpc_universe_proto_rawDescGZIP(), []int{28} + return file_universerpc_universe_proto_rawDescGZIP(), []int{30} } func (x *AddFederationServerRequest) GetServers() []*UniverseFederationServer { @@ -2033,7 +2141,7 @@ type AddFederationServerResponse struct { func (x *AddFederationServerResponse) Reset() { *x = AddFederationServerResponse{} if protoimpl.UnsafeEnabled { - mi := &file_universerpc_universe_proto_msgTypes[29] + mi := &file_universerpc_universe_proto_msgTypes[31] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2046,7 +2154,7 @@ func (x *AddFederationServerResponse) String() string { func (*AddFederationServerResponse) ProtoMessage() {} func (x *AddFederationServerResponse) ProtoReflect() protoreflect.Message { - mi := &file_universerpc_universe_proto_msgTypes[29] + mi := &file_universerpc_universe_proto_msgTypes[31] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2059,7 +2167,7 @@ func (x *AddFederationServerResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use AddFederationServerResponse.ProtoReflect.Descriptor instead. func (*AddFederationServerResponse) Descriptor() ([]byte, []int) { - return file_universerpc_universe_proto_rawDescGZIP(), []int{29} + return file_universerpc_universe_proto_rawDescGZIP(), []int{31} } type DeleteFederationServerRequest struct { @@ -2073,7 +2181,7 @@ type DeleteFederationServerRequest struct { func (x *DeleteFederationServerRequest) Reset() { *x = DeleteFederationServerRequest{} if protoimpl.UnsafeEnabled { - mi := &file_universerpc_universe_proto_msgTypes[30] + mi := &file_universerpc_universe_proto_msgTypes[32] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2086,7 +2194,7 @@ func (x *DeleteFederationServerRequest) String() string { func (*DeleteFederationServerRequest) ProtoMessage() {} func (x *DeleteFederationServerRequest) ProtoReflect() protoreflect.Message { - mi := &file_universerpc_universe_proto_msgTypes[30] + mi := &file_universerpc_universe_proto_msgTypes[32] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2099,7 +2207,7 @@ func (x *DeleteFederationServerRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteFederationServerRequest.ProtoReflect.Descriptor instead. func (*DeleteFederationServerRequest) Descriptor() ([]byte, []int) { - return file_universerpc_universe_proto_rawDescGZIP(), []int{30} + return file_universerpc_universe_proto_rawDescGZIP(), []int{32} } func (x *DeleteFederationServerRequest) GetServers() []*UniverseFederationServer { @@ -2118,7 +2226,7 @@ type DeleteFederationServerResponse struct { func (x *DeleteFederationServerResponse) Reset() { *x = DeleteFederationServerResponse{} if protoimpl.UnsafeEnabled { - mi := &file_universerpc_universe_proto_msgTypes[31] + mi := &file_universerpc_universe_proto_msgTypes[33] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2131,7 +2239,7 @@ func (x *DeleteFederationServerResponse) String() string { func (*DeleteFederationServerResponse) ProtoMessage() {} func (x *DeleteFederationServerResponse) ProtoReflect() protoreflect.Message { - mi := &file_universerpc_universe_proto_msgTypes[31] + mi := &file_universerpc_universe_proto_msgTypes[33] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2144,7 +2252,7 @@ func (x *DeleteFederationServerResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteFederationServerResponse.ProtoReflect.Descriptor instead. func (*DeleteFederationServerResponse) Descriptor() ([]byte, []int) { - return file_universerpc_universe_proto_rawDescGZIP(), []int{31} + return file_universerpc_universe_proto_rawDescGZIP(), []int{33} } type StatsResponse struct { @@ -2161,7 +2269,7 @@ type StatsResponse struct { func (x *StatsResponse) Reset() { *x = StatsResponse{} if protoimpl.UnsafeEnabled { - mi := &file_universerpc_universe_proto_msgTypes[32] + mi := &file_universerpc_universe_proto_msgTypes[34] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2174,7 +2282,7 @@ func (x *StatsResponse) String() string { func (*StatsResponse) ProtoMessage() {} func (x *StatsResponse) ProtoReflect() protoreflect.Message { - mi := &file_universerpc_universe_proto_msgTypes[32] + mi := &file_universerpc_universe_proto_msgTypes[34] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2187,7 +2295,7 @@ func (x *StatsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use StatsResponse.ProtoReflect.Descriptor instead. func (*StatsResponse) Descriptor() ([]byte, []int) { - return file_universerpc_universe_proto_rawDescGZIP(), []int{32} + return file_universerpc_universe_proto_rawDescGZIP(), []int{34} } func (x *StatsResponse) GetNumTotalAssets() int64 { @@ -2235,7 +2343,7 @@ type AssetStatsQuery struct { func (x *AssetStatsQuery) Reset() { *x = AssetStatsQuery{} if protoimpl.UnsafeEnabled { - mi := &file_universerpc_universe_proto_msgTypes[33] + mi := &file_universerpc_universe_proto_msgTypes[35] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2248,7 +2356,7 @@ func (x *AssetStatsQuery) String() string { func (*AssetStatsQuery) ProtoMessage() {} func (x *AssetStatsQuery) ProtoReflect() protoreflect.Message { - mi := &file_universerpc_universe_proto_msgTypes[33] + mi := &file_universerpc_universe_proto_msgTypes[35] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2261,7 +2369,7 @@ func (x *AssetStatsQuery) ProtoReflect() protoreflect.Message { // Deprecated: Use AssetStatsQuery.ProtoReflect.Descriptor instead. func (*AssetStatsQuery) Descriptor() ([]byte, []int) { - return file_universerpc_universe_proto_rawDescGZIP(), []int{33} + return file_universerpc_universe_proto_rawDescGZIP(), []int{35} } func (x *AssetStatsQuery) GetAssetNameFilter() string { @@ -2341,7 +2449,7 @@ type AssetStatsSnapshot struct { func (x *AssetStatsSnapshot) Reset() { *x = AssetStatsSnapshot{} if protoimpl.UnsafeEnabled { - mi := &file_universerpc_universe_proto_msgTypes[34] + mi := &file_universerpc_universe_proto_msgTypes[36] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2354,7 +2462,7 @@ func (x *AssetStatsSnapshot) String() string { func (*AssetStatsSnapshot) ProtoMessage() {} func (x *AssetStatsSnapshot) ProtoReflect() protoreflect.Message { - mi := &file_universerpc_universe_proto_msgTypes[34] + mi := &file_universerpc_universe_proto_msgTypes[36] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2367,7 +2475,7 @@ func (x *AssetStatsSnapshot) ProtoReflect() protoreflect.Message { // Deprecated: Use AssetStatsSnapshot.ProtoReflect.Descriptor instead. func (*AssetStatsSnapshot) Descriptor() ([]byte, []int) { - return file_universerpc_universe_proto_rawDescGZIP(), []int{34} + return file_universerpc_universe_proto_rawDescGZIP(), []int{36} } func (x *AssetStatsSnapshot) GetGroupKey() []byte { @@ -2430,7 +2538,7 @@ type AssetStatsAsset struct { func (x *AssetStatsAsset) Reset() { *x = AssetStatsAsset{} if protoimpl.UnsafeEnabled { - mi := &file_universerpc_universe_proto_msgTypes[35] + mi := &file_universerpc_universe_proto_msgTypes[37] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2443,7 +2551,7 @@ func (x *AssetStatsAsset) String() string { func (*AssetStatsAsset) ProtoMessage() {} func (x *AssetStatsAsset) ProtoReflect() protoreflect.Message { - mi := &file_universerpc_universe_proto_msgTypes[35] + mi := &file_universerpc_universe_proto_msgTypes[37] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2456,7 +2564,7 @@ func (x *AssetStatsAsset) ProtoReflect() protoreflect.Message { // Deprecated: Use AssetStatsAsset.ProtoReflect.Descriptor instead. func (*AssetStatsAsset) Descriptor() ([]byte, []int) { - return file_universerpc_universe_proto_rawDescGZIP(), []int{35} + return file_universerpc_universe_proto_rawDescGZIP(), []int{37} } func (x *AssetStatsAsset) GetAssetId() []byte { @@ -2526,7 +2634,7 @@ type UniverseAssetStats struct { func (x *UniverseAssetStats) Reset() { *x = UniverseAssetStats{} if protoimpl.UnsafeEnabled { - mi := &file_universerpc_universe_proto_msgTypes[36] + mi := &file_universerpc_universe_proto_msgTypes[38] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2539,7 +2647,7 @@ func (x *UniverseAssetStats) String() string { func (*UniverseAssetStats) ProtoMessage() {} func (x *UniverseAssetStats) ProtoReflect() protoreflect.Message { - mi := &file_universerpc_universe_proto_msgTypes[36] + mi := &file_universerpc_universe_proto_msgTypes[38] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2552,7 +2660,7 @@ func (x *UniverseAssetStats) ProtoReflect() protoreflect.Message { // Deprecated: Use UniverseAssetStats.ProtoReflect.Descriptor instead. func (*UniverseAssetStats) Descriptor() ([]byte, []int) { - return file_universerpc_universe_proto_rawDescGZIP(), []int{36} + return file_universerpc_universe_proto_rawDescGZIP(), []int{38} } func (x *UniverseAssetStats) GetAssetStats() []*AssetStatsSnapshot { @@ -2574,7 +2682,7 @@ type QueryEventsRequest struct { func (x *QueryEventsRequest) Reset() { *x = QueryEventsRequest{} if protoimpl.UnsafeEnabled { - mi := &file_universerpc_universe_proto_msgTypes[37] + mi := &file_universerpc_universe_proto_msgTypes[39] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2587,7 +2695,7 @@ func (x *QueryEventsRequest) String() string { func (*QueryEventsRequest) ProtoMessage() {} func (x *QueryEventsRequest) ProtoReflect() protoreflect.Message { - mi := &file_universerpc_universe_proto_msgTypes[37] + mi := &file_universerpc_universe_proto_msgTypes[39] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2600,7 +2708,7 @@ func (x *QueryEventsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use QueryEventsRequest.ProtoReflect.Descriptor instead. func (*QueryEventsRequest) Descriptor() ([]byte, []int) { - return file_universerpc_universe_proto_rawDescGZIP(), []int{37} + return file_universerpc_universe_proto_rawDescGZIP(), []int{39} } func (x *QueryEventsRequest) GetStartTimestamp() int64 { @@ -2628,7 +2736,7 @@ type QueryEventsResponse struct { func (x *QueryEventsResponse) Reset() { *x = QueryEventsResponse{} if protoimpl.UnsafeEnabled { - mi := &file_universerpc_universe_proto_msgTypes[38] + mi := &file_universerpc_universe_proto_msgTypes[40] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2641,7 +2749,7 @@ func (x *QueryEventsResponse) String() string { func (*QueryEventsResponse) ProtoMessage() {} func (x *QueryEventsResponse) ProtoReflect() protoreflect.Message { - mi := &file_universerpc_universe_proto_msgTypes[38] + mi := &file_universerpc_universe_proto_msgTypes[40] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2654,7 +2762,7 @@ func (x *QueryEventsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use QueryEventsResponse.ProtoReflect.Descriptor instead. func (*QueryEventsResponse) Descriptor() ([]byte, []int) { - return file_universerpc_universe_proto_rawDescGZIP(), []int{38} + return file_universerpc_universe_proto_rawDescGZIP(), []int{40} } func (x *QueryEventsResponse) GetEvents() []*GroupedUniverseEvents { @@ -2678,7 +2786,7 @@ type GroupedUniverseEvents struct { func (x *GroupedUniverseEvents) Reset() { *x = GroupedUniverseEvents{} if protoimpl.UnsafeEnabled { - mi := &file_universerpc_universe_proto_msgTypes[39] + mi := &file_universerpc_universe_proto_msgTypes[41] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2691,7 +2799,7 @@ func (x *GroupedUniverseEvents) String() string { func (*GroupedUniverseEvents) ProtoMessage() {} func (x *GroupedUniverseEvents) ProtoReflect() protoreflect.Message { - mi := &file_universerpc_universe_proto_msgTypes[39] + mi := &file_universerpc_universe_proto_msgTypes[41] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2704,7 +2812,7 @@ func (x *GroupedUniverseEvents) ProtoReflect() protoreflect.Message { // Deprecated: Use GroupedUniverseEvents.ProtoReflect.Descriptor instead. func (*GroupedUniverseEvents) Descriptor() ([]byte, []int) { - return file_universerpc_universe_proto_rawDescGZIP(), []int{39} + return file_universerpc_universe_proto_rawDescGZIP(), []int{41} } func (x *GroupedUniverseEvents) GetDate() string { @@ -2740,7 +2848,7 @@ type SetFederationSyncConfigRequest struct { func (x *SetFederationSyncConfigRequest) Reset() { *x = SetFederationSyncConfigRequest{} if protoimpl.UnsafeEnabled { - mi := &file_universerpc_universe_proto_msgTypes[40] + mi := &file_universerpc_universe_proto_msgTypes[42] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2753,7 +2861,7 @@ func (x *SetFederationSyncConfigRequest) String() string { func (*SetFederationSyncConfigRequest) ProtoMessage() {} func (x *SetFederationSyncConfigRequest) ProtoReflect() protoreflect.Message { - mi := &file_universerpc_universe_proto_msgTypes[40] + mi := &file_universerpc_universe_proto_msgTypes[42] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2766,7 +2874,7 @@ func (x *SetFederationSyncConfigRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use SetFederationSyncConfigRequest.ProtoReflect.Descriptor instead. func (*SetFederationSyncConfigRequest) Descriptor() ([]byte, []int) { - return file_universerpc_universe_proto_rawDescGZIP(), []int{40} + return file_universerpc_universe_proto_rawDescGZIP(), []int{42} } func (x *SetFederationSyncConfigRequest) GetGlobalSyncConfigs() []*GlobalFederationSyncConfig { @@ -2792,7 +2900,7 @@ type SetFederationSyncConfigResponse struct { func (x *SetFederationSyncConfigResponse) Reset() { *x = SetFederationSyncConfigResponse{} if protoimpl.UnsafeEnabled { - mi := &file_universerpc_universe_proto_msgTypes[41] + mi := &file_universerpc_universe_proto_msgTypes[43] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2805,7 +2913,7 @@ func (x *SetFederationSyncConfigResponse) String() string { func (*SetFederationSyncConfigResponse) ProtoMessage() {} func (x *SetFederationSyncConfigResponse) ProtoReflect() protoreflect.Message { - mi := &file_universerpc_universe_proto_msgTypes[41] + mi := &file_universerpc_universe_proto_msgTypes[43] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2818,7 +2926,7 @@ func (x *SetFederationSyncConfigResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use SetFederationSyncConfigResponse.ProtoReflect.Descriptor instead. func (*SetFederationSyncConfigResponse) Descriptor() ([]byte, []int) { - return file_universerpc_universe_proto_rawDescGZIP(), []int{41} + return file_universerpc_universe_proto_rawDescGZIP(), []int{43} } // GlobalFederationSyncConfig is a global proof type specific configuration @@ -2843,7 +2951,7 @@ type GlobalFederationSyncConfig struct { func (x *GlobalFederationSyncConfig) Reset() { *x = GlobalFederationSyncConfig{} if protoimpl.UnsafeEnabled { - mi := &file_universerpc_universe_proto_msgTypes[42] + mi := &file_universerpc_universe_proto_msgTypes[44] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2856,7 +2964,7 @@ func (x *GlobalFederationSyncConfig) String() string { func (*GlobalFederationSyncConfig) ProtoMessage() {} func (x *GlobalFederationSyncConfig) ProtoReflect() protoreflect.Message { - mi := &file_universerpc_universe_proto_msgTypes[42] + mi := &file_universerpc_universe_proto_msgTypes[44] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2869,7 +2977,7 @@ func (x *GlobalFederationSyncConfig) ProtoReflect() protoreflect.Message { // Deprecated: Use GlobalFederationSyncConfig.ProtoReflect.Descriptor instead. func (*GlobalFederationSyncConfig) Descriptor() ([]byte, []int) { - return file_universerpc_universe_proto_rawDescGZIP(), []int{42} + return file_universerpc_universe_proto_rawDescGZIP(), []int{44} } func (x *GlobalFederationSyncConfig) GetProofType() ProofType { @@ -2915,7 +3023,7 @@ type AssetFederationSyncConfig struct { func (x *AssetFederationSyncConfig) Reset() { *x = AssetFederationSyncConfig{} if protoimpl.UnsafeEnabled { - mi := &file_universerpc_universe_proto_msgTypes[43] + mi := &file_universerpc_universe_proto_msgTypes[45] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2928,7 +3036,7 @@ func (x *AssetFederationSyncConfig) String() string { func (*AssetFederationSyncConfig) ProtoMessage() {} func (x *AssetFederationSyncConfig) ProtoReflect() protoreflect.Message { - mi := &file_universerpc_universe_proto_msgTypes[43] + mi := &file_universerpc_universe_proto_msgTypes[45] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2941,7 +3049,7 @@ func (x *AssetFederationSyncConfig) ProtoReflect() protoreflect.Message { // Deprecated: Use AssetFederationSyncConfig.ProtoReflect.Descriptor instead. func (*AssetFederationSyncConfig) Descriptor() ([]byte, []int) { - return file_universerpc_universe_proto_rawDescGZIP(), []int{43} + return file_universerpc_universe_proto_rawDescGZIP(), []int{45} } func (x *AssetFederationSyncConfig) GetId() *ID { @@ -2977,7 +3085,7 @@ type QueryFederationSyncConfigRequest struct { func (x *QueryFederationSyncConfigRequest) Reset() { *x = QueryFederationSyncConfigRequest{} if protoimpl.UnsafeEnabled { - mi := &file_universerpc_universe_proto_msgTypes[44] + mi := &file_universerpc_universe_proto_msgTypes[46] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2990,7 +3098,7 @@ func (x *QueryFederationSyncConfigRequest) String() string { func (*QueryFederationSyncConfigRequest) ProtoMessage() {} func (x *QueryFederationSyncConfigRequest) ProtoReflect() protoreflect.Message { - mi := &file_universerpc_universe_proto_msgTypes[44] + mi := &file_universerpc_universe_proto_msgTypes[46] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3003,7 +3111,7 @@ func (x *QueryFederationSyncConfigRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use QueryFederationSyncConfigRequest.ProtoReflect.Descriptor instead. func (*QueryFederationSyncConfigRequest) Descriptor() ([]byte, []int) { - return file_universerpc_universe_proto_rawDescGZIP(), []int{44} + return file_universerpc_universe_proto_rawDescGZIP(), []int{46} } func (x *QueryFederationSyncConfigRequest) GetId() []*ID { @@ -3025,7 +3133,7 @@ type QueryFederationSyncConfigResponse struct { func (x *QueryFederationSyncConfigResponse) Reset() { *x = QueryFederationSyncConfigResponse{} if protoimpl.UnsafeEnabled { - mi := &file_universerpc_universe_proto_msgTypes[45] + mi := &file_universerpc_universe_proto_msgTypes[47] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3038,7 +3146,7 @@ func (x *QueryFederationSyncConfigResponse) String() string { func (*QueryFederationSyncConfigResponse) ProtoMessage() {} func (x *QueryFederationSyncConfigResponse) ProtoReflect() protoreflect.Message { - mi := &file_universerpc_universe_proto_msgTypes[45] + mi := &file_universerpc_universe_proto_msgTypes[47] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3051,7 +3159,7 @@ func (x *QueryFederationSyncConfigResponse) ProtoReflect() protoreflect.Message // Deprecated: Use QueryFederationSyncConfigResponse.ProtoReflect.Descriptor instead. func (*QueryFederationSyncConfigResponse) Descriptor() ([]byte, []int) { - return file_universerpc_universe_proto_rawDescGZIP(), []int{45} + return file_universerpc_universe_proto_rawDescGZIP(), []int{47} } func (x *QueryFederationSyncConfigResponse) GetGlobalSyncConfigs() []*GlobalFederationSyncConfig { @@ -3074,504 +3182,523 @@ var file_universerpc_universe_proto_rawDesc = []byte{ 0x0a, 0x1a, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x2f, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0b, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x72, 0x70, 0x63, 0x1a, 0x13, 0x74, 0x61, 0x70, 0x72, 0x6f, - 0x6f, 0x74, 0x61, 0x73, 0x73, 0x65, 0x74, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xa7, - 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, 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, 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, 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, + 0x6f, 0x74, 0x61, 0x73, 0x73, 0x65, 0x74, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x82, + 0x01, 0x0a, 0x15, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x52, 0x6f, 0x6f, + 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 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, + 0x32, 0x0a, 0x0c, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x5f, 0x69, 0x64, 0x73, 0x18, + 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, + 0x72, 0x70, 0x63, 0x2e, 0x49, 0x44, 0x52, 0x0b, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, + 0x49, 0x64, 0x73, 0x22, 0x5d, 0x0a, 0x16, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x76, 0x65, 0x72, 0x73, + 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x43, 0x0a, + 0x0f, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x5f, 0x72, 0x6f, 0x6f, 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, 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, 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, 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, - 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, 0xf4, 0x02, 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, 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, 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, + 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, 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, + 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, 0xf4, 0x02, 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, - 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, + 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, + 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, 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, 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, 0xbc, 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, 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, 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, 0xbc, 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, 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, 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, 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, 0xcf, 0x0b, 0x0a, 0x08, 0x55, 0x6e, - 0x69, 0x76, 0x65, 0x72, 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, + 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, + 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, 0xaa, 0x0c, + 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, - 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, 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, 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, + 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, 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, 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, + 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, 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, + 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, 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, + 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, 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 ( @@ -3587,154 +3714,161 @@ func file_universerpc_universe_proto_rawDescGZIP() []byte { } var file_universerpc_universe_proto_enumTypes = make([]protoimpl.EnumInfo, 5) -var file_universerpc_universe_proto_msgTypes = make([]protoimpl.MessageInfo, 48) +var file_universerpc_universe_proto_msgTypes = make([]protoimpl.MessageInfo, 50) var file_universerpc_universe_proto_goTypes = []interface{}{ (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 - (*AssetRootRequest)(nil), // 5: universerpc.AssetRootRequest - (*MerkleSumNode)(nil), // 6: universerpc.MerkleSumNode - (*ID)(nil), // 7: universerpc.ID - (*UniverseRoot)(nil), // 8: universerpc.UniverseRoot - (*AssetRootResponse)(nil), // 9: universerpc.AssetRootResponse - (*AssetRootQuery)(nil), // 10: universerpc.AssetRootQuery - (*QueryRootResponse)(nil), // 11: universerpc.QueryRootResponse - (*DeleteRootQuery)(nil), // 12: universerpc.DeleteRootQuery - (*DeleteRootResponse)(nil), // 13: universerpc.DeleteRootResponse - (*Outpoint)(nil), // 14: universerpc.Outpoint - (*AssetKey)(nil), // 15: universerpc.AssetKey - (*AssetLeafKeysRequest)(nil), // 16: universerpc.AssetLeafKeysRequest - (*AssetLeafKeyResponse)(nil), // 17: universerpc.AssetLeafKeyResponse - (*AssetLeaf)(nil), // 18: universerpc.AssetLeaf - (*AssetLeafResponse)(nil), // 19: universerpc.AssetLeafResponse - (*UniverseKey)(nil), // 20: universerpc.UniverseKey - (*AssetProofResponse)(nil), // 21: universerpc.AssetProofResponse - (*AssetProof)(nil), // 22: universerpc.AssetProof - (*InfoRequest)(nil), // 23: universerpc.InfoRequest - (*InfoResponse)(nil), // 24: universerpc.InfoResponse - (*SyncTarget)(nil), // 25: universerpc.SyncTarget - (*SyncRequest)(nil), // 26: universerpc.SyncRequest - (*SyncedUniverse)(nil), // 27: universerpc.SyncedUniverse - (*StatsRequest)(nil), // 28: universerpc.StatsRequest - (*SyncResponse)(nil), // 29: universerpc.SyncResponse - (*UniverseFederationServer)(nil), // 30: universerpc.UniverseFederationServer - (*ListFederationServersRequest)(nil), // 31: universerpc.ListFederationServersRequest - (*ListFederationServersResponse)(nil), // 32: universerpc.ListFederationServersResponse - (*AddFederationServerRequest)(nil), // 33: universerpc.AddFederationServerRequest - (*AddFederationServerResponse)(nil), // 34: universerpc.AddFederationServerResponse - (*DeleteFederationServerRequest)(nil), // 35: universerpc.DeleteFederationServerRequest - (*DeleteFederationServerResponse)(nil), // 36: universerpc.DeleteFederationServerResponse - (*StatsResponse)(nil), // 37: universerpc.StatsResponse - (*AssetStatsQuery)(nil), // 38: universerpc.AssetStatsQuery - (*AssetStatsSnapshot)(nil), // 39: universerpc.AssetStatsSnapshot - (*AssetStatsAsset)(nil), // 40: universerpc.AssetStatsAsset - (*UniverseAssetStats)(nil), // 41: universerpc.UniverseAssetStats - (*QueryEventsRequest)(nil), // 42: universerpc.QueryEventsRequest - (*QueryEventsResponse)(nil), // 43: universerpc.QueryEventsResponse - (*GroupedUniverseEvents)(nil), // 44: universerpc.GroupedUniverseEvents - (*SetFederationSyncConfigRequest)(nil), // 45: universerpc.SetFederationSyncConfigRequest - (*SetFederationSyncConfigResponse)(nil), // 46: universerpc.SetFederationSyncConfigResponse - (*GlobalFederationSyncConfig)(nil), // 47: universerpc.GlobalFederationSyncConfig - (*AssetFederationSyncConfig)(nil), // 48: universerpc.AssetFederationSyncConfig - (*QueryFederationSyncConfigRequest)(nil), // 49: universerpc.QueryFederationSyncConfigRequest - (*QueryFederationSyncConfigResponse)(nil), // 50: universerpc.QueryFederationSyncConfigResponse - nil, // 51: universerpc.UniverseRoot.AmountsByAssetIdEntry - nil, // 52: universerpc.AssetRootResponse.UniverseRootsEntry - (*taprpc.Asset)(nil), // 53: taprpc.Asset - (taprpc.AssetType)(0), // 54: taprpc.AssetType + (*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 + (*AssetProof)(nil), // 24: universerpc.AssetProof + (*InfoRequest)(nil), // 25: universerpc.InfoRequest + (*InfoResponse)(nil), // 26: universerpc.InfoResponse + (*SyncTarget)(nil), // 27: universerpc.SyncTarget + (*SyncRequest)(nil), // 28: universerpc.SyncRequest + (*SyncedUniverse)(nil), // 29: universerpc.SyncedUniverse + (*StatsRequest)(nil), // 30: universerpc.StatsRequest + (*SyncResponse)(nil), // 31: universerpc.SyncResponse + (*UniverseFederationServer)(nil), // 32: universerpc.UniverseFederationServer + (*ListFederationServersRequest)(nil), // 33: universerpc.ListFederationServersRequest + (*ListFederationServersResponse)(nil), // 34: universerpc.ListFederationServersResponse + (*AddFederationServerRequest)(nil), // 35: universerpc.AddFederationServerRequest + (*AddFederationServerResponse)(nil), // 36: universerpc.AddFederationServerResponse + (*DeleteFederationServerRequest)(nil), // 37: universerpc.DeleteFederationServerRequest + (*DeleteFederationServerResponse)(nil), // 38: universerpc.DeleteFederationServerResponse + (*StatsResponse)(nil), // 39: universerpc.StatsResponse + (*AssetStatsQuery)(nil), // 40: universerpc.AssetStatsQuery + (*AssetStatsSnapshot)(nil), // 41: universerpc.AssetStatsSnapshot + (*AssetStatsAsset)(nil), // 42: universerpc.AssetStatsAsset + (*UniverseAssetStats)(nil), // 43: universerpc.UniverseAssetStats + (*QueryEventsRequest)(nil), // 44: universerpc.QueryEventsRequest + (*QueryEventsResponse)(nil), // 45: universerpc.QueryEventsResponse + (*GroupedUniverseEvents)(nil), // 46: universerpc.GroupedUniverseEvents + (*SetFederationSyncConfigRequest)(nil), // 47: universerpc.SetFederationSyncConfigRequest + (*SetFederationSyncConfigResponse)(nil), // 48: universerpc.SetFederationSyncConfigResponse + (*GlobalFederationSyncConfig)(nil), // 49: universerpc.GlobalFederationSyncConfig + (*AssetFederationSyncConfig)(nil), // 50: universerpc.AssetFederationSyncConfig + (*QueryFederationSyncConfigRequest)(nil), // 51: universerpc.QueryFederationSyncConfigRequest + (*QueryFederationSyncConfigResponse)(nil), // 52: universerpc.QueryFederationSyncConfigResponse + nil, // 53: universerpc.UniverseRoot.AmountsByAssetIdEntry + nil, // 54: universerpc.AssetRootResponse.UniverseRootsEntry + (*taprpc.Asset)(nil), // 55: taprpc.Asset + (taprpc.AssetType)(0), // 56: taprpc.AssetType } var file_universerpc_universe_proto_depIdxs = []int32{ - 3, // 0: universerpc.AssetRootRequest.direction:type_name -> universerpc.SortDirection - 0, // 1: universerpc.ID.proof_type:type_name -> universerpc.ProofType - 7, // 2: universerpc.UniverseRoot.id:type_name -> universerpc.ID - 6, // 3: universerpc.UniverseRoot.mssmt_root:type_name -> universerpc.MerkleSumNode - 51, // 4: universerpc.UniverseRoot.amounts_by_asset_id:type_name -> universerpc.UniverseRoot.AmountsByAssetIdEntry - 52, // 5: universerpc.AssetRootResponse.universe_roots:type_name -> universerpc.AssetRootResponse.UniverseRootsEntry - 7, // 6: universerpc.AssetRootQuery.id:type_name -> universerpc.ID - 8, // 7: universerpc.QueryRootResponse.issuance_root:type_name -> universerpc.UniverseRoot - 8, // 8: universerpc.QueryRootResponse.transfer_root:type_name -> universerpc.UniverseRoot - 7, // 9: universerpc.DeleteRootQuery.id:type_name -> universerpc.ID - 14, // 10: universerpc.AssetKey.op:type_name -> universerpc.Outpoint - 7, // 11: universerpc.AssetLeafKeysRequest.id:type_name -> universerpc.ID - 3, // 12: universerpc.AssetLeafKeysRequest.direction:type_name -> universerpc.SortDirection - 15, // 13: universerpc.AssetLeafKeyResponse.asset_keys:type_name -> universerpc.AssetKey - 53, // 14: universerpc.AssetLeaf.asset:type_name -> taprpc.Asset - 18, // 15: universerpc.AssetLeafResponse.leaves:type_name -> universerpc.AssetLeaf - 7, // 16: universerpc.UniverseKey.id:type_name -> universerpc.ID - 15, // 17: universerpc.UniverseKey.leaf_key:type_name -> universerpc.AssetKey - 20, // 18: universerpc.AssetProofResponse.req:type_name -> universerpc.UniverseKey - 8, // 19: universerpc.AssetProofResponse.universe_root:type_name -> universerpc.UniverseRoot - 18, // 20: universerpc.AssetProofResponse.asset_leaf:type_name -> universerpc.AssetLeaf - 6, // 21: universerpc.AssetProofResponse.multiverse_root:type_name -> universerpc.MerkleSumNode - 20, // 22: universerpc.AssetProof.key:type_name -> universerpc.UniverseKey - 18, // 23: universerpc.AssetProof.asset_leaf:type_name -> universerpc.AssetLeaf - 7, // 24: universerpc.SyncTarget.id:type_name -> universerpc.ID - 1, // 25: universerpc.SyncRequest.sync_mode:type_name -> universerpc.UniverseSyncMode - 25, // 26: universerpc.SyncRequest.sync_targets:type_name -> universerpc.SyncTarget - 8, // 27: universerpc.SyncedUniverse.old_asset_root:type_name -> universerpc.UniverseRoot - 8, // 28: universerpc.SyncedUniverse.new_asset_root:type_name -> universerpc.UniverseRoot - 18, // 29: universerpc.SyncedUniverse.new_asset_leaves:type_name -> universerpc.AssetLeaf - 27, // 30: universerpc.SyncResponse.synced_universes:type_name -> universerpc.SyncedUniverse - 30, // 31: universerpc.ListFederationServersResponse.servers:type_name -> universerpc.UniverseFederationServer - 30, // 32: universerpc.AddFederationServerRequest.servers:type_name -> universerpc.UniverseFederationServer - 30, // 33: universerpc.DeleteFederationServerRequest.servers:type_name -> universerpc.UniverseFederationServer - 4, // 34: universerpc.AssetStatsQuery.asset_type_filter:type_name -> universerpc.AssetTypeFilter - 2, // 35: universerpc.AssetStatsQuery.sort_by:type_name -> universerpc.AssetQuerySort - 3, // 36: universerpc.AssetStatsQuery.direction:type_name -> universerpc.SortDirection - 40, // 37: universerpc.AssetStatsSnapshot.group_anchor:type_name -> universerpc.AssetStatsAsset - 40, // 38: universerpc.AssetStatsSnapshot.asset:type_name -> universerpc.AssetStatsAsset - 54, // 39: universerpc.AssetStatsAsset.asset_type:type_name -> taprpc.AssetType - 39, // 40: universerpc.UniverseAssetStats.asset_stats:type_name -> universerpc.AssetStatsSnapshot - 44, // 41: universerpc.QueryEventsResponse.events:type_name -> universerpc.GroupedUniverseEvents - 47, // 42: universerpc.SetFederationSyncConfigRequest.global_sync_configs:type_name -> universerpc.GlobalFederationSyncConfig - 48, // 43: universerpc.SetFederationSyncConfigRequest.asset_sync_configs:type_name -> universerpc.AssetFederationSyncConfig - 0, // 44: universerpc.GlobalFederationSyncConfig.proof_type:type_name -> universerpc.ProofType - 7, // 45: universerpc.AssetFederationSyncConfig.id:type_name -> universerpc.ID - 7, // 46: universerpc.QueryFederationSyncConfigRequest.id:type_name -> universerpc.ID - 47, // 47: universerpc.QueryFederationSyncConfigResponse.global_sync_configs:type_name -> universerpc.GlobalFederationSyncConfig - 48, // 48: universerpc.QueryFederationSyncConfigResponse.asset_sync_configs:type_name -> universerpc.AssetFederationSyncConfig - 8, // 49: universerpc.AssetRootResponse.UniverseRootsEntry.value:type_name -> universerpc.UniverseRoot - 5, // 50: universerpc.Universe.AssetRoots:input_type -> universerpc.AssetRootRequest - 10, // 51: universerpc.Universe.QueryAssetRoots:input_type -> universerpc.AssetRootQuery - 12, // 52: universerpc.Universe.DeleteAssetRoot:input_type -> universerpc.DeleteRootQuery - 16, // 53: universerpc.Universe.AssetLeafKeys:input_type -> universerpc.AssetLeafKeysRequest - 7, // 54: universerpc.Universe.AssetLeaves:input_type -> universerpc.ID - 20, // 55: universerpc.Universe.QueryProof:input_type -> universerpc.UniverseKey - 22, // 56: universerpc.Universe.InsertProof:input_type -> universerpc.AssetProof - 23, // 57: universerpc.Universe.Info:input_type -> universerpc.InfoRequest - 26, // 58: universerpc.Universe.SyncUniverse:input_type -> universerpc.SyncRequest - 31, // 59: universerpc.Universe.ListFederationServers:input_type -> universerpc.ListFederationServersRequest - 33, // 60: universerpc.Universe.AddFederationServer:input_type -> universerpc.AddFederationServerRequest - 35, // 61: universerpc.Universe.DeleteFederationServer:input_type -> universerpc.DeleteFederationServerRequest - 28, // 62: universerpc.Universe.UniverseStats:input_type -> universerpc.StatsRequest - 38, // 63: universerpc.Universe.QueryAssetStats:input_type -> universerpc.AssetStatsQuery - 42, // 64: universerpc.Universe.QueryEvents:input_type -> universerpc.QueryEventsRequest - 45, // 65: universerpc.Universe.SetFederationSyncConfig:input_type -> universerpc.SetFederationSyncConfigRequest - 49, // 66: universerpc.Universe.QueryFederationSyncConfig:input_type -> universerpc.QueryFederationSyncConfigRequest - 9, // 67: universerpc.Universe.AssetRoots:output_type -> universerpc.AssetRootResponse - 11, // 68: universerpc.Universe.QueryAssetRoots:output_type -> universerpc.QueryRootResponse - 13, // 69: universerpc.Universe.DeleteAssetRoot:output_type -> universerpc.DeleteRootResponse - 17, // 70: universerpc.Universe.AssetLeafKeys:output_type -> universerpc.AssetLeafKeyResponse - 19, // 71: universerpc.Universe.AssetLeaves:output_type -> universerpc.AssetLeafResponse - 21, // 72: universerpc.Universe.QueryProof:output_type -> universerpc.AssetProofResponse - 21, // 73: universerpc.Universe.InsertProof:output_type -> universerpc.AssetProofResponse - 24, // 74: universerpc.Universe.Info:output_type -> universerpc.InfoResponse - 29, // 75: universerpc.Universe.SyncUniverse:output_type -> universerpc.SyncResponse - 32, // 76: universerpc.Universe.ListFederationServers:output_type -> universerpc.ListFederationServersResponse - 34, // 77: universerpc.Universe.AddFederationServer:output_type -> universerpc.AddFederationServerResponse - 36, // 78: universerpc.Universe.DeleteFederationServer:output_type -> universerpc.DeleteFederationServerResponse - 37, // 79: universerpc.Universe.UniverseStats:output_type -> universerpc.StatsResponse - 41, // 80: universerpc.Universe.QueryAssetStats:output_type -> universerpc.UniverseAssetStats - 43, // 81: universerpc.Universe.QueryEvents:output_type -> universerpc.QueryEventsResponse - 46, // 82: universerpc.Universe.SetFederationSyncConfig:output_type -> universerpc.SetFederationSyncConfigResponse - 50, // 83: universerpc.Universe.QueryFederationSyncConfig:output_type -> universerpc.QueryFederationSyncConfigResponse - 67, // [67:84] is the sub-list for method output_type - 50, // [50:67] is the sub-list for method input_type - 50, // [50:50] is the sub-list for extension type_name - 50, // [50:50] is the sub-list for extension extendee - 0, // [0:50] is the sub-list for field type_name + 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 + 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 + 53, // 7: universerpc.UniverseRoot.amounts_by_asset_id:type_name -> universerpc.UniverseRoot.AmountsByAssetIdEntry + 54, // 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 + 55, // 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 + 22, // 25: universerpc.AssetProof.key:type_name -> universerpc.UniverseKey + 20, // 26: universerpc.AssetProof.asset_leaf:type_name -> universerpc.AssetLeaf + 9, // 27: universerpc.SyncTarget.id:type_name -> universerpc.ID + 1, // 28: universerpc.SyncRequest.sync_mode:type_name -> universerpc.UniverseSyncMode + 27, // 29: universerpc.SyncRequest.sync_targets:type_name -> universerpc.SyncTarget + 10, // 30: universerpc.SyncedUniverse.old_asset_root:type_name -> universerpc.UniverseRoot + 10, // 31: universerpc.SyncedUniverse.new_asset_root:type_name -> universerpc.UniverseRoot + 20, // 32: universerpc.SyncedUniverse.new_asset_leaves:type_name -> universerpc.AssetLeaf + 29, // 33: universerpc.SyncResponse.synced_universes:type_name -> universerpc.SyncedUniverse + 32, // 34: universerpc.ListFederationServersResponse.servers:type_name -> universerpc.UniverseFederationServer + 32, // 35: universerpc.AddFederationServerRequest.servers:type_name -> universerpc.UniverseFederationServer + 32, // 36: universerpc.DeleteFederationServerRequest.servers:type_name -> universerpc.UniverseFederationServer + 4, // 37: universerpc.AssetStatsQuery.asset_type_filter:type_name -> universerpc.AssetTypeFilter + 2, // 38: universerpc.AssetStatsQuery.sort_by:type_name -> universerpc.AssetQuerySort + 3, // 39: universerpc.AssetStatsQuery.direction:type_name -> universerpc.SortDirection + 42, // 40: universerpc.AssetStatsSnapshot.group_anchor:type_name -> universerpc.AssetStatsAsset + 42, // 41: universerpc.AssetStatsSnapshot.asset:type_name -> universerpc.AssetStatsAsset + 56, // 42: universerpc.AssetStatsAsset.asset_type:type_name -> taprpc.AssetType + 41, // 43: universerpc.UniverseAssetStats.asset_stats:type_name -> universerpc.AssetStatsSnapshot + 46, // 44: universerpc.QueryEventsResponse.events:type_name -> universerpc.GroupedUniverseEvents + 49, // 45: universerpc.SetFederationSyncConfigRequest.global_sync_configs:type_name -> universerpc.GlobalFederationSyncConfig + 50, // 46: universerpc.SetFederationSyncConfigRequest.asset_sync_configs:type_name -> universerpc.AssetFederationSyncConfig + 0, // 47: universerpc.GlobalFederationSyncConfig.proof_type:type_name -> universerpc.ProofType + 9, // 48: universerpc.AssetFederationSyncConfig.id:type_name -> universerpc.ID + 9, // 49: universerpc.QueryFederationSyncConfigRequest.id:type_name -> universerpc.ID + 49, // 50: universerpc.QueryFederationSyncConfigResponse.global_sync_configs:type_name -> universerpc.GlobalFederationSyncConfig + 50, // 51: universerpc.QueryFederationSyncConfigResponse.asset_sync_configs:type_name -> universerpc.AssetFederationSyncConfig + 10, // 52: universerpc.AssetRootResponse.UniverseRootsEntry.value:type_name -> universerpc.UniverseRoot + 5, // 53: universerpc.Universe.MultiverseRoot:input_type -> universerpc.MultiverseRootRequest + 7, // 54: universerpc.Universe.AssetRoots:input_type -> universerpc.AssetRootRequest + 12, // 55: universerpc.Universe.QueryAssetRoots:input_type -> universerpc.AssetRootQuery + 14, // 56: universerpc.Universe.DeleteAssetRoot:input_type -> universerpc.DeleteRootQuery + 18, // 57: universerpc.Universe.AssetLeafKeys:input_type -> universerpc.AssetLeafKeysRequest + 9, // 58: universerpc.Universe.AssetLeaves:input_type -> universerpc.ID + 22, // 59: universerpc.Universe.QueryProof:input_type -> universerpc.UniverseKey + 24, // 60: universerpc.Universe.InsertProof:input_type -> universerpc.AssetProof + 25, // 61: universerpc.Universe.Info:input_type -> universerpc.InfoRequest + 28, // 62: universerpc.Universe.SyncUniverse:input_type -> universerpc.SyncRequest + 33, // 63: universerpc.Universe.ListFederationServers:input_type -> universerpc.ListFederationServersRequest + 35, // 64: universerpc.Universe.AddFederationServer:input_type -> universerpc.AddFederationServerRequest + 37, // 65: universerpc.Universe.DeleteFederationServer:input_type -> universerpc.DeleteFederationServerRequest + 30, // 66: universerpc.Universe.UniverseStats:input_type -> universerpc.StatsRequest + 40, // 67: universerpc.Universe.QueryAssetStats:input_type -> universerpc.AssetStatsQuery + 44, // 68: universerpc.Universe.QueryEvents:input_type -> universerpc.QueryEventsRequest + 47, // 69: universerpc.Universe.SetFederationSyncConfig:input_type -> universerpc.SetFederationSyncConfigRequest + 51, // 70: universerpc.Universe.QueryFederationSyncConfig:input_type -> universerpc.QueryFederationSyncConfigRequest + 6, // 71: universerpc.Universe.MultiverseRoot:output_type -> universerpc.MultiverseRootResponse + 11, // 72: universerpc.Universe.AssetRoots:output_type -> universerpc.AssetRootResponse + 13, // 73: universerpc.Universe.QueryAssetRoots:output_type -> universerpc.QueryRootResponse + 15, // 74: universerpc.Universe.DeleteAssetRoot:output_type -> universerpc.DeleteRootResponse + 19, // 75: universerpc.Universe.AssetLeafKeys:output_type -> universerpc.AssetLeafKeyResponse + 21, // 76: universerpc.Universe.AssetLeaves:output_type -> universerpc.AssetLeafResponse + 23, // 77: universerpc.Universe.QueryProof:output_type -> universerpc.AssetProofResponse + 23, // 78: universerpc.Universe.InsertProof:output_type -> universerpc.AssetProofResponse + 26, // 79: universerpc.Universe.Info:output_type -> universerpc.InfoResponse + 31, // 80: universerpc.Universe.SyncUniverse:output_type -> universerpc.SyncResponse + 34, // 81: universerpc.Universe.ListFederationServers:output_type -> universerpc.ListFederationServersResponse + 36, // 82: universerpc.Universe.AddFederationServer:output_type -> universerpc.AddFederationServerResponse + 38, // 83: universerpc.Universe.DeleteFederationServer:output_type -> universerpc.DeleteFederationServerResponse + 39, // 84: universerpc.Universe.UniverseStats:output_type -> universerpc.StatsResponse + 43, // 85: universerpc.Universe.QueryAssetStats:output_type -> universerpc.UniverseAssetStats + 45, // 86: universerpc.Universe.QueryEvents:output_type -> universerpc.QueryEventsResponse + 48, // 87: universerpc.Universe.SetFederationSyncConfig:output_type -> universerpc.SetFederationSyncConfigResponse + 52, // 88: universerpc.Universe.QueryFederationSyncConfig:output_type -> universerpc.QueryFederationSyncConfigResponse + 71, // [71:89] is the sub-list for method output_type + 53, // [53:71] is the sub-list for method input_type + 53, // [53:53] is the sub-list for extension type_name + 53, // [53:53] is the sub-list for extension extendee + 0, // [0:53] is the sub-list for field type_name } func init() { file_universerpc_universe_proto_init() } @@ -3744,7 +3878,7 @@ func file_universerpc_universe_proto_init() { } if !protoimpl.UnsafeEnabled { file_universerpc_universe_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AssetRootRequest); i { + switch v := v.(*MultiverseRootRequest); i { case 0: return &v.state case 1: @@ -3756,7 +3890,7 @@ func file_universerpc_universe_proto_init() { } } file_universerpc_universe_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*MerkleSumNode); i { + switch v := v.(*MultiverseRootResponse); i { case 0: return &v.state case 1: @@ -3768,7 +3902,7 @@ func file_universerpc_universe_proto_init() { } } file_universerpc_universe_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ID); i { + switch v := v.(*AssetRootRequest); i { case 0: return &v.state case 1: @@ -3780,7 +3914,7 @@ func file_universerpc_universe_proto_init() { } } file_universerpc_universe_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UniverseRoot); i { + switch v := v.(*MerkleSumNode); i { case 0: return &v.state case 1: @@ -3792,7 +3926,7 @@ func file_universerpc_universe_proto_init() { } } file_universerpc_universe_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AssetRootResponse); i { + switch v := v.(*ID); i { case 0: return &v.state case 1: @@ -3804,7 +3938,7 @@ func file_universerpc_universe_proto_init() { } } file_universerpc_universe_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AssetRootQuery); i { + switch v := v.(*UniverseRoot); i { case 0: return &v.state case 1: @@ -3816,7 +3950,7 @@ func file_universerpc_universe_proto_init() { } } file_universerpc_universe_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*QueryRootResponse); i { + switch v := v.(*AssetRootResponse); i { case 0: return &v.state case 1: @@ -3828,7 +3962,7 @@ func file_universerpc_universe_proto_init() { } } file_universerpc_universe_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DeleteRootQuery); i { + switch v := v.(*AssetRootQuery); i { case 0: return &v.state case 1: @@ -3840,7 +3974,7 @@ func file_universerpc_universe_proto_init() { } } file_universerpc_universe_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DeleteRootResponse); i { + switch v := v.(*QueryRootResponse); i { case 0: return &v.state case 1: @@ -3852,7 +3986,7 @@ func file_universerpc_universe_proto_init() { } } file_universerpc_universe_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Outpoint); i { + switch v := v.(*DeleteRootQuery); i { case 0: return &v.state case 1: @@ -3864,7 +3998,7 @@ func file_universerpc_universe_proto_init() { } } file_universerpc_universe_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AssetKey); i { + switch v := v.(*DeleteRootResponse); i { case 0: return &v.state case 1: @@ -3876,7 +4010,7 @@ func file_universerpc_universe_proto_init() { } } file_universerpc_universe_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AssetLeafKeysRequest); i { + switch v := v.(*Outpoint); i { case 0: return &v.state case 1: @@ -3888,7 +4022,7 @@ func file_universerpc_universe_proto_init() { } } file_universerpc_universe_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AssetLeafKeyResponse); i { + switch v := v.(*AssetKey); i { case 0: return &v.state case 1: @@ -3900,7 +4034,7 @@ func file_universerpc_universe_proto_init() { } } file_universerpc_universe_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AssetLeaf); i { + switch v := v.(*AssetLeafKeysRequest); i { case 0: return &v.state case 1: @@ -3912,7 +4046,7 @@ func file_universerpc_universe_proto_init() { } } file_universerpc_universe_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AssetLeafResponse); i { + switch v := v.(*AssetLeafKeyResponse); i { case 0: return &v.state case 1: @@ -3924,7 +4058,7 @@ func file_universerpc_universe_proto_init() { } } file_universerpc_universe_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UniverseKey); i { + switch v := v.(*AssetLeaf); i { case 0: return &v.state case 1: @@ -3936,7 +4070,7 @@ func file_universerpc_universe_proto_init() { } } file_universerpc_universe_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AssetProofResponse); i { + switch v := v.(*AssetLeafResponse); i { case 0: return &v.state case 1: @@ -3948,7 +4082,7 @@ func file_universerpc_universe_proto_init() { } } file_universerpc_universe_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AssetProof); i { + switch v := v.(*UniverseKey); i { case 0: return &v.state case 1: @@ -3960,7 +4094,7 @@ func file_universerpc_universe_proto_init() { } } file_universerpc_universe_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*InfoRequest); i { + switch v := v.(*AssetProofResponse); i { case 0: return &v.state case 1: @@ -3972,7 +4106,7 @@ func file_universerpc_universe_proto_init() { } } file_universerpc_universe_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*InfoResponse); i { + switch v := v.(*AssetProof); i { case 0: return &v.state case 1: @@ -3984,7 +4118,7 @@ func file_universerpc_universe_proto_init() { } } file_universerpc_universe_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SyncTarget); i { + switch v := v.(*InfoRequest); i { case 0: return &v.state case 1: @@ -3996,7 +4130,7 @@ func file_universerpc_universe_proto_init() { } } file_universerpc_universe_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SyncRequest); i { + switch v := v.(*InfoResponse); i { case 0: return &v.state case 1: @@ -4008,7 +4142,7 @@ func file_universerpc_universe_proto_init() { } } file_universerpc_universe_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SyncedUniverse); i { + switch v := v.(*SyncTarget); i { case 0: return &v.state case 1: @@ -4020,7 +4154,7 @@ func file_universerpc_universe_proto_init() { } } file_universerpc_universe_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*StatsRequest); i { + switch v := v.(*SyncRequest); i { case 0: return &v.state case 1: @@ -4032,7 +4166,7 @@ func file_universerpc_universe_proto_init() { } } file_universerpc_universe_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SyncResponse); i { + switch v := v.(*SyncedUniverse); i { case 0: return &v.state case 1: @@ -4044,7 +4178,7 @@ func file_universerpc_universe_proto_init() { } } file_universerpc_universe_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UniverseFederationServer); i { + switch v := v.(*StatsRequest); i { case 0: return &v.state case 1: @@ -4056,7 +4190,7 @@ func file_universerpc_universe_proto_init() { } } file_universerpc_universe_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListFederationServersRequest); i { + switch v := v.(*SyncResponse); i { case 0: return &v.state case 1: @@ -4068,7 +4202,7 @@ func file_universerpc_universe_proto_init() { } } file_universerpc_universe_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListFederationServersResponse); i { + switch v := v.(*UniverseFederationServer); i { case 0: return &v.state case 1: @@ -4080,7 +4214,7 @@ func file_universerpc_universe_proto_init() { } } file_universerpc_universe_proto_msgTypes[28].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AddFederationServerRequest); i { + switch v := v.(*ListFederationServersRequest); i { case 0: return &v.state case 1: @@ -4092,7 +4226,7 @@ func file_universerpc_universe_proto_init() { } } file_universerpc_universe_proto_msgTypes[29].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AddFederationServerResponse); i { + switch v := v.(*ListFederationServersResponse); i { case 0: return &v.state case 1: @@ -4104,7 +4238,7 @@ func file_universerpc_universe_proto_init() { } } file_universerpc_universe_proto_msgTypes[30].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DeleteFederationServerRequest); i { + switch v := v.(*AddFederationServerRequest); i { case 0: return &v.state case 1: @@ -4116,7 +4250,7 @@ func file_universerpc_universe_proto_init() { } } file_universerpc_universe_proto_msgTypes[31].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DeleteFederationServerResponse); i { + switch v := v.(*AddFederationServerResponse); i { case 0: return &v.state case 1: @@ -4128,7 +4262,7 @@ func file_universerpc_universe_proto_init() { } } file_universerpc_universe_proto_msgTypes[32].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*StatsResponse); i { + switch v := v.(*DeleteFederationServerRequest); i { case 0: return &v.state case 1: @@ -4140,7 +4274,7 @@ func file_universerpc_universe_proto_init() { } } file_universerpc_universe_proto_msgTypes[33].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AssetStatsQuery); i { + switch v := v.(*DeleteFederationServerResponse); i { case 0: return &v.state case 1: @@ -4152,7 +4286,7 @@ func file_universerpc_universe_proto_init() { } } file_universerpc_universe_proto_msgTypes[34].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AssetStatsSnapshot); i { + switch v := v.(*StatsResponse); i { case 0: return &v.state case 1: @@ -4164,7 +4298,7 @@ func file_universerpc_universe_proto_init() { } } file_universerpc_universe_proto_msgTypes[35].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AssetStatsAsset); i { + switch v := v.(*AssetStatsQuery); i { case 0: return &v.state case 1: @@ -4176,7 +4310,7 @@ func file_universerpc_universe_proto_init() { } } file_universerpc_universe_proto_msgTypes[36].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UniverseAssetStats); i { + switch v := v.(*AssetStatsSnapshot); i { case 0: return &v.state case 1: @@ -4188,7 +4322,7 @@ func file_universerpc_universe_proto_init() { } } file_universerpc_universe_proto_msgTypes[37].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*QueryEventsRequest); i { + switch v := v.(*AssetStatsAsset); i { case 0: return &v.state case 1: @@ -4200,7 +4334,7 @@ func file_universerpc_universe_proto_init() { } } file_universerpc_universe_proto_msgTypes[38].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*QueryEventsResponse); i { + switch v := v.(*UniverseAssetStats); i { case 0: return &v.state case 1: @@ -4212,7 +4346,7 @@ func file_universerpc_universe_proto_init() { } } file_universerpc_universe_proto_msgTypes[39].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GroupedUniverseEvents); i { + switch v := v.(*QueryEventsRequest); i { case 0: return &v.state case 1: @@ -4224,7 +4358,7 @@ func file_universerpc_universe_proto_init() { } } file_universerpc_universe_proto_msgTypes[40].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SetFederationSyncConfigRequest); i { + switch v := v.(*QueryEventsResponse); i { case 0: return &v.state case 1: @@ -4236,7 +4370,7 @@ func file_universerpc_universe_proto_init() { } } file_universerpc_universe_proto_msgTypes[41].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SetFederationSyncConfigResponse); i { + switch v := v.(*GroupedUniverseEvents); i { case 0: return &v.state case 1: @@ -4248,7 +4382,7 @@ func file_universerpc_universe_proto_init() { } } file_universerpc_universe_proto_msgTypes[42].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GlobalFederationSyncConfig); i { + switch v := v.(*SetFederationSyncConfigRequest); i { case 0: return &v.state case 1: @@ -4260,7 +4394,7 @@ func file_universerpc_universe_proto_init() { } } file_universerpc_universe_proto_msgTypes[43].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AssetFederationSyncConfig); i { + switch v := v.(*SetFederationSyncConfigResponse); i { case 0: return &v.state case 1: @@ -4272,7 +4406,7 @@ func file_universerpc_universe_proto_init() { } } file_universerpc_universe_proto_msgTypes[44].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*QueryFederationSyncConfigRequest); i { + switch v := v.(*GlobalFederationSyncConfig); i { case 0: return &v.state case 1: @@ -4284,6 +4418,30 @@ func file_universerpc_universe_proto_init() { } } file_universerpc_universe_proto_msgTypes[45].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AssetFederationSyncConfig); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_universerpc_universe_proto_msgTypes[46].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*QueryFederationSyncConfigRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_universerpc_universe_proto_msgTypes[47].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*QueryFederationSyncConfigResponse); i { case 0: return &v.state @@ -4296,13 +4454,13 @@ func file_universerpc_universe_proto_init() { } } } - file_universerpc_universe_proto_msgTypes[2].OneofWrappers = []interface{}{ + file_universerpc_universe_proto_msgTypes[4].OneofWrappers = []interface{}{ (*ID_AssetId)(nil), (*ID_AssetIdStr)(nil), (*ID_GroupKey)(nil), (*ID_GroupKeyStr)(nil), } - file_universerpc_universe_proto_msgTypes[10].OneofWrappers = []interface{}{ + file_universerpc_universe_proto_msgTypes[12].OneofWrappers = []interface{}{ (*AssetKey_OpStr)(nil), (*AssetKey_Op)(nil), (*AssetKey_ScriptKeyBytes)(nil), @@ -4314,7 +4472,7 @@ func file_universerpc_universe_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_universerpc_universe_proto_rawDesc, NumEnums: 5, - NumMessages: 48, + NumMessages: 50, NumExtensions: 0, NumServices: 1, }, diff --git a/taprpc/universerpc/universe.pb.gw.go b/taprpc/universerpc/universe.pb.gw.go index 3f41d1066..7208a2831 100644 --- a/taprpc/universerpc/universe.pb.gw.go +++ b/taprpc/universerpc/universe.pb.gw.go @@ -31,6 +31,40 @@ var _ = runtime.String var _ = utilities.NewDoubleArray var _ = metadata.Join +func request_Universe_MultiverseRoot_0(ctx context.Context, marshaler runtime.Marshaler, client UniverseClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq MultiverseRootRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.MultiverseRoot(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Universe_MultiverseRoot_0(ctx context.Context, marshaler runtime.Marshaler, server UniverseServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq MultiverseRootRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.MultiverseRoot(ctx, &protoReq) + return msg, metadata, err + +} + var ( filter_Universe_AssetRoots_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} ) @@ -1365,6 +1399,29 @@ func local_request_Universe_QueryFederationSyncConfig_0(ctx context.Context, mar // Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterUniverseHandlerFromEndpoint instead. func RegisterUniverseHandlerServer(ctx context.Context, mux *runtime.ServeMux, server UniverseServer) error { + mux.Handle("POST", pattern_Universe_MultiverseRoot_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/universerpc.Universe/MultiverseRoot", runtime.WithHTTPPathPattern("/v1/taproot-assets/universe/multiverse")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Universe_MultiverseRoot_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Universe_MultiverseRoot_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + mux.Handle("GET", pattern_Universe_AssetRoots_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -1912,6 +1969,26 @@ func RegisterUniverseHandler(ctx context.Context, mux *runtime.ServeMux, conn *g // "UniverseClient" to call the correct interceptors. func RegisterUniverseHandlerClient(ctx context.Context, mux *runtime.ServeMux, client UniverseClient) error { + mux.Handle("POST", pattern_Universe_MultiverseRoot_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req, "/universerpc.Universe/MultiverseRoot", runtime.WithHTTPPathPattern("/v1/taproot-assets/universe/multiverse")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Universe_MultiverseRoot_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Universe_MultiverseRoot_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + mux.Handle("GET", pattern_Universe_AssetRoots_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -2356,6 +2433,8 @@ func RegisterUniverseHandlerClient(ctx context.Context, mux *runtime.ServeMux, c } var ( + pattern_Universe_MultiverseRoot_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v1", "taproot-assets", "universe", "multiverse"}, "")) + pattern_Universe_AssetRoots_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v1", "taproot-assets", "universe", "roots"}, "")) pattern_Universe_QueryAssetRoots_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5}, []string{"v1", "taproot-assets", "universe", "roots", "asset-id", "id.asset_id_str"}, "")) @@ -2402,6 +2481,8 @@ var ( ) var ( + forward_Universe_MultiverseRoot_0 = runtime.ForwardResponseMessage + forward_Universe_AssetRoots_0 = runtime.ForwardResponseMessage forward_Universe_QueryAssetRoots_0 = runtime.ForwardResponseMessage diff --git a/taprpc/universerpc/universe.pb.json.go b/taprpc/universerpc/universe.pb.json.go index fdf0442db..69425dae8 100644 --- a/taprpc/universerpc/universe.pb.json.go +++ b/taprpc/universerpc/universe.pb.json.go @@ -21,6 +21,31 @@ func RegisterUniverseJSONCallbacks(registry map[string]func(ctx context.Context, }, } + registry["universerpc.Universe.MultiverseRoot"] = func(ctx context.Context, + conn *grpc.ClientConn, reqJSON string, callback func(string, error)) { + + req := &MultiverseRootRequest{} + err := marshaler.Unmarshal([]byte(reqJSON), req) + if err != nil { + callback("", err) + return + } + + client := NewUniverseClient(conn) + resp, err := client.MultiverseRoot(ctx, req) + if err != nil { + callback("", err) + return + } + + respBytes, err := marshaler.Marshal(resp) + if err != nil { + callback("", err) + return + } + callback(string(respBytes), nil) + } + registry["universerpc.Universe.AssetRoots"] = func(ctx context.Context, conn *grpc.ClientConn, reqJSON string, callback func(string, error)) { diff --git a/taprpc/universerpc/universe.proto b/taprpc/universerpc/universe.proto index 20db15825..576b7258c 100644 --- a/taprpc/universerpc/universe.proto +++ b/taprpc/universerpc/universe.proto @@ -7,6 +7,13 @@ package universerpc; option go_package = "github.com/lightninglabs/taproot-assets/taprpc/universerpc"; service Universe { + /* tapcli: `universe multiverse` + MultiverseRoot returns the root of the multiverse tree. This is useful to + determine the equality of two multiverse trees, since the root can directly + be compared to another multiverse root to find out if a sync is required. + */ + rpc MultiverseRoot (MultiverseRootRequest) returns (MultiverseRootResponse); + /* tapcli: `universe roots` AssetRoots queries for the known Universe roots associated with each known asset. These roots represent the supply/audit state for each known asset. @@ -142,6 +149,22 @@ service Universe { returns (QueryFederationSyncConfigResponse); } +message MultiverseRootRequest { + // The proof type to calculate the multiverse root for. + ProofType proof_type = 1; + + // An optional list of universe IDs to include in the multiverse root. If + // none are specified, then all known universes of the given proof type are + // included. NOTE: The proof type within the IDs must either be unspecified + // or match the proof type above. + repeated ID specific_ids = 2; +} + +message MultiverseRootResponse { + // The root of the multiverse tree. + MerkleSumNode multiverse_root = 1; +} + message AssetRootRequest { // If true, then the response will include the amounts for each asset ID // of grouped assets. diff --git a/taprpc/universerpc/universe.swagger.json b/taprpc/universerpc/universe.swagger.json index e478bdbc5..e9be510f9 100644 --- a/taprpc/universerpc/universe.swagger.json +++ b/taprpc/universerpc/universe.swagger.json @@ -505,6 +505,39 @@ ] } }, + "/v1/taproot-assets/universe/multiverse": { + "post": { + "summary": "tapcli: `universe multiverse`\nMultiverseRoot returns the root of the multiverse tree. This is useful to\ndetermine the equality of two multiverse trees, since the root can directly\nbe compared to another multiverse root to find out if a sync is required.", + "operationId": "Universe_MultiverseRoot", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/universerpcMultiverseRootResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/universerpcMultiverseRootRequest" + } + } + ], + "tags": [ + "Universe" + ] + } + }, "/v1/taproot-assets/universe/proofs/asset-id/{id.asset_id_str}/{leaf_key.op.hash_str}/{leaf_key.op.index}/{leaf_key.script_key_str}": { "get": { "summary": "tapcli: `universe proofs query`\nQueryProof attempts to query for an issuance or transfer proof for a given\nasset based on its UniverseKey. A UniverseKey is composed of the Universe\nID (asset_id/group_key) and also a leaf key (outpoint || script_key). If\nfound, then the issuance proof is returned that includes an inclusion proof\nto the known Universe root, as well as a Taproot Asset state transition or\nissuance proof for the said asset.", @@ -1865,6 +1898,31 @@ } } }, + "universerpcMultiverseRootRequest": { + "type": "object", + "properties": { + "proof_type": { + "$ref": "#/definitions/universerpcProofType", + "description": "The proof type to calculate the multiverse root for." + }, + "specific_ids": { + "type": "array", + "items": { + "$ref": "#/definitions/universerpcID" + }, + "description": "An optional list of universe IDs to include in the multiverse root. If\nnone are specified, then all known universes of the given proof type are\nincluded. NOTE: The proof type within the IDs must either be unspecified\nor match the proof type above." + } + } + }, + "universerpcMultiverseRootResponse": { + "type": "object", + "properties": { + "multiverse_root": { + "$ref": "#/definitions/universerpcMerkleSumNode", + "description": "The root of the multiverse tree." + } + } + }, "universerpcOutpoint": { "type": "object", "properties": { diff --git a/taprpc/universerpc/universe.yaml b/taprpc/universerpc/universe.yaml index 84c1ea3ac..11a225640 100644 --- a/taprpc/universerpc/universe.yaml +++ b/taprpc/universerpc/universe.yaml @@ -3,6 +3,10 @@ config_version: 3 http: rules: + - selector: universerpc.Universe.MultiverseRoot + post: "/v1/taproot-assets/universe/multiverse" + body: "*" + - selector: universerpc.Universe.AssetRoots get: "/v1/taproot-assets/universe/roots" diff --git a/taprpc/universerpc/universe_grpc.pb.go b/taprpc/universerpc/universe_grpc.pb.go index 9549dd16f..35b9a066d 100644 --- a/taprpc/universerpc/universe_grpc.pb.go +++ b/taprpc/universerpc/universe_grpc.pb.go @@ -18,6 +18,11 @@ const _ = grpc.SupportPackageIsVersion7 // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. type UniverseClient interface { + // tapcli: `universe multiverse` + // MultiverseRoot returns the root of the multiverse tree. This is useful to + // determine the equality of two multiverse trees, since the root can directly + // be compared to another multiverse root to find out if a sync is required. + MultiverseRoot(ctx context.Context, in *MultiverseRootRequest, opts ...grpc.CallOption) (*MultiverseRootResponse, error) // tapcli: `universe roots` // AssetRoots queries for the known Universe roots associated with each known // asset. These roots represent the supply/audit state for each known asset. @@ -115,6 +120,15 @@ func NewUniverseClient(cc grpc.ClientConnInterface) UniverseClient { return &universeClient{cc} } +func (c *universeClient) MultiverseRoot(ctx context.Context, in *MultiverseRootRequest, opts ...grpc.CallOption) (*MultiverseRootResponse, error) { + out := new(MultiverseRootResponse) + err := c.cc.Invoke(ctx, "/universerpc.Universe/MultiverseRoot", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *universeClient) AssetRoots(ctx context.Context, in *AssetRootRequest, opts ...grpc.CallOption) (*AssetRootResponse, error) { out := new(AssetRootResponse) err := c.cc.Invoke(ctx, "/universerpc.Universe/AssetRoots", in, out, opts...) @@ -272,6 +286,11 @@ func (c *universeClient) QueryFederationSyncConfig(ctx context.Context, in *Quer // All implementations must embed UnimplementedUniverseServer // for forward compatibility type UniverseServer interface { + // tapcli: `universe multiverse` + // MultiverseRoot returns the root of the multiverse tree. This is useful to + // determine the equality of two multiverse trees, since the root can directly + // be compared to another multiverse root to find out if a sync is required. + MultiverseRoot(context.Context, *MultiverseRootRequest) (*MultiverseRootResponse, error) // tapcli: `universe roots` // AssetRoots queries for the known Universe roots associated with each known // asset. These roots represent the supply/audit state for each known asset. @@ -366,6 +385,9 @@ type UniverseServer interface { type UnimplementedUniverseServer struct { } +func (UnimplementedUniverseServer) MultiverseRoot(context.Context, *MultiverseRootRequest) (*MultiverseRootResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method MultiverseRoot not implemented") +} func (UnimplementedUniverseServer) AssetRoots(context.Context, *AssetRootRequest) (*AssetRootResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method AssetRoots not implemented") } @@ -430,6 +452,24 @@ func RegisterUniverseServer(s grpc.ServiceRegistrar, srv UniverseServer) { s.RegisterService(&Universe_ServiceDesc, srv) } +func _Universe_MultiverseRoot_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MultiverseRootRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(UniverseServer).MultiverseRoot(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/universerpc.Universe/MultiverseRoot", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(UniverseServer).MultiverseRoot(ctx, req.(*MultiverseRootRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _Universe_AssetRoots_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(AssetRootRequest) if err := dec(in); err != nil { @@ -743,6 +783,10 @@ var Universe_ServiceDesc = grpc.ServiceDesc{ ServiceName: "universerpc.Universe", HandlerType: (*UniverseServer)(nil), Methods: []grpc.MethodDesc{ + { + MethodName: "MultiverseRoot", + Handler: _Universe_MultiverseRoot_Handler, + }, { MethodName: "AssetRoots", Handler: _Universe_AssetRoots_Handler, From aab22c2694ded1dd5d69c60b5eeaa2d5c9b3f907 Mon Sep 17 00:00:00 2001 From: Oliver Gugger Date: Fri, 27 Oct 2023 16:54:53 +0200 Subject: [PATCH 06/16] cmd/tapcli: add universe multiverse subcommand --- cmd/tapcli/universe.go | 43 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/cmd/tapcli/universe.go b/cmd/tapcli/universe.go index 5c6b64868..b35d800ba 100644 --- a/cmd/tapcli/universe.go +++ b/cmd/tapcli/universe.go @@ -38,6 +38,7 @@ var universeCommands = []cli.Command{ Usage: "Interact with a local or remote tap universe", Category: "Universe", Subcommands: []cli.Command{ + multiverseRootCommand, universeRootsCommand, universeDeleteRootCommand, universeLeavesCommand, @@ -51,6 +52,48 @@ var universeCommands = []cli.Command{ }, } +var multiverseRootCommand = cli.Command{ + Name: "multiverse", + ShortName: "m", + Description: "Show the multiverse root", + Usage: ` + Calculate the multiverse root from the current known asset universes of + the given proof type. + `, + Flags: []cli.Flag{ + cli.StringFlag{ + Name: proofTypeName, + Usage: "the type of proof to show the root for, " + + "either 'issuance' or 'transfer'", + Value: universe.ProofTypeIssuance.String(), + }, + }, + Action: multiverseRoot, +} + +func multiverseRoot(ctx *cli.Context) error { + ctxc := getContext() + client, cleanUp := getUniverseClient(ctx) + defer cleanUp() + + rpcProofType, err := parseProofType(ctx) + if err != nil { + return err + } + + multiverseRoot, err := client.MultiverseRoot( + ctxc, &unirpc.MultiverseRootRequest{ + ProofType: *rpcProofType, + }, + ) + if err != nil { + return err + } + + printRespJSON(multiverseRoot) + return nil +} + var universeRootsCommand = cli.Command{ Name: "roots", ShortName: "r", From c5bd0cc9654e2d5a573fdaa92cd479794e702ac9 Mon Sep 17 00:00:00 2001 From: Oliver Gugger Date: Fri, 27 Oct 2023 18:03:28 +0200 Subject: [PATCH 07/16] itest: assert multiverse roots --- itest/universe_test.go | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/itest/universe_test.go b/itest/universe_test.go index 5f9fe5b19..57a7b509e 100644 --- a/itest/universe_test.go +++ b/itest/universe_test.go @@ -261,6 +261,35 @@ func testUniverseSync(t *harnessTest) { require.True( t.t, AssertUniverseRootsEqual(universeRoots, universeRootsBob), ) + + // Test the multiverse root is equal for both nodes. + multiverseRootAlice, err := t.tapd.MultiverseRoot( + ctxt, &unirpc.MultiverseRootRequest{ + ProofType: unirpc.ProofType_PROOF_TYPE_ISSUANCE, + }, + ) + require.NoError(t.t, err) + + // For Bob we query with the actual IDs of the universe we are aware of. + multiverseRootBob, err := bob.MultiverseRoot( + ctxt, &unirpc.MultiverseRootRequest{ + ProofType: unirpc.ProofType_PROOF_TYPE_ISSUANCE, + SpecificIds: uniIDs, + }, + ) + require.NoError(t.t, err) + + require.Equal( + t.t, multiverseRootAlice.MultiverseRoot.RootHash, + multiverseRootBob.MultiverseRoot.RootHash, + ) + + // We also expect the proof's root hash to be equal to the actual + // multiverse root. + require.Equal( + t.t, firstAssetUniProof.MultiverseRoot.RootHash, + multiverseRootBob.MultiverseRoot.RootHash, + ) } // unmarshalMerkleSumNode un-marshals a protobuf MerkleSumNode. From ea8d35b2831a49a96796fa90e29db17d36941cdc Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Mon, 13 Nov 2023 18:55:02 -0800 Subject: [PATCH 08/16] fn: add new Option[T] type --- fn/option.go | 148 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 148 insertions(+) create mode 100644 fn/option.go diff --git a/fn/option.go b/fn/option.go new file mode 100644 index 000000000..741ef241f --- /dev/null +++ b/fn/option.go @@ -0,0 +1,148 @@ +package fn + +// Option[A] represents a value which may or may not be there. This is very +// often preferable to nil-able pointers. +type Option[A any] struct { + isSome bool + some A +} + +// Some trivially injects a value into an optional context. +// +// Some : A -> Option[A]. +func Some[A any](a A) Option[A] { + return Option[A]{ + isSome: true, + some: a, + } +} + +// None trivially constructs an empty option +// +// None : Option[A]. +func None[A any]() Option[A] { + return Option[A]{} +} + +// ElimOption is the universal Option eliminator. It can be used to safely +// handle all possible values inside the Option by supplying two continuations. +// +// ElimOption : (Option[A], () -> B, A -> B) -> B. +func ElimOption[A, B any](o Option[A], b func() B, f func(A) B) B { + if o.isSome { + return f(o.some) + } + + return b() +} + +// UnwrapOr is used to extract a value from an option, and we supply the default +// value in the case when the Option is empty. +// +// UnwrapOr : (Option[A], A) -> A. +func (o Option[A]) UnwrapOr(a A) A { + if o.isSome { + return o.some + } + + return a +} + +// WhenSome is used to conditionally perform a side-effecting function that +// accepts a value of the type that parameterizes the option. If this function +// performs no side effects, WhenSome is useless. +// +// WhenSome : (Option[A], A -> ()) -> (). +func (o Option[A]) WhenSome(f func(A)) { + if o.isSome { + f(o.some) + } +} + +// IsSome returns true if the Option contains a value +// +// IsSome : Option[A] -> bool. +func (o Option[A]) IsSome() bool { + return o.isSome +} + +// IsNone returns true if the Option is empty +// +// IsNone : Option[A] -> bool. +func (o Option[A]) IsNone() bool { + return !o.isSome +} + +// FlattenOption joins multiple layers of Options together such that if any of +// the layers is None, then the joined value is None. Otherwise the innermost +// Some value is returned. +// +// FlattenOption : Option[Option[A]] -> Option[A]. +func FlattenOption[A any](oo Option[Option[A]]) Option[A] { + if oo.IsNone() { + return None[A]() + } + if oo.some.IsNone() { + return None[A]() + } + + return oo.some +} + +// ChainOption transforms a function A -> Option[B] into one that accepts an +// Option[A] as an argument. +// +// ChainOption : (A -> Option[B]) -> Option[A] -> Option[B]. +func ChainOption[A, B any](f func(A) Option[B]) func(Option[A]) Option[B] { + return func(o Option[A]) Option[B] { + if o.isSome { + return f(o.some) + } + + return None[B]() + } +} + +// MapOption transforms a pure function A -> B into one that will operate +// inside the Option context. +// +// MapOption : (A -> B) -> Option[A] -> Option[B]. +func MapOption[A, B any](f func(A) B) func(Option[A]) Option[B] { + return func(o Option[A]) Option[B] { + if o.isSome { + return Some(f(o.some)) + } + + return None[B]() + } +} + +// LiftA2Option transforms a pure function (A, B) -> C into one that will +// operate in an Option context. For the returned function, if either of its +// arguments are None, then the result will be None. +// +// LiftA2Option : ((A, B) -> C) -> (Option[A], Option[B]) -> Option[C]. +func LiftA2Option[A, B, C any]( + f func(A, B) C) func(Option[A], Option[B]) Option[C] { + + return func(o1 Option[A], o2 Option[B]) Option[C] { + if o1.isSome && o2.isSome { + return Some(f(o1.some, o2.some)) + } + + return None[C]() + } +} + +// Alt chooses the left Option if it is full, otherwise it chooses the right +// option. This can be useful in a long chain if you want to choose between +// many different ways of producing the needed value. +// +// Alt : Option[A] -> Option[A] -> Option[A]. +func (o Option[A]) Alt(o2 Option[A]) Option[A] { + if o.isSome { + return o + } + + return o2 +} From ff8eff40ae340b5603d354f5a3053b3232966981 Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Mon, 13 Nov 2023 18:55:14 -0800 Subject: [PATCH 09/16] fn: add new Either[L, R] type --- fn/either.go | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 fn/either.go diff --git a/fn/either.go b/fn/either.go new file mode 100644 index 000000000..6bd6bd309 --- /dev/null +++ b/fn/either.go @@ -0,0 +1,37 @@ +package fn + +// Either is a type that can be either left or right. +type Either[L any, R any] struct { + left Option[L] + right Option[R] +} + +// NewLeft returns an Either with a left value. +func NewLeft[L any, R any](l L) Either[L, R] { + return Either[L, R]{left: Some(l), right: None[R]()} +} + +// NewRight returns an Either with a right value. +func NewRight[L any, R any](r R) Either[L, R] { + return Either[L, R]{left: None[L](), right: Some(r)} +} + +// WhenLeft executes the given function if the Either is left. +func (e Either[L, R]) WhenLeft(f func(L)) { + e.left.WhenSome(f) +} + +// WhenRight executes the given function if the Either is right. +func (e Either[L, R]) WhenRight(f func(R)) { + e.right.WhenSome(f) +} + +// IsLeft returns true if the Either is left. +func (e Either[L, R]) IsLeft() bool { + return e.left.IsSome() +} + +// IsRight returns true if the Either is right. +func (e Either[L, R]) IsRight() bool { + return e.right.IsSome() +} From 257d35da1e1bdf4c9569331102d1306cb135d402 Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Mon, 13 Nov 2023 18:56:15 -0800 Subject: [PATCH 10/16] fn: rename None to NotAny Otherwise it conflicts with the new Option[T] type --- fn/func.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/fn/func.go b/fn/func.go index c721901b8..d2c7edcb9 100644 --- a/fn/func.go +++ b/fn/func.go @@ -142,9 +142,9 @@ func Any[T any](xs []T, pred func(T) bool) bool { return false } -// None returns true if the passed predicate returns false for all items in the -// slice. -func None[T any](xs []T, pred func(T) bool) bool { +// NotAny returns true if the passed predicate returns false for all items in +// the slice. +func NotAny[T any](xs []T, pred func(T) bool) bool { return !Any(xs, pred) } From 20761302b66dcd0287a473269bc20b292cba7b8b Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Mon, 13 Nov 2023 18:59:16 -0800 Subject: [PATCH 11/16] tapdb: update QueryMultiverseLeaves to return SMT leaf info By modifying this query we can simplify other logic as now we get the full context which includes the value+sum of the SMT leaf. In this case, the value is the universe root hash, and the sum the root sum. --- tapdb/sqlc/queries/universe.sql | 6 +++++- tapdb/sqlc/universe.sql.go | 20 +++++++++++++------- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/tapdb/sqlc/queries/universe.sql b/tapdb/sqlc/queries/universe.sql index 4e2d12835..b3489e86b 100644 --- a/tapdb/sqlc/queries/universe.sql +++ b/tapdb/sqlc/queries/universe.sql @@ -508,8 +508,12 @@ DELETE FROM multiverse_leaves WHERE leaf_node_namespace = @namespace AND leaf_node_key = @leaf_node_key; -- name: QueryMultiverseLeaves :many -SELECT r.namespace_root, r.proof_type, l.asset_id, l.group_key, l.leaf_node_key +SELECT r.namespace_root, r.proof_type, l.asset_id, l.group_key, + smt_nodes.value AS universe_root_hash, smt_nodes.sum AS universe_root_sum FROM multiverse_leaves l +JOIN mssmt_nodes smt_nodes + ON l.leaf_node_key = smt_nodes.key AND + l.leaf_node_namespace = smt_nodes.namespace JOIN multiverse_roots r ON l.multiverse_root_id = r.id WHERE r.proof_type = @proof_type AND diff --git a/tapdb/sqlc/universe.sql.go b/tapdb/sqlc/universe.sql.go index 8fbb8e709..17d05ffc7 100644 --- a/tapdb/sqlc/universe.sql.go +++ b/tapdb/sqlc/universe.sql.go @@ -620,8 +620,12 @@ func (q *Queries) QueryFederationUniSyncConfigs(ctx context.Context) ([]Federati } const queryMultiverseLeaves = `-- name: QueryMultiverseLeaves :many -SELECT r.namespace_root, r.proof_type, l.asset_id, l.group_key, l.leaf_node_key +SELECT r.namespace_root, r.proof_type, l.asset_id, l.group_key, + smt_nodes.value AS universe_root_hash, smt_nodes.sum AS universe_root_sum FROM multiverse_leaves l +JOIN mssmt_nodes smt_nodes + ON l.leaf_node_key = smt_nodes.key AND + l.leaf_node_namespace = smt_nodes.namespace JOIN multiverse_roots r ON l.multiverse_root_id = r.id WHERE r.proof_type = $1 AND @@ -636,11 +640,12 @@ type QueryMultiverseLeavesParams struct { } type QueryMultiverseLeavesRow struct { - NamespaceRoot string - ProofType string - AssetID []byte - GroupKey []byte - LeafNodeKey []byte + NamespaceRoot string + ProofType string + AssetID []byte + GroupKey []byte + UniverseRootHash []byte + UniverseRootSum int64 } func (q *Queries) QueryMultiverseLeaves(ctx context.Context, arg QueryMultiverseLeavesParams) ([]QueryMultiverseLeavesRow, error) { @@ -657,7 +662,8 @@ func (q *Queries) QueryMultiverseLeaves(ctx context.Context, arg QueryMultiverse &i.ProofType, &i.AssetID, &i.GroupKey, - &i.LeafNodeKey, + &i.UniverseRootHash, + &i.UniverseRootSum, ); err != nil { return nil, err } From 93546f79f068334d91548cca7dbdc2fbffbd078d Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Mon, 13 Nov 2023 19:00:02 -0800 Subject: [PATCH 12/16] tapdb: add new FetchMultiverseRoot query This query will be used to fetch the multiverse leaf directly, without first needing to make a temp SMT tree. --- tapdb/sqlc/querier.go | 1 + tapdb/sqlc/queries/universe.sql | 10 ++++++++++ tapdb/sqlc/universe.sql.go | 24 ++++++++++++++++++++++++ 3 files changed, 35 insertions(+) diff --git a/tapdb/sqlc/querier.go b/tapdb/sqlc/querier.go index dc105d7de..928dceda2 100644 --- a/tapdb/sqlc/querier.go +++ b/tapdb/sqlc/querier.go @@ -67,6 +67,7 @@ type Querier interface { FetchManagedUTXOs(ctx context.Context) ([]FetchManagedUTXOsRow, error) FetchMintingBatch(ctx context.Context, rawKey []byte) (FetchMintingBatchRow, error) FetchMintingBatchesByInverseState(ctx context.Context, batchState int16) ([]FetchMintingBatchesByInverseStateRow, error) + FetchMultiverseRoot(ctx context.Context, namespaceRoot string) (FetchMultiverseRootRow, error) FetchRootNode(ctx context.Context, namespace string) (MssmtNode, error) FetchScriptKeyByTweakedKey(ctx context.Context, tweakedScriptKey []byte) (FetchScriptKeyByTweakedKeyRow, error) FetchScriptKeyIDByTweakedKey(ctx context.Context, tweakedScriptKey []byte) (int64, error) diff --git a/tapdb/sqlc/queries/universe.sql b/tapdb/sqlc/queries/universe.sql index b3489e86b..787162906 100644 --- a/tapdb/sqlc/queries/universe.sql +++ b/tapdb/sqlc/queries/universe.sql @@ -490,6 +490,16 @@ ON CONFLICT (namespace_root) DO UPDATE SET namespace_root = EXCLUDED.namespace_root RETURNING id; +-- name: FetchMultiverseRoot :one +SELECT proof_type, n.hash_key as multiverse_root_hash, n.sum as multiverse_root_sum +FROM multiverse_roots r +JOIN mssmt_roots m + ON r.namespace_root = m.namespace +JOIN mssmt_nodes n + ON m.root_hash = n.hash_key AND + m.namespace = n.namespace +WHERE namespace_root = @namespace_root; + -- name: UpsertMultiverseLeaf :one INSERT INTO multiverse_leaves ( multiverse_root_id, asset_id, group_key, leaf_node_key, leaf_node_namespace diff --git a/tapdb/sqlc/universe.sql.go b/tapdb/sqlc/universe.sql.go index 17d05ffc7..c3ed9b058 100644 --- a/tapdb/sqlc/universe.sql.go +++ b/tapdb/sqlc/universe.sql.go @@ -114,6 +114,30 @@ func (q *Queries) DeleteUniverseServer(ctx context.Context, arg DeleteUniverseSe return err } +const fetchMultiverseRoot = `-- name: FetchMultiverseRoot :one +SELECT proof_type, n.hash_key as multiverse_root_hash, n.sum as multiverse_root_sum +FROM multiverse_roots r +JOIN mssmt_roots m + ON r.namespace_root = m.namespace +JOIN mssmt_nodes n + ON m.root_hash = n.hash_key AND + m.namespace = n.namespace +WHERE namespace_root = $1 +` + +type FetchMultiverseRootRow struct { + ProofType string + MultiverseRootHash []byte + MultiverseRootSum int64 +} + +func (q *Queries) FetchMultiverseRoot(ctx context.Context, namespaceRoot string) (FetchMultiverseRootRow, error) { + row := q.db.QueryRowContext(ctx, fetchMultiverseRoot, namespaceRoot) + var i FetchMultiverseRootRow + err := row.Scan(&i.ProofType, &i.MultiverseRootHash, &i.MultiverseRootSum) + return i, err +} + const fetchUniverseKeys = `-- name: FetchUniverseKeys :many SELECT leaves.minting_point, leaves.script_key_bytes FROM universe_leaves leaves From 716053b25da879d3ddca21fc637995c3082fa591 Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Mon, 13 Nov 2023 19:05:07 -0800 Subject: [PATCH 13/16] universe: rename RootNode to MultiverseRootNode In this commit, we rename RootNode to MultiverseRootNode as we can return multiple root types. We also modify the query to use the new `FetchMultiverseRoot` method as well. --- tapdb/multiverse.go | 68 ++++++++++++++++++++++++++++++++++++--------- tapdb/universe.go | 12 -------- 2 files changed, 55 insertions(+), 25 deletions(-) diff --git a/tapdb/multiverse.go b/tapdb/multiverse.go index 94acc75cf..281a8ebc0 100644 --- a/tapdb/multiverse.go +++ b/tapdb/multiverse.go @@ -32,10 +32,27 @@ const ( transferMultiverseNS = "multiverse-transfer" ) +var ( + // ErrNoMultiverseRoot is returned when no universe root is found for + // the target proof type. + ErrNoMultiverseRoot = errors.New("no multiverse root found") +) + type ( BaseUniverseRoot = sqlc.UniverseRootsRow UniverseRootsParams = sqlc.UniverseRootsParams + + // MultiverseRoot is the root of a multiverse tree. Two trees exist: + // issuance and transfers. + MultiverseRoot = sqlc.FetchMultiverseRootRow + + // MultiverseLeaf is a leaf in a multiverse. + MultiverseLeaf = sqlc.QueryMultiverseLeavesRow + + // QueryMultiverseLeaves is used to query for a set of leaves based on + // the proof type and asset ID (or group key) + QueryMultiverseLeaves = sqlc.QueryMultiverseLeavesParams ) // BaseMultiverseStore is used to interact with a set of base universe @@ -43,8 +60,20 @@ type ( type BaseMultiverseStore interface { BaseUniverseStore + // UniverseRoots returns the set of active universe roots for a given + // Multiverse type. UniverseRoots(ctx context.Context, params UniverseRootsParams) ([]BaseUniverseRoot, error) + + // QueryMultiverseLeaves is used to query for the set of leaves that + // reside in a multiverse tree. + QueryMultiverseLeaves(ctx context.Context, + arg QueryMultiverseLeaves) ([]MultiverseLeaf, error) + + // FetchMultiverseRoot returns the root of the multiverse tree for a + // given target namespace (proof type in this case). + FetchMultiverseRoot(ctx context.Context, + proofNamespace string) (MultiverseRoot, error) } // BaseMultiverseOptions is the set of options for multiverse queries. @@ -504,40 +533,53 @@ func namespaceForProof(proofType universe.ProofType) (string, error) { } } -// RootNode returns the root multiverse node for the given proof type. -func (b *MultiverseStore) RootNode(ctx context.Context, - proofType universe.ProofType) (*universe.MultiverseRoot, error) { +// MultiverseRootNode returns the root multiverse node for the given proof +// type. +func (b *MultiverseStore) MultiverseRootNode(ctx context.Context, + proofType universe.ProofType) (fn.Option[universe.MultiverseRoot], + error) { + + none := fn.None[universe.MultiverseRoot]() multiverseNS, err := namespaceForProof(proofType) if err != nil { - return nil, err + return none, err } - var rootNode *universe.MultiverseRoot + var rootNode universe.MultiverseRoot readTx := NewBaseUniverseReadTx() dbErr := b.db.ExecTx(ctx, &readTx, func(db BaseMultiverseStore) error { - multiverseTree := mssmt.NewCompactedTree( - newTreeStoreWrapperTx(db, multiverseNS), - ) + multiverseRoot, err := db.FetchMultiverseRoot(ctx, multiverseNS) + switch { + case errors.Is(err, sql.ErrNoRows): + return ErrNoMultiverseRoot - multiverseRoot, err := multiverseTree.Root(ctx) + case err != nil: + return err + } + + nodeHash, err := newKey(multiverseRoot.MultiverseRootHash[:]) if err != nil { return err } - rootNode = &universe.MultiverseRoot{ - Node: multiverseRoot, + smtRoot := mssmt.NewComputedBranch( + nodeHash, uint64(multiverseRoot.MultiverseRootSum), + ) + + rootNode = universe.MultiverseRoot{ + Node: smtRoot, ProofType: proofType, } return nil }) if dbErr != nil { - return nil, dbErr + return none, dbErr } - return rootNode, nil + return fn.Some(rootNode), nil } // UniverseRootNode returns the Universe root node for the given asset ID. diff --git a/tapdb/universe.go b/tapdb/universe.go index 15cb331d5..ee263125a 100644 --- a/tapdb/universe.go +++ b/tapdb/universe.go @@ -50,13 +50,6 @@ type ( // DeleteMultiverseLeaf is used to delete a multiverse leaf. DeleteMultiverseLeaf = sqlc.DeleteMultiverseLeafParams - - // QueryMultiverseLeaves is used to query for a set of leaves based on - // the proof type and asset ID (or group key) - QueryMultiverseLeaves = sqlc.QueryMultiverseLeavesParams - - // MultiverseLeaf is a leaf in a multiverse. - MultiverseLeaf = sqlc.QueryMultiverseLeavesRow ) // BaseUniverseStore is the main interface for the Taproot Asset universe store. @@ -117,11 +110,6 @@ type BaseUniverseStore interface { // DeleteMultiverseLeaf deletes a multiverse leaf from the database. DeleteMultiverseLeaf(ctx context.Context, arg DeleteMultiverseLeaf) error - - // QueryMultiverseLeaves is used to query for the set of leaves that - // reside in a multiverse tree. - QueryMultiverseLeaves(ctx context.Context, - arg QueryMultiverseLeaves) ([]MultiverseLeaf, error) } // BaseUniverseStoreOptions is the set of options for universe tree queries. From de3db3433badb759d945aed46be6affe0a020bfc Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Mon, 13 Nov 2023 19:05:21 -0800 Subject: [PATCH 14/16] universe: add new MultiverseLeafDesc and MultiverseLeaf types These will be used in the database to modify the existing FetchMultiverseLeaves call to use a single DB query. --- universe/interface.go | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/universe/interface.go b/universe/interface.go index 2490b7e8a..1c7d09bab 100644 --- a/universe/interface.go +++ b/universe/interface.go @@ -13,6 +13,7 @@ import ( "github.com/btcsuite/btcd/btcec/v2/schnorr" "github.com/btcsuite/btcd/wire" "github.com/lightninglabs/taproot-assets/asset" + "github.com/lightninglabs/taproot-assets/fn" "github.com/lightninglabs/taproot-assets/mssmt" "github.com/lightninglabs/taproot-assets/proof" ) @@ -364,6 +365,11 @@ type Root struct { GroupedAssets map[asset.ID]uint64 } +// MultiverseLeafDesc can be used to uniquely identify a Multiverse leave +// (which is a Universe root). A leaf for a given Universe tree (proof type +// assumed) can be identified by either the asset ID or the target group key. +type MultiverseLeafDesc = fn.Either[asset.ID, btcec.PublicKey] + // MultiverseRoot is the ms-smt root for a multiverse. This root can be used to // authenticate any leaf proofs. type MultiverseRoot struct { @@ -374,6 +380,16 @@ type MultiverseRoot struct { mssmt.Node } +// MultiverseLeaf is the leaf within a Multiverse, this stores a value which is +// derived from the root of a normal Universe tree. +type MultiverseLeaf struct { + // ID contains the information to uniquely identify the multiverse + // root: assetID/groupKey and the proof type. + ID Identifier + + *mssmt.LeafNode +} + // MultiverseArchive is an interface used to keep track of the set of universe // roots that we know of. The BaseBackend interface is used to interact with a // particular base universe, while this is used to obtain aggregate information From d9b57fee76a3a3806c5225274bf9e80f1590e8ac Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Mon, 13 Nov 2023 19:06:35 -0800 Subject: [PATCH 15/16] universe: allow FetchMultiverseLeaves to multi-query In this commit, we modify the FetchMultiverseLeaves method to allow it to return either all the leaves, or a subset of leaves filtered by the `MultiverseLeafDesc` type. In the future, we can further extend this to use postgres batch queries so we can get the resp in a single round trip. --- tapdb/multiverse.go | 91 +++++++++++++------- tapdb/universe_test.go | 190 ++++++++++++++++++++++++++--------------- 2 files changed, 180 insertions(+), 101 deletions(-) diff --git a/tapdb/multiverse.go b/tapdb/multiverse.go index 281a8ebc0..fea562e0c 100644 --- a/tapdb/multiverse.go +++ b/tapdb/multiverse.go @@ -1031,54 +1031,81 @@ func (b *MultiverseStore) DeleteUniverse(ctx context.Context, // asset ID, and group key. If both asset ID and group key is nil, all leaves // for the given proof type will be returned. func (b *MultiverseStore) FetchLeaves(ctx context.Context, - assetID *asset.ID, groupKey *btcec.PublicKey, - proofType universe.ProofType) ([]universe.Identifier, error) { + universeTargets []universe.MultiverseLeafDesc, + proofType universe.ProofType) ([]universe.MultiverseLeaf, error) { + + queries := make([]QueryMultiverseLeaves, 0, len(universeTargets)) + switch len(universeTargets) { + // If we don't have any targets, then we'll have just a single query to + // return all universe leaves for the proof type. + case 0: + queries = append(queries, QueryMultiverseLeaves{ + ProofType: proofType.String(), + }) + + // Otherwise, we'll do a query for each universe target specified. + default: + for _, uniTarget := range universeTargets { + var assetIDBytes, groupKeyBytes []byte - var assetIDBytes, groupKeyBytes []byte - if assetID != nil { - assetIDBytes = assetID[:] - } - if groupKey != nil { - groupKeyBytes = schnorr.SerializePubKey(groupKey) + uniTarget.WhenLeft(func(a asset.ID) { + assetIDBytes = a[:] + }) + uniTarget.WhenRight(func(g btcec.PublicKey) { + groupKeyBytes = schnorr.SerializePubKey(&g) + }) + + queries = append(queries, QueryMultiverseLeaves{ + ProofType: proofType.String(), + AssetID: assetIDBytes, + GroupKey: groupKeyBytes, + }) + } } var ( readTx = NewBaseUniverseReadTx() - ids []universe.Identifier + leaves []universe.MultiverseLeaf ) dbErr := b.db.ExecTx(ctx, &readTx, func(q BaseMultiverseStore) error { - leaves, err := q.QueryMultiverseLeaves( - ctx, QueryMultiverseLeaves{ - ProofType: proofType.String(), - AssetID: assetIDBytes, - GroupKey: groupKeyBytes, - }, - ) - if err != nil { - return err - } + leaves = nil - ids = make([]universe.Identifier, len(leaves)) - for i, leaf := range leaves { - ids[i].ProofType = proofType - if len(leaf.AssetID) > 0 { - copy(ids[i].AssetID[:], leaf.AssetID) + for _, query := range queries { + dbLeaves, err := q.QueryMultiverseLeaves(ctx, query) + if err != nil { + return err } - if len(leaf.GroupKey) > 0 { - ids[i].GroupKey, err = schnorr.ParsePubKey( - leaf.GroupKey, - ) - if err != nil { - return err + + for _, leaf := range dbLeaves { + var id universe.Identifier + + id.ProofType = proofType + if len(leaf.AssetID) > 0 { + copy(id.AssetID[:], leaf.AssetID) } + if len(leaf.GroupKey) > 0 { + id.GroupKey, err = schnorr.ParsePubKey( + leaf.GroupKey, + ) + if err != nil { + return err + } + } + + leaves = append(leaves, universe.MultiverseLeaf{ + ID: id, + LeafNode: mssmt.NewLeafNode( + leaf.UniverseRootHash, + uint64(leaf.UniverseRootSum), + ), + }) } } - return nil }) if dbErr != nil { return nil, dbErr } - return ids, nil + return leaves, nil } diff --git a/tapdb/universe_test.go b/tapdb/universe_test.go index 2a579ab76..592428747 100644 --- a/tapdb/universe_test.go +++ b/tapdb/universe_test.go @@ -116,20 +116,22 @@ func newTestUniverseWithDb(db *BaseDB, return NewBaseUniverseTree(dbTxer, id), db } -func assertIDInList(t *testing.T, leaves []universe.Identifier, +func assertIDInList(t *testing.T, leaves []universe.MultiverseLeaf, id universe.Identifier) { - require.True(t, fn.Any(leaves, func(l universe.Identifier) bool { + require.True(t, fn.Any(leaves, func(l universe.MultiverseLeaf) bool { switch { - case l.AssetID != asset.ID{}: - return l.AssetID == id.AssetID + case l.ID.AssetID != asset.ID{}: + return l.ID.AssetID == id.AssetID - case l.GroupKey != nil: + case l.ID.GroupKey != nil: if id.GroupKey == nil { return false } - return test.SchnorrKeysEqual(t, l.GroupKey, id.GroupKey) + return test.SchnorrKeysEqual( + t, l.ID.GroupKey, id.GroupKey, + ) default: require.Fail(t, "invalid leaf") @@ -250,12 +252,12 @@ func TestUniverseIssuanceProofs(t *testing.T) { // The multiverse tree should be empty at this point. issuanceLeaves, err := multiverse.FetchLeaves( - ctx, nil, nil, universe.ProofTypeIssuance, + ctx, nil, universe.ProofTypeIssuance, ) require.NoError(t, err) require.Len(t, issuanceLeaves, 0) transferLeaves, err := multiverse.FetchLeaves( - ctx, nil, nil, universe.ProofTypeTransfer, + ctx, nil, universe.ProofTypeTransfer, ) require.NoError(t, err) require.Len(t, transferLeaves, 0) @@ -337,7 +339,7 @@ func TestUniverseIssuanceProofs(t *testing.T) { // The multiverse tree should just have a single leaf, since we inserted // proofs into the same universe. multiverseLeaves, err := multiverse.FetchLeaves( - ctx, nil, nil, id.ProofType, + ctx, nil, id.ProofType, ) require.NoError(t, err) require.Len(t, multiverseLeaves, 1) @@ -887,10 +889,10 @@ func TestMultiverseRootSum(t *testing.T) { } testCases := []testCase{ - // If we insert two transfers into a transfer tree, then the - // sum should be the sum of the leaf values. The leaf value - // here is itself the root sum of an transfer tree, or the - // number of transfers in a transfer tree. + // If we insert two transfers into a transfer tree, then the sum + // should be the sum of the leaf values. The leaf value here is + // itself the root sum of a transfer tree, or the number of + // transfers in a transfer tree. { name: "transfer sum", finalSum: 4, @@ -922,6 +924,28 @@ func TestMultiverseRootSum(t *testing.T) { }, }, }, + + // We also want to make sure we can insert both transfer and + // issuance proofs at the same time without any conflicts. + { + name: "transfer and issuance sum", + finalSum: 3, + // By specifying this as "unspecified" we signal we want + // both transfer and issuance proofs. The final sum will + // therefore be the same for both trees. + proofType: universe.ProofTypeUnspecified, + leaves: []leaf{ + { + sumAmt: 14, + }, + { + sumAmt: 20, + }, + { + sumAmt: 20, + }, + }, + }, } runTestCase := func(t *testing.T, tc testCase) { @@ -931,88 +955,116 @@ func TestMultiverseRootSum(t *testing.T) { // The multiverse tree should be empty at this point. issuanceLeaves, err := multiverse.FetchLeaves( - ctx, nil, nil, universe.ProofTypeIssuance, + ctx, nil, universe.ProofTypeIssuance, ) require.NoError(t, err) require.Len(t, issuanceLeaves, 0) transferLeaves, err := multiverse.FetchLeaves( - ctx, nil, nil, universe.ProofTypeTransfer, + ctx, nil, universe.ProofTypeTransfer, ) require.NoError(t, err) require.Len(t, transferLeaves, 0) - leaves := make([]universe.Leaf, len(tc.leaves)) - ids := make([]universe.Identifier, len(tc.leaves)) - for i, testLeaf := range tc.leaves { - id := randUniverseID( - t, false, withProofType(tc.proofType), - ) - - ids[i] = id + ids := make([]universe.Identifier, 0, len(tc.leaves)) + for range tc.leaves { + ids = append(ids, randUniverseID(t, false)) + } - assetGen := asset.RandGenesis(t, asset.Normal) - leaf := randMintingLeaf(t, assetGen, id.GroupKey) - leaf.Amt = testLeaf.sumAmt + insertLeaves := func(proofType universe.ProofType) { + for i, testLeaf := range tc.leaves { + id := ids[i] + id.ProofType = proofType - leaves[i] = leaf + assetGen := asset.RandGenesis(t, asset.Normal) + leaf := randMintingLeaf( + t, assetGen, id.GroupKey, + ) + leaf.Amt = testLeaf.sumAmt - targetKey := randLeafKey(t) + targetKey := randLeafKey(t) - // For transfer proofs, we'll modify the witness asset - // proof to look more like a transfer. - if tc.proofType == universe.ProofTypeTransfer { - prevWitnesses := leaf.Asset.PrevWitnesses - prevWitnesses[0].TxWitness = [][]byte{ - {1}, {1}, {1}, + // For transfer proofs, we'll modify the witness + // asset proof to look more like a transfer. + if proofType == universe.ProofTypeTransfer { + prevWitnesses := leaf.Asset.PrevWitnesses + prevWitnesses[0].TxWitness = [][]byte{ + {1}, {1}, {1}, + } + prevID := prevWitnesses[0].PrevID + prevID.OutPoint.Hash = [32]byte{1} } - prevWitnesses[0].PrevID.OutPoint.Hash = [32]byte{1} - } - - _, err := multiverse.UpsertProofLeaf( - ctx, id, targetKey, &leaf, nil, - ) - require.NoError(t, err) - - // If we should add more than one under this ID, then - // we'll generate another instance. - if tc.doubleUp { - targetKey = randLeafKey(t) _, err := multiverse.UpsertProofLeaf( ctx, id, targetKey, &leaf, nil, ) require.NoError(t, err) + + // If we should add more than one under this ID, + // then we'll generate another instance. + if tc.doubleUp { + targetKey = randLeafKey(t) + + _, err := multiverse.UpsertProofLeaf( + ctx, id, targetKey, &leaf, nil, + ) + require.NoError(t, err) + } + + // The multiverse tree should now have one more + // leaf. + multiverseLeaves, err := multiverse.FetchLeaves( + ctx, nil, proofType, + ) + require.NoError(t, err) + require.Len(t, multiverseLeaves, i+1) + + // And we should actually find the leaf we just + // inserted. + assertIDInList(t, multiverseLeaves, id) } + } - // The multiverse tree should now have one more leaf. - multiverseLeaves, err := multiverse.FetchLeaves( - ctx, nil, nil, tc.proofType, + checkSum := func(proofType universe.ProofType) { + rootNode, err := multiverse.MultiverseRootNode( + ctx, proofType, ) require.NoError(t, err) - require.Len(t, multiverseLeaves, i+1) - // And we should actually find the leaf we just - // inserted. - assertIDInList(t, multiverseLeaves, id) - } - - // If we fetch the root value of the tree, it should be - // the same as the finalSum. - rootNode, err := multiverse.RootNode(ctx, tc.proofType) - require.NoError(t, err) + rootNode.WhenSome( + func(rootNode universe.MultiverseRoot) { + require.EqualValues( + t, tc.finalSum, + rootNode.NodeSum(), + ) + }, + ) - require.EqualValues(t, tc.finalSum, rootNode.NodeSum()) + // We now delete the whole universe and expect the + // multiverse leave to also disappear. + id := ids[0] + id.ProofType = proofType + _, err = multiverse.DeleteUniverse(ctx, id) + require.NoError(t, err) - // We now delete the whole universe and expect the multiverse - // leave to also disappear. - _, err = multiverse.DeleteUniverse(ctx, ids[0]) - require.NoError(t, err) + multiverseLeaves, err := multiverse.FetchLeaves( + ctx, nil, proofType, + ) + require.NoError(t, err) + require.Len(t, multiverseLeaves, len(ids)-1) + } - multiverseLeaves, err := multiverse.FetchLeaves( - ctx, nil, nil, tc.proofType, - ) - require.NoError(t, err) - require.Len(t, multiverseLeaves, len(ids)-1) + // If we fetch the root value of the tree, it should be the same + // as the finalSum. + if tc.proofType == universe.ProofTypeUnspecified { + insertLeaves(universe.ProofTypeIssuance) + insertLeaves(universe.ProofTypeTransfer) + + checkSum(universe.ProofTypeIssuance) + checkSum(universe.ProofTypeTransfer) + } else { + insertLeaves(tc.proofType) + checkSum(tc.proofType) + } } for _, testCase := range testCases { From 55f07b1e2dc293b925fe21f811455b5bbdf1ee39 Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Mon, 13 Nov 2023 19:08:00 -0800 Subject: [PATCH 16/16] universe: update MultiverseRoot to use a single db query In this commit, we modify the `MultiverseRoot` method to use a single DB query. If we don't have anything to filter, then we'll fetch the global root for that proof type. Otherwise, we'll query the DB for the leaves that match the set of IDs, then insert those into our in-memory tree. This saves us N DB queries where N is the size of the set of Identifier. --- rpcserver.go | 9 +++-- universe/base.go | 83 +++++++++++++++++++++++-------------------- universe/interface.go | 16 +++++---- 3 files changed, 61 insertions(+), 47 deletions(-) diff --git a/rpcserver.go b/rpcserver.go index ea610dd20..84f0b0e4d 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -3005,9 +3005,12 @@ func (r *rpcServer) MultiverseRoot(ctx context.Context, err) } - return &unirpc.MultiverseRootResponse{ - MultiverseRoot: marshalMssmtNode(rootNode), - }, nil + var resp unirpc.MultiverseRootResponse + rootNode.WhenSome(func(node universe.MultiverseRoot) { + resp.MultiverseRoot = marshalMssmtNode(node) + }) + + return &resp, nil } // AssetRoots queries for the known Universe roots associated with each known diff --git a/universe/base.go b/universe/base.go index f130238d3..244e1a2d0 100644 --- a/universe/base.go +++ b/universe/base.go @@ -139,63 +139,70 @@ func (a *Archive) RootNodes(ctx context.Context, // proof type. If the given list of universe IDs is non-empty, then the root // will be calculated just for those universes. func (a *Archive) MultiverseRoot(ctx context.Context, proofType ProofType, - filterByIDs []Identifier) (mssmt.Node, error) { + filterByIDs []Identifier) (fn.Option[MultiverseRoot], error) { log.Debugf("Fetching multiverse root for proof type: %v", proofType) - leaveIDs, err := a.cfg.Multiverse.FetchLeaves(ctx, nil, nil, proofType) - if err != nil { - return nil, fmt.Errorf("unable to fetch multiverse leaves: %w", - err) - } + none := fn.None[MultiverseRoot]() - // If a filter list is provided, then we'll only include the leaves - // that are in the filter list. - includeUniverse := func(id Identifier) bool { - if len(filterByIDs) == 0 { - return true + // If we don't have any IDs, then we'll return the multiverse root for + // the given proof type. + if len(filterByIDs) == 0 { + rootNode, err := a.cfg.Multiverse.MultiverseRootNode( + ctx, proofType, + ) + if err != nil { + return none, err } - for _, filterID := range filterByIDs { - if id.IsEqual(filterID) { - return true - } + return rootNode, nil + } + + // Otherwise, we'll run the query to fetch the multiverse leaf for each + // of the specified assets. + uniTargets := make([]MultiverseLeafDesc, len(filterByIDs)) + for idx, id := range filterByIDs { + if id.GroupKey != nil { + uniTargets[idx] = fn.NewRight[asset.ID](*id.GroupKey) + } else { + uniTargets[idx] = fn.NewLeft[asset.ID, btcec.PublicKey]( + id.AssetID, + ) } + } - return false + multiverseLeaves, err := a.cfg.Multiverse.FetchLeaves( + ctx, uniTargets, proofType, + ) + if err != nil { + return none, fmt.Errorf("unable to fetch multiverse "+ + "leaves: %w", err) } + // Now that we have the leaves, we'll insert them into an in-memory + // tree, so we can obtain the root for this unique combination. memStore := mssmt.NewDefaultStore() tree := mssmt.NewCompactedTree(memStore) - for _, id := range leaveIDs { - // Only include the universe if it's in the filter list (given - // the filter list is non-empty). - if !includeUniverse(id) { - continue - } - - uniRoot, err := a.cfg.Multiverse.UniverseRootNode(ctx, id) + for _, leaf := range multiverseLeaves { + _, err = tree.Insert(ctx, leaf.ID.Bytes(), leaf.LeafNode) if err != nil { - return nil, fmt.Errorf("unable to fetch universe "+ - "root: %w", err) + return none, fmt.Errorf("unable to insert "+ + "leaf: %w", err) } + } - rootHash := uniRoot.NodeHash() - rootSum := uniRoot.NodeSum() - - if id.ProofType == ProofTypeIssuance { - rootSum = 1 - } + customRoot, err := tree.Root(ctx) + if err != nil { + return none, fmt.Errorf("unable to obtain root: %w", err) + } - uniLeaf := mssmt.NewLeafNode(rootHash[:], rootSum) - _, err = tree.Insert(ctx, id.Bytes(), uniLeaf) - if err != nil { - return nil, fmt.Errorf("unable to insert leaf: %w", err) - } + multiverseRoot := MultiverseRoot{ + ProofType: proofType, + Node: customRoot, } - return tree.Root(ctx) + return fn.Some(multiverseRoot), nil } // UpsertProofLeaf attempts to upsert a proof for an asset issuance or transfer diff --git a/universe/interface.go b/universe/interface.go index 1c7d09bab..ced57668e 100644 --- a/universe/interface.go +++ b/universe/interface.go @@ -428,12 +428,16 @@ type MultiverseArchive interface { UniverseLeafKeys(ctx context.Context, q UniverseLeafKeysQuery) ([]LeafKey, error) - // FetchLeaves returns the set of multiverse leaves for the given proof - // type, asset ID, and group key. If both asset ID and group key is nil, - // all leaves for the given proof type will be returned. - FetchLeaves(ctx context.Context, assetID *asset.ID, - groupKey *btcec.PublicKey, - proofType ProofType) ([]Identifier, error) + // FetchLeaves returns the set of multiverse leaves that satisfy the set + // of universe targets. If the set of targets is empty, all leaves for + // the given proof type will be returned. + FetchLeaves(ctx context.Context, universeTargets []MultiverseLeafDesc, + proofType ProofType) ([]MultiverseLeaf, error) + + // MultiverseRootNode returns the Multiverse root node for the given + // proof type. + MultiverseRootNode(ctx context.Context, + proofType ProofType) (fn.Option[MultiverseRoot], error) } // Registrar is an interface that allows a caller to upsert a proof leaf in a